[Bf-blender-cvs] [9233b609eb9] master: Cleanup: Use utility function for copying curve domain data

Hans Goudey noreply at git.blender.org
Thu Jan 19 22:40:14 CET 2023


Commit: 9233b609eb94785739689227c45fbed1ee10a7cc
Author: Hans Goudey
Date:   Thu Jan 19 15:08:58 2023 -0600
Branches: master
https://developer.blender.org/rB9233b609eb94785739689227c45fbed1ee10a7cc

Cleanup: Use utility function for copying curve domain data

Standardizing the process of creating a new CurvesGeometry with
different curve sizes based on an existing curves is helpful, since
there are a few methods to simplify the process that aren't obvious
at first, like filling the offsets with sizes directly and accumulating
them to become sizes.

Also, in the trim curves node, avoid creating the curve types attribute
all the time. Use the special API functions for the types which do
some optimizations automatically. Also use a more consistent
method to copy the curve domain data, and correct some comments.

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

M	source/blender/blenkernel/BKE_curves_utils.hh
M	source/blender/geometry/intern/resample_curves.cc
M	source/blender/geometry/intern/trim_curves.cc

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

diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh
index 144f934414a..c8b8510a938 100644
--- a/source/blender/blenkernel/BKE_curves_utils.hh
+++ b/source/blender/blenkernel/BKE_curves_utils.hh
@@ -76,14 +76,17 @@ struct CurvePoint : public CurveSegment {
  * [0, range_size) can be iterated over an arbitrary amount of times in between.
  */
 class IndexRangeCyclic {
-  /* Index to the start and end of the iterated range.
+  /**
+   * Index to the start and end of the iterated range.
    */
   int start_ = 0;
   int end_ = 0;
-  /* Size of the underlying iterable range.
+  /**
+   * Size of the underlying iterable range.
    */
   int range_size_ = 0;
-  /* Number of times the range end is passed when the range is iterated.
+  /**
+   * Number of times the range end is passed when the range is iterated.
    */
   int cycles_ = 0;
 
@@ -519,8 +522,12 @@ void fill_points(const CurvesGeometry &curves,
 }
 
 /**
- * Copy only the attributes on the curve domain, but not the offsets or any point attributes,
- * meant for operations that change the number of points but not the number of curves.
+ * Create new curves with the same number of curves as the input, but no points. Copy all curve
+ * domain attributes to the new curves, except the offsets encoding the size of each curve.
+ *
+ * Used for operations that change the number of points but not the number of curves, allowing
+ * creation of the new offsets directly inside the new array.
+ *
  * \warning The returned curves have invalid offsets!
  */
 bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves);
diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc
index eac1d7d8d81..77e136ae886 100644
--- a/source/blender/geometry/intern/resample_curves.cc
+++ b/source/blender/geometry/intern/resample_curves.cc
@@ -239,16 +239,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves,
                                           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. */
-  CurvesGeometry dst_curves = CurvesGeometry(0, src_curves.curves_num());
-
-  /* Directly copy curve attributes, since they stay the same (except for curve types). */
-  CustomData_copy(&src_curves.curve_data,
-                  &dst_curves.curve_data,
-                  CD_MASK_ALL,
-                  CD_DUPLICATE,
-                  src_curves.curves_num());
+  CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
   MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
 
   const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE};
@@ -422,17 +413,8 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves,
   const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
   const OffsetIndices src_evaluated_points_by_curve = src_curves.evaluated_points_by_curve();
 
-  CurvesGeometry dst_curves(0, src_curves.curves_num());
-
-  /* Directly copy curve attributes, since they stay the same (except for curve types). */
-  CustomData_copy(&src_curves.curve_data,
-                  &dst_curves.curve_data,
-                  CD_MASK_ALL,
-                  CD_DUPLICATE,
-                  src_curves.curves_num());
-  /* All resampled curves are poly curves. */
+  CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
   dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY);
