Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some thread safety to Qgs3DMapSettings usage #58398

Merged
merged 11 commits into from
Aug 28, 2024
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions python/3d/auto_generated/qgs3dmapsettings.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 Qgs3DRenderContext instead
for a safe snapshot of settings from Qgs3DMapSettings.
%End

%TypeHeaderCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@




class QgsPointCloudLayer3DRenderer : QgsAbstractPointCloud3DRenderer
{
%Docstring(signature="appended")
Expand Down
2 changes: 0 additions & 2 deletions python/3d/auto_generated/qgsvectorlayer3drenderer.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@





class QgsVectorLayer3DRendererMetadata : Qgs3DRendererAbstractMetadata
{
%Docstring(signature="appended")
Expand Down
6 changes: 6 additions & 0 deletions python/PyQt6/3d/auto_generated/qgs3dmapsettings.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 Qgs3DRenderContext instead
for a safe snapshot of settings from Qgs3DMapSettings.
%End

%TypeHeaderCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@




class QgsPointCloudLayer3DRenderer : QgsAbstractPointCloud3DRenderer
{
%Docstring(signature="appended")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@





class QgsVectorLayer3DRendererMetadata : Qgs3DRendererAbstractMetadata
{
%Docstring(signature="appended")
Expand Down
2 changes: 2 additions & 0 deletions src/3d/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(QGIS_3D_SRCS
qgs3dmapsettings.cpp
qgs3dmaptool.cpp
qgs3dmapcanvas.cpp
qgs3drendercontext.cpp
qgs3dsceneexporter.cpp
qgs3dutils.cpp
qgs3dwiredmesh_p.cpp
Expand Down Expand Up @@ -121,6 +122,7 @@ set(QGIS_3D_HDRS
qgs3dmapscene.h
qgs3dmapsettings.h
qgs3dmaptool.h
qgs3drendercontext.h
qgs3dsceneexporter.h
qgs3dtypes.h
qgs3dutils.h
Expand Down
4 changes: 2 additions & 2 deletions src/3d/chunks/qgschunkedentity_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ static bool hasAnyActiveChildren( QgsChunkNode *node, QList<QgsChunkNode *> &act
}


QgsChunkedEntity::QgsChunkedEntity( float tau, QgsChunkLoaderFactory *loaderFactory, bool ownsFactory, int primitiveBudget, Qt3DCore::QNode *parent )
: Qgs3DMapSceneEntity( parent )
QgsChunkedEntity::QgsChunkedEntity( Qgs3DMapSettings *map, float tau, QgsChunkLoaderFactory *loaderFactory, bool ownsFactory, int primitiveBudget, Qt3DCore::QNode *parent )
: Qgs3DMapSceneEntity( map, parent )
, mTau( tau )
, mChunkLoaderFactory( loaderFactory )
, mOwnsFactory( ownsFactory )
Expand Down
2 changes: 1 addition & 1 deletion src/3d/chunks/qgschunkedentity_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class QgsChunkedEntity : public Qgs3DMapSceneEntity
Q_OBJECT
public:
//! Constructs a chunked entity
QgsChunkedEntity( float tau, QgsChunkLoaderFactory *loaderFactory, bool ownsFactory,
QgsChunkedEntity( Qgs3DMapSettings *map, float tau, QgsChunkLoaderFactory *loaderFactory, bool ownsFactory,
int primitivesBudget = std::numeric_limits<int>::max(),
Qt3DCore::QNode *parent = nullptr );
~QgsChunkedEntity() override;
Expand Down
31 changes: 15 additions & 16 deletions src/3d/mesh/qgsmesh3dentity_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,25 @@
#include <Qt3DRender/QGeometryRenderer>

#include "qgsmeshlayer.h"
#include "qgs3dmapsettings.h"
#include "qgs3drendercontext.h"
#include "qgsmesh3dmaterial_p.h"



QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DMapSettings &map,
QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol )
: mMapSettings( map )
: mRenderContext( context )
, mTriangularMesh( triangularMesh )
, mSymbol( symbol->clone() )
{}

QgsMeshDataset3DEntity::QgsMeshDataset3DEntity(
const Qgs3DMapSettings &map,
const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
QgsMeshLayer *meshLayer,
const QgsMesh3DSymbol *symbol )
: QgsMesh3DEntity( map, triangularMesh, symbol ),
: QgsMesh3DEntity( context, triangularMesh, symbol ),
mLayerRef( meshLayer )
{}

Expand All @@ -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 );
}

Expand All @@ -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 );
}

Expand All @@ -76,28 +76,27 @@ QgsMeshLayer *QgsMeshDataset3DEntity::layer() const
return qobject_cast<QgsMeshLayer *>( mLayerRef.layer.data() );
}

QgsMesh3DTerrainTileEntity::QgsMesh3DTerrainTileEntity(
const Qgs3DMapSettings &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 );
}

