Little refactoring of douglas_peucker()
This commit is contained in:
parent
6d0ceeb886
commit
fd437dcaf5
@ -184,14 +184,14 @@ Polygons ExPolygon::simplify_p(double tolerance) const
|
||||
{
|
||||
Polygon p = this->contour;
|
||||
p.points.push_back(p.points.front());
|
||||
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
|
||||
p.points = MultiPoint::douglas_peucker(p.points, tolerance);
|
||||
p.points.pop_back();
|
||||
pp.emplace_back(std::move(p));
|
||||
}
|
||||
// holes
|
||||
for (Polygon p : this->holes) {
|
||||
p.points.push_back(p.points.front());
|
||||
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
|
||||
p.points = MultiPoint::douglas_peucker(p.points, tolerance);
|
||||
p.points.pop_back();
|
||||
pp.emplace_back(std::move(p));
|
||||
}
|
||||
|
@ -52,15 +52,15 @@ template bool contains(const ExPolygons &vector, const Point &point);
|
||||
|
||||
void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval)
|
||||
{
|
||||
Polygons pp;
|
||||
for (Polygons::const_iterator it = polygons.begin(); it != polygons.end(); ++it) {
|
||||
Polygon p = *it;
|
||||
p.points.push_back(p.points.front());
|
||||
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
|
||||
p.points.pop_back();
|
||||
pp.push_back(p);
|
||||
Polygons simplified_raw;
|
||||
for (const Polygon &source_polygon : polygons) {
|
||||
Points simplified = MultiPoint::douglas_peucker(to_polyline(source_polygon).points, tolerance);
|
||||
if (simplified.size() > 3) {
|
||||
simplified.pop_back();
|
||||
simplified_raw.push_back(Polygon{ std::move(simplified) });
|
||||
}
|
||||
}
|
||||
*retval = Slic3r::simplify_polygons(pp);
|
||||
*retval = Slic3r::simplify_polygons(simplified_raw);
|
||||
}
|
||||
|
||||
double linint(double value, double oldmin, double oldmax, double newmin, double newmax)
|
||||
|
@ -103,7 +103,7 @@ bool MultiPoint::remove_duplicate_points()
|
||||
return false;
|
||||
}
|
||||
|
||||
Points MultiPoint::_douglas_peucker(const Points &pts, const double tolerance)
|
||||
Points MultiPoint::douglas_peucker(const Points &pts, const double tolerance)
|
||||
{
|
||||
Points result_pts;
|
||||
double tolerance_sq = tolerance * tolerance;
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static Points _douglas_peucker(const Points &points, const double tolerance);
|
||||
static Points douglas_peucker(const Points &points, const double tolerance);
|
||||
static Points visivalingam(const Points& pts, const double& tolerance);
|
||||
|
||||
inline auto begin() { return points.begin(); }
|
||||
|
@ -96,7 +96,7 @@ bool Polygon::make_clockwise()
|
||||
void Polygon::douglas_peucker(double tolerance)
|
||||
{
|
||||
this->points.push_back(this->points.front());
|
||||
Points p = MultiPoint::_douglas_peucker(this->points, tolerance);
|
||||
Points p = MultiPoint::douglas_peucker(this->points, tolerance);
|
||||
p.pop_back();
|
||||
this->points = std::move(p);
|
||||
}
|
||||
@ -110,7 +110,7 @@ Polygons Polygon::simplify(double tolerance) const
|
||||
// on the whole polygon
|
||||
Points points = this->points;
|
||||
points.push_back(points.front());
|
||||
Polygon p(MultiPoint::_douglas_peucker(points, tolerance));
|
||||
Polygon p(MultiPoint::douglas_peucker(points, tolerance));
|
||||
p.points.pop_back();
|
||||
|
||||
Polygons pp;
|
||||
@ -577,23 +577,40 @@ void remove_collinear(Polygons &polys)
|
||||
remove_collinear(poly);
|
||||
}
|
||||
|
||||
Polygons polygons_simplify(const Polygons &source_polygons, double tolerance)
|
||||
static inline void simplify_polygon_impl(const Points &points, double tolerance, bool strictly_simple, Polygons &out)
|
||||
{
|
||||
Points simplified = MultiPoint::douglas_peucker(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, strictly_simple)) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
Polygons polygons_simplify(Polygons &&source_polygons, double tolerance, bool strictly_simple /* = true */)
|
||||
{
|
||||
Polygons out;
|
||||
out.reserve(source_polygons.size());
|
||||
for (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),
|
||||
source_polygon.points.emplace_back(source_polygon.points.front());
|
||||
simplify_polygon_impl(source_polygon.points, tolerance, strictly_simple, out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Polygons polygons_simplify(const Polygons &source_polygons, double tolerance, bool strictly_simple /* = true */)
|
||||
{
|
||||
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));
|
||||
}
|
||||
simplify_polygon_impl(to_polyline(source_polygon).points, tolerance, strictly_simple, out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -149,7 +149,8 @@ inline void polygons_append(Polygons &dst, Polygons &&src)
|
||||
}
|
||||
}
|
||||
|
||||
Polygons polygons_simplify(const Polygons &polys, double tolerance);
|
||||
Polygons polygons_simplify(Polygons &&polys, double tolerance, bool strictly_simple = true);
|
||||
Polygons polygons_simplify(const Polygons &polys, double tolerance, bool strictly_simple = true);
|
||||
|
||||
inline void polygons_rotate(Polygons &polys, double angle)
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ Points Polyline::equally_spaced_points(double distance) const
|
||||
|
||||
void Polyline::simplify(double tolerance)
|
||||
{
|
||||
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
|
||||
this->points = MultiPoint::douglas_peucker(this->points, tolerance);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
Loading…
Reference in New Issue
Block a user