Skip to content
Permalink
Browse files

Refactoring

  • Loading branch information
NEDJIMAbelgacem committed Jul 14, 2020
1 parent dffc35a commit babce717086bdf1854af7a4e0ccfebca31d45801
Showing with 86 additions and 136 deletions.
  1. +23 −37 src/3d/qgs3dexportobject.cpp
  2. +6 −8 src/3d/qgs3dexportobject.h
  3. +52 −90 src/3d/qgs3dsceneexporter.cpp
  4. +5 −1 src/3d/qgs3dsceneexporter.h
@@ -20,8 +20,27 @@
#include <QDir>
#include <QImage>

#include <Qt3DRender/QAttribute>
#include <Qt3DRender/QBuffer>
#include <Qt3DRender/QBufferDataGenerator>
#include <Qt3DRender/QBufferDataGeneratorPtr>

#include "qgsphongmaterialsettings.h"


template<typename T>
void insertIndexData( QVector<uint> &vertexIndex, const QVector<T> &faceIndex )
{
for ( int i = 0; i < faceIndex.size(); i += 3 )
{
// skip invalid triangles
if ( faceIndex[i] == faceIndex[i + 1] && faceIndex[i + 1] == faceIndex[i + 2] )
continue;
for ( int j = 0; j < 3; ++j )
vertexIndex << faceIndex[i + j] + 1;
}
}

Qgs3DExportObject::Qgs3DExportObject( const QString &name, const QString &parentName, QObject *parent )
: QObject( parent )
, mName( name )
@@ -39,49 +58,16 @@ void Qgs3DExportObject::setupPositionCoordinates( const QVector<float> &position
mVertexPosition << positionsBuffer[i + j] * scale + translation[j];
}
}

for ( int i = 0; i < positionsBuffer.size() / 3; ++i )
{
mIndexes << i + 1;
}
}

void insertPositionData( QVector<float> &vertexPosition, const QVector<float> &positionsBuffer, float scale, const QVector3D translation )
{
for ( int i = 0; i < positionsBuffer.size(); i += 3 )
{
for ( int j = 0; j < 3; ++j )
{
vertexPosition << positionsBuffer[i + j] * scale + translation[j];
}
}
}

template<typename T>
void insertIndexData( QVector<uint> &vertexIndex, const QVector<T> &faceIndex )
{
for ( int i = 0; i < faceIndex.size(); i += 3 )
{
// skip invalid triangles
if ( faceIndex[i] == faceIndex[i + 1] && faceIndex[i + 1] == faceIndex[i + 2] )
continue;
for ( int j = 0; j < 3; ++j )
vertexIndex << faceIndex[i + j] + 1;
}
}

void Qgs3DExportObject::setupPositionCoordinates( const QVector<float> &positionsBuffer, const QVector<uint> &faceIndex, float scale, const QVector3D translation )
void Qgs3DExportObject::setupFaces( const QVector<uint> &facesIndexes )
{
// TODO: delete vertices that are not used
insertPositionData( mVertexPosition, positionsBuffer, scale, translation );
insertIndexData<uint>( mIndexes, faceIndex );
insertIndexData<uint>( mIndexes, facesIndexes );
}

void Qgs3DExportObject::setupPositionCoordinates( const QVector<float> &positionsBuffer, const QVector<quint16> &faceIndex, float scale, const QVector3D translation )
void Qgs3DExportObject::setupFaces( const QVector<quint16> &facesIndexes )
{
// TODO: delete vertices that are not used
insertPositionData( mVertexPosition, positionsBuffer, scale, translation );
insertIndexData<quint16>( mIndexes, faceIndex );
insertIndexData<quint16>( mIndexes, facesIndexes );
}

void Qgs3DExportObject::setupNormalCoordinates( const QVector<float> &normalsBuffer )
@@ -22,6 +22,8 @@
#include <QVector3D>
#include <QImage>

#include <Qt3DRender/QAttribute>

class QgsPhongMaterialSettings;

/**
@@ -59,14 +61,10 @@ class Qgs3DExportObject : public QObject

//! Sets positions coordinates from just one positions buffer (generates faces automatically) and does the translation and scaling
void setupPositionCoordinates( const QVector<float> &positionsBuffer, float scale = 1.0f, const QVector3D translation = QVector3D( 0, 0, 0 ) );
//! Sets positions coordinates from just one positions buffer and indexes buffer and does the translation and scaling
void setupPositionCoordinates( const QVector<float> &positionsBuffer, const QVector<unsigned int> &facesIndexes, float scale = 1.0f, const QVector3D translation = QVector3D( 0, 0, 0 ) );

/**
* Sets positions coordinates from just one positions buffer and indexes buffer and does the translation and scaling
* Overloaded for 16 bit integers
*/
void setupPositionCoordinates( const QVector<float> &positionsBuffer, const QVector<quint16> &facesIndexes, 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 normal coordinates for each vertex
void setupNormalCoordinates( const QVector<float> &normalsBuffer );
@@ -120,6 +120,17 @@ QVector<uint> getIndexData( QByteArray data )
return result;
}

