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
This commit is contained in:
@@ -991,6 +991,12 @@ void DepsgraphNodeBuilder::build_parameters(ID *id)
|
|||||||
op_node->set_as_exit();
|
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 */
|
/* Recursively build graph for world */
|
||||||
void DepsgraphNodeBuilder::build_world(World *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);
|
build_object_pointcache(object);
|
||||||
/* Geometry. */
|
/* Geometry. */
|
||||||
build_object_data_geometry_datablock((ID *)object->data, is_object_visible);
|
build_object_data_geometry_datablock((ID *)object->data, is_object_visible);
|
||||||
|
build_dimensions(object);
|
||||||
/* Batch cache. */
|
/* Batch cache. */
|
||||||
add_operation_node(&object->id,
|
add_operation_node(&object->id,
|
||||||
NodeType::BATCH_CACHE,
|
NodeType::BATCH_CACHE,
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
|
|||||||
virtual void build_driver_variables(ID *id, FCurve *fcurve);
|
virtual void build_driver_variables(ID *id, FCurve *fcurve);
|
||||||
virtual void build_driver_id_property(ID *id, const char *rna_path);
|
virtual void build_driver_id_property(ID *id, const char *rna_path);
|
||||||
virtual void build_parameters(ID *id);
|
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_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con);
|
||||||
virtual void build_splineik_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);
|
virtual void build_rig(Object *object, bool is_object_visible);
|
||||||
|
|||||||
@@ -1588,6 +1588,15 @@ void DepsgraphRelationBuilder::build_parameters(ID *id)
|
|||||||
add_relation(parameters_eval_key, parameters_exit_key, "Entry -> Exit");
|
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)
|
void DepsgraphRelationBuilder::build_world(World *world)
|
||||||
{
|
{
|
||||||
if (built_map_.checkIsBuiltAndTag(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. */
|
/* Synchronization back to original object. */
|
||||||
ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY);
|
ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY);
|
||||||
OperationKey synchronize_key(
|
OperationKey synchronize_key(
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
|
|||||||
virtual void build_driver_variables(ID *id, FCurve *fcurve);
|
virtual void build_driver_variables(ID *id, FCurve *fcurve);
|
||||||
virtual void build_driver_id_property(ID *id, const char *rna_path);
|
virtual void build_driver_id_property(ID *id, const char *rna_path);
|
||||||
virtual void build_parameters(ID *id);
|
virtual void build_parameters(ID *id);
|
||||||
|
virtual void build_dimensions(Object *object);
|
||||||
virtual void build_world(World *world);
|
virtual void build_world(World *world);
|
||||||
virtual void build_rigidbody(Scene *scene);
|
virtual void build_rigidbody(Scene *scene);
|
||||||
virtual void build_particle_systems(Object *object);
|
virtual void build_particle_systems(Object *object);
|
||||||
|
|||||||
@@ -318,7 +318,8 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
|
|||||||
return node_identifier;
|
return node_identifier;
|
||||||
}
|
}
|
||||||
else if (STREQ(prop_identifier, "dimensions")) {
|
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;
|
return node_identifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ const char *operationCodeAsString(OperationCode opcode)
|
|||||||
/* Object related. */
|
/* Object related. */
|
||||||
case OperationCode::OBJECT_BASE_FLAGS:
|
case OperationCode::OBJECT_BASE_FLAGS:
|
||||||
return "OBJECT_BASE_FLAGS";
|
return "OBJECT_BASE_FLAGS";
|
||||||
|
case OperationCode::DIMENSIONS:
|
||||||
|
return "DIMENSIONS";
|
||||||
/* Transform. */
|
/* Transform. */
|
||||||
case OperationCode::TRANSFORM_INIT:
|
case OperationCode::TRANSFORM_INIT:
|
||||||
return "TRANSFORM_INIT";
|
return "TRANSFORM_INIT";
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ enum class OperationCode {
|
|||||||
|
|
||||||
/* Object related. ------------------------------------------------------ */
|
/* Object related. ------------------------------------------------------ */
|
||||||
OBJECT_BASE_FLAGS,
|
OBJECT_BASE_FLAGS,
|
||||||
|
DIMENSIONS,
|
||||||
|
|
||||||
/* Transform. ----------------------------------------------------------- */
|
/* Transform. ----------------------------------------------------------- */
|
||||||
/* Transform entry point. */
|
/* Transform entry point. */
|
||||||
|
|||||||
Reference in New Issue
Block a user