toPolygon2D() now use Clipper's cleaning algorithm

The old polygon simplification algorithm in toPolygon2D() was broken.
It could create self-intersecting paths which made CGAL barf and
resulted in non-manifold meshes. It has been replaced with the one
built into Clipper. I am not sure Clipper's is guaranteed to be
correct either, but it at least seems to have fewer fail cases.
text-module
Oskar Linde 2014-01-28 19:31:20 +01:00
parent 9a66954003
commit 1942205585
1 changed files with 14 additions and 8 deletions

View File

@ -42,20 +42,26 @@ namespace ClipperUtils {
path before adding it to the Polygon2d.
*/
Polygon2d *toPolygon2d(const ClipperLib::PolyTree &poly) {
const double CLEANING_DISTANCE = 0.001 * CLIPPER_SCALE;
Polygon2d *result = new Polygon2d;
const ClipperLib::PolyNode *node = poly.GetFirst();
while (node) {
Outline2d outline;
outline.positive = !node->IsHole();
const Vector2d *lastv = NULL;
BOOST_FOREACH(const ClipperLib::IntPoint &ip, node->Contour) {
Vector2d v(1.0*ip.X/CLIPPER_SCALE, 1.0*ip.Y/CLIPPER_SCALE);
// Ignore too close vertices. This is to be nice to subsequent processes.
if (lastv && (v-*lastv).squaredNorm() < 0.001) continue;
outline.vertices.push_back(v);
lastv = &outline.vertices.back();
ClipperLib::Path cleaned_path;
ClipperLib::CleanPolygon(node->Contour, cleaned_path, CLEANING_DISTANCE);
// CleanPolygon can in some cases reduce the polygon down to no vertices
if (cleaned_path.size() >= 3) {
BOOST_FOREACH(const ClipperLib::IntPoint &ip, cleaned_path) {
Vector2d v(1.0*ip.X/CLIPPER_SCALE, 1.0*ip.Y/CLIPPER_SCALE);
outline.vertices.push_back(v);
}
result->addOutline(outline);
}
result->addOutline(outline);
node = node->GetNext();
}
result->setSanitized(true);