[Bf-blender-cvs] [d77d9e8f6e1] node-tree-update-refactor: progres
Jacques Lucke
noreply at git.blender.org
Mon Nov 15 19:09:22 CET 2021
Commit: d77d9e8f6e14af2c6181eaa2faad61e811d17871
Author: Jacques Lucke
Date: Mon Nov 15 16:47:12 2021 +0100
Branches: node-tree-update-refactor
https://developer.blender.org/rBd77d9e8f6e14af2c6181eaa2faad61e811d17871
progres
===================================================================
M source/blender/blenkernel/intern/node_tree_update.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index 0ed21a847fc..ac81b239976 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -24,8 +24,11 @@
#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 *>;
@@ -36,7 +39,7 @@ struct NodeTreeRelations {
std::optional<MultiValueMap<bNodeTree *, ObjectModifierPair>> modifiers_users_;
public:
- NodeTreeRelations(Main &bmain) : bmain_(&bmain)
+ NodeTreeRelations(Main *bmain) : bmain_(bmain)
{
}
@@ -47,6 +50,11 @@ struct NodeTreeRelations {
}
group_node_users_.emplace();
+
+ if (bmain_ == nullptr) {
+ return;
+ }
+
FOREACH_NODETREE_BEGIN (bmain_, ntree, id) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->id == nullptr) {
@@ -69,6 +77,11 @@ struct NodeTreeRelations {
}
modifiers_users_.emplace();
+
+ if (bmain_ == nullptr) {
+ return;
+ }
+
LISTBASE_FOREACH (Object *, object, &bmain_->objects) {
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Nodes) {
@@ -80,41 +93,155 @@ struct NodeTreeRelations {
}
}
}
+
+ 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_);
+ return group_node_users_->lookup(ntree);
+ }
+};
+
+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)
+ : bmain_(bmain), params_(params), relations_(bmain)
{
}
void update()
{
+ Vector<bNodeTree *> changed_ntrees;
FOREACH_NODETREE_BEGIN (bmain_, ntree, id) {
- ntreeUpdateTree(bmain_, ntree);
+ 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);
+ }
+ }
+ }
+ }
+
+ Vector<bNodeTree *> trees_with_visible_changes;
+ for (bNodeTree *ntree : root_ntrees) {
+ const TreeUpdateResult result = this->update_tree(*ntree);
+ update_result_by_tree_.add_new(ntree, result);
+
+ if (result.output_changed || result.interface_changed) {
+ trees_with_visible_changes.append(ntree);
+ relations_.ensure_group_node_users();
+ if (ntree->type == NTREE_GEOMETRY) {
+ relations_.ensure_modifier_users();
+ }
+ }
+ }
+
+ if (!trees_with_visible_changes.is_empty()) {
+ relations_.ensure_group_node_users();
+ }
+
+ 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) {
+ 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) {
+ if (params_->tree_output_changed_fn && result.output_changed) {
params_->tree_output_changed_fn(id, ntree, params_->user_data);
}
}
}
- FOREACH_NODETREE_END;
}
- void update_rooted(Span<bNodeTree *> root_trees)
+ private:
+ Vector<bNodeTree *> get_tree_update_order(Span<bNodeTree *> root_ntrees)
+ {
+ relations_.ensure_group_node_users();
+ return {};
+ }
+
+ TreeUpdateResult update_tree(bNodeTree &ntree)
{
- this->update();
+ ntreeUpdateTree(bmain_, &ntree);
+ TreeUpdateResult result;
+ result.interface_changed = true;
+ result.output_changed = true;
+ return result;
}
};
@@ -184,16 +311,35 @@ void BKE_node_tree_update_tag_interface(bNodeTree *ntree)
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});
+ updater.update_rooted({{(ID *)ntree, ntree}});
+ is_updating = false;
}
More information about the Bf-blender-cvs
mailing list