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.
This commit is contained in:
Sergey Sharybin
2024-01-18 19:23:31 +01:00
committed by Sergey Sharybin
parent fc42227b2d
commit 2cc6eab244
5 changed files with 30 additions and 19 deletions

View File

@@ -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);

View File

@@ -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 = {};

View File

@@ -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

View File

@@ -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";

View File

@@ -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);