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;
|
Polygon p = this->contour;
|
||||||
p.points.push_back(p.points.front());
|
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();
|
p.points.pop_back();
|
||||||
pp.emplace_back(std::move(p));
|
pp.emplace_back(std::move(p));
|
||||||
}
|
}
|
||||||
// holes
|
// holes
|
||||||
for (Polygon p : this->holes) {
|
for (Polygon p : this->holes) {
|
||||||
p.points.push_back(p.points.front());
|
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();
|
p.points.pop_back();
|
||||||
pp.emplace_back(std::move(p));
|
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)
|
void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval)
|
||||||
{
|
{
|
||||||
Polygons pp;
|
Polygons simplified_raw;
|
||||||
for (Polygons::const_iterator it = polygons.begin(); it != polygons.end(); ++it) {
|
for (const Polygon &source_polygon : polygons) {
|
||||||
Polygon p = *it;
|
Points simplified = MultiPoint::douglas_peucker(to_polyline(source_polygon).points, tolerance);
|
||||||
p.points.push_back(p.points.front());
|
if (simplified.size() > 3) {
|
||||||
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
|
simplified.pop_back();
|
||||||
p.points.pop_back();
|
simplified_raw.push_back(Polygon{ std::move(simplified) });
|
||||||
pp.push_back(p);
|
}
|
||||||
}
|
}
|
||||||
*retval = Slic3r::simplify_polygons(pp);
|
*retval = Slic3r::simplify_polygons(simplified_raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
double linint(double value, double oldmin, double oldmax, double newmin, double newmax)
|
double linint(double value, double oldmin, double oldmax, double newmin, double newmax)
|
||||||
|
@ -103,7 +103,7 @@ bool MultiPoint::remove_duplicate_points()
|
|||||||
return false;
|
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;
|
Points result_pts;
|
||||||
double tolerance_sq = tolerance * tolerance;
|
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);
|
static Points visivalingam(const Points& pts, const double& tolerance);
|
||||||
|
|
||||||
inline auto begin() { return points.begin(); }
|
inline auto begin() { return points.begin(); }
|
||||||
|
@ -96,7 +96,7 @@ bool Polygon::make_clockwise()
|
|||||||
void Polygon::douglas_peucker(double tolerance)
|
void Polygon::douglas_peucker(double tolerance)
|
||||||
{
|
{
|
||||||
this->points.push_back(this->points.front());
|
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();
|
p.pop_back();
|
||||||
this->points = std::move(p);
|
this->points = std::move(p);
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ Polygons Polygon::simplify(double tolerance) const
|
|||||||
// on the whole polygon
|
// on the whole polygon
|
||||||
Points points = this->points;
|
Points points = this->points;
|
||||||
points.push_back(points.front());
|
points.push_back(points.front());
|
||||||
Polygon p(MultiPoint::_douglas_peucker(points, tolerance));
|
Polygon p(MultiPoint::douglas_peucker(points, tolerance));
|
||||||
p.points.pop_back();
|
p.points.pop_back();
|
||||||
|
|
||||||
Polygons pp;
|
Polygons pp;
|
||||||
@ -577,23 +577,40 @@ void remove_collinear(Polygons &polys)
|
|||||||
remove_collinear(poly);
|
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;
|
Polygons out;
|
||||||
out.reserve(source_polygons.size());
|
out.reserve(source_polygons.size());
|
||||||
for (const Polygon &source_polygon : source_polygons) {
|
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),
|
// 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);
|
simplify_polygon_impl(to_polyline(source_polygon).points, tolerance, strictly_simple, out);
|
||||||
// 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;
|
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)
|
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)
|
void Polyline::simplify(double tolerance)
|
||||||
{
|
{
|
||||||
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
|
this->points = MultiPoint::douglas_peucker(this->points, tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
Reference in New Issue
Block a user