diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 9907dd70d6..7de3d9291f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -311,6 +311,12 @@ static std::vector get_path_of_change_filament(const Print& print) double length = toolchange ? gcodegen.writer().extruder()->retract_length_toolchange() : gcodegen.writer().extruder()->retraction_length(); + + // Ioannis Giannakas: + // Store the amount retracted before wipe because of the retract amount before wipe being set by the user. + // We need to add this amount to any retraction operation done later in this function. + double dE_retracted = length - length*(1. - gcodegen.writer().extruder()->retract_before_wipe()); + // Shorten the retraction length by the amount already retracted before wipe. length *= (1. - gcodegen.writer().extruder()->retract_before_wipe()); @@ -322,7 +328,7 @@ static std::vector get_path_of_change_filament(const Print& print) for the time needed to consume retraction_length at retraction_speed? */ // BBS double wipe_dist = scale_(gcodegen.config().wipe_distance.get_at(gcodegen.writer().extruder()->id())); - + /* 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; @@ -342,6 +348,28 @@ static std::vector get_path_of_change_filament(const Print& print) //BBS: avoid to divide 0 wipe_dist = wipe_dist < EPSILON ? EPSILON : wipe_dist; } + + scale_(gcodegen.config().retraction_speed.get_at(gcodegen.writer().extruder()->id())); + + // Ioannis Giannakas: + // Calculate the maximum retraction length possible in the available wipe distance, in order to maintain the same effective + // retraction speed as a stationary retraction. + double maxRetractionLength = gcodegen.config().retraction_speed.get_at(gcodegen.writer().extruder()->id()) + * (wipe_path.length() / 1000000) + / _wipe_speed; + if (maxRetractionLength < (length - EPSILON)){ + // Ioannis Giannakas: + // the maximum retraction length possible in the available wipe path with the current wipe speed is less than the + // requested retraction length while wiping. As such, perform an immediate retraction for the difference and proceed to + // wipe with the rest. + gcode +=";Wipe retraction adjusted: \n;Desired retraction amount: "+std::to_string(length) + + "\n;Maximum retraction amount: "+std::to_string(maxRetractionLength)+ + "\n;Retract before wipe: "+std::to_string(length - maxRetractionLength)+ + "\n"; + gcode += gcodegen.writer().retract(length - maxRetractionLength + dE_retracted, toolchange); + length = maxRetractionLength; + length = length < EPSILON ? EPSILON : length; + } // add tag for processor gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Start) + "\n"; diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 5fc57307f0..c831ca26c3 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -682,6 +682,15 @@ std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std return w.string(); } +std::string GCodeWriter::retract(double retraction_length, bool toolchange) +{ + return this->_retract( + retraction_length, + toolchange ? m_extruder->retract_restart_extra(): m_extruder->retract_restart_extra_toolchange(), + "retract" + ); +} + std::string GCodeWriter::retract(bool before_wipe) { double factor = before_wipe ? m_extruder->retract_before_wipe() : 1.; diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index bbaa069da0..df7addaa2d 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -75,6 +75,7 @@ public: std::string extrude_arc_to_xy(const Vec2d &point, const Vec2d ¢er_offset, double dE, const bool is_ccw, const std::string &comment = std::string(), bool force_no_extrusion = false); std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); std::string retract(bool before_wipe = false); + std::string retract(double retraction_length, bool toolchange); std::string retract_for_toolchange(bool before_wipe = false); std::string unretract(); std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);