[Bf-blender-cvs] [003fad94316] geometry-nodes-curve-to-points-node: Geometry Nodes: Curve to Points Node

Hans Goudey noreply at git.blender.org
Wed Jun 9 19:32:58 CEST 2021


Commit: 003fad9431656a0252a675eba31ceda3772a6673
Author: Hans Goudey
Date:   Tue Jun 8 17:30:15 2021 -0500
Branches: geometry-nodes-curve-to-points-node
https://developer.blender.org/rB003fad9431656a0252a675eba31ceda3772a6673

Geometry Nodes: Curve to Points Node

This node implements the second option of T87429, creating points
along the input splines with the necessary evaluated information
for instancing: `tangent`, `normal`, and `rotation` attributes.
All generic curve point and spline attributes are copied to the
result points as well.

I'm actually quite happy with the implementation right now. It's
readable enough and there isn't too much boilerplate code. The thing
I expect could use improvement is that there is a lot of temporary
memory allocation. Sharing a buffer for each thread would be a nice
improvement in the future.

The patch currently includes some refactoring of the curve resample
node with some newly abstracted functions. I may commit that separately.
The "Evaluated" mode for the resample node will be a separate commit.

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

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

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/node.cc
M	source/blender/blenkernel/intern/spline_base.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
M	source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
A	source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index e7b93dcc5ea..93240594c71 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -504,6 +504,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeCurveToMesh"),
         NodeItem("GeometryNodeCurveResample"),
         NodeItem("GeometryNodeMeshToCurve"),
+        NodeItem("GeometryNodeCurveToPoints"),
         NodeItem("GeometryNodeCurveLength"),
     ]),
     GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=[
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 16da621a0fa..1051a03f15f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1433,6 +1433,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_DELETE_GEOMETRY 1053
 #define GEO_NODE_CURVE_LENGTH 1054
 #define GEO_NODE_SELECT_BY_MATERIAL 1055
+#define GEO_NODE_CURVE_TO_POINTS 1056
 
 /** \} */
 
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index fc1292e3620..2c34d9050f5 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -171,6 +171,25 @@ class Spline {
 
   blender::Array<float> sample_uniform_index_factors(const int samples_size) const;
   LookupResult lookup_data_from_index_factor(const float index_factor) const;
+  void sample_data_based_on_index_factors(const blender::fn::GVArray &src,
+                                          blender::Span<float> index_factors,
+                                          blender::fn::GMutableSpan dst) const;
+  template<typename T>
+  void sample_data_based_on_index_factors(const blender::VArray<T> &src,
+                                          blender::Span<float> index_factors,
+                                          blender::MutableSpan<T> dst) const
+  {
+    this->sample_data_based_on_index_factors(
+        blender::fn::GVArray_For_VArray(src), index_factors, blender::fn::GMutableSpan(dst));
+  }
+  template<typename T>
+  void sample_data_based_on_index_factors(blender::Span<T> src,
+                                          blender::Span<float> index_factors,
+                                          blender::MutableSpan<T> dst) const
+  {
+    this->sample_data_based_on_index_factors(
+        blender::fn::GVArray_For_Span(src), index_factors, blender::fn::GMutableSpan(dst));
+  }
 
   /**
    * Interpolate a virtual array of data with the size of the number of control points to the
@@ -179,6 +198,13 @@ class Spline {
    */
   virtual blender::fn::GVArrayPtr interpolate_to_evaluated_points(
       const blender::fn::GVArray &source_data) const = 0;
+  blender::fn::GVArrayPtr interpolate_to_evaluated_points(blender::fn::GSpan data) const;
+  template<typename T>
+  blender::fn::GVArray_Typed<T> interpolate_to_evaluated_points(blender::Span<T> data) const
+  {
+    return blender::fn::GVArray_Typed<T>(
+        this->interpolate_to_evaluated_points(blender::fn::GSpan(data)));
+  }
 
  protected:
   virtual void correct_end_tangents() const = 0;
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 10f1f40f390..b024321b973 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5052,6 +5052,7 @@ static void registerGeometryNodes()
   register_node_type_geo_collection_info();
   register_node_type_geo_curve_length();
   register_node_type_geo_curve_to_mesh();
+  register_node_type_geo_curve_to_points();
   register_node_type_geo_curve_resample();
   register_node_type_geo_delete_geometry();
   register_node_type_geo_edge_split();
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index 11620a30948..605bf6f9e7b 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -16,6 +16,7 @@
 
 #include "BLI_array.hh"
 #include "BLI_span.hh"
+#include "BLI_task.hh"
 #include "BLI_timeit.hh"
 
 #include "BKE_spline.hh"
@@ -27,6 +28,12 @@ using blender::float3;
 using blender::IndexRange;
 using blender::MutableSpan;
 using blender::Span;
+using blender::fn::GMutableSpan;
+using blender::fn::GSpan;
+using blender::fn::GVArray;
+using blender::fn::GVArray_For_GSpan;
+using blender::fn::GVArray_Typed;
+using blender::fn::GVArrayPtr;
 
 Spline::Type Spline::type() const
 {
@@ -341,3 +348,29 @@ void Spline::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated)
     minmax_v3v3_v3(min, max, position);
   }
 }
