[Bf-blender-cvs] [9ed2a7e6802] spreadsheet-active-node: improved handling of skipped sockets

Jacques Lucke noreply at git.blender.org
Thu Apr 1 13:55:19 CEST 2021


Commit: 9ed2a7e68023091e1f1eb8448d0aa16cf749f2c1
Author: Jacques Lucke
Date:   Thu Apr 1 11:22:06 2021 +0200
Branches: spreadsheet-active-node
https://developer.blender.org/rB9ed2a7e68023091e1f1eb8448d0aa16cf749f2c1

improved handling of skipped sockets

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

M	source/blender/blenlib/BLI_function_ref.hh
M	source/blender/blenlib/BLI_linear_allocator.hh
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/NOD_derived_node_tree.hh
M	source/blender/nodes/NOD_node_tree_ref.hh
M	source/blender/nodes/intern/derived_node_tree.cc
M	source/blender/nodes/intern/node_tree_ref.cc

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

diff --git a/source/blender/blenlib/BLI_function_ref.hh b/source/blender/blenlib/BLI_function_ref.hh
index 57fffdc09b4..07a20a08e13 100644
--- a/source/blender/blenlib/BLI_function_ref.hh
+++ b/source/blender/blenlib/BLI_function_ref.hh
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <optional>
 #include <type_traits>
 #include <utility>
 
@@ -139,6 +140,23 @@ template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> {
     return callback_(callable_, std::forward<Params>(params)...);
   }
 