QByteArray getData( Qt3DRender::QBuffer *buffer )
{
QByteArray bytes = buffer->data();
if ( bytes.isNull() )
{
Qt3DRender::QBufferDataGeneratorPtr dataGenerator = buffer->dataGenerator();
bytes = dataGenerator->operator()();
}
return bytes;
}

Qgs3DSceneExporter::Qgs3DSceneExporter( Qt3DCore::QNode *parent )
: Qt3DCore::QEntity( parent )
, mSmoothEdges( false )
@@ -302,21 +313,20 @@ void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity )

// Generate vertice data
Qt3DRender::QAttribute *positionAttribute = tileGeometry->positionAttribute();
Qt3DRender::QBufferDataGeneratorPtr positionDataGenerator = positionAttribute->buffer()->dataGenerator();
QByteArray verticesBytes = positionDataGenerator->operator()();
QByteArray verticesBytes = getData( positionAttribute->buffer() );
QVector<float> positionBuffer = getAttributeData<float>( positionAttribute, verticesBytes );

// Generate index data
Qt3DRender::QAttribute *indexAttribute = tileGeometry->indexAttribute();
Qt3DRender::QBufferDataGeneratorPtr indexDataGenerator = indexAttribute->buffer()->dataGenerator();
QByteArray indexBytes = indexDataGenerator->operator()();
QByteArray indexBytes = getData( indexAttribute->buffer() );
QVector<uint> indexesBuffer = getIndexData<quint16>( indexBytes );

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

object->setSmoothEdges( mSmoothEdges );
object->setupPositionCoordinates( positionBuffer, indexesBuffer, scale, translation );
object->setupPositionCoordinates( positionBuffer, scale, translation );
object->setupFaces( indexesBuffer );

if ( mExportNormals )
{
@@ -367,7 +377,8 @@ void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity )
mObjects.push_back( object );

object->setSmoothEdges( mSmoothEdges );
object->setupPositionCoordinates( positionBuffer, indexBuffer, scale, translation );
object->setupPositionCoordinates( positionBuffer, scale, translation );
object->setupFaces( indexBuffer );

