Rework to use Qgs3DRenderContext instead

This commit is contained in:
Nyall Dawson 2024-08-27 09:33:17 +10:00
parent b6bcdea70e
commit 1f94f9bc4e
50 changed files with 288 additions and 319 deletions

View File

@ -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)

View File

@ -20,7 +20,7 @@ Definition of the world.
.. warning::
Qgs3DMapSettings are a QObject subclass, and accordingly are not
safe for access across different threads. See Qgs3DMapSettingsSnapshot instead
safe for access across different threads. See Qgs3DRenderContext instead
for a safe snapshot of settings from Qgs3DMapSettings.
%End
@ -34,7 +34,6 @@ Definition of the world.
~Qgs3DMapSettings();
void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
%Docstring
Reads configuration from a DOM element previously written by :py:func:`~Qgs3DMapSettings.writeXml`

View File

@ -10,7 +10,6 @@
class QgsPointCloudLayer3DRenderer : QgsAbstractPointCloud3DRenderer
{
%Docstring(signature="appended")

View File

@ -20,7 +20,7 @@ Definition of the world.
.. warning::
Qgs3DMapSettings are a QObject subclass, and accordingly are not
safe for access across different threads. See Qgs3DMapSettingsSnapshot instead
safe for access across different threads. See Qgs3DRenderContext instead
for a safe snapshot of settings from Qgs3DMapSettings.
%End
@ -34,7 +34,6 @@ Definition of the world.
~Qgs3DMapSettings();
void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
%Docstring
Reads configuration from a DOM element previously written by :py:func:`~Qgs3DMapSettings.writeXml`

View File

@ -10,7 +10,6 @@
class QgsPointCloudLayer3DRenderer : QgsAbstractPointCloud3DRenderer
{
%Docstring(signature="appended")

View File

@ -13,9 +13,9 @@ set(QGIS_3D_SRCS
qgs3dmapexportsettings.cpp
qgs3dmapscene.cpp
qgs3dmapsettings.cpp
qgs3dmapsettingssnapshot.cpp
qgs3dmaptool.cpp
qgs3dmapcanvas.cpp
qgs3drendercontext.cpp
qgs3dsceneexporter.cpp
qgs3dutils.cpp
qgs3dwiredmesh_p.cpp
@ -121,8 +121,8 @@ set(QGIS_3D_HDRS
qgs3daxissettings.h
qgs3dmapscene.h
qgs3dmapsettings.h
qgs3dmapsettingssnapshot.h
qgs3dmaptool.h
qgs3drendercontext.h
qgs3dsceneexporter.h
qgs3dtypes.h
qgs3dutils.h

View File

@ -20,25 +20,25 @@
#include <Qt3DRender/QGeometryRenderer>
#include "qgsmeshlayer.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
#include "qgsmesh3dmaterial_p.h"
QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DMapSettingsSnapshot &map,
QgsMesh3DEntity::QgsMesh3DEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol )
: mMapSettings( map )
: mRenderContext( context )
, mTriangularMesh( triangularMesh )
, mSymbol( symbol->clone() )
{}
QgsMeshDataset3DEntity::QgsMeshDataset3DEntity(
const Qgs3DMapSettingsSnapshot &map,
const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
QgsMeshLayer *meshLayer,
const QgsMesh3DSymbol *symbol )
: QgsMesh3DEntity( map, triangularMesh, symbol ),
: QgsMesh3DEntity( context, triangularMesh, symbol ),
mLayerRef( meshLayer )
{}
@ -54,7 +54,7 @@ void QgsMeshDataset3DEntity::buildGeometry()
return;
Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer;
mesh->setGeometry( new QgsMeshDataset3DGeometry( mTriangularMesh, layer(), mMapSettings.temporalRange(), mMapSettings.origin(), mMapSettings.extent(), mSymbol.get(), mesh ) );
mesh->setGeometry( new QgsMeshDataset3DGeometry( mTriangularMesh, layer(), mRenderContext.temporalRange(), mRenderContext.origin(), mRenderContext.extent(), mSymbol.get(), mesh ) );
addComponent( mesh );
}
@ -67,7 +67,7 @@ void QgsMeshDataset3DEntity::applyMaterial()
if ( datasetGroupIndex >= 0 )
mSymbol->setColorRampShader( rendererSettings.scalarSettings( datasetGroupIndex ).colorRampShader() );
}
QgsMesh3DMaterial *material = new QgsMesh3DMaterial( layer(), mMapSettings.temporalRange(), mMapSettings.origin(), mSymbol.get(), QgsMesh3DMaterial::ScalarDataSet );
QgsMesh3DMaterial *material = new QgsMesh3DMaterial( layer(), mRenderContext.temporalRange(), mRenderContext.origin(), mSymbol.get(), QgsMesh3DMaterial::ScalarDataSet );
addComponent( material );
}
@ -76,20 +76,19 @@ QgsMeshLayer *QgsMeshDataset3DEntity::layer() const
return qobject_cast<QgsMeshLayer *>( mLayerRef.layer.data() );
}
QgsMesh3DTerrainTileEntity::QgsMesh3DTerrainTileEntity(
const Qgs3DMapSettingsSnapshot &map,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol,
QgsChunkNodeId nodeId,
Qt3DCore::QNode *parent )
QgsMesh3DTerrainTileEntity::QgsMesh3DTerrainTileEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol,
QgsChunkNodeId nodeId,
Qt3DCore::QNode *parent )
: QgsTerrainTileEntity( nodeId, parent )
, QgsMesh3DEntity( map, triangularMesh, symbol )
, QgsMesh3DEntity( context, triangularMesh, symbol )
{}
void QgsMesh3DTerrainTileEntity::buildGeometry()
{
Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer;
mesh->setGeometry( new QgsMeshTerrain3DGeometry( mTriangularMesh, mMapSettings.origin(), mMapSettings.extent(), mSymbol.get()->verticalScale(), mesh ) );
mesh->setGeometry( new QgsMeshTerrain3DGeometry( mTriangularMesh, mRenderContext.origin(), mRenderContext.extent(), mSymbol.get()->verticalScale(), mesh ) );
addComponent( mesh );
}
@ -97,7 +96,7 @@ void QgsMesh3DTerrainTileEntity::applyMaterial()
{
QgsMesh3DMaterial *material = new QgsMesh3DMaterial(
nullptr, QgsDateTimeRange(),
mMapSettings.origin(),
mRenderContext.origin(),
mSymbol.get(),
QgsMesh3DMaterial::ZValue );
addComponent( material );

View File

@ -21,7 +21,7 @@
#include <Qt3DCore/QEntity>
#include "mesh/qgsmesh3dgeometry_p.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
#include "qgsmesh3dsymbol.h"
#include "qgsterraintileentity_p.h"
@ -52,13 +52,13 @@ class QgsMesh3DEntity
void build();
protected:
//! Constructor
QgsMesh3DEntity( const Qgs3DMapSettingsSnapshot &map,
QgsMesh3DEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol );
virtual ~QgsMesh3DEntity() = default;
Qgs3DMapSettingsSnapshot mMapSettings;
Qgs3DRenderContext mRenderContext;
QgsTriangularMesh mTriangularMesh;
std::unique_ptr< QgsMesh3DSymbol > mSymbol;
@ -74,7 +74,7 @@ class QgsMeshDataset3DEntity: public Qt3DCore::QEntity, public QgsMesh3DEntity
public:
//! Constructor
QgsMeshDataset3DEntity( const Qgs3DMapSettingsSnapshot &map,
QgsMeshDataset3DEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
QgsMeshLayer *meshLayer,
const QgsMesh3DSymbol *symbol );
@ -94,7 +94,7 @@ class QgsMesh3DTerrainTileEntity: public QgsTerrainTileEntity, public QgsMesh3DE
Q_OBJECT
public:
QgsMesh3DTerrainTileEntity( const Qgs3DMapSettingsSnapshot &map,
QgsMesh3DTerrainTileEntity( const Qgs3DRenderContext &context,
const QgsTriangularMesh &triangularMesh,
const QgsMesh3DSymbol *symbol,
QgsChunkNodeId nodeId,

View File

@ -23,9 +23,9 @@
#include "qgsmeshlayer.h"
#include "qgsmeshlayer3drenderer.h"
#include "qgsterrainentity_p.h"
#include "qgsterraintextureimage_p.h"
#include "qgsmeshlayerutils.h"
#include "qgs3dmapsettings.h"
#include "qgs3drendercontext.h"
QgsMeshTerrainTileLoader::QgsMeshTerrainTileLoader( QgsTerrainEntity *terrain, QgsChunkNode *node, const QgsTriangularMesh &triangularMesh, const QgsMesh3DSymbol *symbol )
: QgsTerrainTileLoader( terrain, node )
@ -37,7 +37,7 @@ QgsMeshTerrainTileLoader::QgsMeshTerrainTileLoader( QgsTerrainEntity *terrain, Q
Qt3DCore::QEntity *QgsMeshTerrainTileLoader::createEntity( Qt3DCore::QEntity *parent )
{
QgsMesh3DTerrainTileEntity *entity = new QgsMesh3DTerrainTileEntity( terrain()->map3D().snapshot(), mTriangularMesh, mSymbol.get(), mNode->tileId(), parent );
QgsMesh3DTerrainTileEntity *entity = new QgsMesh3DTerrainTileEntity( Qgs3DRenderContext::fromMapSettings( &( terrain()->map3D() ) ), mTriangularMesh, mSymbol.get(), mNode->tileId(), parent );
entity->build();
createTexture( entity );
@ -145,7 +145,7 @@ void QgsMeshTerrainGenerator::readXml( const QDomElement &elem )
mSymbol->readXml( elem.firstChildElement( "symbol" ), rwc );
}
float QgsMeshTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot & ) const
float QgsMeshTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext & ) const
{
return QgsMeshLayerUtils::interpolateZForPoint( mTriangularMesh, x, y );
}

View File

@ -85,7 +85,7 @@ class _3D_EXPORT QgsMeshTerrainGenerator: public QgsTerrainGenerator
QgsRectangle rootChunkExtent() const override;
void writeXml( QDomElement &elem ) const override;
void readXml( const QDomElement &elem ) override;
float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override;
float heightAt( double x, double y, const Qgs3DRenderContext &context ) const override;
private slots:
void updateTriangularMesh();

View File

@ -28,8 +28,7 @@
#include "qgsrasterlayer.h"
#include "qgspointlightsettings.h"
#include "qgsdirectionallightsettings.h"
#include "qgsthreadingutils.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
#include <QDomDocument>
#include <QDomElement>
@ -117,25 +116,6 @@ Qgs3DMapSettings::~Qgs3DMapSettings()
qDeleteAll( mLightSources );
}
Qgs3DMapSettingsSnapshot Qgs3DMapSettings::snapshot() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Qgs3DMapSettingsSnapshot res;
res.setCrs( mCrs );
res.setTransformContext( mTransformContext );
res.setOrigin( mOrigin );
res.setExtent( mExtent );
res.setTemporalRange( temporalRange() );
res.setSelectionColor( mSelectionColor );
res.setOutputDpi( mDpi );
res.setFieldOfView( mFieldOfView );
res.setTerrainRenderingEnabled( mTerrainRenderingEnabled );
res.setTerrainVerticalScale( mTerrainVerticalScale );
res.setTerrainGenerator( mTerrainGenerator.get() );
return res;
}
void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
{
QgsProjectDirtyBlocker blocker( QgsProject::instance() );

View File

@ -40,7 +40,6 @@ class QgsLightSource;
class QgsAbstract3DRenderer;
class QgsReadWriteContext;
class QgsProject;
class Qgs3DMapSettingsSnapshot;
class QDomElement;
@ -49,7 +48,7 @@ class QDomElement;
* \brief Definition of the world.
*
* \warning Qgs3DMapSettings are a QObject subclass, and accordingly are not
* safe for access across different threads. See Qgs3DMapSettingsSnapshot instead
* safe for access across different threads. See Qgs3DRenderContext instead
* for a safe snapshot of settings from Qgs3DMapSettings.
*/
class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObject
@ -63,13 +62,6 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
Qgs3DMapSettings &operator=( Qgs3DMapSettings const & ) = delete;
/**
* Returns a snapshot of settings from this object in a thread-safe, cheap-to-copy structure.
*
* \since QGIS 3.40
*/
Qgs3DMapSettingsSnapshot snapshot() const SIP_SKIP;
//! Reads configuration from a DOM element previously written by writeXml()
void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
//! Writes configuration to a DOM element, to be used later with readXml()

View File

@ -1,5 +1,5 @@
/***************************************************************************
qgs3dmapsettingssnapshot.cpp
qgs3drendercontext.cpp
--------------------------------------
Date : August 2024
Copyright : (C) 2024 by Nyall Dawson
@ -13,15 +13,35 @@
* *
***************************************************************************/
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
#include "qgs3dutils.h"
#include "qgsthreadingutils.h"
QgsVector3D Qgs3DMapSettingsSnapshot::mapToWorldCoordinates( const QgsVector3D &mapCoords ) const
Qgs3DRenderContext Qgs3DRenderContext::fromMapSettings( const Qgs3DMapSettings *mapSettings )
{
QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS( mapSettings );
Qgs3DRenderContext res;
res.mCrs = mapSettings->crs();
res.mTransformContext = mapSettings->transformContext();
res.mOrigin = mapSettings->origin();
res.mExtent = mapSettings->extent();
res.mTemporalRange = mapSettings->temporalRange();
res.mSelectionColor = mapSettings->selectionColor();
res.mDpi = mapSettings->outputDpi();
res.mFieldOfView = mapSettings->fieldOfView();
res.mTerrainRenderingEnabled = mapSettings->terrainRenderingEnabled();
res.mTerrainVerticalScale = mapSettings->terrainVerticalScale();
res.mTerrainGenerator = mapSettings->terrainGenerator();
return res;
}
QgsVector3D Qgs3DRenderContext::mapToWorldCoordinates( const QgsVector3D &mapCoords ) const
{
return Qgs3DUtils::mapToWorldCoordinates( mapCoords, mOrigin );
}
QgsVector3D Qgs3DMapSettingsSnapshot::worldToMapCoordinates( const QgsVector3D &worldCoords ) const
QgsVector3D Qgs3DRenderContext::worldToMapCoordinates( const QgsVector3D &worldCoords ) const
{
return Qgs3DUtils::worldToMapCoordinates( worldCoords, mOrigin );
}

View File

@ -1,5 +1,5 @@
/***************************************************************************
qgs3dmapsettingssnapshot.h
qgs3drendercontext.h
--------------------------------------
Date : August 2024
Copyright : (C) 2024 by Nyall Dawson
@ -13,8 +13,8 @@
* *
***************************************************************************/
#ifndef QGS3DMAPSETTINGSSNAPSHOT_H
#define QGS3DMAPSETTINGSSNAPSHOT_H
#ifndef QGS3DRENDERCONTEXT_H
#define QGS3DRENDERCONTEXT_H
#include "qgis_3d.h"
#include "qgsvector3d.h"
@ -22,27 +22,36 @@
#include "qgsrange.h"
#include "qgscoordinatereferencesystem.h"
#include "qgscoordinatetransformcontext.h"
#include "qgsexpressioncontext.h"
#include <QColor>
class QgsTerrainGenerator;
class Qgs3DMapSettings;
#define SIP_NO_FILE
/**
* \ingroup 3d
* \brief A snapshot of properties from Qgs3DMapSettings, in a thread-safe, cheap-to-copy structure.
* \brief Rendering context for preparation of 3D entities.
*
* Contains a snapshot of properties from Qgs3DMapSettings, in a thread-safe, cheap-to-copy structure.
*
* \note Not available in Python bindings.
*
* \since QGIS 3.40
*/
class _3D_EXPORT Qgs3DMapSettingsSnapshot
class _3D_EXPORT Qgs3DRenderContext
{
public:
Qgs3DMapSettingsSnapshot() = default;
Qgs3DRenderContext() = default;
/**
* Creates an initialized Qgs3DRenderContext instance from given Qgs3DMapSettings.
*/
static Qgs3DRenderContext fromMapSettings(const Qgs3DMapSettings* mapSettings );
/**
* Sets the coordinate reference system used in the 3D scene
@ -230,6 +239,27 @@ class _3D_EXPORT Qgs3DMapSettingsSnapshot
*/
QgsTerrainGenerator *terrainGenerator() const { return mTerrainGenerator; }
/**
* Sets the expression context. This context is used for all expression evaluation
* associated with this render context.
* \see expressionContext()
*/
void setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; }
/**
* Gets the expression context. This context should be used for all expression evaluation
* associated with this render context.
* \see setExpressionContext()
*/
QgsExpressionContext &expressionContext() { return mExpressionContext; }
/**
* Gets the expression context (const version). This context should be used for all expression evaluation
* associated with this render context.
* \see setExpressionContext()
* \note not available in Python bindings
*/
const QgsExpressionContext &expressionContext() const { return mExpressionContext; } SIP_SKIP
private:
QgsCoordinateReferenceSystem mCrs; //!< Destination coordinate system of the world
@ -245,10 +275,13 @@ class _3D_EXPORT Qgs3DMapSettingsSnapshot
bool mTerrainRenderingEnabled = true;
double mTerrainVerticalScale = 1; //!< Multiplier of terrain heights to make the terrain shape more pronounced
//! Expression context
QgsExpressionContext mExpressionContext;
// not owned, currently a pointer to the Qgs3DMapSettings terrain generator.
// TODO -- fix during implementation of https://github.com/qgis/QGIS-Enhancement-Proposals/issues/301
QgsTerrainGenerator *mTerrainGenerator = nullptr; //!< Implementation of the terrain generation
};
#endif // QGS3DMAPSETTINGSSNAPSHOT_H
#endif // QGS3DRENDERCONTEXT_H

