Merge branch 'master' into blender2.8
[blender.git] / source / blender / depsgraph / intern / builder / deg_builder_nodes_rig.cc
index 3ef1eb547b51cf400080235a0d19e244b45039f2..f6f2dcce4672c27a0df0f62fcc794268cc23643d 100644 (file)
@@ -46,6 +46,7 @@ extern "C" {
 #include "DNA_armature_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BKE_action.h"
 #include "BKE_armature.h"
@@ -55,6 +56,7 @@ extern "C" {
 #include "DEG_depsgraph_build.h"
 
 #include "intern/builder/deg_builder.h"
+#include "intern/eval/deg_eval_copy_on_write.h"
 #include "intern/nodes/deg_node.h"
 #include "intern/nodes/deg_node_component.h"
 #include "intern/nodes/deg_node_operation.h"
@@ -64,16 +66,23 @@ extern "C" {
 
 namespace DEG {
 
-void DepsgraphNodeBuilder::build_pose_constraints(Object *object, bPoseChannel *pchan)
+void DepsgraphNodeBuilder::build_pose_constraints(Object *object,
+                                                  bPoseChannel *pchan)
 {
        /* create node for constraint stack */
        add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
-                          function_bind(BKE_pose_constraints_evaluate, _1, scene_, object, pchan),
+                          function_bind(BKE_pose_constraints_evaluate,
+                                        _1,
+                                        get_cow_datablock(scene_),
+                                        get_cow_datablock(object),
+                                        pchan),
                           DEG_OPCODE_BONE_CONSTRAINTS);
 }
 
 /* IK Solver Eval Steps */
-void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
+void DepsgraphNodeBuilder::build_ik_pose(Object *object,
+                                         bPoseChannel *pchan,
+                                         bConstraint *con)
 {
        bKinematicConstraint *data = (bKinematicConstraint *)con->data;
 
@@ -91,12 +100,18 @@ void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bC
 
        /* Operation node for evaluating/running IK Solver. */
        add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
-                          function_bind(BKE_pose_iktree_evaluate, _1, scene_, object, rootchan),
+                          function_bind(BKE_pose_iktree_evaluate,
+                                        _1,
+                                        get_cow_datablock(scene_),
+                                        get_cow_datablock(object),
+                                        rootchan),
                           DEG_OPCODE_POSE_IK_SOLVER);
 }
 
 /* Spline IK Eval Steps */
-void DepsgraphNodeBuilder::build_splineik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
+void DepsgraphNodeBuilder::build_splineik_pose(Object *object,
+                                               bPoseChannel *pchan,
+                                               bConstraint *con)
 {
        bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
 
@@ -104,30 +119,55 @@ void DepsgraphNodeBuilder::build_splineik_pose(Object *object, bPoseChannel *pch
        bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
 
        /* Operation node for evaluating/running Spline IK Solver.
-        * Store the "root bone" of this chain in the solver, so it knows where to start.
+        * Store the "root bone" of this chain in the solver, so it knows where to
+        * start.
         */
        add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
-                          function_bind(BKE_pose_splineik_evaluate, _1, scene_, object, rootchan),
+                          function_bind(BKE_pose_splineik_evaluate,
+                                        _1,
+                                        get_cow_datablock(scene_),
+                                        get_cow_datablock(object),
+                                        rootchan),
                           DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
 }
 
 /* Pose/Armature Bones Graph */
 void DepsgraphNodeBuilder::build_rig(Object *object)
 {
-       bArmature *arm = (bArmature *)object->data;
+       bArmature *armature = (bArmature *)object->data;
+       const short armature_tag = armature->id.tag;
+       Scene *scene_cow;
+       Object *object_cow;
+       bArmature *armature_cow;
+       if (DEG_depsgraph_use_copy_on_write()) {
+               /* NOTE: We need to expand both object and armature, so this way we can
+                * safely create object level pose.
+                */
+               scene_cow = get_cow_datablock(scene_);
+               object_cow = expand_cow_datablock(object);
+               armature_cow = expand_cow_datablock(armature);
+       }
+       else {
+               scene_cow = scene_;
+               object_cow = object;
+               armature_cow = armature;
+       }
        OperationDepsNode *op_node;
 
-       /* animation and/or drivers linking posebones to base-armature used to define them
+       /* Animation and/or drivers linking posebones to base-armature used to
+        * define them.
+        *
         * NOTE: AnimData here is really used to control animated deform properties,
-        *       which ideally should be able to be unique across different instances.
-        *       Eventually, we need some type of proxy/isolation mechanism in-between here
-        *       to ensure that we can use same rig multiple times in same scene...
+        *       which ideally should be able to be unique across different
+        *       instances. Eventually, we need some type of proxy/isolation
+        *       mechanism in-between here to ensure that we can use same rig
+        *       multiple times in same scene.
         */
-       if ((arm->id.tag & LIB_TAG_DOIT) == 0) {
-               build_animdata(&arm->id);
+       if ((armature_tag & LIB_TAG_DOIT) == 0) {
+               build_animdata(&armature->id);
 
                /* Make sure pose is up-to-date with armature updates. */
-               add_operation_node(&arm->id,
+               add_operation_node(&armature->id,
                                   DEG_NODE_TYPE_PARAMETERS,
                                   NULL,
                                   DEG_OPCODE_PLACEHOLDER,
@@ -135,22 +175,22 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
        }
 
        /* Rebuild pose if not up to date. */
-       if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) {
-               BKE_pose_rebuild_ex(object, arm, false);
+       if (object_cow->pose == NULL || (object->pose->flag & POSE_RECALC)) {
+               BKE_pose_rebuild(object_cow, armature_cow);
                /* XXX: Without this animation gets lost in certain circumstances
                 * after loading file. Need to investigate further since it does
                 * not happen with simple scenes..
                 */
-               if (object->adt) {
-                       object->adt->recalc |= ADT_RECALC_ANIM;
+               if (object_cow->adt) {
+                       object_cow->adt->recalc |= ADT_RECALC_ANIM;
                }
        }
 
        /* speed optimization for animation lookups */
-       if (object->pose) {
-               BKE_pose_channels_hash_make(object->pose);
-               if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
-                       BKE_pose_update_constraint_flags(object->pose);
+       if (object_cow->pose != NULL) {
+               BKE_pose_channels_hash_make(object_cow->pose);
+               if (object_cow->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
+                       BKE_pose_update_constraint_flags(object_cow->pose);
                }
        }
 
@@ -171,42 +211,58 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
         * - Used for representing each bone within the rig
         * - Acts to encapsulate the evaluation operations (base matrix + parenting,
         *   and constraint stack) so that they can be easily found.
-        * - Everything else which depends on bone-results hook up to the component only
-        *   so that we can redirect those to point at either the the post-IK/
+        * - Everything else which depends on bone-results hook up to the component
+        *   only so that we can redirect those to point at either the the post-IK/
         *   post-constraint/post-matrix steps, as needed.
         */
 
        /* pose eval context */
        op_node = add_operation_node(&object->id,
                                     DEG_NODE_TYPE_EVAL_POSE,
-                                    function_bind(BKE_pose_eval_init, _1, scene_, object, object->pose),
+                                    function_bind(BKE_pose_eval_init,
+                                                  _1,
+                                                  scene_cow,
+                                                  object_cow,
+                                                  object_cow->pose),
                                     DEG_OPCODE_POSE_INIT);
        op_node->set_as_entry();
 
        op_node = add_operation_node(&object->id,
                                     DEG_NODE_TYPE_EVAL_POSE,
-                                    function_bind(BKE_pose_eval_init_ik, _1, scene_, object, object->pose),
+                                    function_bind(BKE_pose_eval_init_ik,
+                                                  _1,
+                                                  scene_cow,
+                                                  object_cow,
+                                                  object_cow->pose),
                                     DEG_OPCODE_POSE_INIT_IK);
 
        op_node = add_operation_node(&object->id,
                                     DEG_NODE_TYPE_EVAL_POSE,
-                                    function_bind(BKE_pose_eval_flush, _1, scene_, object, object->pose),
+                                    function_bind(BKE_pose_eval_flush,
+                                                  _1,
+                                                  scene_cow,
+                                                  object_cow,
+                                                  object_cow->pose),
                                     DEG_OPCODE_POSE_DONE);
        op_node->set_as_exit();
 
        /* bones */
-       LINKLIST_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+       LINKLIST_FOREACH (bPoseChannel *, pchan, &object_cow->pose->chanbase) {
                /* Node for bone evaluation. */
                op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name, NULL,
                                             DEG_OPCODE_BONE_LOCAL);
                op_node->set_as_entry();
 
                add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
-                                  function_bind(BKE_pose_eval_bone, _1, scene_, object, pchan),
+                                  function_bind(BKE_pose_eval_bone, _1,
+                                                scene_cow,
+                                                object_cow,
+                                                pchan),
                                   DEG_OPCODE_BONE_POSE_PARENT);
 
+               /* NOTE: Dedicated noop for easier relationship construction. */
                add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
-                                  NULL, /* NOTE: dedicated noop for easier relationship construction */
+                                  NULL,
                                   DEG_OPCODE_BONE_READY);
 
                op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
@@ -221,7 +277,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
                                           DEG_OPCODE_PARAMETERS_EVAL,
                                           pchan->name);
                }
-               /* Constraints. */
+               /* Build constraints. */
                if (pchan->constraints.first != NULL) {
                        build_pose_constraints(object, pchan);
                }
@@ -233,8 +289,9 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
                 *   base transforms of a bunch of bones is done)
                 *
                 * 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...
+                * - Care is needed to ensure that multi-headed trees work out the same
+                *   as in ik-tree building
+                * - Animated chain-lengths are a problem.
                 */
                LINKLIST_FOREACH (bConstraint *, con, &pchan->constraints) {
                        switch (con->type) {
@@ -250,6 +307,13 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
                                        break;
                        }
                }
+               /* Custom shape. */
+               /* NOTE: Custom shape datablock is already remapped to CoW version. */
+               if (pchan->custom != NULL) {
+                       build_object(NULL,
+                                    get_orig_datablock(pchan->custom),
+                                    DEG_ID_LINKED_INDIRECTLY);
+               }
        }
 }
 
@@ -257,33 +321,43 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
 {
        ID *obdata = (ID *)object->data;
        OperationDepsNode *op_node;
-
-       build_animdata(obdata);
-
+       Object *object_cow = get_cow_datablock(object);
+       /* Sanity check. */
        BLI_assert(object->pose != NULL);
-
+       /* Animation. */
+       build_animdata(obdata);
        /* speed optimization for animation lookups */
        BKE_pose_channels_hash_make(object->pose);
        if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
                BKE_pose_update_constraint_flags(object->pose);
        }
-
        op_node = add_operation_node(&object->id,
                                     DEG_NODE_TYPE_EVAL_POSE,
-                                    function_bind(BKE_pose_eval_proxy_copy, _1, object),
+                                    function_bind(BKE_pose_eval_proxy_copy,
+                                                  _1,
+                                                  object_cow),
                                     DEG_OPCODE_POSE_INIT);
        op_node->set_as_entry();
-
        LINKLIST_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
-               op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
-                                            NULL, DEG_OPCODE_BONE_LOCAL);
+               /* Local bone transform. */
+               op_node = add_operation_node(&object->id,
+                                            DEG_NODE_TYPE_BONE,
+                                            pchan->name,
+                                            NULL,
+                                            DEG_OPCODE_BONE_LOCAL);
                op_node->set_as_entry();
-
-               add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
-                                  NULL, DEG_OPCODE_BONE_READY);
-
-               op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
-                                            NULL, DEG_OPCODE_BONE_DONE);
+               /* Bone is ready for solvers. */
+               add_operation_node(&object->id,
+                                  DEG_NODE_TYPE_BONE,
+                                  pchan->name,
+                                  NULL,
+                                  DEG_OPCODE_BONE_READY);
+               /* Bone is fully evaluated. */
+               op_node = add_operation_node(&object->id,
+                                            DEG_NODE_TYPE_BONE,
+                                            pchan->name,
+                                            NULL,
+                                            DEG_OPCODE_BONE_DONE);
                op_node->set_as_exit();
 
                /* Custom properties. */
@@ -295,9 +369,10 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
                                           pchan->name);
                }
        }
-
-       op_node = add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE,
-                                    NULL, DEG_OPCODE_POSE_DONE);
+       op_node = add_operation_node(&object->id,
+                                    DEG_NODE_TYPE_EVAL_POSE,
+                                    NULL,
+                                    DEG_OPCODE_POSE_DONE);
        op_node->set_as_exit();
 }