diff options
Diffstat (limited to 'source/blender/functions')
8 files changed, 55 insertions, 8 deletions
diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh index 17976c8acb0..7ec60809194 100644 --- a/source/blender/functions/FN_cpp_type.hh +++ b/source/blender/functions/FN_cpp_type.hh @@ -70,10 +70,11 @@ #include "BLI_index_mask.hh" #include "BLI_math_base.h" #include "BLI_string_ref.hh" +#include "BLI_utility_mixins.hh" namespace blender::fn { -class CPPType { +class CPPType : NonCopyable, NonMovable { public: using ConstructDefaultF = void (*)(void *ptr); using ConstructDefaultNF = void (*)(void *ptr, uint n); diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index c53959203cb..35f144368ac 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -73,6 +73,11 @@ class MultiFunction { return false; } + uint param_amount() const + { + return signature_.param_types.size(); + } + IndexRange param_indices() const { return signature_.param_types.index_range(); diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 5905d1cc315..6e7efb21850 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -203,6 +203,30 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction { }; /** + * Generates a multi-function that converts between two types. + */ +template<typename From, typename To> class CustomMF_Convert : public MultiFunction { + public: + CustomMF_Convert() + { + std::string name = CPPType::get<From>().name() + " to " + CPPType::get<To>().name(); + MFSignatureBuilder signature = this->get_builder(std::move(name)); + signature.single_input<From>("Input"); + signature.single_output<To>("Output"); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan<From> inputs = params.readonly_single_input<From>(0); + MutableSpan<To> outputs = params.uninitialized_single_output<To>(1); + + for (uint i : mask) { + new ((void *)&outputs[i]) To(inputs[i]); + } + } +}; + +/** * A multi-function that outputs the same value every time. The value is not owned by an instance * of this function. The caller is responsible for destructing and freeing the value. */ diff --git a/source/blender/functions/FN_multi_function_param_type.hh b/source/blender/functions/FN_multi_function_param_type.hh index 0e43e355b53..7c16b8cdf10 100644 --- a/source/blender/functions/FN_multi_function_param_type.hh +++ b/source/blender/functions/FN_multi_function_param_type.hh @@ -144,6 +144,11 @@ class MFParamType { return ELEM(interface_type_, Output, Mutable); } + bool is_output() const + { + return interface_type_ == Output; + } + friend bool operator==(const MFParamType &a, const MFParamType &b); friend bool operator!=(const MFParamType &a, const MFParamType &b); }; diff --git a/source/blender/functions/FN_spans.hh b/source/blender/functions/FN_spans.hh index b2622eab95f..c8c98d66628 100644 --- a/source/blender/functions/FN_spans.hh +++ b/source/blender/functions/FN_spans.hh @@ -339,6 +339,16 @@ class GVSpan : public VSpanBase<void> { return ref; } + static GVSpan FromSingleWithMaxSize(const CPPType &type, const void *value) + { + return GVSpan::FromSingle(type, value, UINT32_MAX); + } + + static GVSpan FromDefault(const CPPType &type) + { + return GVSpan::FromSingleWithMaxSize(type, type.default_value()); + } + static GVSpan FromFullPointerArray(const CPPType &type, const void *const *values, uint size) { GVSpan ref; diff --git a/source/blender/functions/intern/multi_function_network.cc b/source/blender/functions/intern/multi_function_network.cc index 47e3bf4d0b5..11c9c065f51 100644 --- a/source/blender/functions/intern/multi_function_network.cc +++ b/source/blender/functions/intern/multi_function_network.cc @@ -197,6 +197,7 @@ MFInputSocket &MFNetwork::add_output(StringRef name, MFDataType data_type) void MFNetwork::relink(MFOutputSocket &old_output, MFOutputSocket &new_output) { BLI_assert(&old_output != &new_output); + BLI_assert(old_output.data_type_ == new_output.data_type_); for (MFInputSocket *input : old_output.targets()) { input->origin_ = &new_output; } diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc index b4dce040da6..b59cbc6a1a2 100644 --- a/source/blender/functions/intern/multi_function_network_evaluation.cc +++ b/source/blender/functions/intern/multi_function_network_evaluation.cc @@ -106,30 +106,30 @@ MFNetworkEvaluator::MFNetworkEvaluator(Vector<const MFOutputSocket *> inputs, BLI_assert(outputs_.size() > 0); MFSignatureBuilder signature = this->get_builder("Function Tree"); - for (auto socket : inputs_) { + for (const MFOutputSocket *socket : inputs_) { BLI_assert(socket->node().is_dummy()); MFDataType type = socket->data_type(); switch (type.category()) { case MFDataType::Single: - signature.single_input("Input", type.single_type()); + signature.single_input(socket->name(), type.single_type()); break; case MFDataType::Vector: - signature.vector_input("Input", type.vector_base_type()); + signature.vector_input(socket->name(), type.vector_base_type()); break; } } - for (auto socket : outputs_) { + for (const MFInputSocket *socket : outputs_) { BLI_assert(socket->node().is_dummy()); MFDataType type = socket->data_type(); switch (type.category()) { case MFDataType::Single: - signature.single_output("Output", type.single_type()); + signature.single_output(socket->name(), type.single_type()); break; case MFDataType::Vector: - signature.vector_output("Output", type.vector_base_type()); + signature.vector_output(socket->name(), type.vector_base_type()); break; } } diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc index 4fe0b506df8..849b24a318f 100644 --- a/source/blender/functions/intern/multi_function_network_optimization.cc +++ b/source/blender/functions/intern/multi_function_network_optimization.cc @@ -454,8 +454,9 @@ static void relink_duplicate_nodes(MFNetwork &network, } Vector<MFNode *, 16> nodes_to_check = nodes_with_same_hash; - Vector<MFNode *, 16> remaining_nodes; while (nodes_to_check.size() >= 2) { + Vector<MFNode *, 16> remaining_nodes; + MFNode &deduplicated_node = *nodes_to_check[0]; for (MFNode *node : nodes_to_check.as_span().drop_front(1)) { /* This is true with fairly high probability, but hash collisions can happen. So we have to |