[Bf-blender-cvs] [fb26ee8a7e7] temp-geometry-nodes-fields--fields: Initial crappy code that doesn't do anything and wouldn't compile

Hans Goudey noreply at git.blender.org
Wed Aug 25 23:23:53 CEST 2021


Commit: fb26ee8a7e7df951880b6917a358e6c3e0728df4
Author: Hans Goudey
Date:   Tue Aug 24 17:35:46 2021 -0500
Branches: temp-geometry-nodes-fields--fields
https://developer.blender.org/rBfb26ee8a7e7df951880b6917a358e6c3e0728df4

Initial crappy code that doesn't do anything and wouldn't compile

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

M	source/blender/functions/CMakeLists.txt
A	source/blender/functions/FN_field.hh
A	source/blender/functions/FN_generic_array.hh
A	source/blender/functions/tests/FN_field_test.cc
A	source/blender/functions/tests/FN_generic_array_test.cc

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

diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index a44086cfec1..a67667ba46e 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -39,6 +39,8 @@ set(SRC
 
   FN_cpp_type.hh
   FN_cpp_type_make.hh
+  FN_field.hh
+  FN_generic_array.hh
   FN_generic_pointer.hh
   FN_generic_span.hh
   FN_generic_value_map.hh
@@ -66,6 +68,8 @@ blender_add_lib(bf_functions "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
 if(WITH_GTESTS)
   set(TEST_SRC
     tests/FN_cpp_type_test.cc
+    tests/FN_field_test.cc
+    tests/FN_generic_array_test.cc
     tests/FN_generic_span_test.cc
     tests/FN_generic_vector_array_test.cc
     tests/FN_multi_function_procedure_test.cc
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
new file mode 100644
index 00000000000..2f701c7ec52
--- /dev/null
+++ b/source/blender/functions/FN_field.hh
@@ -0,0 +1,178 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup fn
+ */
+
+#include "BLI_function_ref.hh"
+#include "BLI_map.hh"
+#include "BLI_vector.hh"
+
+#include "FN_generic_array.hh"
+#include "FN_generic_virtual_array.hh"
+#include "FN_multi_function_procedure.hh"
+#include "FN_multi_function_procedure_builder.hh"
+#include "FN_multi_function_procedure_executor.hh"
+
+namespace blender::fn {
+
+class Field;
+
+class Field {
+  fn::CPPType *type_;
+
+ public:
+  fn::CPPType &type()
+  {
+    return *type_;
+  }
+
+  virtual void foreach_input_recursive(blender::FunctionRef<void(const InputField &input)> fn) = 0;
+  virtual void foreach_input(blender::FunctionRef<void(const InputField &input)> fn) = 0;
+};
+
+class InputField : public Field {
+
+ public:
+  virtual GVArrayPtr get_data(IndexMask mask) const = 0;
+  void foreach_input_recursive(blender::FunctionRef<void(const InputField &input)> fn) final
+  {
+  }
+  void foreach_input(blender::FunctionRef<void(const InputField &input)> fn) final
+  {
+  }
+};
+
+class MultiFunctionField final : public Field {
+  blender::Vector<std::shared_ptr<Field>> input_fields_;
+  MultiFunction &function_;
+
+ public:
+  void foreach_input_recursive(blender::FunctionRef<void(const InputField &input)> fn) final
+  {
+    for (const std::shared_ptr<Field> &field : input_fields_) {
+      if (const InputField *input_field = dynamic_cast<const InputField *>(field.get())) {
+        fn(*input_field);
+      }
+      else {
+        field->foreach_input(fn);
+      }
+    }
+  }
+
+  void foreach_input(blender::FunctionRef<void(const InputField &input)> fn) final
+  {
+    for (const std::shared_ptr<Field> &field : input_fields_) {
+      if (const InputField *input_field = dynamic_cast<const InputField *>(field.get())) {
+        fn(*input_field);
+      }
+    }
+  }
+};
+
+void add_procedure_inputs_recursive(const Field &field, MFProcedureBuilder &builder)
+{
+  field.foreach_input()
+}
+
+/**
+ * Evaluate more than one prodecure at a time
+ */
+void evaluate_fields(const Span<std::shared_ptr<Field>> fields,
+                     const MutableSpan<GMutableSpan> outputs,
+                     const IndexMask mask)
+{
+  blender::Map<const InputField *, GVArrayPtr> computed_inputs;
+  for (const std::shared_ptr<Field> &field : fields) {
+    field->foreach_input_recursive([&](const InputField &input_field) {
+      if (!computed_inputs.contains(&input_field)) {
+        computed_inputs.add_new(&input_field, input_field.get_data(mask));
+      }
+    });
+  }
+
+  /* Build procedure. */
+  MFProcedure procedure;
+  MFProcedureBuilder builder{procedure};
+
+  Map<const InputField *, MFVariable *> fields_to_variables;
+
+  /* Add the unique inputs. */
+  for (blender::Map<const InputField *, GVArrayPtr>::Item item : computed_inputs.items()) {
+    fields_to_variables.add_new(
+        item.key, &builder.add_parameter(MFParamType::ForSingleInput(item.value->type())));
+  }
+
+  /* Add the inputs recursively for the entire group of nodes. */
+  // builder.add_return();
+  // builder.add_output_parameter(*var4);
+
+  BLI_assert(procedure.validate());
+
+  /* Evaluate procedure. */
+  MFProcedureExecutor executor{"Evaluate Field", procedure};
+  MFParamsBuilder params{executor, mask.min_array_size()};
+  MFContextBuilder context;
+
+  /* Add the input data. */
+  for (blender::Map<const InputField *, GVArrayPtr>::Item item : computed_inputs.items()) {
+    params.add_readonly_single_input(*item.value);
+  }
+
+  /* Add the output arrays. */
+  for (const int i : fields.index_range()) {
+    params.add_uninitialized_single_output(outputs[i]);
+  }
+
+  executor.call(mask, params, context);
+
+  // int input_index = 0;
+  // for (const int param_index : fn_->param_indices()) {
+  //   fn::MFParamType param_type = fn_->param_type(param_index);
+  //   switch (param_type.category()) {
+  //     case fn::MFParamType::SingleInput: {
+  //       const Field &field = *input_fields_[input_index];
+  //       FieldOutput &output = scope.add_value(field.evaluate(mask, inputs), __func__);
+  //       params.add_readonly_single_input(output.varray_ref());
+  //       input_index++;
+  //       break;
+  //     }
+  //     case fn::MFParamType::SingleOutput: {
+  //       const CPPType &type = param_type.data_type().single_type();
+  //       void *buffer = MEM_mallocN_aligned(
+  //           mask.min_array_size() * type.size(), type.alignment(), __func__);
+  //       GMutableSpan span{type, buffer, mask.min_array_size()};
+  //       outputs.append(span);
+  //       params.add_uninitialized_single_output(span);
+  //       if (param_index == output_param_index_) {
+  //         output_span_index = outputs.size() - 1;
+  //       }
+  //       break;
+  //     }
+  //     case fn::MFParamType::SingleMutable:
+  //     case fn::MFParamType::VectorInput:
+  //     case fn::MFParamType::VectorMutable:
+  //     case fn::MFParamType::VectorOutput:
+  //       BLI_assert_unreachable();
+  //       break;
+  //   }
+  // }
+}
+
+}  // namespace blender::fn
\ No newline at end of file
diff --git a/source/blender/functions/FN_generic_array.hh b/source/blender/functions/FN_generic_array.hh
new file mode 100644
index 00000000000..523df5e9566
--- /dev/null
+++ b/source/blender/functions/FN_generic_array.hh
@@ -0,0 +1,274 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup fn
+ *
+ * This is a generic counterpart to `blender::Array`, used when the type is not known at runtime.
+ *
+ * `GArray` should generally only be used for passing data around in dynamic contexts.
+ * It does not support a few things that `blender::Array` supports:
+ *  - Small object optimization / inline buffer.
+ *  - Exception safety and various more specific constructors.
+ *
+ * Note that a generic vector is purposefully not added to Blender, since it would encourage use of
+ * the `append` function, which would be inefficient for dynamic types. Dynamic types should
+ * usually be processed in batches.
+ */
+
+#include "BLI_allocator.hh"
+
+#include "FN_cpp_type.hh"
+#include "FN_generic_span.hh"
+
+namespace blender::fn {
+
+template<
+    /**
+     * The allocator used by this array. Should rarely be changed, except when you don't want that
+     * MEM_* functions are used internally.
+     */
+    typename Allocator = GuardedAllocator>
+class GArray {
+ protected:
+  /** The type of the data in the array, will be null after the array is default constructed,
+   * but a value should be assigned before any other interaction with the array. */
+  const CPPType *type_;
+  void *data_;
+  int64_t size_;
+
+  Allocator allocator_;
+
+ public:
+  /**
+   * The default constructor creates an empty array, the only situation in which the type is
+   * allowed to be null. This default constructor exists so `GArray` can be used in containers,
+   * but the type should be supplied before doing anything else to the array.
+   */
+  GArray(Allocator allocator = {}) noexcept : allocator_(allocator)
+  {
+    type_ = nullptr;
+    data_ = nullptr;
+    size_ = 0;
+  }
+
+  /**
+   * Create and allocate a new array, with elements default constructed
+   * (which does not do anything for trivial types).
+   */
+  GArray(const CPPType &type, int64_t size, Allocator allocator = {}) : GArray(type, allocator)
+  {
+    BLI_assert(size >= 0);
+    size_ = size;
+    data_ = this->allocate(size_);
+    type_->default_construct_n(data_, size_);
+  }
+
+  /**
+   * Create an empty array with just a type.
+   */
+  GArray(const CPPType &type, Allocator allocator = {}) : GArray(allocator)
+  {
+    type_ = &type;
+    data_ = nullptr;
+    size_ = 0;
+  }
+
+  /**
+   * Take ownership of a buffer with a provided size. The buffer should be
+   * allocated with the same allocator provided to the constructor.
+   */
+  GA

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list