[Bf-blender-cvs] [908bb036306] master: Geometry Nodes: improve geometry nodes evaluator internal api

Jacques Lucke noreply at git.blender.org
Tue Apr 27 13:04:00 CEST 2021


Commit: 908bb0363062168e16c608e13b9340724510e2cd
Author: Jacques Lucke
Date:   Tue Apr 27 13:03:40 2021 +0200
Branches: master
https://developer.blender.org/rB908bb0363062168e16c608e13b9340724510e2cd

Geometry Nodes: improve geometry nodes evaluator internal api

This is a first step towards T87620.
It should not have any functional changes.

Goals of this refactor:
* Move the evaluator out of `MOD_nodes.cc`. That makes it easier to
  improve it in isolation.
* Extract core input/out parameter management out of `GeoNodeExecParams`.
  Managing this is the responsibility of the evaluator. This separation of
  concerns will be useful once we have lazy evaluation of certain inputs/outputs.

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

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

M	source/blender/functions/FN_cpp_type.hh
M	source/blender/functions/FN_generic_pointer.hh
M	source/blender/functions/FN_generic_value_map.hh
M	source/blender/modifiers/CMakeLists.txt
M	source/blender/modifiers/intern/MOD_nodes.cc
A	source/blender/modifiers/intern/MOD_nodes_evaluator.cc
A	source/blender/modifiers/intern/MOD_nodes_evaluator.hh
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/intern/node_geometry_exec.cc

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

diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh
index 54ea0103fe5..cd1597a742c 100644
--- a/source/blender/functions/FN_cpp_type.hh
+++ b/source/blender/functions/FN_cpp_type.hh
@@ -666,7 +666,7 @@ class CPPType : NonCopyable, NonMovable {
 
   template<typename T> bool is() const
   {
-    return this == &CPPType::get<T>();
+    return this == &CPPType::get<std::decay_t<T>>();
   }
 };
 
diff --git a/source/blender/functions/FN_generic_pointer.hh b/source/blender/functions/FN_generic_pointer.hh
index 2bd66daa7fe..f88ff09f916 100644
--- a/source/blender/functions/FN_generic_pointer.hh
+++ b/source/blender/functions/FN_generic_pointer.hh
@@ -66,6 +66,16 @@ class GMutablePointer {
     return type_ != nullptr && type_->is<T>();
   }
 
