[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