Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@fr.fr>2018-12-06 19:17:25 +0300
committersupermerill <merill@fr.fr>2018-12-06 19:17:25 +0300
commita36fe262f7f566fe347f27c8bdd8294737af34ce (patch)
tree4d2677a3d34484b9152ba900e68a07f7815c5637
parent345da498c8cf8eea3332834088ba9aa9aa33b8bb (diff)
some fix on thin_wallsnot_cool
-rw-r--r--t/thin.t15
-rw-r--r--xs/src/libslic3r/MedialAxis.cpp64
-rw-r--r--xs/src/libslic3r/MedialAxis.hpp1
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.cpp10
4 files changed, 56 insertions, 34 deletions
diff --git a/t/thin.t b/t/thin.t
index d091117a2..fcab28470 100644
--- a/t/thin.t
+++ b/t/thin.t
@@ -1,4 +1,4 @@
-use Test::More tests => 28;
+use Test::More tests => 29;
use strict;
use warnings;
@@ -102,7 +102,9 @@ if (0) {
is scalar(@$res), 1, 'medial axis of a semicircumference is a single line';
# check whether turns are all CCW or all CW
- my @lines = @{$res->[0]->lines};
+ my @alllines = @{$res->[0]->lines};
+ # remove lines taht are near the end.
+ my @lines = grep($_->a->y >= 1578184 || $_->b->y >= 1578184, @alllines);
my @angles = map { $lines[$_-1]->ccw($lines[$_]->b) } 1..$#lines;
ok !!(none { $_ < 0 } @angles) || (none { $_ > 0 } @angles),
'all medial axis segments of a semicircumference have the same orientation';
@@ -113,16 +115,25 @@ if (0) {
[4.3, 4], [4.3, 0], [4,0], [4,4], [0,4], [0,4.5], [4,4.5], [4,10], [4.3,10], [4.3, 4.5],
[6, 4.5], [6,10], [6.2,10], [6.2,4.5], [10,4.5], [10,4], [6.2,4], [6.2,0], [6, 0], [6, 4],
));
+ $expolygon->contour->make_counter_clockwise();
my $res = $expolygon->medial_axis(scale 0.55, scale 0.25);
is scalar(@$res), 2, 'medial axis of a (bit too narrow) french cross is two lines';
ok unscale($res->[0]->length) >= (9.9) - epsilon, 'medial axis has reasonable length';
ok unscale($res->[1]->length) >= (9.9) - epsilon, 'medial axis has reasonable length';
+ my @lines1 = @{$res->[0]->lines};
+ my @angles1 = map { $lines1[$_-1]->ccw($lines1[$_]->b) } 1..$#lines1;
+ my @lines2 = @{$res->[1]->lines};
+ my @angles2 = map { $lines2[$_-1]->ccw($lines2[$_]->b) } 1..$#lines2;
+ my @angles = (@angles1, @angles2);
+ ok !!(none { $_ != 0 } @angles),
+ 'medial axis of a (bit too narrow) french cross is two lines has only strait lines';
}
{
my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new_scale(
[0.86526705,1.4509841], [0.57696039,1.8637021], [0.4502297,2.5569978], [0.45626199,3.2965596], [1.1218851,3.3049455], [0.96681072,2.8243202], [0.86328971,2.2056997], [0.85367905,1.7790778],
));
+ $expolygon->contour->make_counter_clockwise();
my $res = $expolygon->medial_axis(scale 1, scale 0.25);
is scalar(@$res), 1, 'medial axis of a (bit too narrow) french cross is two lines';
ok unscale($res->[0]->length) >= (1.4) - epsilon, 'medial axis has reasonable length';
diff --git a/xs/src/libslic3r/MedialAxis.cpp b/xs/src/libslic3r/MedialAxis.cpp
index 2b0006129..7be8c0958 100644
--- a/xs/src/libslic3r/MedialAxis.cpp
+++ b/xs/src/libslic3r/MedialAxis.cpp
@@ -359,21 +359,21 @@ add_point_same_percent(ThickPolyline* pattern, ThickPolyline* to_modify)
/// return 1 for an angle of 90° and 0 for an angle of 0° or 180°
double
get_coeff_from_angle_countour(Point &point, const ExPolygon &contour, coord_t min_dist_between_point) {
- double nearestDist = point.distance_to(contour.contour.points.front());
- Point nearest = contour.contour.points.front();
+ double nearest_dist = point.distance_to(contour.contour.points.front());
+ Point point_nearest = contour.contour.points.front();
size_t id_nearest = 0;
- double nearDist = nearestDist;
- Point near = nearest;
+ double near_dist = nearest_dist;
+ Point point_near = point_nearest;
size_t id_near = 0;
for (size_t id_point = 1; id_point < contour.contour.points.size(); ++id_point) {
- if (nearestDist > point.distance_to(contour.contour.points[id_point])) {
- //update near
+ if (nearest_dist > point.distance_to(contour.contour.points[id_point])) {
+ //update point_near
id_near = id_nearest;
- near = nearest;
- nearDist = nearestDist;
+ point_near = point_nearest;
+ near_dist = nearest_dist;
//update nearest
- nearestDist = point.distance_to(contour.contour.points[id_point]);
- nearest = contour.contour.points[id_point];
+ nearest_dist = point.distance_to(contour.contour.points[id_point]);
+ point_nearest = contour.contour.points[id_point];
id_nearest = id_point;
}
}
@@ -381,7 +381,7 @@ get_coeff_from_angle_countour(Point &point, const ExPolygon &contour, coord_t mi
size_t id_before = id_nearest == 0 ? contour.contour.points.size() - 1 : id_nearest - 1;
Point point_before = id_nearest == 0 ? contour.contour.points.back() : contour.contour.points[id_nearest - 1];
//Search one point far enough to be relevant
- while (nearest.distance_to(point_before) < min_dist_between_point) {
+ while (point_nearest.distance_to(point_before) < min_dist_between_point) {
point_before = id_before == 0 ? contour.contour.points.back() : contour.contour.points[id_before - 1];
id_before = id_before == 0 ? contour.contour.points.size() - 1 : id_before - 1;
//don't loop
@@ -394,7 +394,7 @@ get_coeff_from_angle_countour(Point &point, const ExPolygon &contour, coord_t mi
size_t id_after = id_nearest == contour.contour.points.size() - 1 ? 0 : id_nearest + 1;
Point point_after = id_nearest == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_nearest + 1];
//Search one point far enough to be relevant
- while (nearest.distance_to(point_after) < min_dist_between_point) {
+ while (point_nearest.distance_to(point_after) < min_dist_between_point) {
point_after = id_after == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_after + 1];
id_after = id_after == contour.contour.points.size() - 1 ? 0 : id_after + 1;
//don't loop
@@ -405,15 +405,15 @@ get_coeff_from_angle_countour(Point &point, const ExPolygon &contour, coord_t mi
}
}
//compute angle
- angle = nearest.ccw_angle(point_before, point_after);
+ angle = point_nearest.ccw_angle(point_before, point_after);
if (angle >= PI) angle = 2 * PI - angle; // smaller angle
//compute the diff from 90°
angle = abs(angle - PI / 2);
- if (near.coincides_with(nearest) && max(nearestDist, nearDist) + SCALED_EPSILON < nearest.distance_to(near)) {
+ if (point_near.coincides_with(point_nearest) && max(nearest_dist, near_dist) + SCALED_EPSILON < point_nearest.distance_to(point_near)) {
//not only nearest
Point point_before = id_near == 0 ? contour.contour.points.back() : contour.contour.points[id_near - 1];
Point point_after = id_near == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_near + 1];
- double angle2 = min(nearest.ccw_angle(point_before, point_after), nearest.ccw_angle(point_after, point_before));
+ double angle2 = min(point_nearest.ccw_angle(point_before, point_after), point_nearest.ccw_angle(point_after, point_before));
angle2 = abs(angle - PI / 2);
angle = (angle + angle2) / 2;
}
@@ -1319,10 +1319,6 @@ MedialAxis::build(ThickPolylines* polylines_out)
// svg.Close();
//}
this->expolygon = simplify_polygon_frontier();
- //check area
- if (this->expolygon.area() < this->max_width * this->min_width) return;
-
- //std::cout << "simplify_polygon_frontier\n";
//{
// stringstream stri;
// stri << "medial_axis_0.5_simplified_" << id << ".svg";
@@ -1331,6 +1327,11 @@ MedialAxis::build(ThickPolylines* polylines_out)
// svg.draw(this->expolygon);
// svg.Close();
//}
+ //safety check
+ if (this->expolygon.area() < this->min_width * this->min_width) this->expolygon = this->surface;
+ if (this->expolygon.area() < this->min_width * this->min_width) return;
+
+ //std::cout << "simplify_polygon_frontier\n";
// compute the Voronoi diagram and extract medial axis polylines
ThickPolylines pp;
this->polyline_from_voronoi(this->expolygon.lines(), &pp);
@@ -1366,7 +1367,6 @@ MedialAxis::build(ThickPolylines* polylines_out)
// svg.Close();
//}
- concatThickPolylines(pp);
// Aligned fusion: Fusion the bits at the end of lines by "increasing thickness"
// For that, we have to find other lines,
@@ -1387,6 +1387,16 @@ 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);
+ }
+ }
+
//reduce extrusion when it's too thin to be printable
remove_too_thin_extrusion(pp);
//{
@@ -1412,12 +1422,14 @@ MedialAxis::build(ThickPolylines* polylines_out)
// Loop through all returned polylines in order to extend their endpoints to the
// expolygon boundaries
- 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 (!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);
+ }
}
//{
// stringstream stri;
diff --git a/xs/src/libslic3r/MedialAxis.hpp b/xs/src/libslic3r/MedialAxis.hpp
index c65cbdb84..560e2bf03 100644
--- a/xs/src/libslic3r/MedialAxis.hpp
+++ b/xs/src/libslic3r/MedialAxis.hpp
@@ -22,6 +22,7 @@ namespace Slic3r {
const double max_width;
const double min_width;
const double height;
+ bool do_not_overextrude = 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) {
};
diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp
index 549ae0a57..eeb60773c 100644
--- a/xs/src/libslic3r/PerimeterGenerator.cpp
+++ b/xs/src/libslic3r/PerimeterGenerator.cpp
@@ -292,13 +292,11 @@ void PerimeterGenerator::process()
for (ExPolygon &bound : bounds) {
if (!intersection_ex(thin[0], bound).empty()) {
//be sure it's not too small to extrude reliably
- ExPolygon simplifiedPolygon = thin[0];
- simplifiedPolygon.remove_point_too_near(SCALED_RESOLUTION);
- if (simplifiedPolygon.area() > min_width*(ext_perimeter_width + ext_perimeter_spacing2)) {
- ExPolygon simplifiedBounds = bound;
- simplifiedBounds.remove_point_too_near(SCALED_RESOLUTION);
+ thin[0].remove_point_too_near(SCALED_RESOLUTION);
+ if (thin[0].area() > min_width*(ext_perimeter_width + ext_perimeter_spacing2)) {
+ 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
- simplifiedPolygon.medial_axis(simplifiedBounds, ext_perimeter_width + ext_perimeter_spacing2, min_width,
+ thin[0].medial_axis(bound, ext_perimeter_width + ext_perimeter_spacing2, min_width,
&thin_walls, this->layer_height);
}
break;