Merge branch 'blender-v5.2-release'

This commit is contained in:
Falk David 2026-06-26 14:31:09 +02:00
commit bcdeac924e
5 changed files with 79 additions and 6 deletions

View file

@ -555,7 +555,7 @@ static wmOperatorStatus grease_pencil_delete_exec(bContext *C, wmOperator *op)
changed = true;
}
else if (selection_domain == bke::AttrDomain::Point) {
curves = geometry::remove_points_and_split(curves, elements_to_delete);
curves = geometry::grease_pencil_remove_points_and_split(curves, elements_to_delete);
info.drawing.tag_topology_changed();
changed = true;
}
@ -2288,7 +2288,7 @@ static bool grease_pencil_separate_selected(bContext &C,
/* Copy strokes to new CurvesGeometry. */
drawing_dst->strokes_for_write() = bke::curves_copy_point_selection(
curves_src, selected_points, {});
curves_src = geometry::remove_points_and_split(curves_src, selected_points);
curves_src = geometry::grease_pencil_remove_points_and_split(curves_src, selected_points);
info.drawing.tag_topology_changed();
drawing_dst->tag_topology_changed();
@ -2715,7 +2715,7 @@ static wmOperatorStatus grease_pencil_copy_strokes_exec(bContext *C, wmOperator
}
else if (selection_domain == bke::AttrDomain::Point) {
const IndexMask selected_points = ed::curves::retrieve_selected_points(curves, memory);
copied_curves = geometry::remove_points_and_split(
copied_curves = geometry::grease_pencil_remove_points_and_split(
curves, selected_points.complement(curves.points_range(), memory));
num_elements_copied += copied_curves.points_num();
}

View file

@ -2054,8 +2054,8 @@ static bool remove_points_and_split_from_drawings(
if (Drawing *drawing = get_current_drawing_or_duplicate_for_autokey(
scene, grease_pencil, info.layer_index))
{
drawing->strokes_for_write() = geometry::remove_points_and_split(drawing->strokes(),
points_to_remove);
drawing->strokes_for_write() = geometry::grease_pencil_remove_points_and_split(
drawing->strokes(), points_to_remove);
drawing->tag_topology_changed();
changed = true;
}

View file

@ -1147,7 +1147,7 @@ static void remove_points_with_low_opacity(bke::CurvesGeometry &curves,
curves.points_range(), memory, [&](const int64_t point) {
return opacities[point] < epsilon && point_was_modified[point];
});
curves = geometry::remove_points_and_split(curves, points_to_remove_and_split);
curves = geometry::grease_pencil_remove_points_and_split(curves, points_to_remove_and_split);
}
void EraseOperation::on_stroke_done(const bContext &C)

View file

@ -15,4 +15,10 @@ namespace blender::geometry {
bke::CurvesGeometry remove_points_and_split(const bke::CurvesGeometry &curves,
const IndexMask &mask);
/**
* Same as above, but will also handle splitting Grease Pencil fills.
*/
bke::CurvesGeometry grease_pencil_remove_points_and_split(const bke::CurvesGeometry &curves,
const IndexMask &mask);
} // namespace blender::geometry

View file

@ -8,6 +8,7 @@
#include "BKE_curves.hh"
#include "BKE_curves_utils.hh"
#include "BKE_deform.hh"
#include "BKE_grease_pencil_fills.hh"
#include "GEO_curves_remove_and_split.hh"
@ -117,4 +118,70 @@ bke::CurvesGeometry remove_points_and_split(const bke::CurvesGeometry &curves,
return dst_curves;
}
bke::CurvesGeometry grease_pencil_remove_points_and_split(const bke::CurvesGeometry &curves,
const IndexMask &mask)
{
bke::CurvesGeometry dst_curves = remove_points_and_split(curves, mask);
bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
if (bke::SpanAttributeWriter<int> dst_fill_ids = dst_attributes.lookup_for_write_span<int>(
"fill_id"))
{
Array<bool> points_to_delete(curves.points_num());
mask.to_bools(points_to_delete.as_mutable_span());
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
const VArray<bool> src_cyclic = curves.cyclic();
Array<Vector<int>> src_to_dst_curve(curves.curves_num());
Vector<int> dst_to_src_curve;
for (const int curve_i : curves.curves_range()) {
const IndexRange points = points_by_curve[curve_i];
const Span<bool> curve_points_to_delete = points_to_delete.as_span().slice(points);
const bool curve_cyclic = src_cyclic[curve_i];
/* Note: These ranges start at zero and need to be shifted by `points.first()` */
const Vector<IndexRange> ranges_to_keep = array_utils::find_all_ranges(
curve_points_to_delete, false);
if (ranges_to_keep.is_empty()) {
continue;
}
const bool is_last_segment_selected = curve_cyclic && ranges_to_keep.first().first() == 0 &&
ranges_to_keep.last().last() == points.size() - 1;
const bool is_curve_self_joined = is_last_segment_selected && ranges_to_keep.size() != 1;
/* Skip the first range because it is joined to the end of the last range. */
const int num_dst_curves = ranges_to_keep.size() - int(is_curve_self_joined);
src_to_dst_curve[curve_i].resize(num_dst_curves);
array_utils::fill_index_range<int>(src_to_dst_curve[curve_i].as_mutable_span(),
dst_to_src_curve.size());
dst_to_src_curve.append_n_times(curve_i, num_dst_curves);
}
IndexMaskMemory memory;
/* Get all the curves that were split off of the original geometry. */
const IndexMask non_original_curves = IndexMask::from_predicate(
dst_to_src_curve.index_range(), memory, [&](const int64_t dst_curve_index) {
/* Skip non-filled curves. */
if (dst_fill_ids.span[dst_curve_index] == 0) {
return false;
}
const int src_curve_index = dst_to_src_curve[dst_curve_index];
return src_to_dst_curve[src_curve_index].first() != dst_curve_index;
});
bke::greasepencil::gather_next_available_fill_ids(
dst_fill_ids.span.varray(), non_original_curves, dst_fill_ids.span);
dst_fill_ids.finish();
}
return dst_curves;
}
} // namespace blender::geometry