Depsgraph: Fix fake cyclic dependencies for node tree drivers
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 16 Jan 2018 10:53:34 +0000 (11:53 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 16 Jan 2018 10:54:32 +0000 (11:54 +0100)
There was a fake cyclic dependency happening when node of node tree is driving
another node of the same tree.

This is related to T53794, but more fixes is needed here.

source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h

index fbf5eac4e8c3ffa7c87e0d0cac778766e1daa328..38e58043e5bc1f9e0448fd748d40e8a7ebe1784b 100644 (file)
@@ -1177,7 +1177,9 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
                                if (RNA_pointer_is_null(&variable_key.ptr)) {
                                        continue;
                                }
-                               if (is_same_bone_dependency(variable_key, self_key)) {
+                               if (is_same_bone_dependency(variable_key, self_key) ||
+                                   is_nodetree_node_dependency(variable_key, self_key))
+                               {
                                        continue;
                                }
                                add_relation(variable_key, driver_key, "RNA Target -> Driver");
index 9558a726402c0bb953436302dc6340d596d35b99..1a761f76744e33e785b0384d87931d3da31cfc34 100644 (file)
@@ -276,9 +276,22 @@ protected:
        DepsNodeHandle create_node_handle(const KeyType& key,
                                          const char *default_name = "");
 
+       /* Check whether two keys correponds to the same bone from same armature.
+        *
+        * This is used by drivers relations builder to avoid possible fake
+        * dependency cycle when one bone property drives another property of the
+        * same bone.
+        */
        template <typename KeyFrom, typename KeyTo>
        bool is_same_bone_dependency(const KeyFrom& key_from, const KeyTo& key_to);
 
+       /* Similar to above, but used to check whether driver is using node from
+        * the same node tree as a driver variable.
+        */
+       template <typename KeyFrom, typename KeyTo>
+       bool is_nodetree_node_dependency(const KeyFrom& key_from,
+                                        const KeyTo& key_to);
+
 private:
        /* State which never changes, same for the whole builder time. */
        Main *bmain_;
index d53b1ee58e1baadd534061d47eac7ca2cc2faae0..5b1f7be8e458fe898ac204504ef66492c8842933 100644 (file)
 
 #pragma once
 
+#include "intern/nodes/deg_node_id.h"
+
+extern "C" {
+#include "DNA_ID.h"
+}
+
 namespace DEG {
 
 template <typename KeyType>
@@ -157,4 +163,37 @@ bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from,
        return true;
 }
 
+template <typename KeyFrom, typename KeyTo>
+bool DepsgraphRelationBuilder::is_nodetree_node_dependency(
+        const KeyFrom& key_from,
+        const KeyTo& key_to)
+{
+       /* Get operations for requested keys. */
+       DepsNode *node_from = get_node(key_from);
+       DepsNode *node_to = get_node(key_to);
+       if (node_from == NULL || node_to == NULL) {
+               return false;
+       }
+       OperationDepsNode *op_from = node_from->get_exit_operation();
+       OperationDepsNode *op_to = node_to->get_entry_operation();
+       if (op_from == NULL || op_to == NULL) {
+               return false;
+       }
+       /* Check if this is actually a node tree. */
+       if (GS(op_from->owner->owner->id->name) != ID_NT) {
+               return false;
+       }
+       /* Different node trees. */
+       if (op_from->owner->owner != op_to->owner->owner) {
+               return false;
+       }
+       /* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */
+       if (!(op_from->opcode == DEG_OPCODE_PARAMETERS_EVAL &&
+             op_to->opcode == DEG_OPCODE_PARAMETERS_EVAL))
+       {
+               return false;
+       }
+       return true;
+}
+
 }  // namespace DEG