Fix T59622: dependency problems with Spline IK.
[blender.git] / source / blender / depsgraph / intern / builder / deg_builder_relations_rig.cc
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2013 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup depsgraph
22  *
23  * Methods for constructing depsgraph
24  */
25
26 #include "intern/builder/deg_builder_relations.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <cstring>  /* required for STREQ later on. */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_utildefines.h"
35 #include "BLI_blenlib.h"
36
37 extern "C" {
38 #include "DNA_action_types.h"
39 #include "DNA_anim_types.h"
40 #include "DNA_armature_types.h"
41 #include "DNA_constraint_types.h"
42 #include "DNA_customdata_types.h"
43 #include "DNA_object_types.h"
44
45 #include "BKE_action.h"
46 #include "BKE_armature.h"
47 #include "BKE_constraint.h"
48 } /* extern "C" */
49
50 #include "DEG_depsgraph.h"
51 #include "DEG_depsgraph_build.h"
52
53 #include "intern/builder/deg_builder.h"
54 #include "intern/builder/deg_builder_pchanmap.h"
55 #include "intern/debug/deg_debug.h"
56 #include "intern/node/deg_node.h"
57 #include "intern/node/deg_node_component.h"
58 #include "intern/node/deg_node_operation.h"
59
60 #include "intern/depsgraph_type.h"
61
62 namespace DEG {
63
64 /* IK Solver Eval Steps */
65 void DepsgraphRelationBuilder::build_ik_pose(Object *object,
66                                              bPoseChannel *pchan,
67                                              bConstraint *con,
68                                              RootPChanMap *root_map)
69 {
70         bKinematicConstraint *data = (bKinematicConstraint *)con->data;
71         /* Attach owner to IK Solver to. */
72         bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
73         if (rootchan == NULL) {
74                 return;
75         }
76         OperationKey pchan_local_key(&object->id,
77                                      NodeType::BONE,
78                                      pchan->name,
79                                      OperationCode::BONE_LOCAL);
80         OperationKey init_ik_key(
81                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
82         OperationKey solver_key(&object->id,
83                                 NodeType::EVAL_POSE,
84                                 rootchan->name,
85                                 OperationCode::POSE_IK_SOLVER);
86         OperationKey pose_cleanup_key(
87                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
88         add_relation(pchan_local_key, init_ik_key, "IK Constraint -> Init IK Tree");
89         add_relation(init_ik_key, solver_key, "Init IK -> IK Solver");
90         /* Never cleanup before solver is run. */
91         add_relation(solver_key,
92                      pose_cleanup_key,
93                      "IK Solver -> Cleanup",
94                      RELATION_FLAG_GODMODE);
95         /* IK target */
96         /* TODO(sergey): This should get handled as part of the constraint code. */
97         if (data->tar != NULL) {
98                 /* TODO(sergey): For until we'll store partial matrices in the
99                  * depsgraph, we create dependency between target object and pose eval
100                  * component.
101                  *
102                  * This way we ensuring the whole subtree is updated from scratch
103                  * without need of intermediate matrices. This is an overkill, but good
104                  * enough for testing IK solver. */
105                 ComponentKey pose_key(&object->id, NodeType::EVAL_POSE);
106                 if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) {
107                         /* TODO(sergey): This is only for until granular update stores
108                          * intermediate result. */
109                         if (data->tar != object) {
110                                 /* Different armature - can just read the results. */
111                                 ComponentKey target_key(
112                                         &data->tar->id, NodeType::BONE, data->subtarget);
113                                 add_relation(target_key, pose_key, con->name);
114                         }
115                         else {
116                                 /* Same armature - we'll use the ready state only, just in case
117                                  * this bone is in the chain we're solving. */
118                                 OperationKey target_key(&data->tar->id,
119                                                         NodeType::BONE,
120                                                         data->subtarget,
121                                                         OperationCode::BONE_DONE);
122                                 add_relation(target_key, solver_key, con->name);
123                         }
124                 }
125                 else if (data->subtarget[0] &&
126                          ELEM(data->tar->type, OB_MESH, OB_LATTICE))
127                 {
128                         /* Vertex group target. */
129                         /* NOTE: for now, we don't need to represent vertex groups
130                          * separately. */
131                         ComponentKey target_key(&data->tar->id, NodeType::GEOMETRY);
132                         add_relation(target_key, solver_key, con->name);
133                         add_customdata_mask(data->tar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
134                 }
135                 else {
136                         /* Standard Object Target. */
137                         ComponentKey target_key(&data->tar->id, NodeType::TRANSFORM);
138                         add_relation(target_key, pose_key, con->name);
139                 }
140                 if (data->tar == object && data->subtarget[0]) {
141                         /* Prevent target's constraints from linking to anything from same
142                          * chain that it controls. */
143                         root_map->add_bone(data->subtarget, rootchan->name);
144                 }
145         }
146         /* Pole Target. */
147         /* TODO(sergey): This should get handled as part of the constraint code. */
148         if (data->poletar != NULL) {
149                 if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) {
150                         ComponentKey target_key(&data->poletar->id,
151                                                 NodeType::BONE,
152                                                 data->polesubtarget);
153                         add_relation(target_key, solver_key, con->name);
154                 }
155                 else if (data->polesubtarget[0] &&
156                          ELEM(data->poletar->type, OB_MESH, OB_LATTICE))
157                 {
158                         /* Vertex group target. */
159                         /* NOTE: for now, we don't need to represent vertex groups
160                          * separately. */
161                         ComponentKey target_key(&data->poletar->id, NodeType::GEOMETRY);
162                         add_relation(target_key, solver_key, con->name);
163                         add_customdata_mask(data->poletar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
164                 }
165                 else {
166                         ComponentKey target_key(&data->poletar->id, NodeType::TRANSFORM);
167                         add_relation(target_key, solver_key, con->name);
168                 }
169         }
170         DEG_DEBUG_PRINTF(
171                 (::Depsgraph *)graph_,
172                 BUILD,
173                 "\nStarting IK Build: pchan = %s, target = (%s, %s), "
174                 "segcount = %d\n",
175                 pchan->name, data->tar ? data->tar->id.name : "NULL",
176                 data->subtarget, data->rootbone);
177         bPoseChannel *parchan = pchan;
178         /* Exclude tip from chain if needed. */
179         if (!(data->flag & CONSTRAINT_IK_TIP)) {
180                 parchan = pchan->parent;
181         }
182         root_map->add_bone(parchan->name, rootchan->name);
183         OperationKey parchan_transforms_key(&object->id, NodeType::BONE,
184                                             parchan->name, OperationCode::BONE_READY);
185         add_relation(parchan_transforms_key, solver_key, "IK Solver Owner");
186         /* Walk to the chain's root. */
187         int segcount = 0;
188         while (parchan != NULL) {
189                 /* Make IK-solver dependent on this bone's result, since it can only run
190                  * after the standard results of the bone are know. Validate links step
191                  * on the bone will ensure that users of this bone only grab the result
192                  * with IK solver results. */
193                 if (parchan != pchan) {
194                         OperationKey parent_key(&object->id,
195                                                 NodeType::BONE,
196                                                 parchan->name,
197                                                 OperationCode::BONE_READY);
198                         add_relation(parent_key, solver_key, "IK Chain Parent");
199                         OperationKey bone_done_key(&object->id,
200                                                    NodeType::BONE,
201                                                    parchan->name,
202                                                    OperationCode::BONE_DONE);
203                         add_relation(solver_key, bone_done_key, "IK Chain Result");
204                 }
205                 else {
206                         OperationKey final_transforms_key(&object->id,
207                                                           NodeType::BONE,
208                                                           parchan->name,
209                                                           OperationCode::BONE_DONE);
210                         add_relation(solver_key, final_transforms_key, "IK Solver Result");
211                 }
212                 parchan->flag |= POSE_DONE;
213                 root_map->add_bone(parchan->name, rootchan->name);
214                 /* continue up chain, until we reach target number of items. */
215                 DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
216                                  BUILD,
217                                  "  %d = %s\n",
218                                  segcount, parchan->name);
219                 /* TODO(sergey): This is an arbitrary value, which was just following
220                  * old code convention. */
221                 segcount++;
222                 if ((segcount == data->rootbone) || (segcount > 255)) {
223                         break;
224                 }
225                 parchan  = parchan->parent;
226         }
227         OperationKey pose_done_key(
228                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
229         add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
230 }
231
232 /* Spline IK Eval Steps */
233 void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
234                                                    bPoseChannel *pchan,
235                                                    bConstraint *con,
236                                                    RootPChanMap *root_map)
237 {
238         bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
239         bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
240         OperationKey transforms_key(&object->id,
241                                     NodeType::BONE,
242                                     pchan->name,
243                                     OperationCode::BONE_READY);
244         OperationKey init_ik_key(&object->id,
245                                  NodeType::EVAL_POSE,
246                                  OperationCode::POSE_INIT_IK);
247         OperationKey solver_key(&object->id,
248                                 NodeType::EVAL_POSE,
249                                 rootchan->name,
250                                 OperationCode::POSE_SPLINE_IK_SOLVER);
251         OperationKey pose_cleanup_key(
252                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
253         /* Solver depends on initialization. */
254         add_relation(init_ik_key, solver_key, "Init IK -> IK Solver");
255         /* Never cleanup before solver is run. */
256         add_relation(solver_key, pose_cleanup_key, "IK Solver -> Cleanup");
257         /* Attach owner to IK Solver. */
258         add_relation(transforms_key,
259                      solver_key,
260                      "Spline IK Solver Owner",
261                      RELATION_FLAG_GODMODE);
262         /* Attach path dependency to solver. */
263         if (data->tar != NULL) {
264                 ComponentKey target_geometry_key(&data->tar->id, NodeType::GEOMETRY);
265                 add_relation(target_geometry_key, solver_key, "Curve.Path -> Spline IK");
266                 ComponentKey target_transform_key(&data->tar->id, NodeType::TRANSFORM);
267                 add_relation(target_transform_key, solver_key, "Curve.Transform -> Spline IK");
268                 add_special_eval_flag(&data->tar->id, DAG_EVAL_NEED_CURVE_PATH);
269         }
270         pchan->flag |= POSE_DONE;
271         OperationKey final_transforms_key(
272                 &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_DONE);
273         add_relation(solver_key, final_transforms_key, "Spline IK Result");
274         root_map->add_bone(pchan->name, rootchan->name);
275         /* Walk to the chain's root/ */
276         int segcount = 1;
277         for (bPoseChannel *parchan = pchan->parent;
278              parchan != NULL && segcount < data->chainlen;
279              parchan = parchan->parent, segcount++)
280         {
281                 /* Make Spline IK solver dependent on this bone's result, since it can
282                  * only run after the standard results of the bone are know. Validate
283                  * links step on the bone will ensure that users of this bone only grab
284                  * the result with IK solver results. */
285                 OperationKey parent_key(&object->id,
286                                                                 NodeType::BONE,
287                                                                 parchan->name,
288                                                                 OperationCode::BONE_READY);
289                 add_relation(parent_key, solver_key, "Spline IK Solver Update");
290                 OperationKey bone_done_key(&object->id,
291                                                                    NodeType::BONE,
292                                                                    parchan->name,
293                                                                    OperationCode::BONE_DONE);
294                 add_relation(solver_key, bone_done_key, "Spline IK Solver Result");
295                 parchan->flag |= POSE_DONE;
296                 root_map->add_bone(parchan->name, rootchan->name);
297         }
298         OperationKey pose_done_key(
299                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
300         add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
301 }
302
303 /* Pose/Armature Bones Graph */
304 void DepsgraphRelationBuilder::build_rig(Object *object)
305 {
306         /* Armature-Data */
307         bArmature *armature = (bArmature *)object->data;
308         // TODO: selection status?
309         /* Attach links between pose operations. */
310         ComponentKey local_transform(&object->id, NodeType::TRANSFORM);
311         OperationKey pose_init_key(
312                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT);
313         OperationKey pose_init_ik_key(
314                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_INIT_IK);
315         OperationKey pose_cleanup_key(
316                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
317         OperationKey pose_done_key(
318                 &object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
319         add_relation(
320                 local_transform, pose_init_key, "Local Transform -> Pose Init");
321         add_relation(pose_init_key, pose_init_ik_key, "Pose Init -> Pose Init IK");
322         add_relation(
323                 pose_init_ik_key, pose_done_key, "Pose Init IK -> Pose Cleanup");
324         /* Make sure pose is up-to-date with armature updates. */
325         build_armature(armature);
326         OperationKey armature_key(&armature->id,
327                                   NodeType::PARAMETERS,
328                                   OperationCode::ARMATURE_EVAL);
329         add_relation(armature_key, pose_init_key, "Data dependency");
330         /* Run cleanup even when there are no bones. */
331         add_relation(pose_init_key, pose_cleanup_key, "Init -> Cleanup");
332         /* IK Solvers.
333          *
334          * - These require separate processing steps are pose-level to be executed
335          *   between chains of bones (i.e. once the base transforms of a bunch of
336          *   bones is done).
337          *
338          * - We build relations for these before the dependencies between operations
339          *   in the same component as it is necessary to check whether such bones
340          *   are in the same IK chain (or else we get weird issues with either
341          *   in-chain references, or with bones being parented to IK'd bones).
342          *
343          * Unsolved Issues:
344          * - Care is needed to ensure that multi-headed trees work out the same as
345          *   in ik-tree building
346          * - Animated chain-lengths are a problem. */
347         RootPChanMap root_map;
348         bool pose_depends_on_local_transform = false;
349         LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
350                 LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
351                         switch (con->type) {
352                                 case CONSTRAINT_TYPE_KINEMATIC:
353                                         build_ik_pose(object, pchan, con, &root_map);
354                                         pose_depends_on_local_transform = true;
355                                         break;
356                                 case CONSTRAINT_TYPE_SPLINEIK:
357                                         build_splineik_pose(object, pchan, con, &root_map);
358                                         pose_depends_on_local_transform = true;
359                                         break;
360                                 /* Constraints which needs world's matrix for transform.
361                                  * TODO(sergey): More constraints here? */
362                                 case CONSTRAINT_TYPE_ROTLIKE:
363                                 case CONSTRAINT_TYPE_SIZELIKE:
364                                 case CONSTRAINT_TYPE_LOCLIKE:
365                                 case CONSTRAINT_TYPE_TRANSLIKE:
366                                         /* TODO(sergey): Add used space check. */
367                                         pose_depends_on_local_transform = true;
368                                         break;
369                                 default:
370                                         break;
371                         }
372                 }
373         }
374         // root_map.print_debug();
375         if (pose_depends_on_local_transform) {
376                 /* TODO(sergey): Once partial updates are possible use relation between
377                  * object transform and solver itself in it's build function. */
378                 ComponentKey pose_key(&object->id, NodeType::EVAL_POSE);
379                 ComponentKey local_transform_key(&object->id, NodeType::TRANSFORM);
380                 add_relation(local_transform_key, pose_key, "Local Transforms");
381         }
382         /* Links between operations for each bone. */
383         LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
384                 OperationKey bone_local_key(&object->id,
385                                             NodeType::BONE,
386                                             pchan->name,
387                                             OperationCode::BONE_LOCAL);
388                 OperationKey bone_pose_key(&object->id,
389                                            NodeType::BONE,
390                                            pchan->name,
391                                            OperationCode::BONE_POSE_PARENT);
392                 OperationKey bone_ready_key(&object->id,
393                                             NodeType::BONE,
394                                             pchan->name,
395                                             OperationCode::BONE_READY);
396                 OperationKey bone_done_key(&object->id,
397                                            NodeType::BONE,
398                                            pchan->name,
399                                            OperationCode::BONE_DONE);
400                 pchan->flag &= ~POSE_DONE;
401                 /* Pose init to bone local. */
402                 add_relation(pose_init_key,
403                              bone_local_key,
404                              "Pose Init - Bone Local",
405                              RELATION_FLAG_GODMODE);
406                 /* Local to pose parenting operation. */
407                 add_relation(bone_local_key, bone_pose_key, "Bone Local - Bone Pose");
408                 /* Parent relation. */
409                 if (pchan->parent != NULL) {
410                         OperationCode parent_key_opcode;
411                         /* NOTE: this difference in handling allows us to prevent lockups
412                          * while ensuring correct poses for separate chains. */
413                         if (root_map.has_common_root(pchan->name, pchan->parent->name)) {
414                                 parent_key_opcode = OperationCode::BONE_READY;
415                         }
416                         else {
417                                 parent_key_opcode = OperationCode::BONE_DONE;
418                         }
419
420                         OperationKey parent_key(&object->id,
421                                                 NodeType::BONE,
422                                                 pchan->parent->name,
423                                                 parent_key_opcode);
424                         add_relation(
425                                 parent_key, bone_pose_key, "Parent Bone -> Child Bone");
426                 }
427                 /* Build constraints. */
428                 if (pchan->constraints.first != NULL) {
429                         /* Build relations for indirectly linked objects. */
430                         BuilderWalkUserData data;
431                         data.builder = this;
432                         BKE_constraints_id_loop(
433                                 &pchan->constraints, constraint_walk, &data);
434                         /* Constraints stack and constraint dependencies. */
435                         build_constraints(&object->id,
436                                           NodeType::BONE,
437                                           pchan->name,
438                                           &pchan->constraints,
439                                           &root_map);
440                         /* Pose -> constraints. */
441                         OperationKey constraints_key(&object->id,
442                                                      NodeType::BONE,
443                                                      pchan->name,
444                                                      OperationCode::BONE_CONSTRAINTS);
445                         add_relation(bone_pose_key, constraints_key, "Pose -> Constraints Stack");
446                         add_relation(bone_local_key, constraints_key, "Local -> Constraints Stack");
447                         /* Constraints -> ready/ */
448                         /* TODO(sergey): When constraint stack is exploded, this step should
449                          * occur before the first IK solver.  */
450                         add_relation(
451                                 constraints_key, bone_ready_key, "Constraints -> Ready");
452                 }
453                 else {
454                         /* Pose -> Ready */
455                         add_relation(bone_pose_key, bone_ready_key, "Pose -> Ready");
456                 }
457                 /* Bone ready -> Bone done.
458                  * NOTE: For bones without IK, this is all that's needed.
459                  *       For IK chains however, an additional rel is created from IK
460                  *       to done, with transitive reduction removing this one. */
461                 add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
462                 /* B-Bone shape is the real final step after Done if present. */
463                 if (pchan->bone != NULL && pchan->bone->segments > 1) {
464                         OperationKey bone_segments_key(&object->id,
465                                                        NodeType::BONE,
466                                                        pchan->name,
467                                                        OperationCode::BONE_SEGMENTS);
468                         /* B-Bone shape depends on the final position of the bone. */
469                         add_relation(bone_done_key,
470                                      bone_segments_key,
471                                      "Done -> B-Bone Segments");
472                         /* B-Bone shape depends on final position of handle bones. */
473                         bPoseChannel *prev, *next;
474                         BKE_pchan_bbone_handles_get(pchan, &prev, &next);
475                         if (prev) {
476                                 OperationKey prev_key(&object->id,
477                                                       NodeType::BONE,
478                                                       prev->name,
479                                                       OperationCode::BONE_DONE);
480                                 add_relation(prev_key,
481                                              bone_segments_key,
482                                              "Prev Handle -> B-Bone Segments");
483                         }
484                         if (next) {
485                                 OperationKey next_key(&object->id,
486                                                       NodeType::BONE,
487                                                       next->name,
488                                                       OperationCode::BONE_DONE);
489                                 add_relation(next_key,
490                                              bone_segments_key,
491                                              "Next Handle -> B-Bone Segments");
492                         }
493                         /* Pose requires the B-Bone shape. */
494                         add_relation(bone_segments_key,
495                                      pose_done_key,
496                                      "PoseEval Result-Bone Link",
497                                      RELATION_FLAG_GODMODE);
498                         add_relation(bone_segments_key,
499                                      pose_cleanup_key,
500                                      "Cleanup dependency");
501                 }
502                 else {
503                         /* Assume that all bones must be done for the pose to be ready
504                          * (for deformers). */
505                         add_relation(bone_done_key,
506                                      pose_done_key,
507                                      "PoseEval Result-Bone Link");
508
509                         /* Bones must be traversed before cleanup. */
510                         add_relation(bone_done_key,
511                                      pose_cleanup_key,
512                                      "Done -> Cleanup");
513
514                         add_relation(bone_ready_key,
515                                      pose_cleanup_key,
516                                      "Ready -> Cleanup");
517                 }
518                 /* Custom shape. */
519                 if (pchan->custom != NULL) {
520                         build_object(NULL, pchan->custom);
521                 }
522         }
523 }
524
525 void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
526 {
527         bArmature *armature = (bArmature *)object->data;
528         Object *proxy_from = object->proxy_from;
529         build_armature(armature);
530         OperationKey pose_init_key(&object->id,
531                                    NodeType::EVAL_POSE,
532                                    OperationCode::POSE_INIT);
533         OperationKey pose_done_key(&object->id,
534                                    NodeType::EVAL_POSE,
535                                    OperationCode::POSE_DONE);
536         OperationKey pose_cleanup_key(&object->id,
537                                       NodeType::EVAL_POSE,
538                                       OperationCode::POSE_CLEANUP);
539         LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
540                 OperationKey bone_local_key(&object->id,
541                                             NodeType::BONE, pchan->name,
542                                             OperationCode::BONE_LOCAL);
543                 OperationKey bone_ready_key(&object->id,
544                                             NodeType::BONE,
545                                             pchan->name,
546                                             OperationCode::BONE_READY);
547                 OperationKey bone_done_key(&object->id,
548                                            NodeType::BONE,
549                                            pchan->name,
550                                            OperationCode::BONE_DONE);
551                 OperationKey from_bone_done_key(&proxy_from->id,
552                                                 NodeType::BONE,
553                                                 pchan->name,
554                                                 OperationCode::BONE_DONE);
555                 add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
556                 add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
557                 add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
558                 add_relation(
559                         bone_done_key, pose_cleanup_key, "Bone Done -> Pose Cleanup");
560                 add_relation(bone_done_key,
561                             pose_done_key,
562                             "Bone Done -> Pose Done",
563                             RELATION_FLAG_GODMODE);
564                 /* Make sure bone in the proxy is not done before it's FROM is done. */
565                 if (pchan->bone && pchan->bone->segments > 1) {
566                         OperationKey from_bone_segments_key(&proxy_from->id,
567                                                             NodeType::BONE,
568                                                             pchan->name,
569                                                             OperationCode::BONE_SEGMENTS);
570                         add_relation(from_bone_segments_key,
571                                      bone_done_key,
572                                      "Bone Segments -> Bone Done",
573                                      RELATION_FLAG_GODMODE);
574                 }
575                 else {
576                         add_relation(from_bone_done_key,
577                                      bone_done_key,
578                                      "Bone Done -> Bone Done");
579                 }
580
581                 if (pchan->prop != NULL) {
582                         OperationKey bone_parameters(&object->id,
583                                                      NodeType::PARAMETERS,
584                                                      OperationCode::PARAMETERS_EVAL,
585                                                      pchan->name);
586                         OperationKey from_bone_parameters(&proxy_from->id,
587                                                           NodeType::PARAMETERS,
588                                                           OperationCode::PARAMETERS_EVAL,
589                                                           pchan->name);
590                         add_relation(from_bone_parameters,
591                                      bone_parameters,
592                                      "Proxy Bone Parameters");
593                 }
594         }
595 }
596
597 }  // namespace DEG