+
+GVArrayPtr Spline::interpolate_to_evaluated_points(GSpan data) const
+{
+  return this->interpolate_to_evaluated_points(GVArray_For_GSpan(data));
+}
+
+void Spline::sample_data_based_on_index_factors(const GVArray &src,
+                                                Span<float> index_factors,
+                                                GMutableSpan dst) const
+{
+  BLI_assert(src.size() == this->evaluated_points_size());
+
+  blender::attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
+    using T = decltype(dummy);
+    const GVArray_Typed<T> src_typed = src.typed<T>();
+    MutableSpan<T> dst_typed = dst.typed<T>();
+    blender::parallel_for(dst_typed.index_range(), 1024, [&](IndexRange range) {
+      for (const int i : range) {
+        const LookupResult interp = this->lookup_data_from_index_factor(index_factors[i]);
+        dst_typed[i] = blender::attribute_math::mix2(interp.factor,
+                                                     src_typed[interp.evaluated_index],
+                                                     src_typed[interp.next_evaluated_index]);
+      }
+    });
+  });
+}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 1ab6c5e52a6..3174b551bd2 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1357,6 +1357,11 @@ typedef struct NodeGeometryCurveResample {
   uint8_t mode;
 } NodeGeometryCurveResample;
 
+typedef struct NodeGeometryCurveToPoints {
+  /* GeometryNodeCurveSampleMode. */
+  uint8_t mode;
+} NodeGeometryCurveToPoints;
+
 typedef struct NodeGeometryAttributeTransfer {
   /* AttributeDomain. */
   int8_t domain;
@@ -1870,6 +1875,7 @@ typedef enum GeometryNodeMeshLineCountMode {
 typedef enum GeometryNodeCurveSampleMode {
   GEO_NODE_CURVE_SAMPLE_COUNT = 0,
   GEO_NODE_CURVE_SAMPLE_LENGTH = 1,
+  GEO_NODE_CURVE_SAMPLE_EVALUATED = 2,
 } GeometryNodeCurveSampleMode;
 
 typedef enum GeometryNodeAttributeTransferMapMode {
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 2bafbd57e11..1e448b0ca1a 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9840,6 +9840,38 @@ static void def_geo_curve_resample(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
 }
 
+static void def_geo_curve_to_points(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  static EnumPropertyItem mode_items[] = {
+      {GEO_NODE_CURVE_SAMPLE_EVALUATED,
+       "EVALUATED",
+       0,
+       "Evaluated",
+       "Add points on the curve's evaluated points, based on the resolution for NURBS and Bezier "
+       "splines"},
+      {GEO_NODE_CURVE_SAMPLE_COUNT,
+       "COUNT",
+       0,
+       "Count",
+       "Sample each spline by evenly distributing the specified number of points"},
+      {GEO_NODE_CURVE_SAMPLE_LENGTH,
+       "LENGTH",
+       0,
+       "Length",
+       "Sample each spline by splitting it into segments with the specified length"},
+      {0, NULL, 0, NULL, NULL},
+  };
+
+  RNA_def_struct_sdna_from(srna, "NodeGeometryCurveResample", "storage");
+
+  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", "How to generate points from the input curve");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
 static void def_geo_attribute_transfer(StructRNA *srna)
 {
   static EnumPropertyItem mapping_items[] = {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 7aaf28869de..92d03b9763a 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -164,6 +164,7 @@ set(SRC
   geometry/nodes/node_geo_common.cc
   geometry/nodes/node_geo_curve_length.cc  
   geometry/nodes/node_geo_curve_to_mesh.cc
+  geometry/nodes/node_geo_curve_to_points.cc
   geometry/nodes/node_geo_curve_resample.cc
   geometry/nodes/node_geo_delete_geometry.cc
   geometry/nodes/node_geo_edge_split.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index df14fcfe5b4..841d17b4ba5 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -52,6 +52,7 @@ void register_node_type_geo_bounding_box(void);
 void register_node_type_geo_collection_info(void);
 void register_node_type_geo_curve_length(void);
 void register_node_type_geo_curve_to_mesh(void);
+void register_node_type_geo_curve_to_points(void);
 void register_node_type_geo_curve_resample(void);
 void register_node_type_geo_delete_geometry(void);
 void register_node_type_geo_edge_split(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index bfd99a2bb60..a9019be8954 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -292,6 +292,7 @@ DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLEC
 DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_RESAMPLE, def_geo_curve_resample, "CURVE_RESAMPLE", CurveResample, "Resample Curve", "")
 DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "")
+DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", Cu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list