diff options
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, ¶ms); +} + 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); } |