if ( mExportNormals )
{
@@ -399,6 +410,9 @@ void Qgs3DSceneExporter::processPolygonGeometry( QgsTessellatedPolygonGeometry *
QByteArray positionBytes = positionAttribute->buffer()->data();
QVector<float> positionData = getAttributeData<float>( positionAttribute, positionBytes );
object->setupPositionCoordinates( positionData );
QVector<uint> facesData;
for ( int i = 0; i < positionData.size() / 3; ++i ) facesData.push_back( i );
object->setupFaces( facesData );

if ( mExportNormals )
{
@@ -423,6 +437,9 @@ void Qgs3DSceneExporter::processBufferedLineGeometry( QgsTessellatedPolygonGeome
QByteArray positionBytes = positionAttribute->buffer()->data();
QVector<float> positionData = getAttributeData<float>( positionAttribute, positionBytes );
object->setupPositionCoordinates( positionData );
QVector<uint> facesData;
for ( int i = 0; i < positionData.size() / 3; ++i ) facesData.push_back( i );
object->setupFaces( facesData );

if ( mExportNormals )
{
@@ -449,21 +466,20 @@ void Qgs3DSceneExporter::processInstancedPointGeometry( Qt3DCore::QEntity *entit
}
if ( positionAttribute == nullptr || indexAttribute == nullptr )
continue;
Qt3DRender::QBufferDataGeneratorPtr vertexDataGenerator = positionAttribute->buffer()->dataGenerator();
Qt3DRender::QBufferDataGeneratorPtr indexDataGenerator = indexAttribute->buffer()->dataGenerator();
QByteArray vertexBytes = vertexDataGenerator->operator()();
QByteArray indexBytes = indexDataGenerator->operator()();
QByteArray vertexBytes = getData( positionAttribute->buffer() );
QByteArray indexBytes = getData( indexAttribute->buffer() );
QVector<float> positionData = getAttributeData<float>( positionAttribute, vertexBytes );
QVector<uint> indexData = getIndexData<quint16>( indexBytes );

Qt3DRender::QAttribute *instanceDataAttribute = findAttribute( geometry, QStringLiteral( "pos" ), Qt3DRender::QAttribute::VertexAttribute );
Qt3DRender::QBuffer *instanceDataBuffer = instanceDataAttribute->buffer();
QVector<float> instancePosition = getAttributeData<float>( instanceDataAttribute, instanceDataBuffer->data() );
QByteArray instancePositionBytes = getData( instanceDataAttribute->buffer() );
QVector<float> instancePosition = getAttributeData<float>( instanceDataAttribute, instancePositionBytes );
for ( int i = 0; i < instancePosition.size(); i += 3 )
{
Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "shape_geometry" ), "", this );
mObjects.push_back( object );
object->setupPositionCoordinates( positionData, indexData, 1.0f, QVector3D( instancePosition[i], instancePosition[i + 1], instancePosition[i + 2] ) );
object->setupPositionCoordinates( positionData, 1.0f, QVector3D( instancePosition[i], instancePosition[i + 1], instancePosition[i + 2] ) );
object->setupFaces( indexData );

object->setSmoothEdges( mSmoothEdges );

@@ -494,73 +510,27 @@ void Qgs3DSceneExporter::processSceneLoaderGeometry( Qt3DRender::QSceneLoader *s
for ( QString entityName : sceneLoader->entityNames() )
{
Qt3DRender::QGeometryRenderer *mesh = qobject_cast<Qt3DRender::QGeometryRenderer *>( sceneLoader->component( entityName, Qt3DRender::QSceneLoader::GeometryRendererComponent ) );
Qt3DRender::QGeometry *geometry = mesh->geometry();

Qt3DRender::QAttribute *positionAttribute = findAttribute( geometry, Qt3DRender::QAttribute::defaultPositionAttributeName(), Qt3DRender::QAttribute::VertexAttribute );
Qt3DRender::QAttribute *indexAttribute = nullptr;
for ( Qt3DRender::QAttribute *attribute : geometry->attributes() )
{
if ( attribute->attributeType() == Qt3DRender::QAttribute::IndexAttribute )
indexAttribute = attribute;
}
if ( positionAttribute == nullptr || indexAttribute == nullptr )
{
qDebug() << "Mesh with null data";
continue;
}
Qt3DRender::QBufferDataGeneratorPtr vertexDataGenerator = positionAttribute->buffer()->dataGenerator();
Qt3DRender::QBufferDataGeneratorPtr indexDataGenerator = indexAttribute->buffer()->dataGenerator();

QByteArray vertexBytes;
QByteArray indexBytes;
if ( vertexDataGenerator.isNull() ) vertexBytes = positionAttribute->buffer()->data();
else vertexBytes = vertexDataGenerator->operator()();
if ( indexDataGenerator.isNull() ) indexBytes = indexAttribute->buffer()->data();
else indexBytes = indexDataGenerator->operator()();

QVector<float> positionData = getAttributeData<float>( positionAttribute, vertexBytes );
QVector<uint> indexData;
if ( indexAttribute->vertexBaseType() == Qt3DRender::QAttribute::VertexBaseType::UnsignedInt ) indexData = getIndexData<quint32>( indexBytes );
if ( indexAttribute->vertexBaseType() == Qt3DRender::QAttribute::VertexBaseType::UnsignedShort ) indexData = getIndexData<quint16>( indexBytes );
Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "shape_geometry" ), "", this );
mObjects.push_back( object );

Qt3DCore::QTransform *transform = qobject_cast<Qt3DCore::QTransform *>( sceneLoader->component( entityName, Qt3DRender::QSceneLoader::TransformComponent ) );
float scale = 1.0f;
QVector3D translation( 0.0f, 0.0f, 0.0f );

if ( transform != nullptr )
{
scale = transform->scale();
translation = transform->translation();
}

object->setupPositionCoordinates( positionData, indexData, scale * entityScale, translation + entityTranslation );

object->setSmoothEdges( mSmoothEdges );

if ( mExportNormals )
{
Qt3DRender::QAttribute *normalsAttribute = findAttribute( geometry, Qt3DRender::QAttribute::defaultNormalAttributeName(), Qt3DRender::QAttribute::VertexAttribute );
// Reuse vertex bytes
QVector<float> normalsData = getAttributeData<float>( normalsAttribute, vertexBytes );
object->setupNormalCoordinates( normalsData );
}

object->setupPhongMaterial( pointSymbol->material() );
processMeshGeometry( mesh, pointSymbol, entityScale, entityTranslation );
}
}

void Qgs3DSceneExporter::processMeshGeometry( Qt3DRender::QMesh *mesh, const QgsPoint3DSymbol *pointSymbol )
void Qgs3DSceneExporter::processMeshGeometry( Qt3DRender::QGeometryRenderer *mesh, const QgsPoint3DSymbol *pointSymbol, float sceneScale, QVector3D sceneTranslation )
{
Qgs3DExportObject *object = processGeometryRenderer( mesh, sceneScale, sceneTranslation );
object->setSmoothEdges( mSmoothEdges );
object->setupPhongMaterial( pointSymbol->material() );
}

Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, float sceneScale, QVector3D sceneTranslation )
{
Qt3DCore::QEntity *meshParent = qobject_cast<Qt3DCore::QEntity *>( mesh->parent() );
Qt3DCore::QTransform *entityTransform = findTypedComponent<Qt3DCore::QTransform>( meshParent );
float entityScale = 1.0f;
QVector3D entityTranslation( 0.0f, 0.0f, 0.0f );
if ( entityTransform != nullptr )
Qt3DCore::QTransform *transform = findTypedComponent<Qt3DCore::QTransform>( meshParent );
float scale = 1.0f;
QVector3D translation( 0.0f, 0.0f, 0.0f );
if ( transform != nullptr )
{
entityScale = entityTransform->scale();
entityTranslation = entityTransform->translation();
scale = transform->scale();
translation = transform->translation();
}
Qt3DRender::QGeometry *geometry = mesh->geometry();

@@ -573,29 +543,21 @@ void Qgs3DSceneExporter::processMeshGeometry( Qt3DRender::QMesh *mesh, const Qgs
}
if ( positionAttribute == nullptr || indexAttribute == nullptr )
{
qDebug() << "Mesh with null data";
return;
qDebug() << "renderer with null data";
return nullptr;
}
Qt3DRender::QBufferDataGeneratorPtr vertexDataGenerator = positionAttribute->buffer()->dataGenerator();
Qt3DRender::QBufferDataGeneratorPtr indexDataGenerator = indexAttribute->buffer()->dataGenerator();

QByteArray vertexBytes;
QByteArray indexBytes;
if ( vertexDataGenerator.isNull() ) vertexBytes = positionAttribute->buffer()->data();
else vertexBytes = vertexDataGenerator->operator()();
if ( indexDataGenerator.isNull() ) indexBytes = indexAttribute->buffer()->data();
else indexBytes = indexDataGenerator->operator()();
QByteArray vertexBytes = getData( positionAttribute->buffer() );
QByteArray indexBytes = getData( indexAttribute->buffer() );

QVector<float> positionData = getAttributeData<float>( positionAttribute, vertexBytes );
QVector<uint> indexData;
if ( indexAttribute->vertexBaseType() == Qt3DRender::QAttribute::VertexBaseType::UnsignedInt ) indexData = getIndexData<quint32>( indexBytes );
if ( indexAttribute->vertexBaseType() == Qt3DRender::QAttribute::VertexBaseType::UnsignedShort ) indexData = getIndexData<quint16>( indexBytes );
Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "shape_geometry" ), "", this );
mObjects.push_back( object );
Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( "mesh_geometry" ), "", this );

