From 6d2deda47a67e0745b51ef4ec88046f9acaf3463 Mon Sep 17 00:00:00 2001 From: supermerill Date: Thu, 27 May 2021 17:21:05 +0200 Subject: [PATCH] Option to let inner perimeters to curve around corners A bit like Cura Arachne --- resources/ui_layout/print.ui | 1 + src/libslic3r/PerimeterGenerator.cpp | 27 +++++++++++++++++---------- src/libslic3r/Preset.cpp | 1 + src/libslic3r/PrintConfig.cpp | 12 +++++++++++- src/libslic3r/PrintConfig.hpp | 2 ++ 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui index cd1fab071..eea13508f 100644 --- a/resources/ui_layout/print.ui +++ b/resources/ui_layout/print.ui @@ -64,6 +64,7 @@ group:Advanced setting:sidetext_width$0:perimeter_loop setting:label_width$5:label$Seam:perimeter_loop_seam end_line + setting:perimeter_round_corners group: External perimeter first setting:label$Activate:external_perimeters_first line:Apply on diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 732a6e813..a037c2f3c 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -431,12 +431,14 @@ void PerimeterGenerator::process() if (thin_perimeter) next_onion = offset_ex( last, - -(float)(ext_perimeter_width / 2)); + -(float)(ext_perimeter_width / 2), + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter)); else next_onion = offset2_ex( last, -(float)(ext_perimeter_width / 2 + ext_min_spacing / 2 - 1), - +(float)(ext_min_spacing / 2 - 1)); + +(float)(ext_min_spacing / 2 - 1), + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter)); // look for thin walls if (this->config->thin_walls) { @@ -510,11 +512,13 @@ void PerimeterGenerator::process() { if (thin_perimeter) next_onion = union_ex(next_onion, offset_ex(diff_ex(last, thins, true), - -(float)(ext_perimeter_width / 2))); + -(float)(ext_perimeter_width / 2), + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter))); else next_onion = union_ex(next_onion, offset2_ex(diff_ex(last, thins, true), -(float)((ext_perimeter_width / 2) + (ext_min_spacing / 4)), - (float)(ext_min_spacing / 4))); + (float)(ext_min_spacing / 4), + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter))); } } if (m_spiral_vase && next_onion.size() > 1) { @@ -534,7 +538,8 @@ void PerimeterGenerator::process() // the original. next_onion = offset2_ex(last, -(float)(good_spacing + min_spacing / 2 - 1), - +(float)(min_spacing / 2 - 1)); + +(float)(min_spacing / 2 - 1), + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter)); ExPolygons no_thin_onion = offset_ex(last, double(-good_spacing)); std::vector divs { 1.8f, 1.6f }; //don't over-extrude, so don't use divider >2 @@ -555,7 +560,8 @@ void PerimeterGenerator::process() } else { // If "overlapping_perimeters" is enabled, this paths will be entered, which // leads to overflows, as in prusa3d/Slic3r GH #32 - next_onion = offset_ex(last, double( - good_spacing)); + next_onion = offset_ex(last, double( - good_spacing), + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter)); } // look for gaps if (this->config->gap_fill @@ -566,7 +572,8 @@ void PerimeterGenerator::process() // won't be able to fill but we'd still remove from infill area append(gaps, diff_ex( offset(last, -0.5f * gap_fill_spacing), - offset(next_onion, 0.5f * good_spacing + 10))); // safety offset + offset(next_onion, 0.5f * good_spacing + 10, + (config->perimeter_round_corners.value ? ClipperLib::JoinType::jtRound : ClipperLib::JoinType::jtMiter)))); // safety offset } if (next_onion.empty()) { @@ -693,15 +700,15 @@ void PerimeterGenerator::process() //get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the min_width_top_surface we removed a bit before) ExPolygons inner_polygons = diff_ex(last, offset_ex(top_polygons, offset_top_surface + min_width_top_surface - //also remove the ext_perimeter_spacing/2 width because we are faking the external periemter, and we will remove ext_perimeter_spacing2 + //also remove the ext_perimeter_spacing/2 width because we are faking the external perimeter, and we will remove ext_perimeter_spacing2 - double(ext_perimeter_spacing / 2)), true); // get the enlarged top surface, by using inner_polygons instead of upper_slices, and clip it for it to be exactly the polygons to fill. top_polygons = diff_ex(fill_clip, inner_polygons, true); // increase by half peri the inner space to fill the frontier between last and stored. top_fills = union_ex(top_fills, top_polygons); - //set the clip to the external wall but go bacjk inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap. + //set the clip to the external wall but go back inside by infill_extrusion_width/2 to be sure the extrusion won't go outside even with a 100% overlap. fill_clip = offset_ex(last, double(ext_perimeter_spacing / 2) - this->config->infill_extrusion_width.get_abs_value(nozzle_diameter) / 2); - ExPolygons oldLast = last; + //ExPolygons oldLast = last; last = intersection_ex(inner_polygons, last); //{ // std::stringstream stri; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6b62f3186..738af3c95 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -540,6 +540,7 @@ const std::vector& Preset::print_options() "extrusion_width", "first_layer_extrusion_spacing", "first_layer_extrusion_width", + "perimeter_round_corners", "perimeter_extrusion_spacing", "perimeter_extrusion_width", "external_perimeter_extrusion_spacing", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 7986275f8..27e60143f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2622,7 +2622,7 @@ void PrintConfigDef::init_fff_params() def = this->add("min_width_top_surface", coFloatOrPercent); def->label = L("Minimum top width for infill"); def->category = OptionCategory::speed; - def->tooltip = L("If a top surface has to be printed and it's partially covered by an other layer, it won't be considered at a top layer where his width is below this value." + def->tooltip = L("If a top surface has to be printed and it's partially covered by an other layer, it won't be considered at a top layer where its width is below this value." " This can be useful to not let the 'one perimeter on top' trigger on surface that should be covered only by perimeters." " This value can be a mm or a % of the perimeter extrusion width."); def->sidetext = L("mm or %"); @@ -2847,6 +2847,15 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionFloatOrPercent(0,false)); + def = this->add("perimeter_round_corners", coBool); + def->label = L("Round corners"); + def->full_label = ("Round corners for perimeters"); + def->category = OptionCategory::perimeter; + def->tooltip = L("Internal periemters will go around sharp corners by tunring around isntead of making the same sharp corner." + " This can help when there is visible holes in sharp corners on perimeters"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("perimeter_extruder", coInt); def->label = L("Perimeter extruder"); def->category = OptionCategory::extruders; @@ -5448,6 +5457,7 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value, "solid_infill_extrusion_spacing", "top_infill_extrusion_spacing", "start_gcode_manual", +"perimeter_round_corners", }; //looks if it's to be removed, or have to be transformed diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 483175417..5b3998acd 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -809,6 +809,7 @@ public: ConfigOptionBool overhangs_reverse; ConfigOptionFloatOrPercent overhangs_reverse_threshold; ConfigOptionEnum no_perimeter_unsupported_algo; + ConfigOptionBool perimeter_round_corners; ConfigOptionInt perimeter_extruder; ConfigOptionFloatOrPercent perimeter_extrusion_width; ConfigOptionBool perimeter_loop; @@ -919,6 +920,7 @@ protected: OPT_PTR(overhangs_reverse); OPT_PTR(overhangs_reverse_threshold); OPT_PTR(no_perimeter_unsupported_algo); + OPT_PTR(perimeter_round_corners); OPT_PTR(perimeter_extruder); OPT_PTR(perimeter_extrusion_width); OPT_PTR(perimeter_loop);