View File

@ -32,11 +32,6 @@
#include "qgschunkedentity_p.h"
#include "qgsterrainentity_p.h"
#include "qgsraycastingutils_p.h"
#include "qgsline3dsymbol.h"
#include "qgspoint3dsymbol.h"
#include "qgspolygon3dsymbol.h"
#include "qgspointcloudrenderer.h"
#include "qgspointcloud3dsymbol.h"
#include "qgspointcloudlayer3drenderer.h"
@ -351,7 +346,7 @@ Qgs3DTypes::CullingMode Qgs3DUtils::cullingModeFromString( const QString &str )
return Qgs3DTypes::NoCulling;
}
float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint &centroid, const Qgs3DMapSettingsSnapshot &map )
float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint &centroid, const Qgs3DRenderContext &context )
{
float terrainZ = 0;
switch ( altClamp )
@ -360,7 +355,7 @@ float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altCl
case Qgis::AltitudeClamping::Terrain:
{
const QgsPointXY pt = altBind == Qgis::AltitudeBinding::Vertex ? p : centroid;
terrainZ = map.terrainRenderingEnabled() && map.terrainGenerator() ? map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) : 0;
terrainZ = context.terrainRenderingEnabled() && context.terrainGenerator() ? context.terrainGenerator()->heightAt( pt.x(), pt.y(), context ) : 0;
break;
}
@ -383,11 +378,11 @@ float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altCl
}
}
const float z = ( terrainZ + geomZ ) * static_cast<float>( map.terrainVerticalScale() ) + offset;
const float z = ( terrainZ + geomZ ) * static_cast<float>( context.terrainVerticalScale() ) + offset;
return z;
}
void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint &centroid, float offset, const Qgs3DMapSettingsSnapshot &map )
void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint &centroid, float offset, const Qgs3DRenderContext &context )
{
for ( int i = 0; i < lineString->nCoordinates(); ++i )
{
@ -410,7 +405,7 @@ void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClampi
break;
}
terrainZ = map.terrainRenderingEnabled() && map.terrainGenerator() ? map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) : 0;
terrainZ = context.terrainRenderingEnabled() && context.terrainGenerator() ? context.terrainGenerator()->heightAt( pt.x(), pt.y(), context ) : 0;
break;
}
@ -431,13 +426,13 @@ void Qgs3DUtils::clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClampi
break;
}
const float z = ( terrainZ + geomZ ) * static_cast<float>( map.terrainVerticalScale() ) + offset;
const float z = ( terrainZ + geomZ ) * static_cast<float>( context.terrainVerticalScale() ) + offset;
lineString->setZAt( i, z );
}
}
bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettingsSnapshot &map )
bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DRenderContext &context )
{
if ( !polygon->is3D() )
polygon->addZValue( 0 );
@ -458,7 +453,7 @@ bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping alt
if ( !lineString )
return false;
clampAltitudes( lineString, altClamp, altBind, centroid, offset, map );
clampAltitudes( lineString, altClamp, altBind, centroid, offset, context );
for ( int i = 0; i < polygon->numInteriorRings(); ++i )
{
@ -467,7 +462,7 @@ bool Qgs3DUtils::clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping alt
if ( !lineString )
return false;
clampAltitudes( lineString, altClamp, altBind, centroid, offset, map );
clampAltitudes( lineString, altClamp, altBind, centroid, offset, context );
}
return true;
}
@ -493,7 +488,7 @@ QMatrix4x4 Qgs3DUtils::stringToMatrix4x4( const QString &str )
return m;
}
void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSettingsSnapshot &map, Qgis::AltitudeClamping altClamp, QVector<QVector3D> &positions )
void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DRenderContext &context, Qgis::AltitudeClamping altClamp, QVector<QVector3D> &positions )
{
const QgsAbstractGeometry *g = f.geometry().constGet();
for ( auto it = g->vertices_begin(); it != g->vertices_end(); ++it )
@ -504,7 +499,7 @@ void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSetti
{
geomZ = pt.z();
}
const float terrainZ = map.terrainRenderingEnabled() && map.terrainGenerator() ? map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ) * map.terrainVerticalScale() : 0;
const float terrainZ = context.terrainRenderingEnabled() && context.terrainGenerator() ? context.terrainGenerator()->heightAt( pt.x(), pt.y(), context ) * context.terrainVerticalScale() : 0;
float h = 0.0f;
switch ( altClamp )
{
@ -518,7 +513,7 @@ void Qgs3DUtils::extractPointPositions( const QgsFeature &f, const Qgs3DMapSetti
h = terrainZ + geomZ;
break;
}
positions.append( QVector3D( pt.x() - map.origin().x(), h, -( pt.y() - map.origin().y() ) ) );
positions.append( QVector3D( pt.x() - context.origin().x(), h, -( pt.y() - context.origin().y() ) ) );
QgsDebugMsgLevel( QStringLiteral( "%1 %2 %3" ).arg( positions.last().x() ).arg( positions.last().y() ).arg( positions.last().z() ), 2 );
}
}

