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:
Diffstat (limited to 'source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc191
1 files changed, 137 insertions, 54 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 29cd72c13fd..8be974aae39 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -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 */
- BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ BLI_LISTBASE_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.
*/
BLI_LISTBASE_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,34 +321,52 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
{
bArmature *arm = (bArmature *)object->data;
OperationDepsNode *op_node;
-
- build_animdata(&arm->id);
-
+ Object *object_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.
+ */
+ object_cow = expand_cow_datablock(object);
+ }
+ else {
+ object_cow = object;
+ }
+ /* Sanity check. */
BLI_assert(object->pose != NULL);
-
+ /* Animation. */
+ build_animdata(&arm->id);
/* 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);
+ if (object_cow->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
+ BKE_pose_update_constraint_flags(object_cow->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();
-
BLI_LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
- NULL, DEG_OPCODE_BONE_LOCAL);
+ 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. */
@@ -296,9 +378,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();
}