@@ -176,7 +176,7 @@ bool QgsMeshEditor::faceCanBeAdded( const QgsMeshFace &face )
176
176
177
177
// Check if there is topological error with the mesh
178
178
QgsTopologicalMesh::TopologicalFaces topologicalFaces = mTopologicalMesh .createNewTopologicalFaces ( facesToAdd, true , error );
179
- error = mTopologicalMesh .canFacesBeAdded ( topologicalFaces );
179
+ error = mTopologicalMesh .facesCanBeAdded ( topologicalFaces );
180
180
181
181
if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
182
182
return false ;
@@ -249,14 +249,22 @@ void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, const QgsMeshVert
249
249
updateElementsCount ( edit.topologicalChanges );
250
250
}
251
251
252
- void QgsMeshEditor::applyRemoveVertexFillHole ( QgsMeshEditor::Edit &edit, int vertexIndex )
252
+ bool QgsMeshEditor::applyRemoveVertexFillHole ( QgsMeshEditor::Edit &edit, int vertexIndex )
253
253
{
254
- applyEditOnTriangularMesh ( edit, mTopologicalMesh .removeVertexFillHole ( vertexIndex ) );
254
+ QgsTopologicalMesh::Changes changes = mTopologicalMesh .removeVertexFillHole ( vertexIndex );
255
255
256
- if ( mZValueDatasetGroup )
257
- mZValueDatasetGroup ->setStatisticObsolete ();
256
+ if ( !changes.isEmpty () )
257
+ {
258
+ applyEditOnTriangularMesh ( edit, changes );
258
259
259
- updateElementsCount ( edit.topologicalChanges );
260
+ if ( mZValueDatasetGroup )
261
+ mZValueDatasetGroup ->setStatisticObsolete ();
262
+
263
+ updateElementsCount ( edit.topologicalChanges );
264
+ return true ;
265
+ }
266
+ else
267
+ return false ;
260
268
}
261
269
262
270
void QgsMeshEditor::applyRemoveVerticesWithoutFillHole ( QgsMeshEditor::Edit &edit, const QList<int > &verticesIndexes )
@@ -348,9 +356,10 @@ void QgsMeshEditor::updateElementsCount( const QgsTopologicalMesh::Changes &chan
348
356
}
349
357
}
350
358
351
- bool QgsMeshEditor::checkConsistency () const
359
+ bool QgsMeshEditor::checkConsistency ( QgsMeshEditingError &error ) const
352
360
{
353
- switch ( mTopologicalMesh .checkConsistency ().errorType )
361
+ error = mTopologicalMesh .checkConsistency ();
362
+ switch ( error.errorType )
354
363
{
355
364
case Qgis::MeshEditingErrorType::NoError:
356
365
break ;
@@ -429,9 +438,14 @@ int QgsMeshEditor::validVerticesCount() const
429
438
return mValidVerticesCount ;
430
439
}
431
440
441
+ int QgsMeshEditor::maximumVerticesPerFace () const
442
+ {
443
+ return mMaximumVerticesPerFace ;
444
+ }
445
+
432
446
QgsMeshEditingError QgsMeshEditor::removeFaces ( const QList<int > &facesToRemove )
433
447
{
434
- QgsMeshEditingError error = mTopologicalMesh .canFacesBeRemoved ( facesToRemove );
448
+ QgsMeshEditingError error = mTopologicalMesh .facesCanBeRemoved ( facesToRemove );
435
449
if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
436
450
return error;
437
451
@@ -468,7 +482,7 @@ void QgsMeshEditor::merge( int vertexIndex1, int vertexIndex2 )
468
482
469
483
bool QgsMeshEditor::faceCanBeSplit ( int faceIndex ) const
470
484
{
471
- return mTopologicalMesh .faceCanBeSplit ( faceIndex );
485
+ return mTopologicalMesh .canBeSplit ( faceIndex );
472
486
}
473
487
474
488
int QgsMeshEditor::splitFaces ( const QList<int > &faceIndexes )
@@ -520,7 +534,7 @@ QgsMeshEditingError QgsMeshEditor::addFaces( const QVector<QVector<int> > &faces
520
534
521
535
QgsTopologicalMesh::TopologicalFaces topologicalFaces = mTopologicalMesh .createNewTopologicalFaces ( facesToAdd, true , error );
522
536
523
- error = mTopologicalMesh .canFacesBeAdded ( topologicalFaces );
537
+ error = mTopologicalMesh .facesCanBeAdded ( topologicalFaces );
524
538
525
539
if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
526
540
return error;
@@ -583,31 +597,34 @@ int QgsMeshEditor::addPointsAsVertices( const QVector<QgsPoint> &point, double t
583
597
return addVertices ( point, tolerance );
584
598
}
585
599
586
- QgsMeshEditingError QgsMeshEditor::removeVertices ( const QList<int > &verticesToRemoveIndexes, bool fillHoles )
600
+ QgsMeshEditingError QgsMeshEditor::removeVerticesWithoutFillHoles ( const QList<int > &verticesToRemoveIndexes )
587
601
{
588
602
QgsMeshEditingError error;
589
603
590
604
QList<int > verticesIndexes = verticesToRemoveIndexes;
591
605
592
- if ( !fillHoles )
593
- {
594
- QSet<int > concernedNativeFaces;
595
- for ( const int vi : std::as_const ( verticesIndexes ) )
596
- concernedNativeFaces.unite ( qgis::listToSet ( mTopologicalMesh .facesAroundVertex ( vi ) ) );
606
+ QSet<int > concernedNativeFaces;
607
+ for ( const int vi : std::as_const ( verticesIndexes ) )
608
+ concernedNativeFaces.unite ( qgis::listToSet ( mTopologicalMesh .facesAroundVertex ( vi ) ) );
597
609
598
- error = mTopologicalMesh .canFacesBeRemoved ( concernedNativeFaces.values () );
599
- if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
600
- return error;
601
- }
610
+ error = mTopologicalMesh .facesCanBeRemoved ( concernedNativeFaces.values () );
602
611
603
- if ( error.errorType == Qgis::MeshEditingErrorType::NoError )
604
- {
605
- mUndoStack ->push ( new QgsMeshLayerUndoCommandRemoveVertices ( this , verticesIndexes, fillHoles ) );
606
- }
612
+ if ( error.errorType != Qgis::MeshEditingErrorType::NoError )
613
+ return error;
607
614
615
+ mUndoStack ->push ( new QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles ( this , verticesIndexes ) );
608
616
return error;
609
617
}
610
618
619
+ QList<int > QgsMeshEditor::removeVerticesFillHoles ( const QList<int > &verticesToRemoveIndexes )
620
+ {
621
+ QList<int > remainingVertices;
622
+ mUndoStack ->push ( new QgsMeshLayerUndoCommandRemoveVerticesFillHoles ( this , verticesToRemoveIndexes, &remainingVertices ) );
623
+
624
+ return remainingVertices;
625
+ }
626
+
627
+
611
628
void QgsMeshEditor::changeZValues ( const QList<int > &verticesIndexes, const QList<double > &newZValues )
612
629
{
613
630
mUndoStack ->push ( new QgsMeshLayerUndoCommandChangeZValue ( this , verticesIndexes, newZValues ) );
@@ -802,32 +819,76 @@ void QgsMeshLayerUndoCommandAddVertices::redo()
802
819
}
803
820
}
804
821
805
- QgsMeshLayerUndoCommandRemoveVertices::QgsMeshLayerUndoCommandRemoveVertices ( QgsMeshEditor *meshEditor, const QList<int > &verticesToRemoveIndexes, bool fillHole )
822
+ QgsMeshLayerUndoCommandRemoveVerticesFillHoles::QgsMeshLayerUndoCommandRemoveVerticesFillHoles (
823
+ QgsMeshEditor *meshEditor,
824
+ const QList<int > &verticesToRemoveIndexes,
825
+ QList<int > *remainingVerticesPointer )
806
826
: QgsMeshLayerUndoCommandMeshEdit( meshEditor )
807
827
, mVerticesToRemoveIndexes( verticesToRemoveIndexes )
808
- , mFillHole( fillHole )
828
+ , mRemainingVerticesPointer( remainingVerticesPointer )
809
829
{
810
- setText ( QObject::tr ( " Remove %n vertices" , nullptr , verticesToRemoveIndexes.count () ) ) ;
830
+ setText ( QObject::tr ( " Remove %n vertices filling holes " , nullptr , verticesToRemoveIndexes.count () ) );
811
831
}
812
832
813
- void QgsMeshLayerUndoCommandRemoveVertices ::redo ()
833
+ void QgsMeshLayerUndoCommandRemoveVerticesFillHoles ::redo ()
814
834
{
835
+ int initialVertexCount = mVerticesToRemoveIndexes .count ();
815
836
if ( !mVerticesToRemoveIndexes .isEmpty () )
816
837
{
817
838
QgsMeshEditor::Edit edit;
818
- if ( mFillHole )
839
+ QList<int > vertexToRetry;
840
+ while ( !mVerticesToRemoveIndexes .isEmpty () )
819
841
{
842
+ // try again and again until there is no vertices to remove anymore or nothing is removed.
820
843
for ( const int &vertex : std::as_const ( mVerticesToRemoveIndexes ) )
821
844
{
822
- mMeshEditor ->applyRemoveVertexFillHole ( edit, vertex );
823
- mEdits .append ( edit );
845
+ if ( mMeshEditor ->applyRemoveVertexFillHole ( edit, vertex ) )
846
+ mEdits .append ( edit );
847
+ else
848
+ vertexToRetry.append ( vertex );
824
849
}
850
+
851
+ if ( vertexToRetry.count () == mVerticesToRemoveIndexes .count () )
852
+ break ;
853
+ else
854
+ mVerticesToRemoveIndexes = vertexToRetry;
825
855
}
826
- else
827
- {
828
- mMeshEditor ->applyRemoveVerticesWithoutFillHole ( edit, mVerticesToRemoveIndexes );
829
- mEdits .append ( edit );
830
- }
856
+
857
+ if ( initialVertexCount == mVerticesToRemoveIndexes .count () )
858
+ setObsolete ( true );
859
+
860
+ if ( mRemainingVerticesPointer != nullptr )
861
+ *mRemainingVerticesPointer = mVerticesToRemoveIndexes ;
862
+
863
+ mRemainingVerticesPointer = nullptr ;
864
+
865
+ mVerticesToRemoveIndexes .clear (); // not needed anymore, changes are store in mEdits
866
+ }
867
+ else
868
+ {
869
+ for ( QgsMeshEditor::Edit &edit : mEdits )
870
+ mMeshEditor ->applyEdit ( edit );
871
+ }
872
+ }
873
+
874
+
875
+ QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles::QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles (
876
+ QgsMeshEditor *meshEditor,
877
+ const QList<int > &verticesToRemoveIndexes )
878
+ : QgsMeshLayerUndoCommandMeshEdit( meshEditor )
879
+ , mVerticesToRemoveIndexes( verticesToRemoveIndexes )
880
+ {
881
+ setText ( QObject::tr ( " Remove %n vertices without filling holes" , nullptr , verticesToRemoveIndexes.count () ) ) ;
882
+ }
883
+
884
+ void QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles::redo ()
885
+ {
886
+ if ( !mVerticesToRemoveIndexes .isEmpty () )
887
+ {
888
+ QgsMeshEditor::Edit edit;
889
+
890
+ mMeshEditor ->applyRemoveVerticesWithoutFillHole ( edit, mVerticesToRemoveIndexes );
891
+ mEdits .append ( edit );
831
892
832
893
mVerticesToRemoveIndexes .clear (); // not needed anymore, changes are store in mEdits
833
894
}
0 commit comments