Skip to content

Commit

Permalink
vecctor layer texture export
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem committed Jul 22, 2020
1 parent 7433219 commit 4290dde
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 38 deletions.
1 change: 1 addition & 0 deletions src/3d/CMakeLists.txt
Expand Up @@ -72,6 +72,7 @@ SET(QGIS_3D_SRCS
qgs3dsceneexporter.cpp
qgs3dexportobject.cpp
qgs3dmapexportsettings.cpp
qgsimagetexture.cpp
)

SET(QGIS_3D_HDRS
Expand Down
3 changes: 3 additions & 0 deletions src/3d/qgs3dexportobject.cpp
Expand Up @@ -33,6 +33,7 @@ void insertIndexData( QVector<uint> &vertexIndex, const QVector<T> &faceIndex )
{
for ( int i = 0; i < faceIndex.size(); i += 3 )
{
if ( i + 2 >= faceIndex.size() ) continue;
// skip invalid triangles
if ( faceIndex[i] == faceIndex[i + 1] && faceIndex[i + 1] == faceIndex[i + 2] )
continue;
Expand Down Expand Up @@ -67,6 +68,7 @@ void Qgs3DExportObject::setupFaces( const QVector<uint> &facesIndexes )

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

Expand Down Expand Up @@ -196,6 +198,7 @@ QString Qgs3DExportObject::saveMaterial( QTextStream &mtlOut, const QString &fol
if ( mTexturesUV.size() != 0 && !mTextureImage.isNull() )
{
QString filePath = QDir( folderPath ).filePath( materialName + ".jpg" );
qDebug() << "saving texture image " << filePath;
mTextureImage.save( filePath, "JPG" );
mtlOut << "\tmap_Kd " << materialName << ".jpg" << "\n";
}
Expand Down
1 change: 1 addition & 0 deletions src/3d/qgs3dexportobject.h
Expand Up @@ -36,6 +36,7 @@ class Qgs3DExportObject : public QObject
{
Q_OBJECT
public:
//! The type of exported geometry
enum ObjectType
{
TriangularFaces,
Expand Down
69 changes: 54 additions & 15 deletions src/3d/qgs3dsceneexporter.cpp
Expand Up @@ -34,15 +34,15 @@
#include <Qt3DRender/QBufferDataGeneratorPtr>
#include <Qt3DRender/QMesh>
#include <Qt3DRender/QSceneLoader>

#include <Qt3DRender/QAbstractTexture>
#include <Qt3DExtras/QCylinderGeometry>
#include <Qt3DExtras/QConeGeometry>
#include <Qt3DExtras/QSphereGeometry>
#include <Qt3DExtras/QCuboidGeometry>
#include <Qt3DExtras/QTorusGeometry>
#include <Qt3DExtras/QExtrudedTextMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QBufferDataGenerator>
#include <Qt3DRender/QAbstractTextureImage>

#include <QByteArray>
#include <QFile>
Expand Down Expand Up @@ -75,6 +75,7 @@
#include "qgsrulebased3drenderer.h"
#include "qgs3dutils.h"
#include "qgsbillboardgeometry.h"
#include "qgsimagetexture.h"

#include <numeric>

Expand All @@ -84,8 +85,14 @@ QVector<T> getAttributeData( Qt3DRender::QAttribute *attribute, QByteArray data
uint bytesOffset = attribute->byteOffset();
uint bytesStride = attribute->byteStride();
uint vertexSize = attribute->vertexSize();

QVector<T> result;

if ( bytesStride == 0 )
{
qDebug() << "WARNING: bytesStride==0 at " << __FILE__ << ":" << __LINE__;
return result;
}

for ( int i = bytesOffset; i < data.size(); i += bytesStride )
{
for ( unsigned int j = 0; j < vertexSize * sizeof( T ); j += sizeof( T ) )
Expand Down Expand Up @@ -213,10 +220,9 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV
if ( entity == nullptr ) continue;
Qgs3DExportObject *object = processGeometryRenderer( renderer );
if ( object == nullptr ) continue;
if ( mExportTextures )
processEntityMaterial( entity, object );
mObjects.push_back( object );
Qt3DExtras::QPhongMaterial *material = findTypedComponent<Qt3DExtras::QPhongMaterial>( entity );
if ( material == nullptr ) continue;
object->setupPhongMaterial( Qgs3DUtils::phongMaterialFromQt3DComponent( material ) );
}
return true;
}
Expand All @@ -227,15 +233,12 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV
QString symbolType = symbol->type();
if ( symbolType == "polygon" )
{
const QgsPolygon3DSymbol *polygonSymbol = dynamic_cast<const QgsPolygon3DSymbol *>( symbol );
QList<Qt3DRender::QGeometryRenderer *> renderers = entity->findChildren<Qt3DRender::QGeometryRenderer *>();
for ( Qt3DRender::QGeometryRenderer *r : renderers )
{
Qgs3DExportObject *object = processGeometryRenderer( r );
object->setName( QStringLiteral( "polygon" ) );
object->setupPhongMaterial( polygonSymbol->material() );
processEntityMaterial( entity, object );
mObjects.push_back( object );
// TODO: handle materials (for rule based renderer's polygons as well)
}
return renderers.size() != 0;
}
Expand Down Expand Up @@ -298,8 +301,12 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV
}
else
{
QVector<Qgs3DExportObject *> objects = processInstancedPointGeometry( entity, pointSymbol );
mObjects << objects;
QVector<Qgs3DExportObject *> objects = processInstancedPointGeometry( entity );
for ( Qgs3DExportObject *obj : objects )
{
obj->setupPhongMaterial( pointSymbol->material() );
mObjects << obj;
}
return true;
}
}
Expand All @@ -308,6 +315,32 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV
return false;
}

void Qgs3DSceneExporter::processEntityMaterial( Qt3DCore::QEntity *entity, Qgs3DExportObject *object )
{
Qt3DExtras::QPhongMaterial *phongMaterial = findTypedComponent<Qt3DExtras::QPhongMaterial>( entity );
if ( phongMaterial != nullptr )
{
object->setupPhongMaterial( Qgs3DUtils::phongMaterialFromQt3DComponent( phongMaterial ) );
}
Qt3DExtras::QDiffuseMapMaterial *diffuseMapMaterial = findTypedComponent<Qt3DExtras::QDiffuseMapMaterial>( entity );
if ( diffuseMapMaterial != nullptr )
{
QVector<Qt3DRender::QAbstractTextureImage *> textureImages = diffuseMapMaterial->diffuse()->textureImages();
QgsImageTexture *imageTexture = nullptr;
for ( Qt3DRender::QAbstractTextureImage *tex : textureImages )
{
imageTexture = dynamic_cast<QgsImageTexture *>( tex );
if ( imageTexture != nullptr ) break;
}
if ( imageTexture != nullptr )
{
qDebug() << "Exporting image texture";
QImage image = imageTexture->getImage();
object->setTextureImage( image );
}
}
}

void Qgs3DSceneExporter::parseTerrain( QgsTerrainEntity *terrain )
{
const Qgs3DMapSettings &settings = terrain->map3D();
Expand Down Expand Up @@ -493,7 +526,7 @@ void Qgs3DSceneExporter::parseMeshTile( QgsTerrainTileEntity *tileEntity )
}
}

QVector<Qgs3DExportObject *> Qgs3DSceneExporter::processInstancedPointGeometry( Qt3DCore::QEntity *entity, const QgsPoint3DSymbol *pointSymbol )
QVector<Qgs3DExportObject *> Qgs3DSceneExporter::processInstancedPointGeometry( Qt3DCore::QEntity *entity )
{
QVector<Qgs3DExportObject *> objects;
QList<Qt3DRender::QGeometry *> geometriesList = entity->findChildren<Qt3DRender::QGeometry *>();
Expand Down Expand Up @@ -532,8 +565,6 @@ QVector<Qgs3DExportObject *> Qgs3DSceneExporter::processInstancedPointGeometry(
QVector<float> normalsData = getAttributeData<float>( normalsAttribute, vertexBytes );
object->setupNormalCoordinates( normalsData );
}

object->setupPhongMaterial( pointSymbol->material() );
}
}
return objects;
Expand Down Expand Up @@ -620,6 +651,14 @@ Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeo
object->setupNormalCoordinates( normalsData );
}