View File

@ -46,6 +46,7 @@ namespace Qt3DExtras
#define SIP_NO_FILE
class Qgs3DRenderContext;
/**
* \ingroup 3d
@ -130,11 +131,11 @@ class _3D_EXPORT Qgs3DUtils
static Qgs3DTypes::CullingMode cullingModeFromString( const QString &str );
//! Clamps altitude of a vertex according to the settings, returns Z value
static float clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint &centroid, const Qgs3DMapSettingsSnapshot &map );
static float clampAltitude( const QgsPoint &p, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const QgsPoint &centroid, const Qgs3DRenderContext &context );
//! Clamps altitude of vertices of a linestring according to the settings
static void clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint &centroid, float offset, const Qgs3DMapSettingsSnapshot &map );
static void clampAltitudes( QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint &centroid, float offset, const Qgs3DRenderContext &context );
//! Clamps altitude of vertices of a polygon according to the settings
static bool clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DMapSettingsSnapshot &map );
static bool clampAltitudes( QgsPolygon *polygon, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, float offset, const Qgs3DRenderContext &context );
//! Converts a 4x4 transform matrix to a string
static QString matrix4x4toString( const QMatrix4x4 &m );
@ -142,7 +143,7 @@ class _3D_EXPORT Qgs3DUtils
static QMatrix4x4 stringToMatrix4x4( const QString &str );
//! Calculates (x,y,z) positions of (multi)point from the given feature
static void extractPointPositions( const QgsFeature &f, const Qgs3DMapSettingsSnapshot &map, Qgis::AltitudeClamping altClamp, QVector<QVector3D> &positions );
static void extractPointPositions( const QgsFeature &f, const Qgs3DRenderContext &context, Qgis::AltitudeClamping altClamp, QVector<QVector3D> &positions );
/**
* Returns TRUE if bbox is completely outside the current viewing volume.

View File

@ -31,56 +31,11 @@
class QgsFeature;
#include "qgsexpressioncontext.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
#define SIP_NO_FILE
/**
* \ingroup 3d
* \brief Rendering context for preparation of 3D entities.
*
* \note Not available in Python bindings
*/
class Qgs3DRenderContext
{
public:
Qgs3DRenderContext( const Qgs3DMapSettingsSnapshot &map ) : mMap( map ) {}
const Qgs3DMapSettingsSnapshot &map() const { return mMap; }
/**
* Sets the expression context. This context is used for all expression evaluation
* associated with this render context.
* \see expressionContext()
*/
void setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; }
/**
* Gets the expression context. This context should be used for all expression evaluation
* associated with this render context.
* \see setExpressionContext()
*/
QgsExpressionContext &expressionContext() { return mExpressionContext; }
/**
* Gets the expression context (const version). This context should be used for all expression evaluation
* associated with this render context.
* \see setExpressionContext()
* \note not available in Python bindings
*/
const QgsExpressionContext &expressionContext() const { return mExpressionContext; } SIP_SKIP
private:
Qgs3DMapSettingsSnapshot mMap;
//! Expression context
QgsExpressionContext mExpressionContext;
};
/**
* \ingroup 3d
* \brief Interface to be implemented by 3D symbol implementations in order to generate 3D entities.

View File

@ -21,6 +21,7 @@
#include "qgsmeshlayer.h"
#include "qgsxmlutils.h"
#include "qgsmesh3dentity_p.h"
#include "qgs3drendercontext.h"
#include "qgs3dmapsettings.h"
QgsMeshLayer3DRendererMetadata::QgsMeshLayer3DRendererMetadata()
@ -92,7 +93,7 @@ Qt3DCore::QEntity *QgsMeshLayer3DRenderer::createEntity( const Qgs3DMapSettings
const QgsCoordinateTransform coordTrans( meshLayer->crs(), map.crs(), map.transformContext() );
meshLayer->updateTriangularMesh( coordTrans );
const QgsTriangularMesh triangularMesh = *meshLayer->triangularMeshByLodIndex( mSymbol->levelOfDetailIndex() );
QgsMeshDataset3DEntity *meshEntity = new QgsMeshDataset3DEntity( map.snapshot(), triangularMesh, meshLayer, mSymbol.get() );
QgsMeshDataset3DEntity *meshEntity = new QgsMeshDataset3DEntity( Qgs3DRenderContext::fromMapSettings( &map ), triangularMesh, meshLayer, mSymbol.get() );
meshEntity->build();
entity = meshEntity;

View File

@ -26,8 +26,8 @@
#include "qgspointcloud3dsymbol.h"
#include "qgspointcloudlayerelevationproperties.h"
QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr<QgsPointCloud3DSymbol> symbol, double zValueScale, double zValueFixedOffset )
: Qgs3DRenderContext( map )
QgsPointCloud3DRenderContext::QgsPointCloud3DRenderContext( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr<QgsPointCloud3DSymbol> symbol, double zValueScale, double zValueFixedOffset )
: Qgs3DRenderContext( context )
, mSymbol( std::move( symbol ) )
, mZValueScale( zValueScale )
, mZValueFixedOffset( zValueFixedOffset )
@ -78,22 +78,22 @@ void QgsPointCloud3DRenderContext::cancelRendering() const
void QgsPointCloud3DRenderContext::updateExtent()
{
if ( map().extent().isEmpty() )
if ( mLayerExtent.isEmpty() )
{
// an empty extent means no filter, so let's pass it without transformation
mExtent = QgsRectangle();
mLayerExtent = QgsRectangle();
}
else
{
try
{
mExtent = mCoordinateTransform.transformBoundingBox( map().extent(), Qgis::TransformDirection::Reverse );
mLayerExtent = mCoordinateTransform.transformBoundingBox( extent(), Qgis::TransformDirection::Reverse );
}
catch ( const QgsCsException & )
{
// bad luck, can't reproject for some reason. Let's use an empty extent to skip filtering.
QgsDebugError( QStringLiteral( "Transformation of extent failed!" ) );
mExtent = QgsRectangle();
mLayerExtent = QgsRectangle();
}
}
}
@ -161,13 +161,13 @@ Qt3DCore::QEntity *QgsPointCloudLayer3DRenderer::createEntity( const Qgs3DMapSet
Qt3DCore::QEntity *entity = nullptr;
if ( pcl->dataProvider()->index() )
{
entity = new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), map.snapshot(), coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(),
entity = new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), Qgs3DRenderContext::fromMapSettings( &map ), coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(),
static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zScale(),
static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zOffset(), mPointBudget );
}
else if ( !pcl->dataProvider()->subIndexes().isEmpty() )
{
entity = new QgsVirtualPointCloudEntity( pcl, map.snapshot(), coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(),
entity = new QgsVirtualPointCloudEntity( pcl, Qgs3DRenderContext::fromMapSettings( &map ), coordinateTransform, dynamic_cast<QgsPointCloud3DSymbol *>( mSymbol->clone() ), static_cast< float >( maximumScreenError() ), showBoundingBoxes(),
static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zScale(),
static_cast< const QgsPointCloudLayerElevationProperties * >( pcl->elevationProperties() )->zOffset(), mPointBudget );
}

View File

@ -27,8 +27,7 @@
class QgsPointCloudLayer;
#include "qgspointcloud3dsymbol.h"
#include "qgsfeature3dhandler_p.h"
#include "qgs3drendercontext.h"
#ifndef SIP_RUN
/**
@ -52,7 +51,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext
* The \a zValueFixedOffset argument specifies any constant offset value which must be added to z values
* taken from the point cloud index.
*/
QgsPointCloud3DRenderContext( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol,
QgsPointCloud3DRenderContext( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, std::unique_ptr< QgsPointCloud3DSymbol > symbol,
double zValueScale, double zValueFixedOffset );
QgsPointCloud3DRenderContext( const QgsPointCloud3DRenderContext &rh ) = delete;
@ -190,7 +189,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext
* Returns the 3D scene's extent in layer crs.
* \since QGIS 3.30
*/
QgsRectangle extent() const { return mExtent; }
QgsRectangle layerExtent() const { return mLayerExtent; }
private:
//! Recalculates the 3D scene's extent in layer's crs
@ -205,7 +204,7 @@ class _3D_NO_EXPORT QgsPointCloud3DRenderContext : public Qgs3DRenderContext
double mZValueFixedOffset = 0;
QgsCoordinateTransform mCoordinateTransform;
std::unique_ptr<QgsFeedback> mFeedback;
QgsRectangle mExtent;
QgsRectangle mLayerExtent;
};

View File