+  using OptionalReturnValue = std::conditional_t<std::is_void_v<Ret>, void, std::optional<Ret>>;
+  OptionalReturnValue call_if_available(Params... params) const
+  {
+    if constexpr (std::is_void_v<Ret>) {
+      if (callback_ == nullptr) {
+        return;
+      }
+      callback_(callable_, std::forward<Params>(params)...);
+    }
+    else {
+      if (callback_ == nullptr) {
+        return {};
+      }
+      return callback_(callable_, std::forward<Params>(params)...);
+    }
+  }
+
   /**
    * Returns true, when the `FunctionRef` references a function currently.
    * If this returns false, the `FunctionRef` must not be called.
diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index 47705b1d40b..6aa97d5c5e7 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -133,6 +133,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
    */
   template<typename T> MutableSpan<T> construct_array_copy(Span<T> src)
   {
+    if (src.is_empty()) {
+      return {};
+    }
     MutableSpan<T> dst = this->allocate_array<T>(src.size());
     uninitialized_copy_n(src.data(), src.size(), dst.data());
     return dst;
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 63bd969a18d..4954ec400a0 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -624,8 +624,15 @@ class GeometryNodesEvaluator {
   {
     /* For all sockets that are linked with the from_socket push the value to their node. */
     Vector<DInputSocket> to_sockets_all;
-    from_socket.foreach_target_socket(
-        [&](DInputSocket to_socket) { to_sockets_all.append_non_duplicates(to_socket); });
+
+    auto handle_target_socket_fn = [&](DInputSocket to_socket) {
+      to_sockets_all.append_non_duplicates(to_socket);
+    };
+    auto handle_skipped_socket_fn = [&, this](DSocket socket) {
+      this->handle_socket_value(socket, value_to_forward);
+    };
+
+    from_socket.foreach_target_socket(handle_target_socket_fn, handle_skipped_socket_fn);
 
     const CPPType &from_type = *value_to_forward.type();
     Vector<DInputSocket> to_sockets_same_type;
diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh
index 738b94cde03..9999a4543c0 100644
--- a/source/blender/nodes/NOD_derived_node_tree.hh
+++ b/source/blender/nodes/NOD_derived_node_tree.hh
@@ -150,7 +150,8 @@ class DOutputSocket : public DSocket {
   DInputSocket get_corresponding_group_node_input() const;
   DInputSocket get_active_corresponding_group_output_socket() const;
 
-  void foreach_target_socket(FunctionRef<void(DInputSocket)> callback) const;
+  void foreach_target_socket(FunctionRef<void(DInputSocket)> callback,
+                             FunctionRef<void(DSocket)> skipped_callback) const;
 };
 
 class DerivedNodeTree {
diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index 465336f5250..6dc0457a812 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -85,11 +85,13 @@ class SocketRef : NonCopyable, NonMovable {
   /* These sockets are linked when reroutes, muted links and muted nodes have been taken into
    * account. */
   MutableSpan<const SocketRef *> logically_linked_sockets_;
+  MutableSpan<const SocketRef *> logically_linked_skipped_sockets_;
 
   friend NodeTreeRef;
 
  public:
   Span<const SocketRef *> logically_linked_sockets() const;
+  Span<const SocketRef *> logically_linked_skipped_sockets() const;
   Span<const SocketRef *> directly_linked_sockets() const;
   Span<const LinkRef *> directly_linked_links() const;
 
@@ -133,8 +135,7 @@ class InputSocketRef final : public SocketRef {
 
   bool is_multi_input_socket() const;
 
-  void foreach_logical_origin(const InputSocketRef &socket,
-                              FunctionRef<void(const OutputSocketRef &)> callback,
+  void foreach_logical_origin(FunctionRef<void(const OutputSocketRef &)> callback,
                               bool only_follow_first_input_link = false) const;
 };
 
@@ -143,8 +144,8 @@ class OutputSocketRef final : public SocketRef {
   Span<const InputSocketRef *> logically_linked_sockets() const;
   Span<const InputSocketRef *> directly_linked_sockets() const;
 
-  void foreach_logical_target(const OutputSocketRef &socket,
-                              FunctionRef<void(const InputSocketRef &)> callback) const;
+  void foreach_logical_target(FunctionRef<void(const InputSocketRef &)> callback,
+                              FunctionRef<void(const SocketRef &)> skipped_callback) const;
 };
 
 class NodeRef : NonCopyable, NonMovable {
@@ -288,6 +289,11 @@ inline Span<const SocketRef *> SocketRef::logically_linked_sockets() const
   return logically_linked_sockets_;
 }
 
+inline Span<const SocketRef *> SocketRef::logically_linked_skipped_sockets() const
+{
+  return logically_linked_skipped_sockets_;
+}
+
 inline Span<const SocketRef *> SocketRef::directly_linked_sockets() const
 {
   return directly_linked_sockets_;
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc
index d83b9737693..b5e943fdb88 100644
--- a/source/blender/nodes/intern/derived_node_tree.cc
+++ b/source/blender/nodes/intern/derived_node_tree.cc
@@ -220,8 +220,12 @@ void DInputSocket::foreach_origin_socket(FunctionRef<void(DSocket)> callback) co
 /* Calls the given callback for every "real" target socket. "Real" means that reroutes, muted nodes
  * and node groups are handled by this function. Target sockets are on the nodes that use the value
  * from this socket.   */
-void DOutputSocket::foreach_target_socket(FunctionRef<void(DInputSocket)> callback) const
+void DOutputSocket::foreach_target_socket(FunctionRef<void(DInputSocket)> callback,
+                                          FunctionRef<void(DSocket)> skipped_callback) const
 {
+  for (const SocketRef *skipped_socket : socket_ref_->logically_linked_skipped_sockets()) {
+    skipped_callback.call_if_available({context_, skipped_socket});
+  }
   for (const InputSocketRef *linked_socket : socket_ref_->as_output().logically_linked_sockets()) {
     const NodeRef &linked_node = linked_socket->node();
     DInputSocket linked_dsocket{context_, linked_socket};
@@ -235,15 +239,19 @@ void DOutputSocket::foreach_target_socket(FunctionRef<void(DInputSocket)> callba
         /* Follow the links going out of the group node in the parent node group. */
         DOutputSocket socket_in_parent_group =
             linked_dsocket.get_corresponding_group_node_output();
-        socket_in_parent_group.foreach_target_socket(callback);
+        skipped_callback.call_if_available(linked_dsocket);
+        skipped_callback.call_if_available(socket_in_parent_group);
+        socket_in_parent_group.foreach_target_socket(callback, skipped_callback);
       }
     }
     else if (linked_node.is_group_node()) {
       /* Follow the links within the nested node group. */
       Vector<DOutputSocket> sockets_in_group =
           linked_dsocket.get_corresponding_group_input_sockets();
+      skipped_callback.call_if_available(linked_dsocket);
       for (DOutputSocket socket_in_group : sockets_in_group) {
-        socket_in_group.foreach_target_socket(callback);
+        skipped_callback.call_if_available(socket_in_group);
+        socket_in_group.foreach_target_socket(callback, skipped_callback);
       }
     }
     else {
diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc
index 7faaf861e4c..5ddccba6ad6 100644
--- a/source/blender/nodes/intern/node_tree_ref.cc
+++ b/source/blender/nodes/intern/node_tree_ref.cc
@@ -173,7 +173,7 @@ void NodeTreeRef::create_linked_socket_caches()
     /* Find logically linked sockets. */
     Vector<const SocketRef *> logically_linked_sockets;
     socket->foreach_logical_origin(
-        *socket, [&](const OutputSocketRef &origin) { logically_linked_sockets.append(&origin); });
+        [&](const OutputSocketRef &origin) { logically_linked_sockets.append(&origin); }, {});
     if (logically_linked_sockets == directly_linked_sockets) {
       socket->logically_linked_sockets_ = socket->directly_linked_sockets_;
     }
@@ -194,8 +194,10 @@ void NodeTreeRef::create_linked_socket_caches()
 
     /* Find logically linked sockets. */
     Vector<const SocketRef *> logically_linked_sockets;
+    Vector<const SocketRef *> logically_linked_skipped_sockets;
     socket->foreach_logical_target(
-        *socket, [&](const InputSocketRef &target) { logically_linked_sockets.append(&target); });
+        [&](const InputSocketRef &target) { logically_linked_sockets.append(&target); },
+        [&](const SocketRef &socket) { logically_linked_skipped_sockets.append(&socket); });
     if (logically_linked_sockets == directly_linked_sockets) {
       socket->logically_linked_sockets_ = socket->directly_linked_sockets_;
     }
@@ -203,14 +205,15 @@ void NodeTreeRef::create_linked_socket_caches()
       socket->logically_linked_sockets_ = allocator_.construct_array_copy(
           logically_linked_sockets.as_span());
     }
+    socket->logically_linked_skipped_sockets_ = allocator_.construct_array_copy(
+        logically_linked_skipped_sockets.as_span());
   }
 }
 
-void InputSocketRef::foreach_logical_origin(const InputSocketRef &socket,
-                                            FunctionRef<void(const OutputSocketRef &)> callback,
+void InputSocketRef::foreach_logical_origin(Functi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list