diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-21 14:37:04 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-21 14:48:07 +0300 |
commit | 6ee2abde82ef121cd6e927995053ac33afdbb438 (patch) | |
tree | f2ed1bb0962c0ea60c30ba7d9dea2a6e184ec247 /source/blender | |
parent | d455eadcd82f2151e858025cae6788b65016811e (diff) |
Functions: use static names for multi-functions
Previously, the function names were stored in `std::string` and were often
created dynamically (especially when the function just output a constant).
This resulted in a lot of overhead.
Now the function name is just a `const char *` that should be statically
allocated. This is good enough for the majority of cases. If a multi-function
needs a more dynamic name, it can override the `MultiFunction::debug_name`
method.
In my test file with >400,000 simple math nodes, the execution time improves from
3s to 1s.
Diffstat (limited to 'source/blender')
13 files changed, 74 insertions, 83 deletions
diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index c57f6cf574e..3059fe59ca7 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -97,6 +97,8 @@ class MultiFunction { return signature_ref_->function_name; } + virtual std::string debug_name() const; + bool depends_on_context() const { return signature_ref_->depends_on_context; diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 0ce05cbca30..eaf9e5ce70f 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -43,7 +43,7 @@ template<typename In1, typename Out1> class CustomMF_SI_SO : public MultiFunctio MFSignature signature_; public: - CustomMF_SI_SO(StringRef name, FunctionT function) : function_(std::move(function)) + CustomMF_SI_SO(const char *name, FunctionT function) : function_(std::move(function)) { MFSignatureBuilder signature{name}; signature.single_input<In1>("In1"); @@ -53,7 +53,7 @@ template<typename In1, typename Out1> class CustomMF_SI_SO : public MultiFunctio } template<typename ElementFuncT> - CustomMF_SI_SO(StringRef name, ElementFuncT element_fn) + CustomMF_SI_SO(const char *name, ElementFuncT element_fn) : CustomMF_SI_SO(name, CustomMF_SI_SO::create_function(element_fn)) { } @@ -92,7 +92,7 @@ class CustomMF_SI_SI_SO : public MultiFunction { MFSignature signature_; public: - CustomMF_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function)) + CustomMF_SI_SI_SO(const char *name, FunctionT function) : function_(std::move(function)) { MFSignatureBuilder signature{name}; signature.single_input<In1>("In1"); @@ -103,7 +103,7 @@ class CustomMF_SI_SI_SO : public MultiFunction { } template<typename ElementFuncT> - CustomMF_SI_SI_SO(StringRef name, ElementFuncT element_fn) + CustomMF_SI_SI_SO(const char *name, ElementFuncT element_fn) : CustomMF_SI_SI_SO(name, CustomMF_SI_SI_SO::create_function(element_fn)) { } @@ -150,7 +150,7 @@ class CustomMF_SI_SI_SI_SO : public MultiFunction { MFSignature signature_; public: - CustomMF_SI_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function)) + CustomMF_SI_SI_SI_SO(const char *name, FunctionT function) : function_(std::move(function)) { MFSignatureBuilder signature{name}; signature.single_input<In1>("In1"); @@ -162,7 +162,7 @@ class CustomMF_SI_SI_SI_SO : public MultiFunction { } template<typename ElementFuncT> - CustomMF_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn) + CustomMF_SI_SI_SI_SO(const char *name, ElementFuncT element_fn) : CustomMF_SI_SI_SI_SO(name, CustomMF_SI_SI_SI_SO::create_function(element_fn)) { } @@ -211,7 +211,7 @@ class CustomMF_SI_SI_SI_SI_SO : public MultiFunction { MFSignature signature_; public: - CustomMF_SI_SI_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function)) + CustomMF_SI_SI_SI_SI_SO(const char *name, FunctionT function) : function_(std::move(function)) { MFSignatureBuilder signature{name}; signature.single_input<In1>("In1"); @@ -224,7 +224,7 @@ class CustomMF_SI_SI_SI_SI_SO : public MultiFunction { } template<typename ElementFuncT> - CustomMF_SI_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn) + CustomMF_SI_SI_SI_SI_SO(const char *name, ElementFuncT element_fn) : CustomMF_SI_SI_SI_SI_SO(name, CustomMF_SI_SI_SI_SI_SO::create_function(element_fn)) { } @@ -265,7 +265,7 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction { MFSignature signature_; public: - CustomMF_SM(StringRef name, FunctionT function) : function_(std::move(function)) + CustomMF_SM(const char *name, FunctionT function) : function_(std::move(function)) { MFSignatureBuilder signature{name}; signature.single_mutable<Mut1>("Mut1"); @@ -274,7 +274,7 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction { } template<typename ElementFuncT> - CustomMF_SM(StringRef name, ElementFuncT element_fn) + CustomMF_SM(const char *name, ElementFuncT element_fn) : CustomMF_SM(name, CustomMF_SM::create_function(element_fn)) { } @@ -306,8 +306,8 @@ template<typename From, typename To> class CustomMF_Convert : public MultiFuncti static MFSignature create_signature() { - std::string name = CPPType::get<From>().name() + " to " + CPPType::get<To>().name(); - MFSignatureBuilder signature{std::move(name)}; + static std::string name = CPPType::get<From>().name() + " to " + CPPType::get<To>().name(); + MFSignatureBuilder signature{name.c_str()}; signature.single_input<From>("Input"); signature.single_output<To>("Output"); return signature.build(); @@ -372,9 +372,7 @@ template<typename T> class CustomMF_Constant : public MultiFunction { template<typename U> CustomMF_Constant(U &&value) : value_(std::forward<U>(value)) { MFSignatureBuilder signature{"Constant"}; - std::stringstream ss; - ss << value_; - signature.single_output<T>(ss.str()); + signature.single_output<T>("Value"); signature_ = signature.build(); this->set_signature(&signature_); } @@ -414,9 +412,7 @@ class CustomMF_DefaultOutput : public MultiFunction { MFSignature signature_; public: - CustomMF_DefaultOutput(StringRef name, - Span<MFDataType> input_types, - Span<MFDataType> output_types); + CustomMF_DefaultOutput(Span<MFDataType> input_types, Span<MFDataType> output_types); void call(IndexMask mask, MFParams params, MFContext context) const override; }; @@ -425,7 +421,7 @@ class CustomMF_GenericCopy : public MultiFunction { MFSignature signature_; public: - CustomMF_GenericCopy(StringRef name, MFDataType data_type); + CustomMF_GenericCopy(MFDataType data_type); void call(IndexMask mask, MFParams params, MFContext context) const override; }; diff --git a/source/blender/functions/FN_multi_function_procedure_executor.hh b/source/blender/functions/FN_multi_function_procedure_executor.hh index 9c8b59739b8..b12e3a91210 100644 --- a/source/blender/functions/FN_multi_function_procedure_executor.hh +++ b/source/blender/functions/FN_multi_function_procedure_executor.hh @@ -31,7 +31,7 @@ class MFProcedureExecutor : public MultiFunction { const MFProcedure &procedure_; public: - MFProcedureExecutor(std::string name, const MFProcedure &procedure); + MFProcedureExecutor(const MFProcedure &procedure); void call(IndexMask mask, MFParams params, MFContext context) const override; }; diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index d05948cc645..2ccaa60fed6 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -30,7 +30,14 @@ namespace blender::fn { struct MFSignature { - std::string function_name; + /** + * The name should be statically allocated so that it lives longer than this signature. This is + * used instead of an #std::string because of the overhead when many functions are created. + * If the name of the function has to be more dynamic for debugging purposes, override + * #MultiFunction::debug_name() instead. Then the dynamic name will only be computed when it is + * actually needed. + */ + const char *function_name; Vector<std::string> param_names; Vector<MFParamType> param_types; Vector<int> param_data_indices; @@ -51,9 +58,9 @@ class MFSignatureBuilder { int vector_array_count_ = 0; public: - MFSignatureBuilder(std::string function_name) + MFSignatureBuilder(const char *function_name) { - signature_.function_name = std::move(function_name); + signature_.function_name = function_name; } MFSignature build() const diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 68a8446e6ae..91b1bdfd8f0 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -237,8 +237,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, 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 ©_fn = scope.construct<CustomMF_GenericCopy>("copy", - variable->data_type()); + const MultiFunction ©_fn = scope.construct<CustomMF_GenericCopy>(variable->data_type()); variable = builder.add_call<1>(copy_fn, {variable})[0]; } builder.add_output_parameter(*variable); @@ -358,7 +357,7 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope, MFProcedure procedure; build_multi_function_procedure_for_fields( procedure, scope, field_tree_info, varying_fields_to_evaluate); - MFProcedureExecutor procedure_executor{"Procedure", procedure}; + MFProcedureExecutor procedure_executor{procedure}; /* Add multi threading capabilities to the field evaluation. */ const int grain_size = 10000; fn::ParallelMultiFunction parallel_procedure_executor{procedure_executor, grain_size}; @@ -415,7 +414,7 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope, MFProcedure procedure; build_multi_function_procedure_for_fields( procedure, scope, field_tree_info, constant_fields_to_evaluate); - MFProcedureExecutor procedure_executor{"Procedure", procedure}; + MFProcedureExecutor procedure_executor{procedure}; MFParamsBuilder mf_params{procedure_executor, 1}; MFContextBuilder mf_context; diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index 43eacdcd2a1..ee2c69068db 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -18,4 +18,9 @@ namespace blender::fn { +std::string MultiFunction::debug_name() const +{ + return signature_ref_->function_name; +} + } // namespace blender::fn diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index f891f162820..24f9bbe0179 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -32,10 +32,8 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, } value_ = value; - MFSignatureBuilder signature{"Constant " + type.name()}; - std::stringstream ss; - type.print_or_default(value, ss, type.name()); - signature.single_output(ss.str(), type); + MFSignatureBuilder signature{"Constant"}; + signature.single_output("Value", type); signature_ = signature.build(); this->set_signature(&signature_); } @@ -73,28 +71,11 @@ bool CustomMF_GenericConstant::equals(const MultiFunction &other) const return type_.is_equal(value_, _other->value_); } -static std::string gspan_to_string(GSpan array) -{ - const CPPType &type = array.type(); - std::stringstream ss; - ss << "["; - const int64_t max_amount = 5; - for (int64_t i : IndexRange(std::min(max_amount, array.size()))) { - type.print_or_default(array[i], ss, type.name()); - ss << ", "; - } - if (max_amount < array.size()) { - ss << "..."; - } - ss << "]"; - return ss.str(); -} - CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array) { const CPPType &type = array.type(); - MFSignatureBuilder signature{"Constant " + type.name() + " Vector"}; - signature.vector_output(gspan_to_string(array), type); + MFSignatureBuilder signature{"Constant Vector"}; + signature.vector_output("Value", type); signature_ = signature.build(); this->set_signature(&signature_); } @@ -109,12 +90,11 @@ void CustomMF_GenericConstantArray::call(IndexMask mask, } } -CustomMF_DefaultOutput::CustomMF_DefaultOutput(StringRef name, - Span<MFDataType> input_types, +CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<MFDataType> input_types, Span<MFDataType> output_types) : output_amount_(output_types.size()) { - MFSignatureBuilder signature{name}; + MFSignatureBuilder signature{"Default Output"}; for (MFDataType data_type : input_types) { signature.input("Input", data_type); } @@ -140,9 +120,9 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNU } } -CustomMF_GenericCopy::CustomMF_GenericCopy(StringRef name, MFDataType data_type) +CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type) { - MFSignatureBuilder signature{name}; + MFSignatureBuilder signature{"Copy"}; signature.input("Input", data_type); signature.output("Output", data_type); signature_ = signature.build(); diff --git a/source/blender/functions/intern/multi_function_procedure.cc b/source/blender/functions/intern/multi_function_procedure.cc index 986c5dff0c4..804beb7d66f 100644 --- a/source/blender/functions/intern/multi_function_procedure.cc +++ b/source/blender/functions/intern/multi_function_procedure.cc @@ -782,7 +782,7 @@ class MFProcedureDotExport { void instruction_to_string(const MFCallInstruction &instruction, std::stringstream &ss) { const MultiFunction &fn = instruction.fn(); - this->instruction_name_format(fn.name() + ": ", ss); + 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]; diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index 85d0cf4909f..1136b03ed58 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -20,10 +20,9 @@ namespace blender::fn { -MFProcedureExecutor::MFProcedureExecutor(std::string name, const MFProcedure &procedure) - : procedure_(procedure) +MFProcedureExecutor::MFProcedureExecutor(const MFProcedure &procedure) : procedure_(procedure) { - MFSignatureBuilder signature(std::move(name)); + MFSignatureBuilder signature("Procedure Executor"); for (const ConstMFParameter ¶m : procedure.params()) { signature.add(param.variable->name(), MFParamType(param.type, param.variable->data_type())); diff --git a/source/blender/functions/tests/FN_multi_function_procedure_test.cc b/source/blender/functions/tests/FN_multi_function_procedure_test.cc index a0919d7926e..e3de23550c5 100644 --- a/source/blender/functions/tests/FN_multi_function_procedure_test.cc +++ b/source/blender/functions/tests/FN_multi_function_procedure_test.cc @@ -32,7 +32,7 @@ TEST(multi_function_procedure, ConstantOutput) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor executor{"My Procedure", procedure}; + MFProcedureExecutor executor{procedure}; MFParamsBuilder params{executor, 2}; MFContextBuilder context; @@ -73,7 +73,7 @@ TEST(multi_function_procedure, SimpleTest) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor executor{"My Procedure", procedure}; + MFProcedureExecutor executor{procedure}; MFParamsBuilder params{executor, 3}; MFContextBuilder context; @@ -125,7 +125,7 @@ TEST(multi_function_procedure, BranchTest) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{"Condition Test", procedure}; + MFProcedureExecutor procedure_fn{procedure}; MFParamsBuilder params(procedure_fn, 5); Array<int> values_a = {1, 5, 3, 6, 2}; @@ -167,7 +167,7 @@ TEST(multi_function_procedure, EvaluateOne) builder.add_return(); builder.add_output_parameter(*var2); - MFProcedureExecutor procedure_fn{"Evaluate One", procedure}; + MFProcedureExecutor procedure_fn{procedure}; MFParamsBuilder params{procedure_fn, 5}; Array<int> values_out = {1, 2, 3, 4, 5}; @@ -239,7 +239,7 @@ TEST(multi_function_procedure, SimpleLoop) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{"Simple Loop", procedure}; + MFProcedureExecutor procedure_fn{procedure}; MFParamsBuilder params{procedure_fn, 5}; Array<int> counts = {4, 3, 7, 6, 4}; @@ -295,7 +295,7 @@ TEST(multi_function_procedure, Vectors) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{"Vectors", procedure}; + MFProcedureExecutor procedure_fn{procedure}; MFParamsBuilder params{procedure_fn, 5}; Array<int> v1 = {5, 2, 3}; @@ -359,7 +359,7 @@ TEST(multi_function_procedure, BufferReuse) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{"Buffer Reuse", procedure}; + MFProcedureExecutor procedure_fn{procedure}; Array<int> inputs = {4, 1, 6, 2, 3}; Array<int> results(5, -1); diff --git a/source/blender/nodes/intern/type_conversions.cc b/source/blender/nodes/intern/type_conversions.cc index b1611679ced..d4cd7dc6bfe 100644 --- a/source/blender/nodes/intern/type_conversions.cc +++ b/source/blender/nodes/intern/type_conversions.cc @@ -29,11 +29,11 @@ using fn::MFDataType; template<typename From, typename To, To (*ConversionF)(const From &)> static void add_implicit_conversion(DataTypeConversions &conversions) { - const CPPType &from_type = CPPType::get<From>(); - const CPPType &to_type = CPPType::get<To>(); - const std::string conversion_name = from_type.name() + " to " + to_type.name(); + static const CPPType &from_type = CPPType::get<From>(); + static const CPPType &to_type = CPPType::get<To>(); + static const std::string conversion_name = from_type.name() + " to " + to_type.name(); - static fn::CustomMF_SI_SO<From, To> multi_function{conversion_name, ConversionF}; + static fn::CustomMF_SI_SO<From, To> multi_function{conversion_name.c_str(), ConversionF}; static auto convert_single_to_initialized = [](const void *src, void *dst) { *(To *)dst = ConversionF(*(const From *)src); }; diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index 284a5f1189f..1e94148c5c7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -88,7 +88,8 @@ static const blender::fn::MultiFunction *get_base_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl_to_fl( mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SO<float, float> fn{info.title_case_name, function}; + static blender::fn::CustomMF_SI_SO<float, float> fn{info.title_case_name.c_str(), + function}; base_fn = &fn; }); if (base_fn != nullptr) { @@ -97,7 +98,7 @@ static const blender::fn::MultiFunction *get_base_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl_fl_to_fl( mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{info.title_case_name, + static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{info.title_case_name.c_str(), function}; base_fn = &fn; }); @@ -108,7 +109,7 @@ static const blender::fn::MultiFunction *get_base_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl_fl_fl_to_fl( mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> fn{ - info.title_case_name, function}; + info.title_case_name.c_str(), function}; base_fn = &fn; }); if (base_fn != nullptr) { diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc index fad93962708..9b1b2467230 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc @@ -201,8 +201,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_fl3_to_fl3( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{info.title_case_name, - function}; + static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{ + info.title_case_name.c_str(), function}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -212,7 +212,7 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_fl3_fl3_to_fl3( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{ - info.title_case_name, function}; + info.title_case_name.c_str(), function}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -222,7 +222,7 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_fl3_fl_to_fl3( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ - info.title_case_name, function}; + info.title_case_name.c_str(), function}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -231,8 +231,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_fl3_to_fl( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{info.title_case_name, - function}; + static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{ + info.title_case_name.c_str(), function}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -241,8 +241,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_fl_to_fl3( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SI_SO<float3, float, float3> fn{info.title_case_name, - function}; + static blender::fn::CustomMF_SI_SI_SO<float3, float, float3> fn{ + info.title_case_name.c_str(), function}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -251,7 +251,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_to_fl3( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SO<float3, float3> fn{info.title_case_name, function}; + static blender::fn::CustomMF_SI_SO<float3, float3> fn{info.title_case_name.c_str(), + function}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -260,7 +261,8 @@ static const blender::fn::MultiFunction *get_multi_function(bNode &node) blender::nodes::try_dispatch_float_math_fl3_to_fl( operation, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) { - static blender::fn::CustomMF_SI_SO<float3, float> fn{info.title_case_name, function}; + static blender::fn::CustomMF_SI_SO<float3, float> fn{info.title_case_name.c_str(), + function}; multi_fn = &fn; }); if (multi_fn != nullptr) { |