Skip to content
Permalink
Browse files

[remote EPT] [point cloud] fix UI freeze bug (#42965)

* fix UI freeze bug

* fix spelling

* fix spelling

* refactor a bit of the code

* rename getPointCloudBlock to pointCloudBlock

* use a feedback object instead of cancelled callback

* do not use QMetaObject::Connection

* Qgs3DRenderContext doesn't need to be QObject

* remove Q_OBJECT
  • Loading branch information
NEDJIMAbelgacem committed May 4, 2021
1 parent d07a0b9 commit e4f74ed90a8e8b35f446f1e4e6f0342025742426
@@ -11,7 +11,6 @@




class QgsPointCloudLayer3DRenderer : QgsAbstract3DRenderer
{
%Docstring(signature="appended")
@@ -27,20 +27,14 @@
#include "qgspointcloud3dsymbol.h"
#include "qgspointcloudlayerelevationproperties.h"

#include "qgis.h"

QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr<QgsPointCloud3DSymbol> symbol, double zValueScale, double zValueFixedOffset )
: Qgs3DRenderContext( map )
, mSymbol( std::move( symbol ) )
, mZValueScale( zValueScale )
, mZValueFixedOffset( zValueFixedOffset )
, mCoordinateTransform( coordinateTransform )
, mFeedback( new QgsFeedback )
{
auto callback = []()->bool
{
return false;
};
mIsCanceledCallback = callback;
}

void QgsPointCloud3DRenderContext::setAttributes( const QgsPointCloudAttributeCollection &attributes )
@@ -71,6 +65,18 @@ void QgsPointCloud3DRenderContext::setCoordinateTransform( const QgsCoordinateTr
mCoordinateTransform = coordinateTransform;
}

bool QgsPointCloud3DRenderContext::isCanceled() const
{
return mFeedback->isCanceled();
}

void QgsPointCloud3DRenderContext::cancelRendering() const
{
mFeedback->cancel();
}
// ---------


QgsPointCloudLayer3DRendererMetadata::QgsPointCloudLayer3DRendererMetadata()
: Qgs3DRendererAbstractMetadata( QStringLiteral( "pointcloud" ) )
{
@@ -22,7 +22,7 @@
#include "qgs3drendererregistry.h"
#include "qgsabstract3drenderer.h"
#include "qgsmaplayerref.h"

#include "qgsfeedback.h"
#include <QObject>

class QgsPointCloudLayer;
@@ -151,14 +151,15 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext
double zValueFixedOffset() const { return mZValueFixedOffset; }

/**
* Sets the function to call to test if the rendering is canceled.
* Returns TRUE if the rendering is canceled.
*/
void setIsCanceledCallback( const std::function< bool() > &callback ) { mIsCanceledCallback = callback; }
bool isCanceled() const;

/**
* Returns TRUE if the rendering is canceled.
* Cancels rendering.
* \see isCanceled()
*/
bool isCanceled() const { return mIsCanceledCallback(); }
void cancelRendering() const;

/**
* Sets the coordinate transform used to transform points from layer CRS to the map CRS
@@ -170,6 +171,10 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext
*/
QgsCoordinateTransform coordinateTransform() const { return mCoordinateTransform; }

/**
* Returns the feedback object used to cancel rendering and check if rendering was canceled.
*/
QgsFeedback *feedback() const { return mFeedback.get(); }
private:
#ifdef SIP_RUN
QgsPointCloudRenderContext( const QgsPointCloudRenderContext &rh );
@@ -180,9 +185,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext
double mZValueScale = 1.0;
double mZValueFixedOffset = 0;
QgsCoordinateTransform mCoordinateTransform;

std::function< bool() > mIsCanceledCallback;

std::unique_ptr<QgsFeedback> mFeedback;
};


@@ -52,7 +52,6 @@ QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointClou
, mFactory( factory )
, mContext( factory->mMap, coordinateTransform, std::move( symbol ), zValueScale, zValueOffset )
{
mContext.setIsCanceledCallback( [this] { return mCanceled; } );

QgsPointCloudIndex *pc = mFactory->mPointCloudIndex;
mContext.setAttributes( pc->attributes() );
@@ -84,7 +83,7 @@ QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointClou
{
QgsEventTracing::ScopedEvent e( QStringLiteral( "3D" ), QStringLiteral( "PC chunk load" ) );

if ( mCanceled )
if ( mContext.isCanceled() )
{
QgsDebugMsgLevel( QStringLiteral( "canceled" ), 2 );
return;
@@ -104,13 +103,14 @@ QgsPointCloudLayerChunkLoader::~QgsPointCloudLayerChunkLoader()
if ( mFutureWatcher && !mFutureWatcher->isFinished() )
{
disconnect( mFutureWatcher, &QFutureWatcher<void>::finished, this, &QgsChunkQueueJob::finished );
mContext.cancelRendering();
mFutureWatcher->waitForFinished();
}
}

void QgsPointCloudLayerChunkLoader::cancel()
{
mCanceled = true;
mContext.cancelRendering();
}

Qt3DCore::QEntity *QgsPointCloudLayerChunkLoader::createEntity( Qt3DCore::QEntity *parent )
@@ -104,7 +104,6 @@ class QgsPointCloudLayerChunkLoader : public QgsChunkLoader
const QgsPointCloudLayerChunkLoaderFactory *mFactory;
std::unique_ptr<QgsPointCloud3DSymbolHandler> mHandler;
QgsPointCloud3DRenderContext mContext;
bool mCanceled = false;
QFutureWatcher<void> *mFutureWatcher = nullptr;
};

@@ -25,6 +25,8 @@
#include "qgscolorramptexture.h"
#include "qgs3dmapsettings.h"
#include "qgspointcloudindex.h"
#include "qgspointcloudblockrequest.h"
#include "qgsfeedback.h"

#include <Qt3DRender/QGeometryRenderer>
#include <Qt3DRender/QAttribute>
@@ -225,6 +227,34 @@ void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const
// cppcheck-suppress memleak
}

QgsPointCloudBlock *QgsPointCloud3DSymbolHandler::pointCloudBlock( QgsPointCloudIndex *pc, const IndexedPointCloudNode &n, const QgsPointCloudRequest &request, const QgsPointCloud3DRenderContext &context )
{
QgsPointCloudBlock *block = nullptr;
if ( pc->accessType() == QgsPointCloudIndex::AccessType::Local )
{
block = pc->nodeData( n, request );
}
else if ( pc->accessType() == QgsPointCloudIndex::AccessType::Remote )
{
bool loopAborted = false;
QEventLoop loop;
QgsPointCloudBlockRequest *req = pc->asyncNodeData( n, request );
QObject::connect( req, &QgsPointCloudBlockRequest::finished, &loop, &QEventLoop::quit );
QObject::connect( context.feedback(), &QgsFeedback::canceled, &loop, [ & ]()
{
loopAborted = true;
loop.quit();
} );
loop.exec();

if ( !loopAborted )
block = req->block();
}
return block;
}

//

QgsSingleColorPointCloud3DSymbolHandler::QgsSingleColorPointCloud3DSymbolHandler()
: QgsPointCloud3DSymbolHandler()
{
@@ -246,7 +276,7 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;

@@ -369,7 +399,7 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc,

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;

@@ -474,7 +504,7 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;

@@ -637,7 +667,7 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;

@@ -64,6 +64,7 @@ class QgsPointCloud3DSymbolHandler // : public QgsFeature3DHandler

void makeEntity( Qt3DCore::QEntity *parent, const QgsPointCloud3DRenderContext &context, PointData &out, bool selected );
virtual Qt3DRender::QGeometry *makeGeometry( Qt3DCore::QNode *parent, const QgsPointCloud3DSymbolHandler::PointData &data, unsigned int byteStride ) = 0;
QgsPointCloudBlock *pointCloudBlock( QgsPointCloudIndex *pc, const IndexedPointCloudNode &node, const QgsPointCloudRequest &request, const QgsPointCloud3DRenderContext &context );

// outputs
PointData outNormal; //!< Features that are not selected

0 comments on commit e4f74ed

Please sign in to comment.