[Bf-blender-cvs] [a55c230b8ae] temp-geometry-nodes-fields--fields-jacques: initial support in evaluator

Jacques Lucke noreply at git.blender.org
Tue Aug 31 13:22:57 CEST 2021


Commit: a55c230b8aeb341deb7d76619d21eb614e7d775f
Author: Jacques Lucke
Date:   Tue Aug 31 11:03:38 2021 +0200
Branches: temp-geometry-nodes-fields--fields-jacques
https://developer.blender.org/rBa55c230b8aeb341deb7d76619d21eb614e7d775f

initial support in evaluator

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

M	source/blender/functions/FN_field.hh
M	source/blender/functions/intern/field.cc
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/intern/node_socket.cc

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

diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index 7327ec7a499..7889126fe76 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -34,6 +34,7 @@
 #include "BLI_vector.hh"
 
 #include "FN_generic_virtual_array.hh"
+#include "FN_multi_function_builder.hh"
 #include "FN_multi_function_procedure.hh"
 #include "FN_multi_function_procedure_builder.hh"
 #include "FN_multi_function_procedure_executor.hh"
@@ -58,11 +59,13 @@ class GField {
   /**
    * Which output of the function this field corresponds to.
    */
-  int output_index_;
+  int output_index_ = 0;
 
   std::shared_ptr<FieldInput> input_;
 
  public:
+  GField() = default;
+
   GField(std::shared_ptr<FieldFunction> function, const int output_index)
       : function_(std::move(function)), output_index_(output_index)
   {
@@ -109,6 +112,8 @@ template<typename T> class Field {
   GField field_;
 
  public:
+  Field() = default;
+
   Field(GField field) : field_(std::move(field))
   {
     BLI_assert(field_.cpp_type().is<T>());
@@ -142,7 +147,7 @@ class FieldFunction {
   blender::Vector<GField> inputs_;
 
  public:
-  FieldFunction(std::unique_ptr<const MultiFunction> function, Vector<GField> &&inputs)
+  FieldFunction(std::unique_ptr<const MultiFunction> function, Vector<GField> inputs = {})
       : owned_function_(std::move(function)), inputs_(std::move(inputs))
   {
     function_ = owned_function_.get();
@@ -199,6 +204,22 @@ class FieldInput {
 void evaluate_fields(blender::Span<GField> fields,
                      blender::IndexMask mask,
                      blender::Span<GMutableSpan> outputs);
+void evaluate_constant_field(const GField &field, void *r_value);
+
+template<typename T> T evaluate_constant_field(const Field<T> &field)
+{
+  T value;
+  value.~T();
+  evaluate_constant_field(*field, &value);
+  return value;
+}
+
+template<typename T> Field<T> make_constant_field(T value)
+{
+  auto constant_fn = std::make_unique<fn::CustomMF_Constant<T>>(std::forward<T>(value));
+  auto field_fn = std::make_shared<FieldFunction>(std::move(constant_fn));
+  return Field<T>{GField{std::move(field_fn), 0}};
+}
 
 /* --------------------------------------------------------------------
  * GField inline methods.
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 151751e9ded..55aa96bc50f 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -243,7 +243,7 @@ static void build_procedure(const Span<GField> fields,
     builder.add_output_parameter(input);
   }
 
-  std::cout << procedure.to_dot();
+  // std::cout << procedure.to_dot();
 
   BLI_assert(procedure.validate());
 }
@@ -343,4 +343,13 @@ void evaluate_fields(const Span<GField> fields,
   }
 }
 
+/**
+ * #r_value is expected to be uninitialized.
+ */
+void evaluate_constant_field(const GField &field, void *r_value)
+{
+  GMutableSpan value_span{field.cpp_type(), r_value, 1};
+  evaluate_fields({field}, IndexRange(1), {value_span});
+}
+
 }  // namespace blender::fn
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index d6a23051c0b..f9a40e48d53 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -16,7 +16,8 @@
 
 #pragma once
 
-#include "FN_generic_value_map.hh"
+#include "FN_field.hh"
+#include "FN_multi_function_builder.hh"
 
 #include "BKE_attribute_access.hh"
 #include "BKE_geometry_set.hh"
@@ -38,11 +39,14 @@ using bke::OutputAttribute_Typed;
 using bke::ReadAttributeLookup;
 using bke::WriteAttributeLookup;
 using fn::CPPType;
+using fn::Field;
+using fn::FieldFunction;
+using fn::FieldInput;
+using fn::GField;
 using fn::GMutablePointer;
 using fn::GMutableSpan;
 using fn::GPointer;
 using fn::GSpan;
-using fn::GValueMap;
 using fn::GVArray;
 using fn::GVArray_GSpan;
 using fn::GVArray_Span;
@@ -121,6 +125,13 @@ class GeoNodeExecParams {
   {
   }
 
+  template<typename T>
+  static inline constexpr bool is_stored_as_field_v = std::is_same_v<T, float> ||
+                                                      std::is_same_v<T, int> ||
+                                                      std::is_same_v<T, bool> ||
+                                                      std::is_same_v<T, ColorGeometry4f> ||
+                                                      std::is_same_v<T, float3>;
+
   /**
    * Get the input value for the input socket with the given identifier.
    *
@@ -142,11 +153,17 @@ class GeoNodeExecParams {
    */
   template<typename T> T extract_input(StringRef identifier)
   {
+    if constexpr (is_stored_as_field_v<T>) {
+      Field<T> field = this->extract_input<Field<T>>(identifier);
+      return fn::evaluate_constant_field(field);
+    }
+    else {
 #ifdef DEBUG
-    this->check_input_access(identifier, &CPPType::get<T>());
+      this->check_input_access(identifier, &CPPType::get<T>());
 #endif
-    GMutablePointer gvalue = this->extract_input(identifier);
-    return gvalue.relocate_out<T>();
+      GMutablePointer gvalue = this->extract_input(identifier);
+      return gvalue.relocate_out<T>();
+    }
   }
 
   /**
@@ -156,6 +173,7 @@ class GeoNodeExecParams {
    */
   template<typename T> Vector<T> extract_multi_input(StringRef identifier)
   {
+    // static_assert(!is_stored_as_field_v<T>);
     Vector<GMutablePointer> gvalues = provider_->extract_multi_input(identifier);
     Vector<T> values;
     for (GMutablePointer gvalue : gvalues) {
@@ -167,14 +185,20 @@ class GeoNodeExecParams {
   /**
    * Get the input value for the input socket with the given identifier.
    */
-  template<typename T> const T &get_input(StringRef identifier) const
+  template<typename T> const T get_input(StringRef identifier) const
   {
+    if constexpr (is_stored_as_field_v<T>) {
+      const Field<T> &field = this->get_input<Field<T>>(identifier);
+      return fn::evaluate_constant_field(field);
+    }
+    else {
 #ifdef DEBUG
-    this->check_input_access(identifier, &CPPType::get<T>());
+      this->check_input_access(identifier, &CPPType::get<T>());
 #endif
-    GPointer gvalue = provider_->get_input(identifier);
-    BLI_assert(gvalue.is_type<T>());
-    return *(const T *)gvalue.get();
+      GPointer gvalue = provider_->get_input(identifier);
+      BLI_assert(gvalue.is_type<T>());
+      return *(const T *)gvalue.get();
+    }
   }
 
   /**
@@ -183,13 +207,19 @@ class GeoNodeExecParams {
   template<typename T> void set_output(StringRef identifier, T &&value)
   {
     using StoredT = std::decay_t<T>;
-    const CPPType &type = CPPType::get<std::decay_t<T>>();
+    if constexpr (is_stored_as_field_v<StoredT>) {
+      this->set_output<Field<StoredT>>(identifier,
+                                       fn::make_constant_field<StoredT>(std::forward<T>(value)));
+    }
+    else {
+      const CPPType &type = CPPType::get<StoredT>();
 #ifdef DEBUG
-    this->check_output_access(identifier, type);
+      this->check_output_access(identifier, type);
 #endif
-    GMutablePointer gvalue = provider_->alloc_output_value(type);
-    new (gvalue.get()) StoredT(std::forward<T>(value));
-    provider_->set_output(identifier, gvalue);
+      GMutablePointer gvalue = provider_->alloc_output_value(type);
+      new (gvalue.get()) StoredT(std::forward<T>(value));
+      provider_->set_output(identifier, gvalue);
+    }
   }
 
   /**
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index d386781e3ce..383153df756 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -48,6 +48,7 @@
 #include "NOD_socket.h"
 
 #include "FN_cpp_type_make.hh"
+#include "FN_field.hh"
 
 using namespace blender;
 using blender::nodes::SocketDeclarationPtr;
@@ -701,8 +702,14 @@ static bNodeSocketType *make_socket_type_bool()
   socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
     *(bool *)r_value = ((bNodeSocketValueBoolean *)socket.default_value)->value;
   };
-  socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
-  socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
+  socktype->get_geometry_nodes_cpp_type = []() {
+    return &blender::fn::CPPType::get<blender::fn::Field<bool>>();
+  };
+  socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) {
+    bool value;
+    socket.typeinfo->get_base_cpp_value(socket, &value);
+    new (r_value) blender::fn::Field<bool>(blender::fn::make_constant_field(value));
+  };
   return socktype;
 }
 
@@ -713,8 +720,14 @@ static bNodeSocketType *make_socket_type_float(PropertySubType subtype)
   socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
     *(float *)r_value = ((bNodeSocketValueFloat *)socket.default_value)->value;
   };
-  socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
-  socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
+  socktype->get_geometry_nodes_cpp_type = []() {
+    return &blender::fn::CPPType::get<blender::fn::Field<float>>();
+  };
+  socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) {
+    float value;
+    socket.typeinfo->get_base_cpp_value(socket, &value);
+    new (r_value) blender::fn::Field<float>(blender::fn::make_constant_field(value));
+  };
   return socktype;
 }
 
@@ -725,8 +738,14 @@ static bNodeSocketType *make_socket_type_int(PropertySubType subtype)
   socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
     *(int *)r_value = ((bNodeSocketValueInt *)socket.default_value)->value;
   };
-  socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
-  socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
+  socktype->get_geometry_nodes_cpp_type = []() {
+    return &blender::fn::CPPType::get<blender::fn::Field<int>>();
+  };
+  socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) {
+    int value;
+    socket.typeinfo->get_base_cpp_value(socket, &value);
+    new (r_value) blender::fn::Field<int>(blender:

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list