[Bf-blender-cvs] [d2869943d2c] master: Nodes: refactor derived node tree

Jacques Lucke noreply at git.blender.org
Sat Mar 6 16:54:22 CET 2021


Commit: d2869943d2c02f1535270f0e206a67aab78c8ebb
Author: Jacques Lucke
Date:   Sat Mar 6 16:51:06 2021 +0100
Branches: master
https://developer.blender.org/rBd2869943d2c02f1535270f0e206a67aab78c8ebb

Nodes: refactor derived node tree

This is a complete rewrite of the derived node tree data structure.
It is a much thinner abstraction about `NodeTreeRef` than before.
This gives the user of the derived node tree more control and allows
for greater introspection capabilities (e.g. before muted nodes were
completely abstracted away; this was convenient, but came with
limitations).

Another nice benefit of the new structure is that it is much cheaper
to build, because it does not inline all nodes and sockets in nested
node groups.

Differential Revision: https://developer.blender.org/D10620

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

M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/NOD_derived_node_tree.hh
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/NOD_node_tree_multi_function.hh
M	source/blender/nodes/function/nodes/node_fn_group_instance_id.cc
M	source/blender/nodes/function/nodes/node_fn_random_float.cc
M	source/blender/nodes/intern/derived_node_tree.cc
M	source/blender/nodes/intern/node_geometry_exec.cc
M	source/blender/nodes/intern/node_tree_multi_function.cc
M	source/blender/nodes/shader/nodes/node_shader_math.cc
M	source/blender/nodes/shader/nodes/node_shader_value.cc

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

diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index b47f5806c9c..4d1823b8951 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -77,6 +77,7 @@
 #include "NOD_type_callbacks.hh"
 
 using blender::float3;
+using blender::FunctionRef;
 using blender::IndexRange;
 using blender::Map;
 using blender::Set;
@@ -90,8 +91,8 @@ using blender::bke::PersistentObjectHandle;
 using blender::fn::GMutablePointer;
 using blender::fn::GValueMap;
 using blender::nodes::GeoNodeExecParams;
-using namespace blender::nodes::derived_node_tree_types;
 using namespace blender::fn::multi_function_types;
