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:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-11-22 13:38:03 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2018-11-23 23:19:23 +0300
commit1e820898ff4dfc734710a6640ca7bafc0bfc69db (patch)
tree8f68fba82219df0295d89581e49e105ff907ba80 /source/blender/depsgraph
parente49c66efae9d9fb85154ca4b3073ae3733400708 (diff)
Depsgraph: add a new operation node for computing B-Bone segments.
Computing the shape of a B-Bone is a quite expensive operation, and there are multiple constraints that can access this information in a variety of useful ways. This means computing the shape once per bone and saving it is good for performance. Since the shape may depend on the position of up to two other bones, often in a "cyclic" manner, this computation has to be a separate node with its own dependencies. Reviewers: sergey Differential Revision: https://developer.blender.org/D3975
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc48
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc56
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type_defines.cc1
-rw-r--r--source/blender/depsgraph/intern/depsgraph_types.h2
5 files changed, 83 insertions, 35 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 eb2ed0e637d..8c349b7067f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -261,7 +261,18 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
object_cow,
pchan_index),
DEG_OPCODE_BONE_DONE);
+
+ /* B-Bone shape computation - the real last step if present. */
+ if (pchan->bone != NULL && pchan->bone->segments > 1) {
+ op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
+ function_bind(BKE_pose_eval_bbone_segments, _1,
+ object_cow,
+ pchan_index),
+ DEG_OPCODE_BONE_SEGMENTS);
+ }
+
op_node->set_as_exit();
+
/* Custom properties. */
if (pchan->prop != NULL) {
add_operation_node(&object->id,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 8f579216518..5e1ebee337c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -206,6 +206,17 @@ static eDepsOperation_Code bone_target_opcode(ID *target,
return DEG_OPCODE_BONE_DONE;
}
+static bool bone_has_segments(Object *object, const char *bone_name)
+{
+ /* Proxies don't have BONE_SEGMENTS */
+ if (ID_IS_LINKED(object) && object->proxy_from != NULL) {
+ return false;
+ }
+ /* Only B-Bones have segments. */
+ bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name);
+ return pchan && pchan->bone && pchan->bone->segments > 1;
+}
+
/* **** General purpose functions **** */
DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain,
@@ -1017,39 +1028,20 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
/* relation to bone */
opcode = bone_target_opcode(&ct->tar->id, ct->subtarget,
id, component_subdata, root_map);
+ /* Armature constraint always wants the final position and chan_mat. */
+ if (ELEM(con->type, CONSTRAINT_TYPE_ARMATURE)) {
+ opcode = DEG_OPCODE_BONE_DONE;
+ }
+ /* if needs bbone shape, reference the segment computation */
+ if (BKE_constraint_target_uses_bbone(con, ct) &&
+ bone_has_segments(ct->tar, ct->subtarget)) {
+ opcode = DEG_OPCODE_BONE_SEGMENTS;
+ }
OperationKey target_key(&ct->tar->id,
DEG_NODE_TYPE_BONE,
ct->subtarget,
opcode);
add_relation(target_key, constraint_op_key, cti->name);
- /* if needs bbone shape, also reference handles */
- if (BKE_constraint_target_uses_bbone(con, ct)) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget);
- /* actually a bbone */
- if (pchan && pchan->bone && pchan->bone->segments > 1) {
- bPoseChannel *prev, *next;
- BKE_pchan_get_bbone_handles(pchan, &prev, &next);
- /* add handle links */
- if (prev) {
- opcode = bone_target_opcode(&ct->tar->id, prev->name,
- id, component_subdata, root_map);
- OperationKey prev_key(&ct->tar->id,
- DEG_NODE_TYPE_BONE,
- prev->name,
- opcode);
- add_relation(prev_key, constraint_op_key, cti->name);
- }
- if (next) {
- opcode = bone_target_opcode(&ct->tar->id, next->name,
- id, component_subdata, root_map);
- OperationKey next_key(&ct->tar->id,
- DEG_NODE_TYPE_BONE,
- next->name,
- opcode);
- add_relation(next_key, constraint_op_key, cti->name);
- }
- }
- }
}
else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) &&
(ct->subtarget[0]))
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 1abed8bb6a2..1260ce013ea 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -488,10 +488,41 @@ 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_get_bbone_handles(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");
+ 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);
@@ -537,9 +568,20 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done");
/* 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,
+ "From Bone Segments -> Bone Done");
+ }
+ else {
+ add_relation(from_bone_done_key,
+ bone_done_key,
+ "From Bone Done -> Bone Done");
+ }
if (pchan->prop != NULL) {
OperationKey bone_parameters(&object->id,
diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
index 44e21656570..3f36b9f7831 100644
--- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc
+++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
@@ -157,6 +157,7 @@ const char *operationCodeAsString(eDepsOperation_Code opcode)
STRINGIFY_OPCODE(BONE_CONSTRAINTS);
STRINGIFY_OPCODE(BONE_READY);
STRINGIFY_OPCODE(BONE_DONE);
+ STRINGIFY_OPCODE(BONE_SEGMENTS);
/* Particles. */
STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL_INIT);
STRINGIFY_OPCODE(PARTICLE_SYSTEM_EVAL);
diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h
index d81483526ed..f8b519cb1aa 100644
--- a/source/blender/depsgraph/intern/depsgraph_types.h
+++ b/source/blender/depsgraph/intern/depsgraph_types.h
@@ -254,6 +254,8 @@ typedef enum eDepsOperation_Code {
// TODO: deform mats could get calculated in the final_transform ops...
DEG_OPCODE_BONE_READY,
DEG_OPCODE_BONE_DONE,
+ /* B-Bone segment shape computation (after DONE) */
+ DEG_OPCODE_BONE_SEGMENTS,
/* Particles. --------------------------------------- */
/* Particle System evaluation. */