@ -49,7 +49,7 @@ QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointClou
const QgsCoordinateTransform &coordinateTransform, double zValueScale, double zValueOffset )
: QgsChunkLoader( node )
, mFactory( factory )
, mContext( factory->mMap, coordinateTransform, std::move( symbol ), zValueScale, zValueOffset )
, mContext( factory->mRenderContext, coordinateTransform, std::move( symbol ), zValueScale, zValueOffset )
{
QgsPointCloudIndex *pc = mFactory->mPointCloudIndex;
@ -131,9 +131,9 @@ Qt3DCore::QEntity *QgsPointCloudLayerChunkLoader::createEntity( Qt3DCore::QEntit
///////////////
QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol,
QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol,
double zValueScale, double zValueOffset, int pointBudget )
: mMap( map )
: mRenderContext( context )
, mCoordinateTransform( coordinateTransform )
, mPointCloudIndex( pc )
, mZValueScale( zValueScale )
@ -144,7 +144,7 @@ QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( cons
try
{
mExtent = mCoordinateTransform.transformBoundingBox( mMap.extent(), Qgis::TransformDirection::Reverse );
mExtent = mCoordinateTransform.transformBoundingBox( mRenderContext.extent(), Qgis::TransformDirection::Reverse );
}
catch ( const QgsCsException & )
{
@ -170,11 +170,11 @@ int QgsPointCloudLayerChunkLoaderFactory::primitivesCount( QgsChunkNode *node )
return mPointCloudIndex->nodePointCount( n );
}
QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset );
QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, double zValueOffset );
QgsChunkNode *QgsPointCloudLayerChunkLoaderFactory::createRootNode() const
{
const QgsAABB bbox = nodeBoundsToAABB( mPointCloudIndex->nodeBounds( IndexedPointCloudNode( 0, 0, 0, 0 ) ), mPointCloudIndex->offset(), mPointCloudIndex->scale(), mMap, mCoordinateTransform, mZValueOffset );
const QgsAABB bbox = nodeBoundsToAABB( mPointCloudIndex->nodeBounds( IndexedPointCloudNode( 0, 0, 0, 0 ) ), mPointCloudIndex->offset(), mPointCloudIndex->scale(), mRenderContext, mCoordinateTransform, mZValueOffset );
const float error = mPointCloudIndex->nodeError( IndexedPointCloudNode( 0, 0, 0, 0 ) );
QgsChunkNode *node = new QgsChunkNode( QgsChunkNodeId( 0, 0, 0, 0 ), bbox, error );
node->setRefinementProcess( mSymbol->renderAsTriangles() ? Qgis::TileRefinementProcess::Replacement : Qgis::TileRefinementProcess::Additive );
@ -220,7 +220,7 @@ QVector<QgsChunkNode *> QgsPointCloudLayerChunkLoaderFactory::createChildren( Qg
///////////////
QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, double zValueOffset )
QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, double zValueOffset )
{
QgsVector3D extentMin3D( nodeBounds.xMin() * scale.x() + offset.x(), nodeBounds.yMin() * scale.y() + offset.y(), nodeBounds.zMin() * scale.z() + offset.z() + zValueOffset );
QgsVector3D extentMax3D( nodeBounds.xMax() * scale.x() + offset.x(), nodeBounds.yMax() * scale.y() + offset.y(), nodeBounds.zMax() * scale.z() + offset.z() + zValueOffset );
@ -235,21 +235,21 @@ QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset
{
QgsDebugError( QStringLiteral( "Error transforming node bounds coordinate" ) );
}
const QgsVector3D worldExtentMin3D = Qgs3DUtils::mapToWorldCoordinates( extentMin3D, map.origin() );
const QgsVector3D worldExtentMax3D = Qgs3DUtils::mapToWorldCoordinates( extentMax3D, map.origin() );
const QgsVector3D worldExtentMin3D = Qgs3DUtils::mapToWorldCoordinates( extentMin3D, context.origin() );
const QgsVector3D worldExtentMax3D = Qgs3DUtils::mapToWorldCoordinates( extentMax3D, context.origin() );
QgsAABB rootBbox( worldExtentMin3D.x(), worldExtentMin3D.y(), worldExtentMin3D.z(),
worldExtentMax3D.x(), worldExtentMax3D.y(), worldExtentMax3D.z() );
return rootBbox;
}
QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettingsSnapshot &map,
QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DRenderContext &context,
const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol,
float maximumScreenSpaceError, bool showBoundingBoxes,
double zValueScale, double zValueOffset,
int pointBudget )
: QgsChunkedEntity( maximumScreenSpaceError,
new QgsPointCloudLayerChunkLoaderFactory( map, coordinateTransform, pc, symbol, zValueScale, zValueOffset, pointBudget ), true, pointBudget )
new QgsPointCloudLayerChunkLoaderFactory( context, coordinateTransform, pc, symbol, zValueScale, zValueOffset, pointBudget ), true, pointBudget )
{
setShowBoundingBoxes( showBoundingBoxes );
}
@ -266,8 +266,8 @@ QVector<QgsRayCastingUtils::RayHit> QgsPointCloudLayerChunkedEntity::rayIntersec
QgsPointCloudLayerChunkLoaderFactory *factory = static_cast<QgsPointCloudLayerChunkLoaderFactory *>( mChunkLoaderFactory );
// transform ray
const QgsVector3D rayOriginMapCoords = factory->mMap.worldToMapCoordinates( ray.origin() );
const QgsVector3D pointMapCoords = factory->mMap.worldToMapCoordinates( ray.origin() + ray.origin().length() * ray.direction().normalized() );
const QgsVector3D rayOriginMapCoords = factory->mRenderContext.worldToMapCoordinates( ray.origin() );
const QgsVector3D pointMapCoords = factory->mRenderContext.worldToMapCoordinates( ray.origin() + ray.origin().length() * ray.direction().normalized() );
QgsVector3D rayDirectionMapCoords = pointMapCoords - rayOriginMapCoords;
rayDirectionMapCoords.normalize();
@ -282,7 +282,7 @@ QVector<QgsRayCastingUtils::RayHit> QgsPointCloudLayerChunkedEntity::rayIntersec
// We're using the angle as a tolerance, effectively meaning we're fetching points intersecting a cone.
// This may be revisited to use a cylinder instead, if the balance between near/far points does not scale
// well with different point sizes, screen sizes and fov values.
const double limitAngle = 2. * pointSize / screenSizePx * factory->mMap.fieldOfView();
const double limitAngle = 2. * pointSize / screenSizePx * factory->mRenderContext.fieldOfView();
// adjust ray to elevation properties
const QgsVector3D adjustedRayOrigin = QgsVector3D( rayOriginMapCoords.x(), rayOriginMapCoords.y(), ( rayOriginMapCoords.z() - factory->mZValueOffset ) / factory->mZValueScale );
@ -361,7 +361,7 @@ QVector<QgsRayCastingUtils::RayHit> QgsPointCloudLayerChunkedEntity::rayIntersec
pointAttr[ QStringLiteral( "Y" ) ] = y;
pointAttr[ QStringLiteral( "Z" ) ] = z;
const QgsVector3D worldPoint = factory->mMap.mapToWorldCoordinates( point );
const QgsVector3D worldPoint = factory->mRenderContext.mapToWorldCoordinates( point );
QgsRayCastingUtils::RayHit hit( dist, worldPoint.toVector3D(), FID_NULL, pointAttr );
if ( context.singleResult )
result.clear();

View File

@ -28,7 +28,6 @@
//
#include "qgschunkloader_p.h"
#include "qgsfeature3dhandler_p.h"
#include "qgschunkedentity_p.h"
#include "qgspointcloud3dsymbol.h"
#include "qgspointcloud3dsymbol_p.h"
@ -66,7 +65,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory
* Constructs the factory
* The factory takes ownership over the passed \a symbol
*/
QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol,
QgsPointCloudLayerChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol,
double zValueScale, double zValueOffset, int pointBudget );
//! Creates loader for the given chunk node. Ownership of the returned is passed to the caller.
@ -74,7 +73,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory
virtual QgsChunkNode *createRootNode() const override;
virtual QVector<QgsChunkNode *> createChildren( QgsChunkNode *node ) const override;
virtual int primitivesCount( QgsChunkNode *node ) const override;
Qgs3DMapSettingsSnapshot mMap;
Qgs3DRenderContext mRenderContext;
QgsCoordinateTransform mCoordinateTransform;
QgsPointCloudIndex *mPointCloudIndex;
std::unique_ptr< QgsPointCloud3DSymbol > mSymbol;
@ -133,7 +132,7 @@ class QgsPointCloudLayerChunkedEntity : public QgsChunkedEntity
{
Q_OBJECT
public:
explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes,
explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes,
double zValueScale, double zValueOffset, int pointBudget );
QVector<QgsRayCastingUtils::RayHit> rayIntersection( const QgsRayCastingUtils::Ray3D &ray, const QgsRayCastingUtils::RayCastContext &context ) const override;

View File

@ -24,6 +24,7 @@
#include "qgsvertexid.h"
#include "qgslinestring.h"
#include "qgssymbollayer.h"
#include "qgs3dmapsettings.h"
#include <Qt3DCore/QEntity>
@ -167,7 +168,7 @@ void QgsRubberBand3D::updateGeometry()
{
QgsLineVertexData lineData;
lineData.withAdjacency = true;
lineData.init( Qgis::AltitudeClamping::Absolute, Qgis::AltitudeBinding::Vertex, 0, mMapSettings->snapshot() );
lineData.init( Qgis::AltitudeClamping::Absolute, Qgis::AltitudeBinding::Vertex, 0, Qgs3DRenderContext::fromMapSettings( mMapSettings ) );
lineData.addLineString( mLineString );
mPositionAttribute->buffer()->setData( lineData.createVertexBuffer() );
@ -189,7 +190,7 @@ void QgsRubberBand3D::updateMarkerMaterial()
{
delete mMarkerMaterial;
mMarkerMaterial = new QgsPoint3DBillboardMaterial();
mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol, mMapSettings->snapshot() );
mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol, Qgs3DRenderContext::fromMapSettings( mMapSettings ) );
mMarkerEntity->addComponent( mMarkerMaterial );
//TODO: QgsAbstract3DEngine::sizeChanged should have const QSize &size param

View File

@ -20,10 +20,7 @@
#include "qgs3dmapsettings.h"
#include "qgs3dutils.h"
#include "qgsline3dsymbol.h"
#include "qgspoint3dsymbol.h"
#include "qgspolygon3dsymbol.h"
#include "qgsfeature3dhandler_p.h"
#include "qgsrulebasedchunkloader_p.h"
#include "qgsapplication.h"
#include "qgs3dsymbolregistry.h"

View File

@ -39,7 +39,7 @@
QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderFactory *factory, QgsChunkNode *node )
: QgsChunkLoader( node )
, mFactory( factory )
, mContext( factory->mMap )
, mContext( factory->mRenderContext )
, mSource( new QgsVectorLayerFeatureSource( factory->mLayer ) )
{
if ( node->level() < mFactory->mLeafLevel )
@ -49,7 +49,6 @@ QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderF
}
QgsVectorLayer *layer = mFactory->mLayer;
const Qgs3DMapSettingsSnapshot &map = mFactory->mMap;
QgsExpressionContext exprContext( Qgs3DUtils::globalProjectLayerExpressionContext( layer ) );
exprContext.setFields( layer->fields() );
@ -68,11 +67,11 @@ QgsRuleBasedChunkLoader::QgsRuleBasedChunkLoader( const QgsRuleBasedChunkLoaderF
// build the feature request
QgsFeatureRequest req;
req.setDestinationCrs( map.crs(), map.transformContext() );
req.setDestinationCrs( mContext.crs(), mContext.transformContext() );
req.setSubsetOfAttributes( attributeNames, layer->fields() );
// only a subset of data to be queried
const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), map.origin() );
const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), mContext.origin() );
req.setFilterRect( rect );
//
@ -165,13 +164,13 @@ Qt3DCore::QEntity *QgsRuleBasedChunkLoader::createEntity( Qt3DCore::QEntity *par
///////////////
QgsRuleBasedChunkLoaderFactory::QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax )
: mMap( map )
QgsRuleBasedChunkLoaderFactory::QgsRuleBasedChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax )
: mRenderContext( context )
, mLayer( vl )
, mRootRule( rootRule->clone() )
, mLeafLevel( leafLevel )
{
const QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( map.extent(), zMin, zMax, map.origin() );
const QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( context.extent(), zMin, zMax, context.origin() );
setupQuadtree( rootBbox, -1, leafLevel ); // negative root error means that the node does not contain anything
}
@ -187,7 +186,7 @@ QgsChunkLoader *QgsRuleBasedChunkLoaderFactory::createChunkLoader( QgsChunkNode
QgsRuleBasedChunkedEntity::QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, double zMin, double zMax, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map )
: QgsChunkedEntity( -1, // max. allowed screen error (negative tau means that we need to go until leaves are reached)
new QgsRuleBasedChunkLoaderFactory( map.snapshot(), vl, rootRule, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true )
new QgsRuleBasedChunkLoaderFactory( Qgs3DRenderContext::fromMapSettings( &map ), vl, rootRule, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true )
{
mTransform = new Qt3DCore::QTransform;
if ( applyTerrainOffset() )

View File

@ -28,9 +28,9 @@
//
#include "qgschunkloader_p.h"
#include "qgsfeature3dhandler_p.h"
#include "qgschunkedentity_p.h"
#include "qgsrulebased3drenderer.h"
#include "qgs3drendercontext.h"
#include <QFutureWatcher>
#define SIP_NO_FILE
@ -59,13 +59,13 @@ class QgsRuleBasedChunkLoaderFactory : public QgsQuadtreeChunkLoaderFactory
public:
//! Constructs the factory (vl and rootRule must not be null)
QgsRuleBasedChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax );
QgsRuleBasedChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, int leafLevel, double zMin, double zMax );
~QgsRuleBasedChunkLoaderFactory() override;
//! Creates loader for the given chunk node. Ownership of the returned is passed to the caller.
virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override;
Qgs3DMapSettingsSnapshot mMap;
Qgs3DRenderContext mRenderContext;
QgsVectorLayer *mLayer;
std::unique_ptr<QgsRuleBased3DRenderer::Rule> mRootRule;
int mLeafLevel;

