[Bf-blender-cvs] [5f7ca5462d3] master: Geometry Nodes: Add index and value inputs to sample curve node

Hans Goudey noreply at git.blender.org
Wed Nov 2 12:36:17 CET 2022


Commit: 5f7ca5462d31ff56f16016d5f9e6a5489b30a05e
Author: Hans Goudey
Date:   Wed Nov 2 12:29:01 2022 +0100
Branches: master
https://developer.blender.org/rB5f7ca5462d31ff56f16016d5f9e6a5489b30a05e

Geometry Nodes: Add index and value inputs to sample curve node

As described in T92474 and T91650, this patch adds two features to the
sample curve node. First is an index input, to allow choosing the curve
to sample for each point. Second is a custom field input, which is
evaluated on the control points of the curve and then sampled like the
other outputs. There is an "All Curves" option for the old behavior
which takes the length of all curves into account.

For invalid curve indices, the node outputs zeros (default values).
Invalid lengths and factors are clamped.

There have been various discussions about splitting the node up more,
but this is an intuitive combination of options and will work well
enough for current use cases. The node could still be generalized more
in the future.

Keep in mind that the source field is evaluated on curve control points,
not the evaluated points used for sampling. This is necessary so that
fields like "Index" work as expected.

Differential Revision: https://developer.blender.org/D16147

===================================================================

