[Bf-blender-cvs] [62953c2bf39] geometry-nodes-point-separate-node: Geometry Nodes: Support equality operations with all data types
Hans Goudey
noreply at git.blender.org
Wed Dec 9 23:42:32 CET 2020
Commit: 62953c2bf39252fc59d0365b9a33453e179b66c0
Author: Hans Goudey
Date: Wed Dec 9 16:42:23 2020 -0600
Branches: geometry-nodes-point-separate-node
https://developer.blender.org/rB62953c2bf39252fc59d0365b9a33453e179b66c0
Geometry Nodes: Support equality operations with all data types
Testing equality of vectors can't be done properly if they are implicitly
converted to float before-hand. This adds a lot of boilerplate code to
the node, maybe that can made more elegant in the future, but it's not
so complicated anyway.
===================================================================
M source/blender/makesdna/DNA_node_types.h
M source/blender/makesrna/intern/rna_nodetree.c
M source/blender/nodes/NOD_math_functions.hh
M source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
===================================================================
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 13f8b11352a..a9e94ee9b0f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1059,6 +1059,17 @@ typedef struct NodeDenoise {
char _pad[7];
} NodeDenoise;
+typedef struct NodeAttributeCompare {
+ /* e.g. NODE_FLOAT_COMPARE_LESS_THAN. */
+ uint8_t operation;
+
+ /* GeometryNodeAttributeInputMode */
+ uint8_t input_type_a;
+ uint8_t input_type_b;
+
+ char _pad[5];
+} NodeAttributeCompare;
+
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0
#define NODE_SCRIPT_EXTERNAL 1
@@ -1336,14 +1347,14 @@ enum {
};
/* Float compare node operations. */
-enum {
+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;
/* Clamp node types. */
enum {
@@ -1469,6 +1480,7 @@ typedef enum GeometryNodeAttributeInputMode {
GEO_NODE_ATTRIBUTE_INPUT_FLOAT = 1,
GEO_NODE_ATTRIBUTE_INPUT_VECTOR = 2,
GEO_NODE_ATTRIBUTE_INPUT_COLOR = 3,
+ GEO_NODE_ATTRIBUTE_INPUT_BOOLEAN = 4,
} GeometryNodeAttributeInputMode;
#ifdef __cplusplus
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 96562805368..9cf11f1197d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -435,6 +435,14 @@ static const EnumPropertyItem rna_node_geometry_attribute_input_b_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static const EnumPropertyItem rna_node_geometry_attribute_input_type_items[] = {
+ {GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE, "ATTRIBUTE", 0, "Attribute", ""},
+ {GEO_NODE_ATTRIBUTE_INPUT_FLOAT, "FLOAT", 0, "Float", ""},
+ {GEO_NODE_ATTRIBUTE_INPUT_VECTOR, "VECTOR", 0, "Vector", ""},
+ {GEO_NODE_ATTRIBUTE_INPUT_COLOR, "COLOR", 0, "Color", ""},
+ {GEO_NODE_ATTRIBUTE_INPUT_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
+ {0, NULL, 0, NULL, NULL},
+};
#endif
#ifdef RNA_RUNTIME
@@ -8372,22 +8380,21 @@ static void def_geo_attribute_attribute_compare(StructRNA *srna)
{
PropertyRNA *prop;
+ RNA_def_struct_sdna_from(srna, "NodeAttributeCompare", "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_default(prop, NODE_MATH_ADD);
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, "input_type_a", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "custom2");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_a_items);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items);
RNA_def_property_ui_text(prop, "Input Type A", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "input_type_b", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "custom2");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_b_items);
+ RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items);
RNA_def_property_ui_text(prop, "Input Type B", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
diff --git a/source/blender/nodes/NOD_math_functions.hh b/source/blender/nodes/NOD_math_functions.hh
index 9c560e163ae..cc750f9595a 100644
--- a/source/blender/nodes/NOD_math_functions.hh
+++ b/source/blender/nodes/NOD_math_functions.hh
@@ -202,7 +202,8 @@ 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 int operation, Callback &&callback)
+inline bool try_dispatch_float_math_fl_fl_to_bool(const FloatCompareOperation operation,
+ Callback &&callback)
{
const FloatMathOperationInfo *info = get_float_compare_operation_info(operation);
if (info == nullptr) {
@@ -224,32 +225,8 @@ inline bool try_dispatch_float_math_fl_fl_to_bool(const int operation, Callback
return dispatch([](float a, float b) { return a > b; });
case NODE_FLOAT_COMPARE_GREATER_EQUAL:
return dispatch([](float a, float b) { return a >= b; });
- }
- return false;
-}
-
-/**
- * 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_fl_to_bool(const int operation, Callback &&callback)
-{
- const FloatMathOperationInfo *info = get_float_compare_operation_info(operation);
- if (info == nullptr) {
- return false;
- }
-
- /* This is just an utility function to keep the individual cases smaller. */
- auto dispatch = [&](auto math_function) -> bool {
- callback(math_function, *info);
- return true;
- };
-
- switch (operation) {
- case NODE_FLOAT_COMPARE_EQUAL:
- return dispatch([](float a, float b, float c) { return compare_ff(a, b, c); });
- case NODE_FLOAT_COMPARE_NOT_EQUAL:
- return dispatch([](float a, float b, float c) { return !compare_ff(a, b, c); });
+ default:
+ return false;
}
return false;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
index bfb8772eb67..dc1fe858b07 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
@@ -30,11 +30,15 @@
static bNodeSocketTemplate geo_node_attribute_compare_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_STRING, N_("Attribute A")},
- {SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
- {SOCK_STRING, N_("Attribute B")},
- {SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
- {SOCK_FLOAT, N_("Epsilon"), 0.01f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_STRING, N_("A")},
+ {SOCK_FLOAT, N_("A"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_VECTOR, N_("A"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_RGBA, N_("A"), 0.5, 0.5, 0.5, 1.0},
+ {SOCK_STRING, N_("B")},
+ {SOCK_FLOAT, N_("B"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_VECTOR, N_("B"), 0.0, 0.0, 0.0, 0.0, -FLT_MAX, FLT_MAX},
+ {SOCK_RGBA, N_("B"), 0.5, 0.5, 0.5, 1.0},
+ {SOCK_FLOAT, N_("Threshold"), 0.01f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
{SOCK_STRING, N_("Result")},
{-1, ""},
};
@@ -46,69 +50,52 @@ static bNodeSocketTemplate geo_node_attribute_compare_out[] = {
static void geo_node_attribute_compare_init(bNodeTree *UNUSED(tree), bNode *node)
{
- node->custom1 = NODE_FLOAT_COMPARE_GREATER_THAN;
- node->custom2 = GEO_NODE_USE_ATTRIBUTE_A | GEO_NODE_USE_ATTRIBUTE_B;
+ NodeAttributeCompare *data = (NodeAttributeCompare *)MEM_callocN(sizeof(NodeAttributeCompare),
+ "attribute mix node");
+ data->operation = NODE_FLOAT_COMPARE_GREATER_THAN;
+ data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
+ node->storage = data;
}
-static bool use_epsilon(const bNode &node)
+static bool operation_is_equality(const NodeAttributeCompare &node_storage)
{
- return ELEM(node.custom1, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL);
+ return ELEM(node_storage.operation, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL);
}
+namespace blender::nodes {
+
static void geo_node_attribute_compare_update(bNodeTree *UNUSED(ntree), bNode *node)
{
- bNodeSocket *socket_attribute_a = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
- bNodeSocket *socket_float_a = socket_attribute_a->next;
- bNodeSocket *socket_attribute_b = socket_float_a->next;
- bNodeSocket *socket_float_b = socket_attribute_b->next;
- bNodeSocket *socket_epsilon = socket_float_b->next;
-
- GeometryNodeUseAttributeFlag flag = static_cast<GeometryNodeUseAttributeFlag>(node->custom2);
-
- nodeSetSocketAvailability(socket_attribute_a, flag & GEO_NODE_USE_ATTRIBUTE_A);
- nodeSetSocketAvailability(socket_attribute_b, flag & GEO_NODE_USE_ATTRIBUTE_B);
- nodeSetSocketAvailability(socket_float_a, !(flag & GEO_NODE_USE_ATTRIBUTE_A));
- nodeSetSocketAvailability(socket_float_b, !(flag & GEO_NODE_USE_ATTRIBUTE_B));
- nodeSetSocketAvailability(socket_epsilon, use_epsilon(*node));
+ NodeAttributeCompare *node_storage = (NodeAttributeCompare *)node->storage;
+ update_attribute_input_socket_availabilities(
+ *node, "A", (GeometryNodeAttributeInputMode)node_storage->input_type_a);
+ update_attribute_input_socket_availabilities(
+ *node, "B", (GeometryNodeAttributeInputMode)node_storage->input_type_b);
+
+ bNodeSocket *socket_epsilon = (bNodeSocket *)BLI_findlink(&node->inputs, 9);
+ nodeSetSocketAvailability(socket_epsilon, operation_is_equality(*node_storage));
}
-namespace blender::nodes {
-
static void do_math_operation(const FloatReadAttribute &input_a,
const FloatReadAttribute &input_b,
- BooleanWriteAttribute result,
- const int operation,
- const float epsilon)
+ const FloatCompareOperation operation,
+ MutableSpan<bool> span_result)
{
const int size = input_a.size();
Span<float> span_a = input_a.get_span();
Span<float> span_b = input_b.get_span();
- MutableSpan<bool> span_result = result.get_span();
if (try_dispatch_float_math_fl_fl_to_bool(
operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list