diff --git a/xs/src/libslic3r/ExPolygon.cpp b/xs/src/libslic3r/ExPolygon.cpp index bfc3d5077a0..d1cc295611b 100644 --- a/xs/src/libslic3r/ExPolygon.cpp +++ b/xs/src/libslic3r/ExPolygon.cpp @@ -212,7 +212,7 @@ ExPolygon::remove_point_too_near(const coord_t tolerance) { void ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_width, ThickPolylines* polylines, double height, bool stop_at_min_width) const { Slic3r::MedialAxis ma(*this, bounds, max_width, min_width, height); - ma.stop_at_min_width = stop_at_min_width; + ma.stop_at_min_width = stop_at_min_width; ma.build(polylines); } diff --git a/xs/src/libslic3r/MedialAxis.cpp b/xs/src/libslic3r/MedialAxis.cpp index 2cd602db1fb..f5de2b49dfa 100644 --- a/xs/src/libslic3r/MedialAxis.cpp +++ b/xs/src/libslic3r/MedialAxis.cpp @@ -301,13 +301,14 @@ remove_point_too_near(ThickPolyline* to_reduce) to_reduce->points.erase(to_reduce->points.begin() + id); to_reduce->width.erase(to_reduce->width.begin() + id); newdist = to_reduce->points[id].distance_to(to_reduce->points[id - 1]); + //if you removed a point, it check if the next one isn't too near from the previous one. + // if not, it bypass it. + if (newdist > smallest) { + ++id; + } } //go to next one - //if you removed a point, it check if the next one isn't too near from the previous one. - // if not, it byepass it. - if (newdist > smallest) { - ++id; - } + else ++id; } } @@ -620,7 +621,7 @@ MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, con line.a = *(polyline.points.begin() + first_idx); } // prevent the line from touching on the other side, otherwise intersection() might return that solution - if (polyline.points.size() == 2) line.a = line.midpoint(); + if (polyline.points.size() == 2 && this->expolygon.contains(line.midpoint())) line.a = line.midpoint(); line.extend_end(max_width); Point new_back; @@ -628,18 +629,37 @@ MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, con new_back = polyline.points.back(); } else { //TODO: verify also for holes. - (void)this->expolygon.contour.first_intersection(line, &new_back); + bool finded = this->expolygon.contour.first_intersection(line, &new_back); + //verify also for holes. + Point new_back_temp; + for (Polygon hole : this->expolygon.holes) { + if (hole.first_intersection(line, &new_back_temp)) { + if (!finded || line.a.distance_to(new_back_temp) < line.a.distance_to(new_back)) { + finded = true; + new_back = new_back_temp; + } + } + } // safety check if no intersection - if (new_back.x == 0 && new_back.y == 0) new_back = line.b; + if (!finded) new_back = line.b; polyline.points.push_back(new_back); polyline.width.push_back(polyline.width.back()); } Point new_bound; - //TODO: verify also for holes. - (void)bounds.contour.first_intersection(line, &new_bound); + bool finded = bounds.contour.first_intersection(line, &new_bound); + //verify also for holes. + Point new_bound_temp; + for (Polygon hole : bounds.holes) { + if (hole.first_intersection(line, &new_bound_temp)) { + if (!finded || line.a.distance_to(new_bound_temp) < line.a.distance_to(new_bound)) { + finded = true; + new_bound = new_bound_temp; + } + } + } // safety check if no intersection - if (new_bound.x == 0 && new_bound.y == 0) { + if (!finded) { if (line.b.coincides_with_epsilon(polyline.points.back())) return; //check if we don't over-shoot inside us bool is_in_anchor = false; @@ -1363,7 +1383,7 @@ MedialAxis::build(ThickPolylines* polylines_out) // Loop through all returned polylines in order to extend their endpoints to the // expolygon boundaries (if done here, it may be cut later if not thick enough) if (stop_at_min_width) { - const ExPolygons anchors = offset2_ex(to_polygons(diff_ex(this->bounds, this->expolygon)), -SCALED_RESOLUTION, SCALED_RESOLUTION); + const ExPolygons anchors = offset2_ex(to_polygons(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); @@ -1398,14 +1418,14 @@ MedialAxis::build(ThickPolylines* polylines_out) // Loop through all returned polylines in order to extend their endpoints to the // expolygon boundaries if (!stop_at_min_width) { - const ExPolygons anchors = offset2_ex(to_polygons(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); - } - } + const ExPolygons anchors = offset2_ex(to_polygons(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); + } + } //{ // stringstream stri; // stri << "medial_axis_5_expand_" << id << ".svg"; diff --git a/xs/src/libslic3r/MedialAxis.hpp b/xs/src/libslic3r/MedialAxis.hpp index 3ec9d467d27..25a2c15f781 100644 --- a/xs/src/libslic3r/MedialAxis.hpp +++ b/xs/src/libslic3r/MedialAxis.hpp @@ -17,7 +17,7 @@ namespace Slic3r { public: Lines lines; //lines is here only to avoid appassing it in argument of amny method. Initialized in polyline_from_voronoi. ExPolygon expolygon; - + const ExPolygon& surface; const ExPolygon& bounds; const double max_width; diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index 681a10f451b..87a1bb66975 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -133,6 +133,7 @@ PerimeterGenerator::process() if (half_thins.size() > 0) { no_thin_zone = diff(last, to_polygons(offset_ex(half_thins, (float)(min_width / 2) - SCALED_EPSILON)), true); } + ExPolygons thin_zones_extruded; // compute a bit of overlap to anchor thin walls inside the print. for (ExPolygon &half_thin : half_thins) { //growing back the polygon @@ -145,17 +146,20 @@ PerimeterGenerator::process() for (ExPolygon &bound : bounds) { if (!intersection_ex(thin[0], bound).empty()) { //be sure it's not too small to extrude reliably - thin[0].remove_point_too_near(SCALED_RESOLUTION); + thin[0].remove_point_too_near(SCALED_RESOLUTION); if (thin[0].area() > min_width*(ext_pwidth + ext_pspacing2)) { - bound.remove_point_too_near(SCALED_RESOLUTION); + bound.remove_point_too_near(SCALED_RESOLUTION); // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop thin[0].medial_axis(bound, ext_pwidth + ext_pspacing2, min_width, &thin_walls, this->layer_height); + thin_zones_extruded.emplace_back(thin[0]); } break; } } } + // recompute the next onion, to be sure to not miss any small areas that can't be extruded by thin_walls + offsets = diff_ex(offset_ex(last, -(float)(ext_perimeter_width / 2)), thin_zones_extruded, true); #ifdef DEBUG printf(" %zu thin walls detected\n", thin_walls.size()); #endif