From 1f94f9bc4ee6d475915fbe2265a1869a33c90c62 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 27 Aug 2024 09:33:17 +1000 Subject: [PATCH] Rework to use Qgs3DRenderContext instead --- CMakeLists.txt | 2 +- .../3d/auto_generated/qgs3dmapsettings.sip.in | 3 +- .../qgspointcloudlayer3drenderer.sip.in | 1 - .../3d/auto_generated/qgs3dmapsettings.sip.in | 3 +- .../qgspointcloudlayer3drenderer.sip.in | 1 - src/3d/CMakeLists.txt | 4 +- src/3d/mesh/qgsmesh3dentity_p.cpp | 31 ++++++------ src/3d/mesh/qgsmesh3dentity_p.h | 10 ++-- src/3d/mesh/qgsmeshterraingenerator.cpp | 6 +-- src/3d/mesh/qgsmeshterraingenerator.h | 2 +- src/3d/qgs3dmapsettings.cpp | 22 +-------- src/3d/qgs3dmapsettings.h | 10 +--- ...ngssnapshot.cpp => qgs3drendercontext.cpp} | 28 +++++++++-- ...ettingssnapshot.h => qgs3drendercontext.h} | 47 ++++++++++++++++--- src/3d/qgs3dutils.cpp | 29 +++++------- src/3d/qgs3dutils.h | 9 ++-- src/3d/qgsfeature3dhandler_p.h | 47 +------------------ src/3d/qgsmeshlayer3drenderer.cpp | 3 +- src/3d/qgspointcloudlayer3drenderer.cpp | 16 +++---- src/3d/qgspointcloudlayer3drenderer.h | 9 ++-- src/3d/qgspointcloudlayerchunkloader_p.cpp | 30 ++++++------ src/3d/qgspointcloudlayerchunkloader_p.h | 7 ++- src/3d/qgsrubberband3d.cpp | 5 +- src/3d/qgsrulebased3drenderer.cpp | 5 +- src/3d/qgsrulebasedchunkloader_p.cpp | 15 +++--- src/3d/qgsrulebasedchunkloader_p.h | 6 +-- src/3d/qgstiledscenechunkloader_p.cpp | 20 ++++---- src/3d/qgstiledscenechunkloader_p.h | 8 ++-- src/3d/qgstiledscenelayer3drenderer.cpp | 2 +- src/3d/qgsvectorlayerchunkloader_p.cpp | 25 +++++----- src/3d/qgsvectorlayerchunkloader_p.h | 7 ++- src/3d/qgsvirtualpointcloudentity_p.cpp | 10 ++-- src/3d/qgsvirtualpointcloudentity_p.h | 6 +-- src/3d/symbols/qgsline3dsymbol_p.cpp | 14 +++--- src/3d/symbols/qgslinevertexdata_p.cpp | 20 ++++---- src/3d/symbols/qgslinevertexdata_p.h | 6 +-- .../symbols/qgspoint3dbillboardmaterial.cpp | 23 +++++---- src/3d/symbols/qgspoint3dbillboardmaterial.h | 11 ++--- src/3d/symbols/qgspoint3dsymbol_p.cpp | 31 ++++++------ src/3d/symbols/qgspoint3dsymbol_p.h | 3 +- src/3d/symbols/qgspointcloud3dsymbol_p.cpp | 20 ++++---- src/3d/symbols/qgspolygon3dsymbol_p.cpp | 12 ++--- src/3d/terrain/qgsdemterraingenerator.cpp | 4 +- src/3d/terrain/qgsdemterraingenerator.h | 5 +- src/3d/terrain/qgsonlineterraingenerator.cpp | 4 +- src/3d/terrain/qgsonlineterraingenerator.h | 2 +- src/3d/terrain/qgsterraingenerator.cpp | 4 +- src/3d/terrain/qgsterraingenerator.h | 4 +- src/core/qgsthreadingutils.h | 10 ++++ tests/src/3d/testqgsmesh3drendering.cpp | 5 +- 50 files changed, 288 insertions(+), 319 deletions(-) rename src/3d/{qgs3dmapsettingssnapshot.cpp => qgs3drendercontext.cpp} (50%) rename src/3d/{qgs3dmapsettingssnapshot.h => qgs3drendercontext.h} (83%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 698a0424cb0..4ef230b3f29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1103,7 +1103,7 @@ if (WITH_CORE AND WITH_BINDINGS) include(SIPMacros) set(SIP_INCLUDES ${PYQT_SIP_DIR} ${CMAKE_SOURCE_DIR}/python) - set(SIP_CONCAT_PARTS 25) + set(SIP_CONCAT_PARTS 22) if (NOT BINDINGS_GLOBAL_INSTALL) set(Python_SITEARCH ${QGIS_DATA_DIR}/python) diff --git a/python/3d/auto_generated/qgs3dmapsettings.sip.in b/python/3d/auto_generated/qgs3dmapsettings.sip.in index ececc4a5889..8a8960bad74 100644 --- a/python/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/3d/auto_generated/qgs3dmapsettings.sip.in @@ -20,7 +20,7 @@ Definition of the world. .. warning:: Qgs3DMapSettings are a QObject subclass, and accordingly are not - safe for access across different threads. See Qgs3DMapSettingsSnapshot instead + safe for access across different threads. See Qgs3DRenderContext instead for a safe snapshot of settings from Qgs3DMapSettings. %End @@ -34,7 +34,6 @@ Definition of the world. ~Qgs3DMapSettings(); - void readXml( const QDomElement &elem, const QgsReadWriteContext &context ); %Docstring Reads configuration from a DOM element previously written by :py:func:`~Qgs3DMapSettings.writeXml` diff --git a/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in b/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in index 6035b17815e..333b4926dca 100644 --- a/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in +++ b/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in @@ -10,7 +10,6 @@ - class QgsPointCloudLayer3DRenderer : QgsAbstractPointCloud3DRenderer { %Docstring(signature="appended") diff --git a/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in b/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in index ececc4a5889..8a8960bad74 100644 --- a/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in @@ -20,7 +20,7 @@ Definition of the world. .. warning:: Qgs3DMapSettings are a QObject subclass, and accordingly are not - safe for access across different threads. See Qgs3DMapSettingsSnapshot instead + safe for access across different threads. See Qgs3DRenderContext instead for a safe snapshot of settings from Qgs3DMapSettings. %End @@ -34,7 +34,6 @@ Definition of the world. ~Qgs3DMapSettings(); - void readXml( const QDomElement &elem, const QgsReadWriteContext &context ); %Docstring Reads configuration from a DOM element previously written by :py:func:`~Qgs3DMapSettings.writeXml` diff --git a/python/PyQt6/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in b/python/PyQt6/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in index 6035b17815e..333b4926dca 100644 --- a/python/PyQt6/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in +++ b/python/PyQt6/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in @@ -10,7 +10,6 @@ - class QgsPointCloudLayer3DRenderer : QgsAbstractPointCloud3DRenderer { %Docstring(signature="appended") diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index ade3975705e..79191decd0e 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -13,9 +13,9 @@ set(QGIS_3D_SRCS qgs3dmapexportsettings.cpp qgs3dmapscene.cpp qgs3dmapsettings.cpp - qgs3dmapsettingssnapshot.cpp qgs3dmaptool.cpp qgs3dmapcanvas.cpp + qgs3drendercontext.cpp qgs3dsceneexporter.cpp qgs3dutils.cpp qgs3dwiredmesh_p.cpp @@ -121,8 +121,8 @@ set(QGIS_3D_HDRS qgs3daxissettings.h qgs3dmapscene.h qgs3dmapsettings.h - qgs3dmapsettingssnapshot.h qgs3dmaptool.h + qgs3drendercontext.h qgs3dsceneexporter.h qgs3dtypes.h qgs3dutils.h diff --git a/src/3d/mesh/qgsmesh3dentity_p.cpp b/src/3d/mesh/qgsmesh3dentity_p.cpp index c238ab915b9..31574981182 100644 --- a/src/3d/mesh/qgsmesh3dentity_p.cpp +++ b/src/3d/mesh/qgsmesh3dentity_p.cpp @@ -20,25 +20,25 @@ #include #include "qgsmeshlayer.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" #include "qgsmesh3dmaterial_p.h" -QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DMapSettingsSnapshot &map, +QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DRenderContext &context, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol ) - : mMapSettings( map ) + : mRenderContext( context ) , mTriangularMesh( triangularMesh ) , mSymbol( symbol->clone() ) {} QgsMeshDataset3DEntity::QgsMeshDataset3DEntity( - const Qgs3DMapSettingsSnapshot &map, + const Qgs3DRenderContext &context, const QgsTriangularMesh &triangularMesh, QgsMeshLayer *meshLayer, const QgsMesh3DSymbol *symbol ) - : QgsMesh3DEntity( map, triangularMesh, symbol ), + : QgsMesh3DEntity( context, triangularMesh, symbol ), mLayerRef( meshLayer ) {} @@ -54,7 +54,7 @@ void QgsMeshDataset3DEntity::buildGeometry() return; Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer; - mesh->setGeometry( new QgsMeshDataset3DGeometry( mTriangularMesh, layer(), mMapSettings.temporalRange(), mMapSettings.origin(), mMapSettings.extent(), mSymbol.get(), mesh ) ); + mesh->setGeometry( new QgsMeshDataset3DGeometry( mTriangularMesh, layer(), mRenderContext.temporalRange(), mRenderContext.origin(), mRenderContext.extent(), mSymbol.get(), mesh ) ); addComponent( mesh ); } @@ -67,7 +67,7 @@ void QgsMeshDataset3DEntity::applyMaterial() if ( datasetGroupIndex >= 0 ) mSymbol->setColorRampShader( rendererSettings.scalarSettings( datasetGroupIndex ).colorRampShader() ); } - QgsMesh3DMaterial *material = new QgsMesh3DMaterial( layer(), mMapSettings.temporalRange(), mMapSettings.origin(), mSymbol.get(), QgsMesh3DMaterial::ScalarDataSet ); + QgsMesh3DMaterial *material = new QgsMesh3DMaterial( layer(), mRenderContext.temporalRange(), mRenderContext.origin(), mSymbol.get(), QgsMesh3DMaterial::ScalarDataSet ); addComponent( material ); } @@ -76,20 +76,19 @@ QgsMeshLayer *QgsMeshDataset3DEntity::layer() const return qobject_cast( mLayerRef.layer.data() ); } -QgsMesh3DTerrainTileEntity::QgsMesh3DTerrainTileEntity( - const Qgs3DMapSettingsSnapshot &map, - const QgsTriangularMesh &triangularMesh, - const QgsMesh3DSymbol *symbol, - QgsChunkNodeId nodeId, - Qt3DCore::QNode *parent ) +QgsMesh3DTerrainTileEntity::QgsMesh3DTerrainTileEntity( const Qgs3DRenderContext &context, + const QgsTriangularMesh &triangularMesh, + const QgsMesh3DSymbol *symbol, + QgsChunkNodeId nodeId, + Qt3DCore::QNode *parent ) : QgsTerrainTileEntity( nodeId, parent ) - , QgsMesh3DEntity( map, triangularMesh, symbol ) + , QgsMesh3DEntity( context, triangularMesh, symbol ) {} void QgsMesh3DTerrainTileEntity::buildGeometry() { Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer; - mesh->setGeometry( new QgsMeshTerrain3DGeometry( mTriangularMesh, mMapSettings.origin(), mMapSettings.extent(), mSymbol.get()->verticalScale(), mesh ) ); + mesh->setGeometry( new QgsMeshTerrain3DGeometry( mTriangularMesh, mRenderContext.origin(), mRenderContext.extent(), mSymbol.get()->verticalScale(), mesh ) ); addComponent( mesh ); } @@ -97,7 +96,7 @@ void QgsMesh3DTerrainTileEntity::applyMaterial() { QgsMesh3DMaterial *material = new QgsMesh3DMaterial( nullptr, QgsDateTimeRange(), - mMapSettings.origin(), + mRenderContext.origin(), mSymbol.get(), QgsMesh3DMaterial::ZValue ); addComponent( material ); diff --git a/src/3d/mesh/qgsmesh3dentity_p.h b/src/3d/mesh/qgsmesh3dentity_p.h index 4fa687d3ec2..88fe32c87fd 100644 --- a/src/3d/mesh/qgsmesh3dentity_p.h +++ b/src/3d/mesh/qgsmesh3dentity_p.h @@ -21,7 +21,7 @@ #include #include "mesh/qgsmesh3dgeometry_p.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" #include "qgsmesh3dsymbol.h" #include "qgsterraintileentity_p.h" @@ -52,13 +52,13 @@ class QgsMesh3DEntity void build(); protected: //! Constructor - QgsMesh3DEntity( const Qgs3DMapSettingsSnapshot &map, + QgsMesh3DEntity( const Qgs3DRenderContext &context, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol ); virtual ~QgsMesh3DEntity() = default; - Qgs3DMapSettingsSnapshot mMapSettings; + Qgs3DRenderContext mRenderContext; QgsTriangularMesh mTriangularMesh; std::unique_ptr< QgsMesh3DSymbol > mSymbol; @@ -74,7 +74,7 @@ class QgsMeshDataset3DEntity: public Qt3DCore::QEntity, public QgsMesh3DEntity public: //! Constructor - QgsMeshDataset3DEntity( const Qgs3DMapSettingsSnapshot &map, + QgsMeshDataset3DEntity( const Qgs3DRenderContext &context, const QgsTriangularMesh &triangularMesh, QgsMeshLayer *meshLayer, const QgsMesh3DSymbol *symbol ); @@ -94,7 +94,7 @@ class QgsMesh3DTerrainTileEntity: public QgsTerrainTileEntity, public QgsMesh3DE Q_OBJECT public: - QgsMesh3DTerrainTileEntity( const Qgs3DMapSettingsSnapshot &map, + QgsMesh3DTerrainTileEntity( const Qgs3DRenderContext &context, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol, QgsChunkNodeId nodeId, diff --git a/src/3d/mesh/qgsmeshterraingenerator.cpp b/src/3d/mesh/qgsmeshterraingenerator.cpp index 88aa2f27658..be164840eb3 100644 --- a/src/3d/mesh/qgsmeshterraingenerator.cpp +++ b/src/3d/mesh/qgsmeshterraingenerator.cpp @@ -23,9 +23,9 @@ #include "qgsmeshlayer.h" #include "qgsmeshlayer3drenderer.h" #include "qgsterrainentity_p.h" -#include "qgsterraintextureimage_p.h" #include "qgsmeshlayerutils.h" #include "qgs3dmapsettings.h" +#include "qgs3drendercontext.h" QgsMeshTerrainTileLoader::QgsMeshTerrainTileLoader( QgsTerrainEntity *terrain, QgsChunkNode *node, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol ) : QgsTerrainTileLoader( terrain, node ) @@ -37,7 +37,7 @@ QgsMeshTerrainTileLoader::QgsMeshTerrainTileLoader( QgsTerrainEntity *terrain, Q Qt3DCore::QEntity *QgsMeshTerrainTileLoader::createEntity( Qt3DCore::QEntity *parent ) { - QgsMesh3DTerrainTileEntity *entity = new QgsMesh3DTerrainTileEntity( terrain()->map3D().snapshot(), mTriangularMesh, mSymbol.get(), mNode->tileId(), parent ); + QgsMesh3DTerrainTileEntity *entity = new QgsMesh3DTerrainTileEntity( Qgs3DRenderContext::fromMapSettings( &( terrain()->map3D() ) ), mTriangularMesh, mSymbol.get(), mNode->tileId(), parent ); entity->build(); createTexture( entity ); @@ -145,7 +145,7 @@ void QgsMeshTerrainGenerator::readXml( const QDomElement &elem ) mSymbol->readXml( elem.firstChildElement( "symbol" ), rwc ); } -float QgsMeshTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot & ) const +float QgsMeshTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext & ) const { return QgsMeshLayerUtils::interpolateZForPoint( mTriangularMesh, x, y ); } diff --git a/src/3d/mesh/qgsmeshterraingenerator.h b/src/3d/mesh/qgsmeshterraingenerator.h index 2e00661010e..652a9d30ec4 100644 --- a/src/3d/mesh/qgsmeshterraingenerator.h +++ b/src/3d/mesh/qgsmeshterraingenerator.h @@ -85,7 +85,7 @@ class _3D_EXPORT QgsMeshTerrainGenerator: public QgsTerrainGenerator QgsRectangle rootChunkExtent() const override; void writeXml( QDomElement &elem ) const override; void readXml( const QDomElement &elem ) override; - float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override; + float heightAt( double x, double y, const Qgs3DRenderContext &context ) const override; private slots: void updateTriangularMesh(); diff --git a/src/3d/qgs3dmapsettings.cpp b/src/3d/qgs3dmapsettings.cpp index 33d8b0df12b..58c6430bfb6 100644 --- a/src/3d/qgs3dmapsettings.cpp +++ b/src/3d/qgs3dmapsettings.cpp @@ -28,8 +28,7 @@ #include "qgsrasterlayer.h" #include "qgspointlightsettings.h" #include "qgsdirectionallightsettings.h" -#include "qgsthreadingutils.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" #include #include @@ -117,25 +116,6 @@ Qgs3DMapSettings::~Qgs3DMapSettings() qDeleteAll( mLightSources ); } -Qgs3DMapSettingsSnapshot Qgs3DMapSettings::snapshot() const -{ - QGIS_PROTECT_QOBJECT_THREAD_ACCESS - - Qgs3DMapSettingsSnapshot res; - res.setCrs( mCrs ); - res.setTransformContext( mTransformContext ); - res.setOrigin( mOrigin ); - res.setExtent( mExtent ); - res.setTemporalRange( temporalRange() ); - res.setSelectionColor( mSelectionColor ); - res.setOutputDpi( mDpi ); - res.setFieldOfView( mFieldOfView ); - res.setTerrainRenderingEnabled( mTerrainRenderingEnabled ); - res.setTerrainVerticalScale( mTerrainVerticalScale ); - res.setTerrainGenerator( mTerrainGenerator.get() ); - return res; -} - void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context ) { QgsProjectDirtyBlocker blocker( QgsProject::instance() ); diff --git a/src/3d/qgs3dmapsettings.h b/src/3d/qgs3dmapsettings.h index eee9c9aeb9b..e09308e6a4c 100644 --- a/src/3d/qgs3dmapsettings.h +++ b/src/3d/qgs3dmapsettings.h @@ -40,7 +40,6 @@ class QgsLightSource; class QgsAbstract3DRenderer; class QgsReadWriteContext; class QgsProject; -class Qgs3DMapSettingsSnapshot; class QDomElement; @@ -49,7 +48,7 @@ class QDomElement; * \brief Definition of the world. * * \warning Qgs3DMapSettings are a QObject subclass, and accordingly are not - * safe for access across different threads. See Qgs3DMapSettingsSnapshot instead + * safe for access across different threads. See Qgs3DRenderContext instead * for a safe snapshot of settings from Qgs3DMapSettings. */ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObject @@ -63,13 +62,6 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec Qgs3DMapSettings &operator=( Qgs3DMapSettings const & ) = delete; - /** - * Returns a snapshot of settings from this object in a thread-safe, cheap-to-copy structure. - * - * \since QGIS 3.40 - */ - Qgs3DMapSettingsSnapshot snapshot() const SIP_SKIP; - //! Reads configuration from a DOM element previously written by writeXml() void readXml( const QDomElement &elem, const QgsReadWriteContext &context ); //! Writes configuration to a DOM element, to be used later with readXml() diff --git a/src/3d/qgs3dmapsettingssnapshot.cpp b/src/3d/qgs3drendercontext.cpp similarity index 50% rename from src/3d/qgs3dmapsettingssnapshot.cpp rename to src/3d/qgs3drendercontext.cpp index 5619c38185e..6019a178b2e 100644 --- a/src/3d/qgs3dmapsettingssnapshot.cpp +++ b/src/3d/qgs3drendercontext.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgs3dmapsettingssnapshot.cpp + qgs3drendercontext.cpp -------------------------------------- Date : August 2024 Copyright : (C) 2024 by Nyall Dawson @@ -13,15 +13,35 @@ * * ***************************************************************************/ -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" #include "qgs3dutils.h" +#include "qgsthreadingutils.h" -QgsVector3D Qgs3DMapSettingsSnapshot::mapToWorldCoordinates( const QgsVector3D &mapCoords ) const +Qgs3DRenderContext Qgs3DRenderContext::fromMapSettings( const Qgs3DMapSettings *mapSettings ) +{ + QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS( mapSettings ); + + Qgs3DRenderContext res; + res.mCrs = mapSettings->crs(); + res.mTransformContext = mapSettings->transformContext(); + res.mOrigin = mapSettings->origin(); + res.mExtent = mapSettings->extent(); + res.mTemporalRange = mapSettings->temporalRange(); + res.mSelectionColor = mapSettings->selectionColor(); + res.mDpi = mapSettings->outputDpi(); + res.mFieldOfView = mapSettings->fieldOfView(); + res.mTerrainRenderingEnabled = mapSettings->terrainRenderingEnabled(); + res.mTerrainVerticalScale = mapSettings->terrainVerticalScale(); + res.mTerrainGenerator = mapSettings->terrainGenerator(); + return res; +} + +QgsVector3D Qgs3DRenderContext::mapToWorldCoordinates( const QgsVector3D &mapCoords ) const { return Qgs3DUtils::mapToWorldCoordinates( mapCoords, mOrigin ); } -QgsVector3D Qgs3DMapSettingsSnapshot::worldToMapCoordinates( const QgsVector3D &worldCoords ) const +QgsVector3D Qgs3DRenderContext::worldToMapCoordinates( const QgsVector3D &worldCoords ) const { return Qgs3DUtils::worldToMapCoordinates( worldCoords, mOrigin ); } diff --git a/src/3d/qgs3dmapsettingssnapshot.h b/src/3d/qgs3drendercontext.h similarity index 83% rename from src/3d/qgs3dmapsettingssnapshot.h rename to src/3d/qgs3drendercontext.h index 5734c29ea75..270c27358b4 100644 --- a/src/3d/qgs3dmapsettingssnapshot.h +++ b/src/3d/qgs3drendercontext.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgs3dmapsettingssnapshot.h + qgs3drendercontext.h -------------------------------------- Date : August 2024 Copyright : (C) 2024 by Nyall Dawson @@ -13,8 +13,8 @@ * * ***************************************************************************/ -#ifndef QGS3DMAPSETTINGSSNAPSHOT_H -#define QGS3DMAPSETTINGSSNAPSHOT_H +#ifndef QGS3DRENDERCONTEXT_H +#define QGS3DRENDERCONTEXT_H #include "qgis_3d.h" #include "qgsvector3d.h" @@ -22,27 +22,36 @@ #include "qgsrange.h" #include "qgscoordinatereferencesystem.h" #include "qgscoordinatetransformcontext.h" +#include "qgsexpressioncontext.h" #include class QgsTerrainGenerator; +class Qgs3DMapSettings; #define SIP_NO_FILE /** * \ingroup 3d - * \brief A snapshot of properties from Qgs3DMapSettings, in a thread-safe, cheap-to-copy structure. + * \brief Rendering context for preparation of 3D entities. + * + * Contains a snapshot of properties from Qgs3DMapSettings, in a thread-safe, cheap-to-copy structure. * * \note Not available in Python bindings. * * \since QGIS 3.40 */ -class _3D_EXPORT Qgs3DMapSettingsSnapshot +class _3D_EXPORT Qgs3DRenderContext { public: - Qgs3DMapSettingsSnapshot() = default; + Qgs3DRenderContext() = default; + + /** + * Creates an initialized Qgs3DRenderContext instance from given Qgs3DMapSettings. + */ + static Qgs3DRenderContext fromMapSettings(const Qgs3DMapSettings* mapSettings ); /** * Sets the coordinate reference system used in the 3D scene @@ -230,6 +239,27 @@ class _3D_EXPORT Qgs3DMapSettingsSnapshot */ QgsTerrainGenerator *terrainGenerator() const { return mTerrainGenerator; } + /** + * Sets the expression context. This context is used for all expression evaluation + * associated with this render context. + * \see expressionContext() + */ + void setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; } + + /** + * Gets the expression context. This context should be used for all expression evaluation + * associated with this render context. + * \see setExpressionContext() + */ + QgsExpressionContext &expressionContext() { return mExpressionContext; } + + /** + * Gets the expression context (const version). This context should be used for all expression evaluation + * associated with this render context. + * \see setExpressionContext() + * \note not available in Python bindings + */ + const QgsExpressionContext &expressionContext() const { return mExpressionContext; } SIP_SKIP private: QgsCoordinateReferenceSystem mCrs; //!< Destination coordinate system of the world @@ -245,10 +275,13 @@ class _3D_EXPORT Qgs3DMapSettingsSnapshot bool mTerrainRenderingEnabled = true; double mTerrainVerticalScale = 1; //!< Multiplier of terrain heights to make the terrain shape more pronounced + //! Expression context + QgsExpressionContext mExpressionContext; + // not owned, currently a pointer to the Qgs3DMapSettings terrain generator. // TODO -- fix during implementation of https://github.com/qgis/QGIS-Enhancement-Proposals/issues/301 QgsTerrainGenerator *mTerrainGenerator = nullptr; //!< Implementation of the terrain generation }; -#endif // QGS3DMAPSETTINGSSNAPSHOT_H +#endif // QGS3DRENDERCONTEXT_H diff --git a/src/3d/qgs3dutils.cpp b/src/3d/qgs3dutils.cpp index c1b268fad81..7e8122ce005 100644 --- a/src/3d/qgs3dutils.cpp +++ b/src/3d/qgs3dutils.cpp @@ -32,11 +32,6 @@ #include "qgschunkedentity_p.h" #include "qgsterrainentity_p.h" #include "qgsraycastingutils_p.h" - -#include "qgsline3dsymbol.h" -#include "qgspoint3dsymbol.h" -#include "qgspolygon3dsymbol.h" - #include "qgspointcloudrenderer.h" #include "qgspointcloud3dsymbol.h" #include "qgspointcloudlayer3drenderer.h" @@ -351,7 +346,7 @@ Qgs3DTypes::CullingMode Qgs3DUtils::cullingModeFromString( const QString &str ) return Qgs3DTypes::NoCulling; } -float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint ¢roid, const Qgs3DMapSettingsSnapshot &map ) +float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint ¢roid, const Qgs3DRenderContext &context ) { float terrainZ = 0; switch ( altClamp ) @@ -360,7 +355,7 @@ float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altCl case Qgis::AltitudeClamping::Terrain: { const QgsPointXY pt = altBind == Qgis::AltitudeBinding::Vertex ? p : centroid; - terrainZ = map.terrainRenderingEnabled() && map.terrainGenerator() ? map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) : 0; + terrainZ = context.terrainRenderingEnabled() && context.terrainGenerator() ? context.terrainGenerator()->heightAt( pt.x(), pt.y(), context ) : 0; break; } @@ -383,11 +378,11 @@ float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altCl } } - const float z = ( terrainZ + geomZ ) * static_cast( map.terrainVerticalScale() ) + offset; + const float z = ( terrainZ + geomZ ) * static_cast( context.terrainVerticalScale() ) + offset; return z; } -void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DMapSettingsSnapshot &map ) +void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DRenderContext &context ) { for ( int i = 0; i < lineString->nCoordinates(); ++i ) { @@ -410,7 +405,7 @@ void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClampi break; } - terrainZ = map.terrainRenderingEnabled() && map.terrainGenerator() ? map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) : 0; + terrainZ = context.terrainRenderingEnabled() && context.terrainGenerator() ? context.terrainGenerator()->heightAt( pt.x(), pt.y(), context ) : 0; break; } @@ -431,13 +426,13 @@ void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClampi break; } - const float z = ( terrainZ + geomZ ) * static_cast( map.terrainVerticalScale() ) + offset; + const float z = ( terrainZ + geomZ ) * static_cast( context.terrainVerticalScale() ) + offset; lineString->setZAt( i, z ); } } -bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettingsSnapshot &map ) +bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DRenderContext &context ) { if ( !polygon->is3D() ) polygon->addZValue( 0 ); @@ -458,7 +453,7 @@ bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping alt if ( !lineString ) return false; - clampAltitudes( lineString, altClamp, altBind, centroid, offset, map ); + clampAltitudes( lineString, altClamp, altBind, centroid, offset, context ); for ( int i = 0; i < polygon->numInteriorRings(); ++i ) { @@ -467,7 +462,7 @@ bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping alt if ( !lineString ) return false; - clampAltitudes( lineString, altClamp, altBind, centroid, offset, map ); + clampAltitudes( lineString, altClamp, altBind, centroid, offset, context ); } return true; } @@ -493,7 +488,7 @@ QMatrix4x4 Qgs3DUtils::stringToMatrix4x4( const QString &str ) return m; } -void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSettingsSnapshot &map, Qgis::AltitudeClamping altClamp, QVector &positions ) +void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DRenderContext &context, Qgis::AltitudeClamping altClamp, QVector &positions ) { const QgsAbstractGeometry *g = f.geometry().constGet(); for ( auto it = g->vertices_begin(); it != g->vertices_end(); ++it ) @@ -504,7 +499,7 @@ void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSetti { geomZ = pt.z(); } - const float terrainZ = map.terrainRenderingEnabled() && map.terrainGenerator() ? map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) * map.terrainVerticalScale() : 0; + const float terrainZ = context.terrainRenderingEnabled() && context.terrainGenerator() ? context.terrainGenerator()->heightAt( pt.x(), pt.y(), context ) * context.terrainVerticalScale() : 0; float h = 0.0f; switch ( altClamp ) { @@ -518,7 +513,7 @@ void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSetti h = terrainZ + geomZ; break; } - positions.append( QVector3D( pt.x() - map.origin().x(), h, -( pt.y() - map.origin().y() ) ) ); + positions.append( QVector3D( pt.x() - context.origin().x(), h, -( pt.y() - context.origin().y() ) ) ); QgsDebugMsgLevel( QStringLiteral( "%1 %2 %3" ).arg( positions.last().x() ).arg( positions.last().y() ).arg( positions.last().z() ), 2 ); } } diff --git a/src/3d/qgs3dutils.h b/src/3d/qgs3dutils.h index 8e9bd1ea739..28d405acac3 100644 --- a/src/3d/qgs3dutils.h +++ b/src/3d/qgs3dutils.h @@ -46,6 +46,7 @@ namespace Qt3DExtras #define SIP_NO_FILE +class Qgs3DRenderContext; /** * \ingroup 3d @@ -130,11 +131,11 @@ class _3D_EXPORT Qgs3DUtils static Qgs3DTypes::CullingMode cullingModeFromString( const QString &str ); //! Clamps altitude of a vertex according to the settings, returns Z value - static float clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint ¢roid, const Qgs3DMapSettingsSnapshot &map ); + static float clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint ¢roid, const Qgs3DRenderContext &context ); //! Clamps altitude of vertices of a linestring according to the settings - static void clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DMapSettingsSnapshot &map ); + static void clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DRenderContext &context ); //! Clamps altitude of vertices of a polygon according to the settings - static bool clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettingsSnapshot &map ); + static bool clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DRenderContext &context ); //! Converts a 4x4 transform matrix to a string static QString matrix4x4toString( const QMatrix4x4 &m ); @@ -142,7 +143,7 @@ class _3D_EXPORT Qgs3DUtils static QMatrix4x4 stringToMatrix4x4( const QString &str ); //! Calculates (x,y,z) positions of (multi)point from the given feature - static void extractPointPositions( const QgsFeature &f, const Qgs3DMapSettingsSnapshot &map, Qgis::AltitudeClamping altClamp, QVector &positions ); + static void extractPointPositions( const QgsFeature &f, const Qgs3DRenderContext &context, Qgis::AltitudeClamping altClamp, QVector &positions ); /** * Returns TRUE if bbox is completely outside the current viewing volume. diff --git a/src/3d/qgsfeature3dhandler_p.h b/src/3d/qgsfeature3dhandler_p.h index 1ae8f8acd9e..a6e3366f8cb 100644 --- a/src/3d/qgsfeature3dhandler_p.h +++ b/src/3d/qgsfeature3dhandler_p.h @@ -31,56 +31,11 @@ class QgsFeature; - -#include "qgsexpressioncontext.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" #define SIP_NO_FILE -/** - * \ingroup 3d - * \brief Rendering context for preparation of 3D entities. - * - * \note Not available in Python bindings - */ -class Qgs3DRenderContext -{ - public: - Qgs3DRenderContext( const Qgs3DMapSettingsSnapshot &map ) : mMap( map ) {} - - const Qgs3DMapSettingsSnapshot &map() const { return mMap; } - - /** - * Sets the expression context. This context is used for all expression evaluation - * associated with this render context. - * \see expressionContext() - */ - void setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; } - - /** - * Gets the expression context. This context should be used for all expression evaluation - * associated with this render context. - * \see setExpressionContext() - */ - QgsExpressionContext &expressionContext() { return mExpressionContext; } - - /** - * Gets the expression context (const version). This context should be used for all expression evaluation - * associated with this render context. - * \see setExpressionContext() - * \note not available in Python bindings - */ - const QgsExpressionContext &expressionContext() const { return mExpressionContext; } SIP_SKIP - - private: - Qgs3DMapSettingsSnapshot mMap; - //! Expression context - QgsExpressionContext mExpressionContext; - -}; - - /** * \ingroup 3d * \brief Interface to be implemented by 3D symbol implementations in order to generate 3D entities. diff --git a/src/3d/qgsmeshlayer3drenderer.cpp b/src/3d/qgsmeshlayer3drenderer.cpp index 3d739e1d553..a50cfcf2e98 100644 --- a/src/3d/qgsmeshlayer3drenderer.cpp +++ b/src/3d/qgsmeshlayer3drenderer.cpp @@ -21,6 +21,7 @@ #include "qgsmeshlayer.h" #include "qgsxmlutils.h" #include "qgsmesh3dentity_p.h" +#include "qgs3drendercontext.h" #include "qgs3dmapsettings.h" QgsMeshLayer3DRendererMetadata::QgsMeshLayer3DRendererMetadata() @@ -92,7 +93,7 @@ Qt3DCore::QEntity *QgsMeshLayer3DRenderer::createEntity( const Qgs3DMapSettings const QgsCoordinateTransform coordTrans( meshLayer->crs(), map.crs(), map.transformContext() ); meshLayer->updateTriangularMesh( coordTrans ); const QgsTriangularMesh triangularMesh = *meshLayer->triangularMeshByLodIndex( mSymbol->levelOfDetailIndex() ); - QgsMeshDataset3DEntity *meshEntity = new QgsMeshDataset3DEntity( map.snapshot(), triangularMesh, meshLayer, mSymbol.get() ); + QgsMeshDataset3DEntity *meshEntity = new QgsMeshDataset3DEntity( Qgs3DRenderContext::fromMapSettings( &map ), triangularMesh, meshLayer, mSymbol.get() ); meshEntity->build(); entity = meshEntity; diff --git a/src/3d/qgspointcloudlayer3drenderer.cpp b/src/3d/qgspointcloudlayer3drenderer.cpp index 8b0c93c6a43..59f3a14692a 100644 --- a/src/3d/qgspointcloudlayer3drenderer.cpp +++ b/src/3d/qgspointcloudlayer3drenderer.cpp @@ -26,8 +26,8 @@ #include "qgspointcloud3dsymbol.h" #include "qgspointcloudlayerelevationproperties.h" -QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr symbol, double zValueScale, double zValueFixedOffset ) - : Qgs3DRenderContext( map ) +QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr symbol, double zValueScale, double zValueFixedOffset ) + : Qgs3DRenderContext( context ) , mSymbol( std::move( symbol ) ) , mZValueScale( zValueScale ) , mZValueFixedOffset( zValueFixedOffset ) @@ -78,22 +78,22 @@ void QgsPointCloud3DRenderContext::cancelRendering() const void QgsPointCloud3DRenderContext::updateExtent() { - if ( map().extent().isEmpty() ) + if ( mLayerExtent.isEmpty() ) { // an empty extent means no filter, so let's pass it without transformation - mExtent = QgsRectangle(); + mLayerExtent = QgsRectangle(); } else { try { - mExtent = mCoordinateTransform.transformBoundingBox( map().extent(), Qgis::TransformDirection::Reverse ); + mLayerExtent = mCoordinateTransform.transformBoundingBox( extent(), Qgis::TransformDirection::Reverse ); } catch ( const QgsCsException & ) { // bad luck, can't reproject for some reason. Let's use an empty extent to skip filtering. QgsDebugError( QStringLiteral( "Transformation of extent failed!" ) ); - mExtent = QgsRectangle(); + mLayerExtent = QgsRectangle(); } } } @@ -161,13 +161,13 @@ Qt3DCore::QEntity *QgsPointCloudLayer3DRenderer::createEntity( const Qgs3DMapSet Qt3DCore::QEntity *entity = nullptr; if ( pcl->dataProvider()->index() ) { - entity = new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), map.snapshot(), coordinateTransform, dynamic_cast( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(), + entity = new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), Qgs3DRenderContext::fromMapSettings( &map ), coordinateTransform, dynamic_cast( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(), static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zScale(), static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zOffset(), mPointBudget ); } else if ( !pcl->dataProvider()->subIndexes().isEmpty() ) { - entity = new QgsVirtualPointCloudEntity( pcl, map.snapshot(), coordinateTransform, dynamic_cast( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(), + entity = new QgsVirtualPointCloudEntity( pcl, Qgs3DRenderContext::fromMapSettings( &map ), coordinateTransform, dynamic_cast( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(), static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zScale(), static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zOffset(), mPointBudget ); } diff --git a/src/3d/qgspointcloudlayer3drenderer.h b/src/3d/qgspointcloudlayer3drenderer.h index 10749d7e062..277782e79f9 100644 --- a/src/3d/qgspointcloudlayer3drenderer.h +++ b/src/3d/qgspointcloudlayer3drenderer.h @@ -27,8 +27,7 @@ class QgsPointCloudLayer; #include "qgspointcloud3dsymbol.h" -#include "qgsfeature3dhandler_p.h" - +#include "qgs3drendercontext.h" #ifndef SIP_RUN /** @@ -52,7 +51,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext * The \a zValueFixedOffset argument specifies any constant offset value which must be added to z values * taken from the point cloud index. */ - QgsPointCloud3DRenderContext( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol, + QgsPointCloud3DRenderContext( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol, double zValueScale, double zValueFixedOffset ); QgsPointCloud3DRenderContext( const QgsPointCloud3DRenderContext &rh ) = delete; @@ -190,7 +189,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext * Returns the 3D scene's extent in layer crs. * \since QGIS 3.30 */ - QgsRectangle extent() const { return mExtent; } + QgsRectangle layerExtent() const { return mLayerExtent; } private: //! Recalculates the 3D scene's extent in layer's crs @@ -205,7 +204,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext double mZValueFixedOffset = 0; QgsCoordinateTransform mCoordinateTransform; std::unique_ptr mFeedback; - QgsRectangle mExtent; + QgsRectangle mLayerExtent; }; diff --git a/src/3d/qgspointcloudlayerchunkloader_p.cpp b/src/3d/qgspointcloudlayerchunkloader_p.cpp index 1393071fe16..35452948c64 100644 --- a/src/3d/qgspointcloudlayerchunkloader_p.cpp +++ b/src/3d/qgspointcloudlayerchunkloader_p.cpp @@ -49,7 +49,7 @@ QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointClou const QgsCoordinateTransform &coordinateTransform, double zValueScale, double zValueOffset ) : QgsChunkLoader( node ) , mFactory( factory ) - , mContext( factory->mMap, coordinateTransform, std::move( symbol ), zValueScale, zValueOffset ) + , mContext( factory->mRenderContext, coordinateTransform, std::move( symbol ), zValueScale, zValueOffset ) { QgsPointCloudIndex *pc = mFactory->mPointCloudIndex; @@ -131,9 +131,9 @@ Qt3DCore::QEntity *QgsPointCloudLayerChunkLoader::createEntity( Qt3DCore::QEntit /////////////// -QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, +QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, double zValueScale, double zValueOffset, int pointBudget ) - : mMap( map ) + : mRenderContext( context ) , mCoordinateTransform( coordinateTransform ) , mPointCloudIndex( pc ) , mZValueScale( zValueScale ) @@ -144,7 +144,7 @@ QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( cons try { - mExtent = mCoordinateTransform.transformBoundingBox( mMap.extent(), Qgis::TransformDirection::Reverse ); + mExtent = mCoordinateTransform.transformBoundingBox( mRenderContext.extent(), Qgis::TransformDirection::Reverse ); } catch ( const QgsCsException & ) { @@ -170,11 +170,11 @@ int QgsPointCloudLayerChunkLoaderFactory::primitivesCount( QgsChunkNode *node ) return mPointCloudIndex->nodePointCount( n ); } -QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ); +QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ); QgsChunkNode *QgsPointCloudLayerChunkLoaderFactory::createRootNode() const { - const QgsAABB bbox = nodeBoundsToAABB( mPointCloudIndex->nodeBounds( IndexedPointCloudNode( 0, 0, 0, 0 ) ), mPointCloudIndex->offset(), mPointCloudIndex->scale(), mMap, mCoordinateTransform, mZValueOffset ); + const QgsAABB bbox = nodeBoundsToAABB( mPointCloudIndex->nodeBounds( IndexedPointCloudNode( 0, 0, 0, 0 ) ), mPointCloudIndex->offset(), mPointCloudIndex->scale(), mRenderContext, mCoordinateTransform, mZValueOffset ); const float error = mPointCloudIndex->nodeError( IndexedPointCloudNode( 0, 0, 0, 0 ) ); QgsChunkNode *node = new QgsChunkNode( QgsChunkNodeId( 0, 0, 0, 0 ), bbox, error ); node->setRefinementProcess( mSymbol->renderAsTriangles() ? Qgis::TileRefinementProcess::Replacement : Qgis::TileRefinementProcess::Additive ); @@ -220,7 +220,7 @@ QVector QgsPointCloudLayerChunkLoaderFactory::createChildren( Qg /////////////// -QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ) +QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ) { QgsVector3D extentMin3D( nodeBounds.xMin() * scale.x() + offset.x(), nodeBounds.yMin() * scale.y() + offset.y(), nodeBounds.zMin() * scale.z() + offset.z() + zValueOffset ); QgsVector3D extentMax3D( nodeBounds.xMax() * scale.x() + offset.x(), nodeBounds.yMax() * scale.y() + offset.y(), nodeBounds.zMax() * scale.z() + offset.z() + zValueOffset ); @@ -235,21 +235,21 @@ QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset { QgsDebugError( QStringLiteral( "Error transforming node bounds coordinate" ) ); } - const QgsVector3D worldExtentMin3D = Qgs3DUtils::mapToWorldCoordinates( extentMin3D, map.origin() ); - const QgsVector3D worldExtentMax3D = Qgs3DUtils::mapToWorldCoordinates( extentMax3D, map.origin() ); + const QgsVector3D worldExtentMin3D = Qgs3DUtils::mapToWorldCoordinates( extentMin3D, context.origin() ); + const QgsVector3D worldExtentMax3D = Qgs3DUtils::mapToWorldCoordinates( extentMax3D, context.origin() ); QgsAABB rootBbox( worldExtentMin3D.x(), worldExtentMin3D.y(), worldExtentMin3D.z(), worldExtentMax3D.x(), worldExtentMax3D.y(), worldExtentMax3D.z() ); return rootBbox; } -QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettingsSnapshot &map, +QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maximumScreenSpaceError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget ) : QgsChunkedEntity( maximumScreenSpaceError, - new QgsPointCloudLayerChunkLoaderFactory( map, coordinateTransform, pc, symbol, zValueScale, zValueOffset, pointBudget ), true, pointBudget ) + new QgsPointCloudLayerChunkLoaderFactory( context, coordinateTransform, pc, symbol, zValueScale, zValueOffset, pointBudget ), true, pointBudget ) { setShowBoundingBoxes( showBoundingBoxes ); } @@ -266,8 +266,8 @@ QVector QgsPointCloudLayerChunkedEntity::rayIntersec QgsPointCloudLayerChunkLoaderFactory *factory = static_cast( mChunkLoaderFactory ); // transform ray - const QgsVector3D rayOriginMapCoords = factory->mMap.worldToMapCoordinates( ray.origin() ); - const QgsVector3D pointMapCoords = factory->mMap.worldToMapCoordinates( ray.origin() + ray.origin().length() * ray.direction().normalized() ); + const QgsVector3D rayOriginMapCoords = factory->mRenderContext.worldToMapCoordinates( ray.origin() ); + const QgsVector3D pointMapCoords = factory->mRenderContext.worldToMapCoordinates( ray.origin() + ray.origin().length() * ray.direction().normalized() ); QgsVector3D rayDirectionMapCoords = pointMapCoords - rayOriginMapCoords; rayDirectionMapCoords.normalize(); @@ -282,7 +282,7 @@ QVector QgsPointCloudLayerChunkedEntity::rayIntersec // We're using the angle as a tolerance, effectively meaning we're fetching points intersecting a cone. // This may be revisited to use a cylinder instead, if the balance between near/far points does not scale // well with different point sizes, screen sizes and fov values. - const double limitAngle = 2. * pointSize / screenSizePx * factory->mMap.fieldOfView(); + const double limitAngle = 2. * pointSize / screenSizePx * factory->mRenderContext.fieldOfView(); // adjust ray to elevation properties const QgsVector3D adjustedRayOrigin = QgsVector3D( rayOriginMapCoords.x(), rayOriginMapCoords.y(), ( rayOriginMapCoords.z() - factory->mZValueOffset ) / factory->mZValueScale ); @@ -361,7 +361,7 @@ QVector QgsPointCloudLayerChunkedEntity::rayIntersec pointAttr[ QStringLiteral( "Y" ) ] = y; pointAttr[ QStringLiteral( "Z" ) ] = z; - const QgsVector3D worldPoint = factory->mMap.mapToWorldCoordinates( point ); + const QgsVector3D worldPoint = factory->mRenderContext.mapToWorldCoordinates( point ); QgsRayCastingUtils::RayHit hit( dist, worldPoint.toVector3D(), FID_NULL, pointAttr ); if ( context.singleResult ) result.clear(); diff --git a/src/3d/qgspointcloudlayerchunkloader_p.h b/src/3d/qgspointcloudlayerchunkloader_p.h index c8add0cbb4a..4f0418b8d6b 100644 --- a/src/3d/qgspointcloudlayerchunkloader_p.h +++ b/src/3d/qgspointcloudlayerchunkloader_p.h @@ -28,7 +28,6 @@ // #include "qgschunkloader_p.h" -#include "qgsfeature3dhandler_p.h" #include "qgschunkedentity_p.h" #include "qgspointcloud3dsymbol.h" #include "qgspointcloud3dsymbol_p.h" @@ -66,7 +65,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory * Constructs the factory * The factory takes ownership over the passed \a symbol */ - QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, + QgsPointCloudLayerChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, double zValueScale, double zValueOffset, int pointBudget ); //! Creates loader for the given chunk node. Ownership of the returned is passed to the caller. @@ -74,7 +73,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory virtual QgsChunkNode *createRootNode() const override; virtual QVector createChildren( QgsChunkNode *node ) const override; virtual int primitivesCount( QgsChunkNode *node ) const override; - Qgs3DMapSettingsSnapshot mMap; + Qgs3DRenderContext mRenderContext; QgsCoordinateTransform mCoordinateTransform; QgsPointCloudIndex *mPointCloudIndex; std::unique_ptr< QgsPointCloud3DSymbol > mSymbol; @@ -133,7 +132,7 @@ class QgsPointCloudLayerChunkedEntity : public QgsChunkedEntity { Q_OBJECT public: - explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, + explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget ); QVector rayIntersection( const QgsRayCastingUtils::Ray3D &ray, const QgsRayCastingUtils::RayCastContext &context ) const override; diff --git a/src/3d/qgsrubberband3d.cpp b/src/3d/qgsrubberband3d.cpp index f43a6db200a..b8a938400dd 100644 --- a/src/3d/qgsrubberband3d.cpp +++ b/src/3d/qgsrubberband3d.cpp @@ -24,6 +24,7 @@ #include "qgsvertexid.h" #include "qgslinestring.h" #include "qgssymbollayer.h" +#include "qgs3dmapsettings.h" #include @@ -167,7 +168,7 @@ void QgsRubberBand3D::updateGeometry() { QgsLineVertexData lineData; lineData.withAdjacency = true; - lineData.init( Qgis::AltitudeClamping::Absolute, Qgis::AltitudeBinding::Vertex, 0, mMapSettings->snapshot() ); + lineData.init( Qgis::AltitudeClamping::Absolute, Qgis::AltitudeBinding::Vertex, 0, Qgs3DRenderContext::fromMapSettings( mMapSettings ) ); lineData.addLineString( mLineString ); mPositionAttribute->buffer()->setData( lineData.createVertexBuffer() ); @@ -189,7 +190,7 @@ void QgsRubberBand3D::updateMarkerMaterial() { delete mMarkerMaterial; mMarkerMaterial = new QgsPoint3DBillboardMaterial(); - mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol, mMapSettings->snapshot() ); + mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol, Qgs3DRenderContext::fromMapSettings( mMapSettings ) ); mMarkerEntity->addComponent( mMarkerMaterial ); //TODO: QgsAbstract3DEngine::sizeChanged should have const QSize &size param diff --git a/src/3d/qgsrulebased3drenderer.cpp b/src/3d/qgsrulebased3drenderer.cpp index 827cfcf5d6f..891dc2e7c2c 100644 --- a/src/3d/qgsrulebased3drenderer.cpp +++ b/src/3d/qgsrulebased3drenderer.cpp @@ -20,10 +20,7 @@ #include "qgs3dmapsettings.h" #include "qgs3dutils.h" -#include "qgsline3dsymbol.h" -#include "qgspoint3dsymbol.h" -#include "qgspolygon3dsymbol.h" - +#include "qgsfeature3dhandler_p.h" #include "qgsrulebasedchunkloader_p.h" #include "qgsapplication.h" #include "qgs3dsymbolregistry.h" diff --git a/src/3d/qgsrulebasedchunkloader_p.cpp b/src/3d/qgsrulebasedchunkloader_p.cpp index 66f86f59759..6cbd0ee7b87 100644 --- a/src/3d/qgsrulebasedchunkloader_p.cpp +++ b/src/3d/qgsrulebasedchunkloader_p.cpp @@ -39,7 +39,7 @@ QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderFactory *factory, QgsChunkNode *node ) : QgsChunkLoader( node ) , mFactory( factory ) - , mContext( factory->mMap ) + , mContext( factory->mRenderContext ) , mSource( new QgsVectorLayerFeatureSource( factory->mLayer ) ) { if ( node->level() < mFactory->mLeafLevel ) @@ -49,7 +49,6 @@ QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderF } QgsVectorLayer *layer = mFactory->mLayer; - const Qgs3DMapSettingsSnapshot &map = mFactory->mMap; QgsExpressionContext exprContext( Qgs3DUtils::globalProjectLayerExpressionContext( layer ) ); exprContext.setFields( layer->fields() ); @@ -68,11 +67,11 @@ QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderF // build the feature request QgsFeatureRequest req; - req.setDestinationCrs( map.crs(), map.transformContext() ); + req.setDestinationCrs( mContext.crs(), mContext.transformContext() ); req.setSubsetOfAttributes( attributeNames, layer->fields() ); // only a subset of data to be queried - const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), map.origin() ); + const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), mContext.origin() ); req.setFilterRect( rect ); // @@ -165,13 +164,13 @@ Qt3DCore::QEntity *QgsRuleBasedChunkLoader::createEntity( Qt3DCore::QEntity *par /////////////// -QgsRuleBasedChunkLoaderFactory::QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ) - : mMap( map ) +QgsRuleBasedChunkLoaderFactory::QgsRuleBasedChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ) + : mRenderContext( context ) , mLayer( vl ) , mRootRule( rootRule->clone() ) , mLeafLevel( leafLevel ) { - const QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( map.extent(), zMin, zMax, map.origin() ); + const QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( context.extent(), zMin, zMax, context.origin() ); setupQuadtree( rootBbox, -1, leafLevel ); // negative root error means that the node does not contain anything } @@ -187,7 +186,7 @@ QgsChunkLoader *QgsRuleBasedChunkLoaderFactory::createChunkLoader( QgsChunkNode QgsRuleBasedChunkedEntity::QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, double zMin, double zMax, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map ) : QgsChunkedEntity( -1, // max. allowed screen error (negative tau means that we need to go until leaves are reached) - new QgsRuleBasedChunkLoaderFactory( map.snapshot(), vl, rootRule, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true ) + new QgsRuleBasedChunkLoaderFactory( Qgs3DRenderContext::fromMapSettings( &map ), vl, rootRule, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true ) { mTransform = new Qt3DCore::QTransform; if ( applyTerrainOffset() ) diff --git a/src/3d/qgsrulebasedchunkloader_p.h b/src/3d/qgsrulebasedchunkloader_p.h index f64a061fb19..8dd4fba8da4 100644 --- a/src/3d/qgsrulebasedchunkloader_p.h +++ b/src/3d/qgsrulebasedchunkloader_p.h @@ -28,9 +28,9 @@ // #include "qgschunkloader_p.h" -#include "qgsfeature3dhandler_p.h" #include "qgschunkedentity_p.h" #include "qgsrulebased3drenderer.h" +#include "qgs3drendercontext.h" #include #define SIP_NO_FILE @@ -59,13 +59,13 @@ class QgsRuleBasedChunkLoaderFactory : public QgsQuadtreeChunkLoaderFactory public: //! Constructs the factory (vl and rootRule must not be null) - QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ); + QgsRuleBasedChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ); ~QgsRuleBasedChunkLoaderFactory() override; //! Creates loader for the given chunk node. Ownership of the returned is passed to the caller. virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override; - Qgs3DMapSettingsSnapshot mMap; + Qgs3DRenderContext mRenderContext; QgsVectorLayer *mLayer; std::unique_ptr mRootRule; int mLeafLevel; diff --git a/src/3d/qgstiledscenechunkloader_p.cpp b/src/3d/qgstiledscenechunkloader_p.cpp index 7c86e07cd3a..6cf64250b9e 100644 --- a/src/3d/qgstiledscenechunkloader_p.cpp +++ b/src/3d/qgstiledscenechunkloader_p.cpp @@ -93,7 +93,7 @@ QgsTiledSceneChunkLoader::QgsTiledSceneChunkLoader( QgsChunkNode *node, const Qg QgsGltf3DUtils::EntityTransform entityTransform; entityTransform.tileTransform = ( tile.transform() ? *tile.transform() : QgsMatrix4x4() ); entityTransform.tileTransform.translate( tileContent.rtcCenter ); - entityTransform.sceneOriginTargetCrs = mFactory.mMap.origin(); + entityTransform.sceneOriginTargetCrs = mFactory.mRenderContext.origin(); entityTransform.ecefToTargetCrs = &mFactory.mBoundsTransform; entityTransform.zValueScale = zValueScale; entityTransform.zValueOffset = zValueOffset; @@ -136,13 +136,13 @@ Qt3DCore::QEntity *QgsTiledSceneChunkLoader::createEntity( Qt3DCore::QEntity *pa /// -QgsTiledSceneChunkLoaderFactory::QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset ) - : mMap( map ) +QgsTiledSceneChunkLoaderFactory::QgsTiledSceneChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset ) + : mRenderContext( context ) , mIndex( index ) , mZValueScale( zValueScale ) , mZValueOffset( zValueOffset ) { - mBoundsTransform = QgsCoordinateTransform( QgsCoordinateReferenceSystem( "EPSG:4978" ), mMap.crs(), mMap.transformContext() ); + mBoundsTransform = QgsCoordinateTransform( QgsCoordinateReferenceSystem( "EPSG:4978" ), mRenderContext.crs(), mRenderContext.transformContext() ); } QgsChunkLoader *QgsTiledSceneChunkLoaderFactory::createChunkLoader( QgsChunkNode *node ) const @@ -163,8 +163,8 @@ QgsChunkNode *QgsTiledSceneChunkLoaderFactory::nodeForTile( const QgsTiledSceneT if ( hasLargeBounds( t ) ) { // use the full extent of the scene - QgsVector3D v0 = mMap.mapToWorldCoordinates( QgsVector3D( mMap.extent().xMinimum(), mMap.extent().yMinimum(), -100 ) ); - QgsVector3D v1 = mMap.mapToWorldCoordinates( QgsVector3D( mMap.extent().xMaximum(), mMap.extent().yMaximum(), +100 ) ); + QgsVector3D v0 = mRenderContext.mapToWorldCoordinates( QgsVector3D( mRenderContext.extent().xMinimum(), mRenderContext.extent().yMinimum(), -100 ) ); + QgsVector3D v1 = mRenderContext.mapToWorldCoordinates( QgsVector3D( mRenderContext.extent().xMaximum(), mRenderContext.extent().yMaximum(), +100 ) ); QgsAABB aabb( v0.x(), v0.y(), v0.z(), v1.x(), v1.y(), v1.z() ); float err = std::min( 1e6, t.geometricError() ); node = new QgsChunkNode( nodeId, aabb, err, parent ); @@ -174,7 +174,7 @@ QgsChunkNode *QgsTiledSceneChunkLoaderFactory::nodeForTile( const QgsTiledSceneT QgsBox3D box = t.boundingVolume().bounds( mBoundsTransform ); box.setZMinimum( box.zMinimum() * mZValueScale + mZValueOffset ); box.setZMaximum( box.zMaximum() * mZValueScale + mZValueOffset ); - const QgsAABB aabb = aabbConvert( box, mMap.origin() ); + const QgsAABB aabb = aabbConvert( box, mRenderContext.origin() ); node = new QgsChunkNode( nodeId, aabb, t.geometricError(), parent ); } @@ -212,7 +212,7 @@ QVector QgsTiledSceneChunkLoaderFactory::createChildren( QgsChun // TODO: make OBB of our scene in ECEF rather than just using center of the scene? const QgsOrientedBox3D obb = t.boundingVolume().box(); - const QgsPointXY c = mMap.extent().center(); + const QgsPointXY c = mRenderContext.extent().center(); const QgsVector3D cEcef = mBoundsTransform.transform( QgsVector3D( c.x(), c.y(), 0 ), Qgis::TransformDirection::Reverse ); const QgsVector3D ecef2 = cEcef - obb.center(); @@ -318,8 +318,8 @@ void QgsTiledSceneChunkLoaderFactory::prepareChildren( QgsChunkNode *node ) /// -QgsTiledSceneLayerChunkedEntity::QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset ) - : QgsChunkedEntity( maximumScreenError, new QgsTiledSceneChunkLoaderFactory( map, index, zValueScale, zValueOffset ), true ) +QgsTiledSceneLayerChunkedEntity::QgsTiledSceneLayerChunkedEntity( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset ) + : QgsChunkedEntity( maximumScreenError, new QgsTiledSceneChunkLoaderFactory( context, index, zValueScale, zValueOffset ), true ) , mIndex( index ) { setShowBoundingBoxes( showBoundingBoxes ); diff --git a/src/3d/qgstiledscenechunkloader_p.h b/src/3d/qgstiledscenechunkloader_p.h index 5a9c0aaa92f..e69c7fc504b 100644 --- a/src/3d/qgstiledscenechunkloader_p.h +++ b/src/3d/qgstiledscenechunkloader_p.h @@ -33,7 +33,7 @@ #include "qgschunknode_p.h" #include "qgstiledsceneindex.h" #include "qgstiledscenetile.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" #include @@ -80,7 +80,7 @@ class QgsTiledSceneChunkLoaderFactory : public QgsChunkLoaderFactory { Q_OBJECT public: - QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, + QgsTiledSceneChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset ); virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override; @@ -93,7 +93,7 @@ class QgsTiledSceneChunkLoaderFactory : public QgsChunkLoaderFactory QgsChunkNode *nodeForTile( const QgsTiledSceneTile &t, const QgsChunkNodeId &nodeId, QgsChunkNode *parent ) const; void fetchHierarchyForNode( long long nodeId, QgsChunkNode *origNode ); - Qgs3DMapSettingsSnapshot mMap; + Qgs3DRenderContext mRenderContext; QString mRelativePathBase; mutable QgsTiledSceneIndex mIndex; double mZValueScale = 1.0; @@ -118,7 +118,7 @@ class QgsTiledSceneLayerChunkedEntity : public QgsChunkedEntity { Q_OBJECT public: - explicit QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, + explicit QgsTiledSceneLayerChunkedEntity( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset ); ~QgsTiledSceneLayerChunkedEntity(); diff --git a/src/3d/qgstiledscenelayer3drenderer.cpp b/src/3d/qgstiledscenelayer3drenderer.cpp index b4d84e70912..c7ca9c0f879 100644 --- a/src/3d/qgstiledscenelayer3drenderer.cpp +++ b/src/3d/qgstiledscenelayer3drenderer.cpp @@ -66,7 +66,7 @@ Qt3DCore::QEntity *QgsTiledSceneLayer3DRenderer::createEntity( const Qgs3DMapSet QgsTiledSceneIndex index = tsl->dataProvider()->index(); - return new QgsTiledSceneLayerChunkedEntity( map.snapshot(), index, + return new QgsTiledSceneLayerChunkedEntity( Qgs3DRenderContext::fromMapSettings( &map ), index, maximumScreenError(), showBoundingBoxes(), qgis::down_cast< const QgsTiledSceneLayerElevationProperties * >( tsl->elevationProperties() )->zScale(), diff --git a/src/3d/qgsvectorlayerchunkloader_p.cpp b/src/3d/qgsvectorlayerchunkloader_p.cpp index 2632ed19380..9bff43022f1 100644 --- a/src/3d/qgsvectorlayerchunkloader_p.cpp +++ b/src/3d/qgsvectorlayerchunkloader_p.cpp @@ -39,7 +39,7 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkLoaderFactory *factory, QgsChunkNode *node ) : QgsChunkLoader( node ) , mFactory( factory ) - , mContext( factory->mMap ) + , mRenderContext( factory->mRenderContext ) , mSource( new QgsVectorLayerFeatureSource( factory->mLayer ) ) { if ( node->level() < mFactory->mLeafLevel ) @@ -50,7 +50,6 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL QgsVectorLayer *layer = mFactory->mLayer; mLayerName = mFactory->mLayer->name(); - const Qgs3DMapSettingsSnapshot &map = mFactory->mMap; QgsFeature3DHandler *handler = QgsApplication::symbol3DRegistry()->createHandlerForSymbol( layer, mFactory->mSymbol.get() ); if ( !handler ) @@ -62,10 +61,10 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL QgsExpressionContext exprContext( Qgs3DUtils::globalProjectLayerExpressionContext( layer ) ); exprContext.setFields( layer->fields() ); - mContext.setExpressionContext( exprContext ); + mRenderContext.setExpressionContext( exprContext ); QSet attributeNames; - if ( !mHandler->prepare( mContext, attributeNames ) ) + if ( !mHandler->prepare( mRenderContext, attributeNames ) ) { QgsDebugError( QStringLiteral( "Failed to prepare 3D feature handler!" ) ); return; @@ -74,12 +73,12 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL // build the feature request QgsFeatureRequest req; req.setCoordinateTransform( - QgsCoordinateTransform( layer->crs3D(), map.crs(), map.transformContext() ) + QgsCoordinateTransform( layer->crs3D(), mRenderContext.crs(), mRenderContext.transformContext() ) ); req.setSubsetOfAttributes( attributeNames, layer->fields() ); // only a subset of data to be queried - const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), map.origin() ); + const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), mRenderContext.origin() ); req.setFilterRect( rect ); // @@ -98,8 +97,8 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL { if ( mCanceled ) break; - mContext.expressionContext().setFeature( f ); - mHandler->processFeature( f, mContext ); + mRenderContext.expressionContext().setFeature( f ); + mHandler->processFeature( f, mRenderContext ); } } ); @@ -141,7 +140,7 @@ Qt3DCore::QEntity *QgsVectorLayerChunkLoader::createEntity( Qt3DCore::QEntity *p Qt3DCore::QEntity *entity = new Qt3DCore::QEntity( parent ); entity->setObjectName( mLayerName + "_" + mNode->tileId().text() ); - mHandler->finalize( entity, mContext ); + mHandler->finalize( entity, mRenderContext ); // fix the vertical range of the node from the estimated vertical range to the true range if ( mHandler->zMinimum() != std::numeric_limits::max() && mHandler->zMaximum() != std::numeric_limits::lowest() ) @@ -160,13 +159,13 @@ Qt3DCore::QEntity *QgsVectorLayerChunkLoader::createEntity( Qt3DCore::QEntity *p /////////////// -QgsVectorLayerChunkLoaderFactory::QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ) - : mMap( map ) +QgsVectorLayerChunkLoaderFactory::QgsVectorLayerChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ) + : mRenderContext( context ) , mLayer( vl ) , mSymbol( symbol->clone() ) , mLeafLevel( leafLevel ) { - QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( map.extent(), zMin, zMax, map.origin() ); + QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( context.extent(), zMin, zMax, context.origin() ); // add small padding to avoid clipping of point features located at the edge of the bounding box rootBbox.xMin -= 1.0; rootBbox.xMax += 1.0; @@ -188,7 +187,7 @@ QgsChunkLoader *QgsVectorLayerChunkLoaderFactory::createChunkLoader( QgsChunkNod QgsVectorLayerChunkedEntity::QgsVectorLayerChunkedEntity( QgsVectorLayer *vl, double zMin, double zMax, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsAbstract3DSymbol *symbol, const Qgs3DMapSettings &map ) : QgsChunkedEntity( -1, // max. allowed screen error (negative tau means that we need to go until leaves are reached) - new QgsVectorLayerChunkLoaderFactory( map.snapshot(), vl, symbol, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true ) + new QgsVectorLayerChunkLoaderFactory( Qgs3DRenderContext::fromMapSettings( &map ), vl, symbol, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true ) { mTransform = new Qt3DCore::QTransform; if ( applyTerrainOffset() ) diff --git a/src/3d/qgsvectorlayerchunkloader_p.h b/src/3d/qgsvectorlayerchunkloader_p.h index 0c464ce3eb4..0c0cd66d9a9 100644 --- a/src/3d/qgsvectorlayerchunkloader_p.h +++ b/src/3d/qgsvectorlayerchunkloader_p.h @@ -33,7 +33,6 @@ #define SIP_NO_FILE -class Qgs3DMapSettings; class QgsVectorLayer; class QgsVectorLayer3DTilingSettings; class QgsVectorLayerFeatureSource; @@ -61,12 +60,12 @@ class QgsVectorLayerChunkLoaderFactory : public QgsQuadtreeChunkLoaderFactory public: //! Constructs the factory - QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ); + QgsVectorLayerChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ); //! Creates loader for the given chunk node. Ownership of the returned is passed to the caller. virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override; - Qgs3DMapSettingsSnapshot mMap; + Qgs3DRenderContext mRenderContext; QgsVectorLayer *mLayer; std::unique_ptr mSymbol; int mLeafLevel; @@ -96,7 +95,7 @@ class QgsVectorLayerChunkLoader : public QgsChunkLoader private: const QgsVectorLayerChunkLoaderFactory *mFactory; std::unique_ptr mHandler; - Qgs3DRenderContext mContext; + Qgs3DRenderContext mRenderContext; std::unique_ptr mSource; bool mCanceled = false; QFutureWatcher *mFutureWatcher = nullptr; diff --git a/src/3d/qgsvirtualpointcloudentity_p.cpp b/src/3d/qgsvirtualpointcloudentity_p.cpp index 401b29f1eb2..9b5d967c232 100644 --- a/src/3d/qgsvirtualpointcloudentity_p.cpp +++ b/src/3d/qgsvirtualpointcloudentity_p.cpp @@ -23,7 +23,7 @@ QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, - const Qgs3DMapSettingsSnapshot &map, + const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maximumScreenSpaceError, @@ -33,7 +33,7 @@ QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *laye int pointBudget ) : Qgs3DMapSceneEntity( nullptr ) , mLayer( layer ) - , mMap( map ) + , mRenderContext( context ) , mCoordinateTransform( coordinateTransform ) , mZValueScale( zValueScale ) , mZValueOffset( zValueOffset ) @@ -43,14 +43,14 @@ QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *laye { mSymbol.reset( symbol ); mBboxesEntity = new QgsChunkBoundsEntity( this ); - const QgsRectangle mapExtent = Qgs3DUtils::tryReprojectExtent2D( mMap.extent(), mMap.crs(), layer->crs(), mMap.transformContext() ); + const QgsRectangle mapExtent = Qgs3DUtils::tryReprojectExtent2D( mRenderContext.extent(), mRenderContext.crs(), layer->crs(), mRenderContext.transformContext() ); const QVector subIndexes = provider()->subIndexes(); for ( int i = 0; i < subIndexes.size(); ++i ) { const QgsPointCloudSubIndex &si = subIndexes.at( i ); const QgsRectangle intersection = si.extent().intersect( mapExtent ); - mBboxes << Qgs3DUtils::mapToWorldExtent( intersection, si.zRange().lower(), si.zRange().upper(), mMap.origin() ); + mBboxes << Qgs3DUtils::mapToWorldExtent( intersection, si.zRange().lower(), si.zRange().upper(), mRenderContext.origin() ); createChunkedEntityForSubIndex( i ); } @@ -86,7 +86,7 @@ void QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex( int i ) return; QgsPointCloudLayerChunkedEntity *newChunkedEntity = new QgsPointCloudLayerChunkedEntity( si.index(), - mMap, + mRenderContext, mCoordinateTransform, static_cast< QgsPointCloud3DSymbol * >( mSymbol->clone() ), mMaximumScreenSpaceError, diff --git a/src/3d/qgsvirtualpointcloudentity_p.h b/src/3d/qgsvirtualpointcloudentity_p.h index 99a628382eb..7a9da4e114d 100644 --- a/src/3d/qgsvirtualpointcloudentity_p.h +++ b/src/3d/qgsvirtualpointcloudentity_p.h @@ -31,7 +31,7 @@ #include "qgscoordinatetransform.h" #include "qgschunkedentity_p.h" #include "qgs3dmapsceneentity_p.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" class QgsAABB; class QgsChunkBoundsEntity; @@ -57,7 +57,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity Q_OBJECT public: //! Constructs - QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, + QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset, int pointBudget ); //! This is called when the camera moves. It's responsible for loading new indexes and decides if subindex will be rendered as bbox or chunked entity. @@ -96,7 +96,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity QMap mChunkedEntitiesMap; QgsChunkBoundsEntity *mBboxesEntity = nullptr; QList mBboxes; - Qgs3DMapSettingsSnapshot mMap; + Qgs3DRenderContext mRenderContext; QgsCoordinateTransform mCoordinateTransform; QgsPointCloudIndex *mPointCloudIndex; std::unique_ptr< QgsPointCloud3DSymbol > mSymbol; diff --git a/src/3d/symbols/qgsline3dsymbol_p.cpp b/src/3d/symbols/qgsline3dsymbol_p.cpp index 09536fa2911..6a6c1f87658 100644 --- a/src/3d/symbols/qgsline3dsymbol_p.cpp +++ b/src/3d/symbols/qgsline3dsymbol_p.cpp @@ -99,11 +99,11 @@ bool QgsBufferedLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->materialSettings() ); - outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, + outNormal.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true, false, false, false, texturedMaterialSettings ? texturedMaterialSettings->requiresTextureCoordinates() : false, 3, texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) ); - outSelected.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, + outSelected.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true, false, false, false, texturedMaterialSettings ? texturedMaterialSettings->requiresTextureCoordinates() : false, 3, texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) ); @@ -168,7 +168,7 @@ void QgsBufferedLine3DSymbolHandler::processFeature( const QgsFeature &f, const void QgsBufferedLine3DSymbolHandler::processPolygon( QgsPolygon *polyBuffered, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, LineData &out ) { - Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context.map() ); + Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context ); Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 ); const uint startingTriangleIndex = static_cast( out.tessellator->dataVerticesCount() / 3 ); @@ -201,7 +201,7 @@ void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, cons QgsMaterialContext materialContext; materialContext.setIsSelected( selected ); - materialContext.setSelectionColor( context.map().selectionColor() ); + materialContext.setSelectionColor( context.selectionColor() ); Qt3DRender::QMaterial *mat = mSymbol->materialSettings()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); // extract vertex buffer data from tessellator @@ -272,8 +272,8 @@ bool QgsThickLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QS outNormal.withAdjacency = true; outSelected.withAdjacency = true; - outNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context.map() ); - outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context.map() ); + outNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context ); + outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context ); QSet attrs = mSymbol->dataDefinedProperties().referencedFields( context.expressionContext() ); attributeNames.unite( attrs ); @@ -347,7 +347,7 @@ void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Q // material (only ambient color is used for the color) QgsMaterialContext materialContext; materialContext.setIsSelected( selected ); - materialContext.setSelectionColor( context.map().selectionColor() ); + materialContext.setSelectionColor( context.selectionColor() ); Qt3DRender::QMaterial *mat = mSymbol->materialSettings()->toMaterial( QgsMaterialSettingsRenderingTechnique::Lines, materialContext ); if ( !mat ) { diff --git a/src/3d/symbols/qgslinevertexdata_p.cpp b/src/3d/symbols/qgslinevertexdata_p.cpp index 1a39b15f6c1..2d51a95b9b6 100644 --- a/src/3d/symbols/qgslinevertexdata_p.cpp +++ b/src/3d/symbols/qgslinevertexdata_p.cpp @@ -46,12 +46,12 @@ QgsLineVertexData::QgsLineVertexData() vertices << QVector3D(); } -void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettingsSnapshot &map ) +void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DRenderContext &context ) { altClamping = clamping; altBinding = binding; baseHeight = height; - mapSettings = map; + renderContext = context; } QByteArray QgsLineVertexData::createVertexBuffer() @@ -133,11 +133,11 @@ void QgsLineVertexData::addLineString( const QgsLineString &lineString, float ex for ( int i = 0; i < lineString.vertexCount(); ++i ) { QgsPoint p = lineString.pointN( i ); - float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, mapSettings ); + float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, renderContext ); - vertices << QVector3D( static_cast< float >( p.x() - mapSettings.origin().x() ), + vertices << QVector3D( static_cast< float >( p.x() - renderContext.origin().x() ), z, - static_cast< float >( -( p.y() - mapSettings.origin().y() ) ) ); + static_cast< float >( -( p.y() - renderContext.origin().y() ) ) ); indexes << vertices.count() - 1; } @@ -162,19 +162,19 @@ void QgsLineVertexData::addVerticalLines( const QgsLineString &lineString, float for ( int i = 0; i < lineString.vertexCount(); ++i ) { QgsPoint p = lineString.pointN( i ); - float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, mapSettings ); + float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, renderContext ); float z2 = z + verticalLength; if ( withAdjacency ) indexes << vertices.count(); // add the following vertex (for adjacency) - vertices << QVector3D( static_cast< float >( p.x() - mapSettings.origin().x() ), + vertices << QVector3D( static_cast< float >( p.x() - renderContext.origin().x() ), z, - static_cast< float >( -( p.y() - mapSettings.origin().y() ) ) ); + static_cast< float >( -( p.y() - renderContext.origin().y() ) ) ); indexes << vertices.count() - 1; - vertices << QVector3D( static_cast< float >( p.x() - mapSettings.origin().x() ), + vertices << QVector3D( static_cast< float >( p.x() - renderContext.origin().x() ), z2, - static_cast< float >( -( p.y() - mapSettings.origin().y() ) ) ); + static_cast< float >( -( p.y() - renderContext.origin().y() ) ) ); indexes << vertices.count() - 1; if ( withAdjacency ) diff --git a/src/3d/symbols/qgslinevertexdata_p.h b/src/3d/symbols/qgslinevertexdata_p.h index fb52daf2af3..98b6947528f 100644 --- a/src/3d/symbols/qgslinevertexdata_p.h +++ b/src/3d/symbols/qgslinevertexdata_p.h @@ -33,7 +33,7 @@ #define SIP_NO_FILE #include "qgis.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" namespace Qt3DCore @@ -79,11 +79,11 @@ struct QgsLineVertexData Qgis::AltitudeClamping altClamping = Qgis::AltitudeClamping::Relative; Qgis::AltitudeBinding altBinding = Qgis::AltitudeBinding::Vertex; float baseHeight = 0; - Qgs3DMapSettingsSnapshot mapSettings; + Qgs3DRenderContext renderContext; QgsLineVertexData(); - void init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettingsSnapshot &map ); + void init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DRenderContext &renderContext ); QByteArray createVertexBuffer(); QByteArray createIndexBuffer(); diff --git a/src/3d/symbols/qgspoint3dbillboardmaterial.cpp b/src/3d/symbols/qgspoint3dbillboardmaterial.cpp index d7b1bf0fb4b..ea8994073a4 100644 --- a/src/3d/symbols/qgspoint3dbillboardmaterial.cpp +++ b/src/3d/symbols/qgspoint3dbillboardmaterial.cpp @@ -26,9 +26,8 @@ #include "qgspoint3dbillboardmaterial.h" #include "qgsterraintextureimage_p.h" #include "qgssymbollayerutils.h" -#include "qgs3dmapsettings.h" #include "qgsmarkersymbol.h" -#include "qgs3dmapsettingssnapshot.h" +#include "qgs3drendercontext.h" QgsPoint3DBillboardMaterial::QgsPoint3DBillboardMaterial() : mSize( new Qt3DRender::QParameter( "BB_SIZE", QSizeF( 100, 100 ), this ) ) @@ -114,21 +113,21 @@ void QgsPoint3DBillboardMaterial::setTexture2DFromImage( QImage image, double si setSize( QSizeF( size + size, size + size ) ); } -void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DMapSettingsSnapshot &map, bool selected ) +void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DRenderContext &context, bool selected ) { // Default texture const std::unique_ptr< QgsMarkerSymbol> defaultSymbol( static_cast( QgsSymbol::defaultSymbol( Qgis::GeometryType::Point ) ) ); - setTexture2DFromSymbol( defaultSymbol.get(), map, selected ); + setTexture2DFromSymbol( defaultSymbol.get(), context, selected ); } -void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettingsSnapshot &map, bool selected ) +void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected ) { - QgsRenderContext context; - context.setSelectionColor( map.selectionColor() ); - context.setScaleFactor( map.outputDpi() / 25.4 ); - context.setFlag( Qgis::RenderContextFlag::Antialiasing ); - context.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms ); - const double pixelSize = context.convertToPainterUnits( markerSymbol->size( context ), markerSymbol->sizeUnit() ); + QgsRenderContext context2D; + context2D.setSelectionColor( context.selectionColor() ); + context2D.setScaleFactor( context.outputDpi() / 25.4 ); + context2D.setFlag( Qgis::RenderContextFlag::Antialiasing ); + context2D.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms ); + const double pixelSize = context2D.convertToPainterUnits( markerSymbol->size( context2D ), markerSymbol->sizeUnit() ); // This number is an max estimation ratio between stroke width and symbol size. const double strokeRatio = 0.5; @@ -138,7 +137,7 @@ void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *marke const double minimumExtraSize = 40; const double extraPixel = minimumExtraSize > pixelSize * strokeRatio ? minimumExtraSize : pixelSize * strokeRatio; const int pixelWithExtra = std::ceil( pixelSize + extraPixel ); - const QPixmap symbolPixmap = QgsSymbolLayerUtils::symbolPreviewPixmap( markerSymbol, QSize( pixelWithExtra, pixelWithExtra ), 0, &context, selected ); + const QPixmap symbolPixmap = QgsSymbolLayerUtils::symbolPreviewPixmap( markerSymbol, QSize( pixelWithExtra, pixelWithExtra ), 0, &context2D, selected ); const QImage symbolImage = symbolPixmap.toImage(); const QImage flippedSymbolImage = symbolImage.mirrored(); setTexture2DFromImage( flippedSymbolImage, pixelWithExtra ); diff --git a/src/3d/symbols/qgspoint3dbillboardmaterial.h b/src/3d/symbols/qgspoint3dbillboardmaterial.h index 1cdbe3b3b7e..ec1cb0504f7 100644 --- a/src/3d/symbols/qgspoint3dbillboardmaterial.h +++ b/src/3d/symbols/qgspoint3dbillboardmaterial.h @@ -20,11 +20,10 @@ #include #include -#include "qgs3dmapsettings.h" - #define SIP_NO_FILE class QgsMarkerSymbol; +class Qgs3DRenderContext; /** * \ingroup 3d @@ -52,11 +51,11 @@ class QgsPoint3DBillboardMaterial : public Qt3DRender::QMaterial //! Returns the size of the view port. QSizeF windowSize() const; - //! Set default symbol for the texture with \a map and \a selected parameter for rendering. - void useDefaultSymbol( const Qgs3DMapSettingsSnapshot &map, bool selected = false ); + //! Set default symbol for the texture with \a context and \a selected parameter for rendering. + void useDefaultSymbol( const Qgs3DRenderContext &context, bool selected = false ); - //! Set \a markerSymbol for the texture with \a map and \a selected parameter for rendering. - void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettingsSnapshot &map, bool selected = false ); + //! Set \a markerSymbol for the texture with \a context and \a selected parameter for rendering. + void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected = false ); private: //! Set the texture2D of the billboard from \a image with \a size. diff --git a/src/3d/symbols/qgspoint3dsymbol_p.cpp b/src/3d/symbols/qgspoint3dsymbol_p.cpp index 60d149355d8..a5a5dcdf38e 100644 --- a/src/3d/symbols/qgspoint3dsymbol_p.cpp +++ b/src/3d/symbols/qgspoint3dsymbol_p.cpp @@ -57,8 +57,6 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include "qgspoint3dsymbol.h" -#include "qgs3dmapsettings.h" - #include "qgsapplication.h" #include "qgsvectorlayer.h" #include "qgs3dutils.h" @@ -122,7 +120,7 @@ void QgsInstancedPoint3DSymbolHandler::processFeature( const QgsFeature &feature if ( feature.geometry().isNull() ) return; - Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions ); + Qgs3DUtils::extractPointPositions( feature, context, mSymbol->altitudeClamping(), out.positions ); mFeatureCount++; } @@ -206,7 +204,7 @@ void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co // build the default material QgsMaterialContext materialContext; materialContext.setIsSelected( selected ); - materialContext.setSelectionColor( context.map().selectionColor() ); + materialContext.setSelectionColor( context.selectionColor() ); Qt3DRender::QMaterial *mat = material( mSymbol.get(), materialContext ); // build the entity @@ -409,8 +407,8 @@ class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler private: - static void addSceneEntities( const Qgs3DMapSettingsSnapshot &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ); - static void addMeshEntities( const Qgs3DMapSettingsSnapshot &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ); + static void addSceneEntities( const Qgs3DRenderContext &context, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ); + static void addMeshEntities( const Qgs3DRenderContext &context, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ); static Qt3DCore::QTransform *transform( QVector3D position, const QgsPoint3DSymbol *symbol ); //! temporary data we will pass to the tessellator @@ -445,7 +443,7 @@ void QgsModelPoint3DSymbolHandler::processFeature( const QgsFeature &feature, co if ( feature.geometry().isNull() ) return; - Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions ); + Qgs3DUtils::extractPointPositions( feature, context, mSymbol->altitudeClamping(), out.positions ); mFeatureCount++; } @@ -467,7 +465,7 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const { if ( selected ) { - addMeshEntities( context.map(), out.positions, mSymbol.get(), parent, true ); + addMeshEntities( context, out.positions, mSymbol.get(), parent, true ); } else { @@ -475,20 +473,19 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const if ( mSymbol->shapeProperty( QStringLiteral( "overwriteMaterial" ) ).toBool() || ( mSymbol->materialSettings() && mSymbol->materialSettings()->type() != QLatin1String( "null" ) ) ) { - addMeshEntities( context.map(), out.positions, mSymbol.get(), parent, false ); + addMeshEntities( context, out.positions, mSymbol.get(), parent, false ); } else { - addSceneEntities( context.map(), out.positions, mSymbol.get(), parent ); + addSceneEntities( context, out.positions, mSymbol.get(), parent ); } } } -void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettingsSnapshot &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ) +void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DRenderContext &, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ) { - Q_UNUSED( map ) for ( const QVector3D &position : positions ) { const QString source = QgsApplication::sourceCache()->localFilePath( symbol->shapeProperty( QStringLiteral( "model" ) ).toString() ); @@ -512,7 +509,7 @@ void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettingsSnaps } } -void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettingsSnapshot &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ) +void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DRenderContext &context, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ) { if ( positions.empty() ) return; @@ -520,7 +517,7 @@ void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettingsSnapsh // build the default material QgsMaterialContext materialContext; materialContext.setIsSelected( are_selected ); - materialContext.setSelectionColor( map.selectionColor() ); + materialContext.setSelectionColor( context.selectionColor() ); Qt3DRender::QMaterial *mat = symbol->materialSettings()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext ); // get nodes @@ -604,7 +601,7 @@ void QgsPoint3DBillboardSymbolHandler::processFeature( const QgsFeature &feature if ( feature.geometry().isNull() ) return; - Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions ); + Qgs3DUtils::extractPointPositions( feature, context, mSymbol->altitudeClamping(), out.positions ); mFeatureCount++; } @@ -640,11 +637,11 @@ void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co if ( symbol ) { - billboardMaterial->setTexture2DFromSymbol( symbol, context.map(), selected ); + billboardMaterial->setTexture2DFromSymbol( symbol, context, selected ); } else { - billboardMaterial->useDefaultSymbol( context.map(), selected ); + billboardMaterial->useDefaultSymbol( context, selected ); } // Billboard Transform diff --git a/src/3d/symbols/qgspoint3dsymbol_p.h b/src/3d/symbols/qgspoint3dsymbol_p.h index ab30b55c96f..dbfe54a8a1c 100644 --- a/src/3d/symbols/qgspoint3dsymbol_p.h +++ b/src/3d/symbols/qgspoint3dsymbol_p.h @@ -33,6 +33,7 @@ class QgsPoint3DSymbol; class QgsAbstract3DSymbol; +class Qgs3DRenderContext; namespace Qgs3DSymbolImpl { @@ -40,7 +41,7 @@ namespace Qgs3DSymbolImpl QgsFeature3DHandler *handlerForPoint3DSymbol( QgsVectorLayer *layer, const QgsAbstract3DSymbol *symbol ); //! convenience function to create a complete entity from QgsPolygon3DSymbol (will run getFeatures() on the layer) - Qt3DCore::QEntity *entityForPoint3DSymbol( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol ); + Qt3DCore::QEntity *entityForPoint3DSymbol( const Qgs3DRenderContext &context, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol ); } /// @endcond diff --git a/src/3d/symbols/qgspointcloud3dsymbol_p.cpp b/src/3d/symbols/qgspointcloud3dsymbol_p.cpp index 1e9663383dc..a6c231ded10 100644 --- a/src/3d/symbols/qgspointcloud3dsymbol_p.cpp +++ b/src/3d/symbols/qgspointcloud3dsymbol_p.cpp @@ -20,16 +20,18 @@ #include "qgspointcloud3dsymbol.h" #include "qgspointcloudattribute.h" #include "qgspointcloudrequest.h" -#include "qgs3dmapsettings.h" #include "qgspointcloudindex.h" #include "qgspointcloudblockrequest.h" #include "qgsfeedback.h" +#include "qgsaabb.h" +#include #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include #include #include +#include typedef Qt3DRender::QAttribute Qt3DQAttribute; typedef Qt3DRender::QBuffer Qt3DQBuffer; @@ -568,7 +570,7 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p QgsPointCloudRequest request; request.setAttributes( attributes ); - request.setFilterRect( context.extent() ); + request.setFilterRect( context.layerExtent() ); std::unique_ptr block( pointCloudBlock( pc, n, request, context ) ); if ( !block ) return; @@ -607,7 +609,7 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p alreadyPrintedDebug = true; } } - const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) ); + const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) ); outNormal.positions.push_back( QVector3D( static_cast( point.x() ), static_cast( point.y() ), static_cast( point.z() ) ) ); } } @@ -691,7 +693,7 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, QgsPointCloudRequest request; request.setAttributes( attributes ); - request.setFilterRect( context.extent() ); + request.setFilterRect( context.layerExtent() ); std::unique_ptr block( pointCloudBlock( pc, n, request, context ) ); if ( !block ) return; @@ -727,7 +729,7 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, alreadyPrintedDebug = true; } } - const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) ); + const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) ); outNormal.positions.push_back( QVector3D( static_cast( point.x() ), static_cast( point.y() ), static_cast( point.z() ) ) ); if ( attrIsX ) @@ -796,7 +798,7 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const QgsPointCloudRequest request; request.setAttributes( attributes ); - request.setFilterRect( context.extent() ); + request.setFilterRect( context.layerExtent() ); std::unique_ptr block( pointCloudBlock( pc, n, request, context ) ); if ( !block ) return; @@ -846,7 +848,7 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const alreadyPrintedDebug = true; } } - const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) ); + const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) ); QVector3D color( 0.0f, 0.0f, 0.0f ); @@ -959,7 +961,7 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex QgsPointCloudRequest request; request.setAttributes( attributes ); - request.setFilterRect( context.extent() ); + request.setFilterRect( context.layerExtent() ); std::unique_ptr block( pointCloudBlock( pc, n, request, context ) ); if ( !block ) return; @@ -1010,7 +1012,7 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex alreadyPrintedDebug = true; } } - const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) ); + const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) ); float iParam = 0.0f; if ( attrIsX ) iParam = x; diff --git a/src/3d/symbols/qgspolygon3dsymbol_p.cpp b/src/3d/symbols/qgspolygon3dsymbol_p.cpp index fe6d460c1ef..bdd9e30535c 100644 --- a/src/3d/symbols/qgspolygon3dsymbol_p.cpp +++ b/src/3d/symbols/qgspolygon3dsymbol_p.cpp @@ -17,7 +17,7 @@ #include "qgspolygon3dsymbol.h" #include "qgstessellatedpolygongeometry.h" -#include "qgs3dmapsettings.h" +#include "qgs3drendercontext.h" #include "qgs3dutils.h" #include "qgstessellator.h" #include "qgsphongtexturedmaterialsettings.h" @@ -90,15 +90,15 @@ class QgsPolygon3DSymbolHandler : public QgsFeature3DHandler bool QgsPolygon3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QSet &attributeNames ) { outEdges.withAdjacency = true; - outEdges.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), 0, context.map() ); + outEdges.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), 0, context ); const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->materialSettings() ); - outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol->invertNormals(), mSymbol->addBackFaces(), false, + outNormal.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true, mSymbol->invertNormals(), mSymbol->addBackFaces(), false, texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates(), mSymbol->renderedFacade(), texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) ); - outSelected.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol->invertNormals(), + outSelected.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true, mSymbol->invertNormals(), mSymbol->addBackFaces(), false, texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates(), mSymbol->renderedFacade(), @@ -138,7 +138,7 @@ void QgsPolygon3DSymbolHandler::processPolygon( const QgsPolygon *poly, QgsFeatu } } - Qgs3DUtils::clampAltitudes( polyClone.get(), mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), offset, context.map() ); + Qgs3DUtils::clampAltitudes( polyClone.get(), mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), offset, context ); Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 ); const uint startingTriangleIndex = static_cast( out.tessellator->dataVerticesCount() / 3 ); @@ -311,7 +311,7 @@ Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSy { QgsMaterialContext materialContext; materialContext.setIsSelected( isSelected ); - materialContext.setSelectionColor( context.map().selectionColor() ); + materialContext.setSelectionColor( context.selectionColor() ); const bool dataDefined = mSymbol->materialSettings()->dataDefinedProperties().hasActiveProperties(); Qt3DRender::QMaterial *material = symbol->materialSettings()->toMaterial( dataDefined ? diff --git a/src/3d/terrain/qgsdemterraingenerator.cpp b/src/3d/terrain/qgsdemterraingenerator.cpp index e808daff834..57bcbcd3608 100644 --- a/src/3d/terrain/qgsdemterraingenerator.cpp +++ b/src/3d/terrain/qgsdemterraingenerator.cpp @@ -67,9 +67,9 @@ QgsRectangle QgsDemTerrainGenerator::rootChunkExtent() const return mTerrainTilingScheme.tileToExtent( 0, 0, 0 ); } -float QgsDemTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const +float QgsDemTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext &context ) const { - Q_UNUSED( map ) + Q_UNUSED( context ) if ( mHeightMapGenerator ) return mHeightMapGenerator->heightAt( x, y ); else diff --git a/src/3d/terrain/qgsdemterraingenerator.h b/src/3d/terrain/qgsdemterraingenerator.h index 257aeef8b66..f0cf6064c7d 100644 --- a/src/3d/terrain/qgsdemterraingenerator.h +++ b/src/3d/terrain/qgsdemterraingenerator.h @@ -20,9 +20,6 @@ #include "qgsterraingenerator.h" - -#include - class QgsRasterLayer; class QgsDemHeightMapGenerator; @@ -70,7 +67,7 @@ class _3D_EXPORT QgsDemTerrainGenerator : public QgsTerrainGenerator Type type() const override; QgsRectangle rootChunkExtent() const override; void setExtent( const QgsRectangle &extent ) override; - float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override; + float heightAt( double x, double y, const Qgs3DRenderContext &context ) const override; void writeXml( QDomElement &elem ) const override; void readXml( const QDomElement &elem ) override; void resolveReferences( const QgsProject &project ) override; diff --git a/src/3d/terrain/qgsonlineterraingenerator.cpp b/src/3d/terrain/qgsonlineterraingenerator.cpp index 323088b10e1..f9a379e7c7e 100644 --- a/src/3d/terrain/qgsonlineterraingenerator.cpp +++ b/src/3d/terrain/qgsonlineterraingenerator.cpp @@ -49,9 +49,9 @@ QgsRectangle QgsOnlineTerrainGenerator::rootChunkExtent() const return mTerrainTilingScheme.tileToExtent( 0, 0, 0 ); } -float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const +float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext &context ) const { - Q_UNUSED( map ) + Q_UNUSED( context ) if ( mHeightMapGenerator ) return mHeightMapGenerator->heightAt( x, y ); else diff --git a/src/3d/terrain/qgsonlineterraingenerator.h b/src/3d/terrain/qgsonlineterraingenerator.h index 8f203ed1128..16fe4341d2f 100644 --- a/src/3d/terrain/qgsonlineterraingenerator.h +++ b/src/3d/terrain/qgsonlineterraingenerator.h @@ -63,7 +63,7 @@ class _3D_EXPORT QgsOnlineTerrainGenerator : public QgsTerrainGenerator Type type() const override; QgsRectangle rootChunkExtent() const override; void setExtent( const QgsRectangle &extent ) override; - float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override; + float heightAt( double x, double y, const Qgs3DRenderContext &context ) const override; void writeXml( QDomElement &elem ) const override; void readXml( const QDomElement &elem ) override; //void resolveReferences( const QgsProject &project ) override; diff --git a/src/3d/terrain/qgsterraingenerator.cpp b/src/3d/terrain/qgsterraingenerator.cpp index e8929c15f33..bd1f056b7cf 100644 --- a/src/3d/terrain/qgsterraingenerator.cpp +++ b/src/3d/terrain/qgsterraingenerator.cpp @@ -44,11 +44,11 @@ void QgsTerrainGenerator::rootChunkHeightRange( float &hMin, float &hMax ) const hMax = 400; } -float QgsTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const +float QgsTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext &context ) const { Q_UNUSED( x ) Q_UNUSED( y ) - Q_UNUSED( map ) + Q_UNUSED( context ) return 0.f; } diff --git a/src/3d/terrain/qgsterraingenerator.h b/src/3d/terrain/qgsterraingenerator.h index 461e22c420e..25d8d3e0a14 100644 --- a/src/3d/terrain/qgsterraingenerator.h +++ b/src/3d/terrain/qgsterraingenerator.h @@ -23,7 +23,7 @@ class QgsAABB; class Qgs3DMapSettings; -class Qgs3DMapSettingsSnapshot; +class Qgs3DRenderContext; class QgsRectangle; class QgsTerrainEntity; @@ -88,7 +88,7 @@ class _3D_EXPORT QgsTerrainGenerator : public QgsQuadtreeChunkLoaderFactory virtual void rootChunkHeightRange( float &hMin, float &hMax ) const; //! Returns height at (x,y) in terrain's CRS - virtual float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const; + virtual float heightAt( double x, double y, const Qgs3DRenderContext &context ) const; //! Write terrain generator's configuration to XML virtual void writeXml( QDomElement &elem ) const = 0; diff --git a/src/core/qgsthreadingutils.h b/src/core/qgsthreadingutils.h index 1f9c6305351..0005fbc46dc 100644 --- a/src/core/qgsthreadingutils.h +++ b/src/core/qgsthreadingutils.h @@ -62,6 +62,16 @@ #define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other) do {} while(false);(void)other; #endif +#ifdef __clang_analyzer__ +#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) do {} while(false);(void)other; +#elif defined(AGGRESSIVE_SAFE_MODE) +#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) if ( other->thread() != QThread::currentThread() ) {qFatal( "%s", QStringLiteral("%2 (%1:%3) Access from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), other->objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( other->thread() ), 0, 16 ).toLocal8Bit().constData() ); } +#elif defined(QGISDEBUG) +#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) if ( other->thread() != QThread::currentThread() ) {qWarning() << QStringLiteral("%2 (%1:%3) Access from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), other->objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( other->thread() ), 0, 16 ).toLocal8Bit().constData(); } +#else +#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) do {} while(false);(void)other; +#endif + /** * \ingroup core diff --git a/tests/src/3d/testqgsmesh3drendering.cpp b/tests/src/3d/testqgsmesh3drendering.cpp index bc06081849f..0bc04e422e9 100644 --- a/tests/src/3d/testqgsmesh3drendering.cpp +++ b/tests/src/3d/testqgsmesh3drendering.cpp @@ -30,8 +30,7 @@ #include "qgsoffscreen3dengine.h" #include "qgspointlightsettings.h" #include "qgsproject.h" -#include "qgs3dmapsettingssnapshot.h" - +#include "qgs3drendercontext.h" class TestQgsMesh3DRendering : public QgsTest { @@ -122,7 +121,7 @@ void TestQgsMesh3DRendering::testMeshTerrain() meshTerrain->setLayer( mLayerMeshTerrain ); map->setTerrainGenerator( meshTerrain ); - QCOMPARE( meshTerrain->heightAt( 750, 2500, map->snapshot() ), 500.0 ); + QCOMPARE( meshTerrain->heightAt( 750, 2500, Qgs3DRenderContext::fromMapSettings( map ) ), 500.0 ); QgsOffscreen3DEngine engine; Qgs3DMapScene *scene = new Qgs3DMapScene( *map, &engine );