mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-08 00:05:09 -04:00
Initial implementation of point-cloud 3D GUI
This commit is contained in:
parent
928997d557
commit
c220bb47a3
@ -43,6 +43,15 @@ Returns point cloud layer associated with the renderer
|
||||
virtual QgsPointCloudLayer3DRenderer *clone() const /Factory/;
|
||||
|
||||
|
||||
void setSymbol( QgsPointCloud3DSymbol *symbol );
|
||||
%Docstring
|
||||
Sets 3D symbol associated with the renderer
|
||||
%End
|
||||
const QgsPointCloud3DSymbol *symbol() const;
|
||||
%Docstring
|
||||
Returns 3D symbol associated with the renderer
|
||||
%End
|
||||
|
||||
virtual void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const;
|
||||
|
||||
virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
|
||||
|
@ -69,6 +69,7 @@ SET(QGIS_3D_SRCS
|
||||
symbols/qgspoint3dsymbol_p.cpp
|
||||
symbols/qgspolygon3dsymbol.cpp
|
||||
symbols/qgspolygon3dsymbol_p.cpp
|
||||
symbols/qgspointcloud3dsymbol.cpp
|
||||
|
||||
terrain/qgsdemterraingenerator.cpp
|
||||
terrain/qgsdemterraintilegeometry_p.cpp
|
||||
@ -135,6 +136,7 @@ SET(QGIS_3D_HDRS
|
||||
symbols/qgspoint3dbillboardmaterial.h
|
||||
symbols/qgspoint3dsymbol.h
|
||||
symbols/qgspolygon3dsymbol.h
|
||||
symbols/qgspointcloud3dsymbol.h
|
||||
|
||||
terrain/qgsdemterraingenerator.h
|
||||
terrain/qgsflatterraingenerator.h
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "qgsline3dsymbol.h"
|
||||
#include "qgspoint3dsymbol.h"
|
||||
#include "qgspolygon3dsymbol.h"
|
||||
//#include "qgspointcloud3dsymbol.h"
|
||||
|
||||
#include <Qt3DExtras/QPhongMaterial>
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "qgsxmlutils.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgs3dsymbolregistry.h"
|
||||
#include "qgspointcloud3dsymbol.h"
|
||||
|
||||
|
||||
QgsPointCloudLayer3DRendererMetadata::QgsPointCloudLayer3DRendererMetadata()
|
||||
@ -64,6 +65,11 @@ QString QgsPointCloudLayer3DRenderer::type() const
|
||||
QgsPointCloudLayer3DRenderer *QgsPointCloudLayer3DRenderer::clone() const
|
||||
{
|
||||
QgsPointCloudLayer3DRenderer *r = new QgsPointCloudLayer3DRenderer;
|
||||
if ( mSymbol )
|
||||
{
|
||||
QgsAbstract3DSymbol *symbolClone = mSymbol->clone();
|
||||
r->setSymbol( dynamic_cast<QgsPointCloud3DSymbol *>( symbolClone ) );
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -73,7 +79,12 @@ Qt3DCore::QEntity *QgsPointCloudLayer3DRenderer::createEntity( const Qgs3DMapSet
|
||||
if ( !pcl || !pcl->dataProvider() || !pcl->dataProvider()->index() )
|
||||
return nullptr;
|
||||
|
||||
return new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), map );
|
||||
return new QgsPointCloudLayerChunkedEntity( pcl->dataProvider()->index(), map, mSymbol );
|
||||
}
|
||||
|
||||
void QgsPointCloudLayer3DRenderer::setSymbol( QgsPointCloud3DSymbol *symbol )
|
||||
{
|
||||
mSymbol = dynamic_cast<QgsPointCloud3DSymbol *>( symbol->clone() );
|
||||
}
|
||||
|
||||
void QgsPointCloudLayer3DRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
|
||||
@ -83,13 +94,23 @@ void QgsPointCloudLayer3DRenderer::writeXml( QDomElement &elem, const QgsReadWri
|
||||
QDomDocument doc = elem.ownerDocument();
|
||||
|
||||
elem.setAttribute( QStringLiteral( "layer" ), mLayerRef.layerId );
|
||||
|
||||
QDomElement elemSymbol = doc.createElement( QStringLiteral( "symbol" ) );
|
||||
if ( mSymbol )
|
||||
{
|
||||
elemSymbol.setAttribute( QStringLiteral( "type" ), mSymbol->type() );
|
||||
mSymbol->writeXml( elemSymbol, context );
|
||||
}
|
||||
elem.appendChild( elemSymbol );
|
||||
}
|
||||
|
||||
void QgsPointCloudLayer3DRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
|
||||
{
|
||||
Q_UNUSED( context )
|
||||
|
||||
mLayerRef = QgsMapLayerRef( elem.attribute( QStringLiteral( "layer" ) ) );
|
||||
|
||||
QDomElement elemSymbol = elem.firstChildElement( QStringLiteral( "symbol" ) );
|
||||
if ( !mSymbol ) mSymbol = new QgsPointCloud3DSymbol;
|
||||
mSymbol->readXml( elemSymbol, context );
|
||||
}
|
||||
|
||||
void QgsPointCloudLayer3DRenderer::resolveReferences( const QgsProject &project )
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <QObject>
|
||||
|
||||
class QgsPointCloudLayer;
|
||||
class QgsPointCloud3DSymbol;
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
@ -69,12 +70,18 @@ class _3D_EXPORT QgsPointCloudLayer3DRenderer : public QgsAbstract3DRenderer
|
||||
QgsPointCloudLayer3DRenderer *clone() const override SIP_FACTORY;
|
||||
Qt3DCore::QEntity *createEntity( const Qgs3DMapSettings &map ) const override SIP_SKIP;
|
||||
|
||||
//! Sets 3D symbol associated with the renderer
|
||||
void setSymbol( QgsPointCloud3DSymbol *symbol );
|
||||
//! Returns 3D symbol associated with the renderer
|
||||
const QgsPointCloud3DSymbol *symbol() const { return mSymbol; }
|
||||
|
||||
void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
|
||||
void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
|
||||
void resolveReferences( const QgsProject &project ) override;
|
||||
|
||||
private:
|
||||
QgsMapLayerRef mLayerRef; //!< Layer used to extract mesh data from
|
||||
QgsPointCloud3DSymbol *mSymbol = nullptr;
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "qgspoint3dsymbol.h"
|
||||
#include "qgsphongmaterialsettings.h"
|
||||
|
||||
#include "qgspointcloud3dsymbol.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgs3dsymbolregistry.h"
|
||||
#include "qgspointcloudattribute.h"
|
||||
@ -93,7 +95,8 @@ void QgsPointCloud3DGeometry::makeVertexBuffer( const QgsPointCloud3DSymbolHandl
|
||||
}
|
||||
|
||||
|
||||
QgsPointCloud3DSymbolHandler::QgsPointCloud3DSymbolHandler()
|
||||
QgsPointCloud3DSymbolHandler::QgsPointCloud3DSymbolHandler( QgsPointCloud3DSymbol *symbol )
|
||||
: mSymbol( symbol )
|
||||
{
|
||||
|
||||
}
|
||||
@ -167,6 +170,9 @@ void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const
|
||||
// Material
|
||||
Qt3DRender::QMaterial *mat = new Qt3DRender::QMaterial;
|
||||
|
||||
Qt3DRender::QParameter *pointSizeParameter = new Qt3DRender::QParameter( "u_pointSize", QVariant::fromValue( mSymbol->pointSize() ) );
|
||||
mat->addParameter( pointSizeParameter );
|
||||
|
||||
Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram( mat );
|
||||
shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/pointcloud.vert" ) ) ) );
|
||||
shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/pointcloud.frag" ) ) ) );
|
||||
@ -176,6 +182,7 @@ void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const
|
||||
|
||||
Qt3DRender::QPointSize *pointSize = new Qt3DRender::QPointSize( renderPass );
|
||||
pointSize->setSizeMode( Qt3DRender::QPointSize::Programmable ); // supported since OpenGL 3.2
|
||||
pointSize->setValue( mSymbol->pointSize() );
|
||||
renderPass->addRenderState( pointSize );
|
||||
|
||||
// without this filter the default forward renderer would not render this
|
||||
@ -206,7 +213,7 @@ void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const
|
||||
}
|
||||
|
||||
|
||||
QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointCloudLayerChunkLoaderFactory *factory, QgsChunkNode *node )
|
||||
QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointCloudLayerChunkLoaderFactory *factory, QgsChunkNode *node, QgsPointCloud3DSymbol *symbol )
|
||||
: QgsChunkLoader( node )
|
||||
, mFactory( factory )
|
||||
, mContext( factory->mMap )
|
||||
@ -219,7 +226,7 @@ QgsPointCloudLayerChunkLoader::QgsPointCloudLayerChunkLoader( const QgsPointClou
|
||||
|
||||
QgsDebugMsgLevel( QStringLiteral( "loading entity %1" ).arg( node->tileId().text() ), 2 );
|
||||
|
||||
QgsPointCloud3DSymbolHandler *handler = new QgsPointCloud3DSymbolHandler;
|
||||
QgsPointCloud3DSymbolHandler *handler = new QgsPointCloud3DSymbolHandler( symbol );
|
||||
mHandler.reset( handler );
|
||||
|
||||
//
|
||||
@ -274,9 +281,10 @@ Qt3DCore::QEntity *QgsPointCloudLayerChunkLoader::createEntity( Qt3DCore::QEntit
|
||||
///////////////
|
||||
|
||||
|
||||
QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, QgsPointCloudIndex *pc )
|
||||
QgsPointCloudLayerChunkLoaderFactory::QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol )
|
||||
: mMap( map )
|
||||
, mPointCloudIndex( pc )
|
||||
, mSymbol( symbol )
|
||||
{
|
||||
}
|
||||
|
||||
@ -284,7 +292,7 @@ QgsChunkLoader *QgsPointCloudLayerChunkLoaderFactory::createChunkLoader( QgsChun
|
||||
{
|
||||
QgsChunkNodeId id = node->tileId();
|
||||
Q_ASSERT( mPointCloudIndex->hasNode( IndexedPointCloudNode( id.d, id.x, id.y, id.z ) ) );
|
||||
return new QgsPointCloudLayerChunkLoader( this, node );
|
||||
return new QgsPointCloudLayerChunkLoader( this, node, mSymbol );
|
||||
}
|
||||
|
||||
QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset, QgsVector3D scale, const Qgs3DMapSettings &map );
|
||||
@ -343,12 +351,12 @@ QgsAABB nodeBoundsToAABB( QgsPointCloudDataBounds nodeBounds, QgsVector3D offset
|
||||
}
|
||||
|
||||
|
||||
QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map )
|
||||
QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map, QgsPointCloud3DSymbol *symbol )
|
||||
: QgsChunkedEntity( 5, // max. allowed screen error (in pixels) -- // TODO
|
||||
new QgsPointCloudLayerChunkLoaderFactory( map, pc ), true )
|
||||
new QgsPointCloudLayerChunkLoaderFactory( map, pc, symbol ), true )
|
||||
{
|
||||
setUsingAdditiveStrategy( true );
|
||||
setShowBoundingBoxes( true );
|
||||
setShowBoundingBoxes( false );
|
||||
}
|
||||
|
||||
QgsPointCloudLayerChunkedEntity::~QgsPointCloudLayerChunkedEntity()
|
||||
|
@ -37,6 +37,7 @@ class Qgs3DMapSettings;
|
||||
class QgsPointCloudLayer;
|
||||
class IndexedPointCloudNode;
|
||||
class QgsPointCloudIndex;
|
||||
class QgsPointCloud3DSymbol;
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <Qt3DRender/QGeometry>
|
||||
@ -47,7 +48,7 @@ class QgsPointCloudIndex;
|
||||
class QgsPointCloud3DSymbolHandler // : public QgsFeature3DHandler
|
||||
{
|
||||
public:
|
||||
QgsPointCloud3DSymbolHandler( );
|
||||
QgsPointCloud3DSymbolHandler( QgsPointCloud3DSymbol *symbol );
|
||||
|
||||
bool prepare( const Qgs3DRenderContext &context );// override;
|
||||
void processNode( QgsPointCloudIndex *pc, const IndexedPointCloudNode &n, const Qgs3DRenderContext &context ); // override;
|
||||
@ -85,6 +86,8 @@ class QgsPointCloud3DSymbolHandler // : public QgsFeature3DHandler
|
||||
// outputs
|
||||
PointData outNormal; //!< Features that are not selected
|
||||
// PointData outSelected; //!< Features that are selected
|
||||
|
||||
QgsPointCloud3DSymbol *mSymbol = nullptr;
|
||||
};
|
||||
|
||||
class QgsPointCloud3DGeometry: public Qt3DRender::QGeometry
|
||||
@ -112,7 +115,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory
|
||||
{
|
||||
public:
|
||||
//! Constructs the factory
|
||||
QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, QgsPointCloudIndex *pc );
|
||||
QgsPointCloudLayerChunkLoaderFactory( const Qgs3DMapSettings &map, QgsPointCloudIndex *pc, QgsPointCloud3DSymbol *symbol );
|
||||
|
||||
//! Creates loader for the given chunk node. Ownership of the returned is passed to the caller.
|
||||
virtual QgsChunkLoader *createChunkLoader( QgsChunkNode *node ) const override;
|
||||
@ -121,6 +124,7 @@ class QgsPointCloudLayerChunkLoaderFactory : public QgsChunkLoaderFactory
|
||||
|
||||
const Qgs3DMapSettings &mMap;
|
||||
QgsPointCloudIndex *mPointCloudIndex;
|
||||
QgsPointCloud3DSymbol *mSymbol = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@ -136,7 +140,7 @@ class QgsPointCloudLayerChunkLoader : public QgsChunkLoader
|
||||
{
|
||||
public:
|
||||
//! Constructs the loader
|
||||
QgsPointCloudLayerChunkLoader( const QgsPointCloudLayerChunkLoaderFactory *factory, QgsChunkNode *node );
|
||||
QgsPointCloudLayerChunkLoader( const QgsPointCloudLayerChunkLoaderFactory *factory, QgsChunkNode *node, QgsPointCloud3DSymbol *symbol );
|
||||
~QgsPointCloudLayerChunkLoader() override;
|
||||
|
||||
virtual void cancel() override;
|
||||
@ -165,7 +169,7 @@ class QgsPointCloudLayerChunkedEntity : public QgsChunkedEntity
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map );
|
||||
explicit QgsPointCloudLayerChunkedEntity( QgsPointCloudIndex *pc, const Qgs3DMapSettings &map, QgsPointCloud3DSymbol *symbol );
|
||||
|
||||
~QgsPointCloudLayerChunkedEntity();
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ uniform mat4 modelViewProjection;
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 viewportMatrix;
|
||||
uniform float u_pointSize;
|
||||
|
||||
in vec3 vertexPosition;
|
||||
in float cls;
|
||||
@ -17,7 +18,7 @@ void main(void)
|
||||
//else
|
||||
gl_Position = modelViewProjection * vec4(vertexPosition, 1);
|
||||
|
||||
gl_PointSize = 2; //5 + vertexPosition.x * 10 + vertexPosition.y * 10;
|
||||
gl_PointSize = u_pointSize; //5 + vertexPosition.x * 10 + vertexPosition.y * 10;
|
||||
//gl_PointSize = viewportMatrix[1][1] * projectionMatrix[1][1] * 1.0 / gl_Position.w;
|
||||
//gl_PointSize = 100.0;
|
||||
|
||||
|
47
src/3d/symbols/qgspointcloud3dsymbol.cpp
Normal file
47
src/3d/symbols/qgspointcloud3dsymbol.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "qgspointcloud3dsymbol.h"
|
||||
|
||||
// TODO: For some reason whwn I define function on a .cpp file they don't get included in the qgis_app target
|
||||
|
||||
//QgsPointCloud3DSymbol::QgsPointCloud3DSymbol()
|
||||
//: QgsAbstract3DSymbol()
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//QgsPointCloud3DSymbol::~QgsPointCloud3DSymbol() { }
|
||||
|
||||
//QgsAbstract3DSymbol *QgsPointCloud3DSymbol::clone() const
|
||||
//{
|
||||
// // TODO: fix memory leak
|
||||
// QgsPointCloud3DSymbol *result = new QgsPointCloud3DSymbol;
|
||||
// result->mEnabled = mEnabled;
|
||||
// result->mPointSize = mPointSize;
|
||||
// copyBaseSettings( result );
|
||||
// return result;
|
||||
//}
|
||||
|
||||
//void QgsPointCloud3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
|
||||
//{
|
||||
// Q_UNUSED( context )
|
||||
|
||||
// elem.setAttribute( QStringLiteral( "enabled" ), mEnabled );
|
||||
// elem.setAttribute( QStringLiteral( "point-size" ), mPointSize );
|
||||
//}
|
||||
|
||||
//void QgsPointCloud3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
|
||||
//{
|
||||
// Q_UNUSED( context )
|
||||
|
||||
// mEnabled = elem.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
|
||||
// mPointSize = elem.attribute( "point-size", QStringLiteral( "5.0" ) ).toFloat();
|
||||
//}
|
||||
|
||||
//void QgsPointCloud3DSymbol::setIsEnabled( bool enabled )
|
||||
//{
|
||||
// mEnabled = enabled;
|
||||
//}
|
||||
|
||||
//void QgsPointCloud3DSymbol::setPointSize( float size )
|
||||
//{
|
||||
// mPointSize = size * 1.0f;
|
||||
//}
|
58
src/3d/symbols/qgspointcloud3dsymbol.h
Normal file
58
src/3d/symbols/qgspointcloud3dsymbol.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef QGSPOINTCLOUD3DSYMBOL_H
|
||||
#define QGSPOINTCLOUD3DSYMBOL_H
|
||||
|
||||
#include "qgis_3d.h"
|
||||
|
||||
#include "qgsabstract3dsymbol.h"
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
class QgsPointCloud3DSymbol : public QgsAbstract3DSymbol
|
||||
{
|
||||
public:
|
||||
//! Constructor for QgsPointCloud3DSymbol
|
||||
QgsPointCloud3DSymbol() : QgsAbstract3DSymbol() { }
|
||||
~QgsPointCloud3DSymbol() override = default;
|
||||
|
||||
QString type() const override { return "pointcloud"; }
|
||||
QgsAbstract3DSymbol *clone() const override SIP_FACTORY
|
||||
{
|
||||
// TODO: use unique_ptr
|
||||
QgsPointCloud3DSymbol *result = new QgsPointCloud3DSymbol;
|
||||
result->mEnabled = mEnabled;
|
||||
result->mPointSize = mPointSize;
|
||||
copyBaseSettings( result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override
|
||||
{
|
||||
Q_UNUSED( context )
|
||||
|
||||
elem.setAttribute( QStringLiteral( "enabled" ), mEnabled );
|
||||
elem.setAttribute( QStringLiteral( "point-size" ), mPointSize );
|
||||
}
|
||||
|
||||
void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override
|
||||
{
|
||||
Q_UNUSED( context )
|
||||
|
||||
mEnabled = elem.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
|
||||
mPointSize = elem.attribute( "point-size", QStringLiteral( "5.0" ) ).toFloat();
|
||||
}
|
||||
|
||||
bool isEnabled() const { return mEnabled; }
|
||||
void setIsEnabled( bool enabled ) { mEnabled = enabled; }
|
||||
|
||||
//! Returns the point size
|
||||
float pointSize() const { return mPointSize; }
|
||||
//! Sets the point size
|
||||
void setPointSize( float size ) { mPointSize = size; }
|
||||
|
||||
private:
|
||||
bool mEnabled;
|
||||
float mPointSize = 10.0f;
|
||||
};
|
||||
|
||||
#endif // QGSPOINTCLOUD3DSYMBOL_H
|
71
src/app/3d/qgspointcloud3dsymbolwidget.cpp
Normal file
71
src/app/3d/qgspointcloud3dsymbolwidget.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "qgspointcloud3dsymbolwidget.h"
|
||||
|
||||
#include "qgspointcloudlayer.h"
|
||||
#include "qgspointcloud3dsymbol.h"
|
||||
#include "qgspointcloudlayer3drenderer.h"
|
||||
|
||||
QgsPointCloud3DSymbolWidget::QgsPointCloud3DSymbolWidget( QgsPointCloudLayer *layer, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
, mLayer( layer )
|
||||
{
|
||||
this->setupUi( this );
|
||||
|
||||
if ( layer )
|
||||
{
|
||||
QgsPointCloudLayer3DRenderer *renderer = dynamic_cast<QgsPointCloudLayer3DRenderer *>( layer->renderer3D() );
|
||||
QgsPointCloud3DSymbol *symbol;
|
||||
if ( renderer != nullptr )
|
||||
{
|
||||
symbol = const_cast<QgsPointCloud3DSymbol *>( renderer->symbol() );
|
||||
setSymbol( symbol );
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = new QgsPointCloud3DSymbol;
|
||||
setSymbol( symbol );
|
||||
delete symbol;
|
||||
}
|
||||
}
|
||||
|
||||
// connect( mPointSizeSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QgsPointCloud3DSymbolWidget::changed);
|
||||
connect( mPointSizeSpinBox, QOverload<double>::of( &QDoubleSpinBox::valueChanged ), [&]( double value )
|
||||
{
|
||||
qDebug() << "mPointSizeSpinBox->valueChanged()";
|
||||
emit changed();
|
||||
} );
|
||||
}
|
||||
|
||||
void QgsPointCloud3DSymbolWidget::setLayer( QgsPointCloudLayer *layer, bool updateSymbol )
|
||||
{
|
||||
mLayer = layer;
|
||||
if ( layer )
|
||||
{
|
||||
QgsPointCloudLayer3DRenderer *renderer = dynamic_cast<QgsPointCloudLayer3DRenderer *>( layer->renderer3D() );
|
||||
QgsPointCloud3DSymbol *symbol;
|
||||
if ( renderer != nullptr )
|
||||
{
|
||||
symbol = const_cast<QgsPointCloud3DSymbol *>( renderer->symbol() );
|
||||
setSymbol( symbol );
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = new QgsPointCloud3DSymbol;
|
||||
setSymbol( symbol );
|
||||
delete symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsPointCloud3DSymbolWidget::setSymbol( QgsPointCloud3DSymbol *symbol )
|
||||
{
|
||||
mPointSizeSpinBox->setValue( symbol->pointSize() );
|
||||
}
|
||||
|
||||
QgsPointCloud3DSymbol *QgsPointCloud3DSymbolWidget::symbol() const
|
||||
{
|
||||
// TODO: fix memory leak
|
||||
QgsPointCloud3DSymbol *symb = new QgsPointCloud3DSymbol;
|
||||
symb->setPointSize( mPointSizeSpinBox->value() );
|
||||
return symb;
|
||||
}
|
||||
|
30
src/app/3d/qgspointcloud3dsymbolwidget.h
Normal file
30
src/app/3d/qgspointcloud3dsymbolwidget.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef QGSPOINTCLOUD3DSYMBOLWIDGET_H
|
||||
#define QGSPOINTCLOUD3DSYMBOLWIDGET_H
|
||||
|
||||
#include "ui_qgspointcloud3dsymbolwidget.h"
|
||||
|
||||
class QgsPointCloudLayer;
|
||||
class QgsPointCloud3DSymbol;
|
||||
|
||||
class QgsPointCloud3DSymbolWidget : public QWidget, private Ui::QgsPointCloud3DSymbolWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsPointCloud3DSymbolWidget( QgsPointCloudLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
void setLayer( QgsPointCloudLayer *meshLayer, bool updateSymbol = true );
|
||||
|
||||
QgsPointCloudLayer *pointCloudLayer() const { return mLayer; }
|
||||
void setSymbol( QgsPointCloud3DSymbol *symbol );
|
||||
|
||||
QgsPointCloud3DSymbol *symbol() const;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
QgsPointCloudLayer *mLayer = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGSPOINTCLOUD3DSYMBOLWIDGET_H
|
127
src/app/3d/qgspointcloudlayer3drendererwidget.cpp
Normal file
127
src/app/3d/qgspointcloudlayer3drendererwidget.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/***************************************************************************
|
||||
qgspointcloudlayer3drendererwidget.cpp
|
||||
------------------------------
|
||||
Date : November 2020
|
||||
Copyright : (C) 2020 by Nedjima Belgacem
|
||||
Email : belgacem dot nedjima 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 "qgspointcloudlayer3drendererwidget.h"
|
||||
|
||||
#include "qgspointcloud3dsymbolwidget.h"
|
||||
#include "qgspointcloudlayer3drenderer.h"
|
||||
|
||||
#include "qgspointcloudlayer.h"
|
||||
#include "qgspointcloud3dsymbol.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
|
||||
QgsPointCloudLayer3DRendererWidget::QgsPointCloudLayer3DRendererWidget( QgsPointCloudLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
|
||||
: QgsMapLayerConfigWidget( layer, canvas, parent )
|
||||
{
|
||||
setPanelTitle( tr( "3D View" ) );
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout( this );
|
||||
layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
|
||||
// TODO: add enabled checkbox
|
||||
// mChkEnabled = new QCheckBox( tr( "Enable 3D Renderer" ), this );
|
||||
// layout->addWidget( mChkEnabled );
|
||||
|
||||
mWidgetPointCloudSymbol = new QgsPointCloud3DSymbolWidget( layer, this );
|
||||
layout->addWidget( mWidgetPointCloudSymbol );
|
||||
|
||||
// connect( mChkEnabled, &QCheckBox::clicked, this, &QgsPointCloudLayer3DRendererWidget::onEnabledClicked );
|
||||
connect( mWidgetPointCloudSymbol, &QgsPointCloud3DSymbolWidget::changed, this, &QgsPointCloudLayer3DRendererWidget::widgetChanged );
|
||||
}
|
||||
|
||||
void QgsPointCloudLayer3DRendererWidget::setRenderer( const QgsPointCloudLayer3DRenderer *renderer )
|
||||
{
|
||||
mRenderer.reset( renderer ? renderer->clone() : nullptr );
|
||||
if ( renderer != nullptr )
|
||||
mWidgetPointCloudSymbol->setSymbol( const_cast<QgsPointCloud3DSymbol *>( renderer->symbol() ) );
|
||||
// whileBlocking( mChkEnabled )->setChecked( renderer ? renderer->symbol()->isEnabled() : false );
|
||||
}
|
||||
|
||||
QgsPointCloudLayer3DRenderer *QgsPointCloudLayer3DRendererWidget::renderer()
|
||||
{
|
||||
// TODO: use unique_ptr for point cloud symbol
|
||||
QgsPointCloud3DSymbol *sym = mWidgetPointCloudSymbol->symbol();
|
||||
mRenderer.reset( new QgsPointCloudLayer3DRenderer );
|
||||
mRenderer->setSymbol( sym );
|
||||
delete sym;
|
||||
mRenderer->setLayer( qobject_cast<QgsPointCloudLayer *>( mLayer ) );
|
||||
return mRenderer.get();
|
||||
}
|
||||
|
||||
void QgsPointCloudLayer3DRendererWidget::apply()
|
||||
{
|
||||
QgsPointCloudLayer3DRenderer *r = renderer();
|
||||
r->setSymbol( mWidgetPointCloudSymbol->symbol() );
|
||||
mLayer->setRenderer3D( r ? r->clone() : nullptr );
|
||||
}
|
||||
|
||||
//void QgsPointCloudLayer3DRendererWidget::onEnabledClicked()
|
||||
//{
|
||||
// mWidgetPointCloudSymbol->setEnabled( mChkEnabled->isChecked() );
|
||||
// emit widgetChanged();
|
||||
//}
|
||||
|
||||
void QgsPointCloudLayer3DRendererWidget::syncToLayer( QgsMapLayer *layer )
|
||||
{
|
||||
mLayer = layer ;
|
||||
QgsPointCloudLayer *pointCloudLayer = qobject_cast<QgsPointCloudLayer *>( layer );
|
||||
mWidgetPointCloudSymbol->setLayer( pointCloudLayer );
|
||||
QgsAbstract3DRenderer *r = layer->renderer3D();
|
||||
if ( r && r->type() == QLatin1String( "pointcloud" ) )
|
||||
{
|
||||
QgsPointCloudLayer3DRenderer *pointCloudRenderer = static_cast<QgsPointCloudLayer3DRenderer *>( r );
|
||||
pointCloudRenderer->setSymbol( mWidgetPointCloudSymbol->symbol() );
|
||||
setRenderer( pointCloudRenderer );
|
||||
mWidgetPointCloudSymbol->setEnabled( pointCloudRenderer->symbol()->isEnabled() );
|
||||
}
|
||||
else
|
||||
{
|
||||
setRenderer( nullptr );
|
||||
mWidgetPointCloudSymbol->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
QgsPointCloudLayer3DRendererWidgetFactory::QgsPointCloudLayer3DRendererWidgetFactory( QObject *parent ):
|
||||
QObject( parent )
|
||||
{
|
||||
setIcon( QIcon( ":/images/themes/default/3d.svg" ) );
|
||||
setTitle( tr( "3D View" ) );
|
||||
}
|
||||
|
||||
QgsMapLayerConfigWidget *QgsPointCloudLayer3DRendererWidgetFactory::createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget, QWidget *parent ) const
|
||||
{
|
||||
Q_UNUSED( dockWidget )
|
||||
QgsPointCloudLayer *pointCloudLayer = qobject_cast<QgsPointCloudLayer *>( layer );
|
||||
if ( !pointCloudLayer )
|
||||
return nullptr;
|
||||
return new QgsPointCloudLayer3DRendererWidget( pointCloudLayer, canvas, parent );
|
||||
}
|
||||
|
||||
bool QgsPointCloudLayer3DRendererWidgetFactory::supportLayerPropertiesDialog() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsPointCloudLayer3DRendererWidgetFactory::supportsLayer( QgsMapLayer *layer ) const
|
||||
{
|
||||
return layer->type() == QgsMapLayerType::PointCloudLayer;
|
||||
}
|
||||
|
||||
QString QgsPointCloudLayer3DRendererWidgetFactory::layerPropertiesPagePositionHint() const
|
||||
{
|
||||
return QStringLiteral( "mOptsPage_Rendering" );
|
||||
}
|
69
src/app/3d/qgspointcloudlayer3drendererwidget.h
Normal file
69
src/app/3d/qgspointcloudlayer3drendererwidget.h
Normal file
@ -0,0 +1,69 @@
|
||||
/***************************************************************************
|
||||
qgspointcloudlayer3drendererwidget.h
|
||||
------------------------------
|
||||
Date : November 2020
|
||||
Copyright : (C) 2020 by Nedjima Belgacem
|
||||
Email : belgacem dot nedjima 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 QGSPOINTCLOUDLAYER3DRENDERERWIDGET_H
|
||||
#define QGSPOINTCLOUDLAYER3DRENDERERWIDGET_H
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "qgsmaplayerconfigwidget.h"
|
||||
#include "qgspointcloudlayer3drenderer.h"
|
||||
#include "qgsmaplayerconfigwidgetfactory.h"
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
class QgsPointCloudLayer;
|
||||
class QgsMapCanvas;
|
||||
class QgsPointCloud3DSymbolWidget;
|
||||
|
||||
//! Widget for configuration of 3D renderer of a point cloud layer
|
||||
class QgsPointCloudLayer3DRendererWidget : public QgsMapLayerConfigWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsPointCloudLayer3DRendererWidget( QgsPointCloudLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr );
|
||||
|
||||
void syncToLayer( QgsMapLayer *layer ) override;
|
||||
|
||||
//! no transfer of ownership
|
||||
void setRenderer( const QgsPointCloudLayer3DRenderer *renderer );
|
||||
//! no transfer of ownership
|
||||
QgsPointCloudLayer3DRenderer *renderer();
|
||||
|
||||
public slots:
|
||||
void apply() override;
|
||||
|
||||
private slots:
|
||||
// void onEnabledClicked();
|
||||
|
||||
private:
|
||||
// QCheckBox *mChkEnabled = nullptr;
|
||||
QgsPointCloud3DSymbolWidget *mWidgetPointCloudSymbol = nullptr;
|
||||
std::unique_ptr<QgsPointCloudLayer3DRenderer> mRenderer;
|
||||
};
|
||||
|
||||
class QgsPointCloudLayer3DRendererWidgetFactory : public QObject, public QgsMapLayerConfigWidgetFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsPointCloudLayer3DRendererWidgetFactory( QObject *parent = nullptr );
|
||||
|
||||
QgsMapLayerConfigWidget *createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget, QWidget *parent ) const override;
|
||||
bool supportLayerPropertiesDialog() const override;
|
||||
bool supportsLayer( QgsMapLayer *layer ) const override;
|
||||
QString layerPropertiesPagePositionHint() const override;
|
||||
};
|
||||
|
||||
#endif // QGSPOINTCLOUDLAYER3DRENDERERWIDGET_H
|
@ -286,6 +286,8 @@ IF (WITH_3D)
|
||||
layout/qgslayout3dmapwidget.cpp
|
||||
3d/qgsskyboxrenderingsettingswidget.cpp
|
||||
3d/qgsshadowrenderingsettingswidget.cpp
|
||||
3d/qgspointcloud3dsymbolwidget.cpp
|
||||
3d/qgspointcloudlayer3drendererwidget.cpp
|
||||
)
|
||||
ENDIF (WITH_3D)
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include "qgspointcloudlayer3drendererwidget.h"
|
||||
|
||||
QgsPointCloudLayerProperties::QgsPointCloudLayerProperties( QgsPointCloudLayer *lyr, QgsMapCanvas *canvas, QgsMessageBar *, QWidget *parent, Qt::WindowFlags flags )
|
||||
: QgsOptionsDialogBase( QStringLiteral( "PointCloudLayerProperties" ), parent, flags )
|
||||
, mLayer( lyr )
|
||||
@ -103,6 +105,13 @@ void QgsPointCloudLayerProperties::apply()
|
||||
{
|
||||
mMetadataWidget->acceptMetadata();
|
||||
|
||||
for ( QgsMapLayerConfigWidget *configWidget : mLayerPropertiesPages )
|
||||
{
|
||||
QgsPointCloudLayer3DRendererWidget *pointCloudRendererWidget = dynamic_cast<QgsPointCloudLayer3DRendererWidget *>( configWidget );
|
||||
if ( pointCloudRendererWidget )
|
||||
pointCloudRendererWidget->apply();
|
||||
}
|
||||
|
||||
// TODO -- move to proper widget classes!
|
||||
mLayer->setCustomProperty( QStringLiteral( "pcMin" ), mMinZSpin->value() );
|
||||
mLayer->setCustomProperty( QStringLiteral( "pcMax" ), mMaxZSpin->value() );
|
||||
@ -142,6 +151,12 @@ void QgsPointCloudLayerProperties::syncToLayer()
|
||||
mMaxZSpin->setValue( mLayer->customProperty( QStringLiteral( "pcMax" ), 600 ).toInt() );
|
||||
mBtnColorRamp->setColorRampFromName( mLayer->customProperty( QStringLiteral( "pcRamp" ), QStringLiteral( "Viridis" ) ).toString() );
|
||||
mBtnColorRamp->setColorRampName( mLayer->customProperty( QStringLiteral( "pcRamp" ), QStringLiteral( "Viridis" ) ).toString() );
|
||||
|
||||
const auto constMLayerPropertiesPages = mLayerPropertiesPages;
|
||||
for ( QgsMapLayerConfigWidget *page : constMLayerPropertiesPages )
|
||||
{
|
||||
page->syncToLayer( mLayer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -376,3 +391,19 @@ void QgsPointCloudLayerProperties::optionsStackedWidget_CurrentChanged( int inde
|
||||
mBtnStyle->setVisible( ! isMetadataPanel );
|
||||
mBtnMetadata->setVisible( isMetadataPanel );
|
||||
}
|
||||
|
||||
void QgsPointCloudLayerProperties::addPropertiesPageFactory( QgsMapLayerConfigWidgetFactory *factory )
|
||||
{
|
||||
if ( !factory->supportsLayer( mLayer ) || !factory->supportLayerPropertiesDialog() )
|
||||
return;
|
||||
|
||||
QgsMapLayerConfigWidget *page = factory->createWidget( mLayer, nullptr, false, this );
|
||||
mLayerPropertiesPages << page;
|
||||
|
||||
const QString beforePage = factory->layerPropertiesPagePositionHint();
|
||||
if ( beforePage.isEmpty() )
|
||||
addPage( factory->title(), factory->title(), factory->icon(), page );
|
||||
else
|
||||
insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,8 @@ class QgsMapCanvas;
|
||||
class QgsMessageBar;
|
||||
class QgsPointCloudLayer;
|
||||
class QgsMetadataWidget;
|
||||
|
||||
class QgsMapLayerConfigWidgetFactory;
|
||||
class QgsMapLayerConfigWidget;
|
||||
|
||||
class QgsPointCloudLayerProperties : public QgsOptionsDialogBase, private Ui::QgsPointCloudLayerPropertiesBase
|
||||
{
|
||||
@ -35,6 +36,9 @@ class QgsPointCloudLayerProperties : public QgsOptionsDialogBase, private Ui::Qg
|
||||
public:
|
||||
QgsPointCloudLayerProperties( QgsPointCloudLayer *lyr, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent = nullptr, Qt::WindowFlags = QgsGuiUtils::ModalDialogFlags );
|
||||
|
||||
//! Adds a properties page factory to the vector layer properties dialog.
|
||||
void addPropertiesPageFactory( QgsMapLayerConfigWidgetFactory *factory );
|
||||
|
||||
private slots:
|
||||
void apply();
|
||||
void onCancel();
|
||||
@ -68,6 +72,9 @@ class QgsPointCloudLayerProperties : public QgsOptionsDialogBase, private Ui::Qg
|
||||
QgsMapCanvas *mMapCanvas = nullptr;
|
||||
QgsMetadataWidget *mMetadataWidget = nullptr;
|
||||
|
||||
//! A list of additional pages provided by plugins
|
||||
QList<QgsMapLayerConfigWidget *> mLayerPropertiesPages;
|
||||
|
||||
/**
|
||||
* Previous layer style. Used to reset style to previous state if new style
|
||||
* was loaded but dialog is canceled.
|
||||
|
@ -116,6 +116,7 @@
|
||||
#include "layout/qgslayoutviewrubberband.h"
|
||||
#include "qgsvectorlayer3drendererwidget.h"
|
||||
#include "qgsmeshlayer3drendererwidget.h"
|
||||
#include "qgspointcloudlayer3drendererwidget.h"
|
||||
#include "qgs3dapputils.h"
|
||||
#endif
|
||||
|
||||
@ -1332,6 +1333,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
#ifdef HAVE_3D
|
||||
registerMapLayerPropertiesFactory( new QgsVectorLayer3DRendererWidgetFactory( this ) );
|
||||
registerMapLayerPropertiesFactory( new QgsMeshLayer3DRendererWidgetFactory( this ) );
|
||||
registerMapLayerPropertiesFactory( new QgsPointCloudLayer3DRendererWidgetFactory( this ) );
|
||||
#endif
|
||||
|
||||
activateDeactivateLayerRelatedActions( nullptr ); // after members were created
|
||||
@ -16252,6 +16254,32 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page )
|
||||
case QgsMapLayerType::PointCloudLayer:
|
||||
{
|
||||
QgsPointCloudLayerProperties pointCloudLayerPropertiesDialog( qobject_cast<QgsPointCloudLayer *>( mapLayer ), mMapCanvas, visibleMessageBar(), this );
|
||||
|
||||
//
|
||||
// connect(
|
||||
// pointCloudLayerPropertiesDialog, static_cast<void ( QgsPointCloudLayerProperties::* )( QgsMapLayer * )>( &QgsPointCloudLayerProperties::toggleEditing ),
|
||||
// this, [ = ]( QgsMapLayer * layer ) { toggleEditing( layer ); }
|
||||
// );
|
||||
// connect( pointCloudLayerPropertiesDialog, &QgsVectorLayerProperties::exportAuxiliaryLayer, this, [ = ]( QgsAuxiliaryLayer * layer )
|
||||
// {
|
||||
// if ( layer )
|
||||
// {
|
||||
// std::unique_ptr<QgsVectorLayer> clone;
|
||||
// clone.reset( layer->toSpatialLayer() );
|
||||
|
||||
// saveAsFile( clone.get() );
|
||||
// }
|
||||
// } );
|
||||
for ( QgsMapLayerConfigWidgetFactory *factory : qgis::as_const( mMapLayerPanelFactories ) )
|
||||
{
|
||||
pointCloudLayerPropertiesDialog.addPropertiesPageFactory( factory );
|
||||
}
|
||||
|
||||
if ( !page.isEmpty() )
|
||||
pointCloudLayerPropertiesDialog.setCurrentPage( page );
|
||||
else
|
||||
pointCloudLayerPropertiesDialog.restoreLastPage();
|
||||
|
||||
if ( !page.isEmpty() )
|
||||
pointCloudLayerPropertiesDialog.setCurrentPage( page );
|
||||
|
||||
|
@ -57,8 +57,7 @@
|
||||
#ifdef HAVE_3D
|
||||
#include "qgsvectorlayer3drendererwidget.h"
|
||||
#include "qgsmeshlayer3drendererwidget.h"
|
||||
|
||||
#include "qgspointcloudlayer3drenderer.h" // TODO remove
|
||||
#include "qgspointcloudlayer3drendererwidget.h"
|
||||
#endif
|
||||
|
||||
|
||||
@ -146,17 +145,6 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
|
||||
if ( layer == mCurrentLayer )
|
||||
return;
|
||||
|
||||
#ifdef HAVE_3D
|
||||
QgsPointCloudLayer *pcLayer = qobject_cast<QgsPointCloudLayer *>( layer );
|
||||
if ( pcLayer )
|
||||
{
|
||||
//TODO remove this ugly hack!
|
||||
QgsPointCloudLayer3DRenderer *r = new QgsPointCloudLayer3DRenderer();
|
||||
r->setLayer( pcLayer );
|
||||
r->resolveReferences( *QgsProject::instance() );
|
||||
pcLayer->setRenderer3D( r );
|
||||
}
|
||||
#endif
|
||||
|
||||
// when current layer is changed, apply the main panel stack to allow it to gracefully clean up
|
||||
mWidgetStack->acceptAllPanels();
|
||||
@ -268,6 +256,12 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
|
||||
|
||||
case QgsMapLayerType::PointCloudLayer:
|
||||
{
|
||||
#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
|
||||
break;
|
||||
}
|
||||
|
||||
@ -444,6 +438,10 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
||||
{
|
||||
mMesh3DWidget = widget;
|
||||
}
|
||||
else if ( QgsPointCloudLayer3DRendererWidget *widget = qobject_cast<QgsPointCloudLayer3DRendererWidget *>( current ) )
|
||||
{
|
||||
mPointCloud3DWidget = widget;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -678,9 +676,24 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
||||
{
|
||||
QgsPointCloudLayer *pcLayer = qobject_cast<QgsPointCloudLayer *>( mCurrentLayer );
|
||||
( void )pcLayer;
|
||||
switch ( row )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
#ifdef HAVE_3D
|
||||
if ( !mPointCloud3DWidget )
|
||||
{
|
||||
mPointCloud3DWidget = new QgsPointCloudLayer3DRendererWidget( nullptr, mMapCanvas, mWidgetStack );
|
||||
mPointCloud3DWidget->setDockMode( true );
|
||||
connect( mPointCloud3DWidget, &QgsPointCloudLayer3DRendererWidget::widgetChanged, this, &QgsLayerStylingWidget::autoApply );
|
||||
}
|
||||
mPointCloud3DWidget->syncToLayer( pcLayer );
|
||||
mWidgetStack->setMainPanel( mPointCloud3DWidget );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
mStackedWidget->setCurrentIndex( mNotSupportedPage );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -816,7 +829,7 @@ bool QgsLayerStyleManagerWidgetFactory::supportsLayer( QgsMapLayer *layer ) cons
|
||||
return false; // TODO
|
||||
|
||||
case QgsMapLayerType::PointCloudLayer:
|
||||
return false; // TODO
|
||||
return true;
|
||||
|
||||
case QgsMapLayerType::PluginLayer:
|
||||
case QgsMapLayerType::AnnotationLayer:
|
||||
|
@ -43,6 +43,7 @@ class QgsRasterHistogramWidget;
|
||||
class QgsMapLayerStyleManagerWidget;
|
||||
class QgsVectorLayer3DRendererWidget;
|
||||
class QgsMeshLayer3DRendererWidget;
|
||||
class QgsPointCloudLayer3DRendererWidget;
|
||||
class QgsMessageBar;
|
||||
class QgsVectorTileBasicRendererWidget;
|
||||
class QgsVectorTileBasicLabelingWidget;
|
||||
@ -148,6 +149,7 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
|
||||
#ifdef HAVE_3D
|
||||
QgsVectorLayer3DRendererWidget *mVector3DWidget = nullptr;
|
||||
QgsMeshLayer3DRendererWidget *mMesh3DWidget = nullptr;
|
||||
QgsPointCloudLayer3DRendererWidget *mPointCloud3DWidget = nullptr;
|
||||
#endif
|
||||
QgsRendererRasterPropertiesWidget *mRasterStyleWidget = nullptr;
|
||||
QgsRendererMeshPropertiesWidget *mMeshStyleWidget = nullptr;
|
||||
|
@ -53,7 +53,8 @@ bool QgsMapLayerProxyModel::layerMatchesFilters( const QgsMapLayer *layer, const
|
||||
( filters.testFlag( VectorLayer ) && layer->type() == QgsMapLayerType::VectorLayer ) ||
|
||||
( filters.testFlag( MeshLayer ) && layer->type() == QgsMapLayerType::MeshLayer ) ||
|
||||
( filters.testFlag( VectorTileLayer ) && layer->type() == QgsMapLayerType::VectorTileLayer ) ||
|
||||
( filters.testFlag( PluginLayer ) && layer->type() == QgsMapLayerType::PluginLayer ) )
|
||||
( filters.testFlag( PluginLayer ) && layer->type() == QgsMapLayerType::PluginLayer ) ||
|
||||
filters.testFlag( PointCloudLayer ) && layer->type() == QgsMapLayerType::PointCloudLayer )
|
||||
return true;
|
||||
|
||||
// geometry type
|
||||
|
51
src/ui/3d/qgspointcloud3dsymbolwidget.ui
Normal file
51
src/ui/3d/qgspointcloud3dsymbolwidget.ui
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsPointCloud3DSymbolWidget</class>
|
||||
<widget class="QWidget" name="QgsPointCloud3DSymbolWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mPointSizeSpinBox">
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>2.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Point size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -35,12 +35,12 @@
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Not supported or no layer</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
Loading…
x
Reference in New Issue
Block a user