Skip to content
Permalink
Browse files

Initial implementation of point-cloud 3D GUI

  • Loading branch information
NEDJIMAbelgacem committed Nov 13, 2020
1 parent 928997d commit c220bb47a3d218cb2da099598db2d255de9dd2d5
@@ -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,17 +281,18 @@ 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 )
{
}

QgsChunkLoader *QgsPointCloudLayerChunkLoaderFactory::createChunkLoader( QgsChunkNode *node ) const
{
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;

@@ -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;
//}

0 comments on commit c220bb4

Please sign in to comment.
You can’t perform that action at this time.