From a0ff5c3fec1d02abf74847f788bc23a822286d69 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 11 May 2020 23:58:15 +0200 Subject: [PATCH] #226 Moar Wipe on external perimeters --- src/libslic3r/GCode.cpp | 75 +++++++++++++++++++++++++++-------- src/libslic3r/Print.cpp | 3 +- src/libslic3r/PrintConfig.cpp | 15 ++++++- src/libslic3r/PrintConfig.hpp | 2 + src/slic3r/GUI/Tab.cpp | 1 + 5 files changed, 77 insertions(+), 19 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index eac841474..517fddd69 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3117,7 +3117,6 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s //exclude if min_layer_height * 2 > layer_height (increase from 2 to 3 because it's working but uses in-between) && this->m_layer->height >= EXTRUDER_CONFIG(min_layer_height) * 2 - EPSILON ) { - std::cout << " ok, loop vase @"<< this->m_layer->id()<<", "<< this->m_layer->print_z<<"\n"; return extrude_loop_vase(original_loop, description, speed, lower_layer_edge_grid); } @@ -3189,21 +3188,65 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s if (m_wipe.enable) m_wipe.path = paths.front().polyline; // TODO: don't limit wipe to last path - - // make a little move inwards before leaving loop - if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) { + + //wipe for External Perimeter + if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 2) { + //get points for wipe + Point prev_point = *(paths.back().polyline.points.end() - 2); // second to last point + // *(paths.back().polyline.points.end() - 2) this is the same as (or should be) as paths.front().first_point(); + Point current_point = paths.front().first_point(); + Point next_point = paths.front().polyline.points[1]; // second point + + //extra wipe before the little move. + if (EXTRUDER_CONFIG(wipe_extra_perimeter) > 0) { + coord_t wipe_dist = scale_(EXTRUDER_CONFIG(wipe_extra_perimeter)); + ExtrusionPaths paths_wipe; + for (int i = 0; i < paths.size(); i++) { + ExtrusionPath& path = paths[i]; + if (path.length() < wipe_dist) { + wipe_dist -= path.length(); + paths_wipe.push_back(path); + } else { + paths_wipe.push_back(path); + paths_wipe.back().clip_end(path.length() - wipe_dist); + + ExtrusionPath next_point_path = path; + next_point_path.reverse(); + next_point_path.clip_end(wipe_dist); + next_point_path.reverse(); + if (next_point_path.size() > 1) { + next_point = next_point_path.polyline.points[1]; + } else if (i + 1 < paths.size()) { + next_point = paths[i + 1].first_point(); + } else { + next_point = paths[0].first_point(); + } + break; + } + } + //move + for (ExtrusionPath& path : paths_wipe) { + for (Point& pt : path.polyline.points) { + prev_point = current_point; + current_point = pt; + gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), config().gcode_comments ? "; extra wipe" : ""); + } + } + } + + // make a little move inwards before leaving loop + // detect angle between last and first segment // the side depends on the original winding order of the polygon (left for contours, right for holes) - //FIXME improve the algorithm in case the loop is tiny. - //FIXME improve the algorithm in case the loop is split into segments with a low number of points (see the Point b query). - Point a = paths.front().polyline.points[1]; // second point - Point b = *(paths.back().polyline.points.end()-3); // second to last point + //FIXME improve the algorithm in case the loop is tiny. + //FIXME improve the algorithm in case the loop is split into segments with a low number of points (see the Point b query). + Point a = next_point; // second point + Point b = prev_point; // second to last point if (is_hole_loop ? loop.polygon().is_counter_clockwise() : loop.polygon().is_clockwise()) { // swap points Point c = a; a = b; b = c; } - - double angle = paths.front().first_point().ccw_angle(a, b) / 3; + double angle = current_point.ccw_angle(a, b) / 3; // turn left if contour, turn right if hole if (is_hole_loop ? loop.polygon().is_counter_clockwise() : loop.polygon().is_clockwise()) angle *= -1; @@ -3211,15 +3254,15 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s // create the destination point along the first segment and rotate it // we make sure we don't exceed the segment length because we don't know // the rotation of the second segment so we might cross the object boundary - Vec2d p1 = paths.front().polyline.points.front().cast(); - Vec2d p2 = paths.front().polyline.points[1].cast(); - Vec2d v = p2 - p1; + Vec2d current_pos = current_point.cast(); + Vec2d next_pos = next_point.cast(); + Vec2d vec_dist = next_pos - current_pos; double nd = scale_(EXTRUDER_CONFIG(nozzle_diameter)); - double l2 = v.squaredNorm(); + double l2 = vec_dist.squaredNorm(); // Shift by no more than a nozzle diameter. //FIXME Hiding the seams will not work nicely for very densely discretized contours! - Point pt = ((nd * nd >= l2) ? p2 : (p1 + v * (nd / sqrt(l2)))).cast(); - pt.rotate(angle, paths.front().polyline.points.front()); + Point pt = ((nd * nd >= l2) ? next_pos : (current_pos + vec_dist * (nd / sqrt(l2)))).cast(); + pt.rotate(angle, current_point); // generate the travel move gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), "move inwards before travel"); } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 58bbbfa00..e6c442ccf 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -150,7 +150,8 @@ bool Print::invalidate_state_by_config_options(const std::vector steps_ignore; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index a5c27d976..c1d4e8a2b 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3255,10 +3255,20 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::wipe; def->label = L("Wipe into this object"); def->tooltip = L("Object will be used to purge the nozzle after a toolchange to save material " - "that would otherwise end up in the wipe tower and decrease print time. " - "Colours of the objects will be mixed as a result."); + "that would otherwise end up in the wipe tower and decrease print time. " + "Colours of the objects will be mixed as a result."); def->set_default_value(new ConfigOptionBool(false)); + def = this->add("wipe_extra_perimeter", coFloats); + def->category = OptionCategory::extruders; + def->label = L("Extra Wipe for external perimeters"); + def->tooltip = L("When the external perimeter loop extrusion end, a wipe is done, going a bit inside the print." + " The number put in this setting increase the wipe by moving the nozzle again along the loop before the final wipe."); + def->min = 0; + def->sidetext = L("mm"); + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloats{ 0.f }); + def = this->add("wipe_tower_bridging", coFloat); def->label = L("Maximal bridging distance"); def->tooltip = L("Maximal distance between supports on sparse infill sections. "); @@ -3353,6 +3363,7 @@ void PrintConfigDef::init_extruder_option_keys() "retract_restart_extra", "retract_before_travel", "wipe", + "wipe_extra_perimeter", "retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index bde272d3b..a3878dc79 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -860,6 +860,7 @@ public: ConfigOptionBool wipe_advanced; ConfigOptionFloat wipe_advanced_nozzle_melted_volume; ConfigOptionFloat wipe_advanced_multiplier; + ConfigOptionFloats wipe_extra_perimeter; ConfigOptionEnum wipe_advanced_algo; std::string get_extrusion_axis() const @@ -954,6 +955,7 @@ protected: OPT_PTR(wipe_advanced_nozzle_melted_volume); OPT_PTR(wipe_advanced_multiplier); OPT_PTR(wipe_advanced_algo); + OPT_PTR(wipe_extra_perimeter); } }; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index b5bd6d0b3..043a130e7 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2975,6 +2975,7 @@ void TabPrinter::build_unregular_pages() optgroup->append_single_option_line("retract_layer_change", extruder_idx); optgroup->append_single_option_line("wipe", extruder_idx); optgroup->append_single_option_line("retract_before_wipe", extruder_idx); + optgroup->append_single_option_line("wipe_extra_perimeter", extruder_idx); optgroup = page->new_optgroup(_(L("Retraction when tool is disabled (advanced settings for multi-extruder setups)"))); optgroup->append_single_option_line("retract_length_toolchange", extruder_idx);