Skip to content
Permalink
Browse files
fix undo/redo and mesh spatial index during mesh edinting
  • Loading branch information
vcloarec authored and wonder-sk committed Aug 24, 2021
1 parent 9258369 commit 196fa15a49212ccede0fbf2246ba36327f1873d2
@@ -184,7 +184,7 @@ void QgsMeshEditor::applyEdit( QgsMeshEditor::Edit &edit )
void QgsMeshEditor::reverseEdit( QgsMeshEditor::Edit &edit )
{
mTopologicalMesh.reverseChanges( edit.topologicalChanges );
mTriangularMesh->reverseChanges( edit.triangularMeshChanges );
mTriangularMesh->reverseChanges( edit.triangularMeshChanges, *mMesh );
}

void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, const QgsMeshVertex &vertex )
@@ -30,6 +30,9 @@ using namespace SpatialIndex;
static Region faceToRegion( const QgsMesh &mesh, int id )
{
const QgsMeshFace face = mesh.face( id );

Q_ASSERT( !face.isEmpty() );

const QVector<QgsMeshVertex> &vertices = mesh.vertices;

double xMinimum = vertices[face[0]].x();
@@ -190,14 +193,19 @@ class QgsMeshIteratorDataStream : public IDataStream
void readNextEntry()
{
SpatialIndex::Region r;
if ( mIterator < mFeaturesCount )
while ( mIterator < mFeaturesCount )
{
r = mFeatureToRegionFunction( mMesh, mIterator );
mNextData = new RTree::Data(
0,
nullptr,
r,
mIterator );
if ( !mMesh.faces.at( mIterator ).isEmpty() )
{
r = mFeatureToRegionFunction( mMesh, mIterator );
mNextData = new RTree::Data(
0,
nullptr,
r,
mIterator );
++mIterator;
return;
}
++mIterator;
}
}
@@ -739,6 +739,11 @@ QList<int> QgsTopologicalMesh::Changes::nativeFacesIndexesGeometryChanged() cons
return mNativeFacesIndexesGeometryChanged;
}

QList<int> QgsTopologicalMesh::Changes::verticesToRemoveIndexes() const
{
return mVerticesToRemoveIndexes;
}

int QgsTopologicalMesh::Changes::addedFaceIndexInMesh( int internalIndex ) const
{
if ( internalIndex == -1 )
@@ -100,6 +100,9 @@ class CORE_EXPORT QgsTopologicalMesh
//! Returns the added vertices with this changes
QVector<QgsMeshVertex> addedVertices() const;

//! Returns the indexes of vertices to remove
QList<int> verticesToRemoveIndexes() const;

//! Returns the indexes of vertices that have changed coordinates
QList<int> changedCoordinatesVerticesIndexes() const;

@@ -160,14 +160,14 @@ bool QgsTriangularMesh::update( QgsMesh *nativeMesh, const QgsCoordinateTransfor

bool needUpdateVerticesCoordinates = mTriangularMesh.vertices.size() != nativeMesh->vertices.size() ||
( ( mCoordinateTransform.isValid() || transform.isValid() ) &&
( mCoordinateTransform.sourceCrs() != transform.sourceCrs() &&
mCoordinateTransform.destinationCrs() != transform.destinationCrs() &&
( mCoordinateTransform.sourceCrs() != transform.sourceCrs() ||
mCoordinateTransform.destinationCrs() != transform.destinationCrs() ||
mCoordinateTransform.isValid() != transform.isValid() ) ) ;

bool needUpdateFrame = mTriangularMesh.vertices.size() != nativeMesh->vertices.size() ||
mNativeMeshFaceCentroids.size() != nativeMesh->faces.size() ||
mTriangularMesh.faces.size() >= nativeMesh->faces.size() ||
mTriangularMesh.edges.size() == nativeMesh->edges.size();
mTriangularMesh.faces.size() < nativeMesh->faces.size() ||
mTriangularMesh.edges.size() != nativeMesh->edges.size();


// FIND OUT IF UPDATE IS NEEDED
@@ -832,7 +832,7 @@ void QgsTriangularMesh::applyChanges( const QgsTriangularMesh::Changes &changes
mNativeMeshFaceCentroids[changes.mNativeFaceIndexesGeometryChanged.at( i )] = calculateCentroid( changes.mNativeFacesGeometryChanged.at( i ) );
}

void QgsTriangularMesh::reverseChanges( const QgsTriangularMesh::Changes &changes )
void QgsTriangularMesh::reverseChanges( const QgsTriangularMesh::Changes &changes, const QgsMesh &nativeMesh )
{
//reverse added faces and added vertices
if ( !changes.mNativeFacesToAdd.isEmpty() )
@@ -850,6 +850,13 @@ void QgsTriangularMesh::reverseChanges( const QgsTriangularMesh::Changes &change
int initialVerticesCount = mTriangularMesh.vertices.count() - changes.mAddedVertices.count();
mTriangularMesh.vertices.resize( initialVerticesCount );

// for each vertex to remove, check if the triangular vertex is empty,
// that means vertices had to be updated from the native mesh but faces was empty
// we need to update the vertices with the reverse native face
for ( const int i : std::as_const( changes.mVerticesIndexesToRemove ) )
if ( mTriangularMesh.vertex( i ).isEmpty() )
mTriangularMesh.vertices[i] = nativeToTriangularCoordinates( nativeMesh.vertex( i ) );

// reverse removed faces
QVector<QgsMeshFace> restoredTriangles;
QVector<int> restoredTriangularToNative;
@@ -906,6 +913,7 @@ QgsTriangularMesh::Changes::Changes( const QgsTopologicalMesh::Changes &topologi
const QgsMesh &nativeMesh )
{
mAddedVertices = topologicalChanges.addedVertices();
mVerticesIndexesToRemove = topologicalChanges.verticesToRemoveIndexes();
mNativeFacesToAdd = topologicalChanges.addedFaces();
mNativeFacesToRemove = topologicalChanges.removedFaces();
mNativeFaceIndexesToRemove = topologicalChanges.removedFaceIndexes();
@@ -263,6 +263,7 @@ class CORE_EXPORT QgsTriangularMesh // TODO rename to QgsRendererMesh in QGIS 4
private:
// triangular mesh elements that can be changed if the triangular mesh is updated, are not stored and have to be retrieve
QVector<QgsMeshVertex> mAddedVertices;
QList<int> mVerticesIndexesToRemove;
QList<int> mChangedVerticesCoordinates;
mutable QList<double> mOldZValue;
QList<double> mNewZValue;
@@ -294,7 +295,7 @@ class CORE_EXPORT QgsTriangularMesh // TODO rename to QgsRendererMesh in QGIS 4
*
* \since QGIS 3.22
*/
void reverseChanges( const Changes &changes );
void reverseChanges( const Changes &changes, const QgsMesh &nativeMesh );

/**
* Transforms the \a vertex from native coordinates system to triangular mesh coordinates system.

0 comments on commit 196fa15

Please sign in to comment.