-
   MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
   threading::parallel_for(selection.index_range(), 4096, [&](IndexRange range) {
     for (const int i : selection.slice(range)) {
diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc
index 1ab330c3c0a..2e3247f0885 100644
--- a/source/blender/geometry/intern/trim_curves.cc
+++ b/source/blender/geometry/intern/trim_curves.cc
@@ -822,8 +822,7 @@ static float trim_sample_length(const Span<float> accumulated_lengths,
 }
 
 /**
- * Compute the selection for the given curve type. Tracks indices for splitting the selection if
- * there are curves reduced to a single point.
+ * Compute the selected range of points for every selected curve.
  */
 static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves,
                                           const IndexMask selection,
@@ -831,7 +830,6 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves,
                                           const VArray<float> &ends,
                                           const GeometryNodeCurveSampleMode mode,
                                           MutableSpan<int> dst_curve_size,
-                                          MutableSpan<int8_t> dst_curve_types,
                                           MutableSpan<bke::curves::CurvePoint> start_points,
                                           MutableSpan<bke::curves::CurvePoint> end_points,
                                           MutableSpan<bke::curves::IndexRangeCyclic> src_ranges)
@@ -841,19 +839,18 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves,
   const VArray<bool> src_cyclic = curves.cyclic();
   const VArray<int> resolution = curves.resolution();
   const VArray<int8_t> curve_types = curves.curve_types();
+  curves.ensure_can_interpolate_to_evaluated();
 
-  /* Compute. */
   threading::parallel_for(selection.index_range(), 128, [&](const IndexRange selection_range) {
     for (const int64_t curve_i : selection.slice(selection_range)) {
       CurveType curve_type = CurveType(curve_types[curve_i]);
 
       int point_count;
       if (curve_type == CURVE_TYPE_NURBS) {
-        dst_curve_types[curve_i] = CURVE_TYPE_POLY;
+        /* The result curve is a poly curve. */
         point_count = evaluated_points_by_curve.size(curve_i);
       }
       else {
-        dst_curve_types[curve_i] = curve_type;
         point_count = points_by_curve.size(curve_i);
       }
       if (point_count == 1) {
@@ -959,50 +956,29 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
   BLI_assert(starts.size() == ends.size());
   src_curves.ensure_evaluated_lengths();
 
-  Vector<int64_t> inverse_selection_indices;
-  const IndexMask inverse_selection = selection.invert(src_curves.curves_range(),
-                                                       inverse_selection_indices);
+  const Vector<IndexRange> inverse_selection = selection.extract_ranges_invert(
+      src_curves.curves_range());
 
-  /* Create destination curves. */
-  bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
+  bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves);
   MutableSpan<int> dst_curve_offsets = dst_curves.offsets_for_write();
-  MutableSpan<int8_t> dst_curve_types = dst_curves.curve_types_for_write();
-  Array<bke::curves::CurvePoint, 12> start_points(src_curves.curves_num());
-  Array<bke::curves::CurvePoint, 12> end_points(src_curves.curves_num());
-  Array<bke::curves::IndexRangeCyclic, 12> src_ranges(src_curves.curves_num());
-
-  if (src_curves.has_curve_with_type({CURVE_TYPE_BEZIER, CURVE_TYPE_NURBS})) {
-    if (src_curves.has_curve_with_type(CURVE_TYPE_NURBS)) {
-      src_curves.evaluated_positions();
-    }
-  }
+  Array<bke::curves::CurvePoint, 16> start_points(src_curves.curves_num());
+  Array<bke::curves::CurvePoint, 16> end_points(src_curves.curves_num());
+  Array<bke::curves::IndexRangeCyclic, 16> src_ranges(src_curves.curves_num());
 
-  /* Compute destination curves. */
   compute_curve_trim_parameters(src_curves,
                                 selection,
                                 starts,
                                 ends,
                                 mode,
                                 dst_curve_offsets,
-                                dst_curve_types,
                                 start_points,
                                 end_points,
                                 src_ranges);
+  bke::curves::fill_curve_counts(src_curves, inverse_selection, dst_curve_offsets);
 
-  /* Transfer copied curves parameters. */
-  const VArray<int8_t> src_curve_types = src_curves.curve_types();
-  const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
-  threading::parallel_for(
-      inverse_selection.index_range(), 4096, [&](const IndexRange selection_range) {
-        for (const int64_t curve_i : inverse_selection.slice(selection_range)) {
-          dst_curve_offsets[curve_i] = src_points_by_curve.size(curve_i);
-          dst_curve_types[curve_i] = src_curve_types[curve_i];
-        }
-      });
   /* Finalize and update the geometry container. */
   offset_indices::accumulate_counts_to_offsets(dst_curve_offsets);
   dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num());
-  dst_curves.update_curve_types();
 
   /* Populate curve domain. */
   const bke::AttributeAccessor src_attributes = src_curves.attributes();
@@ -1013,12 +989,6 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
     transfer_curve_skip.remove("nurbs_order");
     transfer_curve_skip.remove("knots_mode");
   }
-  bke::copy_attribute_domain(src_attributes,
-                             dst_attributes,
-                             selection,
-                             ATTR_DOMAIN_CURVE,
-                             propagation_info,
-                             transfer_curve_skip);
 
   /* Fetch custom point domain attributes for transfer (copy). */
   Vector<bke::AttributeTransferData> transfer_attributes = bke::retrieve_attributes_for_transfer(
@@ -1061,6 +1031,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
                        transfer_attributes);
   };
   auto trim_evaluated = [&](const IndexMask selection) {
+    dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY);
     /* Ensure evaluated positions are

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list