View File

@ -93,7 +93,7 @@ QgsTiledSceneChunkLoader::QgsTiledSceneChunkLoader( QgsChunkNode *node, const Qg
QgsGltf3DUtils::EntityTransform entityTransform;
entityTransform.tileTransform = ( tile.transform() ? *tile.transform() : QgsMatrix4x4() );
entityTransform.tileTransform.translate( tileContent.rtcCenter );
entityTransform.sceneOriginTargetCrs = mFactory.mMap.origin();
entityTransform.sceneOriginTargetCrs = mFactory.mRenderContext.origin();
entityTransform.ecefToTargetCrs = &mFactory.mBoundsTransform;
entityTransform.zValueScale = zValueScale;
entityTransform.zValueOffset = zValueOffset;
@ -136,13 +136,13 @@ Qt3DCore::QEntity *QgsTiledSceneChunkLoader::createEntity( Qt3DCore::QEntity *pa
///
QgsTiledSceneChunkLoaderFactory::QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset )
: mMap( map )
QgsTiledSceneChunkLoaderFactory::QgsTiledSceneChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double zValueScale, double zValueOffset )
: mRenderContext( context )
, mIndex( index )
, mZValueScale( zValueScale )
, mZValueOffset( zValueOffset )
{
mBoundsTransform = QgsCoordinateTransform( QgsCoordinateReferenceSystem( "EPSG:4978" ), mMap.crs(), mMap.transformContext() );
mBoundsTransform = QgsCoordinateTransform( QgsCoordinateReferenceSystem( "EPSG:4978" ), mRenderContext.crs(), mRenderContext.transformContext() );
}
QgsChunkLoader *QgsTiledSceneChunkLoaderFactory::createChunkLoader( QgsChunkNode *node ) const
@ -163,8 +163,8 @@ QgsChunkNode *QgsTiledSceneChunkLoaderFactory::nodeForTile( const QgsTiledSceneT
if ( hasLargeBounds( t ) )
{
// use the full extent of the scene
QgsVector3D v0 = mMap.mapToWorldCoordinates( QgsVector3D( mMap.extent().xMinimum(), mMap.extent().yMinimum(), -100 ) );
QgsVector3D v1 = mMap.mapToWorldCoordinates( QgsVector3D( mMap.extent().xMaximum(), mMap.extent().yMaximum(), +100 ) );
QgsVector3D v0 = mRenderContext.mapToWorldCoordinates( QgsVector3D( mRenderContext.extent().xMinimum(), mRenderContext.extent().yMinimum(), -100 ) );
QgsVector3D v1 = mRenderContext.mapToWorldCoordinates( QgsVector3D( mRenderContext.extent().xMaximum(), mRenderContext.extent().yMaximum(), +100 ) );
QgsAABB aabb( v0.x(), v0.y(), v0.z(), v1.x(), v1.y(), v1.z() );
float err = std::min( 1e6, t.geometricError() );
node = new QgsChunkNode( nodeId, aabb, err, parent );
@ -174,7 +174,7 @@ QgsChunkNode *QgsTiledSceneChunkLoaderFactory::nodeForTile( const QgsTiledSceneT
QgsBox3D box = t.boundingVolume().bounds( mBoundsTransform );
box.setZMinimum( box.zMinimum() * mZValueScale + mZValueOffset );
box.setZMaximum( box.zMaximum() * mZValueScale + mZValueOffset );
const QgsAABB aabb = aabbConvert( box, mMap.origin() );
const QgsAABB aabb = aabbConvert( box, mRenderContext.origin() );
node = new QgsChunkNode( nodeId, aabb, t.geometricError(), parent );
}
@ -212,7 +212,7 @@ QVector<QgsChunkNode *> QgsTiledSceneChunkLoaderFactory::createChildren( QgsChun
// TODO: make OBB of our scene in ECEF rather than just using center of the scene?
const QgsOrientedBox3D obb = t.boundingVolume().box();
const QgsPointXY c = mMap.extent().center();
const QgsPointXY c = mRenderContext.extent().center();
const QgsVector3D cEcef = mBoundsTransform.transform( QgsVector3D( c.x(), c.y(), 0 ), Qgis::TransformDirection::Reverse );
const QgsVector3D ecef2 = cEcef - obb.center();
@ -318,8 +318,8 @@ void QgsTiledSceneChunkLoaderFactory::prepareChildren( QgsChunkNode *node )
///
QgsTiledSceneLayerChunkedEntity::QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset )
: QgsChunkedEntity( maximumScreenError, new QgsTiledSceneChunkLoaderFactory( map, index, zValueScale, zValueOffset ), true )
QgsTiledSceneLayerChunkedEntity::QgsTiledSceneLayerChunkedEntity( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes, double zValueScale, double zValueOffset )
: QgsChunkedEntity( maximumScreenError, new QgsTiledSceneChunkLoaderFactory( context, index, zValueScale, zValueOffset ), true )
, mIndex( index )
{
setShowBoundingBoxes( showBoundingBoxes );

View File

@ -33,7 +33,7 @@
#include "qgschunknode_p.h"
#include "qgstiledsceneindex.h"
#include "qgstiledscenetile.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
#include <QFutureWatcher>
@ -80,7 +80,7 @@ class QgsTiledSceneChunkLoaderFactory : public QgsChunkLoaderFactory
{
Q_OBJECT
public:
QgsTiledSceneChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index,
QgsTiledSceneChunkLoaderFactory( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index,
double zValueScale, double zValueOffset );
virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override;
@ -93,7 +93,7 @@ class QgsTiledSceneChunkLoaderFactory : public QgsChunkLoaderFactory
QgsChunkNode *nodeForTile( const QgsTiledSceneTile &t, const QgsChunkNodeId &nodeId, QgsChunkNode *parent ) const;
void fetchHierarchyForNode( long long nodeId, QgsChunkNode *origNode );
Qgs3DMapSettingsSnapshot mMap;
Qgs3DRenderContext mRenderContext;
QString mRelativePathBase;
mutable QgsTiledSceneIndex mIndex;
double mZValueScale = 1.0;
@ -118,7 +118,7 @@ class QgsTiledSceneLayerChunkedEntity : public QgsChunkedEntity
{
Q_OBJECT
public:
explicit QgsTiledSceneLayerChunkedEntity( const Qgs3DMapSettingsSnapshot &map, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes,
explicit QgsTiledSceneLayerChunkedEntity( const Qgs3DRenderContext &context, const QgsTiledSceneIndex &index, double maximumScreenError, bool showBoundingBoxes,
double zValueScale, double zValueOffset );
~QgsTiledSceneLayerChunkedEntity();

View File

@ -66,7 +66,7 @@ Qt3DCore::QEntity *QgsTiledSceneLayer3DRenderer::createEntity( const Qgs3DMapSet
QgsTiledSceneIndex index = tsl->dataProvider()->index();
return new QgsTiledSceneLayerChunkedEntity( map.snapshot(), index,
return new QgsTiledSceneLayerChunkedEntity( Qgs3DRenderContext::fromMapSettings( &map ), index,
maximumScreenError(),
showBoundingBoxes(),
qgis::down_cast< const QgsTiledSceneLayerElevationProperties * >( tsl->elevationProperties() )->zScale(),

View File

@ -39,7 +39,7 @@
QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkLoaderFactory *factory, QgsChunkNode *node )
: QgsChunkLoader( node )
, mFactory( factory )
, mContext( factory->mMap )
, mRenderContext( factory->mRenderContext )
, mSource( new QgsVectorLayerFeatureSource( factory->mLayer ) )
{
if ( node->level() < mFactory->mLeafLevel )
@ -50,7 +50,6 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL
QgsVectorLayer *layer = mFactory->mLayer;
mLayerName = mFactory->mLayer->name();
const Qgs3DMapSettingsSnapshot &map = mFactory->mMap;
QgsFeature3DHandler *handler = QgsApplication::symbol3DRegistry()->createHandlerForSymbol( layer, mFactory->mSymbol.get() );
if ( !handler )
@ -62,10 +61,10 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL
QgsExpressionContext exprContext( Qgs3DUtils::globalProjectLayerExpressionContext( layer ) );
exprContext.setFields( layer->fields() );
mContext.setExpressionContext( exprContext );
mRenderContext.setExpressionContext( exprContext );
QSet<QString> attributeNames;
if ( !mHandler->prepare( mContext, attributeNames ) )
if ( !mHandler->prepare( mRenderContext, attributeNames ) )
{
QgsDebugError( QStringLiteral( "Failed to prepare 3D feature handler!" ) );
return;
@ -74,12 +73,12 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL
// build the feature request
QgsFeatureRequest req;
req.setCoordinateTransform(
QgsCoordinateTransform( layer->crs3D(), map.crs(), map.transformContext() )
QgsCoordinateTransform( layer->crs3D(), mRenderContext.crs(), mRenderContext.transformContext() )
);
req.setSubsetOfAttributes( attributeNames, layer->fields() );
// only a subset of data to be queried
const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), map.origin() );
const QgsRectangle rect = Qgs3DUtils::worldToMapExtent( node->bbox(), mRenderContext.origin() );
req.setFilterRect( rect );
//
@ -98,8 +97,8 @@ QgsVectorLayerChunkLoader::QgsVectorLayerChunkLoader( const QgsVectorLayerChunkL
{
if ( mCanceled )
break;
mContext.expressionContext().setFeature( f );
mHandler->processFeature( f, mContext );
mRenderContext.expressionContext().setFeature( f );
mHandler->processFeature( f, mRenderContext );
}
} );
@ -141,7 +140,7 @@ Qt3DCore::QEntity *QgsVectorLayerChunkLoader::createEntity( Qt3DCore::QEntity *p
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity( parent );
entity->setObjectName( mLayerName + "_" + mNode->tileId().text() );
mHandler->finalize( entity, mContext );
mHandler->finalize( entity, mRenderContext );
// fix the vertical range of the node from the estimated vertical range to the true range
if ( mHandler->zMinimum() != std::numeric_limits<float>::max() && mHandler->zMaximum() != std::numeric_limits<float>::lowest() )
@ -160,13 +159,13 @@ Qt3DCore::QEntity *QgsVectorLayerChunkLoader::createEntity( Qt3DCore::QEntity *p
///////////////
QgsVectorLayerChunkLoaderFactory::QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax )
: mMap( map )
QgsVectorLayerChunkLoaderFactory::QgsVectorLayerChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax )
: mRenderContext( context )
, mLayer( vl )
, mSymbol( symbol->clone() )
, mLeafLevel( leafLevel )
{
QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( map.extent(), zMin, zMax, map.origin() );
QgsAABB rootBbox = Qgs3DUtils::mapToWorldExtent( context.extent(), zMin, zMax, context.origin() );
// add small padding to avoid clipping of point features located at the edge of the bounding box
rootBbox.xMin -= 1.0;
rootBbox.xMax += 1.0;
@ -188,7 +187,7 @@ QgsChunkLoader *QgsVectorLayerChunkLoaderFactory::createChunkLoader( QgsChunkNod
QgsVectorLayerChunkedEntity::QgsVectorLayerChunkedEntity( QgsVectorLayer *vl, double zMin, double zMax, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsAbstract3DSymbol *symbol, const Qgs3DMapSettings &map )
: QgsChunkedEntity( -1, // max. allowed screen error (negative tau means that we need to go until leaves are reached)
new QgsVectorLayerChunkLoaderFactory( map.snapshot(), vl, symbol, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true )
new QgsVectorLayerChunkLoaderFactory( Qgs3DRenderContext::fromMapSettings( &map ), vl, symbol, tilingSettings.zoomLevelsCount() - 1, zMin, zMax ), true )
{
mTransform = new Qt3DCore::QTransform;
if ( applyTerrainOffset() )

View File

@ -33,7 +33,6 @@
#define SIP_NO_FILE
class Qgs3DMapSettings;
class QgsVectorLayer;
class QgsVectorLayer3DTilingSettings;
class QgsVectorLayerFeatureSource;
@ -61,12 +60,12 @@ class QgsVectorLayerChunkLoaderFactory : public QgsQuadtreeChunkLoaderFactory
public:
//! Constructs the factory
QgsVectorLayerChunkLoaderFactory( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax );
QgsVectorLayerChunkLoaderFactory( const Qgs3DRenderContext &context, QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, int leafLevel, double zMin, double zMax );
//! Creates loader for the given chunk node. Ownership of the returned is passed to the caller.
virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override;
Qgs3DMapSettingsSnapshot mMap;
Qgs3DRenderContext mRenderContext;
QgsVectorLayer *mLayer;
std::unique_ptr<QgsAbstract3DSymbol> mSymbol;
int mLeafLevel;
@ -96,7 +95,7 @@ class QgsVectorLayerChunkLoader : public QgsChunkLoader
private:
const QgsVectorLayerChunkLoaderFactory *mFactory;
std::unique_ptr<QgsFeature3DHandler> mHandler;
Qgs3DRenderContext mContext;
Qgs3DRenderContext mRenderContext;
std::unique_ptr<QgsVectorLayerFeatureSource> mSource;
bool mCanceled = false;
QFutureWatcher<void> *mFutureWatcher = nullptr;

View File

@ -23,7 +23,7 @@
QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer,
const Qgs3DMapSettingsSnapshot &map,
const Qgs3DRenderContext &context,
const QgsCoordinateTransform &coordinateTransform,
QgsPointCloud3DSymbol *symbol,
float maximumScreenSpaceError,
@ -33,7 +33,7 @@ QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *laye
int pointBudget )
: Qgs3DMapSceneEntity( nullptr )
, mLayer( layer )
, mMap( map )
, mRenderContext( context )
, mCoordinateTransform( coordinateTransform )
, mZValueScale( zValueScale )
, mZValueOffset( zValueOffset )
@ -43,14 +43,14 @@ QgsVirtualPointCloudEntity::QgsVirtualPointCloudEntity( QgsPointCloudLayer *laye
{
mSymbol.reset( symbol );
mBboxesEntity = new QgsChunkBoundsEntity( this );
const QgsRectangle mapExtent = Qgs3DUtils::tryReprojectExtent2D( mMap.extent(), mMap.crs(), layer->crs(), mMap.transformContext() );
const QgsRectangle mapExtent = Qgs3DUtils::tryReprojectExtent2D( mRenderContext.extent(), mRenderContext.crs(), layer->crs(), mRenderContext.transformContext() );
const QVector<QgsPointCloudSubIndex> subIndexes = provider()->subIndexes();
for ( int i = 0; i < subIndexes.size(); ++i )
{
const QgsPointCloudSubIndex &si = subIndexes.at( i );
const QgsRectangle intersection = si.extent().intersect( mapExtent );
mBboxes << Qgs3DUtils::mapToWorldExtent( intersection, si.zRange().lower(), si.zRange().upper(), mMap.origin() );
mBboxes << Qgs3DUtils::mapToWorldExtent( intersection, si.zRange().lower(), si.zRange().upper(), mRenderContext.origin() );
createChunkedEntityForSubIndex( i );
}
@ -86,7 +86,7 @@ void QgsVirtualPointCloudEntity::createChunkedEntityForSubIndex( int i )
return;
QgsPointCloudLayerChunkedEntity *newChunkedEntity = new QgsPointCloudLayerChunkedEntity( si.index(),
mMap,
mRenderContext,
mCoordinateTransform,
static_cast< QgsPointCloud3DSymbol * >( mSymbol->clone() ),
mMaximumScreenSpaceError,

View File

@ -31,7 +31,7 @@
#include "qgscoordinatetransform.h"
#include "qgschunkedentity_p.h"
#include "qgs3dmapsceneentity_p.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
class QgsAABB;
class QgsChunkBoundsEntity;
@ -57,7 +57,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity
Q_OBJECT
public:
//! Constructs
QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, const Qgs3DMapSettingsSnapshot &map, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes,
QgsVirtualPointCloudEntity( QgsPointCloudLayer *layer, const Qgs3DRenderContext &context, const QgsCoordinateTransform &coordinateTransform, QgsPointCloud3DSymbol *symbol, float maxScreenError, bool showBoundingBoxes,
double zValueScale, double zValueOffset, int pointBudget );
//! This is called when the camera moves. It's responsible for loading new indexes and decides if subindex will be rendered as bbox or chunked entity.
@ -96,7 +96,7 @@ class QgsVirtualPointCloudEntity : public Qgs3DMapSceneEntity
QMap<int, QgsChunkedEntity *> mChunkedEntitiesMap;
QgsChunkBoundsEntity *mBboxesEntity = nullptr;
QList<QgsAABB> mBboxes;
Qgs3DMapSettingsSnapshot mMap;
Qgs3DRenderContext mRenderContext;
QgsCoordinateTransform mCoordinateTransform;
QgsPointCloudIndex *mPointCloudIndex;
std::unique_ptr< QgsPointCloud3DSymbol > mSymbol;

View File

@ -99,11 +99,11 @@ bool QgsBufferedLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context,
const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->materialSettings() );
outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true,
outNormal.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true,
false, false, false, texturedMaterialSettings ? texturedMaterialSettings->requiresTextureCoordinates() : false,
3,
texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) );
outSelected.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true,
outSelected.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true,
false, false, false, texturedMaterialSettings ? texturedMaterialSettings->requiresTextureCoordinates() : false,
3,
texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) );
@ -168,7 +168,7 @@ void QgsBufferedLine3DSymbolHandler::processFeature( const QgsFeature &f, const
void QgsBufferedLine3DSymbolHandler::processPolygon( QgsPolygon *polyBuffered, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, LineData &out )
{
Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context.map() );
Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context );
Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 );
const uint startingTriangleIndex = static_cast<uint>( out.tessellator->dataVerticesCount() / 3 );
@ -201,7 +201,7 @@ void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, cons
QgsMaterialContext materialContext;
materialContext.setIsSelected( selected );
materialContext.setSelectionColor( context.map().selectionColor() );
materialContext.setSelectionColor( context.selectionColor() );
Qt3DRender::QMaterial *mat = mSymbol->materialSettings()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext );
// extract vertex buffer data from tessellator
@ -272,8 +272,8 @@ bool QgsThickLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QS
outNormal.withAdjacency = true;
outSelected.withAdjacency = true;
outNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context.map() );
outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context.map() );
outNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context );
outSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context );
QSet<QString> attrs = mSymbol->dataDefinedProperties().referencedFields( context.expressionContext() );
attributeNames.unite( attrs );
@ -347,7 +347,7 @@ void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Q
// material (only ambient color is used for the color)
QgsMaterialContext materialContext;
materialContext.setIsSelected( selected );
materialContext.setSelectionColor( context.map().selectionColor() );
materialContext.setSelectionColor( context.selectionColor() );
Qt3DRender::QMaterial *mat = mSymbol->materialSettings()->toMaterial( QgsMaterialSettingsRenderingTechnique::Lines, materialContext );
if ( !mat )
{

View File

@ -46,12 +46,12 @@ QgsLineVertexData::QgsLineVertexData()
vertices << QVector3D();
}
void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettingsSnapshot &map )
void QgsLineVertexData::init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DRenderContext &context )
{
altClamping = clamping;
altBinding = binding;
baseHeight = height;
mapSettings = map;
renderContext = context;
}
QByteArray QgsLineVertexData::createVertexBuffer()
@ -133,11 +133,11 @@ void QgsLineVertexData::addLineString( const QgsLineString &lineString, float ex
for ( int i = 0; i < lineString.vertexCount(); ++i )
{
QgsPoint p = lineString.pointN( i );
float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, mapSettings );
float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, renderContext );
vertices << QVector3D( static_cast< float >( p.x() - mapSettings.origin().x() ),
vertices << QVector3D( static_cast< float >( p.x() - renderContext.origin().x() ),
z,
static_cast< float >( -( p.y() - mapSettings.origin().y() ) ) );
static_cast< float >( -( p.y() - renderContext.origin().y() ) ) );
indexes << vertices.count() - 1;
}
@ -162,19 +162,19 @@ void QgsLineVertexData::addVerticalLines( const QgsLineString &lineString, float
for ( int i = 0; i < lineString.vertexCount(); ++i )
{
QgsPoint p = lineString.pointN( i );
float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, mapSettings );
float z = Qgs3DUtils::clampAltitude( p, altClamping, altBinding, baseHeight + extraHeightOffset, centroid, renderContext );
float z2 = z + verticalLength;
if ( withAdjacency )
indexes << vertices.count(); // add the following vertex (for adjacency)
vertices << QVector3D( static_cast< float >( p.x() - mapSettings.origin().x() ),
vertices << QVector3D( static_cast< float >( p.x() - renderContext.origin().x() ),
z,
static_cast< float >( -( p.y() - mapSettings.origin().y() ) ) );
static_cast< float >( -( p.y() - renderContext.origin().y() ) ) );
indexes << vertices.count() - 1;
vertices << QVector3D( static_cast< float >( p.x() - mapSettings.origin().x() ),
vertices << QVector3D( static_cast< float >( p.x() - renderContext.origin().x() ),
z2,
static_cast< float >( -( p.y() - mapSettings.origin().y() ) ) );
static_cast< float >( -( p.y() - renderContext.origin().y() ) ) );
indexes << vertices.count() - 1;
if ( withAdjacency )

View File

@ -33,7 +33,7 @@
#define SIP_NO_FILE
#include "qgis.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
namespace Qt3DCore
@ -79,11 +79,11 @@ struct QgsLineVertexData
Qgis::AltitudeClamping altClamping = Qgis::AltitudeClamping::Relative;
Qgis::AltitudeBinding altBinding = Qgis::AltitudeBinding::Vertex;
float baseHeight = 0;
Qgs3DMapSettingsSnapshot mapSettings;
Qgs3DRenderContext renderContext;
QgsLineVertexData();
void init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DMapSettingsSnapshot &map );
void init( Qgis::AltitudeClamping clamping, Qgis::AltitudeBinding binding, float height, const Qgs3DRenderContext &renderContext );
QByteArray createVertexBuffer();
QByteArray createIndexBuffer();

