mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 13:05:57 +08:00
Bugfix: spAligned didn't always work in multi-island layers. #3458
This commit is contained in:
parent
90de54f2fc
commit
1806664686
@ -334,25 +334,19 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
|
||||
|
||||
// restore original winding order so that concave and convex detection always happens
|
||||
// on the right/outer side of the polygon
|
||||
if (was_clockwise) {
|
||||
for (Polygons::iterator p = simplified.begin(); p != simplified.end(); ++p)
|
||||
p->reverse();
|
||||
}
|
||||
if (was_clockwise)
|
||||
for (Polygon &p : simplified)
|
||||
p.reverse();
|
||||
|
||||
// concave vertices have priority
|
||||
Points candidates;
|
||||
for (Polygons::const_iterator p = simplified.begin(); p != simplified.end(); ++p) {
|
||||
Points concave = p->concave_points(PI*4/3);
|
||||
candidates.insert(candidates.end(), concave.begin(), concave.end());
|
||||
}
|
||||
for (const Polygon &p : simplified)
|
||||
append_to(candidates, p.concave_points(PI*4/3));
|
||||
|
||||
// if no concave points were found, look for convex vertices
|
||||
if (candidates.empty()) {
|
||||
for (Polygons::const_iterator p = simplified.begin(); p != simplified.end(); ++p) {
|
||||
Points convex = p->convex_points(PI*2/3);
|
||||
candidates.insert(candidates.end(), convex.begin(), convex.end());
|
||||
}
|
||||
}
|
||||
if (candidates.empty())
|
||||
for (const Polygon &p : simplified)
|
||||
append_to(candidates, p.convex_points(PI*2/3));
|
||||
|
||||
// retrieve the last start position for this object
|
||||
if (this->layer != NULL) {
|
||||
@ -375,10 +369,9 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
|
||||
if (!loop.split_at_vertex(point)) loop.split_at(point);
|
||||
} else if (!candidates.empty()) {
|
||||
Points non_overhang;
|
||||
for (Points::const_iterator p = candidates.begin(); p != candidates.end(); ++p) {
|
||||
if (!loop.has_overhang_point(*p))
|
||||
non_overhang.push_back(*p);
|
||||
}
|
||||
for (const Point &p : candidates)
|
||||
if (!loop.has_overhang_point(p))
|
||||
non_overhang.push_back(p);
|
||||
|
||||
if (!non_overhang.empty())
|
||||
candidates = non_overhang;
|
||||
@ -389,8 +382,15 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
|
||||
point = last_pos.projection_onto(polygon);
|
||||
loop.split_at(point);
|
||||
}
|
||||
if (this->layer != NULL)
|
||||
if (this->layer != NULL) {
|
||||
/* Keeping a single starting point for each object works best with objects
|
||||
having a single island. In the other cases, this works when layers are
|
||||
similar, so the algorithm picks the same chain of points. But when an
|
||||
island disappears, the others might suffer from a starting point change
|
||||
even if their shape didn't change. We should probably keep multiple
|
||||
starting points for each layer and test all of them. */
|
||||
this->_seam_position[this->layer->object()] = point;
|
||||
}
|
||||
} else if (seam_position == spRandom) {
|
||||
if (loop.role == elrContourInternalPerimeter) {
|
||||
Polygon polygon = loop.polygon();
|
||||
|
@ -98,19 +98,21 @@ Layer::make_slices()
|
||||
this->slices.expolygons.reserve(slices.size());
|
||||
|
||||
// prepare ordering points
|
||||
// While it's more computationally expensive, we use centroid()
|
||||
// instead of first_point() because it's [much more] deterministic
|
||||
// and preserves ordering across similar layers.
|
||||
Points ordering_points;
|
||||
ordering_points.reserve(slices.size());
|
||||
for (ExPolygons::const_iterator ex = slices.begin(); ex != slices.end(); ++ex)
|
||||
ordering_points.push_back(ex->contour.first_point());
|
||||
for (const ExPolygon &ex : slices)
|
||||
ordering_points.push_back(ex.contour.centroid());
|
||||
|
||||
// sort slices
|
||||
std::vector<Points::size_type> order;
|
||||
Slic3r::Geometry::chained_path(ordering_points, order);
|
||||
|
||||
// populate slices vector
|
||||
for (std::vector<Points::size_type>::const_iterator it = order.begin(); it != order.end(); ++it) {
|
||||
this->slices.expolygons.push_back(slices[*it]);
|
||||
}
|
||||
for (const Points::size_type &o : order)
|
||||
this->slices.expolygons.push_back(slices[o]);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user