Skip to content

Commit

Permalink
[3d][api] Split api from specifying 3d map layers to render from api
Browse files Browse the repository at this point in the history
for specifying terrain layers to render

Previously the one method was used for both, which made it very
difficult to have a different set of layers used for terrain
generation vs 3d entity generation (you had to manually create a map
theme, which is very messy)
  • Loading branch information
nyalldawson committed Aug 3, 2020
1 parent 29ccd61 commit 4f34b8a
Show file tree
Hide file tree
Showing 17 changed files with 313 additions and 50 deletions.
107 changes: 94 additions & 13 deletions python/3d/auto_generated/qgs3dmapsettings.sip.in
Expand Up @@ -162,33 +162,93 @@ Sets color used for selected features
Returns color used for selected features
%End


void setTerrainVerticalScale( double zScale );
void setLayers( const QList<QgsMapLayer *> &layers );
%Docstring
Sets vertical scale (exaggeration) of terrain
(1 = true scale, > 1 = hills get more pronounced)
Sets the list of 3D map ``layers`` to be rendered in the scene.

This setting dictates which layers are to be rendered using their 3D rendering configuration, if available.

.. note::

Layers which are rendered as part of the map terrain are specified via ``setTerrainLayers``().

.. seealso:: :py:func:`layers`

.. seealso:: :py:func:`layersChanged`

.. seealso:: :py:func:`setTerrainLayers`
%End
double terrainVerticalScale() const;

QList<QgsMapLayer *> layers() const;
%Docstring
Returns vertical scale (exaggeration) of terrain
Returns the list of 3D map layers to be rendered in the scene.

This setting dictates which layers are to be rendered using their 3D rendering configuration, if available.

.. note::

Layers which are rendered as part of the map terrain are retrieved via ``terrainLayers``().

.. seealso:: :py:func:`setLayers`

.. seealso:: :py:func:`layersChanged`

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

void setLayers( const QList<QgsMapLayer *> &layers );

void setTerrainLayers( const QList<QgsMapLayer *> &layers );
%Docstring
Sets the list of map layers to be rendered as a texture of the terrain
Sets the list of 2d map ``layers`` to be rendered in the terrain.

.. note::

If terrain map theme is set, it has a priority over the list of layers specified here.
Layers which are rendered as 3D layers as part of the scene are specified via ``setLayers``().

.. note::

If :py:func:`~Qgs3DMapSettings.terrainMapTheme` is set, it has a priority over the list of layers specified here.


.. seealso:: :py:func:`terrainLayers`

.. seealso:: :py:func:`terrainLayersChanged`

.. seealso:: :py:func:`setLayers`

.. versionadded:: 3.16
%End

QList<QgsMapLayer *> layers() const;
QList<QgsMapLayer *> terrainLayers() const;
%Docstring
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.
Layers which are rendered as 3D layers as part of the scene are retrieved via ``layers``().

.. note::

If :py:func:`~Qgs3DMapSettings.terrainMapTheme` is set, it has a priority over the list of layers returned here.


.. seealso:: :py:func:`setTerrainLayers`

.. seealso:: :py:func:`terrainLayersChanged`

.. seealso:: :py:func:`layers`

.. versionadded:: 3.16
%End

void setTerrainVerticalScale( double zScale );
%Docstring
Sets vertical scale (exaggeration) of terrain
(1 = true scale, > 1 = hills get more pronounced)
%End
double terrainVerticalScale() const;
%Docstring
Returns vertical scale (exaggeration) of terrain
%End

void setMapTileResolution( int res );
Expand Down Expand Up @@ -445,10 +505,31 @@ Emitted when the background color has changed
%Docstring
Emitted when the selection color has changed
%End

void layersChanged();
%Docstring
Emitted when the list of map layers for terrain texture has changed
Emitted when the list of map layers for 3d rendering has changed.

.. seealso:: :py:func:`setLayers`

.. seealso:: :py:func:`layers`

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

