[Bf-blender-cvs] [c1cab4aa685] temp-geometry-nodes-fields--fields-jacques: add common base class for field input/operation
Jacques Lucke
noreply at git.blender.org
Wed Sep 1 11:39:26 CEST 2021
Commit: c1cab4aa685fa40bc98fcf4c94f25000ec810315
Author: Jacques Lucke
Date: Wed Sep 1 11:39:18 2021 +0200
Branches: temp-geometry-nodes-fields--fields-jacques
https://developer.blender.org/rBc1cab4aa685fa40bc98fcf4c94f25000ec810315
add common base class for field input/operation
===================================================================
M source/blender/functions/FN_field.hh
M source/blender/functions/intern/field.cc
M source/blender/functions/tests/FN_field_test.cc
M source/blender/modifiers/intern/MOD_nodes_evaluator.cc
M source/blender/nodes/NOD_geometry_exec.hh
===================================================================
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index 4b0dee88491..9217d98d75b 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -41,69 +41,57 @@
namespace blender::fn {
-class FieldInput;
-class FieldFunction;
+class FieldSource {
+ public:
+ ~FieldSource() = default;
+
+ virtual const CPPType &cpp_type_of_output_index(int output_index) const = 0;
+
+ virtual bool is_input() const
+ {
+ return false;
+ }
+};
/**
* Descibes the output of a function. Generally corresponds to the combination of an output socket
* and link combination in a node graph.
*/
class GField {
- /**
- * The function that calculates this field's values. Many fields can share the same function,
- * since a function can have many outputs, just like a node graph, where a single output can be
- * used as multiple inputs. This avoids calling the same function many times, only using one of
- * its results.
- */
- std::shared_ptr<FieldFunction> function_;
- /**
- * Which output of the function this field corresponds to.
- */
- int output_index_ = 0;
-
- std::shared_ptr<FieldInput> input_;
+ std::shared_ptr<FieldSource> source_;
+ int source_output_index_ = 0;
public:
GField() = default;
- GField(std::shared_ptr<FieldFunction> function, const int output_index)
- : function_(std::move(function)), output_index_(output_index)
+ GField(std::shared_ptr<FieldSource> source, const int source_output_index = 0)
+ : source_(std::move(source)), source_output_index_(source_output_index)
{
}
- GField(std::shared_ptr<FieldInput> input) : input_(std::move(input))
+ operator bool() const
{
+ return source_ != nullptr;
}
- const fn::CPPType &cpp_type() const;
-
- bool is_input() const
- {
- return input_.get() != nullptr;
- }
- const FieldInput &input() const
+ const fn::CPPType &cpp_type() const
{
- BLI_assert(!function_);
- BLI_assert(input_);
- return *input_;
+ return source_->cpp_type_of_output_index(source_output_index_);
}
- bool is_function() const
+ bool is_input() const
{
- return function_.get() != nullptr;
+ return source_->is_input();
}
- const FieldFunction &function() const
+
+ const FieldSource &source() const
{
- BLI_assert(function_ != nullptr);
- BLI_assert(input_ == nullptr);
- return *function_;
+ return *source_;
}
- int function_output_index() const
+ int source_output_index() const
{
- BLI_assert(function_ != nullptr);
- BLI_assert(input_ == nullptr);
- return output_index_;
+ return source_output_index_;
}
};
@@ -117,30 +105,20 @@ template<typename T> class Field : public GField {
}
};
-/**
- * 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 field.
- */
+class FieldOperation : public FieldSource {
std::unique_ptr<const MultiFunction> owned_function_;
const MultiFunction *function_;
- /**
- * References to descriptions of the results from the functions this function depends on.
- */
blender::Vector<GField> inputs_;
public:
- FieldFunction(std::unique_ptr<const MultiFunction> function, Vector<GField> inputs = {})
+ FieldOperation(std::unique_ptr<const MultiFunction> function, Vector<GField> inputs = {})
: owned_function_(std::move(function)), inputs_(std::move(inputs))
{
function_ = owned_function_.get();
}
- FieldFunction(const MultiFunction &function, Vector<GField> inputs = {})
+ FieldOperation(const MultiFunction &function, Vector<GField> inputs = {})
: function_(&function), inputs_(std::move(inputs))
{
}
@@ -155,7 +133,7 @@ class FieldFunction {
return *function_;
}
- const CPPType &cpp_type_of_output_index(int output_index) const
+ const CPPType &cpp_type_of_output_index(int output_index) const override
{
int output_counter = 0;
for (const int param_index : function_->param_indices()) {
@@ -172,7 +150,7 @@ class FieldFunction {
}
};
-class FieldInput {
+class FieldInput : public FieldSource {
protected:
const CPPType *type_;
std::string debug_name_;
@@ -194,6 +172,17 @@ class FieldInput {
{
return *type_;
}
+
+ const CPPType &cpp_type_of_output_index(int output_index) const override
+ {
+ BLI_assert(output_index == 0);
+ return *type_;
+ }
+
+ bool is_input() const override
+ {
+ return true;
+ }
};
/**
@@ -216,20 +205,8 @@ template<typename T> T evaluate_constant_field(const Field<T> &field)
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.
- */
-
-inline const CPPType &GField::cpp_type() const
-{
- if (this->is_function()) {
- return function_->cpp_type_of_output_index(output_index_);
- }
- return input_->cpp_type();
+ auto operation = std::make_shared<FieldOperation>(std::move(constant_fn));
+ return Field<T>{GField{std::move(operation), 0}};
}
} // namespace blender::fn
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 69a31699592..87cfc60d502 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -20,60 +20,12 @@
#include "FN_field.hh"
-/**
- * TODO: There might be a more obvious way to implement this, or we might end up with
- * a separate map for functions and inputs anyway, so we could just remove it.
- */
-struct InputOrFunction {
- const void *ptr;
-
- public:
- InputOrFunction(const blender::fn::FieldFunction &function) : ptr(&function)
- {
- }
- InputOrFunction(const blender::fn::FieldInput &input) : ptr(&input)
- {
- }
- InputOrFunction(const blender::fn::GField &field) /* Maybe this is too clever. */
- {
- if (field.is_function()) {
- ptr = &field.function();
- }
- else {
- ptr = &field.input();
- }
- }
- friend bool operator==(const InputOrFunction &a, const InputOrFunction &b)
- {
- return a.ptr == b.ptr;
- }
-};
-
-template<> struct blender::DefaultHash<InputOrFunction> {
- uint64_t operator()(const InputOrFunction &value) const
- {
- return DefaultHash<const void *>{}(value.ptr);
- }
-};
-
namespace blender::fn {
-/**
- * TODO: This exists because it seemed helpful for the procedure creation to be able to store
- * mutable data for each input or function output. That still may be helpful in the future, but
- * currently it isn't useful.
- */
-struct FieldVariable {
- MFVariable *mf_variable;
- FieldVariable(MFVariable &variable) : mf_variable(&variable)
- {
- }
-};
-
/**
* A map to hold the output variables for each function output or input so they can be reused.
*/
-using VariableMap = Map<InputOrFunction, Vector<FieldVariable>>;
+using VariableMap = Map<const FieldSource *, Vector<MFVariable *>>;
/**
* A map of the computed inputs for all of a field system's inputs, to avoid creating duplicates.
@@ -81,27 +33,27 @@ using VariableMap = Map<InputOrFunction, Vector<FieldVariable>>;
*/
using ComputedInputMap = Map<const MFVariable *, GVArrayPtr>;
-static FieldVariable &get_field_variable(const GField &field, VariableMap &unique_variables)
+static MFVariable &get_field_variable(const GField &field, VariableMap &unique_variables)
{
if (field.is_input()) {
- const FieldInput &input = field.input();
- return unique_variables.lookup(input).first();
+ const FieldInput &input = dynamic_cast<const FieldInput &>(field.source());
+ return *unique_variables.lookup(&input).first();
}
- const FieldFunction &function = field.function();
- MutableSpan<FieldVariable> function_outputs = unique_variables.lookup(function);
- return function_outputs[field.function_output_index()];
+ const FieldOperation &operation = dynamic_cast<const FieldOperation &>(field.source());
+ MutableSpan<MFVariable *> operation_outputs = unique_variables.lookup(&operation);
+ return *operation_outputs[field.source_output_index()];
}
-static const FieldVariable &get_field_variable(const GField &field,
- const VariableMap &unique_variables)
+static const MFVariable &get_field_variable(const GField &field,
+ const VariableMap &unique_variables)
{
if (field.is_input()) {
- const FieldInput &input = field.input();
- return unique_variables.lookup(input).first();
+ const FieldInput &input = dynamic_cast<const FieldInput &>(field.source());
+ return *unique_variables.lookup(&input).first();
}
- const FieldFunction &function = field.function();
- Span<FieldVariable> function_outputs = unique_variables.lookup(function);
- return function_outputs[field.function_output_index()];
+ const FieldOperation &operation = dynamic_cast<const FieldOperation &>(field.source());
+ Span<MFVariable *> operation_outputs = unique_variables.lookup(&operation);
+ return *operation_outputs[field.source_output_index()];
}
/**
@@ -113,20 +65,20 @@ static void add_variables_for_input(const GField &field,
VariableMap &unique_variables)
{
fields_to_visit.pop();
- const FieldInput &input = field.input();
+ const FieldInput &input = dynamic_cast<const FieldInput &>(field.source());
MFVariable &variable = builder.add_input_parameter(MFDataType::ForSingle(field.cpp_type()),
input.debug_name());
- unique_variables.add(input, {variable});
+ unique_variables.add(&input, {&variable});
}
-static void add_variables_for_function(const GField &field,
- Stack<const GField *> &fields_to_visit,
- MFProcedureBuilder &builder,
- VariableMa
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list