Skip to content

Commit

Permalink
GUI for configuration of 3D line symbols for vector layers
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Sep 15, 2017
1 parent ba7573a commit 418dc07
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 18 deletions.
6 changes: 3 additions & 3 deletions src/3d/abstract3dsymbol.cpp
Expand Up @@ -101,7 +101,7 @@ Line3DSymbol::Line3DSymbol()
, altBinding( AltBindCentroid )
, height( 0 )
, extrusionHeight( 0 )
, distance( 1 )
, width( 2 )
{

}
Expand All @@ -120,7 +120,7 @@ void Line3DSymbol::writeXml( QDomElement &elem ) const
elemDataProperties.setAttribute( "alt-binding", Utils::altBindingToString( altBinding ) );
elemDataProperties.setAttribute( "height", height );
elemDataProperties.setAttribute( "extrusion-height", extrusionHeight );
elemDataProperties.setAttribute( "distance", distance );
elemDataProperties.setAttribute( "width", width );
elem.appendChild( elemDataProperties );

QDomElement elemMaterial = doc.createElement( "material" );
Expand All @@ -135,7 +135,7 @@ void Line3DSymbol::readXml( const QDomElement &elem )
altBinding = Utils::altBindingFromString( elemDataProperties.attribute( "alt-binding" ) );
height = elemDataProperties.attribute( "height" ).toFloat();
extrusionHeight = elemDataProperties.attribute( "extrusion-height" ).toFloat();
distance = elemDataProperties.attribute( "distance" ).toFloat();
width = elemDataProperties.attribute( "width" ).toFloat();

QDomElement elemMaterial = elem.firstChildElement( "material" );
material.readXml( elemMaterial );
Expand Down
10 changes: 5 additions & 5 deletions src/3d/abstract3dsymbol.h
Expand Up @@ -7,7 +7,7 @@
#include "utils.h"


/** 3D symbols are used by VectorLayer3DRenderer. They define appearance of data in 3D. */
//! 3D symbols are used by VectorLayer3DRenderer. They define appearance of data in 3D.
class _3D_EXPORT Abstract3DSymbol
{
public:
Expand All @@ -21,7 +21,7 @@ class _3D_EXPORT Abstract3DSymbol
};


/** 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls). */
//! 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls).
class _3D_EXPORT Polygon3DSymbol : public Abstract3DSymbol
{
public:
Expand All @@ -42,7 +42,7 @@ class _3D_EXPORT Polygon3DSymbol : public Abstract3DSymbol
};


/** 3D symbol that draws point geometries as 3D objects using one of the predefined shapes. */
//! 3D symbol that draws point geometries as 3D objects using one of the predefined shapes.
class _3D_EXPORT Point3DSymbol : public Abstract3DSymbol
{
public:
Expand All @@ -61,7 +61,7 @@ class _3D_EXPORT Point3DSymbol : public Abstract3DSymbol
};


/** 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer with given thickness). */
//! 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer with given thickness).
class _3D_EXPORT Line3DSymbol : public Abstract3DSymbol
{
public:
Expand All @@ -80,7 +80,7 @@ class _3D_EXPORT Line3DSymbol : public Abstract3DSymbol
float extrusionHeight; //!< How much to extrude (0 means no walls)
PhongMaterialSettings material; //!< Defines appearance of objects

float distance; //!< Distance of buffer of lines
float width; //!< Line width (horizontally)
};


