[Bf-blender-cvs] [ddae2d88fac] master: Depsgraph: only link 'IK Constraint -> Init IK Tree' if animated.

Alexander Gavrilov noreply at git.blender.org
Thu Jan 6 14:43:36 CET 2022


Commit: ddae2d88fac7be1055974a19e4f62e4bc01a4ff6
Author: Alexander Gavrilov
Date:   Mon Jan 3 19:46:25 2022 +0300
Branches: master
https://developer.blender.org/rBddae2d88fac7be1055974a19e4f62e4bc01a4ff6

Depsgraph: only link 'IK Constraint -> Init IK Tree' if animated.

This relation is intended to ensure that the properties of the IK
constraint are ready by the time the IK solver tree is built. This
however can cause spurious dependency cycles, because there is only
one init tree node for the whole armature, and the relation actually
implies dependency on all properties of the bone.

This patch reduces spurious dependencies by only creating the relation
if any properties of the IK constraint specifically are animated.

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

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

M	source/blender/depsgraph/intern/builder/deg_builder_cache.cc
M	source/blender/depsgraph/intern/builder/deg_builder_cache.h
M	source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc

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

diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index af7717d7595..0afaa72aad0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -127,6 +127,7 @@ void AnimatedPropertyStorage::initializeFromID(DepsgraphBuilderCache *builder_ca
 
 void AnimatedPropertyStorage::tagPropertyAsAnimated(const AnimatedPropertyID &property_id)
 {
+  animated_objects_set.add(property_id.data);
   animated_properties_set.add(property_id);
 }
 
@@ -147,6 +148,11 @@ bool AnimatedPropertyStorage::isPropertyAnimated(const PointerRNA *pointer_rna,
   return isPropertyAnimated(AnimatedPropertyID(pointer_rna, property_rna));
 }
 
+bool AnimatedPropertyStorage::isAnyPropertyAnimated(const PointerRNA *pointer_rna)
+{
+  return animated_objects_set.contains(pointer_rna->data);
+}
+
 /* Builder cache itself. */
 
 DepsgraphBuilderCache::~DepsgraphBuilderCache()
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.h b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
index c955a22a5cf..690046cb0d3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
@@ -69,10 +69,13 @@ class AnimatedPropertyStorage {
   bool isPropertyAnimated(const AnimatedPropertyID &property_id);
   bool isPropertyAnimated(const PointerRNA *pointer_rna, const PropertyRNA *property_rna);
 
+  bool isAnyPropertyAnimated(const PointerRNA *pointer_rna);
+
   /* The storage is fully initialized from all F-Curves from corresponding ID. */
   bool is_fully_initialized;
 
   /* indexed by PointerRNA.data. */
+  Set<void *> animated_objects_set;
   Set<AnimatedPropertyID> animated_properties_set;
 
   MEM_CXX_CLASS_ALLOC_FUNCS("AnimatedPropertyStorage");
@@ -102,6 +105,13 @@ class DepsgraphBuilderCache {
     return animated_property_storage->isPropertyAnimated(args...);
   }
 
+  bool isAnyPropertyAnimated(const PointerRNA *ptr)
+  {
+    AnimatedPropertyStorage *animated_property_storage = ensureInitializedAnimatedPropertyStorage(
+        ptr->owner_id);
+    return animated_property_storage->isAnyPropertyAnimated(ptr);
+  }
+
   Map<ID *, AnimatedPropertyStorage *> animated_property_storage_map_;
 
   MEM_CXX_CLASS_ALLOC_FUNCS("DepsgraphBuilderCache");
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 3039eebe857..856e37ee473 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -49,6 +49,7 @@
 #include "DEG_depsgraph_build.h"
 
 #include "intern/builder/deg_builder.h"
+#include "intern/builder/deg_builder_cache.h"
 #include "intern/builder/deg_builder_pchanmap.h"
 #include "intern/debug/deg_debug.h"
 #include "intern/node/deg_node.h"
@@ -84,14 +85,21 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
   OperationKey solver_key(
       &object->id, NodeType::EVAL_POSE, rootchan->name, OperationCode::POSE_IK_SOLVER);
   OperationKey pose_cleanup_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_CLEANUP);
-  add_relation(pchan_local_key, init_ik_key, "IK Constraint -> Init IK Tree");
+  /* If any of the constraint parameters are animated, connect the relation. Since there is only
+   * one Init IK node per armature, this link has quite high risk of spurious dependency cycles.
+   */
+  const bool is_itasc = (object->pose->iksolver == IKSOLVER_ITASC);
+  PointerRNA con_ptr;
+  RNA_pointer_create(&object->id, &RNA_Constraint, con, &con_ptr);
+  if (is_itasc || cache_->isAnyPropertyAnimated(&con_ptr)) {
+    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", RELATION_FLAG_GODMODE);
   /* The ITASC solver currently accesses the target transforms in init tree :(
    * TODO: Fix ITASC and remove this.
    */
-  bool is_itasc = (object->pose->iksolver == IKSOLVER_ITASC);
   OperationKey target_dependent_key = is_itasc ? init_ik_key : solver_key;
   /* IK target */
   /* TODO(sergey): This should get handled as part of the constraint code. */
@@ -100,6 +108,10 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
     if (data->tar != object) {
       ComponentKey target_key(&data->tar->id, NodeType::TRANSFORM);
       add_relation(target_key, target_dependent_key, con->name);
+      /* Ensure target CoW is ready by the time IK tree is built just in case. */
+      ComponentKey target_cow_key(&data->tar->id, NodeType::COPY_ON_WRITE);
+      add_relation(
+          target_cow_key, init_ik_key, "IK Target CoW -> Init IK Tree", RELATION_CHECK_BEFORE_ADD);
     }
     /* Subtarget references: */
     if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) {
@@ -129,6 +141,10 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
     if (data->poletar != object) {
       ComponentKey target_key(&data->poletar->id, NodeType::TRANSFORM);
       add_relation(target_key, target_dependent_key, con->name);
+      /* Ensure target CoW is ready by the time IK tree is built just in case. */
+      ComponentKey target_cow_key(&data->poletar->id, NodeType::COPY_ON_WRITE);
+      add_relation(
+          target_cow_key, init_ik_key, "IK Target CoW -> Init IK Tree", RELATION_CHECK_BEFORE_ADD);
     }
     /* Subtarget references: */
     if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) {



More information about the Bf-blender-cvs mailing list