void terrainLayersChanged();
%Docstring
Emitted when the list of map layers for terrain texture has changed.

.. seealso:: :py:func:`terrainLayers`

.. seealso:: :py:func:`setTerrainLayers`

.. seealso:: :py:func:`layersChanged`

.. versionadded:: 3.16
%End

void terrainGeneratorChanged();
%Docstring
Emitted when the terrain generator has changed
Expand Down
61 changes: 61 additions & 0 deletions src/3d/qgs3dmapsettings.cpp
Expand Up @@ -53,6 +53,7 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other )
, mDirectionalLights( other.mDirectionalLights )
, mFieldOfView( other.mFieldOfView )
, mLayers( other.mLayers )
, mTerrainLayers( other.mTerrainLayers )
, mRenderers() // initialized in body
, mSkyboxEnabled( other.mSkyboxEnabled )
, mSkyboxFileBase( other.mSkyboxFileBase )
Expand Down Expand Up @@ -153,6 +154,23 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
}
mLayers = mapLayers; // needs to resolve refs afterwards

QDomElement elemTerrainLayers = elemTerrain.firstChildElement( QStringLiteral( "terrainLayers" ) );
if ( elemTerrainLayers.isNull() )
{
mTerrainLayers = mLayers;
}
else
{
QDomElement elemTerrainMapLayer = elemTerrainLayers.firstChildElement( QStringLiteral( "layer" ) );
QList<QgsMapLayerRef> terrainMapLayers;
while ( !elemTerrainMapLayer.isNull() )
{
terrainMapLayers << QgsMapLayerRef( elemTerrainMapLayer.attribute( QStringLiteral( "id" ) ) );
elemTerrainMapLayer = elemTerrainMapLayer.nextSiblingElement( QStringLiteral( "layer" ) );
}
mTerrainLayers = mapLayers; // needs to resolve refs afterwards
}

QDomElement elemTerrainGenerator = elemTerrain.firstChildElement( QStringLiteral( "generator" ) );
QString terrainGenType = elemTerrainGenerator.attribute( QStringLiteral( "type" ) );
if ( terrainGenType == QLatin1String( "dem" ) )
Expand Down Expand Up @@ -283,6 +301,16 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon
elemMapLayers.appendChild( elemMapLayer );
}
elemTerrain.appendChild( elemMapLayers );

QDomElement elemTerrainMapLayers = doc.createElement( QStringLiteral( "terrainLayers" ) );
Q_FOREACH ( const QgsMapLayerRef &layerRef, mTerrainLayers )
{
QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) );
elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId );
elemTerrainMapLayers.appendChild( elemMapLayer );
}
elemTerrain.appendChild( elemTerrainMapLayers );

QDomElement elemTerrainGenerator = doc.createElement( QStringLiteral( "generator" ) );
elemTerrainGenerator.setAttribute( QStringLiteral( "type" ), QgsTerrainGenerator::typeToString( mTerrainGenerator->type() ) );
mTerrainGenerator->writeXml( elemTerrainGenerator );
Expand Down Expand Up @@ -327,6 +355,11 @@ void Qgs3DMapSettings::resolveReferences( const QgsProject &project )
QgsMapLayerRef &layerRef = mLayers[i];
layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
}
for ( int i = 0; i < mTerrainLayers.count(); ++i )
{
QgsMapLayerRef &layerRef = mTerrainLayers[i];
layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
}

mTerrainGenerator->resolveReferences( project );

Expand Down Expand Up @@ -432,6 +465,34 @@ QList<QgsMapLayer *> Qgs3DMapSettings::layers() const
return lst;
}

void Qgs3DMapSettings::setTerrainLayers( const QList<QgsMapLayer *> &layers )
{
QList<QgsMapLayerRef> lst;
lst.reserve( layers.count() );
Q_FOREACH ( QgsMapLayer *layer, layers )
{
lst.append( layer );
}

if ( mTerrainLayers == lst )
return;

mTerrainLayers = lst;
emit terrainLayersChanged();
}

