mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-14 09:31:48 +08:00
#226 Moar Wipe on external perimeters
This commit is contained in:
parent
cbc01a1a7e
commit
a0ff5c3fec
@ -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<double>();
|
||||
Vec2d p2 = paths.front().polyline.points[1].cast<double>();
|
||||
Vec2d v = p2 - p1;
|
||||
Vec2d current_pos = current_point.cast<double>();
|
||||
Vec2d next_pos = next_point.cast<double>();
|
||||
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<coord_t>();
|
||||
pt.rotate(angle, paths.front().polyline.points.front());
|
||||
Point pt = ((nd * nd >= l2) ? next_pos : (current_pos + vec_dist * (nd / sqrt(l2)))).cast<coord_t>();
|
||||
pt.rotate(angle, current_point);
|
||||
// generate the travel move
|
||||
gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), "move inwards before travel");
|
||||
}
|
||||
|
@ -150,7 +150,8 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
||||
"use_relative_e_distances",
|
||||
"use_volumetric_e",
|
||||
"variable_layer_height",
|
||||
"wipe"
|
||||
"wipe",
|
||||
"wipe_extra_perimeter"
|
||||
};
|
||||
|
||||
static std::unordered_set<std::string> steps_ignore;
|
||||
|
@ -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",
|
||||
|
@ -860,6 +860,7 @@ public:
|
||||
ConfigOptionBool wipe_advanced;
|
||||
ConfigOptionFloat wipe_advanced_nozzle_melted_volume;
|
||||
ConfigOptionFloat wipe_advanced_multiplier;
|
||||
ConfigOptionFloats wipe_extra_perimeter;
|
||||
ConfigOptionEnum<WipeAlgo> 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user