+using namespace blender::nodes::derived_node_tree_types;
 
 static void initData(ModifierData *md)
 {
@@ -254,8 +255,8 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
 class GeometryNodesEvaluator {
  private:
   blender::LinearAllocator<> allocator_;
-  Map<std::pair<const DInputSocket *, const DOutputSocket *>, GMutablePointer> value_by_input_;
-  Vector<const DInputSocket *> group_outputs_;
+  Map<std::pair<DInputSocket, DOutputSocket>, GMutablePointer> value_by_input_;
+  Vector<DInputSocket> group_outputs_;
   blender::nodes::MultiFunctionByNode &mf_by_node_;
   const blender::nodes::DataTypeConversions &conversions_;
   const PersistentDataHandleMap &handle_map_;
@@ -264,8 +265,8 @@ class GeometryNodesEvaluator {
   Depsgraph *depsgraph_;
 
  public:
-  GeometryNodesEvaluator(const Map<const DOutputSocket *, GMutablePointer> &group_input_data,
-                         Vector<const DInputSocket *> group_outputs,
+  GeometryNodesEvaluator(const Map<DOutputSocket, GMutablePointer> &group_input_data,
+                         Vector<DInputSocket> group_outputs,
                          blender::nodes::MultiFunctionByNode &mf_by_node,
                          const PersistentDataHandleMap &handle_map,
                          const Object *self_object,
@@ -280,15 +281,15 @@ class GeometryNodesEvaluator {
         depsgraph_(depsgraph)
   {
     for (auto item : group_input_data.items()) {
-      this->forward_to_inputs(*item.key, item.value);
+      this->forward_to_inputs(item.key, item.value);
     }
   }
 
   Vector<GMutablePointer> execute()
   {
     Vector<GMutablePointer> results;
-    for (const DInputSocket *group_output : group_outputs_) {
-      Vector<GMutablePointer> result = this->get_input_values(*group_output);
+    for (const DInputSocket &group_output : group_outputs_) {
+      Vector<GMutablePointer> result = this->get_input_values(group_output);
       results.append(result[0]);
     }
     for (GMutablePointer value : value_by_input_.values()) {
@@ -298,62 +299,63 @@ class GeometryNodesEvaluator {
   }
 
  private:
-  Vector<GMutablePointer> get_input_values(const DInputSocket &socket_to_compute)
+  Vector<GMutablePointer> get_input_values(const DInputSocket socket_to_compute)
   {
+    Vector<DSocket> from_sockets;
+    socket_to_compute.foreach_origin_socket([&](DSocket socket) { from_sockets.append(socket); });
 
-    Span<const DOutputSocket *> from_sockets = socket_to_compute.linked_sockets();
-    Span<const DGroupInput *> from_group_inputs = socket_to_compute.linked_group_inputs();
-    const int total_inputs = from_sockets.size() + from_group_inputs.size();
+    /* Multi-input sockets contain a vector of inputs. */
+    if (socket_to_compute->is_multi_input_socket()) {
+      Vector<GMutablePointer> values;
+      for (const DSocket from_socket : from_sockets) {
+        GMutablePointer value = get_input_from_incoming_link(socket_to_compute, from_socket);
+        values.append(value);
+      }
+      return values;
+    }
 
-    if (total_inputs == 0) {
+    if (from_sockets.is_empty()) {
       /* The input is not connected, use the value from the socket itself. */
-      return {get_unlinked_input_value(socket_to_compute)};
+      const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
+      return {get_unlinked_input_value(socket_to_compute, type)};
     }
 
-    if (from_group_inputs.size() == 1) {
-      return {get_unlinked_input_value(socket_to_compute)};
-    }
+    const DSocket from_socket = from_sockets[0];
+    GMutablePointer value = this->get_input_from_incoming_link(socket_to_compute, from_socket);
+    return {value};
+  }
 
-    /* Multi-input sockets contain a vector of inputs. */
-    if (socket_to_compute.is_multi_input_socket()) {
-      Vector<GMutablePointer> values;
-      for (const DOutputSocket *from_socket : from_sockets) {
-        const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
-            &socket_to_compute, from_socket);
-        std::optional<GMutablePointer> value = value_by_input_.pop_try(key);
-        if (value.has_value()) {
-          values.append(*value);
-        }
-        else {
-          this->compute_output_and_forward(*from_socket);
-          GMutablePointer value = value_by_input_.pop(key);
-          values.append(value);
-        }
+  GMutablePointer get_input_from_incoming_link(const DInputSocket socket_to_compute,
+                                               const DSocket from_socket)
+  {
+    if (from_socket->is_output()) {
+      const DOutputSocket from_output_socket{from_socket};
+      const std::pair<DInputSocket, DOutputSocket> key = std::make_pair(socket_to_compute,
+                                                                        from_output_socket);
+      std::optional<GMutablePointer> value = value_by_input_.pop_try(key);
+      if (value.has_value()) {
+        /* This input has been computed before, return it directly. */
+        return {*value};
       }
-      return values;
-    }
 
-    const DOutputSocket &from_socket = *from_sockets[0];
-    const std::pair<const DInputSocket *, const DOutputSocket *> key = std::make_pair(
-        &socket_to_compute, &from_socket);
-    std::optional<GMutablePointer> value = value_by_input_.pop_try(key);
-    if (value.has_value()) {
-      /* This input has been computed before, return it directly. */
-      return {*value};
+      /* Compute the socket now. */
+      this->compute_output_and_forward(from_output_socket);
+      return {value_by_input_.pop(key)};
     }
 
-    /* Compute the socket now. */
-    this->compute_output_and_forward(from_socket);
-    return {value_by_input_.pop(key)};
+    /* Get value from an unlinked input socket. */
+    const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
+    const DInputSocket from_input_socket{from_socket};
+    return {get_unlinked_input_value(from_input_socket, type)};
   }
 
-  void compute_output_and_forward(const DOutputSocket &socket_to_compute)
+  void compute_output_and_forward(const DOutputSocket socket_to_compute)
   {
-    const DNode &node = socket_to_compute.node();
+    const DNode node{socket_to_compute.context(), &socket_to_compute->node()};
 
-    if (!socket_to_compute.is_available()) {
+    if (!socket_to_compute->is_available()) {
       /* If the output is not available, use a default value. */
-      const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute.typeinfo());
+      const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
       void *buffer = allocator_.allocate(type.size(), type.alignment());
       type.copy_to_uninitialized(type.default_value(), buffer);
       this->forward_to_inputs(socket_to_compute, {type, buffer});
@@ -362,9 +364,9 @@ class GeometryNodesEvaluator {
 
     /* Prepare inputs required to execute the node. */
     GValueMap<StringRef> node_inputs_map{allocator_};
-    for (const DInputSocket *input_socket : node.inputs()) {
+    for (const InputSocketRef *input_socket : node->inputs()) {
       if (input_socket->is_available()) {
-        Vector<GMutablePointer> values = this->get_input_values(*input_socket);
+        Vector<GMutablePointer> values = this->get_input_values({node.context(), input_socket});
         for (int i = 0; i < values.size(); ++i) {
           /* Values from Multi Input Sockets are stored in input map with the format
            * <identifier>[<index>]. */
@@ -382,15 +384,15 @@ class GeometryNodesEvaluator {
     this->execute_node(node, params);
 
     /* Forward computed outputs to linked input sockets. */
-    for (const DOutputSocket *output_socket : node.outputs()) {
+    for (const OutputSocketRef *output_socket : node->outputs()) {
       if (output_socket->is_available()) {
         GMutablePointer value = node_outputs_map.extract(output_socket->identifier());
-        this->forward_to_inputs(*output_socket, value);
+        this->forward_to_inputs({node.context(), output_socket}, value);
       }
     }
   }
 
-  void execute_node(const DNode &node, GeoNodeExecParams params)
+  void execute_node(const DNode node, GeoNodeExecParams params)
   {
     const bNode &bnode = params.node();
 
@@ -403,7 +405,7 @@ class GeometryNodesEvaluator {
     }
 
     /* Use the multi-function implementation if it exists. */
-    const MultiFunction *multi_function = mf_by_node_.lookup_default(&node, nullptr);
+    const MultiFunction *multi_function = mf_by_node_.lookup_default(node, nullptr);
     if (multi_function != nullptr) {
       this->execute_multi_function_node(node, params, *multi_function);
       return;
@@ -413,51 +415,52 @@ class GeometryNodesEvaluator {
     this->execute_unknown_node(node, params);
   }
 
-  void store_ui_hints(const DNode &node, GeoNodeExecParams params) const
+  void store_ui_hints(const DNode node, GeoNodeExecParams params) const
   {
-    for (const DInputSocket *dsocket : node.inputs()) {
-      if (!dsocket->is_available()) {
+    for (const InputSocketRef *socket_ref : node->inputs()) {
+      if (!socket_ref->is_available()) {
         continue;
       }
-      if (dsocket->bsocket()->type != SOCK_GEOMETRY) {
+      if (socket_ref->bsocket()->type != SOCK_GEOMETRY) {
         continue;
       }
 
-      bNodeTree *btree_cow = node.node_ref().tree().btree();
+      bNodeTree *btree_cow = node->btree();
       bNodeTree *btree_original = (bNodeTree *)DEG_get_origin

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list