Skip to content
Permalink
Browse files

texture coordinates generation

terrain texture generation
for flat and DEM terrains
  • Loading branch information
NEDJIMAbelgacem committed Jul 7, 2020
1 parent 154d2b2 commit a0638c6f1e8ac63f24abf6d32d138e4b1d2179db
@@ -17,6 +17,8 @@

#include <QVector3D>
#include <QDebug>
#include <QDir>
#include <QImage>

Qgs3DExportObject::Qgs3DExportObject( const QString &name, const QString &parentName, QObject *parent )
: QObject( parent )
@@ -66,6 +68,11 @@ void Qgs3DExportObject::setupNormalCoordinates( const QVector<float> &normalsBuf
mNormals << normalsBuffer;
}

void Qgs3DExportObject::setupTextureCoordinates( const QVector<float> &texturesBuffer )
{
mTexturesUV << texturesBuffer;
}

void Qgs3DExportObject::objectBounds( float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ )
{
for ( int vertice : mIndexes )
@@ -80,12 +87,8 @@ void Qgs3DExportObject::objectBounds( float &minX, float &minY, float &minZ, flo
}
}

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

// Set object name
out << "o " << mName << "\n";

// Set groups
// turns out grouping doest work as expected in blender

@@ -105,11 +108,18 @@ void Qgs3DExportObject::saveTo( QTextStream &out, int scale, const QVector3D &ce
{
out << "vn " << mNormals[i] << " " << mNormals[i + 1] << " " << mNormals[i + 2] << "\n";
}
int u_index = i / 3 * 2;
if ( u_index + 1 < mTexturesUV.size() )
{
// TODO: flip texture in a more appropriate way (for repeated textures)
out << "vt " << mTexturesUV[u_index] << " " << 1.0f - mTexturesUV[u_index + 1] << "\n";
}
}

bool hasTextures = false;
bool hasTextures = mTexturesUV.size() == mVertxPosition.size() / 3 * 2;
// if the object has normals then the normals and positions buffers should be the same size
bool hasNormals = mNormals.size() == mVertxPosition.size();

if ( !hasNormals && !mNormals.empty() )
{
qDebug() << "WARNING: vertex normals count and vertex positions count are different";
@@ -119,9 +129,9 @@ void Qgs3DExportObject::saveTo( QTextStream &out, int scale, const QVector3D &ce
auto getVertexIndex = [&]( int i ) -> QString
{
int negativeIndex = -1 - ( verticesCount - i );
if ( !hasNormals && !hasTextures ) return QString( "%1" ).arg( negativeIndex );
if ( hasNormals && !hasTextures ) return QString( "%1//%2" ).arg( negativeIndex ).arg( negativeIndex );
// TODO: handle other cases
if ( !hasNormals && hasTextures ) return QString( "%1/%2" ).arg( negativeIndex ).arg( negativeIndex );
if ( hasNormals && hasTextures ) return QString( "%1/%2/%3" ).arg( negativeIndex ).arg( negativeIndex ).arg( negativeIndex );
return QString( "%1" ).arg( negativeIndex );
};

@@ -135,3 +145,10 @@ void Qgs3DExportObject::saveTo( QTextStream &out, int scale, const QVector3D &ce
out << "\n";
}
}

void Qgs3DExportObject::saveMaterial( const QString &textureName, const QString &folderPath )
{
if ( mTexturesUV.size() == 0 ) return;
QString filePath = QDir( folderPath ).filePath( textureName + ".jpg" );
mTextureImage.save( filePath, "JPG" );
}
@@ -20,9 +20,10 @@
#include <QTextStream>
#include <QVector>
#include <QVector3D>
#include <QImage>

/**
* @brief The Qgs3DExportObject class
* \brief The Qgs3DExportObject class
* Manages the data of each object of the scene (positions, normals, texture coordinates ...) since each object
* \ingroup 3d
* \since QGIS 3.16
@@ -33,17 +34,22 @@ class Qgs3DExportObject : public QObject
public:

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

//! Returns the object name
QString name() const { return mName; }
//! Sets the object name
void setName( const QString &name ) { mName = name; }

//! Returns whether object edges will look smooth
bool smoothEdges() { return mSmoothEdges; }
//! Sets whether triangles edges will look smooth
@@ -56,6 +62,11 @@ class Qgs3DExportObject : public QObject

//! setss normal coordinates for each vertex
void setupNormalCoordinates( const QVector<float> &normalsBuffer );
//! setss texture coordinates for each vertex
void setupTextureCoordinates( const QVector<float> &texturesBuffer );

void setTextureImage( const QImage &image ) { this->mTextureImage = image; };
QImage textureImage() { return mTextureImage; }

/**
* Updates the box bounds explained with the current object bounds
@@ -64,14 +75,18 @@ class Qgs3DExportObject : public QObject
void objectBounds( float &minX, float &minY, float &minZ, float &maxX, float &maxY, float &maxZ );

//! 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 );
void saveTo( QTextStream &out, float scale, const QVector3D &center );
void saveMaterial( const QString &textureName, const QString &folder );
private:
QString mName;
QString mParentName;
QVector<float> mVertxPosition;
QVector<float> mNormals;
QVector<float> mTexturesUV;
QVector<int> mIndexes;

QImage mTextureImage;

bool mSmoothEdges;
};

@@ -23,7 +23,7 @@
#include <QDir>

/**
* @brief The Qgs3DMapExportSettings class
* \brief The Qgs3DMapExportSettings class
* Manages the various settings the user can choose from when exorting a 3D scene
* \ingroup 3d
* \since QGIS 3.16
@@ -45,6 +45,8 @@ class _3D_EXPORT Qgs3DMapExportSettings : public QObject
bool smoothEdges() const { return mSmoothEdges; }
//! Returns whether normals will be exported
bool exportNormals() const { return mExportNormals; }
//! Returns whether textures will be exported
bool exportTextures() const { return mExportTextures; }

//! Sets the scene name
void setSceneName( const QString &sceneName ) { mSceneName = sceneName; }
@@ -56,6 +58,8 @@ class _3D_EXPORT Qgs3DMapExportSettings : public QObject
void setSmoothEdges( bool smoothEdges ) { mSmoothEdges = smoothEdges; }
//! Sets whether normals should be exported
void setExportNormals( bool exportNormals ) { mExportNormals = exportNormals; }
//! Sets whether textures will be exported
void setExportTextures( bool exportTextures ) { mExportTextures = exportTextures; }
//! Returns a path to a file that with the "name.extension" in the export folder
QString getFilePath( const QString &name, const QString &extension ) const
{
@@ -67,6 +71,7 @@ class _3D_EXPORT Qgs3DMapExportSettings : public QObject
int mTerrainResolution = 128;
bool mSmoothEdges = false;
bool mExportNormals = true;
bool mExportTextures = false;
};

#endif // QGS3DMAPEXPORTSETTINGS_H
@@ -774,6 +774,7 @@ void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings )
exporter.setTerrainResolution( exportSettings.terrrainResolution() );
exporter.setSmoothEdges( exportSettings.smoothEdges() );
exporter.setExportNormals( exportSettings.exportNormals() );
exporter.setExportTextures( exportSettings.exportTextures() );

for ( QgsMapLayer *layer : mLayerEntities.keys() )
{
@@ -782,5 +783,5 @@ void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings )
exporter.parseEntity( mTerrain );

QString filePath = exportSettings.getFilePath( exportSettings.sceneName(), "obj" );
exporter.saveToFile( filePath );
exporter.save( exportSettings.sceneName(), exportSettings.sceneFolderPath() );
}

0 comments on commit a0638c6

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