Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-08-31 12:03:38 +0300
committerJacques Lucke <jacques@blender.org>2021-08-31 12:03:38 +0300
commita55c230b8aeb341deb7d76619d21eb614e7d775f (patch)
tree48ee837379e7b27d9cb866338097ad00fbf9fd92
parent1f1dc4ade307446a9bde561eb478587bdd01fcb2 (diff)
initial support in evaluator
-rw-r--r--source/blender/functions/FN_field.hh25
-rw-r--r--source/blender/functions/intern/field.cc11
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh60
-rw-r--r--source/blender/nodes/intern/node_socket.cc52
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<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::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<blender::fn::Field<blender::float3>>();
+ };
+ 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::float3>(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<blender::fn::Field<blender::ColorGeometry4f>>();
+ };
+ 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::ColorGeometry4f>(blender::fn::make_constant_field(value));
+ };
return socktype;
}