Skip to content
Permalink
Browse files

Adding documentation and fixing code layout

  • Loading branch information
NEDJIMAbelgacem committed Jul 4, 2020
1 parent 69017d4 commit b6f16032aa6fb5a1f6e9407576fad6606ff8d09e
@@ -15,8 +15,12 @@

#include "qgs3dmapexportsettings.h"

Qgs3DMapExportSettings::Qgs3DMapExportSettings(QObject* parent)
: QObject(parent)
Qgs3DMapExportSettings::Qgs3DMapExportSettings( QObject *parent )
: QObject( parent )
, mSceneName( "Scene" )
, mSceneFolderPath( "~/" )
, mTerrainResolution( 128 )
, mSmoothEdges( false )
{

}
@@ -21,19 +21,35 @@
#include <QString>
#include <QObject>

/**
* @brief The Qgs3DMapExportSettings class
* Manages the various settings the user can choose from when exorting a 3D scene
* \ingroup 3d
* \since QGIS 3.16
*/
class _3D_EXPORT Qgs3DMapExportSettings : public QObject
{
Q_OBJECT
public:
// Constructor
Qgs3DMapExportSettings( QObject *parent = nullptr );

// Returns the scene name
QString sceneName() const { return mSceneName; }
// Returns the scene folder path
QString sceneFolderPath() const { return mSceneFolderPath; }
// Returns the terrain resolution
int terrrainResolution() const { return mTerrainResolution; }
// Returns whether triangles edges will look smooth
bool smoothEdges() const { return mSmoothEdges; }

// Sets the scene name
void setSceneName( const QString &sceneName ) { mSceneName = sceneName; }
// Sets the scene's .obj file folder path
void setSceneFolderPath( const QString &sceneFolderPath ) { mSceneFolderPath = sceneFolderPath; }
// Sets the terrain resolution
void setTerrainResolution( int resolution ) { mTerrainResolution = resolution; }
// Sets whether triangles edges will look smooth
void setSmoothEdges( bool smoothEdges ) { mSmoothEdges = smoothEdges; }
private:
QString mSceneName;
@@ -103,6 +103,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
*/
float worldSpaceError( float epsilon, float distance );

// EXports the scene according to the scene export settings
void exportScene( const Qgs3DMapExportSettings &exportSettings );
signals:
//! Emitted when the current terrain entity is replaced by a new one
@@ -31,32 +31,53 @@ class QgsDemTerrainGenerator;
class QgsChunkNode;
class QgsExportObject;

/**
* @brief The Qgs3DSceneExporter class
* Entity that handles the exporting of 3D scene
* \ingroup 3d
* \since QGIS 3.16
*/
class Qgs3DSceneExporter : public Qt3DCore::QEntity
{
Q_OBJECT
public:
Qgs3DSceneExporter( Qt3DCore::QNode *parent = nullptr );

// Creates necessary export objects from entity if it represents valid entity
// If the entity doesn't define exportable object it will be ignored
void parseEntity( Qt3DCore::QEntity *entity );
// Creates terrain export objects from the terrain entity
void parseEntity( QgsTerrainEntity *terrain );
void saveToFile( const QString &filePath );

// Sets whether the triangles will look smooth
void setSmoothEdges( bool smoothEdges ) { mSmoothEdges = smoothEdges; }
// Returns whether the triangles will look smooth
bool smoothEdges() { return mSmoothEdges; }

// Sets the terrian resolution
void setTerrainResolution( int resolution ) { mTerrainResolution = resolution; }
// Returns the terrain resolution
int terrainResolution() { return mTerrainResolution; }

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

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

// constructs a QgsExportObject from the DEM tile entity
void parseDemTile( QgsTerrainTileEntity *tileEntity );
// constructs a QgsExportObject from the flat tile entity
void parseFlatTile( QgsTerrainTileEntity *tileEntity );

// Creates tile entity that contains the geometry to be exported and necessary scaling parameters
// THis function is needed because we need to generate geometry according to terrain resolution
QgsTerrainTileEntity *createDEMTileEntity( QgsTerrainEntity *terrain, QgsChunkNode *node );
private:
QVector<QgsExportObject *> mObjects;
@@ -1,16 +1,32 @@
/***************************************************************************
qgsexportobject.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 "qgsexportobject.h"

#include <QVector3D>

QgsExportObject::QgsExportObject(const QString& name, const QString& parentName, QObject* parent)
: QObject(parent)
, mName(name)
, mParentName(parentName)
, mSmoothEdges(true)
QgsExportObject::QgsExportObject( const QString &name, const QString &parentName, QObject *parent )
: QObject( parent )
, mName( name )
, mParentName( parentName )
, mSmoothEdges( false )
{
}

void QgsExportObject::setupPositionCoordinates( const QVector<float>& positionsBuffer, float scale, const QVector3D translation ) {
void QgsExportObject::setupPositionCoordinates( 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 )
@@ -19,13 +35,13 @@ void QgsExportObject::setupPositionCoordinates( const QVector<float>& positionsB
}
}

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

void QgsExportObject::setupPositionCoordinates( const QVector<float>& positionsBuffer, const QVector<unsigned int>& faceIndex, float scale, const QVector3D translation )
void QgsExportObject::setupPositionCoordinates( const QVector<float> &positionsBuffer, const QVector<unsigned int> &faceIndex, float scale, const QVector3D translation )
{
// TODO: delete vertices that are not used
for ( int i = 0; i < positionsBuffer.size(); i += 3 )
@@ -38,24 +54,27 @@ void QgsExportObject::setupPositionCoordinates( const QVector<float>& positionsB

for ( int i = 0; i < faceIndex.size(); i += 3 )
{
if (faceIndex[i] == faceIndex[i + 1] && faceIndex[i + 1] == faceIndex[i + 2]) continue;
for (int j = 0; j < 3; ++j) mIndexes << faceIndex[i + j] + 1;
if ( faceIndex[i] == faceIndex[i + 1] && faceIndex[i + 1] == faceIndex[i + 2] ) continue;
for ( int j = 0; j < 3; ++j ) mIndexes << faceIndex[i + j] + 1;
}
}

void QgsExportObject::objectBounds(float& minX, float& minY, float& minZ, float& maxX, float& maxY, float& maxZ) {
for (int vertice : mIndexes) {
int heightIndex = (vertice - 1) * 3 + 1;
minX = std::min(minX, mVertxPosition[heightIndex - 1]);
maxX = std::max(maxX, mVertxPosition[heightIndex - 1]);
minY = std::min(minY, mVertxPosition[heightIndex]);
maxY = std::max(maxY, mVertxPosition[heightIndex]);
minZ = std::min(minZ, mVertxPosition[heightIndex + 1]);
maxZ = std::max(maxZ, mVertxPosition[heightIndex + 1]);
void QgsExportObject::objectBounds( float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ )
{
for ( int vertice : mIndexes )
{
int heightIndex = ( vertice - 1 ) * 3 + 1;
minX = std::min( minX, mVertxPosition[heightIndex - 1] );
maxX = std::max( maxX, mVertxPosition[heightIndex - 1] );
minY = std::min( minY, mVertxPosition[heightIndex] );
maxY = std::max( maxY, mVertxPosition[heightIndex] );
minZ = std::min( minZ, mVertxPosition[heightIndex + 1] );
maxZ = std::max( maxZ, mVertxPosition[heightIndex + 1] );
}
}

void QgsExportObject::saveTo(QTextStream& out, int scale, const QVector3D& center) {
void QgsExportObject::saveTo( QTextStream &out, int scale, const QVector3D &center )
{

// Set object name
out << "o " << mName << "\n";
@@ -81,7 +100,7 @@ void QgsExportObject::saveTo(QTextStream& out, int scale, const QVector3D& cente
int verticesCount = mVertxPosition.size() / 3;
for ( int i = 0; i < mIndexes.size(); i += 3 )
{
if (mIndexes[i] == mIndexes[i + 1] && mIndexes[i + 1] == mIndexes[i + 2]) continue;
out << "f " << -1 - (verticesCount - mIndexes[i]) << " " << -1 - (verticesCount - mIndexes[i + 1]) << " " << -1 - (verticesCount - mIndexes[i + 2]) << "\n";
if ( mIndexes[i] == mIndexes[i + 1] && mIndexes[i + 1] == mIndexes[i + 2] ) continue;
out << "f " << -1 - ( verticesCount - mIndexes[i] ) << " " << -1 - ( verticesCount - mIndexes[i + 1] ) << " " << -1 - ( verticesCount - mIndexes[i + 2] ) << "\n";
}
}
@@ -1,3 +1,18 @@
/***************************************************************************
qgsexportobject.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 QGSEXPORTOBJECT_H
#define QGSEXPORTOBJECT_H

@@ -6,20 +21,44 @@
#include <QVector>
#include <QVector3D>

// Manages the data of each object of the scene (positions, normals, texture coordinates ...)
class QgsExportObject : public QObject {
/**
* @brief The QgsExportObject class
* Manages the data of each object of the scene (positions, normals, texture coordinates ...) since each object
* \ingroup 3d
* \since QGIS 3.16
*/
class QgsExportObject : public QObject
{
Q_OBJECT
public:
QgsExportObject(const QString& name, const QString& parentName = QString(), QObject* parent = nullptr);

/**
* @brief QgsExportObject
* Constructs an export object that will be filled with coordinates later
* @param name
* The name of the object (the user will be able to select each object individually using its name in blender)
* @param parentName
* The name of the parent (Will be useful to define scene hierarchie)
* @param parent
* The parent QObject (we use this to delete the QgsExportObject instance once the exporter instance is deallocated)
*/
QgsExportObject( const QString &name, const QString &parentName = QString(), QObject *parent = nullptr );

// Returns whether object edges will look smooth
bool smoothEdges() { return mSmoothEdges; }
void setSmoothEdges(bool smoothEdges) { mSmoothEdges = smoothEdges; }
// Sets whether triangles edges will look smooth
void setSmoothEdges( bool smoothEdges ) { mSmoothEdges = smoothEdges; }

void setupPositionCoordinates( const QVector<float>& positionsBuffer, float scale=1.0f, const QVector3D translation=QVector3D(0, 0, 0) );
void setupPositionCoordinates( const QVector<float>& positionsBuffer, const QVector<unsigned int>& facesIndexes, float scale=1.0f, const QVector3D translation=QVector3D(0, 0, 0) );
void objectBounds(float& minX, float& minY, float& minZ, float& maxX, float& maxY, float& maxZ);
// 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 ) );
// Updates the box bounds explained with the current object bounds
// This expands the bounding box if the current object outside the bounds of the already established bounds
void objectBounds( float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ );

void saveTo(QTextStream& out, int scale, const QVector3D& center);
// Saves the current object to the output stream while scaling the object and centering it to be visible in exported scene
void saveTo( QTextStream &out, int scale, const QVector3D &center );
private:
QString mName;
QString mParentName;
@@ -20,6 +20,7 @@
#include <QFileDialog>
#include <QtGlobal>

#include "qgis.h"
#include "qgs3dmapscene.h"
#include "qgssettings.h"
#include "qgs3dmapexportsettings.h"
@@ -46,7 +47,7 @@ QgsMap3DExportWidget::QgsMap3DExportWidget( Qgs3DMapScene *scene, Qgs3DMapExport
connect( ui->sceneNameLineEdit, &QLineEdit::textChanged, [ = ]( const QString & ) { settingsChanged(); } );
connect( ui->folderPathLineEdit, &QLineEdit::textChanged, [ = ]( const QString & ) { settingsChanged(); } );
connect( ui->smoothEdgesCheckBox, &QCheckBox::stateChanged, [ = ]( int ) { settingsChanged(); } );
connect( ui->terrainResolutionSpinBox, QOverload<int>::of( &QSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } );
connect( ui->terrainResolutionSpinBox, qgis::overload<int>::of( &QSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } );

// sets the export settings to whatever is on the scene
settingsChanged();
@@ -10,9 +10,6 @@
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">

0 comments on commit b6f1603

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