Skip to content

Commit

Permalink
Base class for 3d symbol widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 22, 2020
1 parent c383735 commit 368a58b
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 100 deletions.
49 changes: 49 additions & 0 deletions python/gui/auto_generated/qgs3dsymbolwidget.sip.in
@@ -0,0 +1,49 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgs3dsymbolwidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class Qgs3DSymbolWidget : QWidget
{
%Docstring
Base class for 3D symbol configuration widgets.

.. versionadded:: 3.16
%End

%TypeHeaderCode
#include "qgs3dsymbolwidget.h"
%End
public:

Qgs3DSymbolWidget( QWidget *parent );
%Docstring
Constructor for Qgs3DSymbolWidget with the specified ``parent`` widget.
%End

virtual void setSymbol( const QgsAbstract3DSymbol *symbol, QgsVectorLayer *layer ) = 0;
%Docstring
Sets the ``symbol`` to show in the widget.
%End

virtual QgsAbstract3DSymbol *symbol() = 0 /Factory/;
%Docstring
Return a new instance of the symbol defined by the widget.

Caller takes ownership of the returned symbol.
%End
};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgs3dsymbolwidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/gui/gui_auto.sip
@@ -1,5 +1,6 @@
// Include auto-generated SIP files
%Include auto_generated/qgisinterface.sip
%Include auto_generated/qgs3dsymbolwidget.sip
%Include auto_generated/qgsabstractdatasourcewidget.sip
%Include auto_generated/qgsactionmenu.sip
%Include auto_generated/qgsadvanceddigitizingdockwidget.sip
Expand Down
45 changes: 25 additions & 20 deletions src/app/3d/qgsline3dsymbolwidget.cpp
Expand Up @@ -19,15 +19,16 @@


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

spinHeight->setClearValue( 0.0 );
spinWidth->setClearValue( 0.0 );
spinExtrusion->setClearValue( 0.0 );

setSymbol( QgsLine3DSymbol() );
QgsLine3DSymbol defaultLine;
setSymbol( &defaultLine, nullptr );

connect( spinWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLine3DSymbolWidget::changed );
Expand All @@ -39,29 +40,33 @@ QgsLine3DSymbolWidget::QgsLine3DSymbolWidget( QWidget *parent )
connect( widgetMaterial, &QgsPhongMaterialWidget::changed, this, &QgsLine3DSymbolWidget::changed );
}

void QgsLine3DSymbolWidget::setSymbol( const QgsLine3DSymbol &symbol )
void QgsLine3DSymbolWidget::setSymbol( const QgsAbstract3DSymbol *symbol, QgsVectorLayer * )
{
spinWidth->setValue( symbol.width() );
spinHeight->setValue( symbol.height() );
spinExtrusion->setValue( symbol.extrusionHeight() );
cboAltClamping->setCurrentIndex( static_cast<int>( symbol.altitudeClamping() ) );
cboAltBinding->setCurrentIndex( static_cast<int>( symbol.altitudeBinding() ) );
chkSimpleLines->setChecked( symbol.renderAsSimpleLines() );
widgetMaterial->setMaterial( symbol.material() );
const QgsLine3DSymbol *lineSymbol = dynamic_cast< const QgsLine3DSymbol *>( symbol );
if ( !lineSymbol )
return;

spinWidth->setValue( lineSymbol->width() );
spinHeight->setValue( lineSymbol->height() );
spinExtrusion->setValue( lineSymbol->extrusionHeight() );
cboAltClamping->setCurrentIndex( static_cast<int>( lineSymbol->altitudeClamping() ) );
cboAltBinding->setCurrentIndex( static_cast<int>( lineSymbol->altitudeBinding() ) );
chkSimpleLines->setChecked( lineSymbol->renderAsSimpleLines() );
widgetMaterial->setMaterial( lineSymbol->material() );
updateGuiState();
}

