@@ -121,7 +121,6 @@ static QVector3D _calculateNormal( const QgsCurve *curve )
121
121
122
122
for ( int i = 0 ; i < curve->numPoints () - 1 ; i++ )
123
123
{
124
- QgsPoint pt1, pt2;
125
124
curve->pointAt ( i, pt1, vt );
126
125
curve->pointAt ( i + 1 , pt2, vt );
127
126
@@ -184,7 +183,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
184
183
QgsVertexId::VertexType vt;
185
184
QgsPoint pt;
186
185
187
- QVector3D pNormal = _calculateNormal ( exterior );
186
+ const QVector3D pNormal = _calculateNormal ( exterior );
188
187
const int pCount = exterior->numPoints ();
189
188
190
189
// Polygon is a triangle
@@ -225,7 +224,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
225
224
pXVector = QVector3D ( -pNormal.y () / pNormal.x (), 1 , 0 );
226
225
}
227
226
pXVector.normalize ();
228
- QVector3D pYVector = QVector3D::normal ( pNormal, pXVector );
227
+ const QVector3D pYVector = QVector3D::normal ( pNormal, pXVector );
229
228
230
229
for ( int i = 0 ; i < pCount - 1 ; ++i )
231
230
{
@@ -248,41 +247,6 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
248
247
}
249
248
polylinesToDelete << polyline;
250
249
251
- if ( polyline.size () < 3 )
252
- return ;
253
-
254
- p2t::CDT *cdt = new p2t::CDT ( polyline );
255
-
256
- // polygon holes
257
- for ( int i = 0 ; i < polygon.numInteriorRings (); ++i )
258
- {
259
- std::vector<p2t::Point *> holePolyline;
260
- holePolyline.reserve ( exterior->numPoints () );
261
- const QgsCurve *hole = polygon.interiorRing ( i );
262
- for ( int j = 0 ; j < hole->numPoints () - 1 ; ++j )
263
- {
264
- hole->pointAt ( j, pt, vt );
265
- QVector3D tempPt ( pt.x (), pt.y (), ( qIsNaN ( pt.z () ) ? 0 : pt.z () ) );
266
-
267
- const float x = QVector3D::dotProduct ( tempPt - pOrigin, pXVector );
268
- const float y = QVector3D::dotProduct ( tempPt - pOrigin, pYVector );
269
-
270
- const bool found = std::find_if ( polyline.begin (), polyline.end (), [x, y]( p2t::Point *&p ) { return *p == p2t::Point ( x, y ); } ) != polyline.end ();
271
-
272
- if ( found )
273
- {
274
- continue ;
275
- }
276
-
277
- p2t::Point *pt2 = new p2t::Point ( x, y );
278
- polyline.push_back ( pt2 );
279
-
280
- z[pt2] = qIsNaN ( pt.z () ) ? 0 : pt.z ();
281
- }
282
- cdt->AddHole ( holePolyline );
283
- polylinesToDelete << holePolyline;
284
- }
285
-
286
250
// TODO: robustness (no nearly duplicate points, invalid geometries ...)
287
251
288
252
if ( polyline.size () == 3 && polygon.numInteriorRings () == 0 )
@@ -300,39 +264,70 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
300
264
mData << pNormal.x () << pNormal.z () << - pNormal.y ();
301
265
}
302
266
}
303
- else
267
+ else if (polyline. size () >= 3 )
304
268
{
269
+ p2t::CDT *cdt = new p2t::CDT ( polyline );
270
+
271
+ // polygon holes
272
+ for ( int i = 0 ; i < polygon.numInteriorRings (); ++i )
273
+ {
274
+ std::vector<p2t::Point *> holePolyline;
275
+ holePolyline.reserve ( exterior->numPoints () );
276
+ const QgsCurve *hole = polygon.interiorRing ( i );
277
+ for ( int j = 0 ; j < hole->numPoints () - 1 ; ++j )
278
+ {
279
+ hole->pointAt ( j, pt, vt );
280
+ QVector3D tempPt ( pt.x (), pt.y (), ( qIsNaN ( pt.z () ) ? 0 : pt.z () ) );
281
+
282
+ const float x = QVector3D::dotProduct ( tempPt - pOrigin, pXVector );
283
+ const float y = QVector3D::dotProduct ( tempPt - pOrigin, pYVector );
284
+
285
+ const bool found = std::find_if ( polyline.begin (), polyline.end (), [x, y]( p2t::Point *&p ) { return *p == p2t::Point ( x, y ); } ) != polyline.end ();
286
+
287
+ if ( found )
288
+ {
289
+ continue ;
290
+ }
291
+
292
+ p2t::Point *pt2 = new p2t::Point ( x, y );
293
+ holePolyline.push_back ( pt2 );
294
+
295
+ z[pt2] = qIsNaN ( pt.z () ) ? 0 : pt.z ();
296
+ }
297
+ cdt->AddHole ( holePolyline );
298
+ polylinesToDelete << holePolyline;
299
+ }
305
300
try
306
301
{
307
302
cdt->Triangulate ();
303
+
304
+ std::vector<p2t::Triangle *> triangles = cdt->GetTriangles ();
305
+
306
+ for ( size_t i = 0 ; i < triangles.size (); ++i )
307
+ {
308
+ p2t::Triangle *t = triangles[i];
309
+ for ( int j = 0 ; j < 3 ; ++j )
310
+ {
311
+ p2t::Point *p = t->GetPoint ( j );
312
+ float zPt = z[p];
313
+ QVector3D nPoint = pOrigin + pXVector * p->x + pYVector * p->y ;
314
+ float fx = nPoint.x () - mOriginX ;
315
+ float fy = nPoint.y () - mOriginY ;
316
+ float fz = extrusionHeight + ( qIsNaN ( zPt ) ? 0 : zPt );
317
+ mData << fx << fz << -fy;
318
+ if ( mAddNormals )
319
+ mData << pNormal.x () << pNormal.z () << - pNormal.y ();
320
+ }
321
+ }
308
322
}
309
323
catch ( ... )
310
324
{
311
325
qDebug () << " Triangulation failed. Skipping polygon..." ;
312
- return ;
313
326
}
314
327
315
- std::vector<p2t::Triangle *> triangles = cdt->GetTriangles ();
316
-
317
- for ( size_t i = 0 ; i < triangles.size (); ++i )
318
- {
319
- p2t::Triangle *t = triangles[i];
320
- for ( int j = 0 ; j < 3 ; ++j )
321
- {
322
- p2t::Point *p = t->GetPoint ( j );
323
- float zPt = z[p];
324
- QVector3D nPoint = pOrigin + pXVector * p->x + pYVector * p->y ;
325
- float fx = nPoint.x () - mOriginX ;
326
- float fy = nPoint.y () - mOriginY ;
327
- float fz = extrusionHeight + ( qIsNaN ( zPt ) ? 0 : zPt );
328
- mData << fx << fz << -fy;
329
- if ( mAddNormals )
330
- mData << pNormal.x () << pNormal.z () << - pNormal.y ();
331
- }
332
- }
328
+ delete cdt;
333
329
}
334
330
335
- delete cdt;
336
331
for ( int i = 0 ; i < polylinesToDelete.count (); ++i )
337
332
qDeleteAll ( polylinesToDelete[i] );
338
333
}
0 commit comments