Skip to content

Commit

Permalink
More efficient handling of z range when rendering point clouds
Browse files Browse the repository at this point in the history
Completely skip any nodes which are outside of the z range filter
of the render context, instead of testing point by point
  • Loading branch information
nyalldawson committed Nov 27, 2020
1 parent 033bcce commit 58c09a3
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
14 changes: 12 additions & 2 deletions src/core/pointcloud/qgspointcloudindex.cpp
Expand Up @@ -139,6 +139,11 @@ QgsRectangle QgsPointCloudDataBounds::mapExtent( const QgsVector3D &offset, cons
);
}

QgsDoubleRange QgsPointCloudDataBounds::zRange( const QgsVector3D &offset, const QgsVector3D &scale ) const
{
return QgsDoubleRange( mZMin * scale.z() + offset.z(), mZMax * scale.z() + offset.z() );
}

///@endcond


Expand Down Expand Up @@ -193,9 +198,14 @@ QgsPointCloudDataBounds QgsPointCloudIndex::nodeBounds( const IndexedPointCloudN
return db;
}

QgsRectangle QgsPointCloudIndex::nodeMapExtent( const IndexedPointCloudNode &n ) const
QgsRectangle QgsPointCloudIndex::nodeMapExtent( const IndexedPointCloudNode &node ) const
{
return nodeBounds( node ).mapExtent( mOffset, mScale );
}

QgsDoubleRange QgsPointCloudIndex::nodeZRange( const IndexedPointCloudNode &node ) const
{
return nodeBounds( n ).mapExtent( mOffset, mScale );
return nodeBounds( node ).zRange( mOffset, mScale );
}

float QgsPointCloudIndex::nodeError( const IndexedPointCloudNode &n ) const
Expand Down
23 changes: 19 additions & 4 deletions src/core/pointcloud/qgspointcloudindex.h
Expand Up @@ -30,6 +30,7 @@
#include "qgsvector3d.h"
#include "qgis_sip.h"
#include "qgspointcloudblock.h"
#include "qgsrange.h"

#define SIP_NO_FILE

Expand Down Expand Up @@ -122,6 +123,9 @@ class CORE_EXPORT QgsPointCloudDataBounds
//! Returns 2D rectangle in map coordinates
QgsRectangle mapExtent( const QgsVector3D &offset, const QgsVector3D &scale ) const;

//! Returns the z range, applying the specified \a offset and \a scale.
QgsDoubleRange zRange( const QgsVector3D &offset, const QgsVector3D &scale ) const;

private:
qint32 mXMin, mYMin, mZMin, mXMax, mYMax, mZMax;
};
Expand Down Expand Up @@ -179,11 +183,22 @@ class CORE_EXPORT QgsPointCloudIndex: public QObject
//! Returns z max
double zMax() const { return mZMax; }

//! Returns bounds of particular node
QgsPointCloudDataBounds nodeBounds( const IndexedPointCloudNode &n ) const;
//! Returns bounds of particular \a node
QgsPointCloudDataBounds nodeBounds( const IndexedPointCloudNode &node ) const;

/**
* Returns the extent of a \a node in map coordinates.
*
* \see nodeZRange()
*/
QgsRectangle nodeMapExtent( const IndexedPointCloudNode &node ) const;

//! Returns node extent in map coordinates
QgsRectangle nodeMapExtent( const IndexedPointCloudNode &n ) const;
/**
* Returns the z range of a \a node.
*
* \see nodeMapExtent()
*/
QgsDoubleRange nodeZRange( const IndexedPointCloudNode &node ) const;

//! Returns node's error in map units (used to determine in whether the node has enough detail for the current view)
float nodeError( const IndexedPointCloudNode &n ) const;
Expand Down
5 changes: 5 additions & 0 deletions src/core/pointcloud/qgspointcloudlayerrenderer.cpp
Expand Up @@ -83,8 +83,10 @@ bool QgsPointCloudLayerRenderer::render()

QgsPointCloudDataBounds db;

#ifdef QGISDEBUG
QElapsedTimer t;
t.start();
#endif

const IndexedPointCloudNode root = pc->root();

Expand Down Expand Up @@ -162,6 +164,9 @@ QList<IndexedPointCloudNode> QgsPointCloudLayerRenderer::traverseTree( const Qgs
if ( !context.extent().intersects( pc->nodeMapExtent( n ) ) )
return nodes;

if ( !context.zRange().isInfinite() && !context.zRange().overlaps( pc->nodeZRange( n ) ) )
return nodes;

nodes.append( n );

float childrenErrorPixels = nodeErrorPixels / 2.0f;
Expand Down

0 comments on commit 58c09a3

Please sign in to comment.