From a55c230b8aeb341deb7d76619d21eb614e7d775f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 31 Aug 2021 11:03:38 +0200 Subject: initial support in evaluator --- source/blender/functions/FN_field.hh | 25 ++++++++++++- source/blender/functions/intern/field.cc | 11 +++++- source/blender/nodes/NOD_geometry_exec.hh | 60 ++++++++++++++++++++++-------- source/blender/nodes/intern/node_socket.cc | 52 +++++++++++++++++++++----- 4 files changed, 120 insertions(+), 28 deletions(-) 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 input_; public: + GField() = default; + GField(std::shared_ptr function, const int output_index) : function_(std::move(function)), output_index_(output_index) { @@ -109,6 +112,8 @@ template class Field { GField field_; public: + Field() = default; + Field(GField field) : field_(std::move(field)) { BLI_assert(field_.cpp_type().is()); @@ -142,7 +147,7 @@ class FieldFunction { blender::Vector inputs_; public: - FieldFunction(std::unique_ptr function, Vector &&inputs) + FieldFunction(std::unique_ptr function, Vector 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 fields, blender::IndexMask mask, blender::Span outputs); +void evaluate_constant_field(const GField &field, void *r_value); + +template T evaluate_constant_field(const Field &field) +{ + T value; + value.~T(); + evaluate_constant_field(*field, &value); + return value; +} + +template Field make_constant_field(T value) +{ + auto constant_fn = std::make_unique>(std::forward(value)); + auto field_fn = std::make_shared(std::move(constant_fn)); + return Field{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 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 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 + static inline constexpr bool is_stored_as_field_v = std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; + /** * Get the input value for the input socket with the given identifier. * @@ -142,11 +153,17 @@ class GeoNodeExecParams { */ template T extract_input(StringRef identifier) { + if constexpr (is_stored_as_field_v) { + Field field = this->extract_input>(identifier); + return fn::evaluate_constant_field(field); + } + else { #ifdef DEBUG - this->check_input_access(identifier, &CPPType::get()); + this->check_input_access(identifier, &CPPType::get()); #endif - GMutablePointer gvalue = this->extract_input(identifier); - return gvalue.relocate_out(); + GMutablePointer gvalue = this->extract_input(identifier); + return gvalue.relocate_out(); + } } /** @@ -156,6 +173,7 @@ class GeoNodeExecParams { */ template Vector extract_multi_input(StringRef identifier) { + // static_assert(!is_stored_as_field_v); Vector gvalues = provider_->extract_multi_input(identifier); Vector values; for (GMutablePointer gvalue : gvalues) { @@ -167,14 +185,20 @@ class GeoNodeExecParams { /** * Get the input value for the input socket with the given identifier. */ - template const T &get_input(StringRef identifier) const + template const T get_input(StringRef identifier) const { + if constexpr (is_stored_as_field_v) { + const Field &field = this->get_input>(identifier); + return fn::evaluate_constant_field(field); + } + else { #ifdef DEBUG - this->check_input_access(identifier, &CPPType::get()); + this->check_input_access(identifier, &CPPType::get()); #endif - GPointer gvalue = provider_->get_input(identifier); - BLI_assert(gvalue.is_type()); - return *(const T *)gvalue.get(); + GPointer gvalue = provider_->get_input(identifier); + BLI_assert(gvalue.is_type()); + return *(const T *)gvalue.get(); + } } /** @@ -183,13 +207,19 @@ class GeoNodeExecParams { template void set_output(StringRef identifier, T &&value) { using StoredT = std::decay_t; - const CPPType &type = CPPType::get>(); + if constexpr (is_stored_as_field_v) { + this->set_output>(identifier, + fn::make_constant_field(std::forward(value))); + } + else { + const CPPType &type = CPPType::get(); #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(value)); - provider_->set_output(identifier, gvalue); + GMutablePointer gvalue = provider_->alloc_output_value(type); + new (gvalue.get()) StoredT(std::forward(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>(); + }; + 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(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>(); + }; + 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(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>(); + }; + 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(blender::fn::make_constant_field(value)); + }; return socktype; } @@ -737,8 +756,14 @@ static bNodeSocketType *make_socket_type_vector(PropertySubType subtype) socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(blender::float3 *)r_value = ((bNodeSocketValueVector *)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>(); + }; + socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) { + blender::float3 value; + socket.typeinfo->get_base_cpp_value(socket, &value); + new (r_value) blender::fn::Field(blender::fn::make_constant_field(value)); + }; return socktype; } @@ -751,8 +776,15 @@ static bNodeSocketType *make_socket_type_rgba() socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) { *(blender::ColorGeometry4f *)r_value = ((bNodeSocketValueRGBA *)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>(); + }; + socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) { + blender::ColorGeometry4f value; + socket.typeinfo->get_base_cpp_value(socket, &value); + new (r_value) + blender::fn::Field(blender::fn::make_constant_field(value)); + }; return socktype; } -- cgit v1.2.3