Changeset View
Standalone View
source/blender/nodes/function/nodes/node_fn_compare.cc
- This file was added.
| /* | ||||||||||
| * 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 <cmath> | ||||||||||
| //#include "node_geometry_util.hh" | ||||||||||
| #include "BLI_listbase.h" | ||||||||||
| #include "BLI_string.h" | ||||||||||
| #include "UI_interface.h" | ||||||||||
| #include "UI_resources.h" | ||||||||||
| #include "RNA_enum_types.h" | ||||||||||
| #include "node_function_util.hh" | ||||||||||
| namespace blender::nodes { | ||||||||||
| static void fn_node_compare_declare(NodeDeclarationBuilder &b) | ||||||||||
| { | ||||||||||
| b.is_function_node(); | ||||||||||
| b.add_input<decl::Float>(N_("A")).min(-10000.0f).max(10000.0f); | ||||||||||
| b.add_input<decl::Float>(N_("B")).min(-10000.0f).max(10000.0f); | ||||||||||
| b.add_input<decl::Int>(N_("A"), "A_INT"); | ||||||||||
| b.add_input<decl::Int>(N_("B"), "B_INT"); | ||||||||||
| b.add_input<decl::Vector>(N_("A"), "A_VEC3"); | ||||||||||
| b.add_input<decl::Vector>(N_("B"), "B_VEC3"); | ||||||||||
| b.add_input<decl::Color>(N_("A"), "A_COL"); | ||||||||||
| b.add_input<decl::Color>(N_("B"), "B_COL"); | ||||||||||
| b.add_input<decl::String>(N_("A"), "A_STR"); | ||||||||||
| b.add_input<decl::String>(N_("B"), "B_STR"); | ||||||||||
| b.add_input<decl::Float>(N_("C")).default_value(0.00f); | ||||||||||
| b.add_input<decl::Float>(N_("Angle")).default_value(0.00f).subtype(PROP_ANGLE); | ||||||||||
HooglyBoogly: Maybe a default of `0.9f` makes more sense? Since usually you are comparing to see if the dot… | ||||||||||
Done Inline Actions
HooglyBoogly: | ||||||||||
| b.add_input<decl::Float>(N_("Epsilon")).default_value(0.001f).min(-10000.0f).max(10000.0f); | ||||||||||
Done Inline ActionsI think a default of 5 degrees makes a bit more sense. HooglyBoogly: I think a default of 5 degrees makes a bit more sense. | ||||||||||
| b.add_output<decl::Bool>(N_("Result")); | ||||||||||
| }; | ||||||||||
| static void geo_node_compare_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) | ||||||||||
| { | ||||||||||
| const NodeFunctionCompare *data = (NodeFunctionCompare *)((bNode *)(ptr->data))->storage; | ||||||||||
| uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); | ||||||||||
| if (data->data_type == SOCK_VECTOR) { | ||||||||||
| uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); | ||||||||||
| } | ||||||||||
| uiItemR(layout, ptr, "operation", 0, "", ICON_NONE); | ||||||||||
| } | ||||||||||
| static void node_compare_update(bNodeTree *ntree, bNode *node) | ||||||||||
| { | ||||||||||
| NodeFunctionCompare *data = (NodeFunctionCompare *)node->storage; | ||||||||||
| if (data->data_type == SOCK_RGBA && !ELEM(data->operation, | ||||||||||
| NODE_COMPARE_EQUAL, | ||||||||||
| NODE_COMPARE_NOT_EQUAL, | ||||||||||
| NODE_COMPARE_COLOR_BRIGHTER, | ||||||||||
| NODE_COMPARE_COLOR_DARKER)) { | ||||||||||
| data->operation = NODE_COMPARE_EQUAL; | ||||||||||
| } | ||||||||||
Done Inline ActionsThis should be done in an update function in rna. JacquesLucke: This should be done in an update function in rna. | ||||||||||
Done Inline ActionsNot sure how I should go about that. guitargeek: Not sure how I should go about that. | ||||||||||
Done Inline ActionsFor example, rna_GeometryNodeAttributeRandomize_data_type_update does something similar. HooglyBoogly: For example, `rna_GeometryNodeAttributeRandomize_data_type_update` does something similar. | ||||||||||
Done Inline ActionsAwesome, thanks! guitargeek: Awesome, thanks! | ||||||||||
| bNodeSocket *sock_comp = (bNodeSocket *)BLI_findlink(&node->inputs, 10); | ||||||||||
| bNodeSocket *sock_angle = (bNodeSocket *)BLI_findlink(&node->inputs, 11); | ||||||||||
| bNodeSocket *sock_epsilon = (bNodeSocket *)BLI_findlink(&node->inputs, 12); | ||||||||||
Done Inline ActionsSuggest snake_case naming, maybe even just comp, angle, and epsilon HooglyBoogly: Suggest `snake_case` naming, maybe even just `comp`, `angle`, and `epsilon` | ||||||||||
| LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { | ||||||||||
| nodeSetSocketAvailability(ntree, socket, socket->type == (eNodeSocketDatatype)data->data_type); | ||||||||||
| } | ||||||||||
Done Inline ActionsHmm, I don't think casting from CustomDataType to eNodeSocketDatatype is correct. Ah, it seems that the comment in NodeFunctionCompare is incorrect, it should say eNodeSocketDatatype HooglyBoogly: Hmm, I don't think casting from `CustomDataType` to `eNodeSocketDatatype` is correct.
Ah, it… | ||||||||||
| nodeSetSocketAvailability(ntree, | ||||||||||
| sock_epsilon, | ||||||||||
| ELEM(data->operation, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL) && | ||||||||||
| !ELEM(data->data_type, SOCK_INT, SOCK_STRING)); | ||||||||||
| nodeSetSocketAvailability(ntree, | ||||||||||
| sock_comp, | ||||||||||
| ELEM(data->mode, NODE_COMPARE_MODE_DOT_PRODUCT) && | ||||||||||
| data->data_type == SOCK_VECTOR); | ||||||||||
| nodeSetSocketAvailability(ntree, | ||||||||||
| sock_angle, | ||||||||||
| ELEM(data->mode, NODE_COMPARE_MODE_DIRECTION) && | ||||||||||
| data->data_type == SOCK_VECTOR); | ||||||||||
| } | ||||||||||
| static void node_compare_init(bNodeTree *UNUSED(tree), bNode *node) | ||||||||||
| { | ||||||||||
| NodeFunctionCompare *data = (NodeFunctionCompare *)MEM_callocN(sizeof(NodeFunctionCompare), | ||||||||||
| __func__); | ||||||||||
| data->operation = NODE_COMPARE_GREATER_THAN; | ||||||||||
| data->data_type = SOCK_FLOAT; | ||||||||||
| data->mode = NODE_COMPARE_MODE_ELEMENT; | ||||||||||
| node->storage = data; | ||||||||||
| } | ||||||||||
| static void node_compare_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) | ||||||||||
| { | ||||||||||
| const NodeFunctionCompare *data = (NodeFunctionCompare *)node->storage; | ||||||||||
| const char *name; | ||||||||||
| bool enum_label = RNA_enum_name(rna_enum_node_compare_operation_items, data->operation, &name); | ||||||||||
| if (!enum_label) { | ||||||||||
| name = "Unknown"; | ||||||||||
| } | ||||||||||
| BLI_strncpy(label, IFACE_(name), maxlen); | ||||||||||
| } | ||||||||||
| static const fn::MultiFunction *get_multi_function(bNode &node) | ||||||||||
| { | ||||||||||
| const NodeFunctionCompare *data = (NodeFunctionCompare *)node.storage; | ||||||||||
| /* Float Functions */ | ||||||||||
| static fn::CustomMF_SI_SI_SO<float, float, bool> float_less_than_fn{ | ||||||||||
| "Less Than", [](float a, float b) { return a < b; }}; | ||||||||||
Done Inline ActionsWould it make sense to move the function definitions into the switch statement below? Then every function would be in its own little scope and you could just name it fn. JacquesLucke: Would it make sense to move the function definitions into the switch statement below? Then… | ||||||||||
Done Inline ActionsI like this idea too, seems the code will self-document a little more this way. HooglyBoogly: I like this idea too, seems the code will self-document a little more this way. | ||||||||||
| static fn::CustomMF_SI_SI_SO<float, float, bool> float_less_equal_fn{ | ||||||||||
| "Less Equal", [](float a, float b) { return a <= b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float, float, bool> float_greater_than_fn{ | ||||||||||
| "Greater Than", [](float a, float b) { return a > b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float, float, bool> float_greater_equal_fn{ | ||||||||||
| "Greater Equal", [](float a, float b) { return a >= b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> float_equal_fn{ | ||||||||||
| "Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> float_not_equal_fn{ | ||||||||||
| "Not Equal", [](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }}; | ||||||||||
| /* Integer Functions */ | ||||||||||
Done Inline ActionsUnnecessary newline. There are some below too. HooglyBoogly: Unnecessary newline. There are some below too. | ||||||||||
| static fn::CustomMF_SI_SI_SO<int, int, bool> int_less_than_fn{ | ||||||||||
| "Less Than", [](int a, int b) { return a < b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<int, int, bool> int_less_equal_fn{ | ||||||||||
| "Less Equal", [](int a, int b) { return a <= b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<int, int, bool> int_greater_than_fn{ | ||||||||||
| "Greater Than", [](int a, int b) { return a > b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<int, int, bool> int_greater_equal_fn{ | ||||||||||
| "Greater Equal", [](int a, int b) { return a >= b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<int, int, bool> int_equal_fn{"Equal", | ||||||||||
| [](int a, int b) { return a == b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<int, int, bool> int_not_equal_fn{ | ||||||||||
| "Not Equal", [](int a, int b) { return a != b; }}; | ||||||||||
| /* Vector Functions */ | ||||||||||
| /* Greater Than */ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_greater_than_dotproduct_fn{ | ||||||||||
| "Greater Than - Dot Product", | ||||||||||
| [](float3 a, float3 b, float comp) { return float3::dot(a, b) > comp; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_greater_than_average_fn{ | ||||||||||
| "Greater Than - Average", | ||||||||||
Done Inline ActionsFor directions, I think angle_v3v3 is simpler here, since the dot product doesn't give you the angle directly. HooglyBoogly: For directions, I think `angle_v3v3` is simpler here, since the dot product doesn't give you… | ||||||||||
| [](float3 a, float3 b) { return (a.x + a.y + a.z) / 3.0f > (b.x + b.y + b.z) / 3.0f; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_greater_than_length_fn{ | ||||||||||
| "Greater Than - Length", [](float3 a, float3 b) { return a.length() > b.length(); }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_greater_than_element_fn{ | ||||||||||
| "Greater Than - Element-wise", | ||||||||||
| [](float3 a, float3 b) { return a.x > b.x && a.y > b.y && a.z > b.z; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_greater_than_direction_fn{ | ||||||||||
| "Greater Than - Direction", | ||||||||||
| [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) > angle; }}; | ||||||||||
| /* Greater Equal */ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_greater_equal_dotproduct_fn{ | ||||||||||
| "Greater Equal - Dot Product", | ||||||||||
| [](float3 a, float3 b, float comp) { return float3::dot(a, b) >= comp; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_greater_equal_average_fn{ | ||||||||||
| "Greater Equal - Average", | ||||||||||
| [](float3 a, float3 b) { return (a.x + a.y + a.z) / 3.0f >= (b.x + b.y + b.z) / 3.0f; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_greater_equal_length_fn{ | ||||||||||
| "Greater Equal - Length", [](float3 a, float3 b) { return a.length() >= b.length(); }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_greater_equal_element_fn{ | ||||||||||
| "Greater Equal - Element-wise", | ||||||||||
| [](float3 a, float3 b) { return a.x >= b.x && a.y >= b.y && a.z >= b.z; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_greater_equal_direction_fn{ | ||||||||||
| "Greater Equal - Direction", | ||||||||||
| [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) >= angle; }}; | ||||||||||
| /* Less Than */ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_less_than_dotproduct_fn{ | ||||||||||
| "Less Than - Dot Product", | ||||||||||
| [](float3 a, float3 b, float comp) { return float3::dot(a, b) < comp; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_less_than_average_fn{ | ||||||||||
| "Less Than - Average", | ||||||||||
| [](float3 a, float3 b) { return (a.x + a.y + a.z) / 3.0f < (b.x + b.y + b.z) / 3.0f; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_less_than_length_fn{ | ||||||||||
| "Less Than - Length", [](float3 a, float3 b) { return a.length() < b.length(); }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_less_than_element_fn{ | ||||||||||
| "Less Than - Element-wise", | ||||||||||
| [](float3 a, float3 b) { return a.x < b.x && a.y < b.y && a.z < b.z; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_less_than_direction_fn{ | ||||||||||
| "Less Than - Direction", | ||||||||||
| [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) < angle; }}; | ||||||||||
| /* Less Equal */ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_less_equal_dotproduct_fn{ | ||||||||||
| "Less Equal - Dot Product", | ||||||||||
| [](float3 a, float3 b, float comp) { return float3::dot(a, b) <= comp; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_less_equal_average_fn{ | ||||||||||
| "Less Equal - Average", | ||||||||||
| [](float3 a, float3 b) { return (a.x + a.y + a.z) / 3.0f <= (b.x + b.y + b.z) / 3.0f; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_less_equal_length_fn{ | ||||||||||
| "Less Equal - Length", [](float3 a, float3 b) { return a.length() <= b.length(); }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<float3, float3, bool> float3_less_equal_element_fn{ | ||||||||||
| "Less Equal - Element-wise", | ||||||||||
| [](float3 a, float3 b) { return a.x <= b.x && a.y <= b.y && a.z <= b.z; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_less_equal_direction_fn{ | ||||||||||
| "Less Equal - Direction", | ||||||||||
| [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) <= angle; }}; | ||||||||||
| /* Equal */ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> | ||||||||||
| float3_equal_dotproduct_fn{"Equal - Dot Product", | ||||||||||
| [](float3 a, float3 b, float comp, float epsilon) { | ||||||||||
| return abs(float3::dot(a, b) - comp) <= epsilon; | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_equal_average_fn{ | ||||||||||
| "Equal - Average", [](float3 a, float3 b, float epsilon) { | ||||||||||
| return abs((a.x + a.y + a.z) / 3.0f - (b.x + b.y + b.z) / 3.0f) <= epsilon; | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_equal_length_fn{ | ||||||||||
| "Equal - Length", | ||||||||||
| [](float3 a, float3 b, float epsilon) { return abs(a.length() - b.length()) <= epsilon; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_equal_element_fn{ | ||||||||||
| "Equal - Element-wise", [](float3 a, float3 b, float epsilon) { | ||||||||||
| return abs(a.x - b.x) <= epsilon && abs(a.y - b.y) <= epsilon && abs(a.z - b.z) <= epsilon; | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> float3_equal_direction_fn{ | ||||||||||
| "Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) { | ||||||||||
| return abs(angle_v3v3(a, b) - angle) <= epsilon; | ||||||||||
| }}; | ||||||||||
| /* Not Equal */ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> | ||||||||||
| float3_not_equal_dotproduct_fn{"Not Equal - Dot Product", | ||||||||||
| [](float3 a, float3 b, float comp, float epsilon) { | ||||||||||
| return abs(float3::dot(a, b) - comp) >= epsilon; | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_not_equal_average_fn{ | ||||||||||
| "Not Equal - Average", [](float3 a, float3 b, float epsilon) { | ||||||||||
| return abs((a.x + a.y + a.z) / 3.0f - (b.x + b.y + b.z) / 3.0f) > epsilon; | ||||||||||
| }}; | ||||||||||
Done Inline Actionsadd some utility method to compute the average, this is repeated a lot here JacquesLucke: add some utility method to compute the average, this is repeated a lot here | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_not_equal_length_fn{ | ||||||||||
| "Not Equal - Length", | ||||||||||
| [](float3 a, float3 b, float epsilon) { return abs(a.length() - b.length()) > epsilon; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> float3_not_equal_element_fn{ | ||||||||||
| "Not Equal - Element-wise", [](float3 a, float3 b, float epsilon) { | ||||||||||
| return abs(a.x - b.x) > epsilon && abs(a.y - b.y) > epsilon && abs(a.z - b.z) > epsilon; | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> | ||||||||||
| float3_not_equal_direction_fn{"Not Equal - Direction", | ||||||||||
| [](float3 a, float3 b, float angle, float epsilon) { | ||||||||||
| return abs(angle_v3v3(a, b) - angle) > epsilon; | ||||||||||
| }}; | ||||||||||
| /* Color Functions*/ | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, float, bool> color_equal_fn{ | ||||||||||
Done Inline ActionsComment style. JacquesLucke: Comment style. | ||||||||||
| "Equal", [](ColorGeometry4f a, ColorGeometry4f b, float epsilon) { | ||||||||||
| return abs(a.r - b.r) <= epsilon && abs(a.g - b.g) <= epsilon && abs(a.b - b.b) <= epsilon; | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, float, bool> | ||||||||||
| color_not_equal_fn{"Not Equal", [](ColorGeometry4f a, ColorGeometry4f b, float epsilon) { | ||||||||||
| return abs(a.r - b.r) > epsilon && abs(a.g - b.g) > epsilon && | ||||||||||
| abs(a.b - b.b) > epsilon; | ||||||||||
| }}; | ||||||||||
Done Inline ActionsI think rgb_to_grayscale would be right here HooglyBoogly: I think `rgb_to_grayscale` would be right here | ||||||||||
| static fn::CustomMF_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, bool> color_brighter_fn{ | ||||||||||
| "Brighter", [](ColorGeometry4f a, ColorGeometry4f b) { | ||||||||||
| return rgb_to_grayscale(a) > rgb_to_grayscale(b); | ||||||||||
| }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, bool> color_darker_fn{ | ||||||||||
| "Darker", [](ColorGeometry4f a, ColorGeometry4f b) { | ||||||||||
| return rgb_to_grayscale(a) < rgb_to_grayscale(b); | ||||||||||
| }}; | ||||||||||
| /* String Functions*/ | ||||||||||
| static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> string_greater_than_fn{ | ||||||||||
| "Greater Than", [](std::string a, std::string b) { return a > b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> string_greater_equal_fn{ | ||||||||||
| "Greater Equal", [](std::string a, std::string b) { return a >= b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> string_less_than_fn{ | ||||||||||
| "Less Than", [](std::string a, std::string b) { return a < b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> string_less_equal_fn{ | ||||||||||
| "Less Equal", [](std::string a, std::string b) { return a <= b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> string_equal_fn{ | ||||||||||
| "Equal", [](std::string a, std::string b) { return a == b; }}; | ||||||||||
| static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> string_not_equal_fn{ | ||||||||||
| "Not Equal", [](std::string a, std::string b) { return a != b; }}; | ||||||||||
| switch (data->data_type) { | ||||||||||
| case SOCK_FLOAT: | ||||||||||
| switch (data->operation) { | ||||||||||
| case NODE_COMPARE_LESS_THAN: | ||||||||||
| return &float_less_than_fn; | ||||||||||
| case NODE_COMPARE_LESS_EQUAL: | ||||||||||
| return &float_less_equal_fn; | ||||||||||
| case NODE_COMPARE_GREATER_THAN: | ||||||||||
| return &float_greater_than_fn; | ||||||||||
| case NODE_COMPARE_GREATER_EQUAL: | ||||||||||
| return &float_greater_equal_fn; | ||||||||||
| case NODE_COMPARE_EQUAL: | ||||||||||
| return &float_equal_fn; | ||||||||||
| case NODE_COMPARE_NOT_EQUAL: | ||||||||||
| return &float_not_equal_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case SOCK_INT: | ||||||||||
| switch (data->operation) { | ||||||||||
| case NODE_COMPARE_LESS_THAN: | ||||||||||
| return &int_less_than_fn; | ||||||||||
| case NODE_COMPARE_LESS_EQUAL: | ||||||||||
| return &int_less_equal_fn; | ||||||||||
| case NODE_COMPARE_GREATER_THAN: | ||||||||||
| return &int_greater_than_fn; | ||||||||||
| case NODE_COMPARE_GREATER_EQUAL: | ||||||||||
| return &int_greater_equal_fn; | ||||||||||
| case NODE_COMPARE_EQUAL: | ||||||||||
| return &int_equal_fn; | ||||||||||
| case NODE_COMPARE_NOT_EQUAL: | ||||||||||
| return &int_not_equal_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case SOCK_VECTOR: | ||||||||||
| switch (data->operation) { | ||||||||||
| case NODE_COMPARE_LESS_THAN: | ||||||||||
| switch (data->mode) { | ||||||||||
| case NODE_COMPARE_MODE_AVERAGE: | ||||||||||
| return &float3_less_than_average_fn; | ||||||||||
| case NODE_COMPARE_MODE_DOT_PRODUCT: | ||||||||||
| return &float3_less_than_dotproduct_fn; | ||||||||||
| case NODE_COMPARE_MODE_DIRECTION: | ||||||||||
| return &float3_less_than_direction_fn; | ||||||||||
| case NODE_COMPARE_MODE_ELEMENT: | ||||||||||
| return &float3_less_than_element_fn; | ||||||||||
| case NODE_COMPARE_MODE_LENGTH: | ||||||||||
| return &float3_less_equal_length_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case NODE_COMPARE_LESS_EQUAL: | ||||||||||
| switch (data->mode) { | ||||||||||
| case NODE_COMPARE_MODE_AVERAGE: | ||||||||||
| return &float3_less_equal_average_fn; | ||||||||||
| case NODE_COMPARE_MODE_DOT_PRODUCT: | ||||||||||
| return &float3_less_equal_dotproduct_fn; | ||||||||||
| case NODE_COMPARE_MODE_DIRECTION: | ||||||||||
| return &float3_less_equal_direction_fn; | ||||||||||
| case NODE_COMPARE_MODE_ELEMENT: | ||||||||||
| return &float3_less_equal_element_fn; | ||||||||||
| case NODE_COMPARE_MODE_LENGTH: | ||||||||||
| return &float3_less_equal_length_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case NODE_COMPARE_GREATER_THAN: | ||||||||||
| switch (data->mode) { | ||||||||||
| case NODE_COMPARE_MODE_AVERAGE: | ||||||||||
| return &float3_greater_than_average_fn; | ||||||||||
| case NODE_COMPARE_MODE_DOT_PRODUCT: | ||||||||||
| return &float3_greater_than_dotproduct_fn; | ||||||||||
| case NODE_COMPARE_MODE_DIRECTION: | ||||||||||
| return &float3_greater_than_direction_fn; | ||||||||||
| case NODE_COMPARE_MODE_ELEMENT: | ||||||||||
| return &float3_greater_than_element_fn; | ||||||||||
| case NODE_COMPARE_MODE_LENGTH: | ||||||||||
| return &float3_greater_than_length_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case NODE_COMPARE_GREATER_EQUAL: | ||||||||||
| switch (data->mode) { | ||||||||||
Done Inline Actions/home/hans/Blender-Git/blender/source/blender/nodes/function/nodes/node_fn_compare.cc:379:11: warning: this statement may fall through [-Wimplicit-fallthrough=]
379 | switch (data->mode) {
| ^~~~~~I think there should be a break at the end of the subcases. HooglyBoogly: ```
/home/hans/Blender-Git/blender/source/blender/nodes/function/nodes/node_fn_compare.cc:379… | ||||||||||
| case NODE_COMPARE_MODE_AVERAGE: | ||||||||||
| return &float3_greater_equal_average_fn; | ||||||||||
| case NODE_COMPARE_MODE_DOT_PRODUCT: | ||||||||||
| return &float3_greater_equal_dotproduct_fn; | ||||||||||
| case NODE_COMPARE_MODE_DIRECTION: | ||||||||||
| return &float3_greater_equal_direction_fn; | ||||||||||
| case NODE_COMPARE_MODE_ELEMENT: | ||||||||||
| return &float3_greater_equal_element_fn; | ||||||||||
| case NODE_COMPARE_MODE_LENGTH: | ||||||||||
| return &float3_greater_equal_length_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case NODE_COMPARE_EQUAL: | ||||||||||
| switch (data->mode) { | ||||||||||
| case NODE_COMPARE_MODE_AVERAGE: | ||||||||||
| return &float3_equal_average_fn; | ||||||||||
| case NODE_COMPARE_MODE_DOT_PRODUCT: | ||||||||||
| return &float3_equal_dotproduct_fn; | ||||||||||
| case NODE_COMPARE_MODE_DIRECTION: | ||||||||||
| return &float3_equal_direction_fn; | ||||||||||
| case NODE_COMPARE_MODE_ELEMENT: | ||||||||||
| return &float3_equal_element_fn; | ||||||||||
| case NODE_COMPARE_MODE_LENGTH: | ||||||||||
| return &float3_equal_length_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case NODE_COMPARE_NOT_EQUAL: | ||||||||||
| switch (data->mode) { | ||||||||||
| case NODE_COMPARE_MODE_AVERAGE: | ||||||||||
| return &float3_not_equal_average_fn; | ||||||||||
| case NODE_COMPARE_MODE_DOT_PRODUCT: | ||||||||||
| return &float3_not_equal_dotproduct_fn; | ||||||||||
| case NODE_COMPARE_MODE_DIRECTION: | ||||||||||
| return &float3_not_equal_direction_fn; | ||||||||||
| case NODE_COMPARE_MODE_ELEMENT: | ||||||||||
| return &float3_not_equal_element_fn; | ||||||||||
| case NODE_COMPARE_MODE_LENGTH: | ||||||||||
| return &float3_not_equal_length_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case SOCK_RGBA: | ||||||||||
| switch (data->operation) { | ||||||||||
| case NODE_COMPARE_EQUAL: | ||||||||||
| return &color_equal_fn; | ||||||||||
| case NODE_COMPARE_NOT_EQUAL: | ||||||||||
| return &color_not_equal_fn; | ||||||||||
| case NODE_COMPARE_COLOR_BRIGHTER: | ||||||||||
| return &color_brighter_fn; | ||||||||||
| case NODE_COMPARE_COLOR_DARKER: | ||||||||||
| return &color_darker_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| case SOCK_STRING: | ||||||||||
| switch (data->operation) { | ||||||||||
| case NODE_COMPARE_GREATER_THAN: | ||||||||||
| return &string_greater_than_fn; | ||||||||||
| case NODE_COMPARE_GREATER_EQUAL: | ||||||||||
| return &string_greater_equal_fn; | ||||||||||
| case NODE_COMPARE_LESS_THAN: | ||||||||||
| return &string_less_than_fn; | ||||||||||
| case NODE_COMPARE_LESS_EQUAL: | ||||||||||
| return &string_less_equal_fn; | ||||||||||
| case NODE_COMPARE_EQUAL: | ||||||||||
| return &string_equal_fn; | ||||||||||
| case NODE_COMPARE_NOT_EQUAL: | ||||||||||
| return &string_not_equal_fn; | ||||||||||
| } | ||||||||||
| break; | ||||||||||
| } | ||||||||||
| return nullptr; | ||||||||||
| } | ||||||||||
| static void fn_node_compare_build_multi_function(NodeMultiFunctionBuilder &builder) | ||||||||||
| { | ||||||||||
| const fn::MultiFunction *fn = get_multi_function(builder.node()); | ||||||||||
| builder.set_matching_fn(fn); | ||||||||||
| } | ||||||||||
| } // namespace blender::nodes | ||||||||||
| void register_node_type_fn_compare() | ||||||||||
| { | ||||||||||
| static bNodeType ntype; | ||||||||||
| fn_node_type_base(&ntype, FN_NODE_COMPARE, "Compare", NODE_CLASS_CONVERTER, 0); | ||||||||||
| ntype.declare = blender::nodes::fn_node_compare_declare; | ||||||||||
| node_type_label(&ntype, blender::nodes::node_compare_label); | ||||||||||
| node_type_update(&ntype, blender::nodes::node_compare_update); | ||||||||||
| node_type_init(&ntype, blender::nodes::node_compare_init); | ||||||||||
| node_type_storage( | ||||||||||
| &ntype, "NodeFunctionCompare", node_free_standard_storage, node_copy_standard_storage); | ||||||||||
| ntype.build_multi_function = blender::nodes::fn_node_compare_build_multi_function; | ||||||||||
| ntype.draw_buttons = blender::nodes::geo_node_compare_layout; | ||||||||||
| nodeRegisterType(&ntype); | ||||||||||
| } | ||||||||||
Maybe a default of 0.9f makes more sense? Since usually you are comparing to see if the dot products are equal-ish.
Also, maybe the name "Threshold" would make more sense, since the dot product has to be higher than that value.