FIX: reduce crossing perimeters fix

jira: none

Change-Id: I634dfbcc8875c81fb6a8b62bfa89c8e3f7b778b6
This commit is contained in:
huicong.li 2025-03-13 09:49:12 +08:00 committed by lane.wei
parent 8a21013ebb
commit 96e8fead16
1 changed files with 29 additions and 4 deletions

View File

@ -509,13 +509,14 @@ static float get_perimeter_spacing_external(const Layer &layer)
// Called by avoid_perimeters() and by simplify_travel_heuristics(). // Called by avoid_perimeters() and by simplify_travel_heuristics().
static size_t avoid_perimeters_inner(const AvoidCrossingPerimeters::Boundary &boundary, static size_t avoid_perimeters_inner(const AvoidCrossingPerimeters::Boundary &boundary,
const Point &start, const Point &start_point,
const Point &end, const Point &end_point,
const Layer &layer, const Layer &layer,
std::vector<TravelPoint> &result_out) std::vector<TravelPoint> &result_out)
{ {
const Polygons &boundaries = boundary.boundaries; const Polygons &boundaries = boundary.boundaries;
const EdgeGrid::Grid &edge_grid = boundary.grid; const EdgeGrid::Grid &edge_grid = boundary.grid;
Point start = start_point, end = end_point;
// Find all intersections between boundaries and the line segment, sort them along the line segment. // Find all intersections between boundaries and the line segment, sort them along the line segment.
std::vector<Intersection> intersections; std::vector<Intersection> intersections;
{ {
@ -523,6 +524,29 @@ static size_t avoid_perimeters_inner(const AvoidCrossingPerimeters::Boundary &bo
AllIntersectionsVisitor visitor(edge_grid, intersections, Line(start, end)); AllIntersectionsVisitor visitor(edge_grid, intersections, Line(start, end));
edge_grid.visit_cells_intersecting_line(start, end, visitor); edge_grid.visit_cells_intersecting_line(start, end, visitor);
Vec2d dir = (end - start).cast<double>(); Vec2d dir = (end - start).cast<double>();
// if do not intersect due to the boundaries inner-offset, try to find the closest point to do intersect again!
if (intersections.empty()) {
// try to find the closest point on boundaries to start/end with distance less than extend_distance, which is noted as new start_point/end_point
auto search_radius = 1.5 * get_perimeter_spacing(layer);
const std::vector<ClosestLine> closest_line_to_start = get_closest_lines_in_radius(boundary.grid, start, search_radius);
const std::vector<ClosestLine> closest_line_to_end = get_closest_lines_in_radius(boundary.grid, end, search_radius);
if (!(closest_line_to_start.empty() && closest_line_to_end.empty())) {
auto new_start_point = closest_line_to_start.empty() ? start : closest_line_to_start.front().point;
auto new_end_point = closest_line_to_end.empty() ? end : closest_line_to_end.front().point;
dir = (new_end_point - new_start_point).cast<double>();
auto unit_direction = dir.normalized();
// out-offset new_start_point/new_end_point epsilon along the Line(new_start_point, new_end_point) for right intersection!
new_start_point = new_start_point - (unit_direction * double(coord_t(SCALED_EPSILON))).cast<coord_t>();
new_end_point = new_end_point + (unit_direction * double(coord_t(SCALED_EPSILON))).cast<coord_t>();
AllIntersectionsVisitor visitor(edge_grid, intersections, Line(new_start_point, new_end_point));
edge_grid.visit_cells_intersecting_line(new_start_point, new_end_point, visitor);
if (!intersections.empty()) {
start = new_start_point;
end = new_end_point;
}
}
}
for (Intersection &intersection : intersections) { for (Intersection &intersection : intersections) {
float dist_from_line_begin = (intersection.point - boundary.boundaries[intersection.border_idx][intersection.line_idx]).cast<float>().norm(); float dist_from_line_begin = (intersection.point - boundary.boundaries[intersection.border_idx][intersection.line_idx]).cast<float>().norm();
intersection.distance = boundary.boundaries_params[intersection.border_idx][intersection.line_idx] + dist_from_line_begin; intersection.distance = boundary.boundaries_params[intersection.border_idx][intersection.line_idx] + dist_from_line_begin;
@ -598,6 +622,7 @@ static size_t avoid_perimeters_inner(const AvoidCrossingPerimeters::Boundary &bo
result.push_back({end, -1}); result.push_back({end, -1});
#ifdef AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT #ifdef AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT
{ {
static int iRun = 0; static int iRun = 0;
@ -632,6 +657,7 @@ static size_t avoid_perimeters(const AvoidCrossingPerimeters::Boundary &boundary
size_t num_intersections = avoid_perimeters_inner(boundary, start, end, layer, path); size_t num_intersections = avoid_perimeters_inner(boundary, start, end, layer, path);
result_out = to_polyline(path); result_out = to_polyline(path);
#ifdef AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT #ifdef AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT
{ {
static int iRun = 0; static int iRun = 0;
@ -1127,7 +1153,6 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
const Point start = gcodegen.last_pos() + scaled_origin; const Point start = gcodegen.last_pos() + scaled_origin;
const Point end = point + scaled_origin; const Point end = point + scaled_origin;
const Line travel(start, end); const Line travel(start, end);
Polyline result_pl; Polyline result_pl;
size_t travel_intersection_count = 0; size_t travel_intersection_count = 0;
Vec2d startf = start.cast<double>(); Vec2d startf = start.cast<double>();