[Bf-blender-cvs] [0ff3f96a1b0] master: Nodes: make derived link data more obvious in NodeTreeRef

Jacques Lucke noreply at git.blender.org
Wed Mar 17 16:46:28 CET 2021


Commit: 0ff3f96a1b0193d69dae5ca69e7c93d6cdf34558
Author: Jacques Lucke
Date:   Wed Mar 17 16:43:06 2021 +0100
Branches: master
https://developer.blender.org/rB0ff3f96a1b0193d69dae5ca69e7c93d6cdf34558

Nodes: make derived link data more obvious in NodeTreeRef

`NodeTreeRef` is a thin wrapper on top of `bNodeTree`. By default it
should not hide anything from the underlying `bNodeTree` (before this
it was hiding muted links).

For convenience some "derived" data is cached on sockets. For example
all the connected sockets when reroutes and muted links are ignored.

A nice side benefit of this refactor is that `NodeTreeRef` requires
less memory than before.

===================================================================

M	source/blender/nodes/NOD_node_tree_ref.hh
M	source/blender/nodes/intern/node_tree_ref.cc

===================================================================

diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index ec0444852c8..6b8eb21bf9a 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -45,6 +45,7 @@
  */
 
 #include "BLI_array.hh"
+#include "BLI_function_ref.hh"
 #include "BLI_linear_allocator.hh"
 #include "BLI_map.hh"
 #include "BLI_multi_value_map.hh"
@@ -77,9 +78,10 @@ class SocketRef : NonCopyable, NonMovable {
   int id_;
   int index_;
   PointerRNA rna_;
-  Vector<SocketRef *> linked_sockets_;
-  Vector<SocketRef *> directly_linked_sockets_;
   Vector<LinkRef *> directly_linked_links_;
+  /* This is derived data that is cached for easy and fast access. */
+  MutableSpan<SocketRef *> directly_linked_sockets_;
+  MutableSpan<SocketRef *> linked_sockets_without_reroutes_and_muted_links_;
 
   friend NodeTreeRef;
 
@@ -182,6 +184,8 @@ class LinkRef : NonCopyable, NonMovable {
   const InputSocketRef &to() const;
 
   bNodeLink *blink() const;
+
+  bool is_muted() const;
 };
 
 class InternalLinkRef : NonCopyable, NonMovable {
@@ -238,7 +242,12 @@ class NodeTreeRef : NonCopyable, NonMovable {
   OutputSocketRef &find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
                                       bNode *bnode,
                                       bNodeSocket *bsocket);
-  void find_origins_skipping_reroutes(InputSocketRef &socket, Vector<SocketRef *> &r_origins);
+
+  void create_linked_socket_caches();
+  void foreach_origin_skipping_reroutes_and_muted_links(
+      InputSocketRef &socket, FunctionRef<void(OutputSocketRef &)> callback);
+  void foreach_target_skipping_reroutes_and_muted_links(
+      OutputSocketRef &socket, FunctionRef<void(InputSocketRef &)> callback);
 };
 
 using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
@@ -260,7 +269,7 @@ using nodes::SocketRef;
 
 inline Span<const SocketRef *> SocketRef::linked_sockets() const
 {
-  return linked_sockets_;
+  return linked_sockets_without_reroutes_and_muted_links_;
 }
 
 inline Span<const SocketRef *> SocketRef::directly_linked_sockets() const
@@ -275,7 +284,7 @@ inline Span<const LinkRef *> SocketRef::directly_linked_links() const
 
 inline bool SocketRef::is_linked() const
 {
-  return linked_sockets_.size() > 0;
+  return linked_sockets_without_reroutes_and_muted_links_.size() > 0;
 }
 
 inline const NodeRef &SocketRef::node() const
@@ -376,12 +385,13 @@ inline bool SocketRef::is_available() const
 
 inline Span<const OutputSocketRef *> InputSocketRef::linked_sockets() const
 {
-  return linked_sockets_.as_span().cast<const OutputSocketRef *>();
+  return linked_sockets_without_reroutes_and_muted_links_.as_span()
+      .cast<const OutputSocketRef *>();
 }
 
 inline Span<const OutputSocketRef *> InputSocketRef::directly_linked_sockets() const
 {
-  return directly_linked_sockets_.as_span().cast<const OutputSocketRef *>();
+  return directly_linked_sockets_.cast<const OutputSocketRef *>();
 }
 
 inline bool InputSocketRef::is_multi_input_socket() const
@@ -395,12 +405,12 @@ inline bool InputSocketRef::is_multi_input_socket() const
 
 inline Span<const InputSocketRef *> OutputSocketRef::linked_sockets() const
 {
-  return linked_sockets_.as_span().cast<const InputSocketRef *>();
+  return linked_sockets_without_reroutes_and_muted_links_.as_span().cast<const InputSocketRef *>();
 }
 
 inline Span<const InputSocketRef *> OutputSocketRef::directly_linked_sockets() const
 {
-  return directly_linked_sockets_.as_span().cast<const InputSocketRef *>();
+  return directly_linked_sockets_.cast<const InputSocketRef *>();
 }
 
 /* --------------------------------------------------------------------
@@ -516,6 +526,11 @@ inline bNodeLink *LinkRef::blink() const
   return blink_;
 }
 
+inline bool LinkRef::is_muted() const
+{
+  return blink_->flag & NODE_LINK_MUTED;
+}
+
 /* --------------------------------------------------------------------
  * InternalLinkRef inline methods.
  */
diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc
index 8d979ffac9c..4b326929dbb 100644
--- a/source/blender/nodes/intern/node_tree_ref.cc
+++ b/source/blender/nodes/intern/node_tree_ref.cc
@@ -77,9 +77,6 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
   }
 
   LISTBASE_FOREACH (bNodeLink *, blink, &btree->links) {
-    if (blink->flag & NODE_LINK_MUTED) {
-      continue;
-    }
     OutputSocketRef &from_socket = this->find_output_socket(
         node_mapping, blink->fromnode, blink->fromsock);
     InputSocketRef &to_socket = this->find_input_socket(
@@ -92,7 +89,6 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
 
     links_.append(&link);
 
-    from_socket.directly_linked_sockets_.append(&to_socket);
     from_socket.directly_linked_links_.append(&link);
     to_socket.directly_linked_links_.append(&link);
   }
@@ -109,20 +105,7 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
     }
   }
 
