[Bf-blender-cvs] [38a45e46bc9] master: Cleanup: Use OffsetIndices class in more cases

Hans Goudey noreply at git.blender.org
Thu Jan 19 20:51:44 CET 2023


Commit: 38a45e46bc910c68ae3aa349c1ef3c72a34b6fc8
Author: Hans Goudey
Date:   Thu Jan 19 13:48:20 2023 -0600
Branches: master
https://developer.blender.org/rB38a45e46bc910c68ae3aa349c1ef3c72a34b6fc8

Cleanup: Use OffsetIndices class in more cases

The same logic from D17025 is used in other places in the curve code.
This patch uses the class for the evaluated point offsets and the Bezier
control point offsets. This helps to standardize the behavior and make
it easier to read.

Previously the Bezier control point offsets used a slightly different standard
where the first point was the first offset, just so they could have the same
size as the number of points. However two nodes used a helper function
to use the same `OffsetIndices` system, so switch to that there too.
That requires removing the subtraction by one to find the actual offset.

Also add const when accessing data arrays from curves, for consistency.

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

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

M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/intern/curve_bezier.cc
M	source/blender/blenkernel/intern/curve_catmull_rom.cc
M	source/blender/blenkernel/intern/curve_to_mesh_convert.cc
M	source/blender/blenkernel/intern/curves_geometry.cc
M	source/blender/blenkernel/intern/geometry_component_curves.cc
M	source/blender/blenlib/BLI_offset_indices.hh
M	source/blender/draw/intern/draw_cache_impl_curve.cc
M	source/blender/geometry/intern/fillet_curves.cc
M	source/blender/geometry/intern/resample_curves.cc
M	source/blender/geometry/intern/subdivide_curves.cc
M	source/blender/geometry/intern/trim_curves.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc

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

diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index 6569629c71f..1b52fe709ac 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -30,17 +30,6 @@
 
 namespace blender::bke {
 
-template<typename T, BLI_ENABLE_IF(std::is_integral_v<T>)>
-constexpr IndexRange offsets_to_range(Span<T> offsets, int64_t index)
-{
-  BLI_assert(index >= 0);
-  BLI_assert(index < offsets.size());
-
-  const int offset = offsets[index];
-  const int offset_next = offsets[index + 1];
-  return {offset, offset_next - offset};
-}
-
 namespace curves::nurbs {
 
 struct BasisCache {
@@ -81,7 +70,7 @@ class CurvesGeometryRuntime {
    * evaluated points, Bezier curve vector segments, different resolutions per curve, etc.
    */
   mutable Vector<int> evaluated_offsets_cache;
-  mutable Vector<int> bezier_evaluated_offsets;
+  mutable Vector<int> all_bezier_evaluated_offsets;
   mutable CacheMutex offsets_cache_mutex;
 
   mutable Vector<curves::nurbs::BasisCache> nurbs_basis_cache;
@@ -303,25 +292,14 @@ class CurvesGeometry : public ::CurvesGeometry {
   int evaluated_points_num() const;
 
   /**
-   * Access a range of indices of point data for a specific curve.
-   * Call #evaluated_offsets() first to ensure that the evaluated offsets cache is current.
-   */
-  IndexRange evaluated_points_for_curve(int index) const;
-  IndexRange evaluated_points_for_curves(IndexRange curves) const;
-
-  /**
-   * The index of the first evaluated point for every curve. The size of this span is one larger
-   * than the number of curves. Consider using #evaluated_points_for_curve rather than using the
-   * offsets directly.
+   * The offsets of every curve's evaluated points.
    */
-  Span<int> evaluated_offsets() const;
-
-  /** Makes sure the data described by #evaluated_offsets if necessary. */
-  void ensure_evaluated_offsets() const;
+  OffsetIndices<int> evaluated_points_by_curve() const;
 
   /**
-   * Retrieve offsets into a Bezier curve's evaluated points for each control point.
-   * Call #ensure_evaluated_offsets() first to ensure that the evaluated offsets cache is current.
+   * Retrieve offsets into a Bezier curve's evaluated points for each control point. Stored in the
+   * same format as #OffsetIndices. Call #evaluated_points_by_curve() first to ensure that the
+   * evaluated offsets cache is current.
    */
   Span<int> bezier_evaluated_offsets_for_curve(int curve_index) const;
 
@@ -489,6 +467,17 @@ inline float3 decode_surface_bary_coord(const float2 &v)
   return {v.x, v.y, 1.0f - v.x - v.y};
 }
 
+/**
+ * Return a range used to retrieve values from an array of values stored per point, but with an
+ * extra element at the end of each curve. This is useful for offsets within curves, where it is
+ * convenient to store the first 0 and have the last offset be the total result curve size, using
+ * the same rules as #OffsetIndices.
+ */
+inline IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index)
+{
+  return {curve_index + points.start(), points.size() + 1};
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -567,8 +556,9 @@ bool point_is_sharp(Span<int8_t> handle_types_left, Span<int8_t> handle_types_ri
  * point edges generate the number of edges specified by the resolution, vector segments only
  * generate one edge.
  *
- * The size of the offsets array must be the same as the number of points. The value at each index
- * is the evaluated point offset including the following segment.
+ * The expectations for the result \a evaluated_offsets are the same as for #OffsetIndices, so the
+ * size must be one greater than the number of points. The value at each index is the evaluated
+ * point at the start of that segment.
  */
 void calculate_evaluated_offsets(Span<int8_t> handle_types_left,
                                  Span<int8_t> handle_types_right,
@@ -668,7 +658,7 @@ void evaluate_segment(const float3 &point_0,
 void calculate_evaluated_positions(Span<float3> positions,
                                    Span<float3> handles_left,
                                    Span<float3> handles_right,
-                                   Span<int> evaluated_offsets,
+                                   OffsetIndices<int> evaluated_offsets,
                                    MutableSpan<float3> evaluated_positions);
 
 /**
@@ -676,7 +666,7 @@ void calculate_evaluated_positions(Span<float3> positions,
  * #evaluated_offsets. Unlike other curve types, for Bezier curves generic data and positions
  * are treated separately, since attribute values aren't stored for the handle control points.
  */
-void interpolate_to_evaluated(GSpan src, Span<int> evaluated_offsets, GMutableSpan dst);
+void interpolate_to_evaluated(GSpan src, OffsetIndices<int> evaluated_offsets, GMutableSpan dst);
 
 }  // namespace bezier
 
@@ -702,12 +692,12 @@ int calculate_evaluated_num(int points_num, bool cyclic, int resolution);
 void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst);
 
 /**
- * Evaluate the Catmull Rom curve. The size of each segment and its offset in the #dst span
- * is encoded in #evaluated_offsets, with the same method as #CurvesGeometry::offsets().
+ * Evaluate the Catmull Rom curve. The placement of each segment in the #dst span is desribed by
+ * #evaluated_offsets.
  */
 void interpolate_to_evaluated(const GSpan src,
                               const bool cyclic,
-                              const Span<int> evaluated_offsets,
+                              const OffsetIndices<int> evaluated_offsets,
                               GMutableSpan dst);
 
 void calculate_basis(const float parameter, float4 &r_weights);
@@ -877,36 +867,22 @@ inline OffsetIndices<int> CurvesGeometry::points_by_curve() const
 inline int CurvesGeometry::evaluated_points_num() const
 {
   /* This could avoid calculating offsets in the future in simple circumstances. */
-  return this->evaluated_offsets().last();
-}
-
-inline IndexRange CurvesGeometry::evaluated_points_for_curve(int index) const
-{
-  BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
-  return offsets_to_range(this->runtime->evaluated_offsets_cache.as_span(), index);
-}
-
-inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange curves) const
-{
-  BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
-  BLI_assert(this->curve_num > 0);
-  const int offset = this->runtime->evaluated_offsets_cache[curves.start()];
-  const int offset_next = this->runtime->evaluated_offsets_cache[curves.one_after_last()];
-  return {offset, offset_next - offset};
+  return this->evaluated_points_by_curve().total_size();
 }
 
 inline Span<int> CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const
 {
   const OffsetIndices points_by_curve = this->points_by_curve();
   const IndexRange points = points_by_curve[curve_index];
-  return this->runtime->bezier_evaluated_offsets.as_span().slice(points);
+  const IndexRange range = curves::per_curve_point_offsets_range(points, curve_index);
+  return this->runtime->all_bezier_evaluated_offsets.as_span().slice(range);
 }
 
 inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index,
                                                           const bool cyclic) const
 {
   BLI_assert(cyclic == this->cyclic()[curve_index]);
-  const IndexRange points = this->evaluated_points_for_curve(curve_index);
+  const IndexRange points = this->evaluated_points_by_curve()[curve_index];
   const int start = points.start() + curve_index;
   return {start, curves::segments_num(points.size(), cyclic)};
 }
diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc
index 3aa87be3787..460c96196ea 100644
--- a/source/blender/blenkernel/intern/curve_bezier.cc
+++ b/source/blender/blenkernel/intern/curve_bezier.cc
@@ -33,20 +33,21 @@ void calculate_evaluated_offsets(const Span<int8_t> handle_types_left,
                                  MutableSpan<int> evaluated_offsets)
 {
   const int size = handle_types_left.size();
-  BLI_assert(evaluated_offsets.size() == size);
+  BLI_assert(evaluated_offsets.size() == size + 1);
 
+  evaluated_offsets.first() = 0;
   if (size == 1) {
-    evaluated_offsets.first() = 1;
+    evaluated_offsets.last() = 1;
     return;
   }
 
   int offset = 0;
-
   for (const int i : IndexRange(size - 1)) {
-    offset += segment_is_vector(handle_types_left, handle_types_right, i) ? 1 : resolution;
     evaluated_offsets[i] = offset;
+    offset += segment_is_vector(handle_types_left, handle_types_right, i) ? 1 : resolution;
   }
 
+  evaluated_offsets.last(1) = offset;
   if (cyclic) {
     offset += last_cyclic_segment_is_vector(handle_types_left, handle_types_right) ? 1 :
                                                                                      resolution;
@@ -233,12 +234,11 @@ void evaluate_segment(const float3 &point_0,
 void calculate_evaluated_positions(const Span<float3> positions,
                                    const Span<float3> handles_left,
                                    const Span<float3> handles_right,
-                                   const Span<int> evaluated_offsets,
+                                   const OffsetIndices<int> evaluated_offsets,
                                    MutableSpan<float3> evaluated_positions)
 {
-  BLI_assert(evaluated_offsets.last() == evaluated_positions.size());
-  BLI_assert(evaluated_offsets.size() == positions.size());
-  if (evaluated_offsets.last() == 1) {
+  BLI_assert(evaluated_offsets.total_size() == evaluated_positions.size());
+  if (evaluated_offsets.total_size() == 1) {
     evaluated_positions.first() = positions.first();
     return;
   }
@@ -248,29 +248,29 @@ void calculate_evaluated_positions(const Span<float3> positions,
                    handles_right.first(),
                    handles_left[1],
                    positions[1],
-                   evaluated_positions.take_front(evaluated_offsets.first()));
+                   evaluated_positions.slice(evaluated_offsets[0])

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list