[Bf-blender-cvs] [2c2178549b6] master: Curves: add OffsetIndices abstraction

Jacques Lucke noreply at git.blender.org
Wed Jan 18 11:54:00 CET 2023


Commit: 2c2178549b6c80154184958a55978e1aac7af6fc
Author: Jacques Lucke
Date:   Wed Jan 18 11:52:27 2023 +0100
Branches: master
https://developer.blender.org/rB2c2178549b6c80154184958a55978e1aac7af6fc

Curves: add OffsetIndices abstraction

This changes how we access the points that correspond to each curve in a `CurvesGeometry`.
Previously, `CurvesGeometry::points_for_curve(int curve_index) -> IndexRange`
was called for every curve in many loops. Now one has to call
`CurvesGeometry::points_by_curve() -> OffsetIndices` before the
loop and use the returned value inside the loop.

While this is a little bit more verbose in general, it has some benefits:
* Better standardization of how "offset indices" are used. The new data
  structure can be used independent of curves.
* Allows for better data oriented design. Generally, we want to retrieve
  all the arrays we need for a loop first and then do the processing.
  Accessing the old `CurvesGeometry::points_for_curve(...)` did not follow
  that design because it hid the underlying offset array.
* Makes it easier to pass the offsets to a function without having to
  pass the entire `CurvesGeometry`.
* Can improve performance in theory due to one less memory access
  because `this` does not have to be dereferenced every time.
  This likely doesn't have a noticable impact in practice.

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

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

M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/BKE_curves_utils.hh
M	source/blender/blenkernel/intern/curve_legacy_convert.cc
M	source/blender/blenkernel/intern/curve_to_mesh_convert.cc
M	source/blender/blenkernel/intern/curves_geometry.cc
M	source/blender/blenkernel/intern/curves_utils.cc
M	source/blender/blenkernel/intern/geometry_component_curves.cc
A	source/blender/blenlib/BLI_offset_indices.hh
M	source/blender/blenlib/CMakeLists.txt
A	source/blender/blenlib/intern/offset_indices.cc
M	source/blender/draw/intern/draw_cache_impl_curves.cc
M	source/blender/draw/intern/draw_curves.cc
M	source/blender/editors/curves/intern/curves_add.cc
M	source/blender/editors/curves/intern/curves_ops.cc
M	source/blender/editors/curves/intern/curves_selection.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
M	source/blender/geometry/intern/add_curves_on_mesh.cc
M	source/blender/geometry/intern/fillet_curves.cc
M	source/blender/geometry/intern/resample_curves.cc
M	source/blender/geometry/intern/set_curve_type.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_blur_attribute.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.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_curve_topology_points_of_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
M	source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
M	source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
M	source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc

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

diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index 1ed872c8ab8..6569629c71f 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -18,6 +18,7 @@
 #include "BLI_generic_virtual_array.hh"
 #include "BLI_index_mask.hh"
 #include "BLI_math_vector_types.hh"
+#include "BLI_offset_indices.hh"
 #include "BLI_shared_cache.hh"
 #include "BLI_span.hh"
 #include "BLI_task.hh"
@@ -164,23 +165,17 @@ class CurvesGeometry : public ::CurvesGeometry {
   IndexRange points_range() const;
   IndexRange curves_range() const;
 
-  /**
-   * Number of control points in the indexed curve.
-   */
-  int points_num_for_curve(const int index) const;
-
   /**
    * The index of the first point in every curve. The size of this span is one larger than the
-   * number of curves. Consider using #points_for_curve rather than using the offsets directly.
+   * number of curves. Consider using #points_by_curve rather than using the offsets directly.
    */
   Span<int> offsets() const;
   MutableSpan<int> offsets_for_write();
 
   /**
-   * Access a range of indices of point data for a specific curve.
+   * The offsets of every curve into arrays on the points domain.
    */
-  IndexRange points_for_curve(int index) const;
-  IndexRange points_for_curves(IndexRange curves) const;
+  OffsetIndices<int> points_by_curve() const;
 
   /** The type (#CurveType) of each curve, or potentially a single if all are the same type. */
   VArray<int8_t> curve_types() const;
@@ -852,16 +847,6 @@ inline IndexRange CurvesGeometry::curves_range() const
   return IndexRange(this->curves_num());
 }
 
