Skip to content

Commit

Permalink
Fix review issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Withalion committed Mar 5, 2025
1 parent 5d3623d commit 4e14214
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 11 deletions.
2 changes: 1 addition & 1 deletion python/3d/auto_generated/qgscameracontroller.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ yaw angle in degrees.
.. versionadded:: 3.4
%End

void setCameraPose( const QgsCameraPose &camPose );
void setCameraPose( const QgsCameraPose &camPose, bool force = false );
%Docstring
Sets camera pose

Expand Down
2 changes: 1 addition & 1 deletion python/PyQt6/3d/auto_generated/qgscameracontroller.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ yaw angle in degrees.
.. versionadded:: 3.4
%End

void setCameraPose( const QgsCameraPose &camPose );
void setCameraPose( const QgsCameraPose &camPose, bool force = false );
%Docstring
Sets camera pose

Expand Down
10 changes: 6 additions & 4 deletions src/3d/qgscameracontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,11 @@ void QgsCameraController::setViewFromTop( float worldX, float worldY, float dist
camPose.setDistanceFromCenterPoint( distance );
camPose.setHeadingAngle( yaw );

// a basic setup to make frustum depth range long enough that it does not cull everything
mCamera->setNearPlane( distance / 2 );
mCamera->setFarPlane( distance * 2 );
// we force the updateCameraNearFarPlanes() in Qgs3DMapScene to properly set the planes
mCameraPose = camPose;
updateCameraFromPose();
setCameraPose( camPose, true );
}

QgsVector3D QgsCameraController::lookingAtPoint() const
Expand All @@ -206,9 +208,9 @@ void QgsCameraController::setLookingAtPoint( const QgsVector3D &point, float dis
setCameraPose( camPose );
}

void QgsCameraController::setCameraPose( const QgsCameraPose &camPose )
void QgsCameraController::setCameraPose( const QgsCameraPose &camPose, bool force )
{
if ( camPose == mCameraPose )
if ( camPose == mCameraPose && !force )
return;

mCameraPose = camPose;
Expand Down
2 changes: 1 addition & 1 deletion src/3d/qgscameracontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class _3D_EXPORT QgsCameraController : public QObject
* Sets camera pose
* \since QGIS 3.4
*/
void setCameraPose( const QgsCameraPose &camPose );
void setCameraPose( const QgsCameraPose &camPose, bool force = false );

/**
* Returns camera pose
Expand Down
7 changes: 3 additions & 4 deletions src/core/pointcloud/qgspointcloudlayerelevationproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,12 @@ QgsDoubleRange QgsPointCloudLayerElevationProperties::calculateZRange( QgsMapLay
// try to fetch the elevation properties from virtual point cloud metadata
else if ( QgsVirtualPointCloudProvider *virtualProvider = dynamic_cast< QgsVirtualPointCloudProvider * >( pcLayer->dataProvider() ) )
{
zMin = virtualProvider->subIndexes()[0].zRange().lower();
zMax = virtualProvider->subIndexes()[0].zRange().upper();
for ( QgsPointCloudSubIndex subIndex : virtualProvider->subIndexes() )
{
const QgsDoubleRange newRange = subIndex.zRange();
zMin = std::min( zMin, newRange.lower() );
zMax = std::max( zMax, newRange.upper() );
if ( newRange.isInfinite() ) continue;
zMin = std::isnan( zMin ) ? newRange.lower() : std::min( zMin, newRange.lower() );
zMax = std::isnan( zMax ) ? newRange.upper() : std::max( zMax, newRange.upper() );
}
}

Expand Down
74 changes: 74 additions & 0 deletions tests/src/3d/testqgs3dcameracontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "qgsflatterraingenerator.h"
#include "qgsoffscreen3dengine.h"
#include "qgsphongmaterialsettings.h"
#include "qgspointcloudlayer.h"
#include "qgspointcloudlayer3drenderer.h"
#include "qgspolygon3dsymbol.h"
#include "qgsrasterlayer.h"
#include "qgsvectorlayer.h"
Expand Down Expand Up @@ -50,6 +52,8 @@ class TestQgs3DCameraController : public QgsTest
void testTranslateZoomWheelTranslate();
void testTranslateRotationCameraTranslate();
void testRotationCenterRotationCameraRotationCenter();
void testResetViewRaster();
void testResetViewPointCloud();

private:
void waitForNearPlane( QgsOffscreen3DEngine &engine, Qgs3DMapScene *scene, float atLeast ); //#spellok
Expand Down Expand Up @@ -1190,5 +1194,75 @@ void TestQgs3DCameraController::waitForNearPlane( QgsOffscreen3DEngine &engine,
} while ( scene->cameraController()->camera()->nearPlane() < atLeast ); //#spellok
}

void TestQgs3DCameraController::testResetViewRaster()
{
const QgsRectangle fullExtent = mLayerRgb->extent();

Qgs3DMapSettings *mapSettings = new Qgs3DMapSettings;
mapSettings->setCrs( mLayerRgb->crs() );
mapSettings->setExtent( fullExtent );
mapSettings->setLayers( QList<QgsMapLayer *>() << mLayerRgb << mLayerBuildings );

QgsFlatTerrainGenerator *flatTerrain = new QgsFlatTerrainGenerator;
flatTerrain->setCrs( mapSettings->crs(), QgsCoordinateTransformContext() );
mapSettings->setTerrainGenerator( flatTerrain );

constexpr QPoint winSize = QPoint( 640, 480 ); // default window size
QgsOffscreen3DEngine engine;
engine.setSize( QSize( winSize.x(), winSize.y() ) );
Qgs3DMapScene *scene = new Qgs3DMapScene( *mapSettings, &engine );
engine.setRootEntity( scene );

// compare raster layer + vector layer
scene->viewZoomFull();
QGSCOMPARENEAR( scene->cameraController()->distance(), 2172, 1 );
}

void TestQgs3DCameraController::testResetViewPointCloud()
{
QgsMapLayer *vpcLayer = new QgsPointCloudLayer( testDataPath( "/point_clouds/virtual/sunshine-coast/combined-with-overview.vpc" ), "vpc", "vpc" );
QgsPointCloudLayer3DRenderer *renderer = new QgsPointCloudLayer3DRenderer;
QgsSingleColorPointCloud3DSymbol *symbol = new QgsSingleColorPointCloud3DSymbol;
symbol->setSingleColor( QColor( 255, 0, 0 ) );
renderer->setSymbol( symbol );
vpcLayer->setRenderer3D( renderer );
const QgsRectangle fullExtent = vpcLayer->extent();

Qgs3DMapSettings *mapSettings = new Qgs3DMapSettings;
mapSettings->setCrs( vpcLayer->crs() );
mapSettings->setExtent( fullExtent );
mapSettings->setLayers( QList<QgsMapLayer *>() << vpcLayer );

QgsFlatTerrainGenerator *flatTerrain = new QgsFlatTerrainGenerator;
flatTerrain->setCrs( mapSettings->crs(), QgsCoordinateTransformContext() );
mapSettings->setTerrainGenerator( flatTerrain );

constexpr QPoint winSize = QPoint( 640, 480 ); // default window size
QgsOffscreen3DEngine engine;
engine.setSize( QSize( winSize.x(), winSize.y() ) );
Qgs3DMapScene *scene = new Qgs3DMapScene( *mapSettings, &engine );
engine.setRootEntity( scene );

// compare virtual point cloud layer
scene->viewZoomFull();
QGSCOMPARENEAR( scene->cameraController()->distance(), 86, 1 );

QgsMapLayer *pcLayer = new QgsPointCloudLayer( testDataPath( "/point_clouds/copc/sunshine-coast.copc.laz" ), "test", "copc" );
QgsPointCloudLayer3DRenderer *renderer2 = new QgsPointCloudLayer3DRenderer;
QgsSingleColorPointCloud3DSymbol *symbol2 = new QgsSingleColorPointCloud3DSymbol;
symbol2->setSingleColor( QColor( 255, 0, 0 ) );
renderer2->setSymbol( symbol2 );
pcLayer->setRenderer3D( renderer2 );
mapSettings->setLayers( QList<QgsMapLayer *>() << pcLayer );
scene->cameraController()->setViewFromTop( 0, 0, 10 );

// compare point cloud layer
scene->viewZoomFull();
QGSCOMPARENEAR( scene->cameraController()->distance(), 86, 1 );

delete vpcLayer;
delete pcLayer;
}

QGSTEST_MAIN( TestQgs3DCameraController )
#include "testqgs3dcameracontroller.moc"

0 comments on commit 4e14214

Please sign in to comment.