Skip to content

Commit

Permalink
GUI for configuration of 3D polygon symbols for vector layers
Browse files Browse the repository at this point in the history
In the style dock there is a new "3D View" tab - so far working just for polygon layers.
It is possible to select a polygon layer, enable 3D renderer and adjust its properties.
If a 3D Map View is open, it will be immediately updated (if auto-apply is enabled)

Very exciting! :-)
  • Loading branch information
wonder-sk committed Sep 15, 2017
1 parent b9dd6bc commit ba7573a
Show file tree
Hide file tree
Showing 37 changed files with 850 additions and 60 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -284,6 +284,7 @@ IF(WITH_CORE)
FIND_PACKAGE(Qt53DInput REQUIRED)
FIND_PACKAGE(Qt53DLogic REQUIRED)
FIND_PACKAGE(Qt53DExtras REQUIRED)
SET(HAVE_3D TRUE) # used in qgsconfig.h
ENDIF (WITH_3D)
INCLUDE("cmake/modules/ECMQt4To5Porting.cmake")
MESSAGE(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}")
Expand Down
4 changes: 3 additions & 1 deletion cmake_templates/qgsconfig.h.in
Expand Up @@ -13,7 +13,7 @@
//used in vim src/core/qgis.cpp
//The way below should work but it resolves to a number like 0110 which the compiler treats as octal I think
//because debuggin it out shows the decimal number 72 which results in incorrect version status.
//As a short term fix I (Tim) am defining the version in top level cmake. It would be good to
//As a short term fix I (Tim) am defining the version in top level cmake. It would be good to
//reinstate this more generic approach below at some point though
//#define VERSION_INT ${CPACK_PACKAGE_VERSION_MAJOR}${CPACK_PACKAGE_VERSION_MINOR}${CPACK_PACKAGE_VERSION_PATCH}
#define VERSION_INT ${QGIS_VERSION_INT}
Expand Down Expand Up @@ -58,5 +58,7 @@

#cmakedefine ENABLE_MODELTEST

#cmakedefine HAVE_3D

#endif

1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -570,6 +570,7 @@
<file>themes/default/mGeoPackage.svg</file>
<file>themes/default/mActionAddGeoPackageLayer.svg</file>
<file>icons/qgis_icon.svg</file>
<file>themes/default/3d.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Expand Down
38 changes: 38 additions & 0 deletions images/themes/default/3d.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions python/core/qgsapplication.sip
Expand Up @@ -704,6 +704,7 @@ Returns path to the build output directory. Valid only when running from build d
:rtype: QgsFieldFormatterRegistry
%End


static QString nullRepresentation();
%Docstring
This string is used to represent the value `NULL` throughout QGIS.
Expand Down
8 changes: 8 additions & 0 deletions python/core/qgsmaplayer.sip
Expand Up @@ -754,6 +754,8 @@ Return pointer to layer's undo stack
:rtype: QgsMapLayerStyleManager
%End



