Depsgraph: Fix dependency cycle when ID prop drives ID property
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 2 Mar 2018 15:27:31 +0000 (16:27 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 2 Mar 2018 15:27:31 +0000 (16:27 +0100)
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.

source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes.h
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/depsgraph.cc
source/blender/depsgraph/intern/depsgraph_type_defines.cc
source/blender/depsgraph/intern/depsgraph_types.h

index 6245c514ddbb7078128a22fc2b4ec89c830b408c..0f21c152192f8a29744621ed3c47ea7fb6bd380f 100644 (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 */
index ecaece6a3ac1e83500aca3b126e69eaf46c1854e..9d47dc6bcedcd65c756ff997dd91fb8091b6e1b1 100644 (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);
index 914c8ef33db275d3745e098b51282c29a150edbc..40db9d1b5f116dd1ed26c8ff0e49122ad9b174bd 100644 (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");
                }
        }
index 841242b995ebf54ebd4ddea7b8c34ea6e33c31d2..2e87786639cb9a9bb52a6f373715cce7f275aaea 100644 (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;
index 675002d6b90427665e2dc3c22d6435a88307f2d0..41c72d11eac7d527fc98e1cd64affa135bc4ccca 100644 (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. */
index b2dbe5d2a6278397538e867e06ee1e19585346b3..2d0b67f7ee634c48fd1b1de834dd8dea16d096d8 100644 (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