diff options
author | Jacques Lucke <jacques@blender.org> | 2020-07-07 19:23:33 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-07-07 19:23:33 +0300 |
commit | 4990e4dd01f2b085f5d1842dfa31d79e4df92fbd (patch) | |
tree | 2e368d7e0c8c2e5d090e97c12a33e4514d15b8d4 /source/blender/nodes | |
parent | ff97545c50f458a62a2ea412f8411f8bb34b9c1c (diff) |
Nodes: Generate multi-function network from node tree
This adds new callbacks to `bNodeSocketType` and `bNodeType`.
Those are used to generate a multi-function network from a node
tree. Later, this network is evaluated on e.g. particle data.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D8169
Diffstat (limited to 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/CMakeLists.txt | 6 | ||||
-rw-r--r-- | source/blender/nodes/function/node_function_util.cc | 2 | ||||
-rw-r--r-- | source/blender/nodes/function/node_function_util.hh (renamed from source/blender/nodes/function/node_function_util.h) | 4 | ||||
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_boolean_math.cc | 30 | ||||
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_combine_strings.cc | 27 | ||||
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_float_compare.cc | 45 | ||||
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_group_instance_id.cc | 32 | ||||
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_switch.cc | 2 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket.cc | 113 | ||||
-rw-r--r-- | source/blender/nodes/shader/node_shader_util.h | 6 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c) | 71 |
11 files changed, 310 insertions, 28 deletions
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 31b5e922dab..55c5009ea56 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC ../blenlib ../blentranslation ../depsgraph + ../functions ../gpu ../imbuf ../makesdna @@ -192,7 +193,7 @@ set(SRC shader/nodes/node_shader_script.c shader/nodes/node_shader_sepcombHSV.c shader/nodes/node_shader_sepcombRGB.c - shader/nodes/node_shader_sepcombXYZ.c + shader/nodes/node_shader_sepcombXYZ.cc shader/nodes/node_shader_shaderToRgb.c shader/nodes/node_shader_squeeze.c shader/nodes/node_shader_subsurface_scattering.c @@ -277,7 +278,7 @@ set(SRC intern/node_util.c composite/node_composite_util.h - function/node_function_util.h + function/node_function_util.hh shader/node_shader_util.h simulation/node_simulation_util.h texture/node_texture_util.h @@ -296,6 +297,7 @@ set(SRC ) set(LIB + bf_functions ) if(WITH_PYTHON) diff --git a/source/blender/nodes/function/node_function_util.cc b/source/blender/nodes/function/node_function_util.cc index 0927ba335fe..342c330a8fa 100644 --- a/source/blender/nodes/function/node_function_util.cc +++ b/source/blender/nodes/function/node_function_util.cc @@ -14,7 +14,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "node_function_util.h" +#include "node_function_util.hh" #include "node_util.h" bool fn_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree) diff --git a/source/blender/nodes/function/node_function_util.h b/source/blender/nodes/function/node_function_util.hh index 85e252f9bdd..938cb5dd593 100644 --- a/source/blender/nodes/function/node_function_util.h +++ b/source/blender/nodes/function/node_function_util.hh @@ -19,6 +19,7 @@ #include <string.h> +#include "BLI_float3.hh" #include "BLI_utildefines.h" #include "MEM_guardedalloc.h" @@ -26,6 +27,7 @@ #include "DNA_node_types.h" #include "BKE_node.h" +#include "BKE_node_tree_multi_function.hh" #include "BLT_translation.h" @@ -33,6 +35,8 @@ #include "node_util.h" +#include "FN_multi_function_builder.hh" + void fn_node_type_base( struct bNodeType *ntype, int type, const char *name, short nclass, short flag); bool fn_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree); diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc index 615ad4c6733..3a145311a08 100644 --- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc +++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc @@ -19,7 +19,7 @@ #include "RNA_enum_types.h" -#include "node_function_util.h" +#include "node_function_util.hh" static bNodeSocketTemplate fn_node_boolean_math_in[] = { {SOCK_BOOLEAN, N_("Boolean")}, @@ -50,6 +50,33 @@ static void node_boolean_math_label(bNodeTree *UNUSED(ntree), bNode *node, char BLI_strncpy(label, IFACE_(name), maxlen); } +static const blender::fn::MultiFunction &get_multi_function(bNode &bnode) +{ + static blender::fn::CustomMF_SI_SI_SO<bool, bool, bool> and_fn{ + "And", [](bool a, bool b) { return a && b; }}; + static blender::fn::CustomMF_SI_SI_SO<bool, bool, bool> or_fn{ + "Or", [](bool a, bool b) { return a || b; }}; + static blender::fn::CustomMF_SI_SO<bool, bool> not_fn{"Not", [](bool a) { return !a; }}; + + switch (bnode.custom1) { + case NODE_BOOLEAN_MATH_AND: + return and_fn; + case NODE_BOOLEAN_MATH_OR: + return or_fn; + case NODE_BOOLEAN_MATH_NOT: + return not_fn; + } + + BLI_assert(false); + return blender::fn::dummy_multi_function; +} + +static void node_boolean_expand_in_mf_network(blender::bke::NodeMFNetworkBuilder &builder) +{ + const blender::fn::MultiFunction &fn = get_multi_function(builder.bnode()); + builder.set_matching_fn(fn); +} + void register_node_type_fn_boolean_math() { static bNodeType ntype; @@ -58,5 +85,6 @@ void register_node_type_fn_boolean_math() node_type_socket_templates(&ntype, fn_node_boolean_math_in, fn_node_boolean_math_out); node_type_label(&ntype, node_boolean_math_label); node_type_update(&ntype, node_boolean_math_update); + ntype.expand_in_mf_network = node_boolean_expand_in_mf_network; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_combine_strings.cc b/source/blender/nodes/function/nodes/node_fn_combine_strings.cc index 1b6091451d9..a880933bc12 100644 --- a/source/blender/nodes/function/nodes/node_fn_combine_strings.cc +++ b/source/blender/nodes/function/nodes/node_fn_combine_strings.cc @@ -1,4 +1,20 @@ -#include "node_function_util.h" +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "node_function_util.hh" static bNodeSocketTemplate fn_node_combine_strings_in[] = { {SOCK_STRING, N_("A")}, @@ -11,11 +27,20 @@ static bNodeSocketTemplate fn_node_combine_strings_out[] = { {-1, ""}, }; +static void fn_node_combine_strings_expand_in_mf_network( + blender::bke::NodeMFNetworkBuilder &builder) +{ + static blender::fn::CustomMF_SI_SI_SO<std::string, std::string, std::string> combine_fn{ + "Combine Strings", [](const std::string &a, const std::string &b) { return a + b; }}; + builder.set_matching_fn(combine_fn); +} + void register_node_type_fn_combine_strings() { static bNodeType ntype; fn_node_type_base(&ntype, FN_NODE_COMBINE_STRINGS, "Combine Strings", 0, 0); node_type_socket_templates(&ntype, fn_node_combine_strings_in, fn_node_combine_strings_out); + ntype.expand_in_mf_network = fn_node_combine_strings_expand_in_mf_network; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_float_compare.cc b/source/blender/nodes/function/nodes/node_fn_float_compare.cc index 9788402850b..fb2c4d88caf 100644 --- a/source/blender/nodes/function/nodes/node_fn_float_compare.cc +++ b/source/blender/nodes/function/nodes/node_fn_float_compare.cc @@ -14,12 +14,14 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include <cmath> + #include "BLI_listbase.h" #include "BLI_string.h" #include "RNA_enum_types.h" -#include "node_function_util.h" +#include "node_function_util.hh" static bNodeSocketTemplate fn_node_float_compare_in[] = { {SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, @@ -54,6 +56,46 @@ static void node_float_compare_label(bNodeTree *UNUSED(ntree), BLI_strncpy(label, IFACE_(name), maxlen); } +static const blender::fn::MultiFunction &get_multi_function(bNode &node) +{ + static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_than_fn{ + "Less Than", [](float a, float b) { return a < b; }}; + static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_equal_fn{ + "Less Equal", [](float a, float b) { return a <= b; }}; + static blender::fn::CustomMF_SI_SI_SO<float, float, bool> greater_than_fn{ + "Greater Than", [](float a, float b) { return a > b; }}; + static blender::fn::CustomMF_SI_SI_SO<float, float, bool> greater_equal_fn{ + "Greater Equal", [](float a, float b) { return a >= b; }}; + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> equal_fn{ + "Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }}; + static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> not_equal_fn{ + "Not Equal", [](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }}; + + switch (node.custom1) { + case NODE_FLOAT_COMPARE_LESS_THAN: + return less_than_fn; + case NODE_FLOAT_COMPARE_LESS_EQUAL: + return less_equal_fn; + case NODE_FLOAT_COMPARE_GREATER_THAN: + return greater_than_fn; + case NODE_FLOAT_COMPARE_GREATER_EQUAL: + return greater_equal_fn; + case NODE_FLOAT_COMPARE_EQUAL: + return equal_fn; + case NODE_FLOAT_COMPARE_NOT_EQUAL: + return not_equal_fn; + } + + BLI_assert(false); + return blender::fn::dummy_multi_function; +} + +static void node_float_compare_expand_in_mf_network(blender::bke::NodeMFNetworkBuilder &builder) +{ + const blender::fn::MultiFunction &fn = get_multi_function(builder.bnode()); + builder.set_matching_fn(fn); +} + void register_node_type_fn_float_compare() { static bNodeType ntype; @@ -62,5 +104,6 @@ void register_node_type_fn_float_compare() node_type_socket_templates(&ntype, fn_node_float_compare_in, fn_node_float_compare_out); node_type_label(&ntype, node_float_compare_label); node_type_update(&ntype, node_float_compare_update); + ntype.expand_in_mf_network = node_float_compare_expand_in_mf_network; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc b/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc index 2ac86ee2407..c61c941ee0d 100644 --- a/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc +++ b/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc @@ -1,15 +1,45 @@ -#include "node_function_util.h" +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "node_function_util.hh" static bNodeSocketTemplate fn_node_group_instance_id_out[] = { {SOCK_STRING, N_("Identifier")}, {-1, ""}, }; +static void fn_node_group_instance_id_expand_in_mf_network( + blender::bke::NodeMFNetworkBuilder &builder) +{ + const blender::bke::DNode &node = builder.dnode(); + std::string id = "/"; + for (const blender::bke::DParentNode *parent = node.parent(); parent; + parent = parent->parent()) { + id = "/" + parent->node_ref().name() + id; + } + builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<std::string>>( + std::move(id)); +} + void register_node_type_fn_group_instance_id() { static bNodeType ntype; fn_node_type_base(&ntype, FN_NODE_GROUP_INSTANCE_ID, "Group Instance ID", 0, 0); node_type_socket_templates(&ntype, nullptr, fn_node_group_instance_id_out); + ntype.expand_in_mf_network = fn_node_group_instance_id_expand_in_mf_network; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/function/nodes/node_fn_switch.cc b/source/blender/nodes/function/nodes/node_fn_switch.cc index cb721058875..281ddb05c76 100644 --- a/source/blender/nodes/function/nodes/node_fn_switch.cc +++ b/source/blender/nodes/function/nodes/node_fn_switch.cc @@ -15,7 +15,7 @@ */ #include "BLI_listbase.h" -#include "node_function_util.h" +#include "node_function_util.hh" static bNodeSocketTemplate fn_node_switch_in[] = { {SOCK_BOOLEAN, N_("Switch")}, diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index b23511c3bdb..02124465dda 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -25,6 +25,8 @@ #include "DNA_node_types.h" +#include "BLI_color.hh" +#include "BLI_float3.hh" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" @@ -32,6 +34,7 @@ #include "BKE_lib_id.h" #include "BKE_node.h" +#include "BKE_node_tree_multi_function.hh" #include "RNA_access.h" #include "RNA_types.h" @@ -510,35 +513,105 @@ static bNodeSocketType *make_socket_type_control_flow(int type) return stype; } +static bNodeSocketType *make_socket_type_bool() +{ + bNodeSocketType *socktype = make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE); + socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<bool>(); }; + socktype->expand_in_mf_network = [](blender::bke::SocketMFNetworkBuilder &builder) { + bool value = builder.socket_default_value<bNodeSocketValueBoolean>()->value; + builder.set_constant_value(value); + }; + return socktype; +} + +static bNodeSocketType *make_socket_type_float(PropertySubType subtype) +{ + bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype); + socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<float>(); }; + socktype->expand_in_mf_network = [](blender::bke::SocketMFNetworkBuilder &builder) { + float value = builder.socket_default_value<bNodeSocketValueFloat>()->value; + builder.set_constant_value(value); + }; + return socktype; +} + +static bNodeSocketType *make_socket_type_int(PropertySubType subtype) +{ + bNodeSocketType *socktype = make_standard_socket_type(SOCK_INT, subtype); + socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<int>(); }; + socktype->expand_in_mf_network = [](blender::bke::SocketMFNetworkBuilder &builder) { + int value = builder.socket_default_value<bNodeSocketValueInt>()->value; + builder.set_constant_value(value); + }; + return socktype; +} + +static bNodeSocketType *make_socket_type_vector(PropertySubType subtype) +{ + bNodeSocketType *socktype = make_standard_socket_type(SOCK_VECTOR, subtype); + socktype->get_mf_data_type = []() { + return blender::fn::MFDataType::ForSingle<blender::float3>(); + }; + socktype->expand_in_mf_network = [](blender::bke::SocketMFNetworkBuilder &builder) { + blender::float3 value = builder.socket_default_value<bNodeSocketValueVector>()->value; + builder.set_constant_value(value); + }; + return socktype; +} + +static bNodeSocketType *make_socket_type_rgba() +{ + bNodeSocketType *socktype = make_standard_socket_type(SOCK_RGBA, PROP_NONE); + socktype->get_mf_data_type = []() { + return blender::fn::MFDataType::ForSingle<blender::Color4f>(); + }; + socktype->expand_in_mf_network = [](blender::bke::SocketMFNetworkBuilder &builder) { + blender::Color4f value = builder.socket_default_value<bNodeSocketValueRGBA>()->value; + builder.set_constant_value(value); + }; + return socktype; +} + +static bNodeSocketType *make_socket_type_string() +{ + bNodeSocketType *socktype = make_standard_socket_type(SOCK_STRING, PROP_NONE); + socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<std::string>(); }; + socktype->expand_in_mf_network = [](blender::bke::SocketMFNetworkBuilder &builder) { + std::string value = builder.socket_default_value<bNodeSocketValueString>()->value; + builder.set_constant_value(value); + }; + return socktype; +} + void register_standard_node_socket_types(void) { /* draw callbacks are set in drawnode.c to avoid bad-level calls */ - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_UNSIGNED)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_PERCENTAGE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_FACTOR)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_ANGLE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_TIME)); + nodeRegisterSocketType(make_socket_type_float(PROP_NONE)); + nodeRegisterSocketType(make_socket_type_float(PROP_UNSIGNED)); + nodeRegisterSocketType(make_socket_type_float(PROP_PERCENTAGE)); + nodeRegisterSocketType(make_socket_type_float(PROP_FACTOR)); + nodeRegisterSocketType(make_socket_type_float(PROP_ANGLE)); + nodeRegisterSocketType(make_socket_type_float(PROP_TIME)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_UNSIGNED)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_PERCENTAGE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_FACTOR)); + nodeRegisterSocketType(make_socket_type_int(PROP_NONE)); + nodeRegisterSocketType(make_socket_type_int(PROP_UNSIGNED)); + nodeRegisterSocketType(make_socket_type_int(PROP_PERCENTAGE)); + nodeRegisterSocketType(make_socket_type_int(PROP_FACTOR)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE)); + nodeRegisterSocketType(make_socket_type_bool()); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_TRANSLATION)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_DIRECTION)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_VELOCITY)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_ACCELERATION)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_EULER)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_XYZ)); + nodeRegisterSocketType(make_socket_type_vector(PROP_NONE)); + nodeRegisterSocketType(make_socket_type_vector(PROP_TRANSLATION)); + nodeRegisterSocketType(make_socket_type_vector(PROP_DIRECTION)); + nodeRegisterSocketType(make_socket_type_vector(PROP_VELOCITY)); + nodeRegisterSocketType(make_socket_type_vector(PROP_ACCELERATION)); + nodeRegisterSocketType(make_socket_type_vector(PROP_EULER)); + nodeRegisterSocketType(make_socket_type_vector(PROP_XYZ)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_RGBA, PROP_NONE)); + nodeRegisterSocketType(make_socket_type_rgba()); - nodeRegisterSocketType(make_standard_socket_type(SOCK_STRING, PROP_NONE)); + nodeRegisterSocketType(make_socket_type_string()); nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE)); diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h index fbb9979cdfa..fc262544b4f 100644 --- a/source/blender/nodes/shader/node_shader_util.h +++ b/source/blender/nodes/shader/node_shader_util.h @@ -70,6 +70,12 @@ #include "GPU_uniformbuffer.h" #ifdef __cplusplus +# include "FN_multi_function_builder.hh" + +# include "BKE_node_tree_multi_function.hh" + +# include "BLI_float3.hh" + extern "C" { #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc index 429b1a3e818..e6a7201b855 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc @@ -44,6 +44,42 @@ static int gpu_shader_sepxyz(GPUMaterial *mat, return GPU_stack_link(mat, node, "separate_xyz", in, out); } +class MF_SeparateXYZ : public blender::fn::MultiFunction { + public: + MF_SeparateXYZ() + { + blender::fn::MFSignatureBuilder signature = this->get_builder("Separate XYZ"); + signature.single_input<blender::float3>("XYZ"); + signature.single_output<float>("X"); + signature.single_output<float>("y"); + signature.single_output<float>("z"); + } + + void call(blender::IndexMask mask, + blender::fn::MFParams params, + blender::fn::MFContext UNUSED(context)) const override + { + blender::fn::VSpan<blender::float3> vectors = params.readonly_single_input<blender::float3>( + 0, "XYZ"); + blender::MutableSpan<float> xs = params.uninitialized_single_output<float>(1, "X"); + blender::MutableSpan<float> ys = params.uninitialized_single_output<float>(2, "Y"); + blender::MutableSpan<float> zs = params.uninitialized_single_output<float>(3, "Z"); + + for (uint i : mask) { + blender::float3 xyz = vectors[i]; + xs[i] = xyz.x; + ys[i] = xyz.y; + zs[i] = xyz.z; + } + } +}; + +static void sh_node_sepxyz_expand_in_mf_network(blender::bke::NodeMFNetworkBuilder &builder) +{ + static MF_SeparateXYZ separate_fn; + builder.set_matching_fn(separate_fn); +} + void register_node_type_sh_sepxyz(void) { static bNodeType ntype; @@ -51,6 +87,7 @@ void register_node_type_sh_sepxyz(void) sh_fn_node_type_base(&ntype, SH_NODE_SEPXYZ, "Separate XYZ", NODE_CLASS_CONVERTOR, 0); node_type_socket_templates(&ntype, sh_node_sepxyz_in, sh_node_sepxyz_out); node_type_gpu(&ntype, gpu_shader_sepxyz); + ntype.expand_in_mf_network = sh_node_sepxyz_expand_in_mf_network; nodeRegisterType(&ntype); } @@ -76,6 +113,39 @@ static int gpu_shader_combxyz(GPUMaterial *mat, return GPU_stack_link(mat, node, "combine_xyz", in, out); } +class MF_CombineXYZ : public blender::fn::MultiFunction { + public: + MF_CombineXYZ() + { + blender::fn::MFSignatureBuilder signature = this->get_builder("Combine XYZ"); + signature.single_input<float>("X"); + signature.single_input<float>("Y"); + signature.single_input<float>("Z"); + signature.single_output<blender::float3>("XYZ"); + } + + void call(blender::IndexMask mask, + blender::fn::MFParams params, + blender::fn::MFContext UNUSED(context)) const override + { + blender::fn::VSpan<float> xs = params.readonly_single_input<float>(0, "X"); + blender::fn::VSpan<float> ys = params.readonly_single_input<float>(1, "Y"); + blender::fn::VSpan<float> zs = params.readonly_single_input<float>(2, "Z"); + blender::MutableSpan<blender::float3> vectors = + params.uninitialized_single_output<blender::float3>(3, "XYZ"); + + for (uint i : mask) { + vectors[i] = {xs[i], ys[i], zs[i]}; + } + } +}; + +static void sh_node_combxyz_expand_in_mf_network(blender::bke::NodeMFNetworkBuilder &builder) +{ + static MF_CombineXYZ combine_fn; + builder.set_matching_fn(combine_fn); +} + void register_node_type_sh_combxyz(void) { static bNodeType ntype; @@ -83,6 +153,7 @@ void register_node_type_sh_combxyz(void) sh_fn_node_type_base(&ntype, SH_NODE_COMBXYZ, "Combine XYZ", NODE_CLASS_CONVERTOR, 0); node_type_socket_templates(&ntype, sh_node_combxyz_in, sh_node_combxyz_out); node_type_gpu(&ntype, gpu_shader_combxyz); + ntype.expand_in_mf_network = sh_node_combxyz_expand_in_mf_network; nodeRegisterType(&ntype); } |