70#include <QOpenGLContext>
71#include <QOpenGLFunctions>
76#include <Qt3DExtras/QDiffuseSpecularMaterial>
77#include <Qt3DExtras/QForwardRenderer>
78#include <Qt3DExtras/QPhongAlphaMaterial>
79#include <Qt3DExtras/QPhongMaterial>
80#include <Qt3DExtras/QSphereMesh>
81#include <Qt3DLogic/QFrameAction>
82#include <Qt3DRender/QCamera>
83#include <Qt3DRender/QCullFace>
84#include <Qt3DRender/QDepthTest>
85#include <Qt3DRender/QEffect>
86#include <Qt3DRender/QMesh>
87#include <Qt3DRender/QRenderPass>
88#include <Qt3DRender/QRenderSettings>
89#include <Qt3DRender/QRenderState>
90#include <Qt3DRender/QSceneLoader>
91#include <Qt3DRender/QTechnique>
94#include "moc_qgs3dmapscene.cpp"
96using namespace Qt::StringLiterals;
105 onBackgroundColorChanged();
110 mEngine->renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::OnDemand );
112 QRect viewportRect( QPoint( 0, 0 ), mEngine->size() );
118 float aspectRatio = ( float ) viewportRect.width() / viewportRect.height();
119 mEngine->camera()->lens()->setPerspectiveProjection( mMap.fieldOfView(), aspectRatio, 10.f, 10000.0f );
121 mFrameAction =
new Qt3DLogic::QFrameAction();
122 connect( mFrameAction, &Qt3DLogic::QFrameAction::triggered,
this, &Qgs3DMapScene::onFrameTriggered );
123 addComponent( mFrameAction );
129 mCameraController->resetGlobe( 10'000'000 );
131 mCameraController->resetView( 1000 );
133 addCameraViewCenterEntity( mEngine->camera() );
134 addCameraRotationCenterEntity( mCameraController );
139 createTerrainDeferred();
171 const QList<QgsMapLayer *> modelVectorLayers = mModelVectorLayers;
177 if ( renderer->
type() ==
"vector"_L1 )
180 if ( pointSymbol && pointSymbol->
shapeProperty( u
"model"_s ).toString() == url )
182 removeLayerEntity( layer );
183 addLayerEntity( layer );
186 else if ( renderer->
type() ==
"rulebased"_L1 )
192 if ( pointSymbol && pointSymbol->
shapeProperty( u
"model"_s ).toString() == url )
194 removeLayerEntity( layer );
195 addLayerEntity( layer );
210 onSkyboxSettingsChanged();
215 onEyeDomeShadingSettingsChanged();
217 onDebugShadowMapSettingsChanged();
218 onDebugDepthMapSettingsChanged();
220 onAmbientOcclusionSettingsChanged();
225 mOverlayUpdateTimer =
new QTimer(
this );
226 mOverlayUpdateTimer->setSingleShot(
true );
227 mOverlayUpdateTimer->setInterval( 250 );
228 connect( mOverlayUpdateTimer, &QTimer::timeout,
this, &Qgs3DMapScene::applyPendingOverlayUpdate );
231 onShowMapOverlayChanged();
233 onCameraMovementSpeedChanged();
235 on3DAxisSettingsChanged();
242 mCameraController->resetGlobe( 10'000'000 );
248 const double side = std::max( extent.
width(), extent.
height() );
249 double d = side / 2 / std::tan(
cameraController()->camera()->fieldOfView() / 2 * M_PI / 180 );
251 mCameraController->resetView(
static_cast<float>( d ) );
262 const double xSide = std::abs( p1.
x() - p2.
x() );
263 const double ySide = std::abs( p1.
y() - p2.
y() );
264 const double side = std::max( xSide, ySide );
266 const double fov = qDegreesToRadians(
cameraController()->camera()->fieldOfView() );
267 double distance = side / 2.0f / std::tan( fov / 2.0f );
272 distance += zRange.
upper();
275 mCameraController->setViewFromTop(
276 static_cast<float>( center.
x() - origin.
x() ),
277 static_cast<float>( center.
y() - origin.
y() ),
278 static_cast<float>( distance )
284 Qt3DRender::QCamera *camera = mCameraController->camera();
285 QVector<QgsPointXY> extent;
286 QVector<int> pointsOrder = { 0, 1, 3, 2 };
287 for (
int i : pointsOrder )
289 const QPoint p( ( ( i >> 0 ) & 1 ) ? 0 : mEngine->size().width(), ( ( i >> 1 ) & 1 ) ? 0 : mEngine->size().height() );
292 if ( dir.z() == 0.0 )
293 dir.setZ( 0.000001 );
294 double t = -ray.
origin().z() / dir.z();
298 t = camera->farPlane();
303 t = std::min<float>( t, camera->farPlane() );
305 QVector3D planePoint = ray.
origin() + t * dir;
306 QgsVector3D pMap = mMap.worldToMapCoordinates( planePoint );
315 for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
316 count += entity->pendingJobsCount();
322 Qt3DRender::QCamera *camera = mCameraController->camera();
323 const double fov = camera->fieldOfView();
324 const QSize size = mEngine->size();
325 const int screenSizePx = std::max( size.width(), size.height() );
329 const double frustumWidthAtDistance = 2 * distance * tan( fov / 2 );
330 const double err = frustumWidthAtDistance * epsilon / screenSizePx;
334void Qgs3DMapScene::onCameraChanged()
336 if ( mMap.
projectionType() == Qt3DRender::QCameraLens::OrthographicProjection )
338 QRect viewportRect( QPoint( 0, 0 ), mEngine->
size() );
339 const float viewWidthFromCenter = mCameraController->
distance();
340 const float viewHeightFromCenter = viewportRect.height() * viewWidthFromCenter / viewportRect.width();
341 mEngine->
camera()->lens()->setOrthographicProjection( -viewWidthFromCenter, viewWidthFromCenter, -viewHeightFromCenter, viewHeightFromCenter, mEngine->
camera()->nearPlane(), mEngine->
camera()->farPlane() );
345 updateCameraNearFarPlanes();
347 onShadowSettingsChanged();
351 schedule2DMapOverlayUpdate();
359 constexpr float ORIGIN_SHIFT_THRESHOLD = 10'000;
360 if ( mSceneOriginShiftEnabled && mEngine->camera()->position().length() > ORIGIN_SHIFT_THRESHOLD )
362 const QgsVector3D newOrigin = mMap.origin() + QgsVector3D( mEngine->camera()->position() );
363 QgsDebugMsgLevel( u
"Rebasing scene origin from %1 to %2"_s.arg( mMap.origin().toString( 1 ), newOrigin.
toString( 1 ) ), 2 );
364 mMap.setOrigin( newOrigin );
368bool Qgs3DMapScene::updateScene(
bool forceUpdate )
370 if ( !mSceneUpdatesEnabled )
376 QgsEventTracing::ScopedEvent traceEvent( u
"3D"_s, forceUpdate ? u
"Force update scene"_s : u
"Update scene"_s );
378 Qgs3DMapSceneEntity::SceneContext sceneContext;
379 Qt3DRender::QCamera *camera = mEngine->camera();
380 sceneContext.cameraFov = camera->fieldOfView();
381 sceneContext.cameraPos = camera->position();
382 const QSize size = mEngine->size();
383 sceneContext.screenSizePx = std::max( size.width(), size.height() );
391 QMatrix4x4 projMatrix;
392 switch ( mMap.projectionType() )
394 case Qt3DRender::QCameraLens::PerspectiveProjection:
396 float fovRadians = ( camera->fieldOfView() / 2.0f ) *
static_cast<float>( M_PI ) / 180.0f;
397 float fovCotan = std::cos( fovRadians ) / std::sin( fovRadians );
399 fovCotan / camera->aspectRatio(), 0, 0, 0,
406 case Qt3DRender::QCameraLens::OrthographicProjection:
408 Qt3DRender::QCameraLens *lens = camera->lens();
410 2.0f / ( lens->right() - lens->left() ),
415 2.0f / ( lens->top() - lens->bottom() ),
422 -( lens->left() + lens->right() ) / ( lens->right() - lens->left() ),
423 -( lens->top() + lens->bottom() ) / ( lens->top() - lens->bottom() ),
431 projMatrix = camera->projectionMatrix();
433 sceneContext.viewProjectionMatrix = projMatrix * camera->viewMatrix();
436 bool anyUpdated =
false;
437 for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
439 if ( forceUpdate || ( entity->isEnabled() && entity->needsUpdate() ) )
442 entity->handleSceneUpdate( sceneContext );
443 if ( entity->hasReachedGpuMemoryLimit() )
453bool Qgs3DMapScene::updateCameraNearFarPlanes()
468 QMatrix4x4 viewMatrix = camera->viewMatrix();
474 for ( Qgs3DMapSceneEntity *se : std::as_const( mSceneEntities ) )
476 const QgsRange<float> depthRange = se->getNearFarPlaneRange( viewMatrix );
478 fnear = std::min( fnear, depthRange.
lower() );
479 ffar = std::max( ffar, depthRange.
upper() );
488 if ( fnear == 1e9 && ffar == 0 )
491 sceneZRange = sceneZRange.
isInfinite() ? QgsDoubleRange( 0.0, 0.0 ) : sceneZRange;
498 std::swap( fnear, ffar );
501 float newFar = ffar * 2;
502 float newNear = fnear / 2;
505 camera->setFarPlane( newFar );
506 camera->setNearPlane( newNear );
513void Qgs3DMapScene::onFrameTriggered(
float dt )
515 QgsEventTracing::addEvent( QgsEventTracing::EventType::Instant, u
"3D"_s, u
"Frame begins"_s );
517 mCameraController->frameTriggered( dt );
522 updateCameraNearFarPlanes();
525 static int frameCount = 0;
526 static float accumulatedTime = 0.0f;
528 if ( !mMap.isFpsCounterEnabled() )
536 accumulatedTime += dt;
537 if ( accumulatedTime >= 0.2f )
539 float fps = ( float ) frameCount / accumulatedTime;
541 accumulatedTime = 0.0f;
546void Qgs3DMapScene::update2DMapOverlay(
const QVector<QgsPointXY> &extent2DAsPoints )
548 QgsFrameGraph *frameGraph = mEngine->frameGraph();
551 if ( !mMap.is2DMapOverlayEnabled() )
553 if ( mMapOverlayEntity )
555 mMapOverlayEntity.reset();
557 overlayRenderView.
setEnabled( mMap.debugShadowMapEnabled() || mMap.debugDepthMapEnabled() );
561 if ( !mMapOverlayEntity )
563 QgsWindow3DEngine *
engine = qobject_cast<QgsWindow3DEngine *>( mEngine );
564 mMapOverlayEntity.reset(
new QgsMapOverlayEntity(
engine, &overlayRenderView, &mMap,
this ) );
565 mMapOverlayEntity->setEnabled(
true );
570 Qt3DRender::QCamera *camera = mEngine->camera();
571 const QgsVector3D extentCenter3D = mMap.worldToMapCoordinates( camera->position() );
572 const QgsPointXY extentCenter2D( extentCenter3D.
x(), extentCenter3D.
y() );
579 double minHalfExtent = std::numeric_limits<double>::max();
580 double maxHalfExtent = 0.0;
581 for (
const QgsPointXY &extentPoint : extent2DAsPoints )
583 const double distance = extentCenter2D.distance( extentPoint );
584 minHalfExtent = std::min( minHalfExtent, distance );
585 maxHalfExtent = std::max( maxHalfExtent, distance );
589 const double sceneHalfExtent = 0.6 * std::max( fullExtent.
width(), fullExtent.
height() );
591 minHalfExtent = std::min( 50., minHalfExtent );
592 maxHalfExtent = std::min( 100., maxHalfExtent );
593 const double smoothFactor = std::sin( mCameraController->pitch() / 90.0 * M_PI_2 );
596 const double adjustedHalfExtent = std::min( 3.0 * ( minHalfExtent + smoothFactor * maxHalfExtent ), sceneHalfExtent );
599 const bool showFrustum = mMap.viewFrustumVisualizationEnabled();
600 mMapOverlayEntity->update( overviewExtent, extent2DAsPoints, mCameraController->yaw(), showFrustum );
603void Qgs3DMapScene::createTerrain()
607 mSceneEntities.removeOne( mTerrain );
615 mSceneEntities.removeOne( mGlobe );
621 if ( !mTerrainUpdateScheduled )
624 QTimer::singleShot( 0,
this, &Qgs3DMapScene::createTerrainDeferred );
625 mTerrainUpdateScheduled =
true;
634void Qgs3DMapScene::createTerrainDeferred()
636 QgsChunkedEntity *terrainOrGlobe =
nullptr;
640 mGlobe =
new QgsGlobeEntity( &mMap );
641 terrainOrGlobe = mGlobe;
643 else if ( mMap.sceneMode() ==
Qgis::SceneMode::Local && mMap.terrainRenderingEnabled() && mMap.terrainGenerator() )
645 double tile0width = mMap.terrainGenerator()->rootChunkExtent().width();
646 int maxZoomLevel =
Qgs3DUtils::maxZoomLevel( tile0width, mMap.terrainSettings()->mapTileResolution(), mMap.terrainSettings()->maximumGroundError() );
647 const QgsBox3D rootBox3D = mMap.terrainGenerator()->rootChunkBox3D( mMap );
648 float rootError = mMap.terrainGenerator()->rootChunkError( mMap );
649 const QgsBox3D clippingBox3D( mMap.extent(), rootBox3D.
zMinimum(), rootBox3D.
zMaximum() );
650 mMap.terrainGenerator()->setupQuadtree( rootBox3D, rootError, maxZoomLevel, clippingBox3D );
652 mTerrain =
new QgsTerrainEntity( &mMap );
653 terrainOrGlobe = mTerrain;
656 if ( terrainOrGlobe )
659 QgsFrameGraph *frameGraph = mEngine->frameGraph();
663 terrainOrGlobe->setParent(
this );
664 terrainOrGlobe->setShowBoundingBoxes( mMap.showTerrainBoundingBoxes() );
666 mSceneEntities << terrainOrGlobe;
669 connect( terrainOrGlobe, &Qgs3DMapSceneEntity::newEntityCreated,
this, [
this]( Qt3DCore::QEntity *entity ) {
671 const QList<QgsGeoTransform *> transforms = entity->findChildren<QgsGeoTransform *>();
672 for ( QgsGeoTransform *transform : transforms )
674 transform->setOrigin( mMap.origin() );
678 handleClippingOnEntity( entity );
683 const QList<QgsMapLayer *>
layers = mMap.layers();
684 for ( QgsMapLayer *layer :
layers )
687 removeLayerEntity( layer );
690 addLayerEntity( layer );
695 mTerrainUpdateScheduled =
false;
698void Qgs3DMapScene::onBackgroundColorChanged()
700 mEngine->setClearColor( mMap.backgroundColor() );
703void Qgs3DMapScene::updateLights()
705 for ( Qt3DCore::QEntity *entity : std::as_const( mLightEntities ) )
706 entity->deleteLater();
707 mLightEntities.clear();
709 QgsFrameGraph *frameGraph = mEngine->frameGraph();
710 const QList<QgsLightSource *> newLights = mMap.lightSources();
711 for (
const QgsLightSource *source : newLights )
713 Qt3DCore::QEntity *entity = source->createEntity( mMap,
this );
715 mLightEntities.append( entity );
718 onShadowSettingsChanged();
721void Qgs3DMapScene::updateCameraLens()
723 mEngine->camera()->lens()->setFieldOfView( mMap.fieldOfView() );
724 mEngine->camera()->lens()->setProjectionType( mMap.projectionType() );
728void Qgs3DMapScene::onLayerRenderer3DChanged()
730 QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
734 removeLayerEntity( layer );
737 addLayerEntity( layer );
740void Qgs3DMapScene::onLayersChanged()
742 QSet<QgsMapLayer *> layersBefore = qgis::listToSet( mLayerEntities.keys() );
743 QList<QgsMapLayer *> layersAdded;
744 const QList<QgsMapLayer *>
layers = mMap.layers();
745 for ( QgsMapLayer *layer :
layers )
747 if ( !layersBefore.contains( layer ) )
749 layersAdded << layer;
753 layersBefore.remove( layer );
758 for ( QgsMapLayer *layer : std::as_const( layersBefore ) )
760 removeLayerEntity( layer );
763 for ( QgsMapLayer *layer : std::as_const( layersAdded ) )
765 addLayerEntity( layer );
771 const QList<QgsMapLayer *>
layers = mLayerEntities.keys();
776 if ( temporalProperties->isActive() )
778 removeLayerEntity( layer );
779 addLayerEntity( layer );
787 Q_ASSERT( sceneNewEntity );
789 mSceneEntities.append( sceneNewEntity );
791 sceneNewEntity->setParent(
this );
793 finalizeNewEntity( sceneNewEntity );
795 connect( sceneNewEntity, &Qgs3DMapSceneEntity::newEntityCreated,
this, [
this]( Qt3DCore::QEntity *entity ) {
796 finalizeNewEntity( entity );
798 updateCameraNearFarPlanes();
808 Q_ASSERT( sceneEntity );
810 mSceneEntities.removeOne( sceneEntity );
812 sceneEntity->deleteLater();
816void Qgs3DMapScene::addLayerEntity(
QgsMapLayer *layer )
828 if ( renderer->
type() ==
"vector"_L1 )
836 mModelVectorLayers.append( layer );
840 else if ( renderer->
type() ==
"rulebased"_L1 )
843 for (
auto rule : rules )
845 const QgsPoint3DSymbol *pointSymbol =
dynamic_cast<const QgsPoint3DSymbol *
>( rule->symbol() );
848 mModelVectorLayers.append( layer );
856 QgsMeshLayer3DRenderer *meshRenderer =
static_cast<QgsMeshLayer3DRenderer *
>( renderer );
857 meshRenderer->
setLayer(
static_cast<QgsMeshLayer *
>( layer ) );
861 QgsMesh3DSymbol *sym = meshRenderer->
symbol()->
clone();
867 QgsPointCloudLayer3DRenderer *pointCloudRenderer =
static_cast<QgsPointCloudLayer3DRenderer *
>( renderer );
868 pointCloudRenderer->
setLayer(
static_cast<QgsPointCloudLayer *
>( layer ) );
872 QgsTiledSceneLayer3DRenderer *tiledSceneRenderer =
static_cast<QgsTiledSceneLayer3DRenderer *
>( renderer );
873 tiledSceneRenderer->
setLayer(
static_cast<QgsTiledSceneLayer *
>( layer ) );
877 auto annotationLayerRenderer = qgis::down_cast<QgsAnnotationLayer3DRenderer *>( renderer );
878 annotationLayerRenderer->setLayer( qobject_cast<QgsAnnotationLayer *>( layer ) );
881 Qt3DCore::QEntity *newEntity = renderer->
createEntity( &mMap );
884 mLayerEntities.insert( layer, newEntity );
886 if ( Qgs3DMapSceneEntity *sceneNewEntity = qobject_cast<Qgs3DMapSceneEntity *>( newEntity ) )
893 newEntity->setParent(
this );
894 finalizeNewEntity( newEntity );
903 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
916 QgsPointCloudLayer *pclayer = qobject_cast<QgsPointCloudLayer *>( layer );
922void Qgs3DMapScene::removeLayerEntity(
QgsMapLayer *layer )
924 Qt3DCore::QEntity *entity = mLayerEntities.take( layer );
926 if ( Qgs3DMapSceneEntity *sceneEntity = qobject_cast<Qgs3DMapSceneEntity *>( entity ) )
934 entity->deleteLater();
941 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
945 mModelVectorLayers.removeAll( layer );
955 QgsPointCloudLayer *pclayer = qobject_cast<QgsPointCloudLayer *>( layer );
962void Qgs3DMapScene::finalizeNewEntity( Qt3DCore::QEntity *newEntity )
965 const QList<QgsGeoTransform *> transforms = newEntity->findChildren<QgsGeoTransform *>();
966 for ( QgsGeoTransform *transform : transforms )
968 transform->setOrigin( mMap.origin() );
972 handleClippingOnEntity( newEntity );
976 const QList<QgsLineMaterial *> childLineMaterials = newEntity->findChildren<QgsLineMaterial *>();
977 for ( QgsLineMaterial *lm : childLineMaterials )
980 lm->setViewportSize( mEngine->size() );
983 lm->setViewportSize( mEngine->size() );
986 const QList<QgsPoint3DBillboardMaterial *> childBillboardMaterials = newEntity->findChildren<QgsPoint3DBillboardMaterial *>();
987 for ( QgsPoint3DBillboardMaterial *bm : childBillboardMaterials )
990 bm->setViewportSize( mEngine->size() );
993 bm->setViewportSize( mEngine->size() );
996 QgsFrameGraph *frameGraph = mEngine->frameGraph();
1000 const QVector<Qt3DRender::QLayer *>
layers = newEntity->componentsOfType<Qt3DRender::QLayer>();
1010 const QList<Qt3DRender::QMaterial *> childMaterials = newEntity->findChildren<Qt3DRender::QMaterial *>();
1011 for ( Qt3DRender::QMaterial *material : childMaterials )
1014 if ( Qt3DExtras::QDiffuseSpecularMaterial *ph = qobject_cast<Qt3DExtras::QDiffuseSpecularMaterial *>( material ) )
1016 if ( ph->diffuse().value<QColor>().alphaF() != 1.0f )
1018 Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity *>( ph->parent() );
1019 if ( entity && !entity->components().contains( transparentLayer ) )
1021 entity->addComponent( transparentLayer );
1042 else if ( QgsPoint3DBillboardMaterial *billboardMaterial = qobject_cast<QgsPoint3DBillboardMaterial *>( material ) )
1044 Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity *>( billboardMaterial->parent() );
1045 if ( entity && !entity->components().contains( transparentLayer ) )
1047 entity->addComponent( transparentLayer );
1054 Qt3DRender::QEffect *effect = material->effect();
1057 const QVector<Qt3DRender::QParameter *> parameters = effect->parameters();
1058 for (
const Qt3DRender::QParameter *parameter : parameters )
1060 if ( parameter->name() ==
"opacity" && parameter->value() != 1.0f )
1062 Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity *>( material->parent() );
1063 if ( entity && !entity->components().contains( transparentLayer ) )
1065 entity->addComponent( transparentLayer );
1075int Qgs3DMapScene::maximumTextureSize()
const
1077 QSurface *surface = mEngine->surface();
1078 QOpenGLContext context;
1080 bool success = context.makeCurrent( surface );
1084 QOpenGLFunctions openglFunctions = QOpenGLFunctions( &context );
1087 openglFunctions.initializeOpenGLFunctions();
1088 openglFunctions.glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );
1097void Qgs3DMapScene::addCameraViewCenterEntity( Qt3DRender::QCamera *camera )
1099 mEntityCameraViewCenter =
new Qt3DCore::QEntity;
1101 Qt3DCore::QTransform *trCameraViewCenter =
new Qt3DCore::QTransform;
1102 mEntityCameraViewCenter->addComponent( trCameraViewCenter );
1103 connect( camera, &Qt3DRender::QCamera::viewCenterChanged,
this, [trCameraViewCenter, camera] {
1104 trCameraViewCenter->setTranslation( camera->viewCenter() );
1107 Qt3DExtras::QPhongMaterial *materialCameraViewCenter =
new Qt3DExtras::QPhongMaterial;
1108 materialCameraViewCenter->setAmbient( Qt::red );
1109 mEntityCameraViewCenter->addComponent( materialCameraViewCenter );
1111 Qt3DExtras::QSphereMesh *rendererCameraViewCenter =
new Qt3DExtras::QSphereMesh;
1112 rendererCameraViewCenter->setRadius( 10 );
1113 mEntityCameraViewCenter->addComponent( rendererCameraViewCenter );
1115 mEntityCameraViewCenter->setEnabled( mMap.showCameraViewCenter() );
1116 mEntityCameraViewCenter->setParent(
this );
1119 mEntityCameraViewCenter->setEnabled( mMap.showCameraViewCenter() );
1125 if ( mSceneState == state )
1127 mSceneState = state;
1131void Qgs3DMapScene::updateSceneState()
1133 if ( mTerrainUpdateScheduled )
1139 for ( Qgs3DMapSceneEntity *entity : std::as_const( mSceneEntities ) )
1141 if ( entity->isEnabled() && entity->pendingJobsCount() > 0 )
1148 setSceneState(
Ready );
1151void Qgs3DMapScene::onSkyboxSettingsChanged()
1153 QgsSkyboxSettings skyboxSettings = mMap.skyboxSettings();
1156 mSkybox->deleteLater();
1160 mEngine->setFrustumCullingEnabled( !mMap.isSkyboxEnabled() );
1162 if ( mMap.isSkyboxEnabled() )
1164 QMap<QString, QString> faces;
1169 mSkybox =
new QgsCubeFacesSkyboxEntity(
1170 faces[u
"posX"_s], faces[u
"posY"_s], faces[u
"posZ"_s],
1171 faces[u
"negX"_s], faces[u
"negY"_s], faces[u
"negZ"_s],
1182void Qgs3DMapScene::onShadowSettingsChanged()
1184 mEngine->frameGraph()->updateShadowSettings( mMap.shadowSettings(), mMap.lightSources() );
1187void Qgs3DMapScene::onAmbientOcclusionSettingsChanged()
1189 mEngine->frameGraph()->updateAmbientOcclusionSettings( mMap.ambientOcclusionSettings() );
1192void Qgs3DMapScene::onDebugShadowMapSettingsChanged()
1194 mEngine->frameGraph()->updateDebugShadowMapSettings( mMap );
1197void Qgs3DMapScene::onDebugDepthMapSettingsChanged()
1199 mEngine->frameGraph()->updateDebugDepthMapSettings( mMap );
1202void Qgs3DMapScene::onDebugOverlayEnabledChanged()
1204 mEngine->frameGraph()->setDebugOverlayEnabled( mMap.isDebugOverlayEnabled() );
1205 mEngine->renderSettings()->setRenderPolicy( mMap.isDebugOverlayEnabled() ? Qt3DRender::QRenderSettings::Always : Qt3DRender::QRenderSettings::OnDemand );
1208void Qgs3DMapScene::onEyeDomeShadingSettingsChanged()
1210 mEngine->frameGraph()->updateEyeDomeSettings( mMap );
1213void Qgs3DMapScene::onShowMapOverlayChanged()
1216 update2DMapOverlay( extent2D );
1219void Qgs3DMapScene::onCameraMovementSpeedChanged()
1221 mCameraController->setCameraMovementSpeed( mMap.cameraMovementSpeed() );
1224void Qgs3DMapScene::onCameraNavigationModeChanged()
1226 mCameraController->setCameraNavigationMode( mMap.cameraNavigationMode() );
1231 QVector<QString> notParsedLayers;
1242 for (
auto it = mLayerEntities.constBegin(); it != mLayerEntities.constEnd(); ++it )
1245 Qt3DCore::QEntity *rootEntity = it.value();
1247 switch ( layerType )
1251 notParsedLayers.push_back( layer->
name() );
1261 notParsedLayers.push_back( layer->
name() );
1275 if ( !notParsedLayers.empty() )
1277 QString message = tr(
"The following layers were not exported:" ) +
"\n";
1278 for (
const QString &layerName : notParsedLayers )
1279 message += layerName +
"\n";
1288 QVector<const QgsChunkNode *> chunks;
1289 if ( !mLayerEntities.contains( layer ) )
1291 if ( QgsChunkedEntity *
c = qobject_cast<QgsChunkedEntity *>( mLayerEntities[layer] ) )
1293 const QList<QgsChunkNode *> activeNodes =
c->activeNodes();
1294 for ( QgsChunkNode *n : activeNodes )
1295 chunks.push_back( n );
1302 return mMap.extent();
1307 double zMin = std::numeric_limits<double>::max();
1308 double zMax = std::numeric_limits<double>::lowest();
1309 if ( mMap.terrainRenderingEnabled() && mTerrain && !ignoreTerrain )
1311 const QgsBox3D box3D = mTerrain->rootNode()->box3D();
1312 zMin = std::min( zMin, box3D.
zMinimum() );
1313 zMax = std::max( zMax, box3D.
zMaximum() );
1316 for (
auto it = mLayerEntities.constBegin(); it != mLayerEntities.constEnd(); it++ )
1319 switch ( layer->
type() )
1325 zMin = std::min( zMin, zRange.
lower() );
1326 zMax = std::max( zMax, zRange.
upper() );
1331 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1339 zMin = std::min( zMin, verticalGroupMetadata.
minimum() * verticalScale );
1340 zMax = std::max( zMax, verticalGroupMetadata.
maximum() * verticalScale );
1350 zMin = std::min( zMin, zRange.
lower() );
1351 zMax = std::max( zMax, zRange.
upper() );
1364 const QgsDoubleRange zRange( std::min( zMin, std::numeric_limits<double>::max() ), std::max( zMax, std::numeric_limits<double>::lowest() ) );
1375 mEntityRotationCenter =
new Qt3DCore::QEntity;
1377 Qt3DCore::QTransform *trRotationCenter =
new Qt3DCore::QTransform;
1378 mEntityRotationCenter->addComponent( trRotationCenter );
1379 Qt3DExtras::QPhongMaterial *materialRotationCenter =
new Qt3DExtras::QPhongMaterial;
1380 materialRotationCenter->setAmbient( Qt::blue );
1381 mEntityRotationCenter->addComponent( materialRotationCenter );
1382 Qt3DExtras::QSphereMesh *rendererRotationCenter =
new Qt3DExtras::QSphereMesh;
1383 rendererRotationCenter->setRadius( 10 );
1384 mEntityRotationCenter->addComponent( rendererRotationCenter );
1385 mEntityRotationCenter->setEnabled(
false );
1386 mEntityRotationCenter->setParent(
this );
1389 trRotationCenter->setTranslation( center );
1393 mEntityRotationCenter->setEnabled( mMap.showCameraRotationCenter() );
1397void Qgs3DMapScene::on3DAxisSettingsChanged()
1401 m3DAxis->onAxisSettingsChanged();
1405 if ( QgsWindow3DEngine *
engine =
dynamic_cast<QgsWindow3DEngine *
>( mEngine ) )
1407 m3DAxis =
new Qgs3DAxis(
static_cast<Qgs3DMapCanvas *
>(
engine->window() ),
engine->root(),
this, mCameraController, &mMap );
1412void Qgs3DMapScene::onOriginChanged()
1414 const QList<QgsGeoTransform *> geoTransforms = findChildren<QgsGeoTransform *>();
1415 for ( QgsGeoTransform *transform : geoTransforms )
1417 transform->setOrigin( mMap.origin() );
1420 const QList<QgsGeoTransform *> rubberBandGeoTransforms = mEngine->frameGraph()->rubberBandsRootEntity()->findChildren<QgsGeoTransform *>();
1421 for ( QgsGeoTransform *transform : rubberBandGeoTransforms )
1423 transform->setOrigin( mMap.origin() );
1426 const QgsVector3D oldOrigin = mCameraController->origin();
1427 mCameraController->setOrigin( mMap.origin() );
1429 if ( !mClipPlanesEquations.isEmpty() )
1438 QList<QVector4D> newPlanes;
1439 QgsVector3D originShift = mMap.origin() - oldOrigin;
1440 for ( QVector4D plane : std::as_const( mClipPlanesEquations ) )
1442 plane.setW( originShift.
x() * plane.x() + originShift.
y() * plane.y() + originShift.
z() * plane.z() + plane.w() );
1443 newPlanes.append( plane );
1449void Qgs3DMapScene::handleClippingOnEntity( QEntity *entity )
const
1451 if ( mClipPlanesEquations.isEmpty() )
1453 for ( QgsMaterial *material : entity->componentsOfType<QgsMaterial>() )
1455 material->disableClipping();
1460 for ( QgsMaterial *material : entity->componentsOfType<QgsMaterial>() )
1462 material->enableClipping( mClipPlanesEquations );
1468 for ( QObject *child : entity->children() )
1470 Qt3DCore::QEntity *childEntity = qobject_cast<Qt3DCore::QEntity *>( child );
1473 handleClippingOnEntity( childEntity );
1478void Qgs3DMapScene::handleClippingOnAllEntities()
const
1482 for (
auto it = mLayerEntities.constBegin(); it != mLayerEntities.constEnd(); ++it )
1484 handleClippingOnEntity( it.value() );
1488 handleClippingOnEntity( mTerrain );
1492 handleClippingOnEntity( mGlobe );
1500 QgsDebugMsgLevel( u
"Qgs3DMapScene::enableClipping: it is not possible to use more than %1 clipping planes."_s.arg( mMaxClipPlanes ), 2 );
1508 handleClippingOnAllEntities();
1513 mClipPlanesEquations.clear();
1516 mEngine->frameGraph()->removeClipPlanes();
1519 handleClippingOnAllEntities();
1522void Qgs3DMapScene::onStopUpdatesChanged()
1527void Qgs3DMapScene::schedule2DMapOverlayUpdate()
1530 if ( mMap.is2DMapOverlayEnabled() && mOverlayUpdateTimer && !mOverlayUpdateTimer->isActive() )
1532 mOverlayUpdateTimer->start();
1536void Qgs3DMapScene::applyPendingOverlayUpdate()
1538 if ( mMap.is2DMapOverlayEnabled() )
1541 update2DMapOverlay( extent2D );
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.
QVector< const QgsChunkNode * > getLayerActiveChunkNodes(QgsMapLayer *layer)
Returns the active chunk nodes of layer.
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.
Qgs3DMapScene(Qgs3DMapSettings &map, QgsAbstract3DEngine *engine)
Constructs a 3D scene based on map settings and Qt 3D renderer configuration.
QgsAbstract3DEngine * engine() const
Returns the abstract 3D engine.
void gpuMemoryLimitReached()
Emitted when one of the entities reaches its GPU memory limit and it is not possible to lower the GPU...
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.
void updateTemporal()
Updates the temporale entities.
static Q_DECL_DEPRECATED QMap< QString, Qgs3DMapScene * > openScenes()
Returns a map of 3D map scenes (by name) open in the QGIS application.
void totalPendingJobsCountChanged()
Emitted when the total number of pending jobs changes.
void fpsCounterEnabledChanged(bool fpsCounterEnabled)
Emitted when the FPS counter is activated or deactivated.
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.
void removeSceneEntity(Qgs3DMapSceneEntity *entity)
Removes a 3D scene entity for the scene.
QList< QgsMapLayer * > layers() const
Returns the layers that contain chunked entities.
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 addSceneEntity(Qgs3DMapSceneEntity *entity)
Adds a 3D map scene entity to the scene.
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.
Qt3DRender::QCameraLens::ProjectionType projectionType() const
Returns the camera lens' projection type.
void debugDepthMapSettingsChanged()
Emitted when depth map debugging has 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 skyboxSettingsChanged()
Emitted when skybox settings are 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 debugShadowMapSettingsChanged()
Emitted when shadow map debugging has changed.
void showCameraViewCenterChanged()
Emitted when the flag whether camera's view center is shown has changed.
Entity that handles the exporting of 3D scenes.
bool save(const QString &sceneName, const QString &sceneFolderPath, int precision=6) const
Saves the scene to a .obj file Returns false if the operation failed.
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.
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 QSize size() const =0
Returns size of the engine's rendering area in pixels.
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.
float distance() const
Returns distance of the camera from the point it is looking at.
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.
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.
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.
QgsSkyboxEntity::SkyboxType skyboxType() const
Returns the type of the skybox.
QString panoramicTexturePath() const
Returns the panoramic texture path of a skybox of type "Panormaic skybox".
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).
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)