QgsLine3DSymbol QgsLine3DSymbolWidget::symbol() const
QgsAbstract3DSymbol *QgsLine3DSymbolWidget::symbol()
{
QgsLine3DSymbol sym;
sym.setWidth( spinWidth->value() );
sym.setHeight( spinHeight->value() );
sym.setExtrusionHeight( spinExtrusion->value() );
sym.setAltitudeClamping( static_cast<Qgs3DTypes::AltitudeClamping>( cboAltClamping->currentIndex() ) );
sym.setAltitudeBinding( static_cast<Qgs3DTypes::AltitudeBinding>( cboAltBinding->currentIndex() ) );
sym.setRenderAsSimpleLines( chkSimpleLines->isChecked() );
sym.setMaterial( widgetMaterial->material() );
return sym;
std::unique_ptr< QgsLine3DSymbol > sym = qgis::make_unique< QgsLine3DSymbol >();
sym->setWidth( spinWidth->value() );
sym->setHeight( spinHeight->value() );
sym->setExtrusionHeight( spinExtrusion->value() );
sym->setAltitudeClamping( static_cast<Qgs3DTypes::AltitudeClamping>( cboAltClamping->currentIndex() ) );
sym->setAltitudeBinding( static_cast<Qgs3DTypes::AltitudeBinding>( cboAltBinding->currentIndex() ) );
sym->setRenderAsSimpleLines( chkSimpleLines->isChecked() );
sym->setMaterial( widgetMaterial->material() );
return sym.release();
}

void QgsLine3DSymbolWidget::updateGuiState()
Expand Down
8 changes: 4 additions & 4 deletions src/app/3d/qgsline3dsymbolwidget.h
Expand Up @@ -16,21 +16,21 @@
#ifndef QGSLINE3DSYMBOLWIDGET_H
#define QGSLINE3DSYMBOLWIDGET_H

#include <QWidget>
#include "qgs3dsymbolwidget.h"

#include "ui_line3dsymbolwidget.h"

class QgsLine3DSymbol;

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

void setSymbol( const QgsLine3DSymbol &symbol );
QgsLine3DSymbol symbol() const;
void setSymbol( const QgsAbstract3DSymbol *symbol, QgsVectorLayer *layer ) override;
QgsAbstract3DSymbol *symbol() override;

private slots:
void updateGuiState();
Expand Down
45 changes: 25 additions & 20 deletions src/app/3d/qgspoint3dsymbolwidget.cpp
Expand Up @@ -26,7 +26,7 @@
#include "qgssymbollayerutils.h"

QgsPoint3DSymbolWidget::QgsPoint3DSymbolWidget( QWidget *parent )
: QWidget( parent )
: Qgs3DSymbolWidget( parent )
{
setupUi( this );

Expand All @@ -52,7 +52,8 @@ QgsPoint3DSymbolWidget::QgsPoint3DSymbolWidget( QWidget *parent )
btnChangeSymbol->setSymbolType( QgsSymbol::Marker );
btnChangeSymbol->setDialogTitle( tr( "Billboard symbol" ) );

setSymbol( QgsPoint3DSymbol( ) );
QgsPoint3DSymbol defaultSymbol;
setSymbol( &defaultSymbol, nullptr );
onShapeChanged();

connect( cboAltClamping, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPoint3DSymbolWidget::changed );
Expand Down Expand Up @@ -86,12 +87,16 @@ void QgsPoint3DSymbolWidget::onOverwriteMaterialChecked( int state )
emit changed();
}

