From 7eccc7a758c99bcac741fc33dc5ca3ef50089d53 Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Thu, 10 Mar 2016 16:03:02 -0800 Subject: [PATCH 1/2] Silently drop zero-area polygons instead of showing Clipper errors --- geometry.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/geometry.cc b/geometry.cc index ff4e8a72..eb0b8aea 100644 --- a/geometry.cc +++ b/geometry.cc @@ -241,6 +241,8 @@ static void decode_clipped(ClipperLib::PolyNode *t, drawvec &out) { drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool clip) { ClipperLib::Clipper clipper(ClipperLib::ioStrictlySimple); + bool has_area = false; + for (unsigned i = 0; i < geom.size(); i++) { if (geom[i].op == VT_MOVETO) { unsigned j; @@ -250,6 +252,16 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl } } + double area = 0; + for (unsigned k = i; k < j; k++) { + area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y; + area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x; + } + area = area / 2; + if (area != 0) { + has_area = true; + } + ClipperLib::Path path; drawvec tmp; @@ -297,6 +309,11 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl fprintf(stderr, "Polygon clip failed\n"); } } else { + if (!has_area) { + drawvec out; + return out; + } + if (!clipper.Execute(ClipperLib::ctUnion, clipped)) { fprintf(stderr, "Polygon clean failed\n"); } From 7896c3c2c94afba7680b2fed43876524d2e17cdb Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Thu, 10 Mar 2016 17:07:22 -0800 Subject: [PATCH 2/2] Don't get stuck in a loop if subdividing a complex polygon fails --- geometry.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/geometry.cc b/geometry.cc index eb0b8aea..a3af1ac9 100644 --- a/geometry.cc +++ b/geometry.cc @@ -995,16 +995,29 @@ std::vector chop_polygon(std::vector &geoms) { midx /= count; midy /= count; + drawvec c1, c2; + if (maxy - miny > maxx - minx) { // printf("clipping y to %lld %lld %lld %lld\n", minx, miny, maxx, midy); - out.push_back(simple_clip_poly(geoms[i], minx, miny, maxx, midy)); + c1 = simple_clip_poly(geoms[i], minx, miny, maxx, midy); // printf(" and %lld %lld %lld %lld\n", minx, midy, maxx, maxy); - out.push_back(simple_clip_poly(geoms[i], minx, midy, maxx, maxy)); + c2 = simple_clip_poly(geoms[i], minx, midy, maxx, maxy); } else { // printf("clipping x to %lld %lld %lld %lld\n", minx, miny, midx, maxy); - out.push_back(simple_clip_poly(geoms[i], minx, miny, midx, maxy)); + c1 = simple_clip_poly(geoms[i], minx, miny, midx, maxy); // printf(" and %lld %lld %lld %lld\n", midx, midy, maxx, maxy); - out.push_back(simple_clip_poly(geoms[i], midx, miny, maxx, maxy)); + c2 = simple_clip_poly(geoms[i], midx, miny, maxx, maxy); + } + + if (c1.size() >= geoms[i].size()) { + fprintf(stderr, "Subdividing complex polygon failed\n"); + } else { + out.push_back(c1); + } + if (c2.size() >= geoms[i].size()) { + fprintf(stderr, "Subdividing complex polygon failed\n"); + } else { + out.push_back(c2); } again = true;