void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retval, bool preserve_collinear) { PROFILE_FUNC(); if (!preserve_collinear) { Polygons polygons; simplify_polygons(subject, &polygons, preserve_collinear); union_(polygons, retval); return; } // convert into Clipper polygons ClipperLib::Paths input_subject; Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject); ClipperLib::PolyTree polytree; ClipperLib::Clipper c; c.PreserveCollinear(true); c.StrictlySimple(true); c.AddPaths(input_subject, ClipperLib::ptSubject, true); c.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); // convert into ExPolygons PolyTreeToExPolygons(polytree, retval); }
Polygons Polygon::simplify(double tolerance) const { Polygon p = *this; p.points = MultiPoint::_douglas_peucker(p.points, tolerance); Polygons pp; pp.push_back(p); simplify_polygons(pp, pp); return pp; }
// this only works on CCW polygons as CW will be ripped out by Clipper's simplify_polygons() Polygons Polygon::simplify(double tolerance) const { // repeat first point at the end in order to apply Douglas-Peucker // on the whole polygon Points points = this->points; points.push_back(points.front()); Polygon p(MultiPoint::_douglas_peucker(points, tolerance)); p.points.pop_back(); Polygons pp; pp.push_back(p); simplify_polygons(pp, &pp); return pp; }
ExPolygons simplify_polygons_ex(const Polygons &subject, bool preserve_collinear) { if (! preserve_collinear) return union_ex(simplify_polygons(subject, false)); // convert into Clipper polygons ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject); ClipperLib::PolyTree polytree; ClipperLib::Clipper c; c.PreserveCollinear(true); c.StrictlySimple(true); c.AddPaths(input_subject, ClipperLib::ptSubject, true); c.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); // convert into ExPolygons return PolyTreeToExPolygons(polytree); }