bool isInScaleRange( double scale ) const;
%Docstring
Tests whether the layer should be visible at the specified ``scale``.
Expand Down Expand Up @@ -1014,6 +1016,12 @@ Signal emitted when the blend mode is changed, through QgsMapLayer.setBlendMode(
%Docstring
Signal emitted when legend of the layer has changed
.. versionadded:: 2.6
%End

void renderer3DChanged();
%Docstring
Signal emitted when 3D renderer associated with the layer has changed.
.. versionadded:: 3.0
%End

void configChanged();
Expand Down
5 changes: 3 additions & 2 deletions src/3d/CMakeLists.txt
Expand Up @@ -2,7 +2,6 @@
# sources

SET(QGIS_3D_SRCS
abstract3drenderer.cpp
abstract3dsymbol.cpp
cameracontroller.cpp
lineentity.cpp
Expand All @@ -15,6 +14,7 @@ SET(QGIS_3D_SRCS
tessellator.cpp
tilingscheme.cpp
utils.cpp
vectorlayer3drenderer.cpp

chunks/chunkboundsentity.cpp
chunks/chunkedentity.cpp
Expand Down Expand Up @@ -63,7 +63,6 @@ QT5_ADD_RESOURCES(QGIS_3D_RCC_SRCS shaders.qrc)

SET(QGIS_3D_HDRS
aabb.h
abstract3drenderer.h
abstract3dsymbol.h
cameracontroller.h
lineentity.h
Expand All @@ -76,6 +75,7 @@ SET(QGIS_3D_HDRS
tessellator.h
tilingscheme.h
utils.h
vectorlayer3drenderer.h

chunks/chunkboundsentity.h
chunks/chunkedentity.h
Expand Down Expand Up @@ -105,6 +105,7 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/src/core/symbology-ng
${CMAKE_SOURCE_DIR}/src/core/metadata
${CMAKE_SOURCE_DIR}/src/core/expression
${CMAKE_SOURCE_DIR}/src/core/3d
${CMAKE_BINARY_DIR}/src/core
${CMAKE_BINARY_DIR}/src/3d
)
Expand Down
10 changes: 5 additions & 5 deletions src/3d/map3d.cpp
@@ -1,9 +1,9 @@
#include "map3d.h"

#include "abstract3drenderer.h"
#include "flatterraingenerator.h"
#include "demterraingenerator.h"
//#include "quantizedmeshterraingenerator.h"
#include "vectorlayer3drenderer.h"

#include <QDomDocument>
#include <QDomElement>
Expand Down Expand Up @@ -44,7 +44,7 @@ Map3D::Map3D( const Map3D &other )
, mShowTerrainTileInfo( other.mShowTerrainTileInfo )
, mLayers( other.mLayers )
{
Q_FOREACH ( Abstract3DRenderer *renderer, other.renderers )
Q_FOREACH ( QgsAbstract3DRenderer *renderer, other.renderers )
{
renderers << renderer->clone();
}
Expand Down Expand Up @@ -108,7 +108,7 @@ void Map3D::readXml( const QDomElement &elem, const QgsReadWriteContext &context
QDomElement elemRenderer = elemRenderers.firstChildElement( "renderer" );
while ( !elemRenderer.isNull() )
{
Abstract3DRenderer *renderer = nullptr;
QgsAbstract3DRenderer *renderer = nullptr;
QString type = elemRenderer.attribute( "type" );
if ( type == "vector" )
{
Expand Down Expand Up @@ -167,7 +167,7 @@ QDomElement Map3D::writeXml( QDomDocument &doc, const QgsReadWriteContext &conte
elem.appendChild( elemTerrain );

QDomElement elemRenderers = doc.createElement( "renderers" );
Q_FOREACH ( const Abstract3DRenderer *renderer, renderers )
Q_FOREACH ( const QgsAbstract3DRenderer *renderer, renderers )
{
QDomElement elemRenderer = doc.createElement( "renderer" );
elemRenderer.setAttribute( "type", renderer->type() );
Expand Down Expand Up @@ -203,7 +203,7 @@ void Map3D::resolveReferences( const QgsProject &project )

for ( int i = 0; i < renderers.count(); ++i )
{
Abstract3DRenderer *renderer = renderers[i];
QgsAbstract3DRenderer *renderer = renderers[i];
renderer->resolveReferences( project );
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/3d/map3d.h
Expand Up @@ -13,7 +13,7 @@
class QgsMapLayer;
class QgsRasterLayer;

class Abstract3DRenderer;
class QgsAbstract3DRenderer;
class TerrainGenerator;


Expand Down Expand Up @@ -61,7 +61,7 @@ class _3D_EXPORT Map3D : public QObject
// 3D renderers
//

QList<Abstract3DRenderer *> renderers; //!< Stuff to render as 3D object
QList<QgsAbstract3DRenderer *> renderers; //!< Stuff to render as 3D object

bool skybox; //!< Whether to render skybox
QString skyboxFileBase;
Expand Down
6 changes: 3 additions & 3 deletions src/3d/phongmaterialsettings.h
Expand Up @@ -12,10 +12,10 @@ class _3D_EXPORT PhongMaterialSettings
{
public:
PhongMaterialSettings()
: mAmbient( QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) )
: mAmbient( QColor::fromRgbF( 0.1f, 0.1f, 0.1f, 1.0f ) )
, mDiffuse( QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) )
, mSpecular( QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) )
, mShininess( 150.0f )
, mSpecular( QColor::fromRgbF( 1.0f, 1.0f, 1.0f, 1.0f ) )
, mShininess( 0.0f )
{
}

Expand Down
42 changes: 38 additions & 4 deletions src/3d/scene.cpp
Expand Up @@ -8,7 +8,7 @@
#include <Qt3DLogic/QFrameAction>

#include "aabb.h"
#include "abstract3drenderer.h"
#include "qgsabstract3drenderer.h"
#include "cameracontroller.h"
#include "map3d.h"
#include "terrain.h"
Expand Down Expand Up @@ -59,12 +59,26 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph,

// create entities of renderers

Q_FOREACH ( const Abstract3DRenderer *renderer, map.renderers )
Q_FOREACH ( const QgsAbstract3DRenderer *renderer, map.renderers )
{
Qt3DCore::QEntity *p = renderer->createEntity( map );
p->setParent( this );
}

// create entities of renderers of layers

Q_FOREACH ( QgsMapLayer *layer, map.layers() )
{
if ( layer->renderer3D() )
{
Qt3DCore::QEntity *p = layer->renderer3D()->createEntity( map );
p->setParent( this );
mLayerEntities.insert( layer, p );
}
connect( layer, &QgsMapLayer::renderer3DChanged, this, &Scene::onLayerRenderer3DChanged );
// TODO: connect( layer, &QgsMapLayer::willBeDeleted, this, &Scene::onLayerWillBeDeleted );
}

Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity;
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform;
lightTransform->setTranslation( QVector3D( 0, 1000, 0 ) );
Expand All @@ -83,10 +97,10 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph,
ChunkedEntity *testChunkEntity = new ChunkedEntity( AABB( -500, 0, -500, 500, 100, 500 ), 2.f, 3.f, 7, new TestChunkLoaderFactory );
testChunkEntity->setEnabled( false );
testChunkEntity->setParent( this );
chunkEntities << testChunkEntity
chunkEntities << testChunkEntity;
#endif

connect( mCameraController, &CameraController::cameraChanged, this, &Scene::onCameraChanged );
connect( mCameraController, &CameraController::cameraChanged, this, &Scene::onCameraChanged );
connect( mCameraController, &CameraController::viewportChanged, this, &Scene::onCameraChanged );

#if 0
Expand Down Expand Up @@ -190,3 +204,23 @@ void Scene::createTerrain()

onCameraChanged(); // force update of the new terrain
}

void Scene::onLayerRenderer3DChanged()
{
QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
Q_ASSERT( layer );

// remove old entity - if any
Qt3DCore::QEntity *entity = mLayerEntities.take( layer );
if ( entity )
entity->deleteLater();

// add new entity - if any 3D renderer
QgsAbstract3DRenderer *renderer = layer->renderer3D();
if ( renderer )
{
Qt3DCore::QEntity *newEntity = renderer->createEntity( mMap );
newEntity->setParent( this );
mLayerEntities.insert( layer, newEntity );
}
}
4 changes: 4 additions & 0 deletions src/3d/scene.h
Expand Up @@ -21,6 +21,7 @@ namespace Qt3DExtras
class QForwardRenderer;
}

class QgsMapLayer;
class CameraController;
class Map3D;
class Terrain;
Expand All @@ -42,6 +43,7 @@ class _3D_EXPORT Scene : public Qt3DCore::QEntity
void onCameraChanged();
void onFrameTriggered( float dt );
void createTerrain();
void onLayerRenderer3DChanged();

private:
const Map3D &mMap;
Expand All @@ -50,6 +52,8 @@ class _3D_EXPORT Scene : public Qt3DCore::QEntity
CameraController *mCameraController;
Terrain *mTerrain;
QList<ChunkedEntity *> chunkEntities;
//! Keeps track of entities that belong to a particular layer
QMap<QgsMapLayer *, Qt3DCore::QEntity *> mLayerEntities;
};

#endif // SCENE_H
3 changes: 2 additions & 1 deletion src/3d/testapp/main.cpp
Expand Up @@ -5,10 +5,10 @@
#include <Qt3DRender>
#include <Qt3DExtras>

#include "abstract3drenderer.h"
#include "abstract3dsymbol.h"
#include "maptexturegenerator.h"
#include "sidepanel.h"
#include "vectorlayer3drenderer.h"
#include "window3d.h"
#include "map3d.h"
#include "flatterraingenerator.h"
Expand Down Expand Up @@ -239,6 +239,7 @@ int main( int argc, char *argv[] )
hLayout->addWidget( container, 1 );
hLayout->addWidget( sidePanel );

widget.setWindowTitle( "QGIS 3D" );
widget.resize( 800, 600 );
widget.show();

Expand Down
@@ -1,4 +1,4 @@
#include "abstract3drenderer.h"
#include "vectorlayer3drenderer.h"

#include "abstract3dsymbol.h"
#include "lineentity.h"
Expand All @@ -18,7 +18,7 @@ VectorLayer3DRenderer::~VectorLayer3DRenderer()
{
}

Abstract3DRenderer *VectorLayer3DRenderer::clone() const
VectorLayer3DRenderer *VectorLayer3DRenderer::clone() const
{
VectorLayer3DRenderer *r = new VectorLayer3DRenderer( mSymbol ? mSymbol->clone() : nullptr );
r->layerRef = layerRef;
Expand Down

0 comments on commit ba7573a

Please sign in to comment.