Functions: introduce multi-function namespace

This moves all multi-function related code in the `functions` module
into a new `multi_function` namespace. This is similar to how there
is a `lazy_function` namespace.

The main benefit of this is that many types names that were prefixed
with `MF` (for "multi function") can be simplified.

There is also a common shorthand for the `multi_function` namespace: `mf`.
This is also similar to lazy-functions where the shortened namespace
is called `lf`.
This commit is contained in:
2023-01-07 17:32:28 +01:00
parent a5b27f9858
commit eedcf1876a
87 changed files with 1437 additions and 1459 deletions

View File

@@ -17,7 +17,9 @@
struct Mesh;
struct PointCloud;
namespace blender::fn {
namespace multi_function {
class MultiFunction;
}
class GField;
} // namespace blender::fn
@@ -174,7 +176,7 @@ struct AttributeValidator {
/**
* Single input, single output function that corrects attribute values if necessary.
*/
const fn::MultiFunction *function;
const fn::multi_function::MultiFunction *function;
operator bool() const
{

View File

@@ -107,9 +107,6 @@ class GeoNodeExecParams;
class NodeDeclarationBuilder;
class GatherLinkSearchOpParams;
} // namespace nodes
namespace fn {
class MFDataType;
} // namespace fn
namespace realtime_compositor {
class Context;
class NodeOperation;

View File

@@ -8,19 +8,19 @@
namespace blender::bke {
struct ConversionFunctions {
const fn::MultiFunction *multi_function;
const mf::MultiFunction *multi_function;
void (*convert_single_to_initialized)(const void *src, void *dst);
void (*convert_single_to_uninitialized)(const void *src, void *dst);
};
class DataTypeConversions {
private:
Map<std::pair<fn::MFDataType, fn::MFDataType>, ConversionFunctions> conversions_;
Map<std::pair<mf::DataType, mf::DataType>, ConversionFunctions> conversions_;
public:
void add(fn::MFDataType from_type,
fn::MFDataType to_type,
const fn::MultiFunction &fn,
void add(mf::DataType from_type,
mf::DataType to_type,
const mf::MultiFunction &fn,
void (*convert_single_to_initialized)(const void *src, void *dst),
void (*convert_single_to_uninitialized)(const void *src, void *dst))
{
@@ -28,19 +28,18 @@ class DataTypeConversions {
{&fn, convert_single_to_initialized, convert_single_to_uninitialized});
}
const ConversionFunctions *get_conversion_functions(fn::MFDataType from, fn::MFDataType to) const
const ConversionFunctions *get_conversion_functions(mf::DataType from, mf::DataType to) const
{
return conversions_.lookup_ptr({from, to});
}
const ConversionFunctions *get_conversion_functions(const CPPType &from, const CPPType &to) const
{
return this->get_conversion_functions(fn::MFDataType::ForSingle(from),
fn::MFDataType::ForSingle(to));
return this->get_conversion_functions(mf::DataType::ForSingle(from),
mf::DataType::ForSingle(to));
}
const fn::MultiFunction *get_conversion_multi_function(fn::MFDataType from,
fn::MFDataType to) const
const mf::MultiFunction *get_conversion_multi_function(mf::DataType from, mf::DataType to) const
{
const ConversionFunctions *functions = this->get_conversion_functions(from, to);
return functions ? functions->multi_function : nullptr;
@@ -49,7 +48,7 @@ class DataTypeConversions {
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
{
return conversions_.contains(
{fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type)});
{mf::DataType::ForSingle(from_type), mf::DataType::ForSingle(to_type)});
}
void convert_to_uninitialized(const CPPType &from_type,

View File

@@ -440,12 +440,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
make_array_write_attribute<float3>,
tag_component_positions_changed);
static auto handle_type_clamp = fn::build_mf::SI1_SO<int8_t, int8_t>(
static auto handle_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
"Handle Type Validate",
[](int8_t value) {
return std::clamp<int8_t>(value, BEZIER_HANDLE_FREE, BEZIER_HANDLE_ALIGN);
},
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider handle_type_right("handle_type_right",
ATTR_DOMAIN_POINT,
CD_PROP_INT8,
@@ -484,10 +484,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
make_array_write_attribute<float>,
tag_component_positions_changed);
static const auto nurbs_order_clamp = fn::build_mf::SI1_SO<int8_t, int8_t>(
static const auto nurbs_order_clamp = mf::build::SI1_SO<int8_t, int8_t>(
"NURBS Order Validate",
[](int8_t value) { return std::max<int8_t>(value, 0); },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider nurbs_order("nurbs_order",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -501,12 +501,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
tag_component_topology_changed,
AttributeValidator{&nurbs_order_clamp});
static const auto normal_mode_clamp = fn::build_mf::SI1_SO<int8_t, int8_t>(
static const auto normal_mode_clamp = mf::build::SI1_SO<int8_t, int8_t>(
"Normal Mode Validate",
[](int8_t value) {
return std::clamp<int8_t>(value, NORMAL_MODE_MINIMUM_TWIST, NORMAL_MODE_Z_UP);
},
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider normal_mode("normal_mode",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -520,12 +520,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
tag_component_normals_changed,
AttributeValidator{&normal_mode_clamp});
static const auto knots_mode_clamp = fn::build_mf::SI1_SO<int8_t, int8_t>(
static const auto knots_mode_clamp = mf::build::SI1_SO<int8_t, int8_t>(
"Knots Mode Validate",
[](int8_t value) {
return std::clamp<int8_t>(value, NURBS_KNOT_MODE_NORMAL, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
},
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider nurbs_knots_mode("knots_mode",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -539,12 +539,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
tag_component_topology_changed,
AttributeValidator{&knots_mode_clamp});
static const auto curve_type_clamp = fn::build_mf::SI1_SO<int8_t, int8_t>(
static const auto curve_type_clamp = mf::build::SI1_SO<int8_t, int8_t>(
"Curve Type Validate",
[](int8_t value) {
return std::clamp<int8_t>(value, CURVE_TYPE_CATMULL_ROM, CURVE_TYPES_NUM);
},
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider curve_type("curve_type",
ATTR_DOMAIN_CURVE,
CD_PROP_INT8,
@@ -558,10 +558,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve()
tag_component_curve_types_changed,
AttributeValidator{&curve_type_clamp});
static const auto resolution_clamp = fn::build_mf::SI1_SO<int, int>(
static const auto resolution_clamp = mf::build::SI1_SO<int, int>(
"Resolution Validate",
[](int value) { return std::max<int>(value, 1); },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider resolution("resolution",
ATTR_DOMAIN_CURVE,
CD_PROP_INT32,

View File

@@ -1264,13 +1264,13 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
make_array_write_attribute<int>,
nullptr);
static const auto material_index_clamp = fn::build_mf::SI1_SO<int, int>(
static const auto material_index_clamp = mf::build::SI1_SO<int, int>(
"Material Index Validate",
[](int value) {
/* Use #short for the maximum since many areas still use that type for indices. */
return std::clamp<int>(value, 0, std::numeric_limits<short>::max());
},
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static BuiltinCustomDataLayerProvider material_index("material_index",
ATTR_DOMAIN_FACE,
CD_PROP_INT32,

View File

@@ -11,7 +11,7 @@
namespace blender::bke {
using fn::MFDataType;
using mf::DataType;
template<typename From, typename To, To (*ConversionF)(const From &)>
static void add_implicit_conversion(DataTypeConversions &conversions)
@@ -20,20 +20,20 @@ static void add_implicit_conversion(DataTypeConversions &conversions)
static const CPPType &to_type = CPPType::get<To>();
static const std::string conversion_name = from_type.name() + " to " + to_type.name();
static auto multi_function = fn::build_mf::SI1_SO<From, To>(
static auto multi_function = mf::build::SI1_SO<From, To>(
conversion_name.c_str(),
/* Use lambda instead of passing #ConversionF directly, because otherwise the compiler won't
* inline the function. */
[](const From &a) { return ConversionF(a); },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
static auto convert_single_to_initialized = [](const void *src, void *dst) {
*(To *)dst = ConversionF(*(const From *)src);
};
static auto convert_single_to_uninitialized = [](const void *src, void *dst) {
new (dst) To(ConversionF(*(const From *)src));
};
conversions.add(fn::MFDataType::ForSingle<From>(),
fn::MFDataType::ForSingle<To>(),
conversions.add(mf::DataType::ForSingle<From>(),
mf::DataType::ForSingle<To>(),
multi_function,
convert_single_to_initialized,
convert_single_to_uninitialized);
@@ -361,26 +361,26 @@ void DataTypeConversions::convert_to_uninitialized(const CPPType &from_type,
}
const ConversionFunctions *functions = this->get_conversion_functions(
MFDataType::ForSingle(from_type), MFDataType::ForSingle(to_type));
DataType::ForSingle(from_type), DataType::ForSingle(to_type));
BLI_assert(functions != nullptr);
functions->convert_single_to_uninitialized(from_value, to_value);
}
static void call_convert_to_uninitialized_fn(const GVArray &from,
const fn::MultiFunction &fn,
const mf::MultiFunction &fn,
const IndexMask mask,
GMutableSpan to)
{
fn::MFParamsBuilder params{fn, mask.min_array_size()};
mf::ParamsBuilder params{fn, mask.min_array_size()};
params.add_readonly_single_input(from);
params.add_uninitialized_single_output(to);
fn::MFContextBuilder context;
mf::ContextBuilder context;
fn.call_auto(mask, params, context);
}
static void call_convert_to_uninitialized_fn(const GVArray &from,
const fn::MultiFunction &fn,
const mf::MultiFunction &fn,
GMutableSpan to)
{
call_convert_to_uninitialized_fn(from, fn, IndexMask(from.size()), to);
@@ -394,8 +394,8 @@ void DataTypeConversions::convert_to_initialized_n(GSpan from_span, GMutableSpan
BLI_assert(from_span.size() == to_span.size());
BLI_assert(this->is_convertible(from_type, to_type));
const fn::MultiFunction *fn = this->get_conversion_multi_function(
MFDataType::ForSingle(from_type), MFDataType::ForSingle(to_type));
const mf::MultiFunction *fn = this->get_conversion_multi_function(DataType::ForSingle(from_type),
DataType::ForSingle(to_type));
to_type.destruct_n(to_span.data(), to_span.size());
call_convert_to_uninitialized_fn(GVArray::ForSpan(from_span), *fn, to_span);
@@ -541,8 +541,8 @@ fn::GField DataTypeConversions::try_convert(fn::GField field, const CPPType &to_
if (!this->is_convertible(from_type, to_type)) {
return {};
}
const fn::MultiFunction &fn = *this->get_conversion_multi_function(
fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type));
const mf::MultiFunction &fn = *this->get_conversion_multi_function(
mf::DataType::ForSingle(from_type), mf::DataType::ForSingle(to_type));
return {std::make_shared<fn::FieldOperation>(fn, Vector<fn::GField>{std::move(field)})};
}

View File

@@ -212,28 +212,28 @@ class FieldOperation : public FieldNode {
* The multi-function used by this node. It is optionally owned.
* Multi-functions with mutable or vector parameters are not supported currently.
*/
std::shared_ptr<const MultiFunction> owned_function_;
const MultiFunction *function_;
std::shared_ptr<const mf::MultiFunction> owned_function_;
const mf::MultiFunction *function_;
/** Inputs to the operation. */
blender::Vector<GField> inputs_;
public:
FieldOperation(std::shared_ptr<const MultiFunction> function, Vector<GField> inputs = {});
FieldOperation(const MultiFunction &function, Vector<GField> inputs = {});
FieldOperation(std::shared_ptr<const mf::MultiFunction> function, Vector<GField> inputs = {});
FieldOperation(const mf::MultiFunction &function, Vector<GField> inputs = {});
~FieldOperation();
Span<GField> inputs() const;
const MultiFunction &multi_function() const;
const mf::MultiFunction &multi_function() const;
const CPPType &output_cpp_type(int output_index) const override;
static std::shared_ptr<FieldOperation> Create(std::shared_ptr<const MultiFunction> function,
static std::shared_ptr<FieldOperation> Create(std::shared_ptr<const mf::MultiFunction> function,
Vector<GField> inputs = {})
{
return std::make_shared<FieldOperation>(FieldOperation(std::move(function), inputs));
}
static std::shared_ptr<FieldOperation> Create(const MultiFunction &function,
static std::shared_ptr<FieldOperation> Create(const mf::MultiFunction &function,
Vector<GField> inputs = {})
{
return std::make_shared<FieldOperation>(FieldOperation(function, inputs));
@@ -640,7 +640,7 @@ inline Span<GField> FieldOperation::inputs() const
return inputs_;
}
inline const MultiFunction &FieldOperation::multi_function() const
inline const mf::MultiFunction &FieldOperation::multi_function() const
{
return *function_;
}
@@ -649,7 +649,7 @@ inline const CPPType &FieldOperation::output_cpp_type(int output_index) const
{
int output_counter = 0;
for (const int param_index : function_->param_indices()) {
MFParamType param_type = function_->param_type(param_index);
mf::ParamType param_type = function_->param_type(param_index);
if (param_type.is_output()) {
if (output_counter == output_index) {
return param_type.data_type().single_type();

View File

@@ -470,3 +470,7 @@ inline void Params::assert_valid_thread() const
/** \} */
} // namespace blender::fn::lazy_function
namespace blender {
namespace lf = fn::lazy_function;
}

View File

@@ -22,7 +22,7 @@
* arrays are not owned by MFParams.
* - `IndexMask`: An array of indices indicating which indices in the provided arrays should be
* touched/processed.
* - `MFContext`: Further information for the called function.
* - `Context`: Further information for the called function.
*
* A new multi-function is generally implemented as follows:
* 1. Create a new subclass of MultiFunction.
@@ -35,11 +35,11 @@
#include "FN_multi_function_context.hh"
#include "FN_multi_function_params.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
class MultiFunction {
private:
const MFSignature *signature_ref_ = nullptr;
const Signature *signature_ref_ = nullptr;
public:
virtual ~MultiFunction()
@@ -52,8 +52,8 @@ class MultiFunction {
* - Automatic index mask offsetting to avoid large temporary intermediate arrays that are mostly
* unused.
*/
void call_auto(IndexMask mask, MFParams params, MFContext context) const;
virtual void call(IndexMask mask, MFParams params, MFContext context) const = 0;
void call_auto(IndexMask mask, MFParams params, Context context) const;
virtual void call(IndexMask mask, MFParams params, Context context) const = 0;
virtual uint64_t hash() const
{
@@ -75,7 +75,7 @@ class MultiFunction {
return signature_ref_->params.index_range();
}
MFParamType param_type(int param_index) const
ParamType param_type(int param_index) const
{
return signature_ref_->params[param_index].type;
}
@@ -92,7 +92,7 @@ class MultiFunction {
virtual std::string debug_name() const;
const MFSignature &signature() const
const Signature &signature() const
{
BLI_assert(signature_ref_ != nullptr);
return *signature_ref_;
@@ -128,7 +128,7 @@ class MultiFunction {
* child classes. No copy of the signature is made, so the caller has to make sure that the
* signature lives as long as the multi function. It is ok to embed the signature into the child
* class. */
void set_signature(const MFSignature *signature)
void set_signature(const Signature *signature)
{
/* Take a pointer as argument, so that it is more obvious that no copy is created. */
BLI_assert(signature != nullptr);
@@ -138,25 +138,18 @@ class MultiFunction {
virtual ExecutionHints get_execution_hints() const;
};
inline MFParamsBuilder::MFParamsBuilder(const MultiFunction &fn, int64_t mask_size)
: MFParamsBuilder(fn.signature(), IndexMask(mask_size))
inline ParamsBuilder::ParamsBuilder(const MultiFunction &fn, int64_t mask_size)
: ParamsBuilder(fn.signature(), IndexMask(mask_size))
{
}
inline MFParamsBuilder::MFParamsBuilder(const MultiFunction &fn, const IndexMask *mask)
: MFParamsBuilder(fn.signature(), *mask)
inline ParamsBuilder::ParamsBuilder(const MultiFunction &fn, const IndexMask *mask)
: ParamsBuilder(fn.signature(), *mask)
{
}
namespace multi_function_types {
using fn::MFContext;
using fn::MFContextBuilder;
using fn::MFDataType;
using fn::MFParamCategory;
using fn::MFParams;
using fn::MFParamsBuilder;
using fn::MFParamType;
using fn::MultiFunction;
} // namespace multi_function_types
} // namespace blender::fn::multi_function
} // namespace blender::fn
namespace blender {
namespace mf = fn::multi_function;
}

View File

@@ -10,7 +10,7 @@
#include "FN_multi_function.hh"
namespace blender::fn::build_mf {
namespace blender::fn::multi_function::build {
/**
* These presets determine what code is generated for a #CustomMF. Different presets make different
@@ -66,13 +66,13 @@ struct AllSpanOrSingle {
return std::make_tuple(IndexMaskDevirtualizer<true, true>{mask}, [&]() {
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
return GVArrayDevirtualizer<T, true, true>{varray_impl};
}
else if constexpr (ELEM(ParamTag::category,
MFParamCategory::SingleOutput,
MFParamCategory::SingleMutable)) {
ParamCategory::SingleOutput,
ParamCategory::SingleMutable)) {
T *ptr = std::get<I>(loaded_params);
return BasicDevirtualizer<T *>{ptr};
}
@@ -99,14 +99,14 @@ template<size_t... Indices> struct SomeSpanOrSingle {
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
constexpr bool UseSpan = ValueSequence<size_t, Indices...>::template contains<I>();
const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
return GVArrayDevirtualizer<T, true, UseSpan>{varray_impl};
}
else if constexpr (ELEM(ParamTag::category,
MFParamCategory::SingleOutput,
MFParamCategory::SingleMutable)) {
ParamCategory::SingleOutput,
ParamCategory::SingleMutable)) {
T *ptr = std::get<I>(loaded_params);
return BasicDevirtualizer<T *>{ptr};
}
@@ -135,16 +135,16 @@ void execute_array(TypeSequence<ParamTags...> /*param_tags*/,
for (const int64_t i : mask) {
element_fn([&]() -> decltype(auto) {
using ParamTag = typename TypeSequence<ParamTags...>::template at_index<I>;
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
/* For inputs, pass the value (or a reference to it) to the function. */
return args[i];
}
else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) {
else if constexpr (ParamTag::category == ParamCategory::SingleOutput) {
/* For outputs, pass a pointer to the function. This is done instead of passing a
* reference, because the pointer points to uninitialized memory. */
return args + i;
}
else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) {
else if constexpr (ParamTag::category == ParamCategory::SingleMutable) {
/* For mutables, pass a mutable reference to the function. */
return args[i];
}
@@ -180,13 +180,13 @@ void execute_materialized_impl(TypeSequence<ParamTags...> /*param_tags*/,
const int64_t out_i = out_mask[i];
element_fn([&]() -> decltype(auto) {
using ParamTag = ParamTags;
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
return chunks[in_i];
}
else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) {
else if constexpr (ParamTag::category == ParamCategory::SingleOutput) {
return chunks + out_i;
}
else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) {
else if constexpr (ParamTag::category == ParamCategory::SingleMutable) {
return chunks[out_i];
}
}()...);
@@ -230,7 +230,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
[[maybe_unused]] MaterializeArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
const CommonVArrayInfo common_info = varray_impl.common_info();
if (common_info.type == CommonVArrayInfo::Type::Single) {
@@ -269,7 +269,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
using ParamTag = ParamTags;
using T = typename ParamTag::base_type;
[[maybe_unused]] MaterializeArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
if (arg_info.mode == MaterializeArgMode::Single) {
/* The single value has been filled into a buffer already reused for every chunk. */
return Span<T>(std::get<I>(buffers));
@@ -296,8 +296,8 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
}
}
else if constexpr (ELEM(ParamTag::category,
MFParamCategory::SingleOutput,
MFParamCategory::SingleMutable)) {
ParamCategory::SingleOutput,
ParamCategory::SingleMutable)) {
/* For outputs, just pass a pointer. This is important so that `__restrict` works. */
return std::get<I>(loaded_params);
}
@@ -310,7 +310,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
[[maybe_unused]] MaterializeArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
if (arg_info.mode == MaterializeArgMode::Materialized) {
T *in_chunk = std::get<I>(buffers_owner).ptr();
destruct_n(in_chunk, chunk_size);
@@ -327,7 +327,7 @@ void execute_materialized(TypeSequence<ParamTags...> /* param_tags */,
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
[[maybe_unused]] MaterializeArgInfo<ParamTags> &arg_info = std::get<I>(args_info);
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
if (arg_info.mode == MaterializeArgMode::Single) {
MutableSpan<T> in_chunk = std::get<I>(buffers);
destruct_n(in_chunk.data(), in_chunk.size());
@@ -353,13 +353,13 @@ inline void execute_element_fn_as_multi_function(const ElementFn element_fn,
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
return params.readonly_single_input(I).get_implementation();
}
else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) {
else if constexpr (ParamTag::category == ParamCategory::SingleOutput) {
return static_cast<T *>(params.uninitialized_single_output(I).data());
}
else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) {
else if constexpr (ParamTag::category == ParamCategory::SingleMutable) {
return static_cast<T *>(params.single_mutable(I).data());
}
}()...);
@@ -397,13 +397,13 @@ inline void execute_element_fn_as_multi_function(const ElementFn element_fn,
/* Use `typedef` instead of `using` to work around a compiler bug. */
typedef ParamTags ParamTag;
typedef typename ParamTag::base_type T;
if constexpr (ParamTag::category == MFParamCategory::SingleInput) {
if constexpr (ParamTag::category == ParamCategory::SingleInput) {
const GVArrayImpl &varray_impl = *std::get<I>(loaded_params);
return GVArray(&varray_impl).typed<T>();
}
else if constexpr (ELEM(ParamTag::category,
MFParamCategory::SingleOutput,
MFParamCategory::SingleMutable)) {
ParamCategory::SingleOutput,
ParamCategory::SingleMutable)) {
T *ptr = std::get<I>(loaded_params);
return ptr;
}
@@ -438,20 +438,20 @@ inline auto build_multi_function_call_from_element_fn(const ElementFn element_fn
*/
template<typename CallFn, typename... ParamTags> class CustomMF : public MultiFunction {
private:
MFSignature signature_;
Signature signature_;
CallFn call_fn_;
public:
CustomMF(const char *name, CallFn call_fn, TypeSequence<ParamTags...> /*param_tags*/)
: call_fn_(std::move(call_fn))
{
MFSignatureBuilder builder{name, signature_};
SignatureBuilder builder{name, signature_};
/* Loop over all parameter types and add an entry for each in the signature. */
([&] { builder.add(ParamTags(), ""); }(), ...);
this->set_signature(&signature_);
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
call_fn_(mask, params);
}
@@ -463,8 +463,8 @@ inline auto build_multi_function_with_n_inputs_one_output(const char *name,
const ExecPreset exec_preset,
TypeSequence<In...> /*in_types*/)
{
constexpr auto param_tags = TypeSequence<MFParamTag<MFParamCategory::SingleInput, In>...,
MFParamTag<MFParamCategory::SingleOutput, Out>>();
constexpr auto param_tags = TypeSequence<MFParamTag<ParamCategory::SingleInput, In>...,
MFParamTag<ParamCategory::SingleOutput, Out>>();
auto call_fn = build_multi_function_call_from_element_fn(
[element_fn](const In &...in, Out *out) { new (out) Out(element_fn(in...)); },
exec_preset,
@@ -573,15 +573,15 @@ inline auto SM(const char *name,
const ElementFn element_fn,
const ExecPreset exec_preset = exec_presets::AllSpanOrSingle())
{
constexpr auto param_tags = TypeSequence<MFParamTag<MFParamCategory::SingleMutable, Mut1>>();
constexpr auto param_tags = TypeSequence<MFParamTag<ParamCategory::SingleMutable, Mut1>>();
auto call_fn = detail::build_multi_function_call_from_element_fn(
element_fn, exec_preset, param_tags);
return detail::CustomMF(name, call_fn, param_tags);
}
} // namespace blender::fn::build_mf
} // namespace blender::fn::multi_function::build
namespace blender::fn {
namespace blender::fn::multi_function {
/**
* A multi-function that outputs the same value every time. The value is not owned by an instance
@@ -592,7 +592,7 @@ class CustomMF_GenericConstant : public MultiFunction {
private:
const CPPType &type_;
const void *value_;
MFSignature signature_;
Signature signature_;
bool owns_value_;
template<typename T> friend class CustomMF_Constant;
@@ -600,7 +600,7 @@ class CustomMF_GenericConstant : public MultiFunction {
public:
CustomMF_GenericConstant(const CPPType &type, const void *value, bool make_value_copy);
~CustomMF_GenericConstant();
void call(IndexMask mask, MFParams params, MFContext context) const override;
void call(IndexMask mask, MFParams params, Context context) const override;
uint64_t hash() const override;
bool equals(const MultiFunction &other) const override;
};
@@ -612,11 +612,11 @@ class CustomMF_GenericConstant : public MultiFunction {
class CustomMF_GenericConstantArray : public MultiFunction {
private:
GSpan array_;
MFSignature signature_;
Signature signature_;
public:
CustomMF_GenericConstantArray(GSpan array);
void call(IndexMask mask, MFParams params, MFContext context) const override;
void call(IndexMask mask, MFParams params, Context context) const override;
};
/**
@@ -625,17 +625,17 @@ class CustomMF_GenericConstantArray : public MultiFunction {
template<typename T> class CustomMF_Constant : public MultiFunction {
private:
T value_;
MFSignature signature_;
Signature signature_;
public:
template<typename U> CustomMF_Constant(U &&value) : value_(std::forward<U>(value))
{
MFSignatureBuilder builder{"Constant", signature_};
SignatureBuilder builder{"Constant", signature_};
builder.single_output<T>("Value");
this->set_signature(&signature_);
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
mask.to_best_mask_type([&](const auto &mask) {
@@ -671,20 +671,20 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
class CustomMF_DefaultOutput : public MultiFunction {
private:
int output_amount_;
MFSignature signature_;
Signature signature_;
public:
CustomMF_DefaultOutput(Span<MFDataType> input_types, Span<MFDataType> output_types);
void call(IndexMask mask, MFParams params, MFContext context) const override;
CustomMF_DefaultOutput(Span<DataType> input_types, Span<DataType> output_types);
void call(IndexMask mask, MFParams params, Context context) const override;
};
class CustomMF_GenericCopy : public MultiFunction {
private:
MFSignature signature_;
Signature signature_;
public:
CustomMF_GenericCopy(MFDataType data_type);
void call(IndexMask mask, MFParams params, MFContext context) const override;
CustomMF_GenericCopy(DataType data_type);
void call(IndexMask mask, MFParams params, Context context) const override;
};
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -5,7 +5,7 @@
/** \file
* \ingroup fn
*
* An #MFContext is passed along with every call to a multi-function. Right now it does nothing,
* An #Context is passed along with every call to a multi-function. Right now it does nothing,
* but it can be used for the following purposes:
* - Pass debug information up and down the function call stack.
* - Pass reusable memory buffers to sub-functions to increase performance.
@@ -16,18 +16,18 @@
#include "BLI_map.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
class MFContext;
class Context;
class MFContextBuilder {
class ContextBuilder {
};
class MFContext {
class Context {
public:
MFContext(MFContextBuilder & /*builder*/)
Context(ContextBuilder & /*builder*/)
{
}
};
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -5,16 +5,16 @@
/** \file
* \ingroup fn
*
* A MFDataType describes what type of data a multi-function gets as input, outputs or mutates.
* A DataType describes what type of data a multi-function gets as input, outputs or mutates.
* Currently, only individual elements or vectors of elements are supported. Adding more data types
* is possible when necessary.
*/
#include "BLI_cpp_type.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
class MFDataType {
class DataType {
public:
enum Category {
Single,
@@ -25,31 +25,31 @@ class MFDataType {
Category category_;
const CPPType *type_;
MFDataType(Category category, const CPPType &type) : category_(category), type_(&type)
DataType(Category category, const CPPType &type) : category_(category), type_(&type)
{
}
public:
MFDataType() = default;
DataType() = default;
static MFDataType ForSingle(const CPPType &type)
static DataType ForSingle(const CPPType &type)
{
return MFDataType(Single, type);
return DataType(Single, type);
}
static MFDataType ForVector(const CPPType &type)
static DataType ForVector(const CPPType &type)
{
return MFDataType(Vector, type);
return DataType(Vector, type);
}
template<typename T> static MFDataType ForSingle()
template<typename T> static DataType ForSingle()
{
return MFDataType::ForSingle(CPPType::get<T>());
return DataType::ForSingle(CPPType::get<T>());
}
template<typename T> static MFDataType ForVector()
template<typename T> static DataType ForVector()
{
return MFDataType::ForVector(CPPType::get<T>());
return DataType::ForVector(CPPType::get<T>());
}
bool is_single() const
@@ -79,8 +79,8 @@ class MFDataType {
return *type_;
}
friend bool operator==(const MFDataType &a, const MFDataType &b);
friend bool operator!=(const MFDataType &a, const MFDataType &b);
friend bool operator==(const DataType &a, const DataType &b);
friend bool operator!=(const DataType &a, const DataType &b);
std::string to_string() const
{
@@ -100,14 +100,14 @@ class MFDataType {
}
};
inline bool operator==(const MFDataType &a, const MFDataType &b)
inline bool operator==(const DataType &a, const DataType &b)
{
return a.category_ == b.category_ && a.type_ == b.type_;
}
inline bool operator!=(const MFDataType &a, const MFDataType &b)
inline bool operator!=(const DataType &a, const DataType &b)
{
return !(a == b);
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -14,15 +14,15 @@
* - Mutable: A mutable parameter can be considered to be an input and output. The caller has to
* initialize the data, but the function is allowed to modify it.
*
* Furthermore, every parameter has a MFDataType that describes what kind of data is being passed
* Furthermore, every parameter has a DataType that describes what kind of data is being passed
* around.
*/
#include "FN_multi_function_data_type.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
enum class MFParamCategory {
enum class ParamCategory {
SingleInput,
VectorInput,
SingleOutput,
@@ -31,12 +31,12 @@ enum class MFParamCategory {
VectorMutable,
};
template<MFParamCategory Category, typename T> struct MFParamTag {
static constexpr MFParamCategory category = Category;
template<ParamCategory Category, typename T> struct MFParamTag {
static constexpr ParamCategory category = Category;
using base_type = T;
};
class MFParamType {
class ParamType {
public:
enum InterfaceType {
Input,
@@ -46,45 +46,45 @@ class MFParamType {
private:
InterfaceType interface_type_;
MFDataType data_type_;
DataType data_type_;
public:
MFParamType(InterfaceType interface_type, MFDataType data_type)
ParamType(InterfaceType interface_type, DataType data_type)
: interface_type_(interface_type), data_type_(data_type)
{
}
static MFParamType ForSingleInput(const CPPType &type)
static ParamType ForSingleInput(const CPPType &type)
{
return MFParamType(InterfaceType::Input, MFDataType::ForSingle(type));
return ParamType(InterfaceType::Input, DataType::ForSingle(type));
}
static MFParamType ForVectorInput(const CPPType &base_type)
static ParamType ForVectorInput(const CPPType &base_type)
{
return MFParamType(InterfaceType::Input, MFDataType::ForVector(base_type));
return ParamType(InterfaceType::Input, DataType::ForVector(base_type));
}
static MFParamType ForSingleOutput(const CPPType &type)
static ParamType ForSingleOutput(const CPPType &type)
{
return MFParamType(InterfaceType::Output, MFDataType::ForSingle(type));
return ParamType(InterfaceType::Output, DataType::ForSingle(type));
}
static MFParamType ForVectorOutput(const CPPType &base_type)
static ParamType ForVectorOutput(const CPPType &base_type)
{
return MFParamType(InterfaceType::Output, MFDataType::ForVector(base_type));
return ParamType(InterfaceType::Output, DataType::ForVector(base_type));
}
static MFParamType ForMutableSingle(const CPPType &type)
static ParamType ForMutableSingle(const CPPType &type)
{
return MFParamType(InterfaceType::Mutable, MFDataType::ForSingle(type));
return ParamType(InterfaceType::Mutable, DataType::ForSingle(type));
}
static MFParamType ForMutableVector(const CPPType &base_type)
static ParamType ForMutableVector(const CPPType &base_type)
{
return MFParamType(InterfaceType::Mutable, MFDataType::ForVector(base_type));
return ParamType(InterfaceType::Mutable, DataType::ForVector(base_type));
}
MFDataType data_type() const
DataType data_type() const
{
return data_type_;
}
@@ -94,34 +94,34 @@ class MFParamType {
return interface_type_;
}
MFParamCategory category() const
ParamCategory category() const
{
switch (data_type_.category()) {
case MFDataType::Single: {
case DataType::Single: {
switch (interface_type_) {
case Input:
return MFParamCategory::SingleInput;
return ParamCategory::SingleInput;
case Output:
return MFParamCategory::SingleOutput;
return ParamCategory::SingleOutput;
case Mutable:
return MFParamCategory::SingleMutable;
return ParamCategory::SingleMutable;
}
break;
}
case MFDataType::Vector: {
case DataType::Vector: {
switch (interface_type_) {
case Input:
return MFParamCategory::VectorInput;
return ParamCategory::VectorInput;
case Output:
return MFParamCategory::VectorOutput;
return ParamCategory::VectorOutput;
case Mutable:
return MFParamCategory::VectorMutable;
return ParamCategory::VectorMutable;
}
break;
}
}
BLI_assert_unreachable();
return MFParamCategory::SingleInput;
return ParamCategory::SingleInput;
}
bool is_input_or_mutable() const
@@ -139,18 +139,18 @@ class MFParamType {
return interface_type_ == Output;
}
friend bool operator==(const MFParamType &a, const MFParamType &b);
friend bool operator!=(const MFParamType &a, const MFParamType &b);
friend bool operator==(const ParamType &a, const ParamType &b);
friend bool operator!=(const ParamType &a, const ParamType &b);
};
inline bool operator==(const MFParamType &a, const MFParamType &b)
inline bool operator==(const ParamType &a, const ParamType &b)
{
return a.interface_type_ == b.interface_type_ && a.data_type_ == b.data_type_;
}
inline bool operator!=(const MFParamType &a, const MFParamType &b)
inline bool operator!=(const ParamType &a, const ParamType &b)
{
return !(a == b);
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -5,9 +5,9 @@
/** \file
* \ingroup fn
*
* This file provides an MFParams and MFParamsBuilder structure.
* This file provides an MFParams and ParamsBuilder structure.
*
* `MFParamsBuilder` is used by a function caller to be prepare all parameters that are passed into
* `ParamsBuilder` is used by a function caller to be prepare all parameters that are passed into
* the function. `MFParams` is then used inside the called function to access the parameters.
*/
@@ -21,12 +21,12 @@
#include "FN_multi_function_signature.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
class MFParamsBuilder {
class ParamsBuilder {
private:
ResourceScope scope_;
const MFSignature *signature_;
const Signature *signature_;
IndexMask mask_;
int64_t min_array_size_;
Vector<std::variant<GVArray, GMutableSpan, const GVVectorArray *, GVectorArray *>>
@@ -37,23 +37,23 @@ class MFParamsBuilder {
friend class MFParams;
MFParamsBuilder(const MFSignature &signature, const IndexMask mask)
ParamsBuilder(const Signature &signature, const IndexMask mask)
: signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
{
actual_params_.reserve(signature.params.size());
}
public:
MFParamsBuilder(const class MultiFunction &fn, int64_t size);
ParamsBuilder(const class MultiFunction &fn, int64_t size);
/**
* The indices referenced by the #mask has to live longer than the params builder. This is
* because the it might have to destruct elements for all masked indices in the end.
*/
MFParamsBuilder(const class MultiFunction &fn, const IndexMask *mask);
ParamsBuilder(const class MultiFunction &fn, const IndexMask *mask);
template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get<T>()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single{},
CPPType::get<T>(),
@@ -62,7 +62,7 @@ class MFParamsBuilder {
}
template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get<T>()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single_ref{},
CPPType::get<T>(),
@@ -71,13 +71,13 @@ class MFParamsBuilder {
}
void add_readonly_single_input(const GSpan span, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name);
this->assert_current_param_type(ParamType::ForSingleInput(span.type()), expected_name);
BLI_assert(span.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, varray_tag::span{}, span);
}
void add_readonly_single_input(GPointer value, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name);
this->assert_current_param_type(ParamType::ForSingleInput(*value.type()), expected_name);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
varray_tag::single_ref{},
*value.type(),
@@ -86,7 +86,7 @@ class MFParamsBuilder {
}
void add_readonly_single_input(GVArray varray, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name);
this->assert_current_param_type(ParamType::ForSingleInput(varray.type()), expected_name);
BLI_assert(varray.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, std::move(varray));
}
@@ -104,7 +104,7 @@ class MFParamsBuilder {
}
void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
this->assert_current_param_type(ParamType::ForVectorInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<const GVVectorArray *>, &ref);
}
@@ -116,7 +116,7 @@ class MFParamsBuilder {
}
void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
this->assert_current_param_type(ParamType::ForSingleOutput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
}
@@ -124,8 +124,8 @@ class MFParamsBuilder {
{
this->assert_current_param_name(expected_name);
const int param_index = this->current_param_index();
const MFParamType &param_type = signature_->params[param_index].type;
BLI_assert(param_type.category() == MFParamCategory::SingleOutput);
const ParamType &param_type = signature_->params[param_index].type;
BLI_assert(param_type.category() == ParamCategory::SingleOutput);
const CPPType &type = param_type.data_type().single_type();
/* An empty span indicates that this is ignored. */
const GMutableSpan dummy_span{type};
@@ -134,7 +134,7 @@ class MFParamsBuilder {
void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
this->assert_current_param_type(ParamType::ForVectorOutput(vector_array.type()),
expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
@@ -142,14 +142,14 @@ class MFParamsBuilder {
void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name);
this->assert_current_param_type(ParamType::ForMutableSingle(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
}
void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
{
this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
this->assert_current_param_type(ParamType::ForMutableVector(vector_array.type()),
expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
@@ -158,16 +158,16 @@ class MFParamsBuilder {
GMutableSpan computed_array(int param_index)
{
BLI_assert(ELEM(signature_->params[param_index].type.category(),
MFParamCategory::SingleOutput,
MFParamCategory::SingleMutable));
ParamCategory::SingleOutput,
ParamCategory::SingleMutable));
return *std::get_if<GMutableSpan>(&actual_params_[param_index]);
}
GVectorArray &computed_vector_array(int param_index)
{
BLI_assert(ELEM(signature_->params[param_index].type.category(),
MFParamCategory::VectorOutput,
MFParamCategory::VectorMutable));
ParamCategory::VectorOutput,
ParamCategory::VectorMutable));
return **std::get_if<GVectorArray *>(&actual_params_[param_index]);
}
@@ -177,7 +177,7 @@ class MFParamsBuilder {
}
private:
void assert_current_param_type(MFParamType param_type, StringRef expected_name = "")
void assert_current_param_type(ParamType param_type, StringRef expected_name = "")
{
UNUSED_VARS_NDEBUG(param_type, expected_name);
#ifdef DEBUG
@@ -188,7 +188,7 @@ class MFParamsBuilder {
BLI_assert(actual_name == expected_name);
}
MFParamType expected_type = signature_->params[param_index].type;
ParamType expected_type = signature_->params[param_index].type;
BLI_assert(expected_type == param_type);
#endif
}
@@ -214,10 +214,10 @@ class MFParamsBuilder {
class MFParams {
private:
MFParamsBuilder *builder_;
ParamsBuilder *builder_;
public:
MFParams(MFParamsBuilder &builder) : builder_(&builder)
MFParams(ParamsBuilder &builder) : builder_(&builder)
{
}
@@ -228,7 +228,7 @@ class MFParams {
}
const GVArray &readonly_single_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::SingleInput);
this->assert_correct_param(param_index, name, ParamCategory::SingleInput);
return *std::get_if<GVArray>(&builder_->actual_params_[param_index]);
}
@@ -240,7 +240,7 @@ class MFParams {
*/
bool single_output_is_required(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
return !std::get_if<GMutableSpan>(&builder_->actual_params_[param_index])->is_empty();
}
@@ -251,7 +251,7 @@ class MFParams {
}
GMutableSpan uninitialized_single_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
GMutableSpan span = *std::get_if<GMutableSpan>(&builder_->actual_params_[param_index]);
if (!span.is_empty()) {
return span;
@@ -272,7 +272,7 @@ class MFParams {
}
GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
this->assert_correct_param(param_index, name, ParamCategory::SingleOutput);
return *std::get_if<GMutableSpan>(&builder_->actual_params_[param_index]);
}
@@ -284,7 +284,7 @@ class MFParams {
}
const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::VectorInput);
this->assert_correct_param(param_index, name, ParamCategory::VectorInput);
return **std::get_if<const GVVectorArray *>(&builder_->actual_params_[param_index]);
}
@@ -295,7 +295,7 @@ class MFParams {
}
GVectorArray &vector_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::VectorOutput);
this->assert_correct_param(param_index, name, ParamCategory::VectorOutput);
return **std::get_if<GVectorArray *>(&builder_->actual_params_[param_index]);
}
@@ -305,7 +305,7 @@ class MFParams {
}
GMutableSpan single_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::SingleMutable);
this->assert_correct_param(param_index, name, ParamCategory::SingleMutable);
return *std::get_if<GMutableSpan>(&builder_->actual_params_[param_index]);
}
@@ -316,12 +316,12 @@ class MFParams {
}
GVectorArray &vector_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamCategory::VectorMutable);
this->assert_correct_param(param_index, name, ParamCategory::VectorMutable);
return **std::get_if<GVectorArray *>(&builder_->actual_params_[param_index]);
}
private:
void assert_correct_param(int param_index, StringRef name, MFParamType param_type)
void assert_correct_param(int param_index, StringRef name, ParamType param_type)
{
UNUSED_VARS_NDEBUG(param_index, name, param_type);
#ifdef DEBUG
@@ -332,7 +332,7 @@ class MFParams {
#endif
}
void assert_correct_param(int param_index, StringRef name, MFParamCategory category)
void assert_correct_param(int param_index, StringRef name, ParamCategory category)
{
UNUSED_VARS_NDEBUG(param_index, name, category);
#ifdef DEBUG
@@ -346,4 +346,4 @@ class MFParams {
GMutableSpan ensure_dummy_single_output(int param_index);
};
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -8,19 +8,19 @@
#include "FN_multi_function.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
class MFVariable;
class MFInstruction;
class MFCallInstruction;
class MFBranchInstruction;
class MFDestructInstruction;
class MFDummyInstruction;
class MFReturnInstruction;
class MFProcedure;
class Variable;
class Instruction;
class CallInstruction;
class BranchInstruction;
class DestructInstruction;
class DummyInstruction;
class ReturnInstruction;
class Procedure;
/** Every instruction has exactly one of these types. */
enum class MFInstructionType {
enum class InstructionType {
Call,
Branch,
Destruct,
@@ -29,10 +29,10 @@ enum class MFInstructionType {
};
/**
* An #MFInstructionCursor points to a position in a multi-function procedure, where an instruction
* An #InstructionCursor points to a position in a multi-function procedure, where an instruction
* can be inserted.
*/
class MFInstructionCursor {
class InstructionCursor {
public:
enum Type {
None,
@@ -45,33 +45,33 @@ class MFInstructionCursor {
private:
Type type_ = None;
MFInstruction *instruction_ = nullptr;
Instruction *instruction_ = nullptr;
/* Only used when it is a branch instruction. */
bool branch_output_ = false;
public:
MFInstructionCursor() = default;
MFInstructionCursor(MFCallInstruction &instruction);
MFInstructionCursor(MFDestructInstruction &instruction);
MFInstructionCursor(MFBranchInstruction &instruction, bool branch_output);
MFInstructionCursor(MFDummyInstruction &instruction);
InstructionCursor() = default;
InstructionCursor(CallInstruction &instruction);
InstructionCursor(DestructInstruction &instruction);
InstructionCursor(BranchInstruction &instruction, bool branch_output);
InstructionCursor(DummyInstruction &instruction);
static MFInstructionCursor ForEntry();
static InstructionCursor ForEntry();
MFInstruction *next(MFProcedure &procedure) const;
void set_next(MFProcedure &procedure, MFInstruction *new_instruction) const;
Instruction *next(Procedure &procedure) const;
void set_next(Procedure &procedure, Instruction *new_instruction) const;
MFInstruction *instruction() const;
Instruction *instruction() const;
Type type() const;
friend bool operator==(const MFInstructionCursor &a, const MFInstructionCursor &b)
friend bool operator==(const InstructionCursor &a, const InstructionCursor &b)
{
return a.type_ == b.type_ && a.instruction_ == b.instruction_ &&
a.branch_output_ == b.branch_output_;
}
friend bool operator!=(const MFInstructionCursor &a, const MFInstructionCursor &b)
friend bool operator!=(const InstructionCursor &a, const InstructionCursor &b)
{
return !(a == b);
}
@@ -82,21 +82,21 @@ class MFInstructionCursor {
* either uninitialized or contains a value for every index (remember, a multi-function procedure
* is always evaluated for many indices at the same time).
*/
class MFVariable : NonCopyable, NonMovable {
class Variable : NonCopyable, NonMovable {
private:
MFDataType data_type_;
Vector<MFInstruction *> users_;
DataType data_type_;
Vector<Instruction *> users_;
std::string name_;
int index_in_graph_;
friend MFProcedure;
friend MFCallInstruction;
friend MFBranchInstruction;
friend MFDestructInstruction;
friend Procedure;
friend CallInstruction;
friend BranchInstruction;
friend DestructInstruction;
public:
MFDataType data_type() const;
Span<MFInstruction *> users();
DataType data_type() const;
Span<Instruction *> users();
StringRefNull name() const;
void set_name(std::string name);
@@ -105,78 +105,78 @@ class MFVariable : NonCopyable, NonMovable {
};
/** Base class for all instruction types. */
class MFInstruction : NonCopyable, NonMovable {
class Instruction : NonCopyable, NonMovable {
protected:
MFInstructionType type_;
Vector<MFInstructionCursor> prev_;
InstructionType type_;
Vector<InstructionCursor> prev_;
friend MFProcedure;
friend MFCallInstruction;
friend MFBranchInstruction;
friend MFDestructInstruction;
friend MFDummyInstruction;
friend MFReturnInstruction;
friend Procedure;
friend CallInstruction;
friend BranchInstruction;
friend DestructInstruction;
friend DummyInstruction;
friend ReturnInstruction;
public:
MFInstructionType type() const;
InstructionType type() const;
/**
* Other instructions that come before this instruction. There can be multiple previous
* instructions when branching is used in the procedure.
*/
Span<MFInstructionCursor> prev() const;
Span<InstructionCursor> prev() const;
};
/**
* References a multi-function that is evaluated when the instruction is executed. It also
* references the variables whose data will be passed into the multi-function.
*/
class MFCallInstruction : public MFInstruction {
class CallInstruction : public Instruction {
private:
const MultiFunction *fn_ = nullptr;
MFInstruction *next_ = nullptr;
MutableSpan<MFVariable *> params_;
Instruction *next_ = nullptr;
MutableSpan<Variable *> params_;
friend MFProcedure;
friend Procedure;
public:
const MultiFunction &fn() const;
MFInstruction *next();
const MFInstruction *next() const;
void set_next(MFInstruction *instruction);
Instruction *next();
const Instruction *next() const;
void set_next(Instruction *instruction);
void set_param_variable(int param_index, MFVariable *variable);
void set_params(Span<MFVariable *> variables);
void set_param_variable(int param_index, Variable *variable);
void set_params(Span<Variable *> variables);
Span<MFVariable *> params();
Span<const MFVariable *> params() const;
Span<Variable *> params();
Span<const Variable *> params() const;
};
/**
* What makes a branch instruction special is that it has two successor instructions. One that will
* be used when a condition variable was true, and one otherwise.
*/
class MFBranchInstruction : public MFInstruction {
class BranchInstruction : public Instruction {
private:
MFVariable *condition_ = nullptr;
MFInstruction *branch_true_ = nullptr;
MFInstruction *branch_false_ = nullptr;
Variable *condition_ = nullptr;
Instruction *branch_true_ = nullptr;
Instruction *branch_false_ = nullptr;
friend MFProcedure;
friend Procedure;
public:
MFVariable *condition();
const MFVariable *condition() const;
void set_condition(MFVariable *variable);
Variable *condition();
const Variable *condition() const;
void set_condition(Variable *variable);
MFInstruction *branch_true();
const MFInstruction *branch_true() const;
void set_branch_true(MFInstruction *instruction);
Instruction *branch_true();
const Instruction *branch_true() const;
void set_branch_true(Instruction *instruction);
MFInstruction *branch_false();
const MFInstruction *branch_false() const;
void set_branch_false(MFInstruction *instruction);
Instruction *branch_false();
const Instruction *branch_false() const;
void set_branch_false(Instruction *instruction);
};
/**
@@ -185,55 +185,55 @@ class MFBranchInstruction : public MFInstruction {
* destructed before the procedure ends. Destructing early is generally a good thing, because it
* might help with memory buffer reuse, which decreases memory-usage and increases performance.
*/
class MFDestructInstruction : public MFInstruction {
class DestructInstruction : public Instruction {
private:
MFVariable *variable_ = nullptr;
MFInstruction *next_ = nullptr;
Variable *variable_ = nullptr;
Instruction *next_ = nullptr;
friend MFProcedure;
friend Procedure;
public:
MFVariable *variable();
const MFVariable *variable() const;
void set_variable(MFVariable *variable);
Variable *variable();
const Variable *variable() const;
void set_variable(Variable *variable);
MFInstruction *next();
const MFInstruction *next() const;
void set_next(MFInstruction *instruction);
Instruction *next();
const Instruction *next() const;
void set_next(Instruction *instruction);
};
/**
* This instruction does nothing, it just exists to building a procedure simpler in some cases.
*/
class MFDummyInstruction : public MFInstruction {
class DummyInstruction : public Instruction {
private:
MFInstruction *next_ = nullptr;
Instruction *next_ = nullptr;
friend MFProcedure;
friend Procedure;
public:
MFInstruction *next();
const MFInstruction *next() const;
void set_next(MFInstruction *instruction);
Instruction *next();
const Instruction *next() const;
void set_next(Instruction *instruction);
};
/**
* This instruction ends the procedure.
*/
class MFReturnInstruction : public MFInstruction {
class ReturnInstruction : public Instruction {
};
/**
* Inputs and outputs of the entire procedure network.
*/
struct MFParameter {
MFParamType::InterfaceType type;
MFVariable *variable;
ParamType::InterfaceType type;
Variable *variable;
};
struct ConstMFParameter {
MFParamType::InterfaceType type;
const MFVariable *variable;
ParamType::InterfaceType type;
const Variable *variable;
};
/**
@@ -241,46 +241,46 @@ struct ConstMFParameter {
* variables and instructions that operate on those variables. Branching and looping within the
* procedure is supported as well.
*
* Typically, a #MFProcedure should be constructed using a #MFProcedureBuilder, which has many more
* Typically, a #Procedure should be constructed using a #ProcedureBuilder, which has many more
* utility methods for common use cases.
*/
class MFProcedure : NonCopyable, NonMovable {
class Procedure : NonCopyable, NonMovable {
private:
LinearAllocator<> allocator_;
Vector<MFCallInstruction *> call_instructions_;
Vector<MFBranchInstruction *> branch_instructions_;
Vector<MFDestructInstruction *> destruct_instructions_;
Vector<MFDummyInstruction *> dummy_instructions_;
Vector<MFReturnInstruction *> return_instructions_;
Vector<MFVariable *> variables_;
Vector<CallInstruction *> call_instructions_;
Vector<BranchInstruction *> branch_instructions_;
Vector<DestructInstruction *> destruct_instructions_;
Vector<DummyInstruction *> dummy_instructions_;
Vector<ReturnInstruction *> return_instructions_;
Vector<Variable *> variables_;
Vector<MFParameter> params_;
Vector<destruct_ptr<MultiFunction>> owned_functions_;
MFInstruction *entry_ = nullptr;
Instruction *entry_ = nullptr;
friend class MFProcedureDotExport;
friend class ProcedureDotExport;
public:
MFProcedure() = default;
~MFProcedure();
Procedure() = default;
~Procedure();
MFVariable &new_variable(MFDataType data_type, std::string name = "");
MFCallInstruction &new_call_instruction(const MultiFunction &fn);
MFBranchInstruction &new_branch_instruction();
MFDestructInstruction &new_destruct_instruction();
MFDummyInstruction &new_dummy_instruction();
MFReturnInstruction &new_return_instruction();
Variable &new_variable(DataType data_type, std::string name = "");
CallInstruction &new_call_instruction(const MultiFunction &fn);
BranchInstruction &new_branch_instruction();
DestructInstruction &new_destruct_instruction();
DummyInstruction &new_dummy_instruction();
ReturnInstruction &new_return_instruction();
void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable);
void add_parameter(ParamType::InterfaceType interface_type, Variable &variable);
Span<ConstMFParameter> params() const;
template<typename T, typename... Args> const MultiFunction &construct_function(Args &&...args);
MFInstruction *entry();
const MFInstruction *entry() const;
void set_entry(MFInstruction &entry);
Instruction *entry();
const Instruction *entry() const;
void set_entry(Instruction &entry);
Span<MFVariable *> variables();
Span<const MFVariable *> variables() const;
Span<Variable *> variables();
Span<const Variable *> variables() const;
std::string to_dot() const;
@@ -298,59 +298,49 @@ class MFProcedure : NonCopyable, NonMovable {
bool can_be_uninitialized = false;
};
InitState find_initialization_state_before_instruction(const MFInstruction &target_instruction,
const MFVariable &variable) const;
InitState find_initialization_state_before_instruction(const Instruction &target_instruction,
const Variable &variable) const;
};
namespace multi_function_procedure_types {
using MFVariable = fn::MFVariable;
using MFInstruction = fn::MFInstruction;
using MFCallInstruction = fn::MFCallInstruction;
using MFBranchInstruction = fn::MFBranchInstruction;
using MFDestructInstruction = fn::MFDestructInstruction;
using MFProcedure = fn::MFProcedure;
} // namespace multi_function_procedure_types
/* -------------------------------------------------------------------- */
/** \name #MFInstructionCursor Inline Methods
/** \name #InstructionCursor Inline Methods
* \{ */
inline MFInstructionCursor::MFInstructionCursor(MFCallInstruction &instruction)
inline InstructionCursor::InstructionCursor(CallInstruction &instruction)
: type_(Call), instruction_(&instruction)
{
}
inline MFInstructionCursor::MFInstructionCursor(MFDestructInstruction &instruction)
inline InstructionCursor::InstructionCursor(DestructInstruction &instruction)
: type_(Destruct), instruction_(&instruction)
{
}
inline MFInstructionCursor::MFInstructionCursor(MFBranchInstruction &instruction,
bool branch_output)
inline InstructionCursor::InstructionCursor(BranchInstruction &instruction, bool branch_output)
: type_(Branch), instruction_(&instruction), branch_output_(branch_output)
{
}
inline MFInstructionCursor::MFInstructionCursor(MFDummyInstruction &instruction)
inline InstructionCursor::InstructionCursor(DummyInstruction &instruction)
: type_(Dummy), instruction_(&instruction)
{
}
inline MFInstructionCursor MFInstructionCursor::ForEntry()
inline InstructionCursor InstructionCursor::ForEntry()
{
MFInstructionCursor cursor;
InstructionCursor cursor;
cursor.type_ = Type::Entry;
return cursor;
}
inline MFInstruction *MFInstructionCursor::instruction() const
inline Instruction *InstructionCursor::instruction() const
{
/* This isn't really const correct unfortunately, because to make it correct we'll need a const
* version of #MFInstructionCursor. */
* version of #InstructionCursor. */
return instruction_;
}
inline MFInstructionCursor::Type MFInstructionCursor::type() const
inline InstructionCursor::Type InstructionCursor::type() const
{
return type_;
}
@@ -358,25 +348,25 @@ inline MFInstructionCursor::Type MFInstructionCursor::type() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFVariable Inline Methods
/** \name #Variable Inline Methods
* \{ */
inline MFDataType MFVariable::data_type() const
inline DataType Variable::data_type() const
{
return data_type_;
}
inline Span<MFInstruction *> MFVariable::users()
inline Span<Instruction *> Variable::users()
{
return users_;
}
inline StringRefNull MFVariable::name() const
inline StringRefNull Variable::name() const
{
return name_;
}
inline int MFVariable::index_in_procedure() const
inline int Variable::index_in_procedure() const
{
return index_in_graph_;
}
@@ -384,15 +374,15 @@ inline int MFVariable::index_in_procedure() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFInstruction Inline Methods
/** \name #Instruction Inline Methods
* \{ */
inline MFInstructionType MFInstruction::type() const
inline InstructionType Instruction::type() const
{
return type_;
}
inline Span<MFInstructionCursor> MFInstruction::prev() const
inline Span<InstructionCursor> Instruction::prev() const
{
return prev_;
}
@@ -400,30 +390,30 @@ inline Span<MFInstructionCursor> MFInstruction::prev() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFCallInstruction Inline Methods
/** \name #CallInstruction Inline Methods
* \{ */
inline const MultiFunction &MFCallInstruction::fn() const
inline const MultiFunction &CallInstruction::fn() const
{
return *fn_;
}
inline MFInstruction *MFCallInstruction::next()
inline Instruction *CallInstruction::next()
{
return next_;
}
inline const MFInstruction *MFCallInstruction::next() const
inline const Instruction *CallInstruction::next() const
{
return next_;
}
inline Span<MFVariable *> MFCallInstruction::params()
inline Span<Variable *> CallInstruction::params()
{
return params_;
}
inline Span<const MFVariable *> MFCallInstruction::params() const
inline Span<const Variable *> CallInstruction::params() const
{
return params_;
}
@@ -431,35 +421,35 @@ inline Span<const MFVariable *> MFCallInstruction::params() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFBranchInstruction Inline Methods
/** \name #BranchInstruction Inline Methods
* \{ */
inline MFVariable *MFBranchInstruction::condition()
inline Variable *BranchInstruction::condition()
{
return condition_;
}
inline const MFVariable *MFBranchInstruction::condition() const
inline const Variable *BranchInstruction::condition() const
{
return condition_;
}
inline MFInstruction *MFBranchInstruction::branch_true()
inline Instruction *BranchInstruction::branch_true()
{
return branch_true_;
}
inline const MFInstruction *MFBranchInstruction::branch_true() const
inline const Instruction *BranchInstruction::branch_true() const
{
return branch_true_;
}
inline MFInstruction *MFBranchInstruction::branch_false()
inline Instruction *BranchInstruction::branch_false()
{
return branch_false_;
}
inline const MFInstruction *MFBranchInstruction::branch_false() const
inline const Instruction *BranchInstruction::branch_false() const
{
return branch_false_;
}
@@ -467,25 +457,25 @@ inline const MFInstruction *MFBranchInstruction::branch_false() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFDestructInstruction Inline Methods
/** \name #DestructInstruction Inline Methods
* \{ */
inline MFVariable *MFDestructInstruction::variable()
inline Variable *DestructInstruction::variable()
{
return variable_;
}
inline const MFVariable *MFDestructInstruction::variable() const
inline const Variable *DestructInstruction::variable() const
{
return variable_;
}
inline MFInstruction *MFDestructInstruction::next()
inline Instruction *DestructInstruction::next()
{
return next_;
}
inline const MFInstruction *MFDestructInstruction::next() const
inline const Instruction *DestructInstruction::next() const
{
return next_;
}
@@ -493,15 +483,15 @@ inline const MFInstruction *MFDestructInstruction::next() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFDummyInstruction Inline Methods
/** \name #DummyInstruction Inline Methods
* \{ */
inline MFInstruction *MFDummyInstruction::next()
inline Instruction *DummyInstruction::next()
{
return next_;
}
inline const MFInstruction *MFDummyInstruction::next() const
inline const Instruction *DummyInstruction::next() const
{
return next_;
}
@@ -509,37 +499,37 @@ inline const MFInstruction *MFDummyInstruction::next() const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #MFProcedure Inline Methods
/** \name #Procedure Inline Methods
* \{ */
inline Span<ConstMFParameter> MFProcedure::params() const
inline Span<ConstMFParameter> Procedure::params() const
{
static_assert(sizeof(MFParameter) == sizeof(ConstMFParameter));
return params_.as_span().cast<ConstMFParameter>();
}
inline MFInstruction *MFProcedure::entry()
inline Instruction *Procedure::entry()
{
return entry_;
}
inline const MFInstruction *MFProcedure::entry() const
inline const Instruction *Procedure::entry() const
{
return entry_;
}
inline Span<MFVariable *> MFProcedure::variables()
inline Span<Variable *> Procedure::variables()
{
return variables_;
}
inline Span<const MFVariable *> MFProcedure::variables() const
inline Span<const Variable *> Procedure::variables() const
{
return variables_;
}
template<typename T, typename... Args>
inline const MultiFunction &MFProcedure::construct_function(Args &&...args)
inline const MultiFunction &Procedure::construct_function(Args &&...args)
{
destruct_ptr<T> fn = allocator_.construct<T>(std::forward<Args>(args)...);
const MultiFunction &fn_ref = *fn;
@@ -549,4 +539,4 @@ inline const MultiFunction &MFProcedure::construct_function(Args &&...args)
/** \} */
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -8,182 +8,181 @@
#include "FN_multi_function_procedure.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
/**
* Utility class to build a #MFProcedure.
* Utility class to build a #Procedure.
*/
class MFProcedureBuilder {
class ProcedureBuilder {
private:
/** Procedure that is being build. */
MFProcedure *procedure_ = nullptr;
Procedure *procedure_ = nullptr;
/** Cursors where the next instruction should be inserted. */
Vector<MFInstructionCursor> cursors_;
Vector<InstructionCursor> cursors_;
public:
struct Branch;
struct Loop;
MFProcedureBuilder(MFProcedure &procedure,
MFInstructionCursor initial_cursor = MFInstructionCursor::ForEntry());
ProcedureBuilder(Procedure &procedure,
InstructionCursor initial_cursor = InstructionCursor::ForEntry());
MFProcedureBuilder(Span<MFProcedureBuilder *> builders);
ProcedureBuilder(Span<ProcedureBuilder *> builders);
MFProcedureBuilder(Branch &branch);
ProcedureBuilder(Branch &branch);
void set_cursor(const MFInstructionCursor &cursor);
void set_cursor(Span<MFInstructionCursor> cursors);
void set_cursor(Span<MFProcedureBuilder *> builders);
void set_cursor(const InstructionCursor &cursor);
void set_cursor(Span<InstructionCursor> cursors);
void set_cursor(Span<ProcedureBuilder *> builders);
void set_cursor_after_branch(Branch &branch);
void set_cursor_after_loop(Loop &loop);
void add_destruct(MFVariable &variable);
void add_destruct(Span<MFVariable *> variables);
void add_destruct(Variable &variable);
void add_destruct(Span<Variable *> variables);
MFReturnInstruction &add_return();
ReturnInstruction &add_return();
Branch add_branch(MFVariable &condition);
Branch add_branch(Variable &condition);
Loop add_loop();
void add_loop_continue(Loop &loop);
void add_loop_break(Loop &loop);
MFCallInstruction &add_call_with_no_variables(const MultiFunction &fn);
MFCallInstruction &add_call_with_all_variables(const MultiFunction &fn,
Span<MFVariable *> param_variables);
CallInstruction &add_call_with_no_variables(const MultiFunction &fn);
CallInstruction &add_call_with_all_variables(const MultiFunction &fn,
Span<Variable *> param_variables);
Vector<MFVariable *> add_call(const MultiFunction &fn,
Span<MFVariable *> input_and_mutable_variables = {});
Vector<Variable *> add_call(const MultiFunction &fn,
Span<Variable *> input_and_mutable_variables = {});
template<int OutputN>
std::array<MFVariable *, OutputN> add_call(const MultiFunction &fn,
Span<MFVariable *> input_and_mutable_variables = {});
std::array<Variable *, OutputN> add_call(const MultiFunction &fn,
Span<Variable *> input_and_mutable_variables = {});
void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable);
MFVariable &add_parameter(MFParamType param_type, std::string name = "");
void add_parameter(ParamType::InterfaceType interface_type, Variable &variable);
Variable &add_parameter(ParamType param_type, std::string name = "");
MFVariable &add_input_parameter(MFDataType data_type, std::string name = "");
template<typename T> MFVariable &add_single_input_parameter(std::string name = "");
template<typename T> MFVariable &add_single_mutable_parameter(std::string name = "");
Variable &add_input_parameter(DataType data_type, std::string name = "");
template<typename T> Variable &add_single_input_parameter(std::string name = "");
template<typename T> Variable &add_single_mutable_parameter(std::string name = "");
void add_output_parameter(MFVariable &variable);
void add_output_parameter(Variable &variable);
private:
void link_to_cursors(MFInstruction *instruction);
void link_to_cursors(Instruction *instruction);
};
struct MFProcedureBuilder::Branch {
MFProcedureBuilder branch_true;
MFProcedureBuilder branch_false;
struct ProcedureBuilder::Branch {
ProcedureBuilder branch_true;
ProcedureBuilder branch_false;
};
struct MFProcedureBuilder::Loop {
MFInstruction *begin = nullptr;
MFDummyInstruction *end = nullptr;
struct ProcedureBuilder::Loop {
Instruction *begin = nullptr;
DummyInstruction *end = nullptr;
};
/* --------------------------------------------------------------------
* MFProcedureBuilder inline methods.
* ProcedureBuilder inline methods.
*/
inline MFProcedureBuilder::MFProcedureBuilder(Branch &branch)
: MFProcedureBuilder(*branch.branch_true.procedure_)
inline ProcedureBuilder::ProcedureBuilder(Branch &branch)
: ProcedureBuilder(*branch.branch_true.procedure_)
{
this->set_cursor_after_branch(branch);
}
inline MFProcedureBuilder::MFProcedureBuilder(MFProcedure &procedure,
MFInstructionCursor initial_cursor)
inline ProcedureBuilder::ProcedureBuilder(Procedure &procedure, InstructionCursor initial_cursor)
: procedure_(&procedure), cursors_({initial_cursor})
{
}
inline MFProcedureBuilder::MFProcedureBuilder(Span<MFProcedureBuilder *> builders)
: MFProcedureBuilder(*builders[0]->procedure_)
inline ProcedureBuilder::ProcedureBuilder(Span<ProcedureBuilder *> builders)
: ProcedureBuilder(*builders[0]->procedure_)
{
this->set_cursor(builders);
}
inline void MFProcedureBuilder::set_cursor(const MFInstructionCursor &cursor)
inline void ProcedureBuilder::set_cursor(const InstructionCursor &cursor)
{
cursors_ = {cursor};
}
inline void MFProcedureBuilder::set_cursor(Span<MFInstructionCursor> cursors)
inline void ProcedureBuilder::set_cursor(Span<InstructionCursor> cursors)
{
cursors_ = cursors;
}
inline void MFProcedureBuilder::set_cursor_after_branch(Branch &branch)
inline void ProcedureBuilder::set_cursor_after_branch(Branch &branch)
{
this->set_cursor({&branch.branch_false, &branch.branch_true});
}
inline void MFProcedureBuilder::set_cursor_after_loop(Loop &loop)
inline void ProcedureBuilder::set_cursor_after_loop(Loop &loop)
{
this->set_cursor(MFInstructionCursor{*loop.end});
this->set_cursor(InstructionCursor{*loop.end});
}
inline void MFProcedureBuilder::set_cursor(Span<MFProcedureBuilder *> builders)
inline void ProcedureBuilder::set_cursor(Span<ProcedureBuilder *> builders)
{
cursors_.clear();
for (MFProcedureBuilder *builder : builders) {
for (ProcedureBuilder *builder : builders) {
cursors_.extend(builder->cursors_);
}
}
template<int OutputN>
inline std::array<MFVariable *, OutputN> MFProcedureBuilder::add_call(
const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables)
inline std::array<Variable *, OutputN> ProcedureBuilder::add_call(
const MultiFunction &fn, Span<Variable *> input_and_mutable_variables)
{
Vector<MFVariable *> output_variables = this->add_call(fn, input_and_mutable_variables);
Vector<Variable *> output_variables = this->add_call(fn, input_and_mutable_variables);
BLI_assert(output_variables.size() == OutputN);
std::array<MFVariable *, OutputN> output_array;
std::array<Variable *, OutputN> output_array;
initialized_copy_n(output_variables.data(), OutputN, output_array.data());
return output_array;
}
inline void MFProcedureBuilder::add_parameter(MFParamType::InterfaceType interface_type,
MFVariable &variable)
inline void ProcedureBuilder::add_parameter(ParamType::InterfaceType interface_type,
Variable &variable)
{
procedure_->add_parameter(interface_type, variable);
}
inline MFVariable &MFProcedureBuilder::add_parameter(MFParamType param_type, std::string name)
inline Variable &ProcedureBuilder::add_parameter(ParamType param_type, std::string name)
{
MFVariable &variable = procedure_->new_variable(param_type.data_type(), std::move(name));
Variable &variable = procedure_->new_variable(param_type.data_type(), std::move(name));
this->add_parameter(param_type.interface_type(), variable);
return variable;
}
inline MFVariable &MFProcedureBuilder::add_input_parameter(MFDataType data_type, std::string name)
inline Variable &ProcedureBuilder::add_input_parameter(DataType data_type, std::string name)
{
return this->add_parameter(MFParamType(MFParamType::Input, data_type), std::move(name));
return this->add_parameter(ParamType(ParamType::Input, data_type), std::move(name));
}
template<typename T>
inline MFVariable &MFProcedureBuilder::add_single_input_parameter(std::string name)
inline Variable &ProcedureBuilder::add_single_input_parameter(std::string name)
{
return this->add_parameter(MFParamType::ForSingleInput(CPPType::get<T>()), std::move(name));
return this->add_parameter(ParamType::ForSingleInput(CPPType::get<T>()), std::move(name));
}
template<typename T>
inline MFVariable &MFProcedureBuilder::add_single_mutable_parameter(std::string name)
inline Variable &ProcedureBuilder::add_single_mutable_parameter(std::string name)
{
return this->add_parameter(MFParamType::ForMutableSingle(CPPType::get<T>()), std::move(name));
return this->add_parameter(ParamType::ForMutableSingle(CPPType::get<T>()), std::move(name));
}
inline void MFProcedureBuilder::add_output_parameter(MFVariable &variable)
inline void ProcedureBuilder::add_output_parameter(Variable &variable)
{
this->add_parameter(MFParamType::Output, variable);
this->add_parameter(ParamType::Output, variable);
}
inline void MFProcedureBuilder::link_to_cursors(MFInstruction *instruction)
inline void ProcedureBuilder::link_to_cursors(Instruction *instruction)
{
for (MFInstructionCursor &cursor : cursors_) {
for (InstructionCursor &cursor : cursors_) {
cursor.set_next(*procedure_, instruction);
}
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -8,21 +8,21 @@
#include "FN_multi_function_procedure.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
/** A multi-function that executes a procedure internally. */
class MFProcedureExecutor : public MultiFunction {
class ProcedureExecutor : public MultiFunction {
private:
MFSignature signature_;
const MFProcedure &procedure_;
Signature signature_;
const Procedure &procedure_;
public:
MFProcedureExecutor(const MFProcedure &procedure);
ProcedureExecutor(const Procedure &procedure);
void call(IndexMask mask, MFParams params, MFContext context) const override;
void call(IndexMask mask, MFParams params, Context context) const override;
private:
ExecutionHints get_execution_hints() const override;
};
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -5,11 +5,11 @@
/** \file
* \ingroup fn
*
* A #MFProcedure optimization pass takes an existing procedure and changes it in a way that
* A #Procedure optimization pass takes an existing procedure and changes it in a way that
* improves its performance when executed.
*
* Oftentimes it would also be possible to implement a specific optimization directly during
* construction of the initial #MFProcedure. There is a trade-off between doing that or just
* construction of the initial #Procedure. There is a trade-off between doing that or just
* building a "simple" procedure and then optimizing it uses separate optimization passes.
* - Doing optimizations directly during construction is typically faster than doing it as a
* separate pass. However, it would be much harder to turn the optimization off when it is not
@@ -23,10 +23,10 @@
#include "FN_multi_function_procedure.hh"
namespace blender::fn::procedure_optimization {
namespace blender::fn::multi_function::procedure_optimization {
/**
* When generating a procedure, destruct instructions (#MFDestructInstruction) have to be inserted
* When generating a procedure, destruct instructions (#DestructInstruction) have to be inserted
* for all variables that are not outputs. Often the simplest approach is to add these instructions
* at the very end. However, when the procedure is executed this is not optimal, because many more
* variables are initialized at the same time than necessary. This inhibits the reuse of memory
@@ -42,6 +42,6 @@ namespace blender::fn::procedure_optimization {
* \param block_end_instr: The instruction that points to the last instruction within a linear
* chain of instructions. The algorithm moves instructions backward starting at this instruction.
*/
void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr);
void move_destructs_up(Procedure &procedure, Instruction &block_end_instr);
} // namespace blender::fn::procedure_optimization
} // namespace blender::fn::multi_function::procedure_optimization

View File

@@ -6,18 +6,18 @@
* \ingroup fn
*
* The signature of a multi-function contains the functions name and expected parameters. New
* signatures should be build using the #MFSignatureBuilder class.
* signatures should be build using the #SignatureBuilder class.
*/
#include "FN_multi_function_param_type.hh"
#include "BLI_vector.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
struct MFSignature {
struct Signature {
struct ParamInfo {
MFParamType type;
ParamType type;
const char *name;
};
@@ -32,12 +32,12 @@ struct MFSignature {
Vector<ParamInfo> params;
};
class MFSignatureBuilder {
class SignatureBuilder {
private:
MFSignature &signature_;
Signature &signature_;
public:
MFSignatureBuilder(const char *function_name, MFSignature &signature_to_build)
SignatureBuilder(const char *function_name, Signature &signature_to_build)
: signature_(signature_to_build)
{
signature_.function_name = function_name;
@@ -51,7 +51,7 @@ class MFSignatureBuilder {
}
void single_input(const char *name, const CPPType &type)
{
this->input(name, MFDataType::ForSingle(type));
this->input(name, DataType::ForSingle(type));
}
template<typename T> void vector_input(const char *name)
{
@@ -59,11 +59,11 @@ class MFSignatureBuilder {
}
void vector_input(const char *name, const CPPType &base_type)
{
this->input(name, MFDataType::ForVector(base_type));
this->input(name, DataType::ForVector(base_type));
}
void input(const char *name, MFDataType data_type)
void input(const char *name, DataType data_type)
{
signature_.params.append({MFParamType(MFParamType::Input, data_type), name});
signature_.params.append({ParamType(ParamType::Input, data_type), name});
}
/* Output Parameter Types */
@@ -74,7 +74,7 @@ class MFSignatureBuilder {
}
void single_output(const char *name, const CPPType &type)
{
this->output(name, MFDataType::ForSingle(type));
this->output(name, DataType::ForSingle(type));
}
template<typename T> void vector_output(const char *name)
{
@@ -82,11 +82,11 @@ class MFSignatureBuilder {
}
void vector_output(const char *name, const CPPType &base_type)
{
this->output(name, MFDataType::ForVector(base_type));
this->output(name, DataType::ForVector(base_type));
}
void output(const char *name, MFDataType data_type)
void output(const char *name, DataType data_type)
{
signature_.params.append({MFParamType(MFParamType::Output, data_type), name});
signature_.params.append({ParamType(ParamType::Output, data_type), name});
}
/* Mutable Parameter Types */
@@ -97,7 +97,7 @@ class MFSignatureBuilder {
}
void single_mutable(const char *name, const CPPType &type)
{
this->mutable_(name, MFDataType::ForSingle(type));
this->mutable_(name, DataType::ForSingle(type));
}
template<typename T> void vector_mutable(const char *name)
{
@@ -105,48 +105,48 @@ class MFSignatureBuilder {
}
void vector_mutable(const char *name, const CPPType &base_type)
{
this->mutable_(name, MFDataType::ForVector(base_type));
this->mutable_(name, DataType::ForVector(base_type));
}
void mutable_(const char *name, MFDataType data_type)
void mutable_(const char *name, DataType data_type)
{
signature_.params.append({MFParamType(MFParamType::Mutable, data_type), name});
signature_.params.append({ParamType(ParamType::Mutable, data_type), name});
}
void add(const char *name, const MFParamType &param_type)
void add(const char *name, const ParamType &param_type)
{
switch (param_type.interface_type()) {
case MFParamType::Input:
case ParamType::Input:
this->input(name, param_type.data_type());
break;
case MFParamType::Mutable:
case ParamType::Mutable:
this->mutable_(name, param_type.data_type());
break;
case MFParamType::Output:
case ParamType::Output:
this->output(name, param_type.data_type());
break;
}
}
template<MFParamCategory Category, typename T>
template<ParamCategory Category, typename T>
void add(MFParamTag<Category, T> /* tag */, const char *name)
{
switch (Category) {
case MFParamCategory::SingleInput:
case ParamCategory::SingleInput:
this->single_input<T>(name);
return;
case MFParamCategory::VectorInput:
case ParamCategory::VectorInput:
this->vector_input<T>(name);
return;
case MFParamCategory::SingleOutput:
case ParamCategory::SingleOutput:
this->single_output<T>(name);
return;
case MFParamCategory::VectorOutput:
case ParamCategory::VectorOutput:
this->vector_output<T>(name);
return;
case MFParamCategory::SingleMutable:
case ParamCategory::SingleMutable:
this->single_mutable<T>(name);
return;
case MFParamCategory::VectorMutable:
case ParamCategory::VectorMutable:
this->vector_mutable<T>(name);
return;
}
@@ -154,4 +154,4 @@ class MFSignatureBuilder {
}
};
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -142,19 +142,19 @@ static Set<GFieldRef> find_varying_fields(const FieldTreeInfo &field_tree_info,
/**
* Builds the #procedure so that it computes the fields.
*/
static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
static void build_multi_function_procedure_for_fields(mf::Procedure &procedure,
ResourceScope &scope,
const FieldTreeInfo &field_tree_info,
Span<GFieldRef> output_fields)
{
MFProcedureBuilder builder{procedure};
mf::ProcedureBuilder builder{procedure};
/* Every input, intermediate and output field corresponds to a variable in the procedure. */
Map<GFieldRef, MFVariable *> variable_by_field;
Map<GFieldRef, mf::Variable *> variable_by_field;
/* Start by adding the field inputs as parameters to the procedure. */
for (const FieldInput &field_input : field_tree_info.deduplicated_field_inputs) {
MFVariable &variable = builder.add_input_parameter(
MFDataType::ForSingle(field_input.cpp_type()), field_input.debug_name());
mf::Variable &variable = builder.add_input_parameter(
mf::DataType::ForSingle(field_input.cpp_type()), field_input.debug_name());
variable_by_field.add_new({field_input, 0}, &variable);
}
@@ -196,20 +196,20 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
else {
/* All inputs variables are ready, now gather all variables that are used by the
* function and call it. */
const MultiFunction &multi_function = operation_node.multi_function();
Vector<MFVariable *> variables(multi_function.param_amount());
const mf::MultiFunction &multi_function = operation_node.multi_function();
Vector<mf::Variable *> variables(multi_function.param_amount());
int param_input_index = 0;
int param_output_index = 0;
for (const int param_index : multi_function.param_indices()) {
const MFParamType param_type = multi_function.param_type(param_index);
const MFParamType::InterfaceType interface_type = param_type.interface_type();
if (interface_type == MFParamType::Input) {
const mf::ParamType param_type = multi_function.param_type(param_index);
const mf::ParamType::InterfaceType interface_type = param_type.interface_type();
if (interface_type == mf::ParamType::Input) {
const GField &input_field = operation_inputs[param_input_index];
variables[param_index] = variable_by_field.lookup(input_field);
param_input_index++;
}
else if (interface_type == MFParamType::Output) {
else if (interface_type == mf::ParamType::Output) {
const GFieldRef output_field{operation_node, param_output_index};
const bool output_is_ignored =
field_tree_info.field_users.lookup(output_field).is_empty() &&
@@ -220,7 +220,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
}
else {
/* Create a new variable for used outputs. */
MFVariable &new_variable = procedure.new_variable(param_type.data_type());
mf::Variable &new_variable = procedure.new_variable(param_type.data_type());
variables[param_index] = &new_variable;
variable_by_field.add_new(output_field, &new_variable);
}
@@ -236,9 +236,9 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
}
case FieldNodeType::Constant: {
const FieldConstant &constant_node = static_cast<const FieldConstant &>(field_node);
const MultiFunction &fn = procedure.construct_function<CustomMF_GenericConstant>(
const mf::MultiFunction &fn = procedure.construct_function<mf::CustomMF_GenericConstant>(
constant_node.type(), constant_node.value().get(), false);
MFVariable &new_variable = *builder.add_call<1>(fn)[0];
mf::Variable &new_variable = *builder.add_call<1>(fn)[0];
variable_by_field.add_new(field, &new_variable);
break;
}
@@ -247,13 +247,14 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
}
/* Add output parameters to the procedure. */
Set<MFVariable *> already_output_variables;
Set<mf::Variable *> already_output_variables;
for (const GFieldRef &field : output_fields) {
MFVariable *variable = variable_by_field.lookup(field);
mf::Variable *variable = variable_by_field.lookup(field);
if (!already_output_variables.add(variable)) {
/* One variable can be output at most once. To output the same value twice, we have to make
* a copy first. */
const MultiFunction &copy_fn = scope.construct<CustomMF_GenericCopy>(variable->data_type());
const mf::MultiFunction &copy_fn = scope.construct<mf::CustomMF_GenericCopy>(
variable->data_type());
variable = builder.add_call<1>(copy_fn, {variable})[0];
}
builder.add_output_parameter(*variable);
@@ -264,13 +265,13 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
variable_by_field.remove(field);
}
/* Add destructor calls for the remaining variables. */
for (MFVariable *variable : variable_by_field.values()) {
for (mf::Variable *variable : variable_by_field.values()) {
builder.add_destruct(*variable);
}
MFReturnInstruction &return_instr = builder.add_return();
mf::ReturnInstruction &return_instr = builder.add_return();
procedure_optimization::move_destructs_up(procedure, return_instr);
mf::procedure_optimization::move_destructs_up(procedure, return_instr);
// std::cout << procedure.to_dot() << "\n";
BLI_assert(procedure.validate());
@@ -366,13 +367,13 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope,
/* Evaluate varying fields if necessary. */
if (!varying_fields_to_evaluate.is_empty()) {
/* Build the procedure for those fields. */
MFProcedure procedure;
mf::Procedure procedure;
build_multi_function_procedure_for_fields(
procedure, scope, field_tree_info, varying_fields_to_evaluate);
MFProcedureExecutor procedure_executor{procedure};
mf::ProcedureExecutor procedure_executor{procedure};
MFParamsBuilder mf_params{procedure_executor, &mask};
MFContextBuilder mf_context;
mf::ParamsBuilder mf_params{procedure_executor, &mask};
mf::ContextBuilder mf_context;
/* Provide inputs to the procedure executor. */
for (const GVArray &varray : field_context_inputs) {
@@ -418,12 +419,12 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope,
/* Evaluate constant fields if necessary. */
if (!constant_fields_to_evaluate.is_empty()) {
/* Build the procedure for those fields. */
MFProcedure procedure;
mf::Procedure procedure;
build_multi_function_procedure_for_fields(
procedure, scope, field_tree_info, constant_fields_to_evaluate);
MFProcedureExecutor procedure_executor{procedure};
MFParamsBuilder mf_params{procedure_executor, 1};
MFContextBuilder mf_context;
mf::ProcedureExecutor procedure_executor{procedure};
mf::ParamsBuilder mf_params{procedure_executor, 1};
mf::ContextBuilder mf_context;
/* Provide inputs to the procedure executor. */
for (const GVArray &varray : field_context_inputs) {
@@ -519,8 +520,8 @@ GField make_field_constant_if_possible(GField field)
Field<bool> invert_boolean_field(const Field<bool> &field)
{
static auto not_fn = build_mf::SI1_SO<bool, bool>(
"Not", [](bool a) { return !a; }, build_mf::exec_presets::AllSpanOrSingle());
static auto not_fn = mf::build::SI1_SO<bool, bool>(
"Not", [](bool a) { return !a; }, mf::build::exec_presets::AllSpanOrSingle());
auto not_op = std::make_shared<FieldOperation>(FieldOperation(not_fn, {field}));
return Field<bool>(not_op);
}
@@ -597,7 +598,7 @@ void FieldNode::for_each_field_input_recursive(FunctionRef<void(const FieldInput
/** \name #FieldOperation
* \{ */
FieldOperation::FieldOperation(std::shared_ptr<const MultiFunction> function,
FieldOperation::FieldOperation(std::shared_ptr<const mf::MultiFunction> function,
Vector<GField> inputs)
: FieldOperation(*function, std::move(inputs))
{
@@ -662,7 +663,7 @@ static std::shared_ptr<const FieldInputs> combine_field_inputs(Span<GField> fiel
return new_field_inputs;
}
FieldOperation::FieldOperation(const MultiFunction &function, Vector<GField> inputs)
FieldOperation::FieldOperation(const mf::MultiFunction &function, Vector<GField> inputs)
: FieldNode(FieldNodeType::Operation), function_(&function), inputs_(std::move(inputs))
{
field_inputs_ = combine_field_inputs(inputs_);

View File

@@ -5,7 +5,7 @@
#include "BLI_task.hh"
#include "BLI_threads.h"
namespace blender::fn {
namespace blender::fn::multi_function {
using ExecutionHints = MultiFunction::ExecutionHints;
@@ -22,10 +22,10 @@ ExecutionHints MultiFunction::get_execution_hints() const
static bool supports_threading_by_slicing_params(const MultiFunction &fn)
{
for (const int i : fn.param_indices()) {
const MFParamType param_type = fn.param_type(i);
const ParamType param_type = fn.param_type(i);
if (ELEM(param_type.interface_type(),
MFParamType::InterfaceType::Mutable,
MFParamType::InterfaceType::Output)) {
ParamType::InterfaceType::Mutable,
ParamType::InterfaceType::Output)) {
if (param_type.data_type().is_vector()) {
return false;
}
@@ -52,7 +52,7 @@ static int64_t compute_grain_size(const ExecutionHints &hints, const IndexMask m
return grain_size;
}
void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context) const
void MultiFunction::call_auto(IndexMask mask, MFParams params, Context context) const
{
if (mask.is_empty()) {
return;
@@ -90,24 +90,24 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context
Vector<int64_t> offset_mask_indices;
const IndexMask offset_mask = mask.slice_and_offset(sub_range, offset_mask_indices);
MFParamsBuilder offset_params{*this, offset_mask.min_array_size()};
ParamsBuilder offset_params{*this, offset_mask.min_array_size()};
/* Slice all parameters so that for the actual function call. */
for (const int param_index : this->param_indices()) {
const MFParamType param_type = this->param_type(param_index);
const ParamType param_type = this->param_type(param_index);
switch (param_type.category()) {
case MFParamCategory::SingleInput: {
case ParamCategory::SingleInput: {
const GVArray &varray = params.readonly_single_input(param_index);
offset_params.add_readonly_single_input(varray.slice(input_slice_range));
break;
}
case MFParamCategory::SingleMutable: {
case ParamCategory::SingleMutable: {
const GMutableSpan span = params.single_mutable(param_index);
const GMutableSpan sliced_span = span.slice(input_slice_range);
offset_params.add_single_mutable(sliced_span);
break;
}
case MFParamCategory::SingleOutput: {
case ParamCategory::SingleOutput: {
const GMutableSpan span = params.uninitialized_single_output_if_required(param_index);
if (span.is_empty()) {
offset_params.add_ignored_single_output();
@@ -118,9 +118,9 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context
}
break;
}
case MFParamCategory::VectorInput:
case MFParamCategory::VectorMutable:
case MFParamCategory::VectorOutput: {
case ParamCategory::VectorInput:
case ParamCategory::VectorMutable:
case ParamCategory::VectorOutput: {
BLI_assert_unreachable();
break;
}
@@ -136,4 +136,4 @@ std::string MultiFunction::debug_name() const
return signature_ref_->function_name;
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -4,7 +4,7 @@
#include "BLI_hash.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type,
const void *value,
@@ -18,7 +18,7 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type,
}
value_ = value;
MFSignatureBuilder builder{"Constant", signature_};
SignatureBuilder builder{"Constant", signature_};
builder.single_output("Value", type);
this->set_signature(&signature_);
}
@@ -31,7 +31,7 @@ CustomMF_GenericConstant::~CustomMF_GenericConstant()
}
}
void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, MFContext /*context*/) const
void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, Context /*context*/) const
{
GMutableSpan output = params.uninitialized_single_output(0);
type_.fill_construct_indices(value_, output.data(), mask);
@@ -57,14 +57,14 @@ bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array)
{
const CPPType &type = array.type();
MFSignatureBuilder builder{"Constant Vector", signature_};
SignatureBuilder builder{"Constant Vector", signature_};
builder.vector_output("Value", type);
this->set_signature(&signature_);
}
void CustomMF_GenericConstantArray::call(IndexMask mask,
MFParams params,
MFContext /*context*/) const
Context /*context*/) const
{
GVectorArray &vectors = params.vector_output(0);
for (int64_t i : mask) {
@@ -72,23 +72,23 @@ void CustomMF_GenericConstantArray::call(IndexMask mask,
}
}
CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<MFDataType> input_types,
Span<MFDataType> output_types)
CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<DataType> input_types,
Span<DataType> output_types)
: output_amount_(output_types.size())
{
MFSignatureBuilder builder{"Default Output", signature_};
for (MFDataType data_type : input_types) {
SignatureBuilder builder{"Default Output", signature_};
for (DataType data_type : input_types) {
builder.input("Input", data_type);
}
for (MFDataType data_type : output_types) {
for (DataType data_type : output_types) {
builder.output("Output", data_type);
}
this->set_signature(&signature_);
}
void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*context*/) const
void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, Context /*context*/) const
{
for (int param_index : this->param_indices()) {
MFParamType param_type = this->param_type(param_index);
ParamType param_type = this->param_type(param_index);
if (!param_type.is_output()) {
continue;
}
@@ -101,25 +101,25 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*c
}
}
CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type)
CustomMF_GenericCopy::CustomMF_GenericCopy(DataType data_type)
{
MFSignatureBuilder builder{"Copy", signature_};
SignatureBuilder builder{"Copy", signature_};
builder.input("Input", data_type);
builder.output("Output", data_type);
this->set_signature(&signature_);
}
void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext /*context*/) const
void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, Context /*context*/) const
{
const MFDataType data_type = this->param_type(0).data_type();
const DataType data_type = this->param_type(0).data_type();
switch (data_type.category()) {
case MFDataType::Single: {
case DataType::Single: {
const GVArray &inputs = params.readonly_single_input(0, "Input");
GMutableSpan outputs = params.uninitialized_single_output(1, "Output");
inputs.materialize_to_uninitialized(mask, outputs.data());
break;
}
case MFDataType::Vector: {
case DataType::Vector: {
const GVVectorArray &inputs = params.readonly_vector_input(0, "Input");
GVectorArray &outputs = params.vector_output(1, "Output");
outputs.extend(mask, inputs);
@@ -128,4 +128,4 @@ void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext /*con
}
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -2,7 +2,7 @@
#include "FN_multi_function_params.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
GMutableSpan MFParams::ensure_dummy_single_output(int param_index)
{
@@ -27,4 +27,4 @@ GMutableSpan MFParams::ensure_dummy_single_output(int param_index)
return span;
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -5,9 +5,9 @@
#include "BLI_dot_export.hh"
#include "BLI_stack.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
void MFInstructionCursor::set_next(MFProcedure &procedure, MFInstruction *new_instruction) const
void InstructionCursor::set_next(Procedure &procedure, Instruction *new_instruction) const
{
switch (type_) {
case Type::None: {
@@ -18,11 +18,11 @@ void MFInstructionCursor::set_next(MFProcedure &procedure, MFInstruction *new_in
break;
}
case Type::Call: {
static_cast<MFCallInstruction *>(instruction_)->set_next(new_instruction);
static_cast<CallInstruction *>(instruction_)->set_next(new_instruction);
break;
}
case Type::Branch: {
MFBranchInstruction &branch_instruction = *static_cast<MFBranchInstruction *>(instruction_);
BranchInstruction &branch_instruction = *static_cast<BranchInstruction *>(instruction_);
if (branch_output_) {
branch_instruction.set_branch_true(new_instruction);
}
@@ -32,17 +32,17 @@ void MFInstructionCursor::set_next(MFProcedure &procedure, MFInstruction *new_in
break;
}
case Type::Destruct: {
static_cast<MFDestructInstruction *>(instruction_)->set_next(new_instruction);
static_cast<DestructInstruction *>(instruction_)->set_next(new_instruction);
break;
}
case Type::Dummy: {
static_cast<MFDummyInstruction *>(instruction_)->set_next(new_instruction);
static_cast<DummyInstruction *>(instruction_)->set_next(new_instruction);
break;
}
}
}
MFInstruction *MFInstructionCursor::next(MFProcedure &procedure) const
Instruction *InstructionCursor::next(Procedure &procedure) const
{
switch (type_) {
case Type::None:
@@ -50,28 +50,28 @@ MFInstruction *MFInstructionCursor::next(MFProcedure &procedure) const
case Type::Entry:
return procedure.entry();
case Type::Call:
return static_cast<MFCallInstruction *>(instruction_)->next();
return static_cast<CallInstruction *>(instruction_)->next();
case Type::Branch: {
MFBranchInstruction &branch_instruction = *static_cast<MFBranchInstruction *>(instruction_);
BranchInstruction &branch_instruction = *static_cast<BranchInstruction *>(instruction_);
if (branch_output_) {
return branch_instruction.branch_true();
}
return branch_instruction.branch_false();
}
case Type::Destruct:
return static_cast<MFDestructInstruction *>(instruction_)->next();
return static_cast<DestructInstruction *>(instruction_)->next();
case Type::Dummy:
return static_cast<MFDummyInstruction *>(instruction_)->next();
return static_cast<DummyInstruction *>(instruction_)->next();
}
return nullptr;
}
void MFVariable::set_name(std::string name)
void Variable::set_name(std::string name)
{
name_ = std::move(name);
}
void MFCallInstruction::set_next(MFInstruction *instruction)
void CallInstruction::set_next(Instruction *instruction)
{
if (next_ != nullptr) {
next_->prev_.remove_first_occurrence_and_reorder(*this);
@@ -82,7 +82,7 @@ void MFCallInstruction::set_next(MFInstruction *instruction)
next_ = instruction;
}
void MFCallInstruction::set_param_variable(int param_index, MFVariable *variable)
void CallInstruction::set_param_variable(int param_index, Variable *variable)
{
if (params_[param_index] != nullptr) {
params_[param_index]->users_.remove_first_occurrence_and_reorder(this);
@@ -94,7 +94,7 @@ void MFCallInstruction::set_param_variable(int param_index, MFVariable *variable
params_[param_index] = variable;
}
void MFCallInstruction::set_params(Span<MFVariable *> variables)
void CallInstruction::set_params(Span<Variable *> variables)
{
BLI_assert(variables.size() == params_.size());
for (const int i : variables.index_range()) {
@@ -102,7 +102,7 @@ void MFCallInstruction::set_params(Span<MFVariable *> variables)
}
}
void MFBranchInstruction::set_condition(MFVariable *variable)
void BranchInstruction::set_condition(Variable *variable)
{
if (condition_ != nullptr) {
condition_->users_.remove_first_occurrence_and_reorder(this);
@@ -113,7 +113,7 @@ void MFBranchInstruction::set_condition(MFVariable *variable)
condition_ = variable;
}
void MFBranchInstruction::set_branch_true(MFInstruction *instruction)
void BranchInstruction::set_branch_true(Instruction *instruction)
{
if (branch_true_ != nullptr) {
branch_true_->prev_.remove_first_occurrence_and_reorder({*this, true});
@@ -124,7 +124,7 @@ void MFBranchInstruction::set_branch_true(MFInstruction *instruction)
branch_true_ = instruction;
}
void MFBranchInstruction::set_branch_false(MFInstruction *instruction)
void BranchInstruction::set_branch_false(Instruction *instruction)
{
if (branch_false_ != nullptr) {
branch_false_->prev_.remove_first_occurrence_and_reorder({*this, false});
@@ -135,7 +135,7 @@ void MFBranchInstruction::set_branch_false(MFInstruction *instruction)
branch_false_ = instruction;
}
void MFDestructInstruction::set_variable(MFVariable *variable)
void DestructInstruction::set_variable(Variable *variable)
{
if (variable_ != nullptr) {
variable_->users_.remove_first_occurrence_and_reorder(this);
@@ -146,7 +146,7 @@ void MFDestructInstruction::set_variable(MFVariable *variable)
variable_ = variable;
}
void MFDestructInstruction::set_next(MFInstruction *instruction)
void DestructInstruction::set_next(Instruction *instruction)
{
if (next_ != nullptr) {
next_->prev_.remove_first_occurrence_and_reorder(*this);
@@ -157,7 +157,7 @@ void MFDestructInstruction::set_next(MFInstruction *instruction)
next_ = instruction;
}
void MFDummyInstruction::set_next(MFInstruction *instruction)
void DummyInstruction::set_next(Instruction *instruction)
{
if (next_ != nullptr) {
next_->prev_.remove_first_occurrence_and_reorder(*this);
@@ -168,9 +168,9 @@ void MFDummyInstruction::set_next(MFInstruction *instruction)
next_ = instruction;
}
MFVariable &MFProcedure::new_variable(MFDataType data_type, std::string name)
Variable &Procedure::new_variable(DataType data_type, std::string name)
{
MFVariable &variable = *allocator_.construct<MFVariable>().release();
Variable &variable = *allocator_.construct<Variable>().release();
variable.name_ = std::move(name);
variable.data_type_ = data_type;
variable.index_in_graph_ = variables_.size();
@@ -178,86 +178,86 @@ MFVariable &MFProcedure::new_variable(MFDataType data_type, std::string name)
return variable;
}
MFCallInstruction &MFProcedure::new_call_instruction(const MultiFunction &fn)
CallInstruction &Procedure::new_call_instruction(const MultiFunction &fn)
{
MFCallInstruction &instruction = *allocator_.construct<MFCallInstruction>().release();
instruction.type_ = MFInstructionType::Call;
CallInstruction &instruction = *allocator_.construct<CallInstruction>().release();
instruction.type_ = InstructionType::Call;
instruction.fn_ = &fn;
instruction.params_ = allocator_.allocate_array<MFVariable *>(fn.param_amount());
instruction.params_ = allocator_.allocate_array<Variable *>(fn.param_amount());
instruction.params_.fill(nullptr);
call_instructions_.append(&instruction);
return instruction;
}
MFBranchInstruction &MFProcedure::new_branch_instruction()
BranchInstruction &Procedure::new_branch_instruction()
{
MFBranchInstruction &instruction = *allocator_.construct<MFBranchInstruction>().release();
instruction.type_ = MFInstructionType::Branch;
BranchInstruction &instruction = *allocator_.construct<BranchInstruction>().release();
instruction.type_ = InstructionType::Branch;
branch_instructions_.append(&instruction);
return instruction;
}
MFDestructInstruction &MFProcedure::new_destruct_instruction()
DestructInstruction &Procedure::new_destruct_instruction()
{
MFDestructInstruction &instruction = *allocator_.construct<MFDestructInstruction>().release();
instruction.type_ = MFInstructionType::Destruct;
DestructInstruction &instruction = *allocator_.construct<DestructInstruction>().release();
instruction.type_ = InstructionType::Destruct;
destruct_instructions_.append(&instruction);
return instruction;
}
MFDummyInstruction &MFProcedure::new_dummy_instruction()
DummyInstruction &Procedure::new_dummy_instruction()
{
MFDummyInstruction &instruction = *allocator_.construct<MFDummyInstruction>().release();
instruction.type_ = MFInstructionType::Dummy;
DummyInstruction &instruction = *allocator_.construct<DummyInstruction>().release();
instruction.type_ = InstructionType::Dummy;
dummy_instructions_.append(&instruction);
return instruction;
}
MFReturnInstruction &MFProcedure::new_return_instruction()
ReturnInstruction &Procedure::new_return_instruction()
{
MFReturnInstruction &instruction = *allocator_.construct<MFReturnInstruction>().release();
instruction.type_ = MFInstructionType::Return;
ReturnInstruction &instruction = *allocator_.construct<ReturnInstruction>().release();
instruction.type_ = InstructionType::Return;
return_instructions_.append(&instruction);
return instruction;
}
void MFProcedure::add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable)
void Procedure::add_parameter(ParamType::InterfaceType interface_type, Variable &variable)
{
params_.append({interface_type, &variable});
}
void MFProcedure::set_entry(MFInstruction &entry)
void Procedure::set_entry(Instruction &entry)
{
if (entry_ != nullptr) {
entry_->prev_.remove_first_occurrence_and_reorder(MFInstructionCursor::ForEntry());
entry_->prev_.remove_first_occurrence_and_reorder(InstructionCursor::ForEntry());
}
entry_ = &entry;
entry_->prev_.append(MFInstructionCursor::ForEntry());
entry_->prev_.append(InstructionCursor::ForEntry());
}
MFProcedure::~MFProcedure()
Procedure::~Procedure()
{
for (MFCallInstruction *instruction : call_instructions_) {
instruction->~MFCallInstruction();
for (CallInstruction *instruction : call_instructions_) {
instruction->~CallInstruction();
}
for (MFBranchInstruction *instruction : branch_instructions_) {
instruction->~MFBranchInstruction();
for (BranchInstruction *instruction : branch_instructions_) {
instruction->~BranchInstruction();
}
for (MFDestructInstruction *instruction : destruct_instructions_) {
instruction->~MFDestructInstruction();
for (DestructInstruction *instruction : destruct_instructions_) {
instruction->~DestructInstruction();
}
for (MFDummyInstruction *instruction : dummy_instructions_) {
instruction->~MFDummyInstruction();
for (DummyInstruction *instruction : dummy_instructions_) {
instruction->~DummyInstruction();
}
for (MFReturnInstruction *instruction : return_instructions_) {
instruction->~MFReturnInstruction();
for (ReturnInstruction *instruction : return_instructions_) {
instruction->~ReturnInstruction();
}
for (MFVariable *variable : variables_) {
variable->~MFVariable();
for (Variable *variable : variables_) {
variable->~Variable();
}
}
bool MFProcedure::validate() const
bool Procedure::validate() const
{
if (entry_ == nullptr) {
return false;
@@ -280,19 +280,19 @@ bool MFProcedure::validate() const
return true;
}
bool MFProcedure::validate_all_instruction_pointers_set() const
bool Procedure::validate_all_instruction_pointers_set() const
{
for (const MFCallInstruction *instruction : call_instructions_) {
for (const CallInstruction *instruction : call_instructions_) {
if (instruction->next_ == nullptr) {
return false;
}
}
for (const MFDestructInstruction *instruction : destruct_instructions_) {
for (const DestructInstruction *instruction : destruct_instructions_) {
if (instruction->next_ == nullptr) {
return false;
}
}
for (const MFBranchInstruction *instruction : branch_instructions_) {
for (const BranchInstruction *instruction : branch_instructions_) {
if (instruction->branch_true_ == nullptr) {
return false;
}
@@ -300,7 +300,7 @@ bool MFProcedure::validate_all_instruction_pointers_set() const
return false;
}
}
for (const MFDummyInstruction *instruction : dummy_instructions_) {
for (const DummyInstruction *instruction : dummy_instructions_) {
if (instruction->next_ == nullptr) {
return false;
}
@@ -308,28 +308,28 @@ bool MFProcedure::validate_all_instruction_pointers_set() const
return true;
}
bool MFProcedure::validate_all_params_provided() const
bool Procedure::validate_all_params_provided() const
{
for (const MFCallInstruction *instruction : call_instructions_) {
for (const CallInstruction *instruction : call_instructions_) {
const MultiFunction &fn = instruction->fn();
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
if (param_type.category() == MFParamCategory::SingleOutput) {
const ParamType param_type = fn.param_type(param_index);
if (param_type.category() == ParamCategory::SingleOutput) {
/* Single outputs are optional. */
continue;
}
const MFVariable *variable = instruction->params_[param_index];
const Variable *variable = instruction->params_[param_index];
if (variable == nullptr) {
return false;
}
}
}
for (const MFBranchInstruction *instruction : branch_instructions_) {
for (const BranchInstruction *instruction : branch_instructions_) {
if (instruction->condition_ == nullptr) {
return false;
}
}
for (const MFDestructInstruction *instruction : destruct_instructions_) {
for (const DestructInstruction *instruction : destruct_instructions_) {
if (instruction->variable_ == nullptr) {
return false;
}
@@ -337,13 +337,13 @@ bool MFProcedure::validate_all_params_provided() const
return true;
}
bool MFProcedure::validate_same_variables_in_one_call() const
bool Procedure::validate_same_variables_in_one_call() const
{
for (const MFCallInstruction *instruction : call_instructions_) {
for (const CallInstruction *instruction : call_instructions_) {
const MultiFunction &fn = *instruction->fn_;
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
const MFVariable *variable = instruction->params_[param_index];
const ParamType param_type = fn.param_type(param_index);
const Variable *variable = instruction->params_[param_index];
if (variable == nullptr) {
continue;
}
@@ -351,17 +351,17 @@ bool MFProcedure::validate_same_variables_in_one_call() const
if (other_param_index == param_index) {
continue;
}
const MFVariable *other_variable = instruction->params_[other_param_index];
const Variable *other_variable = instruction->params_[other_param_index];
if (other_variable != variable) {
continue;
}
if (ELEM(param_type.interface_type(), MFParamType::Mutable, MFParamType::Output)) {
if (ELEM(param_type.interface_type(), ParamType::Mutable, ParamType::Output)) {
/* When a variable is used as mutable or output parameter, it can only be used once. */
return false;
}
const MFParamType other_param_type = fn.param_type(other_param_index);
const ParamType other_param_type = fn.param_type(other_param_index);
/* A variable is allowed to be used as input more than once. */
if (other_param_type.interface_type() != MFParamType::Input) {
if (other_param_type.interface_type() != ParamType::Input) {
return false;
}
}
@@ -370,9 +370,9 @@ bool MFProcedure::validate_same_variables_in_one_call() const
return true;
}
bool MFProcedure::validate_parameters() const
bool Procedure::validate_parameters() const
{
Set<const MFVariable *> variables;
Set<const Variable *> variables;
for (const MFParameter &param : params_) {
/* One variable cannot be used as multiple parameters. */
if (!variables.add(param.variable)) {
@@ -382,45 +382,45 @@ bool MFProcedure::validate_parameters() const
return true;
}
bool MFProcedure::validate_initialization() const
bool Procedure::validate_initialization() const
{
/* TODO: Issue warning when it maybe wrongly initialized. */
for (const MFDestructInstruction *instruction : destruct_instructions_) {
const MFVariable &variable = *instruction->variable_;
for (const DestructInstruction *instruction : destruct_instructions_) {
const Variable &variable = *instruction->variable_;
const InitState state = this->find_initialization_state_before_instruction(*instruction,
variable);
if (!state.can_be_initialized) {
return false;
}
}
for (const MFBranchInstruction *instruction : branch_instructions_) {
const MFVariable &variable = *instruction->condition_;
for (const BranchInstruction *instruction : branch_instructions_) {
const Variable &variable = *instruction->condition_;
const InitState state = this->find_initialization_state_before_instruction(*instruction,
variable);
if (!state.can_be_initialized) {
return false;
}
}
for (const MFCallInstruction *instruction : call_instructions_) {
for (const CallInstruction *instruction : call_instructions_) {
const MultiFunction &fn = *instruction->fn_;
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
const ParamType param_type = fn.param_type(param_index);
/* If the parameter was an unneeded output, it could be null. */
if (!instruction->params_[param_index]) {
continue;
}
const MFVariable &variable = *instruction->params_[param_index];
const Variable &variable = *instruction->params_[param_index];
const InitState state = this->find_initialization_state_before_instruction(*instruction,
variable);
switch (param_type.interface_type()) {
case MFParamType::Input:
case MFParamType::Mutable: {
case ParamType::Input:
case ParamType::Mutable: {
if (!state.can_be_initialized) {
return false;
}
break;
}
case MFParamType::Output: {
case ParamType::Output: {
if (!state.can_be_uninitialized) {
return false;
}
@@ -429,14 +429,14 @@ bool MFProcedure::validate_initialization() const
}
}
}
Set<const MFVariable *> variables_that_should_be_initialized_on_return;
Set<const Variable *> variables_that_should_be_initialized_on_return;
for (const MFParameter &param : params_) {
if (ELEM(param.type, MFParamType::Mutable, MFParamType::Output)) {
if (ELEM(param.type, ParamType::Mutable, ParamType::Output)) {
variables_that_should_be_initialized_on_return.add_new(param.variable);
}
}
for (const MFReturnInstruction *instruction : return_instructions_) {
for (const MFVariable *variable : variables_) {
for (const ReturnInstruction *instruction : return_instructions_) {
for (const Variable *variable : variables_) {
const InitState init_state = this->find_initialization_state_before_instruction(*instruction,
*variable);
if (variables_that_should_be_initialized_on_return.contains(variable)) {
@@ -454,8 +454,8 @@ bool MFProcedure::validate_initialization() const
return true;
}
MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction(
const MFInstruction &target_instruction, const MFVariable &target_variable) const
Procedure::InitState Procedure::find_initialization_state_before_instruction(
const Instruction &target_instruction, const Variable &target_variable) const
{
InitState state;
@@ -463,7 +463,7 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction
bool caller_initialized_variable = false;
for (const MFParameter &param : params_) {
if (param.variable == &target_variable) {
if (ELEM(param.type, MFParamType::Input, MFParamType::Mutable)) {
if (ELEM(param.type, ParamType::Input, ParamType::Mutable)) {
caller_initialized_variable = true;
break;
}
@@ -481,30 +481,30 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction
check_entry_instruction();
}
Set<const MFInstruction *> checked_instructions;
Stack<const MFInstruction *> instructions_to_check;
for (const MFInstructionCursor &cursor : target_instruction.prev_) {
Set<const Instruction *> checked_instructions;
Stack<const Instruction *> instructions_to_check;
for (const InstructionCursor &cursor : target_instruction.prev_) {
if (cursor.instruction() != nullptr) {
instructions_to_check.push(cursor.instruction());
}
}
while (!instructions_to_check.is_empty()) {
const MFInstruction &instruction = *instructions_to_check.pop();
const Instruction &instruction = *instructions_to_check.pop();
if (!checked_instructions.add(&instruction)) {
/* Skip if the instruction has been checked already. */
continue;
}
bool state_modified = false;
switch (instruction.type_) {
case MFInstructionType::Call: {
const MFCallInstruction &call_instruction = static_cast<const MFCallInstruction &>(
case InstructionType::Call: {
const CallInstruction &call_instruction = static_cast<const CallInstruction &>(
instruction);
const MultiFunction &fn = *call_instruction.fn_;
for (const int param_index : fn.param_indices()) {
if (call_instruction.params_[param_index] == &target_variable) {
const MFParamType param_type = fn.param_type(param_index);
if (param_type.interface_type() == MFParamType::Output) {
const ParamType param_type = fn.param_type(param_index);
if (param_type.interface_type() == ParamType::Output) {
state.can_be_initialized = true;
state_modified = true;
break;
@@ -513,18 +513,18 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction
}
break;
}
case MFInstructionType::Destruct: {
const MFDestructInstruction &destruct_instruction =
static_cast<const MFDestructInstruction &>(instruction);
case InstructionType::Destruct: {
const DestructInstruction &destruct_instruction = static_cast<const DestructInstruction &>(
instruction);
if (destruct_instruction.variable_ == &target_variable) {
state.can_be_uninitialized = true;
state_modified = true;
}
break;
}
case MFInstructionType::Branch:
case MFInstructionType::Dummy:
case MFInstructionType::Return: {
case InstructionType::Branch:
case InstructionType::Dummy:
case InstructionType::Return: {
/* These instruction types don't change the initialization state of variables. */
break;
}
@@ -534,7 +534,7 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction
if (&instruction == entry_) {
check_entry_instruction();
}
for (const MFInstructionCursor &cursor : instruction.prev_) {
for (const InstructionCursor &cursor : instruction.prev_) {
if (cursor.instruction() != nullptr) {
instructions_to_check.push(cursor.instruction());
}
@@ -545,15 +545,15 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction
return state;
}
class MFProcedureDotExport {
class ProcedureDotExport {
private:
const MFProcedure &procedure_;
const Procedure &procedure_;
dot::DirectedGraph digraph_;
Map<const MFInstruction *, dot::Node *> dot_nodes_by_begin_;
Map<const MFInstruction *, dot::Node *> dot_nodes_by_end_;
Map<const Instruction *, dot::Node *> dot_nodes_by_begin_;
Map<const Instruction *, dot::Node *> dot_nodes_by_end_;
public:
MFProcedureDotExport(const MFProcedure &procedure) : procedure_(procedure)
ProcedureDotExport(const Procedure &procedure) : procedure_(procedure)
{
}
@@ -566,7 +566,7 @@ class MFProcedureDotExport {
void create_nodes()
{
Vector<const MFInstruction *> all_instructions;
Vector<const Instruction *> all_instructions;
auto add_instructions = [&](auto instructions) {
all_instructions.extend(instructions.begin(), instructions.end());
};
@@ -576,38 +576,38 @@ class MFProcedureDotExport {
add_instructions(procedure_.dummy_instructions_);
add_instructions(procedure_.return_instructions_);
Set<const MFInstruction *> handled_instructions;
Set<const Instruction *> handled_instructions;
for (const MFInstruction *representative : all_instructions) {
for (const Instruction *representative : all_instructions) {
if (handled_instructions.contains(representative)) {
continue;
}
Vector<const MFInstruction *> block_instructions = this->get_instructions_in_block(
Vector<const Instruction *> block_instructions = this->get_instructions_in_block(
*representative);
std::stringstream ss;
ss << "<";
for (const MFInstruction *current : block_instructions) {
for (const Instruction *current : block_instructions) {
handled_instructions.add_new(current);
switch (current->type()) {
case MFInstructionType::Call: {
this->instruction_to_string(*static_cast<const MFCallInstruction *>(current), ss);
case InstructionType::Call: {
this->instruction_to_string(*static_cast<const CallInstruction *>(current), ss);
break;
}
case MFInstructionType::Destruct: {
this->instruction_to_string(*static_cast<const MFDestructInstruction *>(current), ss);
case InstructionType::Destruct: {
this->instruction_to_string(*static_cast<const DestructInstruction *>(current), ss);
break;
}
case MFInstructionType::Dummy: {
this->instruction_to_string(*static_cast<const MFDummyInstruction *>(current), ss);
case InstructionType::Dummy: {
this->instruction_to_string(*static_cast<const DummyInstruction *>(current), ss);
break;
}
case MFInstructionType::Return: {
this->instruction_to_string(*static_cast<const MFReturnInstruction *>(current), ss);
case InstructionType::Return: {
this->instruction_to_string(*static_cast<const ReturnInstruction *>(current), ss);
break;
}
case MFInstructionType::Branch: {
this->instruction_to_string(*static_cast<const MFBranchInstruction *>(current), ss);
case InstructionType::Branch: {
this->instruction_to_string(*static_cast<const BranchInstruction *>(current), ss);
break;
}
}
@@ -625,7 +625,7 @@ class MFProcedureDotExport {
void create_edges()
{
auto create_edge = [&](dot::Node &from_node,
const MFInstruction *to_instruction) -> dot::DirectedEdge & {
const Instruction *to_instruction) -> dot::DirectedEdge & {
if (to_instruction == nullptr) {
dot::Node &to_node = digraph_.new_node("missing");
to_node.set_shape(dot::Attr_shape::Diamond);
@@ -636,35 +636,35 @@ class MFProcedureDotExport {
};
for (auto item : dot_nodes_by_end_.items()) {
const MFInstruction &from_instruction = *item.key;
const Instruction &from_instruction = *item.key;
dot::Node &from_node = *item.value;
switch (from_instruction.type()) {
case MFInstructionType::Call: {
const MFInstruction *to_instruction =
static_cast<const MFCallInstruction &>(from_instruction).next();
case InstructionType::Call: {
const Instruction *to_instruction =
static_cast<const CallInstruction &>(from_instruction).next();
create_edge(from_node, to_instruction);
break;
}
case MFInstructionType::Destruct: {
const MFInstruction *to_instruction =
static_cast<const MFDestructInstruction &>(from_instruction).next();
case InstructionType::Destruct: {
const Instruction *to_instruction =
static_cast<const DestructInstruction &>(from_instruction).next();
create_edge(from_node, to_instruction);
break;
}
case MFInstructionType::Dummy: {
const MFInstruction *to_instruction =
static_cast<const MFDummyInstruction &>(from_instruction).next();
case InstructionType::Dummy: {
const Instruction *to_instruction =
static_cast<const DummyInstruction &>(from_instruction).next();
create_edge(from_node, to_instruction);
break;
}
case MFInstructionType::Return: {
case InstructionType::Return: {
break;
}
case MFInstructionType::Branch: {
const MFBranchInstruction &branch_instruction = static_cast<const MFBranchInstruction &>(
case InstructionType::Branch: {
const BranchInstruction &branch_instruction = static_cast<const BranchInstruction &>(
from_instruction);
const MFInstruction *to_true_instruction = branch_instruction.branch_true();
const MFInstruction *to_false_instruction = branch_instruction.branch_false();
const Instruction *to_true_instruction = branch_instruction.branch_true();
const Instruction *to_false_instruction = branch_instruction.branch_false();
create_edge(from_node, to_true_instruction).attributes.set("color", "#118811");
create_edge(from_node, to_false_instruction).attributes.set("color", "#881111");
break;
@@ -676,22 +676,22 @@ class MFProcedureDotExport {
create_edge(entry_node, procedure_.entry());
}
bool has_to_be_block_begin(const MFInstruction &instruction)
bool has_to_be_block_begin(const Instruction &instruction)
{
if (instruction.prev().size() != 1) {
return true;
}
if (ELEM(instruction.prev()[0].type(),
MFInstructionCursor::Type::Branch,
MFInstructionCursor::Type::Entry)) {
InstructionCursor::Type::Branch,
InstructionCursor::Type::Entry)) {
return true;
}
return false;
}
const MFInstruction &get_first_instruction_in_block(const MFInstruction &representative)
const Instruction &get_first_instruction_in_block(const Instruction &representative)
{
const MFInstruction *current = &representative;
const Instruction *current = &representative;
while (!this->has_to_be_block_begin(*current)) {
current = current->prev()[0].instruction();
if (current == &representative) {
@@ -702,25 +702,25 @@ class MFProcedureDotExport {
return *current;
}
const MFInstruction *get_next_instruction_in_block(const MFInstruction &instruction,
const MFInstruction &block_begin)
const Instruction *get_next_instruction_in_block(const Instruction &instruction,
const Instruction &block_begin)
{
const MFInstruction *next = nullptr;
const Instruction *next = nullptr;
switch (instruction.type()) {
case MFInstructionType::Call: {
next = static_cast<const MFCallInstruction &>(instruction).next();
case InstructionType::Call: {
next = static_cast<const CallInstruction &>(instruction).next();
break;
}
case MFInstructionType::Destruct: {
next = static_cast<const MFDestructInstruction &>(instruction).next();
case InstructionType::Destruct: {
next = static_cast<const DestructInstruction &>(instruction).next();
break;
}
case MFInstructionType::Dummy: {
next = static_cast<const MFDummyInstruction &>(instruction).next();
case InstructionType::Dummy: {
next = static_cast<const DummyInstruction &>(instruction).next();
break;
}
case MFInstructionType::Return:
case MFInstructionType::Branch: {
case InstructionType::Return:
case InstructionType::Branch: {
break;
}
}
@@ -736,18 +736,18 @@ class MFProcedureDotExport {
return next;
}
Vector<const MFInstruction *> get_instructions_in_block(const MFInstruction &representative)
Vector<const Instruction *> get_instructions_in_block(const Instruction &representative)
{
Vector<const MFInstruction *> instructions;
const MFInstruction &begin = this->get_first_instruction_in_block(representative);
for (const MFInstruction *current = &begin; current != nullptr;
Vector<const Instruction *> instructions;
const Instruction &begin = this->get_first_instruction_in_block(representative);
for (const Instruction *current = &begin; current != nullptr;
current = this->get_next_instruction_in_block(*current, begin)) {
instructions.append(current);
}
return instructions;
}
void variable_to_string(const MFVariable *variable, std::stringstream &ss)
void variable_to_string(const Variable *variable, std::stringstream &ss)
{
if (variable == nullptr) {
ss << "null";
@@ -765,24 +765,24 @@ class MFProcedureDotExport {
ss << name;
}
void instruction_to_string(const MFCallInstruction &instruction, std::stringstream &ss)
void instruction_to_string(const CallInstruction &instruction, std::stringstream &ss)
{
const MultiFunction &fn = instruction.fn();
this->instruction_name_format(fn.debug_name() + ": ", ss);
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
const MFVariable *variable = instruction.params()[param_index];
const ParamType param_type = fn.param_type(param_index);
const Variable *variable = instruction.params()[param_index];
ss << R"(<font color="grey30">)";
switch (param_type.interface_type()) {
case MFParamType::Input: {
case ParamType::Input: {
ss << "in";
break;
}
case MFParamType::Mutable: {
case ParamType::Mutable: {
ss << "mut";
break;
}
case MFParamType::Output: {
case ParamType::Output: {
ss << "out";
break;
}
@@ -795,24 +795,24 @@ class MFProcedureDotExport {
}
}
void instruction_to_string(const MFDestructInstruction &instruction, std::stringstream &ss)
void instruction_to_string(const DestructInstruction &instruction, std::stringstream &ss)
{
instruction_name_format("Destruct ", ss);
variable_to_string(instruction.variable(), ss);
}
void instruction_to_string(const MFDummyInstruction & /*instruction*/, std::stringstream &ss)
void instruction_to_string(const DummyInstruction & /*instruction*/, std::stringstream &ss)
{
instruction_name_format("Dummy ", ss);
}
void instruction_to_string(const MFReturnInstruction & /*instruction*/, std::stringstream &ss)
void instruction_to_string(const ReturnInstruction & /*instruction*/, std::stringstream &ss)
{
instruction_name_format("Return ", ss);
Vector<ConstMFParameter> outgoing_parameters;
for (const ConstMFParameter &param : procedure_.params()) {
if (ELEM(param.type, MFParamType::Mutable, MFParamType::Output)) {
if (ELEM(param.type, ParamType::Mutable, ParamType::Output)) {
outgoing_parameters.append(param);
}
}
@@ -825,7 +825,7 @@ class MFProcedureDotExport {
}
}
void instruction_to_string(const MFBranchInstruction &instruction, std::stringstream &ss)
void instruction_to_string(const BranchInstruction &instruction, std::stringstream &ss)
{
instruction_name_format("Branch ", ss);
variable_to_string(instruction.condition(), ss);
@@ -837,7 +837,7 @@ class MFProcedureDotExport {
ss << "Entry: ";
Vector<ConstMFParameter> incoming_parameters;
for (const ConstMFParameter &param : procedure_.params()) {
if (ELEM(param.type, MFParamType::Input, MFParamType::Mutable)) {
if (ELEM(param.type, ParamType::Input, ParamType::Mutable)) {
incoming_parameters.append(param);
}
}
@@ -855,10 +855,10 @@ class MFProcedureDotExport {
}
};
std::string MFProcedure::to_dot() const
std::string Procedure::to_dot() const
{
MFProcedureDotExport dot_export{*this};
ProcedureDotExport dot_export{*this};
return dot_export.generate();
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -2,64 +2,64 @@
#include "FN_multi_function_procedure_builder.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
void MFProcedureBuilder::add_destruct(MFVariable &variable)
void ProcedureBuilder::add_destruct(Variable &variable)
{
MFDestructInstruction &instruction = procedure_->new_destruct_instruction();
DestructInstruction &instruction = procedure_->new_destruct_instruction();
instruction.set_variable(&variable);
this->link_to_cursors(&instruction);
cursors_ = {MFInstructionCursor{instruction}};
cursors_ = {InstructionCursor{instruction}};
}
void MFProcedureBuilder::add_destruct(Span<MFVariable *> variables)
void ProcedureBuilder::add_destruct(Span<Variable *> variables)
{
for (MFVariable *variable : variables) {
for (Variable *variable : variables) {
this->add_destruct(*variable);
}
}
MFReturnInstruction &MFProcedureBuilder::add_return()
ReturnInstruction &ProcedureBuilder::add_return()
{
MFReturnInstruction &instruction = procedure_->new_return_instruction();
ReturnInstruction &instruction = procedure_->new_return_instruction();
this->link_to_cursors(&instruction);
cursors_ = {};
return instruction;
}
MFCallInstruction &MFProcedureBuilder::add_call_with_no_variables(const MultiFunction &fn)
CallInstruction &ProcedureBuilder::add_call_with_no_variables(const MultiFunction &fn)
{
MFCallInstruction &instruction = procedure_->new_call_instruction(fn);
CallInstruction &instruction = procedure_->new_call_instruction(fn);
this->link_to_cursors(&instruction);
cursors_ = {MFInstructionCursor{instruction}};
cursors_ = {InstructionCursor{instruction}};
return instruction;
}
MFCallInstruction &MFProcedureBuilder::add_call_with_all_variables(
const MultiFunction &fn, Span<MFVariable *> param_variables)
CallInstruction &ProcedureBuilder::add_call_with_all_variables(const MultiFunction &fn,
Span<Variable *> param_variables)
{
MFCallInstruction &instruction = this->add_call_with_no_variables(fn);
CallInstruction &instruction = this->add_call_with_no_variables(fn);
instruction.set_params(param_variables);
return instruction;
}
Vector<MFVariable *> MFProcedureBuilder::add_call(const MultiFunction &fn,
Span<MFVariable *> input_and_mutable_variables)
Vector<Variable *> ProcedureBuilder::add_call(const MultiFunction &fn,
Span<Variable *> input_and_mutable_variables)
{
Vector<MFVariable *> output_variables;
MFCallInstruction &instruction = this->add_call_with_no_variables(fn);
Vector<Variable *> output_variables;
CallInstruction &instruction = this->add_call_with_no_variables(fn);
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
const ParamType param_type = fn.param_type(param_index);
switch (param_type.interface_type()) {
case MFParamType::Input:
case MFParamType::Mutable: {
MFVariable *variable = input_and_mutable_variables.first();
case ParamType::Input:
case ParamType::Mutable: {
Variable *variable = input_and_mutable_variables.first();
instruction.set_param_variable(param_index, variable);
input_and_mutable_variables = input_and_mutable_variables.drop_front(1);
break;
}
case MFParamType::Output: {
MFVariable &variable = procedure_->new_variable(param_type.data_type(),
case ParamType::Output: {
Variable &variable = procedure_->new_variable(param_type.data_type(),
fn.param_name(param_index));
instruction.set_param_variable(param_index, &variable);
output_variables.append(&variable);
@@ -72,26 +72,26 @@ Vector<MFVariable *> MFProcedureBuilder::add_call(const MultiFunction &fn,
return output_variables;
}
MFProcedureBuilder::Branch MFProcedureBuilder::add_branch(MFVariable &condition)
ProcedureBuilder::Branch ProcedureBuilder::add_branch(Variable &condition)
{
MFBranchInstruction &instruction = procedure_->new_branch_instruction();
BranchInstruction &instruction = procedure_->new_branch_instruction();
instruction.set_condition(&condition);
this->link_to_cursors(&instruction);
/* Clear cursors because this builder ends here. */
cursors_.clear();
Branch branch{*procedure_, *procedure_};
branch.branch_true.set_cursor(MFInstructionCursor{instruction, true});
branch.branch_false.set_cursor(MFInstructionCursor{instruction, false});
branch.branch_true.set_cursor(InstructionCursor{instruction, true});
branch.branch_false.set_cursor(InstructionCursor{instruction, false});
return branch;
}
MFProcedureBuilder::Loop MFProcedureBuilder::add_loop()
ProcedureBuilder::Loop ProcedureBuilder::add_loop()
{
MFDummyInstruction &loop_begin = procedure_->new_dummy_instruction();
MFDummyInstruction &loop_end = procedure_->new_dummy_instruction();
DummyInstruction &loop_begin = procedure_->new_dummy_instruction();
DummyInstruction &loop_end = procedure_->new_dummy_instruction();
this->link_to_cursors(&loop_begin);
cursors_ = {MFInstructionCursor{loop_begin}};
cursors_ = {InstructionCursor{loop_begin}};
Loop loop;
loop.begin = &loop_begin;
@@ -100,18 +100,18 @@ MFProcedureBuilder::Loop MFProcedureBuilder::add_loop()
return loop;
}
void MFProcedureBuilder::add_loop_continue(Loop &loop)
void ProcedureBuilder::add_loop_continue(Loop &loop)
{
this->link_to_cursors(loop.begin);
/* Clear cursors because this builder ends here. */
cursors_.clear();
}
void MFProcedureBuilder::add_loop_break(Loop &loop)
void ProcedureBuilder::add_loop_break(Loop &loop)
{
this->link_to_cursors(loop.end);
/* Clear cursors because this builder ends here. */
cursors_.clear();
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -4,14 +4,14 @@
#include "BLI_stack.hh"
namespace blender::fn {
namespace blender::fn::multi_function {
MFProcedureExecutor::MFProcedureExecutor(const MFProcedure &procedure) : procedure_(procedure)
ProcedureExecutor::ProcedureExecutor(const Procedure &procedure) : procedure_(procedure)
{
MFSignatureBuilder builder("Procedure Executor", signature_);
SignatureBuilder builder("Procedure Executor", signature_);
for (const ConstMFParameter &param : procedure.params()) {
builder.add("Parameter", MFParamType(param.type, param.variable->data_type()));
builder.add("Parameter", ParamType(param.type, param.variable->data_type()));
}
this->set_signature(&signature_);
@@ -236,7 +236,7 @@ class ValueAllocator : NonCopyable, NonMovable {
return this->obtain<VariableValue_OneVector>(*vector_array);
}
void release_value(VariableValue *value, const MFDataType &data_type)
void release_value(VariableValue *value, const DataType &data_type)
{
switch (value->type) {
case ValueType::GVArray: {
@@ -317,7 +317,7 @@ class VariableState : NonCopyable, NonMovable {
/* This a non-owning pointer to either span buffer or #GVectorArray or null. */
void *caller_provided_storage_ = nullptr;
void destruct_value(ValueAllocator &value_allocator, const MFDataType &data_type)
void destruct_value(ValueAllocator &value_allocator, const DataType &data_type)
{
value_allocator.release_value(value_, data_type);
value_ = nullptr;
@@ -359,7 +359,7 @@ class VariableState : NonCopyable, NonMovable {
return tot_initialized_ == 0;
}
void add_as_input(MFParamsBuilder &params, IndexMask mask, const MFDataType &data_type) const
void add_as_input(ParamsBuilder &params, IndexMask mask, const DataType &data_type) const
{
/* Sanity check to make sure that enough values are initialized. */
BLI_assert(mask.size() <= tot_initialized_);
@@ -399,7 +399,7 @@ class VariableState : NonCopyable, NonMovable {
}
void ensure_is_mutable(IndexMask full_mask,
const MFDataType &data_type,
const DataType &data_type,
ValueAllocator &value_allocator)
{
if (value_ != nullptr && ELEM(value_->type, ValueType::Span, ValueType::GVectorArray)) {
@@ -409,7 +409,7 @@ class VariableState : NonCopyable, NonMovable {
const int array_size = full_mask.min_array_size();
switch (data_type.category()) {
case MFDataType::Single: {
case DataType::Single: {
const CPPType &type = data_type.single_type();
VariableValue_Span *new_value = nullptr;
if (caller_provided_storage_ == nullptr) {
@@ -440,7 +440,7 @@ class VariableState : NonCopyable, NonMovable {
value_ = new_value;
break;
}
case MFDataType::Vector: {
case DataType::Vector: {
const CPPType &type = data_type.vector_base_type();
VariableValue_GVectorArray *new_value = nullptr;
if (caller_provided_storage_ == nullptr) {
@@ -471,10 +471,10 @@ class VariableState : NonCopyable, NonMovable {
}
}
void add_as_mutable(MFParamsBuilder &params,
void add_as_mutable(ParamsBuilder &params,
IndexMask mask,
IndexMask full_mask,
const MFDataType &data_type,
const DataType &data_type,
ValueAllocator &value_allocator)
{
/* Sanity check to make sure that enough values are initialized. */
@@ -504,10 +504,10 @@ class VariableState : NonCopyable, NonMovable {
}
}
void add_as_output(MFParamsBuilder &params,
void add_as_output(ParamsBuilder &params,
IndexMask mask,
IndexMask full_mask,
const MFDataType &data_type,
const DataType &data_type,
ValueAllocator &value_allocator)
{
/* Sanity check to make sure that enough values are not initialized. */
@@ -538,7 +538,7 @@ class VariableState : NonCopyable, NonMovable {
tot_initialized_ += mask.size();
}
void add_as_input__one(MFParamsBuilder &params, const MFDataType &data_type) const
void add_as_input__one(ParamsBuilder &params, const DataType &data_type) const
{
BLI_assert(this->is_one());
BLI_assert(value_ != nullptr);
@@ -571,7 +571,7 @@ class VariableState : NonCopyable, NonMovable {
}
}
void ensure_is_mutable__one(const MFDataType &data_type, ValueAllocator &value_allocator)
void ensure_is_mutable__one(const DataType &data_type, ValueAllocator &value_allocator)
{
BLI_assert(this->is_one());
if (value_ != nullptr && ELEM(value_->type, ValueType::OneSingle, ValueType::OneVector)) {
@@ -579,7 +579,7 @@ class VariableState : NonCopyable, NonMovable {
}
switch (data_type.category()) {
case MFDataType::Single: {
case DataType::Single: {
const CPPType &type = data_type.single_type();
VariableValue_OneSingle *new_value = value_allocator.obtain_OneSingle(type);
if (value_ != nullptr) {
@@ -600,7 +600,7 @@ class VariableState : NonCopyable, NonMovable {
value_ = new_value;
break;
}
case MFDataType::Vector: {
case DataType::Vector: {
const CPPType &type = data_type.vector_base_type();
VariableValue_OneVector *new_value = value_allocator.obtain_OneVector(type);
if (value_ != nullptr) {
@@ -624,8 +624,8 @@ class VariableState : NonCopyable, NonMovable {
}
}
void add_as_mutable__one(MFParamsBuilder &params,
const MFDataType &data_type,
void add_as_mutable__one(ParamsBuilder &params,
const DataType &data_type,
ValueAllocator &value_allocator)
{
BLI_assert(this->is_one());
@@ -653,9 +653,9 @@ class VariableState : NonCopyable, NonMovable {
}
}
void add_as_output__one(MFParamsBuilder &params,
void add_as_output__one(ParamsBuilder &params,
IndexMask mask,
const MFDataType &data_type,
const DataType &data_type,
ValueAllocator &value_allocator)
{
BLI_assert(this->is_one());
@@ -697,7 +697,7 @@ class VariableState : NonCopyable, NonMovable {
*/
bool destruct(IndexMask mask,
IndexMask full_mask,
const MFDataType &data_type,
const DataType &data_type,
ValueAllocator &value_allocator)
{
BLI_assert(value_ != nullptr);
@@ -822,14 +822,14 @@ class VariableState : NonCopyable, NonMovable {
class VariableStates {
private:
ValueAllocator value_allocator_;
const MFProcedure &procedure_;
/** The state of every variable, indexed by #MFVariable::index_in_procedure(). */
const Procedure &procedure_;
/** The state of every variable, indexed by #Variable::index_in_procedure(). */
Array<VariableState> variable_states_;
IndexMask full_mask_;
public:
VariableStates(LinearAllocator<> &linear_allocator,
const MFProcedure &procedure,
const Procedure &procedure,
IndexMask full_mask)
: value_allocator_(linear_allocator),
procedure_(procedure),
@@ -843,7 +843,7 @@ class VariableStates {
for (const int variable_i : procedure_.variables().index_range()) {
VariableState &state = variable_states_[variable_i];
if (state.value_ != nullptr) {
const MFVariable *variable = procedure_.variables()[variable_i];
const Variable *variable = procedure_.variables()[variable_i];
state.destruct_value(value_allocator_, variable->data_type());
}
}
@@ -859,13 +859,13 @@ class VariableStates {
return full_mask_;
}
void add_initial_variable_states(const MFProcedureExecutor &fn,
const MFProcedure &procedure,
void add_initial_variable_states(const ProcedureExecutor &fn,
const Procedure &procedure,
MFParams &params)
{
for (const int param_index : fn.param_indices()) {
MFParamType param_type = fn.param_type(param_index);
const MFVariable *variable = procedure.params()[param_index].variable;
ParamType param_type = fn.param_type(param_index);
const Variable *variable = procedure.params()[param_index].variable;
auto add_state = [&](VariableValue *value,
bool input_is_initialized,
@@ -880,32 +880,32 @@ class VariableStates {
};
switch (param_type.category()) {
case MFParamCategory::SingleInput: {
case ParamCategory::SingleInput: {
const GVArray &data = params.readonly_single_input(param_index);
add_state(value_allocator_.obtain_GVArray(data), true);
break;
}
case MFParamCategory::VectorInput: {
case ParamCategory::VectorInput: {
const GVVectorArray &data = params.readonly_vector_input(param_index);
add_state(value_allocator_.obtain_GVVectorArray(data), true);
break;
}
case MFParamCategory::SingleOutput: {
case ParamCategory::SingleOutput: {
GMutableSpan data = params.uninitialized_single_output(param_index);
add_state(value_allocator_.obtain_Span_not_owned(data.data()), false, data.data());
break;
}
case MFParamCategory::VectorOutput: {
case ParamCategory::VectorOutput: {
GVectorArray &data = params.vector_output(param_index);
add_state(value_allocator_.obtain_GVectorArray_not_owned(data), false, &data);
break;
}
case MFParamCategory::SingleMutable: {
case ParamCategory::SingleMutable: {
GMutableSpan data = params.single_mutable(param_index);
add_state(value_allocator_.obtain_Span_not_owned(data.data()), true, data.data());
break;
}
case MFParamCategory::VectorMutable: {
case ParamCategory::VectorMutable: {
GVectorArray &data = params.vector_mutable(param_index);
add_state(value_allocator_.obtain_GVectorArray_not_owned(data), true, &data);
break;
@@ -915,21 +915,21 @@ class VariableStates {
}
void add_as_param(VariableState &variable_state,
MFParamsBuilder &params,
const MFParamType &param_type,
ParamsBuilder &params,
const ParamType &param_type,
const IndexMask &mask)
{
const MFDataType data_type = param_type.data_type();
const DataType data_type = param_type.data_type();
switch (param_type.interface_type()) {
case MFParamType::Input: {
case ParamType::Input: {
variable_state.add_as_input(params, mask, data_type);
break;
}
case MFParamType::Mutable: {
case ParamType::Mutable: {
variable_state.add_as_mutable(params, mask, full_mask_, data_type, value_allocator_);
break;
}
case MFParamType::Output: {
case ParamType::Output: {
variable_state.add_as_output(params, mask, full_mask_, data_type, value_allocator_);
break;
}
@@ -937,28 +937,28 @@ class VariableStates {
}
void add_as_param__one(VariableState &variable_state,
MFParamsBuilder &params,
const MFParamType &param_type,
ParamsBuilder &params,
const ParamType &param_type,
const IndexMask &mask)
{
const MFDataType data_type = param_type.data_type();
const DataType data_type = param_type.data_type();
switch (param_type.interface_type()) {
case MFParamType::Input: {
case ParamType::Input: {
variable_state.add_as_input__one(params, data_type);
break;
}
case MFParamType::Mutable: {
case ParamType::Mutable: {
variable_state.add_as_mutable__one(params, data_type, value_allocator_);
break;
}
case MFParamType::Output: {
case ParamType::Output: {
variable_state.add_as_output__one(params, mask, data_type, value_allocator_);
break;
}
}
}
void destruct(const MFVariable &variable, const IndexMask &mask)
void destruct(const Variable &variable, const IndexMask &mask)
{
VariableState &variable_state = this->get_variable_state(variable);
if (variable_state.destruct(mask, full_mask_, variable.data_type(), value_allocator_)) {
@@ -966,7 +966,7 @@ class VariableStates {
}
}
VariableState &get_variable_state(const MFVariable &variable)
VariableState &get_variable_state(const Variable &variable)
{
const int variable_i = variable.index_in_procedure();
VariableState &variable_state = variable_states_[variable_i];
@@ -990,12 +990,12 @@ static bool evaluate_as_one(Span<VariableState *> param_variable_states,
}
static void gather_parameter_variable_states(const MultiFunction &fn,
const MFCallInstruction &instruction,
const CallInstruction &instruction,
VariableStates &variable_states,
MutableSpan<VariableState *> r_param_variable_states)
{
for (const int param_index : fn.param_indices()) {
const MFVariable *variable = instruction.params()[param_index];
const Variable *variable = instruction.params()[param_index];
if (variable == nullptr) {
r_param_variable_states[param_index] = nullptr;
}
@@ -1008,12 +1008,12 @@ static void gather_parameter_variable_states(const MultiFunction &fn,
static void fill_params__one(const MultiFunction &fn,
const IndexMask mask,
MFParamsBuilder &params,
ParamsBuilder &params,
VariableStates &variable_states,
const Span<VariableState *> param_variable_states)
{
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
const ParamType param_type = fn.param_type(param_index);
VariableState *variable_state = param_variable_states[param_index];
if (variable_state == nullptr) {
params.add_ignored_single_output();
@@ -1026,12 +1026,12 @@ static void fill_params__one(const MultiFunction &fn,
static void fill_params(const MultiFunction &fn,
const IndexMask mask,
MFParamsBuilder &params,
ParamsBuilder &params,
VariableStates &variable_states,
const Span<VariableState *> param_variable_states)
{
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
const ParamType param_type = fn.param_type(param_index);
VariableState *variable_state = param_variable_states[param_index];
if (variable_state == nullptr) {
params.add_ignored_single_output();
@@ -1042,10 +1042,10 @@ static void fill_params(const MultiFunction &fn,
}
}
static void execute_call_instruction(const MFCallInstruction &instruction,
static void execute_call_instruction(const CallInstruction &instruction,
const IndexMask mask,
VariableStates &variable_states,
const MFContext &context)
const Context &context)
{
const MultiFunction &fn = instruction.fn();
@@ -1056,7 +1056,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction,
/* If all inputs to the function are constant, it's enough to call the function only once instead
* of for every index. */
if (evaluate_as_one(param_variable_states, mask, variable_states.full_mask())) {
MFParamsBuilder params(fn, 1);
ParamsBuilder params(fn, 1);
fill_params__one(fn, mask, params, variable_states, param_variable_states);
try {
@@ -1068,7 +1068,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction,
}
}
else {
MFParamsBuilder params(fn, &mask);
ParamsBuilder params(fn, &mask);
fill_params(fn, mask, params, variable_states, param_variable_states);
try {
@@ -1098,7 +1098,7 @@ struct InstructionIndices {
/** Contains information about the next instruction that should be executed. */
struct NextInstructionInfo {
const MFInstruction *instruction = nullptr;
const Instruction *instruction = nullptr;
InstructionIndices indices;
IndexMask mask() const
@@ -1123,7 +1123,7 @@ class InstructionScheduler {
public:
InstructionScheduler() = default;
void add_referenced_indices(const MFInstruction &instruction, IndexMask mask)
void add_referenced_indices(const Instruction &instruction, IndexMask mask)
{
if (mask.is_empty()) {
return;
@@ -1134,7 +1134,7 @@ class InstructionScheduler {
next_instructions_.push({&instruction, std::move(new_indices)});
}
void add_owned_indices(const MFInstruction &instruction, Vector<int64_t> indices)
void add_owned_indices(const Instruction &instruction, Vector<int64_t> indices)
{
if (indices.is_empty()) {
return;
@@ -1158,7 +1158,7 @@ class InstructionScheduler {
return next_instructions_.peek();
}
void update_instruction_pointer(const MFInstruction &instruction)
void update_instruction_pointer(const Instruction &instruction)
{
next_instructions_.peek().instruction = &instruction;
}
@@ -1169,7 +1169,7 @@ class InstructionScheduler {
}
};
void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext context) const
void ProcedureExecutor::call(IndexMask full_mask, MFParams params, Context context) const
{
BLI_assert(procedure_.validate());
@@ -1186,19 +1186,19 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
/* Loop until all indices got to a return instruction. */
while (!scheduler.is_done()) {
const NextInstructionInfo &instr_info = scheduler.peek();
const MFInstruction &instruction = *instr_info.instruction;
const Instruction &instruction = *instr_info.instruction;
switch (instruction.type()) {
case MFInstructionType::Call: {
const MFCallInstruction &call_instruction = static_cast<const MFCallInstruction &>(
case InstructionType::Call: {
const CallInstruction &call_instruction = static_cast<const CallInstruction &>(
instruction);
execute_call_instruction(call_instruction, instr_info.mask(), variable_states, context);
scheduler.update_instruction_pointer(*call_instruction.next());
break;
}
case MFInstructionType::Branch: {
const MFBranchInstruction &branch_instruction = static_cast<const MFBranchInstruction &>(
case InstructionType::Branch: {
const BranchInstruction &branch_instruction = static_cast<const BranchInstruction &>(
instruction);
const MFVariable *condition_var = branch_instruction.condition();
const Variable *condition_var = branch_instruction.condition();
VariableState &variable_state = variable_states.get_variable_state(*condition_var);
IndicesSplitVectors new_indices;
@@ -1208,21 +1208,21 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
scheduler.add_owned_indices(*branch_instruction.branch_true(), new_indices[true]);
break;
}
case MFInstructionType::Destruct: {
const MFDestructInstruction &destruct_instruction =
static_cast<const MFDestructInstruction &>(instruction);
const MFVariable *variable = destruct_instruction.variable();
case InstructionType::Destruct: {
const DestructInstruction &destruct_instruction = static_cast<const DestructInstruction &>(
instruction);
const Variable *variable = destruct_instruction.variable();
variable_states.destruct(*variable, instr_info.mask());
scheduler.update_instruction_pointer(*destruct_instruction.next());
break;
}
case MFInstructionType::Dummy: {
const MFDummyInstruction &dummy_instruction = static_cast<const MFDummyInstruction &>(
case InstructionType::Dummy: {
const DummyInstruction &dummy_instruction = static_cast<const DummyInstruction &>(
instruction);
scheduler.update_instruction_pointer(*dummy_instruction.next());
break;
}
case MFInstructionType::Return: {
case InstructionType::Return: {
/* Don't insert the indices back into the scheduler. */
scheduler.pop();
break;
@@ -1231,17 +1231,17 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
}
for (const int param_index : this->param_indices()) {
const MFParamType param_type = this->param_type(param_index);
const MFVariable *variable = procedure_.params()[param_index].variable;
const ParamType param_type = this->param_type(param_index);
const Variable *variable = procedure_.params()[param_index].variable;
VariableState &variable_state = variable_states.get_variable_state(*variable);
switch (param_type.interface_type()) {
case MFParamType::Input: {
case ParamType::Input: {
/* Input variables must be destructed in the end. */
BLI_assert(variable_state.is_fully_uninitialized(full_mask));
break;
}
case MFParamType::Mutable:
case MFParamType::Output: {
case ParamType::Mutable:
case ParamType::Output: {
/* Mutable and output variables must be initialized in the end. */
BLI_assert(variable_state.is_fully_initialized(full_mask));
/* Make sure that the data is in the memory provided by the caller. */
@@ -1253,7 +1253,7 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
}
}
MultiFunction::ExecutionHints MFProcedureExecutor::get_execution_hints() const
MultiFunction::ExecutionHints ProcedureExecutor::get_execution_hints() const
{
ExecutionHints hints;
hints.allocates_array = true;
@@ -1261,4 +1261,4 @@ MultiFunction::ExecutionHints MFProcedureExecutor::get_execution_hints() const
return hints;
}
} // namespace blender::fn
} // namespace blender::fn::multi_function

View File

@@ -2,20 +2,19 @@
#include "FN_multi_function_procedure_optimization.hh"
namespace blender::fn::procedure_optimization {
namespace blender::fn::multi_function::procedure_optimization {
void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr)
void move_destructs_up(Procedure &procedure, Instruction &block_end_instr)
{
/* A mapping from a variable to its destruct instruction. */
Map<MFVariable *, MFDestructInstruction *> destruct_instructions;
MFInstruction *current_instr = &block_end_instr;
Map<Variable *, DestructInstruction *> destruct_instructions;
Instruction *current_instr = &block_end_instr;
while (true) {
MFInstructionType instr_type = current_instr->type();
InstructionType instr_type = current_instr->type();
switch (instr_type) {
case MFInstructionType::Destruct: {
MFDestructInstruction &destruct_instr = static_cast<MFDestructInstruction &>(
*current_instr);
MFVariable *variable = destruct_instr.variable();
case InstructionType::Destruct: {
DestructInstruction &destruct_instr = static_cast<DestructInstruction &>(*current_instr);
Variable *variable = destruct_instr.variable();
if (variable == nullptr) {
continue;
}
@@ -24,31 +23,31 @@ void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr)
destruct_instructions.add(variable, &destruct_instr);
break;
}
case MFInstructionType::Call: {
MFCallInstruction &call_instr = static_cast<MFCallInstruction &>(*current_instr);
case InstructionType::Call: {
CallInstruction &call_instr = static_cast<CallInstruction &>(*current_instr);
/* For each variable, place the corresponding remembered destruct instruction right after
* this call instruction. */
for (MFVariable *variable : call_instr.params()) {
for (Variable *variable : call_instr.params()) {
if (variable == nullptr) {
continue;
}
MFDestructInstruction *destruct_instr = destruct_instructions.pop_default(variable,
DestructInstruction *destruct_instr = destruct_instructions.pop_default(variable,
nullptr);
if (destruct_instr == nullptr) {
continue;
}
/* Unlink destruct instruction from previous position. */
MFInstruction *after_destruct_instr = destruct_instr->next();
Instruction *after_destruct_instr = destruct_instr->next();
while (!destruct_instr->prev().is_empty()) {
/* Do a copy of the cursor here, because `destruct_instr->prev()` changes when
* #set_next is called below. */
const MFInstructionCursor cursor = destruct_instr->prev()[0];
const InstructionCursor cursor = destruct_instr->prev()[0];
cursor.set_next(procedure, after_destruct_instr);
}
/* Insert destruct instruction in new position. */
MFInstruction *next_instr = call_instr.next();
Instruction *next_instr = call_instr.next();
call_instr.set_next(destruct_instr);
destruct_instr->set_next(next_instr);
}
@@ -59,12 +58,12 @@ void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr)
}
}
const Span<MFInstructionCursor> prev_cursors = current_instr->prev();
const Span<InstructionCursor> prev_cursors = current_instr->prev();
if (prev_cursors.size() != 1) {
/* Stop when there is some branching before this instruction. */
break;
}
const MFInstructionCursor &prev_cursor = prev_cursors[0];
const InstructionCursor &prev_cursor = prev_cursors[0];
current_instr = prev_cursor.instruction();
if (current_instr == nullptr) {
/* Stop when there is no previous instruction. E.g. when this is the first instruction. */
@@ -73,4 +72,4 @@ void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr)
}
}
} // namespace blender::fn::procedure_optimization
} // namespace blender::fn::multi_function::procedure_optimization

View File

@@ -13,7 +13,7 @@ TEST(field, ConstantFunction)
{
/* TODO: Figure out how to not use another "FieldOperation(" inside of std::make_shared. */
GField constant_field{std::make_shared<FieldOperation>(
FieldOperation(std::make_unique<CustomMF_Constant<int>>(10), {})),
FieldOperation(std::make_unique<mf::CustomMF_Constant<int>>(10), {})),
0};
Array<int> result(4);
@@ -104,7 +104,7 @@ TEST(field, InputAndFunction)
{
GField index_field{std::make_shared<IndexFieldInput>()};
auto add_fn = build_mf::SI2_SO<int, int, int>("add", [](int a, int b) { return a + b; });
auto add_fn = mf::build::SI2_SO<int, int, int>("add", [](int a, int b) { return a + b; });
GField output_field{
std::make_shared<FieldOperation>(FieldOperation(add_fn, {index_field, index_field})), 0};
@@ -127,11 +127,11 @@ TEST(field, TwoFunctions)
{
GField index_field{std::make_shared<IndexFieldInput>()};
auto add_fn = build_mf::SI2_SO<int, int, int>("add", [](int a, int b) { return a + b; });
auto add_fn = mf::build::SI2_SO<int, int, int>("add", [](int a, int b) { return a + b; });
GField add_field{
std::make_shared<FieldOperation>(FieldOperation(add_fn, {index_field, index_field})), 0};
auto add_10_fn = build_mf::SI1_SO<int, int>("add_10", [](int a) { return a + 10; });
auto add_10_fn = mf::build::SI1_SO<int, int>("add_10", [](int a) { return a + 10; });
GField result_field{std::make_shared<FieldOperation>(FieldOperation(add_10_fn, {add_field})), 0};
Array<int> result(10);
@@ -149,14 +149,14 @@ TEST(field, TwoFunctions)
EXPECT_EQ(result[8], 26);
}
class TwoOutputFunction : public MultiFunction {
class TwoOutputFunction : public mf::MultiFunction {
private:
MFSignature signature_;
mf::Signature signature_;
public:
TwoOutputFunction()
{
MFSignatureBuilder builder{"Two Outputs", signature_};
mf::SignatureBuilder builder{"Two Outputs", signature_};
builder.single_input<int>("In1");
builder.single_input<int>("In2");
builder.single_output<int>("Add");
@@ -164,7 +164,7 @@ class TwoOutputFunction : public MultiFunction {
this->set_signature(&signature_);
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<int> &in1 = params.readonly_single_input<int>(0, "In1");
const VArray<int> &in2 = params.readonly_single_input<int>(1, "In2");
@@ -223,7 +223,7 @@ TEST(field, TwoFunctionsTwoOutputs)
Field<int> result_field_1{fn, 0};
Field<int> intermediate_field{fn, 1};
auto add_10_fn = build_mf::SI1_SO<int, int>("add_10", [](int a) { return a + 10; });
auto add_10_fn = mf::build::SI1_SO<int, int>("add_10", [](int a) { return a + 10; });
Field<int> result_field_2{
std::make_shared<FieldOperation>(FieldOperation(add_10_fn, {intermediate_field})), 0};
@@ -248,7 +248,7 @@ TEST(field, TwoFunctionsTwoOutputs)
TEST(field, SameFieldTwice)
{
GField constant_field{
std::make_shared<FieldOperation>(std::make_unique<CustomMF_Constant<int>>(10)), 0};
std::make_shared<FieldOperation>(std::make_unique<mf::CustomMF_Constant<int>>(10)), 0};
FieldContext field_context;
IndexMask mask{IndexRange(2)};
@@ -267,7 +267,7 @@ TEST(field, SameFieldTwice)
TEST(field, IgnoredOutput)
{
static OptionalOutputsFunction fn;
static mf::tests::OptionalOutputsFunction fn;
Field<int> field{std::make_shared<FieldOperation>(fn), 0};
FieldContext field_context;

View File

@@ -7,7 +7,7 @@
#include "FN_multi_function_procedure_executor.hh"
#include "FN_multi_function_test_common.hh"
namespace blender::fn::tests {
namespace blender::fn::multi_function::tests {
TEST(multi_function_procedure, ConstantOutput)
{
@@ -19,10 +19,10 @@ TEST(multi_function_procedure, ConstantOutput)
*/
CustomMF_Constant<int> constant_fn{5};
auto add_fn = build_mf::SI2_SO<int, int, int>("Add", [](int a, int b) { return a + b; });
auto add_fn = build::SI2_SO<int, int, int>("Add", [](int a, int b) { return a + b; });
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
auto [var1] = builder.add_call<1>(constant_fn);
auto [var2] = builder.add_call<1>(add_fn, {var1, var1});
@@ -32,10 +32,10 @@ TEST(multi_function_procedure, ConstantOutput)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor executor{procedure};
ProcedureExecutor executor{procedure};
MFParamsBuilder params{executor, 2};
MFContextBuilder context;
ParamsBuilder params{executor, 2};
ContextBuilder context;
Array<int> output_array(2);
params.add_uninitialized_single_output(output_array.as_mutable_span());
@@ -56,14 +56,14 @@ TEST(multi_function_procedure, SimpleTest)
* }
*/
auto add_fn = fn::build_mf::SI2_SO<int, int, int>("add", [](int a, int b) { return a + b; });
auto add_10_fn = fn::build_mf::SM<int>("add_10", [](int &a) { a += 10; });
auto add_fn = mf::build::SI2_SO<int, int, int>("add", [](int a, int b) { return a + b; });
auto add_10_fn = mf::build::SM<int>("add_10", [](int &a) { a += 10; });
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
MFVariable *var1 = &builder.add_single_input_parameter<int>();
MFVariable *var2 = &builder.add_single_input_parameter<int>();
Variable *var1 = &builder.add_single_input_parameter<int>();
Variable *var2 = &builder.add_single_input_parameter<int>();
auto [var3] = builder.add_call<1>(add_fn, {var1, var2});
auto [var4] = builder.add_call<1>(add_fn, {var2, var3});
builder.add_call(add_10_fn, {var4});
@@ -73,10 +73,10 @@ TEST(multi_function_procedure, SimpleTest)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor executor{procedure};
ProcedureExecutor executor{procedure};
MFParamsBuilder params{executor, 3};
MFContextBuilder context;
ParamsBuilder params{executor, 3};
ContextBuilder context;
Array<int> input_array = {1, 2, 3};
params.add_readonly_single_input(input_array.as_span());
@@ -106,16 +106,16 @@ TEST(multi_function_procedure, BranchTest)
* }
*/
auto add_10_fn = build_mf::SM<int>("add_10", [](int &a) { a += 10; });
auto add_100_fn = build_mf::SM<int>("add_100", [](int &a) { a += 100; });
auto add_10_fn = build::SM<int>("add_10", [](int &a) { a += 10; });
auto add_100_fn = build::SM<int>("add_100", [](int &a) { a += 100; });
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
MFVariable *var1 = &builder.add_single_mutable_parameter<int>();
MFVariable *var2 = &builder.add_single_input_parameter<bool>();
Variable *var1 = &builder.add_single_mutable_parameter<int>();
Variable *var2 = &builder.add_single_input_parameter<bool>();
MFProcedureBuilder::Branch branch = builder.add_branch(*var2);
ProcedureBuilder::Branch branch = builder.add_branch(*var2);
branch.branch_false.add_call(add_10_fn, {var1});
branch.branch_true.add_call(add_100_fn, {var1});
builder.set_cursor_after_branch(branch);
@@ -125,8 +125,8 @@ TEST(multi_function_procedure, BranchTest)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor procedure_fn{procedure};
MFParamsBuilder params(procedure_fn, 5);
ProcedureExecutor procedure_fn{procedure};
ParamsBuilder params(procedure_fn, 5);
Array<int> values_a = {1, 5, 3, 6, 2};
Array<bool> values_cond = {true, false, true, true, false};
@@ -134,7 +134,7 @@ TEST(multi_function_procedure, BranchTest)
params.add_single_mutable(values_a.as_mutable_span());
params.add_readonly_single_input(values_cond.as_span());
MFContextBuilder context;
ContextBuilder context;
procedure_fn.call({1, 2, 3, 4}, params, context);
EXPECT_EQ(values_a[0], 1);
@@ -153,28 +153,28 @@ TEST(multi_function_procedure, EvaluateOne)
*/
int tot_evaluations = 0;
const auto add_10_fn = fn::build_mf::SI1_SO<int, int>("add_10", [&](int a) {
const auto add_10_fn = mf::build::SI1_SO<int, int>("add_10", [&](int a) {
tot_evaluations++;
return a + 10;
});
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
MFVariable *var1 = &builder.add_single_input_parameter<int>();
Variable *var1 = &builder.add_single_input_parameter<int>();
auto [var2] = builder.add_call<1>(add_10_fn, {var1});
builder.add_destruct(*var1);
builder.add_return();
builder.add_output_parameter(*var2);
MFProcedureExecutor procedure_fn{procedure};
MFParamsBuilder params{procedure_fn, 5};
ProcedureExecutor procedure_fn{procedure};
ParamsBuilder params{procedure_fn, 5};
Array<int> values_out = {1, 2, 3, 4, 5};
params.add_readonly_single_input_value(1);
params.add_uninitialized_single_output(values_out.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
procedure_fn.call({0, 1, 3, 4}, params, context);
EXPECT_EQ(values_out[0], 11);
@@ -205,25 +205,25 @@ TEST(multi_function_procedure, SimpleLoop)
CustomMF_Constant<int> const_1_fn{1};
CustomMF_Constant<int> const_0_fn{0};
auto greater_or_equal_fn = fn::build_mf::SI2_SO<int, int, bool>(
auto greater_or_equal_fn = mf::build::SI2_SO<int, int, bool>(
"greater or equal", [](int a, int b) { return a >= b; });
auto double_fn = build_mf::SM<int>("double", [](int &a) { a *= 2; });
auto add_1000_fn = build_mf::SM<int>("add 1000", [](int &a) { a += 1000; });
auto add_1_fn = build_mf::SM<int>("add 1", [](int &a) { a += 1; });
auto double_fn = build::SM<int>("double", [](int &a) { a *= 2; });
auto add_1000_fn = build::SM<int>("add 1000", [](int &a) { a += 1000; });
auto add_1_fn = build::SM<int>("add 1", [](int &a) { a += 1; });
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
MFVariable *var_count = &builder.add_single_input_parameter<int>("count");
Variable *var_count = &builder.add_single_input_parameter<int>("count");
auto [var_out] = builder.add_call<1>(const_1_fn);
var_out->set_name("out");
auto [var_index] = builder.add_call<1>(const_0_fn);
var_index->set_name("index");
MFProcedureBuilder::Loop loop = builder.add_loop();
ProcedureBuilder::Loop loop = builder.add_loop();
auto [var_condition] = builder.add_call<1>(greater_or_equal_fn, {var_index, var_count});
var_condition->set_name("condition");
MFProcedureBuilder::Branch branch = builder.add_branch(*var_condition);
ProcedureBuilder::Branch branch = builder.add_branch(*var_condition);
branch.branch_true.add_destruct(*var_condition);
branch.branch_true.add_loop_break(loop);
branch.branch_false.add_destruct(*var_condition);
@@ -239,8 +239,8 @@ TEST(multi_function_procedure, SimpleLoop)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor procedure_fn{procedure};
MFParamsBuilder params{procedure_fn, 5};
ProcedureExecutor procedure_fn{procedure};
ParamsBuilder params{procedure_fn, 5};
Array<int> counts = {4, 3, 7, 6, 4};
Array<int> results(5, -1);
@@ -248,7 +248,7 @@ TEST(multi_function_procedure, SimpleLoop)
params.add_readonly_single_input(counts.as_span());
params.add_uninitialized_single_output(results.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
procedure_fn.call({0, 1, 3, 4}, params, context);
EXPECT_EQ(results[0], 1016);
@@ -277,11 +277,11 @@ TEST(multi_function_procedure, Vectors)
SumVectorFunction sum_elements_fn;
CustomMF_Constant<int> constant_5_fn{5};
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
MFVariable *var_v1 = &builder.add_input_parameter(MFDataType::ForVector<int>());
MFVariable *var_v2 = &builder.add_parameter(MFParamType::ForMutableVector(CPPType::get<int>()));
Variable *var_v1 = &builder.add_input_parameter(DataType::ForVector<int>());
Variable *var_v2 = &builder.add_parameter(ParamType::ForMutableVector(CPPType::get<int>()));
builder.add_call(extend_fn, {var_v1, var_v2});
auto [var_constant] = builder.add_call<1>(constant_5_fn);
builder.add_call(append_fn, {var_v2, var_constant});
@@ -295,8 +295,8 @@ TEST(multi_function_procedure, Vectors)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor procedure_fn{procedure};
MFParamsBuilder params{procedure_fn, 5};
ProcedureExecutor procedure_fn{procedure};
ParamsBuilder params{procedure_fn, 5};
Array<int> v1 = {5, 2, 3};
GVectorArray v2{CPPType::get<int>(), 5};
@@ -310,7 +310,7 @@ TEST(multi_function_procedure, Vectors)
params.add_vector_mutable(v2);
params.add_vector_output(v3);
MFContextBuilder context;
ContextBuilder context;
procedure_fn.call({0, 1, 3, 4}, params, context);
EXPECT_EQ(v2[0].size(), 6);
@@ -338,12 +338,12 @@ TEST(multi_function_procedure, BufferReuse)
* }
*/
auto add_10_fn = build_mf::SI1_SO<int, int>("add 10", [](int a) { return a + 10; });
auto add_10_fn = build::SI1_SO<int, int>("add 10", [](int a) { return a + 10; });
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
MFVariable *var_a = &builder.add_single_input_parameter<int>();
Variable *var_a = &builder.add_single_input_parameter<int>();
auto [var_b] = builder.add_call<1>(add_10_fn, {var_a});
builder.add_destruct(*var_a);
auto [var_c] = builder.add_call<1>(add_10_fn, {var_b});
@@ -359,16 +359,16 @@ TEST(multi_function_procedure, BufferReuse)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor procedure_fn{procedure};
ProcedureExecutor procedure_fn{procedure};
Array<int> inputs = {4, 1, 6, 2, 3};
Array<int> results(5, -1);
MFParamsBuilder params{procedure_fn, 5};
ParamsBuilder params{procedure_fn, 5};
params.add_readonly_single_input(inputs.as_span());
params.add_uninitialized_single_output(results.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
procedure_fn.call({0, 2, 3, 4}, params, context);
EXPECT_EQ(results[0], 54);
@@ -380,12 +380,12 @@ TEST(multi_function_procedure, BufferReuse)
TEST(multi_function_procedure, OutputBufferReplaced)
{
MFProcedure procedure;
MFProcedureBuilder builder{procedure};
Procedure procedure;
ProcedureBuilder builder{procedure};
const int output_value = 42;
CustomMF_GenericConstant constant_fn(CPPType::get<int>(), &output_value, false);
MFVariable &var_o = procedure.new_variable(MFDataType::ForSingle<int>());
Variable &var_o = procedure.new_variable(DataType::ForSingle<int>());
builder.add_output_parameter(var_o);
builder.add_call_with_all_variables(constant_fn, {&var_o});
builder.add_destruct(var_o);
@@ -394,13 +394,13 @@ TEST(multi_function_procedure, OutputBufferReplaced)
EXPECT_TRUE(procedure.validate());
MFProcedureExecutor procedure_fn{procedure};
ProcedureExecutor procedure_fn{procedure};
Array<int> output(3, 0);
fn::MFParamsBuilder params(procedure_fn, output.size());
mf::ParamsBuilder params(procedure_fn, output.size());
params.add_uninitialized_single_output(output.as_mutable_span());
fn::MFContextBuilder context;
mf::ContextBuilder context;
procedure_fn.call(IndexMask(output.size()), params, context);
EXPECT_EQ(output[0], output_value);
@@ -408,4 +408,4 @@ TEST(multi_function_procedure, OutputBufferReplaced)
EXPECT_EQ(output[2], output_value);
}
} // namespace blender::fn::tests
} // namespace blender::fn::multi_function::tests

View File

@@ -6,28 +6,28 @@
#include "FN_multi_function_builder.hh"
#include "FN_multi_function_test_common.hh"
namespace blender::fn::tests {
namespace blender::fn::multi_function::tests {
namespace {
class AddFunction : public MultiFunction {
public:
AddFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder("Add", signature);
Signature signature;
SignatureBuilder builder("Add", signature);
builder.single_input<int>("A");
builder.single_input<int>("B");
builder.single_output<int>("Result");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
const VArray<int> &a = params.readonly_single_input<int>(0, "A");
const VArray<int> &b = params.readonly_single_input<int>(1, "B");
@@ -47,12 +47,12 @@ TEST(multi_function, AddFunction)
Array<int> input2 = {10, 20, 30};
Array<int> output(3, -1);
MFParamsBuilder params(fn, 3);
ParamsBuilder params(fn, 3);
params.add_readonly_single_input(input1.as_span());
params.add_readonly_single_input(input2.as_span());
params.add_uninitialized_single_output(output.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
fn.call({0, 2}, params, context);
@@ -74,11 +74,11 @@ TEST(multi_function, AddPrefixFunction)
std::string prefix = "AB";
MFParamsBuilder params(fn, strings.size());
ParamsBuilder params(fn, strings.size());
params.add_readonly_single_input(&prefix);
params.add_single_mutable(strings.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
fn.call({0, 2, 3}, params, context);
@@ -96,11 +96,11 @@ TEST(multi_function, CreateRangeFunction)
GVectorArray_TypedMutableRef<int> ranges_ref{ranges};
Array<int> sizes = {3, 0, 6, 1, 4};
MFParamsBuilder params(fn, ranges.size());
ParamsBuilder params(fn, ranges.size());
params.add_readonly_single_input(sizes.as_span());
params.add_vector_output(ranges);
MFContextBuilder context;
ContextBuilder context;
fn.call({0, 1, 2, 3}, params, context);
@@ -128,11 +128,11 @@ TEST(multi_function, GenericAppendFunction)
vectors_ref.append(2, 6);
Array<int> values = {5, 7, 3, 1};
MFParamsBuilder params(fn, vectors.size());
ParamsBuilder params(fn, vectors.size());
params.add_vector_mutable(vectors);
params.add_readonly_single_input(values.as_span());
MFContextBuilder context;
ContextBuilder context;
fn.call(IndexRange(vectors.size()), params, context);
@@ -156,10 +156,10 @@ TEST(multi_function, CustomMF_Constant)
Array<int> outputs(4, 0);
MFParamsBuilder params(fn, outputs.size());
ParamsBuilder params(fn, outputs.size());
params.add_uninitialized_single_output(outputs.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
fn.call({0, 2, 3}, params, context);
@@ -176,10 +176,10 @@ TEST(multi_function, CustomMF_GenericConstant)
Array<int> outputs(4, 0);
MFParamsBuilder params(fn, outputs.size());
ParamsBuilder params(fn, outputs.size());
params.add_uninitialized_single_output(outputs.as_mutable_span());
MFContextBuilder context;
ContextBuilder context;
fn.call({0, 1, 2}, params, context);
@@ -197,10 +197,10 @@ TEST(multi_function, CustomMF_GenericConstantArray)
GVectorArray vector_array{CPPType::get<int32_t>(), 4};
GVectorArray_TypedMutableRef<int> vector_array_ref{vector_array};
MFParamsBuilder params(fn, vector_array.size());
ParamsBuilder params(fn, vector_array.size());
params.add_vector_output(vector_array);
MFContextBuilder context;
ContextBuilder context;
fn.call({1, 2, 3}, params, context);
@@ -220,20 +220,20 @@ TEST(multi_function, IgnoredOutputs)
{
OptionalOutputsFunction fn;
{
MFParamsBuilder params(fn, 10);
ParamsBuilder params(fn, 10);
params.add_ignored_single_output("Out 1");
params.add_ignored_single_output("Out 2");
MFContextBuilder context;
ContextBuilder context;
fn.call(IndexRange(10), params, context);
}
{
Array<int> results_1(10);
Array<std::string> results_2(10, NoInitialization());
MFParamsBuilder params(fn, 10);
ParamsBuilder params(fn, 10);
params.add_uninitialized_single_output(results_1.as_mutable_span(), "Out 1");
params.add_uninitialized_single_output(results_2.as_mutable_span(), "Out 2");
MFContextBuilder context;
ContextBuilder context;
fn.call(IndexRange(10), params, context);
EXPECT_EQ(results_1[0], 5);
@@ -244,4 +244,4 @@ TEST(multi_function, IgnoredOutputs)
}
} // namespace
} // namespace blender::fn::tests
} // namespace blender::fn::multi_function::tests

View File

@@ -2,26 +2,26 @@
#include "FN_multi_function.hh"
namespace blender::fn::tests {
namespace blender::fn::multi_function::tests {
class AddPrefixFunction : public MultiFunction {
public:
AddPrefixFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder{"Add Prefix", signature};
Signature signature;
SignatureBuilder builder{"Add Prefix", signature};
builder.single_input<std::string>("Prefix");
builder.single_mutable<std::string>("Strings");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
const VArray<std::string> &prefixes = params.readonly_single_input<std::string>(0, "Prefix");
MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings");
@@ -36,20 +36,20 @@ class CreateRangeFunction : public MultiFunction {
public:
CreateRangeFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder{"Create Range", signature};
Signature signature;
SignatureBuilder builder{"Create Range", signature};
builder.single_input<int>("Size");
builder.vector_output<int>("Range");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
const VArray<int> &sizes = params.readonly_single_input<int>(0, "Size");
GVectorArray &ranges = params.vector_output(1, "Range");
@@ -65,18 +65,18 @@ class CreateRangeFunction : public MultiFunction {
class GenericAppendFunction : public MultiFunction {
private:
MFSignature signature_;
Signature signature_;
public:
GenericAppendFunction(const CPPType &type)
{
MFSignatureBuilder builder{"Append", signature_};
SignatureBuilder builder{"Append", signature_};
builder.vector_mutable("Vector", type);
builder.single_input("Value", type);
this->set_signature(&signature_);
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
GVectorArray &vectors = params.vector_mutable(0, "Vector");
const GVArray &values = params.readonly_single_input(1, "Value");
@@ -94,20 +94,20 @@ class ConcatVectorsFunction : public MultiFunction {
public:
ConcatVectorsFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder{"Concat Vectors", signature};
Signature signature;
SignatureBuilder builder{"Concat Vectors", signature};
builder.vector_mutable<int>("A");
builder.vector_input<int>("B");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
GVectorArray &a = params.vector_mutable(0);
const GVVectorArray &b = params.readonly_vector_input(1);
@@ -119,20 +119,20 @@ class AppendFunction : public MultiFunction {
public:
AppendFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder{"Append", signature};
Signature signature;
SignatureBuilder builder{"Append", signature};
builder.vector_mutable<int>("Vector");
builder.single_input<int>("Value");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
GVectorArray_TypedMutableRef<int> vectors = params.vector_mutable<int>(0);
const VArray<int> &values = params.readonly_single_input<int>(1);
@@ -147,20 +147,20 @@ class SumVectorFunction : public MultiFunction {
public:
SumVectorFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder{"Sum Vectors", signature};
Signature signature;
SignatureBuilder builder{"Sum Vectors", signature};
builder.vector_input<int>("Vector");
builder.single_output<int>("Sum");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
const VVectorArray<int> &vectors = params.readonly_vector_input<int>(0);
MutableSpan<int> sums = params.uninitialized_single_output<int>(1);
@@ -179,20 +179,20 @@ class OptionalOutputsFunction : public MultiFunction {
public:
OptionalOutputsFunction()
{
static MFSignature signature = create_signature();
static Signature signature = create_signature();
this->set_signature(&signature);
}
static MFSignature create_signature()
static Signature create_signature()
{
MFSignature signature;
MFSignatureBuilder builder{"Optional Outputs", signature};
Signature signature;
SignatureBuilder builder{"Optional Outputs", signature};
builder.single_output<int>("Out 1");
builder.single_output<std::string>("Out 2");
return signature;
}
void call(IndexMask mask, MFParams params, MFContext /*context*/) const override
void call(IndexMask mask, MFParams params, Context /*context*/) const override
{
if (params.single_output_is_required(0, "Out 1")) {
MutableSpan<int> values = params.uninitialized_single_output<int>(0, "Out 1");
@@ -205,4 +205,4 @@ class OptionalOutputsFunction : public MultiFunction {
}
};
} // namespace blender::fn::tests
} // namespace blender::fn::multi_function::tests

View File

@@ -17,10 +17,10 @@ namespace blender::geometry {
static fn::Field<int> get_count_input_max_one(const fn::Field<int> &count_field)
{
static auto max_one_fn = fn::build_mf::SI1_SO<int, int>(
static auto max_one_fn = mf::build::SI1_SO<int, int>(
"Clamp Above One",
[](int value) { return std::max(1, value); },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
auto clamp_op = std::make_shared<fn::FieldOperation>(
fn::FieldOperation(max_one_fn, {count_field}));
@@ -29,7 +29,7 @@ static fn::Field<int> get_count_input_max_one(const fn::Field<int> &count_field)
static fn::Field<int> get_count_input_from_length(const fn::Field<float> &length_field)
{
static auto get_count_fn = fn::build_mf::SI2_SO<float, float, int>(
static auto get_count_fn = mf::build::SI2_SO<float, float, int>(
"Length Input to Count",
[](const float curve_length, const float sample_length) {
/* Find the number of sampled segments by dividing the total length by
@@ -37,7 +37,7 @@ static fn::Field<int> get_count_input_from_length(const fn::Field<float> &length
const int count = int(curve_length / sample_length) + 1;
return std::max(1, count);
},
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
auto get_count_op = std::make_shared<fn::FieldOperation>(fn::FieldOperation(
get_count_fn,

View File

@@ -125,17 +125,16 @@ using blender::fn::ValueOrFieldCPPType;
using blender::nodes::FieldInferencingInterface;
using blender::nodes::GeoNodeExecParams;
using blender::nodes::InputSocketFieldType;
using blender::nodes::geo_eval_log::GeoModifierLog;
using blender::threading::EnumerableThreadSpecific;
using namespace blender::fn::multi_function_types;
using blender::nodes::geo_eval_log::GeometryAttributeInfo;
using blender::nodes::geo_eval_log::GeometryInfoLog;
using blender::nodes::geo_eval_log::GeoModifierLog;
using blender::nodes::geo_eval_log::GeoNodeLog;
using blender::nodes::geo_eval_log::GeoTreeLog;
using blender::nodes::geo_eval_log::NamedAttributeUsage;
using blender::nodes::geo_eval_log::NodeWarning;
using blender::nodes::geo_eval_log::NodeWarningType;
using blender::nodes::geo_eval_log::ValueLog;
using blender::threading::EnumerableThreadSpecific;
static void initData(ModifierData *md)
{

View File

@@ -31,8 +31,8 @@ struct Depsgraph;
namespace blender::nodes {
namespace lf = fn::lazy_function;
using lf::LazyFunction;
using mf::MultiFunction;
/**
* Data that is passed into geometry nodes evaluation from the modifier.

View File

@@ -51,8 +51,8 @@ inline bool try_dispatch_float_math_fl_to_fl(const int operation, Callback &&cal
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = mf::build::exec_presets::Materialized();
/* This is just an utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -118,8 +118,8 @@ inline bool try_dispatch_float_math_fl_fl_to_fl(const int operation, Callback &&
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = mf::build::exec_presets::Materialized();
/* This is just an utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -180,21 +180,21 @@ inline bool try_dispatch_float_math_fl_fl_fl_to_fl(const int operation, Callback
switch (operation) {
case NODE_MATH_MULTIPLY_ADD:
return dispatch(fn::build_mf::exec_presets::AllSpanOrSingle(),
return dispatch(mf::build::exec_presets::AllSpanOrSingle(),
[](float a, float b, float c) { return a * b + c; });
case NODE_MATH_COMPARE:
return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(),
return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0, 1>(),
[](float a, float b, float c) -> float {
return ((a == b) || (fabsf(a - b) <= fmaxf(c, FLT_EPSILON))) ? 1.0f : 0.0f;
});
case NODE_MATH_SMOOTH_MIN:
return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(),
return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0, 1>(),
[](float a, float b, float c) { return smoothminf(a, b, c); });
case NODE_MATH_SMOOTH_MAX:
return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(),
return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0, 1>(),
[](float a, float b, float c) { return -smoothminf(-a, -b, c); });
case NODE_MATH_WRAP:
return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0>(),
return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0>(),
[](float a, float b, float c) { return wrapf(a, b, c); });
}
return false;
@@ -214,8 +214,8 @@ inline bool try_dispatch_float_math_fl3_fl3_to_fl3(const NodeVectorMathOperation
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = mf::build::exec_presets::Materialized();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -269,7 +269,7 @@ inline bool try_dispatch_float_math_fl3_fl3_to_fl(const NodeVectorMathOperation
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -302,8 +302,8 @@ inline bool try_dispatch_float_math_fl3_fl3_fl3_to_fl3(const NodeVectorMathOpera
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = mf::build::exec_presets::Materialized();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -341,7 +341,7 @@ inline bool try_dispatch_float_math_fl3_fl3_fl_to_fl3(const NodeVectorMathOperat
return false;
}
static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized();
static auto exec_preset_slow = mf::build::exec_presets::Materialized();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -373,7 +373,7 @@ inline bool try_dispatch_float_math_fl3_to_fl(const NodeVectorMathOperation oper
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -402,7 +402,7 @@ inline bool try_dispatch_float_math_fl3_fl_to_fl3(const NodeVectorMathOperation
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {
@@ -433,8 +433,8 @@ inline bool try_dispatch_float_math_fl3_to_fl3(const NodeVectorMathOperation ope
return false;
}
static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized();
static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle();
static auto exec_preset_slow = mf::build::exec_presets::Materialized();
/* This is just a utility function to keep the individual cases smaller. */
auto dispatch = [&](auto exec_preset, auto math_function) -> bool {

View File

@@ -8,8 +8,6 @@
namespace blender::nodes {
using namespace fn::multi_function_types;
class NodeMultiFunctions;
/**
@@ -19,8 +17,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable {
private:
const bNode &node_;
const bNodeTree &tree_;
std::shared_ptr<MultiFunction> owned_built_fn_;
const MultiFunction *built_fn_ = nullptr;
std::shared_ptr<mf::MultiFunction> owned_built_fn_;
const mf::MultiFunction *built_fn_ = nullptr;
friend NodeMultiFunctions;
@@ -31,8 +29,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable {
* Assign a multi-function for the current node. The input and output parameters of the function
* have to match the available sockets in the node.
*/
void set_matching_fn(const MultiFunction *fn);
void set_matching_fn(const MultiFunction &fn);
void set_matching_fn(const mf::MultiFunction *fn);
void set_matching_fn(const mf::MultiFunction &fn);
/**
* Utility method for creating and assigning a multi-function when it can't have a static
@@ -50,8 +48,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable {
class NodeMultiFunctions {
public:
struct Item {
const MultiFunction *fn = nullptr;
std::shared_ptr<MultiFunction> owned_fn;
const mf::MultiFunction *fn = nullptr;
std::shared_ptr<mf::MultiFunction> owned_fn;
};
private:
@@ -82,12 +80,12 @@ inline const bNodeTree &NodeMultiFunctionBuilder::tree()
return tree_;
}
inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn)
inline void NodeMultiFunctionBuilder::set_matching_fn(const mf::MultiFunction *fn)
{
built_fn_ = fn;
}
inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction &fn)
inline void NodeMultiFunctionBuilder::set_matching_fn(const mf::MultiFunction &fn)
{
built_fn_ = &fn;
}

View File

@@ -133,7 +133,7 @@ static void align_rotations_fixed_pivot(IndexMask mask,
});
}
class MF_AlignEulerToVector : public fn::MultiFunction {
class MF_AlignEulerToVector : public mf::MultiFunction {
private:
int main_axis_mode_;
int pivot_axis_mode_;
@@ -142,14 +142,14 @@ class MF_AlignEulerToVector : public fn::MultiFunction {
MF_AlignEulerToVector(int main_axis_mode, int pivot_axis_mode)
: main_axis_mode_(main_axis_mode), pivot_axis_mode_(pivot_axis_mode)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Align Euler to Vector", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Align Euler to Vector", signature};
builder.single_input<float3>("Rotation");
builder.single_input<float>("Factor");
builder.single_input<float3>("Vector");
@@ -158,7 +158,7 @@ class MF_AlignEulerToVector : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &input_rotations = params.readonly_single_input<float3>(0, "Rotation");
const VArray<float> &factors = params.readonly_single_input<float>(1, "Factor");

View File

@@ -65,26 +65,26 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
{
static auto exec_preset = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto and_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto exec_preset = mf::build::exec_presets::AllSpanOrSingle();
static auto and_fn = mf::build::SI2_SO<bool, bool, bool>(
"And", [](bool a, bool b) { return a && b; }, exec_preset);
static auto or_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto or_fn = mf::build::SI2_SO<bool, bool, bool>(
"Or", [](bool a, bool b) { return a || b; }, exec_preset);
static auto not_fn = fn::build_mf::SI1_SO<bool, bool>(
static auto not_fn = mf::build::SI1_SO<bool, bool>(
"Not", [](bool a) { return !a; }, exec_preset);
static auto nand_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto nand_fn = mf::build::SI2_SO<bool, bool, bool>(
"Not And", [](bool a, bool b) { return !(a && b); }, exec_preset);
static auto nor_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto nor_fn = mf::build::SI2_SO<bool, bool, bool>(
"Nor", [](bool a, bool b) { return !(a || b); }, exec_preset);
static auto xnor_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto xnor_fn = mf::build::SI2_SO<bool, bool, bool>(
"Equal", [](bool a, bool b) { return a == b; }, exec_preset);
static auto xor_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto xor_fn = mf::build::SI2_SO<bool, bool, bool>(
"Not Equal", [](bool a, bool b) { return a != b; }, exec_preset);
static auto imply_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto imply_fn = mf::build::SI2_SO<bool, bool, bool>(
"Imply", [](bool a, bool b) { return !a || b; }, exec_preset);
static auto nimply_fn = fn::build_mf::SI2_SO<bool, bool, bool>(
static auto nimply_fn = mf::build::SI2_SO<bool, bool, bool>(
"Subtract", [](bool a, bool b) { return a && !b; }, exec_preset);
switch (bnode.custom1) {
@@ -114,7 +114,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}

View File

@@ -49,20 +49,20 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
{
const NodeCombSepColor &storage = node_storage(bnode);
static auto rgba_fn = fn::build_mf::SI4_SO<float, float, float, float, ColorGeometry4f>(
static auto rgba_fn = mf::build::SI4_SO<float, float, float, float, ColorGeometry4f>(
"RGB", [](float r, float g, float b, float a) { return ColorGeometry4f(r, g, b, a); });
static auto hsva_fn = fn::build_mf::SI4_SO<float, float, float, float, ColorGeometry4f>(
static auto hsva_fn = mf::build::SI4_SO<float, float, float, float, ColorGeometry4f>(
"HSV", [](float h, float s, float v, float a) {
ColorGeometry4f r_color;
hsv_to_rgb(h, s, v, &r_color.r, &r_color.g, &r_color.b);
r_color.a = a;
return r_color;
});
static auto hsla_fn = fn::build_mf::SI4_SO<float, float, float, float, ColorGeometry4f>(
static auto hsla_fn = mf::build::SI4_SO<float, float, float, float, ColorGeometry4f>(
"HSL", [](float h, float s, float l, float a) {
ColorGeometry4f color;
hsl_to_rgb(h, s, l, &color.r, &color.g, &color.b);
@@ -85,7 +85,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}

View File

@@ -164,45 +164,45 @@ static float component_average(float3 a)
return (a.x + a.y + a.z) / 3.0f;
}
static const fn::MultiFunction *get_multi_function(const bNode &node)
static const mf::MultiFunction *get_multi_function(const bNode &node)
{
const NodeFunctionCompare *data = (NodeFunctionCompare *)node.storage;
static auto exec_preset_all = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto exec_preset_first_two = fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>();
static auto exec_preset_all = mf::build::exec_presets::AllSpanOrSingle();
static auto exec_preset_first_two = mf::build::exec_presets::SomeSpanOrSingle<0, 1>();
switch (data->data_type) {
case SOCK_FLOAT:
switch (data->operation) {
case NODE_COMPARE_LESS_THAN: {
static auto fn = fn::build_mf::SI2_SO<float, float, bool>(
static auto fn = mf::build::SI2_SO<float, float, bool>(
"Less Than", [](float a, float b) { return a < b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_LESS_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<float, float, bool>(
static auto fn = mf::build::SI2_SO<float, float, bool>(
"Less Equal", [](float a, float b) { return a <= b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_GREATER_THAN: {
static auto fn = fn::build_mf::SI2_SO<float, float, bool>(
static auto fn = mf::build::SI2_SO<float, float, bool>(
"Greater Than", [](float a, float b) { return a > b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_GREATER_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<float, float, bool>(
static auto fn = mf::build::SI2_SO<float, float, bool>(
"Greater Equal", [](float a, float b) { return a >= b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_EQUAL: {
static auto fn = fn::build_mf::SI3_SO<float, float, float, bool>(
static auto fn = mf::build::SI3_SO<float, float, float, bool>(
"Equal",
[](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_NOT_EQUAL:
static auto fn = fn::build_mf::SI3_SO<float, float, float, bool>(
static auto fn = mf::build::SI3_SO<float, float, float, bool>(
"Not Equal",
[](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; },
exec_preset_first_two);
@@ -212,32 +212,32 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case SOCK_INT:
switch (data->operation) {
case NODE_COMPARE_LESS_THAN: {
static auto fn = fn::build_mf::SI2_SO<int, int, bool>(
static auto fn = mf::build::SI2_SO<int, int, bool>(
"Less Than", [](int a, int b) { return a < b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_LESS_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<int, int, bool>(
static auto fn = mf::build::SI2_SO<int, int, bool>(
"Less Equal", [](int a, int b) { return a <= b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_GREATER_THAN: {
static auto fn = fn::build_mf::SI2_SO<int, int, bool>(
static auto fn = mf::build::SI2_SO<int, int, bool>(
"Greater Than", [](int a, int b) { return a > b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_GREATER_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<int, int, bool>(
static auto fn = mf::build::SI2_SO<int, int, bool>(
"Greater Equal", [](int a, int b) { return a >= b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<int, int, bool>(
static auto fn = mf::build::SI2_SO<int, int, bool>(
"Equal", [](int a, int b) { return a == b; }, exec_preset_all);
return &fn;
}
case NODE_COMPARE_NOT_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<int, int, bool>(
static auto fn = mf::build::SI2_SO<int, int, bool>(
"Not Equal", [](int a, int b) { return a != b; }, exec_preset_all);
return &fn;
}
@@ -248,35 +248,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_COMPARE_LESS_THAN:
switch (data->mode) {
case NODE_COMPARE_MODE_AVERAGE: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Less Than - Average",
[](float3 a, float3 b) { return component_average(a) < component_average(b); },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_DOT_PRODUCT: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Less Than - Dot Product",
[](float3 a, float3 b, float comp) { return math::dot(a, b) < comp; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_DIRECTION: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Less Than - Direction",
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) < angle; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_ELEMENT: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Less Than - Element-wise",
[](float3 a, float3 b) { return a.x < b.x && a.y < b.y && a.z < b.z; },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_LENGTH: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Less Than - Length",
[](float3 a, float3 b) { return math::length(a) < math::length(b); },
exec_preset_all);
@@ -287,35 +287,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_COMPARE_LESS_EQUAL:
switch (data->mode) {
case NODE_COMPARE_MODE_AVERAGE: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Less Equal - Average",
[](float3 a, float3 b) { return component_average(a) <= component_average(b); },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_DOT_PRODUCT: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Less Equal - Dot Product",
[](float3 a, float3 b, float comp) { return math::dot(a, b) <= comp; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_DIRECTION: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Less Equal - Direction",
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) <= angle; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_ELEMENT: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Less Equal - Element-wise",
[](float3 a, float3 b) { return a.x <= b.x && a.y <= b.y && a.z <= b.z; },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_LENGTH: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Less Equal - Length",
[](float3 a, float3 b) { return math::length(a) <= math::length(b); },
exec_preset_all);
@@ -326,35 +326,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_COMPARE_GREATER_THAN:
switch (data->mode) {
case NODE_COMPARE_MODE_AVERAGE: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Greater Than - Average",
[](float3 a, float3 b) { return component_average(a) > component_average(b); },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_DOT_PRODUCT: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Greater Than - Dot Product",
[](float3 a, float3 b, float comp) { return math::dot(a, b) > comp; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_DIRECTION: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Greater Than - Direction",
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) > angle; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_ELEMENT: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Greater Than - Element-wise",
[](float3 a, float3 b) { return a.x > b.x && a.y > b.y && a.z > b.z; },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_LENGTH: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Greater Than - Length",
[](float3 a, float3 b) { return math::length(a) > math::length(b); },
exec_preset_all);
@@ -365,35 +365,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_COMPARE_GREATER_EQUAL:
switch (data->mode) {
case NODE_COMPARE_MODE_AVERAGE: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Greater Equal - Average",
[](float3 a, float3 b) { return component_average(a) >= component_average(b); },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_DOT_PRODUCT: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Greater Equal - Dot Product",
[](float3 a, float3 b, float comp) { return math::dot(a, b) >= comp; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_DIRECTION: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Greater Equal - Direction",
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) >= angle; },
exec_preset_first_two);
return &fn;
}
case NODE_COMPARE_MODE_ELEMENT: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Greater Equal - Element-wise",
[](float3 a, float3 b) { return a.x >= b.x && a.y >= b.y && a.z >= b.z; },
exec_preset_all);
return &fn;
}
case NODE_COMPARE_MODE_LENGTH: {
static auto fn = fn::build_mf::SI2_SO<float3, float3, bool>(
static auto fn = mf::build::SI2_SO<float3, float3, bool>(
"Greater Equal - Length",
[](float3 a, float3 b) { return math::length(a) >= math::length(b); },
exec_preset_all);
@@ -404,7 +404,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_COMPARE_EQUAL:
switch (data->mode) {
case NODE_COMPARE_MODE_AVERAGE: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Equal - Average",
[](float3 a, float3 b, float epsilon) {
return abs(component_average(a) - component_average(b)) <= epsilon;
@@ -413,7 +413,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_DOT_PRODUCT: {
static auto fn = fn::build_mf::SI4_SO<float3, float3, float, float, bool>(
static auto fn = mf::build::SI4_SO<float3, float3, float, float, bool>(
"Equal - Dot Product",
[](float3 a, float3 b, float comp, float epsilon) {
return abs(math::dot(a, b) - comp) <= epsilon;
@@ -422,7 +422,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_DIRECTION: {
static auto fn = fn::build_mf::SI4_SO<float3, float3, float, float, bool>(
static auto fn = mf::build::SI4_SO<float3, float3, float, float, bool>(
"Equal - Direction",
[](float3 a, float3 b, float angle, float epsilon) {
return abs(angle_v3v3(a, b) - angle) <= epsilon;
@@ -431,7 +431,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_ELEMENT: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Equal - Element-wise",
[](float3 a, float3 b, float epsilon) {
return abs(a.x - b.x) <= epsilon && abs(a.y - b.y) <= epsilon &&
@@ -441,7 +441,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_LENGTH: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Equal - Length",
[](float3 a, float3 b, float epsilon) {
return abs(math::length(a) - math::length(b)) <= epsilon;
@@ -454,7 +454,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_COMPARE_NOT_EQUAL:
switch (data->mode) {
case NODE_COMPARE_MODE_AVERAGE: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Not Equal - Average",
[](float3 a, float3 b, float epsilon) {
return abs(component_average(a) - component_average(b)) > epsilon;
@@ -463,7 +463,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_DOT_PRODUCT: {
static auto fn = fn::build_mf::SI4_SO<float3, float3, float, float, bool>(
static auto fn = mf::build::SI4_SO<float3, float3, float, float, bool>(
"Not Equal - Dot Product",
[](float3 a, float3 b, float comp, float epsilon) {
return abs(math::dot(a, b) - comp) >= epsilon;
@@ -472,7 +472,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_DIRECTION: {
static auto fn = fn::build_mf::SI4_SO<float3, float3, float, float, bool>(
static auto fn = mf::build::SI4_SO<float3, float3, float, float, bool>(
"Not Equal - Direction",
[](float3 a, float3 b, float angle, float epsilon) {
return abs(angle_v3v3(a, b) - angle) > epsilon;
@@ -481,7 +481,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_ELEMENT: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Not Equal - Element-wise",
[](float3 a, float3 b, float epsilon) {
return abs(a.x - b.x) > epsilon || abs(a.y - b.y) > epsilon ||
@@ -491,7 +491,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_MODE_LENGTH: {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, bool>(
static auto fn = mf::build::SI3_SO<float3, float3, float, bool>(
"Not Equal - Length",
[](float3 a, float3 b, float epsilon) {
return abs(math::length(a) - math::length(b)) > epsilon;
@@ -506,7 +506,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case SOCK_RGBA:
switch (data->operation) {
case NODE_COMPARE_EQUAL: {
static auto fn = fn::build_mf::SI3_SO<ColorGeometry4f, ColorGeometry4f, float, bool>(
static auto fn = mf::build::SI3_SO<ColorGeometry4f, ColorGeometry4f, float, bool>(
"Equal",
[](ColorGeometry4f a, ColorGeometry4f b, float epsilon) {
return abs(a.r - b.r) <= epsilon && abs(a.g - b.g) <= epsilon &&
@@ -516,7 +516,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_NOT_EQUAL: {
static auto fn = fn::build_mf::SI3_SO<ColorGeometry4f, ColorGeometry4f, float, bool>(
static auto fn = mf::build::SI3_SO<ColorGeometry4f, ColorGeometry4f, float, bool>(
"Not Equal",
[](ColorGeometry4f a, ColorGeometry4f b, float epsilon) {
return abs(a.r - b.r) > epsilon || abs(a.g - b.g) > epsilon ||
@@ -526,7 +526,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_COLOR_BRIGHTER: {
static auto fn = fn::build_mf::SI2_SO<ColorGeometry4f, ColorGeometry4f, bool>(
static auto fn = mf::build::SI2_SO<ColorGeometry4f, ColorGeometry4f, bool>(
"Brighter",
[](ColorGeometry4f a, ColorGeometry4f b) {
return rgb_to_grayscale(a) > rgb_to_grayscale(b);
@@ -535,7 +535,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
return &fn;
}
case NODE_COMPARE_COLOR_DARKER: {
static auto fn = fn::build_mf::SI2_SO<ColorGeometry4f, ColorGeometry4f, bool>(
static auto fn = mf::build::SI2_SO<ColorGeometry4f, ColorGeometry4f, bool>(
"Darker",
[](ColorGeometry4f a, ColorGeometry4f b) {
return rgb_to_grayscale(a) < rgb_to_grayscale(b);
@@ -548,12 +548,12 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case SOCK_STRING:
switch (data->operation) {
case NODE_COMPARE_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<std::string, std::string, bool>(
static auto fn = mf::build::SI2_SO<std::string, std::string, bool>(
"Equal", [](std::string a, std::string b) { return a == b; });
return &fn;
}
case NODE_COMPARE_NOT_EQUAL: {
static auto fn = fn::build_mf::SI2_SO<std::string, std::string, bool>(
static auto fn = mf::build::SI2_SO<std::string, std::string, bool>(
"Not Equal", [](std::string a, std::string b) { return a != b; });
return &fn;
}
@@ -565,7 +565,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}

View File

@@ -36,16 +36,16 @@ static void node_label(const bNodeTree * /*tree*/, const bNode *node, char *labe
BLI_strncpy(label, IFACE_(name), maxlen);
}
static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
{
static auto exec_preset = fn::build_mf::exec_presets::AllSpanOrSingle();
static auto round_fn = fn::build_mf::SI1_SO<float, int>(
static auto exec_preset = mf::build::exec_presets::AllSpanOrSingle();
static auto round_fn = mf::build::SI1_SO<float, int>(
"Round", [](float a) { return int(round(a)); }, exec_preset);
static auto floor_fn = fn::build_mf::SI1_SO<float, int>(
static auto floor_fn = mf::build::SI1_SO<float, int>(
"Floor", [](float a) { return int(floor(a)); }, exec_preset);
static auto ceil_fn = fn::build_mf::SI1_SO<float, int>(
static auto ceil_fn = mf::build::SI1_SO<float, int>(
"Ceiling", [](float a) { return int(ceil(a)); }, exec_preset);
static auto trunc_fn = fn::build_mf::SI1_SO<float, int>(
static auto trunc_fn = mf::build::SI1_SO<float, int>(
"Truncate", [](float a) { return int(trunc(a)); }, exec_preset);
switch (static_cast<FloatToIntRoundingMode>(bnode.custom1)) {
@@ -65,7 +65,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}

View File

@@ -24,7 +24,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const bNode &bnode = builder.node();
NodeInputBool *node_storage = static_cast<NodeInputBool *>(bnode.storage);
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<bool>>(node_storage->boolean);
builder.construct_and_set_matching_fn<mf::CustomMF_Constant<bool>>(node_storage->boolean);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)

View File

@@ -25,7 +25,7 @@ static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &
const bNode &bnode = builder.node();
NodeInputColor *node_storage = static_cast<NodeInputColor *>(bnode.storage);
blender::ColorGeometry4f color = (ColorGeometry4f)node_storage->color;
builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<ColorGeometry4f>>(color);
builder.construct_and_set_matching_fn<blender::mf::CustomMF_Constant<ColorGeometry4f>>(color);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)

View File

@@ -24,7 +24,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const bNode &bnode = builder.node();
NodeInputInt *node_storage = static_cast<NodeInputInt *>(bnode.storage);
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<int>>(node_storage->integer);
builder.construct_and_set_matching_fn<mf::CustomMF_Constant<int>>(node_storage->integer);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)

View File

@@ -10,24 +10,24 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::String>(N_("Tab"));
}
class MF_SpecialCharacters : public fn::MultiFunction {
class MF_SpecialCharacters : public mf::MultiFunction {
public:
MF_SpecialCharacters()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Special Characters", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Special Characters", signature};
builder.single_output<std::string>("Line Break");
builder.single_output<std::string>("Tab");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
MutableSpan<std::string> lb = params.uninitialized_single_output<std::string>(0, "Line Break");
MutableSpan<std::string> tab = params.uninitialized_single_output<std::string>(1, "Tab");

View File

@@ -23,7 +23,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
const bNode &bnode = builder.node();
NodeInputString *node_storage = static_cast<NodeInputString *>(bnode.storage);
std::string string = std::string((node_storage->string) ? node_storage->string : "");
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<std::string>>(std::move(string));
builder.construct_and_set_matching_fn<mf::CustomMF_Constant<std::string>>(std::move(string));
}
static void node_init(bNodeTree * /*tree*/, bNode *node)

View File

@@ -25,7 +25,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
const bNode &bnode = builder.node();
NodeInputVector *node_storage = static_cast<NodeInputVector *>(bnode.storage);
float3 vector(node_storage->vector);
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<float3>>(vector);
builder.construct_and_set_matching_fn<mf::CustomMF_Constant<float3>>(vector);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)

View File

@@ -141,7 +141,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
switch (data_type) {
case CD_PROP_FLOAT3: {
static auto fn = fn::build_mf::SI4_SO<float3, float3, int, int, float3>(
static auto fn = mf::build::SI4_SO<float3, float3, int, int, float3>(
"Random Vector",
[](float3 min_value, float3 max_value, int id, int seed) -> float3 {
const float x = noise::hash_to_float(seed, id, 0);
@@ -149,23 +149,23 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
const float z = noise::hash_to_float(seed, id, 2);
return float3(x, y, z) * (max_value - min_value) + min_value;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<2>());
mf::build::exec_presets::SomeSpanOrSingle<2>());
builder.set_matching_fn(fn);
break;
}
case CD_PROP_FLOAT: {
static auto fn = fn::build_mf::SI4_SO<float, float, int, int, float>(
static auto fn = mf::build::SI4_SO<float, float, int, int, float>(
"Random Float",
[](float min_value, float max_value, int id, int seed) -> float {
const float value = noise::hash_to_float(seed, id);
return value * (max_value - min_value) + min_value;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<2>());
mf::build::exec_presets::SomeSpanOrSingle<2>());
builder.set_matching_fn(fn);
break;
}
case CD_PROP_INT32: {
static auto fn = fn::build_mf::SI4_SO<int, int, int, int, int>(
static auto fn = mf::build::SI4_SO<int, int, int, int, int>(
"Random Int",
[](int min_value, int max_value, int id, int seed) -> int {
const float value = noise::hash_to_float(id, seed);
@@ -173,17 +173,17 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
* distribution for the first and last values (See T93591). */
return floor(value * (max_value + 1 - min_value) + min_value);
},
fn::build_mf::exec_presets::SomeSpanOrSingle<2>());
mf::build::exec_presets::SomeSpanOrSingle<2>());
builder.set_matching_fn(fn);
break;
}
case CD_PROP_BOOL: {
static auto fn = fn::build_mf::SI3_SO<float, int, int, bool>(
static auto fn = mf::build::SI3_SO<float, int, int, bool>(
"Random Bool",
[](float probability, int id, int seed) -> bool {
return noise::hash_to_float(id, seed) <= probability;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<1>());
mf::build::exec_presets::SomeSpanOrSingle<1>());
builder.set_matching_fn(fn);
break;
}

View File

@@ -30,10 +30,8 @@ static std::string replace_all(const StringRefNull str,
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto substring_fn =
fn::build_mf::SI3_SO<std::string, std::string, std::string, std::string>(
"Replace",
[](const std::string &str, const std::string &find, const std::string &replace) {
static auto substring_fn = mf::build::SI3_SO<std::string, std::string, std::string, std::string>(
"Replace", [](const std::string &str, const std::string &find, const std::string &replace) {
return replace_all(str, find, replace);
});
builder.set_matching_fn(&substring_fn);

View File

@@ -52,9 +52,9 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
{
static auto obj_euler_rot = fn::build_mf::SI2_SO<float3, float3, float3>(
static auto obj_euler_rot = mf::build::SI2_SO<float3, float3, float3>(
"Rotate Euler by Euler/Object", [](const float3 &input, const float3 &rotation) {
float input_mat[3][3];
eul_to_mat3(input_mat, input);
@@ -66,7 +66,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
mat3_to_eul(result, mat_res);
return result;
});
static auto obj_AA_rot = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto obj_AA_rot = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate Euler by AxisAngle/Object",
[](const float3 &input, const float3 &axis, float angle) {
float input_mat[3][3];
@@ -79,7 +79,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
mat3_to_eul(result, mat_res);
return result;
});
static auto local_euler_rot = fn::build_mf::SI2_SO<float3, float3, float3>(
static auto local_euler_rot = mf::build::SI2_SO<float3, float3, float3>(
"Rotate Euler by Euler/Local", [](const float3 &input, const float3 &rotation) {
float input_mat[3][3];
eul_to_mat3(input_mat, input);
@@ -91,7 +91,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
mat3_to_eul(result, mat_res);
return result;
});
static auto local_AA_rot = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto local_AA_rot = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate Euler by AxisAngle/Local", [](const float3 &input, const float3 &axis, float angle) {
float input_mat[3][3];
eul_to_mat3(input_mat, input);
@@ -107,12 +107,12 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
short space = bnode.custom2;
if (type == FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE) {
return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ?
static_cast<const MultiFunction *>(&obj_AA_rot) :
static_cast<const mf::MultiFunction *>(&obj_AA_rot) :
&local_AA_rot;
}
if (type == FN_NODE_ROTATE_EULER_TYPE_EULER) {
return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ?
static_cast<const MultiFunction *>(&obj_euler_rot) :
static_cast<const mf::MultiFunction *>(&obj_euler_rot) :
&local_euler_rot;
}
BLI_assert_unreachable();
@@ -121,7 +121,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}

View File

@@ -37,18 +37,18 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
class SeparateRGBAFunction : public fn::MultiFunction {
class SeparateRGBAFunction : public mf::MultiFunction {
public:
SeparateRGBAFunction()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Separate Color", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Separate Color", signature};
builder.single_input<ColorGeometry4f>("Color");
builder.single_output<float>("Red");
builder.single_output<float>("Green");
@@ -57,7 +57,7 @@ class SeparateRGBAFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -99,18 +99,18 @@ class SeparateRGBAFunction : public fn::MultiFunction {
}
};
class SeparateHSVAFunction : public fn::MultiFunction {
class SeparateHSVAFunction : public mf::MultiFunction {
public:
SeparateHSVAFunction()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Separate Color", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Separate Color", signature};
builder.single_input<ColorGeometry4f>("Color");
builder.single_output<float>("Hue");
builder.single_output<float>("Saturation");
@@ -119,7 +119,7 @@ class SeparateHSVAFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -140,18 +140,18 @@ class SeparateHSVAFunction : public fn::MultiFunction {
}
};
class SeparateHSLAFunction : public fn::MultiFunction {
class SeparateHSLAFunction : public mf::MultiFunction {
public:
SeparateHSLAFunction()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Separate Color", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Separate Color", signature};
builder.single_input<ColorGeometry4f>("Color");
builder.single_output<float>("Hue");
builder.single_output<float>("Saturation");
@@ -160,7 +160,7 @@ class SeparateHSLAFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");

View File

@@ -16,7 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto slice_fn = fn::build_mf::SI3_SO<std::string, int, int, std::string>(
static auto slice_fn = mf::build::SI3_SO<std::string, int, int, std::string>(
"Slice", [](const std::string &str, int a, int b) {
const int len = BLI_strlen_utf8(str.c_str());
const int start = BLI_str_utf8_offset_from_index(str.c_str(), std::clamp(a, 0, len));

View File

@@ -16,7 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto str_len_fn = fn::build_mf::SI1_SO<std::string, int>(
static auto str_len_fn = mf::build::SI1_SO<std::string, int>(
"String Length", [](const std::string &a) { return BLI_strlen_utf8(a.c_str()); });
builder.set_matching_fn(&str_len_fn);
}

View File

@@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto to_str_fn = fn::build_mf::SI2_SO<float, int, std::string>(
static auto to_str_fn = mf::build::SI2_SO<float, int, std::string>(
"Value To String", [](float a, int b) {
std::stringstream stream;
stream << std::fixed << std::setprecision(std::max(0, b)) << a;

View File

@@ -201,7 +201,7 @@ static void sample_indices_and_factors_to_compressed(const Span<float> accumulat
* Given an array of accumulated lengths, find the segment indices that
* sample lengths lie on, and how far along the segment they are.
*/
class SampleFloatSegmentsFunction : public fn::MultiFunction {
class SampleFloatSegmentsFunction : public mf::MultiFunction {
private:
Array<float> accumulated_lengths_;
GeometryNodeCurveSampleMode length_mode_;
@@ -211,14 +211,14 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction {
const GeometryNodeCurveSampleMode length_mode)
: accumulated_lengths_(std::move(accumulated_lengths)), length_mode_(length_mode)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample Curve Index", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample Curve Index", signature};
builder.single_input<float>("Length");
builder.single_output<int>("Curve Index");
@@ -226,7 +226,7 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArraySpan<float> lengths = params.readonly_single_input<float>(0, "Length");
MutableSpan<int> indices = params.uninitialized_single_output<int>(1, "Curve Index");
@@ -238,7 +238,7 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction {
}
};
class SampleCurveFunction : public fn::MultiFunction {
class SampleCurveFunction : public mf::MultiFunction {
private:
/**
* The function holds a geometry set instead of curves or a curve component reference in order
@@ -249,7 +249,7 @@ class SampleCurveFunction : public fn::MultiFunction {
GField src_field_;
GeometryNodeCurveSampleMode length_mode_;
fn::MFSignature signature_;
mf::Signature signature_;
std::optional<bke::CurvesFieldContext> source_context_;
std::unique_ptr<FieldEvaluator> source_evaluator_;
@@ -266,10 +266,10 @@ class SampleCurveFunction : public fn::MultiFunction {
this->evaluate_source();
}
fn::MFSignature create_signature()
mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample Curve", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample Curve", signature};
builder.single_input<int>("Curve Index");
builder.single_input<float>("Length");
builder.single_output<float3>("Position");
@@ -279,7 +279,7 @@ class SampleCurveFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
MutableSpan<float3> sampled_positions = params.uninitialized_single_output_if_required<float3>(
2, "Position");

View File

@@ -1325,10 +1325,10 @@ static void node_geo_exec(GeoNodeExecParams params)
/* Create a combined field from the offset and the scale so the field evaluator
* can take care of the multiplication and to simplify each extrude function. */
static auto multiply_fn = fn::build_mf::SI2_SO<float3, float, float3>(
static auto multiply_fn = mf::build::SI2_SO<float3, float, float3>(
"Scale",
[](const float3 &offset, const float scale) { return offset * scale; },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
std::shared_ptr<FieldOperation> multiply_op = std::make_shared<FieldOperation>(
FieldOperation(multiply_fn, {std::move(offset_field), std::move(scale_field)}));
const Field<float3> final_offset{std::move(multiply_op)};

View File

@@ -45,7 +45,7 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = tex;
}
class ImageFieldsFunction : public fn::MultiFunction {
class ImageFieldsFunction : public mf::MultiFunction {
private:
const int8_t interpolation_;
const int8_t extension_;
@@ -64,7 +64,7 @@ class ImageFieldsFunction : public fn::MultiFunction {
image_(image),
image_user_(image_user)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
image_buffer_ = BKE_image_acquire_ibuf(&image_, &image_user_, &image_lock_);
@@ -91,10 +91,10 @@ class ImageFieldsFunction : public fn::MultiFunction {
BKE_image_release_ibuf(&image_, image_buffer_, image_lock_);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"ImageFunction", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"ImageFunction", signature};
builder.single_input<float3>("Vector");
builder.single_output<ColorGeometry4f>("Color");
builder.single_output<float>("Alpha");
@@ -319,7 +319,7 @@ class ImageFieldsFunction : public fn::MultiFunction {
}
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vectors = params.readonly_single_input<float3>(0, "Vector");
MutableSpan<ColorGeometry4f> r_color = params.uninitialized_single_output<ColorGeometry4f>(

View File

@@ -121,10 +121,10 @@ static void node_geo_exec(GeoNodeExecParams params)
/* Use another multi-function operation to make sure the input radius is greater than zero.
* TODO: Use mutable multi-function once that is supported. */
static auto max_zero_fn = fn::build_mf::SI1_SO<float, float>(
static auto max_zero_fn = mf::build::SI1_SO<float, float>(
__func__,
[](float value) { return std::max(0.0f, value); },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
auto max_zero_op = std::make_shared<FieldOperation>(
FieldOperation(max_zero_fn, {std::move(radius)}));
Field<float> positive_radius(std::move(max_zero_op), 0);

View File

@@ -129,7 +129,7 @@ static bool calculate_pointcloud_proximity(const VArray<float3> &positions,
return true;
}
class ProximityFunction : public fn::MultiFunction {
class ProximityFunction : public mf::MultiFunction {
private:
GeometrySet target_;
GeometryNodeProximityTargetType type_;
@@ -138,21 +138,21 @@ class ProximityFunction : public fn::MultiFunction {
ProximityFunction(GeometrySet target, GeometryNodeProximityTargetType type)
: target_(std::move(target)), type_(type)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Geometry Proximity", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Geometry Proximity", signature};
builder.single_input<float3>("Source Position");
builder.single_output<float3>("Position");
builder.single_output<float>("Distance");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &src_positions = params.readonly_single_input<float3>(0,
"Source Position");

View File

@@ -202,7 +202,7 @@ static void raycast_to_mesh(IndexMask mask,
}
}
class RaycastFunction : public fn::MultiFunction {
class RaycastFunction : public mf::MultiFunction {
private:
GeometrySet target_;
GeometryNodeRaycastMapMode mapping_;
@@ -217,7 +217,7 @@ class RaycastFunction : public fn::MultiFunction {
* the field inputs for better performance. */
const eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
fn::MFSignature signature_;
mf::Signature signature_;
public:
RaycastFunction(GeometrySet target, GField src_field, GeometryNodeRaycastMapMode mapping)
@@ -229,10 +229,10 @@ class RaycastFunction : public fn::MultiFunction {
this->set_signature(&signature_);
}
fn::MFSignature create_signature()
mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Geometry Proximity", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Geometry Proximity", signature};
builder.single_input<float3>("Source Position");
builder.single_input<float3>("Ray Direction");
builder.single_input<float>("Ray Length");
@@ -246,7 +246,7 @@ class RaycastFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
/* Hit positions are always necessary for retrieving the attribute from the target if that
* output is required, so always retrieve a span from the evaluator in that case (it's

View File

@@ -176,13 +176,13 @@ void copy_with_clamped_indices(const VArray<T> &src,
* instance geometry set in the source. A future optimization could be removing that limitation
* internally.
*/
class SampleIndexFunction : public fn::MultiFunction {
class SampleIndexFunction : public mf::MultiFunction {
GeometrySet src_geometry_;
GField src_field_;
eAttrDomain domain_;
bool clamp_;
fn::MFSignature signature_;
mf::Signature signature_;
std::optional<bke::GeometryFieldContext> geometry_context_;
std::unique_ptr<FieldEvaluator> evaluator_;
@@ -206,10 +206,10 @@ class SampleIndexFunction : public fn::MultiFunction {
this->evaluate_field();
}
fn::MFSignature create_signature()
mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample Index", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample Index", signature};
builder.single_input<int>("Index");
builder.single_output("Value", src_field_.cpp_type());
return signature;
@@ -229,7 +229,7 @@ class SampleIndexFunction : public fn::MultiFunction {
src_data_ = &evaluator_->get_evaluated(0);
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<int> &indices = params.readonly_single_input<int>(0, "Index");
GMutableSpan dst = params.uninitialized_single_output(1, "Value");

View File

@@ -232,13 +232,13 @@ static const GeometryComponent *find_source_component(const GeometrySet &geometr
return nullptr;
}
class SampleNearestFunction : public fn::MultiFunction {
class SampleNearestFunction : public mf::MultiFunction {
GeometrySet source_;
eAttrDomain domain_;
const GeometryComponent *src_component_;
fn::MFSignature signature_;
mf::Signature signature_;
public:
SampleNearestFunction(GeometrySet geometry, eAttrDomain domain)
@@ -251,16 +251,16 @@ class SampleNearestFunction : public fn::MultiFunction {
this->src_component_ = find_source_component(source_, domain_);
}
fn::MFSignature create_signature()
mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample Nearest", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample Nearest", signature};
builder.single_input<float3>("Position");
builder.single_output<int>("Index");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &positions = params.readonly_single_input<float3>(0, "Position");
MutableSpan<int> indices = params.uninitialized_single_output<int>(1, "Index");

View File

@@ -116,7 +116,7 @@ static void get_closest_mesh_looptris(const Mesh &mesh,
* function could be called many times, calculate the data from the source geometry once and store
* it for later.
*/
class SampleNearestSurfaceFunction : public fn::MultiFunction {
class SampleNearestSurfaceFunction : public mf::MultiFunction {
GeometrySet source_;
GField src_field_;
@@ -128,7 +128,7 @@ class SampleNearestSurfaceFunction : public fn::MultiFunction {
*/
eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
fn::MFSignature signature_;
mf::Signature signature_;
std::optional<bke::MeshFieldContext> source_context_;
std::unique_ptr<FieldEvaluator> source_evaluator_;
@@ -144,16 +144,16 @@ class SampleNearestSurfaceFunction : public fn::MultiFunction {
this->evaluate_source_field();
}
fn::MFSignature create_signature()
mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample Nearest Surface", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample Nearest Surface", signature};
builder.single_input<float3>("Position");
builder.single_output("Value", src_field_.cpp_type());
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &positions = params.readonly_single_input<float3>(0, "Position");
GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Value");

View File

@@ -105,7 +105,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
class SampleMeshBarycentricFunction : public fn::MultiFunction {
class SampleMeshBarycentricFunction : public mf::MultiFunction {
GeometrySet source_;
GField src_field_;
@@ -116,7 +116,7 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction {
*/
eAttrDomain domain_ = ATTR_DOMAIN_CORNER;
fn::MFSignature signature_;
mf::Signature signature_;
std::optional<bke::MeshFieldContext> source_context_;
std::unique_ptr<FieldEvaluator> source_evaluator_;
@@ -134,17 +134,17 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction {
this->evaluate_source();
}
fn::MFSignature create_signature()
mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample Barycentric Triangles", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample Barycentric Triangles", signature};
builder.single_input<int>("Triangle Index");
builder.single_input<float3>("Barycentric Weight");
builder.single_output("Value", src_field_.cpp_type());
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArraySpan<int> triangle_indices = params.readonly_single_input<int>(0,
"Triangle Index");
@@ -185,7 +185,7 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction {
}
};
class ReverseUVSampleFunction : public fn::MultiFunction {
class ReverseUVSampleFunction : public mf::MultiFunction {
GeometrySet source_;
Field<float2> src_uv_map_field_;
@@ -200,15 +200,15 @@ class ReverseUVSampleFunction : public fn::MultiFunction {
: source_(std::move(geometry)), src_uv_map_field_(std::move(src_uv_map_field))
{
source_.ensure_owns_direct_data();
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
this->evaluate_source();
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Sample UV Surface", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Sample UV Surface", signature};
builder.single_input<float2>("Sample UV");
builder.single_output<bool>("Is Valid");
builder.single_output<int>("Triangle Index");
@@ -216,7 +216,7 @@ class ReverseUVSampleFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArraySpan<float2> sample_uvs = params.readonly_single_input<float2>(0, "Sample UV");
MutableSpan<bool> is_valid = params.uninitialized_single_output_if_required<bool>(1,

View File

@@ -171,7 +171,7 @@ template<typename T> void switch_fields(GeoNodeExecParams &params, const StringR
Field<T> falses_field = params.extract_input<Field<T>>(name_false);
Field<T> trues_field = params.extract_input<Field<T>>(name_true);
static auto switch_fn = fn::build_mf::SI3_SO<bool, T, T, T>(
static auto switch_fn = mf::build::SI3_SO<bool, T, T, T>(
"Switch", [](bool condition, const T &false_value, const T &true_value) {
return condition ? true_value : false_value;
});

View File

@@ -37,7 +37,6 @@ namespace blender::nodes {
using fn::ValueOrField;
using fn::ValueOrFieldCPPType;
using namespace fn::multi_function_types;
static const CPPType *get_socket_cpp_type(const bNodeSocketType &typeinfo)
{
@@ -353,8 +352,8 @@ static void execute_multi_function_on_value_or_field(
}
else {
/* In this case, the multi-function is evaluated directly. */
MFParamsBuilder params{fn, 1};
MFContextBuilder context;
mf::ParamsBuilder params{fn, 1};
mf::ContextBuilder context;
for (const int i : input_types.index_range()) {
const ValueOrFieldCPPType &type = *input_types[i];
@@ -445,7 +444,7 @@ class LazyFunctionForMutedNode : public LazyFunction {
if (from_type != nullptr && to_type != nullptr) {
if (conversions.is_convertible(from_type->value, to_type->value)) {
const MultiFunction &multi_fn = *conversions.get_conversion_multi_function(
MFDataType::ForSingle(from_type->value), MFDataType::ForSingle(to_type->value));
mf::DataType::ForSingle(from_type->value), mf::DataType::ForSingle(to_type->value));
execute_multi_function_on_value_or_field(
multi_fn, {}, {from_type}, {to_type}, {input_value}, {output_value});
}
@@ -1676,8 +1675,8 @@ struct GeometryNodesLazyFunctionGraphBuilder {
if (from_field_type != nullptr && to_field_type != nullptr) {
if (conversions_->is_convertible(from_field_type->value, to_field_type->value)) {
const MultiFunction &multi_fn = *conversions_->get_conversion_multi_function(
MFDataType::ForSingle(from_field_type->value),
MFDataType::ForSingle(to_field_type->value));
mf::DataType::ForSingle(from_field_type->value),
mf::DataType::ForSingle(to_field_type->value));
auto fn = std::make_unique<LazyFunctionForMultiFunctionConversion>(
multi_fn, *from_field_type, *to_field_type);
lf::Node &conversion_node = lf_graph_->add_function(*fn);

View File

@@ -44,10 +44,10 @@ static int gpu_shader_clamp(GPUMaterial *mat,
static void sh_node_clamp_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto minmax_fn = fn::build_mf::SI3_SO<float, float, float, float>(
static auto minmax_fn = mf::build::SI3_SO<float, float, float, float>(
"Clamp (Min Max)",
[](float value, float min, float max) { return std::min(std::max(value, min), max); });
static auto range_fn = fn::build_mf::SI3_SO<float, float, float, float>(
static auto range_fn = mf::build::SI3_SO<float, float, float, float>(
"Clamp (Range)", [](float value, float a, float b) {
if (a < b) {
return clamp_f(value, a, b);

View File

@@ -87,28 +87,28 @@ static int gpu_shader_valtorgb(GPUMaterial *mat,
return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_constant(&layer));
}
class ColorBandFunction : public fn::MultiFunction {
class ColorBandFunction : public mf::MultiFunction {
private:
const ColorBand &color_band_;
public:
ColorBandFunction(const ColorBand &color_band) : color_band_(color_band)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Color Band", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Color Band", signature};
builder.single_input<float>("Value");
builder.single_output<ColorGeometry4f>("Color");
builder.single_output<float>("Alpha");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float> &values = params.readonly_single_input<float>(0, "Value");
MutableSpan<ColorGeometry4f> colors = params.uninitialized_single_output<ColorGeometry4f>(

View File

@@ -63,28 +63,28 @@ static int gpu_shader_curve_vec(GPUMaterial *mat,
GPU_uniform(end_slopes));
}
class CurveVecFunction : public fn::MultiFunction {
class CurveVecFunction : public mf::MultiFunction {
private:
const CurveMapping &cumap_;
public:
CurveVecFunction(const CurveMapping &cumap) : cumap_(cumap)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Curve Vec", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Curve Vec", signature};
builder.single_input<float>("Fac");
builder.single_input<float3>("Vector");
builder.single_output<float3>("Vector");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
const VArray<float3> &vec_in = params.readonly_single_input<float3>(1, "Vector");
@@ -209,28 +209,28 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
GPU_uniform(end_slopes));
}
class CurveRGBFunction : public fn::MultiFunction {
class CurveRGBFunction : public mf::MultiFunction {
private:
const CurveMapping &cumap_;
public:
CurveRGBFunction(const CurveMapping &cumap) : cumap_(cumap)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Curve RGB", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Curve RGB", signature};
builder.single_input<float>("Fac");
builder.single_input<ColorGeometry4f>("Color");
builder.single_output<ColorGeometry4f>("Color");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
const VArray<ColorGeometry4f> &col_in = params.readonly_single_input<ColorGeometry4f>(1,
@@ -332,28 +332,28 @@ static int gpu_shader_curve_float(GPUMaterial *mat,
GPU_uniform(end_slopes));
}
class CurveFloatFunction : public fn::MultiFunction {
class CurveFloatFunction : public mf::MultiFunction {
private:
const CurveMapping &cumap_;
public:
CurveFloatFunction(const CurveMapping &cumap) : cumap_(cumap)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Curve Float", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Curve Float", signature};
builder.single_input<float>("Factor");
builder.single_input<float>("Value");
builder.single_output<float>("Value");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Factor");
const VArray<float> &val_in = params.readonly_single_input<float>(1, "Value");

View File

@@ -233,7 +233,7 @@ static float3 clamp_range(const float3 value, const float3 min, const float3 max
template<bool Clamp> static auto build_float_linear()
{
return fn::build_mf::SI5_SO<float, float, float, float, float, float>(
return mf::build::SI5_SO<float, float, float, float, float, float>(
Clamp ? "Map Range (clamped)" : "Map Range (unclamped)",
[](float value, float from_min, float from_max, float to_min, float to_max) -> float {
const float factor = safe_divide(value - from_min, from_max - from_min);
@@ -243,12 +243,12 @@ template<bool Clamp> static auto build_float_linear()
}
return result;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
}
template<bool Clamp> static auto build_float_stepped()
{
return fn::build_mf::SI6_SO<float, float, float, float, float, float, float>(
return mf::build::SI6_SO<float, float, float, float, float, float, float>(
Clamp ? "Map Range Stepped (clamped)" : "Map Range Stepped (unclamped)",
[](float value, float from_min, float from_max, float to_min, float to_max, float steps)
-> float {
@@ -260,12 +260,12 @@ template<bool Clamp> static auto build_float_stepped()
}
return result;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
}
template<bool Clamp> static auto build_vector_linear()
{
return fn::build_mf::SI5_SO<float3, float3, float3, float3, float3, float3>(
return mf::build::SI5_SO<float3, float3, float3, float3, float3, float3>(
Clamp ? "Vector Map Range (clamped)" : "Vector Map Range (unclamped)",
[](const float3 &value,
const float3 &from_min,
@@ -279,12 +279,12 @@ template<bool Clamp> static auto build_vector_linear()
}
return result;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
}
template<bool Clamp> static auto build_vector_stepped()
{
return fn::build_mf::SI6_SO<float3, float3, float3, float3, float3, float3, float3>(
return mf::build::SI6_SO<float3, float3, float3, float3, float3, float3, float3>(
Clamp ? "Vector Map Range Stepped (clamped)" : "Vector Map Range Stepped (unclamped)",
[](const float3 &value,
const float3 &from_min,
@@ -300,7 +300,7 @@ template<bool Clamp> static auto build_vector_stepped()
}
return result;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
}
static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &builder)
@@ -335,7 +335,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
break;
}
case NODE_MAP_RANGE_SMOOTHSTEP: {
static auto fn = fn::build_mf::SI5_SO<float3, float3, float3, float3, float3, float3>(
static auto fn = mf::build::SI5_SO<float3, float3, float3, float3, float3, float3>(
"Vector Map Range Smoothstep",
[](const float3 &value,
const float3 &from_min,
@@ -347,12 +347,12 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
factor = (float3(3.0f) - 2.0f * factor) * (factor * factor);
return factor * (to_max - to_min) + to_min;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
builder.set_matching_fn(fn);
break;
}
case NODE_MAP_RANGE_SMOOTHERSTEP: {
static auto fn = fn::build_mf::SI5_SO<float3, float3, float3, float3, float3, float3>(
static auto fn = mf::build::SI5_SO<float3, float3, float3, float3, float3, float3>(
"Vector Map Range Smootherstep",
[](const float3 &value,
const float3 &from_min,
@@ -364,7 +364,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
return factor * (to_max - to_min) + to_min;
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
builder.set_matching_fn(fn);
break;
}
@@ -397,7 +397,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
break;
}
case NODE_MAP_RANGE_SMOOTHSTEP: {
static auto fn = fn::build_mf::SI5_SO<float, float, float, float, float, float>(
static auto fn = mf::build::SI5_SO<float, float, float, float, float, float>(
"Map Range Smoothstep",
[](float value, float from_min, float from_max, float to_min, float to_max)
-> float {
@@ -406,12 +406,12 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
factor = (3.0f - 2.0f * factor) * (factor * factor);
return to_min + factor * (to_max - to_min);
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
builder.set_matching_fn(fn);
break;
}
case NODE_MAP_RANGE_SMOOTHERSTEP: {
static auto fn = fn::build_mf::SI5_SO<float, float, float, float, float, float>(
static auto fn = mf::build::SI5_SO<float, float, float, float, float, float>(
"Map Range Smoothstep",
[](float value, float from_min, float from_max, float to_min, float to_max)
-> float {
@@ -420,7 +420,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui
factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
return to_min + factor * (to_max - to_min);
},
fn::build_mf::exec_presets::SomeSpanOrSingle<0>());
mf::build::exec_presets::SomeSpanOrSingle<0>());
builder.set_matching_fn(fn);
break;
}

View File

@@ -102,14 +102,14 @@ static int gpu_shader_math(GPUMaterial *mat,
return 0;
}
static const fn::MultiFunction *get_base_multi_function(const bNode &node)
static const mf::MultiFunction *get_base_multi_function(const bNode &node)
{
const int mode = node.custom1;
const fn::MultiFunction *base_fn = nullptr;
const mf::MultiFunction *base_fn = nullptr;
try_dispatch_float_math_fl_to_fl(
mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI1_SO<float, float>(
static auto fn = mf::build::SI1_SO<float, float>(
info.title_case_name.c_str(), function, devi_fn);
base_fn = &fn;
});
@@ -119,7 +119,7 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node)
try_dispatch_float_math_fl_fl_to_fl(
mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI2_SO<float, float, float>(
static auto fn = mf::build::SI2_SO<float, float, float>(
info.title_case_name.c_str(), function, devi_fn);
base_fn = &fn;
});
@@ -129,7 +129,7 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node)
try_dispatch_float_math_fl_fl_fl_to_fl(
mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI3_SO<float, float, float, float>(
static auto fn = mf::build::SI3_SO<float, float, float, float>(
info.title_case_name.c_str(), function, devi_fn);
base_fn = &fn;
});
@@ -140,17 +140,17 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node)
return nullptr;
}
class ClampWrapperFunction : public fn::MultiFunction {
class ClampWrapperFunction : public mf::MultiFunction {
private:
const fn::MultiFunction &fn_;
const mf::MultiFunction &fn_;
public:
ClampWrapperFunction(const fn::MultiFunction &fn) : fn_(fn)
ClampWrapperFunction(const mf::MultiFunction &fn) : fn_(fn)
{
this->set_signature(&fn.signature());
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext context) const override
void call(IndexMask mask, mf::MFParams params, mf::Context context) const override
{
fn_.call(mask, params, context);
@@ -168,7 +168,7 @@ class ClampWrapperFunction : public fn::MultiFunction {
static void sh_node_math_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *base_function = get_base_multi_function(builder.node());
const mf::MultiFunction *base_function = get_base_multi_function(builder.node());
const bool clamp_output = builder.node().custom2 != 0;
if (clamp_output) {

View File

@@ -351,7 +351,7 @@ static int gpu_shader_mix(GPUMaterial *mat,
return ret;
}
class MixColorFunction : public fn::MultiFunction {
class MixColorFunction : public mf::MultiFunction {
private:
const bool clamp_factor_;
const bool clamp_result_;
@@ -361,14 +361,14 @@ class MixColorFunction : public fn::MultiFunction {
MixColorFunction(const bool clamp_factor, const bool clamp_result, const int blend_type)
: clamp_factor_(clamp_factor), clamp_result_(clamp_result), blend_type_(blend_type)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"MixColor", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"MixColor", signature};
builder.single_input<float>("Factor");
builder.single_input<ColorGeometry4f>("A");
builder.single_input<ColorGeometry4f>("B");
@@ -376,7 +376,7 @@ class MixColorFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Factor");
const VArray<ColorGeometry4f> &col1 = params.readonly_single_input<ColorGeometry4f>(1, "A");
@@ -405,7 +405,7 @@ class MixColorFunction : public fn::MultiFunction {
}
};
static const fn::MultiFunction *get_multi_function(const bNode &node)
static const mf::MultiFunction *get_multi_function(const bNode &node)
{
const NodeShaderMix *data = (NodeShaderMix *)node.storage;
bool uniform_factor = data->factor_mode == NODE_MIX_MODE_UNIFORM;
@@ -413,14 +413,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
switch (data->data_type) {
case SOCK_FLOAT: {
if (clamp_factor) {
static auto fn = fn::build_mf::SI3_SO<float, float, float, float>(
static auto fn = mf::build::SI3_SO<float, float, float, float>(
"Clamp Mix Float", [](float t, const float a, const float b) {
return math::interpolate(a, b, std::clamp(t, 0.0f, 1.0f));
});
return &fn;
}
else {
static auto fn = fn::build_mf::SI3_SO<float, float, float, float>(
static auto fn = mf::build::SI3_SO<float, float, float, float>(
"Mix Float", [](const float t, const float a, const float b) {
return math::interpolate(a, b, t);
});
@@ -430,14 +430,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case SOCK_VECTOR: {
if (clamp_factor) {
if (uniform_factor) {
static auto fn = fn::build_mf::SI3_SO<float, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float, float3, float3, float3>(
"Clamp Mix Vector", [](const float t, const float3 a, const float3 b) {
return math::interpolate(a, b, std::clamp(t, 0.0f, 1.0f));
});
return &fn;
}
else {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
"Clamp Mix Vector Non Uniform", [](float3 t, const float3 a, const float3 b) {
t = math::clamp(t, 0.0f, 1.0f);
return a * (float3(1.0f) - t) + b * t;
@@ -447,14 +447,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
}
else {
if (uniform_factor) {
static auto fn = fn::build_mf::SI3_SO<float, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float, float3, float3, float3>(
"Mix Vector", [](const float t, const float3 a, const float3 b) {
return math::interpolate(a, b, t);
});
return &fn;
}
else {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
"Mix Vector Non Uniform", [](const float3 t, const float3 a, const float3 b) {
return a * (float3(1.0f) - t) + b * t;
});
@@ -476,7 +476,7 @@ static void sh_node_mix_build_multi_function(NodeMultiFunctionBuilder &builder)
storage.clamp_factor, storage.clamp_result, storage.blend_type);
}
else {
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}
}

View File

@@ -91,7 +91,7 @@ static int gpu_shader_mix_rgb(GPUMaterial *mat,
return ret;
}
class MixRGBFunction : public fn::MultiFunction {
class MixRGBFunction : public mf::MultiFunction {
private:
bool clamp_;
int type_;
@@ -99,14 +99,14 @@ class MixRGBFunction : public fn::MultiFunction {
public:
MixRGBFunction(bool clamp, int type) : clamp_(clamp), type_(type)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"MixRGB", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"MixRGB", signature};
builder.single_input<float>("Fac");
builder.single_input<ColorGeometry4f>("Color1");
builder.single_input<ColorGeometry4f>("Color2");
@@ -114,7 +114,7 @@ class MixRGBFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float> &fac = params.readonly_single_input<float>(0, "Fac");
const VArray<ColorGeometry4f> &col1 = params.readonly_single_input<ColorGeometry4f>(1,

View File

@@ -27,18 +27,18 @@ static int gpu_shader_seprgb(GPUMaterial *mat,
return GPU_stack_link(mat, node, "separate_rgb", in, out);
}
class SeparateRGBFunction : public fn::MultiFunction {
class SeparateRGBFunction : public mf::MultiFunction {
public:
SeparateRGBFunction()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Separate RGB", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Separate RGB", signature};
builder.single_input<ColorGeometry4f>("Color");
builder.single_output<float>("R");
builder.single_output<float>("G");
@@ -46,7 +46,7 @@ class SeparateRGBFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
@@ -109,7 +109,7 @@ static int gpu_shader_combrgb(GPUMaterial *mat,
static void sh_node_combrgb_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto fn = fn::build_mf::SI3_SO<float, float, float, ColorGeometry4f>(
static auto fn = mf::build::SI3_SO<float, float, float, ColorGeometry4f>(
"Combine RGB", [](float r, float g, float b) { return ColorGeometry4f(r, g, b, 1.0f); });
builder.set_matching_fn(fn);
}

View File

@@ -27,18 +27,18 @@ static int gpu_shader_sepxyz(GPUMaterial *mat,
return GPU_stack_link(mat, node, "separate_xyz", in, out);
}
class MF_SeparateXYZ : public fn::MultiFunction {
class MF_SeparateXYZ : public mf::MultiFunction {
public:
MF_SeparateXYZ()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Separate XYZ", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Separate XYZ", signature};
builder.single_input<float3>("XYZ");
builder.single_output<float>("X");
builder.single_output<float>("Y");
@@ -46,7 +46,7 @@ class MF_SeparateXYZ : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vectors = params.readonly_single_input<float3>(0, "XYZ");
MutableSpan<float> xs = params.uninitialized_single_output_if_required<float>(1, "X");
@@ -126,10 +126,10 @@ static int gpu_shader_combxyz(GPUMaterial *mat,
static void sh_node_combxyz_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto fn = fn::build_mf::SI3_SO<float, float, float, float3>(
static auto fn = mf::build::SI3_SO<float, float, float, float3>(
"Combine Vector",
[](float x, float y, float z) { return float3(x, y, z); },
fn::build_mf::exec_presets::AllSpanOrSingle());
mf::build::exec_presets::AllSpanOrSingle());
builder.set_matching_fn(fn);
}

View File

@@ -108,7 +108,7 @@ static int node_shader_gpu_tex_brick(GPUMaterial *mat,
GPU_constant(&squash_freq));
}
class BrickFunction : public fn::MultiFunction {
class BrickFunction : public mf::MultiFunction {
private:
const float offset_;
const int offset_freq_;
@@ -122,14 +122,14 @@ class BrickFunction : public fn::MultiFunction {
const int squash_freq)
: offset_(offset), offset_freq_(offset_freq), squash_(squash), squash_freq_(squash_freq)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"BrickTexture", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"BrickTexture", signature};
builder.single_input<float3>("Vector");
builder.single_input<ColorGeometry4f>("Color1");
builder.single_input<ColorGeometry4f>("Color2");
@@ -204,7 +204,7 @@ class BrickFunction : public fn::MultiFunction {
return float2(tint, mortar);
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<ColorGeometry4f> &color1_values = params.readonly_single_input<ColorGeometry4f>(

View File

@@ -44,18 +44,18 @@ static int node_shader_gpu_tex_checker(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_tex_checker", in, out);
}
class NodeTexChecker : public fn::MultiFunction {
class NodeTexChecker : public mf::MultiFunction {
public:
NodeTexChecker()
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Checker", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Checker", signature};
builder.single_input<float3>("Vector");
builder.single_input<ColorGeometry4f>("Color1");
builder.single_input<ColorGeometry4f>("Color2");
@@ -65,7 +65,7 @@ class NodeTexChecker : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<ColorGeometry4f> &color1 = params.readonly_single_input<ColorGeometry4f>(

View File

@@ -47,28 +47,28 @@ static int node_shader_gpu_tex_gradient(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_tex_gradient", in, out, GPU_constant(&gradient_type));
}
class GradientFunction : public fn::MultiFunction {
class GradientFunction : public mf::MultiFunction {
private:
int gradient_type_;
public:
GradientFunction(int gradient_type) : gradient_type_(gradient_type)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"GradientFunction", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"GradientFunction", signature};
builder.single_input<float3>("Vector");
builder.single_output<ColorGeometry4f>("Color");
builder.single_output<float>("Fac");
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");

View File

@@ -48,21 +48,21 @@ static int node_shader_gpu_tex_magic(GPUMaterial *mat,
return GPU_stack_link(mat, node, "node_tex_magic", in, out, GPU_constant(&depth));
}
class MagicFunction : public fn::MultiFunction {
class MagicFunction : public mf::MultiFunction {
private:
int depth_;
public:
MagicFunction(int depth) : depth_(depth)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"MagicFunction", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"MagicFunction", signature};
builder.single_input<float3>("Vector");
builder.single_input<float>("Scale");
builder.single_input<float>("Distortion");
@@ -71,7 +71,7 @@ class MagicFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");

View File

@@ -125,7 +125,7 @@ static void node_shader_update_tex_musgrave(bNodeTree *ntree, bNode *node)
node_sock_label(outFacSock, "Height");
}
class MusgraveFunction : public fn::MultiFunction {
class MusgraveFunction : public mf::MultiFunction {
private:
const int dimensions_;
const int musgrave_type_;
@@ -136,7 +136,7 @@ class MusgraveFunction : public fn::MultiFunction {
{
BLI_assert(dimensions >= 1 && dimensions <= 4);
BLI_assert(musgrave_type >= 0 && musgrave_type <= 4);
static std::array<fn::MFSignature, 20> signatures{
static std::array<mf::Signature, 20> signatures{
create_signature(1, SHD_MUSGRAVE_MULTIFRACTAL),
create_signature(2, SHD_MUSGRAVE_MULTIFRACTAL),
create_signature(3, SHD_MUSGRAVE_MULTIFRACTAL),
@@ -165,10 +165,10 @@ class MusgraveFunction : public fn::MultiFunction {
this->set_signature(&signatures[dimensions + musgrave_type * 4 - 1]);
}
static fn::MFSignature create_signature(const int dimensions, const int musgrave_type)
static mf::Signature create_signature(const int dimensions, const int musgrave_type)
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Musgrave", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Musgrave", signature};
if (ELEM(dimensions, 2, 3, 4)) {
builder.single_input<float3>("Vector");
@@ -195,7 +195,7 @@ class MusgraveFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");

View File

@@ -81,7 +81,7 @@ static void node_shader_update_tex_noise(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, sockW, storage.dimensions == 1 || storage.dimensions == 4);
}
class NoiseFunction : public fn::MultiFunction {
class NoiseFunction : public mf::MultiFunction {
private:
int dimensions_;
@@ -89,7 +89,7 @@ class NoiseFunction : public fn::MultiFunction {
NoiseFunction(int dimensions) : dimensions_(dimensions)
{
BLI_assert(dimensions >= 1 && dimensions <= 4);
static std::array<fn::MFSignature, 4> signatures{
static std::array<mf::Signature, 4> signatures{
create_signature(1),
create_signature(2),
create_signature(3),
@@ -98,10 +98,10 @@ class NoiseFunction : public fn::MultiFunction {
this->set_signature(&signatures[dimensions - 1]);
}
static fn::MFSignature create_signature(int dimensions)
static mf::Signature create_signature(int dimensions)
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"Noise", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"Noise", signature};
if (ELEM(dimensions, 2, 3, 4)) {
builder.single_input<float3>("Vector");
@@ -121,7 +121,7 @@ class NoiseFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);
const VArray<float> &scale = params.readonly_single_input<float>(param++, "Scale");

View File

@@ -179,9 +179,9 @@ static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, outRadiusSock, storage.feature == SHD_VORONOI_N_SPHERE_RADIUS);
}
static MultiFunction::ExecutionHints voronoi_execution_hints{50, false};
static mf::MultiFunction::ExecutionHints voronoi_execution_hints{50, false};
class VoronoiMinowskiFunction : public fn::MultiFunction {
class VoronoiMinowskiFunction : public mf::MultiFunction {
private:
int dimensions_;
int feature_;
@@ -191,7 +191,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction {
{
BLI_assert(dimensions >= 2 && dimensions <= 4);
BLI_assert(feature >= 0 && feature <= 2);
static std::array<fn::MFSignature, 9> signatures{
static std::array<mf::Signature, 9> signatures{
create_signature(2, SHD_VORONOI_F1),
create_signature(3, SHD_VORONOI_F1),
create_signature(4, SHD_VORONOI_F1),
@@ -207,10 +207,10 @@ class VoronoiMinowskiFunction : public fn::MultiFunction {
this->set_signature(&signatures[(dimensions - 1) + feature * 3 - 1]);
}
static fn::MFSignature create_signature(int dimensions, int feature)
static mf::Signature create_signature(int dimensions, int feature)
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"voronoi_minowski", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"voronoi_minowski", signature};
if (ELEM(dimensions, 2, 3, 4)) {
builder.single_input<float3>("Vector");
@@ -237,7 +237,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");
@@ -614,7 +614,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction {
}
};
class VoronoiMetricFunction : public fn::MultiFunction {
class VoronoiMetricFunction : public mf::MultiFunction {
private:
int dimensions_;
int feature_;
@@ -626,7 +626,7 @@ class VoronoiMetricFunction : public fn::MultiFunction {
{
BLI_assert(dimensions >= 1 && dimensions <= 4);
BLI_assert(feature >= 0 && feature <= 4);
static std::array<fn::MFSignature, 12> signatures{
static std::array<mf::Signature, 12> signatures{
create_signature(1, SHD_VORONOI_F1),
create_signature(2, SHD_VORONOI_F1),
create_signature(3, SHD_VORONOI_F1),
@@ -645,10 +645,10 @@ class VoronoiMetricFunction : public fn::MultiFunction {
this->set_signature(&signatures[dimensions + feature * 4 - 1]);
}
static fn::MFSignature create_signature(int dimensions, int feature)
static mf::Signature create_signature(int dimensions, int feature)
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"voronoi_metric", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"voronoi_metric", signature};
if (ELEM(dimensions, 2, 3, 4)) {
builder.single_input<float3>("Vector");
@@ -674,7 +674,7 @@ class VoronoiMetricFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");
@@ -1134,7 +1134,7 @@ class VoronoiMetricFunction : public fn::MultiFunction {
}
};
class VoronoiEdgeFunction : public fn::MultiFunction {
class VoronoiEdgeFunction : public mf::MultiFunction {
private:
int dimensions_;
int feature_;
@@ -1144,7 +1144,7 @@ class VoronoiEdgeFunction : public fn::MultiFunction {
{
BLI_assert(dimensions >= 1 && dimensions <= 4);
BLI_assert(feature >= 3 && feature <= 4);
static std::array<fn::MFSignature, 8> signatures{
static std::array<mf::Signature, 8> signatures{
create_signature(1, SHD_VORONOI_DISTANCE_TO_EDGE),
create_signature(2, SHD_VORONOI_DISTANCE_TO_EDGE),
create_signature(3, SHD_VORONOI_DISTANCE_TO_EDGE),
@@ -1158,10 +1158,10 @@ class VoronoiEdgeFunction : public fn::MultiFunction {
this->set_signature(&signatures[dimensions + (feature - 3) * 4 - 1]);
}
static fn::MFSignature create_signature(int dimensions, int feature)
static mf::Signature create_signature(int dimensions, int feature)
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"voronoi_edge", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"voronoi_edge", signature};
if (ELEM(dimensions, 2, 3, 4)) {
builder.single_input<float3>("Vector");
@@ -1182,7 +1182,7 @@ class VoronoiEdgeFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
auto get_vector = [&](int param_index) -> VArray<float3> {
return params.readonly_single_input<float3>(param_index, "Vector");

View File

@@ -80,7 +80,7 @@ static int node_shader_gpu_tex_wave(GPUMaterial *mat,
GPU_constant(&wave_profile));
}
class WaveFunction : public fn::MultiFunction {
class WaveFunction : public mf::MultiFunction {
private:
int wave_type_;
int bands_direction_;
@@ -94,14 +94,14 @@ class WaveFunction : public fn::MultiFunction {
rings_direction_(rings_direction),
wave_profile_(wave_profile)
{
static fn::MFSignature signature = create_signature();
static mf::Signature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
static mf::Signature create_signature()
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"MagicFunction", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"MagicFunction", signature};
builder.single_input<float3>("Vector");
builder.single_input<float>("Scale");
builder.single_input<float>("Distortion");
@@ -114,7 +114,7 @@ class WaveFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
const VArray<float3> &vector = params.readonly_single_input<float3>(0, "Vector");
const VArray<float> &scale = params.readonly_single_input<float>(1, "Scale");

View File

@@ -63,7 +63,7 @@ static void node_shader_update_tex_white_noise(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, sockW, node->custom1 == 1 || node->custom1 == 4);
}
class WhiteNoiseFunction : public fn::MultiFunction {
class WhiteNoiseFunction : public mf::MultiFunction {
private:
int dimensions_;
@@ -71,7 +71,7 @@ class WhiteNoiseFunction : public fn::MultiFunction {
WhiteNoiseFunction(int dimensions) : dimensions_(dimensions)
{
BLI_assert(dimensions >= 1 && dimensions <= 4);
static std::array<fn::MFSignature, 4> signatures{
static std::array<mf::Signature, 4> signatures{
create_signature(1),
create_signature(2),
create_signature(3),
@@ -80,10 +80,10 @@ class WhiteNoiseFunction : public fn::MultiFunction {
this->set_signature(&signatures[dimensions - 1]);
}
static fn::MFSignature create_signature(int dimensions)
static mf::Signature create_signature(int dimensions)
{
fn::MFSignature signature;
fn::MFSignatureBuilder builder{"WhiteNoise", signature};
mf::Signature signature;
mf::SignatureBuilder builder{"WhiteNoise", signature};
if (ELEM(dimensions, 2, 3, 4)) {
builder.single_input<float3>("Vector");
@@ -98,7 +98,7 @@ class WhiteNoiseFunction : public fn::MultiFunction {
return signature;
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override
{
int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);

View File

@@ -29,7 +29,7 @@ static void sh_node_value_build_multi_function(NodeMultiFunctionBuilder &builder
{
const bNodeSocket *bsocket = (bNodeSocket *)builder.node().outputs.first;
const bNodeSocketValueFloat *value = (const bNodeSocketValueFloat *)bsocket->default_value;
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<float>>(value->value);
builder.construct_and_set_matching_fn<mf::CustomMF_Constant<float>>(value->value);
}
} // namespace blender::nodes::node_shader_value_cc

View File

@@ -225,15 +225,15 @@ static void node_shader_update_vector_math(bNodeTree *ntree, bNode *node)
}
}
static const fn::MultiFunction *get_multi_function(const bNode &node)
static const mf::MultiFunction *get_multi_function(const bNode &node)
{
NodeVectorMathOperation operation = NodeVectorMathOperation(node.custom1);
const fn::MultiFunction *multi_fn = nullptr;
const mf::MultiFunction *multi_fn = nullptr;
try_dispatch_float_math_fl3_fl3_to_fl3(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI2_SO<float3, float3, float3>(
static auto fn = mf::build::SI2_SO<float3, float3, float3>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -243,7 +243,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
try_dispatch_float_math_fl3_fl3_fl3_to_fl3(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -253,7 +253,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
try_dispatch_float_math_fl3_fl3_fl_to_fl3(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -263,7 +263,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
try_dispatch_float_math_fl3_fl3_to_fl(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI2_SO<float3, float3, float>(
static auto fn = mf::build::SI2_SO<float3, float3, float>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -273,7 +273,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
try_dispatch_float_math_fl3_fl_to_fl3(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI2_SO<float3, float, float3>(
static auto fn = mf::build::SI2_SO<float3, float, float3>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -283,7 +283,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
try_dispatch_float_math_fl3_to_fl3(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI1_SO<float3, float3>(
static auto fn = mf::build::SI1_SO<float3, float3>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -293,7 +293,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
try_dispatch_float_math_fl3_to_fl(
operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) {
static auto fn = fn::build_mf::SI1_SO<float3, float>(
static auto fn = mf::build::SI1_SO<float3, float>(
info.title_case_name.c_str(), function, exec_preset);
multi_fn = &fn;
});
@@ -306,7 +306,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
static void sh_node_vector_math_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}

View File

@@ -96,7 +96,7 @@ static float3 sh_node_vector_rotate_euler(const float3 &vector,
return result + center;
}
static const fn::MultiFunction *get_multi_function(const bNode &node)
static const mf::MultiFunction *get_multi_function(const bNode &node)
{
bool invert = node.custom2;
const int mode = node.custom1;
@@ -104,14 +104,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
switch (mode) {
case NODE_VECTOR_ROTATE_TYPE_AXIS: {
if (invert) {
static auto fn = fn::build_mf::SI4_SO<float3, float3, float3, float, float3>(
static auto fn = mf::build::SI4_SO<float3, float3, float3, float, float3>(
"Rotate Axis",
[](const float3 &in, const float3 &center, const float3 &axis, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
});
return &fn;
}
static auto fn = fn::build_mf::SI4_SO<float3, float3, float3, float, float3>(
static auto fn = mf::build::SI4_SO<float3, float3, float3, float, float3>(
"Rotate Axis",
[](const float3 &in, const float3 &center, const float3 &axis, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, angle);
@@ -121,13 +121,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_VECTOR_ROTATE_TYPE_AXIS_X: {
float3 axis = float3(1.0f, 0.0f, 0.0f);
if (invert) {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate X-Axis", [=](const float3 &in, const float3 &center, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
});
return &fn;
}
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate X-Axis", [=](const float3 &in, const float3 &center, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, angle);
});
@@ -136,13 +136,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: {
float3 axis = float3(0.0f, 1.0f, 0.0f);
if (invert) {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate Y-Axis", [=](const float3 &in, const float3 &center, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
});
return &fn;
}
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate Y-Axis", [=](const float3 &in, const float3 &center, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, angle);
});
@@ -151,13 +151,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: {
float3 axis = float3(0.0f, 0.0f, 1.0f);
if (invert) {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate Z-Axis", [=](const float3 &in, const float3 &center, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
});
return &fn;
}
static auto fn = fn::build_mf::SI3_SO<float3, float3, float, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float, float3>(
"Rotate Z-Axis", [=](const float3 &in, const float3 &center, float angle) {
return sh_node_vector_rotate_around_axis(in, center, axis, angle);
});
@@ -165,13 +165,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
}
case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: {
if (invert) {
static auto fn = fn::build_mf::SI3_SO<float3, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
"Rotate Euler", [](const float3 &in, const float3 &center, const float3 &rotation) {
return sh_node_vector_rotate_euler(in, center, rotation, true);
});
return &fn;
}
static auto fn = fn::build_mf::SI3_SO<float3, float3, float3, float3>(
static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
"Rotate Euler", [](const float3 &in, const float3 &center, const float3 &rotation) {
return sh_node_vector_rotate_euler(in, center, rotation, false);
});
@@ -185,7 +185,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node)
static void sh_node_vector_rotate_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
const mf::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}