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
path: root/src
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2021-11-01 22:30:14 +0300
committersupermerill <merill@free.fr>2021-11-06 15:48:34 +0300
commit703e26bc6d51b2c3534780a93978de6ef3bf1670 (patch)
treef446618b4f8d101d97ea1562e56dc76d99833551 /src
parentd4fe1e573d76dfd5d8befe7e60a928624e7f6812 (diff)
Better bridge direction when only one anchor area
Diffstat (limited to 'src')
-rw-r--r--src/libslic3r/BridgeDetector.cpp101
-rw-r--r--src/libslic3r/BridgeDetector.hpp2
2 files changed, 87 insertions, 16 deletions
diff --git a/src/libslic3r/BridgeDetector.cpp b/src/libslic3r/BridgeDetector.cpp
index 9dcde4c0e..7b33a6dd5 100644
--- a/src/libslic3r/BridgeDetector.cpp
+++ b/src/libslic3r/BridgeDetector.cpp
@@ -97,22 +97,21 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
for (size_t i_angle = 0; i_angle < candidates.size(); ++ i_angle)
{
const double angle = candidates[i_angle].angle;
-
Lines lines;
{
// Get an oriented bounding box around _anchor_regions.
BoundingBox bbox = get_extents_rotated(this->_anchor_regions, - angle);
// Cover the region with line segments.
- lines.reserve((bbox.max(1) - bbox.min(1) + this->spacing) / this->spacing);
+ lines.reserve((bbox.max.y() - bbox.min.y() + this->spacing - SCALED_EPSILON) / this->spacing);
double s = sin(angle);
double c = cos(angle);
- //FIXME Vojtech: The lines shall be spaced half the line width from the edge, but then
- // some of the test cases fail. Need to adjust the test cases then?
-// for (coord_t y = bbox.min(1) + this->spacing / 2; y <= bbox.max(1); y += this->spacing)
- for (coord_t y = bbox.min(1); y <= bbox.max(1); y += this->spacing)
+ // As The lines be spaced half the line width from the edge
+ // FIXME: some of the test cases may fail. Need to adjust the test cases
+ for (coord_t y = bbox.min.y() + this->spacing / 2; y <= bbox.max.y(); y += this->spacing)
+ //for (coord_t y = bbox.min.y(); y <= bbox.max.y(); y += this->spacing) //this is the old version
lines.push_back(Line(
- Point((coord_t)round(c * bbox.min(0) - s * y), (coord_t)round(c * y + s * bbox.min(0))),
- Point((coord_t)round(c * bbox.max(0) - s * y), (coord_t)round(c * y + s * bbox.max(0)))));
+ Point((coord_t)round(c * bbox.min.x() - s * y), (coord_t)round(c * y + s * bbox.min.x())),
+ Point((coord_t)round(c * bbox.max.x() - s * y), (coord_t)round(c * y + s * bbox.max.x()))));
}
//compute stat on line with anchors, and their lengths.
@@ -122,7 +121,13 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
Lines clipped_lines = intersection_ln(lines, clip_area);
for (size_t i = 0; i < clipped_lines.size(); ++i) {
const Line &line = clipped_lines[i];
+ bool good_line = false;
if (expolygons_contain(this->_anchor_regions, line.a) && expolygons_contain(this->_anchor_regions, line.b)) {
+ //check that it isn't always inside
+ Lines lines = intersection_ln(line, to_polygons(this->_anchor_regions));
+ good_line = lines.size() > 1;
+ }
+ if(good_line) {
// This line could be anchored.
coordf_t len = line.length();
//store stats
@@ -154,11 +159,76 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
}
}
+ // if no direction produced coverage, then there's no bridge direction ?
+ if (!have_coverage) {
+ //try again to choose the least worse
+ // use only poly contour angles
+ if (bridge_direction_override == 0.) {
+ candidates = bridge_direction_candidates(true);
+ } else
+ candidates.emplace_back(BridgeDirection(bridge_direction_override));
+ for (size_t i_angle = 0; i_angle < candidates.size(); ++i_angle)
+ {
+ const double angle = candidates[i_angle].angle;
+ //use the whole polygon
+ Lines lines;
+ {
+ // Get an oriented bounding box around _anchor_regions.
+ BoundingBox bbox = get_extents_rotated(clip_area, -angle);
+ // Cover the region with line segments.
+ lines.reserve((bbox.max.y() - bbox.min.y() + this->spacing - SCALED_EPSILON) / this->spacing);
+ double s = sin(angle);
+ double c = cos(angle);
+ // The lines be spaced half the line width from the edge
+ for (coord_t y = bbox.min.y() + this->spacing / 2; y <= bbox.max.y(); y += this->spacing)
+ lines.push_back(Line(
+ Point((coord_t)round(c * bbox.min.x() - s * y), (coord_t)round(c * y + s * bbox.min.x())),
+ Point((coord_t)round(c * bbox.max.x() - s * y), (coord_t)round(c * y + s * bbox.max.x()))));
+ }
+ //compute stat on line with anchors, and their lengths.
+ BridgeDirection& c = candidates[i_angle];
+ std::vector<coordf_t> dist_anchored;
+ {
+ Lines clipped_lines = intersection_ln(lines, clip_area);
+ for (size_t i = 0; i < clipped_lines.size(); ++i) {
+ const Line& line = clipped_lines[i];
+ if (expolygons_contain(this->_anchor_regions, line.a) || expolygons_contain(this->_anchor_regions, line.b)) {
+ // This line has one anchor
+ coordf_t len = line.length();
+ //store stats
+ c.total_length_anchored += len;
+ c.max_length_anchored = std::max(c.max_length_anchored, len);
+ c.nb_lines_anchored++;
+ dist_anchored.push_back(len);
+ } else {
+ // this line could NOT be anchored.
+ coordf_t len = line.length();
+ c.total_length_free += len;
+ c.max_length_free = std::max(c.max_length_free, len);
+ c.nb_lines_free++;
+ }
+ }
+ }
+ if (c.total_length_anchored == 0. || c.nb_lines_anchored == 0) {
+ continue;
+ } else {
+ have_coverage = true;
+ // compute median
+ if (!dist_anchored.empty()) {
+ std::sort(dist_anchored.begin(), dist_anchored.end());
+ c.median_length_anchor = dist_anchored[dist_anchored.size() / 2];
+ }
+
+
+ // size is 20%
+ }
+ }
+ }
+
// if no direction produced coverage, then there's no bridge direction
- if (! have_coverage)
+ if (!have_coverage)
return false;
-
//compute global stat (max & min median & max length)
std::vector<coordf_t> all_median_length;
std::vector<coordf_t> all_max_length;
@@ -189,7 +259,7 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
c.coverage += 15 * ratio_max;
//bonus for perimeter dir
if (c.along_perimeter)
- c.coverage += 0.05;
+ c.coverage += 5;
}
@@ -212,12 +282,13 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
return true;
}
-std::vector<BridgeDetector::BridgeDirection> BridgeDetector::bridge_direction_candidates() const
+std::vector<BridgeDetector::BridgeDirection> BridgeDetector::bridge_direction_candidates(bool only_from_polygon) const
{
- // we test angles according to configured resolution
std::vector<BridgeDirection> angles;
- for (int i = 0; i <= PI/this->resolution; ++i)
- angles.emplace_back(i * this->resolution);
+ // we test angles according to configured resolution
+ if (!only_from_polygon)
+ for (int i = 0; i <= PI/this->resolution; ++i)
+ angles.emplace_back(i * this->resolution);
// we also test angles of each bridge contour
{
diff --git a/src/libslic3r/BridgeDetector.hpp b/src/libslic3r/BridgeDetector.hpp
index af7ccb8ee..9a81aa06f 100644
--- a/src/libslic3r/BridgeDetector.hpp
+++ b/src/libslic3r/BridgeDetector.hpp
@@ -63,7 +63,7 @@ private:
};
public:
// Get possible briging direction candidates.
- std::vector<BridgeDirection> bridge_direction_candidates() const;
+ std::vector<BridgeDirection> bridge_direction_candidates(bool only_from_polygon = false) const;
// Open lines representing the supporting edges.
Polylines _edges;