[Bf-blender-cvs] [17021adceae] master: Geometry Nodes: Curve Sample Node

Hans Goudey noreply at git.blender.org
Tue Sep 21 03:23:44 CEST 2021


Commit: 17021adceaee28295b89301b4f715b6bcd8d5fca
Author: Hans Goudey
Date:   Mon Sep 20 20:23:26 2021 -0500
Branches: master
https://developer.blender.org/rB17021adceaee28295b89301b4f715b6bcd8d5fca

Geometry Nodes: Curve Sample Node

This node allows sampling positions, tangents, and normals at any
arbitrary point along a curve. The curve can include multiple splines,
all are taken into account. The node does not yet support transferring
generic attributes like radius, because some more general tooling will
make that much more feasible and useful in different scenarios.

This is a field node, so it is evaluated in the context of a data-flow
node like "Set Position". One nice thing about that is it can easily
be used to move an entire geometry like the follow path constraint.

The point along the curve is chosen either with a factor of the total
length of the curve, or a length into the curve, the same choice used
in the curve trim node.

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

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/BKE_spline.hh
M	source/blender/blenkernel/intern/curve_eval.cc
M	source/blender/blenkernel/intern/node.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index bc024ac96cf..b8bb4e551d2 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -527,6 +527,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeCurveFill"),
         NodeItem("GeometryNodeCurveTrim"),
         NodeItem("GeometryNodeCurveLength"),
