[Bf-blender-cvs] [d7e2fe275d0] master: Depsgraph: build bbone operation if bone segments has animation

Sergey Sharybin noreply at git.blender.org
Tue Apr 30 11:32:17 CEST 2019


Commit: d7e2fe275d0c575ca20216f5534d85fb8bf6a2dc
Author: Sergey Sharybin
Date:   Mon Apr 29 14:19:56 2019 +0200
Branches: master
https://developer.blender.org/rBd7e2fe275d0c575ca20216f5534d85fb8bf6a2dc

Depsgraph: build bbone operation if bone segments has animation

This is a part of T61296: Crash with animated b-bone segments.

Consider animated/driven bendy bones segments as something what requires
special bendy-bones operation and relation in the dependency graph.

This is because it is more beneficial from a performance point of view
to not build operations if they are not needed. But if the property is
animated it is not possible to make any reliable decision based on just
a property value.

Differential Revision: https://developer.blender.org/D4739

===================================================================

M	source/blender/depsgraph/intern/builder/deg_builder.cc
M	source/blender/depsgraph/intern/builder/deg_builder.h
M	source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
M	source/blender/depsgraph/intern/builder/deg_builder_rna.cc

===================================================================

diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 5e35a620c81..b8e0ba51019 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -26,6 +26,7 @@
 #include <cstring>
 
 #include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
 #include "DNA_layer_types.h"
 #include "DNA_ID.h"
 #include "DNA_object_types.h"
@@ -34,6 +35,8 @@
 #include "BLI_ghash.h"
 #include "BLI_stack.h"
 
+#include "BKE_action.h"
+
 extern "C" {
 #include "BKE_animsys.h"
 }
@@ -97,6 +100,38 @@ bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
   return cache_->isPropertyAnimated(&object->id, property_id);
 }
 
+bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel *pchan)
+{
+  BLI_assert(object->type == OB_ARMATURE);
+  if (pchan->bone == NULL) {
+    return false;
+  }
+  /* We don't really care whether segments are higher than 1 due to static user input (as in,
+   * rigger entered value like 3 manually), or due to animation. In either way we need to create
+   * special evaluation. */
+  if (pchan->bone->segments > 1) {
+    return true;
+  }
+  bArmature *armature = static_cast<bArmature *>(object->data);
+  AnimatedPropertyID property_id(&armature->id, &RNA_Bone, pchan->bone, "bbone_segments");
+  return cache_->isPropertyAnimated(&armature->id, property_id);
+}
+
+bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan)
+{
+  /* Proxies don't have BONE_SEGMENTS */
+  if (ID_IS_LINKED(object) && object->proxy_from != NULL) {
+    return false;
+  }
+  return check_pchan_has_bbone(object, pchan);
+}
+
+bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const char *bone_name)
+{
+  const bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name);
+  return check_pchan_has_bbone_segments(object, pchan);
+}
+
 /*******************************************************************************
  * Builder finalizer.
  */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index 2f5bc42aeae..224e3212d57 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -23,8 +23,10 @@
 
 #pragma once
 
+struct bPoseChannel;
 struct Base;
 struct Main;
+struct Object;
 
 namespace DEG {
 
@@ -35,6 +37,10 @@ class DepsgraphBuilder {
  public:
   bool need_pull_base_into_graph(Base *base);
 
+  bool check_pchan_has_bbone(Object *object, const bPoseChannel *pchan);
+  bool check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan);
+  bool check_pchan_has_bbone_segments(Object *object, const char *bone_name);
+
  protected:
   /* NOTE: The builder does NOT take ownership over any of those resources. */
   DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache);
@@ -46,6 +52,6 @@ class DepsgraphBuilder {
 };
 
 bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base);
-void deg_graph_build_finalize(struct Main *bmain, struct Depsgraph *graph);
+void deg_graph_build_finalize(Main *bmain, Depsgraph *graph);
 
 }  // namespace DEG
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 6f141bd7222..979e1a02e71 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -231,7 +231,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
                                  function_bind(BKE_pose_bone_done, _1, object_cow, pchan_index));
 
     /* B-Bone shape computation - the real last step if present. */
-    if (pchan->bone != NULL && pchan->bone->segments > 1) {
+    if (check_pchan_has_bbone(object, pchan)) {
       op_node = add_operation_node(
           &object->id,
           NodeType::BONE,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 36cc105273d..147d82c5999 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -196,17 +196,6 @@ static OperationCode bone_target_opcode(ID *target,
   return OperationCode::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,
@@ -1019,7 +1008,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
           }
           /* if needs bbone shape, reference the segment computation */
           if (BKE_constraint_target_uses_bbone(con, ct) &&
-              bone_has_segments(ct->tar, ct->subtarget)) {
+              check_pchan_has_bbone_segments(ct->tar, ct->subtarget)) {
             opcode = OperationCode::BONE_SEGMENTS;
           }
           OperationKey target_key(&ct->tar->id, NodeType::BONE, ct->subtarget, opcode);
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 c1f904150f3..fadce685d31 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -374,7 +374,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
      *       to done, with transitive reduction removing this one. */
     add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
     /* B-Bone shape is the real final step after Done if present. */
-    if (pchan->bone != NULL && pchan->bone->segments > 1) {
+    if (check_pchan_has_bbone(object, pchan)) {
       OperationKey bone_segments_key(
           &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS);
       /* B-Bone shape depends on the final position of the bone. */
@@ -434,7 +434,7 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
     add_relation(bone_done_key, pose_cleanup_key, "Bone Done -> Pose Cleanup");
     add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done", RELATION_FLAG_GODMODE);
     /* Make sure bone in the proxy is not done before it's FROM is done. */
-    if (pchan->bone && pchan->bone->segments > 1) {
+    if (check_pchan_has_bbone(object, pchan)) {
       OperationKey from_bone_segments_key(
           &proxy_from->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS);
       add_relation(from_bone_segments_key,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index ac4e8e84d44..1238cdc70c6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -197,8 +197,9 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
       node_identifier.type = NodeType::BONE;
       node_identifier.component_name = pchan->name;
       /* But B-Bone properties should connect to the actual operation. */
-      if (!ELEM(NULL, pchan->bone, prop) && pchan->bone->segments > 1 &&
-          STRPREFIX(RNA_property_identifier(prop), "bbone_")) {
+      Object *object = reinterpret_cast<Object *>(node_identifier.id);
+      if (!ELEM(NULL, pchan->bone, prop) && STRPREFIX(RNA_property_identifier(prop), "bbone_") &&
+          builder_->check_pchan_has_bbone_segments(object, pchan)) {
         node_identifier.operation_code = OperationCode::BONE_SEGMENTS;
       }
     }



More information about the Bf-blender-cvs mailing list