-inline int CurvesGeometry::points_num_for_curve(const int index) const
-{
-  BLI_assert(this->curve_num > 0);
-  BLI_assert(this->curve_num > index);
-  BLI_assert(this->curve_offsets != nullptr);
-  const int offset = this->curve_offsets[index];
-  const int offset_next = this->curve_offsets[index + 1];
-  return offset_next - offset;
-}
-
 inline bool CurvesGeometry::is_single_type(const CurveType type) const
 {
   return this->curve_type_counts()[type] == this->curves_num();
@@ -884,25 +869,9 @@ inline const std::array<int, CURVE_TYPES_NUM> &CurvesGeometry::curve_type_counts
   return this->runtime->type_counts;
 }
 
-inline IndexRange CurvesGeometry::points_for_curve(const int index) const
+inline OffsetIndices<int> CurvesGeometry::points_by_curve() const
 {
-  /* Offsets are not allocated when there are no curves. */
-  BLI_assert(this->curve_num > 0);
-  BLI_assert(this->curve_num > index);
-  BLI_assert(this->curve_offsets != nullptr);
-  const int offset = this->curve_offsets[index];
-  const int offset_next = this->curve_offsets[index + 1];
-  return {offset, offset_next - offset};
-}
-
-inline IndexRange CurvesGeometry::points_for_curves(const IndexRange curves) const
-{
-  /* Offsets are not allocated when there are no curves. */
-  BLI_assert(this->curve_num > 0);
-  BLI_assert(this->curve_offsets != nullptr);
-  const int offset = this->curve_offsets[curves.start()];
-  const int offset_next = this->curve_offsets[curves.one_after_last()];
-  return {offset, offset_next - offset};
+  return OffsetIndices<int>({this->curve_offsets, this->curve_num + 1});
 }
 
 inline int CurvesGeometry::evaluated_points_num() const
@@ -928,7 +897,8 @@ inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange c
 
 inline Span<int> CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const
 {
-  const IndexRange points = this->points_for_curve(curve_index);
+  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);
 }
 
diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh
index 77998b24a32..144f934414a 100644
--- a/source/blender/blenkernel/BKE_curves_utils.hh
+++ b/source/blender/blenkernel/BKE_curves_utils.hh
@@ -532,11 +532,6 @@ void fill_curve_counts(const bke::CurvesGeometry &curves,
                        Span<IndexRange> curve_ranges,
                        MutableSpan<int> counts);
 
-/**
- * Turn an array of sizes into the offset at each index including all previous sizes.
- */
-void accumulate_counts_to_offsets(MutableSpan<int> counts_to_offsets, int start_offset = 0);
-
 IndexMask indices_for_type(const VArray<int8_t> &types,
                            const std::array<int, CURVE_TYPES_NUM> &type_counts,
                            const CurveType type,
diff --git a/source/blender/blenkernel/intern/curve_legacy_convert.cc b/source/blender/blenkernel/intern/curve_legacy_convert.cc
index 938dcbd6269..f82d931114e 100644
--- a/source/blender/blenkernel/intern/curve_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/curve_legacy_convert.cc
@@ -108,6 +108,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
     return curves_id;
   }
 
+  const OffsetIndices points_by_curve = curves.points_by_curve();
   MutableSpan<float3> positions = curves.positions_for_write();
   SpanAttributeWriter<float> radius_attribute =
       curves_attributes.lookup_or_add_for_write_only_span<float>("radius", ATTR_DOMAIN_POINT);
