@@ -282,6 +282,21 @@ static QgsPolygon *_transform_polygon_to_new_base( const QgsPolygon &polygon, co
282282
283283static bool _check_intersecting_rings ( const QgsPolygon &polygon )
284284{
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+
285300 // At this point we assume that input polygons are valid according to the OGC definition.
286301 // This means e.g. no duplicate points, polygons are simple (no butterfly shaped polygon with self-intersection),
287302 // 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 )
301316
302317 if ( polygon.numInteriorRings () > 0 )
303318 {
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-
309319 for ( int i = 0 ; i < geomRings.count (); ++i )
310320 for ( int j = i + 1 ; j < geomRings.count (); ++j )
311321 {
@@ -417,7 +427,7 @@ void QgsTessellator::addPolygon( const QgsPolygon &polygon, float extrusionHeigh
417427 if ( !_check_intersecting_rings ( *polygonNew.get () ) )
418428 {
419429 // 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" ) );
421431 return ;
422432 }
423433
0 commit comments