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:
authorremi durand <remi-j.durand@thalesgroup.com>2022-01-12 10:49:19 +0300
committerremi durand <remi-j.durand@thalesgroup.com>2022-01-12 10:49:19 +0300
commit6e0017ff8fc82ce66e65bcddd2285d48c1b6fb1c (patch)
tree07fa4bca6aa5dfb8fb3dcdeb8c5d691e443247dc /src/libslic3r/BridgeDetector.cpp
parent42db5ca0d12e9a54b8c378dbf8ec12671566a9ec (diff)
parent215e845c31889f92f78e8be1d9ee52f6209a8082 (diff)
Merge remote-tracking branch 'remotes/prusa/master' 2.4 into dev 2.3.58
still need much tests (& bugfixes) and finish some merging things.
Diffstat (limited to 'src/libslic3r/BridgeDetector.cpp')
-rw-r--r--src/libslic3r/BridgeDetector.cpp127
1 files changed, 116 insertions, 11 deletions
diff --git a/src/libslic3r/BridgeDetector.cpp b/src/libslic3r/BridgeDetector.cpp
index dd9c5e5f3..407a8d7ce 100644
--- a/src/libslic3r/BridgeDetector.cpp
+++ b/src/libslic3r/BridgeDetector.cpp
@@ -40,7 +40,7 @@ void BridgeDetector::initialize()
this->angle = -1.;
// Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors.
- Polygons grown = offset(to_polygons(this->expolygons), float(this->spacing));
+ Polygons grown = offset(this->expolygons, float(this->spacing));
// Detect possible anchoring edges of this bridging region.
// Detect what edges lie on lower slices by turning bridge contour and holes
@@ -58,7 +58,7 @@ void BridgeDetector::initialize()
// detect anchors as intersection between our bridge expolygon and the lower slices
// safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some edges
- this->_anchor_regions = intersection_ex(grown, to_polygons(this->lower_slices), true);
+ this->_anchor_regions = intersection_ex(grown, union_safety_offset(this->lower_slices));
/*
if (0) {
@@ -433,8 +433,116 @@ std::vector<BridgeDetector::BridgeDirection> BridgeDetector::bridge_direction_ca
return angles;
}
-Polygons BridgeDetector::coverage(double angle, bool precise) const {
+/*
+static void get_trapezoids(const ExPolygon &expoly, Polygons* polygons) const
+{
+ ExPolygons expp;
+ expp.push_back(expoly);
+ boost::polygon::get_trapezoids(*polygons, expp);
+}
+
+void ExPolygon::get_trapezoids(ExPolygon clone, Polygons* polygons, double angle) const
+{
+ clone.rotate(PI/2 - angle, Point(0,0));
+ clone.get_trapezoids(polygons);
+ for (Polygons::iterator polygon = polygons->begin(); polygon != polygons->end(); ++polygon)
+ polygon->rotate(-(PI/2 - angle), Point(0,0));
+}
+*/
+
+// This algorithm may return more trapezoids than necessary
+// (i.e. it may break a single trapezoid in several because
+// other parts of the object have x coordinates in the middle)
+static void get_trapezoids2(const ExPolygon& expoly, Polygons* polygons)
+{
+ Polygons src_polygons = to_polygons(expoly);
+ // get all points of this ExPolygon
+ const Points pp = to_points(src_polygons);
+
+ // build our bounding box
+ BoundingBox bb(pp);
+
+ // get all x coordinates
+ std::vector<coord_t> xx;
+ xx.reserve(pp.size());
+ for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p)
+ xx.push_back(p->x());
+ std::sort(xx.begin(), xx.end());
+
+ // find trapezoids by looping from first to next-to-last coordinate
+ Polygons rectangle;
+ rectangle.emplace_back(Polygon());
+ for (std::vector<coord_t>::const_iterator x = xx.begin(); x != xx.end()-1; ++x) {
+ coord_t next_x = *(x + 1);
+ if (*x != next_x) {
+ // intersect with rectangle
+ // append results to return value
+ rectangle.front() = { { *x, bb.min.y() }, { next_x, bb.min.y() }, { next_x, bb.max.y() }, { *x, bb.max.y() } };
+ polygons_append(*polygons, intersection(rectangle, src_polygons));
+ }
+ }
+}
+
+static void get_trapezoids2(const ExPolygon &expoly, Polygons* polygons, double angle)
+{
+ ExPolygon clone = expoly;
+ clone.rotate(PI/2 - angle, Point(0,0));
+ get_trapezoids2(clone, polygons);
+ for (Polygon &polygon : *polygons)
+ polygon.rotate(-(PI/2 - angle), Point(0,0));
+}
+
+
+void get_trapezoids3_half(const ExPolygon& expoly, Polygons* polygons, float spacing)
+{
+
+ // get all points of this ExPolygon
+ Points pp = expoly;
+
+ if (pp.empty()) return;
+
+ // build our bounding box
+ BoundingBox bb(pp);
+
+ // get all x coordinates
+ coord_t min_x = pp[0].x(), max_x = pp[0].x();
+ std::vector<coord_t> xx;
+ for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p) {
+ if (min_x > p->x()) min_x = p->x();
+ if (max_x < p->x()) max_x = p->x();
+ }
+ for (coord_t x = min_x; x < max_x - (coord_t)(spacing / 2); x += (coord_t)spacing) {
+ xx.push_back(x);
+ }
+ xx.push_back(max_x);
+ //std::sort(xx.begin(), xx.end());
+
+ // find trapezoids by looping from first to next-to-last coordinate
+ for (std::vector<coord_t>::const_iterator x = xx.begin(); x != xx.end() - 1; ++x) {
+ coord_t next_x = *(x + 1);
+ if (*x == next_x) continue;
+
+ // build rectangle
+ Polygon poly;
+ poly.points.resize(4);
+ poly[0].x() = *x + (coord_t)spacing / 4;
+ poly[0].y() = bb.min(1);
+ poly[1].x() = next_x - (coord_t)spacing / 4;
+ poly[1].y() = bb.min(1);
+ poly[2].x() = next_x - (coord_t)spacing / 4;
+ poly[2].y() = bb.max(1);
+ poly[3].x() = *x + (coord_t)spacing / 4;
+ poly[3].y() = bb.max(1);
+
+ // intersect with this expolygon
+ // append results to return value
+ polygons_append(*polygons, intersection(Polygons{ poly }, to_polygons(expoly)));
+ }
+}
+
+Polygons BridgeDetector::coverage(double angle, bool precise) const
+{
if (angle == -1)
angle = this->angle;
@@ -457,8 +565,8 @@ Polygons BridgeDetector::coverage(double angle, bool precise) const {
for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * float(this->spacing))) {
// Compute trapezoids according to a vertical orientation
Polygons trapezoids;
- if (!precise) expoly.get_trapezoids2(&trapezoids, PI / 2);
- else expoly.get_trapezoids3_half(&trapezoids, float(this->spacing));
+ if (!precise) get_trapezoids2(expoly, &trapezoids, PI / 2);
+ else get_trapezoids3_half(expoly, &trapezoids, float(this->spacing));
for (Polygon &trapezoid : trapezoids) {
size_t n_supported = 0;
if (!precise) {
@@ -511,7 +619,7 @@ Polygons BridgeDetector::coverage(double angle, bool precise) const {
covered = union_(covered);
// Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
polygons_rotate(covered, -(PI/2.0 - angle));
- //covered = intersection(covered, to_polygons(this->expolygons));
+ //covered = intersection(this->expolygons, covered);
#if 0
{
my @lines = map @{$_->lines}, @$trapezoids;
@@ -534,8 +642,7 @@ Polygons BridgeDetector::coverage(double angle, bool precise) const {
/* This method returns the bridge edges (as polylines) that are not supported
but would allow the entire bridge area to be bridged with detected angle
if supported too */
-void
-BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
+void BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
{
if (angle == -1) angle = this->angle;
if (angle == -1) return;
@@ -575,9 +682,7 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
*/
}
-Polylines
-BridgeDetector::unsupported_edges(double angle) const
-{
+Polylines BridgeDetector::unsupported_edges(double angle) const {
Polylines pp;
this->unsupported_edges(angle, &pp);
return pp;