Skip to content

Commit

Permalink
Improvements to tessellator unit test + death to qIsNaN()
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Oct 11, 2017
1 parent 2c24690 commit 8412a87
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/3d/qgscameracontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ void QgsCameraController::frameTriggered( float dt )
mCameraData.y -= p2.y() - p1.y();
}

if ( qIsNaN( mCameraData.x ) || qIsNaN( mCameraData.y ) )
if ( std::isnan( mCameraData.x ) || std::isnan( mCameraData.y ) )
{
// something went horribly wrong but we need to at least try to fix it somehow
qDebug() << "camera position got NaN!";
Expand Down
16 changes: 8 additions & 8 deletions src/3d/qgstessellator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static QVector3D _calculateNormal( const QgsCurve *curve, bool &hasValidZ )
curve->pointAt( i, pt1, vt );
curve->pointAt( i + 1, pt2, vt );

if ( qIsNaN( pt1.z() ) || qIsNaN( pt2.z() ) )
if ( std::isnan( pt1.z() ) || std::isnan( pt2.z() ) )
continue;

hasValidZ = true;
Expand Down Expand Up @@ -219,7 +219,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
}

const QgsPoint ptFirst( exterior->startPoint() );
QVector3D pOrigin( ptFirst.x(), ptFirst.y(), qIsNaN( ptFirst.z() ) ? 0 : ptFirst.z() );
QVector3D pOrigin( ptFirst.x(), ptFirst.y(), std::isnan( ptFirst.z() ) ? 0 : ptFirst.z() );
QVector3D pXVector;
// Here we define the two perpendicular vectors that define the local
// 2D space on the plane. They will act as axis for which we will
Expand All @@ -242,7 +242,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
for ( int i = 0; i < pCount - 1; ++i )
{
exterior->pointAt( i, pt, vt );
QVector3D tempPt( pt.x(), pt.y(), ( qIsNaN( pt.z() ) ? 0 : pt.z() ) );
QVector3D tempPt( pt.x(), pt.y(), ( std::isnan( pt.z() ) ? 0 : pt.z() ) );
const float x = QVector3D::dotProduct( tempPt - pOrigin, pXVector );
const float y = QVector3D::dotProduct( tempPt - pOrigin, pYVector );

Expand All @@ -256,7 +256,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
p2t::Point *pt2 = new p2t::Point( x, y );
polyline.push_back( pt2 );

z[pt2] = qIsNaN( pt.z() ) ? 0 : pt.z();
z[pt2] = std::isnan( pt.z() ) ? 0 : pt.z();
}
polylinesToDelete << polyline;

