[Bf-blender-cvs] [13bafb91b96] temp-lineart-embree: Curves: Add a utility to count curves of each type

Hans Goudey noreply at git.blender.org
Sat Mar 26 17:10:56 CET 2022


Commit: 13bafb91b96e627fb9ffc701da9153768b215dcb
Author: Hans Goudey
Date:   Fri Mar 25 09:00:30 2022 -0500
Branches: temp-lineart-embree
https://developer.blender.org/rB13bafb91b96e627fb9ffc701da9153768b215dcb

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

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

M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/intern/curves_geometry.cc
M	source/blender/blenkernel/intern/curves_geometry_test.cc
M	source/blender/makesdna/DNA_curves_types.h

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

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. */



More information about the Bf-blender-cvs mailing list