[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