View File

@ -26,9 +26,8 @@
#include "qgspoint3dbillboardmaterial.h"
#include "qgsterraintextureimage_p.h"
#include "qgssymbollayerutils.h"
#include "qgs3dmapsettings.h"
#include "qgsmarkersymbol.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
QgsPoint3DBillboardMaterial::QgsPoint3DBillboardMaterial()
: mSize( new Qt3DRender::QParameter( "BB_SIZE", QSizeF( 100, 100 ), this ) )
@ -114,21 +113,21 @@ void QgsPoint3DBillboardMaterial::setTexture2DFromImage( QImage image, double si
setSize( QSizeF( size + size, size + size ) );
}
void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DMapSettingsSnapshot &map, bool selected )
void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DRenderContext &context, bool selected )
{
// Default texture
const std::unique_ptr< QgsMarkerSymbol> defaultSymbol( static_cast<QgsMarkerSymbol *>( QgsSymbol::defaultSymbol( Qgis::GeometryType::Point ) ) );
setTexture2DFromSymbol( defaultSymbol.get(), map, selected );
setTexture2DFromSymbol( defaultSymbol.get(), context, selected );
}
void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettingsSnapshot &map, bool selected )
void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected )
{
QgsRenderContext context;
context.setSelectionColor( map.selectionColor() );
context.setScaleFactor( map.outputDpi() / 25.4 );
context.setFlag( Qgis::RenderContextFlag::Antialiasing );
context.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms );
const double pixelSize = context.convertToPainterUnits( markerSymbol->size( context ), markerSymbol->sizeUnit() );
QgsRenderContext context2D;
context2D.setSelectionColor( context.selectionColor() );
context2D.setScaleFactor( context.outputDpi() / 25.4 );
context2D.setFlag( Qgis::RenderContextFlag::Antialiasing );
context2D.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms );
const double pixelSize = context2D.convertToPainterUnits( markerSymbol->size( context2D ), markerSymbol->sizeUnit() );
// This number is an max estimation ratio between stroke width and symbol size.
const double strokeRatio = 0.5;
@ -138,7 +137,7 @@ void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *marke
const double minimumExtraSize = 40;
const double extraPixel = minimumExtraSize > pixelSize * strokeRatio ? minimumExtraSize : pixelSize * strokeRatio;
const int pixelWithExtra = std::ceil( pixelSize + extraPixel );
const QPixmap symbolPixmap = QgsSymbolLayerUtils::symbolPreviewPixmap( markerSymbol, QSize( pixelWithExtra, pixelWithExtra ), 0, &context, selected );
const QPixmap symbolPixmap = QgsSymbolLayerUtils::symbolPreviewPixmap( markerSymbol, QSize( pixelWithExtra, pixelWithExtra ), 0, &context2D, selected );
const QImage symbolImage = symbolPixmap.toImage();
const QImage flippedSymbolImage = symbolImage.mirrored();
setTexture2DFromImage( flippedSymbolImage, pixelWithExtra );

