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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user