Skip to content
Permalink
Browse files
adapt 3D for live update with mesh editing (#44025)
  • Loading branch information
vcloarec committed Jul 12, 2021
1 parent aa64b29 commit d2fae52497b84e17bee2a32506ad9c52d6e57164
@@ -128,13 +128,22 @@ static QByteArray createIndexData( const QgsTriangularMesh &mesh )
const int faces = mesh.triangles().count();
const quint32 indices = static_cast<quint32>( 3 * faces );
Q_ASSERT( indices < std::numeric_limits<quint32>::max() );

// count non void faces
int nonVoidFaces = 0;
for ( int i = 0; i < faces; ++i )
if ( !mesh.triangles().at( i ).isEmpty() )
nonVoidFaces++;

QByteArray indexBytes;
indexBytes.resize( int( indices * sizeof( quint32 ) ) );
indexBytes.resize( int( nonVoidFaces * 3 * sizeof( quint32 ) ) );
quint32 *indexPtr = reinterpret_cast<quint32 *>( indexBytes.data() );

for ( int i = 0; i < faces; ++i )
{
const QgsMeshFace &face = mesh.triangles().at( i );
if ( face.isEmpty() )
continue;
for ( int i = 0; i < 3; ++i )
*indexPtr++ = quint32( face.at( i ) );
}
@@ -318,12 +327,15 @@ void QgsMesh3dGeometry::getData()
{
const uint nVerts = uint( mTriangulaMesh.vertices().count() );

const QByteArray indexData = mBuilder->indexData();
const uint effectiveIndexCount = indexData.size() / sizeof( qint32 );

mPositionAttribute->setCount( nVerts );
mNormalAttribute->setCount( nVerts );
mIndexAttribute->setCount( mTriangulaMesh.triangles().size() * 3 );
mIndexAttribute->setCount( effectiveIndexCount );

mVertexBuffer->setData( mBuilder->vertexData() );
mIndexBuffer->setData( mBuilder->indexData() );
mIndexBuffer->setData( indexData );
}

void QgsMesh3dGeometry::prepareVerticesPositionAttribute( Qt3DRender::QBuffer *buffer, int stride, int offset )
@@ -91,9 +91,17 @@ void QgsMeshTerrainGenerator::resolveReferences( const QgsProject &project )

void QgsMeshTerrainGenerator::setLayer( QgsMeshLayer *layer )
{
if ( mLayer.get() )
disconnect( mLayer.get(), &QgsMeshLayer::request3DUpdate, this, &QgsMeshTerrainGenerator::terrainChanged );

mLayer = QgsMapLayerRef( layer );
mIsValid = layer != nullptr;
updateTriangularMesh();
if ( mIsValid )
{
connect( mLayer.get(), &QgsMeshLayer::request3DUpdate, this, &QgsMeshTerrainGenerator::updateTriangularMesh );
connect( mLayer.get(), &QgsMeshLayer::request3DUpdate, this, &QgsMeshTerrainGenerator::terrainChanged );
}
}


@@ -57,6 +57,7 @@ class QgsMeshTerrainTileLoader: public QgsTerrainTileLoader
*/
class _3D_EXPORT QgsMeshTerrainGenerator: public QgsTerrainGenerator
{
Q_OBJECT
public:
//! Creates mesh terrain generator object
QgsMeshTerrainGenerator();
@@ -86,14 +87,17 @@ class _3D_EXPORT QgsMeshTerrainGenerator: public QgsTerrainGenerator
void readXml( const QDomElement &elem ) override;
float heightAt( double x, double y, const Qgs3DMapSettings & ) const override;

private slots:
void updateTriangularMesh();

private:
QgsMapLayerRef mLayer;
QgsCoordinateReferenceSystem mCrs;
QgsCoordinateTransformContext mTransformContext;
std::unique_ptr< QgsMesh3DSymbol > mSymbol;
QgsTriangularMesh mTriangularMesh;

void updateTriangularMesh();

};

#endif // QGSMESHTERRAINGENERATOR_H
@@ -202,25 +202,25 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
{
QgsDemTerrainGenerator *demTerrainGenerator = new QgsDemTerrainGenerator;
demTerrainGenerator->setCrs( mCrs, mTransformContext );
mTerrainGenerator.reset( demTerrainGenerator );
setTerrainGenerator( demTerrainGenerator );
}
else if ( terrainGenType == QLatin1String( "online" ) )
{
QgsOnlineTerrainGenerator *onlineTerrainGenerator = new QgsOnlineTerrainGenerator;
onlineTerrainGenerator->setCrs( mCrs, mTransformContext );
mTerrainGenerator.reset( onlineTerrainGenerator );
setTerrainGenerator( onlineTerrainGenerator );
}
else if ( terrainGenType == QLatin1String( "mesh" ) )
{
QgsMeshTerrainGenerator *meshTerrainGenerator = new QgsMeshTerrainGenerator;
meshTerrainGenerator->setCrs( mCrs, mTransformContext );
mTerrainGenerator.reset( meshTerrainGenerator );
setTerrainGenerator( meshTerrainGenerator );
}
else // "flat"
{
QgsFlatTerrainGenerator *flatGen = new QgsFlatTerrainGenerator;
flatGen->setCrs( mCrs );
mTerrainGenerator.reset( flatGen );
setTerrainGenerator( flatGen );
}
mTerrainGenerator->readXml( elemTerrainGenerator );

@@ -626,10 +626,12 @@ void Qgs3DMapSettings::setTerrainGenerator( QgsTerrainGenerator *gen )
if ( mTerrainGenerator )
{
disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::terrainChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
}

mTerrainGenerator.reset( gen );
connect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
connect( mTerrainGenerator.get(), &QgsTerrainGenerator::terrainChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );

emit terrainGeneratorChanged();
}
@@ -113,6 +113,9 @@ class _3D_EXPORT QgsTerrainGenerator : public QgsQuadtreeChunkLoaderFactory
//! Emitted when the terrain extent has changed
void extentChanged();

//! Emitted when the terrain changed (for example, raster DEM or mesh have data changed)
void terrainChanged();

protected:

QgsTilingScheme mTerrainTilingScheme; //!< Tiling scheme of the terrain
@@ -707,6 +707,7 @@ void QgsMeshLayer::onMeshEdited()
mRendererCache.reset( new QgsMeshLayerRendererCache() );
emit layerModified();
triggerRepaint();
trigger3DUpdate();
}

QgsMeshDatasetGroupTreeItem *QgsMeshLayer::datasetGroupTreeRootItem() const
@@ -461,6 +461,9 @@ QVector<QVector3D> QgsTriangularMesh::vertexNormals( float vertScale ) const

for ( const auto &face : triangles() )
{
if ( face.isEmpty() )
continue;

for ( int i = 0; i < 3; i++ )
{
int index1( face.at( i ) );

0 comments on commit d2fae52

Please sign in to comment.