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
23 changes: 19 additions & 4 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 Expand Up @@ -74,10 +80,15 @@ 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.

.. seealso:: :py:func:`origin`
%End

QgsVector3D origin() const;
%Docstring
Returns coordinates in map CRS at which 3D scene has origin (0,0,0)
Returns coordinates in map CRS at which 3D scene has origin (0,0,0).

.. seealso:: :py:func:`setOrigin`
%End

QgsVector3D mapToWorldCoordinates( const QgsVector3D &mapCoords ) const;
Expand All @@ -91,11 +102,16 @@ Converts 3D world coordinates to map coordinates (applies offset and turns (x,y,

void setCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
Sets coordinate reference system used in the 3D scene
Sets coordinate reference system used in the 3D scene.

.. seealso:: :py:func:`crs`
%End

QgsCoordinateReferenceSystem crs() const;
%Docstring
Returns coordinate reference system used in the 3D scene
Returns coordinate reference system used in the 3D scene.

.. seealso:: :py:func:`setCrs`
%End

QgsCoordinateTransformContext transformContext() const;
Expand Down Expand Up @@ -528,7 +544,6 @@ Sets DPI used for conversion between real world units (e.g. mm) and pixels
.. versionadded:: 3.10
%End


double outputDpi() const;
%Docstring
Returns DPI used for conversion between real world units (e.g. mm) and pixels
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
23 changes: 19 additions & 4 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 Expand Up @@ -74,10 +80,15 @@ 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.

.. seealso:: :py:func:`origin`
%End

QgsVector3D origin() const;
%Docstring
Returns coordinates in map CRS at which 3D scene has origin (0,0,0)
Returns coordinates in map CRS at which 3D scene has origin (0,0,0).

.. seealso:: :py:func:`setOrigin`
%End

QgsVector3D mapToWorldCoordinates( const QgsVector3D &mapCoords ) const;
Expand All @@ -91,11 +102,16 @@ Converts 3D world coordinates to map coordinates (applies offset and turns (x,y,

void setCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
Sets coordinate reference system used in the 3D scene
Sets coordinate reference system used in the 3D scene.

.. seealso:: :py:func:`crs`
%End

QgsCoordinateReferenceSystem crs() const;
%Docstring
Returns coordinate reference system used in the 3D scene
Returns coordinate reference system used in the 3D scene.

.. seealso:: :py:func:`setCrs`
%End

QgsCoordinateTransformContext transformContext() const;
Expand Down Expand Up @@ -528,7 +544,6 @@ Sets DPI used for conversion between real world units (e.g. mm) and pixels
.. versionadded:: 3.10
%End


double outputDpi() const;
%Docstring
Returns DPI used for conversion between real world units (e.g. mm) and pixels
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 *mapSettings, float tau, QgsChunkLoaderFactory *loaderFactory, bool ownsFactory, int primitiveBudget, Qt3DCore::QNode *parent )
: Qgs3DMapSceneEntity( mapSettings, 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 *mapSettings, 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()->mapSettings() ), 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
Loading
Loading