diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-06-08 12:42:41 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-06-08 12:57:16 +0300 |
commit | 4017b4833152655dbb161896ab1bf47469a61d69 (patch) | |
tree | 2e767b2204bacabe2af1d834c57454d11df629ce /source/blender/depsgraph | |
parent | 378e42e11933bd069b49a83232c5eccb279bc6c7 (diff) |
Depsgraph: Don't optimize out collections used by duplication system
This makes evaluated objects to point to a non-evaluated collection,
which is already really bad. What is even more worse, objects in those
collections are not evaluated either.
Proper solution would be to implement visibility flag for nodes, which
will be set to 0 for transform/geometry components, but which will be
1 for copy-on-write components.
This way we will guarantee consistency of dependency graph.
For now this change is good enough and unlocks production.
Fixes T55375: Crash when changing visibility of instanced collection
Fixes T55357: Particle geometry crash
Diffstat (limited to 'source/blender/depsgraph')
7 files changed, 51 insertions, 28 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 3cafa29b894..04208cf10ed 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -390,7 +390,7 @@ void DepsgraphNodeBuilder::build_id(ID *id) { build_camera((Camera *)id); break; case ID_GR: - build_collection((Collection *)id); + build_collection(DEG_COLLECTION_OWNER_UNKNOWN, (Collection *)id); break; case ID_OB: build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY); @@ -438,28 +438,32 @@ void DepsgraphNodeBuilder::build_id(ID *id) { } } -void DepsgraphNodeBuilder::build_collection(Collection *collection) +void DepsgraphNodeBuilder::build_collection( + eDepsNode_CollectionOwner owner_type, + Collection *collection) { if (built_map_.checkIsBuiltAndTag(collection)) { return; } - - const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? - COLLECTION_RESTRICT_VIEW : COLLECTION_RESTRICT_RENDER; - if (collection->flag & restrict_flag) { - return; + const bool allow_restrict_flags = (owner_type == DEG_COLLECTION_OWNER_SCENE); + if (allow_restrict_flags) { + const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) + ? COLLECTION_RESTRICT_VIEW + : COLLECTION_RESTRICT_RENDER; + if (collection->flag & restrict_flag) { + return; + } } - + /* Collection itself. */ + add_id_node(&collection->id); /* Build collection objects. */ LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { build_object(-1, cob->ob, DEG_ID_LINKED_INDIRECTLY); } /* Build child collections. */ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - build_collection(child->collection); + build_collection(owner_type, child->collection); } - - add_id_node(&collection->id); } void DepsgraphNodeBuilder::build_object(int base_index, @@ -531,7 +535,7 @@ void DepsgraphNodeBuilder::build_object(int base_index, } /* Object dupligroup. */ if (object->dup_group != NULL) { - build_collection(object->dup_group); + build_collection(DEG_COLLECTION_OWNER_OBJECT, object->dup_group); } } @@ -968,7 +972,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object) break; case PART_DRAW_GR: if (part->dup_group != NULL) { - build_collection(part->dup_group); + build_collection(DEG_COLLECTION_OWNER_OBJECT, part->dup_group); } break; } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 9d3e51ef38d..72aa5dbe003 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -161,7 +161,8 @@ struct DepsgraphNodeBuilder { void build_view_layer(Scene *scene, ViewLayer *view_layer, eDepsNode_LinkedState_Type linked_state); - void build_collection(Collection *collection); + void build_collection(eDepsNode_CollectionOwner owner_type, + Collection *collection); void build_object(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index 7f44356a5cf..e2526272570 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -75,7 +75,7 @@ void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb) continue; } if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) { - build_collection(lc->collection); + build_collection(DEG_COLLECTION_OWNER_SCENE, lc->collection); } build_layer_collections(&lc->layer_collections); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 0dffe60e9d9..eb1ee0c1535 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -406,7 +406,7 @@ void DepsgraphRelationBuilder::build_id(ID *id) build_camera((Camera *)id); break; case ID_GR: - build_collection(NULL, (Collection *)id); + build_collection(DEG_COLLECTION_OWNER_UNKNOWN, NULL, (Collection *)id); break; case ID_OB: build_object(NULL, (Object *)id); @@ -451,14 +451,20 @@ void DepsgraphRelationBuilder::build_id(ID *id) } } -void DepsgraphRelationBuilder::build_collection(Object *object, Collection *collection) +void DepsgraphRelationBuilder::build_collection( + eDepsNode_CollectionOwner owner_type, + Object *object, + Collection *collection) { - const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? - COLLECTION_RESTRICT_VIEW : COLLECTION_RESTRICT_RENDER; - if (collection->flag & restrict_flag) { - return; + const bool allow_restrict_flags = (owner_type == DEG_COLLECTION_OWNER_SCENE); + if (allow_restrict_flags) { + const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) + ? COLLECTION_RESTRICT_VIEW + : COLLECTION_RESTRICT_RENDER; + if (collection->flag & restrict_flag) { + return; + } } - const bool group_done = built_map_.checkIsBuiltAndTag(collection); OperationKey object_local_transform_key(object != NULL ? &object->id : NULL, DEG_NODE_TYPE_TRANSFORM, @@ -468,7 +474,7 @@ void DepsgraphRelationBuilder::build_collection(Object *object, Collection *coll build_object(NULL, cob->ob); } LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - build_collection(NULL, child->collection); + build_collection(owner_type, NULL, child->collection); } } if (object != NULL) { @@ -591,7 +597,7 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) /* Object dupligroup. */ if (object->dup_group != NULL) { - build_collection(object, object->dup_group); + build_collection(DEG_COLLECTION_OWNER_OBJECT, object, object->dup_group); } } @@ -1602,7 +1608,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object) break; case PART_DRAW_GR: if (part->dup_group != NULL) { - build_collection(NULL, part->dup_group); + build_collection(DEG_COLLECTION_OWNER_OBJECT, NULL, part->dup_group); LISTBASE_FOREACH (CollectionObject *, go, &part->dup_group->gobject) { build_particles_visualization_object(object, psys, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index ec932eccc9f..3d3a73b6551 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -201,7 +201,9 @@ struct DepsgraphRelationBuilder void build_id(ID *id); void build_layer_collections(ListBase *lb); void build_view_layer(Scene *scene, ViewLayer *view_layer); - void build_collection(Object *object, Collection *collection); + void build_collection(eDepsNode_CollectionOwner owner_type, + Object *object, + Collection *collection); void build_object(Base *base, Object *object); void build_object_flags(Base *base, Object *object); void build_object_data(Object *object); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc index 0f159248ff4..ce0571362c6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc @@ -77,7 +77,7 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb) for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) { if (!(lc->collection->flag & restrict_flag)) { if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) { - build_collection(NULL, lc->collection); + build_collection(DEG_COLLECTION_OWNER_SCENE, NULL, lc->collection); } build_layer_collections(&lc->layer_collections); diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index 18bc0bd0501..cec279a04bb 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -272,7 +272,17 @@ typedef enum eDepsOperation_Code { DEG_NUM_OPCODES, } eDepsOperation_Code; - const char *operationCodeAsString(eDepsOperation_Code opcode); +typedef enum eDepsNode_CollectionOwner { + /* Unknown owner of collection, collection is pulled directly, maybe + * via driver. + */ + DEG_COLLECTION_OWNER_UNKNOWN, + /* Collection belongs to a scene. */ + DEG_COLLECTION_OWNER_SCENE, + /* Collection is used by object, as a dupli-system. */ + DEG_COLLECTION_OWNER_OBJECT, +} eDepsNode_CollectionOwner; + } // namespace DEG |