Bugfix: spAligned didn't always work in multi-island layers. #3458

This commit is contained in:
Alessandro Ranellucci 2017-05-01 17:25:48 +02:00
parent 90de54f2fc
commit 1806664686
2 changed files with 26 additions and 24 deletions

View File

@ -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 // restore original winding order so that concave and convex detection always happens
// on the right/outer side of the polygon // on the right/outer side of the polygon
if (was_clockwise) { if (was_clockwise)
for (Polygons::iterator p = simplified.begin(); p != simplified.end(); ++p) for (Polygon &p : simplified)
p->reverse(); p.reverse();
}
// concave vertices have priority // concave vertices have priority
Points candidates; Points candidates;
for (Polygons::const_iterator p = simplified.begin(); p != simplified.end(); ++p) { for (const Polygon &p : simplified)
Points concave = p->concave_points(PI*4/3); append_to(candidates, p.concave_points(PI*4/3));
candidates.insert(candidates.end(), concave.begin(), concave.end());
}
// if no concave points were found, look for convex vertices // if no concave points were found, look for convex vertices
if (candidates.empty()) { if (candidates.empty())
for (Polygons::const_iterator p = simplified.begin(); p != simplified.end(); ++p) { for (const Polygon &p : simplified)
Points convex = p->convex_points(PI*2/3); append_to(candidates, p.convex_points(PI*2/3));
candidates.insert(candidates.end(), convex.begin(), convex.end());
}
}
// retrieve the last start position for this object // retrieve the last start position for this object
if (this->layer != NULL) { 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); if (!loop.split_at_vertex(point)) loop.split_at(point);
} else if (!candidates.empty()) { } else if (!candidates.empty()) {
Points non_overhang; Points non_overhang;
for (Points::const_iterator p = candidates.begin(); p != candidates.end(); ++p) { for (const Point &p : candidates)
if (!loop.has_overhang_point(*p)) if (!loop.has_overhang_point(p))
non_overhang.push_back(*p); non_overhang.push_back(p);
}
if (!non_overhang.empty()) if (!non_overhang.empty())
candidates = non_overhang; candidates = non_overhang;
@ -389,8 +382,15 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
point = last_pos.projection_onto(polygon); point = last_pos.projection_onto(polygon);
loop.split_at(point); 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; this->_seam_position[this->layer->object()] = point;
}
} else if (seam_position == spRandom) { } else if (seam_position == spRandom) {
if (loop.role == elrContourInternalPerimeter) { if (loop.role == elrContourInternalPerimeter) {
Polygon polygon = loop.polygon(); Polygon polygon = loop.polygon();

View File

@ -98,19 +98,21 @@ Layer::make_slices()
this->slices.expolygons.reserve(slices.size()); this->slices.expolygons.reserve(slices.size());
// prepare ordering points // 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; Points ordering_points;
ordering_points.reserve(slices.size()); ordering_points.reserve(slices.size());
for (ExPolygons::const_iterator ex = slices.begin(); ex != slices.end(); ++ex) for (const ExPolygon &ex : slices)
ordering_points.push_back(ex->contour.first_point()); ordering_points.push_back(ex.contour.centroid());
// sort slices // sort slices
std::vector<Points::size_type> order; std::vector<Points::size_type> order;
Slic3r::Geometry::chained_path(ordering_points, order); Slic3r::Geometry::chained_path(ordering_points, order);
// populate slices vector // populate slices vector
for (std::vector<Points::size_type>::const_iterator it = order.begin(); it != order.end(); ++it) { for (const Points::size_type &o : order)
this->slices.expolygons.push_back(slices[*it]); this->slices.expolygons.push_back(slices[o]);
}
} }
void void