diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index 3e2d10984f3..5074f804c18 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -897,8 +897,9 @@ void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings ) break; } } + if ( mTerrain != nullptr ) - exporter.parseTerrain( mTerrain ); + exporter.parseTerrain( mTerrain, "Terrain" ); exporter.save( exportSettings.sceneName(), exportSettings.sceneFolderPath() ); diff --git a/src/3d/qgs3dsceneexporter.cpp b/src/3d/qgs3dsceneexporter.cpp index c9501d6305a..bcbcb4f491c 100644 --- a/src/3d/qgs3dsceneexporter.cpp +++ b/src/3d/qgs3dsceneexporter.cpp @@ -218,7 +218,7 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV { Qt3DCore::QEntity *entity = qobject_cast( renderer->parent() ); if ( entity == nullptr ) continue; - Qgs3DExportObject *object = processGeometryRenderer( renderer ); + Qgs3DExportObject *object = processGeometryRenderer( renderer, layer->name() + QStringLiteral( "_" ) ); if ( object == nullptr ) continue; if ( mExportTextures ) processEntityMaterial( entity, object ); @@ -236,7 +236,7 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV QList renderers = entity->findChildren(); for ( Qt3DRender::QGeometryRenderer *r : renderers ) { - Qgs3DExportObject *object = processGeometryRenderer( r ); + Qgs3DExportObject *object = processGeometryRenderer( r, layer->name() + QStringLiteral( "_" ) ); if ( object == nullptr ) continue; processEntityMaterial( entity, object ); mObjects.push_back( object ); @@ -248,7 +248,7 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV const QgsLine3DSymbol *lineSymbol = dynamic_cast( symbol ); if ( lineSymbol->renderAsSimpleLines() ) { - QVector objs = processLines( entity ); + QVector objs = processLines( entity, layer->name() + QStringLiteral( "_" ) ); mObjects << objs; return objs.size() != 0; } @@ -257,7 +257,7 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV QList renderers = entity->findChildren(); for ( Qt3DRender::QGeometryRenderer *r : renderers ) { - Qgs3DExportObject *object = processGeometryRenderer( r ); + Qgs3DExportObject *object = processGeometryRenderer( r, layer->name() + QStringLiteral( "_" ) ); if ( object == nullptr ) continue; object->setupPhongMaterial( lineSymbol->material() ); mObjects.push_back( object ); @@ -273,7 +273,7 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV Qt3DRender::QSceneLoader *sceneLoader = entity->findChild(); if ( sceneLoader != nullptr ) { - QVector objects = processSceneLoaderGeometries( sceneLoader ); + QVector objects = processSceneLoaderGeometries( sceneLoader, layer->name() + QStringLiteral( "_" ) ); for ( Qgs3DExportObject *obj : objects ) { obj->setSmoothEdges( mSmoothEdges ); @@ -286,7 +286,7 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV QList meshes = entity->findChildren(); for ( Qt3DRender::QMesh *mesh : meshes ) { - Qgs3DExportObject *object = processGeometryRenderer( mesh ); + Qgs3DExportObject *object = processGeometryRenderer( mesh, layer->name() + QStringLiteral( "_" ) ); if ( object == nullptr ) continue; object->setSmoothEdges( mSmoothEdges ); object->setupPhongMaterial( pointSymbol->material() ); @@ -297,13 +297,13 @@ bool Qgs3DSceneExporter::parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsV } else if ( pointSymbol->shape() == QgsPoint3DSymbol::Billboard ) { - Qgs3DExportObject *obj = processPoints( entity ); + Qgs3DExportObject *obj = processPoints( entity, layer->name() + QStringLiteral( "_" ) ); if ( obj != nullptr ) mObjects << obj; if ( obj != nullptr ) return true; } else { - QVector objects = processInstancedPointGeometry( entity ); + QVector objects = processInstancedPointGeometry( entity, layer->name() + QStringLiteral( "_" ) ); for ( Qgs3DExportObject *obj : objects ) { obj->setupPhongMaterial( pointSymbol->material() ); @@ -342,7 +342,7 @@ void Qgs3DSceneExporter::processEntityMaterial( Qt3DCore::QEntity *entity, Qgs3D } } -void Qgs3DSceneExporter::parseTerrain( QgsTerrainEntity *terrain ) +void Qgs3DSceneExporter::parseTerrain( QgsTerrainEntity *terrain, const QString &layerName ) { const Qgs3DMapSettings &settings = terrain->map3D(); QgsChunkNode *node = terrain->rootNode(); @@ -357,16 +357,16 @@ void Qgs3DSceneExporter::parseTerrain( QgsTerrainEntity *terrain ) { case QgsTerrainGenerator::Dem: terrainTile = getDemTerrainEntity( terrain, node ); - parseDemTile( terrainTile ); + parseDemTile( terrainTile, layerName + QStringLiteral( "_" ) ); break; case QgsTerrainGenerator::Flat: terrainTile = getFlatTerrainEntity( terrain, node ); - parseFlatTile( terrainTile ); + parseFlatTile( terrainTile, layerName + QStringLiteral( "_" ) ); break; // TODO: implement other terrain types case QgsTerrainGenerator::Mesh: terrainTile = getMeshTerrainEntity( terrain, node ); - parseMeshTile( terrainTile ); + parseMeshTile( terrainTile, layerName + QStringLiteral( "_" ) ); break; case QgsTerrainGenerator::Online: break; @@ -410,7 +410,7 @@ QgsTerrainTileEntity *Qgs3DSceneExporter::getMeshTerrainEntity( QgsTerrainEntity return tileEntity; } -void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity ) +void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity, const QString &layerName ) { Qt3DRender::QGeometryRenderer *mesh = findTypedComponent( tileEntity ); Qt3DCore::QTransform *transform = findTypedComponent( tileEntity ); @@ -436,7 +436,10 @@ void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity ) QByteArray indexBytes = getData( indexAttribute->buffer() ); QVector indexesBuffer = getIndexData( indexAttribute, indexBytes ); - Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( QStringLiteral( "Flat_tile" ) ), "", this ); + QString objectNamePrefix = layerName; + if ( objectNamePrefix != QString() ) objectNamePrefix += QStringLiteral( "" ); + + Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( objectNamePrefix + QStringLiteral( "Flat_tile" ) ), "", this ); mObjects.push_back( object ); object->setSmoothEdges( mSmoothEdges ); @@ -464,7 +467,7 @@ void Qgs3DSceneExporter::parseFlatTile( QgsTerrainTileEntity *tileEntity ) } } -void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity ) +void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity, const QString &layerName ) { Qt3DRender::QGeometryRenderer *mesh = findTypedComponent( tileEntity ); Qt3DCore::QTransform *transform = findTypedComponent( tileEntity ); @@ -488,7 +491,10 @@ void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity ) QByteArray indexBytes = indexAttribute->buffer()->data(); QVector indexBuffer = getIndexData( indexAttribute, indexBytes ); - Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( QStringLiteral( "DEM_tile" ) ), "", this ); + QString objectNamePrefix = layerName; + if ( objectNamePrefix != QString() ) objectNamePrefix += QStringLiteral( "_" ); + + Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( layerName + QStringLiteral( "DEM_tile" ) ), "", this ); mObjects.push_back( object ); object->setSmoothEdges( mSmoothEdges ); @@ -516,18 +522,21 @@ void Qgs3DSceneExporter::parseDemTile( QgsTerrainTileEntity *tileEntity ) } } -void Qgs3DSceneExporter::parseMeshTile( QgsTerrainTileEntity *tileEntity ) +void Qgs3DSceneExporter::parseMeshTile( QgsTerrainTileEntity *tileEntity, const QString &layerName ) { + QString objectNamePrefix = layerName; + if ( objectNamePrefix != QString() ) objectNamePrefix += QStringLiteral( "_" ); + QList renderers = tileEntity->findChildren(); for ( Qt3DRender::QGeometryRenderer *renderer : renderers ) { - Qgs3DExportObject *obj = processGeometryRenderer( renderer ); + Qgs3DExportObject *obj = processGeometryRenderer( renderer, objectNamePrefix ); if ( obj == nullptr ) continue; mObjects << obj; } } -QVector Qgs3DSceneExporter::processInstancedPointGeometry( Qt3DCore::QEntity *entity ) +QVector Qgs3DSceneExporter::processInstancedPointGeometry( Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) { QVector objects; QList geometriesList = entity->findChildren(); @@ -552,7 +561,7 @@ QVector Qgs3DSceneExporter::processInstancedPointGeometry( QVector instancePosition = getAttributeData( instanceDataAttribute, instancePositionBytes ); for ( int i = 0; i < instancePosition.size(); i += 3 ) { - Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( QStringLiteral( "shape_geometry" ) ), "", this ); + Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( objectNamePrefix + QStringLiteral( "shape_geometry" ) ), "", this ); objects.push_back( object ); object->setupPositionCoordinates( positionData, 1.0f, QVector3D( instancePosition[i], instancePosition[i + 1], instancePosition[i + 2] ) ); object->setupFaces( indexData ); @@ -571,7 +580,7 @@ QVector Qgs3DSceneExporter::processInstancedPointGeometry( return objects; } -QVector Qgs3DSceneExporter::processSceneLoaderGeometries( Qt3DRender::QSceneLoader *sceneLoader ) +QVector Qgs3DSceneExporter::processSceneLoaderGeometries( Qt3DRender::QSceneLoader *sceneLoader, const QString &objectNamePrefix ) { QVector objects; Qt3DCore::QEntity *sceneLoaderParent = qobject_cast( sceneLoader->parent() ); @@ -586,14 +595,14 @@ QVector Qgs3DSceneExporter::processSceneLoaderGeometries( Q for ( QString entityName : sceneLoader->entityNames() ) { Qt3DRender::QGeometryRenderer *mesh = qobject_cast( sceneLoader->component( entityName, Qt3DRender::QSceneLoader::GeometryRendererComponent ) ); - Qgs3DExportObject *object = processGeometryRenderer( mesh, sceneScale, sceneTranslation ); + Qgs3DExportObject *object = processGeometryRenderer( mesh, objectNamePrefix, sceneScale, sceneTranslation ); if ( object == nullptr ) continue; objects.push_back( object ); } return objects; } -Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, float sceneScale, QVector3D sceneTranslation ) +Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, const QString &objectNamePrefix, float sceneScale, QVector3D sceneTranslation ) { // We only export triangles for now if ( mesh->primitiveType() != Qt3DRender::QGeometryRenderer::Triangles ) return nullptr; @@ -651,7 +660,7 @@ Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeo return nullptr; } - Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( QStringLiteral( "mesh_geometry" ) ), "", this ); + Qgs3DExportObject *object = new Qgs3DExportObject( getObjectName( objectNamePrefix + QStringLiteral( "mesh_geometry" ) ), "", this ); object->setupPositionCoordinates( positionData, scale * sceneScale, translation + sceneTranslation ); object->setupFaces( indexData ); @@ -674,7 +683,7 @@ Qgs3DExportObject *Qgs3DSceneExporter::processGeometryRenderer( Qt3DRender::QGeo return object; } -QVector Qgs3DSceneExporter::processLines( Qt3DCore::QEntity *entity ) +QVector Qgs3DSceneExporter::processLines( Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) { QVector objs; QList renderers = entity->findChildren(); @@ -703,7 +712,7 @@ QVector Qgs3DSceneExporter::processLines( Qt3DCore::QEntity QVector positionData = getAttributeData( positionAttribute, vertexBytes ); QVector indexData = getIndexData( indexAttribute, indexBytes ); - Qgs3DExportObject *exportObject = new Qgs3DExportObject( getObjectName( "line" ), "", this ); + Qgs3DExportObject *exportObject = new Qgs3DExportObject( getObjectName( objectNamePrefix + QStringLiteral( "line" ) ), QString(), this ); exportObject->setType( Qgs3DExportObject::LineStrip ); exportObject->setupPositionCoordinates( positionData ); exportObject->setupLine( indexData ); @@ -713,7 +722,7 @@ QVector Qgs3DSceneExporter::processLines( Qt3DCore::QEntity return objs; } -Qgs3DExportObject *Qgs3DSceneExporter::processPoints( Qt3DCore::QEntity *entity ) +Qgs3DExportObject *Qgs3DSceneExporter::processPoints( Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) { QVector points; QList renderers = entity->findChildren(); @@ -729,7 +738,7 @@ Qgs3DExportObject *Qgs3DSceneExporter::processPoints( Qt3DCore::QEntity *entity QVector positions = getAttributeData( positionAttribute, positionBytes ); points << positions; } - Qgs3DExportObject *obj = new Qgs3DExportObject( getObjectName( "points" ), "", this ); + Qgs3DExportObject *obj = new Qgs3DExportObject( getObjectName( objectNamePrefix + QStringLiteral( "points" ) ), QString(), this ); obj->setType( Qgs3DExportObject::Points ); obj->setupPositionCoordinates( points ); return obj; diff --git a/src/3d/qgs3dsceneexporter.h b/src/3d/qgs3dsceneexporter.h index 1c7f88c9669..5f6b7b5c54a 100644 --- a/src/3d/qgs3dsceneexporter.h +++ b/src/3d/qgs3dsceneexporter.h @@ -60,7 +60,8 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity bool parseVectorLayerEntity( Qt3DCore::QEntity *entity, QgsVectorLayer *layer ); //! Creates terrain export objects from the terrain entity - void parseTerrain( QgsTerrainEntity *terrain ); + void parseTerrain( QgsTerrainEntity *terrain, const QString &layer ); + //! Saves the scene to a .obj file void save( const QString &sceneName, const QString &sceneFolderPath ); @@ -95,17 +96,17 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity private: //! Constructs Qgs3DExportObject from instanced point geometry - QVector processInstancedPointGeometry( Qt3DCore::QEntity *entity ); + QVector processInstancedPointGeometry( Qt3DCore::QEntity *entity, const QString &objectNamePrefix ); //! Constructs Qgs3DExportObject from 3D models loaded using a scene loader - QVector processSceneLoaderGeometries( Qt3DRender::QSceneLoader *sceneLoader ); + QVector processSceneLoaderGeometries( Qt3DRender::QSceneLoader *sceneLoader, const QString &objectNamePrefix ); //! Constructs Qgs3DExportObject from geometry renderer - Qgs3DExportObject *processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, float sceneScale = 1.0f, QVector3D sceneTranslation = QVector3D( 0.0f, 0.0f, 0.0f ) ); + Qgs3DExportObject *processGeometryRenderer( Qt3DRender::QGeometryRenderer *mesh, const QString &objectNamePrefix, 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 processLines( Qt3DCore::QEntity *entity ); + QVector processLines( Qt3DCore::QEntity *entity, const QString &objectNamePrefix ); //! Constricts Qgs3DExportObject from billboard point entity - Qgs3DExportObject *processPoints( Qt3DCore::QEntity *entity ); + Qgs3DExportObject *processPoints( Qt3DCore::QEntity *entity, const QString &objectNamePrefix ); //! Returns a tile entity that contains the geometry to be exported and necessary scaling parameters QgsTerrainTileEntity *getFlatTerrainEntity( QgsTerrainEntity *terrain, QgsChunkNode *node ); @@ -115,11 +116,11 @@ class Qgs3DSceneExporter : public Qt3DCore::QEntity QgsTerrainTileEntity *getMeshTerrainEntity( QgsTerrainEntity *terrain, QgsChunkNode *node ); //! Constructs a Qgs3DExportObject from the DEM tile entity - void parseDemTile( QgsTerrainTileEntity *tileEntity ); + void parseDemTile( QgsTerrainTileEntity *tileEntity, const QString &layerName ); //! Constructs a Qgs3DExportObject from the flat tile entity - void parseFlatTile( QgsTerrainTileEntity *tileEntity ); + void parseFlatTile( QgsTerrainTileEntity *tileEntity, const QString &layerName ); //! Constructs a Qgs3DExportObject from the mesh terrain entity - void parseMeshTile( QgsTerrainTileEntity *meshEntity ); + void parseMeshTile( QgsTerrainTileEntity *meshEntity, const QString &layerName ); QString getObjectName( const QString &name ); private: