diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 941dd2e..d648d6f 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -1228,14 +1228,24 @@ void PerimeterGenerator::add_infill_contour_for_arachne(ExPolygons infill_contou //w38 -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) { if (entity->is_loop()) { ExtrusionLoop *eloop = static_cast(entity); bool need_reverse = ((eloop->loop_role() & elrHole) == elrHole) ? steep_overhang_hole : steep_overhang_contour; - if (need_reverse) { + bool isExternal = false; + if (reverse_internal_only) { + for (auto path : eloop->paths) { + if (path.role().is_external_perimeter()) { + isExternal = true; + break; + } + } + } + + if (need_reverse && !isExternal) { eloop->make_clockwise(); } } @@ -1453,7 +1463,7 @@ void PerimeterGenerator::process_arachne( if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(params, lower_slices_polygons_cache, 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, params.config.overhang_reverse_internal_only); out_loops.append(extrusion_coll); } @@ -1797,7 +1807,7 @@ void PerimeterGenerator::process_with_one_wall_arachne( if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(params, lower_slices_polygons_cache, 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, params.config.overhang_reverse_internal_only); out_loops.append(extrusion_coll); } @@ -2194,7 +2204,7 @@ void PerimeterGenerator::process_classic( bool steep_overhang_contour = false; bool steep_overhang_hole = false; ExtrusionEntityCollection entities = traverse_loops_classic(params, lower_layer_polygons_cache, 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, params.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 // TODO: add test for perimeter order diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 76ef2f5..1b9547c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -496,7 +496,7 @@ static std::vector s_Preset_print_options { //w33 ,"ironing_pattern" //w38 - ,"overhang_reverse","overhang_reverse_threshold"}; + ,"overhang_reverse","overhang_reverse_internal_only","overhang_reverse_threshold"}; static std::vector s_Preset_filament_options { "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 6240d2e..5af8147 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2317,6 +2317,18 @@ void PrintConfigDef::init_fff_params() 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->category = L("Layers and Perimeters"); + def->tooltip = L("Apply the reverse perimeters logic only on internal perimeters. \n\nThis setting greatly reduces part stresses as " + "they are now distributed in alternating directions. This should reduce part warping while also maintaining external " + "wall quality. This feature can be very useful for warp prone material, like ABS/ASA, and also for elastic filaments, " + "like TPU and Silk PLA. It can also help reduce warping on floating regions over supports.\n\nFor this setting to be " + "the most effective, it is recomended to set the Reverse Threshold to 0 so that all internal walls print in " + "alternating directions on odd layers irrespective of their overhang degree."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + //w38 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 cbe2c4d..7305ed5 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -678,6 +678,7 @@ PRINT_CONFIG_CLASS_DEFINE( //w38 ((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 69dc0d3..13e9b31 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -876,7 +876,11 @@ bool PrintObject::invalidate_state_by_config_options( //w17 || opt_key == "top_area_threshold" //w23 - || opt_key == "only_one_wall_first_layer") { + || opt_key == "only_one_wall_first_layer" + //w38 + || opt_key == "overhang_reverse" + || opt_key == "overhang_reverse_internal_only" + || opt_key == "overhang_reverse_threshold") { steps.emplace_back(posSlice); } else if ( opt_key == "seam_position" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 12c39e1..90a672e 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -385,6 +385,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) bool has_overhang_reverse = config->opt_bool("overhang_reverse"); bool allow_overhang_reverse = has_detect_overhang_wall && !has_spiral_vase; toggle_field("overhang_reverse", allow_overhang_reverse); + toggle_field("overhang_reverse_internal_only", allow_overhang_reverse && has_overhang_reverse); toggle_field("overhang_reverse_threshold", allow_overhang_reverse && has_overhang_reverse); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 73c587f..ceb17f2 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1462,6 +1462,7 @@ void TabPrint::build() //w38 optgroup->append_single_option_line("overhang_reverse"); + optgroup->append_single_option_line("overhang_reverse_internal_only"); optgroup->append_single_option_line("overhang_reverse_threshold"); optgroup = page->new_optgroup(L("Advanced"));