Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-03-25 17:00:30 +0300
committerHans Goudey <h.goudey@me.com>2022-03-25 17:00:30 +0300
commitc0016d85b2a62858229d31bd97399fbe2608f99d (patch)
tree9ccabf7543a5c7043d85a55f37c42c403e6b6013
parent59de9ceda05c84670d27fcb526d513e30a8e29b4 (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
-rw-r--r--source/blender/blenkernel/BKE_curves.hh2
-rw-r--r--source/blender/blenkernel/intern/curves_geometry.cc34
-rw-r--r--source/blender/blenkernel/intern/curves_geometry_test.cc22
-rw-r--r--source/blender/makesdna/DNA_curves_types.h1
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. */