object->setupPositionCoordinates( positionData, indexData, entityScale, entityTranslation );

object->setSmoothEdges( mSmoothEdges );
object->setupPositionCoordinates( positionData, scale * sceneScale, translation + sceneTranslation );
object->setupFaces( indexData );

if ( mExportNormals )
{
@@ -605,7 +567,7 @@ void Qgs3DSceneExporter::processMeshGeometry( Qt3DRender::QMesh *mesh, const Qgs
object->setupNormalCoordinates( normalsData );
}

object->setupPhongMaterial( pointSymbol->material() );
return object;
}

void Qgs3DSceneExporter::save( const QString &sceneName, const QString &sceneFolderPath )
@@ -23,6 +23,7 @@
#include <Qt3DRender/QMesh>
#include <QMap>
#include <QFile>
#include <QVector3D>

class QgsTessellatedPolygonGeometry;
class QgsTerrainTileEntity;
@@ -103,7 +104,10 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity
//! Constructs Qgs3DExportObject from 3D models loaded using a scene loader
void processSceneLoaderGeometry( Qt3DRender::QSceneLoader *sceneLoader, const QgsPoint3DSymbol *pointSymbol );
//! Constructs Qgs3DExportObject from 3D models loaded using QMesh class
void processMeshGeometry( Qt3DRender::QMesh *mesh, const QgsPoint3DSymbol *pointSymbol );
void processMeshGeometry( Qt3DRender::QGeometryRenderer *mesh, const QgsPoint3DSymbol *pointSymbol, float sceneScale = 1.0f, QVector3D sceneTranslation = QVector3D( 0.0f, 0.0f, 0.0f ) );

//! Constructs Qgs3DExportObject from geometry renderer
Qgs3DExportObject *processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, float sceneScale = 1.0f, QVector3D sceneTranslation = QVector3D( 0.0f, 0.0f, 0.0f ) );

//! 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 babce71

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