QList<QgsMapLayer *> Qgs3DMapSettings::terrainLayers() const
{
QList<QgsMapLayer *> lst;
lst.reserve( mTerrainLayers.count() );
Q_FOREACH ( const QgsMapLayerRef &layerRef, mTerrainLayers )
{
if ( layerRef.layer )
lst.append( layerRef.layer );
}
return lst;
}

void Qgs3DMapSettings::setMapTileResolution( int res )
{
if ( mMapTileResolution == res )
Expand Down
86 changes: 74 additions & 12 deletions src/3d/qgs3dmapsettings.h
Expand Up @@ -155,29 +155,71 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
//! Returns color used for selected features
QColor selectionColor() const;

/**
* Sets the list of 3D map \a layers to be rendered in the scene.
*
* This setting dictates which layers are to be rendered using their 3D rendering configuration, if available.
*
* \note Layers which are rendered as part of the map terrain are specified via \a setTerrainLayers().
*
* \see layers()
* \see layersChanged()
* \see setTerrainLayers()
*/
void setLayers( const QList<QgsMapLayer *> &layers );

/**
* Returns the list of 3D map layers to be rendered in the scene.
*
* This setting dictates which layers are to be rendered using their 3D rendering configuration, if available.
*
* \note Layers which are rendered as part of the map terrain are retrieved via \a terrainLayers().
*
* \see setLayers()
* \see layersChanged()
* \see terrainLayers()
*/
QList<QgsMapLayer *> layers() const;

//
// terrain related config
//

/**
* Sets vertical scale (exaggeration) of terrain
* (1 = true scale, > 1 = hills get more pronounced)
* Sets the list of 2d map \a layers to be rendered in the terrain.
*
* \note Layers which are rendered as 3D layers as part of the scene are specified via \a setLayers().
*
* \note If terrainMapTheme() is set, it has a priority over the list of layers specified here.
*
* \see terrainLayers()
* \see terrainLayersChanged()
* \see setLayers()
* \since QGIS 3.16
*/
void setTerrainVerticalScale( double zScale );
//! Returns vertical scale (exaggeration) of terrain
double terrainVerticalScale() const;
void setTerrainLayers( const QList<QgsMapLayer *> &layers );

/**
* 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.
* Returns the list of map layers to be rendered as a texture of the terrain.
*
* \note Layers which are rendered as 3D layers as part of the scene are retrieved via \a layers().
*
* \note If terrainMapTheme() is set, it has a priority over the list of layers returned here.
*
* \see setTerrainLayers()
* \see terrainLayersChanged()
* \see layers()
* \since QGIS 3.16
*/
void setLayers( const QList<QgsMapLayer *> &layers );
QList<QgsMapLayer *> terrainLayers() const;

/**
* 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.
* Sets vertical scale (exaggeration) of terrain
* (1 = true scale, > 1 = hills get more pronounced)
*/
QList<QgsMapLayer *> layers() const;
void setTerrainVerticalScale( double zScale );
//! Returns vertical scale (exaggeration) of terrain
double terrainVerticalScale() const;

/**
* Sets resolution (in pixels) of the texture of a terrain tile
Expand Down Expand Up @@ -389,8 +431,27 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
void backgroundColorChanged();
//! Emitted when the selection color has changed
void selectionColorChanged();
//! Emitted when the list of map layers for terrain texture has changed

/**
* Emitted when the list of map layers for 3d rendering has changed.
*
* \see setLayers()
* \see layers()
* \see terrainLayersChanged()
*/
void layersChanged();

/**
* Emitted when the list of map layers for terrain texture has changed.
*
* \see terrainLayers()
* \see setTerrainLayers()
* \see layersChanged()
*
* \since QGIS 3.16
*/
void terrainLayersChanged();

//! Emitted when the terrain generator has changed
void terrainGeneratorChanged();
//! Emitted when the vertical scale of the terrain has changed
Expand Down Expand Up @@ -486,6 +547,7 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
QList<QgsDirectionalLightSettings> mDirectionalLights; //!< List of directional lights defined for the scene
float mFieldOfView = 45.0f; //<! Camera lens field of view value
QList<QgsMapLayerRef> mLayers; //!< Layers to be rendered
QList<QgsMapLayerRef> mTerrainLayers; //!< Terrain layers to be rendered
QList<QgsAbstract3DRenderer *> mRenderers; //!< Extra stuff to render as 3D object
bool mSkyboxEnabled = false; //!< Whether to render skybox
QString mSkyboxFileBase; //!< Base part of the files with skybox textures
Expand Down
2 changes: 1 addition & 1 deletion src/3d/terrain/qgsdemterraintileloader_p.cpp
Expand Up @@ -109,7 +109,7 @@ Qt3DCore::QEntity *QgsDemTerrainTileLoader::createEntity( Qt3DCore::QEntity *par

// create material

createTextureComponent( entity, map.isTerrainShadingEnabled(), map.terrainShadingMaterial() );
createTextureComponent( entity, map.isTerrainShadingEnabled(), map.terrainShadingMaterial(), !map.terrainLayers().empty() );

// create transform

Expand Down
2 changes: 1 addition & 1 deletion src/3d/terrain/qgsflatterraingenerator.cpp
Expand Up @@ -53,7 +53,7 @@ Qt3DCore::QEntity *FlatTerrainChunkLoader::createEntity( Qt3DCore::QEntity *pare
// create material

const Qgs3DMapSettings &map = terrain()->map3D();
createTextureComponent( entity, map.isTerrainShadingEnabled(), map.terrainShadingMaterial() );
createTextureComponent( entity, map.isTerrainShadingEnabled(), map.terrainShadingMaterial(), !map.terrainLayers().empty() );

// create transform

Expand Down
4 changes: 2 additions & 2 deletions src/3d/terrain/qgsterrainentity_p.cpp
Expand Up @@ -69,7 +69,7 @@ QgsTerrainEntity::QgsTerrainEntity( int maxLevel, const Qgs3DMapSettings &map, Q
connect( &map, &Qgs3DMapSettings::showTerrainBoundingBoxesChanged, this, &QgsTerrainEntity::onShowBoundingBoxesChanged );
connect( &map, &Qgs3DMapSettings::showTerrainTilesInfoChanged, this, &QgsTerrainEntity::invalidateMapImages );
connect( &map, &Qgs3DMapSettings::showLabelsChanged, this, &QgsTerrainEntity::invalidateMapImages );
connect( &map, &Qgs3DMapSettings::layersChanged, this, &QgsTerrainEntity::onLayersChanged );
connect( &map, &Qgs3DMapSettings::terrainLayersChanged, this, &QgsTerrainEntity::onLayersChanged );
connect( &map, &Qgs3DMapSettings::backgroundColorChanged, this, &QgsTerrainEntity::invalidateMapImages );
connect( &map, &Qgs3DMapSettings::terrainMapThemeChanged, this, &QgsTerrainEntity::invalidateMapImages );

Expand Down Expand Up @@ -175,7 +175,7 @@ void QgsTerrainEntity::connectToLayersRepaintRequest()
disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsTerrainEntity::invalidateMapImages );
}

mLayers = mMap.layers();
mLayers = mMap.terrainLayers();

Q_FOREACH ( QgsMapLayer *layer, mLayers )
{
Expand Down
2 changes: 1 addition & 1 deletion src/3d/terrain/qgsterraintexturegenerator_p.cpp
Expand Up @@ -154,7 +154,7 @@ QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings()
QString mapThemeName = mMap.terrainMapTheme();
if ( mapThemeName.isEmpty() || !mapThemes || !mapThemes->hasMapTheme( mapThemeName ) )
{
mapSettings.setLayers( mMap.layers() );
mapSettings.setLayers( mMap.terrainLayers() );
}
else
{
Expand Down

0 comments on commit 4f34b8a

Please sign in to comment.