diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-01-16 13:53:34 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-01-16 13:54:32 +0300 |
commit | 0b500ba1479550c9d6696889f74b945ad0c0dbd5 (patch) | |
tree | 3d25c228fbb0ee8c618a479265a514536747e0dc /source | |
parent | 45b5de9cb390bee1f3d9888cdaa3f4365f1a1479 (diff) |
Depsgraph: Fix fake cyclic dependencies for node tree drivers
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.
Diffstat (limited to 'source')
3 files changed, 55 insertions, 1 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index fbf5eac4e8c..38e58043e5b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -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"); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 9558a726402..1a761f76744 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -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_; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h index d53b1ee58e1..5b1f7be8e45 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h @@ -30,6 +30,12 @@ #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 |