Expand Down
2 changes: 1 addition & 1 deletion src/3d/lineentity.cpp
Expand Up @@ -45,7 +45,7 @@ LineEntity::LineEntity( const Map3D &map, QgsVectorLayer *layer, const Line3DSym
QgsAbstractGeometry *g = f.geometry().geometry();

QgsGeos engine( g );
QgsAbstractGeometry *buffered = engine.buffer( symbol.distance, nSegments, endCapStyle, joinStyle, mitreLimit ); // factory
QgsAbstractGeometry *buffered = engine.buffer( symbol.width / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); // factory

if ( QgsWkbTypes::flatType( buffered->wkbType() ) == QgsWkbTypes::Polygon )
{
Expand Down
2 changes: 1 addition & 1 deletion src/3d/testapp/main.cpp
Expand Up @@ -186,7 +186,7 @@ int main( int argc, char *argv[] )
lineSymbol->material.setShininess( 0 );
lineSymbol->altBinding = AltBindVertex; // follow terrain
lineSymbol->height = 1.5;
lineSymbol->distance = 2.5;
lineSymbol->width = 5;
VectorLayer3DRenderer *lr = new VectorLayer3DRenderer( lineSymbol );
lr->setLayer( vlLines );
map.renderers << lr;
Expand Down
41 changes: 41 additions & 0 deletions src/app/3d/qgsline3dsymbolwidget.cpp
@@ -0,0 +1,41 @@
#include "qgsline3dsymbolwidget.h"

#include "abstract3dsymbol.h"


QgsLine3DSymbolWidget::QgsLine3DSymbolWidget( QWidget *parent )
: QWidget( parent )
{
setupUi( this );

setSymbol( Line3DSymbol() );

connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( spinExtrusion, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( cboAltClamping, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( cboAltBinding, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( widgetMaterial, &QgsPhongMaterialWidget::changed, this, &QgsLine3DSymbolWidget::changed );
}

void QgsLine3DSymbolWidget::setSymbol( const Line3DSymbol &symbol )
{
spinWidth->setValue( symbol.width );
spinHeight->setValue( symbol.height );
spinExtrusion->setValue( symbol.extrusionHeight );
cboAltClamping->setCurrentIndex( ( int ) symbol.altClamping );
cboAltBinding->setCurrentIndex( ( int ) symbol.altBinding );
widgetMaterial->setMaterial( symbol.material );
}

Line3DSymbol QgsLine3DSymbolWidget::symbol() const
{
Line3DSymbol sym;
sym.width = spinWidth->value();
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 changes: 26 additions & 0 deletions src/app/3d/qgsline3dsymbolwidget.h
@@ -0,0 +1,26 @@
#ifndef QGSLINE3DSYMBOLWIDGET_H
#define QGSLINE3DSYMBOLWIDGET_H

#include <QWidget>

#include "ui_line3dsymbolwidget.h"

class Line3DSymbol;

//! A widget for configuration of 3D symbol for polygons
class QgsLine3DSymbolWidget : public QWidget, private Ui::Line3DSymbolWidget
{
Q_OBJECT
public:
explicit QgsLine3DSymbolWidget( QWidget *parent = nullptr );

void setSymbol( const Line3DSymbol &symbol );
Line3DSymbol symbol() const;

signals:
void changed();

public slots:
};

#endif // QGSLINE3DSYMBOLWIDGET_H
69 changes: 61 additions & 8 deletions src/app/3d/qgsvectorlayer3drendererwidget.cpp
@@ -1,13 +1,15 @@
#include "qgsvectorlayer3drendererwidget.h"

#include "abstract3dsymbol.h"
#include "qgsline3dsymbolwidget.h"
#include "qgspolygon3dsymbolwidget.h"
#include "vectorlayer3drenderer.h"

#include "qgsvectorlayer.h"

#include <QBoxLayout>
#include <QCheckBox>
#include <QStackedWidget>

QgsVectorLayer3DRendererWidget::QgsVectorLayer3DRendererWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
: QgsMapLayerConfigWidget( layer, canvas, parent )
Expand All @@ -16,13 +18,20 @@ QgsVectorLayer3DRendererWidget::QgsVectorLayer3DRendererWidget( QgsVectorLayer *

QVBoxLayout *layout = new QVBoxLayout( this );
chkEnabled = new QCheckBox( "Enable 3D renderer", this );
widgetPolygon = new QgsPolygon3DSymbolWidget( this );
widgetStack = new QStackedWidget( this );
layout->addWidget( chkEnabled );
layout->addWidget( widgetPolygon );
layout->addWidget( widgetStack );

widgetUnsupported = new QLabel( tr( "Sorry, this layer is not supported." ), this );
widgetLine = new QgsLine3DSymbolWidget( this );
widgetPolygon = new QgsPolygon3DSymbolWidget( this );

widgetPolygon->setEnabled( false );
widgetStack->addWidget( widgetUnsupported );
widgetStack->addWidget( widgetLine );
widgetStack->addWidget( widgetPolygon );

connect( chkEnabled, &QCheckBox::clicked, this, &QgsVectorLayer3DRendererWidget::onEnabledClicked );
connect( widgetLine, &QgsLine3DSymbolWidget::changed, this, &QgsVectorLayer3DRendererWidget::widgetChanged );
connect( widgetPolygon, &QgsPolygon3DSymbolWidget::changed, this, &QgsVectorLayer3DRendererWidget::widgetChanged );
}

Expand Down Expand Up @@ -51,21 +60,64 @@ void QgsVectorLayer3DRendererWidget::setRenderer( const VectorLayer3DRenderer *r
mRenderer.reset( renderer ? renderer->clone() : nullptr );

whileBlocking( chkEnabled )->setChecked( ( bool )mRenderer );
widgetLine->setEnabled( chkEnabled->isChecked() );
widgetPolygon->setEnabled( chkEnabled->isChecked() );

if ( mRenderer && mRenderer->symbol() && mRenderer->symbol()->type() == "polygon" )
int pageIndex;
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer );
switch ( vlayer->geometryType() )
{
whileBlocking( widgetPolygon )->setSymbol( *static_cast<const Polygon3DSymbol *>( mRenderer->symbol() ) );
case QgsWkbTypes::LineGeometry:
pageIndex = 1;
if ( mRenderer && mRenderer->symbol() && mRenderer->symbol()->type() == "line" )
{
whileBlocking( widgetLine )->setSymbol( *static_cast<const Line3DSymbol *>( mRenderer->symbol() ) );
}
else
{
whileBlocking( widgetLine )->setSymbol( Line3DSymbol() );
}
break;

case QgsWkbTypes::PolygonGeometry:
pageIndex = 2;
if ( mRenderer && mRenderer->symbol() && mRenderer->symbol()->type() == "polygon" )
{
whileBlocking( widgetPolygon )->setSymbol( *static_cast<const Polygon3DSymbol *>( mRenderer->symbol() ) );
}
else
{
whileBlocking( widgetPolygon )->setSymbol( Polygon3DSymbol() );
}
break;

default:
pageIndex = 0; // unsupported
break;
}
widgetStack->setCurrentIndex( pageIndex );
}

VectorLayer3DRenderer *QgsVectorLayer3DRendererWidget::renderer()
{
if ( chkEnabled->isChecked() )
{
VectorLayer3DRenderer *r = new VectorLayer3DRenderer( new Polygon3DSymbol( widgetPolygon->symbol() ) );
r->setLayer( qobject_cast<QgsVectorLayer *>( mLayer ) );
mRenderer.reset( r );
int pageIndex = widgetStack->currentIndex();
if ( pageIndex == 1 || pageIndex == 2 )
{
Abstract3DSymbol *sym;
if ( pageIndex == 1 )
sym = new Line3DSymbol( widgetLine->symbol() );
else
sym = new Polygon3DSymbol( widgetPolygon->symbol() );
VectorLayer3DRenderer *r = new VectorLayer3DRenderer( sym );
r->setLayer( qobject_cast<QgsVectorLayer *>( mLayer ) );
mRenderer.reset( r );
}
else
{
mRenderer.reset();
}
}
else
{
Expand All @@ -83,6 +135,7 @@ void QgsVectorLayer3DRendererWidget::apply()

void QgsVectorLayer3DRendererWidget::onEnabledClicked()
{
widgetLine->setEnabled( chkEnabled->isChecked() );
widgetPolygon->setEnabled( chkEnabled->isChecked() );
emit widgetChanged();
}
7 changes: 7 additions & 0 deletions src/app/3d/qgsvectorlayer3drendererwidget.h
Expand Up @@ -6,6 +6,10 @@
#include "qgsmaplayerconfigwidget.h"

class QCheckBox;
class QLabel;
class QStackedWidget;

class QgsLine3DSymbolWidget;
class QgsPolygon3DSymbolWidget;
class QgsVectorLayer;
class QgsMapCanvas;
Expand Down Expand Up @@ -35,7 +39,10 @@ class QgsVectorLayer3DRendererWidget : public QgsMapLayerConfigWidget

private:
QCheckBox *chkEnabled;
QStackedWidget *widgetStack;
QgsLine3DSymbolWidget *widgetLine;
QgsPolygon3DSymbolWidget *widgetPolygon;
QLabel *widgetUnsupported;

std::unique_ptr<VectorLayer3DRenderer> mRenderer;
};
Expand Down
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -370,6 +370,7 @@ IF (WITH_3D)
3d/qgs3dmapcanvas.cpp
3d/qgs3dmapcanvasdockwidget.cpp
3d/qgs3dmapconfigwidget.cpp
3d/qgsline3dsymbolwidget.cpp
3d/qgspolygon3dsymbolwidget.cpp
3d/qgsphongmaterialwidget.cpp
3d/qgsvectorlayer3drendererwidget.cpp
Expand All @@ -380,6 +381,7 @@ IF (WITH_3D)
3d/qgs3dmapcanvas.h
3d/qgs3dmapcanvasdockwidget.h
3d/qgs3dmapconfigwidget.h
3d/qgsline3dsymbolwidget.h
3d/qgspolygon3dsymbolwidget.h
3d/qgsphongmaterialwidget.h
3d/qgsvectorlayer3drendererwidget.h
Expand Down

0 comments on commit 418dc07

Please sign in to comment.