Skip to content

Commit f939932

Browse files
committedOct 9, 2017
3D tesselator fixes and refactoring to avoid leaks
1 parent a2da64a commit f939932

File tree

1 file changed

+54
-59
lines changed

1 file changed

+54
-59
lines changed
 

‎src/3d/qgstessellator.cpp

Lines changed: 54 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ static QVector3D _calculateNormal( const QgsCurve *curve )
121121

122122
for ( int i = 0; i < curve->numPoints() - 1; i++ )
123123
{
124-
QgsPoint pt1, pt2;
125124
curve->pointAt( i, pt1, vt );
126125
curve->pointAt( i + 1, pt2, vt );
127126

@@ -184,7 +183,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
184183
QgsVertexId::VertexType vt;
185184
QgsPoint pt;
186185

187-
QVector3D pNormal = _calculateNormal( exterior );
186+
const QVector3D pNormal = _calculateNormal( exterior );
188187
const int pCount = exterior->numPoints();
189188

190189
// Polygon is a triangle
@@ -225,7 +224,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
225224
pXVector = QVector3D( -pNormal.y() / pNormal.x(), 1, 0 );
226225
}
227226
pXVector.normalize();
228-
QVector3D pYVector = QVector3D::normal( pNormal, pXVector );
227+
const QVector3D pYVector = QVector3D::normal( pNormal, pXVector );
229228

230229
for ( int i = 0; i < pCount - 1; ++i )
231230
{
@@ -248,41 +247,6 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
248247
}
249248
polylinesToDelete << polyline;
250249

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-
286250
// TODO: robustness (no nearly duplicate points, invalid geometries ...)
287251

288252
if ( polyline.size() == 3 && polygon.numInteriorRings() == 0 )
@@ -300,39 +264,70 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
300264
mData << pNormal.x() << pNormal.z() << - pNormal.y();
301265
}
302266
}
303-
else
267+
else if (polyline.size() >= 3)
304268
{
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+
}
305300
try
306301
{
307302
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+
}
308322
}
309323
catch ( ... )
310324
{
311325
qDebug() << "Triangulation failed. Skipping polygon...";
312-
return;
313326
}
314327

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;
333329
}
334330

335-
delete cdt;
336331
for ( int i = 0; i < polylinesToDelete.count(); ++i )
337332
qDeleteAll( polylinesToDelete[i] );
338333
}

0 commit comments

Comments
 (0)
Please sign in to comment.