Expand All @@ -271,7 +271,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
QVector3D nPoint = pOrigin + pXVector * p->x + pYVector * p->y;
const double fx = nPoint.x() - mOriginX;
const double fy = nPoint.y() - mOriginY;
const double fz = extrusionHeight + ( qIsNaN( zPt ) ? 0 : zPt );
const double fz = extrusionHeight + ( std::isnan( zPt ) ? 0 : zPt );
mData << fx << fz << -fy;
if ( mAddNormals )
mData << pNormal.x() << pNormal.z() << - pNormal.y();
Expand All @@ -290,7 +290,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
for ( int j = 0; j < hole->numPoints() - 1; ++j )
{
hole->pointAt( j, pt, vt );
QVector3D tempPt( pt.x(), pt.y(), ( qIsNaN( pt.z() ) ? 0 : pt.z() ) );
QVector3D tempPt( pt.x(), pt.y(), ( std::isnan( pt.z() ) ? 0 : pt.z() ) );

const float x = QVector3D::dotProduct( tempPt - pOrigin, pXVector );
const float y = QVector3D::dotProduct( tempPt - pOrigin, pYVector );
Expand All @@ -305,7 +305,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
p2t::Point *pt2 = new p2t::Point( x, y );
holePolyline.push_back( pt2 );

z[pt2] = qIsNaN( pt.z() ) ? 0 : pt.z();
z[pt2] = std::isnan( pt.z() ) ? 0 : pt.z();
}
cdt->AddHole( holePolyline );
polylinesToDelete << holePolyline;
Expand All @@ -326,7 +326,7 @@ void QgsTessellator::addPolygon( const QgsPolygonV2 &polygon, float extrusionHei
QVector3D nPoint = pOrigin + pXVector * p->x + pYVector * p->y;
float fx = nPoint.x() - mOriginX;
float fy = nPoint.y() - mOriginY;
float fz = extrusionHeight + ( qIsNaN( zPt ) ? 0 : zPt );
float fz = extrusionHeight + ( std::isnan( zPt ) ? 0 : zPt );
mData << fx << fz << -fy;
if ( mAddNormals )
mData << pNormal.x() << pNormal.z() << - pNormal.y();
Expand Down
52 changes: 52 additions & 0 deletions tests/src/3d/testqgstessellator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,56 @@

#include "qgstest.h"

#include <QVector3D>

#include "qgspoint.h"
#include "qgspolygon.h"
#include "qgstessellator.h"

/**
* Simple structure to record an expected triangle from tessellator.
* Triangle vertices are expected to be in counter-clockwise order.
*/
struct TriangleCoords
{
//! Constructs from expected triangle coordinates
TriangleCoords( const QVector3D &a, const QVector3D &b, const QVector3D &c,
const QVector3D &na = QVector3D(), const QVector3D &nb = QVector3D(), const QVector3D &nc = QVector3D() )
{
pts[0] = a; pts[1] = b; pts[2] = c;
normals[0] = na; normals[1] = nb; normals[2] = nc;
}

//! Constructs from tessellator output. Note: tessellator outputs (X,-Z,Y) tuples for (X,Y,Z) input coords
TriangleCoords( const float *data, bool withNormal )
{
pts[0] = QVector3D( data[0], -data[2], data[1] );
pts[1] = QVector3D( data[3], -data[5], data[4] );
pts[2] = QVector3D( data[6], -data[8], data[7] );
if ( withNormal )
{
data += 9;
normals[0] = QVector3D( data[0], -data[2], data[1] );
normals[1] = QVector3D( data[3], -data[5], data[4] );
normals[2] = QVector3D( data[6], -data[8], data[7] );
}
else
{
normals[0] = normals[1] = normals[2] = QVector3D();
}
}

//! Compares two triangles
bool operator==( const TriangleCoords &other ) const
{
// TODO: allow that the two triangles have coordinates shifted (but still in the same order)
return pts[0] == other.pts[0] && pts[1] == other.pts[1] && pts[2] == other.pts[2] &&
normals[0] == other.normals[0] && normals[1] == other.normals[1] && normals[2] == other.normals[2];
}

QVector3D pts[3];
QVector3D normals[3];
};

/**
* \ingroup UnitTests
Expand Down Expand Up @@ -60,8 +106,14 @@ void TestQgsTessellator::testBasic()
QgsTessellator t( 0, 0, false );
t.addPolygon( polygon, 0 );

TriangleCoords tcA( QVector3D( 1, 2, 0 ), QVector3D( 2, 1, 0 ), QVector3D( 3, 2, 0 ) );
TriangleCoords tcB( QVector3D( 1, 2, 0 ), QVector3D( 1, 1, 0 ), QVector3D( 2, 1, 0 ) );

QVector<float> polygonData = t.data();
QCOMPARE( polygonData.count(), 2 * 3 * 3 ); // two triangles (3 points with x/y/z coords)
// TODO: allow arbitrary order of triangles in output
QVERIFY( tcA == TriangleCoords( polygonData.constData(), false ) );
QVERIFY( tcB == TriangleCoords( polygonData.constData() + 9, false ) );
}


Expand Down

0 comments on commit 8412a87

Please sign in to comment.