QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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 "qgis.h"
20#include "qgsmeshdataprovider.h"
21#include "qgsmeshdataset.h"
22#include "qgstopologicalmesh.h"
23#include "qgstriangularmesh.h"
24
25#include <QObject>
26#include <QPointer>
27#include <QUndoCommand>
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
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
77 ~QgsMeshEditor() override;
78
79 // TODO QGIS 5.0 -- fix this mess
80
88 std::unique_ptr< QgsMeshDatasetGroup > createZValueDatasetGroup();
89
92
100
106 bool fixError( const QgsMeshEditingError &error );
107
110
116 bool faceCanBeAdded( const QgsMeshFace &face ) const;
117
126 bool faceCanBeAddedWithNewVertices( const QList<int> &verticesIndex, const QList<QgsMeshVertex> &newVertices ) const; SIP_SKIP
127
132 bool isFaceGeometricallyCompatible( const QgsMeshFace &face ) const;
133
135 QgsMeshEditingError addFaces( const QVector<QgsMeshFace> &faces ); SIP_SKIP
136
138 QgsMeshEditingError addFace( const QVector<int> &vertexIndexes );
139
148 QgsMeshEditingError addFaceWithNewVertices( const QList<int> &vertexIndexes, const QList<QgsMeshVertex> &newVertices ); SIP_SKIP
149
151 QgsMeshEditingError removeFaces( const QList<int> &facesToRemove );
152
154 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
155
157 void flipEdge( int vertexIndex1, int vertexIndex2 );
158
162 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
163
165 void merge( int vertexIndex1, int vertexIndex2 );
166
170 bool faceCanBeSplit( int faceIndex ) const;
171
176 int splitFaces( const QList<int> &faceIndexes );
177
186 int addVertices( const QVector<QgsMeshVertex> &vertices, double tolerance ); SIP_SKIP
187
196 int addPointsAsVertices( const QVector<QgsPoint> &point, double tolerance );
197
203 QgsMeshEditingError removeVerticesWithoutFillHoles( const QList<int> &verticesToRemoveIndexes );
204
212 QList<int> removeVerticesFillHoles( const QList<int> &verticesToRemoveIndexes );
213
217 void changeZValues( const QList<int> &verticesIndexes, const QList<double> &newValues );
218
230 bool canBeTransformed( const QList<int> &facesToCheck, const std::function<const QgsMeshVertex( int )> &transformFunction ) const; SIP_SKIP
231
237 void changeXYValues( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
238
244 void changeCoordinates( const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
245
249 void advancedEdit( QgsMeshAdvancedEditing *editing );
250
252 void stopEditing();
253
255 QgsRectangle extent() const;
256
258 bool isModified() const;
259
267 bool reindex( bool renumbering );
268
269 //----------- access element methods
270
272 QList<int> freeVerticesIndexes() const;
273
275 bool isVertexOnBoundary( int vertexIndex ) const;
276
278 bool isVertexFree( int vertexIndex ) const;
279
287 QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const; SIP_SKIP
288
291
294
296 bool checkConsistency( QgsMeshEditingError &error ) const;
297
302 bool edgeIsClose( QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition );
303
305 int validFacesCount() const;
306
308 int validVerticesCount() const;
309
311 int maximumVerticesPerFace() const;
312
319 void addVertexWithDelaunayRefinement( const QgsMeshVertex &vertex, const double tolerance );
320
321 signals:
324
325 private:
326 QgsMesh *mMesh = nullptr;
327 QgsTopologicalMesh mTopologicalMesh;
328 QgsTriangularMesh *mTriangularMesh = nullptr;
329 int mMaximumVerticesPerFace = 0;
330 QgsMeshDatasetGroup *mZValueDatasetGroup = nullptr;
331 int mValidVerticesCount = 0;
332 int mValidFacesCount = 0;
333
334 QVector<QgsMeshFace> prepareFaces( const QVector<QgsMeshFace> &faces, QgsMeshEditingError &error ) const;
335 QList<int> prepareFaceWithNewVertices( const QList<int> &vertices, const QList<QgsMeshVertex> &newVertices, QgsMeshEditingError &error ) const;
336 bool isFaceGeometricallyCompatible( const QList<int> &vertexIndex, const QList<QgsMeshVertex> &vertices ) const;
337
339 QUndoStack *mUndoStack = nullptr;
340
341 struct Edit
342 {
343 QgsTopologicalMesh::Changes topologicalChanges;
344 QgsTriangularMesh::Changes triangularMeshChanges;
345 };
346 void applyEdit( Edit &edit );
347 void reverseEdit( Edit &edit );
348
349 void applyAddVertex( Edit &edit, const QgsMeshVertex &vertex, double tolerance );
350 bool applyRemoveVertexFillHole( Edit &edit, int vertexIndex );
351 void applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes );
352 void applyAddFaces( Edit &edit, const QgsTopologicalMesh::TopologicalFaces &faces );
353 void applyRemoveFaces( Edit &edit, const QList<int> &faceToRemoveIndex );
354 void applyChangeZValue( Edit &edit, const QList<int> &verticesIndexes, const QList<double> &newValues );
355 void applyChangeXYValue( Edit &edit, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
356 void applyFlipEdge( Edit &edit, int vertexIndex1, int vertexIndex2 );
357 void applyMerge( Edit &edit, int vertexIndex1, int vertexIndex2 );
358 void applySplit( QgsMeshEditor::Edit &edit, int faceIndex );
359 void applyAdvancedEdit( Edit &edit, QgsMeshAdvancedEditing *editing );
360
361 void applyEditOnTriangularMesh( Edit &edit, const QgsTopologicalMesh::Changes &topologicChanges );
362
363 void updateElementsCount( const QgsTopologicalMesh::Changes &changes, bool apply = true );
364
365 friend class TestQgsMeshEditor;
380
382};
383
384#ifndef SIP_RUN
385
393class QgsMeshLayerUndoCommandMeshEdit : public QUndoCommand
394{
395 public:
396
397 void undo() override;
398 void redo() override;
399
400 protected:
401
404 QPointer<QgsMeshEditor> mMeshEditor;
405 QList<QgsMeshEditor::Edit> mEdits;
406};
407
416{
417 public:
418
420 QgsMeshLayerUndoCommandAddVertices( QgsMeshEditor *meshEditor, const QVector<QgsMeshVertex> &vertices, double tolerance );
421 void redo() override;
422
423 private:
424 QVector<QgsMeshVertex> mVertices;
425 double mTolerance = 0;
426};
427
436{
437 public:
438
442 QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes );
443 void redo() override;
444
445 private:
446 QList<int> mVerticesToRemoveIndexes;
447};
448
457{
458 public:
459
468 QgsMeshLayerUndoCommandRemoveVerticesFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes, QList<int> *remainingVerticesPointer = nullptr );
469 void redo() override;
470
471 private:
472 QList<int> mVerticesToRemoveIndexes;
473 QList<int> *mRemainingVerticesPointer = nullptr;
474};
475
484{
485 public:
486
489
490 void redo() override;
491 private:
493};
494
503{
504 public:
505
507 QgsMeshLayerUndoCommandRemoveFaces( QgsMeshEditor *meshEditor, const QList<int> &facesToRemoveIndexes );
508
509 void redo() override;
510 private:
511 QList<int> mfacesToRemoveIndexes;
512};
513
522{
523 public:
524
529 QgsMeshLayerUndoCommandChangeZValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<double> &newValues );
530 void redo() override;
531
532 private:
533 QList<int> mVerticesIndexes;
534 QList<double> mNewValues;
535};
536
545{
546 public:
547
552 QgsMeshLayerUndoCommandChangeXYValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
553 void redo() override;
554
555 private:
556 QList<int> mVerticesIndexes;
557 QList<QgsPointXY> mNewValues;
558};
559
568{
569 public:
570
575 QgsMeshLayerUndoCommandChangeCoordinates( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
576 void redo() override;
577
578 private:
579 QList<int> mVerticesIndexes;
580 QList<QgsPoint> mNewCoordinates;
581};
582
591{
592 public:
593
597 QgsMeshLayerUndoCommandFlipEdge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
598 void redo() override;
599
600 private:
601 int mVertexIndex1 = -1;
602 int mVertexIndex2 = -1;
603};
604
613{
614 public:
615
620 QgsMeshLayerUndoCommandMerge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
621 void redo() override;
622
623 private:
624 int mVertexIndex1 = -1;
625 int mVertexIndex2 = -1;
626};
627
636{
637 public:
638
642 QgsMeshLayerUndoCommandSplitFaces( QgsMeshEditor *meshEditor, const QList<int> &faceIndexes );
643 void redo() override;
644
645 private:
646 QList<int> mFaceIndexes;
647};
648
649
657{
658 public:
659
662 void redo() override;
663
664 private:
665 QgsMeshAdvancedEditing *mAdvancedEditing = nullptr;
666};
667
668
677{
678 public:
679
682
683 void redo() override;
684 private:
685 QList<std::pair<int, int>> innerEdges( const QSet<int> &faces );
686 QSet<int> secondNeighboringTriangularFaces();
687
688 QgsMeshVertex mVertex;
689 double mTolerance;
690};
691
692#endif //SIP_RUN
693
694#endif // QGSMESHEDITOR_H
MeshEditingErrorType
Type of error that can occur during mesh frame editing.
Definition qgis.h:1659
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
QgsMeshEditingError()
Constructor of the default error, that is NoError.
Handles edit operations on a mesh layer.
friend class QgsMeshLayerUndoCommandSplitFaces
QgsMeshEditingError initialize()
Initializes the mesh editor and returns first error if the internal native mesh has topological error...
friend class QgsMeshLayerUndoCommandMeshEdit
friend class QgsMeshLayerUndoCommandMerge
void changeXYValues(const QList< int > &verticesIndexes, const QList< QgsPointXY > &newValues)
Changes the (X,Y) coordinates values of the vertices with indexes in verticesIndexes with the values ...
int validFacesCount() const
Returns the count of valid faces, that is non void faces in the mesh.
friend class QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles
QgsMeshEditingError removeFaces(const QList< int > &facesToRemove)
Removes faces faces to the mesh, returns topological errors if this operation fails (operation is not...
QgsMeshEditingError addFaces(const QVector< QgsMeshFace > &faces)
Adds faces faces to the mesh, returns topological errors if this operation fails (operation is not re...
bool checkConsistency(QgsMeshEditingError &error) const
Return true if the edited mesh is consistent.
QList< int > removeVerticesFillHoles(const QList< int > &verticesToRemoveIndexes)
Removes vertices with indexes in the list verticesToRemoveIndexes in the mesh the surrounding faces A...
void flipEdge(int vertexIndex1, int vertexIndex2)
Flips edge (vertexIndex1, vertexIndex2).
QgsRectangle extent() const
Returns the extent of the edited mesh.
friend class QgsMeshLayerUndoCommandAddVertices
bool faceCanBeSplit(int faceIndex) const
Returns true if face with index faceIndex can be split.
QgsMeshEditingError initializeWithErrorsFix()
Initializes the mesh editor.
int maximumVerticesPerFace() const
Returns the maximum count of vertices per face that the mesh can support.
QgsMeshEditingError addFace(const QVector< int > &vertexIndexes)
Adds a face face to the mesh with vertex indexes vertexIndexes, returns topological errors if this op...
QgsMeshEditor(QgsMeshLayer *meshLayer)
Constructor with a specified layer meshLayer.
void merge(int vertexIndex1, int vertexIndex2)
Merges faces separated by vertices with indexes vertexIndex1 and vertexIndex2.
bool edgeIsClose(QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition)
Returns true if an edge of face is closest than the tolerance from the point in triangular mesh coord...
QgsMeshEditingError removeVerticesWithoutFillHoles(const QList< int > &verticesToRemoveIndexes)
Removes vertices with indexes in the list verticesToRemoveIndexes in the mesh removing the surroundin...
bool isFaceGeometricallyCompatible(const QgsMeshFace &face) const
Returns true if the face does not intersect or contains any other elements (faces or vertices) The to...
QList< int > freeVerticesIndexes() const
Returns all the free vertices indexes.
friend class QgsMeshLayerUndoCommandChangeXYValue
void addVertexWithDelaunayRefinement(const QgsMeshVertex &vertex, const double tolerance)
Add a vertex in a face with Delaunay refinement of neighboring faces All neighboring faces sharing a ...
bool isVertexOnBoundary(int vertexIndex) const
Returns whether the vertex with index vertexIndex is on a boundary.
friend class QgsMeshLayerUndoCommandFlipEdge
bool faceCanBeAdded(const QgsMeshFace &face) const
Returns true if a face can be added to the mesh.
void changeCoordinates(const QList< int > &verticesIndexes, const QList< QgsPoint > &newCoordinates)
Changes the (X,Y,Z) coordinates values of the vertices with indexes in vertices indexes with the valu...
void stopEditing()
Stops editing.
friend class QgsMeshLayerUndoCommandAdvancedEditing
bool canBeMerged(int vertexIndex1, int vertexIndex2) const
Returns true if faces separated by vertices with indexes vertexIndex1 and vertexIndex2 can be merged.
friend class QgsMeshLayerUndoCommandAddFaces
QgsMeshEditingError addFaceWithNewVertices(const QList< int > &vertexIndexes, const QList< QgsMeshVertex > &newVertices)
Adds a face formed by some vertices vertexIndexes to the mesh, returns topological errors if this ope...
friend class QgsMeshLayerUndoCommandSetZValue
friend class QgsMeshLayerUndoCommandChangeCoordinates
bool edgeCanBeFlipped(int vertexIndex1, int vertexIndex2) const
Returns true if the edge can be flipped (only available for edge shared by two faces with 3 vertices)...
int splitFaces(const QList< int > &faceIndexes)
Splits faces with index faceIndexes.
QgsMeshVertexCirculator vertexCirculator(int vertexIndex) const
Returns a vertex circulator linked to this mesh around the vertex with index vertexIndex.
bool faceCanBeAddedWithNewVertices(const QList< int > &verticesIndex, const QList< QgsMeshVertex > &newVertices) const
Returns true if a face formed by some vertices can be added to the mesh.
void meshEdited()
Emitted when the mesh is edited.
friend class QgsMeshLayerUndoCommandAddVertexInFaceWithDelaunayRefinement
void changeZValues(const QList< int > &verticesIndexes, const QList< double > &newValues)
Changes the Z values of the vertices with indexes in vertices indexes with the values in newValues.
void resetTriangularMesh(QgsTriangularMesh *triangularMesh)
Resets the triangular mesh.
bool isModified() const
Returns whether the mesh has been modified.
void advancedEdit(QgsMeshAdvancedEditing *editing)
Applies an advance editing on the edited mesh, see QgsMeshAdvancedEditing.
bool canBeTransformed(const QList< int > &facesToCheck, const std::function< const QgsMeshVertex(int)> &transformFunction) const
Returns true if faces with index in transformedFaces can be transformed without obtaining topologic o...
int addVertices(const QVector< QgsMeshVertex > &vertices, double tolerance)
Adds vertices in triangular mesh coordinate in the mesh.
int validVerticesCount() const
Returns the count of valid vertices, that is non void vertices in the mesh.
friend class QgsMeshLayerUndoCommandRemoveVerticesFillHoles
bool isVertexFree(int vertexIndex) const
Returns whether the vertex with index vertexIndex is a free vertex.
bool reindex(bool renumbering)
Reindexes the mesh, that is remove unusued index of face and vertices, this operation void the undo/r...
std::unique_ptr< QgsMeshDatasetGroup > createZValueDatasetGroup()
Creates and returns a scalar dataset group with value on vertex that is can be used to access the Z v...
friend class QgsMeshLayerUndoCommandChangeZValue
QgsTriangularMesh * triangularMesh()
Returns a pointer to the triangular mesh.
bool fixError(const QgsMeshEditingError &error)
Tries to fix the topological error in the mesh.
friend class QgsMeshLayerUndoCommandRemoveFaces
QgsTopologicalMesh & topologicalMesh()
Returns a reference to the topological mesh.
~QgsMeshEditor() override
friend class TestQgsMeshEditor
int addPointsAsVertices(const QVector< QgsPoint > &point, double tolerance)
Adds points as vertices in triangular mesh coordinate in the mesh.
QgsMeshLayerUndoCommandAddFaces(QgsMeshEditor *meshEditor, QgsTopologicalMesh::TopologicalFaces &faces)
Constructor with the associated meshEditor and faces that will be added.
QgsMeshLayerUndoCommandAddVertexInFaceWithDelaunayRefinement(QgsMeshEditor *meshEditor, const QgsMeshVertex &vertex, double tolerance)
Constructor with the associated meshEditor and indexes vertex and tolerance.
QgsMeshLayerUndoCommandAddVertices(QgsMeshEditor *meshEditor, const QVector< QgsMeshVertex > &vertices, double tolerance)
Constructor with the associated meshEditor and vertices that will be added.
QgsMeshLayerUndoCommandAdvancedEditing(QgsMeshEditor *meshEditor, QgsMeshAdvancedEditing *advancdEdit)
Constructor with the associated meshEditor.
QgsMeshLayerUndoCommandChangeCoordinates(QgsMeshEditor *meshEditor, const QList< int > &verticesIndexes, const QList< QgsPoint > &newCoordinates)
Constructor with the associated meshEditor and indexes verticesIndexes of the vertices that will have...
QgsMeshLayerUndoCommandChangeXYValue(QgsMeshEditor *meshEditor, const QList< int > &verticesIndexes, const QList< QgsPointXY > &newValues)
Constructor with the associated meshEditor and indexes verticesIndexes of the vertices that will have...
QgsMeshLayerUndoCommandChangeZValue(QgsMeshEditor *meshEditor, const QList< int > &verticesIndexes, const QList< double > &newValues)
Constructor with the associated meshEditor and indexes verticesIndexes of the vertices that will have...
QgsMeshLayerUndoCommandFlipEdge(QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2)
Constructor with the associated meshEditor and the vertex indexes of the edge (vertexIndex1,...
QgsMeshLayerUndoCommandMerge(QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2)
Constructor with the associated meshEditor and the vertex indexes of the edge (vertexIndex1,...
QList< QgsMeshEditor::Edit > mEdits
QgsMeshLayerUndoCommandMeshEdit(QgsMeshEditor *meshEditor)
Constructor for the base class.
QPointer< QgsMeshEditor > mMeshEditor
QgsMeshLayerUndoCommandRemoveFaces(QgsMeshEditor *meshEditor, const QList< int > &facesToRemoveIndexes)
Constructor with the associated meshEditor and indexes facesToRemoveIndexes of the faces that will be...
QgsMeshLayerUndoCommandRemoveVerticesFillHoles(QgsMeshEditor *meshEditor, const QList< int > &verticesToRemoveIndexes, QList< int > *remainingVerticesPointer=nullptr)
Constructor with the associated meshEditor and vertices that will be removed.
QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles(QgsMeshEditor *meshEditor, const QList< int > &verticesToRemoveIndexes)
Constructor with the associated meshEditor and vertices that will be removed.
QgsMeshLayerUndoCommandSplitFaces(QgsMeshEditor *meshEditor, const QList< int > &faceIndexes)
Constructor with the associated meshEditor and indexes faceIndexes of the faces to split.
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
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:134
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QVector< int > QgsMeshFace
List of vertex indexes.
QgsPoint QgsMeshVertex
xyz coords of vertex
Mesh - vertices, edges and faces.