Skip to content

Commit

Permalink
trying to export lines and points
Browse files Browse the repository at this point in the history
refactoring
  • Loading branch information
NEDJIMAbelgacem committed Jul 19, 2020
1 parent 5323fbe commit f57f21e
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 26 deletions.
35 changes: 26 additions & 9 deletions src/3d/qgs3dexportobject.cpp
Expand Up @@ -65,9 +65,9 @@ void Qgs3DExportObject::setupFaces( const QVector<uint> &facesIndexes )
insertIndexData<uint>( mIndexes, facesIndexes );
}

void Qgs3DExportObject::setupFaces( const QVector<quint16> &facesIndexes )
void Qgs3DExportObject::setupLine( const QVector<uint> &lineIndexes )
{
insertIndexData<quint16>( mIndexes, facesIndexes );
for ( int i = 0; i < mVertexPosition.size(); i += 3 ) mIndexes << i / 3 + 1;
}

void Qgs3DExportObject::setupNormalCoordinates( const QVector<float> &normalsBuffer )
Expand All @@ -94,6 +94,7 @@ void Qgs3DExportObject::setupPhongMaterial( const QgsPhongMaterialSettings &mate

void Qgs3DExportObject::objectBounds( float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ )
{
if ( mType != TriangularFaces ) return;
for ( unsigned int vertice : mIndexes )
{
int heightIndex = ( vertice - 1 ) * 3 + 1;
Expand Down Expand Up @@ -159,14 +160,30 @@ void Qgs3DExportObject::saveTo( QTextStream &out, float scale, const QVector3D &
return QString( "%1" ).arg( negativeIndex );
};

// Construct faces
for ( int i = 0; i < mIndexes.size(); i += 3 )
if ( mType == TriangularFaces )
{
if ( mIndexes[i] == mIndexes[i + 1] && mIndexes[i + 1] == mIndexes[i + 2] )
continue;
out << "f " << getVertexIndex( mIndexes[i] );
out << " " << getVertexIndex( mIndexes[i + 1] );
out << " " << getVertexIndex( mIndexes[i + 2] );
// Construct triangular faces
for ( int i = 0; i < mIndexes.size(); i += 3 )
{
if ( mIndexes[i] == mIndexes[i + 1] && mIndexes[i + 1] == mIndexes[i + 2] )
continue;
out << "f " << getVertexIndex( mIndexes[i] );
out << " " << getVertexIndex( mIndexes[i + 1] );
out << " " << getVertexIndex( mIndexes[i + 2] );
out << "\n";
}
}
else if ( mType == LineStrip )
{
out << "l";
for ( int i : mIndexes ) out << " " << getVertexIndex( i );
out << "\n";
}
else if ( mType == Points )
{
out << "p";
for ( int i = 0; i < mVertexPosition.size(); i += 3 )
out << " " << getVertexIndex( i / 3 + 1 );
out << "\n";
}
}
Expand Down
16 changes: 14 additions & 2 deletions src/3d/qgs3dexportobject.h
Expand Up @@ -36,6 +36,12 @@ class Qgs3DExportObject : public QObject
{
Q_OBJECT
public:
enum ObjectType
{
TriangularFaces,
LineStrip,
Points
};

/**
* \brief Qgs3DExportObject
Expand All @@ -54,6 +60,11 @@ class Qgs3DExportObject : public QObject
//! Sets the object name
void setName( const QString &name ) { mName = name; }

//! Returns the object type
ObjectType type() const { return mType; }
//! Sets the object type
void setType( ObjectType type ) { mType = type; }

//! Returns whether object edges will look smooth
bool smoothEdges() { return mSmoothEdges; }
//! Sets whether triangles edges will look smooth
Expand All @@ -63,8 +74,8 @@ class Qgs3DExportObject : public QObject
void setupPositionCoordinates( const QVector<float> &positionsBuffer, float scale = 1.0f, const QVector3D translation = QVector3D( 0, 0, 0 ) );
//! Sets the faces in facesIndexes to the faces in the object
void setupFaces( const QVector<uint> &facesIndexes );
//! Sets the faces in facesIndexes to the faces in the object
void setupFaces( const QVector<quint16> &facesIndexes );
//! sets line vertex indexes
void setupLine( const QVector<uint> &facesIndexes );

//! Sets normal coordinates for each vertex
void setupNormalCoordinates( const QVector<float> &normalsBuffer );
Expand Down Expand Up @@ -95,6 +106,7 @@ class Qgs3DExportObject : public QObject

private:
QString mName;
ObjectType mType = ObjectType::TriangularFaces;
QString mParentName;
QVector<float> mVertexPosition;
QVector<float> mNormals;
Expand Down
112 changes: 98 additions & 14 deletions src/3d/qgs3dsceneexporter.cpp
Expand Up @@ -74,13 +74,13 @@
#include "qgspoint3dsymbol.h"
#include "qgsrulebased3drenderer.h"
#include "qgs3dutils.h"
#include "qgsbillboardgeometry.h"

#include <numeric>

template<typename T>
QVector<T> getAttributeData( Qt3DRender::QAttribute *attribute, QByteArray data )
{
// QByteArray data = attribute->buffer()->data();
uint bytesOffset = attribute->byteOffset();
uint bytesStride = attribute->byteStride();
uint vertexSize = attribute->vertexSize();
Expand All @@ -104,24 +104,44 @@ QVector<T> getAttributeData( Qt3DRender::QAttribute *attribute, QByteArray data
}

template<typename T>
QVector<uint> getIndexData( QByteArray data )
QVector<uint> _getIndexDataImplementation( QByteArray data )
{
QVector<uint> result;
for ( int i = 0; i < data.size(); i += sizeof( T ) )
{
// maybe a problem with indienness can happen?
T v;
char *vArr = ( char * )&v;
for ( T k = 0; k < sizeof( T ); ++k )
{
for ( unsigned long k = 0; k < sizeof( T ); ++k )
vArr[k] = data.at( i + k );
}
result.push_back( ( uint ) v );
}

return result;
}

QVector<uint> getIndexData( Qt3DRender::QAttribute *indexAttribute, QByteArray data )
{
switch ( indexAttribute->vertexBaseType() )
{
case Qt3DRender::QAttribute::VertexBaseType::Int:
return _getIndexDataImplementation<int>( data );
case Qt3DRender::QAttribute::VertexBaseType::UnsignedInt:
return _getIndexDataImplementation<uint>( data );
case Qt3DRender::QAttribute::VertexBaseType::Short:
return _getIndexDataImplementation<short>( data );
case Qt3DRender::QAttribute::VertexBaseType::UnsignedShort:
return _getIndexDataImplementation<ushort>( data );
case Qt3DRender::QAttribute::VertexBaseType::Byte:
return _getIndexDataImplementation<char>( data );
case Qt3DRender::QAttribute::VertexBaseType::UnsignedByte:
return _getIndexDataImplementation<uchar>( data );
default:
qDebug() << "WARNING: Probably trying to get index data using an attribute that has vertex data at " << __FILE__ << ":" << __LINE__;
break;
}
return QVector<uint>();
}

QByteArray getData( Qt3DRender::QBuffer *buffer )
{
QByteArray bytes = buffer->data();
Expand Down Expand Up @@ -224,7 +244,9 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV
const QgsLine3DSymbol *lineSymbol = dynamic_cast<const QgsLine3DSymbol *>( symbol );
if ( lineSymbol->renderAsSimpleLines() )
{
//TODO: handle simple line geometries in some way
QVector<Qgs3DExportObject *> objs = processLines( entity );
mObjects << objs;
return objs.size() != 0;
}
else
{
Expand Down Expand Up @@ -270,6 +292,9 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV
}
else if ( pointSymbol->shape() == QgsPoint3DSymbol::Billboard )
{
Qgs3DExportObject *obj = processPoints( entity );
if ( obj != nullptr ) mObjects << obj;
if ( obj != nullptr ) return true;
}
else
{
Expand Down Expand Up @@ -348,7 +373,6 @@ QgsTerrainTileEntity *Qgs3DSceneExporter::getMeshTerrainEntity( QgsTerrainEntity
QgsMeshTerrainTileLoader *loader = qobject_cast<QgsMeshTerrainTileLoader *>( generator->createChunkLoader( node ) );
// TODO: export textures
QgsTerrainTileEntity *tileEntity = qobject_cast<QgsTerrainTileEntity *>( loader->createEntity( this ) );
delete generator;
return tileEntity;
}

Expand Down Expand Up @@ -376,7 +400,7 @@ void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity )
// Generate index data
Qt3DRender::QAttribute *indexAttribute = tileGeometry->indexAttribute();
QByteArray indexBytes = getData( indexAttribute->buffer() );
QVector<uint> indexesBuffer = getIndexData<quint16>( indexBytes );
QVector<uint> indexesBuffer = getIndexData( indexAttribute, indexBytes );

Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( QStringLiteral( "Flat_tile" ) ), "", this );
mObjects.push_back( object );
Expand All @@ -387,7 +411,7 @@ void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity )

if ( mExportNormals )
{
// Evert
// Everts
QVector<float> normalsBuffer;
for ( int i = 0; i < positionBuffer.size(); i += 3 ) normalsBuffer << 0.0f << 1.0f << 0.0f;
object->setupNormalCoordinates( normalsBuffer );
Expand Down Expand Up @@ -428,7 +452,7 @@ void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity )

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

Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( QStringLiteral( "DEM_tile" ) ), "", this );
mObjects.push_back( object );
Expand Down Expand Up @@ -487,7 +511,7 @@ QVector<Qgs3DExportObject *> Qgs3DSceneExporter::processInstancedPointGeometry(
QByteArray vertexBytes = getData( positionAttribute->buffer() );
QByteArray indexBytes = getData( indexAttribute->buffer() );
QVector<float> positionData = getAttributeData<float>( positionAttribute, vertexBytes );
QVector<uint> indexData = getIndexData<quint16>( indexBytes );
QVector<uint> indexData = getIndexData( indexAttribute, indexBytes );

Qt3DRender::QAttribute *instanceDataAttribute = findAttribute( geometry, QStringLiteral( "pos" ), Qt3DRender::QAttribute::VertexAttribute );
QByteArray instancePositionBytes = getData( instanceDataAttribute->buffer() );
Expand Down Expand Up @@ -563,8 +587,7 @@ Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeo
if ( indexAttribute != nullptr )
{
indexBytes = getData( indexAttribute->buffer() );
if ( indexAttribute->vertexBaseType() == Qt3DRender::QAttribute::VertexBaseType::UnsignedInt ) indexData = getIndexData<quint32>( indexBytes );
if ( indexAttribute->vertexBaseType() == Qt3DRender::QAttribute::VertexBaseType::UnsignedShort ) indexData = getIndexData<quint16>( indexBytes );
indexData = getIndexData( indexAttribute, indexBytes );
}

if ( positionAttribute != nullptr )
Expand Down Expand Up @@ -600,6 +623,67 @@ Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeo
return object;
}

QVector<Qgs3DExportObject *> Qgs3DSceneExporter::processLines( Qt3DCore::QEntity *entity )
{
QVector<Qgs3DExportObject *> objs;
QList<Qt3DRender::QGeometryRenderer *> renderers = entity->findChildren<Qt3DRender::QGeometryRenderer *>();
for ( Qt3DRender::QGeometryRenderer *renderer : renderers )
{
if ( renderer->primitiveType() != Qt3DRender::QGeometryRenderer::LineStripAdjacency ) continue;
Qt3DRender::QGeometry *geom = renderer->geometry();
Qt3DRender::QAttribute *positionAttribute = findAttribute( geom, Qt3DRender::QAttribute::defaultPositionAttributeName(), Qt3DRender::QAttribute::VertexAttribute );
Qt3DRender::QAttribute *indexAttribute = nullptr;
for ( Qt3DRender::QAttribute *attribute : geom->attributes() )
{
if ( attribute->attributeType() == Qt3DRender::QAttribute::IndexAttribute )
{
indexAttribute = attribute;
break;
}
}
if ( positionAttribute == nullptr || indexAttribute == nullptr )
{
qDebug() << "WARNING: position or index attribute was not found at " << __FILE__ << ":" << __LINE__;
continue;
}

QByteArray vertexBytes = getData( positionAttribute->buffer() );
QByteArray indexBytes = getData( indexAttribute->buffer() );
QVector<float> positionData = getAttributeData<float>( positionAttribute, vertexBytes );
QVector<uint> indexData = getIndexData( indexAttribute, indexBytes );

Qgs3DExportObject *exportObject = new Qgs3DExportObject( getObjectName( "line" ), "", this );
exportObject->setType( Qgs3DExportObject::LineStrip );
exportObject->setupPositionCoordinates( positionData );
exportObject->setupLine( indexData );

objs.push_back( exportObject );
}
return objs;
}

Qgs3DExportObject *Qgs3DSceneExporter::processPoints( Qt3DCore::QEntity *entity )
{
QVector<float> points;
QList<Qt3DRender::QGeometryRenderer *> renderers = entity->findChildren<Qt3DRender::QGeometryRenderer *>();
for ( Qt3DRender::QGeometryRenderer *renderer : renderers )
{
Qt3DRender::QGeometry *geometry = qobject_cast<QgsBillboardGeometry *>( renderer->geometry() );
if ( geometry == nullptr )
continue;
Qt3DRender::QAttribute *positionAttribute = findAttribute( geometry, Qt3DRender::QAttribute::defaultPositionAttributeName(), Qt3DRender::QAttribute::VertexAttribute );
QByteArray positionBytes = getData( positionAttribute->buffer() );
if ( positionBytes.size() == 0 )
continue;
QVector<float> positions = getAttributeData<float>( positionAttribute, positionBytes );
points << positions;
}
Qgs3DExportObject *obj = new Qgs3DExportObject( getObjectName( "points" ), "", this );
obj->setType( Qgs3DExportObject::Points );
obj->setupPositionCoordinates( points );
return obj;
}

void Qgs3DSceneExporter::save( const QString &sceneName, const QString &sceneFolderPath )
{
QString objFilePath = QDir( sceneFolderPath ).filePath( sceneName + QStringLiteral( ".obj" ) );
Expand Down
4 changes: 4 additions & 0 deletions src/3d/qgs3dsceneexporter.h
Expand Up @@ -100,6 +100,10 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity
QVector<Qgs3DExportObject *> processSceneLoaderGeometries( Qt3DRender::QSceneLoader *sceneLoader );
//! Constructs Qgs3DExportObject from geometry renderer
Qgs3DExportObject *processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, float sceneScale = 1.0f, QVector3D sceneTranslation = QVector3D( 0.0f, 0.0f, 0.0f ) );
//! Constricts Qgs3DExportObject from line entity
QVector<Qgs3DExportObject *> processLines( Qt3DCore::QEntity *entity );
//! Constricts Qgs3DExportObject from billboard point entity
Qgs3DExportObject *processPoints( Qt3DCore::QEntity *entity );

//! Returns a tile entity that contains the geometry to be exported and necessary scaling parameters
QgsTerrainTileEntity *getFlatTerrainEntity( QgsTerrainEntity *terrain, QgsChunkNode *node );
Expand Down
2 changes: 2 additions & 0 deletions src/3d/symbols/qgsbillboardgeometry.cpp
Expand Up @@ -31,6 +31,8 @@ QgsBillboardGeometry::QgsBillboardGeometry( Qt3DCore::QNode *parent )
mPositionAttribute->setBuffer( mVertexBuffer );
mPositionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
mPositionAttribute->setVertexSize( 3 );
mPositionAttribute->setByteOffset( 0 );
mPositionAttribute->setByteStride( 3 * sizeof( float ) );
mPositionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );

addAttribute( mPositionAttribute );
Expand Down
1 change: 0 additions & 1 deletion src/3d/symbols/qgsbillboardgeometry.h
Expand Up @@ -45,7 +45,6 @@ class QgsBillboardGeometry : public Qt3DRender::QGeometry

//! Returns the number of points.
int count() const;

signals:
//! Signal when the number of points changed.
void countChanged( int count );
Expand Down
5 changes: 5 additions & 0 deletions src/3d/symbols/qgslinevertexdata_p.cpp
Expand Up @@ -91,16 +91,21 @@ Qt3DRender::QGeometry *QgsLineVertexData::createGeometry( Qt3DCore::QNode *paren
positionAttribute->setBuffer( vertexBuffer );
positionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
positionAttribute->setVertexSize( 3 );
positionAttribute->setByteStride( 3 * sizeof( float ) );
positionAttribute->setByteOffset( 0 );
positionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );

Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute( parent );
indexAttribute->setAttributeType( Qt3DRender::QAttribute::IndexAttribute );
indexAttribute->setBuffer( indexBuffer );
indexAttribute->setByteOffset( 0 );
indexAttribute->setByteStride( sizeof( uint ) );
indexAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedInt );

Qt3DRender::QGeometry *geom = new Qt3DRender::QGeometry;
geom->addAttribute( positionAttribute );
geom->addAttribute( indexAttribute );

return geom;
}

Expand Down
1 change: 1 addition & 0 deletions src/3d/symbols/qgspoint3dsymbol_p.cpp
Expand Up @@ -244,6 +244,7 @@ Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer( const
instanceDataAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
instanceDataAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
instanceDataAttribute->setVertexSize( 3 );
instanceDataAttribute->setByteOffset( 0 );
instanceDataAttribute->setDivisor( 1 );
instanceDataAttribute->setBuffer( instanceBuffer );
instanceDataAttribute->setCount( count );
Expand Down

0 comments on commit f57f21e

Please sign in to comment.