From 61cb715c4edb179d464514d5435f4df991dc9df7 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Mon, 19 Nov 2018 16:29:53 +0100 Subject: [PATCH] [FEATURE] Optionally use a map theme to render terrain textures Often it is useful to have a different map theme for terrain in 3D view than the map theme used in the main map canvas. --- src/3d/qgs3dmapsettings.cpp | 12 +++++++ src/3d/qgs3dmapsettings.h | 36 +++++++++++++++++-- src/3d/terrain/qgsterrainentity_p.cpp | 1 + .../terrain/qgsterraintexturegenerator_p.cpp | 16 ++++++++- src/app/3d/qgs3dmapconfigwidget.cpp | 13 ++++++- src/ui/3d/map3dconfigwidget.ui | 21 +++++++++-- 6 files changed, 93 insertions(+), 6 deletions(-) diff --git a/src/3d/qgs3dmapsettings.cpp b/src/3d/qgs3dmapsettings.cpp index 66e477eb8059..1a4cca9d771e 100644 --- a/src/3d/qgs3dmapsettings.cpp +++ b/src/3d/qgs3dmapsettings.cpp @@ -39,6 +39,7 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other ) , mMaxTerrainGroundError( other.mMaxTerrainGroundError ) , mTerrainShadingEnabled( other.mTerrainShadingEnabled ) , mTerrainShadingMaterial( other.mTerrainShadingMaterial ) + , mTerrainMapTheme( other.mTerrainMapTheme ) , mShowTerrainBoundingBoxes( other.mShowTerrainBoundingBoxes ) , mShowTerrainTileInfo( other.mShowTerrainTileInfo ) , mShowCameraViewCenter( other.mShowCameraViewCenter ) @@ -87,6 +88,7 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte QDomElement elemTerrainShadingMaterial = elemTerrain.firstChildElement( QStringLiteral( "shading-material" ) ); if ( !elemTerrainShadingMaterial.isNull() ) mTerrainShadingMaterial.readXml( elemTerrainShadingMaterial ); + mTerrainMapTheme = elemTerrain.attribute( QStringLiteral( "map-theme" ) ); mShowLabels = elemTerrain.attribute( QStringLiteral( "show-labels" ), QStringLiteral( "0" ) ).toInt(); mPointLights.clear(); @@ -204,6 +206,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon QDomElement elemTerrainShadingMaterial = doc.createElement( QStringLiteral( "shading-material" ) ); mTerrainShadingMaterial.writeXml( elemTerrainShadingMaterial ); elemTerrain.appendChild( elemTerrainShadingMaterial ); + elemTerrain.setAttribute( QStringLiteral( "map-theme" ), mTerrainMapTheme ); elemTerrain.setAttribute( QStringLiteral( "show-labels" ), mShowLabels ? 1 : 0 ); QDomElement elemPointLights = doc.createElement( QStringLiteral( "point-lights" ) ); @@ -432,6 +435,15 @@ void Qgs3DMapSettings::setTerrainShadingMaterial( const QgsPhongMaterialSettings emit terrainShadingChanged(); } +void Qgs3DMapSettings::setTerrainMapTheme( const QString &theme ) +{ + if ( mTerrainMapTheme == theme ) + return; + + mTerrainMapTheme = theme; + emit terrainMapThemeChanged(); +} + void Qgs3DMapSettings::setRenderers( const QList &renderers ) { mRenderers = renderers; diff --git a/src/3d/qgs3dmapsettings.h b/src/3d/qgs3dmapsettings.h index 27031a89f716..a7ff5c17697b 100644 --- a/src/3d/qgs3dmapsettings.h +++ b/src/3d/qgs3dmapsettings.h @@ -148,9 +148,16 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject //! Returns vertical scale (exaggeration) of terrain double terrainVerticalScale() const; - //! Sets the list of map layers to be rendered as a texture of the terrain + /** + * Sets the list of map layers to be rendered as a texture of the terrain + * \note If terrain map theme is set, it has a priority over the list of layers specified here. + */ void setLayers( const QList &layers ); - //! Returns the list of map layers to be rendered as a texture of the terrain + + /** + * Returns the list of map layers to be rendered as a texture of the terrain + * \note If terrain map theme is set, it has a priority over the list of layers specified here. + */ QList layers() const; /** @@ -231,6 +238,24 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject */ QgsPhongMaterialSettings terrainShadingMaterial() const { return mTerrainShadingMaterial; } + /** + * Sets name of the map theme. + * \see terrainMapTheme() + * \since QGIS 3.6 + */ + void setTerrainMapTheme( const QString &theme ); + + /** + * Returns name of the map theme (from the active project) that will be used for terrain's texture. + * Empty map theme name means that the map theme is not overridden and the current map theme will be used. + * \since QGIS 3.6 + */ + QString terrainMapTheme() const { return mTerrainMapTheme; } + + // + // misc configuration + // + //! Sets list of extra 3D renderers to use in the scene. Takes ownership of the objects. void setRenderers( const QList &renderers SIP_TRANSFER ); //! Returns list of extra 3D renderers @@ -310,6 +335,12 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject * \since QGIS 3.6 */ void terrainShadingChanged(); + + /** + * Emitted when terrain's map theme has changed + * \since QGIS 3.6 + */ + void terrainMapThemeChanged(); //! Emitted when the flag whether terrain's bounding boxes are shown has changed void showTerrainBoundingBoxesChanged(); //! Emitted when the flag whether terrain's tile info is shown has changed @@ -342,6 +373,7 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject float mMaxTerrainGroundError = 1.f; //!< Maximum allowed horizontal map error in map units (determines how many zoom levels will be used) bool mTerrainShadingEnabled = false; //!< Whether terrain should be shaded taking lights into account QgsPhongMaterialSettings mTerrainShadingMaterial; //!< Material to use for the terrain (if shading is enabled). Diffuse color is ignored. + QString mTerrainMapTheme; //!< Name of map theme used for terrain's texture (empty means use the current map theme) bool mShowTerrainBoundingBoxes = false; //!< Whether to show bounding boxes of entities - useful for debugging bool mShowTerrainTileInfo = false; //!< Whether to draw extra information about terrain tiles to the textures - useful for debugging bool mShowCameraViewCenter = false; //!< Whether to show camera view center as a sphere - useful for debugging diff --git a/src/3d/terrain/qgsterrainentity_p.cpp b/src/3d/terrain/qgsterrainentity_p.cpp index 75be3e34558a..fb0af0e655d1 100644 --- a/src/3d/terrain/qgsterrainentity_p.cpp +++ b/src/3d/terrain/qgsterrainentity_p.cpp @@ -69,6 +69,7 @@ QgsTerrainEntity::QgsTerrainEntity( int maxLevel, const Qgs3DMapSettings &map, Q connect( &map, &Qgs3DMapSettings::showLabelsChanged, this, &QgsTerrainEntity::invalidateMapImages ); connect( &map, &Qgs3DMapSettings::layersChanged, this, &QgsTerrainEntity::onLayersChanged ); connect( &map, &Qgs3DMapSettings::backgroundColorChanged, this, &QgsTerrainEntity::invalidateMapImages ); + connect( &map, &Qgs3DMapSettings::terrainMapThemeChanged, this, &QgsTerrainEntity::invalidateMapImages ); connectToLayersRepaintRequest(); diff --git a/src/3d/terrain/qgsterraintexturegenerator_p.cpp b/src/3d/terrain/qgsterraintexturegenerator_p.cpp index a185734e594d..33d95709f24c 100644 --- a/src/3d/terrain/qgsterraintexturegenerator_p.cpp +++ b/src/3d/terrain/qgsterraintexturegenerator_p.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "qgs3dmapsettings.h" @@ -127,13 +128,26 @@ void QgsTerrainTextureGenerator::onRenderingFinished() QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings() { QgsMapSettings mapSettings; - mapSettings.setLayers( mMap.layers() ); + mapSettings.setOutputSize( QSize( mMap.mapTileResolution(), mMap.mapTileResolution() ) ); mapSettings.setDestinationCrs( mMap.crs() ); mapSettings.setBackgroundColor( mMap.backgroundColor() ); mapSettings.setFlag( QgsMapSettings::DrawLabeling, mMap.showLabels() ); mapSettings.setTransformContext( mMap.transformContext() ); mapSettings.setPathResolver( mMap.pathResolver() ); + + QgsMapThemeCollection *mapThemes = QgsProject::instance()->mapThemeCollection(); + QString mapThemeName = mMap.terrainMapTheme(); + if ( mapThemeName.isEmpty() || !mapThemes->hasMapTheme( mapThemeName ) ) + { + mapSettings.setLayers( mMap.layers() ); + } + else + { + mapSettings.setLayers( mapThemes->mapThemeVisibleLayers( mapThemeName ) ); + mapSettings.setLayerStyleOverrides( mapThemes->mapThemeStyleOverrides( mapThemeName ) ); + } + return mapSettings; } diff --git a/src/app/3d/qgs3dmapconfigwidget.cpp b/src/app/3d/qgs3dmapconfigwidget.cpp index fcebeb369184..ac7953ee3a38 100644 --- a/src/app/3d/qgs3dmapconfigwidget.cpp +++ b/src/app/3d/qgs3dmapconfigwidget.cpp @@ -21,8 +21,9 @@ #include "qgs3dutils.h" #include "qgsmapcanvas.h" +#include "qgsmapthemecollection.h" #include "qgsrasterlayer.h" -//#include "qgsproject.h" +#include "qgsproject.h" Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas *mainCanvas, QWidget *parent ) : QWidget( parent ) @@ -73,6 +74,14 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas widgetTerrainMaterial->setDiffuseVisible( false ); widgetTerrainMaterial->setMaterial( mMap->terrainShadingMaterial() ); + // populate combo box with map themes + const QStringList mapThemeNames = QgsProject::instance()->mapThemeCollection()->mapThemes(); + cboTerrainMapTheme->addItem( QString() ); // empty item for no map theme + for ( QString themeName : mapThemeNames ) + cboTerrainMapTheme->addItem( themeName ); + + cboTerrainMapTheme->setCurrentText( mMap->terrainMapTheme() ); + widgetLights->setPointLights( mMap->pointLights() ); connect( cboTerrainLayer, static_cast( &QgsMapLayerComboBox::currentIndexChanged ), this, &Qgs3DMapConfigWidget::onTerrainLayerChanged ); @@ -144,6 +153,8 @@ void Qgs3DMapConfigWidget::apply() mMap->setTerrainShadingEnabled( groupTerrainShading->isChecked() ); mMap->setTerrainShadingMaterial( widgetTerrainMaterial->material() ); + mMap->setTerrainMapTheme( cboTerrainMapTheme->currentText() ); + mMap->setPointLights( widgetLights->pointLights() ); } diff --git a/src/ui/3d/map3dconfigwidget.ui b/src/ui/3d/map3dconfigwidget.ui index f2567f8a1ba7..40d2fbff680e 100644 --- a/src/ui/3d/map3dconfigwidget.ui +++ b/src/ui/3d/map3dconfigwidget.ui @@ -7,7 +7,7 @@ 0 0 691 - 1135 + 1122 @@ -15,7 +15,7 @@ - + Terrain @@ -84,6 +84,20 @@ + + + + Map theme + + + + + + + false + + + @@ -275,12 +289,15 @@ spinTerrainScale spinTerrainResolution spinTerrainSkirtHeight + cboTerrainMapTheme + groupTerrainShading spinMapResolution spinScreenError spinGroundError chkShowLabels chkShowTileInfo chkShowBoundingBoxes + chkShowCameraViewCenter