[Bf-blender-cvs] [09a5ea059f1] temp-geometry-nodes-fields--fields: Add a slightly more complicated test
Hans Goudey
noreply at git.blender.org
Sat Aug 28 07:41:08 CEST 2021
Commit: 09a5ea059f17527dd76812824f13ef8d2db33fc1
Author: Hans Goudey
Date: Sat Aug 28 00:40:58 2021 -0500
Branches: temp-geometry-nodes-fields--fields
https://developer.blender.org/rB09a5ea059f17527dd76812824f13ef8d2db33fc1
Add a slightly more complicated test
This one doesn't pass, I'll need to debug it
===================================================================
M source/blender/functions/FN_field.hh
M source/blender/functions/intern/field.cc
M source/blender/functions/tests/FN_field_test.cc
===================================================================
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index 0416eb11d50..65220b6a4a8 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -30,6 +30,7 @@
* the embedded multi-function.
*/
+#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
#include "FN_multi_function_procedure.hh"
@@ -38,64 +39,8 @@
namespace blender::fn {
-class Field;
-
-/**
- * An operation acting on data described by fields. Generally corresponds
- * to a node or a subset of a node in a node graph.
- */
-class FieldFunction {
- /**
- * The function used to calculate the
- */
- std::unique_ptr<MultiFunction> function_;
-
- /**
- * References to descriptions of the results from the functions this function depends on.
- */
- blender::Vector<Field *> inputs_;
-
- std::string name_;
-
- public:
- FieldFunction(std::unique_ptr<MultiFunction> function,
- Span<Field *> inputs,
- std::string &&name = "")
- : function_(std::move(function)), inputs_(inputs), name_(std::move(name))
- {
- }
-
- Span<Field *> inputs() const
- {
- return inputs_;
- }
-
- const MultiFunction &multi_function() const
- {
- return *function_;
- }
-
- blender::StringRef name() const
- {
- return name_;
- }
-};
-
-class FieldInput {
- std::string name_;
-
- public:
- FieldInput(std::string &&name = "") : name_(std::move(name))
- {
- }
-
- virtual GVArrayPtr retrieve_data(IndexMask mask) const = 0;
-
- blender::StringRef name() const
- {
- return name_;
- }
-};
+class FieldInput;
+class FieldFunction;
/**
* Descibes the output of a function. Generally corresponds to the combination of an output socket
@@ -121,13 +66,19 @@ class Field {
std::shared_ptr<FieldInput> input_;
+ StringRef name_;
+
public:
- Field(const fn::CPPType &type, std::shared_ptr<FieldFunction> function, const int output_index)
- : type_(&type), function_(function), output_index_(output_index)
+ Field(const fn::CPPType &type,
+ std::shared_ptr<FieldFunction> function,
+ const int output_index,
+ StringRef name = "")
+ : type_(&type), function_(function), output_index_(output_index), name_(name)
{
}
- Field(const fn::CPPType &type, std::shared_ptr<FieldInput> input) : type_(&type), input_(input)
+ Field(const fn::CPPType &type, std::shared_ptr<FieldInput> input, StringRef name = "")
+ : type_(&type), input_(input), name_(name)
{
}
@@ -168,13 +119,47 @@ class Field {
blender::StringRef name() const
{
- if (this->is_function()) {
- return function_->name();
- }
- return input_->name();
+ return name_;
}
};
+/**
+ * An operation acting on data described by fields. Generally corresponds
+ * to a node or a subset of a node in a node graph.
+ */
+class FieldFunction {
+ /**
+ * The function used to calculate the
+ */
+ std::unique_ptr<MultiFunction> function_;
+
+ /**
+ * References to descriptions of the results from the functions this function depends on.
+ */
+ blender::Vector<Field> inputs_;
+
+ public:
+ FieldFunction(std::unique_ptr<MultiFunction> function, Vector<Field> &&inputs)
+ : function_(std::move(function)), inputs_(std::move(inputs))
+ {
+ }
+
+ Span<Field> inputs() const
+ {
+ return inputs_;
+ }
+
+ const MultiFunction &multi_function() const
+ {
+ return *function_;
+ }
+};
+
+class FieldInput {
+ public:
+ virtual GVArrayPtr retrieve_data(IndexMask mask) const = 0;
+};
+
/**
* Evaluate more than one field at a time, as an optimization
* in case they share inputs or various intermediate values.
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index c4148d0fdc1..39a56b1aeaa 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -33,15 +33,15 @@ using VariableMap = Map<const void *, Vector<MFVariable *>>;
*/
using ComputedInputMap = Map<const MFVariable *, GVArrayPtr>;
-static MFVariable *get_field_variable(const Field &field, const VariableMap &variable_map)
+static MFVariable &get_field_variable(const Field &field, const VariableMap &variable_map)
{
if (field.is_input()) {
const FieldInput &input = field.input();
- return variable_map.lookup(&input).first();
+ return *variable_map.lookup(&input).first();
}
const FieldFunction &function = field.function();
const Span<MFVariable *> function_outputs = variable_map.lookup(&function);
- return function_outputs[field.function_output_index()];
+ return *function_outputs[field.function_output_index()];
}
/**
@@ -62,17 +62,17 @@ static void add_field_variables_recursive(const Field &field,
}
else {
const FieldFunction &function = field.function();
- for (const Field *input_field : function.inputs()) {
- add_field_variables_recursive(*input_field, builder, variable_map);
+ for (const Field &input_field : function.inputs()) {
+ add_field_variables_recursive(input_field, builder, variable_map);
}
/* Add the immediate inputs to this field, which were added earlier in the
* recursive call. This will be skipped for functions with no inputs. */
Vector<MFVariable *> inputs;
- for (const Field *input_field : function.inputs()) {
- MFVariable *input = get_field_variable(*input_field, variable_map);
- builder.add_input_parameter(input->data_type(), input_field->name());
- inputs.append(input);
+ for (const Field &input_field : function.inputs()) {
+ MFVariable &input = get_field_variable(input_field, variable_map);
+ builder.add_input_parameter(input.data_type());
+ inputs.append(&input);
}
Vector<MFVariable *> outputs = builder.add_call(function.multi_function(), inputs);
@@ -96,8 +96,8 @@ static void build_procedure(const Span<Field> fields,
builder.add_return();
for (const Field &field : fields) {
- MFVariable *input = get_field_variable(field, variable_map);
- builder.add_output_parameter(*input);
+ MFVariable &input = get_field_variable(field, variable_map);
+ builder.add_output_parameter(input);
}
std::cout << procedure.to_dot();
@@ -122,14 +122,14 @@ static void gather_inputs_recursive(const Field &field,
if (!computed_inputs.contains(variable)) {
GVArrayPtr data = input.retrieve_data(mask);
computed_inputs.add_new(variable);
- params.add_readonly_single_input(*data, input.name());
+ params.add_readonly_single_input(*data, field.name());
r_inputs.append(std::move(data));
}
}
else {
const FieldFunction &function = field.function();
- for (const Field *input_field : function.inputs()) {
- gather_inputs_recursive(*input_field, variable_map, mask, params, computed_inputs, r_inputs);
+ for (const Field &input_field : function.inputs()) {
+ gather_inputs_recursive(input_field, variable_map, mask, params, computed_inputs, r_inputs);
}
}
}
diff --git a/source/blender/functions/tests/FN_field_test.cc b/source/blender/functions/tests/FN_field_test.cc
index 029527249ef..b6b9e84f2f1 100644
--- a/source/blender/functions/tests/FN_field_test.cc
+++ b/source/blender/functions/tests/FN_field_test.cc
@@ -37,7 +37,7 @@ class IndexFieldInput final : public FieldInput {
TEST(field, VArrayInput)
{
- Field index_field = Field(CPPType::get<int>(), std::make_shared<IndexFieldInput>());
+ Field index_field = Field(CPPType::get<int>(), std::make_shared<IndexFieldInput>(), "Index");
Array<int> result_1(4);
GMutableSpan result_generic_1(result_1.as_mutable_span());
@@ -60,8 +60,8 @@ TEST(field, VArrayInput)
TEST(field, VArrayInputMultipleOutputs)
{
std::shared_ptr<FieldInput> index_input = std::make_shared<IndexFieldInput>();
- Field field_1 = Field(CPPType::get<int>(), index_input);
- Field field_2 = Field(CPPType::get<int>(), index_input);
+ Field field_1 = Field(CPPType::get<int>(), index_input, "Index");
+ Field field_2 = Field(CPPType::get<int>(), index_input, "Index");
Array<int> result_1(10);
Array<int> result_2(10);
@@ -69,10 +69,38 @@ TEST(field, VArrayInputMultipleOutputs)
GMutableSpan result_generic_2(result_2.as_mutable_span());
evaluate_fields({field_1, field_2}, {2, 4, 6, 8}, {result_generic_1, result_generic_2});
+ EXPECT_EQ(result_1[2], 2);
+ EXPECT_EQ(result_1[4], 4);
+ EXPECT_EQ(result_1[6], 6);
+ EXPECT_EQ(result_1[8], 8);
EXPECT_EQ(result_2[2], 2);
EXPECT_EQ(result_2[4], 4);
EXPECT_EQ(result_2[6], 6);
EXPECT_EQ(result_2[8], 8);
}
+TEST(field, InputAndFunction)
+{
+ Field index_field = Field(CPPType::get<int>(), std::make_shared<IndexFieldInput>(), "Index");
+
+ Field output_field = Field(CPPType::get<int>(),
+ std::make_shared<FieldFunction>(
+ FieldFunction(std::make_unique<CustomMF_SI_SI_SO<int, int, int>>(
+ "add", [](int a, int b) { return a + b; }),
+ {index_field, index_field})),
+ 0);
+
+ std::shared_ptr<FieldInput> index_input = std::make_shared<IndexFieldInput>();
+ Field field_1 = Field(CPPType::get<int>(), index_input);
+ Field field_2 = Field(CPPType::get<int>(), index_input);
+
+ Array<int> result(10);
+ GMutableSpan result_generic(result.as_mutable_span());
+ evaluate_fields({output_field}, {2, 4, 6, 8}, {result_generic});
+ EXPECT_EQ(result[2], 4);
+ EXPECT_EQ(result[4], 8);
+ EXPECT_EQ(result[6], 12);
+ EXPECT_EQ(result[8], 16);
+}
+
} // namespace blender::fn::tests
More information about the Bf-blender-cvs
mailing list