mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
GUI for configuration of 3D polygon symbols for vector layers
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! :-)
This commit is contained in:
parent
b9dd6bc622
commit
ba7573a94e
@ -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}")
|
||||
|
@ -58,5 +58,7 @@
|
||||
|
||||
#cmakedefine ENABLE_MODELTEST
|
||||
|
||||
#cmakedefine HAVE_3D
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -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>
|
||||
|
38
images/themes/default/3d.svg
Normal file
38
images/themes/default/3d.svg
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg12"
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16">
|
||||
<metadata
|
||||
id="metadata18">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs16" />
|
||||
<path
|
||||
d="M 2.3348556,4.5414044 8.0212426,8.3776059 13.466994,4.7037083 7.7806076,0.86750671 Z"
|
||||
style="fill:#f79191;fill-opacity:1;fill-rule:evenodd;stroke:#a40000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4535" />
|
||||
<path
|
||||
d="M 8.6635732,9.3611399 V 14.964189 L 14.109324,11.290292 V 5.6872423 Z"
|
||||
style="fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4537" />
|
||||
<path
|
||||
d="m 1.6730308,5.5249384 5.686387,3.8362015 v 5.6030491 l -5.686387,-3.836201 z"
|
||||
style="fill:#8ae234;fill-opacity:1;fill-rule:evenodd;stroke:#4e9a06;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4539" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -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.
|
||||
|
@ -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``.
|
||||
@ -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();
|
||||
|
@ -2,7 +2,6 @@
|
||||
# sources
|
||||
|
||||
SET(QGIS_3D_SRCS
|
||||
abstract3drenderer.cpp
|
||||
abstract3dsymbol.cpp
|
||||
cameracontroller.cpp
|
||||
lineentity.cpp
|
||||
@ -15,6 +14,7 @@ SET(QGIS_3D_SRCS
|
||||
tessellator.cpp
|
||||
tilingscheme.cpp
|
||||
utils.cpp
|
||||
vectorlayer3drenderer.cpp
|
||||
|
||||
chunks/chunkboundsentity.cpp
|
||||
chunks/chunkedentity.cpp
|
||||
@ -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
|
||||
@ -76,6 +75,7 @@ SET(QGIS_3D_HDRS
|
||||
tessellator.h
|
||||
tilingscheme.h
|
||||
utils.h
|
||||
vectorlayer3drenderer.h
|
||||
|
||||
chunks/chunkboundsentity.h
|
||||
chunks/chunkedentity.h
|
||||
@ -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
|
||||
)
|
||||
|
@ -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>
|
||||
@ -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();
|
||||
}
|
||||
@ -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" )
|
||||
{
|
||||
@ -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() );
|
||||
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
class QgsMapLayer;
|
||||
class QgsRasterLayer;
|
||||
|
||||
class Abstract3DRenderer;
|
||||
class QgsAbstract3DRenderer;
|
||||
class TerrainGenerator;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
@ -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 )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
@ -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 ) );
|
||||
@ -83,7 +97,7 @@ 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 );
|
||||
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace Qt3DExtras
|
||||
class QForwardRenderer;
|
||||
}
|
||||
|
||||
class QgsMapLayer;
|
||||
class CameraController;
|
||||
class Map3D;
|
||||
class Terrain;
|
||||
@ -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;
|
||||
@ -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
|
||||
|
@ -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"
|
||||
@ -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();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "abstract3drenderer.h"
|
||||
#include "vectorlayer3drenderer.h"
|
||||
|
||||
#include "abstract3dsymbol.h"
|
||||
#include "lineentity.h"
|
||||
@ -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;
|
@ -1,8 +1,10 @@
|
||||
#ifndef ABSTRACT3DRENDERER_H
|
||||
#define ABSTRACT3DRENDERER_H
|
||||
#ifndef VECTORLAYER3DRENDERER_H
|
||||
#define VECTORLAYER3DRENDERER_H
|
||||
|
||||
#include "qgis_3d.h"
|
||||
|
||||
#include "qgsabstract3drenderer.h"
|
||||
|
||||
#include "phongmaterialsettings.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -13,34 +15,11 @@
|
||||
class QgsVectorLayer;
|
||||
|
||||
class Abstract3DSymbol;
|
||||
class Map3D;
|
||||
|
||||
|
||||
namespace Qt3DCore
|
||||
{
|
||||
class QEntity;
|
||||
}
|
||||
|
||||
class _3D_EXPORT Abstract3DRenderer //: public QObject
|
||||
{
|
||||
//Q_OBJECT
|
||||
public:
|
||||
virtual ~Abstract3DRenderer() {}
|
||||
|
||||
virtual QString type() const = 0;
|
||||
virtual Abstract3DRenderer *clone() const = 0;
|
||||
virtual Qt3DCore::QEntity *createEntity( const Map3D &map ) const = 0;
|
||||
|
||||
virtual void writeXml( QDomElement &elem ) const = 0;
|
||||
virtual void readXml( const QDomElement &elem ) = 0;
|
||||
virtual void resolveReferences( const QgsProject &project ) { Q_UNUSED( project ); }
|
||||
};
|
||||
|
||||
|
||||
/** 3D renderer that renders all features of a vector layer with the same 3D symbol.
|
||||
* The appearance if completely defined by the symbol.
|
||||
* The appearance is completely defined by the symbol.
|
||||
*/
|
||||
class _3D_EXPORT VectorLayer3DRenderer : public Abstract3DRenderer
|
||||
class _3D_EXPORT VectorLayer3DRenderer : public QgsAbstract3DRenderer
|
||||
{
|
||||
public:
|
||||
//! Takes ownership of the symbol object
|
||||
@ -55,7 +34,7 @@ class _3D_EXPORT VectorLayer3DRenderer : public Abstract3DRenderer
|
||||
const Abstract3DSymbol *symbol() const;
|
||||
|
||||
QString type() const override { return "vector"; }
|
||||
Abstract3DRenderer *clone() const override;
|
||||
VectorLayer3DRenderer *clone() const override;
|
||||
Qt3DCore::QEntity *createEntity( const Map3D &map ) const override;
|
||||
|
||||
void writeXml( QDomElement &elem ) const override;
|
||||
@ -68,4 +47,4 @@ class _3D_EXPORT VectorLayer3DRenderer : public Abstract3DRenderer
|
||||
};
|
||||
|
||||
|
||||
#endif // ABSTRACT3DRENDERER_H
|
||||
#endif // VECTORLAYER3DRENDERER_H
|
35
src/app/3d/qgsphongmaterialwidget.cpp
Normal file
35
src/app/3d/qgsphongmaterialwidget.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "qgsphongmaterialwidget.h"
|
||||
|
||||
#include "phongmaterialsettings.h"
|
||||
|
||||
|
||||
QgsPhongMaterialWidget::QgsPhongMaterialWidget( QWidget *parent )
|
||||
: QWidget( parent )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
setMaterial( PhongMaterialSettings() );
|
||||
|
||||
connect( btnDiffuse, &QgsColorButton::colorChanged, this, &QgsPhongMaterialWidget::changed );
|
||||
connect( btnAmbient, &QgsColorButton::colorChanged, this, &QgsPhongMaterialWidget::changed );
|
||||
connect( btnSpecular, &QgsColorButton::colorChanged, this, &QgsPhongMaterialWidget::changed );
|
||||
connect( spinShininess, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPhongMaterialWidget::changed );
|
||||
}
|
||||
|
||||
void QgsPhongMaterialWidget::setMaterial( const PhongMaterialSettings &material )
|
||||
{
|
||||
btnDiffuse->setColor( material.diffuse() );
|
||||
btnAmbient->setColor( material.ambient() );
|
||||
btnSpecular->setColor( material.specular() );
|
||||
spinShininess->setValue( material.shininess() );
|
||||
}
|
||||
|
||||
PhongMaterialSettings QgsPhongMaterialWidget::material() const
|
||||
{
|
||||
PhongMaterialSettings m;
|
||||
m.setDiffuse( btnDiffuse->color() );
|
||||
m.setAmbient( btnAmbient->color() );
|
||||
m.setSpecular( btnSpecular->color() );
|
||||
m.setShininess( spinShininess->value() );
|
||||
return m;
|
||||
}
|
27
src/app/3d/qgsphongmaterialwidget.h
Normal file
27
src/app/3d/qgsphongmaterialwidget.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef QGSPHONGMATERIALWIDGET_H
|
||||
#define QGSPHONGMATERIALWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <ui_phongmaterialwidget.h>
|
||||
|
||||
class PhongMaterialSettings;
|
||||
|
||||
|
||||
//! Widget for configuration of Phong material settings
|
||||
class QgsPhongMaterialWidget : public QWidget, private Ui::PhongMaterialWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsPhongMaterialWidget( QWidget *parent = nullptr );
|
||||
|
||||
void setMaterial( const PhongMaterialSettings &material );
|
||||
PhongMaterialSettings material() const;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // QGSPHONGMATERIALWIDGET_H
|
38
src/app/3d/qgspolygon3dsymbolwidget.cpp
Normal file
38
src/app/3d/qgspolygon3dsymbolwidget.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "qgspolygon3dsymbolwidget.h"
|
||||
|
||||
#include "abstract3dsymbol.h"
|
||||
|
||||
|
||||
QgsPolygon3DSymbolWidget::QgsPolygon3DSymbolWidget( QWidget *parent )
|
||||
: QWidget( parent )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
setSymbol( Polygon3DSymbol() );
|
||||
|
||||
connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPolygon3DSymbolWidget::changed );
|
||||
connect( spinExtrusion, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPolygon3DSymbolWidget::changed );
|
||||
connect( cboAltClamping, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPolygon3DSymbolWidget::changed );
|
||||
connect( cboAltBinding, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPolygon3DSymbolWidget::changed );
|
||||
connect( widgetMaterial, &QgsPhongMaterialWidget::changed, this, &QgsPolygon3DSymbolWidget::changed );
|
||||
}
|
||||
|
||||
void QgsPolygon3DSymbolWidget::setSymbol( const Polygon3DSymbol &symbol )
|
||||
{
|
||||
spinHeight->setValue( symbol.height );
|
||||
spinExtrusion->setValue( symbol.extrusionHeight );
|
||||
cboAltClamping->setCurrentIndex( ( int ) symbol.altClamping );
|
||||
cboAltBinding->setCurrentIndex( ( int ) symbol.altBinding );
|
||||
widgetMaterial->setMaterial( symbol.material );
|
||||
}
|
||||
|
||||
Polygon3DSymbol QgsPolygon3DSymbolWidget::symbol() const
|
||||
{
|
||||
Polygon3DSymbol sym;
|
||||
sym.height = spinHeight->value();
|
||||
sym.extrusionHeight = spinExtrusion->value();
|
||||
sym.altClamping = ( AltitudeClamping ) cboAltClamping->currentIndex();
|
||||
sym.altBinding = ( AltitudeBinding ) cboAltBinding->currentIndex();
|
||||
sym.material = widgetMaterial->material();
|
||||
return sym;
|
||||
}
|
26
src/app/3d/qgspolygon3dsymbolwidget.h
Normal file
26
src/app/3d/qgspolygon3dsymbolwidget.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef QGSPOLYGON3DSYMBOLWIDGET_H
|
||||
#define QGSPOLYGON3DSYMBOLWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui_polygon3dsymbolwidget.h"
|
||||
|
||||
class Polygon3DSymbol;
|
||||
|
||||
//! A widget for configuration of 3D symbol for polygons
|
||||
class QgsPolygon3DSymbolWidget : public QWidget, private Ui::Polygon3DSymbolWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsPolygon3DSymbolWidget( QWidget *parent = nullptr );
|
||||
|
||||
void setSymbol( const Polygon3DSymbol &symbol );
|
||||
Polygon3DSymbol symbol() const;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // QGSPOLYGON3DSYMBOLWIDGET_H
|
88
src/app/3d/qgsvectorlayer3drendererwidget.cpp
Normal file
88
src/app/3d/qgsvectorlayer3drendererwidget.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "qgsvectorlayer3drendererwidget.h"
|
||||
|
||||
#include "abstract3dsymbol.h"
|
||||
#include "qgspolygon3dsymbolwidget.h"
|
||||
#include "vectorlayer3drenderer.h"
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
|
||||
QgsVectorLayer3DRendererWidget::QgsVectorLayer3DRendererWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
|
||||
: QgsMapLayerConfigWidget( layer, canvas, parent )
|
||||
{
|
||||
setPanelTitle( tr( "3D View" ) );
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout( this );
|
||||
chkEnabled = new QCheckBox( "Enable 3D renderer", this );
|
||||
widgetPolygon = new QgsPolygon3DSymbolWidget( this );
|
||||
layout->addWidget( chkEnabled );
|
||||
layout->addWidget( widgetPolygon );
|
||||
|
||||
widgetPolygon->setEnabled( false );
|
||||
|
||||
connect( chkEnabled, &QCheckBox::clicked, this, &QgsVectorLayer3DRendererWidget::onEnabledClicked );
|
||||
connect( widgetPolygon, &QgsPolygon3DSymbolWidget::changed, this, &QgsVectorLayer3DRendererWidget::widgetChanged );
|
||||
}
|
||||
|
||||
QgsVectorLayer3DRendererWidget::~QgsVectorLayer3DRendererWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void QgsVectorLayer3DRendererWidget::setLayer( QgsVectorLayer *layer )
|
||||
{
|
||||
mLayer = layer;
|
||||
|
||||
QgsAbstract3DRenderer *r = layer->renderer3D();
|
||||
if ( r && r->type() == "vector" )
|
||||
{
|
||||
VectorLayer3DRenderer *vectorRenderer = static_cast<VectorLayer3DRenderer *>( r );
|
||||
setRenderer( vectorRenderer );
|
||||
}
|
||||
else
|
||||
{
|
||||
setRenderer( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayer3DRendererWidget::setRenderer( const VectorLayer3DRenderer *renderer )
|
||||
{
|
||||
mRenderer.reset( renderer ? renderer->clone() : nullptr );
|
||||
|
||||
whileBlocking( chkEnabled )->setChecked( ( bool )mRenderer );
|
||||
widgetPolygon->setEnabled( chkEnabled->isChecked() );
|
||||
|
||||
if ( mRenderer && mRenderer->symbol() && mRenderer->symbol()->type() == "polygon" )
|
||||
{
|
||||
whileBlocking( widgetPolygon )->setSymbol( *static_cast<const Polygon3DSymbol *>( mRenderer->symbol() ) );
|
||||
}
|
||||
}
|
||||
|
||||
VectorLayer3DRenderer *QgsVectorLayer3DRendererWidget::renderer()
|
||||
{
|
||||
if ( chkEnabled->isChecked() )
|
||||
{
|
||||
VectorLayer3DRenderer *r = new VectorLayer3DRenderer( new Polygon3DSymbol( widgetPolygon->symbol() ) );
|
||||
r->setLayer( qobject_cast<QgsVectorLayer *>( mLayer ) );
|
||||
mRenderer.reset( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
mRenderer.reset();
|
||||
}
|
||||
|
||||
return mRenderer.get();
|
||||
}
|
||||
|
||||
void QgsVectorLayer3DRendererWidget::apply()
|
||||
{
|
||||
VectorLayer3DRenderer *r = renderer();
|
||||
mLayer->setRenderer3D( r ? r->clone() : nullptr );
|
||||
}
|
||||
|
||||
void QgsVectorLayer3DRendererWidget::onEnabledClicked()
|
||||
{
|
||||
widgetPolygon->setEnabled( chkEnabled->isChecked() );
|
||||
emit widgetChanged();
|
||||
}
|
43
src/app/3d/qgsvectorlayer3drendererwidget.h
Normal file
43
src/app/3d/qgsvectorlayer3drendererwidget.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef QGSVECTORLAYER3DRENDERERWIDGET_H
|
||||
#define QGSVECTORLAYER3DRENDERERWIDGET_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "qgsmaplayerconfigwidget.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QgsPolygon3DSymbolWidget;
|
||||
class QgsVectorLayer;
|
||||
class QgsMapCanvas;
|
||||
class VectorLayer3DRenderer;
|
||||
|
||||
|
||||
//! Widget for configuration of 3D renderer of a vector layer
|
||||
class QgsVectorLayer3DRendererWidget : public QgsMapLayerConfigWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsVectorLayer3DRendererWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr );
|
||||
~QgsVectorLayer3DRendererWidget();
|
||||
|
||||
void setLayer( QgsVectorLayer *layer );
|
||||
|
||||
//! no transfer of ownership
|
||||
void setRenderer( const VectorLayer3DRenderer *renderer );
|
||||
//! no transfer of ownership
|
||||
VectorLayer3DRenderer *renderer();
|
||||
|
||||
public slots:
|
||||
virtual void apply() override;
|
||||
|
||||
private slots:
|
||||
void onEnabledClicked();
|
||||
|
||||
private:
|
||||
QCheckBox *chkEnabled;
|
||||
QgsPolygon3DSymbolWidget *widgetPolygon;
|
||||
|
||||
std::unique_ptr<VectorLayer3DRenderer> mRenderer;
|
||||
};
|
||||
|
||||
#endif // QGSVECTORLAYER3DRENDERERWIDGET_H
|
@ -370,6 +370,9 @@ IF (WITH_3D)
|
||||
3d/qgs3dmapcanvas.cpp
|
||||
3d/qgs3dmapcanvasdockwidget.cpp
|
||||
3d/qgs3dmapconfigwidget.cpp
|
||||
3d/qgspolygon3dsymbolwidget.cpp
|
||||
3d/qgsphongmaterialwidget.cpp
|
||||
3d/qgsvectorlayer3drendererwidget.cpp
|
||||
)
|
||||
|
||||
SET (QGIS_APP_MOC_HDRS
|
||||
@ -377,6 +380,9 @@ IF (WITH_3D)
|
||||
3d/qgs3dmapcanvas.h
|
||||
3d/qgs3dmapcanvasdockwidget.h
|
||||
3d/qgs3dmapconfigwidget.h
|
||||
3d/qgspolygon3dsymbolwidget.h
|
||||
3d/qgsphongmaterialwidget.h
|
||||
3d/qgsvectorlayer3drendererwidget.h
|
||||
)
|
||||
ENDIF (WITH_3D)
|
||||
|
||||
@ -561,6 +567,7 @@ INCLUDE_DIRECTORIES(
|
||||
IF (WITH_3D)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/app/3d
|
||||
${CMAKE_SOURCE_DIR}/src/core/3d
|
||||
${CMAKE_SOURCE_DIR}/src/3d
|
||||
${CMAKE_SOURCE_DIR}/src/3d/terrain
|
||||
${CMAKE_SOURCE_DIR}/src/3d/chunks
|
||||
|
@ -9879,6 +9879,7 @@ void QgisApp::newMapCanvas()
|
||||
}
|
||||
}
|
||||
|
||||
#include "qgsabstract3drenderer.h"
|
||||
#include "qgs3dmapcanvasdockwidget.h"
|
||||
#include "map3d.h"
|
||||
#include "flatterraingenerator.h"
|
||||
@ -9890,8 +9891,6 @@ void QgisApp::new3DMapCanvas()
|
||||
QgsRectangle fullExtent = mMapCanvas->fullExtent();
|
||||
|
||||
Map3D *map = new Map3D;
|
||||
map->setShowTerrainBoundingBoxes( true );
|
||||
map->setShowTerrainTilesInfo( true );
|
||||
map->crs = prj->crs();
|
||||
map->originX = fullExtent.center().x();
|
||||
map->originY = fullExtent.center().y();
|
||||
@ -9910,7 +9909,7 @@ void QgisApp::new3DMapCanvas()
|
||||
map3DWidget->setGeometry( QRect( rect().width() * 0.75, rect().height() * 0.5, 400, 400 ) );
|
||||
map3DWidget->setMap( map );
|
||||
map3DWidget->setMainCanvas( mMapCanvas );
|
||||
addDockWidget( Qt::RightDockWidgetArea, map3DWidget );
|
||||
addDockWidget( Qt::BottomDockWidgetArea, map3DWidget );
|
||||
}
|
||||
|
||||
void QgisApp::setExtent( const QgsRectangle &rect )
|
||||
|
@ -45,6 +45,10 @@
|
||||
#include "qgsruntimeprofiler.h"
|
||||
#include "qgsrasterminmaxwidget.h"
|
||||
|
||||
#ifdef HAVE_3D
|
||||
#include "qgsvectorlayer3drendererwidget.h"
|
||||
#endif
|
||||
|
||||
|
||||
QgsLayerStylingWidget::QgsLayerStylingWidget( QgsMapCanvas *canvas, const QList<QgsMapLayerConfigWidgetFactory *> &pages, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
@ -158,6 +162,13 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
|
||||
labelItem->setData( Qt::UserRole, VectorLabeling );
|
||||
labelItem->setToolTip( tr( "Labels" ) );
|
||||
mOptionsListWidget->addItem( labelItem );
|
||||
|
||||
#ifdef HAVE_3D
|
||||
QListWidgetItem *symbol3DItem = new QListWidgetItem( QgsApplication::getThemeIcon( QStringLiteral( "3d.svg" ) ), QString() );
|
||||
symbol3DItem->setData( Qt::UserRole, Symbology3D );
|
||||
symbol3DItem->setToolTip( tr( "3D View" ) );
|
||||
mOptionsListWidget->addItem( symbol3DItem );
|
||||
#endif
|
||||
}
|
||||
else if ( layer->type() == QgsMapLayer::RasterLayer )
|
||||
{
|
||||
@ -318,6 +329,12 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
||||
{
|
||||
mRasterStyleWidget = widget;
|
||||
}
|
||||
#ifdef HAVE_3D
|
||||
else if ( QgsVectorLayer3DRendererWidget *widget = qobject_cast<QgsVectorLayer3DRendererWidget *>( current ) )
|
||||
{
|
||||
mVector3DWidget = widget;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -369,6 +386,20 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
||||
mWidgetStack->setMainPanel( mLabelingWidget );
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_3D
|
||||
case 2: // 3D View
|
||||
{
|
||||
if ( !mVector3DWidget )
|
||||
{
|
||||
mVector3DWidget = new QgsVectorLayer3DRendererWidget( nullptr, mMapCanvas, mWidgetStack );
|
||||
mVector3DWidget->setDockMode( true );
|
||||
connect( mVector3DWidget, &QgsVectorLayer3DRendererWidget::widgetChanged, this, &QgsLayerStylingWidget::autoApply );
|
||||
}
|
||||
mVector3DWidget->setLayer( vlayer );
|
||||
mWidgetStack->setMainPanel( mVector3DWidget );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ class QgsRendererRasterPropertiesWidget;
|
||||
class QgsUndoWidget;
|
||||
class QgsRasterHistogramWidget;
|
||||
class QgsMapLayerStyleManagerWidget;
|
||||
class QgsVectorLayer3DRendererWidget;
|
||||
|
||||
class APP_EXPORT QgsLayerStyleManagerWidgetFactory : public QgsMapLayerConfigWidgetFactory
|
||||
{
|
||||
@ -84,6 +85,7 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
|
||||
RasterTransparency,
|
||||
RasterHistogram,
|
||||
History,
|
||||
Symbology3D,
|
||||
};
|
||||
|
||||
QgsLayerStylingWidget( QgsMapCanvas *canvas, const QList<QgsMapLayerConfigWidgetFactory *> &pages, QWidget *parent = 0 );
|
||||
@ -131,6 +133,9 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
|
||||
QgsUndoWidget *mUndoWidget = nullptr;
|
||||
QgsMapLayer *mCurrentLayer = nullptr;
|
||||
QgsLabelingWidget *mLabelingWidget = nullptr;
|
||||
#ifdef HAVE_3D
|
||||
QgsVectorLayer3DRendererWidget *mVector3DWidget = nullptr;
|
||||
#endif
|
||||
QgsRendererRasterPropertiesWidget *mRasterStyleWidget = nullptr;
|
||||
QList<QgsMapLayerConfigWidgetFactory *> mPageFactories;
|
||||
QMap<int, QgsMapLayerConfigWidgetFactory *> mUserPages;
|
||||
|
45
src/core/3d/qgs3drendererregistry.cpp
Normal file
45
src/core/3d/qgs3drendererregistry.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "qgs3drendererregistry.h"
|
||||
|
||||
|
||||
Qgs3DRendererAbstractMetadata::Qgs3DRendererAbstractMetadata( const QString &name )
|
||||
: mName( name )
|
||||
{
|
||||
}
|
||||
|
||||
QString Qgs3DRendererAbstractMetadata::name() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
|
||||
// ----------
|
||||
|
||||
|
||||
Qgs3DRendererRegistry::Qgs3DRendererRegistry()
|
||||
{
|
||||
}
|
||||
|
||||
Qgs3DRendererRegistry::~Qgs3DRendererRegistry()
|
||||
{
|
||||
qDeleteAll( mRenderers );
|
||||
}
|
||||
|
||||
void Qgs3DRendererRegistry::addRenderer( Qgs3DRendererAbstractMetadata *metadata )
|
||||
{
|
||||
mRenderers.insert( metadata->name(), metadata );
|
||||
}
|
||||
|
||||
void Qgs3DRendererRegistry::removeRenderer( const QString &name )
|
||||
{
|
||||
delete mRenderers.take( name );
|
||||
}
|
||||
|
||||
Qgs3DRendererAbstractMetadata *Qgs3DRendererRegistry::rendererMetadata( const QString &name ) const
|
||||
{
|
||||
return mRenderers.value( name );
|
||||
}
|
||||
|
||||
QStringList Qgs3DRendererRegistry::renderersList() const
|
||||
{
|
||||
return mRenderers.keys();
|
||||
}
|
61
src/core/3d/qgs3drendererregistry.h
Normal file
61
src/core/3d/qgs3drendererregistry.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef QGS3DRENDERERREGISTRY_H
|
||||
#define QGS3DRENDERERREGISTRY_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
|
||||
#include <QMap>
|
||||
|
||||
class QDomElement;
|
||||
class QgsAbstract3DRenderer;
|
||||
class QgsReadWriteContext;
|
||||
|
||||
|
||||
/**
|
||||
* Base metadata class for 3D renderers. Instances of derived classes may be registered in Qgs3DRendererRegistry.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT Qgs3DRendererAbstractMetadata
|
||||
{
|
||||
public:
|
||||
|
||||
Qgs3DRendererAbstractMetadata( const QString &name );
|
||||
|
||||
QString name() const;
|
||||
|
||||
/** Return new instance of the renderer given the DOM element. Returns NULL on error.
|
||||
* Pure virtual function: must be implemented in derived classes. */
|
||||
virtual QgsAbstract3DRenderer *createRenderer( QDomElement &elem, const QgsReadWriteContext &context ) = 0;
|
||||
|
||||
protected:
|
||||
//! name used within QGIS for identification (the same what renderer's type() returns)
|
||||
QString mName;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Keeps track of available 3D renderers. Should be accessed through QgsApplication::renderer3DRegistry() singleton.
|
||||
* \since QGIS 3.0
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT Qgs3DRendererRegistry
|
||||
{
|
||||
public:
|
||||
Qgs3DRendererRegistry();
|
||||
|
||||
~Qgs3DRendererRegistry();
|
||||
|
||||
//! takes ownership
|
||||
void addRenderer( Qgs3DRendererAbstractMetadata *metadata );
|
||||
|
||||
void removeRenderer( const QString &name );
|
||||
|
||||
Qgs3DRendererAbstractMetadata *rendererMetadata( const QString &name ) const;
|
||||
|
||||
QStringList renderersList() const;
|
||||
|
||||
private:
|
||||
QMap<QString, Qgs3DRendererAbstractMetadata *> mRenderers;
|
||||
};
|
||||
|
||||
#endif // QGS3DRENDERERREGISTRY_H
|
11
src/core/3d/qgsabstract3drenderer.cpp
Normal file
11
src/core/3d/qgsabstract3drenderer.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "qgsabstract3drenderer.h"
|
||||
|
||||
|
||||
QgsAbstract3DRenderer::~QgsAbstract3DRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
void QgsAbstract3DRenderer::resolveReferences( const QgsProject &project )
|
||||
{
|
||||
Q_UNUSED( project );
|
||||
}
|
35
src/core/3d/qgsabstract3drenderer.h
Normal file
35
src/core/3d/qgsabstract3drenderer.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef QGSABSTRACT3DRENDERER_H
|
||||
#define QGSABSTRACT3DRENDERER_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QDomElement;
|
||||
class QgsProject;
|
||||
class Map3D;
|
||||
|
||||
namespace Qt3DCore
|
||||
{
|
||||
class QEntity;
|
||||
}
|
||||
|
||||
//! Base class for all renderers that may to participate in 3D view.
|
||||
class CORE_EXPORT QgsAbstract3DRenderer //: public QObject
|
||||
{
|
||||
//Q_OBJECT
|
||||
public:
|
||||
virtual ~QgsAbstract3DRenderer();
|
||||
|
||||
virtual QString type() const = 0;
|
||||
virtual QgsAbstract3DRenderer *clone() const = 0;
|
||||
virtual Qt3DCore::QEntity *createEntity( const Map3D &map ) const = 0;
|
||||
|
||||
virtual void writeXml( QDomElement &elem ) const = 0;
|
||||
virtual void readXml( const QDomElement &elem ) = 0;
|
||||
virtual void resolveReferences( const QgsProject &project );
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // QGSABSTRACT3DRENDERER_H
|
@ -463,6 +463,9 @@ SET(QGIS_CORE_SRCS
|
||||
geometry/qgswkbptr.cpp
|
||||
geometry/qgswkbtypes.cpp
|
||||
|
||||
3d/qgs3drendererregistry.cpp
|
||||
3d/qgsabstract3drenderer.cpp
|
||||
|
||||
fieldformatter/qgsdatetimefieldformatter.cpp
|
||||
fieldformatter/qgsfallbackfieldformatter.cpp
|
||||
fieldformatter/qgskeyvaluefieldformatter.cpp
|
||||
@ -1093,6 +1096,9 @@ SET(QGIS_CORE_HDRS
|
||||
geometry/qgswkbptr.h
|
||||
geometry/qgswkbtypes.h
|
||||
|
||||
3d/qgs3drendererregistry.h
|
||||
3d/qgsabstract3drenderer.h
|
||||
|
||||
fieldformatter/qgsdatetimefieldformatter.h
|
||||
fieldformatter/qgsfallbackfieldformatter.h
|
||||
fieldformatter/qgskeyvaluefieldformatter.h
|
||||
@ -1118,6 +1124,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${LIBZIP_INCLUDE_DIR}
|
||||
3d
|
||||
annotations
|
||||
auth
|
||||
composer
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "qgsuserprofile.h"
|
||||
#include "qgsuserprofilemanager.h"
|
||||
#include "qgsreferencedgeometry.h"
|
||||
#include "qgs3drendererregistry.h"
|
||||
|
||||
#include "gps/qgsgpsconnectionregistry.h"
|
||||
#include "processing/qgsprocessingregistry.h"
|
||||
@ -1574,6 +1575,11 @@ QgsFieldFormatterRegistry *QgsApplication::fieldFormatterRegistry()
|
||||
return members()->mFieldFormatterRegistry;
|
||||
}
|
||||
|
||||
Qgs3DRendererRegistry *QgsApplication::renderer3DRegistry()
|
||||
{
|
||||
return members()->m3DRendererRegistry;
|
||||
}
|
||||
|
||||
QgsApplication::ApplicationMembers::ApplicationMembers()
|
||||
{
|
||||
// don't use initializer lists or scoped pointers - as more objects are added here we
|
||||
@ -1598,11 +1604,13 @@ QgsApplication::ApplicationMembers::ApplicationMembers()
|
||||
mLayoutItemRegistry->populate();
|
||||
mProcessingRegistry->addProvider( new QgsNativeAlgorithms( mProcessingRegistry ) );
|
||||
mAnnotationRegistry = new QgsAnnotationRegistry();
|
||||
m3DRendererRegistry = new Qgs3DRendererRegistry();
|
||||
}
|
||||
|
||||
QgsApplication::ApplicationMembers::~ApplicationMembers()
|
||||
{
|
||||
delete mActionScopeRegistry;
|
||||
delete m3DRendererRegistry;
|
||||
delete mAnnotationRegistry;
|
||||
delete mColorSchemeRegistry;
|
||||
delete mFieldFormatterRegistry;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "qgis.h"
|
||||
#include "qgsconfig.h"
|
||||
|
||||
class Qgs3DRendererRegistry;
|
||||
class QgsActionScopeRegistry;
|
||||
class QgsRuntimeProfiler;
|
||||
class QgsTaskManager;
|
||||
@ -583,6 +584,13 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
*/
|
||||
static QgsFieldFormatterRegistry *fieldFormatterRegistry();
|
||||
|
||||
/**
|
||||
* Returns registry of available 3D renderers.
|
||||
* \note not available in Python bindings
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
static Qgs3DRendererRegistry *renderer3DRegistry() SIP_SKIP;
|
||||
|
||||
/**
|
||||
* This string is used to represent the value `NULL` throughout QGIS.
|
||||
*
|
||||
@ -698,6 +706,7 @@ class CORE_EXPORT QgsApplication : public QApplication
|
||||
|
||||
struct ApplicationMembers
|
||||
{
|
||||
Qgs3DRendererRegistry *m3DRendererRegistry = nullptr;
|
||||
QgsActionScopeRegistry *mActionScopeRegistry = nullptr;
|
||||
QgsAnnotationRegistry *mAnnotationRegistry = nullptr;
|
||||
QgsColorSchemeRegistry *mColorSchemeRegistry = nullptr;
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "qgsabstract3drenderer.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
@ -88,6 +89,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
|
||||
|
||||
QgsMapLayer::~QgsMapLayer()
|
||||
{
|
||||
delete m3DRenderer;
|
||||
delete mLegend;
|
||||
delete mStyleManager;
|
||||
}
|
||||
@ -1673,6 +1675,21 @@ QgsMapLayerStyleManager *QgsMapLayer::styleManager() const
|
||||
return mStyleManager;
|
||||
}
|
||||
|
||||
void QgsMapLayer::setRenderer3D( QgsAbstract3DRenderer *renderer )
|
||||
{
|
||||
if ( renderer == m3DRenderer )
|
||||
return;
|
||||
|
||||
delete m3DRenderer;
|
||||
m3DRenderer = renderer;
|
||||
emit renderer3DChanged();
|
||||
}
|
||||
|
||||
QgsAbstract3DRenderer *QgsMapLayer::renderer3D() const
|
||||
{
|
||||
return m3DRenderer;
|
||||
}
|
||||
|
||||
void QgsMapLayer::triggerRepaint( bool deferredUpdate )
|
||||
{
|
||||
emit repaintRequested( deferredUpdate );
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "qgsmaplayerdependency.h"
|
||||
#include "qgslayermetadata.h"
|
||||
|
||||
class QgsAbstract3DRenderer;
|
||||
class QgsDataProvider;
|
||||
class QgsMapLayerLegend;
|
||||
class QgsMapLayerRenderer;
|
||||
@ -675,6 +676,20 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
*/
|
||||
QgsMapLayerStyleManager *styleManager() const;
|
||||
|
||||
/**
|
||||
* Sets 3D renderer for the layer. Takes ownership of the renderer.
|
||||
* \note not available in Python bindings
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void setRenderer3D( QgsAbstract3DRenderer *renderer SIP_TRANSFER ) SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Returns 3D renderer associated with the layer. May be null.
|
||||
* \note not available in Python bindings
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsAbstract3DRenderer *renderer3D() const SIP_SKIP;
|
||||
|
||||
/** Tests whether the layer should be visible at the specified \a scale.
|
||||
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
|
||||
* \returns true if the layer is visible at the given scale.
|
||||
@ -897,6 +912,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
*/
|
||||
void legendChanged();
|
||||
|
||||
/**
|
||||
* Signal emitted when 3D renderer associated with the layer has changed.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void renderer3DChanged();
|
||||
|
||||
/**
|
||||
* Emitted whenever the configuration is changed. The project listens to this signal
|
||||
* to be marked as dirty.
|
||||
@ -1080,6 +1101,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
|
||||
QgsLayerMetadata mMetadata;
|
||||
|
||||
//! Renderer for 3D views
|
||||
QgsAbstract3DRenderer *m3DRenderer = nullptr;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QgsMapLayer * )
|
||||
|
94
src/ui/3d/phongmaterialwidget.ui
Normal file
94
src/ui/3d/phongmaterialwidget.ui
Normal file
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PhongMaterialWidget</class>
|
||||
<widget class="QWidget" name="PhongMaterialWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>334</width>
|
||||
<height>252</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Diffuse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsColorButton" name="btnDiffuse">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Ambient</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsColorButton" name="btnAmbient">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Specular</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QgsColorButton" name="btnSpecular">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Shininess</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinShininess">
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsColorButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>qgscolorbutton.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
110
src/ui/3d/polygon3dsymbolwidget.ui
Normal file
110
src/ui/3d/polygon3dsymbolwidget.ui
Normal file
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Polygon3DSymbolWidget</class>
|
||||
<widget class="QWidget" name="Polygon3DSymbolWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>538</width>
|
||||
<height>452</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinHeight"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Extrusion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinExtrusion"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Altitude Clamping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cboAltClamping">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Absolute</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Relative</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Terrain</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Altitude Binding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="cboAltBinding">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Vertex</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Centroid</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsPhongMaterialWidget" name="widgetMaterial" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsPhongMaterialWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qgsphongmaterialwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>332</width>
|
||||
<height>319</height>
|
||||
<width>573</width>
|
||||
<height>507</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -336,6 +336,12 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsColorButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>qgscolorbutton.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsPropertyOverrideButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
@ -352,12 +358,6 @@
|
||||
<header>qgsunitselectionwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsColorButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>qgscolorbutton.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsPenJoinStyleComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
|
Loading…
x
Reference in New Issue
Block a user