diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index c461f71c1e9..bbb23369943 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -1404,7 +1404,7 @@ void PerimeterGenerator::apply_extra_perimeters(ExPolygons &infill_area) } // Reorient loop direction -static void reorient_perimeters(ExtrusionEntityCollection &entities, bool steep_overhang_contour, bool steep_overhang_hole) +static void reorient_perimeters(ExtrusionEntityCollection &entities, bool steep_overhang_contour, bool steep_overhang_hole, bool reverse_internal_only) { if (steep_overhang_hole || steep_overhang_contour) { for (auto entity : entities) { @@ -1413,7 +1413,17 @@ static void reorient_perimeters(ExtrusionEntityCollection &entities, bool steep_ // Only reverse when needed bool need_reverse = ((eloop->loop_role() & elrHole) == elrHole) ? steep_overhang_hole : steep_overhang_contour; - if (need_reverse && eloop[0].role()!=erExternalPerimeter) { + bool isExternal = false; + if(reverse_internal_only){ + for(auto path : eloop->paths){ + if(path.role() == erExternalPerimeter){ + isExternal = true; + break; + } + } + } + + if (need_reverse && !isExternal) { eloop->make_clockwise(); } } @@ -1711,7 +1721,7 @@ void PerimeterGenerator::process_classic() bool steep_overhang_contour = false; bool steep_overhang_hole = false; ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole); - reorient_perimeters(entities, steep_overhang_contour, steep_overhang_hole); + reorient_perimeters(entities, steep_overhang_contour, steep_overhang_hole, this->config->overhang_reverse_internal_only); // if brim will be printed, reverse the order of perimeters so that // we continue inwards after having finished the brim @@ -2233,7 +2243,7 @@ void PerimeterGenerator::process_arachne() bool steep_overhang_contour = false; bool steep_overhang_hole = false; if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions, steep_overhang_contour, steep_overhang_hole); !extrusion_coll.empty()) { - reorient_perimeters(extrusion_coll, steep_overhang_contour, steep_overhang_hole); + reorient_perimeters(extrusion_coll, steep_overhang_contour, steep_overhang_hole, this->config->overhang_reverse_internal_only); this->loops->append(extrusion_coll); } diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index c8c158f9308..c9777b3c381 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -726,7 +726,7 @@ bool Preset::has_cali_lines(PresetBundle* preset_bundle) static std::vector s_Preset_print_options { "layer_height", "initial_layer_print_height", "wall_loops", "slice_closing_radius", "spiral_mode", "slicing_mode", "top_shell_layers", "top_shell_thickness", "bottom_shell_layers", "bottom_shell_thickness", - "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold", + "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold","overhang_reverse_internal_only", "seam_position", "staggered_inner_seams", "wall_infill_order", "sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern", "infill_direction", "minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 94cb997fbcc..9903d5b0bc9 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -843,6 +843,14 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Extrude perimeters that have a part over an overhang in the reverse direction on odd layers. This alternating pattern can drastically improve steep overhang."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("overhang_reverse_internal_only", coBool); + def->label = L("Reverse only internal perimeters"); + def->full_label = L("Reverse only internal perimeters"); + def->category = L("Quality"); + def->tooltip = L("Apply the reverse perimeters logic only on internal perimeters. This reduces the effectiveness of the setting somewhat; however it prevents artefacts on the external walls caused by inaccuracies in the motion system.\nIt may also help to reduce part warping due to lower part stresses."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); def = this->add("overhang_reverse_threshold", coFloatOrPercent); def->label = L("Reverse threshold"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 6404b367ae1..40cc7a6d628 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -877,6 +877,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold)) ((ConfigOptionBool, hole_to_polyhole_twisted)) ((ConfigOptionBool, overhang_reverse)) + ((ConfigOptionBool, overhang_reverse_internal_only)) ((ConfigOptionFloatOrPercent, overhang_reverse_threshold)) ) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 8d6175cc0a9..48da72f5f3f 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1097,6 +1097,7 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "fuzzy_skin_point_distance" || opt_key == "detect_overhang_wall" || opt_key == "overhang_reverse" + || opt_key == "overhang_reverse_internal_only" || opt_key == "overhang_reverse_threshold" //BBS || opt_key == "enable_overhang_speed" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 934ddb10191..1541d6fad57 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -736,6 +736,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co bool allow_overhang_reverse = has_detect_overhang_wall && !has_spiral_vase; toggle_field("overhang_reverse", allow_overhang_reverse); toggle_line("overhang_reverse_threshold", allow_overhang_reverse && has_overhang_reverse); + toggle_line("overhang_reverse_internal_only", allow_overhang_reverse && has_overhang_reverse); toggle_line("timelapse_type", is_BBL_Printer); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 9a38c7409a7..2b2b8b913ee 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1911,6 +1911,7 @@ void TabPrint::build() optgroup->append_single_option_line("max_travel_detour_distance"); optgroup->append_single_option_line("extra_perimeters_on_overhangs"); optgroup->append_single_option_line("overhang_reverse"); + optgroup->append_single_option_line("overhang_reverse_internal_only"); optgroup->append_single_option_line("overhang_reverse_threshold"); page = add_options_page(L("Strength"), "empty");