From cfbe11563a5dfd39e5b765b986892382f6f4db99 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 4 Aug 2022 11:52:42 +0200 Subject: Depsgrapg: Add per-modifier graph nodes No functional changes expected. --- .../depsgraph/intern/builder/deg_builder_nodes.cc | 22 ++++-- .../depsgraph/intern/builder/deg_builder_nodes.h | 1 + .../intern/builder/deg_builder_relations.cc | 85 +++++++++++++++------- .../intern/builder/deg_builder_relations.h | 1 + .../depsgraph/intern/node/deg_node_operation.cc | 2 + .../depsgraph/intern/node/deg_node_operation.h | 2 + 6 files changed, 80 insertions(+), 33 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index be087c0b2d4..025b2cf21a8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -769,11 +769,7 @@ void DepsgraphNodeBuilder::build_object(int base_index, build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible); } /* Modifiers. */ - if (object->modifiers.first != nullptr) { - BuilderWalkUserData data; - data.builder = this; - BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); - } + build_object_modifiers(object); /* Grease Pencil Modifiers. */ if (object->greasepencil_modifiers.first != nullptr) { BuilderWalkUserData data; @@ -877,6 +873,22 @@ void DepsgraphNodeBuilder::build_object_instance_collection(Object *object, bool is_parent_collection_visible_ = is_current_parent_collection_visible; } +void DepsgraphNodeBuilder::build_object_modifiers(Object *object) +{ + if (BLI_listbase_is_empty(&object->modifiers)) { + return; + } + + LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) { + add_operation_node( + &object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, nullptr, modifier->name); + } + + BuilderWalkUserData data; + data.builder = this; + BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); +} + void DepsgraphNodeBuilder::build_object_data(Object *object) { if (object->data == nullptr) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 18e28311132..d5ac601ebff 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -174,6 +174,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_object_flags(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state); + virtual void build_object_modifiers(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/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index fc5e5189e82..8b51ed214a2 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -298,7 +298,8 @@ void DepsgraphRelationBuilder::add_depends_on_transform_relation(const DepsNodeH { IDNode *id_node = handle->node->owner->owner; ID *id = id_node->id_orig; - ComponentKey geometry_key(id, NodeType::GEOMETRY); + const OperationKey geometry_key( + id, NodeType::GEOMETRY, OperationCode::MODIFIER, handle->node->name.c_str()); /* Wire up the actual relation. */ add_depends_on_transform_relation(id, geometry_key, description); } @@ -718,11 +719,7 @@ void DepsgraphRelationBuilder::build_object(Object *object) } /* Modifiers. */ - if (object->modifiers.first != nullptr) { - BuilderWalkUserData data; - data.builder = this; - BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); - } + build_object_modifiers(object); /* Grease Pencil Modifiers. */ if (object->greasepencil_modifiers.first != nullptr) { @@ -870,6 +867,53 @@ void DepsgraphRelationBuilder::build_object_layer_component_relations(Object *ob add_relation(object_from_layer_exit_key, synchronize_key, "Synchronize to Original"); } +void DepsgraphRelationBuilder::build_object_modifiers(Object *object) +{ + if (BLI_listbase_is_empty(&object->modifiers)) { + return; + } + + const OperationKey eval_init_key( + &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT); + const OperationKey eval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + + ModifierUpdateDepsgraphContext ctx = {}; + ctx.scene = scene_; + ctx.object = object; + + OperationKey previous_key = eval_init_key; + LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) { + const OperationKey modifier_key( + &object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, modifier->name); + + /* Relation for the modifier stack chain. */ + add_relation(previous_key, modifier_key, "Modifier"); + + const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)modifier->type); + if (mti->updateDepsgraph) { + const BuilderStack::ScopedEntry stack_entry = stack_.trace(*modifier); + + DepsNodeHandle handle = create_node_handle(modifier_key); + ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle); + mti->updateDepsgraph(modifier, &ctx); + } + + /* Time dependency. */ + if (BKE_modifier_depends_ontime(scene_, modifier)) { + const TimeSourceKey time_src_key; + add_relation(time_src_key, modifier_key, "Time Source -> Modifier"); + } + + previous_key = modifier_key; + } + add_relation(previous_key, eval_key, "modifier stack order"); + + /* Build IDs referenced by the modifiers. */ + BuilderWalkUserData data; + data.builder = this; + BKE_modifiers_foreach_ID_link(object, modifier_walk, &data); +} + void DepsgraphRelationBuilder::build_object_data(Object *object) { if (object->data == nullptr) { @@ -2193,26 +2237,6 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) * evaluated prior to Scene's CoW is ready. */ OperationKey scene_key(&scene_->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL); add_relation(scene_key, obdata_ubereval_key, "CoW Relation", RELATION_FLAG_NO_FLUSH); - /* Modifiers */ - if (object->modifiers.first != nullptr) { - ModifierUpdateDepsgraphContext ctx = {}; - ctx.scene = scene_; - ctx.object = object; - LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { - const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); - if (mti->updateDepsgraph) { - const BuilderStack::ScopedEntry stack_entry = stack_.trace(*md); - - DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); - ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle); - mti->updateDepsgraph(md, &ctx); - } - if (BKE_modifier_depends_ontime(scene_, md)) { - TimeSourceKey time_src_key; - add_relation(time_src_key, obdata_ubereval_key, "Time Source -> Modifier"); - } - } - } /* Grease Pencil Modifiers. */ if (object->greasepencil_modifiers.first != nullptr) { ModifierUpdateDepsgraphContext ctx = {}; @@ -2256,8 +2280,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) if (ELEM(object->type, OB_MESH, OB_CURVES_LEGACY, OB_LATTICE)) { // add geometry collider relations } - /* Make sure uber update is the last in the dependencies. */ - add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval"); + /* Make sure uber update is the last in the dependencies. + * Only do it here unless there are modifiers. This avoids transitive relations. */ + if (BLI_listbase_is_empty(&object->modifiers)) { + OperationKey obdata_ubereval_key( + &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL); + add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval"); + } if (object->type == OB_MBALL) { Object *mom = BKE_mball_basis_find(scene_, object); ComponentKey mom_geom_key(&mom->id, NodeType::GEOMETRY); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index db237303027..7d3a0fd9217 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -265,6 +265,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_object(Object *object); virtual void build_object_from_view_layer_base(Object *object); virtual void build_object_layer_component_relations(Object *object); + virtual void build_object_modifiers(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/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index de4bc0668cf..4c8c8089ac1 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -84,6 +84,8 @@ const char *operationCodeAsString(OperationCode opcode) /* Geometry. */ case OperationCode::GEOMETRY_EVAL_INIT: return "GEOMETRY_EVAL_INIT"; + case OperationCode::MODIFIER: + return "MODIFIER"; case OperationCode::GEOMETRY_EVAL: return "GEOMETRY_EVAL"; case OperationCode::GEOMETRY_EVAL_DONE: diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 656b27550f6..317bb4a2a93 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -84,6 +84,8 @@ enum class OperationCode { /* Initialize evaluation of the geometry. Is an entry operation of geometry * component. */ GEOMETRY_EVAL_INIT, + /* Modifier. */ + MODIFIER, /* Evaluate the whole geometry, including modifiers. */ GEOMETRY_EVAL, /* Evaluation of geometry is completely done. */ -- cgit v1.2.3