Skip to content

Commit

Permalink
Change rendering parameter to point cloud attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed Dec 3, 2020
1 parent 3766712 commit 5e76bc6
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 129 deletions.
35 changes: 22 additions & 13 deletions python/3d/auto_generated/symbols/qgspointcloud3dsymbol.sip.in
Expand Up @@ -37,7 +37,7 @@ class QgsPointCloud3DSymbol : QgsAbstract3DSymbol
ColorRamp,
};

QgsPointCloud3DSymbol( QgsPointCloud3DSymbol::RenderingStyle style );
QgsPointCloud3DSymbol( QgsPointCloudLayer *layer, QgsPointCloud3DSymbol::RenderingStyle style );
%Docstring
Constructor for QgsPointCloud3DSymbol
%End
Expand All @@ -50,6 +50,18 @@ Constructor for QgsPointCloud3DSymbol

virtual QString type() const;

QgsPointCloudLayer *layer();
%Docstring
Returns the point cloud layer object used by the symbol
see setLayer( :py:class:`QgsPointCloudLayer` *layer )
%End

void setLayer( QgsPointCloudLayer *layer );
%Docstring
Sets the point cloud layer object used by the symbol
see :py:func:`~QgsPointCloud3DSymbol.layer`
%End

QgsPointCloud3DSymbol::RenderingStyle renderingStyle() const;
%Docstring
Returns the rendering style used to render the point cloud
Expand All @@ -75,7 +87,7 @@ class QgsNoRenderingPointCloud3DSymbol : QgsPointCloud3DSymbol
#include "qgspointcloud3dsymbol.h"
%End
public:
QgsNoRenderingPointCloud3DSymbol();
QgsNoRenderingPointCloud3DSymbol( QgsPointCloudLayer *layer );

virtual QgsAbstract3DSymbol *clone() const /Factory/;

Expand Down Expand Up @@ -103,7 +115,7 @@ class QgsSingleColorPointCloud3DSymbol : QgsPointCloud3DSymbol
#include "qgspointcloud3dsymbol.h"
%End
public:
QgsSingleColorPointCloud3DSymbol();
QgsSingleColorPointCloud3DSymbol( QgsPointCloudLayer *layer );

virtual QgsAbstract3DSymbol *clone() const /Factory/;

Expand Down Expand Up @@ -160,14 +172,7 @@ class QgsColorRampPointCloud3DSymbol : QgsPointCloud3DSymbol
#include "qgspointcloud3dsymbol.h"
%End
public:

enum RenderingParameter
{
Height,
ClassID
};

QgsColorRampPointCloud3DSymbol();
QgsColorRampPointCloud3DSymbol( QgsPointCloudLayer *layer );

virtual QgsAbstract3DSymbol *clone() const /Factory/;

Expand All @@ -191,14 +196,14 @@ Sets the point size
.. seealso:: :py:func:`pointSize`
%End

QgsColorRampPointCloud3DSymbol::RenderingParameter renderingParameter() const;
QString renderingParameter() const;
%Docstring
Returns the parameter used to select the color of the point cloud

.. seealso:: :py:func:`setRenderingParameter`
%End

void setRenderingParameter( QgsColorRampPointCloud3DSymbol::RenderingParameter parameter );
void setRenderingParameter( const QString &parameter );
%Docstring
Sets the parameter used to select the color of the point cloud

Expand All @@ -208,11 +213,15 @@ Sets the parameter used to select the color of the point cloud
QgsColorRampShader colorRampShader() const;
%Docstring
Returns the color ramp shader used to render the color

.. seealso:: :py:func:`setColorRampShader`
%End

void setColorRampShader( const QgsColorRampShader &colorRampShader );
%Docstring
Sets the color ramp shader used to render the point cloud

.. seealso:: :py:func:`colorRampShader`
%End

