Merge branch 'blender2.7'
[blender.git] / source / blender / depsgraph / intern / builder / deg_builder_relations_rig.cc
index 2b4d8d394ab47d62a76265cb50be9768bc284da7..efedf847515e61985ca5cfce41c3b164cc87d368 100644 (file)
@@ -93,8 +93,15 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
                                DEG_NODE_TYPE_EVAL_POSE,
                                rootchan->name,
                                DEG_OPCODE_POSE_IK_SOLVER);
+       OperationKey pose_cleanup_key(
+               &object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_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",
+                    DEPSREL_FLAG_GODMODE);
        /* IK target */
        /* TODO(sergey): This should get handled as part of the constraint code. */
        if (data->tar != NULL) {
@@ -133,9 +140,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
                         * separately. */
                        ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_GEOMETRY);
                        add_relation(target_key, solver_key, con->name);
-                       if (data->tar->type == OB_MESH) {
-                               add_customdata_mask(target_key, CD_MASK_MDEFORMVERT);
-                       }
+                       add_customdata_mask(data->tar, CD_MASK_MDEFORMVERT);
                }
                else {
                        /* Standard Object Target. */
@@ -165,9 +170,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
                         * separately. */
                        ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_GEOMETRY);
                        add_relation(target_key, solver_key, con->name);
-                       if (data->poletar->type == OB_MESH) {
-                               add_customdata_mask(target_key, CD_MASK_MDEFORMVERT);
-                       }
+                       add_customdata_mask(data->poletar, CD_MASK_MDEFORMVERT);
                }
                else {
                        ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_TRANSFORM);
@@ -254,10 +257,17 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
                                DEG_NODE_TYPE_EVAL_POSE,
                                rootchan->name,
                                DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
+       OperationKey pose_cleanup_key(
+               &object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_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");
+       add_relation(transforms_key,
+                    solver_key,
+                    "Spline IK Solver Owner",
+                    DEPSREL_FLAG_GODMODE);
        /* Attach path dependency to solver. */
        if (data->tar != NULL) {
                /* TODO(sergey): For until we'll store partial matricies in the
@@ -474,10 +484,56 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
                 *       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");
-               /* 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");
-               add_relation(bone_done_key, pose_cleanup_key, "Cleanup dependency");
+               /* 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,
+                                                      DEG_NODE_TYPE_BONE,
+                                                      pchan->name,
+                                                      DEG_OPCODE_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,
+                                                     DEG_NODE_TYPE_BONE,
+                                                     prev->name,
+                                                     DEG_OPCODE_BONE_DONE);
+                               add_relation(prev_key,
+                                            bone_segments_key,
+                                            "Prev Handle -> B-Bone Segments");
+                       }
+                       if (next) {
+                               OperationKey next_key(&object->id,
+                                                     DEG_NODE_TYPE_BONE,
+                                                     next->name,
+                                                     DEG_OPCODE_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",
+                                    DEPSREL_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");
+                       add_relation(bone_done_key,
+                                    pose_cleanup_key,
+                                    "Cleanup dependency");
+               }
                /* Custom shape. */
                if (pchan->custom != NULL) {
                        build_object(NULL, pchan->custom);
@@ -520,12 +576,27 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
                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");
+               add_relation(bone_done_key,
+                           pose_done_key,
+                           "Bone Done -> Pose Done",
+                           DEPSREL_FLAG_GODMODE);
 
                /* Make sure bone in the proxy is not done before it's FROM is done. */
-               add_relation(from_bone_done_key,
-                            bone_done_key,
-                            "From Bone Done -> Pose Done");
+               if (pchan->bone && pchan->bone->segments > 1) {
+                       OperationKey from_bone_segments_key(&proxy_from->id,
+                                                           DEG_NODE_TYPE_BONE,
+                                                           pchan->name,
+                                                           DEG_OPCODE_BONE_SEGMENTS);
+                       add_relation(from_bone_segments_key,
+                                    bone_done_key,
+                                    "Bone Segments -> Bone Done",
+                                    DEPSREL_FLAG_GODMODE);
+               }
+               else {
+                       add_relation(from_bone_done_key,
+                                    bone_done_key,
+                                    "Bone Done -> Bone Done");
+               }
 
                if (pchan->prop != NULL) {
                        OperationKey bone_parameters(&object->id,