Skip to content

Commit

Permalink
move handler to qgspointcloud3dsymbol_p
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 a271e81 commit 05149fa
Show file tree
Hide file tree
Showing 5 changed files with 418 additions and 404 deletions.
1 change: 0 additions & 1 deletion python/3d/3d_auto.sip
Expand Up @@ -24,4 +24,3 @@
%Include auto_generated/symbols/qgspointcloud3dsymbol.sip
%Include auto_generated/qgs3dmapexportsettings.sip
%Include auto_generated/qgscolorramptexture.sip
%Include auto_generated/symbols/qgspointcloud3dsymbol_p.sip
304 changes: 0 additions & 304 deletions src/3d/qgspointcloudlayerchunkloader_p.cpp
Expand Up @@ -43,310 +43,6 @@

///@cond PRIVATE

QgsPointCloud3DSymbolHandler::QgsPointCloud3DSymbolHandler( QgsPointCloud3DSymbol *symbol )
{
mSymbol.reset( symbol ) ;
}

void QgsPointCloud3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, QgsPointCloud3DSymbolHandler::PointData &out, bool selected )
{
Q_UNUSED( selected )
Q_UNUSED( context )

if ( out.positions.empty() )
return;

// Geometry
Qt3DRender::QGeometry *geom = makeGeometry( parent, out );//new QgsPointCloud3DGeometry( parent, out, mSymbol.get() );
Qt3DRender::QGeometryRenderer *gr = new Qt3DRender::QGeometryRenderer;
gr->setPrimitiveType( Qt3DRender::QGeometryRenderer::Points );
gr->setVertexCount( out.positions.count() );
gr->setGeometry( geom );

// Transform
Qt3DCore::QTransform *tr = new Qt3DCore::QTransform;

// Material
Qt3DRender::QMaterial *mat = new Qt3DRender::QMaterial;
if ( mSymbol )
mSymbol->fillMaterial( mat );

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" ) ) ) );

Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass( mat );
renderPass->setShaderProgram( shaderProgram );

Qt3DRender::QPointSize *pointSize = new Qt3DRender::QPointSize( renderPass );
pointSize->setSizeMode( Qt3DRender::QPointSize::Programmable ); // supported since OpenGL 3.2
pointSize->setValue( mSymbol ? mSymbol->pointSize() : 1.0f );
renderPass->addRenderState( pointSize );

// without this filter the default forward renderer would not render this
Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey;
filterKey->setName( QStringLiteral( "renderingStyle" ) );
filterKey->setValue( "forward" );

Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
technique->addRenderPass( renderPass );
technique->addFilterKey( filterKey );
technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
technique->graphicsApiFilter()->setMajorVersion( 3 );
technique->graphicsApiFilter()->setMinorVersion( 1 );

Qt3DRender::QEffect *eff = new Qt3DRender::QEffect;
eff->addTechnique( technique );
mat->setEffect( eff );

// All together
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
entity->addComponent( gr );
entity->addComponent( tr );
entity->addComponent( mat );
entity->setParent( parent );
// cppcheck wrongly believes entity will leak
// cppcheck-suppress memleak
}

QgsSingleColorPointCloud3DSymbolHandler::QgsSingleColorPointCloud3DSymbolHandler( QgsPointCloud3DSymbol *symbol )
: QgsPointCloud3DSymbolHandler( symbol )
{

}

bool QgsSingleColorPointCloud3DSymbolHandler::prepare( const Qgs3DRenderContext &context )
{
Q_UNUSED( context )
return true;
}

void QgsSingleColorPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const IndexedPointCloudNode &n, const Qgs3DRenderContext &context )
{
QgsPointCloudAttributeCollection attributes;
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "X" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Y" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Z" ), QgsPointCloudAttribute::Int32 ) );

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
if ( !block )
return;

const char *ptr = block->data();
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();

for ( int i = 0; i < count; ++i )
{
qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );

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() ) );
}
}

void QgsSingleColorPointCloud3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
{
makeEntity( parent, context, outNormal, false );
}

Qt3DRender::QGeometry *QgsSingleColorPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, const QgsPointCloud3DSymbolHandler::PointData &data )
{
return new QgsSingleColorPointCloud3DGeometry( parent, data, mSymbol.get() );
}

QgsColorRampPointCloud3DSymbolHandler::QgsColorRampPointCloud3DSymbolHandler( QgsPointCloud3DSymbol *symbol )
: QgsPointCloud3DSymbolHandler( symbol )
{

}

bool QgsColorRampPointCloud3DSymbolHandler::prepare( const Qgs3DRenderContext &context )
{
Q_UNUSED( context )
return true;
}

void QgsColorRampPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const IndexedPointCloudNode &n, const Qgs3DRenderContext &context )
{
QgsPointCloudAttributeCollection attributes;
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "X" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Y" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Z" ), QgsPointCloudAttribute::Int32 ) );

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

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
if ( !block )
return;

const char *ptr = block->data();
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();

for ( int i = 0; i < count; ++i )
{
qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
float iParam = 0.0f;
if ( parameterAttribute )
{
switch ( parameterAttribute->type() )
{
case QgsPointCloudAttribute::DataType::Char:
iParam = *( char * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Short:
iParam = *( short * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Int32:
iParam = *( qint32 * )( ptr + i * recordSize + 12 );
break;
case QgsPointCloudAttribute::DataType::Float:
iParam = *( float * )( 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() ) );
if ( parameterAttribute && parameterAttribute->name() == "X" )
outNormal.parameter.push_back( x );
else if ( parameterAttribute && parameterAttribute->name() == "Y" )
outNormal.parameter.push_back( y );
else if ( parameterAttribute && parameterAttribute->name() == "Z" )
outNormal.parameter.push_back( z );
else
outNormal.parameter.push_back( iParam );
}
}

void QgsColorRampPointCloud3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
{
makeEntity( parent, context, outNormal, false );
}

QgsPointCloud3DGeometry *QgsColorRampPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, const QgsPointCloud3DSymbolHandler::PointData &data )
{
return new QgsColorRampPointCloud3DGeometry( parent, data, mSymbol.get() );
}

QgsRGBPointCloud3DSymbolHandler::QgsRGBPointCloud3DSymbolHandler( QgsPointCloud3DSymbol *symbol )
: QgsPointCloud3DSymbolHandler( symbol )
{

}

bool QgsRGBPointCloud3DSymbolHandler::prepare( const Qgs3DRenderContext &context )
{
Q_UNUSED( context )
return true;
}

void QgsRGBPointCloud3DSymbolHandler::processNode( QgsPointCloudIndex *pc, const IndexedPointCloudNode &n, const Qgs3DRenderContext &context )
{
QgsPointCloudAttributeCollection attributes;
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "X" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Y" ), QgsPointCloudAttribute::Int32 ) );
attributes.push_back( QgsPointCloudAttribute( QStringLiteral( "Z" ), QgsPointCloudAttribute::Int32 ) );

if ( mSymbol.get()->renderingStyle() == QgsPointCloud3DSymbol::RGBRendering )
{
attributes.push_back( QgsPointCloudAttribute( "Red", QgsPointCloudAttribute::DataType::Short ) );
attributes.push_back( QgsPointCloudAttribute( "Green", QgsPointCloudAttribute::DataType::Short ) );
attributes.push_back( QgsPointCloudAttribute( "Blue", QgsPointCloudAttribute::DataType::Short ) );
}

QgsPointCloudRequest request;
request.setAttributes( attributes );
std::unique_ptr<QgsPointCloudBlock> block( pc->nodeData( n, request ) );
if ( !block )
return;

const char *ptr = block->data();
int count = block->pointCount();
const std::size_t recordSize = attributes.pointRecordSize();

const QgsVector3D scale = pc->scale();
const QgsVector3D offset = pc->offset();

for ( int i = 0; i < count; ++i )
{
qint32 ix = *( qint32 * )( ptr + i * recordSize + 0 );
qint32 iy = *( qint32 * )( ptr + i * recordSize + 4 );
qint32 iz = *( qint32 * )( ptr + i * recordSize + 8 );
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() ) );

QVector3D color( 0.0f, 0.0f, 0.0f );
if ( recordSize > 10 )
{
short ir = *( short * )( ptr + i * recordSize + 12 );
color.setX( ( ( float )ir ) / 256.0f );
}
if ( recordSize > 12 )
{
short ig = *( short * )( ptr + i * recordSize + 14 );
color.setY( ( ( float )ig ) / 256.0f );
}
if ( recordSize > 14 )
{
short ib = *( short * )( ptr + i * recordSize + 16 );
color.setZ( ( ( float )ib ) / 256.0f );
}
outNormal.colors.push_back( color );
}
}

void QgsRGBPointCloud3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
{
makeEntity( parent, context, outNormal, false );
}

Qt3DRender::QGeometry *QgsRGBPointCloud3DSymbolHandler::makeGeometry( Qt3DCore::QNode *parent, const QgsPointCloud3DSymbolHandler::PointData &data )
{
return new QgsRGBPointCloud3DGeometry( parent, data, mSymbol.get() );
}

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

Expand Down

0 comments on commit 05149fa

Please sign in to comment.