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
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2022-04-13 18:57:22 +0300
committersupermerill <merill@free.fr>2022-04-15 13:33:56 +0300
commit8d4feed33c75dbe68dba046d68520913935449a8 (patch)
tree7ba518b1c5f67b590ec98698932f530c1207e7af /src/libslic3r
parent914e0e54cbe1b9baac42bc0424451ca67891515b (diff)
Settings for the little wipe for external perimeters
supermerill/SuperSlicer#2503 supermerill/SuperSlicer#2689 supermerill/SuperSlicer#2156
Diffstat (limited to 'src/libslic3r')
-rw-r--r--src/libslic3r/GCode.cpp86
-rw-r--r--src/libslic3r/Preset.cpp2
-rw-r--r--src/libslic3r/Print.cpp4
-rw-r--r--src/libslic3r/PrintConfig.cpp26
-rw-r--r--src/libslic3r/PrintConfig.hpp2
5 files changed, 98 insertions, 22 deletions
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index dc0f2cc67..dfdb353b5 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -3458,7 +3458,7 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
Point inward_point;
//move the seam point inward a little bit
- if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
+ if (EXTRUDER_CONFIG_WITH_DEFAULT(wipe_inside_end, true) && paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
// 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.
@@ -3470,7 +3470,7 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
Point c = a; a = b; b = c;
}
- double angle = paths.front().first_point().ccw_angle(a, b)*2 / 3;
+ double angle = paths.front().first_point().ccw_angle(a, b) * 2 / 3;
// turn left if contour, turn right if hole
if (reverse_turn) angle *= -1;
@@ -3485,7 +3485,7 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
double l2 = v.squaredNorm();
// Shift by no more than a nozzle diameter.
//FIXME Hiding the seams will not work nicely for very densely discretized contours!
- inward_point = ((nd * nd >= l2) ? p2 : (p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
+ inward_point = (/*(nd * nd >= l2) ? p2 : */(p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
inward_point.rotate(angle, paths.front().polyline.points.front());
}
@@ -3635,7 +3635,7 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s
double l2 = v.squaredNorm();
// Shift by no more than a nozzle diameter.
//FIXME Hiding the seams will not work nicely for very densely discretized contours!
- inward_point = ((nd * nd >= l2) ? p2 : (p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
+ inward_point = (/*(nd * nd >= l2) ? p2 : */(p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
inward_point.rotate(angle, paths.front().polyline.points.front());
// generate the travel move
@@ -3787,10 +3787,51 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
}
}
}
+
+ std::string gcode;
+
+ // generate the unretracting/wipe start move (same thign than for the end, but on the other side)
+ assert(!paths.empty() && paths.front().size() > 1 && !paths.back().empty());
+ if (EXTRUDER_CONFIG_WITH_DEFAULT(wipe_inside_start, true) && !paths.empty() && paths.front().size() > 1 && !paths.back().empty() && paths.front().role() == erExternalPerimeter) {
+ //note: previous & next are inverted to extrude "in the opposite direction, ans we are "rewinding"
+ //Point previous_point = paths.back().polyline.points.back();
+ Point previous_point = paths.front().polyline.points[1];
+ Point current_point = paths.front().polyline.points.front();
+ //Point next_point = paths.front().polyline.points[1];
+ Point next_point = paths.back().polyline.points.back();
+ Point a = next_point; // second point
+ Point b = previous_point; // second to last point
+ if (is_hole_loop ? (!is_full_loop_ccw) : (is_full_loop_ccw)) {
+ // swap points
+ Point c = a; a = b; b = c;
+ }
+ double angle = current_point.ccw_angle(a, b) / 3;
+
+ // turn left if contour, turn right if hole
+ if (is_hole_loop ? (!is_full_loop_ccw) : (is_full_loop_ccw)) angle *= -1;
+
+ // 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 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();
+ // 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.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);
+ // use extrude instead of travel_to_xy to trigger the unretract
+ ExtrusionPath fake_path_wipe(Polyline{ pt , current_point }, paths.front());
+ fake_path_wipe.mm3_per_mm = 0;
+ gcode += extrude_path(fake_path_wipe, "move inwards before retraction/seam", speed);
+ }
// extrude along the path
//FIXME: we can have one-point paths in the loop that don't move : it's useless! and can create problems!
- std::string gcode;
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
if(path->polyline.points.size()>1)
gcode += extrude_path(*path, description, speed);
@@ -3860,7 +3901,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
}
// 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.
@@ -3881,21 +3922,24 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
// the rotation of the second segment so we might cross the object boundary
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));
+ 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();
// 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.rotate(angle, current_point);
+ Point pt_inside = (/*(nd * nd >= l2) ? next_pos : */ (current_pos + vec_dist * (nd / sqrt(l2)))).cast<coord_t>();
+ pt_inside.rotate(angle, current_point);
// generate the travel move
- gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), 0.0, "move inwards before travel");
- this->set_last_pos(pt);
+ if (EXTRUDER_CONFIG_WITH_DEFAULT(wipe_inside_end, true)) {
+ gcode += m_writer.travel_to_xy(this->point_to_gcode(pt_inside), 0.0, "move inwards before travel");
+ this->set_last_pos(pt_inside);
+ }
+
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_End) + "\n";
- // also shift the wipe on retract
- if (m_wipe.enable) {
- current_pos = pt.cast<double>();
+ // also shift the wipe on retract if wipe_inside_end
+ if (m_wipe.enable && EXTRUDER_CONFIG_WITH_DEFAULT(wipe_inside_end, true)) {
+ 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);
@@ -3908,11 +3952,11 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
if (poly.is_clockwise() ^ original_polygon.is_clockwise())
poly.reverse();
for (size_t pt_idx = 0; pt_idx < poly.points.size(); pt_idx++) {
- if (poly.points[pt_idx].distance_to_square(pt) < best_sqr_dist) {
- best_sqr_dist = poly.points[pt_idx].distance_to_square(pt);
+ if (poly.points[pt_idx].distance_to_square(pt_inside) < best_sqr_dist) {
+ best_sqr_dist = poly.points[pt_idx].distance_to_square(pt_inside);
best_poly_idx = poly_idx;
best_pt_idx = pt_idx;
- }
+ }
}
}
if (best_sqr_dist == nd * nd * 2) {
@@ -3923,8 +3967,8 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
poly.reverse();
poly.points.push_back(poly.points.front());
for (size_t pt_idx = 0; pt_idx < poly.points.size()-1; pt_idx++) {
- if (Line{ poly.points[pt_idx], poly.points[pt_idx + 1] }.distance_to_squared(pt) < best_sqr_dist) {
- poly.points.insert(poly.points.begin() + pt_idx + 1, pt);
+ if (Line{ poly.points[pt_idx], poly.points[pt_idx + 1] }.distance_to_squared(pt_inside) < best_sqr_dist) {
+ poly.points.insert(poly.points.begin() + pt_idx + 1, pt_inside);
best_sqr_dist = 0;
best_poly_idx = poly_idx;
best_pt_idx = pt_idx + 1;
@@ -4724,7 +4768,7 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
}
- // compute sped here to be able to know it for travel_deceleration_use_target
+ // compute speed here to be able to know it for travel_deceleration_use_target
speed = _compute_speed_mm_per_sec(path, speed);
if (m_config.travel_deceleration_use_target){
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 85619dddf..5728a1edb 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -737,6 +737,8 @@ 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_end",
+ "filament_wipe_inside_start",
// Profile compatibility
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits",
//merill adds
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 4916e3845..3ee5d52e1 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -197,9 +197,11 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
"use_volumetric_e",
"variable_layer_height",
"wipe",
+ "wipe_extra_perimeter",
+ "wipe_inside_end",
+ "wipe_inside_start",
"wipe_only_crossing",
"wipe_speed",
- "wipe_extra_perimeter"
};
static std::unordered_set<std::string> steps_ignore;
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 10d6cea78..9397ab789 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -5452,6 +5452,25 @@ void PrintConfigDef::init_fff_params()
def->is_vector_extruder = true;
def->set_default_value(new ConfigOptionBools{ false });
+ def = this->add("wipe_inside_start", coBools);
+ def->label = L("Wipe inside at start");
+ def->category = OptionCategory::extruders;
+ def->tooltip = L("Before extruding an external perimeter, this flag will place the nozzle a bit inward and in advance of the seam position before unretracting."
+ " It will then move to the seam position before extruding.");
+ def->mode = comAdvancedE | comSuSi;
+ def->is_vector_extruder = true;
+ def->set_default_value(new ConfigOptionBools{ false });
+
+ def = this->add("wipe_inside_end", coBools);
+ def->label = L("Wipe inside at start");
+ def->category = OptionCategory::extruders;
+ def->tooltip = L("This flag will wipe the nozzle a bit inward after extruding an external perimeter."
+ " The wipe_extra_perimeter is executed first, then this move inward before the retraction wipe."
+ " Note that the retraction wipe will follow the exact external perimeter (center) line if this parameter is disabled, and will follow the inner side of the external periemter line if enabled");
+ def->mode = comAdvancedE | comSuSi;
+ def->is_vector_extruder = true;
+ def->set_default_value(new ConfigOptionBools{ true });
+
def = this->add("wipe_only_crossing", coBools);
def->label = L("Wipe only when crossing perimeters");
def->category = OptionCategory::extruders;
@@ -5738,6 +5757,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",
// bools
"retract_layer_change", "wipe", "wipe_only_crossing",
// percents
@@ -5792,6 +5812,8 @@ void PrintConfigDef::init_extruder_option_keys()
"tool_name",
"wipe",
"wipe_extra_perimeter",
+ "wipe_inside_end",
+ "wipe_inside_start",
"wipe_only_crossing",
"wipe_speed",
};
@@ -5810,6 +5832,8 @@ void PrintConfigDef::init_extruder_option_keys()
"seam_gap",
"wipe",
"wipe_extra_perimeter",
+ "wipe_inside_end",
+ "wipe_inside_start",
"wipe_only_crossing",
"wipe_speed",
};
@@ -7191,6 +7215,8 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
"wipe_advanced_nozzle_melted_volume",
"wipe_advanced",
"wipe_extra_perimeter",
+"wipe_inside_end",
+"wipe_inside_start",
"wipe_only_crossing",
"wipe_speed",
"xy_inner_size_compensation",
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index 8db96ff38..51a0638c0 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -1047,6 +1047,8 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, wipe_advanced))
((ConfigOptionFloat, wipe_advanced_nozzle_melted_volume))
((ConfigOptionFloat, wipe_advanced_multiplier))
+ ((ConfigOptionBools, wipe_inside_end))
+ ((ConfigOptionBools, wipe_inside_start))
((ConfigOptionFloats, wipe_extra_perimeter))
((ConfigOptionEnum<WipeAlgo>, wipe_advanced_algo))
((ConfigOptionBools, wipe_only_crossing))