74#include <QOpenGLContext>
75#include <QOpenGLFunctions>
80#include <Qt3DExtras/QDiffuseSpecularMaterial>
81#include <Qt3DExtras/QForwardRenderer>
82#include <Qt3DExtras/QPhongMaterial>
83#include <Qt3DExtras/QSphereMesh>
84#include <Qt3DLogic/QFrameAction>
85#include <Qt3DRender/QCamera>
86#include <Qt3DRender/QCullFace>
87#include <Qt3DRender/QDepthTest>
88#include <Qt3DRender/QEffect>
89#include <Qt3DRender/QMaterial>
90#include <Qt3DRender/QMesh>
91#include <Qt3DRender/QRenderPass>
92#include <Qt3DRender/QRenderSettings>
93#include <Qt3DRender/QRenderState>
94#include <Qt3DRender/QSceneLoader>
95#include <Qt3DRender/QTechnique>
98#include "moc_qgs3dmapscene.cpp"
100using namespace Qt::StringLiterals;
109 onBackgroundColorChanged();
114 mEngine->renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::OnDemand );
116 QRect viewportRect( QPoint( 0, 0 ), mEngine->size() );
122 float aspectRatio = ( float ) viewportRect.width() / viewportRect.height();
123 mEngine->camera()->lens()->setPerspectiveProjection( mMap.fieldOfView(), aspectRatio, 10.f, 10000.0f );
125 mFrameAction =
new Qt3DLogic::QFrameAction();
126 connect( mFrameAction, &Qt3DLogic::QFrameAction::triggered,
this, &Qgs3DMapScene::onFrameTriggered );
127 addComponent( mFrameAction );
133 mCameraController->resetGlobe( 10'000'000 );
135 mCameraController->resetView( 1000 );
137 addCameraViewCenterEntity( mEngine->camera() );
138 addCameraRotationCenterEntity( mCameraController );
143 createTerrainDeferred();
175 const QList<QgsMapLayer *> modelVectorLayers = mModelVectorLayers;
181 if ( renderer->
type() ==
"vector"_L1 )
184 if ( pointSymbol && pointSymbol->
shapeProperty( u
"model"_s ).toString() == url )
186 removeLayerEntity( layer );
187 addLayerEntity( layer );
190 else if ( renderer->
type() ==
"rulebased"_L1 )
196 if ( pointSymbol && pointSymbol->
shapeProperty( u
"model"_s ).toString() == url )
198 removeLayerEntity( layer );
199 addLayerEntity( layer );
215 onBackgroundSettingsChanged();
220 onEyeDomeShadingSettingsChanged();
222 onDebugDepthMapSettingsChanged();
224 onAmbientOcclusionSettingsChanged();
226 onMsaaEnabledChanged();
228 onBloomSettingsChanged();
233 mOverlayUpdateTimer =
new QTimer(
this );
234 mOverlayUpdateTimer->setSingleShot(
true );
235 mOverlayUpdateTimer->setInterval( 250 );
236 connect( mOverlayUpdateTimer, &QTimer::timeout,
this, &Qgs3DMapScene::applyPendingOverlayUpdate );
239 onShowMapOverlayChanged();
241 onCameraMovementSpeedChanged();
243 on3DAxisSettingsChanged();
250 mCameraController->resetGlobe( 10'000'000 );
256 const double side = std::max( extent.
width(), extent.
height() );
257 double d = side / 2 / std::tan(
cameraController()->camera()->fieldOfView() / 2 * M_PI / 180 );
259 mCameraController->resetView(
static_cast<float>( d ) );
270 const double xSide = std::abs( p1.
x() - p2.
x() );
271 const double ySide = std::abs( p1.
y() - p2.
y() );
272 const double side = std::max( xSide, ySide );
274 const double fov = qDegreesToRadians(
cameraController()->camera()->fieldOfView() );
275 double distance = side / 2.0f / std::tan( fov / 2.0f );
280 distance += zRange.
upper();
284 mCameraController->setViewFromTop(
285 static_cast<float>( center.
x() - origin.
x() ),
286 static_cast<float>( center.
y() - origin.
y() ),
287 static_cast<float>( distance )
294 Qt3DRender::QCamera *camera = mCameraController->camera();
295 QVector<QgsPointXY> extent;
296 QVector<int> pointsOrder = { 0, 1, 3, 2 };
297 for (
int i : pointsOrder )
299 const QPoint p( ( ( i >> 0 ) & 1 ) ? 0 : mEngine->size().width(), ( ( i >> 1 ) & 1 ) ? 0 : mEngine->size().height() );
302 if ( dir.z() == 0.0 )
303 dir.setZ( 0.000001 );
304 double t = -ray.
origin().z() / dir.z();
308 t = camera->farPlane();
313 t = std::min<float>( t, camera->farPlane() );
315 QVector3D planePoint = ray.
origin() + t * dir;
316 QgsVector3D pMap = mMap.worldToMapCoordinates( planePoint );
325 for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
326 count += entity->pendingJobsCount();
332 Qt3DRender::QCamera *camera = mCameraController->camera();
333 const double fov = camera->fieldOfView();
334 const QSize size = mEngine->size();
335 const int screenSizePx = std::max( size.width(), size.height() );
339 const double frustumWidthAtDistance = 2 * distance * tan( fov / 2 );
340 const double err = frustumWidthAtDistance * epsilon / screenSizePx;
344void Qgs3DMapScene::onCameraChanged()
347 updateCameraNearFarPlanes();
349 onShadowSettingsChanged();
353 schedule2DMapOverlayUpdate();
361 constexpr float ORIGIN_SHIFT_THRESHOLD = 10'000;
362 if ( mSceneOriginShiftEnabled && mEngine->
camera()->position().length() > ORIGIN_SHIFT_THRESHOLD )
370bool Qgs3DMapScene::updateScene(
bool forceUpdate )
372 if ( !mSceneUpdatesEnabled )
378 QgsEventTracing::ScopedEvent traceEvent( u
"3D"_s, forceUpdate ? u
"Force update scene"_s : u
"Update scene"_s );
380 Qgs3DMapSceneEntity::SceneContext sceneContext;
381 Qt3DRender::QCamera *camera = mEngine->camera();
382 sceneContext.cameraFov = camera->fieldOfView();
383 sceneContext.cameraPos = camera->position();
384 const QSize size = mEngine->size();
385 sceneContext.screenSizePx = std::max( size.width(), size.height() );
393 QMatrix4x4 projMatrix;
394 switch ( mMap.projectionType() )
396 case Qt3DRender::QCameraLens::PerspectiveProjection:
398 float fovRadians = ( camera->fieldOfView() / 2.0f ) *
static_cast<float>( M_PI ) / 180.0f;
399 float fovCotan = std::cos( fovRadians ) / std::sin( fovRadians );
402 fovCotan / camera->aspectRatio(), 0, 0, 0,
410 case Qt3DRender::QCameraLens::OrthographicProjection:
412 Qt3DRender::QCameraLens *lens = camera->lens();
415 2.0f / ( lens->right() - lens->left() ), 0, 0, 0,
416 0, 2.0f / ( lens->top() - lens->bottom() ), 0, 0,
418 -( lens->left() + lens->right() ) / ( lens->right() - lens->left() ), -( lens->top() + lens->bottom() ) / ( lens->top() - lens->bottom() ), -1.0f, 1.0f
425 projMatrix = camera->projectionMatrix();
427 sceneContext.viewProjectionMatrix = projMatrix * camera->viewMatrix();
430 bool anyUpdated =
false;
431 for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
433 if ( forceUpdate || ( entity->isEnabled() && entity->needsUpdate() ) )
436 entity->handleSceneUpdate( sceneContext );
437 if ( entity->hasReachedGpuMemoryLimit() )
447bool Qgs3DMapScene::updateCameraNearFarPlanes()
462 QMatrix4x4 viewMatrix = camera->viewMatrix();
468 for ( Qgs3DMapSceneEntity *se : std::as_const( mSceneEntities ) )
470 const QgsRange<float> depthRange = se->getNearFarPlaneRange( viewMatrix );
472 fnear = std::min( fnear, depthRange.
lower() );
473 ffar = std::max( ffar, depthRange.
upper() );
482 if ( fnear == 1e9 && ffar == 0 )
485 sceneZRange = sceneZRange.
isInfinite() ? QgsDoubleRange( 0.0, 0.0 ) : sceneZRange;
492 std::swap( fnear, ffar );
495 float newFar = ffar * 2;
496 float newNear = fnear / 2;
499 camera->setFarPlane( newFar );
500 camera->setNearPlane( newNear );
507void Qgs3DMapScene::onFrameTriggered(
float dt )
509 QgsEventTracing::addEvent( QgsEventTracing::EventType::Instant, u
"3D"_s, u
"Frame begins"_s );
511 mCameraController->frameTriggered( dt );
516 updateCameraNearFarPlanes();
519 static int frameCount = 0;
520 static float accumulatedTime = 0.0f;
522 if ( !mMap.isFpsCounterEnabled() )
530 accumulatedTime += dt;
531 if ( accumulatedTime >= 0.2f )
533 float fps = ( float ) frameCount / accumulatedTime;
535 accumulatedTime = 0.0f;
540void Qgs3DMapScene::update2DMapOverlay(
const QVector<QgsPointXY> &extent2DAsPoints )
542 QgsFrameGraph *frameGraph = mEngine->frameGraph();
545 if ( !mMap.is2DMapOverlayEnabled() )
547 if ( mMapOverlayEntity )
549 mMapOverlayEntity.reset();
551 overlayRenderView.
setEnabled( mMap.debugDepthMapEnabled() );
555 if ( !mMapOverlayEntity )
557 QgsWindow3DEngine *
engine = qobject_cast<QgsWindow3DEngine *>( mEngine );
558 mMapOverlayEntity.reset(
new QgsMapOverlayEntity(
engine, &overlayRenderView, &mMap,
this ) );
559 mMapOverlayEntity->setEnabled(
true );
564 Qt3DRender::QCamera *camera = mEngine->camera();
565 const QgsVector3D extentCenter3D = mMap.worldToMapCoordinates( camera->position() );
566 const QgsPointXY extentCenter2D( extentCenter3D.
x(), extentCenter3D.
y() );
573 double minHalfExtent = std::numeric_limits<double>::max();
574 double maxHalfExtent = 0.0;
575 for (
const QgsPointXY &extentPoint : extent2DAsPoints )
577 const double distance = extentCenter2D.distance( extentPoint );
578 minHalfExtent = std::min( minHalfExtent, distance );
579 maxHalfExtent = std::max( maxHalfExtent, distance );
583 const double sceneHalfExtent = 0.6 * std::max( fullExtent.
width(), fullExtent.
height() );
585 minHalfExtent = std::min( 50., minHalfExtent );
586 maxHalfExtent = std::min( 100., maxHalfExtent );
587 const double smoothFactor = std::sin( mCameraController->pitch() / 90.0 * M_PI_2 );
590 const double adjustedHalfExtent = std::min( 3.0 * ( minHalfExtent + smoothFactor * maxHalfExtent ), sceneHalfExtent );
593 const bool showFrustum = mMap.viewFrustumVisualizationEnabled();
594 mMapOverlayEntity->update( overviewExtent, extent2DAsPoints, mCameraController->yaw(), showFrustum );
597void Qgs3DMapScene::createTerrain()
601 mSceneEntities.removeOne( mTerrain );
609 mSceneEntities.removeOne( mGlobe );
615 if ( !mTerrainUpdateScheduled )
618 QTimer::singleShot( 0,
this, &Qgs3DMapScene::createTerrainDeferred );
619 mTerrainUpdateScheduled =
true;
628void Qgs3DMapScene::createTerrainDeferred()
630 QgsChunkedEntity *terrainOrGlobe =
nullptr;
634 mGlobe =
new QgsGlobeEntity( &mMap );
635 terrainOrGlobe = mGlobe;
637 else if ( mMap.sceneMode() ==
Qgis::SceneMode::Local && mMap.terrainRenderingEnabled() && mMap.terrainGenerator() )
639 double tile0width = mMap.terrainGenerator()->rootChunkExtent().width();
640 int maxZoomLevel =
Qgs3DUtils::maxZoomLevel( tile0width, mMap.terrainSettings()->mapTileResolution(), mMap.terrainSettings()->maximumGroundError() );
641 const QgsBox3D rootBox3D = mMap.terrainGenerator()->rootChunkBox3D( mMap );
642 float rootError = mMap.terrainGenerator()->rootChunkError( mMap );
643 const QgsBox3D clippingBox3D( mMap.extent(), rootBox3D.
zMinimum(), rootBox3D.
zMaximum() );
644 mMap.terrainGenerator()->setupQuadtree( rootBox3D, rootError, maxZoomLevel, clippingBox3D );
646 mTerrain =
new QgsTerrainEntity( &mMap );
647 terrainOrGlobe = mTerrain;
650 if ( terrainOrGlobe )
653 QgsFrameGraph *frameGraph = mEngine->frameGraph();
657 terrainOrGlobe->setParent(
this );
658 terrainOrGlobe->setShowBoundingBoxes( mMap.showTerrainBoundingBoxes() );
660 mSceneEntities << terrainOrGlobe;
663 connect( terrainOrGlobe, &Qgs3DMapSceneEntity::newEntityCreated,
this, [
this]( Qt3DCore::QEntity *entity ) {
665 const QList<QgsGeoTransform *> transforms = entity->findChildren<QgsGeoTransform *>();
666 for ( QgsGeoTransform *transform : transforms )
668 transform->setOrigin( mMap.origin() );
672 handleClippingOnEntity( entity );
677 const QList<QgsMapLayer *>
layers = mMap.layers();
678 for ( QgsMapLayer *layer :
layers )
681 removeLayerEntity( layer );
684 addLayerEntity( layer );
689 mTerrainUpdateScheduled =
false;
692void Qgs3DMapScene::onBackgroundColorChanged()
694 mEngine->setClearColor( mMap.backgroundColor() );
697void Qgs3DMapScene::updateLights()
699 for ( Qt3DCore::QEntity *entity : std::as_const( mLightEntities ) )
700 entity->deleteLater();
701 mLightEntities.clear();
703 QgsFrameGraph *frameGraph = mEngine->frameGraph();
704 const QList<QgsLightSource *> newLights = mMap.lightSources();
705 for (
const QgsLightSource *source : newLights )
707 Qt3DCore::QEntity *entity = source->createEntity( mMap,
this );
709 mLightEntities.append( entity );
712 onShadowSettingsChanged();
715void Qgs3DMapScene::updateCameraLens()
717 mEngine->camera()->lens()->setFieldOfView( mMap.fieldOfView() );
718 mEngine->camera()->lens()->setProjectionType( mMap.projectionType() );
722void Qgs3DMapScene::onLayerRenderer3DChanged()
724 QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
728 removeLayerEntity( layer );
731 addLayerEntity( layer );
734void Qgs3DMapScene::onLayersChanged()
736 QSet<QgsMapLayer *> layersBefore = qgis::listToSet( mLayerEntities.keys() );
737 QList<QgsMapLayer *> layersAdded;
738 const QList<QgsMapLayer *>
layers = mMap.layers();
739 for ( QgsMapLayer *layer :
layers )
741 if ( !layersBefore.contains( layer ) )
743 layersAdded << layer;
747 layersBefore.remove( layer );
752 for ( QgsMapLayer *layer : std::as_const( layersBefore ) )
754 removeLayerEntity( layer );
757 for ( QgsMapLayer *layer : std::as_const( layersAdded ) )
759 addLayerEntity( layer );
765 const QList<QgsMapLayer *>
layers = mLayerEntities.keys();
770 if ( temporalProperties->isActive() )
772 removeLayerEntity( layer );
773 addLayerEntity( layer );
781 Q_ASSERT( sceneNewEntity );
783 mSceneEntities.append( sceneNewEntity );
785 sceneNewEntity->setParent(
this );
787 finalizeNewEntity( sceneNewEntity );
789 connect( sceneNewEntity, &Qgs3DMapSceneEntity::newEntityCreated,
this, [
this]( Qt3DCore::QEntity *entity ) {
790 finalizeNewEntity( entity );
792 updateCameraNearFarPlanes();
802 Q_ASSERT( sceneEntity );
804 mSceneEntities.removeOne( sceneEntity );
806 sceneEntity->deleteLater();
810void Qgs3DMapScene::addLayerEntity(
QgsMapLayer *layer )
822 if ( renderer->
type() ==
"vector"_L1 )
830 mModelVectorLayers.append( layer );
834 else if ( renderer->
type() ==
"rulebased"_L1 )
837 for (
auto rule : rules )
839 const QgsPoint3DSymbol *pointSymbol =
dynamic_cast<const QgsPoint3DSymbol *
>( rule->symbol() );
842 mModelVectorLayers.append( layer );
847 else if ( renderer->
type() ==
"categorized"_L1 )
849 const Qgs3DCategoryList categories =
static_cast<QgsCategorized3DRenderer *
>( renderer )->categories();
850 for (
const Qgs3DRendererCategory &category : categories )
852 const QgsPoint3DSymbol *pointSymbol =
dynamic_cast<const QgsPoint3DSymbol *
>( category.symbol() );
855 mModelVectorLayers.append( layer );
863 QgsMeshLayer3DRenderer *meshRenderer =
static_cast<QgsMeshLayer3DRenderer *
>( renderer );
864 meshRenderer->
setLayer(
static_cast<QgsMeshLayer *
>( layer ) );
868 QgsMesh3DSymbol *sym = meshRenderer->
symbol()->
clone();
874 QgsPointCloudLayer3DRenderer *pointCloudRenderer =
static_cast<QgsPointCloudLayer3DRenderer *
>( renderer );
875 pointCloudRenderer->
setLayer(
static_cast<QgsPointCloudLayer *
>( layer ) );
879 QgsTiledSceneLayer3DRenderer *tiledSceneRenderer =
static_cast<QgsTiledSceneLayer3DRenderer *
>( renderer );
880 tiledSceneRenderer->
setLayer(
static_cast<QgsTiledSceneLayer *
>( layer ) );
884 auto annotationLayerRenderer = qgis::down_cast<QgsAnnotationLayer3DRenderer *>( renderer );
885 annotationLayerRenderer->setLayer( qobject_cast<QgsAnnotationLayer *>( layer ) );
888 Qt3DCore::QEntity *newEntity = renderer->
createEntity( &mMap );
891 mLayerEntities.insert( layer, newEntity );
893 if ( Qgs3DMapSceneEntity *sceneNewEntity = qobject_cast<Qgs3DMapSceneEntity *>( newEntity ) )
900 newEntity->setParent(
this );
901 finalizeNewEntity( newEntity );
910 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
923 QgsPointCloudLayer *pclayer = qobject_cast<QgsPointCloudLayer *>( layer );
929void Qgs3DMapScene::removeLayerEntity(
QgsMapLayer *layer )
931 Qt3DCore::QEntity *entity = mLayerEntities.take( layer );
933 if ( Qgs3DMapSceneEntity *sceneEntity = qobject_cast<Qgs3DMapSceneEntity *>( entity ) )
941 entity->deleteLater();
948 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
952 mModelVectorLayers.removeAll( layer );
962 QgsPointCloudLayer *pclayer = qobject_cast<QgsPointCloudLayer *>( layer );
969void Qgs3DMapScene::finalizeNewEntity( Qt3DCore::QEntity *newEntity )
972 const QList<QgsGeoTransform *> transforms = newEntity->findChildren<QgsGeoTransform *>();
973 for ( QgsGeoTransform *transform : transforms )
975 transform->setOrigin( mMap.origin() );
979 handleClippingOnEntity( newEntity );
983 const QList<Qt3DRender::QMaterial *> childMaterials = newEntity->findChildren<Qt3DRender::QMaterial *>();
987 for ( Qt3DRender::QMaterial *material : childMaterials )
989 if (
auto lm = qobject_cast< QgsLineMaterial * >( material ) )
992 lm->setViewportSize( mEngine->size() );
994 else if (
auto bm = qobject_cast< QgsPoint3DBillboardMaterial * >( material ) )
997 bm->setViewportSize( mEngine->size() );
1001 QgsFrameGraph *frameGraph = mEngine->frameGraph();
1005 const QVector<Qt3DRender::QLayer *>
layers = newEntity->componentsOfType<Qt3DRender::QLayer>();
1014 for ( Qt3DRender::QMaterial *material : childMaterials )
1018 auto materialEntity = qobject_cast<Qt3DCore::QEntity *>( material->parent() );
1019 if ( !materialEntity )
1022 bool materialCastsShadows =
false;
1023 if (
auto qgsMaterial = qobject_cast< QgsMaterial * >( material ) )
1025 if ( qgsMaterial->castsShadows() )
1027 materialCastsShadows =
true;
1033 materialCastsShadows =
true;
1036 if ( materialCastsShadows && !materialEntity->components().contains( shadowCastingEntityLayer ) )
1038 materialEntity->addComponent( shadowCastingEntityLayer );
1044 if (
auto ph = qobject_cast<Qt3DExtras::QDiffuseSpecularMaterial *>( material ) )
1046 if ( ph->diffuse().value<QColor>().alphaF() != 1.0f )
1048 if ( !materialEntity->components().contains( transparentLayer ) )
1050 materialEntity->addComponent( transparentLayer );
1071 else if (
auto billboardMaterial = qobject_cast<QgsPoint3DBillboardMaterial *>( material ) )
1073 Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity *>( billboardMaterial->parent() );
1074 if ( !materialEntity->components().contains( transparentLayer ) )
1076 materialEntity->addComponent( transparentLayer );
1083 if ( Qt3DRender::QEffect *effect = material->effect() )
1085 const QVector<Qt3DRender::QParameter *> parameters = effect->parameters();
1086 for (
const Qt3DRender::QParameter *parameter : parameters )
1088 if ( parameter->name() ==
"opacity" && parameter->value() != 1.0f )
1090 if ( !materialEntity->components().contains( transparentLayer ) )
1092 materialEntity->addComponent( transparentLayer );
1101 if ( childMaterials.empty() )
1104 newEntity->addComponent( shadowCastingEntityLayer );
1108int Qgs3DMapScene::maximumTextureSize()
const
1110 QSurface *surface = mEngine->surface();
1111 QOpenGLContext context;
1113 bool success = context.makeCurrent( surface );
1117 QOpenGLFunctions openglFunctions = QOpenGLFunctions( &context );
1120 openglFunctions.initializeOpenGLFunctions();
1121 openglFunctions.glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );
1130void Qgs3DMapScene::addCameraViewCenterEntity( Qt3DRender::QCamera *camera )
1132 mEntityCameraViewCenter =
new Qt3DCore::QEntity;
1134 Qt3DCore::QTransform *trCameraViewCenter =
new Qt3DCore::QTransform;
1135 mEntityCameraViewCenter->addComponent( trCameraViewCenter );
1136 connect( camera, &Qt3DRender::QCamera::viewCenterChanged,
this, [trCameraViewCenter, camera] { trCameraViewCenter->setTranslation( camera->viewCenter() ); } );
1138 Qt3DExtras::QPhongMaterial *materialCameraViewCenter =
new Qt3DExtras::QPhongMaterial;
1139 materialCameraViewCenter->setAmbient( Qt::red );
1140 mEntityCameraViewCenter->addComponent( materialCameraViewCenter );
1142 Qt3DExtras::QSphereMesh *rendererCameraViewCenter =
new Qt3DExtras::QSphereMesh;
1143 rendererCameraViewCenter->setRadius( 10 );
1144 mEntityCameraViewCenter->addComponent( rendererCameraViewCenter );
1146 mEntityCameraViewCenter->setEnabled( mMap.showCameraViewCenter() );
1147 mEntityCameraViewCenter->setParent(
this );
1154 if ( mSceneState == state )
1156 mSceneState = state;
1160void Qgs3DMapScene::updateSceneState()
1162 if ( mTerrainUpdateScheduled )
1168 for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
1170 if ( entity->isEnabled() && entity->pendingJobsCount() > 0 )
1177 setSceneState(
Ready );
1180void Qgs3DMapScene::onBackgroundSettingsChanged()
1182 if ( mBackgroundEntity )
1184 mBackgroundEntity->deleteLater();
1185 mBackgroundEntity =
nullptr;
1188 const QgsAbstract3DMapBackgroundSettings *settings = mMap.backgroundSettings();
1192 QgsFrameGraph *frameGraph = mEngine->frameGraph();
1196 const QgsSkyboxSettings *skyboxSettings =
dynamic_cast<const QgsSkyboxSettings *
>( settings );
1198 mBackgroundEntity =
new QgsCubeFacesSkyboxEntity( skyboxSettings->
cubeMapping(), faces[u
"posX"_s], faces[u
"posY"_s], faces[u
"posZ"_s], faces[u
"negX"_s], faces[u
"negY"_s], faces[u
"negZ"_s],
this );
1202 const QgsFixedGradientBackgroundSettings *gradientSettings =
dynamic_cast<const QgsFixedGradientBackgroundSettings *
>( settings );
1203 mBackgroundEntity =
new QgsGradientBackgroundEntity( gradientSettings->
topColor(), gradientSettings->
bottomColor(),
this );
1210void Qgs3DMapScene::onShadowSettingsChanged()
1215void Qgs3DMapScene::onAmbientOcclusionSettingsChanged()
1217 mEngine->frameGraph()->updateAmbientOcclusionSettings( mMap.ambientOcclusionSettings() );
1220void Qgs3DMapScene::onBloomSettingsChanged()
1222 mEngine->frameGraph()->updateBloomSettings( mMap.bloomSettings() );
1225void Qgs3DMapScene::onDebugDepthMapSettingsChanged()
1227 mEngine->frameGraph()->updateDebugDepthMapSettings( mMap );
1230void Qgs3DMapScene::onDebugOverlayEnabledChanged()
1232 mEngine->frameGraph()->setDebugOverlayEnabled( mMap.isDebugOverlayEnabled() );
1233 mEngine->renderSettings()->setRenderPolicy( mMap.isDebugOverlayEnabled() ? Qt3DRender::QRenderSettings::Always : Qt3DRender::QRenderSettings::OnDemand );
1236void Qgs3DMapScene::onEyeDomeShadingSettingsChanged()
1238 mEngine->frameGraph()->updateEyeDomeSettings( mMap );
1241void Qgs3DMapScene::onMsaaEnabledChanged()
1243 mEngine->frameGraph()->setMsaaEnabled( mMap.isMsaaEnabled() );
1246void Qgs3DMapScene::onShowMapOverlayChanged()
1249 update2DMapOverlay( extent2D );
1252void Qgs3DMapScene::onCameraMovementSpeedChanged()
1254 mCameraController->setCameraMovementSpeed( mMap.cameraMovementSpeed() );
1257void Qgs3DMapScene::onCameraNavigationModeChanged()
1259 mCameraController->setCameraNavigationMode( mMap.cameraNavigationMode() );
1264 QVector<QString> notParsedLayers;
1275 for (
auto it = mLayerEntities.constBegin(); it != mLayerEntities.constEnd(); ++it )
1278 Qt3DCore::QEntity *rootEntity = it.value();
1280 switch ( layerType )
1284 notParsedLayers.push_back( layer->
name() );
1294 notParsedLayers.push_back( layer->
name() );
1308 if ( !notParsedLayers.empty() )
1310 QString message = tr(
"The following layers were not exported:" ) +
"\n";
1311 for (
const QString &layerName : notParsedLayers )
1312 message += layerName +
"\n";
1321 QVector<const QgsChunkNode *> chunks;
1322 if ( !mLayerEntities.contains( layer ) )
1324 if ( QgsChunkedEntity *
c = qobject_cast<QgsChunkedEntity *>( mLayerEntities[layer] ) )
1326 const QList<QgsChunkNode *> activeNodes =
c->activeNodes();
1327 for ( QgsChunkNode *n : activeNodes )
1328 chunks.push_back( n );
1335 return mMap.extent();
1340 double zMin = std::numeric_limits<double>::max();
1341 double zMax = std::numeric_limits<double>::lowest();
1342 if ( mMap.terrainRenderingEnabled() && mTerrain && !ignoreTerrain )
1344 const QgsBox3D box3D = mTerrain->rootNode()->box3D();
1345 zMin = std::min( zMin, box3D.
zMinimum() );
1346 zMax = std::max( zMax, box3D.
zMaximum() );
1349 for (
auto it = mLayerEntities.constBegin(); it != mLayerEntities.constEnd(); it++ )
1352 switch ( layer->
type() )
1358 zMin = std::min( zMin, zRange.
lower() );
1359 zMax = std::max( zMax, zRange.
upper() );
1364 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1372 zMin = std::min( zMin, verticalGroupMetadata.
minimum() * verticalScale );
1373 zMax = std::max( zMax, verticalGroupMetadata.
maximum() * verticalScale );
1383 zMin = std::min( zMin, zRange.
lower() );
1384 zMax = std::max( zMax, zRange.
upper() );
1397 const QgsDoubleRange zRange( std::min( zMin, std::numeric_limits<double>::max() ), std::max( zMax, std::numeric_limits<double>::lowest() ) );
1408 mEntityRotationCenter =
new Qt3DCore::QEntity;
1410 Qt3DCore::QTransform *trRotationCenter =
new Qt3DCore::QTransform;
1411 mEntityRotationCenter->addComponent( trRotationCenter );
1412 Qt3DExtras::QPhongMaterial *materialRotationCenter =
new Qt3DExtras::QPhongMaterial;
1413 materialRotationCenter->setAmbient( Qt::blue );
1414 mEntityRotationCenter->addComponent( materialRotationCenter );
1415 Qt3DExtras::QSphereMesh *rendererRotationCenter =
new Qt3DExtras::QSphereMesh;
1416 rendererRotationCenter->setRadius( 10 );
1417 mEntityRotationCenter->addComponent( rendererRotationCenter );
1418 mEntityRotationCenter->setEnabled(
false );
1419 mEntityRotationCenter->setParent(
this );
1426void Qgs3DMapScene::on3DAxisSettingsChanged()
1430 m3DAxis->onAxisSettingsChanged();
1434 if ( QgsWindow3DEngine *
engine =
dynamic_cast<QgsWindow3DEngine *
>( mEngine ) )
1436 m3DAxis =
new Qgs3DAxis(
static_cast<Qgs3DMapCanvas *
>(
engine->window() ),
engine->root(),
this, mCameraController, &mMap );
1441void Qgs3DMapScene::onOriginChanged()
1443 const QList<QgsGeoTransform *> geoTransforms = findChildren<QgsGeoTransform *>();
1444 for ( QgsGeoTransform *transform : geoTransforms )
1446 transform->setOrigin( mMap.origin() );
1449 const QList<QgsGeoTransform *> rubberBandGeoTransforms = mEngine->frameGraph()->rubberBandsRootEntity()->findChildren<QgsGeoTransform *>();
1450 for ( QgsGeoTransform *transform : rubberBandGeoTransforms )
1452 transform->setOrigin( mMap.origin() );
1455 const QgsVector3D oldOrigin = mCameraController->origin();
1456 mCameraController->setOrigin( mMap.origin() );
1458 if ( !mClipPlanesEquations.isEmpty() )
1467 QList<QVector4D> newPlanes;
1468 QgsVector3D originShift = mMap.origin() - oldOrigin;
1469 for ( QVector4D plane : std::as_const( mClipPlanesEquations ) )
1471 plane.setW( originShift.
x() * plane.x() + originShift.
y() * plane.y() + originShift.
z() * plane.z() + plane.w() );
1472 newPlanes.append( plane );
1478void Qgs3DMapScene::handleClippingOnEntity( QEntity *entity )
const
1480 if ( mClipPlanesEquations.isEmpty() )
1482 for ( QgsMaterial *material : entity->componentsOfType<QgsMaterial>() )
1484 material->disableClipping();
1489 for ( QgsMaterial *material : entity->componentsOfType<QgsMaterial>() )
1491 material->enableClipping( mClipPlanesEquations );
1497 for ( QObject *child : entity->children() )
1499 Qt3DCore::QEntity *childEntity = qobject_cast<Qt3DCore::QEntity *>( child );
1502 handleClippingOnEntity( childEntity );
1507void Qgs3DMapScene::handleClippingOnAllEntities()
const
1511 for (
auto it = mLayerEntities.constBegin(); it != mLayerEntities.constEnd(); ++it )
1513 handleClippingOnEntity( it.value() );
1517 handleClippingOnEntity( mTerrain );
1521 handleClippingOnEntity( mGlobe );
1529 QgsDebugMsgLevel( u
"Qgs3DMapScene::enableClipping: it is not possible to use more than %1 clipping planes."_s.arg( mMaxClipPlanes ), 2 );
1537 handleClippingOnAllEntities();
1542 mClipPlanesEquations.clear();
1545 mEngine->frameGraph()->removeClipPlanes();
1548 handleClippingOnAllEntities();
1551void Qgs3DMapScene::onStopUpdatesChanged()
1556void Qgs3DMapScene::schedule2DMapOverlayUpdate()
1559 if ( mMap.is2DMapOverlayEnabled() && mOverlayUpdateTimer && !mOverlayUpdateTimer->isActive() )
1561 mOverlayUpdateTimer->start();
1565void Qgs3DMapScene::applyPendingOverlayUpdate()
1567 if ( mMap.is2DMapOverlayEnabled() )
1570 update2DMapOverlay( extent2D );
@ DistinctTextureSkybox
Skybox with 6 distinct textures for different faces.
@ FixedGradientBackground
Two color gradient, fixed in place.
LayerType
Types of layers that can be added to a map.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ Globe
Scene is represented as a globe using a geocentric CRS.
@ Local
Local scene based on a projected CRS.
Manages the various settings the user can choose from when exporting a 3D scene.
bool exportNormals() const
Returns whether normals will be exported.
int terrrainResolution() const
Returns the terrain resolution.
QString sceneFolderPath() const
Returns the scene folder path.
float scale() const
Returns the scale of the exported model.
int terrainTextureResolution() const
Returns the terrain texture resolution.
bool terrainExportEnabled() const
Returns whether terrain export is enabled.
QString sceneName() const
Returns the scene name.
bool smoothEdges() const
Returns whether triangles edges will look smooth.
bool exportTextures() const
Returns whether textures will be exported.
Qgis::Export3DSceneFormat exportFormat() const
Returns the export format for the 3D scene.
void viewed2DExtentFrom3DChanged(QVector< QgsPointXY > extent)
Emitted when the viewed 2D extent seen by the 3D camera has changed.
QList< QVector4D > clipPlaneEquations() const
Returns list of clipping planes if clipping is enabled, otherwise an empty list.
static std::function< QMap< QString, Qgs3DMapScene * >()> sOpenScenesFunction
Static function for returning open 3D map scenes.
void fpsCountChanged(float fpsCount)
Emitted when the FPS count changes.
void setViewFrom2DExtent(const QgsRectangle &extent)
Resets camera view to show the extent extent (top view).
void disableClipping()
Disables OpenGL clipping.
QVector< const QgsChunkNode * > getLayerActiveChunkNodes(QgsMapLayer *layer) SIP_SKIP
Returns the active chunk nodes of layer.
void gpuMemoryLimitReached()
Emitted when one of the entities reaches its GPU memory limit and it is not possible to lower the GPU...
static Q_DECL_DEPRECATED QMap< QString, Qgs3DMapScene * > openScenes() SIP_DEPRECATED
Returns a map of 3D map scenes (by name) open in the QGIS application.
QgsCameraController * cameraController() const
Returns camera controller.
SceneState
Enumeration of possible states of the 3D scene.
@ Ready
The scene is fully loaded/updated.
@ Updating
The scene is still being loaded/updated.
bool exportScene(const Qgs3DMapExportSettings &exportSettings)
Exports the scene according to the scene export settings Returns false if the operation failed.
int totalPendingJobsCount() const
Returns number of pending jobs for all chunked entities.
QList< QgsMapLayer * > layers() const SIP_SKIP
Returns the layers that contain chunked entities.
void addSceneEntity(Qgs3DMapSceneEntity *entity) SIP_SKIP
Adds a 3D map scene entity to the scene.
void updateTemporal()
Updates the temporale entities.
void totalPendingJobsCountChanged()
Emitted when the total number of pending jobs changes.
Qgs3DMapScene(Qgs3DMapSettings &map, QgsAbstract3DEngine *engine) SIP_SKIP
Constructs a 3D scene based on map settings and Qt 3D renderer configuration.
void fpsCounterEnabledChanged(bool fpsCounterEnabled)
Emitted when the FPS counter is activated or deactivated.
void removeSceneEntity(Qgs3DMapSceneEntity *entity) SIP_SKIP
Removes a 3D scene entity for the scene.
QgsDoubleRange elevationRange(bool ignoreTerrain=false) const
Returns the scene's elevation range.
QgsRectangle sceneExtent() const
Returns the scene extent in the map's CRS.
void sceneStateChanged()
Emitted when the scene's state has changed.
QgsAbstract3DEngine * engine() const SIP_SKIP
Returns the abstract 3D engine.
QVector< QgsPointXY > viewFrustum2DExtent() const
Calculates the 2D extent viewed by the 3D camera as the vertices of the viewed trapezoid.
void enableClipping(const QList< QVector4D > &clipPlaneEquations)
Enables OpenGL clipping based on the planes equations defined in clipPlaneEquations.
void terrainEntityChanged()
Emitted when the current terrain entity is replaced by a new one.
void viewZoomFull()
Resets camera view to show the whole scene (top view).
double worldSpaceError(double epsilon, double distance) const
Given screen error (in pixels) and distance from camera (in 3D world coordinates),...
void extentChanged()
Emitted when the 3d view's 2d extent has changed.
void originChanged()
Emitted when the world's origin point has been shifted.
void eyeDomeLightingDistanceChanged()
Emitted when the eye dome lighting distance has changed.
void terrainShadingChanged()
Emitted when terrain shading enabled flag or terrain shading material has changed.
void bloomSettingsChanged()
Emitted when the bloom lighting effect settings are changed.
void debugDepthMapSettingsChanged()
Emitted when depth map debugging has changed.
void backgroundSettingsChanged()
Emitted when background settings are changed.
void backgroundColorChanged()
Emitted when the background color has changed.
void showCameraRotationCenterChanged()
Emitted when the flag whether camera's rotation center is shown has changed.
void cameraNavigationModeChanged()
Emitted when the camera navigation mode was changed.
void shadowSettingsChanged()
Emitted when shadow rendering settings are changed.
void show2DMapOverlayChanged()
Emitted when the 2D map overlay is enabled or disabled.
bool stopUpdates() const
Returns whether the scene updates on camera movement.
void eyeDomeLightingEnabledChanged()
Emitted when the flag whether eye dome lighting is used has changed.
void debugOverlayEnabledChanged(bool debugOverlayEnabled)
Emitted when the debug overaly is enabled or disabled.
void setOrigin(const QgsVector3D &origin)
Sets coordinates in map CRS at which our 3D world has origin (0,0,0).
void msaaEnabledChanged()
Emitted when the MSAA enabled flag has changed.
void projectionTypeChanged()
Emitted when the camera lens projection type changes.
void stopUpdatesChanged()
Emitted when the flag whether to keep updating scene has changed.
void lightSourcesChanged()
Emitted when any of the light source settings in the map changes.
void showLightSourceOriginsChanged()
Emitted when the flag whether light source origins are shown has changed.
void terrainSettingsChanged()
Emitted when the terrain settings are changed.
void fpsCounterEnabledChanged(bool fpsCounterEnabled)
Emitted when the FPS counter is enabled or disabled.
void axisSettingsChanged()
Emitted when 3d axis rendering settings are changed.
void viewFrustumVisualizationEnabledChanged()
Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled...
void ambientOcclusionSettingsChanged()
Emitted when ambient occlusion rendering settings are changed.
void layersChanged()
Emitted when the list of map layers for 3d rendering has changed.
void eyeDomeLightingStrengthChanged()
Emitted when the eye dome lighting strength has changed.
void cameraMovementSpeedChanged()
Emitted when the camera movement speed was changed.
void fieldOfViewChanged()
Emitted when the camera lens field of view changes.
void terrainGeneratorChanged()
Emitted when the terrain generator has changed.
void showCameraViewCenterChanged()
Emitted when the flag whether camera's view center is shown has changed.
QgsVector3D origin() const
Returns coordinates in map CRS at which 3D scene has origin (0,0,0).
Entity that handles the exporting of 3D scenes.
void setExportTextures(bool exportTextures)
Sets whether the textures will be exported.
void parseTerrain(QgsTerrainEntity *terrain, const QString &layer)
Creates terrain export objects from the terrain entity.
void setTerrainResolution(int resolution)
Sets the terrain resolution.
void setTerrainTextureResolution(int resolution)
Sets the terrain texture resolution.
bool parseVectorLayerEntity(Qt3DCore::QEntity *entity, QgsVectorLayer *layer)
Creates necessary export objects from entity if it represents valid vector layer entity Returns false...
void setScale(float scale)
Sets the scale of the exported 3D model.
bool save(QString sceneName, QString sceneFolderPath, const Qgis::Export3DSceneFormat &exportFormat=Qgis::Export3DSceneFormat::Obj, int precision=6) const
Saves the scene to a file Returns false if the operation failed.
void setExportNormals(bool exportNormals)
Sets whether the normals will be exported.
void setSmoothEdges(bool smoothEdges)
Sets whether the triangles will look smooth.
void setTerrainExportEnabled(bool enabled)
Sets whether terrain export is enabled.
static int maxZoomLevel(double tile0width, double tileResolution, double maxError)
Calculates the highest needed zoom level for tiles in quad-tree given width of the base tile (zoom le...
static QgsAABB mapToWorldExtent(const QgsRectangle &extent, double zMin, double zMax, const QgsVector3D &mapOrigin)
Converts map extent to axis aligned bounding box in 3D world coordinates.
static void computeBoundingBoxNearFarPlanes(const QgsAABB &bbox, const QMatrix4x4 &viewMatrix, float &fnear, float &ffar)
This routine computes nearPlane farPlane from the closest and farthest corners point of bounding box ...
static QgsRay3D rayFromScreenPoint(const QPoint &point, const QSize &windowSize, Qt3DRender::QCamera *camera)
Convert from clicked point on the screen to a ray in world coordinates.
static int openGlMaxClipPlanes(QSurface *surface)
Gets the maximum number of clip planes that can be used.
Base class for 3D engine implementation.
void sizeChanged()
Emitted after a call to setSize().
virtual Qt3DRender::QCamera * camera()=0
Returns pointer to the engine's camera entity.
virtual Qgis::Map3DBackgroundType type() const =0
Returns the unique type for this background settings class.
Base class for all renderers that participate in 3D views.
virtual QString type() const =0
Returns unique identifier of the renderer class (used to identify subclass).
virtual Qt3DCore::QEntity * createEntity(Qgs3DMapSettings *map) const =0
Returns a 3D entity that will be used to show renderer's data in 3D scene.
virtual void setEnabled(bool enable)
Enable or disable via enable the render view sub tree.
Base class for 3D renderers that are based on vector layers.
static QgsSourceCache * sourceCache()
Returns the application's source cache, used for caching embedded and remote source strings as local ...
A 3-dimensional box composed of x, y, z coordinates.
double zMaximum() const
Returns the maximum z value.
double zMinimum() const
Returns the minimum z value.
Object that controls camera movement based on user input.
Qt3DRender::QCamera * camera() const
Returns camera that is being controlled.
void cameraChanged()
Emitted when camera has been updated.
void cameraRotationCenterChanged(QVector3D position)
Emitted when the camera rotation center changes.
QgsRange which stores a range of double values.
bool isInfinite() const
Returns true if the range consists of all possible values.
QColor topColor() const
Returns the color at the top of the gradient.
QColor bottomColor() const
Returns the color at the bottom of the gradient.
Qt3DRender::QLayer * renderLayer()
Returns a layer object used to indicate that the object is transparent.
Qt3DRender::QLayer * transparentObjectLayer()
Returns a layer object used to indicate that the object is transparent.
Qt3DRender::QLayer * backgroundLayer()
Returns a layer object used for skybox and background gradient entities.
void updateShadowSettings(const QgsShadowSettings &shadowSettings, const QList< QgsLightSource * > &lightSources)
Updates shadow bias, light and texture size according to shadowSettings and lightSources.
QgsHighlightsRenderView & highlightsRenderView()
Returns the highlights renderview, used for rendering highlight overlays of identified features.
QgsForwardRenderView & forwardRenderView()
Returns forward renderview.
QgsOverlayTextureRenderView & overlayTextureRenderView()
Returns overlay texture renderview.
QgsShadowRenderView & shadowRenderView()
Returns shadow renderview.
Qt3DRender::QLayer * highlightsLayer()
Returns a layer that should be attached to entities meant to be rendered by QgsHighlightsRenderView.
virtual QgsDoubleRange calculateZRange(QgsMapLayer *layer) const
Attempts to calculate the overall elevation or z range for the specified layer, using the settings de...
Base class for storage of map layer temporal properties.
Base class for all map layer types.
QgsAbstract3DRenderer * renderer3D() const
Returns 3D renderer associated with the layer.
void request3DUpdate()
Signal emitted when a layer requires an update in any 3D maps.
void renderer3DChanged()
Signal emitted when 3D renderer associated with the layer has changed.
void rendererChanged()
Signal emitted when renderer is changed.
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
void layerModified()
Emitted when modifications has been done on layer.
double verticalScale() const
Returns mesh vertical scale.
int verticalDatasetGroupIndex() const
Returns the index of the dataset group that will be used to render the vertical component of the 3D m...
void setMaximumTextureSize(int maximumTextureSize)
Sets the maximum texture size supported by the hardware Used to store the GL_MAX_TEXTURE_SIZE value t...
QgsMesh3DSymbol * clone() const override SIP_FACTORY
Returns a new instance of the symbol with the same settings.
3D renderer that renders all mesh triangles of a mesh layer.
void setSymbol(QgsMesh3DSymbol *symbol)
Sets 3D symbol associated with the renderer.
const QgsMesh3DSymbol * symbol() const
Returns 3D symbol associated with the renderer.
void setLayer(QgsMeshLayer *layer)
Sets vector layer associated with the renderer.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
virtual void showMessage(bool blocking=true)=0
display the message to the user and deletes itself
3D symbol that draws point geometries as 3D objects using one of the predefined shapes.
Qgis::Point3DShape shape() const
Returns 3D shape for points.
QVariant shapeProperty(const QString &property) const
Returns the value for a specific shape property.
void setLayer(QgsPointCloudLayer *layer)
Sets point cloud layer associated with the renderer.
Represents a map layer supporting display of point clouds.
QgsMapLayerElevationProperties * elevationProperties() override
Returns the layer's elevation properties.
void subsetStringChanged()
Emitted when the layer's subset string has changed.
T lower() const
Returns the lower bound of the range.
T upper() const
Returns the upper bound of the range.
bool isEmpty() const
Returns true if the range is empty, ie the lower bound equals (or exceeds) the upper bound and either...
A representation of a ray in 3D.
QVector3D origin() const
Returns the origin of the ray.
QVector3D direction() const
Returns the direction of the ray see setDirection().
A rectangle specified with double values.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
A child rule for a QgsRuleBased3DRenderer.
QList< QgsRuleBased3DRenderer::Rule * > RuleList
Qt3DRender::QLayer * entityCastingShadowsLayer() const
Returns the layer to be used by entities to be included in this renderview.
QMap< QString, QString > cubeMapFacesPaths() const
Returns a map containing the path of each texture specified by the user.
Qgis::SkyboxCubeMapping cubeMapping() const
Returns the cube face mapping scheme.
void remoteSourceFetched(const QString &url)
Emitted when the cache has finished retrieving a 3D model from a remote url.
void setLayer(QgsTiledSceneLayer *layer)
Sets tiled scene layer associated with the renderer.
Represents a map layer supporting display of tiled scene objects.
QgsMapLayerElevationProperties * elevationProperties() override
Returns the layer's elevation properties.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
QString toString(int precision=17) const
Returns a string representation of the 3D vector.
double x() const
Returns X coordinate.
3D renderer that renders all features of a vector layer with the same 3D symbol.
const QgsAbstract3DSymbol * symbol() const
Returns 3D symbol associated with the renderer.
Represents a vector layer which manages a vector based dataset.
void subsetStringChanged()
Emitted when the layer's subset string has changed.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsFloatNear(float a, float b, float epsilon=4 *FLT_EPSILON)
Compare two floats (but allow some difference).
QList< Qgs3DRendererCategory > Qgs3DCategoryList
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)