void QgsPoint3DSymbolWidget::setSymbol( const QgsPoint3DSymbol &symbol )
void QgsPoint3DSymbolWidget::setSymbol( const QgsAbstract3DSymbol *symbol, QgsVectorLayer * )
{
cboAltClamping->setCurrentIndex( static_cast<int>( symbol.altitudeClamping() ) );
const QgsPoint3DSymbol *pointSymbol = dynamic_cast< const QgsPoint3DSymbol *>( symbol );
if ( !pointSymbol )
return;

QVariantMap vm = symbol.shapeProperties();
int index = cboShape->findData( symbol.shape() );
cboAltClamping->setCurrentIndex( static_cast<int>( pointSymbol->altitudeClamping() ) );

QVariantMap vm = pointSymbol->shapeProperties();
int index = cboShape->findData( pointSymbol->shape() );
cboShape->setCurrentIndex( index != -1 ? index : 1 ); // use cylinder by default if shape is not set
widgetMaterial->setEnabled( true );
switch ( cboShape->currentIndex() )
Expand Down Expand Up @@ -127,19 +132,19 @@ void QgsPoint3DSymbolWidget::setSymbol( const QgsPoint3DSymbol &symbol )
break;
}
case 7: // billboard
if ( symbol.billboardSymbol() )
if ( pointSymbol->billboardSymbol() )
{
btnChangeSymbol->setSymbol( symbol.billboardSymbol()->clone() );
btnChangeSymbol->setSymbol( pointSymbol->billboardSymbol()->clone() );
}
break;
}

widgetMaterial->setMaterial( symbol.material() );
widgetMaterial->setMaterial( pointSymbol->material() );

// decompose the transform matrix
// assuming the last row has values [0 0 0 1]
// see https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati
QMatrix4x4 m = symbol.transform();
QMatrix4x4 m = pointSymbol->transform();
float *md = m.data(); // returns data in column-major order
float sx = QVector3D( md[0], md[1], md[2] ).length();
float sy = QVector3D( md[4], md[5], md[6] ).length();
Expand All @@ -165,11 +170,11 @@ void QgsPoint3DSymbolWidget::setSymbol( const QgsPoint3DSymbol &symbol )
spinRZ->setValue( QgsLayoutUtils::normalizedAngle( rot.z() ) );
}

QgsPoint3DSymbol QgsPoint3DSymbolWidget::symbol() const
QgsAbstract3DSymbol *QgsPoint3DSymbolWidget::symbol()
{
QVariantMap vm;
QgsPoint3DSymbol sym;
sym.setBillboardSymbol( static_cast<QgsMarkerSymbol *>( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) ) );
std::unique_ptr< QgsPoint3DSymbol > sym = qgis::make_unique< QgsPoint3DSymbol >();
sym->setBillboardSymbol( static_cast<QgsMarkerSymbol *>( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) ) );
switch ( cboShape->currentIndex() )
{
case 0: // sphere
Expand Down Expand Up @@ -199,7 +204,7 @@ QgsPoint3DSymbol QgsPoint3DSymbolWidget::symbol() const
vm[QStringLiteral( "overwriteMaterial" )] = cbOverwriteMaterial->isChecked();
break;
case 7: // billboard
sym.setBillboardSymbol( btnChangeSymbol->clonedSymbol<QgsMarkerSymbol>() );
sym->setBillboardSymbol( btnChangeSymbol->clonedSymbol<QgsMarkerSymbol>() );
break;
}

Expand All @@ -212,12 +217,12 @@ QgsPoint3DSymbol QgsPoint3DSymbolWidget::symbol() const
tr.scale( sca );
tr.rotate( rot );

sym.setAltitudeClamping( static_cast<Qgs3DTypes::AltitudeClamping>( cboAltClamping->currentIndex() ) );
sym.setShape( static_cast<QgsPoint3DSymbol::Shape>( cboShape->itemData( cboShape->currentIndex() ).toInt() ) );
sym.setShapeProperties( vm );
sym.setMaterial( widgetMaterial->material() );
sym.setTransform( tr );
return sym;
sym->setAltitudeClamping( static_cast<Qgs3DTypes::AltitudeClamping>( cboAltClamping->currentIndex() ) );
sym->setShape( static_cast<QgsPoint3DSymbol::Shape>( cboShape->itemData( cboShape->currentIndex() ).toInt() ) );
sym->setShapeProperties( vm );
sym->setMaterial( widgetMaterial->material() );
sym->setTransform( tr );
return sym.release();
}

void QgsPoint3DSymbolWidget::onShapeChanged()
Expand Down
10 changes: 5 additions & 5 deletions src/app/3d/qgspoint3dsymbolwidget.h
Expand Up @@ -16,21 +16,21 @@
#ifndef QGSPOINT3DSYMBOLWIDGET_H
#define QGSPOINT3DSYMBOLWIDGET_H

