[Bf-blender-cvs] [2a5c0c34914] master: Geometry Nodes: add socket value logging capability

Jacques Lucke noreply at git.blender.org
Thu Apr 1 13:12:23 CEST 2021


Commit: 2a5c0c34914cc89efb8816edba2cf62a6299a6c1
Author: Jacques Lucke
Date:   Thu Apr 1 13:10:22 2021 +0200
Branches: master
https://developer.blender.org/rB2a5c0c34914cc89efb8816edba2cf62a6299a6c1

Geometry Nodes: add socket value logging capability

The node tree evaluator now calls a callback for every used socket with
its corresponding value(s). Right now the callback does nothing.
However, we can use it to collect attribute name hints, socket values
for debugging or data that will be displayed in the spreadsheet.

The main difficulty here was to also call the callback for sockets in
nodes that are not directly executed (such as group nodes, muted
nodes and reroutes).

No functional changes are expected.

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

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/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 72842a1d32d..267c4be5571 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -89,6 +89,7 @@ using blender::bke::PersistentCollectionHandle;
 using blender::bke::PersistentDataHandleMap;
 using blender::bke::PersistentObjectHandle;
 using blender::fn::GMutablePointer;
+using blender::fn::GPointer;
 using blender::fn::GValueMap;
 using blender::nodes::GeoNodeExecParams;
 using namespace blender::fn::multi_function_types;