M	source/blender/blenkernel/BKE_blender_version.h
M	source/blender/blenloader/intern/versioning_300.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 806fff2099e..1a642cf4eb3 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -25,7 +25,7 @@ extern "C" {
 
 /* Blender file format version. */
 #define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 5
+#define BLENDER_FILE_SUBVERSION 6
 
 /* Minimum Blender version that supports reading file written with the current
  * version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc
index a2bd7fd2fd1..65094655cfe 100644
--- a/source/blender/blenloader/intern/versioning_300.cc
+++ b/source/blender/blenloader/intern/versioning_300.cc
@@ -3653,6 +3653,25 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
     }
   }
 
+  if (!MAIN_VERSION_ATLEAST(bmain, 304, 6)) {
+    LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+      if (ntree->type != NTREE_GEOMETRY) {
+        continue;
+      }
+      LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+        if (node->type != GEO_NODE_SAMPLE_CURVE) {
+          continue;
+        }
+        static_cast<NodeGeometryCurveSample *>(node->storage)->use_all_curves = true;
+        static_cast<NodeGeometryCurveSample *>(node->storage)->data_type = CD_PROP_FLOAT;
+        bNodeSocket *curve_socket = nodeFindSocket(node, SOCK_IN, "Curve");
+        BLI_assert(curve_socket != nullptr);
+        STRNCPY(curve_socket->name, "Curves");
+        STRNCPY(curve_socket->identifier, "Curves");
+      }
+    }
+  }
+
   /**
    * Versioning code until next subversion bump goes here.
    *
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 74714cf7e41..0b7c17d44bb 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1497,6 +1497,10 @@ typedef struct NodeGeometryCurveToPoints {
 typedef struct NodeGeometryCurveSample {
   /* GeometryNodeCurveSampleMode. */
   uint8_t mode;
+  int8_t use_all_curves;
+  /* eCustomDataType. */
+  int8_t data_type;
+  char _pad[1];
 } NodeGeometryCurveSample;
 
 typedef struct NodeGeometryTransferAttribute {
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 865399df9ef..7457267a83c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9442,10 +9442,26 @@ static void def_geo_curve_sample(StructRNA *srna)
 
   RNA_def_struct_sdna_from(srna, "NodeGeometryCurveSample", "storage");
 
-  PropertyRNA *prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+  PropertyRNA *prop;
+  prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_items(prop, mode_items);
   RNA_def_property_ui_text(prop, "Mode", "Method for sampling input");
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+  prop = RNA_def_property(srna, "use_all_curves", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_ui_text(prop,
+                           "All Curves",
+                           "Sample lengths based on the total lengh of all curves, rather than "
+                           "using a length inside each selected curve");
+  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_items(prop, rna_enum_attribute_type_items);
+  RNA_def_property_enum_funcs(
+      prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf");
+  RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
+  RNA_def_property_ui_text(prop, "Data Type", "");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
 static void def_geo_triangulate(StructRNA *srna)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
index 27e111822bf..2b732bba889 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
 #include "BLI_devirtualize_parameters.hh"
+#include "BLI_generic_array.hh"
 #include "BLI_length_parameterize.hh"
 
 #include "BKE_curves.hh"
@@ -8,6 +9,8 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "NOD_socket_search_link.hh"
+
 #include "node_geometry_util.hh"
 
 namespace blender::nodes::node_geo_curve_sample_cc {
@@ -16,9 +19,16 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveSample)
 
 static void node_declare(NodeDeclarationBuilder &b)
 {
-  b.add_input<decl::Geometry>(N_("Curve"))
+  b.add_input<decl::Geometry>(N_("Curves"))
       .only_realized_data()
       .supported_type(GEO_COMPONENT_TYPE_CURVE);
+
+  b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field();
+  b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field();
+  b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field();
+  b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field();
+  b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field();
+
   b.add_input<decl::Float>(N_("Factor"))
       .min(0.0f)
       .max(1.0f)
@@ -30,6 +40,16 @@ static void node_declare(NodeDeclarationBuilder &b)
       .subtype(PROP_DISTANCE)
       .supports_field()
       .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; });
+  b.add_input<decl::Int>(N_("Curve Index")).supports_field().make_available([](bNode &node) {
+    node_storage(node).use_all_curves = false;
+  });
+
+  b.add_output<decl::Float>(N_("Value"), "Value_Float").dependent_field();
+  b.add_output<decl::Int>(N_("Value"), "Value_Int").dependent_field();
+  b.add_output<decl::Vector>(N_("Value"), "Value_Vector").dependent_field();
+  b.add_output<decl::Color>(N_("Value"), "Value_Color").dependent_field();
+  b.add_output<decl::Bool>(N_("Value"), "Value_Bool").dependent_field();
+
   b.add_output<decl::Vector>(N_("Position")).dependent_field();
   b.add_output<decl::Vector>(N_("Tangent")).dependent_field();
   b.add_output<decl::Vector>(N_("Normal")).dependent_field();
@@ -37,13 +57,17 @@ static void node_declare(NodeDeclarationBuilder &b)
 
 static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
 {
+  uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
   uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+  uiItemR(layout, ptr, "use_all_curves", 0, nullptr, ICON_NONE);
 }
 
 static void node_type_init(bNodeTree * /*tree*/, bNode *node)
 {
   NodeGeometryCurveSample *data = MEM_cnew<NodeGeometryCurveSample>(__func__);
-  data->mode = GEO_NODE_CURVE_SAMPLE_LENGTH;
+  data->mode = GEO_NODE_CURVE_SAMPLE_FACTOR;
+  data->use_all_curves = false;
+  data->data_type = CD_PROP_FLOAT;
   node->storage = data;
 }
 
@@ -51,16 +75,62 @@ static void node_update(bNodeTree *ntree, bNode *node)
 {
   const NodeGeometryCurveSample &storage = node_storage(*node);
   const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
+  const eCustomDataType data_type = eCustomDataType(storage.data_type);
+
+  bNodeSocket *in_socket_float = static_cast<bNodeSocket *>(node->inputs.first)->next;
+  bNodeSocket *in_socket_int32 = in_socket_float->next;
+  bNodeSocket *in_socket_vector = in_socket_int32->next;
+  bNodeSocket *in_socket_color4f = in_socket_vector->next;
+  bNodeSocket *in_socket_bool = in_socket_color4f->next;
 
-  bNodeSocket *factor = static_cast<bNodeSocket *>(node->inputs.first)->next;
+  bNodeSocket *factor = in_socket_bool->next;
   bNodeSocket *length = factor->next;
+  bNodeSocket *curve_index = length->next;
 
   nodeSetSocketAvailability(ntree, factor, mode == GEO_NODE_CURVE_SAMPLE_FACTOR);
   nodeSetSocketAvailability(ntree, length, mode == GEO_NODE_CURVE_SAMPLE_LENGTH);
+  nodeSetSocketAvailability(ntree, curve_index, !storage.use_all_curves);
+
+  nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
+  nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
+  nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
+  nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
+  nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
+
+  bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
+  bNodeSocket *out_socket_int32 = out_socket_float->next;
+  bNodeSocket *out_socket_vector = out_socket_int32->next;
+  bNodeSocket *out_socket_color4f = out_socket_vector->next;
+  bNodeSocket *out_socket_bool = out_socket_color4f->next;
+
+  nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
+  nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
+  nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
+  nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
+  nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+  const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+  search_link_ops_for_declarations(params, declaration.inputs().take_front(4));
+  search_link_ops_for_declarations(params, declaration.outputs().take_front(3));
+
+  const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
+      eNodeSocketDatatype(params.other_socket().type));
+  if (type && *type != CD_PROP_STRING) {
+    /* The input and output sockets have the same name. */
+    params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
+      bNode &node = params.add_node("GeometryNodeSampleCurve");
+      node_storage(node).data_type = *type;
+      params.update_and_connect_available_socke

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list