mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 20:19:03 +08:00
Fix bridge detector
Reduce the number of angle to choose from If two angle are too close, keep the one from the longest line. supermerill/SuperSlicer#1824
This commit is contained in:
parent
bf3b9acec8
commit
65bb95cd81
@ -258,7 +258,7 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
|
|||||||
double ratio_max = 1 - double(c.max_length_anchored - min_max_length) / (double)std::max(1., max_max_length - min_max_length);
|
double ratio_max = 1 - double(c.max_length_anchored - min_max_length) / (double)std::max(1., max_max_length - min_max_length);
|
||||||
c.coverage += 15 * ratio_max;
|
c.coverage += 15 * ratio_max;
|
||||||
//bonus for perimeter dir
|
//bonus for perimeter dir
|
||||||
if (c.along_perimeter)
|
if (c.along_perimeter_length > 0)
|
||||||
c.coverage += 5;
|
c.coverage += 5;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -293,8 +293,21 @@ std::vector<BridgeDetector::BridgeDirection> BridgeDetector::bridge_direction_ca
|
|||||||
// we also test angles of each bridge contour
|
// we also test angles of each bridge contour
|
||||||
{
|
{
|
||||||
Lines lines = to_lines(this->expolygons);
|
Lines lines = to_lines(this->expolygons);
|
||||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line)
|
//if many lines, only takes the bigger ones.
|
||||||
angles.emplace_back(line->direction(), true);
|
float mean_sqr_size = 0;
|
||||||
|
if (lines.size() > 200) {
|
||||||
|
for (int i = 0; i < 200; i++) {
|
||||||
|
mean_sqr_size += (float)lines[i].a.distance_to_square(lines[i].b);
|
||||||
|
}
|
||||||
|
mean_sqr_size /= 200;
|
||||||
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
|
float dist_sqr = line->a.distance_to_square(line->b);
|
||||||
|
if (dist_sqr > mean_sqr_size)
|
||||||
|
angles.emplace_back(line->direction(), dist_sqr);
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line)
|
||||||
|
angles.emplace_back(line->direction(), line->a.distance_to_square(line->b));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we also test angles of each open supporting edge
|
/* we also test angles of each open supporting edge
|
||||||
@ -304,12 +317,51 @@ std::vector<BridgeDetector::BridgeDirection> BridgeDetector::bridge_direction_ca
|
|||||||
angles.emplace_back(Line(edge.first_point(), edge.last_point()).direction());
|
angles.emplace_back(Line(edge.first_point(), edge.last_point()).direction());
|
||||||
|
|
||||||
// remove duplicates
|
// remove duplicates
|
||||||
double min_resolution = PI/(4*180.0); // /180 = 1 degree
|
std::sort(angles.begin(), angles.end(), [](const BridgeDirection& bt1, const BridgeDirection& bt2) { return bt1.angle < bt2.angle; });
|
||||||
std::sort(angles.begin(), angles.end());
|
|
||||||
|
//first delete angles too close to an angle from a perimeter
|
||||||
for (size_t i = 1; i < angles.size(); ++i) {
|
for (size_t i = 1; i < angles.size(); ++i) {
|
||||||
if (Slic3r::Geometry::directions_parallel(angles[i].angle, angles[i-1].angle, min_resolution)) {
|
if (angles[i - 1].along_perimeter_length > 0 && angles[i].along_perimeter_length == 0)
|
||||||
angles.erase(angles.begin() + i);
|
if (Slic3r::Geometry::directions_parallel(angles[i].angle, angles[i - 1].angle, this->resolution)) {
|
||||||
--i;
|
angles.erase(angles.begin() + i);
|
||||||
|
--i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (angles[i].along_perimeter_length > 0 && angles[i - 1].along_perimeter_length == 0)
|
||||||
|
if (Slic3r::Geometry::directions_parallel(angles[i].angle, angles[i - 1].angle, this->resolution)) {
|
||||||
|
angles.erase(angles.begin() + (i-1));
|
||||||
|
--i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//then delete angle to close to each other (high resolution)
|
||||||
|
double min_resolution = this->resolution / 8;
|
||||||
|
for (size_t i = 1; i < angles.size(); ++i) {
|
||||||
|
if (Slic3r::Geometry::directions_parallel(angles[i].angle, angles[i - 1].angle, min_resolution)) {
|
||||||
|
// keep the longest of the two.
|
||||||
|
if (angles[i].along_perimeter_length < angles[i - 1].along_perimeter_length) {
|
||||||
|
angles.erase(angles.begin() + i);
|
||||||
|
--i;
|
||||||
|
} else {
|
||||||
|
angles.erase(angles.begin() + (i-1));
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//then, if too much angles, delete more
|
||||||
|
while (angles.size() > 200) {
|
||||||
|
min_resolution *= 2;
|
||||||
|
for (size_t i = 1; i < angles.size(); ++i) {
|
||||||
|
if (Slic3r::Geometry::directions_parallel(angles[i].angle, angles[i - 1].angle, min_resolution)) {
|
||||||
|
// keep the longest of the two.
|
||||||
|
if (angles[i].along_perimeter_length < angles[i - 1].along_perimeter_length) {
|
||||||
|
angles.erase(angles.begin() + i);
|
||||||
|
--i;
|
||||||
|
} else {
|
||||||
|
angles.erase(angles.begin() + (i - 1));
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* compare first value with last one and remove the greatest one (PI)
|
/* compare first value with last one and remove the greatest one (PI)
|
||||||
|
@ -43,16 +43,12 @@ private:
|
|||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
struct BridgeDirection {
|
struct BridgeDirection {
|
||||||
BridgeDirection(double a = -1., bool along_perimeter = false) : angle(a), coverage(0.), along_perimeter(along_perimeter){}
|
BridgeDirection(double a = -1., float along_perimeter = 0) : angle(a), coverage(0.), along_perimeter_length(along_perimeter){}
|
||||||
// the best direction is the one causing most lines to be bridged (thus most coverage)
|
|
||||||
bool operator<(const BridgeDirection &other) const {
|
|
||||||
// Initial sort by coverage only - comparator must obey strict weak ordering
|
|
||||||
return this->coverage > other.coverage;
|
|
||||||
};
|
|
||||||
double angle;
|
double angle;
|
||||||
double coverage;
|
double coverage;
|
||||||
|
|
||||||
bool along_perimeter;
|
float along_perimeter_length;
|
||||||
coordf_t total_length_anchored = 0;
|
coordf_t total_length_anchored = 0;
|
||||||
coordf_t median_length_anchor = 0;
|
coordf_t median_length_anchor = 0;
|
||||||
coordf_t max_length_anchored = 0;
|
coordf_t max_length_anchored = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user