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.
This commit is contained in:
Sergey Sharybin 2019-01-31 10:40:38 +01:00
parent 13de53ecc5
commit 9a7ea778b3
5 changed files with 35 additions and 49 deletions

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

View 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");
}
}
/**

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

View 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

View 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)) {