diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-06-26 13:29:20 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-06-26 13:34:38 +0300 |
commit | c7694185c92aa44c90fa43e58e88742e085183d9 (patch) | |
tree | 1a29c6845aa54004a2310ce2e9371989a3c55627 /source/blender/depsgraph | |
parent | 2a72421cfb38d9a4a19a473184ba28b8ef8851e4 (diff) |
Fix T78071: Drivers reading object visibility not updating automatically
A driver reading `Object.hide_viewport` would break when that object was
hidden. Hidden objects don't have the `OBJECT_BASE_FLAGS` node in the
depsgraph, but that node was required for the driver to work.
Now the `OBJECT_FROM_LAYER` component (which optionally contains the
`OBJECT_FROM_LAYER` node) has explicit `ENTRY` and `EXIT` nodes, which
are used for relations with other components. These relations now remain
valid, even when the `OBJECT_FROM_LAYER` node is absent.
Differential Revision: https://developer.blender.org/D8124
Reviewed By: sergey
Diffstat (limited to 'source/blender/depsgraph')
7 files changed, 53 insertions, 18 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index d84ec9b1363..dab5c3ea911 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -594,7 +594,7 @@ void DepsgraphNodeBuilder::build_object(int base_index, } id_node->has_base |= (base_index != -1); /* Various flags, flushing from bases/collections. */ - build_object_flags(base_index, object, linked_state); + build_object_from_layer(base_index, object, linked_state); /* Transform. */ build_object_transform(object); /* Parent. */ @@ -662,6 +662,21 @@ void DepsgraphNodeBuilder::build_object(int base_index, function_bind(BKE_object_sync_to_original, _1, object_cow)); } +void DepsgraphNodeBuilder::build_object_from_layer(int base_index, + Object *object, + eDepsNode_LinkedState_Type linked_state) +{ + + OperationNode *entry_node = add_operation_node( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_ENTRY); + entry_node->set_as_entry(); + OperationNode *exit_node = add_operation_node( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_EXIT); + exit_node->set_as_exit(); + + build_object_flags(base_index, object, linked_state); +} + void DepsgraphNodeBuilder::build_object_flags(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index e0553182918..dbe3e310d72 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -168,6 +168,9 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_object_proxy_from(Object *object, bool is_object_visible); virtual void build_object_proxy_group(Object *object, bool is_object_visible); virtual void build_object_instance_collection(Object *object, bool is_object_visible); + virtual void build_object_from_layer(int base_index, + Object *object, + eDepsNode_LinkedState_Type linked_state); virtual void build_object_flags(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index e21a83485ad..5b49e13e17a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -621,12 +621,9 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll } } -void DepsgraphRelationBuilder::build_object(Base *base, Object *object) +void DepsgraphRelationBuilder::build_object(Base * /*base*/, Object *object) { if (built_map_.checkIsBuiltAndTag(object)) { - if (base != nullptr) { - build_object_flags(base, object); - } return; } /* Object Transforms */ @@ -644,7 +641,7 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) OperationKey ob_eval_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL); add_relation(init_transform_key, local_transform_key, "Transform Init"); /* Various flags, flushing from bases/collections. */ - build_object_flags(base, object); + build_object_from_layer_relations(object); /* Parenting. */ if (object->parent != nullptr) { /* Make sure parent object's relations are built. */ @@ -755,20 +752,34 @@ void DepsgraphRelationBuilder::build_object_proxy_group(Object *object) add_relation(proxy_group_eval_key, transform_eval_key, "Proxy Group Transform"); } -void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object) +void DepsgraphRelationBuilder::build_object_from_layer_relations(Object *object) { - if (base == nullptr) { - return; + OperationKey object_from_layer_entry_key( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_ENTRY); + OperationKey object_from_layer_exit_key( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_FROM_LAYER_EXIT); + OperationKey object_flags_key( + &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_BASE_FLAGS); + + /* Only connect Entry -> Exit if there is no OBJECT_BASE_FLAGS node. */ + if (has_node(object_flags_key)) { + /* Entry -> OBJECT_BASE_FLAGS -> Exit */ + add_relation(object_from_layer_entry_key, object_flags_key, "Base flags flush Entry"); + add_relation(object_flags_key, object_from_layer_exit_key, "Base flags flush Exit"); + + /* Synchronization back to original object. */ + OperationKey synchronize_key( + &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); + add_relation(object_from_layer_exit_key, synchronize_key, "Synchronize to Original"); + } + else { + /* Directly connect Entry -> Exit. */ + add_relation(object_from_layer_entry_key, object_from_layer_exit_key, "Object from Layer"); } + OperationKey view_layer_done_key( &scene_->id, NodeType::LAYER_COLLECTIONS, OperationCode::VIEW_LAYER_EVAL); - OperationKey object_flags_key( - &object->id, NodeType::OBJECT_FROM_LAYER, OperationCode::OBJECT_BASE_FLAGS); - add_relation(view_layer_done_key, object_flags_key, "Base flags flush"); - /* Synchronization back to original object. */ - OperationKey synchronize_key( - &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); - add_relation(object_flags_key, synchronize_key, "Synchronize to Original"); + add_relation(view_layer_done_key, object_from_layer_entry_key, "View Layer flags to Object"); } void DepsgraphRelationBuilder::build_object_data(Object *object) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index aa6d8ababd3..1be68babbc5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -213,7 +213,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_object(Base *base, Object *object); virtual void build_object_proxy_from(Object *object); virtual void build_object_proxy_group(Object *object); - virtual void build_object_flags(Base *base, Object *object); + virtual void build_object_from_layer_relations(Object *object); virtual void build_object_data(Object *object); virtual void build_object_data_camera(Object *object); virtual void build_object_data_geometry(Object *object); diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index b757a4fc477..73aa58d2072 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -109,7 +109,7 @@ void depsgraph_select_tag_to_component_opcode(const ID *id, } else if (id_type == ID_OB) { *component_type = NodeType::OBJECT_FROM_LAYER; - *operation_code = OperationCode::OBJECT_BASE_FLAGS; + *operation_code = OperationCode::OBJECT_FROM_LAYER_ENTRY; } else if (id_type == ID_MC) { *component_type = NodeType::BATCH_CACHE; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 91bd0117f6c..33d2bf79a5e 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -63,8 +63,12 @@ const char *operationCodeAsString(OperationCode opcode) case OperationCode::AUDIO_VOLUME: return "AUDIO_VOLUME"; /* Object related. */ + case OperationCode::OBJECT_FROM_LAYER_ENTRY: + return "OBJECT_FROM_LAYER_ENTRY"; case OperationCode::OBJECT_BASE_FLAGS: return "OBJECT_BASE_FLAGS"; + case OperationCode::OBJECT_FROM_LAYER_EXIT: + return "OBJECT_FROM_LAYER_EXIT"; case OperationCode::DIMENSIONS: return "DIMENSIONS"; /* Transform. */ diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 6b14e6af02f..4ed266d355f 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -63,7 +63,9 @@ enum class OperationCode { AUDIO_VOLUME, /* Object related. ------------------------------------------------------ */ + OBJECT_FROM_LAYER_ENTRY, OBJECT_BASE_FLAGS, + OBJECT_FROM_LAYER_EXIT, DIMENSIONS, /* Transform. ----------------------------------------------------------- */ |