diff --git a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc index 18581c6b695..b2bd73e486a 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_paint.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_paint.cc @@ -26,6 +26,7 @@ #include "ED_grease_pencil.hh" #include "ED_view3d.hh" +#include "GEO_simplify_curves.hh" #include "GEO_smooth_curves.hh" #include "WM_api.hh" @@ -705,55 +706,41 @@ void PaintOperation::on_stroke_extended(const bContext &C, const InputSample &ex WM_event_add_notifier(&C, NC_GEOM | ND_DATA, grease_pencil); } -static float dist_to_interpolated_2d( - float2 pos, float2 posA, float2 posB, float val, float valA, float valB) -{ - const float dist1 = math::distance_squared(posA, pos); - const float dist2 = math::distance_squared(posB, pos); - - if (dist1 + dist2 > 1e-5f) { - const float interpolated_val = math::interpolate(valB, valA, dist1 / (dist1 + dist2)); - return math::distance(interpolated_val, val); - } - return 0.0f; -} - void PaintOperation::simplify_stroke(const bContext &C, bke::greasepencil::Drawing &drawing, - const float epsilon_px) + const float epsilon) { const Scene *scene = CTX_data_scene(&C); + const bke::CurvesGeometry &curves = drawing.strokes(); + const bool on_back = (scene->toolsettings->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) != 0; - const int active_curve = on_back ? drawing.strokes().curves_range().first() : - drawing.strokes().curves_range().last(); - const IndexRange points = drawing.strokes().points_by_curve()[active_curve]; - bke::CurvesGeometry &curves = drawing.strokes_for_write(); + const int active_curve = on_back ? curves.curves_range().first() : curves.curves_range().last(); + + IndexMaskMemory memory; + IndexMask points_to_delete = geometry::simplify_curve_attribute( + curves.positions(), + IndexRange::from_single(active_curve), + curves.points_by_curve(), + curves.cyclic(), + epsilon, + curves.positions(), + memory); + const VArray radii = drawing.radii(); + if (!radii.is_empty() && radii.is_span()) { + const IndexMask radii_mask = geometry::simplify_curve_attribute( + curves.positions(), + IndexRange::from_single(active_curve), + curves.points_by_curve(), + curves.cyclic(), + epsilon, + radii.get_internal_span(), + memory); + points_to_delete = IndexMask::from_intersection(points_to_delete, radii_mask, memory); + } - /* Distance function for `ramer_douglas_peucker_simplify`. */ - const Span positions_2d = this->screen_space_smoothed_coords_.as_span(); - const auto dist_function = [&](int64_t first_index, int64_t last_index, int64_t index) { - /* 2D coordinates are only stored for the current stroke, so offset the indices. */ - const float dist_position_px = dist_to_line_segment_v2( - positions_2d[index - points.first()], - positions_2d[first_index - points.first()], - positions_2d[last_index - points.first()]); - const float dist_radii_px = dist_to_interpolated_2d(positions_2d[index - points.first()], - positions_2d[first_index - points.first()], - positions_2d[last_index - points.first()], - radii[index], - radii[first_index], - radii[last_index]); - return math::max(dist_position_px, dist_radii_px); - }; - - Array points_to_delete(curves.points_num(), false); - int64_t total_points_to_delete = ed::greasepencil::ramer_douglas_peucker_simplify( - points, epsilon_px, dist_function, points_to_delete.as_mutable_span()); - - if (total_points_to_delete > 0) { - IndexMaskMemory memory; - curves.remove_points(IndexMask::from_bools(points_to_delete, memory), {}); + if (!points_to_delete.is_empty()) { + drawing.strokes_for_write().remove_points(points_to_delete, {}); } } @@ -867,8 +854,7 @@ void PaintOperation::on_stroke_done(const bContext &C) bke::greasepencil::Drawing &drawing = *grease_pencil.get_editable_drawing_at(active_layer, scene->r.cfra); if (do_post_processing) { - const float simplifiy_threshold_px = 0.5f; - this->simplify_stroke(C, drawing, simplifiy_threshold_px); + this->simplify_stroke(C, drawing, settings->simplify_f); } this->process_stroke_end(C, drawing); drawing.tag_topology_changed();