@@ -119,7 +120,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
       for (const int curve_i : selection.slice(range)) {
         const Nurb &src_curve = *src_curves[curve_i];
         const Span<BPoint> src_points(src_curve.bp, src_curve.pntsu);
-        const IndexRange points = curves.points_for_curve(curve_i);
+        const IndexRange points = points_by_curve[curve_i];
 
         for (const int i : src_points.index_range()) {
           const BPoint &bp = src_points[i];
@@ -146,7 +147,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
       for (const int curve_i : selection.slice(range)) {
         const Nurb &src_curve = *src_curves[curve_i];
         const Span<BezTriple> src_points(src_curve.bezt, src_curve.pntsu);
-        const IndexRange points = curves.points_for_curve(curve_i);
+        const IndexRange points = points_by_curve[curve_i];
 
         resolutions[curve_i] = src_curve.resolu;
 
@@ -174,7 +175,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
       for (const int curve_i : selection.slice(range)) {
         const Nurb &src_curve = *src_curves[curve_i];
         const Span src_points(src_curve.bp, src_curve.pntsu);
-        const IndexRange points = curves.points_for_curve(curve_i);
+        const IndexRange points = points_by_curve[curve_i];
 
         resolutions[curve_i] = src_curve.resolu;
         nurbs_orders[curve_i] = src_curve.orderu;
diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
index 481e3018942..9fd35fbfb65 100644
--- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
+++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
@@ -633,10 +633,11 @@ static void write_sharp_bezier_edges(const CurvesInfo &curves_info,
 
   sharp_edges = mesh_attributes.lookup_or_add_for_write_span<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
 
+  const OffsetIndices profile_points_by_curve = profile.points_by_curve();
   const VArray<int8_t> types = profile.curve_types();
   foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
     if (types[info.i_profile] == CURVE_TYPE_BEZIER) {
-      const IndexRange points = profile.points_for_curve(info.i_profile);
+      const IndexRange points = profile_points_by_curve[info.i_profile];
       mark_bezier_vector_edges_sharp(points.size(),
                                      info.main_segment_num,
                                      profile.bezier_evaluated_offsets_for_curve(info.i_profile),
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index 3d4f81019a7..3ca951858c6 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -457,6 +457,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
                                         MutableSpan<int> offsets,
                                         MutableSpan<int> bezier_evaluated_offsets)
 {
+  const OffsetIndices points_by_curve = curves.points_by_curve();
   VArray<int8_t> types = curves.curve_types();
   VArray<int> resolution = curves.resolution();
   VArray<bool> cyclic = curves.cyclic();
@@ -468,7 +469,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
   VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
 
   build_offsets(offsets, [&](const int curve_index) -> int {
-    const IndexRange points = curves.points_for_curve(curve_index);
+    const IndexRange points = points_by_curve[curve_index];
     switch (types[curve_index]) {
       case CURVE_TYPE_CATMULL_ROM:
         return curves::catmull_rom::calculate_evaluated_num(
@@ -533,9 +534,10 @@ IndexMask CurvesGeometry::indices_for_curve_type(const CurveType type,
 
 Array<int> CurvesGeometry::point_to_curve_map() const
 {
+  const OffsetIndices points_by_curve = this->points_by_curve();
   Array<int> map(this->points_num());
   for (const int i : this->curves_range()) {
-    map.as_mutable_span().slice(this->points_for_curve(i)).fill(i);
+    map.as_mutable_span().slice(points_by_curve[i]).fill(i);
   }
   return map;
 }
@@ -552,13 +554,14 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
     this->runtime->nurbs_basis_cache.resize(this->curves_num());
     MutableSpan<curves::nurbs::BasisCache> basis_caches(this->runtime->nurbs_basis_cache);
 
+    const OffsetIndices points_by_curve = this->points_by_curve();
     VArray<bool> cyclic = this->cyclic();
     VArray<int8_t> orders = this->nurbs_orders();
     VArray<int8_t> knots_modes = this->nurbs_knots_modes();
 
     threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) {
       for (const int curve_index : nurbs_mask.slice(range)) {
-        const Inde

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list