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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs