diff options
author | supermerill <merill@free.fr> | 2022-04-13 20:42:49 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2022-04-15 13:34:01 +0300 |
commit | 45ab973c6018011681bfd874f51f2f22a43590f4 (patch) | |
tree | 2ac831fb5781a05f57d3189ae61ae9906be77a36 | |
parent | 8d4feed33c75dbe68dba046d68520913935449a8 (diff) |
wipe_inside_depth setting to control the depth of wipe move.
-rw-r--r-- | resources/ui_layout/default/extruder.ui | 1 | ||||
-rw-r--r-- | resources/ui_layout/example/extruder.ui | 1 | ||||
-rw-r--r-- | src/libslic3r/Extruder.cpp | 4 | ||||
-rw-r--r-- | src/libslic3r/Extruder.hpp | 1 | ||||
-rw-r--r-- | src/libslic3r/GCode.cpp | 97 | ||||
-rw-r--r-- | src/libslic3r/GCodeWriter.hpp | 2 | ||||
-rw-r--r-- | src/libslic3r/Preset.cpp | 1 | ||||
-rw-r--r-- | src/libslic3r/Print.cpp | 1 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 19 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.hpp | 1 | ||||
-rw-r--r-- | src/slic3r/GUI/Tab.cpp | 2 |
11 files changed, 117 insertions, 13 deletions
diff --git a/resources/ui_layout/default/extruder.ui b/resources/ui_layout/default/extruder.ui index 610df29f9..5c94f3d02 100644 --- a/resources/ui_layout/default/extruder.ui +++ b/resources/ui_layout/default/extruder.ui @@ -38,6 +38,7 @@ group:General wipe line:Wipe inside setting:idx:label$At start:wipe_inside_start setting:idx:label$At end:wipe_inside_end + setting:idx:label$Depth:wipe_inside_depth end_line setting:idx:wipe_extra_perimeter setting:idx:seam_gap diff --git a/resources/ui_layout/example/extruder.ui b/resources/ui_layout/example/extruder.ui index 610df29f9..5c94f3d02 100644 --- a/resources/ui_layout/example/extruder.ui +++ b/resources/ui_layout/example/extruder.ui @@ -38,6 +38,7 @@ group:General wipe line:Wipe inside setting:idx:label$At start:wipe_inside_start setting:idx:label$At end:wipe_inside_end + setting:idx:label$Depth:wipe_inside_depth end_line setting:idx:wipe_extra_perimeter setting:idx:seam_gap diff --git a/src/libslic3r/Extruder.cpp b/src/libslic3r/Extruder.cpp index 1edad1857..76b624e43 100644 --- a/src/libslic3r/Extruder.cpp +++ b/src/libslic3r/Extruder.cpp @@ -77,6 +77,10 @@ double Tool::unretract() return dE; } +double Tool::need_unretract() { + return m_retracted + m_restart_extra + m_restart_extra_toolchange != 0; +} + // Called after a M600 or somethgin like that, so you don't have to unretract, but the absolute position won't change. void Tool::reset_retract() { m_retracted = 0.; diff --git a/src/libslic3r/Extruder.hpp b/src/libslic3r/Extruder.hpp index 9daec0dec..5e665f856 100644 --- a/src/libslic3r/Extruder.hpp +++ b/src/libslic3r/Extruder.hpp @@ -26,6 +26,7 @@ public: virtual double extrude(double dE); virtual double retract(double length, double restart_extra, double restart_extra_from_toolchange); + virtual double need_unretract(); virtual double unretract(); virtual void reset_retract(); double E() const { return m_E; } diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index dfdb353b5..3f5e2b613 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3682,6 +3682,59 @@ void GCode::split_at_seam_pos(ExtrusionLoop& loop, std::unique_ptr<EdgeGrid::Gri lower_layer_edge_grid ? lower_layer_edge_grid->get() : nullptr); } +namespace check_wipe { + bool check_reduce(const Polygon& external_polygon, coord_t wipe_inside_depth, Point reference, coord_t threshold) { + //reduce + Polygons reduced = offset(external_polygon, -wipe_inside_depth); + for (Polygon& poly_to_test : reduced) { + const Point* closest = poly_to_test.closest_point(external_polygon.front()); + // because sqrt(2) = 1.42 and it's the worst case + if (closest->distance_to(external_polygon.front()) < coordf_t(wipe_inside_depth * 1.43)) { + Point pt_proj = poly_to_test.point_projection(reference); + Point pt_temp; + if (pt_proj.distance_to(reference) < threshold || poly_to_test.intersection(Line{ reference , external_polygon.front() }, &pt_temp)) { + //ok + return true; + } + } + } + return false; + } + coord_t max_depth(const ExtrusionPaths& paths, coord_t wipe_inside_depth, coord_t nozzle_width, std::function<Point(coord_t)> compute_point) { + assert(wipe_inside_depth > 0); + assert(nozzle_width > 0); + //create polygon + Polyline full_polyline; + for (const ExtrusionPath& path : paths) { + full_polyline.points.insert(full_polyline.end(), path.polyline.points.begin(), path.polyline.points.end()); + } + full_polyline.simplify(nozzle_width); + Polygon external_polygon(full_polyline.points); + // check dichotomic + coord_t current_dist = wipe_inside_depth; + bool increased = true; + coord_t delta = wipe_inside_depth - nozzle_width / 2; + bool success = check_reduce(external_polygon, current_dist, compute_point(current_dist), nozzle_width / 2); + if (!success) { + int iter = 0; + const size_t nb_iter = size_t(std::sqrt(int(delta / nozzle_width))); + for (iter = 0; iter < nb_iter; ++iter) { + delta /= 2; + increased = success; + if (increased) + current_dist += delta; + else + current_dist -= delta; + success = check_reduce(external_polygon, current_dist, compute_point(current_dist), nozzle_width/2); + } + } + if (!success) { + return std::max(nozzle_width / 2, current_dist - delta); + } else { + return current_dist; + } + } +} std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::string &description, double speed, std::unique_ptr<EdgeGrid::Grid> *lower_layer_edge_grid) { @@ -3816,11 +3869,26 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s Vec2d current_pos = current_point.cast<double>(); Vec2d next_pos = next_point.cast<double>(); Vec2d vec_dist = next_pos - current_pos; - const coordf_t nd = scale_d(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)); - double l2 = vec_dist.squaredNorm(); + double vec_norm = vec_dist.norm(); + const double nozzle_diam = (EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)); + const double setting_max_depth = (m_config.wipe_inside_depth.get_abs_value(m_writer.tool()->id(), nozzle_diam)); + coordf_t dist = scale_d(nozzle_diam) / 2; + Point pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>(); + pt.rotate(angle, current_point); + //check if we can go to higher dist + if (nozzle_diam != 0 && setting_max_depth > nozzle_diam * 0.55) { + // call travel_to to trigger retract, so we can check it (but don't use the travel) + travel_to(gcode, pt, paths.front().role()); + if (m_writer.tool()->need_unretract()) + dist = coordf_t(check_wipe::max_depth(paths, scale_t(setting_max_depth), scale_t(nozzle_diam), [current_pos, current_point, vec_dist, vec_norm, angle](coord_t dist)->Point { + Point pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>(); + pt.rotate(angle, current_point); + return pt; + })); + } // 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) ? next_pos : */(current_pos + vec_dist * (nd / sqrt(l2)))).cast<coord_t>(); + pt = (/*(nd >= vec_norm) ? next_pos : */(current_pos + vec_dist * ( 2 * dist / vec_norm))).cast<coord_t>(); pt.rotate(angle, current_point); //gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), 0.0, "move inwards before retraction/seam"); //this->set_last_pos(pt); @@ -3923,11 +3991,19 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s Vec2d current_pos = current_point.cast<double>(); Vec2d next_pos = next_point.cast<double>(); Vec2d vec_dist = next_pos - current_pos; - const coordf_t nd = scale_d(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)); - double l2 = vec_dist.squaredNorm(); + double vec_norm = vec_dist.norm(); + const double nozzle_diam = (EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)); + const double setting_max_depth = (m_config.wipe_inside_depth.get_abs_value(m_writer.tool()->id(), nozzle_diam)); + coordf_t dist = scale_d(nozzle_diam) / 2; + if (nozzle_diam != 0 && setting_max_depth > nozzle_diam * 0.55) + dist = coordf_t(check_wipe::max_depth(paths, scale_t(setting_max_depth), scale_t(nozzle_diam), [current_pos, current_point, vec_dist, vec_norm, angle](coord_t dist)->Point { + Point pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>(); + pt.rotate(angle, current_point); + return pt; + })); // Shift by no more than a nozzle diameter. //FIXME Hiding the seams will not work nicely for very densely discretized contours! - Point pt_inside = (/*(nd * nd >= l2) ? next_pos : */ (current_pos + vec_dist * (nd / sqrt(l2)))).cast<coord_t>(); + Point pt_inside = (/*(nd >= vec_norm) ? next_pos : */ (current_pos + vec_dist * (2 * dist / vec_norm))).cast<coord_t>(); pt_inside.rotate(angle, current_point); // generate the travel move if (EXTRUDER_CONFIG_WITH_DEFAULT(wipe_inside_end, true)) { @@ -3942,11 +4018,12 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s current_pos = pt_inside.cast<double>(); //go to the inside (use clipper for easy shift) Polygon original_polygon = original_loop.polygon(); - Polygons polys = offset(original_polygon, (original_polygon.is_clockwise()?1:-1) * nd / 2); + Polygons polys = offset(original_polygon, (original_polygon.is_clockwise()?1:-1) * dist); //find nearest point size_t best_poly_idx = 0; size_t best_pt_idx = 0; - coordf_t best_sqr_dist = nd*nd*2; + const coordf_t max_sqr_dist = dist * dist * 8; // 2*nozzle² + coordf_t best_sqr_dist = max_sqr_dist; for (size_t poly_idx = 0; poly_idx < polys.size(); poly_idx++) { Polygon& poly = polys[poly_idx]; if (poly.is_clockwise() ^ original_polygon.is_clockwise()) @@ -3959,7 +4036,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s } } } - if (best_sqr_dist == nd * nd * 2) { + if (best_sqr_dist == max_sqr_dist) { //try to find an edge for (size_t poly_idx = 0; poly_idx < polys.size(); poly_idx++) { Polygon& poly = polys[poly_idx]; @@ -3978,7 +4055,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s } } } - if (best_sqr_dist == nd * nd * 2) { + if (best_sqr_dist == max_sqr_dist) { //can't find a path, use the old one //BOOST_LOG_TRIVIAL(warning) << "Warn: can't find a proper path for wipe on retract. Layer " << m_layer_index << ", pos " << this->point_to_gcode(pt).x() << " : " << this->point_to_gcode(pt).y() << " !"; } else { diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index a1529b739..29b5221a8 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -36,7 +36,7 @@ public: void set_extruders(std::vector<uint16_t> extruder_ids); const std::vector<Extruder>& extruders() const { return m_extruders; } std::vector<uint16_t> extruder_ids() const; - void set_mills(std::vector<uint16_t> extruder_ids); + void set_mills(std::vector<uint16_t> extruder_ids); const std::vector<Mill>& mills() const { return m_millers; } std::vector<uint16_t> mill_ids() const; //give the first mill id or an id after the last extruder. Can be used to see if an id is an extruder or a mill diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 5728a1edb..0449f7ce2 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -737,6 +737,7 @@ static std::vector<std::string> s_Preset_filament_options { "filament_retract_layer_change", "filament_retract_before_wipe", "filament_seam_gap", "filament_wipe", "filament_wipe_only_crossing", "filament_wipe_extra_perimeter", "filament_wipe_speed", + "filament_wipe_inside_depth", "filament_wipe_inside_end", "filament_wipe_inside_start", // Profile compatibility diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 3ee5d52e1..b521079e9 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -198,6 +198,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne "variable_layer_height", "wipe", "wipe_extra_perimeter", + "wipe_inside_depth", "wipe_inside_end", "wipe_inside_start", "wipe_only_crossing", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 9397ab789..84e4d2a6d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5471,6 +5471,18 @@ void PrintConfigDef::init_fff_params() def->is_vector_extruder = true; def->set_default_value(new ConfigOptionBools{ true }); + def = this->add("wipe_inside_depth", coPercents); + def->label = L("Max Wipe deviation"); + def->full_label = L("Maximum Wipe deviation to the inside"); + def->category = OptionCategory::extruders; + def->tooltip = L("By how much the 'wipe inside' can dive inside the object (if possible)?" + "\nIn % of the perimeter width." + "\nNote: don't put a value higher than 50% if you have only one perimeter, or 150% for two perimeter, etc... or it will ooze instead of wipe."); + def->sidetext = L("%"); + def->mode = comAdvancedE | comSuSi; + def->is_vector_extruder = true; + def->set_default_value(new ConfigOptionPercents{ 50 }); + def = this->add("wipe_only_crossing", coBools); def->label = L("Wipe only when crossing perimeters"); def->category = OptionCategory::extruders; @@ -5757,7 +5769,7 @@ void PrintConfigDef::init_fff_params() // floats "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed", "retract_restart_extra", "retract_before_travel", "wipe_extra_perimeter", "wipe_speed", - "wipe_inside_end", "wipe_inside_start", + "wipe_inside_depth", "wipe_inside_end", "wipe_inside_start", // bools "retract_layer_change", "wipe", "wipe_only_crossing", // percents @@ -5811,7 +5823,8 @@ void PrintConfigDef::init_extruder_option_keys() "seam_gap", "tool_name", "wipe", - "wipe_extra_perimeter", + "wipe_extra_perimeter", + "wipe_inside_depth", "wipe_inside_end", "wipe_inside_start", "wipe_only_crossing", @@ -5832,6 +5845,7 @@ void PrintConfigDef::init_extruder_option_keys() "seam_gap", "wipe", "wipe_extra_perimeter", + "wipe_inside_depth", "wipe_inside_end", "wipe_inside_start", "wipe_only_crossing", @@ -7215,6 +7229,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = { "wipe_advanced_nozzle_melted_volume", "wipe_advanced", "wipe_extra_perimeter", +"wipe_inside_depth", "wipe_inside_end", "wipe_inside_start", "wipe_only_crossing", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 51a0638c0..acef37df5 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1047,6 +1047,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionBool, wipe_advanced)) ((ConfigOptionFloat, wipe_advanced_nozzle_melted_volume)) ((ConfigOptionFloat, wipe_advanced_multiplier)) + ((ConfigOptionPercents, wipe_inside_depth)) ((ConfigOptionBools, wipe_inside_end)) ((ConfigOptionBools, wipe_inside_start)) ((ConfigOptionFloats, wipe_extra_perimeter)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 4054a0217..2489180bc 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2704,6 +2704,7 @@ PageShp TabFilament::create_filament_overrides_page() "filament_seam_gap", "filament_wipe", "filament_wipe_extra_perimeter", + "filament_wipe_inside_depth", "filament_wipe_inside_end", "filament_wipe_inside_start", "filament_wipe_only_crossing", @@ -2738,6 +2739,7 @@ void TabFilament::update_filament_overrides_page() "filament_seam_gap", "filament_wipe", "filament_wipe_inside_end", + "filament_wipe_inside_depth", "filament_wipe_inside_start", "filament_wipe_extra_perimeter", "filament_wipe_only_crossing", |