Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc900
1 files changed, 384 insertions, 516 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index 9d36e9495e3..1d222258449 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -27,7 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include <cstring> /* required for STREQ later on. */
+#include <cstring> /* required for STREQ later on. */
#include "MEM_guardedalloc.h"
@@ -67,166 +67,139 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
bConstraint *con,
RootPChanMap *root_map)
{
- bKinematicConstraint *data = (bKinematicConstraint *)con->data;
- /* Attach owner to IK Solver to. */
- bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
- if (rootchan == NULL) {
- return;
- }
- OperationKey pchan_local_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_LOCAL);
- OperationKey init_ik_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
- OperationKey solver_key(&object->id,
- NodeType::EVAL_POSE,
- rootchan->name,
- OperationCode::POSE_IK_SOLVER);
- OperationKey pose_cleanup_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
- add_relation(pchan_local_key, init_ik_key, "IK Constraint -> Init IK Tree");
- add_relation(init_ik_key, solver_key, "Init IK -> IK Solver");
- /* Never cleanup before solver is run. */
- add_relation(solver_key,
- pose_cleanup_key,
- "IK Solver -> Cleanup",
- RELATION_FLAG_GODMODE);
- /* IK target */
- /* TODO(sergey): This should get handled as part of the constraint code. */
- if (data->tar != NULL) {
- /* TODO(sergey): For until we'll store partial matrices in the
- * depsgraph, we create dependency between target object and pose eval
- * component.
- *
- * This way we ensuring the whole subtree is updated from scratch
- * without need of intermediate matrices. This is an overkill, but good
- * enough for testing IK solver. */
- ComponentKey pose_key(&object->id, NodeType::EVAL_POSE);
- if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) {
- /* TODO(sergey): This is only for until granular update stores
- * intermediate result. */
- if (data->tar != object) {
- /* Different armature - can just read the results. */
- ComponentKey target_key(
- &data->tar->id, NodeType::BONE, data->subtarget);
- add_relation(target_key, pose_key, con->name);
- }
- else {
- /* Same armature - we'll use the ready state only, just in case
- * this bone is in the chain we're solving. */
- OperationKey target_key(&data->tar->id,
- NodeType::BONE,
- data->subtarget,
- OperationCode::BONE_DONE);
- add_relation(target_key, solver_key, con->name);
- }
- }
- else if (data->subtarget[0] &&
- ELEM(data->tar->type, OB_MESH, OB_LATTICE))
- {
- /* Vertex group target. */
- /* NOTE: for now, we don't need to represent vertex groups
- * separately. */
- ComponentKey target_key(&data->tar->id, NodeType::GEOMETRY);
- add_relation(target_key, solver_key, con->name);
- add_customdata_mask(data->tar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
- }
- else {
- /* Standard Object Target. */
- ComponentKey target_key(&data->tar->id, NodeType::TRANSFORM);
- add_relation(target_key, pose_key, con->name);
- }
- if (data->tar == object && data->subtarget[0]) {
- /* Prevent target's constraints from linking to anything from same
- * chain that it controls. */
- root_map->add_bone(data->subtarget, rootchan->name);
- }
- }
- /* Pole Target. */
- /* TODO(sergey): This should get handled as part of the constraint code. */
- if (data->poletar != NULL) {
- if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) {
- ComponentKey target_key(&data->poletar->id,
- NodeType::BONE,
- data->polesubtarget);
- add_relation(target_key, solver_key, con->name);
- }
- else if (data->polesubtarget[0] &&
- ELEM(data->poletar->type, OB_MESH, OB_LATTICE))
- {
- /* Vertex group target. */
- /* NOTE: for now, we don't need to represent vertex groups
- * separately. */
- ComponentKey target_key(&data->poletar->id, NodeType::GEOMETRY);
- add_relation(target_key, solver_key, con->name);
- add_customdata_mask(data->poletar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
- }
- else {
- ComponentKey target_key(&data->poletar->id, NodeType::TRANSFORM);
- add_relation(target_key, solver_key, con->name);
- }
- }
- DEG_DEBUG_PRINTF(
- (::Depsgraph *)graph_,
- BUILD,
- "\nStarting IK Build: pchan = %s, target = (%s, %s), "
- "segcount = %d\n",
- pchan->name, data->tar ? data->tar->id.name : "NULL",
- data->subtarget, data->rootbone);
- bPoseChannel *parchan = pchan;
- /* Exclude tip from chain if needed. */
- if (!(data->flag & CONSTRAINT_IK_TIP)) {
- parchan = pchan->parent;
- }
- root_map->add_bone(parchan->name, rootchan->name);
- OperationKey parchan_transforms_key(&object->id, NodeType::BONE,
- parchan->name, OperationCode::BONE_READY);
- add_relation(parchan_transforms_key, solver_key, "IK Solver Owner");
- /* Walk to the chain's root. */
- int segcount = 0;
- while (parchan != NULL) {
- /* Make IK-solver dependent on this bone's result, since it can only run
- * after the standard results of the bone are know. Validate links step
- * on the bone will ensure that users of this bone only grab the result
- * with IK solver results. */
- if (parchan != pchan) {
- OperationKey parent_key(&object->id,
- NodeType::BONE,
- parchan->name,
- OperationCode::BONE_READY);
- add_relation(parent_key, solver_key, "IK Chain Parent");
- OperationKey bone_done_key(&object->id,
- NodeType::BONE,
- parchan->name,
- OperationCode::BONE_DONE);
- add_relation(solver_key, bone_done_key, "IK Chain Result");
- }
- else {
- OperationKey final_transforms_key(&object->id,
- NodeType::BONE,
- parchan->name,
- OperationCode::BONE_DONE);
- add_relation(solver_key, final_transforms_key, "IK Solver Result");
- }
- parchan->flag |= POSE_DONE;
- root_map->add_bone(parchan->name, rootchan->name);
- /* continue up chain, until we reach target number of items. */
- DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
- BUILD,
- " %d = %s\n",
- segcount, parchan->name);
- /* TODO(sergey): This is an arbitrary value, which was just following
- * old code convention. */
- segcount++;
- if ((segcount == data->rootbone) || (segcount > 255)) {
- break;
- }
- parchan = parchan->parent;
- }
- OperationKey pose_done_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
- add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
+ bKinematicConstraint *data = (bKinematicConstraint *)con->data;
+ /* Attach owner to IK Solver to. */
+ bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
+ if (rootchan == NULL) {
+ return;
+ }
+ OperationKey pchan_local_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
+ OperationKey init_ik_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
+ OperationKey solver_key(
+ &object->id, NodeType::EVAL_POSE, rootchan->name, OperationCode::POSE_IK_SOLVER);
+ OperationKey pose_cleanup_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
+ add_relation(pchan_local_key, init_ik_key, "IK Constraint -> Init IK Tree");
+ add_relation(init_ik_key, solver_key, "Init IK -> IK Solver");
+ /* Never cleanup before solver is run. */
+ add_relation(solver_key, pose_cleanup_key, "IK Solver -> Cleanup", RELATION_FLAG_GODMODE);
+ /* IK target */
+ /* TODO(sergey): This should get handled as part of the constraint code. */
+ if (data->tar != NULL) {
+ /* TODO(sergey): For until we'll store partial matrices in the
+ * depsgraph, we create dependency between target object and pose eval
+ * component.
+ *
+ * This way we ensuring the whole subtree is updated from scratch
+ * without need of intermediate matrices. This is an overkill, but good
+ * enough for testing IK solver. */
+ ComponentKey pose_key(&object->id, NodeType::EVAL_POSE);
+ if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) {
+ /* TODO(sergey): This is only for until granular update stores
+ * intermediate result. */
+ if (data->tar != object) {
+ /* Different armature - can just read the results. */
+ ComponentKey target_key(&data->tar->id, NodeType::BONE, data->subtarget);
+ add_relation(target_key, pose_key, con->name);
+ }
+ else {
+ /* Same armature - we'll use the ready state only, just in case
+ * this bone is in the chain we're solving. */
+ OperationKey target_key(
+ &data->tar->id, NodeType::BONE, data->subtarget, OperationCode::BONE_DONE);
+ add_relation(target_key, solver_key, con->name);
+ }
+ }
+ else if (data->subtarget[0] && ELEM(data->tar->type, OB_MESH, OB_LATTICE)) {
+ /* Vertex group target. */
+ /* NOTE: for now, we don't need to represent vertex groups
+ * separately. */
+ ComponentKey target_key(&data->tar->id, NodeType::GEOMETRY);
+ add_relation(target_key, solver_key, con->name);
+ add_customdata_mask(data->tar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
+ }
+ else {
+ /* Standard Object Target. */
+ ComponentKey target_key(&data->tar->id, NodeType::TRANSFORM);
+ add_relation(target_key, pose_key, con->name);
+ }
+ if (data->tar == object && data->subtarget[0]) {
+ /* Prevent target's constraints from linking to anything from same
+ * chain that it controls. */
+ root_map->add_bone(data->subtarget, rootchan->name);
+ }
+ }
+ /* Pole Target. */
+ /* TODO(sergey): This should get handled as part of the constraint code. */
+ if (data->poletar != NULL) {
+ if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) {
+ ComponentKey target_key(&data->poletar->id, NodeType::BONE, data->polesubtarget);
+ add_relation(target_key, solver_key, con->name);
+ }
+ else if (data->polesubtarget[0] && ELEM(data->poletar->type, OB_MESH, OB_LATTICE)) {
+ /* Vertex group target. */
+ /* NOTE: for now, we don't need to represent vertex groups
+ * separately. */
+ ComponentKey target_key(&data->poletar->id, NodeType::GEOMETRY);
+ add_relation(target_key, solver_key, con->name);
+ add_customdata_mask(data->poletar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
+ }
+ else {
+ ComponentKey target_key(&data->poletar->id, NodeType::TRANSFORM);
+ add_relation(target_key, solver_key, con->name);
+ }
+ }
+ DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
+ BUILD,
+ "\nStarting IK Build: pchan = %s, target = (%s, %s), "
+ "segcount = %d\n",
+ pchan->name,
+ data->tar ? data->tar->id.name : "NULL",
+ data->subtarget,
+ data->rootbone);
+ bPoseChannel *parchan = pchan;
+ /* Exclude tip from chain if needed. */
+ if (!(data->flag & CONSTRAINT_IK_TIP)) {
+ parchan = pchan->parent;
+ }
+ root_map->add_bone(parchan->name, rootchan->name);
+ OperationKey parchan_transforms_key(
+ &object->id, NodeType::BONE, parchan->name, OperationCode::BONE_READY);
+ add_relation(parchan_transforms_key, solver_key, "IK Solver Owner");
+ /* Walk to the chain's root. */
+ int segcount = 0;
+ while (parchan != NULL) {
+ /* Make IK-solver dependent on this bone's result, since it can only run
+ * after the standard results of the bone are know. Validate links step
+ * on the bone will ensure that users of this bone only grab the result
+ * with IK solver results. */
+ if (parchan != pchan) {
+ OperationKey parent_key(
+ &object->id, NodeType::BONE, parchan->name, OperationCode::BONE_READY);
+ add_relation(parent_key, solver_key, "IK Chain Parent");
+ OperationKey bone_done_key(
+ &object->id, NodeType::BONE, parchan->name, OperationCode::BONE_DONE);
+ add_relation(solver_key, bone_done_key, "IK Chain Result");
+ }
+ else {
+ OperationKey final_transforms_key(
+ &object->id, NodeType::BONE, parchan->name, OperationCode::BONE_DONE);
+ add_relation(solver_key, final_transforms_key, "IK Solver Result");
+ }
+ parchan->flag |= POSE_DONE;
+ root_map->add_bone(parchan->name, rootchan->name);
+ /* continue up chain, until we reach target number of items. */
+ DEG_DEBUG_PRINTF((::Depsgraph *)graph_, BUILD, " %d = %s\n", segcount, parchan->name);
+ /* TODO(sergey): This is an arbitrary value, which was just following
+ * old code convention. */
+ segcount++;
+ if ((segcount == data->rootbone) || (segcount > 255)) {
+ break;
+ }
+ parchan = parchan->parent;
+ }
+ OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
+ add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
}
/* Spline IK Eval Steps */
@@ -235,375 +208,270 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
bConstraint *con,
RootPChanMap *root_map)
{
- bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
- bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
- OperationKey transforms_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_READY);
- OperationKey init_ik_key(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_INIT_IK);
- OperationKey solver_key(&object->id,
- NodeType::EVAL_POSE,
- rootchan->name,
- OperationCode::POSE_SPLINE_IK_SOLVER);
- OperationKey pose_cleanup_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
- /* Solver depends on initialization. */
- add_relation(init_ik_key, solver_key, "Init IK -> IK Solver");
- /* Never cleanup before solver is run. */
- add_relation(solver_key, pose_cleanup_key, "IK Solver -> Cleanup");
- /* Attach owner to IK Solver. */
- add_relation(transforms_key,
- solver_key,
- "Spline IK Solver Owner",
- RELATION_FLAG_GODMODE);
- /* Attach path dependency to solver. */
- if (data->tar != NULL) {
- ComponentKey target_geometry_key(&data->tar->id, NodeType::GEOMETRY);
- add_relation(target_geometry_key, solver_key, "Curve.Path -> Spline IK");
- ComponentKey target_transform_key(&data->tar->id, NodeType::TRANSFORM);
- add_relation(target_transform_key, solver_key, "Curve.Transform -> Spline IK");
- add_special_eval_flag(&data->tar->id, DAG_EVAL_NEED_CURVE_PATH);
- }
- pchan->flag |= POSE_DONE;
- OperationKey final_transforms_key(
- &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
- add_relation(solver_key, final_transforms_key, "Spline IK Result");
- root_map->add_bone(pchan->name, rootchan->name);
- /* Walk to the chain's root/ */
- int segcount = 1;
- for (bPoseChannel *parchan = pchan->parent;
- parchan != NULL && segcount < data->chainlen;
- parchan = parchan->parent, segcount++)
- {
- /* Make Spline IK solver dependent on this bone's result, since it can
- * only run after the standard results of the bone are know. Validate
- * links step on the bone will ensure that users of this bone only grab
- * the result with IK solver results. */
- OperationKey parent_key(&object->id,
- NodeType::BONE,
- parchan->name,
- OperationCode::BONE_READY);
- add_relation(parent_key, solver_key, "Spline IK Solver Update");
- OperationKey bone_done_key(&object->id,
- NodeType::BONE,
- parchan->name,
- OperationCode::BONE_DONE);
- add_relation(solver_key, bone_done_key, "Spline IK Solver Result");
- parchan->flag |= POSE_DONE;
- root_map->add_bone(parchan->name, rootchan->name);
- }
- OperationKey pose_done_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
- add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
+ bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
+ bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
+ OperationKey transforms_key(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
+ OperationKey init_ik_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
+ OperationKey solver_key(
+ &object->id, NodeType::EVAL_POSE, rootchan->name, OperationCode::POSE_SPLINE_IK_SOLVER);
+ OperationKey pose_cleanup_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
+ /* Solver depends on initialization. */
+ add_relation(init_ik_key, solver_key, "Init IK -> IK Solver");
+ /* Never cleanup before solver is run. */
+ add_relation(solver_key, pose_cleanup_key, "IK Solver -> Cleanup");
+ /* Attach owner to IK Solver. */
+ add_relation(transforms_key, solver_key, "Spline IK Solver Owner", RELATION_FLAG_GODMODE);
+ /* Attach path dependency to solver. */
+ if (data->tar != NULL) {
+ ComponentKey target_geometry_key(&data->tar->id, NodeType::GEOMETRY);
+ add_relation(target_geometry_key, solver_key, "Curve.Path -> Spline IK");
+ ComponentKey target_transform_key(&data->tar->id, NodeType::TRANSFORM);
+ add_relation(target_transform_key, solver_key, "Curve.Transform -> Spline IK");
+ add_special_eval_flag(&data->tar->id, DAG_EVAL_NEED_CURVE_PATH);
+ }
+ pchan->flag |= POSE_DONE;
+ OperationKey final_transforms_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
+ add_relation(solver_key, final_transforms_key, "Spline IK Result");
+ root_map->add_bone(pchan->name, rootchan->name);
+ /* Walk to the chain's root/ */
+ int segcount = 1;
+ for (bPoseChannel *parchan = pchan->parent; parchan != NULL && segcount < data->chainlen;
+ parchan = parchan->parent, segcount++) {
+ /* Make Spline IK solver dependent on this bone's result, since it can
+ * only run after the standard results of the bone are know. Validate
+ * links step on the bone will ensure that users of this bone only grab
+ * the result with IK solver results. */
+ OperationKey parent_key(&object->id, NodeType::BONE, parchan->name, OperationCode::BONE_READY);
+ add_relation(parent_key, solver_key, "Spline IK Solver Update");
+ OperationKey bone_done_key(
+ &object->id, NodeType::BONE, parchan->name, OperationCode::BONE_DONE);
+ add_relation(solver_key, bone_done_key, "Spline IK Solver Result");
+ parchan->flag |= POSE_DONE;
+ root_map->add_bone(parchan->name, rootchan->name);
+ }
+ OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
+ add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
}
/* Pose/Armature Bones Graph */
void DepsgraphRelationBuilder::build_rig(Object *object)
{
- /* Armature-Data */
- bArmature *armature = (bArmature *)object->data;
- // TODO: selection status?
- /* Attach links between pose operations. */
- ComponentKey local_transform(&object->id, NodeType::TRANSFORM);
- OperationKey pose_init_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT);
- OperationKey pose_init_ik_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
- OperationKey pose_cleanup_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
- OperationKey pose_done_key(
- &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
- add_relation(
- local_transform, pose_init_key, "Local Transform -> Pose Init");
- add_relation(pose_init_key, pose_init_ik_key, "Pose Init -> Pose Init IK");
- add_relation(
- pose_init_ik_key, pose_done_key, "Pose Init IK -> Pose Cleanup");
- /* Make sure pose is up-to-date with armature updates. */
- build_armature(armature);
- OperationKey armature_key(&armature->id,
- NodeType::PARAMETERS,
- OperationCode::ARMATURE_EVAL);
- add_relation(armature_key, pose_init_key, "Data dependency");
- /* Run cleanup even when there are no bones. */
- add_relation(pose_init_key, pose_cleanup_key, "Init -> Cleanup");
- /* IK Solvers.
- *
- * - These require separate processing steps are pose-level to be executed
- * between chains of bones (i.e. once the base transforms of a bunch of
- * bones is done).
- *
- * - We build relations for these before the dependencies between operations
- * in the same component as it is necessary to check whether such bones
- * are in the same IK chain (or else we get weird issues with either
- * in-chain references, or with bones being parented to IK'd bones).
- *
- * Unsolved Issues:
- * - Care is needed to ensure that multi-headed trees work out the same as
- * in ik-tree building
- * - Animated chain-lengths are a problem. */
- RootPChanMap root_map;
- bool pose_depends_on_local_transform = false;
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
- switch (con->type) {
- case CONSTRAINT_TYPE_KINEMATIC:
- build_ik_pose(object, pchan, con, &root_map);
- pose_depends_on_local_transform = true;
- break;
- case CONSTRAINT_TYPE_SPLINEIK:
- build_splineik_pose(object, pchan, con, &root_map);
- pose_depends_on_local_transform = true;
- break;
- /* Constraints which needs world's matrix for transform.
- * TODO(sergey): More constraints here? */
- case CONSTRAINT_TYPE_ROTLIKE:
- case CONSTRAINT_TYPE_SIZELIKE:
- case CONSTRAINT_TYPE_LOCLIKE:
- case CONSTRAINT_TYPE_TRANSLIKE:
- /* TODO(sergey): Add used space check. */
- pose_depends_on_local_transform = true;
- break;
- default:
- break;
- }
- }
- }
- // root_map.print_debug();
- if (pose_depends_on_local_transform) {
- /* TODO(sergey): Once partial updates are possible use relation between
- * object transform and solver itself in it's build function. */
- ComponentKey pose_key(&object->id, NodeType::EVAL_POSE);
- ComponentKey local_transform_key(&object->id, NodeType::TRANSFORM);
- add_relation(local_transform_key, pose_key, "Local Transforms");
- }
- /* Links between operations for each bone. */
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- OperationKey bone_local_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_LOCAL);
- OperationKey bone_pose_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_POSE_PARENT);
- OperationKey bone_ready_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_READY);
- OperationKey bone_done_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_DONE);
- pchan->flag &= ~POSE_DONE;
- /* Pose init to bone local. */
- add_relation(pose_init_key,
- bone_local_key,
- "Pose Init - Bone Local",
- RELATION_FLAG_GODMODE);
- /* Local to pose parenting operation. */
- add_relation(bone_local_key, bone_pose_key, "Bone Local - Bone Pose");
- /* Parent relation. */
- if (pchan->parent != NULL) {
- OperationCode parent_key_opcode;
- /* NOTE: this difference in handling allows us to prevent lockups
- * while ensuring correct poses for separate chains. */
- if (root_map.has_common_root(pchan->name, pchan->parent->name)) {
- parent_key_opcode = OperationCode::BONE_READY;
- }
- else {
- parent_key_opcode = OperationCode::BONE_DONE;
- }
+ /* Armature-Data */
+ bArmature *armature = (bArmature *)object->data;
+ // TODO: selection status?
+ /* Attach links between pose operations. */
+ ComponentKey local_transform(&object->id, NodeType::TRANSFORM);
+ OperationKey pose_init_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT);
+ OperationKey pose_init_ik_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
+ OperationKey pose_cleanup_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
+ OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
+ add_relation(local_transform, pose_init_key, "Local Transform -> Pose Init");
+ add_relation(pose_init_key, pose_init_ik_key, "Pose Init -> Pose Init IK");
+ add_relation(pose_init_ik_key, pose_done_key, "Pose Init IK -> Pose Cleanup");
+ /* Make sure pose is up-to-date with armature updates. */
+ build_armature(armature);
+ OperationKey armature_key(&armature->id, NodeType::PARAMETERS, OperationCode::ARMATURE_EVAL);
+ add_relation(armature_key, pose_init_key, "Data dependency");
+ /* Run cleanup even when there are no bones. */
+ add_relation(pose_init_key, pose_cleanup_key, "Init -> Cleanup");
+ /* IK Solvers.
+ *
+ * - These require separate processing steps are pose-level to be executed
+ * between chains of bones (i.e. once the base transforms of a bunch of
+ * bones is done).
+ *
+ * - We build relations for these before the dependencies between operations
+ * in the same component as it is necessary to check whether such bones
+ * are in the same IK chain (or else we get weird issues with either
+ * in-chain references, or with bones being parented to IK'd bones).
+ *
+ * Unsolved Issues:
+ * - Care is needed to ensure that multi-headed trees work out the same as
+ * in ik-tree building
+ * - Animated chain-lengths are a problem. */
+ RootPChanMap root_map;
+ bool pose_depends_on_local_transform = false;
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
+ switch (con->type) {
+ case CONSTRAINT_TYPE_KINEMATIC:
+ build_ik_pose(object, pchan, con, &root_map);
+ pose_depends_on_local_transform = true;
+ break;
+ case CONSTRAINT_TYPE_SPLINEIK:
+ build_splineik_pose(object, pchan, con, &root_map);
+ pose_depends_on_local_transform = true;
+ break;
+ /* Constraints which needs world's matrix for transform.
+ * TODO(sergey): More constraints here? */
+ case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_SIZELIKE:
+ case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_TRANSLIKE:
+ /* TODO(sergey): Add used space check. */
+ pose_depends_on_local_transform = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ // root_map.print_debug();
+ if (pose_depends_on_local_transform) {
+ /* TODO(sergey): Once partial updates are possible use relation between
+ * object transform and solver itself in it's build function. */
+ ComponentKey pose_key(&object->id, NodeType::EVAL_POSE);
+ ComponentKey local_transform_key(&object->id, NodeType::TRANSFORM);
+ add_relation(local_transform_key, pose_key, "Local Transforms");
+ }
+ /* Links between operations for each bone. */
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ OperationKey bone_local_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
+ OperationKey bone_pose_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_POSE_PARENT);
+ OperationKey bone_ready_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
+ OperationKey bone_done_key(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
+ pchan->flag &= ~POSE_DONE;
+ /* Pose init to bone local. */
+ add_relation(pose_init_key, bone_local_key, "Pose Init - Bone Local", RELATION_FLAG_GODMODE);
+ /* Local to pose parenting operation. */
+ add_relation(bone_local_key, bone_pose_key, "Bone Local - Bone Pose");
+ /* Parent relation. */
+ if (pchan->parent != NULL) {
+ OperationCode parent_key_opcode;
+ /* NOTE: this difference in handling allows us to prevent lockups
+ * while ensuring correct poses for separate chains. */
+ if (root_map.has_common_root(pchan->name, pchan->parent->name)) {
+ parent_key_opcode = OperationCode::BONE_READY;
+ }
+ else {
+ parent_key_opcode = OperationCode::BONE_DONE;
+ }
- OperationKey parent_key(&object->id,
- NodeType::BONE,
- pchan->parent->name,
- parent_key_opcode);
- add_relation(
- parent_key, bone_pose_key, "Parent Bone -> Child Bone");
- }
- /* Build constraints. */
- if (pchan->constraints.first != NULL) {
- /* Build relations for indirectly linked objects. */
- BuilderWalkUserData data;
- data.builder = this;
- BKE_constraints_id_loop(
- &pchan->constraints, constraint_walk, &data);
- /* Constraints stack and constraint dependencies. */
- build_constraints(&object->id,
- NodeType::BONE,
- pchan->name,
- &pchan->constraints,
- &root_map);
- /* Pose -> constraints. */
- OperationKey constraints_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_CONSTRAINTS);
- add_relation(bone_pose_key, constraints_key, "Pose -> Constraints Stack");
- add_relation(bone_local_key, constraints_key, "Local -> Constraints Stack");
- /* Constraints -> ready/ */
- /* TODO(sergey): When constraint stack is exploded, this step should
- * occur before the first IK solver. */
- add_relation(
- constraints_key, bone_ready_key, "Constraints -> Ready");
- }
- else {
- /* Pose -> Ready */
- add_relation(bone_pose_key, bone_ready_key, "Pose -> Ready");
- }
- /* Bone ready -> Bone done.
- * NOTE: For bones without IK, this is all that's needed.
- * For IK chains however, an additional rel is created from IK
- * to done, with transitive reduction removing this one. */
- add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
- /* B-Bone shape is the real final step after Done if present. */
- if (pchan->bone != NULL && pchan->bone->segments > 1) {
- OperationKey bone_segments_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_SEGMENTS);
- /* B-Bone shape depends on the final position of the bone. */
- add_relation(bone_done_key,
- bone_segments_key,
- "Done -> B-Bone Segments");
- /* B-Bone shape depends on final position of handle bones. */
- bPoseChannel *prev, *next;
- BKE_pchan_bbone_handles_get(pchan, &prev, &next);
- if (prev) {
- OperationKey prev_key(&object->id,
- NodeType::BONE,
- prev->name,
- OperationCode::BONE_DONE);
- add_relation(prev_key,
- bone_segments_key,
- "Prev Handle -> B-Bone Segments");
- }
- if (next) {
- OperationKey next_key(&object->id,
- NodeType::BONE,
- next->name,
- OperationCode::BONE_DONE);
- add_relation(next_key,
- bone_segments_key,
- "Next Handle -> B-Bone Segments");
- }
- /* Pose requires the B-Bone shape. */
- add_relation(bone_segments_key,
- pose_done_key,
- "PoseEval Result-Bone Link",
- RELATION_FLAG_GODMODE);
- add_relation(bone_segments_key,
- pose_cleanup_key,
- "Cleanup dependency");
- }
- else {
- /* Assume that all bones must be done for the pose to be ready
- * (for deformers). */
- add_relation(bone_done_key,
- pose_done_key,
- "PoseEval Result-Bone Link");
+ OperationKey parent_key(&object->id, NodeType::BONE, pchan->parent->name, parent_key_opcode);
+ add_relation(parent_key, bone_pose_key, "Parent Bone -> Child Bone");
+ }
+ /* Build constraints. */
+ if (pchan->constraints.first != NULL) {
+ /* Build relations for indirectly linked objects. */
+ BuilderWalkUserData data;
+ data.builder = this;
+ BKE_constraints_id_loop(&pchan->constraints, constraint_walk, &data);
+ /* Constraints stack and constraint dependencies. */
+ build_constraints(&object->id, NodeType::BONE, pchan->name, &pchan->constraints, &root_map);
+ /* Pose -> constraints. */
+ OperationKey constraints_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_CONSTRAINTS);
+ add_relation(bone_pose_key, constraints_key, "Pose -> Constraints Stack");
+ add_relation(bone_local_key, constraints_key, "Local -> Constraints Stack");
+ /* Constraints -> ready/ */
+ /* TODO(sergey): When constraint stack is exploded, this step should
+ * occur before the first IK solver. */
+ add_relation(constraints_key, bone_ready_key, "Constraints -> Ready");
+ }
+ else {
+ /* Pose -> Ready */
+ add_relation(bone_pose_key, bone_ready_key, "Pose -> Ready");
+ }
+ /* Bone ready -> Bone done.
+ * NOTE: For bones without IK, this is all that's needed.
+ * For IK chains however, an additional rel is created from IK
+ * to done, with transitive reduction removing this one. */
+ add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
+ /* B-Bone shape is the real final step after Done if present. */
+ if (pchan->bone != NULL && pchan->bone->segments > 1) {
+ OperationKey bone_segments_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS);
+ /* B-Bone shape depends on the final position of the bone. */
+ add_relation(bone_done_key, bone_segments_key, "Done -> B-Bone Segments");
+ /* B-Bone shape depends on final position of handle bones. */
+ bPoseChannel *prev, *next;
+ BKE_pchan_bbone_handles_get(pchan, &prev, &next);
+ if (prev) {
+ OperationKey prev_key(&object->id, NodeType::BONE, prev->name, OperationCode::BONE_DONE);
+ add_relation(prev_key, bone_segments_key, "Prev Handle -> B-Bone Segments");
+ }
+ if (next) {
+ OperationKey next_key(&object->id, NodeType::BONE, next->name, OperationCode::BONE_DONE);
+ add_relation(next_key, bone_segments_key, "Next Handle -> B-Bone Segments");
+ }
+ /* Pose requires the B-Bone shape. */
+ add_relation(
+ bone_segments_key, pose_done_key, "PoseEval Result-Bone Link", RELATION_FLAG_GODMODE);
+ add_relation(bone_segments_key, pose_cleanup_key, "Cleanup dependency");
+ }
+ else {
+ /* Assume that all bones must be done for the pose to be ready
+ * (for deformers). */
+ add_relation(bone_done_key, pose_done_key, "PoseEval Result-Bone Link");
- /* Bones must be traversed before cleanup. */
- add_relation(bone_done_key,
- pose_cleanup_key,
- "Done -> Cleanup");
+ /* Bones must be traversed before cleanup. */
+ add_relation(bone_done_key, pose_cleanup_key, "Done -> Cleanup");
- add_relation(bone_ready_key,
- pose_cleanup_key,
- "Ready -> Cleanup");
- }
- /* Custom shape. */
- if (pchan->custom != NULL) {
- build_object(NULL, pchan->custom);
- }
- }
+ add_relation(bone_ready_key, pose_cleanup_key, "Ready -> Cleanup");
+ }
+ /* Custom shape. */
+ if (pchan->custom != NULL) {
+ build_object(NULL, pchan->custom);
+ }
+ }
}
void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
{
- bArmature *armature = (bArmature *)object->data;
- Object *proxy_from = object->proxy_from;
- build_armature(armature);
- OperationKey pose_init_key(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_INIT);
- OperationKey pose_done_key(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_DONE);
- OperationKey pose_cleanup_key(&object->id,
- NodeType::EVAL_POSE,
- OperationCode::POSE_CLEANUP);
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- OperationKey bone_local_key(&object->id,
- NodeType::BONE, pchan->name,
- OperationCode::BONE_LOCAL);
- OperationKey bone_ready_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_READY);
- OperationKey bone_done_key(&object->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_DONE);
- OperationKey from_bone_done_key(&proxy_from->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_DONE);
- add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
- add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
- add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
- add_relation(
- bone_done_key, pose_cleanup_key, "Bone Done -> Pose Cleanup");
- add_relation(bone_done_key,
- pose_done_key,
- "Bone Done -> Pose Done",
- RELATION_FLAG_GODMODE);
- /* Make sure bone in the proxy is not done before it's FROM is done. */
- if (pchan->bone && pchan->bone->segments > 1) {
- OperationKey from_bone_segments_key(&proxy_from->id,
- NodeType::BONE,
- pchan->name,
- OperationCode::BONE_SEGMENTS);
- add_relation(from_bone_segments_key,
- bone_done_key,
- "Bone Segments -> Bone Done",
- RELATION_FLAG_GODMODE);
- }
- else {
- add_relation(from_bone_done_key,
- bone_done_key,
- "Bone Done -> Bone Done");
- }
+ bArmature *armature = (bArmature *)object->data;
+ Object *proxy_from = object->proxy_from;
+ build_armature(armature);
+ OperationKey pose_init_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT);
+ OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
+ OperationKey pose_cleanup_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ OperationKey bone_local_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
+ OperationKey bone_ready_key(
+ &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_READY);
+ OperationKey bone_done_key(&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
+ OperationKey from_bone_done_key(
+ &proxy_from->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
+ add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
+ add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
+ add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
+ add_relation(bone_done_key, pose_cleanup_key, "Bone Done -> Pose Cleanup");
+ add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done", RELATION_FLAG_GODMODE);
+ /* Make sure bone in the proxy is not done before it's FROM is done. */
+ if (pchan->bone && pchan->bone->segments > 1) {
+ OperationKey from_bone_segments_key(
+ &proxy_from->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS);
+ add_relation(from_bone_segments_key,
+ bone_done_key,
+ "Bone Segments -> Bone Done",
+ RELATION_FLAG_GODMODE);
+ }
+ else {
+ add_relation(from_bone_done_key, bone_done_key, "Bone Done -> Bone Done");
+ }
- /* Parent relation: even though the proxy bone itself doesn't need
- * the parent bone, some users expect the parent to be ready if the
- * bone itself is (e.g. for computing the local space matrix).
- */
- if (pchan->parent != NULL) {
- OperationKey parent_key(&object->id,
- NodeType::BONE,
- pchan->parent->name,
- OperationCode::BONE_DONE);
- add_relation(parent_key, bone_done_key, "Parent Bone -> Child Bone");
- }
+ /* Parent relation: even though the proxy bone itself doesn't need
+ * the parent bone, some users expect the parent to be ready if the
+ * bone itself is (e.g. for computing the local space matrix).
+ */
+ if (pchan->parent != NULL) {
+ OperationKey parent_key(
+ &object->id, NodeType::BONE, pchan->parent->name, OperationCode::BONE_DONE);
+ add_relation(parent_key, bone_done_key, "Parent Bone -> Child Bone");
+ }
- if (pchan->prop != NULL) {
- OperationKey bone_parameters(&object->id,
- NodeType::PARAMETERS,
- OperationCode::PARAMETERS_EVAL,
- pchan->name);
- OperationKey from_bone_parameters(&proxy_from->id,
- NodeType::PARAMETERS,
- OperationCode::PARAMETERS_EVAL,
- pchan->name);
- add_relation(from_bone_parameters,
- bone_parameters,
- "Proxy Bone Parameters");
- }
- }
+ if (pchan->prop != NULL) {
+ OperationKey bone_parameters(
+ &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, pchan->name);
+ OperationKey from_bone_parameters(
+ &proxy_from->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, pchan->name);
+ add_relation(from_bone_parameters, bone_parameters, "Proxy Bone Parameters");
+ }
+ }
}
} // namespace DEG