Skip to content

Commit

Permalink
Got exporting feature to work on vector layer data
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem committed Jun 29, 2020
1 parent 273b8f3 commit 798ca96
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 90 deletions.
15 changes: 10 additions & 5 deletions src/3d/qgs3dmapscene.cpp
Expand Up @@ -766,14 +766,19 @@ void Qgs3DMapScene::updateSceneState()
setSceneState( Ready );
}

void Qgs3DMapScene::exportScene(const QString& sceneName, const QString& sceneDir) {
void Qgs3DMapScene::exportScene( const QString &sceneName, const QString &sceneDir )
{
Qgs3DSceneExporter exporter;

for ( QgsMapLayer * layer : mLayerEntities.keys() ) {
exporter.parseEntity(mLayerEntities[layer]);
for ( QgsMapLayer *layer : mLayerEntities.keys() )
{
exporter.parseEntity( mLayerEntities[layer] );
}
// TODO: figure out why terrain entity is not parsed correctly
exporter.parseEntity( mTerrain );

QString filePath = sceneDir;
if (!filePath.endsWith('/')) filePath.push_back('/');
if ( !filePath.endsWith( '/' ) ) filePath.push_back( '/' );
filePath += sceneName + ".obj";
exporter.saveToFile(filePath);
exporter.saveToFile( filePath );
}
137 changes: 65 additions & 72 deletions src/3d/qgs3dsceneexporter.cpp
@@ -1,6 +1,20 @@
#include "qgs3dsceneexporter.h"
/***************************************************************************
qgs3dsceneexporter.cpp
--------------------------------------
Date : June 2020
Copyright : (C) 2020 by Belgacem Nedjima
Email : gb underscore nedjima at esi dot dz
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgs3dsceneexporter.h"

#include <QDebug>
#include <QVector>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QComponent>
Expand All @@ -9,103 +23,82 @@
#include <Qt3DRender/QAttribute>
#include <Qt3DRender/QBuffer>
#include <Qt3DRender/QGeometryRenderer>
#include <qgstessellatedpolygongeometry.h>
#include <qgs3dmapscene.h>
#include <QByteArray>
#include <QFile>
#include <QTextStream>
#include <QtMath>

Qgs3DSceneExporter::Qgs3DSceneExporter( )
: mVertices(QVector<float>())
: mVertices( QVector<float>() )
{

}


void Qgs3DSceneExporter::parseEntity(Qt3DCore::QEntity* entity) {
if (entity == nullptr) return;
for (Qt3DCore::QComponent *c : entity->components()) {
Qt3DRender::QGeometryRenderer* comp = qobject_cast<Qt3DRender::QGeometryRenderer*>(c);
if (comp == nullptr) continue;
Qt3DRender::QGeometry* geom = comp->geometry();
QgsTessellatedPolygonGeometry* polygonGeometry = qobject_cast<QgsTessellatedPolygonGeometry*>(geom);
if (geom == nullptr) continue;
if (polygonGeometry != nullptr) processGeometry(polygonGeometry);
// for (Qt3DRender::QAttribute* attribute : geom->attributes()) {
// processAttribute(attribute);
// }
void Qgs3DSceneExporter::parseEntity( Qt3DCore::QEntity *entity )
{
if ( entity == nullptr ) return;
for ( Qt3DCore::QComponent *c : entity->components() )
{
Qt3DRender::QGeometryRenderer *comp = qobject_cast<Qt3DRender::QGeometryRenderer *>( c );
if ( comp == nullptr ) continue;
Qt3DRender::QGeometry *geom = comp->geometry();
for ( Qt3DRender::QAttribute *attribute : geom->attributes() )
{
processAttribute( attribute );
}
}
for (QObject* child : entity->children()) {
Qt3DCore::QEntity* childEntity = qobject_cast<Qt3DCore::QEntity*>( child );
if (childEntity != nullptr) parseEntity(childEntity);
for ( QObject *child : entity->children() )
{
Qt3DCore::QEntity *childEntity = qobject_cast<Qt3DCore::QEntity *>( child );
if ( childEntity != nullptr ) parseEntity( childEntity );
}
}

void Qgs3DSceneExporter::processAttribute(Qt3DRender::QAttribute* attribute) {
qDebug() << __PRETTY_FUNCTION__;
Qt3DRender::QBuffer* buffer = attribute->buffer();
QByteArray bufferData = buffer->data();
void Qgs3DSceneExporter::processAttribute( Qt3DRender::QAttribute *attribute )
{
// We only process position attributes
if ( attribute->name() != Qt3DRender::QAttribute::defaultPositionAttributeName() ) return;

QByteArray data = attribute->buffer()->data();
uint bytesOffset = attribute->byteOffset();
uint bytesStride = attribute->byteStride();
uint verticesCount = attribute->count();
uint vertexSize = attribute->vertexSize();

QDataStream stream(bufferData);

for (int offset = bytesOffset; offset < vertexSize * verticesCount * bytesStride; offset += bytesStride) {
QVector<float> verticeData;
for (int i = 0; i < vertexSize; ++i) {
float v;
stream >> v;
if (qIsInf(v)) break;
verticeData.push_back(v);
}
if (verticeData.size() == vertexSize) {
mVertices.append(verticeData);
qDebug() << "v" << verticeData[0] << verticeData[1] << verticeData[2];
QVector<float> floatData;
for ( int i = 0; i < data.size(); i += sizeof( float ) )
{
float v = 0x0;
// Maybe we can have a problem with endianness ?
char *v_arr = ( char * ) &v;
for ( int j = 0; j < sizeof( float ); ++j )
{
v_arr[j] = data.at( i + j );
}
floatData.push_back( v );
}

for ( int i = bytesOffset / sizeof( float ); i < floatData.size(); i += bytesStride / sizeof( float ) )
{
mVertices << floatData[i] << floatData[i + 1] << floatData[i + 2];
}
}

void Qgs3DSceneExporter::saveToFile(const QString& filePath) {
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
void Qgs3DSceneExporter::saveToFile( const QString &filePath )
{
QFile file( filePath );
if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
return;

qDebug() << filePath;
QTextStream out(&file);
QTextStream out( &file );

// Construct vertices
for (int i = 0; i < mVertices.size(); i += 3) {
for ( int i = 0; i < mVertices.size(); i += 3 )
{
out << "v " << mVertices[i] << " " << mVertices[i + 1] << " " << mVertices[i + 2] << "\n";
// qDebug() << "v " << mVertices[i] << " " << mVertices[i + 1] << " " << mVertices[i + 2] << "\n";

}

// Construct faces
for (int i = 0; i < mVertices.size() / 9; ++i) {
for ( int i = 0; i < mVertices.size() / 9; ++i )
{
out << "f " << 3 * i + 1 << " " << 3 * i + 2 << " " << 3 * i + 3 << "\n";
// qDebug() << "f " << 3 * i << " " << 3 * i + 1 << " " << 3 * i + 2 << "\n";
}
}

void Qgs3DSceneExporter::processGeometry(QgsTessellatedPolygonGeometry* geom) {
QByteArray data = geom->mVertexBuffer->data();
Qt3DRender::QAttribute* attribute = geom->mPositionAttribute;
uint bytesOffset = attribute->byteOffset();
uint bytesStride = attribute->byteStride();
uint verticesCount = attribute->count();
uint vertexSize = attribute->vertexSize();

QVector<float> floatData;
QDataStream dataStream(data);
while (!dataStream.atEnd()) {
float f;
dataStream >> f;
floatData.push_back(f);
}

for (int i = 0; i < floatData.size(); i += bytesStride / sizeof(float)) {
mVertices << floatData[i] << floatData[i + 1] << floatData[i + 2];
}
}
36 changes: 23 additions & 13 deletions src/3d/qgs3dsceneexporter.h
@@ -1,26 +1,36 @@
/***************************************************************************
qgs3dsceneexporter.h
--------------------------------------
Date : June 2020
Copyright : (C) 2020 by Belgacem Nedjima
Email : gb underscore nedjima at esi dot dz
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGS3DSCENEEXPORTER_H
#define QGS3DSCENEEXPORTER_H

#include <Qt3DCore/QEntity>
#include <Qt3DRender/QGeometry>
#include <Qt3DRender/QAttribute>

class QgsTessellatedPolygonGeometry;
class Qgs3DMapSettings;

class Qgs3DSceneExporter
{

public:
Qgs3DSceneExporter( );
public:
Qgs3DSceneExporter( );

void parseEntity(Qt3DCore::QEntity* entity);
void saveToFile(const QString& filePath);
private:
void processAttribute(Qt3DRender::QAttribute* attribute);
void processGeometry(QgsTessellatedPolygonGeometry* geom);
private:
QVector<float> mVertices;
void parseEntity( Qt3DCore::QEntity *entity );
void saveToFile( const QString &filePath );
private:
void processAttribute( Qt3DRender::QAttribute *attribute );
private:
QVector<float> mVertices;
};

#endif // QGS3DSCENEEXPORTER_H

0 comments on commit 798ca96

Please sign in to comment.