diff options
author | Hans Goudey <h.goudey@me.com> | 2022-03-25 17:00:30 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-03-25 17:00:30 +0300 |
commit | c0016d85b2a62858229d31bd97399fbe2608f99d (patch) | |
tree | 9ccabf7543a5c7043d85a55f37c42c403e6b6013 /source | |
parent | 59de9ceda05c84670d27fcb526d513e30a8e29b4 (diff) |
Curves: Add a utility to count curves of each type
This commit adds a utility that returns an array with the number
of curves of every type. One use case for this is detecting whether
to remove handle or NURBS attributes when changing curve types.
It's best to avoid using this when it's not necessary, but sometimes
it can't really be avoided, and having a utility at least makes using
an optimized version simple.
In the future, this information can be cached in the curves runtime.
Differential Revision: https://developer.blender.org/D14448
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_curves.hh | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curves_geometry.cc | 34 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curves_geometry_test.cc | 22 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curves_types.h | 1 |
4 files changed, 59 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 0f2ae8a02a6..96963dcbd8d 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -146,6 +146,8 @@ class CurvesGeometry : public ::CurvesGeometry { MutableSpan<int8_t> curve_types(); bool has_curve_with_type(const CurveType type) const; + /** Return the number of curves with each type. */ + std::array<int, CURVE_TYPES_NUM> count_curve_types() const; MutableSpan<float3> positions(); Span<float3> positions() const; diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 5bb6a97fa49..207d0d173ac 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -277,6 +277,40 @@ bool CurvesGeometry::has_curve_with_type(const CurveType type) const return false; } +std::array<int, CURVE_TYPES_NUM> CurvesGeometry::count_curve_types() const +{ + using CountsType = std::array<int, CURVE_TYPES_NUM>; + + CountsType identity; + identity.fill(0); + + const VArray<int8_t> types = this->curve_types(); + if (types.is_single()) { + identity[types.get_internal_single()] = this->curves_num(); + return identity; + } + + Span<int8_t> types_span = types.get_internal_span(); + return threading::parallel_reduce( + this->curves_range(), + 2048, + identity, + [&](const IndexRange curves_range, const CountsType &init) { + CountsType result = init; + for (const int curve_index : curves_range) { + result[types_span[curve_index]]++; + } + return result; + }, + [](const CountsType &a, const CountsType &b) { + CountsType result = a; + for (const int i : IndexRange(CURVE_TYPES_NUM)) { + result[i] += b[i]; + } + return result; + }); +} + MutableSpan<float3> CurvesGeometry::positions() { this->position = (float(*)[3])CustomData_duplicate_referenced_layer_named( diff --git a/source/blender/blenkernel/intern/curves_geometry_test.cc b/source/blender/blenkernel/intern/curves_geometry_test.cc index bc99785de1c..574f90f2e51 100644 --- a/source/blender/blenkernel/intern/curves_geometry_test.cc +++ b/source/blender/blenkernel/intern/curves_geometry_test.cc @@ -63,6 +63,28 @@ TEST(curves_geometry, Move) EXPECT_EQ(second_other.offsets().data(), offsets_data); } +TEST(curves_geometry, TypeCount) +{ + CurvesGeometry curves = create_basic_curves(100, 10); + curves.curve_types().copy_from({ + CURVE_TYPE_BEZIER, + CURVE_TYPE_NURBS, + CURVE_TYPE_NURBS, + CURVE_TYPE_NURBS, + CURVE_TYPE_CATMULL_ROM, + CURVE_TYPE_CATMULL_ROM, + CURVE_TYPE_CATMULL_ROM, + CURVE_TYPE_POLY, + CURVE_TYPE_POLY, + CURVE_TYPE_POLY, + }); + std::array<int, CURVE_TYPES_NUM> counts = curves.count_curve_types(); + EXPECT_EQ(counts[CURVE_TYPE_CATMULL_ROM], 3); + EXPECT_EQ(counts[CURVE_TYPE_POLY], 3); + EXPECT_EQ(counts[CURVE_TYPE_BEZIER], 1); + EXPECT_EQ(counts[CURVE_TYPE_NURBS], 3); +} + TEST(curves_geometry, CatmullRomEvaluation) { CurvesGeometry curves(4, 1); diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index f1626781fc6..97cc588e639 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -28,6 +28,7 @@ typedef enum CurveType { CURVE_TYPE_BEZIER = 2, CURVE_TYPE_NURBS = 3, } CurveType; +#define CURVE_TYPES_NUM 4 typedef enum HandleType { /** The handle can be moved anywhere, and doesn't influence the point's other handle. */ |