[Bf-blender-cvs] [7dda3cf] master: Fix T49993: Indirectly used taper/bevel crashes new dependency graph

Sergey Sharybin noreply at git.blender.org
Fri Nov 11 15:04:24 CET 2016


Commit: 7dda3cf830a38ebdcc30502a3b1b0cea3885e949
Author: Sergey Sharybin
Date:   Fri Nov 11 14:46:19 2016 +0100
Branches: master
https://developer.blender.org/rB7dda3cf830a38ebdcc30502a3b1b0cea3885e949

Fix T49993: Indirectly used taper/bevel crashes new dependency graph

New dependency graph expects strict separation between nodes and relations builder,
meaning, if we try to create relation with an object which is not in the graph yet
we'll have an error in depsgraph.

Now, so far object nodes were created from bases of the current scene, which caused
missing objects in graph in certain cases.

Didn't find better approach than to simply ensure object nodes exists when we know
they'll be used by relation builder.

===================================================================

M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc

===================================================================

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 7808a12..8cf0fdf 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -108,6 +108,40 @@ extern "C" {
 
 namespace DEG {
 
+namespace {
+
+struct BuilderWalkUserData {
+	DepsgraphNodeBuilder *builder;
+	Scene *scene;
+};
+
+static void modifier_walk(void *user_data,
+                          struct Object * /*ob*/,
+                          struct Object **obpoin,
+                          int /*cd_flag*/)
+{
+	BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
+	if (*obpoin) {
+		data->builder->build_object(data->scene, NULL, *obpoin);
+	}
+}
+
+void constraint_walk(bConstraint * /*con*/,
+                     ID **idpoin,
+                     bool /*is_reference*/,
+                     void *user_data)
+{
+	BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
+	if (*idpoin) {
+		ID *id = *idpoin;
+		if (GS(id) == ID_OB) {
+			data->builder->build_object(data->scene, NULL, (Object *)id);
+		}
+	}
+}
+
+}  /* namespace */
+
 /* ************ */
 /* Node Builder */
 
@@ -405,19 +439,22 @@ SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group)
 	{
 		/*Object *ob = go->ob;*/
 
-		/* Each "group object" is effectively a separate instance of the underlying
-		 * object data. When the group is evaluated, the transform results and/or
-		 * some other attributes end up getting overridden by the group
+		/* Each "group object" is effectively a separate instance of the
+		 * underlying object data. When the group is evaluated, the transform
+		 * results and/or some other attributes end up getting overridden by
+		 * the group.
 		 */
 	}
 
-	/* create a node for representing subgraph */
+	/* Create a node for representing subgraph. */
 	SubgraphDepsNode *subgraph_node = m_graph->add_subgraph_node(&group->id);
 	subgraph_node->graph = subgraph;
 
-	/* make a copy of the data this node will need? */
-	// XXX: do we do this now, or later?
-	// TODO: need API function which queries graph's ID's hash, and duplicates those blocks thoroughly with all outside links removed...
+	/* Make a copy of the data this node will need? */
+	/* XXX: do we do this now, or later? */
+	/* TODO: need API function which queries graph's ID's hash, and duplicates
+	 * those blocks thoroughly with all outside links removed.
+	 */
 
 	return subgraph_node;
 }
@@ -432,13 +469,32 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
 	ob->id.tag |= LIB_TAG_DOIT;
 
 	IDDepsNode *id_node = add_id_node(&ob->id);
-	id_node->layers |= base->lay;
+	if (base != NULL) {
+		id_node->layers |= base->lay;
+	}
 	ob->customdata_mask = 0;
 
-	/* standard components */
+	/* Standard components. */
 	build_object_transform(scene, ob);
 
