diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c27551a213..55acf9350e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2105,6 +2105,26 @@ bool GCodeGenerator::line_distancer_is_required(const std::vector& return false; } +namespace GCode::Impl { +AABBTreeLines::LinesDistancer get_previous_layer_distancer( + const GCodeGenerator::ObjectsLayerToPrint& objects_to_print, + const ExPolygons& slices +) { + std::vector lines; + for (const GCodeGenerator::ObjectLayerToPrint &object_to_print : objects_to_print) { + for (const PrintInstance& instance: object_to_print.object()->instances()) { + for (const ExPolygon& polygon : slices) { + for (const Line& line : polygon.lines()) { + lines.emplace_back(unscaled(Point{line.a + instance.shift}), unscaled(Point{line.b + instance.shift})); + } + } + + } + } + return AABBTreeLines::LinesDistancer{std::move(lines)}; +} +} + // In sequential mode, process_layer is called once per each object and its copy, // therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object. // In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated. @@ -2206,7 +2226,7 @@ LayerResult GCodeGenerator::process_layer( gcode += this->change_layer(previous_layer_z, print_z, result.spiral_vase_enable); // this will increase m_layer_index m_layer = &layer; if (this->line_distancer_is_required(layer_tools.extruders) && this->m_layer != nullptr && this->m_layer->lower_layer != nullptr) { - this->m_previous_layer_distancer = GCode::Impl::get_expolygons_distancer(m_layer->lower_layer->lslices); + this->m_previous_layer_distancer = GCode::Impl::get_previous_layer_distancer(layers, layer.lower_layer->lslices); } m_object_layer_over_raft = false; if (! print.config().layer_gcode.value.empty()) { @@ -3362,16 +3382,6 @@ Points3 generate_elevated_travel( return result; } -AABBTreeLines::LinesDistancer get_expolygons_distancer(const ExPolygons& polygons) { - std::vector lines; - for (const ExPolygon& polygon : polygons) { - for (const Line& line : polygon.lines()) { - lines.emplace_back(unscaled(line.a), unscaled(line.b)); - } - } - - return AABBTreeLines::LinesDistancer{std::move(lines)}; -} std::optional get_first_crossed_line_distance( tcb::span xy_path, @@ -3458,7 +3468,8 @@ Points3 generate_travel_to_extrusion( const FullPrintConfig& config, const unsigned extruder_id, const double initial_elevation, - const std::optional>& previous_layer_distancer + const std::optional>& previous_layer_distancer, + const Point& xy_path_coord_origin ) { const double upper_limit = config.retract_lift_below.get_at(extruder_id); const double lower_limit = config.retract_lift_above.get_at(extruder_id); @@ -3469,8 +3480,13 @@ Points3 generate_travel_to_extrusion( return generate_flat_travel(xy_path.points, initial_elevation); } + Lines global_xy_path; + for (const Line& line : xy_path.lines()) { + global_xy_path.emplace_back(line.a + xy_path_coord_origin, line.b + xy_path_coord_origin); + } + ElevatedTravelParams elevation_params{get_elevated_traval_params( - xy_path.lines(), + global_xy_path, config, extruder_id, previous_layer_distancer @@ -3650,7 +3666,8 @@ std::string GCodeGenerator::travel_to(const Point &point, ExtrusionRole role, st this->m_config, extruder_id, initial_elevation, - this->m_previous_layer_distancer + this->m_previous_layer_distancer, + scaled(m_origin) ) ); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 809efe8655..20c806f8f5 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -135,16 +135,6 @@ Points3 generate_elevated_travel( const std::function& elevation ); -/** - * @brief Takes a list o polygons and builds a AABBTree over all unscaled lines. - * - * @param polygons A list of polygons. - * @return AABB Tree over all lines of the polygons. - * - * Unscales the lines in the process! - */ -AABBTreeLines::LinesDistancer get_expolygons_distancer(const ExPolygons& polygons); - /** * @brief Given a AABB tree over lines find intersection with xy_path closest to the xy_path start. * diff --git a/tests/fff_print/test_gcode.cpp b/tests/fff_print/test_gcode.cpp index 7cccfe54f8..69acc44901 100644 --- a/tests/fff_print/test_gcode.cpp +++ b/tests/fff_print/test_gcode.cpp @@ -178,8 +178,15 @@ TEST_CASE("Get first crossed line distance", "[GCode]") { scaled(Vec2f{0, 5}), }.lines()}; + std::vector lines; + for (const ExPolygon& polygon : {square_with_hole, square_above}) { + for (const Line& line : polygon.lines()) { + lines.emplace_back(unscale(line.a), unscale(line.b)); + } + } // Try different cases by skipping lines in the travel. - AABBTreeLines::LinesDistancer distancer = get_expolygons_distancer({square_with_hole, square_above}); + AABBTreeLines::LinesDistancer distancer{std::move(lines)}; + CHECK(*get_first_crossed_line_distance(travel, distancer) == Approx(1)); CHECK(*get_first_crossed_line_distance(tcb::span{travel}.subspan(1), distancer) == Approx(0.2)); CHECK(*get_first_crossed_line_distance(tcb::span{travel}.subspan(2), distancer) == Approx(0.5));