if ( mExportTextures )
{
Qt3DRender::QAttribute *texCoordsAttribute = findAttribute( geometry, Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName(), Qt3DRender::QAttribute::VertexAttribute );
// Reuse vertex bytes
QVector<float> texCoordsData = getAttributeData<float>( texCoordsAttribute, vertexBytes );
object->setupTextureCoordinates( texCoordsData );
}

return object;
}

Expand Down
4 changes: 3 additions & 1 deletion src/3d/qgs3dsceneexporter.h
Expand Up @@ -95,11 +95,13 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity

private:
//! Constructs Qgs3DExportObject from instanced point geometry
QVector<Qgs3DExportObject *> processInstancedPointGeometry( Qt3DCore::QEntity *entity, const QgsPoint3DSymbol *pointSymbol );
QVector<Qgs3DExportObject *> processInstancedPointGeometry( Qt3DCore::QEntity *entity );
//! Constructs Qgs3DExportObject from 3D models loaded using a scene loader
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 ) );
//! Extracts material information from geometry renderer and inserts it into the export object
void processEntityMaterial( Qt3DCore::QEntity *entity, Qgs3DExportObject *object );
//! Constricts Qgs3DExportObject from line entity
QVector<Qgs3DExportObject *> processLines( Qt3DCore::QEntity *entity );
//! Constricts Qgs3DExportObject from billboard point entity
Expand Down
24 changes: 24 additions & 0 deletions src/3d/qgsimagetexture.cpp
@@ -0,0 +1,24 @@
/***************************************************************************
qgs3dsceneexporter.h
--------------------------------------
Date : July 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 "qgsimagetexture.h"


QgsImageTexture::QgsImageTexture( const QImage &image, Qt3DCore::QNode *parent )
: Qt3DRender::QPaintedTextureImage( parent )
, mImage( image )
{
setSize( mImage.size() );
}
42 changes: 42 additions & 0 deletions src/3d/qgsimagetexture.h
@@ -0,0 +1,42 @@
/***************************************************************************
qgs3dsceneexporter.h
--------------------------------------
Date : July 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 QGSIMAGETEXTURE_H
#define QGSIMAGETEXTURE_H

#include <QImage>
#include <QPainter>
#include <Qt3DCore/QNode>
#include <Qt3DRender/QPaintedTextureImage>

class QgsImageTexture : public Qt3DRender::QPaintedTextureImage
{
public:
QgsImageTexture( const QImage &image, Qt3DCore::QNode *parent = nullptr );

void paint( QPainter *painter ) override
{
painter->drawImage( mImage.rect(), mImage, mImage.rect() );
}

QImage getImage() const { return mImage; }

private:

QImage mImage;

};

#endif // QGSIMAGETEXTURE_H
26 changes: 4 additions & 22 deletions src/3d/symbols/qgspolygon3dsymbol_p.cpp
Expand Up @@ -44,6 +44,8 @@
#include "qgslinevertexdata_p.h"
#include "qgslinematerial_p.h"

#include "qgsimagetexture.h"

/// @cond PRIVATE


Expand Down Expand Up @@ -282,26 +284,6 @@ static void applyCullingMode( Qgs3DTypes::CullingMode cullingMode, Qt3DRender::Q
}


class QgsQImageTextureImage : public Qt3DRender::QPaintedTextureImage
{
public:
QgsQImageTextureImage( const QImage &image, Qt3DCore::QNode *parent = nullptr )
: Qt3DRender::QPaintedTextureImage( parent )
, mImage( image )
{
setSize( mImage.size() );
}

void paint( QPainter *painter ) override
{
painter->drawImage( mImage.rect(), mImage, mImage.rect() );
}

private:

QImage mImage;

};


Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSymbol &symbol, bool isSelected, const Qgs3DRenderContext &context ) const
Expand All @@ -311,7 +293,6 @@ Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSy

if ( symbol.material().shouldUseDiffuseTexture() )
textureSourceImage = QgsApplication::imageCache()->pathAsImage( symbol.material().texturePath(), QSize(), true, 1.0, fitsInCache );
( void )fitsInCache;

Qt3DRender::QMaterial *retMaterial = nullptr;
if ( !textureSourceImage.isNull() )
Expand All @@ -320,7 +301,8 @@ Qt3DRender::QMaterial *QgsPolygon3DSymbolHandler::material( const QgsPolygon3DSy

applyCullingMode( symbol.cullingMode(), material );

QgsQImageTextureImage *textureImage = new QgsQImageTextureImage( textureSourceImage );
QgsImageTexture *textureImage = new QgsImageTexture( textureSourceImage );

material->diffuse()->addTextureImage( textureImage );

material->diffuse()->wrapMode()->setX( Qt3DRender::QTextureWrapMode::Repeat );
Expand Down

0 comments on commit 4290dde

Please sign in to comment.