-  for (InputSocketRef *input_socket : input_sockets_) {
-    for (const LinkRef *link : input_socket->directly_linked_links()) {
-      input_socket->directly_linked_sockets_.append(link->from_);
-    }
-  }
-
-  for (InputSocketRef *socket : input_sockets_) {
-    if (!socket->node_->is_reroute_node()) {
-      this->find_origins_skipping_reroutes(*socket, socket->linked_sockets_);
-      for (SocketRef *origin : socket->linked_sockets_) {
-        origin->linked_sockets_.append(socket);
-      }
-    }
-  }
+  this->create_linked_socket_caches();
 
   for (NodeRef *node : nodes_by_id_) {
     const bNodeType *nodetype = node->bnode_->typeinfo;
@@ -176,15 +159,84 @@ OutputSocketRef &NodeTreeRef::find_output_socket(Map<bNode *, NodeRef *> &node_m
   return *node->outputs_[0];
 }
 
-void NodeTreeRef::find_origins_skipping_reroutes(InputSocketRef &socket,
-                                                 Vector<SocketRef *> &r_origins)
+void NodeTreeRef::create_linked_socket_caches()
 {
-  for (SocketRef *direct_origin : socket.directly_linked_sockets_) {
-    if (direct_origin->node_->is_reroute_node()) {
-      this->find_origins_skipping_reroutes(*direct_origin->node_->inputs_[0], r_origins);
+  for (InputSocketRef *socket : input_sockets_) {
+    /* Find directly linked socket based on incident links. */
+    Vector<SocketRef *> directly_linked_sockets;
+    for (LinkRef *link : socket->directly_linked_links_) {
+      directly_linked_sockets.append(link->from_);
+    }
+    socket->directly_linked_sockets_ = allocator_.construct_array_copy(
+        directly_linked_sockets.as_span());
+
+    /* Find linked sockets when skipping reroutes. */
+    Vector<SocketRef *> linked_sockets;
+    this->foreach_origin_skipping_reroutes_and_muted_links(
+        *socket, [&](OutputSocketRef &origin) { linked_sockets.append(&origin); });
+    if (linked_sockets == directly_linked_sockets) {
+      socket->linked_sockets_without_reroutes_and_muted_links_ = socket->directly_linked_sockets_;
+    }
+    else {
+      socket->linked_sockets_without_reroutes_and_muted_links_ = allocator_.construct_array_copy(
+          linked_sockets.as_span());
+    }
+  }
+
+  for (OutputSocketRef *socket : output_sockets_) {
+    /* Find directly linked socket based on incident links. */
+    Vector<SocketRef *> directly_linked_sockets;
+    for (LinkRef *link : socket->directly_linked_links_) {
+      directly_linked_sockets.append(link->to_);
+    }
+    socket->directly_linked_sockets_ = allocator_.construct_array_copy(
+        directly_linked_sockets.as_span());
+
+    /* Find linked sockets when skipping reroutes. */
+    Vector<SocketRef *> linked_sockets;
+    this->foreach_target_skipping_reroutes_and_muted_links(
+        *socket, [&](InputSocketRef &target) { linked_sockets.append(&target); });
+    if (linked_sockets == directly_linked_sockets) {
+      socket->linked_sockets_without_reroutes_and_muted_links_ = socket->directly_linked_sockets_;
+    }
+    else {
+      socket->linked_sockets_without_reroutes_and_muted_links_ = allocator_.construct_array_copy(
+          linked_sockets.as_span());
+    }
+  }
+}
+
+void NodeTreeRef::foreach_origin_skipping_reroutes_and_muted_links(
+    InputSocketRef &socket, FunctionRef<void(OutputSocketRef &)> callback)
+{
+  for (LinkRef *link : socket.directly_linked_links_) {
+    if (link->is_muted()) {
+      continue;
+    }
+    OutputSocketRef *origin = link->from_;
+    if (origin->node_->is_reroute_node()) {
+      this->foreach_origin_skipping_reroutes_and_muted_links(*origin->node_->inputs_[0], callback);
+    }
+    else {
+      callback(*(OutputSocketRef *)origin);
+    }
+  }
+}
+
+void NodeTreeRef::foreach_target_skipping_reroutes_and_muted_links(
+    OutputSocketRef &socket, FunctionRef<void(InputSocketRef &)> callback)
+{
+  for (LinkRef *link : socket.directly_linked_links_) {
+    if (link->is_muted()) {
+      continue;
+    }
+    InputSocketRef *target = link->to_;
+    if (target->node_->is_reroute_node()) {
+      this->foreach_target_skipping_reroutes_and_muted_links(*target->node_->outputs_[0],
+                                                             callback);
     }
     else {
-      r_origins.append(direct_origin);
+      callback(*(InputSocketRef *)target);
     }
   }
 }



More information about the Bf-blender-cvs mailing list