void QgsMesh3DTerrainTileEntity::applyMaterial()
{
QgsMesh3DMaterial *material = new QgsMesh3DMaterial(
nullptr, QgsDateTimeRange(),
mMapSettings.origin(),
mRenderContext.origin(),
mSymbol.get(),
QgsMesh3DMaterial::ZValue );
addComponent( material );
Expand Down
10 changes: 5 additions & 5 deletions src/3d/mesh/qgsmesh3dentity_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <Qt3DCore/QEntity>

#include "mesh/qgsmesh3dgeometry_p.h"
#include "qgs3dmapsettings.h"
#include "qgs3drendercontext.h"
#include "qgsmesh3dsymbol.h"
#include "qgsterraintileentity_p.h"

Expand Down Expand Up @@ -52,13 +52,13 @@ class QgsMesh3DEntity
void build();
protected:
//! Constructor
QgsMesh3DEntity( const Qgs3DMapSettings &map,
QgsMesh3DEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol );

virtual ~QgsMesh3DEntity() = default;

Qgs3DMapSettings mMapSettings;
Qgs3DRenderContext mRenderContext;
QgsTriangularMesh mTriangularMesh;
std::unique_ptr< QgsMesh3DSymbol > mSymbol;

Expand All @@ -74,7 +74,7 @@ class QgsMeshDataset3DEntity: public Qt3DCore::QEntity, public QgsMesh3DEntity

public:
//! Constructor
QgsMeshDataset3DEntity( const Qgs3DMapSettings &map,
QgsMeshDataset3DEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
QgsMeshLayer *meshLayer,
const QgsMesh3DSymbol *symbol );
Expand All @@ -94,7 +94,7 @@ class QgsMesh3DTerrainTileEntity: public QgsTerrainTileEntity, public QgsMesh3DE
Q_OBJECT

public:
QgsMesh3DTerrainTileEntity( const Qgs3DMapSettings &map,
QgsMesh3DTerrainTileEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol,
QgsChunkNodeId nodeId,
Expand Down
8 changes: 4 additions & 4 deletions src/3d/mesh/qgsmeshterraingenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand All @@ -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( Qgs3DRenderContext::fromMapSettings( terrain()->map() ), mTriangularMesh, mSymbol.get(), mNode->tileId(), parent );
entity->build();
createTexture( entity );

Expand Down Expand Up @@ -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 Qgs3DRenderContext & ) const
{
return QgsMeshLayerUtils::interpolateZForPoint( mTriangularMesh, x, y );
}
Expand Down
2 changes: 1 addition & 1 deletion src/3d/mesh/qgsmeshterraingenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 Qgs3DRenderContext &context ) const override;

private slots:
void updateTriangularMesh();
Expand Down
4 changes: 2 additions & 2 deletions src/3d/qgs3dmapscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ void Qgs3DMapScene::createTerrainDeferred()
const QgsAABB clippingBbox = Qgs3DUtils::mapToWorldExtent( mMap.extent(), rootBbox.zMin, rootBbox.zMax, mMap.origin() );
mMap.terrainGenerator()->setupQuadtree( rootBbox, rootError, maxZoomLevel, clippingBbox );

mTerrain = new QgsTerrainEntity( mMap );
mTerrain = new QgsTerrainEntity( &mMap );
mTerrain->setParent( this );
mTerrain->setShowBoundingBoxes( mMap.showTerrainBoundingBoxes() );

Expand Down Expand Up @@ -645,7 +645,7 @@ void Qgs3DMapScene::addLayerEntity( QgsMapLayer *layer )
tiledSceneRenderer->setLayer( static_cast<QgsTiledSceneLayer *>( layer ) );
}

Qt3DCore::QEntity *newEntity = renderer->createEntity( mMap );
Qt3DCore::QEntity *newEntity = renderer->createEntity( &mMap );
if ( newEntity )
{
newEntity->setParent( this );
Expand Down
13 changes: 12 additions & 1 deletion src/3d/qgs3dmapsceneentity_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "qgsrange.h"
#include "qgssettings.h"

class Qgs3DMapSettings;

#define SIP_NO_FILE


Expand All @@ -47,8 +49,9 @@ class Qgs3DMapSceneEntity : public Qt3DCore::QEntity
Q_OBJECT
public:
//! Constructs a chunked entity
Qgs3DMapSceneEntity( Qt3DCore::QNode *parent = nullptr )
Qgs3DMapSceneEntity( Qgs3DMapSettings *map, Qt3DCore::QNode *parent = nullptr )
: Qt3DCore::QEntity( parent )
, mMap( map )
{
const QgsSettings settings;
mGpuMemoryLimit = settings.value( QStringLiteral( "map3d/gpuMemoryLimit" ), 500.0, QgsSettings::App ).toDouble();
Expand All @@ -75,6 +78,12 @@ class Qgs3DMapSceneEntity : public Qt3DCore::QEntity
//! Returns the near to far plane range for the entity using the specified \a viewMatrix
virtual QgsRange<float> getNearFarPlaneRange( const QMatrix4x4 &viewMatrix ) const { Q_UNUSED( viewMatrix ) return QgsRange<float>( 1e9, 0 ); }

/**
* Returns the associated 3D map settings.
*
* \since QGIS 3.40
*/
Qgs3DMapSettings *map() { return mMap; }

//! Sets the limit of the GPU memory used to render the entity
void setGpuMemoryLimit( double gpuMemoryLimit ) { mGpuMemoryLimit = gpuMemoryLimit; }
Expand All @@ -97,6 +106,8 @@ class Qgs3DMapSceneEntity : public Qt3DCore::QEntity
void newEntityCreated( Qt3DCore::QEntity *entity );

protected:
Qgs3DMapSettings *mMap = nullptr;

//! Limit how much GPU memory this entity can use
double mGpuMemoryLimit = 500.0; // in megabytes
//! Whether the entity is currently over the GPU memory limit (used to report a warning to the user)
Expand Down
4 changes: 1 addition & 3 deletions src/3d/qgs3dmapsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@
#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"
#include "qgscolorutils.h"
#include "qgsrasterlayer.h"
#include "qgspointlightsettings.h"
#include "qgsdirectionallightsettings.h"
#include "qgs3drendercontext.h"

#include <QDomDocument>
#include <QDomElement>
Expand Down
3 changes: 3 additions & 0 deletions src/3d/qgs3dmapsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,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 Qgs3DRenderContext instead
* for a safe snapshot of settings from Qgs3DMapSettings.
*/
class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObject
{
Expand Down
Loading
Loading