FIX: optimize avoid crossing wall

jira: STUDIO-11682

Change-Id: I49b6756a5d3aeb482c019813074d8f6f9cc3c6ef
This commit is contained in:
huicong.li 2025-05-14 15:04:18 +08:00 committed by lane.wei
parent ca4a2059fe
commit e9b7006db9
3 changed files with 17 additions and 10 deletions

View File

@ -5821,8 +5821,7 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
// if a retraction would be needed, try to use reduce_crossing_wall to plan a // if a retraction would be needed, try to use reduce_crossing_wall to plan a
// multi-hop travel path inside the configuration space // multi-hop travel path inside the configuration space
// if ( // if (
if (needs_retraction if (m_config.reduce_crossing_wall
&& m_config.reduce_crossing_wall
&& !m_avoid_crossing_perimeters.disabled_once() && !m_avoid_crossing_perimeters.disabled_once()
&& m_writer.is_current_position_clear()) && m_writer.is_current_position_clear())
//BBS: don't generate detour travel paths when current position is unclea //BBS: don't generate detour travel paths when current position is unclea

View File

@ -1245,7 +1245,7 @@ static ExPolygons get_boundary(const Layer &layer, float perimeter_spacing)
} }
// called by AvoidCrossingPerimeters::travel_to() // called by AvoidCrossingPerimeters::travel_to()
static ExPolygons get_slice_boundary(const Layer &layer) static ExPolygons get_slice_boundary_internal(const Layer &layer)
{ {
auto const *support_layer = dynamic_cast<const SupportLayer *>(&layer); auto const *support_layer = dynamic_cast<const SupportLayer *>(&layer);
ExPolygons boundary = layer.lslices; ExPolygons boundary = layer.lslices;
@ -1414,22 +1414,27 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
const std::vector<BoundingBox> &lslices_bboxes = gcodegen.layer()->lslices_bboxes; const std::vector<BoundingBox> &lslices_bboxes = gcodegen.layer()->lslices_bboxes;
bool is_support_layer = (dynamic_cast<const SupportLayer *>(gcodegen.layer()) != nullptr); bool is_support_layer = (dynamic_cast<const SupportLayer *>(gcodegen.layer()) != nullptr);
if (!use_external && (is_support_layer || (!lslices.empty() && !any_expolygon_contains(lslices, lslices_bboxes, m_grid_lslice, travel)))) { if (!use_external && (is_support_layer || (!lslices.empty() && !any_expolygon_contains(lslices, lslices_bboxes, m_grid_lslice, travel)))) {
AvoidCrossingPerimeters::Boundary slice_boundary; if (m_lslice_internal.boundaries.empty()) {
init_boundary(&slice_boundary, to_polygons(get_slice_boundary(*gcodegen.layer())), {start, end}); init_boundary(&m_lslice_internal, to_polygons(get_slice_boundary_internal(*gcodegen.layer())), {start, end});
} else if (!(m_lslice_internal.bbox.contains(startf) && m_lslice_internal.bbox.contains(endf))) {
// check if start and end are in bbox
m_lslice_internal.clear();
init_boundary(&m_lslice_internal, to_polygons(get_slice_boundary_internal(*gcodegen.layer())), {start, end});
}
// Initialize m_internal only when it is necessary. // Initialize m_internal only when it is necessary.
if (m_internal.boundaries.empty()) { if (m_internal.boundaries.empty()) {
init_boundary(&m_internal, to_polygons(get_boundary(*gcodegen.layer(), get_perimeter_spacing(*gcodegen.layer()))), get_extents(slice_boundary.boundaries), init_boundary(&m_internal, to_polygons(get_boundary(*gcodegen.layer(), get_perimeter_spacing(*gcodegen.layer()))), get_extents(m_lslice_internal.boundaries),
{start, end}); {start, end});
} else if (!(m_internal.bbox.contains(startf) && m_internal.bbox.contains(endf))) { } else if (!(m_internal.bbox.contains(startf) && m_internal.bbox.contains(endf))) {
// check if start and end are in bbox, if not, merge start and end points to bbox // check if start and end are in bbox, if not, merge start and end points to bbox
m_internal.clear(); m_internal.clear();
init_boundary(&m_internal, to_polygons(get_boundary(*gcodegen.layer(), get_perimeter_spacing(*gcodegen.layer()))), get_extents(slice_boundary.boundaries), init_boundary(&m_internal, to_polygons(get_boundary(*gcodegen.layer(), get_perimeter_spacing(*gcodegen.layer()))), get_extents(m_lslice_internal.boundaries),
{start, end}); {start, end});
} }
// Trim the travel line by the bounding box.
if (!m_internal.boundaries.empty()) { if (!m_internal.boundaries.empty()) {
travel_intersection_count = avoid_perimeters(slice_boundary, m_internal, start, end, *gcodegen.layer(), result_pl); travel_intersection_count = avoid_perimeters(m_lslice_internal, m_internal, start, end, *gcodegen.layer(), result_pl);
result_pl.points.front() = start; result_pl.points.front() = start;
result_pl.points.back() = end; result_pl.points.back() = end;
} }
@ -1491,6 +1496,7 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
void AvoidCrossingPerimeters::init_layer(const Layer &layer) void AvoidCrossingPerimeters::init_layer(const Layer &layer)
{ {
m_internal.clear(); m_internal.clear();
m_lslice_internal.clear();
m_external.clear(); m_external.clear();
BoundingBox bbox_slice(get_extents(layer.lslices)); BoundingBox bbox_slice(get_extents(layer.lslices));

View File

@ -62,6 +62,8 @@ private:
EdgeGrid::Grid m_grid_lslice; EdgeGrid::Grid m_grid_lslice;
// Store all needed data for travels inside object // Store all needed data for travels inside object
Boundary m_internal; Boundary m_internal;
// Store all needed data for travels inside object without inner offset
Boundary m_lslice_internal;
// Store all needed data for travels outside object // Store all needed data for travels outside object
Boundary m_external; Boundary m_external;
}; };