Skip to content
Permalink
Browse files

Some code cleanup

  • Loading branch information
NEDJIMAbelgacem committed Jul 9, 2020
1 parent 8278693 commit ed035b94d40ca53080b6da48535c606cb521d352
@@ -75,7 +75,7 @@ void Qgs3DExportObject::setupTextureCoordinates( const QVector<float> &texturesB

void Qgs3DExportObject::objectBounds( float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ )
{
for ( int vertice : mIndexes )
for ( unsigned int vertice : mIndexes )
{
int heightIndex = ( vertice - 1 ) * 3 + 1;
minX = std::min( minX, mVertxPosition[heightIndex - 1] );
@@ -86,7 +86,7 @@ class Qgs3DExportObject : public QObject
QVector<float> mVertxPosition;
QVector<float> mNormals;
QVector<float> mTexturesUV;
QVector<int> mIndexes;
QVector<unsigned int> mIndexes;

QImage mTextureImage;

@@ -780,9 +780,30 @@ void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings )

for ( QgsMapLayer *layer : mLayerEntities.keys() )
{
exporter.parseEntity( mLayerEntities[layer] );
QgsMapLayerType layerType = layer->type();
Qt3DCore::QEntity *rootEntity = mLayerEntities[layer];
switch ( layerType )
{
case QgsMapLayerType::VectorLayer:
qDebug() << "Parsing vector layer";
exporter.parseVectorLayerEntity( rootEntity );
break;
case QgsMapLayerType::RasterLayer:
qDebug() << "Raster layer skipped";
break;
case QgsMapLayerType::PluginLayer:
qDebug() << "Plugin layer skipped";
break;
case QgsMapLayerType::MeshLayer: //!< Added in 3.2
qDebug() << "Mesh layer skipped";
break;
case QgsMapLayerType::VectorTileLayer: //!< Added in 3.14
qDebug() << "Vector tile layer skipped";
break;
}
}
exporter.parseEntity( mTerrain );
if ( mTerrain != nullptr )
exporter.parseTerrain( mTerrain );

exporter.save( exportSettings.sceneName(), exportSettings.sceneFolderPath() );
}
@@ -48,13 +48,18 @@
#include "qgs3dexportobject.h"
#include "qgsterraintextureimage_p.h"
#include "qgsterraintexturegenerator_p.h"
#include "qgsmesh3dgeometry_p.h"
#include <Qt3DRender/qbufferdatagenerator.h>
#include "qgsmeshlayer.h"
#include "qgsmesh3dentity_p.h"
#include "qgsmeshterraingenerator.h"

#include <numeric>

template<typename T>
QVector<T> getAttributeData( Qt3DRender::QAttribute *attribute )
QVector<T> getAttributeData( Qt3DRender::QAttribute *attribute, QByteArray data )
{
QByteArray data = attribute->buffer()->data();
// QByteArray data = attribute->buffer()->data();
uint bytesOffset = attribute->byteOffset();
uint bytesStride = attribute->byteStride();
uint vertexSize = attribute->vertexSize();
@@ -78,17 +83,15 @@ QVector<T> getAttributeData( Qt3DRender::QAttribute *attribute )
}

template<>
QVector<unsigned int> getAttributeData<unsigned int>( Qt3DRender::QAttribute *attribute )
QVector<unsigned int> getAttributeData<unsigned int>( Qt3DRender::QAttribute *attribute, QByteArray data )
{
QByteArray data = attribute->buffer()->data();

QVector<unsigned int> result;
for ( int i = 0; i < data.size(); i += sizeof( unsigned int ) )
{
// maybe a problem with indienness can happen?
unsigned int v;
char *vArr = ( char * )&v;
for ( int k = 0; k < ( int )sizeof( unsigned int ); ++k )
for ( unsigned int k = 0; k < sizeof( unsigned int ); ++k )
{
vArr[k] = data.at( i + k );
}
@@ -216,17 +219,10 @@ Qgs3DSceneExporter::Qgs3DSceneExporter( Qt3DCore::QNode *parent )

}

void Qgs3DSceneExporter::parseEntity( Qt3DCore::QEntity *entity )
void Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity )
{
if ( entity == nullptr ) return;
// check if the current entity is a terrain tile
QgsTerrainTileEntity *terrainTile = qobject_cast<QgsTerrainTileEntity *>( entity );
if ( terrainTile != nullptr )
{
parseEntity( terrainTile );
return;
}

// We iterate over every component and find components that represent a tessellated geometry
for ( Qt3DCore::QComponent *c : entity->components() )
{
Qt3DRender::QGeometryRenderer *comp = qobject_cast<Qt3DRender::QGeometryRenderer *>( c );
@@ -236,26 +232,21 @@ void Qgs3DSceneExporter::parseEntity( Qt3DCore::QEntity *entity )
QgsTessellatedPolygonGeometry *tessellated = qobject_cast<QgsTessellatedPolygonGeometry *>( geom );
if ( tessellated != nullptr )
{
process( tessellated );
processPolygonGeometry( tessellated );
continue;
}

// Qt3DExtras::QPlaneGeometry *plane = qobject_cast<Qt3DExtras::QPlaneGeometry *>( geom );
// if ( plane != nullptr )
// {
// process( plane );
// continue;
// }

// pocessPoistionAttributes(geom);
}

for ( QObject *child : entity->children() )
{
Qt3DCore::QEntity *childEntity = qobject_cast<Qt3DCore::QEntity *>( child );
if ( childEntity != nullptr ) parseEntity( childEntity );
if ( childEntity != nullptr ) parseVectorLayerEntity( childEntity );
}
}

void Qgs3DSceneExporter::parseEntity( QgsTerrainEntity *terrain )
void Qgs3DSceneExporter::parseTerrain( QgsTerrainEntity *terrain )
{
const Qgs3DMapSettings &settings = terrain->map3D();
QgsChunkNode *root = terrain->rootNode();
@@ -425,8 +416,13 @@ void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity, QgsTerr
float scale = transform->scale();
QVector3D translation = transform->translation();

QVector<float> positionBuffer = getAttributeData<float>( tileGeometry->positionAttribute() );
QVector<unsigned int> indexBuffer = getAttributeData<unsigned int>( tileGeometry->indexAttribute() );
Qt3DRender::QAttribute *positionAttribute = tileGeometry->positionAttribute();
QByteArray positionBytes = positionAttribute->buffer()->data();
QVector<float> positionBuffer = getAttributeData<float>( positionAttribute, positionBytes );

Qt3DRender::QAttribute *indexAttribute = tileGeometry->indexAttribute();
QByteArray indexBytes = indexAttribute->buffer()->data();
QVector<unsigned int> indexBuffer = getAttributeData<unsigned int>( indexAttribute, indexBytes );

Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "DEM_tile" ), "", this );
mObjects.push_back( object );
@@ -436,34 +432,42 @@ void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity, QgsTerr

