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:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_nodes_evaluator.cc')
-rw-r--r--source/blender/modifiers/intern/MOD_nodes_evaluator.cc63
1 files changed, 42 insertions, 21 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index 5646e37707c..4f21924619b 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -21,6 +21,8 @@
#include "DEG_depsgraph_query.h"
+#include "FN_field.hh"
+#include "FN_field_cpp_type.hh"
#include "FN_generic_value_map.hh"
#include "FN_multi_function.hh"
@@ -33,6 +35,9 @@
namespace blender::modifiers::geometry_nodes {
using fn::CPPType;
+using fn::Field;
+using fn::FieldCPPType;
+using fn::GField;
using fn::GValueMap;
using nodes::GeoNodeExecParams;
using namespace fn::multi_function_types;
@@ -858,11 +863,10 @@ class GeometryNodesEvaluator {
const MultiFunction &fn,
NodeState &node_state)
{
- MFContextBuilder fn_context;
- MFParamsBuilder fn_params{fn, 1};
LinearAllocator<> &allocator = local_allocators_.local();
/* Prepare the inputs for the multi function. */
+ Vector<GField> input_fields;
for (const int i : node->inputs().index_range()) {
const InputSocketRef &socket_ref = node->input(i);
if (!socket_ref.is_available()) {
@@ -873,24 +877,12 @@ class GeometryNodesEvaluator {
BLI_assert(input_state.was_ready_for_execution);
SingleInputValue &single_value = *input_state.value.single;
BLI_assert(single_value.value != nullptr);
- fn_params.add_readonly_single_input(GPointer{*input_state.type, single_value.value});
- }
- /* Prepare the outputs for the multi function. */
- Vector<GMutablePointer> outputs;
- for (const int i : node->outputs().index_range()) {
- const OutputSocketRef &socket_ref = node->output(i);
- if (!socket_ref.is_available()) {
- continue;
- }
- const CPPType &type = *get_socket_cpp_type(socket_ref);
- void *buffer = allocator.allocate(type.size(), type.alignment());
- fn_params.add_uninitialized_single_output(GMutableSpan{type, buffer, 1});
- outputs.append({type, buffer});
+ input_fields.append(std::move(*(GField *)single_value.value));
}
- fn.call(IndexRange(1), fn_params, fn_context);
+ auto operation = std::make_shared<fn::FieldOperation>(fn, std::move(input_fields));
- /* Forward the computed outputs. */
+ /* Forward outputs. */
int output_index = 0;
for (const int i : node->outputs().index_range()) {
const OutputSocketRef &socket_ref = node->output(i);
@@ -899,8 +891,9 @@ class GeometryNodesEvaluator {
}
OutputState &output_state = node_state.outputs[i];
const DOutputSocket socket{node.context(), &socket_ref};
- GMutablePointer value = outputs[output_index];
- this->forward_output(socket, value);
+ const CPPType *cpp_type = get_socket_cpp_type(socket_ref);
+ GField &field = *allocator.construct<GField>(operation, output_index).release();
+ this->forward_output(socket, {cpp_type, &field});
output_state.has_been_computed = true;
output_index++;
}
@@ -922,7 +915,7 @@ class GeometryNodesEvaluator {
OutputState &output_state = node_state.outputs[socket->index()];
output_state.has_been_computed = true;
void *buffer = allocator.allocate(type->size(), type->alignment());
- type->copy_construct(type->default_value(), buffer);
+ this->construct_default_value(*type, buffer);
this->forward_output({node.context(), socket}, {*type, buffer});
}
}
@@ -1389,14 +1382,42 @@ class GeometryNodesEvaluator {
return;
}
+ const FieldCPPType *from_field_type = dynamic_cast<const FieldCPPType *>(&from_type);
+ const FieldCPPType *to_field_type = dynamic_cast<const FieldCPPType *>(&to_type);
+
+ if (from_field_type != nullptr && to_field_type != nullptr) {
+ const CPPType &from_base_type = from_field_type->field_type();
+ const CPPType &to_base_type = to_field_type->field_type();
+ if (conversions_.is_convertible(from_base_type, to_base_type)) {
+ const MultiFunction &fn = *conversions_.get_conversion_multi_function(
+ MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type));
+ const GField &from_field = *(const GField *)from_value;
+ auto operation = std::make_shared<fn::FieldOperation>(fn, Vector<GField>{from_field});
+ new (to_value) GField(std::move(operation), 0);
+ return;
+ }
+ }
if (conversions_.is_convertible(from_type, to_type)) {
/* Do the conversion if possible. */
conversions_.convert_to_uninitialized(from_type, to_type, from_value, to_value);
}
else {
/* Cannot convert, use default value instead. */
- to_type.copy_construct(to_type.default_value(), to_value);
+ this->construct_default_value(to_type, to_value);
+ }
+ }
+
+ void construct_default_value(const CPPType &type, void *r_value)
+ {
+ if (const FieldCPPType *field_cpp_type = dynamic_cast<const FieldCPPType *>(&type)) {
+ const CPPType &base_type = field_cpp_type->field_type();
+ auto constant_fn = std::make_unique<fn::CustomMF_GenericConstant>(base_type,
+ base_type.default_value());
+ auto operation = std::make_shared<fn::FieldOperation>(std::move(constant_fn));
+ new (r_value) GField(std::move(operation), 0);
+ return;
}
+ type.copy_construct(type.default_value(), r_value);
}
NodeState &get_node_state(const DNode node)