diff options
-rw-r--r-- | resources/ui_layout/print.ui | 17 | ||||
-rw-r--r-- | src/libslic3r/Layer.cpp | 3 | ||||
-rw-r--r-- | src/libslic3r/PerimeterGenerator.cpp | 27 | ||||
-rw-r--r-- | src/libslic3r/PerimeterGenerator.hpp | 8 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 40 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.hpp | 6 | ||||
-rw-r--r-- | src/libslic3r/PrintObject.cpp | 3 | ||||
-rw-r--r-- | src/slic3r/GUI/ConfigManipulation.cpp | 7 | ||||
-rw-r--r-- | src/slic3r/GUI/Preset.cpp | 3 |
9 files changed, 91 insertions, 23 deletions
diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui index 1fc4d1c81..5e56b8444 100644 --- a/resources/ui_layout/print.ui +++ b/resources/ui_layout/print.ui @@ -15,12 +15,12 @@ group:Horizontal shells end_line top_bottom_shell_thickness_explanation setting:enforce_full_fill_volume -group:Quality (slower slicing) +group:Quality + setting:only_one_perimeter_top line:Extra perimeters - setting:extra_perimeters + setting:extra_perimeters_overhangs setting:extra_perimeters_odd_layers end_line - setting:only_one_perimeter_top setting:ensure_vertical_shell_thickness line:Avoid crossing perimeters setting:label$:avoid_crossing_perimeters @@ -32,12 +32,17 @@ group:Quality (slower slicing) setting:width$5:thin_walls_min_width setting:width$5:thin_walls_overlap end_line - line:Overhangs - setting:overhangs +group:Overhangs + line:On perimeters + setting:sidetext_width$1:overhangs setting:width$5:overhangs_width end_line - setting:no_perimeter_unsupported_algo + line:Extrusion direction + setting:sidetext_width$1:overhangs_reverse + setting:width$5:overhangs_reverse_threshold + end_line group:Advanced + setting:no_perimeter_unsupported_algo line:Gap Fill setting:gap_fill setting:width$5:gap_fill_min_area diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 0528fdc85..0729f99ae 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -144,6 +144,7 @@ void Layer::make_perimeters() && config.external_perimeters_nothole == other_config.external_perimeters_nothole && config.external_perimeter_speed == other_config.external_perimeter_speed && config.extra_perimeters_odd_layers == other_config.extra_perimeters_odd_layers + && config.extra_perimeters_overhangs == other_config.extra_perimeters_overhangs && config.gap_fill == other_config.gap_fill && config.gap_fill_min_area == other_config.gap_fill_min_area && config.gap_fill_speed == other_config.gap_fill_speed @@ -153,6 +154,8 @@ void Layer::make_perimeters() && config.only_one_perimeter_top == other_config.only_one_perimeter_top && config.overhangs == other_config.overhangs && config.overhangs_width == other_config.overhangs_width + && config.overhangs_reverse == other_config.overhangs_reverse + && config.overhangs_reverse_threshold == other_config.overhangs_reverse_threshold && config.perimeter_extrusion_width == other_config.perimeter_extrusion_width && config.perimeter_loop == other_config.perimeter_loop && config.perimeter_loop_seam == other_config.perimeter_loop_seam diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 2ec55961e..66678d72c 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -295,8 +295,8 @@ void PerimeterGenerator::process() // Add perimeters on overhangs : initialization ExPolygons overhangs_unsupported; - if (this->config->extra_perimeters && !last.empty() - && this->lower_slices != NULL && !this->lower_slices->empty()) { + if ( (this->config->extra_perimeters_overhangs || (this->config->overhangs_reverse && this->layer_id % 2 == 1)) + && !last.empty() && this->lower_slices != NULL && !this->lower_slices->empty()) { //remove holes from lower layer, we only ant that for overhangs, not bridges! ExPolygons lower_without_holes; for (const ExPolygon &exp : *this->lower_slices) @@ -330,6 +330,18 @@ void PerimeterGenerator::process() } } } + bool has_steep_overhang = false; + if (this->layer_id % 2 == 1 && this->config->overhangs_reverse //check if my option is set and good layer + && !last.empty() && !overhangs_unsupported.empty() //has something to work with + ) { + coord_t offset = scale_(config->overhangs_reverse_threshold.get_abs_value(this->perimeter_flow.width)); + //version with °: scale_(std::tan(PI * (0.5f / 90) * config->overhangs_reverse_threshold.value ) * this->layer_height) + + if (offset_ex(overhangs_unsupported, -offset / 2).size() > 0) { + //allow this loop to be printed in reverse + has_steep_overhang = true; + } + } // In case no perimeters are to be generated, loop_number will equal to -1. std::vector<PerimeterGeneratorLoops> contours(loop_number+1); // depth => loops @@ -341,10 +353,10 @@ void PerimeterGenerator::process() // We can add more perimeters if there are uncovered overhangs // improvement for future: find a way to add perimeters only where it's needed. bool has_overhang = false; - if (this->config->extra_perimeters && !last.empty() && !overhangs_unsupported.empty()) { + if ( this->config->extra_perimeters_overhangs && !last.empty() && !overhangs_unsupported.empty()) { overhangs_unsupported = intersection_ex(overhangs_unsupported, last, true); if (overhangs_unsupported.size() > 0) { - //add fake perimeters here + //please don't stop adding periemter yet. has_overhang = true; } } @@ -512,11 +524,11 @@ void PerimeterGenerator::process() for (const ExPolygon &expolygon : next_onion) { //TODO: add width here to allow variable width (if we want to extrude a sightly bigger perimeter, see thin wall) - contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true, has_overhang)); + contours[i].emplace_back(expolygon.contour, i, true, has_steep_overhang); if (! expolygon.holes.empty()) { holes[i].reserve(holes[i].size() + expolygon.holes.size()); for (const Polygon &hole : expolygon.holes) - holes[i].emplace_back(PerimeterGeneratorLoop(hole, i, false, has_overhang)); + holes[i].emplace_back(hole, i, false, has_steep_overhang); } } last = std::move(next_onion); @@ -889,7 +901,8 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( ExtrusionLoop *eloop = static_cast<ExtrusionLoop*>(coll.entities[idx.first]); coll.entities[idx.first] = nullptr; if (loop.is_contour) { - if (loop.is_overhang && this->layer_id % 2 == 1) + //note: this->layer_id % 2 == 1 already taken into account in the is_steep_overhang compute (to save time). + if (loop.is_steep_overhang && this->layer_id % 2 == 1) eloop->make_clockwise(); else eloop->make_counter_clockwise(); diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp index a3e5a3c8e..070b03e50 100644 --- a/src/libslic3r/PerimeterGenerator.hpp +++ b/src/libslic3r/PerimeterGenerator.hpp @@ -29,7 +29,7 @@ public: // Contours are CCW oriented, holes are CW oriented. bool is_contour; //overhang may need to be reversed - bool is_overhang; + bool is_steep_overhang; // Depth in the hierarchy. External perimeter has depth = 0. An external perimeter could be both a contour and a hole. unsigned short depth; // Children contour, may be both CCW and CW oriented (outer contours or holes). @@ -37,9 +37,9 @@ public: PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour) : - polygon(polygon), is_contour(is_contour), depth(depth), is_overhang(false) {} - PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour, bool is_overhang) : - polygon(polygon), is_contour(is_contour), depth(depth), is_overhang(is_overhang) {} + polygon(polygon), is_contour(is_contour), depth(depth), is_steep_overhang(false) {} + PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour, bool is_steep_overhang) : + polygon(polygon), is_contour(is_contour), depth(depth), is_steep_overhang(is_steep_overhang) {} // External perimeter. It may be CCW or CW oriented (outer contour or hole contour). bool is_external() const { return this->depth == 0; } // An island, which may have holes, but it does not have another internal island. diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 04c87fdc6..35d061475 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -761,12 +761,24 @@ void PrintConfigDef::init_fff_params() def = this->add("extra_perimeters", coBool); def->label = L("filling horizontal gaps on slopes"); - def->full_label = L("Extra perimeters if needed"); + def->full_label = L("Extra perimeters (do nothing)"); def->category = OptionCategory::perimeter; def->tooltip = L("Add more perimeters when needed for avoiding gaps in sloping walls. " "Slic3r keeps adding perimeters, until more than 70% of the loop immediately above " - "is supported, and keep adding periemter until all overhangs are filled." - "\n!! this is a very slow algorithm !!"); + "is supported." + "\nIf you succeed to trigger the algorihtm behind this setting, please send me a message." + " Personally, i think it's useless."); + def->mode = comExpert; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("extra_perimeters_overhangs", coBool); + def->label = L("on overhangs"); + def->full_label = L("Extra perimeters in overhangs"); + def->category = OptionCategory::perimeter; + def->tooltip = L("Add more perimeters when needed for avoiding gaps in sloping walls. " + "Slic3r keeps adding periemter until all overhangs are filled." + "\n!! this is a very slow algorithm !!" + "\nIf you use this setting, consider strongly using also overhangs_reverse."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); @@ -2030,13 +2042,31 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionBool(true)); def = this->add("overhangs_width", coFloatOrPercent); - def->label = L("Threshold"); - def->full_label = L("Overhang Threshold"); + def->label = L("As bridge threshold"); + def->full_label = L("Overhang bridge threshold"); def->category = OptionCategory::perimeter; def->tooltip = L("Minimum unsupported width for an extrusion to be considered an overhang. Can be in mm or in a % of the nozzle diameter."); def->mode = comExpert; def->set_default_value(new ConfigOptionFloatOrPercent(50, true)); + def = this->add("overhangs_reverse", coBool); + def->label = L("Reverse on odd"); + def->full_label = L("Overhang reversal"); + def->category = OptionCategory::perimeter; + def->tooltip = L("Extrude perimeters that have a part over an overhang in the reverse direction in odd layers. That alternating pattern can drastically improve steep overhang." + "\n!! this is a very slow algorithm (it uses the same results as extra_perimeters_overhangs) !!"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("overhangs_reverse_threshold", coFloatOrPercent); + def->label = L("Reverse threshold"); + def->full_label = L("Overhang reversal threshold"); + def->category = OptionCategory::perimeter; + def->tooltip = L("Number of mm the overhang need to be for the reversal to be considered useful. Can be a % of the periemter width."); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloatOrPercent(250, true)); + def = this->add("no_perimeter_unsupported_algo", coEnum); def->label = L("No perimeters on bridge areas"); def->category = OptionCategory::perimeter; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index c2a3951a4..49c13b9f1 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -597,6 +597,7 @@ public: ConfigOptionBool external_perimeters_hole; ConfigOptionBool extra_perimeters; ConfigOptionBool extra_perimeters_odd_layers; + ConfigOptionBool extra_perimeters_overhangs; ConfigOptionBool only_one_perimeter_top; ConfigOptionFloat fill_angle; ConfigOptionPercent fill_density; @@ -620,6 +621,8 @@ public: // Detect bridging perimeters ConfigOptionBool overhangs; ConfigOptionFloatOrPercent overhangs_width; + ConfigOptionBool overhangs_reverse; + ConfigOptionFloatOrPercent overhangs_reverse_threshold; ConfigOptionEnum<NoPerimeterUnsupportedAlgo> no_perimeter_unsupported_algo; ConfigOptionInt perimeter_extruder; ConfigOptionFloatOrPercent perimeter_extrusion_width; @@ -675,6 +678,7 @@ protected: OPT_PTR(external_perimeters_hole); OPT_PTR(extra_perimeters); OPT_PTR(extra_perimeters_odd_layers); + OPT_PTR(extra_perimeters_overhangs); OPT_PTR(only_one_perimeter_top); OPT_PTR(fill_angle); OPT_PTR(fill_density); @@ -697,6 +701,8 @@ protected: OPT_PTR(infill_first); OPT_PTR(overhangs); OPT_PTR(overhangs_width); + OPT_PTR(overhangs_reverse); + OPT_PTR(overhangs_reverse_threshold); OPT_PTR(no_perimeter_unsupported_algo); OPT_PTR(perimeter_extruder); OPT_PTR(perimeter_extrusion_width); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 16923e46b..3e4eb9844 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -598,6 +598,9 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_ || opt_key == "gap_fill" || opt_key == "gap_fill_speed" || opt_key == "overhangs" + || opt_key == "overhangs_width" + || opt_key == "overhangs_reverse" + || opt_key == "overhangs_reverse_threshold" || opt_key == "first_layer_extrusion_width" || opt_key == "perimeter_extrusion_width" || opt_key == "infill_overlap" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 58fc8322a..6849c5be1 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -294,11 +294,16 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) { bool have_perimeters = config->opt_int("perimeters") > 0; - for (auto el : { "extra_perimeters", "extra_perimeters_odd_layers", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "thin_walls", "overhangs", + for (auto el : { "extra_perimeters", "extra_perimeters_overhangs", "extra_perimeters_odd_layers", + "only_one_perimeter_top", "ensure_vertical_shell_thickness", "thin_walls", + "overhangs", "overhangs_reverse", "seam_position", "external_perimeters_first", "external_perimeters_vase", "external_perimeter_extrusion_width", "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "perimeter_loop", "perimeter_loop_seam" }) toggle_field(el, have_perimeters); + toggle_field("overhangs_width", config->opt_bool("overhangs")); + toggle_field("overhangs_reverse_threshold", config->opt_bool("overhangs_reverse")); + for (auto el : { "external_perimeters_vase", "external_perimeters_nothole", "external_perimeters_hole"}) toggle_field(el, config->opt_bool("external_perimeters_first")); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 4bc0e26a0..c63900291 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -426,6 +426,7 @@ const std::vector<std::string>& Preset::print_options() "bottom_solid_min_thickness", "extra_perimeters", "extra_perimeters_odd_layers", + "extra_perimeters_overhangs", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "allow_empty_layers", "avoid_crossing_perimeters", @@ -433,6 +434,8 @@ const std::vector<std::string>& Preset::print_options() "thin_perimeters", "thin_walls", "overhangs", "overhangs_width", + "overhangs_reverse", + "overhangs_reverse_threshold", "seam_position", "external_perimeters_first", "external_perimeters_vase", |