Fixed polygons_simplify() to correctly handle holes.
This fixes some missing tree / organic supports in the middle of an object surrounded by walls all around.
This commit is contained in:
parent
a98467f661
commit
da00cedc84
3 changed files with 42 additions and 29 deletions
|
@ -99,9 +99,11 @@ void Polygon::douglas_peucker(double tolerance)
|
|||
this->points = std::move(p);
|
||||
}
|
||||
|
||||
// this only works on CCW polygons as CW will be ripped out by Clipper's simplify_polygons()
|
||||
Polygons Polygon::simplify(double tolerance) const
|
||||
{
|
||||
// Works on CCW polygons only, CW contour will be reoriented to CCW by Clipper's simplify_polygons()!
|
||||
assert(this->is_counter_clockwise());
|
||||
|
||||
// repeat first point at the end in order to apply Douglas-Peucker
|
||||
// on the whole polygon
|
||||
Points points = this->points;
|
||||
|
@ -114,13 +116,6 @@ Polygons Polygon::simplify(double tolerance) const
|
|||
return simplify_polygons(pp);
|
||||
}
|
||||
|
||||
void Polygon::simplify(double tolerance, Polygons &polygons) const
|
||||
{
|
||||
Polygons pp = this->simplify(tolerance);
|
||||
polygons.reserve(polygons.size() + pp.size());
|
||||
polygons.insert(polygons.end(), pp.begin(), pp.end());
|
||||
}
|
||||
|
||||
// Only call this on convex polygons or it will return invalid results
|
||||
void Polygon::triangulate_convex(Polygons* polygons) const
|
||||
{
|
||||
|
@ -562,6 +557,27 @@ void remove_collinear(Polygons &polys)
|
|||
remove_collinear(poly);
|
||||
}
|
||||
|
||||
Polygons polygons_simplify(const Polygons &source_polygons, double tolerance)
|
||||
{
|
||||
Polygons out;
|
||||
out.reserve(source_polygons.size());
|
||||
for (const Polygon &source_polygon : source_polygons) {
|
||||
// Run Douglas / Peucker simplification algorithm on an open polyline (by repeating the first point at the end of the polyline),
|
||||
Points simplified = MultiPoint::_douglas_peucker(to_polyline(source_polygon).points, tolerance);
|
||||
// then remove the last (repeated) point.
|
||||
simplified.pop_back();
|
||||
// Simplify the decimated contour by ClipperLib.
|
||||
bool ccw = ClipperLib::Area(simplified) > 0.;
|
||||
for (Points &path : ClipperLib::SimplifyPolygons(ClipperUtils::SinglePathProvider(simplified), ClipperLib::pftNonZero)) {
|
||||
if (! ccw)
|
||||
// ClipperLib likely reoriented negative area contours to become positive. Reverse holes back to CW.
|
||||
std::reverse(path.begin(), path.end());
|
||||
out.emplace_back(std::move(path));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Do polygons match? If they match, they must have the same topology,
|
||||
// however their contours may be rotated.
|
||||
bool polygons_match(const Polygon &l, const Polygon &r)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue