Fix T61030: Drivers for shape keys not evaluated in correct order
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 31 Jan 2019 09:40:38 +0000 (10:40 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 31 Jan 2019 12:00:11 +0000 (13:00 +0100)
Was happening when value of one shape key was driving property of
another shape key of same datablock.

Solved by making shape key blocks properties more granular.

source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
source/blender/depsgraph/intern/depsgraph.cc

index 85745f3..33d047b 100644 (file)
@@ -1238,10 +1238,21 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
                return;
        }
        build_animdata(&key->id);
+       /* This is an exit operation for the entire key datablock, is what is used
+        * as dependency for modifiers evaluation. */
        add_operation_node(&key->id,
                           DEG_NODE_TYPE_GEOMETRY,
                           NULL,
                           DEG_OPCODE_GEOMETRY_SHAPEKEY);
+       /* Create per-key block properties, allowing tricky inter-dependnecies for
+        * drivers evaluation. */
+       LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
+               add_operation_node(&key->id,
+                                  DEG_NODE_TYPE_PARAMETERS,
+                                  NULL,
+                                  DEG_OPCODE_PARAMETERS_EVAL,
+                                  key_block->name);
+       }
 }
 
 /* ObData Geometry Evaluation */
index 9553535..04d0c6c 100644 (file)
@@ -1553,8 +1553,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
                                        continue;
                                }
                                if (is_same_bone_dependency(variable_exit_key, self_key) ||
-                                   is_same_nodetree_node_dependency(variable_exit_key, self_key) ||
-                                   is_same_shapekey_dependency(variable_exit_key, self_key))
+                                   is_same_nodetree_node_dependency(variable_exit_key, self_key))
                                {
                                        continue;
                                }
@@ -1929,8 +1928,17 @@ void DepsgraphRelationBuilder::build_shapekeys(Key *key)
        if (built_map_.checkIsBuiltAndTag(key)) {
                return;
        }
-       /* attach animdata to geometry */
+       /* Attach animdata to geometry. */
        build_animdata(&key->id);
+       /* Connect all blocks properties to the final result evaluation. */
+       ComponentKey geometry_key(&key->id, DEG_NODE_TYPE_GEOMETRY);
+       LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
+               OperationKey key_block_key(&key->id,
+                                          DEG_NODE_TYPE_PARAMETERS,
+                                          DEG_OPCODE_PARAMETERS_EVAL,
+                                          key_block->name);
+               add_relation(key_block_key, geometry_key, "Key Block Properties");
+       }
 }
 
 /**
index 3b1a2d0..aafd351 100644 (file)
@@ -347,13 +347,6 @@ protected:
        bool is_same_nodetree_node_dependency(const KeyFrom& key_from,
                                              const KeyTo& key_to);
 
-       /* Similar to above, but used to check whether driver is using key from
-        * the same key datablock as a driver variable.
-        */
-       template <typename KeyFrom, typename KeyTo>
-       bool is_same_shapekey_dependency(const KeyFrom& key_from,
-                                        const KeyTo& key_to);
-
 private:
        struct BuilderWalkUserData {
                DepsgraphRelationBuilder *builder;
index 726393f..f5b9a9e 100644 (file)
@@ -217,31 +217,4 @@ bool DepsgraphRelationBuilder::is_same_nodetree_node_dependency(
        return true;
 }
 
-template <typename KeyFrom, typename KeyTo>
-bool DepsgraphRelationBuilder::is_same_shapekey_dependency(
-        const KeyFrom& key_from,
-        const KeyTo& key_to)
-{
-       /* Get operations for requested keys. */
-       DepsNode *node_from = get_node(key_from);
-       DepsNode *node_to = get_node(key_to);
-       if (node_from == NULL || node_to == NULL) {
-               return false;
-       }
-       OperationDepsNode *op_from = node_from->get_exit_operation();
-       OperationDepsNode *op_to = node_to->get_entry_operation();
-       if (op_from == NULL || op_to == NULL) {
-               return false;
-       }
-       /* Check if this is actually a shape key datablock. */
-       if (GS(op_from->owner->owner->id_orig->name) != ID_KE) {
-               return false;
-       }
-       /* Different key data blocks. */
-       if (op_from->owner->owner != op_to->owner->owner) {
-               return false;
-       }
-       return true;
-}
-
 }  // namespace DEG
