From 54299d8eb0db7910b73aba7101484a10823dc32d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 14 Jan 2019 19:57:41 +0100 Subject: [PATCH] Fix of https://github.com/prusa3d/Slic3r/issues/1631 This is a fix of a long standing bug, where an extrusion is incorrectly drawn from the end of the last wipe move. Interestingly enough, this bug is in Slic3r at least since 1.2.9, but lucky enough it only occured for single perimeter, no infill prints with wipe after retract enabled, and only if the two successive slices were discretized exactly the same, which is quite unlikely. --- src/libslic3r/GCode.cpp | 40 ++++++++++++++++++++++------------------ src/libslic3r/GCode.hpp | 5 +++-- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index bff72a9c0c..4d314004d6 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -103,8 +103,7 @@ OozePrevention::_get_temp(GCode &gcodegen) : gcodegen.config().temperature.get_at(gcodegen.writer().extruder()->id()); } -std::string -Wipe::wipe(GCode &gcodegen, bool toolchange) +std::string Wipe::wipe(GCode &gcodegen, bool toolchange) { std::string gcode; @@ -137,19 +136,22 @@ Wipe::wipe(GCode &gcodegen, bool toolchange) wipe_path.clip_end(wipe_path.length() - wipe_dist); // subdivide the retraction in segments - for (const Line &line : wipe_path.lines()) { - double segment_length = line.length(); - /* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one - due to rounding (TODO: test and/or better math for this) */ - double dE = length * (segment_length / wipe_dist) * 0.95; - //FIXME one shall not generate the unnecessary G1 Fxxx commands, here wipe_speed is a constant inside this cycle. - // Is it here for the cooling markers? Or should it be outside of the cycle? - gcode += gcodegen.writer().set_speed(wipe_speed*60, "", gcodegen.enable_cooling_markers() ? ";_WIPE" : ""); - gcode += gcodegen.writer().extrude_to_xy( - gcodegen.point_to_gcode(line.b), - -dE, - "wipe and retract" - ); + if (! wipe_path.empty()) { + for (const Line &line : wipe_path.lines()) { + double segment_length = line.length(); + /* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one + due to rounding (TODO: test and/or better math for this) */ + double dE = length * (segment_length / wipe_dist) * 0.95; + //FIXME one shall not generate the unnecessary G1 Fxxx commands, here wipe_speed is a constant inside this cycle. + // Is it here for the cooling markers? Or should it be outside of the cycle? + gcode += gcodegen.writer().set_speed(wipe_speed*60, "", gcodegen.enable_cooling_markers() ? ";_WIPE" : ""); + gcode += gcodegen.writer().extrude_to_xy( + gcodegen.point_to_gcode(line.b), + -dE, + "wipe and retract" + ); + } + gcodegen.set_last_pos(wipe_path.points.back()); } // prevent wiping again on same path @@ -2577,9 +2579,11 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string // use G1 because we rely on paths being straight (G0 may make round paths) Lines lines = travel.lines(); - for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) - gcode += m_writer.travel_to_xy(this->point_to_gcode(line->b), comment); - + if (! lines.empty()) { + for (const Line &line : lines) + gcode += m_writer.travel_to_xy(this->point_to_gcode(line.b), comment); + this->set_last_pos(lines.back().b); + } return gcode; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 32a7057512..86a6cacee3 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -155,11 +155,11 @@ public: void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. - const Vec2d& origin() const { return m_origin; } + const Vec2d& origin() const { return m_origin; } void set_origin(const Vec2d &pointf); void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Vec2d(x, y)); } const Point& last_pos() const { return m_last_pos; } - Vec2d point_to_gcode(const Point &point) const; + Vec2d point_to_gcode(const Point &point) const; Point gcode_to_point(const Vec2d &point) const; const FullPrintConfig &config() const { return m_config; } const Layer* layer() const { return m_layer; } @@ -360,6 +360,7 @@ protected: size_t num_objects, size_t num_islands); + friend class Wipe; friend class WipeTowerIntegration; };