Fix dependency graph for constraints depending on B-Bone shape.

Some constraints have an option to take the final bezier shape of
the target B-Bone into account. This shape usually depends on two
other bones in addition to the target itself, so the graph should
include the relevant dependencies.

Reviewers: sergey

Differential Revision: https://developer.blender.org/D3591
This commit is contained in:
2018-08-09 17:17:40 +03:00
parent ff6bd57873
commit a5aeca4a64
7 changed files with 98 additions and 52 deletions

View File

@@ -185,6 +185,23 @@ static bool check_id_has_anim_component(ID *id)
(!BLI_listbase_is_empty(&adt->nla_tracks));
}
static eDepsOperation_Code bone_target_opcode(ID *target, const char *subtarget, ID *id, const char *component_subdata, RootPChanMap *root_map)
{
/* same armature */
if (target == id) {
/* Using "done" here breaks in-chain deps, while using
* "ready" here breaks most production rigs instead.
* So, we do a compromise here, and only do this when an
* IK chain conflict may occur.
*/
if (root_map->has_common_root(component_subdata, subtarget)) {
return DEG_OPCODE_BONE_READY;
}
}
return DEG_OPCODE_BONE_DONE;
}
/* **** General purpose functions **** */
DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain,
@@ -907,38 +924,42 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
add_relation(target_transform_key, constraint_op_key, cti->name);
}
else if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) {
/* bone */
if (&ct->tar->id == id) {
/* same armature */
eDepsOperation_Code target_key_opcode;
/* Using "done" here breaks in-chain deps, while using
* "ready" here breaks most production rigs instead.
* So, we do a compromise here, and only do this when an
* IK chain conflict may occur.
*/
if (root_map->has_common_root(component_subdata,
ct->subtarget))
{
target_key_opcode = DEG_OPCODE_BONE_READY;
eDepsOperation_Code opcode;
/* relation to bone */
opcode = bone_target_opcode(&ct->tar->id, ct->subtarget,
id, component_subdata, root_map);
OperationKey target_key(&ct->tar->id,
DEG_NODE_TYPE_BONE,
ct->subtarget,
opcode);
add_relation(target_key, constraint_op_key, cti->name);
/* if needs bbone shape, also reference handles */
if (con->flag & CONSTRAINT_BBONE_SHAPE) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget);
/* actually a bbone */
if (pchan && pchan->bone && pchan->bone->segments > 1) {
bPoseChannel *prev, *next;
BKE_pchan_get_bbone_handles(pchan, &prev, &next);
/* add handle links */
if (prev) {
opcode = bone_target_opcode(&ct->tar->id, prev->name,
id, component_subdata, root_map);
OperationKey prev_key(&ct->tar->id,
DEG_NODE_TYPE_BONE,
prev->name,
opcode);
add_relation(prev_key, constraint_op_key, cti->name);
}
if (next) {
opcode = bone_target_opcode(&ct->tar->id, next->name,
id, component_subdata, root_map);
OperationKey next_key(&ct->tar->id,
DEG_NODE_TYPE_BONE,
next->name,
opcode);
add_relation(next_key, constraint_op_key, cti->name);
}
}
else {
target_key_opcode = DEG_OPCODE_BONE_DONE;
}
OperationKey target_key(&ct->tar->id,
DEG_NODE_TYPE_BONE,
ct->subtarget,
target_key_opcode);
add_relation(target_key, constraint_op_key, cti->name);
}
else {
/* Different armature - we can safely use the result
* of that.
*/
OperationKey target_key(&ct->tar->id,
DEG_NODE_TYPE_BONE,
ct->subtarget,
DEG_OPCODE_BONE_DONE);
add_relation(target_key, constraint_op_key, cti->name);
}
}
else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) &&