Geometry Nodes: Generalized Compare Node
Replace compare floats node with a generalized compare node. The node allows for the comparison of float, int, string, color, and vector. The datatypes support the following operators: Float, Int: <, >, <=, >=, ==, != String: ==, != Color: ==, !=, lighter, darker (using rgb_to_grayscale value as the brightness value) Vector Supports 5 comparison modes for: ==, !=, <, >, <=, >= Average: The average of the components of the vectors are compared. Dot Product: The dot product of the vectors are compared. Direction: The angle between the vectors is compared to an angle Element-wise: The individual components of the vectors are compared. Length: The lengths of the vectors are compared. Differential Revision: https://developer.blender.org/D13228
This commit is contained in:
parent
f8dd03d3dd
commit
1757840843
|
@ -750,7 +750,7 @@ geometry_node_categories = [
|
|||
NodeItem("ShaderNodeMath"),
|
||||
NodeItem("FunctionNodeBooleanMath"),
|
||||
NodeItem("FunctionNodeRotateEuler"),
|
||||
NodeItem("FunctionNodeCompareFloats"),
|
||||
NodeItem("FunctionNodeCompare"),
|
||||
NodeItem("FunctionNodeFloatToInt"),
|
||||
NodeItem("GeometryNodeSwitch"),
|
||||
NodeItem("FunctionNodeRandomValue"),
|
||||
|
|
|
@ -1563,7 +1563,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
|
|||
* \{ */
|
||||
|
||||
#define FN_NODE_BOOLEAN_MATH 1200
|
||||
#define FN_NODE_COMPARE_FLOATS 1202
|
||||
#define FN_NODE_COMPARE 1202
|
||||
#define FN_NODE_LEGACY_RANDOM_FLOAT 1206
|
||||
#define FN_NODE_INPUT_VECTOR 1207
|
||||
#define FN_NODE_INPUT_STRING 1208
|
||||
|
|
|
@ -5970,7 +5970,7 @@ static void registerFunctionNodes()
|
|||
|
||||
register_node_type_fn_align_euler_to_vector();
|
||||
register_node_type_fn_boolean_math();
|
||||
register_node_type_fn_float_compare();
|
||||
register_node_type_fn_compare();
|
||||
register_node_type_fn_float_to_int();
|
||||
register_node_type_fn_input_bool();
|
||||
register_node_type_fn_input_color();
|
||||
|
|
|
@ -2191,7 +2191,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
if (ntree->type != NTREE_GEOMETRY) {
|
||||
continue;
|
||||
}
|
||||
version_node_id(ntree, FN_NODE_COMPARE_FLOATS, "FunctionNodeCompareFloats");
|
||||
version_node_id(ntree, FN_NODE_COMPARE, "FunctionNodeCompareFloats");
|
||||
version_node_id(ntree, GEO_NODE_CAPTURE_ATTRIBUTE, "GeometryNodeCaptureAttribute");
|
||||
version_node_id(ntree, GEO_NODE_MESH_BOOLEAN, "GeometryNodeMeshBoolean");
|
||||
version_node_id(ntree, GEO_NODE_FILL_CURVE, "GeometryNodeFillCurve");
|
||||
|
@ -2414,6 +2414,19 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
version_node_add_socket_if_not_exist(
|
||||
ntree, node, SOCK_OUT, SOCK_INT, PROP_NONE, "Index", "Index");
|
||||
}
|
||||
|
||||
/* Convert float compare into a more general compare node. */
|
||||
if (node->type == FN_NODE_COMPARE) {
|
||||
if (node->storage == NULL) {
|
||||
NodeFunctionCompare *data = (NodeFunctionCompare *)MEM_callocN(
|
||||
sizeof(NodeFunctionCompare), __func__);
|
||||
data->data_type = SOCK_FLOAT;
|
||||
data->operation = node->custom1;
|
||||
strcpy(node->idname, "FunctionNodeCompare");
|
||||
node->update = NODE_UPDATE;
|
||||
node->storage = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1606,6 +1606,16 @@ typedef struct NodeGeometryViewer {
|
|||
int8_t data_type;
|
||||
} NodeGeometryViewer;
|
||||
|
||||
typedef struct NodeFunctionCompare {
|
||||
/* NodeCompareOperation */
|
||||
int8_t operation;
|
||||
/* eNodeSocketDatatype */
|
||||
int8_t data_type;
|
||||
/* NodeCompareMode */
|
||||
int8_t mode;
|
||||
char _pad[1];
|
||||
} NodeFunctionCompare;
|
||||
|
||||
/* script node mode */
|
||||
#define NODE_SCRIPT_INTERNAL 0
|
||||
#define NODE_SCRIPT_EXTERNAL 1
|
||||
|
@ -1886,14 +1896,25 @@ enum {
|
|||
};
|
||||
|
||||
/* Float compare node operations. */
|
||||
typedef enum FloatCompareOperation {
|
||||
NODE_FLOAT_COMPARE_LESS_THAN = 0,
|
||||
NODE_FLOAT_COMPARE_LESS_EQUAL = 1,
|
||||
NODE_FLOAT_COMPARE_GREATER_THAN = 2,
|
||||
NODE_FLOAT_COMPARE_GREATER_EQUAL = 3,
|
||||
NODE_FLOAT_COMPARE_EQUAL = 4,
|
||||
NODE_FLOAT_COMPARE_NOT_EQUAL = 5,
|
||||
} FloatCompareOperation;
|
||||
typedef enum NodeCompareMode {
|
||||
NODE_COMPARE_MODE_ELEMENT = 0,
|
||||
NODE_COMPARE_MODE_LENGTH = 1,
|
||||
NODE_COMPARE_MODE_AVERAGE = 2,
|
||||
NODE_COMPARE_MODE_DOT_PRODUCT = 3,
|
||||
NODE_COMPARE_MODE_DIRECTION = 4
|
||||
} NodeCompareMode;
|
||||
|
||||
typedef enum NodeCompareOperation {
|
||||
NODE_COMPARE_LESS_THAN = 0,
|
||||
NODE_COMPARE_LESS_EQUAL = 1,
|
||||
NODE_COMPARE_GREATER_THAN = 2,
|
||||
NODE_COMPARE_GREATER_EQUAL = 3,
|
||||
NODE_COMPARE_EQUAL = 4,
|
||||
NODE_COMPARE_NOT_EQUAL = 5,
|
||||
NODE_COMPARE_COLOR_BRIGHTER = 6,
|
||||
NODE_COMPARE_COLOR_DARKER = 7,
|
||||
|
||||
} NodeCompareOperation;
|
||||
|
||||
/* Float to Int node operations. */
|
||||
typedef enum FloatToIntRoundingMode {
|
||||
|
|
|
@ -172,6 +172,7 @@ DEF_ENUM(rna_enum_mapping_type_items)
|
|||
DEF_ENUM(rna_enum_node_vec_math_items)
|
||||
DEF_ENUM(rna_enum_node_boolean_math_items)
|
||||
DEF_ENUM(rna_enum_node_float_compare_items)
|
||||
DEF_ENUM(rna_enum_node_compare_operation_items)
|
||||
DEF_ENUM(rna_enum_node_filter_items)
|
||||
DEF_ENUM(rna_enum_node_float_to_int_items)
|
||||
DEF_ENUM(rna_enum_node_map_range_items)
|
||||
|
|
|
@ -305,32 +305,28 @@ const EnumPropertyItem rna_enum_node_boolean_math_items[] = {
|
|||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_node_float_compare_items[] = {
|
||||
{NODE_FLOAT_COMPARE_LESS_THAN,
|
||||
{NODE_COMPARE_LESS_THAN,
|
||||
"LESS_THAN",
|
||||
0,
|
||||
"Less Than",
|
||||
"True when the first input is smaller than second input"},
|
||||
{NODE_FLOAT_COMPARE_LESS_EQUAL,
|
||||
{NODE_COMPARE_LESS_EQUAL,
|
||||
"LESS_EQUAL",
|
||||
0,
|
||||
"Less Than or Equal",
|
||||
"True when the first input is smaller than the second input or equal"},
|
||||
{NODE_FLOAT_COMPARE_GREATER_THAN,
|
||||
{NODE_COMPARE_GREATER_THAN,
|
||||
"GREATER_THAN",
|
||||
0,
|
||||
"Greater Than",
|
||||
"True when the first input is greater than the second input"},
|
||||
{NODE_FLOAT_COMPARE_GREATER_EQUAL,
|
||||
{NODE_COMPARE_GREATER_EQUAL,
|
||||
"GREATER_EQUAL",
|
||||
0,
|
||||
"Greater Than or Equal",
|
||||
"True when the first input is greater than the second input or equal"},
|
||||
{NODE_FLOAT_COMPARE_EQUAL,
|
||||
"EQUAL",
|
||||
0,
|
||||
"Equal",
|
||||
"True when both inputs are approximately equal"},
|
||||
{NODE_FLOAT_COMPARE_NOT_EQUAL,
|
||||
{NODE_COMPARE_EQUAL, "EQUAL", 0, "Equal", "True when both inputs are approximately equal"},
|
||||
{NODE_COMPARE_NOT_EQUAL,
|
||||
"NOT_EQUAL",
|
||||
0,
|
||||
"Not Equal",
|
||||
|
@ -338,6 +334,42 @@ const EnumPropertyItem rna_enum_node_float_compare_items[] = {
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_node_compare_operation_items[] = {
|
||||
{NODE_COMPARE_LESS_THAN,
|
||||
"LESS_THAN",
|
||||
0,
|
||||
"Less Than",
|
||||
"True when the first input is smaller than second input"},
|
||||
{NODE_COMPARE_LESS_EQUAL,
|
||||
"LESS_EQUAL",
|
||||
0,
|
||||
"Less Than or Equal",
|
||||
"True when the first input is smaller than the second input or equal"},
|
||||
{NODE_COMPARE_GREATER_THAN,
|
||||
"GREATER_THAN",
|
||||
0,
|
||||
"Greater Than",
|
||||
"True when the first input is greater than the second input"},
|
||||
{NODE_COMPARE_GREATER_EQUAL,
|
||||
"GREATER_EQUAL",
|
||||
0,
|
||||
"Greater Than or Equal",
|
||||
"True when the first input is greater than the second input or equal"},
|
||||
{NODE_COMPARE_EQUAL, "EQUAL", 0, "Equal", "True when both inputs are approximately equal"},
|
||||
{NODE_COMPARE_NOT_EQUAL,
|
||||
"NOT_EQUAL",
|
||||
0,
|
||||
"Not Equal",
|
||||
"True when both inputs are not approximately equal"},
|
||||
{NODE_COMPARE_COLOR_BRIGHTER,
|
||||
"BRIGHTER",
|
||||
0,
|
||||
"Brighter",
|
||||
"True when the first input is brighter"},
|
||||
{NODE_COMPARE_COLOR_DARKER, "DARKER", 0, "Darker", "True when the first input is darker"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_node_float_to_int_items[] = {
|
||||
{FN_NODE_FLOAT_TO_INT_ROUND,
|
||||
"ROUND",
|
||||
|
@ -2070,10 +2102,76 @@ static const EnumPropertyItem *rna_GeometryNodeSwitch_type_itemf(bContext *UNUSE
|
|||
return itemf_function_check(node_socket_data_type_items, switch_type_supported);
|
||||
}
|
||||
|
||||
static bool compare_type_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value, SOCK_FLOAT, SOCK_INT, SOCK_VECTOR, SOCK_STRING, SOCK_RGBA);
|
||||
}
|
||||
|
||||
static bool compare_main_operation_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return !ELEM(item->value, NODE_COMPARE_COLOR_BRIGHTER, NODE_COMPARE_COLOR_DARKER);
|
||||
}
|
||||
|
||||
static bool compare_rgba_operation_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value,
|
||||
NODE_COMPARE_EQUAL,
|
||||
NODE_COMPARE_NOT_EQUAL,
|
||||
NODE_COMPARE_COLOR_BRIGHTER,
|
||||
NODE_COMPARE_COLOR_DARKER);
|
||||
}
|
||||
|
||||
static bool compare_string_operation_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL);
|
||||
}
|
||||
|
||||
static bool compare_other_operation_supported(const EnumPropertyItem *UNUSED(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_FunctionNodeCompare_type_itemf(bContext *UNUSED(C),
|
||||
PointerRNA *UNUSED(ptr),
|
||||
PropertyRNA *UNUSED(prop),
|
||||
bool *r_free)
|
||||
{
|
||||
*r_free = true;
|
||||
return itemf_function_check(node_socket_data_type_items, compare_type_supported);
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_FunctionNodeCompare_operation_itemf(bContext *UNUSED(C),
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *UNUSED(prop),
|
||||
bool *r_free)
|
||||
{
|
||||
*r_free = true;
|
||||
bNode *node = ptr->data;
|
||||
NodeFunctionCompare *data = (NodeFunctionCompare *)node->storage;
|
||||
|
||||
if (ELEM(data->data_type, SOCK_FLOAT, SOCK_INT, SOCK_VECTOR)) {
|
||||
return itemf_function_check(rna_enum_node_compare_operation_items,
|
||||
compare_main_operation_supported);
|
||||
}
|
||||
else if (data->data_type == SOCK_STRING) {
|
||||
return itemf_function_check(rna_enum_node_compare_operation_items,
|
||||
compare_string_operation_supported);
|
||||
}
|
||||
else if (data->data_type == SOCK_RGBA) {
|
||||
return itemf_function_check(rna_enum_node_compare_operation_items,
|
||||
compare_rgba_operation_supported);
|
||||
}
|
||||
else {
|
||||
return itemf_function_check(rna_enum_node_compare_operation_items,
|
||||
compare_other_operation_supported);
|
||||
}
|
||||
}
|
||||
|
||||
static bool attribute_clamp_type_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_INT32, CD_PROP_COLOR);
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_GeometryNodeAttributeClamp_type_itemf(bContext *UNUSED(C),
|
||||
PointerRNA *UNUSED(ptr),
|
||||
PropertyRNA *UNUSED(prop),
|
||||
|
@ -2150,6 +2248,30 @@ static void rna_GeometryNodeAttributeRandomize_data_type_update(Main *bmain,
|
|||
rna_Node_socket_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_GeometryNodeCompare_data_type_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bNode *node = ptr->data;
|
||||
NodeFunctionCompare *node_storage = (NodeFunctionCompare *)node->storage;
|
||||
|
||||
if (node_storage->data_type == SOCK_RGBA && !ELEM(node_storage->operation,
|
||||
NODE_COMPARE_EQUAL,
|
||||
NODE_COMPARE_NOT_EQUAL,
|
||||
NODE_COMPARE_COLOR_BRIGHTER,
|
||||
NODE_COMPARE_COLOR_DARKER)) {
|
||||
node_storage->operation = NODE_COMPARE_EQUAL;
|
||||
}
|
||||
else if (node_storage->data_type == SOCK_STRING &&
|
||||
!ELEM(node_storage->operation, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL)) {
|
||||
node_storage->operation = NODE_COMPARE_EQUAL;
|
||||
}
|
||||
else if (node_storage->data_type != SOCK_RGBA &&
|
||||
ELEM(node_storage->operation, NODE_COMPARE_COLOR_BRIGHTER, NODE_COMPARE_COLOR_DARKER)) {
|
||||
node_storage->operation = NODE_COMPARE_EQUAL;
|
||||
}
|
||||
|
||||
rna_Node_socket_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static bool attribute_convert_type_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value,
|
||||
|
@ -4865,15 +4987,57 @@ static void def_boolean_math(StructRNA *srna)
|
|||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
|
||||
}
|
||||
|
||||
static void def_float_compare(StructRNA *srna)
|
||||
static void def_compare(StructRNA *srna)
|
||||
{
|
||||
|
||||
static const EnumPropertyItem mode_items[] = {
|
||||
{NODE_COMPARE_MODE_ELEMENT,
|
||||
"ELEMENT",
|
||||
0,
|
||||
"Element-Wise",
|
||||
"Compare each element of the input vectors"},
|
||||
{NODE_COMPARE_MODE_LENGTH, "LENGTH", 0, "Length", "Compare the length of the input vectors"},
|
||||
{NODE_COMPARE_MODE_AVERAGE,
|
||||
"AVERAGE",
|
||||
0,
|
||||
"Average",
|
||||
"Compare the average of the input vectors elements"},
|
||||
{NODE_COMPARE_MODE_DOT_PRODUCT,
|
||||
"DOT_PRODUCT",
|
||||
0,
|
||||
"Dot Product",
|
||||
"Compare the dot products of the input vectors"},
|
||||
{NODE_COMPARE_MODE_DIRECTION,
|
||||
"DIRECTION",
|
||||
0,
|
||||
"Direction",
|
||||
"Compare the direction of the input vectors"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
PropertyRNA *prop;
|
||||
|
||||
RNA_def_struct_sdna_from(srna, "NodeFunctionCompare", "storage");
|
||||
|
||||
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, rna_enum_node_float_compare_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_FunctionNodeCompare_operation_itemf");
|
||||
RNA_def_property_enum_items(prop, rna_enum_node_compare_operation_items);
|
||||
RNA_def_property_enum_default(prop, NODE_COMPARE_EQUAL);
|
||||
RNA_def_property_ui_text(prop, "Operation", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
|
||||
|
||||
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_FunctionNodeCompare_type_itemf");
|
||||
RNA_def_property_enum_items(prop, node_socket_data_type_items);
|
||||
RNA_def_property_enum_default(prop, SOCK_FLOAT);
|
||||
RNA_def_property_ui_text(prop, "Input Type", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNodeCompare_data_type_update");
|
||||
|
||||
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, mode_items);
|
||||
RNA_def_property_enum_default(prop, NODE_COMPARE_MODE_ELEMENT);
|
||||
RNA_def_property_ui_text(prop, "Mode", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
|
||||
}
|
||||
|
||||
static void def_float_to_int(StructRNA *srna)
|
||||
|
@ -9589,7 +9753,7 @@ static void def_geo_attribute_attribute_compare(StructRNA *srna)
|
|||
|
||||
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_node_float_compare_items);
|
||||
RNA_def_property_enum_default(prop, NODE_FLOAT_COMPARE_GREATER_THAN);
|
||||
RNA_def_property_enum_default(prop, NODE_COMPARE_GREATER_THAN);
|
||||
RNA_def_property_ui_text(prop, "Operation", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ set(SRC
|
|||
|
||||
function/nodes/node_fn_align_euler_to_vector.cc
|
||||
function/nodes/node_fn_boolean_math.cc
|
||||
function/nodes/node_fn_float_compare.cc
|
||||
function/nodes/node_fn_compare.cc
|
||||
function/nodes/node_fn_float_to_int.cc
|
||||
function/nodes/node_fn_input_bool.cc
|
||||
function/nodes/node_fn_input_color.cc
|
||||
|
|
|
@ -24,7 +24,7 @@ void register_node_type_fn_legacy_random_float(void);
|
|||
|
||||
void register_node_type_fn_align_euler_to_vector(void);
|
||||
void register_node_type_fn_boolean_math(void);
|
||||
void register_node_type_fn_float_compare(void);
|
||||
void register_node_type_fn_compare(void);
|
||||
void register_node_type_fn_float_to_int(void);
|
||||
void register_node_type_fn_input_bool(void);
|
||||
void register_node_type_fn_input_color(void);
|
||||
|
|
|
@ -204,7 +204,7 @@ inline bool try_dispatch_float_math_fl_fl_fl_to_fl(const int operation, Callback
|
|||
* This is similar to try_dispatch_float_math_fl_to_fl, just with a different callback signature.
|
||||
*/
|
||||
template<typename Callback>
|
||||
inline bool try_dispatch_float_math_fl_fl_to_bool(const FloatCompareOperation operation,
|
||||
inline bool try_dispatch_float_math_fl_fl_to_bool(const NodeCompareOperation operation,
|
||||
Callback &&callback)
|
||||
{
|
||||
const FloatMathOperationInfo *info = get_float_compare_operation_info(operation);
|
||||
|
@ -219,13 +219,13 @@ inline bool try_dispatch_float_math_fl_fl_to_bool(const FloatCompareOperation op
|
|||
};
|
||||
|
||||
switch (operation) {
|
||||
case NODE_FLOAT_COMPARE_LESS_THAN:
|
||||
case NODE_COMPARE_LESS_THAN:
|
||||
return dispatch([](float a, float b) { return a < b; });
|
||||
case NODE_FLOAT_COMPARE_LESS_EQUAL:
|
||||
case NODE_COMPARE_LESS_EQUAL:
|
||||
return dispatch([](float a, float b) { return a <= b; });
|
||||
case NODE_FLOAT_COMPARE_GREATER_THAN:
|
||||
case NODE_COMPARE_GREATER_THAN:
|
||||
return dispatch([](float a, float b) { return a > b; });
|
||||
case NODE_FLOAT_COMPARE_GREATER_EQUAL:
|
||||
case NODE_COMPARE_GREATER_EQUAL:
|
||||
return dispatch([](float a, float b) { return a >= b; });
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -267,7 +267,7 @@ DefNode(FunctionNode, FN_NODE_LEGACY_RANDOM_FLOAT, 0, "LEGACY_RANDOM_FLOAT", Leg
|
|||
|
||||
DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler To Vector", "")
|
||||
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
|
||||
DefNode(FunctionNode, FN_NODE_COMPARE_FLOATS, def_float_compare, "COMPARE_FLOATS", CompareFloats, "Compare Floats", "")
|
||||
DefNode(FunctionNode, FN_NODE_COMPARE, def_compare, "COMPARE", Compare, "Compare", "")
|
||||
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
|
||||
DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "")
|
||||
DefNode(FunctionNode, FN_NODE_INPUT_COLOR, def_fn_input_color, "INPUT_COLOR", InputColor, "Color", "")
|
||||
|
|
|
@ -0,0 +1,490 @@
|
|||
/*
|
||||
* 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::node_fn_compare_cc {
|
||||
|
||||
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.9f);
|
||||
b.add_input<decl::Float>(N_("Angle")).default_value(0.0872665f).subtype(PROP_ANGLE);
|
||||
b.add_input<decl::Float>(N_("Epsilon")).default_value(0.001).min(-10000.0f).max(10000.0f);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
nodeSetSocketAvailability(ntree, socket, socket->type == (eNodeSocketDatatype)data->data_type);
|
||||
}
|
||||
|
||||
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 float component_average(float3 a)
|
||||
{
|
||||
return (a.x + a.y + a.z) / 3.0f;
|
||||
}
|
||||
|
||||
static const fn::MultiFunction *get_multi_function(bNode &node)
|
||||
{
|
||||
const NodeFunctionCompare *data = (NodeFunctionCompare *)node.storage;
|
||||
|
||||
switch (data->data_type) {
|
||||
case SOCK_FLOAT:
|
||||
switch (data->operation) {
|
||||
case NODE_COMPARE_LESS_THAN: {
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> fn{
|
||||
"Less Than", [](float a, float b) { return a < b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_LESS_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> fn{
|
||||
"Less Equal", [](float a, float b) { return a <= b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_GREATER_THAN: {
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> fn{
|
||||
"Greater Than", [](float a, float b) { return a > b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_GREATER_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> fn{
|
||||
"Greater Equal", [](float a, float b) { return a >= b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> fn{
|
||||
"Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_NOT_EQUAL:
|
||||
static fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> fn{
|
||||
"Not Equal",
|
||||
[](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }};
|
||||
return &fn;
|
||||
}
|
||||
break;
|
||||
case SOCK_INT:
|
||||
switch (data->operation) {
|
||||
case NODE_COMPARE_LESS_THAN: {
|
||||
static fn::CustomMF_SI_SI_SO<int, int, bool> fn{"Less Than",
|
||||
[](int a, int b) { return a < b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_LESS_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<int, int, bool> fn{"Less Equal",
|
||||
[](int a, int b) { return a <= b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_GREATER_THAN: {
|
||||
static fn::CustomMF_SI_SI_SO<int, int, bool> fn{"Greater Than",
|
||||
[](int a, int b) { return a > b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_GREATER_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<int, int, bool> fn{"Greater Equal",
|
||||
[](int a, int b) { return a >= b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<int, int, bool> fn{"Equal",
|
||||
[](int a, int b) { return a == b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_NOT_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<int, int, bool> fn{"Not Equal",
|
||||
[](int a, int b) { return a != b; }};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SOCK_VECTOR:
|
||||
switch (data->operation) {
|
||||
case NODE_COMPARE_LESS_THAN:
|
||||
switch (data->mode) {
|
||||
case NODE_COMPARE_MODE_AVERAGE: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Less Than - Average",
|
||||
[](float3 a, float3 b) { return component_average(a) < component_average(b); }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DOT_PRODUCT: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Less Than - Dot Product",
|
||||
[](float3 a, float3 b, float comp) { return float3::dot(a, b) < comp; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DIRECTION: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Less Than - Direction",
|
||||
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) < angle; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_ELEMENT: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Less Than - Element-wise",
|
||||
[](float3 a, float3 b) { return a.x < b.x && a.y < b.y && a.z < b.z; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_LENGTH: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Less Than - Length",
|
||||
[](float3 a, float3 b) { return a.length() < b.length(); }};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODE_COMPARE_LESS_EQUAL:
|
||||
switch (data->mode) {
|
||||
case NODE_COMPARE_MODE_AVERAGE: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Less Equal - Average",
|
||||
[](float3 a, float3 b) { return component_average(a) <= component_average(b); }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DOT_PRODUCT: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Less Equal - Dot Product",
|
||||
[](float3 a, float3 b, float comp) { return float3::dot(a, b) <= comp; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DIRECTION: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Less Equal - Direction",
|
||||
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) <= angle; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_ELEMENT: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Less Equal - Element-wise",
|
||||
[](float3 a, float3 b) { return a.x <= b.x && a.y <= b.y && a.z <= b.z; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_LENGTH: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Less Equal - Length",
|
||||
[](float3 a, float3 b) { return a.length() <= b.length(); }};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODE_COMPARE_GREATER_THAN:
|
||||
switch (data->mode) {
|
||||
case NODE_COMPARE_MODE_AVERAGE: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Greater Than - Average",
|
||||
[](float3 a, float3 b) { return component_average(a) > component_average(b); }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DOT_PRODUCT: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Greater Than - Dot Product",
|
||||
[](float3 a, float3 b, float comp) { return float3::dot(a, b) > comp; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DIRECTION: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Greater Than - Direction",
|
||||
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) > angle; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_ELEMENT: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Greater Than - Element-wise",
|
||||
[](float3 a, float3 b) { return a.x > b.x && a.y > b.y && a.z > b.z; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_LENGTH: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Greater Than - Length",
|
||||
[](float3 a, float3 b) { return a.length() > b.length(); }};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODE_COMPARE_GREATER_EQUAL:
|
||||
switch (data->mode) {
|
||||
case NODE_COMPARE_MODE_AVERAGE: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Greater Equal - Average",
|
||||
[](float3 a, float3 b) { return component_average(a) >= component_average(b); }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DOT_PRODUCT: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Greater Equal - Dot Product",
|
||||
[](float3 a, float3 b, float comp) { return float3::dot(a, b) >= comp; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DIRECTION: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Greater Equal - Direction",
|
||||
[](float3 a, float3 b, float angle) { return angle_v3v3(a, b) >= angle; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_ELEMENT: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Greater Equal - Element-wise",
|
||||
[](float3 a, float3 b) { return a.x >= b.x && a.y >= b.y && a.z >= b.z; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_LENGTH: {
|
||||
static fn::CustomMF_SI_SI_SO<float3, float3, bool> fn{
|
||||
"Greater Equal - Length",
|
||||
[](float3 a, float3 b) { return a.length() >= b.length(); }};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODE_COMPARE_EQUAL:
|
||||
switch (data->mode) {
|
||||
case NODE_COMPARE_MODE_AVERAGE: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Equal - Average", [](float3 a, float3 b, float epsilon) {
|
||||
return abs(component_average(a) - component_average(b)) <= epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DOT_PRODUCT: {
|
||||
static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> fn{
|
||||
"Equal - Dot Product", [](float3 a, float3 b, float comp, float epsilon) {
|
||||
return abs(float3::dot(a, b) - comp) <= epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DIRECTION: {
|
||||
static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> fn{
|
||||
"Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) {
|
||||
return abs(angle_v3v3(a, b) - angle) <= epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_ELEMENT: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> 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;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_LENGTH: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Equal - Length", [](float3 a, float3 b, float epsilon) {
|
||||
return abs(a.length() - b.length()) <= epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NODE_COMPARE_NOT_EQUAL:
|
||||
switch (data->mode) {
|
||||
case NODE_COMPARE_MODE_AVERAGE: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Not Equal - Average", [](float3 a, float3 b, float epsilon) {
|
||||
return abs(component_average(a) - component_average(b)) > epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DOT_PRODUCT: {
|
||||
static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> fn{
|
||||
"Not Equal - Dot Product", [](float3 a, float3 b, float comp, float epsilon) {
|
||||
return abs(float3::dot(a, b) - comp) >= epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_DIRECTION: {
|
||||
static fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float, float, bool> fn{
|
||||
"Not Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) {
|
||||
return abs(angle_v3v3(a, b) - angle) > epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_ELEMENT: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> 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;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_MODE_LENGTH: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, bool> fn{
|
||||
"Not Equal - Length", [](float3 a, float3 b, float epsilon) {
|
||||
return abs(a.length() - b.length()) > epsilon;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SOCK_RGBA:
|
||||
switch (data->operation) {
|
||||
case NODE_COMPARE_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, float, bool> fn{
|
||||
"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;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_NOT_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, float, bool> 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;
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_COLOR_BRIGHTER: {
|
||||
static fn::CustomMF_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, bool> fn{
|
||||
"Brighter", [](ColorGeometry4f a, ColorGeometry4f b) {
|
||||
return rgb_to_grayscale(a) > rgb_to_grayscale(b);
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_COLOR_DARKER: {
|
||||
static fn::CustomMF_SI_SI_SO<ColorGeometry4f, ColorGeometry4f, bool> fn{
|
||||
"Darker", [](ColorGeometry4f a, ColorGeometry4f b) {
|
||||
return rgb_to_grayscale(a) < rgb_to_grayscale(b);
|
||||
}};
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
switch (data->operation) {
|
||||
case NODE_COMPARE_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> fn{
|
||||
"Equal", [](std::string a, std::string b) { return a == b; }};
|
||||
return &fn;
|
||||
}
|
||||
case NODE_COMPARE_NOT_EQUAL: {
|
||||
static fn::CustomMF_SI_SI_SO<std::string, std::string, bool> fn{
|
||||
"Not Equal", [](std::string a, std::string b) { return a != b; }};
|
||||
return &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::node_fn_compare_cc
|
||||
|
||||
void register_node_type_fn_compare()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_fn_compare_cc;
|
||||
|
||||
static bNodeType ntype;
|
||||
fn_node_type_base(&ntype, FN_NODE_COMPARE, "Compare", NODE_CLASS_CONVERTER, 0);
|
||||
ntype.declare = file_ns::fn_node_compare_declare;
|
||||
node_type_label(&ntype, file_ns::node_compare_label);
|
||||
node_type_update(&ntype, file_ns::node_compare_update);
|
||||
node_type_init(&ntype, file_ns::node_compare_init);
|
||||
node_type_storage(
|
||||
&ntype, "NodeFunctionCompare", node_free_standard_storage, node_copy_standard_storage);
|
||||
ntype.build_multi_function = file_ns::fn_node_compare_build_multi_function;
|
||||
ntype.draw_buttons = file_ns::geo_node_compare_layout;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
* 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 "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
static void fn_node_float_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::Float>(N_("Epsilon")).default_value(0.001f).min(-10000.0f).max(10000.0f);
|
||||
b.add_output<decl::Bool>(N_("Result"));
|
||||
};
|
||||
|
||||
static void geo_node_float_compare_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_float_compare_update(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
bNodeSocket *sockEpsilon = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
|
||||
|
||||
nodeSetSocketAvailability(
|
||||
ntree,
|
||||
sockEpsilon,
|
||||
ELEM(node->custom1, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL));
|
||||
}
|
||||
|
||||
static void node_float_compare_label(bNodeTree *UNUSED(ntree),
|
||||
bNode *node,
|
||||
char *label,
|
||||
int maxlen)
|
||||
{
|
||||
const char *name;
|
||||
bool enum_label = RNA_enum_name(rna_enum_node_float_compare_items, node->custom1, &name);
|
||||
if (!enum_label) {
|
||||
name = "Unknown";
|
||||
}
|
||||
BLI_strncpy(label, IFACE_(name), maxlen);
|
||||
}
|
||||
|
||||
static const fn::MultiFunction *get_multi_function(bNode &node)
|
||||
{
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> less_than_fn{
|
||||
"Less Than", [](float a, float b) { return a < b; }};
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> less_equal_fn{
|
||||
"Less Equal", [](float a, float b) { return a <= b; }};
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> greater_than_fn{
|
||||
"Greater Than", [](float a, float b) { return a > b; }};
|
||||
static fn::CustomMF_SI_SI_SO<float, float, bool> greater_equal_fn{
|
||||
"Greater Equal", [](float a, float b) { return a >= b; }};
|
||||
static 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 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 ¬_equal_fn;
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void fn_node_float_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_float_compare()
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
fn_node_type_base(&ntype, FN_NODE_COMPARE_FLOATS, "Compare Floats", NODE_CLASS_CONVERTER, 0);
|
||||
ntype.declare = blender::nodes::fn_node_float_compare_declare;
|
||||
node_type_label(&ntype, blender::nodes::node_float_compare_label);
|
||||
node_type_update(&ntype, blender::nodes::node_float_compare_update);
|
||||
ntype.build_multi_function = blender::nodes::fn_node_float_compare_build_multi_function;
|
||||
ntype.draw_buttons = blender::nodes::geo_node_float_compare_layout;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
|
@ -52,7 +52,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
|
|||
{
|
||||
NodeAttributeCompare *data = (NodeAttributeCompare *)MEM_callocN(sizeof(NodeAttributeCompare),
|
||||
__func__);
|
||||
data->operation = NODE_FLOAT_COMPARE_GREATER_THAN;
|
||||
data->operation = NODE_COMPARE_GREATER_THAN;
|
||||
data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
|
||||
data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
|
||||
node->storage = data;
|
||||
|
@ -60,7 +60,7 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
|
|||
|
||||
static bool operation_tests_equality(const NodeAttributeCompare &node_storage)
|
||||
{
|
||||
return ELEM(node_storage.operation, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL);
|
||||
return ELEM(node_storage.operation, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL);
|
||||
}
|
||||
|
||||
static void node_update(bNodeTree *ntree, bNode *node)
|
||||
|
@ -77,7 +77,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void do_math_operation(const VArray<float> &input_a,
|
||||
const VArray<float> &input_b,
|
||||
const FloatCompareOperation operation,
|
||||
const NodeCompareOperation operation,
|
||||
MutableSpan<bool> span_result)
|
||||
{
|
||||
const int size = input_a.size();
|
||||
|
@ -241,7 +241,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
|
|||
{
|
||||
const bNode &node = params.node();
|
||||
NodeAttributeCompare *node_storage = (NodeAttributeCompare *)node.storage;
|
||||
const FloatCompareOperation operation = static_cast<FloatCompareOperation>(
|
||||
const NodeCompareOperation operation = static_cast<NodeCompareOperation>(
|
||||
node_storage->operation);
|
||||
const std::string result_name = params.get_input<std::string>("Result");
|
||||
|
||||
|
@ -271,7 +271,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
|
|||
* conversions and float comparison. In other words, the comparison is not element-wise. */
|
||||
if (operation_tests_equality(*node_storage)) {
|
||||
const float threshold = params.get_input<float>("Threshold");
|
||||
if (operation == NODE_FLOAT_COMPARE_EQUAL) {
|
||||
if (operation == NODE_COMPARE_EQUAL) {
|
||||
if (input_data_type == CD_PROP_FLOAT) {
|
||||
do_equal_operation_float(
|
||||
attribute_a.typed<float>(), attribute_b.typed<float>(), threshold, result_span);
|
||||
|
@ -291,7 +291,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
|
|||
attribute_a.typed<bool>(), attribute_b.typed<bool>(), threshold, result_span);
|
||||
}
|
||||
}
|
||||
else if (operation == NODE_FLOAT_COMPARE_NOT_EQUAL) {
|
||||
else if (operation == NODE_COMPARE_NOT_EQUAL) {
|
||||
if (input_data_type == CD_PROP_FLOAT) {
|
||||
do_not_equal_operation_float(
|
||||
attribute_a.typed<float>(), attribute_b.typed<float>(), threshold, result_span);
|
||||
|
|
|
@ -127,17 +127,17 @@ const FloatMathOperationInfo *get_float_compare_operation_info(const int operati
|
|||
((void)0)
|
||||
|
||||
switch (operation) {
|
||||
case NODE_FLOAT_COMPARE_LESS_THAN:
|
||||
case NODE_COMPARE_LESS_THAN:
|
||||
RETURN_OPERATION_INFO("Less Than", "math_less_than");
|
||||
case NODE_FLOAT_COMPARE_LESS_EQUAL:
|
||||
case NODE_COMPARE_LESS_EQUAL:
|
||||
RETURN_OPERATION_INFO("Less Than or Equal", "math_less_equal");
|
||||
case NODE_FLOAT_COMPARE_GREATER_THAN:
|
||||
case NODE_COMPARE_GREATER_THAN:
|
||||
RETURN_OPERATION_INFO("Greater Than", "math_greater_than");
|
||||
case NODE_FLOAT_COMPARE_GREATER_EQUAL:
|
||||
case NODE_COMPARE_GREATER_EQUAL:
|
||||
RETURN_OPERATION_INFO("Greater Than or Equal", "math_greater_equal");
|
||||
case NODE_FLOAT_COMPARE_EQUAL:
|
||||
case NODE_COMPARE_EQUAL:
|
||||
RETURN_OPERATION_INFO("Equal", "math_equal");
|
||||
case NODE_FLOAT_COMPARE_NOT_EQUAL:
|
||||
case NODE_COMPARE_NOT_EQUAL:
|
||||
RETURN_OPERATION_INFO("Not Equal", "math_not_equal");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue