From 74df3a450babb322b4cb657819aae96b220f19c0 Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Sun, 13 Apr 2025 17:36:36 +0800 Subject: [PATCH] Fix wrong travel before printing first skirt point (#9179) Fix wrong travel before printing first skirt point (SoftFever/OrcaSlicer#9109) don't modify `last_pos`, otherwise it could move out of plate/to wrong places and cause issue --- src/libslic3r/GCode.cpp | 22 +++++++++++++--------- src/libslic3r/GCode.hpp | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index a74f90d821..9951010230 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3556,12 +3556,15 @@ std::string GCode::generate_skirt(const Print &print, path.mm3_per_mm = mm3_per_mm; } - //set skirt start point location - if (first_layer && i==loops.first) - this->set_last_pos(Skirt::find_start_point(loop, layer.object()->config().skirt_start_angle)); - //FIXME using the support_speed of the 1st object printed. - gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value); + if (first_layer && i==loops.first) { + //set skirt start point location + const Point desired_start_point = Skirt::find_start_point(loop, layer.object()->config().skirt_start_angle); + gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value, {}, &desired_start_point); + } + else + gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value); + // If we only want a single wall on non-first layers, break now if (!first_layer && print.m_config.single_loop_draft_shield) { break; @@ -4632,7 +4635,7 @@ static std::unique_ptr calculate_layer_edge_grid(const Layer& la return out; } -std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed, const ExtrusionEntitiesPtr& region_perimeters) +std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed, const ExtrusionEntitiesPtr& region_perimeters, const Point* start_point) { // get a copy; don't modify the orientation of the original loop object otherwise @@ -4648,12 +4651,13 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // loop.reverse(); // find the point of the loop that is closest to the current extruder position - // or randomize if requested - Point last_pos = this->last_pos(); + // or randomize if requested; + // or, if `start_point` is specified, start the loop at point closest to it + Point last_pos = start_point ? *start_point : this->last_pos(); float seam_overhang = std::numeric_limits::lowest(); if (!m_config.spiral_mode && description == "perimeter") { assert(m_layer != nullptr); - m_seam_placer.place_seam(m_layer, loop, this->last_pos(), seam_overhang); + m_seam_placer.place_seam(m_layer, loop, last_pos, seam_overhang); } else loop.split_at(last_pos, false); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 8cee34edbd..5131742dc3 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -363,7 +363,7 @@ private: std::string extrude_entity(const ExtrusionEntity &entity, std::string description = "", double speed = -1., const ExtrusionEntitiesPtr& region_perimeters = ExtrusionEntitiesPtr()); // Orca: pass the complete collection of region perimeters to the extrude loop to check whether the wipe before external loop // should be executed - std::string extrude_loop(ExtrusionLoop loop, std::string description, double speed = -1., const ExtrusionEntitiesPtr& region_perimeters = ExtrusionEntitiesPtr()); + std::string extrude_loop(ExtrusionLoop loop, std::string description, double speed = -1., const ExtrusionEntitiesPtr& region_perimeters = ExtrusionEntitiesPtr(), const Point* start_point = nullptr); std::string extrude_multi_path(ExtrusionMultiPath multipath, std::string description = "", double speed = -1.); std::string extrude_path(ExtrusionPath path, std::string description = "", double speed = -1.);