@@ -282,6 +282,21 @@ static QgsPolygon *_transform_polygon_to_new_base( const QgsPolygon &polygon, co
282
282
283
283
static bool _check_intersecting_rings ( const QgsPolygon &polygon )
284
284
{
285
+ QList<QgsGeometry> geomRings;
286
+ geomRings << QgsGeometry ( polygon.exteriorRing ()->clone () );
287
+ for ( int i = 0 ; i < polygon.numInteriorRings (); ++i )
288
+ geomRings << QgsGeometry ( polygon.interiorRing ( i )->clone () );
289
+
290
+ // we need to make sure that the polygon has no rings with self-intersection: that may
291
+ // crash the tessellator. The original geometry maybe have been valid and the self-intersection
292
+ // was introduced when transforming to a new base (in a rare case when all points are not in the same plane)
293
+
294
+ for ( int i = 0 ; i < geomRings.count (); ++i )
295
+ {
296
+ if ( !geomRings[i].isSimple () )
297
+ return false ;
298
+ }
299
+
285
300
// At this point we assume that input polygons are valid according to the OGC definition.
286
301
// This means e.g. no duplicate points, polygons are simple (no butterfly shaped polygon with self-intersection),
287
302
// internal rings are inside exterior rings, rings do not cross each other, no dangles.
@@ -301,11 +316,6 @@ static bool _check_intersecting_rings( const QgsPolygon &polygon )
301
316
302
317
if ( polygon.numInteriorRings () > 0 )
303
318
{
304
- QList<QgsGeometry> geomRings;
305
- geomRings << QgsGeometry ( polygon.exteriorRing ()->clone () );
306
- for ( int i = 0 ; i < polygon.numInteriorRings (); ++i )
307
- geomRings << QgsGeometry ( polygon.interiorRing ( i )->clone () );
308
-
309
319
for ( int i = 0 ; i < geomRings.count (); ++i )
310
320
for ( int j = i + 1 ; j < geomRings.count (); ++j )
311
321
{
@@ -417,7 +427,7 @@ void QgsTessellator::addPolygon( const QgsPolygon &polygon, float extrusionHeigh
417
427
if ( !_check_intersecting_rings ( *polygonNew.get () ) )
418
428
{
419
429
// skip the polygon - it would cause a crash inside poly2tri library
420
- QgsMessageLog::logMessage ( QObject::tr ( " polygon rings intersect each other - skipping" ), QObject::tr ( " 3D" ) );
430
+ QgsMessageLog::logMessage ( QObject::tr ( " polygon rings self-intersect or intersect each other - skipping" ), QObject::tr ( " 3D" ) );
421
431
return ;
422
432
}
423
433
0 commit comments