[Bf-blender-cvs] [9a7ea778b37] master: Fix T61030: Drivers for shape keys not evaluated in correct order

Sergey Sharybin noreply at git.blender.org
Thu Jan 31 14:34:52 CET 2019


Commit: 9a7ea778b37538b0ff479c7fcbf00cdfe721d7fb
Author: Sergey Sharybin
Date:   Thu Jan 31 10:40:38 2019 +0100
Branches: master
https://developer.blender.org/rB9a7ea778b37538b0ff479c7fcbf00cdfe721d7fb

Fix T61030: Drivers for shape keys not evaluated in correct order

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.

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

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

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

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 85745f36ec1..33d047bf674 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -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 */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 95535355bb5..04d0c6cd02c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -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");
+	}
 }
 
 /**
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 3b1a2d00e98..aafd351cbc5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -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;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
index 726393f39b9..f5b9a9ed25a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
@@ -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
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index d7da6658e3e..00a16f3e32c 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -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)) {



More information about the Bf-blender-cvs mailing list