Curves: Parallelize nurbs custom knots offsets cache calculation

Build the size for each curve in parallel, then accumulate the sizes
to offsets afterwards. This way it's easy to parallel. Also only count
custom knots for NURBS.

Pull Request: https://projects.blender.org/blender/blender/pulls/145581
This commit is contained in:
Hans Goudey
2025-09-03 04:29:08 +02:00
committed by Hans Goudey
parent 623f3c2585
commit 848ced8fe6
3 changed files with 26 additions and 10 deletions

View File

@@ -548,23 +548,31 @@ IndexMask CurvesGeometry::nurbs_custom_knot_curves(IndexMaskMemory &memory) cons
OffsetIndices<int> CurvesGeometry::nurbs_custom_knots_by_curve() const
{
const CurvesGeometryRuntime &runtime = *this->runtime;
if (this->is_empty()) {
if (!this->has_curve_with_type(CURVE_TYPE_NURBS)) {
return {};
}
runtime.custom_knot_offsets_cache.ensure([&](Vector<int> &r_data) {
r_data.resize(this->curve_num + 1, 0);
r_data.resize(this->curve_num + 1);
const OffsetIndices points_by_curve = this->points_by_curve();
const OffsetIndices<int> points_by_curve = this->points_by_curve();
const VArray<int8_t> curve_types = this->curve_types();
const VArray<int8_t> knot_modes = this->nurbs_knots_modes();
const VArray<int8_t> orders = this->nurbs_orders();
int knot_count = 0;
for (const int curve : this->curves_range()) {
knot_count += knot_modes[curve] == NURBS_KNOT_MODE_CUSTOM ?
points_by_curve[curve].size() + orders[curve] :
0;
r_data[curve + 1] = knot_count;
}
threading::parallel_for(this->curves_range(), 1024, [&](const IndexRange range) {
for (const int curve : range) {
if (curve_types[curve] != CURVE_TYPE_NURBS) {
r_data[curve] = 0;
continue;
}
if (knot_modes[curve] != NURBS_KNOT_MODE_CUSTOM) {
r_data[curve] = 0;
continue;
}
r_data[curve] = points_by_curve[curve].size() + orders[curve];
}
});
offset_indices::accumulate_counts_to_offsets(r_data.as_mutable_span());
});
return OffsetIndices<int>(runtime.custom_knot_offsets_cache.data());
}

View File

@@ -190,21 +190,28 @@ TEST(grease_pencil_merge, merge_keyframes)
Drawing *drawing = grease_pencil.insert_frame(layer1, 0);
drawing->strokes_for_write().resize(10, 2);
drawing->strokes_for_write().update_curve_types();
drawing = grease_pencil.insert_frame(layer2, 0);
drawing->strokes_for_write().resize(20, 3);
drawing->strokes_for_write().update_curve_types();
drawing = grease_pencil.insert_frame(layer2, 2);
drawing->strokes_for_write().resize(30, 4);
drawing->strokes_for_write().update_curve_types();
drawing = grease_pencil.insert_frame(layer3, 0);
drawing->strokes_for_write().resize(40, 5);
drawing->strokes_for_write().update_curve_types();
drawing = grease_pencil.insert_frame(layer3, 3);
drawing->strokes_for_write().resize(50, 6);
drawing->strokes_for_write().update_curve_types();
drawing = grease_pencil.insert_frame(layer4, 1);
drawing->strokes_for_write().resize(60, 7);
drawing->strokes_for_write().update_curve_types();
drawing = grease_pencil.insert_frame(layer4, 3);
drawing->strokes_for_write().resize(70, 8);
drawing->strokes_for_write().update_curve_types();
GreasePencil *merged_grease_pencil = BKE_grease_pencil_new_nomain();
BKE_grease_pencil_copy_parameters(grease_pencil, *merged_grease_pencil);

View File

@@ -44,6 +44,7 @@ static void create_test_curves(bke::CurvesGeometry &curves, Span<int> offsets)
curves.resize(points_num, curves_num);
curves.offsets_for_write().copy_from(offsets);
curves.update_curve_types();
/* Attribute storing original indices to test point remapping. */
SpanAttributeWriter<int> test_indices_writer =