From 7d9a5b7b10b439f62bcc522fee307a942b859ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 5 Mar 2020 17:37:30 +0100 Subject: Fix T73254: Drivers with the object.dimension variable are not updated This fixes an issue where drivers using `object.dimension` only add a dependency on `GEOMETRY` to the depsgraph, whereas they should also depend on `TRANSFORM`. This patch adds a new no-op operation that depends on the geometry and transform components to the Parameters component. An alternative implementation would be to have `RNANodeQuery::construct_node_identifier` return multiple node identifiers. However, this would spread throughout the depsgraph code and unnecessarily force many other functions to either return or handle multiple nodes where in 99.999% of the time a single node would suffice. The new `DIMENSIONS` node is added for each object. An upcoming patch will go over all no-op operation nodes and remove them from the depsgraph. Since this is a more dangerous operation, it'll be reviewed separately. Differential Revision: https://developer.blender.org/D7031 --- source/blender/depsgraph/intern/builder/deg_builder_nodes.cc | 7 +++++++ source/blender/depsgraph/intern/builder/deg_builder_nodes.h | 1 + .../blender/depsgraph/intern/builder/deg_builder_relations.cc | 10 ++++++++++ .../blender/depsgraph/intern/builder/deg_builder_relations.h | 1 + source/blender/depsgraph/intern/builder/deg_builder_rna.cc | 3 ++- source/blender/depsgraph/intern/node/deg_node_operation.cc | 2 ++ source/blender/depsgraph/intern/node/deg_node_operation.h | 1 + 7 files changed, 24 insertions(+), 1 deletion(-) (limited to 'source/blender/depsgraph') diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 1cef9e357e4..b976875508c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -991,6 +991,12 @@ void DepsgraphNodeBuilder::build_parameters(ID *id) op_node->set_as_exit(); } +void DepsgraphNodeBuilder::build_dimensions(Object *object) +{ + /* Object dimensions (bounding box) node. Will depend on both geometry and transform. */ + add_operation_node(&object->id, NodeType::PARAMETERS, OperationCode::DIMENSIONS); +} + /* Recursively build graph for world */ void DepsgraphNodeBuilder::build_world(World *world) { @@ -1224,6 +1230,7 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob build_object_pointcache(object); /* Geometry. */ build_object_data_geometry_datablock((ID *)object->data, is_object_visible); + build_dimensions(object); /* Batch cache. */ add_operation_node(&object->id, NodeType::BATCH_CACHE, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 54a4768d12a..7ddd8d0ade0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -192,6 +192,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_driver_variables(ID *id, FCurve *fcurve); virtual void build_driver_id_property(ID *id, const char *rna_path); virtual void build_parameters(ID *id); + virtual void build_dimensions(Object *object); virtual void build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con); virtual void build_splineik_pose(Object *object, bPoseChannel *pchan, bConstraint *con); virtual void build_rig(Object *object, bool is_object_visible); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 7c8403271f0..78e05a69819 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1588,6 +1588,15 @@ void DepsgraphRelationBuilder::build_parameters(ID *id) add_relation(parameters_eval_key, parameters_exit_key, "Entry -> Exit"); } +void DepsgraphRelationBuilder::build_dimensions(Object *object) +{ + OperationKey dimensions_key(&object->id, NodeType::PARAMETERS, OperationCode::DIMENSIONS); + ComponentKey geometry_key(&object->id, NodeType::GEOMETRY); + ComponentKey transform_key(&object->id, NodeType::TRANSFORM); + add_relation(geometry_key, dimensions_key, "Geometry -> Dimensions"); + add_relation(transform_key, dimensions_key, "Transform -> Dimensions"); +} + void DepsgraphRelationBuilder::build_world(World *world) { if (built_map_.checkIsBuiltAndTag(world)) { @@ -2029,6 +2038,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) } } } + build_dimensions(object); /* Synchronization back to original object. */ ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY); OperationKey synchronize_key( diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 7da3577a7b5..e5e2116008b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -242,6 +242,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_driver_variables(ID *id, FCurve *fcurve); virtual void build_driver_id_property(ID *id, const char *rna_path); virtual void build_parameters(ID *id); + virtual void build_dimensions(Object *object); virtual void build_world(World *world); virtual void build_rigidbody(Scene *scene); virtual void build_particle_systems(Object *object); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 7fb92e77adf..6ae2e4ce696 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -318,7 +318,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, return node_identifier; } else if (STREQ(prop_identifier, "dimensions")) { - node_identifier.type = NodeType::GEOMETRY; + node_identifier.type = NodeType::PARAMETERS; + node_identifier.operation_code = OperationCode::DIMENSIONS; return node_identifier; } } diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc index e313b5ccee7..820dd607e3f 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc @@ -64,6 +64,8 @@ const char *operationCodeAsString(OperationCode opcode) /* Object related. */ case OperationCode::OBJECT_BASE_FLAGS: return "OBJECT_BASE_FLAGS"; + case OperationCode::DIMENSIONS: + return "DIMENSIONS"; /* Transform. */ case OperationCode::TRANSFORM_INIT: return "TRANSFORM_INIT"; diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 87c1a7f10a1..cedbad3715a 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -63,6 +63,7 @@ enum class OperationCode { /* Object related. ------------------------------------------------------ */ OBJECT_BASE_FLAGS, + DIMENSIONS, /* Transform. ----------------------------------------------------------- */ /* Transform entry point. */ -- cgit v1.2.3