From 2cc6eab244dfcef2ce83ecad74e5c58b9ca3ddac Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Jan 2024 19:23:31 +0100 Subject: [PATCH] Cleanup: Simplify tracking of relations for instancing Instead of having a set of hardcoded rules in the collection and object instance collection builder introduce new node on object's INSTANCING component which is to be hooked up to the node which is duplicating the object. Should be no functional changes. --- .../intern/builder/deg_builder_nodes.cc | 8 +++-- .../intern/builder/deg_builder_relations.cc | 31 +++++++++---------- .../builder/deg_builder_relations_rig.cc | 5 +++ .../intern/node/deg_node_operation.cc | 2 ++ .../intern/node/deg_node_operation.hh | 3 ++ 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 33321f3c7ab..afd4ac7262d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -836,10 +836,14 @@ void DepsgraphNodeBuilder::build_object(int base_index, /* Object instancing. */ if (object->instance_collection != nullptr) { build_object_instance_collection(object, is_visible); - OperationNode *op_node = add_operation_node( + + OperationNode *instancer_node = add_operation_node( &object->id, NodeType::INSTANCING, OperationCode::INSTANCER); - op_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED; + instancer_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED; } + OperationNode *instance_node = add_operation_node( + &object->id, NodeType::INSTANCING, OperationCode::INSTANCE); + instance_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED; build_object_light_linking(object); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 5db8e106bd4..ff10acf8b0a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -690,17 +690,9 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll const ComponentKey object_hierarchy_key{&object->id, NodeType::HIERARCHY}; add_relation(collection_hierarchy_key, object_hierarchy_key, "Collection -> Object hierarchy"); - /* The geometry of a collection depends on the positions of the elements in it. */ - const OperationKey object_transform_key{ - &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL}; - add_relation(object_transform_key, collection_geometry_key, "Collection Geometry"); - - /* Only create geometry relations to child objects, if they have a geometry component. */ - const OperationKey object_geometry_key{ - &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL}; - if (find_node(object_geometry_key) != nullptr) { - add_relation(object_geometry_key, collection_geometry_key, "Collection Geometry"); - } + const OperationKey object_instance_key{ + &object->id, NodeType::INSTANCING, OperationCode::INSTANCE}; + add_relation(object_instance_key, collection_geometry_key, "Collection Geometry"); /* An instance is part of the geometry of the collection. */ if (object->type == OB_EMPTY) { @@ -758,6 +750,10 @@ void DepsgraphRelationBuilder::build_object(Object *object) add_relation(local_transform_key, parent_transform_key, "ObLocal -> ObParent"); } + add_relation(ComponentKey(&object->id, NodeType::TRANSFORM), + OperationKey{&object->id, NodeType::INSTANCING, OperationCode::INSTANCE}, + "Transform -> Instance"); + /* Modifiers. */ build_object_modifiers(object); @@ -1266,12 +1262,9 @@ void DepsgraphRelationBuilder::build_object_instance_collection(Object *object) add_relation(dupli_transform_key, object_transform_final_key, "Dupligroup"); /* Hook to special component, to ensure proper visibility/evaluation optimizations. */ - add_relation(dupli_transform_key, instancer_key, "Dupligroup"); - const NodeType dupli_geometry_component_type = geometry_tag_to_component(&ob->id); - if (dupli_geometry_component_type != NodeType::UNDEFINED) { - ComponentKey dupli_geometry_component_key(&ob->id, dupli_geometry_component_type); - add_relation(dupli_geometry_component_key, instancer_key, "Dupligroup"); - } + add_relation(OperationKey(&ob->id, NodeType::INSTANCING, OperationCode::INSTANCE), + instancer_key, + "Instance -> Instancer"); } FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END; } @@ -2489,6 +2482,10 @@ 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); + /* Relation to the instance, so that instancer can use geometry of this object. */ + add_relation(ComponentKey(&object->id, NodeType::GEOMETRY), + OperationKey(&object->id, NodeType::INSTANCING, OperationCode::INSTANCE), + "Transform -> Instance"); /* Grease Pencil Modifiers. */ if (object->greasepencil_modifiers.first != nullptr) { ModifierUpdateDepsgraphContext ctx = {}; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index c7bb2007f4d..04dc215d52b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -306,6 +306,11 @@ void DepsgraphRelationBuilder::build_rig(Object *object) add_relation(armature_key, pose_init_key, "Data dependency"); /* Run cleanup even when there are no bones. */ add_relation(pose_init_key, pose_cleanup_key, "Init -> Cleanup"); + /* Relation to the instance, so that instancer can use pose of this object. */ + add_relation(ComponentKey(&object->id, NodeType::EVAL_POSE), + OperationKey{&object->id, NodeType::INSTANCING, OperationCode::INSTANCE}, + "Transform -> Instance"); + /* IK Solvers. * * - These require separate processing steps are pose-level to be executed diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index 65d1ce444f7..afbc20af6e4 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -202,6 +202,8 @@ const char *operationCodeAsString(OperationCode opcode) /* instancing. */ case OperationCode::INSTANCER: return "INSTANCER"; + case OperationCode::INSTANCE: + return "INSTANCE"; } BLI_assert_msg(0, "Unhandled operation code, should never happen."); return "UNKNOWN"; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.hh b/source/blender/depsgraph/intern/node/deg_node_operation.hh index 48948b18833..1f05559b01f 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.hh +++ b/source/blender/depsgraph/intern/node/deg_node_operation.hh @@ -202,6 +202,9 @@ enum class OperationCode { /* Operation on an instancer object. Relations from instanced objects go here. */ INSTANCER, + + /* Operation on an object which is being instanced. */ + INSTANCE, }; const char *operationCodeAsString(OperationCode opcode);