diff options
Diffstat (limited to 'src/libslic3r/GCode.cpp')
-rw-r--r-- | src/libslic3r/GCode.cpp | 108 |
1 files changed, 52 insertions, 56 deletions
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 13aedab1b..6a53917de 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -27,7 +27,6 @@ #include <boost/foreach.hpp> #include <boost/filesystem.hpp> #include <boost/log/trivial.hpp> -#include <boost/beast/core/detail/base64.hpp> #include <boost/nowide/iostream.hpp> #include <boost/nowide/cstdio.hpp> @@ -155,63 +154,52 @@ namespace Slic3r { std::string Wipe::wipe(GCode& gcodegen, bool toolchange) { - std::string gcode; - - /* Reduce feedrate a bit; travel speed is often too high to move on existing material. - Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */ - double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8; - - // get the retraction length - double length = toolchange - ? gcodegen.writer().extruder()->retract_length_toolchange() - : gcodegen.writer().extruder()->retract_length(); - // Shorten the retraction length by the amount already retracted before wipe. - length *= (1. - gcodegen.writer().extruder()->retract_before_wipe()); - - if (length > 0) { - /* Calculate how long we need to travel in order to consume the required - amount of retraction. In other words, how far do we move in XY at wipe_speed - for the time needed to consume retract_length at retract_speed? */ - double wipe_dist = scale_(length / gcodegen.writer().extruder()->retract_speed() * wipe_speed); - - /* Take the stored wipe path and replace first point with the current actual position - (they might be different, for example, in case of loop clipping). */ - Polyline wipe_path; - wipe_path.append(gcodegen.last_pos()); - wipe_path.append( - this->path.points.begin() + 1, - this->path.points.end() - ); - - wipe_path.clip_end(wipe_path.length() - wipe_dist); - - // subdivide the retraction in segments - if (!wipe_path.empty()) { - // add tag for processor + std::string gcode; + const Extruder &extruder = *gcodegen.writer().extruder(); + + // Remaining quantized retraction length. + if (double retract_length = extruder.retract_to_go(toolchange ? extruder.retract_length_toolchange() : extruder.retract_length()); + retract_length > 0 && this->path.size() >= 2) { + // Reduce feedrate a bit; travel speed is often too high to move on existing material. + // Too fast = ripping of existing material; too slow = short wipe path, thus more blob. + const double wipe_speed = gcodegen.writer().config.travel_speed.value * 0.8; + // 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). + const double xy_to_e = 0.95 * extruder.retract_speed() / wipe_speed; + // Start with the current position, which may be different from the wipe path start in case of loop clipping. + Vec2d prev = gcodegen.point_to_gcode_quantized(gcodegen.last_pos()); + auto it = this->path.points.begin(); + Vec2d p = gcodegen.point_to_gcode_quantized(*(++ it)); + if (p != prev) { gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Start) + "\n"; - 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; + auto end = this->path.points.end(); + bool done = false; + for (; it != end; ++ it) { + p = gcodegen.point_to_gcode_quantized(*it); + double segment_length = (p - prev).norm(); + double dE = GCodeFormatter::quantize_e(xy_to_e * segment_length); + if (dE > retract_length - EPSILON) { + if (dE > retract_length + EPSILON) + // Shorten the segment. + p = prev + (p - prev) * (retract_length / dE); + dE = retract_length; + done = true; + } //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" - ); + gcode += gcodegen.writer().set_speed(wipe_speed * 60, {}, gcodegen.enable_cooling_markers() ? ";_WIPE" : ""); + gcode += gcodegen.writer().extrude_to_xy(p, -dE, "wipe and retract"); + prev = p; + retract_length -= dE; } // add tag for processor gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_End) + "\n"; - gcodegen.set_last_pos(wipe_path.points.back()); + gcodegen.set_last_pos(gcodegen.gcode_to_point(prev)); } - - // prevent wiping again on same path - this->reset_path(); } + // Prevent wiping again on the same path. + this->reset_path(); return gcode; } @@ -3010,13 +2998,15 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double path_length = 0.; { std::string comment = m_config.gcode_comments ? description : ""; - for (const Line &line : path.polyline.lines()) { - const double line_length = line.length() * SCALING_FACTOR; + Vec2d prev = this->point_to_gcode_quantized(path.polyline.points.front()); + auto it = path.polyline.points.begin(); + auto end = path.polyline.points.end(); + for (++ it; it != end; ++ it) { + Vec2d p = this->point_to_gcode_quantized(*it); + const double line_length = (p - prev).norm(); path_length += line_length; - gcode += m_writer.extrude_to_xy( - this->point_to_gcode(line.b), - e_per_mm * line_length, - comment); + gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, comment); + prev = p; } } if (m_enable_cooling_markers) @@ -3239,7 +3229,13 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z) Vec2d GCode::point_to_gcode(const Point &point) const { Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset); - return unscale(point) + m_origin - extruder_offset; + return unscaled<double>(point) + m_origin - extruder_offset; +} + +Vec2d GCode::point_to_gcode_quantized(const Point &point) const +{ + Vec2d p = this->point_to_gcode(point); + return { GCodeFormatter::quantize_xyzf(p.x()), GCodeFormatter::quantize_xyzf(p.y()) }; } // convert a model-space scaled point into G-code coordinates |