Depsgraph: Fix dependency cycle when ID prop drives ID property
Introduced explicit ID property node for driers in depsgraph, so it is clear what is the input for driver, and what is the output. This also solved relations builder throwing lots of errors due to ID property not being found.
This commit is contained in:
parent
411a781491
commit
f76d49ed95
Notes:
blender-bot
2023-02-14 06:37:01 +01:00
Referenced by issue #52656, Driver stops updating dynamically if no/incomplete variable is defined
|
@ -532,15 +532,54 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
|
|||
* \param id: ID-Block that driver is attached to
|
||||
* \param fcu: Driver-FCurve
|
||||
*/
|
||||
void DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
void DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcurve)
|
||||
{
|
||||
/* Create data node for this driver */
|
||||
ensure_operation_node(id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
function_bind(BKE_animsys_eval_driver, _1, id, fcu),
|
||||
function_bind(BKE_animsys_eval_driver, _1, id, fcurve),
|
||||
DEG_OPCODE_DRIVER,
|
||||
fcu->rna_path ? fcu->rna_path : "",
|
||||
fcu->array_index);
|
||||
fcurve->rna_path ? fcurve->rna_path : "",
|
||||
fcurve->array_index);
|
||||
build_driver_variables(id, fcurve);
|
||||
}
|
||||
|
||||
void DepsgraphNodeBuilder::build_driver_variables(ID * id, FCurve *fcurve)
|
||||
{
|
||||
build_driver_id_property(id, fcurve->rna_path);
|
||||
LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) {
|
||||
DRIVER_TARGETS_USED_LOOPER(dvar)
|
||||
{
|
||||
build_driver_id_property(dtar->id, dtar->rna_path);
|
||||
}
|
||||
DRIVER_TARGETS_LOOPER_END
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphNodeBuilder::build_driver_id_property(ID *id,
|
||||
const char *rna_path)
|
||||
{
|
||||
if (id == NULL || rna_path == NULL) {
|
||||
return;
|
||||
}
|
||||
PointerRNA id_ptr, ptr;
|
||||
PropertyRNA *prop;
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
if (!RNA_path_resolve_full(&id_ptr, rna_path, &ptr, &prop, NULL)) {
|
||||
return;
|
||||
}
|
||||
if (prop == NULL) {
|
||||
return;
|
||||
}
|
||||
if (!RNA_property_is_idprop(prop)) {
|
||||
return;
|
||||
}
|
||||
const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
|
||||
ensure_operation_node(id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
NULL,
|
||||
DEG_OPCODE_ID_PROPERTY,
|
||||
prop_identifier);
|
||||
}
|
||||
|
||||
/* Recursively build graph for world */
|
||||
|
|
|
@ -138,6 +138,8 @@ struct DepsgraphNodeBuilder {
|
|||
void build_cloth(Object *object);
|
||||
void build_animdata(ID *id);
|
||||
void build_driver(ID *id, FCurve *fcurve);
|
||||
void build_driver_variables(ID *id, FCurve *fcurve);
|
||||
void build_driver_id_property(ID *id, const char *rna_path);
|
||||
void build_ik_pose(Object *object,
|
||||
bPoseChannel *pchan,
|
||||
bConstraint *con);
|
||||
|
|
|
@ -1134,6 +1134,16 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
|
|||
*/
|
||||
}
|
||||
else {
|
||||
if (target_key.prop != NULL &&
|
||||
RNA_property_is_idprop(target_key.prop))
|
||||
{
|
||||
OperationKey parameters_key(id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
DEG_OPCODE_PARAMETERS_EVAL);
|
||||
add_relation(target_key,
|
||||
parameters_key,
|
||||
"Driver Target -> Properties");
|
||||
}
|
||||
add_relation(driver_key, target_key, "Driver -> Target");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,10 +214,18 @@ static bool pointer_to_component_node_criteria(
|
|||
}
|
||||
if (prop != NULL) {
|
||||
/* All unknown data effectively falls under "parameter evaluation". */
|
||||
*type = DEG_NODE_TYPE_PARAMETERS;
|
||||
*operation_code = DEG_OPCODE_PARAMETERS_EVAL;
|
||||
*operation_name = "";
|
||||
*operation_name_tag = -1;
|
||||
if (RNA_property_is_idprop(prop)) {
|
||||
*type = DEG_NODE_TYPE_PARAMETERS;
|
||||
*operation_code = DEG_OPCODE_ID_PROPERTY;
|
||||
*operation_name = RNA_property_identifier((PropertyRNA *)prop);
|
||||
*operation_name_tag = -1;
|
||||
}
|
||||
else {
|
||||
*type = DEG_NODE_TYPE_PARAMETERS;
|
||||
*operation_code = DEG_OPCODE_PARAMETERS_EVAL;
|
||||
*operation_name = "";
|
||||
*operation_name_tag = -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -81,6 +81,7 @@ static const char *stringify_opcode(eDepsOperation_Code opcode)
|
|||
#define STRINGIFY_OPCODE(name) case DEG_OPCODE_##name: return #name
|
||||
/* Generic Operations. */
|
||||
STRINGIFY_OPCODE(OPERATION);
|
||||
STRINGIFY_OPCODE(ID_PROPERTY);
|
||||
STRINGIFY_OPCODE(PARAMETERS_EVAL);
|
||||
STRINGIFY_OPCODE(PLACEHOLDER);
|
||||
/* Animation, Drivers, etc. */
|
||||
|
|
|
@ -137,6 +137,7 @@ typedef enum eDepsOperation_Code {
|
|||
DEG_OPCODE_OPERATION = 0,
|
||||
|
||||
/* Generic parameters evaluation. */
|
||||
DEG_OPCODE_ID_PROPERTY,
|
||||
DEG_OPCODE_PARAMETERS_EVAL,
|
||||
|
||||
// XXX: Placeholder while porting depsgraph code
|
||||
|
|
Loading…
Reference in New Issue