Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-11-11 16:46:19 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-11-11 16:52:05 +0300
commit7dda3cf830a38ebdcc30502a3b1b0cea3885e949 (patch)
tree72083ac66faeff6626ca51208e22b9a013932f81 /source/blender
parentb1743cda5a4249beafea462288df3cd9556d2cd7 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc123
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc3
2 files changed, 94 insertions, 32 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 7808a12ec53..8cf0fdff915 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 49ae82390ea..30b31864414 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");
}
}