Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2022-04-13 20:42:49 +0300
committersupermerill <merill@free.fr>2022-04-15 13:34:01 +0300
commit45ab973c6018011681bfd874f51f2f22a43590f4 (patch)
tree2ac831fb5781a05f57d3189ae61ae9906be77a36 /src
parent8d4feed33c75dbe68dba046d68520913935449a8 (diff)
wipe_inside_depth setting to control the depth of wipe move.
Diffstat (limited to 'src')
-rw-r--r--src/libslic3r/Extruder.cpp4
-rw-r--r--src/libslic3r/Extruder.hpp1
-rw-r--r--src/libslic3r/GCode.cpp97
-rw-r--r--src/libslic3r/GCodeWriter.hpp2
-rw-r--r--src/libslic3r/Preset.cpp1
-rw-r--r--src/libslic3r/Print.cpp1
-rw-r--r--src/libslic3r/PrintConfig.cpp19
-rw-r--r--src/libslic3r/PrintConfig.hpp1
-rw-r--r--src/slic3r/GUI/Tab.cpp2
9 files changed, 115 insertions, 13 deletions
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",