ENH: Port of "wipe inside before extruding an external perimeter" feature from super slicer (#3287)
* Wipe Inside at Start of perimeter Co-Authored-By: Merill <6536403+supermerill@users.noreply.github.com> * Cleaned up code and linked it to the wipe on loop parameter * Trigger build * Introduced wipe before external loop parameter. * Removed redundant functions --------- Co-authored-by: Merill <6536403+supermerill@users.noreply.github.com> Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
90dd67e4e4
commit
7ab2fabe6a
5 changed files with 61 additions and 1 deletions
|
@ -4437,6 +4437,58 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||
|
||||
// extrude along the path
|
||||
std::string gcode;
|
||||
|
||||
// Port of "wipe inside before extruding an external perimeter" feature from super slicer
|
||||
if (m_config.wipe_before_external_loop.value && !paths.empty() && paths.front().size() > 1 && paths.back().size() > 1 && paths.front().role() == erExternalPerimeter) {
|
||||
const bool is_full_loop_ccw = loop.polygon().is_counter_clockwise();
|
||||
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0; // loop.make_counter_clockwise();
|
||||
const double nozzle_diam = EXTRUDER_CONFIG(nozzle_diameter);
|
||||
|
||||
// note: previous & next are inverted to extrude "in the opposite direction, and we are "rewinding"
|
||||
Point previous_point = paths.front().polyline.points[1];
|
||||
Point current_point = paths.front().polyline.points.front();
|
||||
Point next_point = paths.back().polyline.points.back();
|
||||
|
||||
// can happen if seam_gap is null
|
||||
if (next_point == current_point) {
|
||||
next_point = paths.back().polyline.points[paths.back().polyline.points.size() - 2];
|
||||
}
|
||||
|
||||
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
|
||||
std::swap(a, b);
|
||||
}
|
||||
|
||||
double angle = current_point.ccw_angle(a, b) / 3;
|
||||
|
||||
// turn outwards if contour, turn inwwards if hole
|
||||
if (is_hole_loop ? !is_full_loop_ccw : is_full_loop_ccw) angle *= -1;
|
||||
|
||||
Vec2d current_pos = current_point.cast<double>();
|
||||
Vec2d next_pos = next_point.cast<double>();
|
||||
Vec2d vec_dist = next_pos - current_pos;
|
||||
double vec_norm = vec_dist.norm();
|
||||
// Offset distance is the minimum between half the nozzle diameter or half the line width for the upcomming perimeter
|
||||
// This is to mimimize potential instances where the de-retraction is performed on top of a neighbouring
|
||||
// thin perimeter due to arachne reducing line width.
|
||||
coordf_t dist = std::min(scaled(nozzle_diam) * 0.5, scaled(paths.front().width) * 0.5);
|
||||
|
||||
// FIXME Hiding the seams will not work nicely for very densely discretized contours!
|
||||
Point pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>();
|
||||
pt.rotate(angle, current_point);
|
||||
pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>();
|
||||
pt.rotate(angle, current_point);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_small_peri = false;
|
||||
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
|
||||
// description += ExtrusionLoop::role_to_string(loop.loop_role());
|
||||
|
|
|
@ -808,7 +808,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"small_perimeter_speed", "small_perimeter_threshold","bridge_angle", "filter_out_gap_fill", "travel_acceleration","inner_wall_acceleration", "min_width_top_surface",
|
||||
"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk",
|
||||
"top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer", "print_flow_ratio", "seam_gap",
|
||||
"role_based_wipe_speed", "wipe_speed", "accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops",
|
||||
"role_based_wipe_speed", "wipe_speed", "accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops", "wipe_before_external_loop",
|
||||
"bridge_density", "precise_outer_wall", "overhang_speed_classic", "bridge_acceleration",
|
||||
"sparse_infill_acceleration", "internal_solid_infill_acceleration", "tree_support_adaptive_layer_height", "tree_support_auto_brim",
|
||||
"tree_support_brim_width", "gcode_comments", "gcode_label_objects",
|
||||
|
|
|
@ -3327,6 +3327,12 @@ def = this->add("filament_loading_speed", coFloats);
|
|||
def->tooltip = L("To minimize the visibility of the seam in a closed loop extrusion, a small inward movement is executed before the extruder leaves the loop.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("wipe_before_external_loop", coBool);
|
||||
def->label = L("Wipe before external loop");
|
||||
def->tooltip = L("To minimise visibility of potential overextrusion at the start of an external perimeter when printing with Outer/Inner or Inner/Outer/Inner wall print order, the deretraction is performed slightly on the inside from the start of the external perimeter. Thatway any potential over extrusion is hidden from the outside surface. \n\nThis is useful when printing with Outer/Inner or Inner/Outer/Inner wall print order as in these modes it is more likely an external perimeter is printed immediately after a deretraction move.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("wipe_speed", coFloatOrPercent);
|
||||
def->label = L("Wipe speed");
|
||||
|
|
|
@ -880,6 +880,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionBool, role_based_wipe_speed))
|
||||
((ConfigOptionFloatOrPercent, wipe_speed))
|
||||
((ConfigOptionBool, wipe_on_loops))
|
||||
((ConfigOptionBool, wipe_before_external_loop))
|
||||
((ConfigOptionEnum<WallInfillOrder>, wall_infill_order))
|
||||
((ConfigOptionBool, precise_outer_wall))
|
||||
((ConfigOptionBool, overhang_speed_classic))
|
||||
|
|
|
@ -1924,6 +1924,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("role_based_wipe_speed","seam");
|
||||
optgroup->append_single_option_line("wipe_speed", "seam");
|
||||
optgroup->append_single_option_line("wipe_on_loops","seam");
|
||||
optgroup->append_single_option_line("wipe_before_external_loop","seam");
|
||||
|
||||
|
||||
optgroup = page->new_optgroup(L("Precision"), L"param_precision");
|
||||
|
|
Loading…
Reference in a new issue