if ( mExportNormals )
{
QVector<float> normalsBuffer = getAttributeData<float>( tileGeometry->normalAttribute() );
Qt3DRender::QAttribute *normalsAttributes = tileGeometry->normalAttribute();
QByteArray normalsBytes = normalsAttributes->buffer()->data();
QVector<float> normalsBuffer = getAttributeData<float>( normalsAttributes, normalsBytes );
object->setupNormalCoordinates( normalsBuffer );
}

if ( mExportTextures )
{
QVector<float> texCoordsBuffer = getAttributeData<float>( tileGeometry->texCoordsAttribute() );
Qt3DRender::QAttribute *texCoordsAttribute = tileGeometry->texCoordsAttribute();
QByteArray texCoordsBytes = texCoordsAttribute->buffer()->data();
QVector<float> texCoordsBuffer = getAttributeData<float>( texCoordsAttribute, texCoordsBytes );
object->setupTextureCoordinates( texCoordsBuffer );

QImage img = textureGenerator->renderSynchronously( tileEntity->textureImage()->imageExtent(), tileEntity->textureImage()->imageDebugText() );
object->setTextureImage( img );
}
}

void Qgs3DSceneExporter::processAttribute( Qt3DRender::QAttribute *attribute )
void Qgs3DSceneExporter::processPolygonGeometry( QgsTessellatedPolygonGeometry *geom )
{
QVector<float> floatData = getAttributeData<float>( attribute );

Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "geometry" ), "", this );
Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "polygon_geometry" ), "", this );
mObjects.push_back( object );

object->setupPositionCoordinates( floatData );
}
Qt3DRender::QAttribute *positionAttribute = geom->mPositionAttribute;
QByteArray positionBytes = positionAttribute->buffer()->data();
QVector<float> positionData = getAttributeData<float>( positionAttribute, positionBytes );
object->setupPositionCoordinates( positionData );

void Qgs3DSceneExporter::process( QgsTessellatedPolygonGeometry *geom )
{
// Just use position attributes for now
processAttribute( geom->mPositionAttribute );
if ( mExportNormals )
{
Qt3DRender::QAttribute *normalsAttribute = geom->mNormalAttribute;
QByteArray normalsBytes = normalsAttribute->buffer()->data();
QVector<float> normalsData = getAttributeData<float>( normalsAttribute, normalsBytes );
object->setupNormalCoordinates( normalsData );
}
// TODO: handle textures
}

void Qgs3DSceneExporter::save( const QString &sceneName, const QString &sceneFolderPath )
@@ -515,7 +519,7 @@ QString Qgs3DSceneExporter::getObjectName( const QString &name )
QString ret = name;
if ( usedObjectNamesCounter.contains( name ) )
{
ret = usedObjectNamesCounter[name];
ret = QString( "%1%2" ).arg( name ).arg( usedObjectNamesCounter[name] );
usedObjectNamesCounter[name]++;
}
else
@@ -46,12 +46,12 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity
Qgs3DSceneExporter( Qt3DCore::QNode *parent = nullptr );

/**
* Creates necessary export objects from entity if it represents valid entity
* Creates necessary export objects from entity if it represents valid vector layer entity
* If the entity doesn't define exportable object it will be ignored
*/
void parseEntity( Qt3DCore::QEntity *entity );
void parseVectorLayerEntity( Qt3DCore::QEntity *entity );
//! Creates terrain export objects from the terrain entity
void parseEntity( QgsTerrainEntity *terrain );
void parseTerrain( QgsTerrainEntity *terrain );
//! Saves the scene to a .obj file
void save( const QString &sceneName, const QString &sceneFolderPath );

@@ -86,9 +86,9 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity

private:
//! Processes the attribute directly by taking a position buffer and converting it to Qgs3DExportObject
void processAttribute( Qt3DRender::QAttribute *attribute );
//! Processes the tessellated polygons geometry and constructs Qgs3DExportObject from it
void process( QgsTessellatedPolygonGeometry *geom );
void pocessPoistionAttributes( Qt3DRender::QGeometry *geometry );
//! constructs Qgs3DExportObject from the polygon geometry
void processPolygonGeometry( QgsTessellatedPolygonGeometry *geom );

//! Returns a tile entity that contains the geometry to be exported and necessary scaling parameters
QgsTerrainTileEntity *getFlatTerrainEntity( QgsTerrainEntity *terrain, QgsChunkNode *node );

0 comments on commit ed035b9

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