double colorRampShaderMin() const;
Expand Down
9 changes: 6 additions & 3 deletions src/3d/qgspointcloudlayer3drenderer.cpp
Expand Up @@ -51,6 +51,8 @@ QgsPointCloudLayer3DRenderer::QgsPointCloudLayer3DRenderer( )
void QgsPointCloudLayer3DRenderer::setLayer( QgsPointCloudLayer *layer )
{
mLayerRef = QgsMapLayerRef( layer );
if ( mSymbol )
mSymbol->setLayer( layer );
}

QgsPointCloudLayer *QgsPointCloudLayer3DRenderer::layer() const
Expand Down Expand Up @@ -117,13 +119,13 @@ void QgsPointCloudLayer3DRenderer::readXml( const QDomElement &elem, const QgsRe
switch ( renderingStyle )
{
case QgsPointCloud3DSymbol::RenderingStyle::NoRendering:
mSymbol.reset( new QgsSingleColorPointCloud3DSymbol );
mSymbol.reset( new QgsNoRenderingPointCloud3DSymbol( layer() ) );
break;
case QgsPointCloud3DSymbol::RenderingStyle::SingleColor:
mSymbol.reset( new QgsSingleColorPointCloud3DSymbol );
mSymbol.reset( new QgsSingleColorPointCloud3DSymbol( layer() ) );
break;
case QgsPointCloud3DSymbol::RenderingStyle::ColorRamp:
mSymbol.reset( new QgsColorRampPointCloud3DSymbol );
mSymbol.reset( new QgsColorRampPointCloud3DSymbol( layer() ) );
break;
}
mSymbol->readXml( elemSymbol, context );
Expand All @@ -132,4 +134,5 @@ void QgsPointCloudLayer3DRenderer::readXml( const QDomElement &elem, const QgsRe
void QgsPointCloudLayer3DRenderer::resolveReferences( const QgsProject &project )
{
mLayerRef.setLayer( project.mapLayer( mLayerRef.layerId ) );
mSymbol->setLayer( layer() );
}
76 changes: 59 additions & 17 deletions src/3d/qgspointcloudlayerchunkloader_p.cpp
Expand Up @@ -48,7 +48,7 @@
QgsPointCloud3DGeometry::QgsPointCloud3DGeometry( Qt3DCore::QNode *parent, const QgsPointCloud3DSymbolHandler::PointData &data )
: Qt3DRender::QGeometry( parent )
, mPositionAttribute( new Qt3DRender::QAttribute( this ) )
, mClassAttribute( new Qt3DRender::QAttribute( this ) )
, mParameterAttribute( new Qt3DRender::QAttribute( this ) )
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
, mVertexBuffer( new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer, this ) )
#else
Expand All @@ -63,17 +63,16 @@ QgsPointCloud3DGeometry::QgsPointCloud3DGeometry( Qt3DCore::QNode *parent, const
mPositionAttribute->setByteOffset( 0 );
mPositionAttribute->setByteStride( 16 );

mClassAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
mClassAttribute->setBuffer( mVertexBuffer );
mClassAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
mClassAttribute->setVertexSize( 1 );
mClassAttribute->setName( "cls" );
mClassAttribute->setByteOffset( 12 );
mClassAttribute->setByteStride( 16 );
mParameterAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
mParameterAttribute->setBuffer( mVertexBuffer );
mParameterAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
mParameterAttribute->setVertexSize( 1 );
mParameterAttribute->setName( "vertexParameter" );
mParameterAttribute->setByteOffset( 12 );
mParameterAttribute->setByteStride( 16 );

addAttribute( mPositionAttribute );
addAttribute( mClassAttribute );

addAttribute( mParameterAttribute );

makeVertexBuffer( data );
}
Expand All @@ -84,13 +83,13 @@ void QgsPointCloud3DGeometry::makeVertexBuffer( const QgsPointCloud3DSymbolHandl
vertexBufferData.resize( data.positions.size() * 4 * sizeof( float ) );
float *rawVertexArray = reinterpret_cast<float *>( vertexBufferData.data() );
int idx = 0;
Q_ASSERT( data.positions.count() == data.classes.count() );
Q_ASSERT( data.positions.count() == data.parameter.count() );
for ( int i = 0; i < data.positions.size(); ++i )
{
rawVertexArray[idx++] = data.positions.at( i ).x();
rawVertexArray[idx++] = data.positions.at( i ).y();
rawVertexArray[idx++] = data.positions.at( i ).z();
rawVertexArray[idx++] = data.classes.at( i );
rawVertexArray[idx++] = data.parameter.at( i );
}

mVertexCount = data.positions.size();
Expand All @@ -115,7 +114,26 @@ void QgsPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const In
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "X" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Y" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Z" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Classification" ), QgsPointCloudAttribute::Char ) );

std::unique_ptr< QgsPointCloudAttribute > parameterAttribute;
if ( mSymbol.get()->renderingStyle() == QgsPointCloud3DSymbol::ColorRamp )
{
QgsColorRampPointCloud3DSymbol *symbol = dynamic_cast<QgsColorRampPointCloud3DSymbol *>( mSymbol.get() );
QgsPointCloudLayer *layer = symbol->layer();
if ( symbol && layer )
{
int offset = 0;
const QgsPointCloudAttribute *attr = layer->attributes().find( symbol->renderingParameter(), offset );
if ( attr )
{
parameterAttribute.reset( new QgsPointCloudAttribute( attr->name(), attr->type() ) );
attributes.push_back( *parameterAttribute.get() );
}
}
}


// attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Classification" ), QgsPointCloudAttribute::Char ) );
QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
Expand All @@ -134,16 +152,40 @@ void QgsPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const In
qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
char cls = *( char * )( ptr + i * recordSize + 12 );
float iParam = 0.0f;
if ( parameterAttribute )
{
switch ( parameterAttribute->type() )
{
case QgsPointCloudAttribute::DataType::Char:
iParam = *( char * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Float:
iParam = *( float * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Int32:
iParam = *( qint32 * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Short:
iParam = *( short * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Double:
iParam = *( double * )( ptr + i * recordSize + 12 );
break;
}
}

double x = offset.x() + scale.x() * ix;
double y = offset.y() + scale.y() * iy;
double z = offset.z() + scale.z() * iz;
QVector3D point( x, y, z );
QgsVector3D p = context.map().mapToWorldCoordinates( point );
outNormal.positions.push_back( QVector3D( p.x(), p.y(), p.z() ) );
outNormal.classes.push_back( cls );
outNormal.parameter.push_back( iParam );
}
qDebug() << "outNormal.positions.size() " << outNormal.positions.size();
qDebug() << "outNormal.parameter.size() " << outNormal.parameter.size();
qDebug() << "--------------------------------------------------";
}

void QgsPointCloud3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
Expand Down Expand Up @@ -263,8 +305,8 @@ Qt3DRender::QMaterial *QgsPointCloud3DSymbolHandler::constructMaterial( QgsColor
mat->addParameter( renderingStyle );
Qt3DRender::QParameter *pointSizeParameter = new Qt3DRender::QParameter( "u_pointSize", QVariant::fromValue( symbol->pointSize() ) );
mat->addParameter( pointSizeParameter );
Qt3DRender::QParameter *renderingParameter = new Qt3DRender::QParameter( "u_renderingParameter", symbol->renderingParameter() );
mat->addParameter( renderingParameter );
// Qt3DRender::QParameter *renderingParameter = new Qt3DRender::QParameter( "u_renderingParameter", symbol->renderingParameter() );
// mat->addParameter( renderingParameter );
QgsColorRampShader colorRampShader = symbol->colorRampShader();
// Create the texture to pass the color ramp
Qt3DRender::QTexture1D *colorRampTexture = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions src/3d/qgspointcloudlayerchunkloader_p.h
Expand Up @@ -64,7 +64,7 @@ class QgsPointCloud3DSymbolHandler // : public QgsFeature3DHandler
struct PointData
{
QVector<QVector3D> positions; // contains triplets of float x,y,z for each point
QVector<char> classes;
QVector<float> parameter;
};

protected:
Expand Down Expand Up @@ -105,7 +105,7 @@ class QgsPointCloud3DGeometry: public Qt3DRender::QGeometry
void makeVertexBuffer( const QgsPointCloud3DSymbolHandler::PointData &data );

Qt3DRender::QAttribute *mPositionAttribute = nullptr;
Qt3DRender::QAttribute *mClassAttribute = nullptr;
Qt3DRender::QAttribute *mParameterAttribute = nullptr;
Qt3DRender::QBuffer *mVertexBuffer = nullptr;
int mVertexCount = 0;
};
Expand Down
59 changes: 29 additions & 30 deletions src/3d/shaders/pointcloud.frag
@@ -1,7 +1,6 @@
#version 150

in float magnitude;
in float clsid;
in float parameter;

out vec4 color;

Expand All @@ -16,29 +15,29 @@ uniform sampler1D u_colorRampTexture; //
// Sets the color ramp value count, used to check the if not void
uniform int u_colorRampCount; //

vec4 clsidBasedRendering()
{
vec4 color;
if ( abs(clsid-2) < 0.1 ) // ground
color = vec4(1,1,0,1);
else if ( abs( clsid - 3 ) < 0.1 ) // low vegetation
color = vec4(0,0.4,0,1);
else if ( abs( clsid - 4 ) < 0.1 ) // medium vegetation
color = vec4(0,0.6,0,1);
else if ( abs( clsid - 5 ) < 0.1 ) // high vegetation
color = vec4(0,1,0,1);
else if ( abs( clsid - 12 ) < 0.1 ) // overlaps
{
color = vec4(1,0,0,1);
discard; // skip overlaps
}
else
{
color = vec4(0,1,1,1);
//discard;
}
return color;
}
//vec4 clsidBasedRendering()
//{
// vec4 color;
// if ( abs(clsid-2) < 0.1 ) // ground
// color = vec4(1,1,0,1);
// else if ( abs( clsid - 3 ) < 0.1 ) // low vegetation
// color = vec4(0,0.4,0,1);
// else if ( abs( clsid - 4 ) < 0.1 ) // medium vegetation
// color = vec4(0,0.6,0,1);
// else if ( abs( clsid - 5 ) < 0.1 ) // high vegetation
// color = vec4(0,1,0,1);
// else if ( abs( clsid - 12 ) < 0.1 ) // overlaps
// {
// color = vec4(1,0,0,1);
// discard; // skip overlaps
// }
// else
// {
// color = vec4(0,1,1,1);
// //discard;
// }
// return color;
//}

vec3 linearColorRamp()
{
Expand All @@ -62,12 +61,12 @@ vec3 linearColorRamp()
float value1=colorRampLine1.x;
float value2=colorRampLine2.x;

if (magnitude<=value1 )
if (parameter <= value1 )
return color1;

if (magnitude>value1 && magnitude<=value2)
if (parameter > value1 && parameter <= value2)
{
float mixValue=(magnitude-value1)/(value2-value1);
float mixValue=(parameter - value1)/(value2-value1);
return mix(color1,color2,mixValue);
}
}
Expand All @@ -89,7 +88,7 @@ vec3 discreteColorRamp()
vec4 colorRampLine=texelFetch(u_colorRampTexture,i,0);
color=colorRampLine.yzw;
float value=colorRampLine.x;
if ( isinf(value) || magnitude<value)
if ( isinf(value) || parameter < value)
return color;
}

Expand All @@ -105,7 +104,7 @@ vec3 exactColorRamp()
vec4 colorRampLine = texelFetch( u_colorRampTexture, i, 0 );
vec3 color=colorRampLine.yzw;
float value=colorRampLine.x;
if ( abs( magnitude - value ) < 0.01 )
if ( abs( parameter - value ) < 0.01 )
return color;
}

Expand Down

0 comments on commit 5e76bc6

Please sign in to comment.