QGIS API Documentation 3.43.0-Master (37eec98dbf6)
qgsmesheditor.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsmesheditor.h - QgsMeshEditor
3
4 ---------------------
5 begin : 8.6.2021
6 copyright : (C) 2021 by Vincent Cloarec
7 email : vcloarec at gmail dot com
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16#ifndef QGSMESHEDITOR_H
17#define QGSMESHEDITOR_H
18
19#include <QObject>
20#include <QUndoCommand>
21#include <QPointer>
22
23#include "qgis.h"
24#include "qgsmeshdataset.h"
25#include "qgsmeshdataprovider.h"
26#include "qgstriangularmesh.h"
27#include "qgstopologicalmesh.h"
28
30
31#if defined(_MSC_VER)
32template CORE_EXPORT QVector<QVector<int>> SIP_SKIP;
33#endif
34
42class CORE_EXPORT QgsMeshEditingError
43{
44 public:
45
48
50 QgsMeshEditingError( Qgis::MeshEditingErrorType type, int elementIndex );
51
53
54 int elementIndex = -1;
55
56 bool operator==( const QgsMeshEditingError &other ) const {return ( other.errorType == errorType && other.elementIndex == elementIndex );}
57 bool operator!=( const QgsMeshEditingError &other ) const {return !operator==( other );}
58};
59
67class CORE_EXPORT QgsMeshEditor : public QObject
68{
69 Q_OBJECT
70 public:
71
73 QgsMeshEditor( QgsMeshLayer *meshLayer );
74
76 QgsMeshEditor( QgsMesh *nativeMesh, QgsTriangularMesh *triangularMesh, QObject *parent = nullptr ); SIP_SKIP
78
83 QgsMeshDatasetGroup *createZValueDatasetGroup() SIP_TRANSFERBACK;
84
86 QgsMeshEditingError initialize();
87
94 QgsMeshEditingError initializeWithErrorsFix();
95
101 bool fixError( const QgsMeshEditingError &error );
102
104 void resetTriangularMesh( QgsTriangularMesh *triangularMesh ); SIP_SKIP
105
111 bool faceCanBeAdded( const QgsMeshFace &face ) const;
112
121 bool faceCanBeAddedWithNewVertices( const QList<int> &verticesIndex, const QList<QgsMeshVertex> &newVertices ) const; SIP_SKIP
122
127 bool isFaceGeometricallyCompatible( const QgsMeshFace &face ) const;
128
130 QgsMeshEditingError addFaces( const QVector<QgsMeshFace> &faces ); SIP_SKIP
131
133 QgsMeshEditingError addFace( const QVector<int> &vertexIndexes );
134
143 QgsMeshEditingError addFaceWithNewVertices( const QList<int> &vertexIndexes, const QList<QgsMeshVertex> &newVertices ); SIP_SKIP
144
146 QgsMeshEditingError removeFaces( const QList<int> &facesToRemove );
147
149 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
150
152 void flipEdge( int vertexIndex1, int vertexIndex2 );
153
157 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
158
160 void merge( int vertexIndex1, int vertexIndex2 );
161
165 bool faceCanBeSplit( int faceIndex ) const;
166
171 int splitFaces( const QList<int> &faceIndexes );
172
181 int addVertices( const QVector<QgsMeshVertex> &vertices, double tolerance ); SIP_SKIP
182
191 int addPointsAsVertices( const QVector<QgsPoint> &point, double tolerance );
192
198 QgsMeshEditingError removeVerticesWithoutFillHoles( const QList<int> &verticesToRemoveIndexes );
199
207 QList<int> removeVerticesFillHoles( const QList<int> &verticesToRemoveIndexes );
208
212 void changeZValues( const QList<int> &verticesIndexes, const QList<double> &newValues );
213
225 bool canBeTransformed( const QList<int> &facesToCheck, const std::function<const QgsMeshVertex( int )> &transformFunction ) const; SIP_SKIP
226
232 void changeXYValues( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
233
239 void changeCoordinates( const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
240
244 void advancedEdit( QgsMeshAdvancedEditing *editing );
245
247 void stopEditing();
248
250 QgsRectangle extent() const;
251
253 bool isModified() const;
254
262 bool reindex( bool renumbering );
263
264 //----------- access element methods
265
267 QList<int> freeVerticesIndexes() const;
268
270 bool isVertexOnBoundary( int vertexIndex ) const;
271
273 bool isVertexFree( int vertexIndex ) const;
274
282 QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const; SIP_SKIP
283
285 QgsTopologicalMesh &topologicalMesh(); SIP_SKIP
286
288 QgsTriangularMesh *triangularMesh(); SIP_SKIP
289
291 bool checkConsistency( QgsMeshEditingError &error ) const;
292
297 bool edgeIsClose( QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition );
298
300 int validFacesCount() const;
301
303 int validVerticesCount() const;
304
306 int maximumVerticesPerFace() const;
307
314 void addVertexWithDelaunayRefinement( const QgsMeshVertex &vertex, const double tolerance );
315
316 signals:
318 void meshEdited();
319
320 private:
321 QgsMesh *mMesh = nullptr;
322 QgsTopologicalMesh mTopologicalMesh;
323 QgsTriangularMesh *mTriangularMesh = nullptr;
324 int mMaximumVerticesPerFace = 0;
325 QgsMeshDatasetGroup *mZValueDatasetGroup = nullptr;
326 int mValidVerticesCount = 0;
327 int mValidFacesCount = 0;
328
329 QVector<QgsMeshFace> prepareFaces( const QVector<QgsMeshFace> &faces, QgsMeshEditingError &error ) const;
330 QList<int> prepareFaceWithNewVertices( const QList<int> &vertices, const QList<QgsMeshVertex> &newVertices, QgsMeshEditingError &error ) const;
331 bool isFaceGeometricallyCompatible( const QList<int> &vertexIndex, const QList<QgsMeshVertex> &vertices ) const;
332
334 QUndoStack *mUndoStack = nullptr;
335
336 struct Edit
337 {
338 QgsTopologicalMesh::Changes topologicalChanges;
339 QgsTriangularMesh::Changes triangularMeshChanges;
340 };
341 void applyEdit( Edit &edit );
342 void reverseEdit( Edit &edit );
343
344 void applyAddVertex( Edit &edit, const QgsMeshVertex &vertex, double tolerance );
345 bool applyRemoveVertexFillHole( Edit &edit, int vertexIndex );
346 void applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes );
347 void applyAddFaces( Edit &edit, const QgsTopologicalMesh::TopologicalFaces &faces );
348 void applyRemoveFaces( Edit &edit, const QList<int> &faceToRemoveIndex );
349 void applyChangeZValue( Edit &edit, const QList<int> &verticesIndexes, const QList<double> &newValues );
350 void applyChangeXYValue( Edit &edit, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
351 void applyFlipEdge( Edit &edit, int vertexIndex1, int vertexIndex2 );
352 void applyMerge( Edit &edit, int vertexIndex1, int vertexIndex2 );
353 void applySplit( QgsMeshEditor::Edit &edit, int faceIndex );
354 void applyAdvancedEdit( Edit &edit, QgsMeshAdvancedEditing *editing );
355
356 void applyEditOnTriangularMesh( Edit &edit, const QgsTopologicalMesh::Changes &topologicChanges );
357
358 void updateElementsCount( const QgsTopologicalMesh::Changes &changes, bool apply = true );
359
360 friend class TestQgsMeshEditor;
367 friend class QgsMeshLayerUndoCommandSetZValue;
375
377};
378
379#ifndef SIP_RUN
380
388class QgsMeshLayerUndoCommandMeshEdit : public QUndoCommand
389{
390 public:
391
392 void undo() override;
393 void redo() override;
394
395 protected:
396
399 QPointer<QgsMeshEditor> mMeshEditor;
400 QList<QgsMeshEditor::Edit> mEdits;
401};
402
411{
412 public:
413
415 QgsMeshLayerUndoCommandAddVertices( QgsMeshEditor *meshEditor, const QVector<QgsMeshVertex> &vertices, double tolerance );
416 void redo() override;
417
418 private:
419 QVector<QgsMeshVertex> mVertices;
420 double mTolerance = 0;
421};
422
431{
432 public:
433
437 QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes );
438 void redo() override;
439
440 private:
441 QList<int> mVerticesToRemoveIndexes;
442};
443
452{
453 public:
454
463 QgsMeshLayerUndoCommandRemoveVerticesFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes, QList<int> *remainingVerticesPointer = nullptr );
464 void redo() override;
465
466 private:
467 QList<int> mVerticesToRemoveIndexes;
468 QList<int> *mRemainingVerticesPointer = nullptr;
469};
470
479{
480 public:
481
484
485 void redo() override;
486 private:
488};
489
498{
499 public:
500
502 QgsMeshLayerUndoCommandRemoveFaces( QgsMeshEditor *meshEditor, const QList<int> &facesToRemoveIndexes );
503
504 void redo() override;
505 private:
506 QList<int> mfacesToRemoveIndexes;
507};
508
517{
518 public:
519
524 QgsMeshLayerUndoCommandChangeZValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<double> &newValues );
525 void redo() override;
526
527 private:
528 QList<int> mVerticesIndexes;
529 QList<double> mNewValues;
530};
531
540{
541 public:
542
547 QgsMeshLayerUndoCommandChangeXYValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
548 void redo() override;
549
550 private:
551 QList<int> mVerticesIndexes;
552 QList<QgsPointXY> mNewValues;
553};
554
563{
564 public:
565
570 QgsMeshLayerUndoCommandChangeCoordinates( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
571 void redo() override;
572
573 private:
574 QList<int> mVerticesIndexes;
575 QList<QgsPoint> mNewCoordinates;
576};
577
586{
587 public:
588
592 QgsMeshLayerUndoCommandFlipEdge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
593 void redo() override;
594
595 private:
596 int mVertexIndex1 = -1;
597 int mVertexIndex2 = -1;
598};
599
608{
609 public:
610
615 QgsMeshLayerUndoCommandMerge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
616 void redo() override;
617
618 private:
619 int mVertexIndex1 = -1;
620 int mVertexIndex2 = -1;
621};
622
631{
632 public:
633
637 QgsMeshLayerUndoCommandSplitFaces( QgsMeshEditor *meshEditor, const QList<int> &faceIndexes );
638 void redo() override;
639
640 private:
641 QList<int> mFaceIndexes;
642};
643
644
652{
653 public:
654
657 void redo() override;
658
659 private:
660 QgsMeshAdvancedEditing *mAdvancedEditing = nullptr;
661};
662
663
672{
673 public:
674
677
678 void redo() override;
679 private:
680 QList<std::pair<int, int>> innerEdges( const QSet<int> &faces );
681 QSet<int> secondNeighboringTriangularFaces();
682
683 QgsMeshVertex mVertex;
684 double mTolerance;
685};
686
687#endif //SIP_RUN
688
689#endif // QGSMESHEDITOR_H
MeshEditingErrorType
Type of error that can occur during mesh frame editing.
Definition qgis.h:1622
Abstract class that can be derived to implement advanced editing on mesh.
Abstract class that represents a dataset group.
Represents an error which occurred during mesh editing.
Qgis::MeshEditingErrorType errorType
bool operator==(const QgsMeshEditingError &other) const
bool operator!=(const QgsMeshEditingError &other) const
Handles edit operations on a mesh layer.
Mesh layer undo/redo command for adding faces in mesh.
Mesh layer undo/redo command for adding vertex to face with Delaunay refinement of faces surrounding.
Mesh layer undo/redo command for adding vertices in mesh.
Mesh layer undo/redo command for applying advanced editing.
Mesh layer undo/redo command for changing coordinate (X,Y,Z) values of vertices.
Mesh layer undo/redo command for changing (X,Y) value of vertices.
Mesh layer undo/redo command for changing Z value of vertices.
Mesh layer undo/redo command for flipping edges.
Mesh layer undo/redo command for merging faces.
Base class for undo/redo command for mesh editing.
QList< QgsMeshEditor::Edit > mEdits
QPointer< QgsMeshEditor > mMeshEditor
Mesh layer undo/redo command for removing faces in mesh.
Mesh layer undo/redo command for removing vertices in mesh filling holes created by removed faces.
Mesh layer undo/redo command for removing vertices in mesh without filling holes created by removed f...
Mesh layer undo/redo command for splitting faces.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Convenience class that turns around a vertex and provides information about faces and vertices.
Represents a 2D point.
Definition qgspointxy.h:60
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
A rectangle specified with double values.
Contains topological differences between two states of a topological mesh, only accessible from the Q...
Contains independent faces and topological information about these faces.
Wraps a QgsMesh to ensure the consistency of the mesh during editing and helps to access elements fro...
Makes changes to a triangular mesh and keeps track of these changes.
A triangular/derived mesh with vertices in map coordinates.
#define SIP_SKIP
Definition qgis_sip.h:126
#define SIP_TRANSFERBACK
Definition qgis_sip.h:48
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QVector< int > QgsMeshFace
List of vertex indexes.
Mesh - vertices, edges and faces.