-	/* object data */
+	if (ob->parent != NULL) {
+		build_object(scene, NULL, ob->parent);
+	}
+	if (ob->modifiers.first != NULL) {
+		BuilderWalkUserData data;
+		data.builder = this;
+		data.scene = scene;
+		modifiers_foreachObjectLink(ob, modifier_walk, &data);
+	}
+	if (ob->constraints.first != NULL) {
+		BuilderWalkUserData data;
+		data.builder = this;
+		data.scene = scene;
+		modifiers_foreachObjectLink(ob, modifier_walk, &data);
+		BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data);
+	}
+
+	/* Object data. */
 	if (ob->data) {
 		/* type-specific data... */
 		switch (ob->type) {
@@ -1110,9 +1166,10 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
 		}
 
 		case OB_CURVE:
+		case OB_SURF:
 		case OB_FONT:
 		{
-			/* Curve evaluation operations. */
+			/* Curve/nurms evaluation operations. */
 			/* - calculate curve geometry (including path) */
 			add_operation_node(obdata,
 			                   DEPSNODE_TYPE_GEOMETRY,
@@ -1124,28 +1181,30 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
 			                   "Geometry Eval");
 
 			/* Calculate curve path - this is used by constraints, etc. */
-			add_operation_node(obdata,
-			                   DEPSNODE_TYPE_GEOMETRY,
-			                   DEPSOP_TYPE_EXEC,
-			                   function_bind(BKE_curve_eval_path,
-			                                 _1,
-			                                 (Curve *)obdata),
-			                   DEG_OPCODE_GEOMETRY_PATH,
-			                   "Path");
-			break;
-		}
+			if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
+				add_operation_node(obdata,
+				                   DEPSNODE_TYPE_GEOMETRY,
+				                   DEPSOP_TYPE_EXEC,
+				                   function_bind(BKE_curve_eval_path,
+				                                 _1,
+				                                 (Curve *)obdata),
+				                   DEG_OPCODE_GEOMETRY_PATH,
+				                   "Path");
+			}
 
-		case OB_SURF:
-		{
-			/* Nurbs evaluation operations. */
-			add_operation_node(obdata,
-			                   DEPSNODE_TYPE_GEOMETRY,
-			                   DEPSOP_TYPE_INIT,
-			                   function_bind(BKE_curve_eval_geometry,
-			                                 _1,
-			                                 (Curve *)obdata),
-			                   DEG_OPCODE_PLACEHOLDER,
-			                   "Geometry Eval");
+			/* Make sure objects used for bevel.taper are in the graph.
+			 * NOTE: This objects might be not linked to the scene.
+			 */
+			Curve *cu = (Curve *)obdata;
+			if (cu->bevobj != NULL) {
+				build_object(scene, NULL, cu->bevobj);
+			}
+			if (cu->taperobj != NULL) {
+				build_object(scene, NULL, cu->bevobj);
+			}
+			if (ob->type == OB_FONT && cu->textoncurve != NULL) {
+				build_object(scene, NULL, cu->textoncurve);
+			}
 			break;
 		}
 
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 49ae823..30b3186 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1908,15 +1908,18 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
 			// XXX: these needs geom data, but where is geom stored?
 			if (cu->bevobj) {
 				ComponentKey bevob_key(&cu->bevobj->id, DEPSNODE_TYPE_GEOMETRY);
+				build_object(bmain, scene, cu->bevobj);
 				add_relation(bevob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Bevel");
 			}
 			if (cu->taperobj) {
 				ComponentKey taperob_key(&cu->taperobj->id, DEPSNODE_TYPE_GEOMETRY);
+				build_object(bmain, scene, cu->taperobj);
 				add_relation(taperob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Taper");
 			}
 			if (ob->type == OB_FONT) {
 				if (cu->textoncurve) {
 					ComponentKey textoncurve_key(&cu->textoncurve->id, DEPSNODE_TYPE_GEOMETRY);
+					build_object(bmain, scene, cu->textoncurve);
 					add_relation(textoncurve_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Text on Curve");
 				}
 			}




More information about the Bf-blender-cvs mailing list