+  template<typename T> T relocate_out()
+  {
+    BLI_assert(this->is_type<T>());
+    T value;
+    type_->relocate_to_initialized(data_, &value);
+    data_ = nullptr;
+    type_ = nullptr;
+    return value;
+  }
+
   void destruct()
   {
     BLI_assert(data_ != nullptr);
diff --git a/source/blender/functions/FN_generic_value_map.hh b/source/blender/functions/FN_generic_value_map.hh
index 68cb945f1af..4e7fe298874 100644
--- a/source/blender/functions/FN_generic_value_map.hh
+++ b/source/blender/functions/FN_generic_value_map.hh
@@ -93,6 +93,11 @@ template<typename Key> class GValueMap {
     return values_.pop_as(key);
   }
 
+  template<typename ForwardKey> GPointer lookup(const ForwardKey &key) const
+  {
+    return values_.lookup_as(key);
+  }
+
   /* Remove the value for the given name from the container and remove it. */
   template<typename T, typename ForwardKey> T extract(const ForwardKey &key)
   {
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 54caaed9231..6ac2629c006 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -79,6 +79,7 @@ set(SRC
   intern/MOD_mirror.c
   intern/MOD_multires.c
   intern/MOD_nodes.cc
+  intern/MOD_nodes_evaluator.cc
   intern/MOD_none.c
   intern/MOD_normal_edit.c
   intern/MOD_ocean.c
@@ -118,6 +119,7 @@ set(SRC
   MOD_modifiertypes.h
   MOD_nodes.h
   intern/MOD_meshcache_util.h
+  intern/MOD_nodes_evaluator.hh
   intern/MOD_solidify_util.h
   intern/MOD_ui_common.h
   intern/MOD_util.h
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index cc8f4a544c0..bc045b39904 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -75,16 +75,14 @@
 
 #include "MOD_modifiertypes.h"
 #include "MOD_nodes.h"
+#include "MOD_nodes_evaluator.hh"
 #include "MOD_ui_common.h"
 
 #include "ED_spreadsheet.h"
 
 #include "NOD_derived_node_tree.hh"
 #include "NOD_geometry.h"
-#include "NOD_geometry_exec.hh"
 #include "NOD_node_tree_multi_function.hh"
-#include "NOD_type_callbacks.hh"
-#include "NOD_type_conversions.hh"
 
 using blender::float3;
 using blender::FunctionRef;
@@ -100,7 +98,6 @@ 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;
 using namespace blender::nodes::derived_node_tree_types;
@@ -268,368 +265,6 @@ static bool logging_enabled(const ModifierEvalContext *ctx)
   return true;
 }
 
-class GeometryNodesEvaluator {
- public:
-  using LogSocketValueFn = std::function<void(DSocket, Span<GPointer>)>;
-
- private:
-  blender::LinearAllocator<> allocator_;
-  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_;
-  const Object *self_object_;
-  const ModifierData *modifier_;
-  Depsgraph *depsgraph_;
-  LogSocketValueFn log_socket_value_fn_;
-
- public:
-  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,
-                         const ModifierData *modifier,
-                         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),
-        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);
-    }
-  }
-
-  Vector<GMutablePointer> execute()
-  {
-    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()) {
-      value.destruct();
-    }
-    return results;
-  }
-
- private:
-  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); });
-
-    if (from_sockets.is_empty()) {
-      /* The input is not connected, use the value from the socket itself. */
-      const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket_to_compute->typeinfo());
-      return {get_unlinked_input_value(socket_to_compute, type)};
-    }
-
-    /* Multi-input sockets contain a vector of inputs. */
-    if (socket_to_compute->is_multi_input_socket()) {
-      return this->get_inputs_from_incoming_links(socket_to_compute, from_sockets);
-    }
-
-    const DSocket from_socket = from_sockets[0];
-    GMutablePointer value = this->get_input_from_incoming_link(socket_to_compute, from_socket);
-    return {value};
-  }
-
-  Vector<GMutablePointer> get_inputs_from_incoming_links(const DInputSocket socket_to_compute,
-                                                         const Span<DSocket> from_sockets)
-  {
-    Vector<GMutablePointer> values;
-    for (const int i : from_sockets.index_range()) {
-      const DSocket from_socket = from_sockets[i];
-      const int first_occurence = from_sockets.take_front(i).first_index_try(from_socket);
-      if (first_occurence == -1) {
-        values.append(this->get_input_from_incoming_link(socket_to_compute, from_socket));
-      }
-      else {
-        /* If the same from-socket occurs more than once, we make a copy of the first value. This
-         * can happen when a node linked to a multi-input-socket is muted. */
-        GMutablePointer value = values[first_occurence];
-        const CPPType *type = value.type();
-        void *copy_buffer = allocator_.allocate(type->size(), type->alignment());
-        type->copy_to_uninitialized(value.get(), copy_buffer);
-        values.append({type, copy_buffer});
-      }
-    }
-    return values;
-  }
-
-  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};
-      }
-
-      /* Compute the socket now. */
-      this->compute_output_and_forward(from_output_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)
-  {
-    const DNode node{socket_to_compute.context(), &socket_to_compute->node()};
-
-    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());
-      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});
-      return;
-    }
-
-    /* Prepare inputs required to execute the node. */
-    GValueMap<StringRef> node_inputs_map{allocator_};
-    for (const InputSocketRef *input_socket : node->inputs()) {
-      if (input_socket->is_available()) {
-        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>]. */
-          blender::StringRefNull key = allocator_.copy_string(
-              input_socket->identifier() + (i > 0 ? ("[" + std::to_string(i)) + "]" : ""));
-          node_inputs_map.add_new_direct(key, std::move(values[i]));
-        }
-      }
-    }
-
-    /* Execute the node. */
-    GValueMap<StringRef> node_outputs_map{allocator_};
-    GeoNodeExecParams params{
-        node, n

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list