#include <QWidget>

#include "qgs3dsymbolwidget.h"
#include "ui_point3dsymbolwidget.h"

class QgsPoint3DSymbol;


//! A widget for configuration of 3D symbol for points
class QgsPoint3DSymbolWidget : public QWidget, private Ui::Point3DSymbolWidget
class QgsPoint3DSymbolWidget : public Qgs3DSymbolWidget, private Ui::Point3DSymbolWidget
{
Q_OBJECT
public:
explicit QgsPoint3DSymbolWidget( QWidget *parent = nullptr );

void setSymbol( const QgsPoint3DSymbol &symbol );
QgsPoint3DSymbol symbol() const;
void setSymbol( const QgsAbstract3DSymbol *symbol, QgsVectorLayer *layer ) override;
QgsAbstract3DSymbol *symbol() override;

signals:
void changed();
Expand Down
77 changes: 41 additions & 36 deletions src/app/3d/qgspolygon3dsymbolwidget.cpp
Expand Up @@ -19,13 +19,14 @@


QgsPolygon3DSymbolWidget::QgsPolygon3DSymbolWidget( QWidget *parent )
: QWidget( parent )
: Qgs3DSymbolWidget( parent )
{
setupUi( this );
spinHeight->setClearValue( 0.0 );
spinExtrusion->setClearValue( 0.0 );

setSymbol( QgsPolygon3DSymbol(), nullptr );
QgsPolygon3DSymbol defaultSymbol;
setSymbol( &defaultSymbol, nullptr );

connect( spinHeight, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPolygon3DSymbolWidget::changed );
connect( spinExtrusion, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPolygon3DSymbolWidget::changed );
Expand All @@ -45,48 +46,52 @@ QgsPolygon3DSymbolWidget::QgsPolygon3DSymbolWidget( QWidget *parent )
widgetMaterial->activateTexturingUI( true );
}

void QgsPolygon3DSymbolWidget::setSymbol( const QgsPolygon3DSymbol &symbol, QgsVectorLayer *layer )
void QgsPolygon3DSymbolWidget::setSymbol( const QgsAbstract3DSymbol *symbol, QgsVectorLayer *layer )
{
spinHeight->setValue( symbol.height() );
spinExtrusion->setValue( symbol.extrusionHeight() );
cboAltClamping->setCurrentIndex( static_cast<int>( symbol.altitudeClamping() ) );
cboAltBinding->setCurrentIndex( static_cast<int>( symbol.altitudeBinding() ) );
cboCullingMode->setCurrentIndex( static_cast<int>( symbol.cullingMode() ) );
cboRenderedFacade->setCurrentIndex( symbol.renderedFacade() );

chkAddBackFaces->setChecked( symbol.addBackFaces() );
chkInvertNormals->setChecked( symbol.invertNormals() );
widgetMaterial->setMaterial( symbol.material() );

btnHeightDD->init( QgsAbstract3DSymbol::PropertyHeight, symbol.dataDefinedProperties(), QgsAbstract3DSymbol::propertyDefinitions(), layer, true );
btnExtrusionDD->init( QgsAbstract3DSymbol::PropertyExtrusionHeight, symbol.dataDefinedProperties(), QgsAbstract3DSymbol::propertyDefinitions(), layer, true );

groupEdges->setChecked( symbol.edgesEnabled() );
spinEdgeWidth->setValue( symbol.edgeWidth() );
btnEdgeColor->setColor( symbol.edgeColor() );
const QgsPolygon3DSymbol *polygonSymbol = dynamic_cast< const QgsPolygon3DSymbol * >( symbol );
if ( !polygonSymbol )
return;

spinHeight->setValue( polygonSymbol->height() );
spinExtrusion->setValue( polygonSymbol->extrusionHeight() );
cboAltClamping->setCurrentIndex( static_cast<int>( polygonSymbol->altitudeClamping() ) );
cboAltBinding->setCurrentIndex( static_cast<int>( polygonSymbol->altitudeBinding() ) );
cboCullingMode->setCurrentIndex( static_cast<int>( polygonSymbol->cullingMode() ) );
cboRenderedFacade->setCurrentIndex( polygonSymbol->renderedFacade() );

chkAddBackFaces->setChecked( polygonSymbol->addBackFaces() );
chkInvertNormals->setChecked( polygonSymbol->invertNormals() );
widgetMaterial->setMaterial( polygonSymbol->material() );

btnHeightDD->init( QgsAbstract3DSymbol::PropertyHeight, polygonSymbol->dataDefinedProperties(), QgsAbstract3DSymbol::propertyDefinitions(), layer, true );
btnExtrusionDD->init( QgsAbstract3DSymbol::PropertyExtrusionHeight, polygonSymbol->dataDefinedProperties(), QgsAbstract3DSymbol::propertyDefinitions(), layer, true );

groupEdges->setChecked( polygonSymbol->edgesEnabled() );
spinEdgeWidth->setValue( polygonSymbol->edgeWidth() );
btnEdgeColor->setColor( polygonSymbol->edgeColor() );
}

QgsPolygon3DSymbol QgsPolygon3DSymbolWidget::symbol() const
QgsAbstract3DSymbol *QgsPolygon3DSymbolWidget::symbol()
{
QgsPolygon3DSymbol sym;
sym.setHeight( spinHeight->value() );
sym.setExtrusionHeight( spinExtrusion->value() );
sym.setAltitudeClamping( static_cast<Qgs3DTypes::AltitudeClamping>( cboAltClamping->currentIndex() ) );
sym.setAltitudeBinding( static_cast<Qgs3DTypes::AltitudeBinding>( cboAltBinding->currentIndex() ) );
sym.setCullingMode( static_cast<Qgs3DTypes::CullingMode>( cboCullingMode->currentIndex() ) );
sym.setRenderedFacade( cboRenderedFacade->currentIndex() );
sym.setAddBackFaces( chkAddBackFaces->isChecked() );
sym.setInvertNormals( chkInvertNormals->isChecked() );
sym.setMaterial( widgetMaterial->material() );
std::unique_ptr< QgsPolygon3DSymbol > sym = qgis::make_unique< QgsPolygon3DSymbol >();
sym->setHeight( spinHeight->value() );
sym->setExtrusionHeight( spinExtrusion->value() );
sym->setAltitudeClamping( static_cast<Qgs3DTypes::AltitudeClamping>( cboAltClamping->currentIndex() ) );
sym->setAltitudeBinding( static_cast<Qgs3DTypes::AltitudeBinding>( cboAltBinding->currentIndex() ) );
sym->setCullingMode( static_cast<Qgs3DTypes::CullingMode>( cboCullingMode->currentIndex() ) );
sym->setRenderedFacade( cboRenderedFacade->currentIndex() );
sym->setAddBackFaces( chkAddBackFaces->isChecked() );
sym->setInvertNormals( chkInvertNormals->isChecked() );
sym->setMaterial( widgetMaterial->material() );

QgsPropertyCollection ddp;
ddp.setProperty( QgsAbstract3DSymbol::PropertyHeight, btnHeightDD->toProperty() );
ddp.setProperty( QgsAbstract3DSymbol::PropertyExtrusionHeight, btnExtrusionDD->toProperty() );
sym.setDataDefinedProperties( ddp );
sym->setDataDefinedProperties( ddp );

sym.setEdgesEnabled( groupEdges->isChecked() );
sym.setEdgeWidth( spinEdgeWidth->value() );
sym.setEdgeColor( btnEdgeColor->color() );
sym->setEdgesEnabled( groupEdges->isChecked() );
sym->setEdgeWidth( spinEdgeWidth->value() );
sym->setEdgeColor( btnEdgeColor->color() );

return sym;
return sym.release();
}

0 comments on commit 368a58b

Please sign in to comment.