Skip to content

Commit

Permalink
Add tiling configuration to vector layer 3d renderer + widget
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Jan 10, 2020
1 parent 89829c5 commit 8d1ccb1
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 11 deletions.
26 changes: 26 additions & 0 deletions src/3d/qgsabstractvectorlayer3drenderer.cpp
Expand Up @@ -18,6 +18,29 @@
#include "qgsvectorlayer.h"



void QgsVectorLayer3DTilingSettings::writeXml( QDomElement &elem ) const
{
QDomDocument doc = elem.ownerDocument();

QDomElement elemTiling = doc.createElement( QStringLiteral( "vector-layer-3d-tiling" ) );
elemTiling.setAttribute( QStringLiteral( "zoom-levels-count" ), mZoomLevelsCount );
elem.appendChild( elemTiling );
}

void QgsVectorLayer3DTilingSettings::readXml( const QDomElement &elem )
{
QDomElement elemTiling = elem.firstChildElement( QStringLiteral( "vector-layer-3d-tiling" ) );
if ( !elemTiling.isNull() )
{
mZoomLevelsCount = elemTiling.attribute( QStringLiteral( "zoom-levels-count" ) ).toInt();
}
}


//////////////////


QgsAbstractVectorLayer3DRenderer::QgsAbstractVectorLayer3DRenderer()
{
}
Expand All @@ -35,18 +58,21 @@ QgsVectorLayer *QgsAbstractVectorLayer3DRenderer::layer() const
void QgsAbstractVectorLayer3DRenderer::copyBaseProperties( QgsAbstractVectorLayer3DRenderer *r ) const
{
r->mLayerRef = mLayerRef;
r->mTilingSettings = mTilingSettings;
}

void QgsAbstractVectorLayer3DRenderer::writeXmlBaseProperties( QDomElement &elem, const QgsReadWriteContext &context ) const
{
Q_UNUSED( context )
elem.setAttribute( QStringLiteral( "layer" ), mLayerRef.layerId );
mTilingSettings.writeXml( elem );
}

void QgsAbstractVectorLayer3DRenderer::readXmlBaseProperties( const QDomElement &elem, const QgsReadWriteContext &context )
{
Q_UNUSED( context )
mLayerRef = QgsMapLayerRef( elem.attribute( QStringLiteral( "layer" ) ) );
mTilingSettings.readXml( elem );
}

void QgsAbstractVectorLayer3DRenderer::resolveReferences( const QgsProject &project )
Expand Down
27 changes: 27 additions & 0 deletions src/3d/qgsabstractvectorlayer3drenderer.h
Expand Up @@ -23,6 +23,29 @@

class QgsVectorLayer;

/**
* \ingroup 3d
* This class defines configuration of how a vector layer gets tiled for 3D rendering.
*
* Zoom levels count tells how deep will be the quadtree and thus how many tiles will
* be generated ( 4 ^ (count-1) ). So for example, for count=1 there will be just
* a single tile for the whole layer, for count=3 there will be 16 tiles.
*
* \since QGIS 3.12
*/
class _3D_EXPORT QgsVectorLayer3DTilingSettings
{
public:
int zoomLevelsCount() const { return mZoomLevelsCount; }
void setZoomLevelsCount( int count ) { mZoomLevelsCount = count; }

void writeXml( QDomElement &elem ) const;
void readXml( const QDomElement &elem );

private:
int mZoomLevelsCount = 3;
};


