From ef26519880d0910fa96891bdb32c6bff8606f138 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Jun 2023 10:37:18 +0200 Subject: [PATCH] Nodes: add utilities to access all node links and toposort index --- source/blender/blenkernel/BKE_node_runtime.hh | 17 +++++++++++++++++ .../blender/blenkernel/intern/node_runtime.cc | 8 ++++++++ .../blenkernel/intern/node_tree_dot_export.cc | 2 +- source/blender/editors/space_node/node_draw.cc | 4 ++-- source/blender/makesdna/DNA_node_types.h | 3 +++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 049061a14aa..122a5ac819b 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -291,6 +291,9 @@ class bNodeRuntime : NonCopyable, NonMovable { bool has_available_linked_outputs = false; Vector direct_children_in_frame; bNodeTree *owner_tree = nullptr; + /** Can be used to toposort a subset of nodes. */ + int toposort_left_to_right_index = -1; + int toposort_right_to_left_index = -1; }; namespace node_tree_runtime { @@ -515,6 +518,18 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } +inline blender::Span bNodeTree::all_links() +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + return this->runtime->links; +} + +inline blender::Span bNodeTree::all_links() const +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + return this->runtime->links; +} + inline blender::Span bNodeTree::panels() const { return blender::Span(panels_array, panels_num); @@ -525,6 +540,8 @@ inline blender::MutableSpan bNodeTree::panels_for_write() return blender::MutableSpan(panels_array, panels_num); } +/** \} */ + /* -------------------------------------------------------------------- */ /** \name #bNode Inline Methods * \{ */ diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc index 575500cbe2d..94825c17dd9 100644 --- a/source/blender/blenkernel/intern/node_runtime.cc +++ b/source/blender/blenkernel/intern/node_runtime.cc @@ -506,11 +506,19 @@ static void ensure_topology_cache(const bNodeTree &ntree) ToposortDirection::LeftToRight, tree_runtime.toposort_left_to_right, tree_runtime.has_available_link_cycle); + for (const int i : tree_runtime.toposort_left_to_right.index_range()) { + const bNode &node = *tree_runtime.toposort_left_to_right[i]; + node.runtime->toposort_left_to_right_index = i; + } }, [&]() { bool dummy; update_toposort( ntree, ToposortDirection::RightToLeft, tree_runtime.toposort_right_to_left, dummy); + for (const int i : tree_runtime.toposort_right_to_left.index_range()) { + const bNode &node = *tree_runtime.toposort_right_to_left[i]; + node.runtime->toposort_right_to_left_index = i; + } }, [&]() { update_root_frames(ntree); }, [&]() { update_direct_frames_childrens(ntree); }); diff --git a/source/blender/blenkernel/intern/node_tree_dot_export.cc b/source/blender/blenkernel/intern/node_tree_dot_export.cc index a65cc8b9756..673533d115a 100644 --- a/source/blender/blenkernel/intern/node_tree_dot_export.cc +++ b/source/blender/blenkernel/intern/node_tree_dot_export.cc @@ -57,7 +57,7 @@ std::string node_tree_to_dot(const bNodeTree &tree, const bNodeTreeToDotOptions dot_nodes.add_new(node, dot::NodeWithSocketsRef(dot_node, dot_node_with_sockets)); } - LISTBASE_FOREACH (const bNodeLink *, link, &tree.links) { + for (const bNodeLink *link : tree.all_links()) { const dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(link->fromnode); const dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(link->tonode); const dot::NodePort from_dot_port = from_dot_node.output(link->fromsock->index()); diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 654ec2cc5f6..eadfd9f34ea 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -3246,14 +3246,14 @@ static void node_draw_nodetree(const bContext &C, GPU_blend(GPU_BLEND_ALPHA); nodelink_batch_start(snode); - LISTBASE_FOREACH (const bNodeLink *, link, &ntree.links) { + for (const bNodeLink *link : ntree.all_links()) { if (!nodeLinkIsHidden(link) && !bke::nodeLinkIsSelected(link)) { node_draw_link(C, region.v2d, snode, *link, false); } } /* Draw selected node links after the unselected ones, so they are shown on top. */ - LISTBASE_FOREACH (const bNodeLink *, link, &ntree.links) { + for (const bNodeLink *link : ntree.all_links()) { if (!nodeLinkIsHidden(link) && bke::nodeLinkIsSelected(link)) { node_draw_link(C, region.v2d, snode, *link, true); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 73bb93a5a5e..b5166042f73 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -646,6 +646,9 @@ typedef struct bNodeTree { blender::Span nodes_by_type(blender::StringRefNull type_idname) const; /** Frame nodes without any parents. */ blender::Span root_frames() const; + /** A span containing all links in the node tree. */ + blender::Span all_links(); + blender::Span all_links() const; /** * Cached toposort of all nodes. If there are cycles, the returned array is not actually a * toposort. However, if a connected component does not contain a cycle, this component is sorted