From 3a014ae0bf1d15c06e7d1b850a33a959f98175ed Mon Sep 17 00:00:00 2001 From: Belgacem Date: Wed, 6 Jan 2021 01:50:28 +0100 Subject: [PATCH] make identification work with point size --- .../qgspointclouddataprovider.sip.in | 1 + .../pointcloud/qgspointcloudlayer.sip.in | 1 - src/3d/chunks/qgschunkedentity_p.cpp | 10 ---- src/3d/qgs3dmapscene.cpp | 21 +++++-- src/3d/qgs3dmapscene.h | 4 +- src/app/3d/qgs3dmapcanvas.cpp | 34 ++++++----- src/app/3d/qgs3dmapcanvas.h | 4 +- src/app/3d/qgs3dmaptoolidentify.cpp | 28 ++++++++- src/app/3d/qgs3dmaptoolidentify.h | 6 +- src/app/qgsmaptoolidentifyaction.cpp | 21 +++++++ src/app/qgsmaptoolidentifyaction.h | 1 + .../pointcloud/qgspointclouddataprovider.cpp | 57 +++++++++++++++++-- .../pointcloud/qgspointclouddataprovider.h | 2 +- src/core/pointcloud/qgspointcloudlayer.cpp | 12 ---- src/core/pointcloud/qgspointcloudlayer.h | 1 - 15 files changed, 142 insertions(+), 61 deletions(-) diff --git a/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in b/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in index 6ddab7e90f8b..5a664b4d462c 100644 --- a/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in @@ -56,6 +56,7 @@ Ctor ~QgsPointCloudDataProvider(); + SIP_PYLIST identify( float maxErrorInMapCoords, QgsGeometry extentGeometry, const QgsDoubleRange extentZRange = QgsDoubleRange(), int pointsLimit = 1000 ); %Docstring Returns the list of points of the point cloud according to a zoom level diff --git a/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in index 7d5019a11d3f..ff9edf13480f 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in @@ -132,7 +132,6 @@ Ownership of ``renderer`` is transferred to the layer. .. seealso:: :py:func:`renderer` %End - QVector> getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx ); private: QgsPointCloudLayer( const QgsPointCloudLayer &rhs ); }; diff --git a/src/3d/chunks/qgschunkedentity_p.cpp b/src/3d/chunks/qgschunkedentity_p.cpp index 159ab8e95ef0..c9af754447dc 100644 --- a/src/3d/chunks/qgschunkedentity_p.cpp +++ b/src/3d/chunks/qgschunkedentity_p.cpp @@ -54,16 +54,6 @@ static float screenSpaceError( float epsilon, float distance, float screenSize, * camera */ float phi = epsilon * screenSize / ( 2 * distance * tan( fov * M_PI / ( 2 * 180 ) ) ); - { - static int k = 0; - if ( k % 20 == 0 ) - { - qDebug() << "screenSize: " << screenSize; - qDebug() << "fov: " << fov; - qDebug() << "epsilon: " << epsilon; - } - ++k; - } return phi; } diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index 2bb9477f5eb5..3a38dfc4fc3b 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -77,6 +77,8 @@ #include "qgsskyboxsettings.h" #include "qgswindow3dengine.h" +#include "qgspointcloudlayerelevationproperties.h" +#include "qgspointcloudlayer.h" Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *engine ) : mMap( map ) @@ -1099,17 +1101,13 @@ void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings ) } } -void Qgs3DMapScene::onRayCasted( const QVector3D &rayOrigin, const QVector3D &rayDirection ) +void Qgs3DMapScene::identifyPointCloudOnRay( QVector>> &selectedPoints, const QVector3D &rayOrigin, const QVector3D &rayDirection ) { - qDebug() << __PRETTY_FUNCTION__ << " " << rayOrigin << " " << rayDirection; -// QVector3D point2 = rayOrigin + rayOrigin.length() * rayDirection.normalized(); - qDebug() << "Origin: " << mMap.origin().x() << " " << mMap.origin().y() << " " << mMap.origin().z(); QgsVector3D originMapCoords = mMap.worldToMapCoordinates( rayOrigin ); QgsVector3D pointMapCoords = mMap.worldToMapCoordinates( rayOrigin + rayOrigin.length() * rayDirection.normalized() ); QgsVector3D directionMapCoords = pointMapCoords - originMapCoords; directionMapCoords.normalize(); - QVector3D rayOriginMapCoords( originMapCoords.x(), originMapCoords.y(), originMapCoords.z() ); QVector3D rayDirectionMapCoords( directionMapCoords.x(), directionMapCoords.y(), directionMapCoords.z() ); @@ -1124,7 +1122,18 @@ void Qgs3DMapScene::onRayCasted( const QVector3D &rayOrigin, const QVector3D &ra { QgsPointCloudLayer3DRenderer *renderer = dynamic_cast( pc->renderer3D() ); double maxScreenError = renderer->maximumScreenError(); - pc->getPointsOnRay( rayOriginMapCoords, rayDirectionMapCoords, maxScreenError, fov, screenSizePx ); + const QgsPointCloud3DSymbol *symbol = renderer->symbol(); + float pointSize = symbol->pointSize(); + double angle = pointSize / screenSizePx * mCameraController->camera()->fieldOfView(); + + // adjust ray to elevation properties + QgsPointCloudLayerElevationProperties *elevationProps = dynamic_cast( pc->elevationProperties() ); + QVector3D adjutedRayOrigin = QVector3D( rayOriginMapCoords.x(), rayOriginMapCoords.y(), ( rayOriginMapCoords.z() - elevationProps->zOffset() ) / elevationProps->zScale() ); + QVector3D adjutedRayDirection = QVector3D( rayDirectionMapCoords.x(), rayDirectionMapCoords.y(), rayDirectionMapCoords.z() / elevationProps->zScale() ); + adjutedRayDirection.normalize(); + + QVector points = pc->dataProvider()->getPointsOnRay( adjutedRayOrigin, adjutedRayDirection, maxScreenError, fov, screenSizePx, angle ); + selectedPoints.append( qMakePair( layer, points ) ); } } } diff --git a/src/3d/qgs3dmapscene.h b/src/3d/qgs3dmapscene.h index 06c9f9342a64..10d4b341a673 100644 --- a/src/3d/qgs3dmapscene.h +++ b/src/3d/qgs3dmapscene.h @@ -121,6 +121,9 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity //! Exports the scene according to the scene export settings void exportScene( const Qgs3DMapExportSettings &exportSettings ); + + void identifyPointCloudOnRay( QVector>> &selectedPoints, const QVector3D &rayOrigin, const QVector3D &rayDirection ); + signals: //! Emitted when the current terrain entity is replaced by a new one void terrainEntityChanged(); @@ -143,7 +146,6 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity public slots: //! Updates the temporale entities void updateTemporal(); - void onRayCasted( const QVector3D &rayOrigin, const QVector3D &rayDirection ); private slots: void onCameraChanged(); diff --git a/src/app/3d/qgs3dmapcanvas.cpp b/src/app/3d/qgs3dmapcanvas.cpp index 298a90911512..bf5815504833 100644 --- a/src/app/3d/qgs3dmapcanvas.cpp +++ b/src/app/3d/qgs3dmapcanvas.cpp @@ -254,26 +254,30 @@ void Qgs3DMapCanvas::updateTemporalRange( const QgsDateTimeRange &temporalrange mScene->updateTemporal(); } - -void Qgs3DMapCanvas::mouseReleased( QMouseEvent *event ) +bool Qgs3DMapCanvas::identifyPointCloudOnMouseEvent( QVector>> &result, QMouseEvent *event ) { -// qDebug() << __PRETTY_FUNCTION__ << " " << event->x() << " " << event->y(); QVector3D deviceCoords( event->x(), event->y(), 0.0 ); QSize windowSize = mEngine->size(); + // normalized device coordinates QVector3D normDeviceCoords( 2.0 * deviceCoords.x() / windowSize.width() - 1.0f, 1.0f - 2.0 * deviceCoords.y() / windowSize.height(), mEngine->camera()->nearPlane() ); -// qDebug() << "NDC " << normDeviceCoords.x() << " " << normDeviceCoords.y() << " " << normDeviceCoords.z(); - QVector4D rayClip( normDeviceCoords.x(), normDeviceCoords.y(), -1.0f, 0.0f ); + // clip coordinates + QVector4D rayClip( normDeviceCoords.x(), normDeviceCoords.y(), -1.0, 0.0 ); + QMatrix4x4 projMatrix = mEngine->camera()->projectionMatrix(); QMatrix4x4 viewMatrix = mEngine->camera()->viewMatrix(); - QVector4D rayEye = projMatrix.inverted() * rayClip; - rayEye.setZ( -1.0f ); - rayEye.setW( 0.0f ); - QVector4D rayWorld4D = viewMatrix.inverted() * rayEye; - QVector3D rayWorld( rayWorld4D.x(), rayWorld4D.y(), rayWorld4D.z() ); - rayWorld = rayWorld.normalized(); -// qDebug() << "rayEye: " << rayEye; -// qDebug() << "rayWorld: " << rayWorld; - QVector4D rayOrigin = viewMatrix.inverted() * QVector4D( 0.0f, 0.0f, 0.0f, 1.0f ); - mScene->onRayCasted( QVector3D( rayOrigin ), rayWorld ); + // ray direction in view coordinates + QVector4D rayDirView = projMatrix.inverted() * rayClip; + // ray origin in world coordinates + QVector4D rayOriginWorld = viewMatrix.inverted() * QVector4D( 0.0f, 0.0f, 0.0f, 1.0f ); + + // ray direction in world coordinates + rayDirView.setZ( -1.0f ); + rayDirView.setW( 0.0f ); + QVector4D rayDirWorld4D = viewMatrix.inverted() * rayDirView; + QVector3D rayDirWorld( rayDirWorld4D.x(), rayDirWorld4D.y(), rayDirWorld4D.z() ); + rayDirWorld = rayDirWorld.normalized(); + + mScene->identifyPointCloudOnRay( result, QVector3D( rayOriginWorld ), rayDirWorld ); + return true; } diff --git a/src/app/3d/qgs3dmapcanvas.h b/src/app/3d/qgs3dmapcanvas.h index 8d20896057be..e6dca313e03a 100644 --- a/src/app/3d/qgs3dmapcanvas.h +++ b/src/app/3d/qgs3dmapcanvas.h @@ -86,6 +86,9 @@ class Qgs3DMapCanvas : public QWidget */ void setTemporalController( QgsTemporalController *temporalController ); + // + bool identifyPointCloudOnMouseEvent( QVector>> &result, QMouseEvent *event ); + signals: //! Emitted when the 3D map canvas was successfully saved as image void savedAsImage( QString fileName ); @@ -98,7 +101,6 @@ class Qgs3DMapCanvas : public QWidget //! Emitted when the FPS counter is enabled or disabeld void fpsCounterEnabledChanged( bool enabled ); public slots: - void mouseReleased( QMouseEvent *event ); private slots: void updateTemporalRange( const QgsDateTimeRange &timeRange ); diff --git a/src/app/3d/qgs3dmaptoolidentify.cpp b/src/app/3d/qgs3dmaptoolidentify.cpp index 94cfdebb8f97..9268996908be 100644 --- a/src/app/3d/qgs3dmaptoolidentify.cpp +++ b/src/app/3d/qgs3dmaptoolidentify.cpp @@ -30,6 +30,7 @@ #include #include +#include "qgspointcloudlayer.h" #include "qgs3dmapscenepickhandler.h" @@ -66,7 +67,6 @@ Qgs3DMapToolIdentify::Qgs3DMapToolIdentify( Qgs3DMapCanvas *canvas ) { mPickHandler.reset( new Qgs3DMapToolIdentifyPickHandler( this ) ); connect( canvas, &Qgs3DMapCanvas::mapSettingsChanged, this, &Qgs3DMapToolIdentify::onMapSettingsChanged ); - connect( this, &Qgs3DMapToolIdentify::mouseReleased, canvas, &Qgs3DMapCanvas::mouseReleased ); } Qgs3DMapToolIdentify::~Qgs3DMapToolIdentify() = default; @@ -80,11 +80,35 @@ void Qgs3DMapToolIdentify::mousePressEvent( QMouseEvent *event ) identifyTool2D->clearResults(); } +void Qgs3DMapToolIdentify::mouseReleaseEvent( QMouseEvent *event ) +{ + if ( event->button() != Qt::MouseButton::LeftButton ) + return; + + QVector>> layerPoints; + canvas()->identifyPointCloudOnMouseEvent( layerPoints, event ); + + QgsMapToolIdentifyAction *identifyTool2D = QgisApp::instance()->identifyMapTool(); + identifyTool2D->showPointCloudIdentifyResults( layerPoints ); +} + void Qgs3DMapToolIdentify::activate() { if ( QgsTerrainEntity *terrainEntity = mCanvas->scene()->terrainEntity() ) { - connect( terrainEntity->terrainPicker(), &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked ); + bool disableTerrainPicker = false; + const Qgs3DMapSettings &map = terrainEntity->map3D(); + // if the terrain contains point cloud data disable the terrain picker signals + for ( QgsMapLayer *layer : map.layers() ) + { + if ( layer->type() == QgsMapLayerType::PointCloudLayer ) + { + disableTerrainPicker = true; + break; + } + } + if ( !disableTerrainPicker ) + connect( terrainEntity->terrainPicker(), &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked ); } mCanvas->scene()->registerPickHandler( mPickHandler.get() ); diff --git a/src/app/3d/qgs3dmaptoolidentify.h b/src/app/3d/qgs3dmaptoolidentify.h index 03431630357b..a9ea122d5445 100644 --- a/src/app/3d/qgs3dmaptoolidentify.h +++ b/src/app/3d/qgs3dmaptoolidentify.h @@ -38,11 +38,7 @@ class Qgs3DMapToolIdentify : public Qgs3DMapTool ~Qgs3DMapToolIdentify() override; void mousePressEvent( QMouseEvent *event ) override; - void mouseReleaseEvent( QMouseEvent *event ) override - { - Q_UNUSED( event ) - emit mouseReleased( event ); - } + void mouseReleaseEvent( QMouseEvent *event ) override; void mouseMoveEvent( QMouseEvent *event ) override {Q_UNUSED( event )} void activate() override; diff --git a/src/app/qgsmaptoolidentifyaction.cpp b/src/app/qgsmaptoolidentifyaction.cpp index 383a48fe4688..4987e51fa683 100644 --- a/src/app/qgsmaptoolidentifyaction.cpp +++ b/src/app/qgsmaptoolidentifyaction.cpp @@ -41,6 +41,7 @@ #include "qgsactionscoperegistry.h" #include "qgssettings.h" #include "qgsmapmouseevent.h" +#include "qgspointcloudlayer.h" #include #include @@ -270,3 +271,23 @@ void QgsMapToolIdentifyAction::keyReleaseEvent( QKeyEvent *e ) QgsMapTool::keyReleaseEvent( e ); } + +void QgsMapToolIdentifyAction::showPointCloudIdentifyResults( const QVector>> &layersAndPoints ) +{ + for ( int i = 0; i < layersAndPoints.size(); ++i ) + { + QgsMapLayer *layer = layersAndPoints[i].first; + int id = 0; + for ( const QVariantMap &pt : layersAndPoints[i].second ) + { + QMap strMap; + for ( QString key : pt.keys() ) + strMap[ key ] = pt[ key ].toString(); + resultsDialog()->addFeature( IdentifyResult( layer, QString( "%1_%2" ).arg( layer->name() ).arg( id ), strMap, strMap ) ); + ++id; + } + } + resultsDialog()->show(); + // update possible view modes + resultsDialog()->updateViewModes(); +} diff --git a/src/app/qgsmaptoolidentifyaction.h b/src/app/qgsmaptoolidentifyaction.h index 8953bef66ca8..f48626273f8d 100644 --- a/src/app/qgsmaptoolidentifyaction.h +++ b/src/app/qgsmaptoolidentifyaction.h @@ -69,6 +69,7 @@ class APP_EXPORT QgsMapToolIdentifyAction : public QgsMapToolIdentify //! Looks up feature by its ID and outputs the result in GUI void showResultsForFeature( QgsVectorLayer *vlayer, QgsFeatureId fid, const QgsPoint &pt ); + void showPointCloudIdentifyResults( const QVector>> &layersAndPoints ); public slots: void handleCopyToClipboard( QgsFeatureStore & ); void handleChangedRasterResults( QList &results ); diff --git a/src/core/pointcloud/qgspointclouddataprovider.cpp b/src/core/pointcloud/qgspointclouddataprovider.cpp index 13fad74d064a..cb4b5482657d 100644 --- a/src/core/pointcloud/qgspointclouddataprovider.cpp +++ b/src/core/pointcloud/qgspointclouddataprovider.cpp @@ -23,6 +23,7 @@ #include "qgsgeometryengine.h" #include #include +#include #include @@ -407,17 +408,64 @@ QVector QgsPointCloudDataProvider::traverseTree( return nodes; } -QVector> QgsPointCloudDataProvider::getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx ) + +QVector> QgsPointCloudDataProvider::getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx, double pointAngle ) { QVector> points; - qDebug() << "Ray: " << rayOrigin << " " << rayDirection; QgsPointCloudIndex *index = this->index(); IndexedPointCloudNode root = index->root(); QgsRectangle rootNodeExtentMapCoords = index->nodeMapExtent( root ); const float rootErrorInMapCoordinates = rootNodeExtentMapCoords.width() / index->span(); QVector nodes = getNodesIntersectingWithRay( index, root, maxScreenError, rootErrorInMapCoordinates, cameraFov, screenSizePx, rayOrigin, rayDirection ); - qDebug() << "Intersected nodes: " << nodes.size(); + + QgsPointCloudAttributeCollection attributeCollection = index->attributes(); + QgsPointCloudRequest request; + request.setAttributes( attributeCollection ); + + for ( IndexedPointCloudNode n : nodes ) + { + std::unique_ptr block( index->nodeData( n, request ) ); + + if ( !block ) + continue; + const char *ptr = block->data(); + QgsPointCloudAttributeCollection blockAttributes = block->attributes(); + const std::size_t recordSize = blockAttributes.pointRecordSize(); + int xOffset, yOffset, zOffset; + blockAttributes.find( QStringLiteral( "X" ), xOffset ); + blockAttributes.find( QStringLiteral( "Y" ), yOffset ); + blockAttributes.find( QStringLiteral( "Z" ), zOffset ); + for ( int i = 0; i < block->pointCount(); ++i ) + { + double x, y, z; + _pointXY( ptr, i, recordSize, xOffset, yOffset, index->scale(), index->offset(), x, y ); + z = _pointZ( ptr, i, recordSize, zOffset, index->scale(), index->offset() ); + QVector3D point( x, y, z ); + // project point on ray + QVector3D projectedPoint = rayOrigin + QgsVector3D::dotProduct( point - rayOrigin, rayDirection ) * rayDirection; + // check whether point is in front of the ray + bool isInFront = QgsVector3D::dotProduct( point - rayOrigin, rayDirection ) > 0.0; + + if ( !isInFront ) + continue; + + // calculate the angle between the point and the projected point + QVector3D v1 = ( projectedPoint - rayOrigin ).normalized(); + QVector3D v2 = ( point - rayOrigin ).normalized(); + double angle = qRadiansToDegrees( std::acos( std::abs( QVector3D::dotProduct( v1, v2 ) ) ) ); + + if ( angle > pointAngle ) + continue; + + QVariantMap pointAttr = _attributeMap( ptr, i * recordSize, blockAttributes ); + pointAttr[ QStringLiteral( "X" ) ] = x; + pointAttr[ QStringLiteral( "Y" ) ] = y; + pointAttr[ QStringLiteral( "Z" ) ] = z; + points.push_back( pointAttr ); + } + } + return points; } @@ -476,7 +524,6 @@ QVector QgsPointCloudDataProvider::getNodesIntersectingWi // calculate screen space error: float distance = box.distanceFromPoint( rayOrigin.x(), rayOrigin.y(), rayOrigin.z() ); - qDebug() << "Node error: " << nodeError; float phi = nodeError * screenSizePx / ( 2 * distance * tan( cameraFov * M_PI / ( 2 * 180 ) ) ); if ( !__boxIntesects( box, rayOrigin, rayDirection ) ) @@ -490,8 +537,6 @@ QVector QgsPointCloudDataProvider::getNodesIntersectingWi if ( phi < maxError ) return nodes; - qDebug() << "Passed"; - const QList children = pc->nodeChildren( n ); for ( const IndexedPointCloudNode &nn : children ) { diff --git a/src/core/pointcloud/qgspointclouddataprovider.h b/src/core/pointcloud/qgspointclouddataprovider.h index 3c8050691a8a..2221d87b343b 100644 --- a/src/core/pointcloud/qgspointclouddataprovider.h +++ b/src/core/pointcloud/qgspointclouddataprovider.h @@ -121,7 +121,7 @@ class CORE_EXPORT QgsPointCloudDataProvider: public QgsDataProvider } % End #endif - QVector> getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx ) SIP_SKIP; + QVector> getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx, double pointAngle ) SIP_SKIP; QVector getNodesIntersectingWithRay( const QgsPointCloudIndex *pc, IndexedPointCloudNode n, double maxError, double nodeError, double cameraFov, int screenSizePx, const QVector3D &rayOrigin, const QVector3D &rayDirection ); /** diff --git a/src/core/pointcloud/qgspointcloudlayer.cpp b/src/core/pointcloud/qgspointcloudlayer.cpp index ba081940816d..90a2d1c2e0cc 100644 --- a/src/core/pointcloud/qgspointcloudlayer.cpp +++ b/src/core/pointcloud/qgspointcloudlayer.cpp @@ -621,15 +621,3 @@ void QgsPointCloudLayer::setRenderer( QgsPointCloudRenderer *renderer ) emit rendererChanged(); emit styleChanged(); } - -QVector> QgsPointCloudLayer::getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx ) -{ - qDebug() << __PRETTY_FUNCTION__ << rayOrigin << " " << rayDirection; - QVector> points; - QVector3D adjutedRayOrigin = QVector3D( rayOrigin.x(), rayOrigin.y(), ( rayOrigin.z() - mElevationProperties->zOffset() ) / mElevationProperties->zScale() ); - QVector3D adjutedRayDirection = QVector3D( rayDirection.x(), rayDirection.y(), rayDirection.z() / mElevationProperties->zScale() ); - adjutedRayDirection.normalize(); - - points = mDataProvider->getPointsOnRay( adjutedRayOrigin, adjutedRayDirection, maxScreenError, cameraFov, screenSizePx ); - return points; -} diff --git a/src/core/pointcloud/qgspointcloudlayer.h b/src/core/pointcloud/qgspointcloudlayer.h index 224f69d784ae..372fb219978b 100644 --- a/src/core/pointcloud/qgspointcloudlayer.h +++ b/src/core/pointcloud/qgspointcloudlayer.h @@ -167,7 +167,6 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer */ void setRenderer( QgsPointCloudRenderer *renderer SIP_TRANSFER ); - QVector> getPointsOnRay( const QVector3D &rayOrigin, const QVector3D &rayDirection, double maxScreenError, double cameraFov, int screenSizePx ); private slots: void onPointCloudIndexGenerationStateChanged( QgsPointCloudDataProvider::PointCloudIndexGenerationState state );