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:
Sergey Sharybin 2018-03-02 16:27:31 +01:00
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
6 changed files with 69 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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. */

View File

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