From 546e16a00246c57ccf8a560d3d93ee06e911f0e2 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 28 Oct 2022 10:05:04 -0700 Subject: [PATCH] Add multi-level fallback in tesselation Some clipper cases do not get resolved with the `FAST` mode, so in those cases, do a second pass in the `SIMPLE` mode. If both fail, return a broken polygon instead of an infinite loop Fixes https://gitlab.com/kicad/code/kicad/issues/12761 --- libs/kimath/src/geometry/shape_poly_set.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/kimath/src/geometry/shape_poly_set.cpp b/libs/kimath/src/geometry/shape_poly_set.cpp index 9a4cbfa491..b6628ea871 100644 --- a/libs/kimath/src/geometry/shape_poly_set.cpp +++ b/libs/kimath/src/geometry/shape_poly_set.cpp @@ -2695,6 +2695,7 @@ void SHAPE_POLY_SET::CacheTriangulation( bool aPartition ) std::vector>& dest ) { bool triangulationValid = false; + int pass = 0; while( polySet.OutlineCount() > 0 ) { @@ -2709,7 +2710,15 @@ void SHAPE_POLY_SET::CacheTriangulation( bool aPartition ) // This may result in multiple, disjoint polygons. if( !tess.TesselatePolygon( polySet.Polygon( 0 ).front() ) ) { - polySet.Fracture( PM_FAST ); + ++pass; + + if( pass == 1 ) + polySet.Fracture( PM_FAST ); + else if( pass == 2 ) + polySet.Fracture( PM_STRICTLY_SIMPLE ); + else + break; + triangulationValid = false; continue; }