/**
* \ingroup 3d
Expand All @@ -40,6 +63,9 @@ class _3D_EXPORT QgsAbstractVectorLayer3DRenderer : public QgsAbstract3DRenderer
//! Returns vector layer associated with the renderer
QgsVectorLayer *layer() const;

void setTilingSettings( const QgsVectorLayer3DTilingSettings &settings ) { mTilingSettings = settings; }
QgsVectorLayer3DTilingSettings tilingSettings() const { return mTilingSettings; }

void resolveReferences( const QgsProject &project ) override;

protected:
Expand All @@ -52,6 +78,7 @@ class _3D_EXPORT QgsAbstractVectorLayer3DRenderer : public QgsAbstract3DRenderer

private:
QgsMapLayerRef mLayerRef; //!< Layer used to extract polygons from
QgsVectorLayer3DTilingSettings mTilingSettings; //!< How is layer tiled into chunks
};

#endif // QGSABSTRACTVECTORLAYER3DRENDERER_H
2 changes: 1 addition & 1 deletion src/3d/qgsrulebased3drenderer.cpp
Expand Up @@ -406,7 +406,7 @@ Qt3DCore::QEntity *QgsRuleBased3DRenderer::createEntity( const Qgs3DMapSettings
if ( !vl )
return nullptr;

return new QgsRuleBasedChunkedEntity( vl, mRootRule, map );
return new QgsRuleBasedChunkedEntity( vl, tilingSettings(), mRootRule, map );
}

void QgsRuleBased3DRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
Expand Down
6 changes: 3 additions & 3 deletions src/3d/qgsrulebasedchunkloader_p.cpp
Expand Up @@ -147,12 +147,12 @@ QgsChunkLoader *QgsRuleBasedChunkLoaderFactory::createChunkLoader( QgsChunkNode

///////////////

QgsRuleBasedChunkedEntity::QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map )
QgsRuleBasedChunkedEntity::QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map )
: QgsChunkedEntity( Qgs3DUtils::layerToWorldExtent( vl->extent(), vl->crs(), map.origin(), map.crs(), map.transformContext() ),
-1, // rootError TODO: negative error should mean that the node does not contain anything
-1, // tau = max. allowed screen error. TODO: negative tau should mean that we need to go until leaves are reached
2, // TODO: figure out from the number of features
new QgsRuleBasedChunkLoaderFactory( map, vl, rootRule, 2 ) )
tilingSettings.zoomLevelsCount() - 1,
new QgsRuleBasedChunkLoaderFactory( map, vl, rootRule, tilingSettings.zoomLevelsCount() - 1 ) )
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/3d/qgsrulebasedchunkloader_p.h
Expand Up @@ -109,7 +109,7 @@ class QgsRuleBasedChunkedEntity : public QgsChunkedEntity
Q_OBJECT
public:
//! Constructs the entity. The argument maxLevel determines how deep the tree of tiles will be
explicit QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map );
explicit QgsRuleBasedChunkedEntity( QgsVectorLayer *vl, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsRuleBased3DRenderer::Rule *rootRule, const Qgs3DMapSettings &map );

~QgsRuleBasedChunkedEntity();
};
Expand Down
2 changes: 1 addition & 1 deletion src/3d/qgsvectorlayer3drenderer.cpp
Expand Up @@ -70,7 +70,7 @@ Qt3DCore::QEntity *QgsVectorLayer3DRenderer::createEntity( const Qgs3DMapSetting
if ( !mSymbol || !vl )
return nullptr;

return new QgsVectorLayerChunkedEntity( vl, mSymbol.get(), map );
return new QgsVectorLayerChunkedEntity( vl, tilingSettings(), mSymbol.get(), map );
}

void QgsVectorLayer3DRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
Expand Down
7 changes: 4 additions & 3 deletions src/3d/qgsvectorlayerchunkloader_p.cpp
Expand Up @@ -16,6 +16,7 @@
#include "qgsvectorlayerchunkloader_p.h"

#include "qgs3dutils.h"
#include "qgsabstractvectorlayer3drenderer.h"
#include "qgschunknode_p.h"
#include "qgspolygon3dsymbol_p.h"
#include "qgseventtracing.h"
Expand Down Expand Up @@ -150,12 +151,12 @@ QgsChunkLoader *QgsVectorLayerChunkLoaderFactory::createChunkLoader( QgsChunkNod
///////////////


QgsVectorLayerChunkedEntity::QgsVectorLayerChunkedEntity( QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, const Qgs3DMapSettings &map )
QgsVectorLayerChunkedEntity::QgsVectorLayerChunkedEntity( QgsVectorLayer *vl, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsAbstract3DSymbol *symbol, const Qgs3DMapSettings &map )
: QgsChunkedEntity( Qgs3DUtils::layerToWorldExtent( vl->extent(), vl->crs(), map.origin(), map.crs(), map.transformContext() ),
-1, // rootError TODO: negative error should mean that the node does not contain anything
-1, // tau = max. allowed screen error. TODO: negative tau should mean that we need to go until leaves are reached
2, // TODO: figure out from the number of features
new QgsVectorLayerChunkLoaderFactory( map, vl, symbol, 2 ) )
tilingSettings.zoomLevelsCount() - 1,
new QgsVectorLayerChunkLoaderFactory( map, vl, symbol, tilingSettings.zoomLevelsCount() - 1 ) )
{
}

Expand Down
3 changes: 2 additions & 1 deletion src/3d/qgsvectorlayerchunkloader_p.h
Expand Up @@ -33,6 +33,7 @@

class Qgs3DMapSettings;
class QgsVectorLayer;
class QgsVectorLayer3DTilingSettings;
class QgsVectorLayerFeatureSource;
class QgsAbstract3DSymbol;
class QgsFeature3DHandler;
Expand Down Expand Up @@ -106,7 +107,7 @@ class QgsVectorLayerChunkedEntity : public QgsChunkedEntity
Q_OBJECT
public:
//! Constructs the entity. The argument maxLevel determines how deep the tree of tiles will be
explicit QgsVectorLayerChunkedEntity( QgsVectorLayer *vl, QgsAbstract3DSymbol *symbol, const Qgs3DMapSettings &map );
explicit QgsVectorLayerChunkedEntity( QgsVectorLayer *vl, const QgsVectorLayer3DTilingSettings &tilingSettings, QgsAbstract3DSymbol *symbol, const Qgs3DMapSettings &map );

~QgsVectorLayerChunkedEntity();
};
Expand Down
38 changes: 38 additions & 0 deletions src/app/3d/qgsvectorlayer3dpropertieswidget.cpp
@@ -0,0 +1,38 @@
/***************************************************************************
qgsvectorlayer3dpropertieswidget.cpp
--------------------------------------
Date : January 2020
Copyright : (C) 2020 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsvectorlayer3dpropertieswidget.h"

#include "qgsabstractvectorlayer3drenderer.h"

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

connect( spinZoomLevelsCount, qgis::overload<int>::of( &QSpinBox::valueChanged ), this, &QgsVectorLayer3DPropertiesWidget::changed );
}

void QgsVectorLayer3DPropertiesWidget::load( QgsAbstractVectorLayer3DRenderer *renderer )
{
whileBlocking( spinZoomLevelsCount )->setValue( renderer->tilingSettings().zoomLevelsCount() );
}

void QgsVectorLayer3DPropertiesWidget::apply( QgsAbstractVectorLayer3DRenderer *renderer )
{
QgsVectorLayer3DTilingSettings tilingSettings;
tilingSettings.setZoomLevelsCount( spinZoomLevelsCount->value() );
renderer->setTilingSettings( tilingSettings );
}
42 changes: 42 additions & 0 deletions src/app/3d/qgsvectorlayer3dpropertieswidget.h
@@ -0,0 +1,42 @@
/***************************************************************************
qgsvectorlayer3dpropertieswidget.h
--------------------------------------
Date : January 2020
Copyright : (C) 2020 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSVECTORLAYER3DPROPERTIESWIDGET_H
#define QGSVECTORLAYER3DPROPERTIESWIDGET_H

#include <QWidget>

#include "ui_qgsvectorlayer3dpropertieswidget.h"

class QgsAbstractVectorLayer3DRenderer;


class QgsVectorLayer3DPropertiesWidget : public QWidget, private Ui::QgsVectorLayer3DPropertiesWidget
{
Q_OBJECT
public:
QgsVectorLayer3DPropertiesWidget( QWidget *parent = nullptr );

//! Initializes GUI from the given renderer
void load( QgsAbstractVectorLayer3DRenderer *renderer );
//! Applies configuration from GUI to the given renderer
void apply( QgsAbstractVectorLayer3DRenderer *renderer );

signals:
//! Emitted whenever any paramater gets changed
void changed();
};

#endif // QGSVECTORLAYER3DPROPERTIESWIDGET_H
13 changes: 12 additions & 1 deletion src/app/3d/qgsvectorlayer3drendererwidget.cpp
Expand Up @@ -20,6 +20,7 @@
#include "qgsrulebased3drendererwidget.h"
#include "qgssymbol3dwidget.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayer3dpropertieswidget.h"
#include "qgsvectorlayer3drenderer.h"
#include "qgsapplication.h"

Expand Down Expand Up @@ -78,9 +79,12 @@ QgsVectorLayer3DRendererWidget::QgsVectorLayer3DRendererWidget( QgsVectorLayer *
cboRendererType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "rendererSingleSymbol.svg" ) ), tr( "Single symbol" ) );
cboRendererType->addItem( QgsApplication::getThemeIcon( QStringLiteral( "rendererRuleBasedSymbol.svg" ) ), tr( "Rule-based" ) );

widgetBaseProperties = new QgsVectorLayer3DPropertiesWidget( this );

widgetRendererStack = new QStackedWidget( this );
layout->addWidget( cboRendererType );
layout->addWidget( widgetRendererStack );
layout->addWidget( widgetBaseProperties );

widgetNoRenderer = new QLabel;
widgetSingleSymbolRenderer = new QgsSingleSymbol3DRendererWidget( this );
Expand All @@ -93,8 +97,8 @@ QgsVectorLayer3DRendererWidget::QgsVectorLayer3DRendererWidget( QgsVectorLayer *
connect( cboRendererType, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, &QgsVectorLayer3DRendererWidget::onRendererTypeChanged );
connect( widgetSingleSymbolRenderer, &QgsSingleSymbol3DRendererWidget::widgetChanged, this, &QgsVectorLayer3DRendererWidget::widgetChanged );
connect( widgetRuleBasedRenderer, &QgsRuleBased3DRendererWidget::widgetChanged, this, &QgsVectorLayer3DRendererWidget::widgetChanged );

connect( widgetRuleBasedRenderer, &QgsRuleBased3DRendererWidget::showPanel, this, &QgsPanelWidget::openPanel );
connect( widgetBaseProperties, &QgsVectorLayer3DPropertiesWidget::changed, this, &QgsVectorLayer3DRendererWidget::widgetChanged );
}


Expand All @@ -120,6 +124,11 @@ void QgsVectorLayer3DRendererWidget::setLayer( QgsVectorLayer *layer )
}
widgetRendererStack->setCurrentIndex( pageIndex );
whileBlocking( cboRendererType )->setCurrentIndex( pageIndex );

if ( r && ( r->type() == QLatin1String( "vector" ) || r->type() == QLatin1String( "rulebased" ) ) )
{
widgetBaseProperties->load( static_cast<QgsAbstractVectorLayer3DRenderer *>( r ) );
}
}

void QgsVectorLayer3DRendererWidget::setDockMode( bool dockMode )
Expand All @@ -141,13 +150,15 @@ void QgsVectorLayer3DRendererWidget::apply()
{
QgsVectorLayer3DRenderer *r = new QgsVectorLayer3DRenderer( widgetSingleSymbolRenderer->symbol() );
r->setLayer( qobject_cast<QgsVectorLayer *>( mLayer ) );
widgetBaseProperties->apply( r );
mLayer->setRenderer3D( r );
}
break;
case 2:
{
QgsRuleBased3DRenderer *r = new QgsRuleBased3DRenderer( widgetRuleBasedRenderer->rootRule()->clone() );
r->setLayer( qobject_cast<QgsVectorLayer *>( mLayer ) );
widgetBaseProperties->apply( r );
mLayer->setRenderer3D( r );
}
break;
Expand Down
2 changes: 2 additions & 0 deletions src/app/3d/qgsvectorlayer3drendererwidget.h
Expand Up @@ -31,6 +31,7 @@ class QgsMapCanvas;

class QgsRuleBased3DRendererWidget;
class QgsSymbol3DWidget;
class QgsVectorLayer3DPropertiesWidget;


class QgsSingleSymbol3DRendererWidget : public QWidget
Expand Down Expand Up @@ -78,6 +79,7 @@ class QgsVectorLayer3DRendererWidget : public QgsMapLayerConfigWidget
private:
QComboBox *cboRendererType = nullptr;
QStackedWidget *widgetRendererStack = nullptr;
QgsVectorLayer3DPropertiesWidget *widgetBaseProperties = nullptr;

QLabel *widgetNoRenderer = nullptr;
QgsSingleSymbol3DRendererWidget *widgetSingleSymbolRenderer = nullptr;
Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -283,6 +283,7 @@ IF (WITH_3D)
3d/qgsphongmaterialwidget.cpp
3d/qgsrulebased3drendererwidget.cpp
3d/qgssymbol3dwidget.cpp
3d/qgsvectorlayer3dpropertieswidget.cpp
3d/qgsvectorlayer3drendererwidget.cpp
3d/qgsmeshlayer3drendererwidget.cpp
layout/qgslayout3dmapwidget.cpp
Expand Down
45 changes: 45 additions & 0 deletions src/ui/3d/qgsvectorlayer3dpropertieswidget.ui
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsVectorLayer3DPropertiesWidget</class>
<widget class="QWidget" name="QgsVectorLayer3DPropertiesWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>539</width>
<height>90</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Zoom levels count</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinZoomLevelsCount">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

0 comments on commit 8d1ccb1

Please sign in to comment.