index d7da665..00a16f3 100644 (file)
@@ -124,7 +124,7 @@ static bool pointer_to_component_node_criteria(
         RNAPointerSource /*source*/,
         ID **id,
         eDepsNode_Type *type,
-        const char **subdata,
+        const char **component_name,
         eDepsOperation_Code *operation_code,
         const char **operation_name,
         int *operation_name_tag)
@@ -134,7 +134,7 @@ static bool pointer_to_component_node_criteria(
        }
        /* Set default values for returns. */
        *id = (ID *)ptr->id.data;
-       *subdata = "";
+       *component_name = "";
        *operation_code = DEG_OPCODE_OPERATION;
        *operation_name = "";
        *operation_name_tag = -1;
@@ -150,7 +150,7 @@ static bool pointer_to_component_node_criteria(
                else {
                        /* Bone - generally, we just want the bone component. */
                        *type = DEG_NODE_TYPE_BONE;
-                       *subdata = pchan->name;
+                       *component_name = pchan->name;
                        /* But B-Bone properties should connect to the actual operation. */
                        if (!ELEM(NULL, pchan->bone, prop) && pchan->bone->segments > 1 &&
                            STRPREFIX(RNA_property_identifier(prop), "bbone_"))
@@ -165,7 +165,7 @@ static bool pointer_to_component_node_criteria(
                /* armature-level bone, but it ends up going to bone component anyway */
                // NOTE: the ID in this case will end up being bArmature.
                *type = DEG_NODE_TYPE_BONE;
-               *subdata = bone->name;
+               *component_name = bone->name;
                return true;
        }
        else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
@@ -174,8 +174,7 @@ static bool pointer_to_component_node_criteria(
                /* Check whether is object or bone constraint. */
                /* NOTE: Currently none of the area can address transform of an object
                 * at a given constraint, but for rigging one might use constraint
-                * influence to be used to drive some corrective shape keys or so.
-                */
+                * influence to be used to drive some corrective shape keys or so. */
                if (BLI_findindex(&object->constraints, con) != -1) {
                        *type = DEG_NODE_TYPE_TRANSFORM;
                        *operation_code = DEG_OPCODE_TRANSFORM_LOCAL;
@@ -186,7 +185,7 @@ static bool pointer_to_component_node_criteria(
                                if (BLI_findindex(&pchan->constraints, con) != -1) {
                                        *type = DEG_NODE_TYPE_BONE;
                                        *operation_code = DEG_OPCODE_BONE_LOCAL;
-                                       *subdata = pchan->name;
+                                       *component_name = pchan->name;
                                        return true;
                                }
                        }
@@ -202,7 +201,7 @@ static bool pointer_to_component_node_criteria(
                        if (pchan != NULL) {
                                *type = DEG_NODE_TYPE_BONE;
                                *operation_code = DEG_OPCODE_BONE_LOCAL;
-                               *subdata = pchan->name;
+                               *component_name = pchan->name;
                        }
                        else {
                                *type = DEG_NODE_TYPE_TRANSFORM;
@@ -230,16 +229,18 @@ static bool pointer_to_component_node_criteria(
                        }
                        else if (strstr(prop_identifier, "data")) {
                                /* We access object.data, most likely a geometry.
-                                * Might be a bone tho..
-                                */
+                                * Might be a bone tho. */
                                *type = DEG_NODE_TYPE_GEOMETRY;
                                return true;
                        }
                }
        }
        else if (ptr->type == &RNA_ShapeKey) {
+               KeyBlock *key_block = (KeyBlock *)ptr->data;
                *id = (ID *)ptr->id.data;
-               *type = DEG_NODE_TYPE_GEOMETRY;
+               *type = DEG_NODE_TYPE_PARAMETERS;
+               *operation_code = DEG_OPCODE_PARAMETERS_EVAL;
+               *operation_name = key_block->name;
                return true;
        }
        else if (ptr->type == &RNA_Key) {
@@ -251,7 +252,7 @@ static bool pointer_to_component_node_criteria(
                Sequence *seq = (Sequence *)ptr->data;
                /* Sequencer strip */
                *type = DEG_NODE_TYPE_SEQUENCER;
-               *subdata = seq->name; // xxx?
+               *component_name = seq->name;
                return true;
        }
        else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {