diff --git a/python/3d/auto_generated/qgs3dmapsettings.sip.in b/python/3d/auto_generated/qgs3dmapsettings.sip.in index ed9fe0385e397..ececc4a5889c9 100644 --- a/python/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/3d/auto_generated/qgs3dmapsettings.sip.in @@ -16,6 +16,12 @@ class Qgs3DMapSettings : QObject, QgsTemporalRangeObject { %Docstring(signature="appended") Definition of the world. + +.. warning:: + + Qgs3DMapSettings are a QObject subclass, and accordingly are not + safe for access across different threads. See Qgs3DMapSettingsSnapshot instead + for a safe snapshot of settings from Qgs3DMapSettings. %End %TypeHeaderCode @@ -28,6 +34,7 @@ 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/qgs3dmapsettings.sip.in b/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in index ed9fe0385e397..ececc4a5889c9 100644 --- a/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in @@ -16,6 +16,12 @@ class Qgs3DMapSettings : QObject, QgsTemporalRangeObject { %Docstring(signature="appended") Definition of the world. + +.. warning:: + + Qgs3DMapSettings are a QObject subclass, and accordingly are not + safe for access across different threads. See Qgs3DMapSettingsSnapshot instead + for a safe snapshot of settings from Qgs3DMapSettings. %End %TypeHeaderCode @@ -28,6 +34,7 @@ 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/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index 7735a3c65ce1e..534ff97f25aaf 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -13,6 +13,7 @@ set(QGIS_3D_SRCS qgs3dmapexportsettings.cpp qgs3dmapscene.cpp qgs3dmapsettings.cpp + qgs3dmapsettingssnapshot.cpp qgs3dmaptool.cpp qgs3dmapcanvas.cpp qgs3dsceneexporter.cpp @@ -117,6 +118,7 @@ set(QGIS_3D_HDRS qgs3daxissettings.h qgs3dmapscene.h qgs3dmapsettings.h + qgs3dmapsettingssnapshot.h qgs3dmaptool.h qgs3dsceneexporter.h qgs3dtypes.h diff --git a/src/3d/mesh/qgsmesh3dentity_p.cpp b/src/3d/mesh/qgsmesh3dentity_p.cpp index e89134bdba69d..c238ab915b9e8 100644 --- a/src/3d/mesh/qgsmesh3dentity_p.cpp +++ b/src/3d/mesh/qgsmesh3dentity_p.cpp @@ -20,12 +20,12 @@ #include #include "qgsmeshlayer.h" -#include "qgs3dmapsettings.h" +#include "qgs3dmapsettingssnapshot.h" #include "qgsmesh3dmaterial_p.h" -QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DMapSettings &map, +QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol ) : mMapSettings( map ) @@ -34,7 +34,7 @@ QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DMapSettings &map, {} QgsMeshDataset3DEntity::QgsMeshDataset3DEntity( - const Qgs3DMapSettings &map, + const Qgs3DMapSettingsSnapshot &map, const QgsTriangularMesh &triangularMesh, QgsMeshLayer *meshLayer, const QgsMesh3DSymbol *symbol ) @@ -77,7 +77,7 @@ QgsMeshLayer *QgsMeshDataset3DEntity::layer() const } QgsMesh3DTerrainTileEntity::QgsMesh3DTerrainTileEntity( - const Qgs3DMapSettings &map, + const Qgs3DMapSettingsSnapshot &map, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol, QgsChunkNodeId nodeId, diff --git a/src/3d/mesh/qgsmesh3dentity_p.h b/src/3d/mesh/qgsmesh3dentity_p.h index 81b7287ecfd38..4fa687d3ec2a7 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 "qgs3dmapsettings.h" +#include "qgs3dmapsettingssnapshot.h" #include "qgsmesh3dsymbol.h" #include "qgsterraintileentity_p.h" @@ -52,13 +52,13 @@ class QgsMesh3DEntity void build(); protected: //! Constructor - QgsMesh3DEntity( const Qgs3DMapSettings &map, + QgsMesh3DEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol ); virtual ~QgsMesh3DEntity() = default; - Qgs3DMapSettings mMapSettings; + Qgs3DMapSettingsSnapshot mMapSettings; QgsTriangularMesh mTriangularMesh; std::unique_ptr< QgsMesh3DSymbol > mSymbol; @@ -74,7 +74,7 @@ class QgsMeshDataset3DEntity: public Qt3DCore::QEntity, public QgsMesh3DEntity public: //! Constructor - QgsMeshDataset3DEntity( const Qgs3DMapSettings &map, + QgsMeshDataset3DEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTriangularMesh &triangularMesh, QgsMeshLayer *meshLayer, const QgsMesh3DSymbol *symbol ); @@ -94,7 +94,7 @@ class QgsMesh3DTerrainTileEntity: public QgsTerrainTileEntity, public QgsMesh3DE Q_OBJECT public: - QgsMesh3DTerrainTileEntity( const Qgs3DMapSettings &map, + QgsMesh3DTerrainTileEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol, QgsChunkNodeId nodeId, diff --git a/src/3d/mesh/qgsmeshterraingenerator.cpp b/src/3d/mesh/qgsmeshterraingenerator.cpp index 7285093b222c6..88aa2f27658a1 100644 --- a/src/3d/mesh/qgsmeshterraingenerator.cpp +++ b/src/3d/mesh/qgsmeshterraingenerator.cpp @@ -25,7 +25,7 @@ #include "qgsterrainentity_p.h" #include "qgsterraintextureimage_p.h" #include "qgsmeshlayerutils.h" - +#include "qgs3dmapsettings.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(), mTriangularMesh, mSymbol.get(), mNode->tileId(), parent ); + QgsMesh3DTerrainTileEntity *entity = new QgsMesh3DTerrainTileEntity( terrain()->map3D().snapshot(), 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 Qgs3DMapSettings & ) const +float QgsMeshTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot & ) const { return QgsMeshLayerUtils::interpolateZForPoint( mTriangularMesh, x, y ); } diff --git a/src/3d/mesh/qgsmeshterraingenerator.h b/src/3d/mesh/qgsmeshterraingenerator.h index c9fb246310f21..2e00661010ea0 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 Qgs3DMapSettings & ) const override; + float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override; private slots: void updateTriangularMesh(); diff --git a/src/3d/qgs3dmapsettings.cpp b/src/3d/qgs3dmapsettings.cpp index 9447f60a7b2d1..33d8b0df12b25 100644 --- a/src/3d/qgs3dmapsettings.cpp +++ b/src/3d/qgs3dmapsettings.cpp @@ -21,9 +21,6 @@ #include "qgsmeshterraingenerator.h" #include "qgsonlineterraingenerator.h" #include "qgsprojectviewsettings.h" -#include "qgsvectorlayer3drenderer.h" -#include "qgsmeshlayer3drenderer.h" -#include "qgspointcloudlayer3drenderer.h" #include "qgsprojectelevationproperties.h" #include "qgsterrainprovider.h" #include "qgslightsource.h" @@ -31,6 +28,8 @@ #include "qgsrasterlayer.h" #include "qgspointlightsettings.h" #include "qgsdirectionallightsettings.h" +#include "qgsthreadingutils.h" +#include "qgs3dmapsettingssnapshot.h" #include #include @@ -118,6 +117,25 @@ 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 c9abdfa3957bb..eee9c9aeb9bc4 100644 --- a/src/3d/qgs3dmapsettings.h +++ b/src/3d/qgs3dmapsettings.h @@ -40,6 +40,7 @@ class QgsLightSource; class QgsAbstract3DRenderer; class QgsReadWriteContext; class QgsProject; +class Qgs3DMapSettingsSnapshot; class QDomElement; @@ -47,6 +48,9 @@ class QDomElement; * \ingroup 3d * \brief Definition of the world. * + * \warning Qgs3DMapSettings are a QObject subclass, and accordingly are not + * safe for access across different threads. See Qgs3DMapSettingsSnapshot instead + * for a safe snapshot of settings from Qgs3DMapSettings. */ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObject { @@ -59,6 +63,13 @@ 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/qgs3dmapsettingssnapshot.cpp new file mode 100644 index 0000000000000..5619c38185eeb --- /dev/null +++ b/src/3d/qgs3dmapsettingssnapshot.cpp @@ -0,0 +1,27 @@ +/*************************************************************************** + qgs3dmapsettingssnapshot.cpp + -------------------------------------- + Date : August 2024 + Copyright : (C) 2024 by Nyall Dawson + Email : nyall dot dawson at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgs3dmapsettingssnapshot.h" +#include "qgs3dutils.h" + +QgsVector3D Qgs3DMapSettingsSnapshot::mapToWorldCoordinates( const QgsVector3D &mapCoords ) const +{ + return Qgs3DUtils::mapToWorldCoordinates( mapCoords, mOrigin ); +} + +QgsVector3D Qgs3DMapSettingsSnapshot::worldToMapCoordinates( const QgsVector3D &worldCoords ) const +{ + return Qgs3DUtils::worldToMapCoordinates( worldCoords, mOrigin ); +} diff --git a/src/3d/qgs3dmapsettingssnapshot.h b/src/3d/qgs3dmapsettingssnapshot.h new file mode 100644 index 0000000000000..5734c29ea75e4 --- /dev/null +++ b/src/3d/qgs3dmapsettingssnapshot.h @@ -0,0 +1,254 @@ +/*************************************************************************** + qgs3dmapsettingssnapshot.h + -------------------------------------- + Date : August 2024 + Copyright : (C) 2024 by Nyall Dawson + Email : nyall dot dawson at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGS3DMAPSETTINGSSNAPSHOT_H +#define QGS3DMAPSETTINGSSNAPSHOT_H + +#include "qgis_3d.h" +#include "qgsvector3d.h" +#include "qgsrectangle.h" +#include "qgsrange.h" +#include "qgscoordinatereferencesystem.h" +#include "qgscoordinatetransformcontext.h" + +#include + +class QgsTerrainGenerator; + +#define SIP_NO_FILE + +/** + * \ingroup 3d + * \brief 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 +{ + + public: + + Qgs3DMapSettingsSnapshot() = default; + + /** + * Sets the coordinate reference system used in the 3D scene + * + * \see crs() + */ + void setCrs( const QgsCoordinateReferenceSystem &crs ) { mCrs = crs; } + + /** + * Returns the coordinate reference system used in the 3D scene. + * + * \see setCrs() + */ + QgsCoordinateReferenceSystem crs() const { return mCrs; } + + /** + * Returns the coordinate transform context, which stores various + * information regarding which datum transforms should be used when transforming points + * from a source to destination coordinate reference system. + * + * \see setTransformContext() + */ + QgsCoordinateTransformContext transformContext() const { return mTransformContext; } + + /** + * Sets the coordinate transform \a context, which stores various + * information regarding which datum transforms should be used when transforming points + * from a source to destination coordinate reference system. + * + * \see transformContext() + */ + void setTransformContext( const QgsCoordinateTransformContext &context ) { mTransformContext = context; } + + /** + * Returns the 3D scene's 2D extent in the 3D scene's CRS + * + * \see crs() + * \see setExtent() + */ + QgsRectangle extent() const { return mExtent; } + + /** + * Sets the 3D scene's 2D \a extent in the 3D scene's CRS, while also setting the scene's origin to the extent's center + * This needs to be called during initialization, as terrain will only be generated + * within this extent and layer 3D data will only be loaded within this extent too. + * + * \see extent() + * \see setOrigin() + * \see setCrs() + */ + void setExtent( const QgsRectangle &extent ) { mExtent = extent; } + + /** + * Sets coordinates in map CRS at which our 3D world has origin (0,0,0) + * + * We move the 3D world origin to the center of the extent of our terrain: this is done + * to minimize the impact of numerical errors when operating with 32-bit floats. + * Unfortunately this is not enough when working with a large area (still results in jitter + * with scenes spanning hundreds of kilometers and zooming in a lot). + * + * Need to look into more advanced techniques like "relative to center" or "relative to eye" + * to improve the precision. + * + * \see origin() + */ + void setOrigin( const QgsVector3D &origin ) { mOrigin = origin; } + + /** + * Returns coordinates in map CRS at which 3D scene has origin (0,0,0) + * + * \see setOrigin() + */ + QgsVector3D origin() const { return mOrigin; } + + /** + * Sets the temporal \a range for the map. + * + * \see temporalRange() + */ + void setTemporalRange( const QgsDateTimeRange &range ) { mTemporalRange = range; } + + /** + * Returns the temporal range for the map. + * + * \see setTemporalRange() + */ + const QgsDateTimeRange &temporalRange() const { return mTemporalRange; } + + /** + * Sets color used for selected features + * + * \see selectionColor() + */ + void setSelectionColor( const QColor &color ) { mSelectionColor = color; } + + /** + * Returns color used for selected features + * + * \see setSelectionColor() + */ + QColor selectionColor() const { return mSelectionColor; } + + /** + * Sets DPI used for conversion between real world units (e.g. mm) and pixels + * + * \see outputDpi() + */ + void setOutputDpi( const double dpi ) {mDpi = dpi;} + + /** + * Returns DPI used for conversion between real world units (e.g. mm) and pixels + * Default value is 96 + * + * \see setOutputDpi() + */ + double outputDpi() const { return mDpi; } + + /** + * Returns the camera lens' field of view. + * + * \see setFieldOfView() + */ + float fieldOfView() const { return mFieldOfView; } + + /** + * Sets the camera lens' field of view. + * + * \see fieldOfView() + */ + void setFieldOfView( const float fieldOfView ) { mFieldOfView = fieldOfView; } + + /** + * Converts map coordinates to 3D world coordinates (applies offset and turns (x,y,z) into (x,-z,y)). + * + * \see worldToMapCoordinates() + */ + QgsVector3D mapToWorldCoordinates( const QgsVector3D &mapCoords ) const; + + /** + * Converts 3D world coordinates to map coordinates (applies offset and turns (x,y,z) into (x,-z,y)). + * + * \see mapToWorldCoordinates() + */ + QgsVector3D worldToMapCoordinates( const QgsVector3D &worldCoords ) const; + + /** + * Returns whether the 2D terrain surface will be rendered. + * \see setTerrainRenderingEnabled() + */ + bool terrainRenderingEnabled() const { return mTerrainRenderingEnabled; } + + /** + * Sets whether the 2D terrain surface will be rendered in. + * \see terrainRenderingEnabled() + */ + void setTerrainRenderingEnabled( bool terrainRenderingEnabled ) { mTerrainRenderingEnabled = terrainRenderingEnabled; } + + /** + * Sets the vertical scale (exaggeration) of terrain. + * (1 = true scale, > 1 = hills get more pronounced) + * + * \see terrainVerticalScale() + */ + void setTerrainVerticalScale( double zScale ) { mTerrainVerticalScale = zScale; } + + /** + * Returns vertical scale (exaggeration) of terrain + * \see setTerrainVerticalScale() + */ + double terrainVerticalScale() const { return mTerrainVerticalScale; } + + /** + * Sets terrain generator. + * + * Ownership is NOT transferred, and belongs to the Qgs3DMapSettings. + * + * \see terrainGenerator() + */ + void setTerrainGenerator( QgsTerrainGenerator *gen ) { mTerrainGenerator = gen; } + + /** + * Returns the terrain generator. + * + * \see setTerrainGenerator() + */ + QgsTerrainGenerator *terrainGenerator() const { return mTerrainGenerator; } + + + private: + QgsCoordinateReferenceSystem mCrs; //!< Destination coordinate system of the world + //! Coordinate transform context + QgsCoordinateTransformContext mTransformContext; + //! Offset in map CRS coordinates at which our 3D world has origin (0,0,0) + QgsVector3D mOrigin; + QgsRectangle mExtent; //!< 2d extent used to limit the 3d view + QgsDateTimeRange mTemporalRange; + QColor mSelectionColor; //!< Color to be used for selected map features + double mDpi = 96; //!< Dot per inch value for the screen / painter + float mFieldOfView = 45.0f; //!< Camera lens field of view value + bool mTerrainRenderingEnabled = true; + double mTerrainVerticalScale = 1; //!< Multiplier of terrain heights to make the terrain shape more pronounced + + // 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 diff --git a/src/3d/qgs3dutils.cpp b/src/3d/qgs3dutils.cpp index 74709da626c2f..c1b268fad8150 100644 --- a/src/3d/qgs3dutils.cpp +++ b/src/3d/qgs3dutils.cpp @@ -351,7 +351,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 Qgs3DMapSettings &map ) +float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint ¢roid, const Qgs3DMapSettingsSnapshot &map ) { float terrainZ = 0; switch ( altClamp ) @@ -387,7 +387,7 @@ float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altCl return z; } -void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DMapSettings &map ) +void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DMapSettingsSnapshot &map ) { for ( int i = 0; i < lineString->nCoordinates(); ++i ) { @@ -437,7 +437,7 @@ void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClampi } -bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettings &map ) +bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettingsSnapshot &map ) { if ( !polygon->is3D() ) polygon->addZValue( 0 ); @@ -493,7 +493,7 @@ QMatrix4x4 Qgs3DUtils::stringToMatrix4x4( const QString &str ) return m; } -void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSettings &map, Qgis::AltitudeClamping altClamp, QVector &positions ) +void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSettingsSnapshot &map, Qgis::AltitudeClamping altClamp, QVector &positions ) { const QgsAbstractGeometry *g = f.geometry().constGet(); for ( auto it = g->vertices_begin(); it != g->vertices_end(); ++it ) diff --git a/src/3d/qgs3dutils.h b/src/3d/qgs3dutils.h index 433c0843b9c39..8e9bd1ea73926 100644 --- a/src/3d/qgs3dutils.h +++ b/src/3d/qgs3dutils.h @@ -130,11 +130,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 Qgs3DMapSettings &map ); + static float clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint ¢roid, const Qgs3DMapSettingsSnapshot &map ); //! 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 Qgs3DMapSettings &map ); + static void clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DMapSettingsSnapshot &map ); //! 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 Qgs3DMapSettings &map ); + static bool clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettingsSnapshot &map ); //! Converts a 4x4 transform matrix to a string static QString matrix4x4toString( const QMatrix4x4 &m ); @@ -142,7 +142,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 Qgs3DMapSettings &map, Qgis::AltitudeClamping altClamp, QVector &positions ); + static void extractPointPositions( const QgsFeature &f, const Qgs3DMapSettingsSnapshot &map, 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 0434ba9998f42..1ae8f8acd9eef 100644 --- a/src/3d/qgsfeature3dhandler_p.h +++ b/src/3d/qgsfeature3dhandler_p.h @@ -33,8 +33,7 @@ class QgsFeature; #include "qgsexpressioncontext.h" - -class Qgs3DMapSettings; +#include "qgs3dmapsettingssnapshot.h" #define SIP_NO_FILE @@ -48,9 +47,9 @@ class Qgs3DMapSettings; class Qgs3DRenderContext { public: - Qgs3DRenderContext( const Qgs3DMapSettings &map ) : mMap( map ) {} + Qgs3DRenderContext( const Qgs3DMapSettingsSnapshot &map ) : mMap( map ) {} - const Qgs3DMapSettings &map() const { return mMap; } + const Qgs3DMapSettingsSnapshot &map() const { return mMap; } /** * Sets the expression context. This context is used for all expression evaluation @@ -75,7 +74,7 @@ class Qgs3DRenderContext const QgsExpressionContext &expressionContext() const { return mExpressionContext; } SIP_SKIP private: - const Qgs3DMapSettings &mMap; + Qgs3DMapSettingsSnapshot mMap; //! Expression context QgsExpressionContext mExpressionContext; diff --git a/src/3d/qgsmeshlayer3drenderer.cpp b/src/3d/qgsmeshlayer3drenderer.cpp index 8a23ad5a87eb5..3d739e1d553ba 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 "qgs3dmapsettings.h" QgsMeshLayer3DRendererMetadata::QgsMeshLayer3DRendererMetadata() : Qgs3DRendererAbstractMetadata( QStringLiteral( "mesh" ) ) @@ -91,7 +92,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, triangularMesh, meshLayer, mSymbol.get() ); + QgsMeshDataset3DEntity *meshEntity = new QgsMeshDataset3DEntity( map.snapshot(), triangularMesh, meshLayer, mSymbol.get() ); meshEntity->build(); entity = meshEntity; diff --git a/src/3d/qgspointcloudlayer3drenderer.cpp b/src/3d/qgspointcloudlayer3drenderer.cpp index 07ff97126f037..500586debde90 100644 --- a/src/3d/qgspointcloudlayer3drenderer.cpp +++ b/src/3d/qgspointcloudlayer3drenderer.cpp @@ -26,7 +26,7 @@ #include "qgspointcloud3dsymbol.h" #include "qgspointcloudlayerelevationproperties.h" -QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr symbol, double zValueScale, double zValueFixedOffset ) +QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr symbol, double zValueScale, double zValueFixedOffset ) : Qgs3DRenderContext( map ) , mSymbol( std::move( symbol ) ) , mZValueScale( zValueScale ) @@ -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, coordinateTransform, dynamic_cast( mSymbol->clone() ), maximumScreenError(), showBoundingBoxes(), + entity = new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), map.snapshot(), coordinateTransform, dynamic_cast( mSymbol->clone() ), 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, coordinateTransform, dynamic_cast( mSymbol->clone() ), maximumScreenError(), showBoundingBoxes(), + entity = new QgsVirtualPointCloudEntity( pcl, map.snapshot(), coordinateTransform, dynamic_cast( mSymbol->clone() ), 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 77789607d9354..10749d7e06213 100644 --- a/src/3d/qgspointcloudlayer3drenderer.h +++ b/src/3d/qgspointcloudlayer3drenderer.h @@ -52,7 +52,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 Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol, + QgsPointCloud3DRenderContext( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol, double zValueScale, double zValueFixedOffset ); QgsPointCloud3DRenderContext( const QgsPointCloud3DRenderContext &rh ) = delete; diff --git a/src/3d/qgspointcloudlayerchunkloader_p.cpp b/src/3d/qgspointcloudlayerchunkloader_p.cpp index cfd55d326eeb0..1393071fe16ae 100644 --- a/src/3d/qgspointcloudlayerchunkloader_p.cpp +++ b/src/3d/qgspointcloudlayerchunkloader_p.cpp @@ -131,7 +131,7 @@ Qt3DCore::QEntity *QgsPointCloudLayerChunkLoader::createEntity( Qt3DCore::QEntit /////////////// -QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, +QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, double zValueScale, double zValueOffset, int pointBudget ) : mMap( map ) , mCoordinateTransform( coordinateTransform ) @@ -170,7 +170,7 @@ int QgsPointCloudLayerChunkLoaderFactory::primitivesCount( QgsChunkNode *node ) return mPointCloudIndex->nodePointCount( n ); } -QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ); +QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ); QgsChunkNode *QgsPointCloudLayerChunkLoaderFactory::createRootNode() const { @@ -220,7 +220,7 @@ QVector QgsPointCloudLayerChunkLoaderFactory::createChildren( Qg /////////////// -QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset ) +QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettingsSnapshot &map, 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 ); @@ -243,7 +243,7 @@ QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset } -QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map, +QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maximumScreenSpaceError, bool showBoundingBoxes, double zValueScale, double zValueOffset, diff --git a/src/3d/qgspointcloudlayerchunkloader_p.h b/src/3d/qgspointcloudlayerchunkloader_p.h index 377182ff260e2..c8add0cbb4abb 100644 --- a/src/3d/qgspointcloudlayerchunkloader_p.h +++ b/src/3d/qgspointcloudlayerchunkloader_p.h @@ -66,7 +66,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory * Constructs the factory * The factory takes ownership over the passed \a symbol */ - QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol, + QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, 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 +74,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory virtual QgsChunkNode *createRootNode() const override; virtual QVector createChildren( QgsChunkNode *node ) const override; virtual int primitivesCount( QgsChunkNode *node ) const override; - const Qgs3DMapSettings &mMap; + Qgs3DMapSettingsSnapshot mMap; QgsCoordinateTransform mCoordinateTransform; QgsPointCloudIndex *mPointCloudIndex; std::unique_ptr< QgsPointCloud3DSymbol > mSymbol; @@ -133,7 +133,7 @@ class QgsPointCloudLayerChunkedEntity : public QgsChunkedEntity { Q_OBJECT public: - explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, + explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettingsSnapshot &map, 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 f314bf8b7dee0..f43a6db200a21 100644 --- a/src/3d/qgsrubberband3d.cpp +++ b/src/3d/qgsrubberband3d.cpp @@ -167,7 +167,7 @@ void QgsRubberBand3D::updateGeometry() { QgsLineVertexData lineData; lineData.withAdjacency = true; - lineData.init( Qgis::AltitudeClamping::Absolute, Qgis::AltitudeBinding::Vertex, 0, mMapSettings ); + lineData.init( Qgis::AltitudeClamping::Absolute, Qgis::AltitudeBinding::Vertex, 0, mMapSettings->snapshot() ); lineData.addLineString( mLineString ); mPositionAttribute->buffer()->setData( lineData.createVertexBuffer() ); @@ -189,7 +189,7 @@ void QgsRubberBand3D::updateMarkerMaterial() { delete mMarkerMaterial; mMarkerMaterial = new QgsPoint3DBillboardMaterial(); - mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol, *mMapSettings ); + mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol, mMapSettings->snapshot() ); mMarkerEntity->addComponent( mMarkerMaterial ); //TODO: QgsAbstract3DEngine::sizeChanged should have const QSize &size param diff --git a/src/3d/qgsrulebasedchunkloader_p.cpp b/src/3d/qgsrulebasedchunkloader_p.cpp index 1407b18273a32..66f86f5975988 100644 --- a/src/3d/qgsrulebasedchunkloader_p.cpp +++ b/src/3d/qgsrulebasedchunkloader_p.cpp @@ -49,7 +49,7 @@ QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderF } QgsVectorLayer *layer = mFactory->mLayer; - const Qgs3DMapSettings &map = mFactory->mMap; + const Qgs3DMapSettingsSnapshot &map = mFactory->mMap; QgsExpressionContext exprContext( Qgs3DUtils::globalProjectLayerExpressionContext( layer ) ); exprContext.setFields( layer->fields() ); @@ -165,7 +165,7 @@ Qt3DCore::QEntity *QgsRuleBasedChunkLoader::createEntity( Qt3DCore::QEntity *par /////////////// -QgsRuleBasedChunkLoaderFactory::QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettings &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ) +QgsRuleBasedChunkLoaderFactory::QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ) : mMap( map ) , mLayer( vl ) , mRootRule( rootRule->clone() ) @@ -187,7 +187,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, vl, rootRule, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true ) + new QgsRuleBasedChunkLoaderFactory( map.snapshot(), 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 02cf6ac03af64..f64a061fb19d3 100644 --- a/src/3d/qgsrulebasedchunkloader_p.h +++ b/src/3d/qgsrulebasedchunkloader_p.h @@ -59,13 +59,13 @@ class QgsRuleBasedChunkLoaderFactory : public QgsQuadtreeChunkLoaderFactory public: //! Constructs the factory (vl and rootRule must not be null) - QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettings &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax ); + QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, 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; - const Qgs3DMapSettings &mMap; + Qgs3DMapSettingsSnapshot mMap; QgsVectorLayer *mLayer; std::unique_ptr mRootRule; int mLeafLevel; diff --git a/src/3d/qgstiledscenechunkloader_p.cpp b/src/3d/qgstiledscenechunkloader_p.cpp index 23fe0b3eb9985..7c86e07cd3a15 100644 --- a/src/3d/qgstiledscenechunkloader_p.cpp +++ b/src/3d/qgstiledscenechunkloader_p.cpp @@ -136,7 +136,7 @@ Qt3DCore::QEntity *QgsTiledSceneChunkLoader::createEntity( Qt3DCore::QEntity *pa /// -QgsTiledSceneChunkLoaderFactory::QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettings &map, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset ) +QgsTiledSceneChunkLoaderFactory::QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset ) : mMap( map ) , mIndex( index ) , mZValueScale( zValueScale ) @@ -318,7 +318,7 @@ void QgsTiledSceneChunkLoaderFactory::prepareChildren( QgsChunkNode *node ) /// -QgsTiledSceneLayerChunkedEntity::QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettings &map, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset ) +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 ) , mIndex( index ) { diff --git a/src/3d/qgstiledscenechunkloader_p.h b/src/3d/qgstiledscenechunkloader_p.h index dd6c95f2c5c0e..5a9c0aaa92fe0 100644 --- a/src/3d/qgstiledscenechunkloader_p.h +++ b/src/3d/qgstiledscenechunkloader_p.h @@ -33,6 +33,7 @@ #include "qgschunknode_p.h" #include "qgstiledsceneindex.h" #include "qgstiledscenetile.h" +#include "qgs3dmapsettingssnapshot.h" #include @@ -79,7 +80,7 @@ class QgsTiledSceneChunkLoaderFactory : public QgsChunkLoaderFactory { Q_OBJECT public: - QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettings &map, const QgsTiledSceneIndex &index, + QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset ); virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override; @@ -92,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 ); - const Qgs3DMapSettings &mMap; + Qgs3DMapSettingsSnapshot mMap; QString mRelativePathBase; mutable QgsTiledSceneIndex mIndex; double mZValueScale = 1.0; @@ -117,7 +118,7 @@ class QgsTiledSceneLayerChunkedEntity : public QgsChunkedEntity { Q_OBJECT public: - explicit QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettings &map, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, + explicit QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettingsSnapshot &map, 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 7fc9c2eff193c..b4d84e70912c1 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, index, + return new QgsTiledSceneLayerChunkedEntity( map.snapshot(), 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 b641baf3d1118..2632ed193804e 100644 --- a/src/3d/qgsvectorlayerchunkloader_p.cpp +++ b/src/3d/qgsvectorlayerchunkloader_p.cpp @@ -50,7 +50,7 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL QgsVectorLayer *layer = mFactory->mLayer; mLayerName = mFactory->mLayer->name(); - const Qgs3DMapSettings &map = mFactory->mMap; + const Qgs3DMapSettingsSnapshot &map = mFactory->mMap; QgsFeature3DHandler *handler = QgsApplication::symbol3DRegistry()->createHandlerForSymbol( layer, mFactory->mSymbol.get() ); if ( !handler ) @@ -160,7 +160,7 @@ Qt3DCore::QEntity *QgsVectorLayerChunkLoader::createEntity( Qt3DCore::QEntity *p /////////////// -QgsVectorLayerChunkLoaderFactory::QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettings &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ) +QgsVectorLayerChunkLoaderFactory::QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ) : mMap( map ) , mLayer( vl ) , mSymbol( symbol->clone() ) @@ -188,7 +188,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, vl, symbol, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true ) + new QgsVectorLayerChunkLoaderFactory( map.snapshot(), 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 38bdeeb0cb989..0c464ce3eb4a1 100644 --- a/src/3d/qgsvectorlayerchunkloader_p.h +++ b/src/3d/qgsvectorlayerchunkloader_p.h @@ -61,12 +61,12 @@ class QgsVectorLayerChunkLoaderFactory : public QgsQuadtreeChunkLoaderFactory public: //! Constructs the factory - QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettings &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax ); + QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, 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; - const Qgs3DMapSettings &mMap; + Qgs3DMapSettingsSnapshot mMap; QgsVectorLayer *mLayer; std::unique_ptr mSymbol; int mLeafLevel; diff --git a/src/3d/qgsvirtualpointcloudentity_p.cpp b/src/3d/qgsvirtualpointcloudentity_p.cpp index 66204dbe5cebe..401b29f1eb258 100644 --- a/src/3d/qgsvirtualpointcloudentity_p.cpp +++ b/src/3d/qgsvirtualpointcloudentity_p.cpp @@ -23,7 +23,7 @@ QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, - const Qgs3DMapSettings &map, + const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maximumScreenSpaceError, diff --git a/src/3d/qgsvirtualpointcloudentity_p.h b/src/3d/qgsvirtualpointcloudentity_p.h index 918b1d529eeab..99a628382eb6e 100644 --- a/src/3d/qgsvirtualpointcloudentity_p.h +++ b/src/3d/qgsvirtualpointcloudentity_p.h @@ -31,6 +31,7 @@ #include "qgscoordinatetransform.h" #include "qgschunkedentity_p.h" #include "qgs3dmapsceneentity_p.h" +#include "qgs3dmapsettingssnapshot.h" class QgsAABB; class QgsChunkBoundsEntity; @@ -56,7 +57,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity Q_OBJECT public: //! Constructs - QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, const Qgs3DMapSettings &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes, + QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, const Qgs3DMapSettingsSnapshot &map, 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. @@ -95,7 +96,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity QMap mChunkedEntitiesMap; QgsChunkBoundsEntity *mBboxesEntity = nullptr; QList mBboxes; - const Qgs3DMapSettings &mMap; + Qgs3DMapSettingsSnapshot mMap; 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 4ff809701fe11..09536fa291181 100644 --- a/src/3d/symbols/qgsline3dsymbol_p.cpp +++ b/src/3d/symbols/qgsline3dsymbol_p.cpp @@ -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.map() ); + outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context.map() ); QSet attrs = mSymbol->dataDefinedProperties().referencedFields( context.expressionContext() ); attributeNames.unite( attrs ); diff --git a/src/3d/symbols/qgslinevertexdata_p.cpp b/src/3d/symbols/qgslinevertexdata_p.cpp index 8cc02f15bdd71..5c0d7cef8df5f 100644 --- a/src/3d/symbols/qgslinevertexdata_p.cpp +++ b/src/3d/symbols/qgslinevertexdata_p.cpp @@ -46,7 +46,7 @@ QgsLineVertexData::QgsLineVertexData() vertices << QVector3D(); } -void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettings *map ) +void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettingsSnapshot &map ) { altClamping = clamping; altBinding = binding; @@ -133,9 +133,9 @@ 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, mapSettings ); - vertices << QVector3D( p.x() - mapSettings->origin().x(), z, -( p.y() - mapSettings->origin().y() ) ); + vertices << QVector3D( p.x() - mapSettings.origin().x(), z, -( p.y() - mapSettings.origin().y() ) ); indexes << vertices.count() - 1; } @@ -160,15 +160,15 @@ 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, mapSettings ); float z2 = z + verticalLength; if ( withAdjacency ) indexes << vertices.count(); // add the following vertex (for adjacency) - vertices << QVector3D( p.x() - mapSettings->origin().x(), z, -( p.y() - mapSettings->origin().y() ) ); + vertices << QVector3D( p.x() - mapSettings.origin().x(), z, -( p.y() - mapSettings.origin().y() ) ); indexes << vertices.count() - 1; - vertices << QVector3D( p.x() - mapSettings->origin().x(), z2, -( p.y() - mapSettings->origin().y() ) ); + vertices << QVector3D( p.x() - mapSettings.origin().x(), z2, -( p.y() - mapSettings.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 fd0272a427bd4..fb52daf2af322 100644 --- a/src/3d/symbols/qgslinevertexdata_p.h +++ b/src/3d/symbols/qgslinevertexdata_p.h @@ -33,6 +33,7 @@ #define SIP_NO_FILE #include "qgis.h" +#include "qgs3dmapsettingssnapshot.h" namespace Qt3DCore @@ -51,7 +52,6 @@ namespace Qt3DRender #endif class QgsLineString; -class Qgs3DMapSettings; /** @@ -79,11 +79,11 @@ struct QgsLineVertexData Qgis::AltitudeClamping altClamping = Qgis::AltitudeClamping::Relative; Qgis::AltitudeBinding altBinding = Qgis::AltitudeBinding::Vertex; float baseHeight = 0; - const Qgs3DMapSettings *mapSettings = nullptr; + Qgs3DMapSettingsSnapshot mapSettings; QgsLineVertexData(); - void init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettings *map ); + void init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettingsSnapshot &map ); QByteArray createVertexBuffer(); QByteArray createIndexBuffer(); diff --git a/src/3d/symbols/qgspoint3dbillboardmaterial.cpp b/src/3d/symbols/qgspoint3dbillboardmaterial.cpp index 57e0ad15b26dd..d7b1bf0fb4b7e 100644 --- a/src/3d/symbols/qgspoint3dbillboardmaterial.cpp +++ b/src/3d/symbols/qgspoint3dbillboardmaterial.cpp @@ -28,6 +28,7 @@ #include "qgssymbollayerutils.h" #include "qgs3dmapsettings.h" #include "qgsmarkersymbol.h" +#include "qgs3dmapsettingssnapshot.h" QgsPoint3DBillboardMaterial::QgsPoint3DBillboardMaterial() : mSize( new Qt3DRender::QParameter( "BB_SIZE", QSizeF( 100, 100 ), this ) ) @@ -113,14 +114,14 @@ void QgsPoint3DBillboardMaterial::setTexture2DFromImage( QImage image, double si setSize( QSizeF( size + size, size + size ) ); } -void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DMapSettings &map, bool selected ) +void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DMapSettingsSnapshot &map, bool selected ) { // Default texture const std::unique_ptr< QgsMarkerSymbol> defaultSymbol( static_cast( QgsSymbol::defaultSymbol( Qgis::GeometryType::Point ) ) ); setTexture2DFromSymbol( defaultSymbol.get(), map, selected ); } -void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettings &map, bool selected ) +void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettingsSnapshot &map, bool selected ) { QgsRenderContext context; context.setSelectionColor( map.selectionColor() ); diff --git a/src/3d/symbols/qgspoint3dbillboardmaterial.h b/src/3d/symbols/qgspoint3dbillboardmaterial.h index b9230c91cadef..1cdbe3b3b7e4d 100644 --- a/src/3d/symbols/qgspoint3dbillboardmaterial.h +++ b/src/3d/symbols/qgspoint3dbillboardmaterial.h @@ -53,10 +53,10 @@ class QgsPoint3DBillboardMaterial : public Qt3DRender::QMaterial QSizeF windowSize() const; //! Set default symbol for the texture with \a map and \a selected parameter for rendering. - void useDefaultSymbol( const Qgs3DMapSettings &map, bool selected = false ); + void useDefaultSymbol( const Qgs3DMapSettingsSnapshot &map, bool selected = false ); //! Set \a markerSymbol for the texture with \a map and \a selected parameter for rendering. - void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettings &map, bool selected = false ); + void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettingsSnapshot &map, 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 8bec1d439723a..60d149355d88b 100644 --- a/src/3d/symbols/qgspoint3dsymbol_p.cpp +++ b/src/3d/symbols/qgspoint3dsymbol_p.cpp @@ -409,8 +409,8 @@ class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler private: - static void addSceneEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ); - static void addMeshEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ); + 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 Qt3DCore::QTransform *transform( QVector3D position, const QgsPoint3DSymbol *symbol ); //! temporary data we will pass to the tessellator @@ -486,7 +486,7 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const -void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ) +void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettingsSnapshot &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent ) { Q_UNUSED( map ) for ( const QVector3D &position : positions ) @@ -512,7 +512,7 @@ void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettings &map } } -void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettings &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ) +void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettingsSnapshot &map, const QVector &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected ) { if ( positions.empty() ) return; diff --git a/src/3d/symbols/qgspoint3dsymbol_p.h b/src/3d/symbols/qgspoint3dsymbol_p.h index d2a6901526029..ab30b55c96f55 100644 --- a/src/3d/symbols/qgspoint3dsymbol_p.h +++ b/src/3d/symbols/qgspoint3dsymbol_p.h @@ -40,7 +40,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 Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol ); + Qt3DCore::QEntity *entityForPoint3DSymbol( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol ); } /// @endcond diff --git a/src/3d/symbols/qgspolygon3dsymbol_p.cpp b/src/3d/symbols/qgspolygon3dsymbol_p.cpp index de1dee02c8564..fe6d460c1ef76 100644 --- a/src/3d/symbols/qgspolygon3dsymbol_p.cpp +++ b/src/3d/symbols/qgspolygon3dsymbol_p.cpp @@ -90,7 +90,7 @@ 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.map() ); const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->materialSettings() ); diff --git a/src/3d/terrain/qgsdemterraingenerator.cpp b/src/3d/terrain/qgsdemterraingenerator.cpp index a8b04d72f8ada..e808daff83429 100644 --- a/src/3d/terrain/qgsdemterraingenerator.cpp +++ b/src/3d/terrain/qgsdemterraingenerator.cpp @@ -67,7 +67,7 @@ QgsRectangle QgsDemTerrainGenerator::rootChunkExtent() const return mTerrainTilingScheme.tileToExtent( 0, 0, 0 ); } -float QgsDemTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettings &map ) const +float QgsDemTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const { Q_UNUSED( map ) if ( mHeightMapGenerator ) diff --git a/src/3d/terrain/qgsdemterraingenerator.h b/src/3d/terrain/qgsdemterraingenerator.h index 7bbba6c84894d..257aeef8b6641 100644 --- a/src/3d/terrain/qgsdemterraingenerator.h +++ b/src/3d/terrain/qgsdemterraingenerator.h @@ -70,7 +70,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 Qgs3DMapSettings &map ) const override; + float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) 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 6e5fdc9e0015e..323088b10e13c 100644 --- a/src/3d/terrain/qgsonlineterraingenerator.cpp +++ b/src/3d/terrain/qgsonlineterraingenerator.cpp @@ -49,7 +49,7 @@ QgsRectangle QgsOnlineTerrainGenerator::rootChunkExtent() const return mTerrainTilingScheme.tileToExtent( 0, 0, 0 ); } -float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettings &map ) const +float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const { Q_UNUSED( map ) if ( mHeightMapGenerator ) diff --git a/src/3d/terrain/qgsonlineterraingenerator.h b/src/3d/terrain/qgsonlineterraingenerator.h index 1a2b28f3a768a..8f203ed11289a 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 Qgs3DMapSettings &map ) const override; + float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) 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 b735c778d07a8..e8929c15f3315 100644 --- a/src/3d/terrain/qgsterraingenerator.cpp +++ b/src/3d/terrain/qgsterraingenerator.cpp @@ -44,7 +44,7 @@ void QgsTerrainGenerator::rootChunkHeightRange( float &hMin, float &hMax ) const hMax = 400; } -float QgsTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettings &map ) const +float QgsTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const { Q_UNUSED( x ) Q_UNUSED( y ) diff --git a/src/3d/terrain/qgsterraingenerator.h b/src/3d/terrain/qgsterraingenerator.h index 86356dacd5e81..461e22c420e02 100644 --- a/src/3d/terrain/qgsterraingenerator.h +++ b/src/3d/terrain/qgsterraingenerator.h @@ -23,6 +23,7 @@ class QgsAABB; class Qgs3DMapSettings; +class Qgs3DMapSettingsSnapshot; class QgsRectangle; class QgsTerrainEntity; @@ -87,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 Qgs3DMapSettings &map ) const; + virtual float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const; //! Write terrain generator's configuration to XML virtual void writeXml( QDomElement &elem ) const = 0; diff --git a/tests/src/3d/testqgsmesh3drendering.cpp b/tests/src/3d/testqgsmesh3drendering.cpp index 312bfd95577e7..bc06081849fbb 100644 --- a/tests/src/3d/testqgsmesh3drendering.cpp +++ b/tests/src/3d/testqgsmesh3drendering.cpp @@ -30,6 +30,7 @@ #include "qgsoffscreen3dengine.h" #include "qgspointlightsettings.h" #include "qgsproject.h" +#include "qgs3dmapsettingssnapshot.h" class TestQgsMesh3DRendering : public QgsTest @@ -121,7 +122,7 @@ void TestQgsMesh3DRendering::testMeshTerrain() meshTerrain->setLayer( mLayerMeshTerrain ); map->setTerrainGenerator( meshTerrain ); - QCOMPARE( meshTerrain->heightAt( 750, 2500, *map ), 500.0 ); + QCOMPARE( meshTerrain->heightAt( 750, 2500, map->snapshot() ), 500.0 ); QgsOffscreen3DEngine engine; Qgs3DMapScene *scene = new Qgs3DMapScene( *map, &engine );