[Bf-blender-cvs] [ca1b4be6f8c] temp-T97352-3d-texturing-seam-bleeding-b2: Curves: Port Curve to Points node to the new data-block

Hans Goudey noreply at git.blender.org
Tue Sep 20 10:32:15 CEST 2022


Commit: ca1b4be6f8c312d576bdf3a07bbeddf7a1247852
Author: Hans Goudey
Date:   Sun Sep 18 14:56:15 2022 -0500
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rBca1b4be6f8c312d576bdf3a07bbeddf7a1247852

Curves: Port Curve to Points node to the new data-block

This is the last node to use the `CurveEval` type. Since the curve to
points node is basically the same as the resample node, now it just
reuses the resample code and moves the curve point `CustomData` to a
new point cloud at the end. I had to add support for sampling tangents
and normals to the resampling.

There is one behavior change: If the radius attribute doesn't exist,
the node won't set the radius to 1 for the output point cloud anymore.
Instead, the default radius for point clouds will be used.
That issue was similar to T99814.

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

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

M	source/blender/blenkernel/BKE_curves_utils.hh
M	source/blender/blenkernel/intern/curves_utils.cc
M	source/blender/geometry/GEO_resample_curves.hh
M	source/blender/geometry/intern/resample_curves.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc

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

diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh
index 7d81847f4c1..f9155023db7 100644
--- a/source/blender/blenkernel/BKE_curves_utils.hh
+++ b/source/blender/blenkernel/BKE_curves_utils.hh
@@ -326,8 +326,8 @@ void copy_point_data(const CurvesGeometry &src_curves,
 template<typename T>
 void copy_point_data(const CurvesGeometry &src_curves,
                      const CurvesGeometry &dst_curves,
-                     const IndexMask src_curve_selection,
-                     const Span<T> src,
+                     IndexMask src_curve_selection,
+                     Span<T> src,
                      MutableSpan<T> dst)
 {
   copy_point_data(src_curves, dst_curves, src_curve_selection, GSpan(src), GMutableSpan(dst));
@@ -340,13 +340,27 @@ void fill_points(const CurvesGeometry &curves,
 
 template<typename T>
 void fill_points(const CurvesGeometry &curves,
-                 const IndexMask curve_selection,
+                 IndexMask curve_selection,
                  const T &value,
                  MutableSpan<T> dst)
 {
   fill_points(curves, curve_selection, &value, dst);
 }
 
+void fill_points(const CurvesGeometry &curves,
+                 Span<IndexRange> curve_ranges,
+                 GPointer value,
+                 GMutableSpan dst);
+
+template<typename T>
+void fill_points(const CurvesGeometry &curves,
+                 Span<IndexRange> curve_ranges,
+                 const T &value,
+                 MutableSpan<T> dst)
+{
+  fill_points(curves, curve_ranges, &value, dst);
+}
+
 /**
  * Copy only the information on the point domain, but not the offsets or any point attributes,
  * meant for operations that change the number of points but not the number of curves.
diff --git a/source/blender/blenkernel/intern/curves_utils.cc b/source/blender/blenkernel/intern/curves_utils.cc
index d98832e796c..f5a69a995a3 100644
--- a/source/blender/blenkernel/intern/curves_utils.cc
+++ b/source/blender/blenkernel/intern/curves_utils.cc
@@ -84,6 +84,21 @@ void fill_points(const CurvesGeometry &curves,
   });
 }
 
+void fill_points(const CurvesGeometry &curves,
+                 Span<IndexRange> curve_ranges,
+                 GPointer value,
+                 GMutableSpan dst)
+{
+  BLI_assert(*value.type() == dst.type());
+  const CPPType &type = dst.type();
+  threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) {
+    for (const IndexRange range : curve_ranges.slice(range)) {
+      const IndexRange points = curves.points_for_curves(range);
+      type.fill_assign_n(value.get(), dst.slice(points).data(), points.size());
+    }
+  });
+}
+
 bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
 {
   bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
diff --git a/source/blender/geometry/GEO_resample_curves.hh b/source/blender/geometry/GEO_resample_curves.hh
index 7ecfb5c26ec..35365167eba 100644
--- a/source/blender/geometry/GEO_resample_curves.hh
+++ b/source/blender/geometry/GEO_resample_curves.hh
@@ -4,12 +4,18 @@
 
 #include "FN_field.hh"
 
+#include "BKE_anonymous_attribute.hh"
 #include "BKE_curves.hh"
 
 namespace blender::geometry {
 
 using bke::CurvesGeometry;
 
+struct ResampleCurvesOutputAttributeIDs {
+  bke::AttributeIDRef tangent_id;
+  bke::AttributeIDRef normal_id;
+};
+
 /**
  * Create new curves where the selected curves have been resampled with a number of uniform-length
  * samples defined by the count field. Interpolate attributes to the result, with an accuracy that
@@ -19,7 +25,8 @@ using bke::CurvesGeometry;
  */
 CurvesGeometry resample_to_count(const CurvesGeometry &src_curves,
                                  const fn::Field<bool> &selection_field,
-                                 const fn::Field<int> &count_field);
+                                 const fn::Field<int> &count_field,
+                                 const ResampleCurvesOutputAttributeIDs &output_ids = {});
 
 /**
  * Create new curves resampled to make each segment have the length specified by the
@@ -28,12 +35,14 @@ CurvesGeometry resample_to_count(const CurvesGeometry &src_curves,
  */
 CurvesGeometry resample_to_length(const CurvesGeometry &src_curves,
                                   const fn::Field<bool> &selection_field,
-                                  const fn::Field<float> &segment_length_field);
+                                  const fn::Field<float> &segment_length_field,
+                                  const ResampleCurvesOutputAttributeIDs &output_ids = {});
 
 /**
  * Evaluate each selected curve to its implicit evaluated points.
  */
 CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
-                                     const fn::Field<bool> &selection_field);
+                                     const fn::Field<bool> &selection_field,
+                                     const ResampleCurvesOutputAttributeIDs &output_ids = {});
 
 }  // namespace blender::geometry
diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc
index d5560a95a18..a7f6ac16f8d 100644
--- a/source/blender/geometry/intern/resample_curves.cc
+++ b/source/blender/geometry/intern/resample_curves.cc
@@ -116,14 +116,21 @@ struct AttributesForInterpolation : NonCopyable, NonMovable {
 
   Vector<GSpan> src_no_interpolation;
   Vector<GMutableSpan> dst_no_interpolation;
+
+  Span<float3> src_evaluated_tangents;
+  Span<float3> src_evaluated_normals;
+  MutableSpan<float3> dst_tangents;
+  MutableSpan<float3> dst_normals;
 };
 
 /**
  * Gather a set of all generic attribute IDs to copy to the result curves.
  */
-static void gather_point_attributes_to_interpolate(const CurvesGeometry &src_curves,
-                                                   CurvesGeometry &dst_curves,
-                                                   AttributesForInterpolation &result)
+static void gather_point_attributes_to_interpolate(
+    const CurvesGeometry &src_curves,
+    CurvesGeometry &dst_curves,
+    AttributesForInterpolation &result,
+    const ResampleCurvesOutputAttributeIDs &output_ids)
 {
   VectorSet<bke::AttributeIDRef> ids;
   VectorSet<bke::AttributeIDRef> ids_no_interpolation;
@@ -159,11 +166,75 @@ static void gather_point_attributes_to_interpolate(const CurvesGeometry &src_cur
                            result.src_no_interpolation,
                            result.dst_no_interpolation,
                            result.dst_attributes);
+
+  bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
+  if (output_ids.tangent_id) {
+    result.src_evaluated_tangents = src_curves.evaluated_tangents();
+    bke::GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
+        output_ids.tangent_id, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+    result.dst_tangents = dst_attribute.span.typed<float3>();
+    result.dst_attributes.append(std::move(dst_attribute));
+  }
+  if (output_ids.normal_id) {
+    result.src_evaluated_normals = src_curves.evaluated_normals();
+    bke::GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
+        output_ids.normal_id, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
+    result.dst_normals = dst_attribute.span.typed<float3>();
+    result.dst_attributes.append(std::move(dst_attribute));
+  }
+}
+
+static void copy_or_defaults_for_unselected_curves(const CurvesGeometry &src_curves,
+                                                   const Span<IndexRange> unselected_ranges,
+                                                   const AttributesForInterpolation &attributes,
+                                                   CurvesGeometry &dst_curves)
+{
+  bke::curves::copy_point_data(src_curves,
+                               dst_curves,
+                               unselected_ranges,
+                               src_curves.positions(),
+                               dst_curves.positions_for_write());
+
+  for (const int i : attributes.src.index_range()) {
+    bke::curves::copy_point_data(
+        src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
+  }
+  for (const int i : attributes.src_no_interpolation.index_range()) {
+    bke::curves::copy_point_data(src_curves,
+                                 dst_curves,
+                                 unselected_ranges,
+                                 attributes.src_no_interpolation[i],
+                                 attributes.dst_no_interpolation[i]);
+  }
+
+  if (!attributes.dst_tangents.is_empty()) {
+    bke::curves::fill_points(dst_curves, unselected_ranges, float3(0), attributes.dst_tangents);
+  }
+  if (!attributes.dst_normals.is_empty()) {
+    bke::curves::fill_points(dst_curves, unselected_ranges, float3(0), attributes.dst_normals);
+  }
+}
+
+static void normalize_span(MutableSpan<float3> data)
+{
+  for (const int i : data.index_range()) {
+    data[i] = math::normalize(data[i]);
+  }
+}
+
+static void normalize_curve_point_data(const CurvesGeometry &curves,
+                                       const IndexMask curve_selection,
+                                       MutableSpan<float3> data)
+{
+  for (const int i_curve : curve_selection) {
+    normalize_span(data.slice(curves.points_for_curve(i_curve)));
+  }
 }
 
 static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
                                           const fn::Field<bool> &selection_field,
-                                          const fn::Field<int> &count_field)
+                                          const fn::Field<int> &count_field,
+                                          const ResampleCurvesOutputAttributeIDs &output_ids)
 {
   /* Create the new curves without any points and evaluate the final count directly
    * into the offsets array, in order to be accumulated into offsets later. */
@@ -200,7 +271,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
   MutableSpan<float3> dst_positions = dst_curves.positions_for_write();
 
   AttributesForInterpolation attributes;
-  gather_point_attributes_to_interpolate(src_curves, dst_c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list