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:
-rw-r--r--source/blender/blenkernel/BKE_node_tree_update.h98
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/linestyle.c3
-rw-r--r--source/blender/blenkernel/intern/node.cc42
-rw-r--r--source/blender/blenkernel/intern/node_tree_update.cc493
-rw-r--r--source/blender/blenloader/intern/versioning_250.c9
-rw-r--r--source/blender/blenloader/intern/versioning_280.c11
-rw-r--r--source/blender/blenloader/intern/versioning_300.c3
-rw-r--r--source/blender/blenloader/intern/versioning_cycles.c29
-rw-r--r--source/blender/editors/include/ED_node.h19
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c2
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_node/drawnode.cc3
-rw-r--r--source/blender/editors/space_node/node_add.cc40
-rw-r--r--source/blender/editors/space_node/node_edit.cc150
-rw-r--r--source/blender/editors/space_node/node_group.cc37
-rw-r--r--source/blender/editors/space_node/node_relationships.cc44
-rw-r--r--source/blender/editors/space_node/node_templates.cc15
-rw-r--r--source/blender/editors/transform/transform_convert_node.c3
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c2
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp3
-rw-r--r--source/blender/io/collada/Materials.cpp4
-rw-r--r--source/blender/io/usd/intern/usd_reader_material.cc3
-rw-r--r--source/blender/makesdna/DNA_node_types.h33
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c89
-rw-r--r--source/blender/makesrna/intern/rna_texture.c2
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc3
-rw-r--r--source/blender/nodes/intern/node_common.cc3
-rw-r--r--source/blender/nodes/intern/node_exec.cc3
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c21
32 files changed, 887 insertions, 287 deletions
diff --git a/source/blender/blenkernel/BKE_node_tree_update.h b/source/blender/blenkernel/BKE_node_tree_update.h
new file mode 100644
index 00000000000..83183a61ce3
--- /dev/null
+++ b/source/blender/blenkernel/BKE_node_tree_update.h
@@ -0,0 +1,98 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ */
+
+struct bNode;
+struct bNodeSocket;
+struct bNodeTree;
+struct bNodeLink;
+struct Main;
+struct ID;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Tag tree as changed without providing any more information about what has changed exactly.
+ * The update process has to assume that everything may have changed.
+ */
+void BKE_node_tree_update_tag(struct bNodeTree *ntree);
+
+/**
+ * More specialized tag functions that may result in a more efficient update.
+ */
+void BKE_node_tree_update_tag_node(struct bNodeTree *ntree, struct bNode *node);
+void BKE_node_tree_update_tag_socket(struct bNodeTree *ntree, struct bNodeSocket *socket);
+void BKE_node_tree_update_tag_link(struct bNodeTree *ntree);
+void BKE_node_tree_update_tag_node_removed(struct bNodeTree *ntree);
+void BKE_node_tree_update_tag_node_added(struct bNodeTree *ntree, struct bNode *node);
+void BKE_node_tree_update_tag_link_removed(struct bNodeTree *ntree);
+void BKE_node_tree_update_tag_link_added(struct bNodeTree *ntree, struct bNodeLink *link);
+void BKE_node_tree_update_tag_link_mute(struct bNodeTree *ntree, struct bNodeLink *link);
+void BKE_node_tree_update_tag_missing_runtime_data(struct bNodeTree *ntree);
+void BKE_node_tree_update_tag_interface(struct bNodeTree *ntree);
+
+typedef struct NodeTreeUpdateExtraParams {
+ /**
+ * Data passed into the callbacks.
+ */
+ void *user_data;
+
+ /**
+ * Called for every tree that has been changed during the update. This can be used to send
+ * notifiers to trigger redraws or depsgraph updates.
+ */
+ void (*tree_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
+
+ /**
+ * Called for every tree whose interface (e.g. input sockets) changed in some way.
+ */
+ void (*tree_interface_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
+
+ /**
+ * Called for every tree whose output value may have changed based on the provided update tags.
+ * This can be used to tag the depsgraph if necessary.
+ */
+ void (*tree_output_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
+} NodeTreeUpdateExtraParams;
+
+/**
+ * Updates #bmain based on changes to node trees.
+ */
+void BKE_node_tree_update_main(struct Main *bmain, struct NodeTreeUpdateExtraParams *params);
+
+/**
+ * Same as #BKE_node_tree_update_main, but will first only look at the provided tree and only looks
+ * at #bmain when something relevant for other data-blocks changed.
+ *
+ * If #bmain is null, only the provided tree is updated. This should only be used in very rare
+ * cases because it may result it incorrectly synced data in DNA.
+ *
+ * If #tree is null, this will update everything.
+ */
+void BKE_node_tree_update_main_rooted(struct Main *bmain,
+ struct bNodeTree *ntree,
+ struct NodeTreeUpdateExtraParams *params);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b2418d0539c..5f6e0a8e968 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -226,6 +226,7 @@ set(SRC
intern/multires_versioning.c
intern/nla.c
intern/node.cc
+ intern/node_tree_update.cc
intern/object.cc
intern/object_deform.c
intern/object_dupli.cc
@@ -418,6 +419,7 @@ set(SRC
BKE_multires.h
BKE_nla.h
BKE_node.h
+ BKE_node_tree_update.h
BKE_object.h
BKE_object_deform.h
BKE_object_facemap.h
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 3c305d1fb3f..8e473f7795d 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -50,6 +50,7 @@
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_texture.h"
#include "BLO_read_write.h"
@@ -2087,5 +2088,5 @@ void BKE_linestyle_default_shader(const bContext *C, FreestyleLineStyle *linesty
tosock = BLI_findlink(&output_linestyle->inputs, 0); /* Color */
nodeAddLink(ntree, input_texure, fromsock, output_linestyle, tosock);
- ntreeUpdateTree(CTX_data_main(C), ntree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(C), ntree, NULL);
}
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 98c31eab7cd..4fa2e0c379a 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -73,6 +73,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
@@ -99,6 +100,7 @@
#define NODE_DEFAULT_MAX_WIDTH 700
using blender::Array;
+using blender::Map;
using blender::MutableSpan;
using blender::Set;
using blender::Span;
@@ -695,6 +697,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
ntree->execdata = nullptr;
ntree->field_inferencing_interface = nullptr;
+ BKE_node_tree_update_tag_missing_runtime_data(ntree);
BLO_read_data_address(reader, &ntree->adt);
BKE_animdata_blend_read_data(reader, ntree->adt);
@@ -838,11 +841,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
/* TODO: should be dealt by new generic cache handling of IDs... */
ntree->previews = nullptr;
- if (ntree->type == NTREE_GEOMETRY) {
- /* Update field referencing for the geometry nodes modifier. */
- ntree->update |= NTREE_UPDATE_FIELD_INFERENCING;
- }
-
BLO_read_data_address(reader, &ntree->preview);
BKE_previewimg_blend_read(reader, ntree->preview);
@@ -1217,6 +1215,7 @@ static void node_socket_set_typeinfo(bNodeTree *ntree,
ntree->init &= ~NTREE_TYPE_INIT;
}
+ BKE_node_tree_update_tag_socket(ntree, sock);
}
/* Set specific typeinfo pointers in all node trees on register/unregister */
@@ -1707,7 +1706,7 @@ bNodeSocket *nodeAddSocket(bNodeTree *ntree,
BLI_remlink(lb, sock); /* does nothing for new socket */
BLI_addtail(lb, sock);
- node->update |= NODE_UPDATE;
+ BKE_node_tree_update_tag_socket(ntree, sock);
return sock;
}
@@ -2218,7 +2217,7 @@ bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idnam
BLI_strncpy(node->idname, idname, sizeof(node->idname));
node_set_typeinfo(C, ntree, node, nodeTypeFind(idname));
- ntree->update |= NTREE_UPDATE_NODES;
+ BKE_node_tree_update_tag_node(ntree, node);
return node;
}
@@ -2347,7 +2346,7 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
}
if (ntree) {
- ntree->update |= NTREE_UPDATE_NODES;
+ BKE_node_tree_update_tag_node(ntree, node_dst);
}
/* Reset the declaration of the new node. */
@@ -2445,7 +2444,7 @@ bNodeLink *nodeAddLink(
}
if (ntree) {
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link_added(ntree, link);
}
if (link != nullptr && link->tosock->flag & SOCK_MULTI_INPUT) {
@@ -2468,7 +2467,7 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
MEM_freeN(link);
if (ntree) {
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link_removed(ntree);
}
}
@@ -2568,7 +2567,7 @@ void nodeMuteLinkToggle(bNodeTree *ntree, bNodeLink *link)
}
if (ntree) {
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link_mute(ntree, link);
}
}
@@ -2579,8 +2578,6 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
nodeRemLink(ntree, link);
}
}
-
- ntree->update |= NTREE_UPDATE_LINKS;
}
bool nodeLinkIsHidden(const bNodeLink *link)
@@ -2645,7 +2642,7 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
link->flag |= NODE_LINK_MUTED;
}
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link(ntree);
}
else {
if (link->tosock->flag & SOCK_MULTI_INPUT) {
@@ -3189,7 +3186,7 @@ static void node_free_node(bNodeTree *ntree, bNode *node)
MEM_freeN(node);
if (ntree) {
- ntree->update |= NTREE_UPDATE_NODES;
+ BKE_node_tree_update_tag_node_removed(ntree);
}
}
@@ -3576,12 +3573,11 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree,
bNodeSocket *iosock = make_socket_interface(ntree, in_out, idname, name);
if (in_out == SOCK_IN) {
BLI_addtail(&ntree->inputs, iosock);
- ntree->update |= NTREE_UPDATE_GROUP_IN;
}
else if (in_out == SOCK_OUT) {
BLI_addtail(&ntree->outputs, iosock);
- ntree->update |= NTREE_UPDATE_GROUP_OUT;
}
+ BKE_node_tree_update_tag_interface(ntree);
return iosock;
}
@@ -3594,12 +3590,11 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree,
bNodeSocket *iosock = make_socket_interface(ntree, in_out, idname, name);
if (in_out == SOCK_IN) {
BLI_insertlinkbefore(&ntree->inputs, next_sock, iosock);
- ntree->update |= NTREE_UPDATE_GROUP_IN;
}
else if (in_out == SOCK_OUT) {
BLI_insertlinkbefore(&ntree->outputs, next_sock, iosock);
- ntree->update |= NTREE_UPDATE_GROUP_OUT;
}
+ BKE_node_tree_update_tag_interface(ntree);
return iosock;
}
@@ -3645,7 +3640,7 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock)
node_socket_interface_free(ntree, sock, true);
MEM_freeN(sock);
- ntree->update |= NTREE_UPDATE_GROUP;
+ BKE_node_tree_update_tag_interface(ntree);
}
/* generates a valid RNA identifier from the node tree name */
@@ -4527,21 +4522,24 @@ static void ntree_validate_links(bNodeTree *ntree)
void ntreeUpdateAllNew(Main *main)
{
+ Vector<bNodeTree *> new_ntrees;
+
/* Update all new node trees on file read or append, to add/remove sockets
* in groups nodes if the group changed, and handle any update flags that
* might have been set in file reading or versioning. */
FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
if (owner_id->tag & LIB_TAG_NEW) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ /* TODO: Move to update function. */
if (node->typeinfo->group_update_func) {
node->typeinfo->group_update_func(ntree, node);
}
}
-
- ntreeUpdateTree(nullptr, ntree);
+ BKE_node_tree_update_tag(ntree);
}
}
FOREACH_NODETREE_END;
+ BKE_node_tree_update_main(main, nullptr);
}
namespace blender::bke::node_field_inferencing {
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
new file mode 100644
index 00000000000..82b62b5d37c
--- /dev/null
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -0,0 +1,493 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_map.hh"
+#include "BLI_multi_value_map.hh"
+#include "BLI_set.hh"
+#include "BLI_vector_set.hh"
+
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
+
+#include "MOD_nodes.h"
+
+namespace blender::bke {
+
+using IDTreePair = std::pair<ID *, bNodeTree *>;
+using TreeNodePair = std::pair<bNodeTree *, bNode *>;
+using ObjectModifierPair = std::pair<Object *, ModifierData *>;
+
+struct NodeTreeRelations {
+ private:
+ Main *bmain_;
+ std::optional<Vector<IDTreePair>> all_trees_;
+ std::optional<MultiValueMap<bNodeTree *, TreeNodePair>> group_node_users_;
+ std::optional<MultiValueMap<bNodeTree *, ObjectModifierPair>> modifiers_users_;
+
+ public:
+ NodeTreeRelations(Main *bmain) : bmain_(bmain)
+ {
+ }
+
+ void ensure_all_trees()
+ {
+ if (all_trees_.has_value()) {
+ return;
+ }
+ all_trees_.emplace();
+ if (bmain_ == nullptr) {
+ return;
+ }
+
+ FOREACH_NODETREE_BEGIN (bmain_, ntree, id) {
+ all_trees_->append({id, ntree});
+ }
+ FOREACH_NODETREE_END;
+ }
+
+ void ensure_group_node_users()
+ {
+ if (group_node_users_.has_value()) {
+ return;
+ }
+ group_node_users_.emplace();
+ if (bmain_ == nullptr) {
+ return;
+ }
+
+ this->ensure_all_trees();
+
+ for (const IDTreePair &pair : *all_trees_) {
+ bNodeTree *ntree = pair.second;
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->id == nullptr) {
+ continue;
+ }
+ ID *id = node->id;
+ if (GS(id->name) == ID_NT) {
+ bNodeTree *group = (bNodeTree *)id;
+ group_node_users_->add(group, {ntree, node});
+ }
+ }
+ }
+ }
+
+ void ensure_modifier_users()
+ {
+ if (modifiers_users_.has_value()) {
+ return;
+ }
+ modifiers_users_.emplace();
+ if (bmain_ == nullptr) {
+ return;
+ }
+
+ LISTBASE_FOREACH (Object *, object, &bmain_->objects) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Nodes) {
+ NodesModifierData *nmd = (NodesModifierData *)md;
+ if (nmd->node_group != nullptr) {
+ modifiers_users_->add(nmd->node_group, {object, md});
+ }
+ }
+ }
+ }
+ }
+
+ Span<ObjectModifierPair> get_modifier_users(bNodeTree *ntree)
+ {
+ BLI_assert(modifiers_users_.has_value());
+ return modifiers_users_->lookup(ntree);
+ }
+
+ Span<TreeNodePair> get_group_node_users(bNodeTree *ntree)
+ {
+ BLI_assert(group_node_users_.has_value());
+ return group_node_users_->lookup(ntree);
+ }
+
+ Span<IDTreePair> get_all_trees()
+ {
+ BLI_assert(all_trees_.has_value());
+ return *all_trees_;
+ }
+};
+
+struct TreeUpdateResult {
+ bool interface_changed = false;
+ bool output_changed = false;
+};
+
+class NodeTreeMainUpdater {
+ private:
+ Main *bmain_;
+ NodeTreeUpdateExtraParams *params_;
+ Map<bNodeTree *, TreeUpdateResult> update_result_by_tree_;
+ NodeTreeRelations relations_;
+
+ public:
+ NodeTreeMainUpdater(Main *bmain, NodeTreeUpdateExtraParams *params)
+ : bmain_(bmain), params_(params), relations_(bmain)
+ {
+ }
+
+ void update()
+ {
+ Vector<bNodeTree *> changed_ntrees;
+ FOREACH_NODETREE_BEGIN (bmain_, ntree, id) {
+ if (ntree->changed_flag != NTREE_CHANGED_NONE) {
+ changed_ntrees.append(ntree);
+ }
+ }
+ FOREACH_NODETREE_END;
+ this->update_rooted(changed_ntrees);
+ }
+
+ void update_rooted(Span<bNodeTree *> root_ntrees)
+ {
+ if (root_ntrees.is_empty()) {
+ return;
+ }
+
+ bool is_single_tree_update = false;
+
+ if (root_ntrees.size() == 1) {
+ bNodeTree *ntree = root_ntrees[0];
+ const TreeUpdateResult result = this->update_tree(*ntree);
+ update_result_by_tree_.add_new(ntree, result);
+ if (!result.interface_changed && !result.output_changed) {
+ is_single_tree_update = true;
+ }
+ }
+
+ if (!is_single_tree_update) {
+ Vector<bNodeTree *> ntrees_in_order = this->get_tree_update_order(root_ntrees);
+ for (bNodeTree *ntree : ntrees_in_order) {
+ if (ntree->changed_flag == NTREE_CHANGED_NONE) {
+ continue;
+ }
+ if (!update_result_by_tree_.contains(ntree)) {
+ const TreeUpdateResult result = this->update_tree(*ntree);
+ update_result_by_tree_.add_new(ntree, result);
+ }
+ const TreeUpdateResult result = update_result_by_tree_.lookup(ntree);
+ if (result.output_changed || result.interface_changed) {
+ Span<TreeNodePair> dependent_trees = relations_.get_group_node_users(ntree);
+ for (const TreeNodePair &pair : dependent_trees) {
+ BKE_node_tree_update_tag_node(pair.first, pair.second);
+ }
+ }
+ }
+ }
+
+ for (const auto &item : update_result_by_tree_.items()) {
+ bNodeTree *ntree = item.key;
+ const TreeUpdateResult &result = item.value;
+ /* TODO: Use owner id of embedded node trees. */
+ ID *id = &ntree->id;
+
+ ntree->changed_flag = NTREE_CHANGED_NONE;
+
+ if (result.interface_changed) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ relations_.ensure_modifier_users();
+ for (const ObjectModifierPair &pair : relations_.get_modifier_users(ntree)) {
+ Object *object = pair.first;
+ ModifierData *md = pair.second;
+
+ if (md->type == eModifierType_Nodes) {
+ MOD_nodes_update_interface(object, (NodesModifierData *)md);
+ }
+ }
+ }
+ }
+
+ if (params_) {
+ if (params_->tree_changed_fn) {
+ params_->tree_changed_fn(id, ntree, params_->user_data);
+ }
+ if (params_->tree_interface_changed_fn && result.interface_changed) {
+ params_->tree_interface_changed_fn(id, ntree, params_->user_data);
+ }
+ if (params_->tree_output_changed_fn && result.output_changed) {
+ params_->tree_output_changed_fn(id, ntree, params_->user_data);
+ }
+ }
+ }
+ }
+
+ private:
+ enum class ToposortMark {
+ None,
+ Temporary,
+ Permanent,
+ };
+
+ using ToposortMarkMap = Map<bNodeTree *, ToposortMark>;
+
+ Vector<bNodeTree *> get_tree_update_order(Span<bNodeTree *> root_ntrees)
+ {
+ relations_.ensure_all_trees();
+ relations_.ensure_group_node_users();
+
+ Set<bNodeTree *> trees_to_update = get_trees_to_update(root_ntrees);
+
+ Vector<bNodeTree *> sorted_ntrees;
+
+ ToposortMarkMap marks;
+ for (bNodeTree *ntree : trees_to_update) {
+ marks.add_new(ntree, ToposortMark::None);
+ }
+ for (bNodeTree *ntree : trees_to_update) {
+ if (marks.lookup(ntree) == ToposortMark::None) {
+ const bool cycle_detected = !this->get_tree_update_order__visit_recursive(
+ ntree, marks, sorted_ntrees);
+ BLI_assert(!cycle_detected);
+ }
+ }
+
+ return sorted_ntrees;
+ }
+
+ bool get_tree_update_order__visit_recursive(bNodeTree *ntree,
+ ToposortMarkMap &marks,
+ Vector<bNodeTree *> &sorted_ntrees)
+ {
+ ToposortMark &mark = marks.lookup(ntree);
+ if (mark == ToposortMark::Permanent) {
+ return true;
+ }
+ if (mark == ToposortMark::Temporary) {
+ /* There is a dependency cycle. */
+ return false;
+ }
+
+ mark = ToposortMark::Temporary;
+
+ for (const TreeNodePair &pair : relations_.get_group_node_users(ntree)) {
+ this->get_tree_update_order__visit_recursive(pair.first, marks, sorted_ntrees);
+ }
+ sorted_ntrees.append(ntree);
+
+ mark = ToposortMark::Permanent;
+ return true;
+ }
+
+ Set<bNodeTree *> get_trees_to_update(Span<bNodeTree *> root_ntrees)
+ {
+ relations_.ensure_group_node_users();
+
+ Set<bNodeTree *> reachable_trees;
+ VectorSet<bNodeTree *> trees_to_check = root_ntrees;
+
+ while (!trees_to_check.is_empty()) {
+ bNodeTree *ntree = trees_to_check.pop();
+ if (reachable_trees.add(ntree)) {
+ for (const TreeNodePair &pair : relations_.get_group_node_users(ntree)) {
+ trees_to_check.add(pair.first);
+ }
+ }
+ }
+
+ return reachable_trees;
+ }
+
+ TreeUpdateResult update_tree(bNodeTree &ntree)
+ {
+ TreeUpdateResult result;
+
+ if (ntree.changed_flag & NTREE_CHANGED_INTERFACE) {
+ result.interface_changed = true;
+ }
+
+ if (ntree.changed_flag & NTREE_CHANGED_LINK) {
+ this->update_input_socket_link_pointers(ntree);
+ }
+ this->update_individual_nodes(ntree);
+
+ if (ntree.typeinfo->update) {
+ ntree.typeinfo->update(&ntree);
+ }
+
+ result.interface_changed = true;
+ result.output_changed = true;
+
+ if (result.interface_changed) {
+ ntreeInterfaceTypeUpdate(&ntree);
+ }
+
+ return result;
+ }
+
+ void update_input_socket_link_pointers(bNodeTree &ntree)
+ {
+ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ socket->link = nullptr;
+ }
+ }
+
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
+ link->tosock->link = link;
+ }
+
+ this->update_socket_used_tags(ntree);
+ }
+
+ void update_socket_used_tags(bNodeTree &ntree)
+ {
+ /* First clear flag. */
+ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+ sock->flag &= ~SOCK_IN_USE;
+ }
+ LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
+ sock->flag &= ~SOCK_IN_USE;
+ }
+ }
+
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
+ link->fromsock->flag |= SOCK_IN_USE;
+ if (!(link->flag & NODE_LINK_MUTED)) {
+ link->tosock->flag |= SOCK_IN_USE;
+ }
+ }
+ }
+
+ void update_individual_nodes(bNodeTree &ntree)
+ {
+ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+ if (ntree.changed_flag & NTREE_CHANGED_ANY || node->changed_flag & NODE_CHANGED_ANY) {
+ this->update_individual_node(ntree, *node);
+ }
+ }
+ }
+
+ void update_individual_node(bNodeTree &ntree, bNode &node)
+ {
+ if (node.typeinfo->updatefunc) {
+ node.typeinfo->updatefunc(&ntree, &node);
+ }
+
+ BLI_freelistN(&node.internal_links);
+ if (node.typeinfo->update_internal_links) {
+ node.typeinfo->update_internal_links(&ntree, &node);
+ }
+ }
+};
+
+} // namespace blender::bke
+
+void BKE_node_tree_update_tag(bNodeTree *ntree)
+{
+ ntree->changed_flag |= NTREE_CHANGED_ALL;
+ ntree->update |= NTREE_UPDATE;
+}
+
+void BKE_node_tree_update_tag_node(bNodeTree *ntree, bNode *node)
+{
+ ntree->changed_flag |= NTREE_CHANGED_NODE;
+ node->changed_flag |= NODE_CHANGED_ANY;
+ ntree->update |= NTREE_UPDATE;
+}
+
+void BKE_node_tree_update_tag_socket(bNodeTree *ntree, bNodeSocket *socket)
+{
+ ntree->changed_flag |= NTREE_CHANGED_SOCKET;
+ socket->changed_flag |= SOCK_CHANGED_ANY;
+ ntree->update |= NTREE_UPDATE;
+}
+
+void BKE_node_tree_update_tag_node_removed(bNodeTree *ntree)
+{
+ ntree->changed_flag |= NTREE_CHANGED_REMOVED_ANY;
+ ntree->update |= NTREE_UPDATE;
+}
+
+void BKE_node_tree_update_tag_link(bNodeTree *ntree)
+{
+ ntree->changed_flag |= NTREE_CHANGED_LINK;
+ ntree->update |= NTREE_UPDATE;
+}
+
+void BKE_node_tree_update_tag_node_added(bNodeTree *ntree, bNode *node)
+{
+ BKE_node_tree_update_tag_node(ntree, node);
+}
+
+void BKE_node_tree_update_tag_link_removed(bNodeTree *ntree)
+{
+ BKE_node_tree_update_tag_link(ntree);
+}
+
+void BKE_node_tree_update_tag_link_added(bNodeTree *ntree, bNodeLink *UNUSED(link))
+{
+ BKE_node_tree_update_tag_link(ntree);
+}
+
+void BKE_node_tree_update_tag_link_mute(bNodeTree *ntree, bNodeLink *UNUSED(link))
+{
+ BKE_node_tree_update_tag_link(ntree);
+}
+
+void BKE_node_tree_update_tag_missing_runtime_data(bNodeTree *ntree)
+{
+ ntree->changed_flag |= NTREE_CHANGED_MISSING_RUNTIME_DATA;
+ ntree->update |= NTREE_UPDATE;
+}
+
+void BKE_node_tree_update_tag_interface(bNodeTree *ntree)
+{
+ ntree->changed_flag |= NTREE_CHANGED_INTERFACE;
+ ntree->update |= NTREE_UPDATE;
+}
+
+static bool is_updating = false;
+
+void BKE_node_tree_update_main(Main *bmain, NodeTreeUpdateExtraParams *params)
+{
+ if (is_updating) {
+ return;
+ }
+
+ is_updating = true;
+ blender::bke::NodeTreeMainUpdater updater{bmain, params};
+ updater.update();
+ is_updating = false;
+}
+
+void BKE_node_tree_update_main_rooted(Main *bmain,
+ bNodeTree *ntree,
+ NodeTreeUpdateExtraParams *params)
+{
+ if (ntree == nullptr) {
+ BKE_node_tree_update_main(bmain, params);
+ return;
+ }
+
+ if (is_updating) {
+ return;
+ }
+
+ is_updating = true;
+ blender::bke::NodeTreeMainUpdater updater{bmain, params};
+ updater.update_rooted({ntree});
+ is_updating = false;
+}
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 54e673b51eb..de7cee8abf5 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -70,6 +70,7 @@
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
+#include "BKE_node_tree_update.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_screen.h"
@@ -590,7 +591,7 @@ static bNodeSocket *do_versions_node_group_add_socket_2_56_2(bNodeTree *ngroup,
BLI_addtail(in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock);
- ngroup->update |= (in_out == SOCK_IN ? NTREE_UPDATE_GROUP_IN : NTREE_UPDATE_GROUP_OUT);
+ BKE_node_tree_update_tag_interface(ngroup);
return gsock;
}
@@ -2019,7 +2020,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
link->fromsock = gsock;
link->tonode = node;
link->tosock = sock;
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link_added(ntree, link);
sock->link = link;
}
@@ -2042,7 +2043,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
link->fromsock = sock;
link->tonode = NULL;
link->tosock = gsock;
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link_added(ntree, link);
gsock->link = link;
}
@@ -2282,7 +2283,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
do_versions_socket_default_value_259(sock);
}
- ntree->update |= NTREE_UPDATE;
+ BKE_node_tree_update_tag(ntree);
}
FOREACH_NODETREE_END;
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 4333bdb851c..e15de53bd0d 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -88,6 +88,7 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_paint.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
@@ -810,7 +811,9 @@ static void do_versions_seq_alloc_transform_and_crop(ListBase *seqbase)
}
/* Return true if there is something to convert. */
-static void do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, char blend_method)
+static void do_versions_material_convert_legacy_blend_mode(Main *bmain,
+ bNodeTree *ntree,
+ char blend_method)
{
bool need_update = false;
@@ -896,7 +899,7 @@ static void do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, cha
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
}
}
@@ -1594,13 +1597,13 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
bNodeTree *ntree = ma->nodetree;
if (ma->blend_method == 1 /* MA_BM_ADD */) {
if (ma->use_nodes) {
- do_versions_material_convert_legacy_blend_mode(ntree, 1 /* MA_BM_ADD */);
+ do_versions_material_convert_legacy_blend_mode(bmain, ntree, 1 /* MA_BM_ADD */);
}
ma->blend_method = MA_BM_BLEND;
}
else if (ma->blend_method == 2 /* MA_BM_MULTIPLY */) {
if (ma->use_nodes) {
- do_versions_material_convert_legacy_blend_mode(ntree, 2 /* MA_BM_MULTIPLY */);
+ do_versions_material_convert_legacy_blend_mode(bmain, ntree, 2 /* MA_BM_MULTIPLY */);
}
ma->blend_method = MA_BM_BLEND;
}
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 5296a0b4f82..e25d90ea90b 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -58,6 +58,7 @@
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -585,7 +586,7 @@ static bNodeTree *add_realize_node_tree(Main *bmain)
nodeSetSelected(node, false);
}
- ntreeUpdateTree(bmain, node_tree);
+ BKE_node_tree_update_main_rooted(bmain, node_tree, NULL);
return node_tree;
}
diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c
index afe2e1067ae..2336895b3e1 100644
--- a/source/blender/blenloader/intern/versioning_cycles.c
+++ b/source/blender/blenloader/intern/versioning_cycles.c
@@ -41,6 +41,7 @@
#include "BKE_idprop.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "MEM_guardedalloc.h"
@@ -170,7 +171,7 @@ static void displacement_node_insert(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -243,7 +244,7 @@ static void square_roughness_node_insert(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -318,7 +319,7 @@ static void ambient_occlusion_node_relink(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -466,7 +467,7 @@ static void update_math_node_single_operand_operators(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -528,7 +529,7 @@ static void update_vector_math_node_add_and_subtract_operators(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -566,7 +567,7 @@ static void update_vector_math_node_dot_product_operator(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -631,7 +632,7 @@ static void update_vector_math_node_cross_product_operator(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -683,7 +684,7 @@ static void update_vector_math_node_normalize_operator(bNodeTree *ntree)
}
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -785,7 +786,7 @@ static void update_vector_math_node_average_operator(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -974,7 +975,7 @@ static void update_mapping_node_inputs_and_properties(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -1149,7 +1150,7 @@ static void update_voronoi_node_crackle(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -1191,7 +1192,7 @@ static void update_voronoi_node_coloring(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -1234,7 +1235,7 @@ static void update_voronoi_node_square_distance(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
@@ -1279,7 +1280,7 @@ static void update_noise_and_wave_distortion(bNodeTree *ntree)
}
if (need_update) {
- ntreeUpdateTree(NULL, ntree);
+ BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
}
}
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index e68617f7867..0e7e57643ea 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -120,6 +120,25 @@ void ED_node_set_active(struct Main *bmain,
struct bNode *node,
bool *r_active_texture_changed);
+/**
+ * Call after one or more node trees have been changed and have been tagged accordingly.
+ *
+ * This function will make sure that other parts of Blender update accordingly. For example, if the
+ * node group interface changed, parent node groups have to be updated as well.
+ *
+ * Additionally, this will send notifiers and tag the depsgraph based on the changes. Depsgraph
+ * relation updates have to be triggered by the caller.
+ *
+ * \param C: Context if available. This can be null.
+ * \param bmain: Main whose data-blocks should be updated based on the changes.
+ * \param only_tagged_tree: Under some circumstances the caller knows that only one node tree has
+ * changed since the last update. In this case the function may be able to skip scanning bmain
+ * for other things that have to be changed.
+ */
+void ED_node_tree_propagate_change(const struct bContext *C,
+ struct Main *bmain,
+ struct bNodeTree *ntree);
+
void ED_node_composite_job(const struct bContext *C,
struct bNodeTree *nodetree,
struct Scene *scene_owner);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index db3e69b0953..96a0beb6426 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -6636,7 +6636,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
}
}
- ntreeUpdateTree(CTX_data_main(C), ntree);
+ ED_node_tree_propagate_change(C, bmain, ntree);
/* In case we added more than one node, position them too. */
nodePositionPropagate(out_node);
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index e88d61fe880..444ab6c827e 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../../imbuf
../../makesdna
../../makesrna
+ ../../modifiers
../../nodes
../../render
../../windowmanager
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index 63461056c8f..0226c7ba61e 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -3323,7 +3323,8 @@ static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), Poin
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
bNode *node = (bNode *)ptr->data;
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ UNUSED_VARS(node);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocketTemplate *stemp)
diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc
index ea78ff36ab6..ae59cf7e365 100644
--- a/source/blender/editors/space_node/node_add.cc
+++ b/source/blender/editors/space_node/node_add.cc
@@ -37,6 +37,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
@@ -89,7 +90,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
nodeSetSelected(node, true);
- ntreeUpdateTree(bmain, snode->edittree);
+ BKE_node_tree_update_main_rooted(bmain, snode->edittree, nullptr);
ED_node_set_active(bmain, snode, snode->edittree, node, nullptr);
snode_update(snode, node);
@@ -288,9 +289,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
BLI_freelistN(&input_links);
/* always last */
- ntreeUpdateTree(CTX_data_main(C), ntree);
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
return OPERATOR_FINISHED;
}
@@ -392,11 +391,7 @@ static int node_add_group_exec(bContext *C, wmOperator *op)
id_us_plus(group_node->id);
nodeSetActive(ntree, group_node);
- ntreeUpdateTree(bmain, node_group);
- ntreeUpdateTree(bmain, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, nullptr);
return OPERATOR_FINISHED;
}
@@ -487,12 +482,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
id_us_plus(&object->id);
nodeSetActive(ntree, object_node);
- ntreeUpdateTree(bmain, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
-
- ED_node_tag_update_nodetree(bmain, ntree, object_node);
+ ED_node_tree_propagate_change(C, bmain, ntree);
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
@@ -587,14 +577,9 @@ static int node_add_texture_exec(bContext *C, wmOperator *op)
id_us_plus(&texture->id);
nodeSetActive(ntree, texture_node);
- ntreeUpdateTree(bmain, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, ntree);
DEG_relations_tag_update(bmain);
- ED_node_tag_update_nodetree(bmain, ntree, texture_node);
-
return OPERATOR_FINISHED;
}
@@ -693,14 +678,9 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
id_us_plus(&collection->id);
nodeSetActive(ntree, collection_node);
- ntreeUpdateTree(bmain, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, ntree);
DEG_relations_tag_update(bmain);
- ED_node_tag_update_nodetree(bmain, ntree, collection_node);
-
return OPERATOR_FINISHED;
}
@@ -817,8 +797,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
}
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
@@ -913,8 +892,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
node->id = mask;
id_us_plus(mask);
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index 3d44d893b88..7c112524ca4 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -27,6 +27,7 @@
#include "DNA_light_types.h"
#include "DNA_material_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_text_types.h"
#include "DNA_world_types.h"
@@ -41,6 +42,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_workspace.h"
@@ -63,6 +65,8 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "MOD_nodes.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -440,6 +444,53 @@ void snode_notify(bContext *C, SpaceNode *snode)
}
}
+static void handle_tree_change(ID *id, bNodeTree *ntree)
+{
+ WM_main_add_notifier(NC_NODE | NA_EDITED, nullptr);
+
+ if (ntree->type == NTREE_SHADER) {
+ if (GS(id->name) == ID_MA) {
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
+ }
+ else if (GS(id->name) == ID_LA) {
+ WM_main_add_notifier(NC_LAMP | ND_LIGHTING, id);
+ }
+ else if (GS(id->name) == ID_WO) {
+ WM_main_add_notifier(NC_WORLD | ND_WORLD, id);
+ }
+ }
+ else if (ntree->type == NTREE_COMPOSIT) {
+ WM_main_add_notifier(NC_SCENE | ND_NODES, id);
+ }
+ else if (ntree->type == NTREE_TEXTURE) {
+ WM_main_add_notifier(NC_TEXTURE | ND_NODES, id);
+ }
+ else if (ntree->type == NTREE_GEOMETRY) {
+ WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, id);
+ }
+}
+
+void ED_node_tree_propagate_change(const bContext *UNUSED(C), Main *bmain, bNodeTree *ntree)
+{
+ struct UserData {
+ Main *bmain;
+ } user_data = {bmain};
+
+ NodeTreeUpdateExtraParams params = {0};
+ params.user_data = &user_data;
+ params.tree_changed_fn = [](ID *id, bNodeTree *ntree, void *UNUSED(user_data)) {
+ handle_tree_change(id, ntree);
+ };
+ params.tree_output_changed_fn = [](ID *id, bNodeTree *ntree, void *UNUSED(user_data)) {
+ if (id != nullptr) {
+ DEG_id_tag_update(id, 0);
+ }
+ DEG_id_tag_update(&ntree->id, 0);
+ };
+
+ BKE_node_tree_update_main_rooted(bmain, ntree, &params);
+}
+
void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
{
if (typeinfo) {
@@ -490,7 +541,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
}
ma->nodetree = ntreeCopyTree(bmain, ma_default->nodetree);
- ntreeUpdateTree(bmain, ma->nodetree);
+ BKE_node_tree_update_main_rooted(bmain, ma->nodetree, nullptr);
}
else if (ELEM(GS(id->name), ID_WO, ID_LA)) {
/* Emission */
@@ -530,7 +581,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
output->locx = 300.0f;
output->locy = 300.0f;
nodeSetActive(ntree, output);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, nullptr);
}
else {
printf("ED_node_shader_default called on wrong ID type.\n");
@@ -570,7 +621,7 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
bNodeSocket *tosock = (bNodeSocket *)out->inputs.first;
nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
- ntreeUpdateTree(CTX_data_main(C), sce->nodetree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(C), sce->nodetree, nullptr);
}
/* assumes nothing being done in ntree yet, sets the default in/out node */
@@ -600,7 +651,7 @@ void ED_node_texture_default(const bContext *C, Tex *tex)
bNodeSocket *tosock = (bNodeSocket *)out->inputs.first;
nodeAddLink(tex->nodetree, in, fromsock, out, tosock);
- ntreeUpdateTree(CTX_data_main(C), tex->nodetree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(C), tex->nodetree, nullptr);
}
/* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */
@@ -712,14 +763,10 @@ void ED_node_set_active(
}
node->flag |= NODE_DO_OUTPUT;
- if (was_output == 0) {
- ED_node_tag_update_nodetree(bmain, ntree, node);
- }
- }
- else if (do_update) {
- ED_node_tag_update_nodetree(bmain, ntree, node);
}
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
+
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
/* If active texture changed, free glsl materials. */
LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
@@ -765,7 +812,7 @@ void ED_node_set_active(
if (r_active_texture_changed) {
*r_active_texture_changed = true;
}
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
WM_main_add_notifier(NC_IMAGE, nullptr);
}
@@ -782,7 +829,7 @@ void ED_node_set_active(
node->flag |= NODE_DO_OUTPUT;
if (was_output == 0) {
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
/* Adding a node doesn't link this yet. */
@@ -797,11 +844,11 @@ void ED_node_set_active(
}
node->flag |= NODE_DO_OUTPUT;
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
}
else if (do_update) {
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
}
else if (ntree->type == NTREE_TEXTURE) {
@@ -1398,12 +1445,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
}
}
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
-
- snode_notify(C, snode);
- if (do_tag_update) {
- snode_dag_update(C, snode);
- }
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1495,8 +1537,7 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1663,7 +1704,7 @@ static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
node_flag_toggle_exec(snode, NODE_PREVIEW);
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1742,7 +1783,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
@@ -1783,10 +1824,7 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- snode_notify(C, snode);
- if (do_tag_update) {
- snode_dag_update(C, snode);
- }
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1823,12 +1861,7 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
-
- snode_notify(C, snode);
- if (do_tag_update) {
- snode_dag_update(C, snode);
- }
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1872,10 +1905,7 @@ static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1910,10 +1940,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1960,7 +1987,7 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "file_path", file_path);
ntreeCompositOutputFileAddSocket(ntree, node, file_path, &scene->r.im_format);
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -2009,7 +2036,7 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U
return OPERATOR_CANCELLED;
}
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
return OPERATOR_FINISHED;
}
@@ -2076,7 +2103,7 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
nimf->active_input++;
}
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -2322,10 +2349,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
}
Main *bmain = CTX_data_main(C);
- ntreeUpdateTree(bmain, snode->edittree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, snode->edittree);
/* Pasting nodes can create arbitrary new relations, because nodes can reference IDs. */
DEG_relations_tag_update(bmain);
@@ -2393,10 +2417,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
/* make the new socket active */
sock->flag |= SELECT;
- ntreeUpdateTree(CTX_data_main(C), ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
@@ -2443,10 +2464,7 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *op)
active_sock->flag |= SELECT;
}
- ntreeUpdateTree(CTX_data_main(C), ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
@@ -2497,7 +2515,7 @@ static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
/* Need the extra update here because the loop above does not check for valid links in the node
* group we're currently editing. */
- ntree->update |= NTREE_UPDATE_GROUP | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ntree);
/* Deactivate sockets. */
LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) {
@@ -2506,10 +2524,7 @@ static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
/* Make the new socket active. */
iosock->flag |= SELECT;
- ntreeUpdateTree(main, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, main, ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
@@ -2620,11 +2635,8 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
}
}
- ntree->update |= NTREE_UPDATE_GROUP;
- ntreeUpdateTree(CTX_data_main(C), ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ BKE_node_tree_update_tag_interface(ntree);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
@@ -2940,7 +2952,7 @@ static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op))
ntreeCompositCryptomatteAddSocket(ntree, node);
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
return OPERATOR_FINISHED;
}
@@ -2986,7 +2998,7 @@ static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(o
return OPERATOR_CANCELLED;
}
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc
index d9fbbc81a8f..125c2ba8249 100644
--- a/source/blender/editors/space_node/node_group.cc
+++ b/source/blender/editors/space_node/node_group.cc
@@ -40,6 +40,7 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "DEG_depsgraph_build.h"
@@ -391,7 +392,7 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* delete the group instance and dereference group tree */
nodeRemoveNode(bmain, ntree, gnode, true);
- ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ntree);
return 1;
}
@@ -410,16 +411,14 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op)
}
if (gnode->id && node_group_ungroup(bmain, snode->edittree, gnode)) {
- ntreeUpdateTree(bmain, snode->nodetree);
+ BKE_node_tree_update_main_rooted(bmain, snode->edittree, nullptr);
}
else {
BKE_report(op->reports, RPT_WARNING, "Cannot ungroup");
return OPERATOR_CANCELLED;
}
- snode_notify(C, snode);
- snode_dag_update(C, snode);
-
+ ED_node_tree_propagate_change(C, CTX_data_main(C), nullptr);
return OPERATOR_FINISHED;
}
@@ -554,9 +553,9 @@ static int node_group_separate_selected(
}
}
- ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ntree);
if (!make_copy) {
- ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ngroup);
}
return 1;
@@ -611,10 +610,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
/* switch to parent tree */
ED_node_tree_pop(snode);
- ntreeUpdateTree(CTX_data_main(C), snode->nodetree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), nullptr);
return OPERATOR_FINISHED;
}
@@ -982,9 +978,9 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
}
/* update of the group tree */
- ngroup->update |= NTREE_UPDATE | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ngroup);
/* update of the tree containing the group instance node */
- ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ntree);
}
static bNode *node_group_make_from_selected(const bContext *C,
@@ -1014,7 +1010,7 @@ static bNode *node_group_make_from_selected(const bContext *C,
node_group_make_insert_selected(C, ntree, gnode);
/* update of the tree containing the group instance node */
- ntree->update |= NTREE_UPDATE_NODES;
+ BKE_node_tree_update_tag(ntree);
return gnode;
}
@@ -1044,14 +1040,10 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
sort_multi_input_socket_links(snode, node, nullptr, nullptr);
}
- ntreeUpdateTree(bmain, ngroup);
}
}
- ntreeUpdateTree(bmain, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, nullptr);
/* We broke relations in node tree, need to rebuild them in the graphs. */
DEG_relations_tag_update(bmain);
@@ -1104,12 +1096,7 @@ static int node_group_insert_exec(bContext *C, wmOperator *op)
nodeSetActive(ntree, gnode);
ED_node_tree_push(snode, ngroup, gnode);
- ntreeUpdateTree(bmain, ngroup);
-
- ntreeUpdateTree(bmain, ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, bmain, nullptr);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc
index ab20eaf131f..623615f112d 100644
--- a/source/blender/editors/space_node/node_relationships.cc
+++ b/source/blender/editors/space_node/node_relationships.cc
@@ -36,6 +36,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_screen.h"
#include "ED_node.h" /* own include */
@@ -604,7 +605,7 @@ static void snode_autoconnect(Main *bmain,
}
if (numlinks > 0) {
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, nullptr);
}
BLI_freelistN(nodelist);
@@ -851,7 +852,7 @@ static int link_socket_to_viewer(const bContext *C,
else {
link_to_change->fromnode = bnode_to_view;
link_to_change->fromsock = bsocket_to_view;
- btree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link(btree);
}
remove_links_to_unavailable_viewer_sockets(*btree, *viewer_bnode);
@@ -860,7 +861,7 @@ static int link_socket_to_viewer(const bContext *C,
ED_spreadsheet_context_paths_set_geometry_node(CTX_data_main(C), snode, viewer_bnode);
}
- ntreeUpdateTree(CTX_data_main(C), btree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(C), btree, nullptr);
snode_update(snode, viewer_bnode);
DEG_id_tag_update(&btree->id, 0);
@@ -908,7 +909,7 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- snode_notify(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1037,8 +1038,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
/* add link to the node tree */
BLI_addtail(&ntree->links, link);
-
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link(ntree);
/* tag tonode for update */
link->tonode->update |= NODE_UPDATE;
@@ -1058,11 +1058,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
}
ntree->is_updating = false;
- ntreeUpdateTree(bmain, ntree);
- snode_notify(C, snode);
- if (do_tag_update) {
- snode_dag_update(C, snode);
- }
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
if (reset_view) {
UI_view2d_edge_pan_cancel(C, &nldrag->pan_data);
@@ -1425,9 +1421,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op)
node_deselect_all_input_sockets(snode, false);
node_deselect_all_output_sockets(snode, false);
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
- snode_notify(C, snode);
- snode_dag_update(C, snode);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1530,12 +1524,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
}
if (found) {
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
- snode_notify(C, snode);
- if (do_tag_update) {
- snode_dag_update(C, snode);
- }
-
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1639,12 +1628,7 @@ static int mute_links_exec(bContext *C, wmOperator *op)
link->flag &= ~NODE_LINK_TEST;
}
- ntreeUpdateTree(CTX_data_main(C), snode->edittree);
- snode_notify(C, snode);
- if (do_tag_update) {
- snode_dag_update(C, snode);
- }
-
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
return OPERATOR_FINISHED;
}
@@ -1695,11 +1679,7 @@ static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- ntreeUpdateTree(CTX_data_main(C), ntree);
-
- snode_notify(C, snode);
- snode_dag_update(C, snode);
-
+ ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
return OPERATOR_FINISHED;
}
@@ -2616,7 +2596,7 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
snode->runtime->iofsd = iofsd;
}
- ntreeUpdateTree(bmain, snode->edittree); /* needed for pointers */
+ BKE_node_tree_update_main_rooted(bmain, snode->edittree, nullptr); /* needed for pointers */
snode_update(snode, select);
ED_node_tag_update_id((ID *)snode->edittree);
ED_node_tag_update_id(snode->id);
diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc
index b2a7c1753fb..a060bbefa5c 100644
--- a/source/blender/editors/space_node/node_templates.cc
+++ b/source/blender/editors/space_node/node_templates.cc
@@ -37,6 +37,7 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_node_tree_update.h"
#include "RNA_access.h"
@@ -84,7 +85,7 @@ static void node_link_item_apply(Main *bmain, bNode *node, NodeLinkItem *item)
{
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
node->id = (ID *)item->ngroup;
- ntreeUpdateTree(bmain, item->ngroup);
+ BKE_node_tree_update_main_rooted(bmain, item->ngroup, nullptr);
}
else {
/* nothing to do for now */
@@ -180,9 +181,7 @@ static void node_socket_disconnect(Main *bmain,
sock_to->flag |= SOCK_COLLAPSED;
nodeUpdate(ntree, node_to);
- ntreeUpdateTree(bmain, ntree);
-
- ED_node_tag_update_nodetree(bmain, ntree, node_to);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
/* remove all nodes connected to this socket, if they aren't connected to other nodes */
@@ -196,9 +195,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN
sock_to->flag |= SOCK_COLLAPSED;
nodeUpdate(ntree, node_to);
- ntreeUpdateTree(bmain, ntree);
-
- ED_node_tag_update_nodetree(bmain, ntree, node_to);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
/* add new node connected to this socket, or replace an existing one */
@@ -301,9 +298,7 @@ static void node_socket_add_replace(const bContext *C,
nodeUpdate(ntree, node_from);
nodeUpdate(ntree, node_to);
- ntreeUpdateTree(CTX_data_main(C), ntree);
-
- ED_node_tag_update_nodetree(CTX_data_main(C), ntree, node_to);
+ ED_node_tree_propagate_change(nullptr, bmain, ntree);
}
/****************************** Node Link Menu *******************************/
diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.c
index da11666d445..cf9a2b9e5c7 100644
--- a/source/blender/editors/transform/transform_convert_node.c
+++ b/source/blender/editors/transform/transform_convert_node.c
@@ -31,6 +31,7 @@
#include "BKE_context.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "ED_node.h"
@@ -246,7 +247,7 @@ void special_aftertrans_update__node(bContext *C, TransInfo *t)
nodeRemoveNode(bmain, ntree, node, true);
}
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
}
}
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index acdffd5ff98..9fb2ae926ea 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -180,7 +180,7 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i
if (node && is_image_texture_node(node)) {
node->id = &ima->id;
- ED_node_tag_update_nodetree(bmain, ma->nodetree, node);
+ ED_node_tree_propagate_change(NULL, bmain, ma->nodetree);
}
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 0a82c237256..c56a68a39f5 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -48,6 +48,7 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -415,7 +416,7 @@ Material *BlenderStrokeRenderer::GetStrokeShader(Main *bmain,
}
nodeSetActive(ntree, output_material);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
return ma;
}
diff --git a/source/blender/io/collada/Materials.cpp b/source/blender/io/collada/Materials.cpp
index 81f0cc608d2..224289a8fe0 100644
--- a/source/blender/io/collada/Materials.cpp
+++ b/source/blender/io/collada/Materials.cpp
@@ -16,6 +16,8 @@
#include "Materials.h"
+#include "BKE_node_tree_update.h"
+
MaterialNode::MaterialNode(bContext *C, Material *ma, KeyImageMap &key_image_map)
: mContext(C), material(ma), effect(nullptr), key_image_map(&key_image_map)
{
@@ -107,7 +109,7 @@ bNodeTree *MaterialNode::prepare_material_nodetree()
void MaterialNode::update_material_nodetree()
{
- ntreeUpdateTree(CTX_data_main(mContext), ntree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(mContext), ntree, NULL);
}
bNode *MaterialNode::add_node(int node_type, int locx, int locy, std::string label)
diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc
index 317dfd2a62b..ac8b00e5755 100644
--- a/source/blender/io/usd/intern/usd_reader_material.cc
+++ b/source/blender/io/usd/intern/usd_reader_material.cc
@@ -23,6 +23,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BLI_math_vector.h"
#include "BLI_string.h"
@@ -340,7 +341,7 @@ void USDMaterialReader::import_usd_preview(Material *mtl,
nodeSetActive(ntree, output);
- ntreeUpdateTree(bmain_, ntree);
+ BKE_node_tree_update_main_rooted(bmain_, ntree, nullptr);
/* Optionally, set the material blend mode. */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 59cf4da26f6..3db38a08622 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -172,6 +172,9 @@ typedef struct bNodeSocket {
* data. It has to be updated when the node declaration changes.
*/
const SocketDeclarationHandle *declaration;
+
+ uint8_t changed_flag;
+ char _pad[7];
} bNodeSocket;
/* sock->type */
@@ -261,7 +264,7 @@ typedef struct bNode {
/** Used as a boolean for execution. */
uint8_t need_exec;
- char _pad[1];
+ uint8_t changed_flag;
/** Custom user-defined color. */
float color[3];
@@ -551,7 +554,8 @@ typedef struct bNodeTree {
* in case multiple different editors are used and make context ambiguous.
*/
bNodeInstanceKey active_viewer_key;
- char _pad[4];
+ char _pad[3];
+ uint8_t changed_flag;
/** Execution data.
*
@@ -576,6 +580,31 @@ typedef struct bNodeTree {
struct PreviewImage *preview;
} bNodeTree;
+/** bNodeSocket->changed_flag */
+typedef enum eNodeSocketChangedFlag {
+ SOCK_CHANGED_NONE = 0,
+ SOCK_CHANGED_ANY = (1 << 0),
+} eNodeSocketChangedFlag;
+
+/** bNode->changed_flag */
+typedef enum eNodeChangedFlag {
+ NODE_CHANGED_NONE = 0,
+ NODE_CHANGED_ANY = (1 << 0),
+} eNodeChangedFlag;
+
+/** bNodeTree->changed_flag */
+typedef enum eNodeTreeChangedFlag {
+ NTREE_CHANGED_NONE = 0,
+ NTREE_CHANGED_ANY = (1 << 0),
+ NTREE_CHANGED_SOCKET = (1 << 1),
+ NTREE_CHANGED_NODE = (1 << 2),
+ NTREE_CHANGED_LINK = (1 << 3),
+ NTREE_CHANGED_REMOVED_ANY = (1 << 4),
+ NTREE_CHANGED_MISSING_RUNTIME_DATA = (1 << 5),
+ NTREE_CHANGED_INTERFACE = (1 << 6),
+ NTREE_CHANGED_ALL = -1,
+} eNodeTreeChangedFlag;
+
/* ntree->type, index */
#define NTREE_UNDEFINED -2 /* Represents #NodeTreeTypeUndefined type. */
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 5c12fc3a227..091b457cc83 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -321,7 +321,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
CMP_NODE_VALTORGB,
TEX_NODE_VALTORGB,
GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP)) {
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
}
break;
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 2f42e521b52..0d86572357f 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -168,7 +168,7 @@ static void rna_ImageUser_update(Main *bmain, Scene *scene, PointerRNA *ptr)
if (id) {
if (GS(id->name) == ID_NT) {
/* Special update for nodetrees to find parent datablock. */
- ED_node_tag_update_nodetree(bmain, (bNodeTree *)id, NULL);
+ ED_node_tree_propagate_change(NULL, bmain, NULL);
}
else {
/* Update material or texture for render preview. */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index aef3823338b..5e62020537e 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -41,6 +41,7 @@
#include "BKE_cryptomatte.h"
#include "BKE_image.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_texture.h"
#include "RNA_access.h"
@@ -1186,7 +1187,7 @@ static void rna_NodeTree_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *p
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
- ED_node_tag_update_nodetree(bmain, ntree, NULL);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
@@ -1235,7 +1236,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
ntreeTexCheckCyclics(ntree);
}
- ntreeUpdateTree(CTX_data_main(C), ntree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(C), ntree, NULL);
nodeUpdate(ntree, node);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
@@ -1262,7 +1263,7 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree,
RNA_POINTER_INVALIDATE(node_ptr);
- ntreeUpdateTree(bmain, ntree); /* update group node socket links */
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL); /* update group node socket links */
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1282,7 +1283,7 @@ static void rna_NodeTree_node_clear(bNodeTree *ntree, Main *bmain, ReportList *r
node = next_node;
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1366,9 +1367,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
nodeUpdate(ntree, tonode);
}
- ntreeUpdateTree(bmain, ntree);
-
- ED_node_tag_update_nodetree(bmain, ntree, ret->tonode);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
return ret;
@@ -1393,7 +1392,7 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree,
nodeRemLink(ntree, link);
RNA_POINTER_INVALIDATE(link_ptr);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1412,7 +1411,7 @@ static void rna_NodeTree_link_clear(bNodeTree *ntree, Main *bmain, ReportList *r
link = next_link;
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1470,7 +1469,7 @@ static bNodeSocket *rna_NodeTree_inputs_new(
bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
return sock;
@@ -1485,7 +1484,7 @@ static bNodeSocket *rna_NodeTree_outputs_new(
bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
return sock;
@@ -1506,7 +1505,7 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree,
else {
ntreeRemoveSocketInterface(ntree, sock);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
DEG_id_tag_update(&ntree->id, 0);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1522,7 +1521,7 @@ static void rna_NodeTree_inputs_clear(bNodeTree *ntree, Main *bmain, ReportList
ntreeRemoveSocketInterface(ntree, socket);
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1536,7 +1535,7 @@ static void rna_NodeTree_outputs_clear(bNodeTree *ntree, Main *bmain, ReportList
ntreeRemoveSocketInterface(ntree, socket);
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1565,9 +1564,9 @@ static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_ind
}
}
- ntree->update |= NTREE_UPDATE_GROUP_IN;
+ BKE_node_tree_update_tag_interface(ntree);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1596,9 +1595,9 @@ static void rna_NodeTree_outputs_move(bNodeTree *ntree, Main *bmain, int from_in
}
}
- ntree->update |= NTREE_UPDATE_GROUP_OUT;
+ BKE_node_tree_update_tag_interface(ntree);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1606,10 +1605,8 @@ static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C)
{
Main *bmain = CTX_data_main(C);
- ntree->update |= NTREE_UPDATE_GROUP;
- ntreeUpdateTree(bmain, ntree);
-
- ED_node_tag_update_nodetree(bmain, ntree, NULL);
+ BKE_node_tree_update_tag_interface(ntree);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
/* ******** NodeLink ******** */
@@ -2489,7 +2486,8 @@ static void rna_Node_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
bNode *node = (bNode *)ptr->data;
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ UNUSED_VARS(node);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
static void rna_Node_update_relations(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -2498,9 +2496,9 @@ static void rna_Node_update_relations(Main *bmain, Scene *scene, PointerRNA *ptr
DEG_relations_tag_update(bmain);
}
-static void rna_Node_socket_value_update(ID *id, bNode *node, bContext *C)
+static void rna_Node_socket_value_update(ID *id, bNode *UNUSED(node), bContext *C)
{
- ED_node_tag_update_nodetree(CTX_data_main(C), (bNodeTree *)id, node);
+ ED_node_tree_propagate_change(C, CTX_data_main(C), (bNodeTree *)id);
}
static void rna_Node_select_set(PointerRNA *ptr, bool value)
@@ -2554,7 +2552,7 @@ static bNodeSocket *rna_Node_inputs_new(ID *id,
BKE_report(reports, RPT_ERROR, "Unable to create socket");
}
else {
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2588,7 +2586,7 @@ static bNodeSocket *rna_Node_outputs_new(ID *id,
BKE_report(reports, RPT_ERROR, "Unable to create socket");
}
else {
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2606,7 +2604,7 @@ static void rna_Node_socket_remove(
else {
nodeRemoveSocket(ntree, node, sock);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
}
@@ -2621,7 +2619,7 @@ static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain)
nodeRemoveSocket(ntree, node, sock);
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2635,7 +2633,7 @@ static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain)
nodeRemoveSocket(ntree, node, sock);
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2667,7 +2665,7 @@ static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_inde
}
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2699,7 +2697,7 @@ static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_ind
}
}
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2928,9 +2926,8 @@ static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
bNodeSocket *sock = (bNodeSocket *)ptr->data;
bNode *node;
- if (nodeFindNode(ntree, sock, &node, NULL)) {
- ED_node_tag_update_nodetree(bmain, ntree, node);
- }
+ UNUSED_VARS(sock, node);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
static bool rna_NodeSocket_is_output_get(PointerRNA *ptr)
@@ -3220,10 +3217,8 @@ static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), Po
return;
}
- ntree->update |= NTREE_UPDATE_GROUP;
- ntreeUpdateTree(bmain, ntree);
-
- ED_node_tag_update_nodetree(bmain, ntree, NULL);
+ BKE_node_tree_update_tag_interface(ntree);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
/* ******** Standard Node Socket Base Types ******** */
@@ -3342,7 +3337,7 @@ static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C,
rna_NodeSocketStandard_value_update(C, ptr);
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
Main *bmain = CTX_data_main(C);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
DEG_relations_tag_update(bmain);
}
@@ -3589,21 +3584,17 @@ static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), Pointer
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
bNode *node = (bNode *)ptr->data;
+ UNUSED_VARS(node);
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
WM_main_add_notifier(NC_IMAGE, NULL);
}
static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
- bNode *node = (bNode *)ptr->data;
-
- if (node->id) {
- ntreeUpdateTree(bmain, (bNodeTree *)node->id);
- }
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
DEG_relations_tag_update(bmain);
}
@@ -4264,7 +4255,7 @@ static bNodeSocket *rna_NodeOutputFile_slots_new(
sock = ntreeCompositOutputFileAddSocket(ntree, node, name, im_format);
- ntreeUpdateTree(CTX_data_main(C), ntree);
+ BKE_node_tree_update_main_rooted(CTX_data_main(C), ntree, NULL);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
return sock;
@@ -4373,7 +4364,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
RE_engine_free(engine);
}
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
static void rna_ShaderNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 5a74cfa9964..f66fb2653b5 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -199,7 +199,7 @@ static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *pt
}
else if (GS(id->name) == ID_NT) {
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
- ED_node_tag_update_nodetree(bmain, ntree, NULL);
+ ED_node_tree_propagate_change(NULL, bmain, ntree);
}
}
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 70f6020f5a9..fb9dbc0ad0a 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -60,6 +60,7 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_node_tree_update.h"
#include "BKE_object.h"
#include "BKE_pointcloud.h"
#include "BKE_screen.h"
@@ -695,7 +696,7 @@ void MOD_nodes_init(Main *bmain, NodesModifierData *nmd)
group_input_node,
(bNodeSocket *)group_input_node->outputs.first);
- ntreeUpdateTree(bmain, ntree);
+ BKE_node_tree_update_main_rooted(bmain, ntree, nullptr);
}
static void initialize_group_input(NodesModifierData &nmd,
diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc
index e5ec50858d9..ac9cbc158c8 100644
--- a/source/blender/nodes/intern/node_common.cc
+++ b/source/blender/nodes/intern/node_common.cc
@@ -37,6 +37,7 @@
#include "BLT_translation.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "RNA_types.h"
@@ -145,7 +146,7 @@ static bNodeSocket *group_verify_socket(bNodeTree *ntree,
if (sock->typeinfo != iosock->typeinfo) {
nodeModifySocketType(ntree, gnode, sock, iosock->idname);
/* Flag the tree to make sure link validity is updated after type changes. */
- ntree->update |= NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag_link(ntree);
}
if (iosock->typeinfo->interface_verify_socket) {
diff --git a/source/blender/nodes/intern/node_exec.cc b/source/blender/nodes/intern/node_exec.cc
index 18403417af3..d7d97c9025b 100644
--- a/source/blender/nodes/intern/node_exec.cc
+++ b/source/blender/nodes/intern/node_exec.cc
@@ -28,6 +28,7 @@
#include "BKE_global.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "MEM_guardedalloc.h"
@@ -172,7 +173,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context,
/* Using global main here is likely totally wrong, not sure what to do about that one though...
* We cannot even check ntree is in global main,
* since most of the time it won't be (thanks to ntree design)!!! */
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, nullptr);
/* get a dependency-sorted list of nodes */
ntreeGetDependencyList(ntree, &nodelist, &totnodes);
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 83ee0c2f411..f9ac0b4f03d 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -44,6 +44,7 @@
#include "BKE_lib_id.h"
#include "BKE_linestyle.h"
#include "BKE_node.h"
+#include "BKE_node_tree_update.h"
#include "BKE_scene.h"
#include "RNA_access.h"
@@ -375,7 +376,7 @@ static void ntree_shader_unlink_hidden_value_sockets(bNode *group_node, bNodeSoc
}
if (removed_link) {
- ntreeUpdateTree(G.main, group_ntree);
+ BKE_node_tree_update_main_rooted(G.main, group_ntree, NULL);
}
}
@@ -434,7 +435,7 @@ static void ntree_shader_groups_expand_inputs(bNodeTree *localtree)
}
if (link_added) {
- ntreeUpdateTree(G.main, localtree);
+ BKE_node_tree_update_main_rooted(G.main, localtree, NULL);
}
}
@@ -514,7 +515,7 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
ntreeFreeLocalNode(ntree, node);
}
- ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ BKE_node_tree_update_tag(ntree);
}
/* Flatten group to only have a simple single tree */
@@ -539,7 +540,7 @@ static void ntree_shader_groups_flatten(bNodeTree *localtree)
}
}
- ntreeUpdateTree(G.main, localtree);
+ BKE_node_tree_update_main_rooted(G.main, localtree, NULL);
}
/* Check whether shader has a displacement.
@@ -559,7 +560,7 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
return false;
}
/* Make sure sockets links pointers are correct. */
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
bNodeSocket *displacement = ntree_shader_node_find_input(output_node, "Displacement");
if (displacement == NULL) {
@@ -648,7 +649,7 @@ static void ntree_shader_bypass_tagged_bump_nodes(bNodeTree *ntree)
ntree_shader_bypass_bump_link(ntree, node, link);
}
}
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
}
static bool ntree_branch_count_and_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
@@ -733,7 +734,7 @@ static void ntree_shader_copy_branch_displacement(bNodeTree *ntree,
nodeRemLink(ntree, displacement_link);
nodeAddLink(ntree, displacement_node, displacement_socket, tonode, tosock);
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
}
/* Re-link displacement output to unconnected normal sockets via bump node.
@@ -797,12 +798,12 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
geo_node->tmp_flag = -2;
bump_node->tmp_flag = -2;
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
/* Connect all free-standing Normal inputs and relink geometry/coordinate nodes. */
ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
/* We modified the tree, it needs to be updated now. */
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
}
static void node_tag_branch_as_derivative(bNode *node, int dx)
@@ -882,7 +883,7 @@ void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tag
return;
}
/* Make sure sockets links pointers are correct. */
- ntreeUpdateTree(G.main, ntree);
+ BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
nodeChainIterBackwards(ntree, output_node, ntree_tag_bsdf_cb, tags, 0);
}