@@ -253,6 +254,9 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
 }
 
 class GeometryNodesEvaluator {
+ public:
+  using LogSocketValueFn = std::function<void(DSocket, Span<GPointer>)>;
+
  private:
   blender::LinearAllocator<> allocator_;
   Map<std::pair<DInputSocket, DOutputSocket>, GMutablePointer> value_by_input_;
@@ -263,6 +267,7 @@ class GeometryNodesEvaluator {
   const Object *self_object_;
   const ModifierData *modifier_;
   Depsgraph *depsgraph_;
+  LogSocketValueFn log_socket_value_fn_;
 
  public:
   GeometryNodesEvaluator(const Map<DOutputSocket, GMutablePointer> &group_input_data,
@@ -271,16 +276,19 @@ class GeometryNodesEvaluator {
                          const PersistentDataHandleMap &handle_map,
                          const Object *self_object,
                          const ModifierData *modifier,
-                         Depsgraph *depsgraph)
+                         Depsgraph *depsgraph,
+                         LogSocketValueFn log_socket_value_fn)
       : group_outputs_(std::move(group_outputs)),
         mf_by_node_(mf_by_node),
         conversions_(blender::nodes::get_implicit_type_conversions()),
         handle_map_(handle_map),
         self_object_(self_object),
         modifier_(modifier),
-        depsgraph_(depsgraph)
+        depsgraph_(depsgraph),
+        log_socket_value_fn_(std::move(log_socket_value_fn))
   {
     for (auto item : group_input_data.items()) {
+      this->log_socket_value(item.key, item.value);
       this->forward_to_inputs(item.key, item.value);
     }
   }
@@ -290,6 +298,7 @@ class GeometryNodesEvaluator {
     Vector<GMutablePointer> results;
     for (const DInputSocket &group_output : group_outputs_) {
       Vector<GMutablePointer> result = this->get_input_values(group_output);
+      this->log_socket_value(group_output, result);
       results.append(result[0]);
     }
     for (GMutablePointer value : value_by_input_.values()) {
@@ -384,7 +393,9 @@ class GeometryNodesEvaluator {
     GValueMap<StringRef> node_inputs_map{allocator_};
     for (const InputSocketRef *input_socket : node->inputs()) {
       if (input_socket->is_available()) {
-        Vector<GMutablePointer> values = this->get_input_values({node.context(), input_socket});
+        DInputSocket dsocket{node.context(), input_socket};
+        Vector<GMutablePointer> values = this->get_input_values(dsocket);
+        this->log_socket_value(dsocket, values);
         for (int i = 0; i < values.size(); ++i) {
           /* Values from Multi Input Sockets are stored in input map with the format
            * <identifier>[<index>]. */
@@ -404,12 +415,31 @@ class GeometryNodesEvaluator {
     /* Forward computed outputs to linked input sockets. */
     for (const OutputSocketRef *output_socket : node->outputs()) {
       if (output_socket->is_available()) {
+        const DOutputSocket dsocket{node.context(), output_socket};
         GMutablePointer value = node_outputs_map.extract(output_socket->identifier());
-        this->forward_to_inputs({node.context(), output_socket}, value);
+        this->log_socket_value(dsocket, value);
+        this->forward_to_inputs(dsocket, value);
       }
     }
   }
 
+  void log_socket_value(const DSocket socket, Span<GPointer> values)
+  {
+    if (log_socket_value_fn_) {
+      log_socket_value_fn_(socket, values);
+    }
+  }
+
+  void log_socket_value(const DSocket socket, Span<GMutablePointer> values)
+  {
+    this->log_socket_value(socket, values.cast<GPointer>());
+  }
+
+  void log_socket_value(const DSocket socket, GPointer value)
+  {
+    this->log_socket_value(socket, Span<GPointer>(&value, 1));
+  }
+
   void execute_node(const DNode node, GeoNodeExecParams params)
   {
     const bNode &bnode = params.node();
@@ -523,8 +553,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->log_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;
@@ -1112,7 +1149,8 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
                                    handle_map,
                                    ctx->object,
                                    (ModifierData *)nmd,
-                                   ctx->depsgraph};
+                                   ctx->depsgraph,
+                                   {}};
 
   Vector<GMutablePointer> results = evaluator.execute();
   BLI_assert(results.size() == 1);
diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh
index c29de611e18..e294bef2ea8 100644
--- a/source/blender/nodes/NOD_derived_node_tree.hh
+++ b/source/blender/nodes/NOD_derived_node_tree.hh
@@ -59,6 +59,7 @@ class DTreeContext {
   const NodeTreeRef *tree_;
   /* All the children contexts of this context. */
   Map<const NodeRef *, DTreeContext *> children_;
+  DerivedNodeTree *derived_tree_;
 
   friend DerivedNodeTree;
 
@@ -67,6 +68,7 @@ class DTreeContext {
   const DTreeContext *parent_context() const;
   const NodeRef *parent_node() const;
   const DTreeContext *child_context(const NodeRef &node) const;
+  const DerivedNodeTree &derived_tree() const;
   bool is_root() const;
 };
 
@@ -117,6 +119,8 @@ class DSocket {
   operator bool() const;
 
   uint64_t hash() const;
+
+  DNode node() const;
 };
 
 /* A (nullable) reference to an input socket and the context it is in. */
@@ -132,7 +136,7 @@ class DInputSocket : public DSocket {
   DOutputSocket get_corresponding_group_node_output() const;
   Vector<DOutputSocket, 4> get_corresponding_group_input_sockets() const;
 
-  void foreach_origin_socket(FunctionRef<void(DSocket)> callback) const;
+  void foreach_origin_socket(FunctionRef<void(DSocket)> origin_fn) const;
 };
 
 /* A (nullable) reference to an output socket and the context it is in. */
@@ -148,7 +152,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)> target_fn,
+                             FunctionRef<void(DSocket)> skipped_fn) const;
 };
 
 class DerivedNodeTree {
@@ -214,6 +219,11 @@ inline const DTreeContext *DTreeContext::child_context(const NodeRef &node) cons
   return children_.lookup_default(&node, nullptr);
 }
 
+inline const DerivedNodeTree &DTreeContext::derived_tree() const
+{
+  return *derived_tree_;
+}
+
 inline bool DTreeContext::is_root() const
 {
   return parent_context_ == nullptr;
@@ -319,6 +329,12 @@ inline uint64_t DSocket::hash() const
   return get_default_hash_2(context_, socket_ref_);
 }
 
+inline DNode DSocket::node() const
+{
+  BLI_assert(socket_ref_ != nullptr);
+  return {context_, &socket_ref_->node()};
+}
+
 /* --------------------------------------------------------------------
  * DInputSocket inline methods.
  */
diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index 3710bd2fe00..f4c5d277f16 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -81,15 +81,19 @@ class SocketRef : NonCopyable, NonMovable {
   Vector<LinkRef *> directly_linked_links_;
 
   /* These sockets are linked directly, i.e. with a single link in between. */
-  MutableSpan<SocketRef *> directly_linked_sockets_;
+  MutableSpan<const SocketRef *> directly_linked_sockets_;
   /* These sockets are linked when reroutes, muted links and muted nodes have been taken into
    * account. */
-  MutableSpan<SocketRef *> logically_linked_sockets_;
+  MutableSpan<const SocketRef *> logically_linked_sockets_;
+  /* These are the sockets that have been skipped when searching for logicaly linked sockets. That
+   * includes for example the input and output socket of an intermediate reroute node. */
+  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;
 
@@ -132,12 +136,19 @@ class InputSocketRef final : public SocketRef {
   Span<const OutputSocketRef *> directly_linked_sockets() const;
 
   bool is_multi_input_socket() const;
+
+  void foreach_logical_origin(FunctionRef<void(const OutputSocketRef &)> origin_fn,
+                              FunctionRef<void(const SocketRef &)> skipped_fn,
+                              bool only_follow_first_input_link = false) const;
 };
 
 class OutputSocketRef final : public SocketRef {
  public:
   Span<const InputSocketRef *> logically_linked_sockets() const;
   Span<const InputSocketRef *> directly_linked_sockets() const;
+
+  void foreach_logical_target(FunctionRef<void(const InputSocketRef &)> target_fn,
+                              FunctionRef<void(const S

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list