+        NodeItem("GeometryNodeCurveSample", poll=geometry_nodes_fields_poll),
     ]),
     GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[
         NodeItem("GeometryNodeCurvePrimitiveLine"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 45ce843ef78..e4e9a6eff3a 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1495,6 +1495,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_MATERIAL_ASSIGN 1082
 #define GEO_NODE_REALIZE_INSTANCES 1083
 #define GEO_NODE_ATTRIBUTE_STATISTIC 1084
+#define GEO_NODE_CURVE_SAMPLE 1085
 
 /** \} */
 
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index 0fbf39a52fa..541ff19c1cd 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -565,6 +565,7 @@ struct CurveEval {
 
   blender::Array<int> control_point_offsets() const;
   blender::Array<int> evaluated_point_offsets() const;
+  blender::Array<float> accumulated_spline_lengths() const;
 
   void assert_valid_point_attributes() const;
 };
diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc
index ea84766943d..8eec7f5dfab 100644
--- a/source/blender/blenkernel/intern/curve_eval.cc
+++ b/source/blender/blenkernel/intern/curve_eval.cc
@@ -143,6 +143,23 @@ blender::Array<int> CurveEval::evaluated_point_offsets() const
   return offsets;
 }
 
+/**
+ * Return the accumulated length at the start of every spline in the curve.
+ *
+ * \note The result is one longer than the spline count; the last element is the total length.
+ */
+blender::Array<float> CurveEval::accumulated_spline_lengths() const
+{
+  Array<float> spline_lengths(splines_.size() + 1);
+  float spline_length = 0.0f;
+  for (const int i : splines_.index_range()) {
+    spline_lengths[i] = spline_length;
+    spline_length += splines_[i]->length();
+  }
+  spline_lengths.last() = spline_length;
+  return spline_lengths;
+}
+
 static BezierSpline::HandleType handle_type_from_dna_bezt(const eBezTriple_Handle dna_handle_type)
 {
   switch (dna_handle_type) {
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 7d679cfd076..e2891f00119 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5183,6 +5183,7 @@ static void registerGeometryNodes()
   register_node_type_geo_bounding_box();
   register_node_type_geo_collection_info();
   register_node_type_geo_convex_hull();
+  register_node_type_geo_curve_sample();
   register_node_type_geo_curve_endpoints();
   register_node_type_geo_curve_fill();
   register_node_type_geo_curve_length();
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index f4c88333528..49083542fd7 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1452,6 +1452,11 @@ typedef struct NodeGeometryCurveToPoints {
   uint8_t mode;
 } NodeGeometryCurveToPoints;
 
+typedef struct NodeGeometryCurveSample {
+  /* GeometryNodeCurveSampleMode. */
+  uint8_t mode;
+} NodeGeometryCurveSample;
+
 typedef struct NodeGeometryAttributeTransfer {
   /* AttributeDomain. */
   int8_t domain;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index ae5f8d5f5da..d0bf60d5d02 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9088,6 +9088,30 @@ static void def_geo_curve_primitive_bezier_segment(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
+static void def_geo_curve_sample(StructRNA *srna)
+{
+  static EnumPropertyItem mode_items[] = {
+      {GEO_NODE_CURVE_SAMPLE_FACTOR,
+       "FACTOR",
+       0,
+       "Factor",
+       "Find sample positions on the curve using a factor of its total length"},
+      {GEO_NODE_CURVE_SAMPLE_LENGTH,
+       "LENGTH",
+       0,
+       "Length",
+       "Find sample positions on the curve using a distance from its beginning"},
+      {0, NULL, 0, NULL, NULL},
+  };
+
+  RNA_def_struct_sdna_from(srna, "NodeGeometryCurveSample", "storage");
+
+  PropertyRNA *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");
+}
+
 static void def_geo_triangulate(StructRNA *srna)
 {
   PropertyRNA *prop;
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 6da7b0be4e9..842c76935d1 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -170,6 +170,7 @@ set(SRC
   geometry/nodes/node_geo_collection_info.cc
   geometry/nodes/node_geo_common.cc
   geometry/nodes/node_geo_convex_hull.cc
+  geometry/nodes/node_geo_curve_sample.cc
   geometry/nodes/node_geo_curve_endpoints.cc
   geometry/nodes/node_geo_curve_fill.cc
   geometry/nodes/node_geo_curve_length.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 5e8abce6eb8..63330b7df62 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -59,6 +59,7 @@ void register_node_type_geo_convex_hull(void);
 void register_node_type_geo_curve_endpoints(void);
 void register_node_type_geo_curve_fill(void);
 void register_node_type_geo_curve_length(void);
+void register_node_type_geo_curve_sample(void);
 void register_node_type_geo_curve_primitive_bezier_segment(void);
 void register_node_type_geo_curve_primitive_circle(void);
 void register_node_type_geo_curve_primitive_line(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 0be5459c9e1..918c82dec1c 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -312,6 +312,7 @@ DefNode(GeometryNode, GEO_NODE_BOOLEAN, def_geo_boolean, "BOOLEAN", Boolean, "Bo
 DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "")
 DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "")
 DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "")
+DefNode(GeometryNode, GEO_NODE_CURVE_SAMPLE, def_geo_curve_sample, "CURVE_SAMPLE", CurveSample, "Curve Sample", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINTS, 0, "CURVE_ENDPOINTS", CurveEndpoints, "Curve Endpoints", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_FILL, def_geo_curve_fill, "CURVE_FILL", CurveFill, "Curve Fill", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
new file mode 100644
index 00000000000..1dbb1f20915
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -0,0 +1,292 @@
+/*
+ * 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 "BLI_task.hh"
+
+#include "BKE_spline.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+static void geo_node_curve_sample_declare(NodeDeclarationBuilder &b)
+{
+  b.add_input<decl::Geometry>("Curve");
+  b.add_input<decl::Float>("Factor").min(0.0f).max(1.0f).subtype(PROP_FACTOR);
+  b.add_input<decl::Float>("Length").min(0.0f).subtype(PROP_DISTANCE);
+
+  b.add_output<decl::Vector>("Position");
+  b.add_output<decl::Vector>("Tangent");
+  b.add_output<decl::Vector>("Normal");
+}
+
+static void geo_node_curve_sample_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+  uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+}
+
+static void geo_node_curve_sample_type_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+  NodeGeometryCurveSample *data = (NodeGeometryCurveSample *)MEM_callocN(
+      sizeof(NodeGeometryCurveSample), __func__);
+  data->mode = GEO_NODE_CURVE_SAMPLE_LENGTH;
+  node->storage = data;
+}
+
+static void geo_node_curve_sample_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+  const NodeGeometryCurveSample &node_storage = *(NodeGeometryCurveSample *)node->storage;
+  const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)node_storage.mode;
+
+  bNodeSocket *factor = ((bNodeSocket *)node->inputs.first)->next;
+  bNodeSocket *length = factor->next;
+
+  nodeSetSocketAvailability(factor, mode == GEO_NODE_CURVE_SAMPLE_FACTOR);
+  nodeSetSocketAvailability(length, mode == GEO_NODE_CURVE_SAMPLE_LENGTH);
+}
+
+template<typename T> static T sample_with_lookup(const Spline::LookupResult lookup, Span<T> data)
+{
+  return attribute_math::mix2(
+      lookup.factor, data[lookup.evaluated_index], data[lookup.next_evaluated_index]);
+}
+
+class Sample

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list