[Bf-blender-cvs] [1c586040706] master: Depsgraph: fix Bone property drivers stored in Object animdata.

Alexander Gavrilov noreply at git.blender.org
Sun May 5 09:45:50 CEST 2019


Commit: 1c58604070682a1fe01d6fd49820c1578f18580a
Author: Alexander Gavrilov
Date:   Sat May 4 20:12:19 2019 +0300
Branches: master
https://developer.blender.org/rB1c58604070682a1fe01d6fd49820c1578f18580a

Depsgraph: fix Bone property drivers stored in Object animdata.

This can easily happen if adding drivers through Python via
pose.bones[...].bone.driver_add(), e.g. in Rigify code: the
bone field doesn't change id_data, so the driver is associated
with the object ID.

To handle this it's necessary to skip from Object to data in
RNA_Bone-specific code both for generic RNA and in the custom
code for drivers. The latter also had to be changed to use the
proper parsed RNA pointer instead of string matching on paths.

===================================================================

M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/builder/deg_builder_rna.cc

===================================================================

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 3f6e33eed61..4c4bc01a3dd 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1327,25 +1327,47 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
 
 void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
 {
-  OperationKey driver_key(id,
-                          NodeType::PARAMETERS,
-                          OperationCode::DRIVER,
-                          fcu->rna_path ? fcu->rna_path : "",
-                          fcu->array_index);
-  const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
-  if (GS(id->name) == ID_AR && STRPREFIX(rna_path, "bones[")) {
+  /* Validate the RNA path pointer just in case. */
+  const char *rna_path = fcu->rna_path;
+  if (rna_path == NULL || rna_path[0] == '\0') {
+    return;
+  }
+  /* Parse the RNA path to find the target property pointer. */
+  RNAPathKey property_entry_key(id, rna_path, RNAPointerSource::ENTRY);
+  if (RNA_pointer_is_null(&property_entry_key.ptr)) {
+    /* TODO(sergey): This would only mean that driver is broken.
+     * so we can't create relation anyway. However, we need to avoid
+     * adding drivers which are known to be buggy to a dependency
+     * graph, in order to save computational power. */
+    return;
+  }
+  OperationKey driver_key(
+      id, NodeType::PARAMETERS, OperationCode::DRIVER, rna_path, fcu->array_index);
+  /* If the target of the driver is a Bone property, find the Armature data,
+   * and then link the driver to all pose bone evaluation components that use
+   * it. This is necessary to provide more granular dependencies specifically for
+   * Bone objects, because the armature data doesn't have per-bone components,
+   * and generic add_relation can only add one link. */
+  ID *id_ptr = (ID *)property_entry_key.ptr.id.data;
+  bool is_bone = id_ptr && property_entry_key.ptr.type == &RNA_Bone;
+  /* If the Bone property is referenced via obj.pose.bones[].bone,
+   * the RNA pointer refers to the Object ID, so skip to data. */
+  if (is_bone && GS(id_ptr->name) == ID_OB) {
+    id_ptr = (ID *)((Object *)id_ptr)->data;
+  }
+  if (is_bone && GS(id_ptr->name) == ID_AR) {
     /* Drivers on armature-level bone settings (i.e. bbone stuff),
      * which will affect the evaluation of corresponding pose bones. */
-    char *bone_name = BLI_str_quoted_substrN(rna_path, "bones[");
-    if (bone_name != NULL) {
+    Bone *bone = (Bone *)property_entry_key.ptr.data;
+    if (bone != NULL) {
       /* Find objects which use this, and make their eval callbacks
        * depend on this. */
       for (IDNode *to_node : graph_->id_nodes) {
         if (GS(to_node->id_orig->name) == ID_OB) {
           Object *object = (Object *)to_node->id_orig;
           /* We only care about objects with pose data which use this. */
-          if (object->data == id && object->pose != NULL) {
-            bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name);
+          if (object->data == id_ptr && object->pose != NULL) {
+            bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone->name);
             if (pchan != NULL) {
               OperationKey bone_key(
                   &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
@@ -1354,23 +1376,18 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
           }
         }
       }
-      /* Free temp data. */
-      MEM_freeN(bone_name);
-      bone_name = NULL;
+      /* Make the driver depend on COW, similar to the generic case below. */
+      if (id_ptr != id) {
+        ComponentKey cow_key(id_ptr, NodeType::COPY_ON_WRITE);
+        add_relation(cow_key, driver_key, "Driven CoW -> Driver", RELATION_CHECK_BEFORE_ADD);
+      }
     }
     else {
       fprintf(stderr, "Couldn't find armature bone name for driver path - '%s'\n", rna_path);
     }
   }
-  else if (rna_path != NULL && rna_path[0] != '\0') {
-    RNAPathKey property_entry_key(id, rna_path, RNAPointerSource::ENTRY);
-    if (RNA_pointer_is_null(&property_entry_key.ptr)) {
-      /* TODO(sergey): This would only mean that driver is broken.
-       * so we can't create relation anyway. However, we need to avoid
-       * adding drivers which are known to be buggy to a dependency
-       * graph, in order to save computational power. */
-      return;
-    }
+  else {
+    /* If it's not a Bone, handle the generic single dependency case. */
     add_relation(driver_key, property_entry_key, "Driver -> Driven Property");
     /* Similar to the case with f-curves, driver might drive a nested
      * datablock, which means driver execution should wait for that
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 1238cdc70c6..ea5f86a31a8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -211,6 +211,12 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
      * bone components, instead of using this generic code. */
     node_identifier.type = NodeType::PARAMETERS;
     node_identifier.operation_code = OperationCode::ARMATURE_EVAL;
+    /* If trying to look up via an Object, e.g. due to lookup via
+     * obj.pose.bones[].bone in a driver attached to the Object,
+     * redirect to its data. */
+    if (GS(node_identifier.id->name) == ID_OB) {
+      node_identifier.id = (ID *)((Object *)node_identifier.id)->data;
+    }
     return node_identifier;
   }
   else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {



More information about the Bf-blender-cvs mailing list