View File

@ -20,11 +20,10 @@
#include <Qt3DRender/QTexture>
#include <Qt3DRender/QMaterial>
#include "qgs3dmapsettings.h"
#define SIP_NO_FILE
class QgsMarkerSymbol;
class Qgs3DRenderContext;
/**
* \ingroup 3d
@ -52,11 +51,11 @@ class QgsPoint3DBillboardMaterial : public Qt3DRender::QMaterial
//! Returns the size of the view port.
QSizeF windowSize() const;
//! Set default symbol for the texture with \a map and \a selected parameter for rendering.
void useDefaultSymbol( const Qgs3DMapSettingsSnapshot &map, bool selected = false );
//! Set default symbol for the texture with \a context and \a selected parameter for rendering.
void useDefaultSymbol( const Qgs3DRenderContext &context, bool selected = false );
//! Set \a markerSymbol for the texture with \a map and \a selected parameter for rendering.
void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettingsSnapshot &map, bool selected = false );
//! Set \a markerSymbol for the texture with \a context and \a selected parameter for rendering.
void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected = false );
private:
//! Set the texture2D of the billboard from \a image with \a size.

View File

@ -57,8 +57,6 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry;
#include <QVector3D>
#include "qgspoint3dsymbol.h"
#include "qgs3dmapsettings.h"
#include "qgsapplication.h"
#include "qgsvectorlayer.h"
#include "qgs3dutils.h"
@ -122,7 +120,7 @@ void QgsInstancedPoint3DSymbolHandler::processFeature( const QgsFeature &feature
if ( feature.geometry().isNull() )
return;
Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions );
Qgs3DUtils::extractPointPositions( feature, context, mSymbol->altitudeClamping(), out.positions );
mFeatureCount++;
}
@ -206,7 +204,7 @@ void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co
// build the default material
QgsMaterialContext materialContext;
materialContext.setIsSelected( selected );
materialContext.setSelectionColor( context.map().selectionColor() );
materialContext.setSelectionColor( context.selectionColor() );
Qt3DRender::QMaterial *mat = material( mSymbol.get(), materialContext );
// build the entity
@ -409,8 +407,8 @@ class QgsModelPoint3DSymbolHandler : public QgsFeature3DHandler
private:
static void addSceneEntities( const Qgs3DMapSettingsSnapshot &map, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent );
static void addMeshEntities( const Qgs3DMapSettingsSnapshot &map, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected );
static void addSceneEntities( const Qgs3DRenderContext &context, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent );
static void addMeshEntities( const Qgs3DRenderContext &context, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected );
static Qt3DCore::QTransform *transform( QVector3D position, const QgsPoint3DSymbol *symbol );
//! temporary data we will pass to the tessellator
@ -445,7 +443,7 @@ void QgsModelPoint3DSymbolHandler::processFeature( const QgsFeature &feature, co
if ( feature.geometry().isNull() )
return;
Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions );
Qgs3DUtils::extractPointPositions( feature, context, mSymbol->altitudeClamping(), out.positions );
mFeatureCount++;
}
@ -467,7 +465,7 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const
{
if ( selected )
{
addMeshEntities( context.map(), out.positions, mSymbol.get(), parent, true );
addMeshEntities( context, out.positions, mSymbol.get(), parent, true );
}
else
{
@ -475,20 +473,19 @@ void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const
if ( mSymbol->shapeProperty( QStringLiteral( "overwriteMaterial" ) ).toBool()
|| ( mSymbol->materialSettings() && mSymbol->materialSettings()->type() != QLatin1String( "null" ) ) )
{
addMeshEntities( context.map(), out.positions, mSymbol.get(), parent, false );
addMeshEntities( context, out.positions, mSymbol.get(), parent, false );
}
else
{
addSceneEntities( context.map(), out.positions, mSymbol.get(), parent );
addSceneEntities( context, out.positions, mSymbol.get(), parent );
}
}
}
void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettingsSnapshot &map, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent )
void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DRenderContext &, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent )
{
Q_UNUSED( map )
for ( const QVector3D &position : positions )
{
const QString source = QgsApplication::sourceCache()->localFilePath( symbol->shapeProperty( QStringLiteral( "model" ) ).toString() );
@ -512,7 +509,7 @@ void QgsModelPoint3DSymbolHandler::addSceneEntities( const Qgs3DMapSettingsSnaps
}
}
void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettingsSnapshot &map, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected )
void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DRenderContext &context, const QVector<QVector3D> &positions, const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, bool are_selected )
{
if ( positions.empty() )
return;
@ -520,7 +517,7 @@ void QgsModelPoint3DSymbolHandler::addMeshEntities( const Qgs3DMapSettingsSnapsh
// build the default material
QgsMaterialContext materialContext;
materialContext.setIsSelected( are_selected );
materialContext.setSelectionColor( map.selectionColor() );
materialContext.setSelectionColor( context.selectionColor() );
Qt3DRender::QMaterial *mat = symbol->materialSettings()->toMaterial( QgsMaterialSettingsRenderingTechnique::Triangles, materialContext );
// get nodes
@ -604,7 +601,7 @@ void QgsPoint3DBillboardSymbolHandler::processFeature( const QgsFeature &feature
if ( feature.geometry().isNull() )
return;
Qgs3DUtils::extractPointPositions( feature, context.map(), mSymbol->altitudeClamping(), out.positions );
Qgs3DUtils::extractPointPositions( feature, context, mSymbol->altitudeClamping(), out.positions );
mFeatureCount++;
}
@ -640,11 +637,11 @@ void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, co
if ( symbol )
{
billboardMaterial->setTexture2DFromSymbol( symbol, context.map(), selected );
billboardMaterial->setTexture2DFromSymbol( symbol, context, selected );
}
else
{
billboardMaterial->useDefaultSymbol( context.map(), selected );
billboardMaterial->useDefaultSymbol( context, selected );
}
// Billboard Transform

View File

@ -33,6 +33,7 @@
class QgsPoint3DSymbol;
class QgsAbstract3DSymbol;
class Qgs3DRenderContext;
namespace Qgs3DSymbolImpl
{
@ -40,7 +41,7 @@ namespace Qgs3DSymbolImpl
QgsFeature3DHandler *handlerForPoint3DSymbol( QgsVectorLayer *layer, const QgsAbstract3DSymbol *symbol );
//! convenience function to create a complete entity from QgsPolygon3DSymbol (will run getFeatures() on the layer)
Qt3DCore::QEntity *entityForPoint3DSymbol( const Qgs3DMapSettingsSnapshot &map, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol );
Qt3DCore::QEntity *entityForPoint3DSymbol( const Qgs3DRenderContext &context, QgsVectorLayer *layer, const QgsPoint3DSymbol &symbol );
}
/// @endcond

View File

@ -20,16 +20,18 @@
#include "qgspointcloud3dsymbol.h"
#include "qgspointcloudattribute.h"
#include "qgspointcloudrequest.h"
#include "qgs3dmapsettings.h"
#include "qgspointcloudindex.h"
#include "qgspointcloudblockrequest.h"
#include "qgsfeedback.h"
#include "qgsaabb.h"
#include <Qt3DCore/QEntity>
#include <Qt3DRender/QGeometryRenderer>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <Qt3DRender/QAttribute>
#include <Qt3DRender/QBuffer>
#include <Qt3DRender/QGeometry>
#include <Qt3DRender/QParameter>
typedef Qt3DRender::QAttribute Qt3DQAttribute;
typedef Qt3DRender::QBuffer Qt3DQBuffer;
@ -568,7 +570,7 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p
QgsPointCloudRequest request;
request.setAttributes( attributes );
request.setFilterRect( context.extent() );
request.setFilterRect( context.layerExtent() );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;
@ -607,7 +609,7 @@ void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *p
alreadyPrintedDebug = true;
}
}
const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) );
const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) );
outNormal.positions.push_back( QVector3D( static_cast<float>( point.x() ), static_cast<float>( point.y() ), static_cast<float>( point.z() ) ) );
}
}
@ -691,7 +693,7 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc,
QgsPointCloudRequest request;
request.setAttributes( attributes );
request.setFilterRect( context.extent() );
request.setFilterRect( context.layerExtent() );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;
@ -727,7 +729,7 @@ void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc,
alreadyPrintedDebug = true;
}
}
const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) );
const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) );
outNormal.positions.push_back( QVector3D( static_cast<float>( point.x() ), static_cast<float>( point.y() ), static_cast<float>( point.z() ) ) );
if ( attrIsX )
@ -796,7 +798,7 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const
QgsPointCloudRequest request;
request.setAttributes( attributes );
request.setFilterRect( context.extent() );
request.setFilterRect( context.layerExtent() );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;
@ -846,7 +848,7 @@ void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const
alreadyPrintedDebug = true;
}
}
const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) );
const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) );
QVector3D color( 0.0f, 0.0f, 0.0f );
@ -959,7 +961,7 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex
QgsPointCloudRequest request;
request.setAttributes( attributes );
request.setFilterRect( context.extent() );
request.setFilterRect( context.layerExtent() );
std::unique_ptr<QgsPointCloudBlock> block( pointCloudBlock( pc, n, request, context ) );
if ( !block )
return;
@ -1010,7 +1012,7 @@ void QgsClassificationPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex
alreadyPrintedDebug = true;
}
}
const QgsVector3D point = context.map().mapToWorldCoordinates( QgsVector3D( x, y, z ) );
const QgsVector3D point = context.mapToWorldCoordinates( QgsVector3D( x, y, z ) );
float iParam = 0.0f;
if ( attrIsX )
iParam = x;

View File

@ -17,7 +17,7 @@
#include "qgspolygon3dsymbol.h"
#include "qgstessellatedpolygongeometry.h"
#include "qgs3dmapsettings.h"
#include "qgs3drendercontext.h"
#include "qgs3dutils.h"
#include "qgstessellator.h"
#include "qgsphongtexturedmaterialsettings.h"
@ -90,15 +90,15 @@ class QgsPolygon3DSymbolHandler : public QgsFeature3DHandler
bool QgsPolygon3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
{
outEdges.withAdjacency = true;
outEdges.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), 0, context.map() );
outEdges.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), 0, context );
const QgsPhongTexturedMaterialSettings *texturedMaterialSettings = dynamic_cast< const QgsPhongTexturedMaterialSettings * >( mSymbol->materialSettings() );
outNormal.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol->invertNormals(), mSymbol->addBackFaces(), false,
outNormal.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true, mSymbol->invertNormals(), mSymbol->addBackFaces(), false,
texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates(),
mSymbol->renderedFacade(),
texturedMaterialSettings ? texturedMaterialSettings->textureRotation() : 0 ) );
outSelected.tessellator.reset( new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true, mSymbol->invertNormals(),
outSelected.tessellator.reset( new QgsTessellator( context.origin().x(), context.origin().y(), true, mSymbol->invertNormals(),
mSymbol->addBackFaces(), false,
texturedMaterialSettings && texturedMaterialSettings->requiresTextureCoordinates(),
mSymbol->renderedFacade(),
@ -138,7 +138,7 @@ void QgsPolygon3DSymbolHandler::processPolygon( const QgsPolygon *poly, QgsFeatu
}
}
Qgs3DUtils::clampAltitudes( polyClone.get(), mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), offset, context.map() );
Qgs3DUtils::clampAltitudes( polyClone.get(), mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), offset, context );
Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 );
const uint startingTriangleIndex = static_cast<uint>( out.tessellator->dataVerticesCount() / 3 );
@ -311,7 +311,7 @@ Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSy
{
QgsMaterialContext materialContext;
materialContext.setIsSelected( isSelected );
materialContext.setSelectionColor( context.map().selectionColor() );
materialContext.setSelectionColor( context.selectionColor() );
const bool dataDefined = mSymbol->materialSettings()->dataDefinedProperties().hasActiveProperties();
Qt3DRender::QMaterial *material = symbol->materialSettings()->toMaterial( dataDefined ?

View File

@ -67,9 +67,9 @@ QgsRectangle QgsDemTerrainGenerator::rootChunkExtent() const
return mTerrainTilingScheme.tileToExtent( 0, 0, 0 );
}
float QgsDemTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const
float QgsDemTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext &context ) const
{
Q_UNUSED( map )
Q_UNUSED( context )
if ( mHeightMapGenerator )
return mHeightMapGenerator->heightAt( x, y );
else

View File

@ -20,9 +20,6 @@
#include "qgsterraingenerator.h"
#include <memory>
class QgsRasterLayer;
class QgsDemHeightMapGenerator;
@ -70,7 +67,7 @@ class _3D_EXPORT QgsDemTerrainGenerator : public QgsTerrainGenerator
Type type() const override;
QgsRectangle rootChunkExtent() const override;
void setExtent( const QgsRectangle &extent ) override;
float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override;
float heightAt( double x, double y, const Qgs3DRenderContext &context ) const override;
void writeXml( QDomElement &elem ) const override;
void readXml( const QDomElement &elem ) override;
void resolveReferences( const QgsProject &project ) override;

View File

@ -49,9 +49,9 @@ QgsRectangle QgsOnlineTerrainGenerator::rootChunkExtent() const
return mTerrainTilingScheme.tileToExtent( 0, 0, 0 );
}
float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const
float QgsOnlineTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext &context ) const
{
Q_UNUSED( map )
Q_UNUSED( context )
if ( mHeightMapGenerator )
return mHeightMapGenerator->heightAt( x, y );
else

View File

@ -63,7 +63,7 @@ class _3D_EXPORT QgsOnlineTerrainGenerator : public QgsTerrainGenerator
Type type() const override;
QgsRectangle rootChunkExtent() const override;
void setExtent( const QgsRectangle &extent ) override;
float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const override;
float heightAt( double x, double y, const Qgs3DRenderContext &context ) const override;
void writeXml( QDomElement &elem ) const override;
void readXml( const QDomElement &elem ) override;
//void resolveReferences( const QgsProject &project ) override;

View File

@ -44,11 +44,11 @@ void QgsTerrainGenerator::rootChunkHeightRange( float &hMin, float &hMax ) const
hMax = 400;
}
float QgsTerrainGenerator::heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const
float QgsTerrainGenerator::heightAt( double x, double y, const Qgs3DRenderContext &context ) const
{
Q_UNUSED( x )
Q_UNUSED( y )
Q_UNUSED( map )
Q_UNUSED( context )
return 0.f;
}

View File

@ -23,7 +23,7 @@
class QgsAABB;
class Qgs3DMapSettings;
class Qgs3DMapSettingsSnapshot;
class Qgs3DRenderContext;
class QgsRectangle;
class QgsTerrainEntity;
@ -88,7 +88,7 @@ class _3D_EXPORT QgsTerrainGenerator : public QgsQuadtreeChunkLoaderFactory
virtual void rootChunkHeightRange( float &hMin, float &hMax ) const;
//! Returns height at (x,y) in terrain's CRS
virtual float heightAt( double x, double y, const Qgs3DMapSettingsSnapshot &map ) const;
virtual float heightAt( double x, double y, const Qgs3DRenderContext &context ) const;
//! Write terrain generator's configuration to XML
virtual void writeXml( QDomElement &elem ) const = 0;

View File

@ -62,6 +62,16 @@
#define QGIS_CHECK_QOBJECT_THREAD_EQUALITY(other) do {} while(false);(void)other;
#endif
#ifdef __clang_analyzer__
#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) do {} while(false);(void)other;
#elif defined(AGGRESSIVE_SAFE_MODE)
#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) if ( other->thread() != QThread::currentThread() ) {qFatal( "%s", QStringLiteral("%2 (%1:%3) Access from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), other->objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( other->thread() ), 0, 16 ).toLocal8Bit().constData() ); }
#elif defined(QGISDEBUG)
#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) if ( other->thread() != QThread::currentThread() ) {qWarning() << QStringLiteral("%2 (%1:%3) Access from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), other->objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( other->thread() ), 0, 16 ).toLocal8Bit().constData(); }
#else
#define QGIS_CHECK_OTHER_QOBJECT_THREAD_ACCESS(other) do {} while(false);(void)other;
#endif
/**
* \ingroup core

View File

@ -30,8 +30,7 @@
#include "qgsoffscreen3dengine.h"
#include "qgspointlightsettings.h"
#include "qgsproject.h"
#include "qgs3dmapsettingssnapshot.h"
#include "qgs3drendercontext.h"
class TestQgsMesh3DRendering : public QgsTest
{
@ -122,7 +121,7 @@ void TestQgsMesh3DRendering::testMeshTerrain()
meshTerrain->setLayer( mLayerMeshTerrain );
map->setTerrainGenerator( meshTerrain );
QCOMPARE( meshTerrain->heightAt( 750, 2500, map->snapshot() ), 500.0 );
QCOMPARE( meshTerrain->heightAt( 750, 2500, Qgs3DRenderContext::fromMapSettings( map ) ), 500.0 );
QgsOffscreen3DEngine engine;
Qgs3DMapScene *scene = new Qgs3DMapScene( *map, &engine );