From 7c4aa2f4cc2d4289bb1fba71439951f26b229725 Mon Sep 17 00:00:00 2001 From: supermerill Date: Thu, 13 Dec 2018 19:41:37 +0100 Subject: [PATCH 1/3] medial_axis changes from review --- xs/src/libslic3r/MedialAxis.cpp | 76 +++++++++++-------------- xs/src/libslic3r/MedialAxis.hpp | 5 +- xs/src/libslic3r/PerimeterGenerator.cpp | 2 +- xs/src/libslic3r/Polyline.hpp | 2 +- 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/xs/src/libslic3r/MedialAxis.cpp b/xs/src/libslic3r/MedialAxis.cpp index 64bd1bdf4..2074a87d6 100644 --- a/xs/src/libslic3r/MedialAxis.cpp +++ b/xs/src/libslic3r/MedialAxis.cpp @@ -606,6 +606,17 @@ MedialAxis::fusion_corners(ThickPolylines &pp) } +void +MedialAxis::extends_line_both_side(ThickPolylines& pp) { + const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION); + for (size_t i = 0; i < pp.size(); ++i) { + ThickPolyline& polyline = pp[i]; + this->extends_line(polyline, anchors, this->min_width); + polyline.reverse(); + this->extends_line(polyline, anchors, this->min_width); + } +} + void MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width) { @@ -722,18 +733,19 @@ void MedialAxis::main_fusion(ThickPolylines& pp) { //int idf = 0; - //reoder pp by length (ascending) It's really important to do that to avoid building the line from the width insteand of the length - std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { - bool ahas0 = a.width.front() == 0 || a.width.back() == 0; - bool bhas0 = b.width.front() == 0 || b.width.back() == 0; - if (ahas0 && !bhas0) return true; - if (!ahas0 && bhas0) return false; - return a.length() < b.length(); - }); bool changes = true; map coeff_angle_cache; while (changes) { + concatThickPolylines(pp); + //reoder pp by length (ascending) It's really important to do that to avoid building the line from the width insteand of the length + std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { + bool ahas0 = a.width.front() == 0 || a.width.back() == 0; + bool bhas0 = b.width.front() == 0 || b.width.back() == 0; + if (ahas0 && !bhas0) return true; + if (!ahas0 && bhas0) return false; + return a.length() < b.length(); + }); changes = false; for (size_t i = 0; i < pp.size(); ++i) { ThickPolyline& polyline = pp[i]; @@ -962,12 +974,12 @@ MedialAxis::main_fusion(ThickPolylines& pp) //Add last point polyline.points.push_back(best_candidate->points[idx_point]); polyline.width.push_back(best_candidate->width[idx_point]); - //select if an end opccur + //select if an end occur polyline.endpoints.second &= best_candidate->endpoints.second; } } else { - //select if an end opccur + //select if an end occur polyline.endpoints.second &= best_candidate->endpoints.second; } @@ -1018,17 +1030,6 @@ MedialAxis::main_fusion(ThickPolylines& pp) break; } } - if (changes) { - concatThickPolylines(pp); - ///reorder, in case of change - std::sort(pp.begin(), pp.end(), [](const ThickPolyline & a, const ThickPolyline & b) { - bool ahas0 = a.width.front() == 0 || a.width.back() == 0; - bool bhas0 = b.width.front() == 0 || b.width.back() == 0; - if (ahas0 && !bhas0) return true; - if (!ahas0 && bhas0) return false; - return a.length() < b.length(); - }); - } } } @@ -1239,7 +1240,7 @@ MedialAxis::remove_too_short_polylines(ThickPolylines& pp, const coord_t min_siz } } - if (shortest_idx >= 0 && shortest_idx < pp.size()) { + if (shortest_idx < pp.size()) { pp.erase(pp.begin() + shortest_idx); changes = true; } @@ -1255,7 +1256,7 @@ MedialAxis::ensure_not_overextrude(ThickPolylines& pp) double surface = 0; double volume = 0; for (ThickPolyline& polyline : pp) { - for (ThickLine l : polyline.thicklines()) { + for (ThickLine &l : polyline.thicklines()) { surface += l.length() * (l.a_width + l.b_width) / 2; double width_mean = (l.a_width + l.b_width) / 2; volume += height * (width_mean - height * (1. - 0.25 * PI)) * l.length(); @@ -1269,8 +1270,8 @@ MedialAxis::ensure_not_overextrude(ThickPolylines& pp) double perimeterRoundGap = bounds.contour.length() * height * (1 - 0.25*PI) * 0.5; // add holes "perimeter gaps" double holesGaps = 0; - for (auto hole = bounds.holes.begin(); hole != bounds.holes.end(); ++hole) { - holesGaps += hole->length() * height * (1 - 0.25*PI) * 0.5; + for (const Polygon &hole : bounds.holes) { + holesGaps += hole.length() * height * (1 - 0.25*PI) * 0.5; } boundsVolume += perimeterRoundGap + holesGaps; @@ -1278,7 +1279,7 @@ MedialAxis::ensure_not_overextrude(ThickPolylines& pp) //reduce width double reduce_by = boundsVolume / volume; for (ThickPolyline& polyline : pp) { - for (ThickLine l : polyline.thicklines()) { + for (ThickLine &l : polyline.thicklines()) { l.a_width *= reduce_by; l.b_width *= reduce_by; } @@ -1291,8 +1292,7 @@ MedialAxis::simplify_polygon_frontier() { //simplify the boundary between us and the bounds. - //int firstIdx = 0; - //while (firstIdx < contour.points.size() && bounds.contour.contains(contour.points[firstIdx])) firstIdx++; + //it will remove every point in the surface contour that aren't on the bounds contour ExPolygon simplified_poly = this->surface; if (&this->surface != &this->bounds) { bool need_intersect = false; @@ -1410,14 +1410,8 @@ MedialAxis::build(ThickPolylines* polylines_out) //fusion right-angle corners. fusion_corners(pp); - if (do_not_overextrude) { - const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION); - for (size_t i = 0; i < pp.size(); ++i) { - ThickPolyline& polyline = pp[i]; - extends_line(polyline, anchors, min_width); - polyline.reverse(); - extends_line(polyline, anchors, min_width); - } + if (stop_at_min_width) { + extends_line_both_side(pp); } //reduce extrusion when it's too thin to be printable @@ -1445,14 +1439,8 @@ MedialAxis::build(ThickPolylines* polylines_out) // Loop through all returned polylines in order to extend their endpoints to the // expolygon boundaries - if (!do_not_overextrude) { - const ExPolygons anchors = offset2_ex(diff_ex(this->bounds, this->expolygon), -SCALED_RESOLUTION, SCALED_RESOLUTION); - for (size_t i = 0; i < pp.size(); ++i) { - ThickPolyline& polyline = pp[i]; - extends_line(polyline, anchors, min_width); - polyline.reverse(); - extends_line(polyline, anchors, min_width); - } + if (!stop_at_min_width) { + extends_line_both_side(pp); } //{ // stringstream stri; diff --git a/xs/src/libslic3r/MedialAxis.hpp b/xs/src/libslic3r/MedialAxis.hpp index e4fd8e85d..21fbe3895 100644 --- a/xs/src/libslic3r/MedialAxis.hpp +++ b/xs/src/libslic3r/MedialAxis.hpp @@ -17,14 +17,14 @@ namespace Slic3r { class MedialAxis { public: - Lines lines; //lines is here only to avoid appassing it in argument of amny method. Initialized in polyline_from_voronoi. + Lines lines; //lines is here only to avoid passing it in argument of many methods. Initialized in polyline_from_voronoi. ExPolygon expolygon; const ExPolygon& bounds; const ExPolygon& surface; const double max_width; const double min_width; const double height; - bool do_not_overextrude = true; + bool stop_at_min_width = true; MedialAxis(const ExPolygon &_expolygon, const ExPolygon &_bounds, const double _max_width, const double _min_width, const double _height) : surface(_expolygon), bounds(_bounds), max_width(_max_width), min_width(_min_width), height(_height) { }; @@ -53,6 +53,7 @@ namespace Slic3r { void fusion_curve(ThickPolylines &pp); void main_fusion(ThickPolylines& pp); void fusion_corners(ThickPolylines &pp); + void extends_line_both_side(ThickPolylines& pp); void extends_line(ThickPolyline& polyline, const ExPolygons& anchors, const coord_t join_width); void remove_too_thin_extrusion(ThickPolylines& pp); void concatenate_polylines_with_crossing(ThickPolylines& pp); diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index 066b6ceb7..05a8efab7 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -286,7 +286,7 @@ void PerimeterGenerator::process() for (ExPolygon &half_thin : half_thins) { //growing back the polygon ExPolygons thin = offset_ex(half_thin, (float)(min_width / 2)); - if (thin.size() != 1) continue; // impossible error, growing a single polygon can't create multiple or 0. + assert(thin.size() == 1); ExPolygons anchor = intersection_ex(offset_ex(half_thin, (float)(min_width / 2) + (float)(ext_perimeter_width / 2), jtSquare), no_thin_zone, true); ExPolygons bounds = union_ex(thin, anchor, true); diff --git a/xs/src/libslic3r/Polyline.hpp b/xs/src/libslic3r/Polyline.hpp index 2935e6450..10076cdd7 100644 --- a/xs/src/libslic3r/Polyline.hpp +++ b/xs/src/libslic3r/Polyline.hpp @@ -132,7 +132,7 @@ bool remove_degenerate(Polylines &polylines); /// ThickPolyline : a polyline with a width for each point -/// This calss has a vector of coordf_t, it must be the same size than points. +/// This class has a vector of coordf_t, it must be the same size as points. /// it's used to store the size of the line at this point. /// Also, the endpoint let us know if the front() and back() of the polyline /// join something or is a dead-end. From e4a0f71d3c7224748d17c4ebc359d15062864011 Mon Sep 17 00:00:00 2001 From: supermerill Date: Sun, 16 Dec 2018 00:56:38 +0100 Subject: [PATCH 2/3] medial axis bugfix (ctd) --- xs/src/libslic3r/MedialAxis.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xs/src/libslic3r/MedialAxis.cpp b/xs/src/libslic3r/MedialAxis.cpp index 2074a87d6..18242b8ab 100644 --- a/xs/src/libslic3r/MedialAxis.cpp +++ b/xs/src/libslic3r/MedialAxis.cpp @@ -1325,7 +1325,8 @@ MedialAxis::simplify_polygon_frontier() } } - simplified_poly.remove_point_too_near(SCALED_RESOLUTION); + if (!simplified_poly.contour.points.empty()) + simplified_poly.remove_point_too_near(SCALED_RESOLUTION); return simplified_poly; } From 35808fef10095883ee7c6391a04ae13c0f3b0531 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 17 Dec 2018 12:48:44 +0100 Subject: [PATCH 3/3] typos (thanks to photog0411) --- xs/src/libslic3r/PrintConfig.cpp | 18 +++++++++--------- xs/src/slic3r/GUI/Tab.cpp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index f17b4c67f..05e01bd7b 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -359,14 +359,14 @@ PrintConfigDef::PrintConfigDef() def = this->add("enforce_full_fill_volume", coBool); def->label = L("Enforce full fill volume"); def->category = L("Infill"); - def->tooltip = L("Experimental option wich modify (top/bottom) fill flow to have the exact amount of plastic inside the volume to fill."); + def->tooltip = L("Experimental option which modifies (top/bottom) fill flow to have the exact amount of plastic inside the volume to fill."); def->cli = "enforce-full-fill-volume!"; def->default_value = new ConfigOptionBool(true); def = this->add("external_infill_margin", coFloat); def->label = L("Default"); def->category = L("Infill"); - def->tooltip = L("This parameter grow the top/bottom/solid layers by some mm to anchor them into the part. Put 0 to deactivate it."); + def->tooltip = L("This parameter grows the top/bottom/solid layers by the specified MM to anchor them into the part. Put 0 to deactivate it."); def->sidetext = L("mm"); def->cli = "top-layer-anchor=f"; def->min = 0; @@ -375,7 +375,7 @@ PrintConfigDef::PrintConfigDef() def = this->add("bridged_infill_margin", coFloat); def->label = L("Bridged"); def->category = L("Infill"); - def->tooltip = L("This parameter grow the bridged solid infill layers by some mm to anchor them into the part. Put 0 to deactivate it."); + def->tooltip = L("This parameter grows the bridged solid infill layers by the specified MM to anchor them into the part. Put 0 to deactivate it."); def->sidetext = L("mm"); def->cli = "top-layer-anchor=f"; def->min = 0; @@ -415,7 +415,7 @@ PrintConfigDef::PrintConfigDef() def->label = L(" "); def->category = L("Layers and Perimeters"); def->tooltip = L("Join the perimeters to create only one continuous extrusion without any z-hop." - " Long inside travel (from external to holes) are not extruded to give some place to the infill."); + " Long inside travel (from external to holes) are not extruded to give some space to the infill."); def->cli = "loop-perimeter!"; def->default_value = new ConfigOptionBool(false); @@ -962,8 +962,8 @@ PrintConfigDef::PrintConfigDef() def = this->add("infill_dense", coBool); def->label = (""); def->category = L("Infill"); - def->tooltip = L("Enable the creation of a support layer under the first solid layer. Allow to use lower infill ratio without compromizing the top quality." - " The dense infill is layed out with a 50% infill density."); + def->tooltip = L("Enables the creation of a support layer under the first solid layer. This allows you to use a lower infill ratio without compromizing the top quality." + " The dense infill is laid out with a 50% infill density."); def->cli = "infill-dense!"; def->default_value = new ConfigOptionBool(false); @@ -1377,7 +1377,7 @@ PrintConfigDef::PrintConfigDef() def = this->add("no_perimeter_unsupported", coBool); def->label = L(""); def->category = L("Layers and Perimeters"); - def->tooltip = L("Experimental option to remove perimeters where there are nothing under and a bridged infill should be better."); + def->tooltip = L("Experimental option to remove perimeters where there is nothing under it and a bridged infill should be better."); def->cli = "no-perimeter-unsupported!"; def->default_value = new ConfigOptionBool(false); @@ -1390,9 +1390,9 @@ PrintConfigDef::PrintConfigDef() def->default_value = new ConfigOptionInt(0); def = this->add("noperi_bridge_only", coBool); - def->label = L("Only on briged area"); + def->label = L("Only on bridged areas"); def->category = L("Layers and Perimeters"); - def->tooltip = L("Only remove perimeters over area marked as 'bridge'. Can be useful to let perimeter run over overhangs, but it's not very reliable."); + def->tooltip = L("Only remove perimeters over areas marked as 'bridge'. Can be useful to let perimeter run over overhangs, but it's not very reliable."); def->cli = "noperi-bridge-only!"; def->default_value = new ConfigOptionBool(true); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index d334aa7aa..06f313817 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -844,7 +844,7 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Reducing printing time"))); optgroup->append_single_option_line("infill_every_layers"); optgroup->append_single_option_line("infill_only_where_needed"); - line = { _(L("Suporting dense layer")), "" }; + line = { _(L("Supporting dense layer")), "" }; line.append_option(optgroup->get_option("infill_dense")); line.append_option(optgroup->get_option("infill_dense_algo")); optgroup->append_line(line);