QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgstopologicalmesh.h
Go to the documentation of this file.
1/***************************************************************************
2 qgstopologicalmesh.h - QgsTopologicalMesh
3
4 ---------------------
5 begin : 18.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 QGSTOPOLOGICALMESH_H
17#define QGSTOPOLOGICALMESH_H
18
19#include <QSet>
20
21#include "qgsmeshdataprovider.h"
22
23#if defined(_MSC_VER)
24template CORE_EXPORT QVector<int> SIP_SKIP;
25template CORE_EXPORT QList<int> SIP_SKIP;
26template CORE_EXPORT QVector<QVector<int>> SIP_SKIP;
27#endif
28
30
33
47class CORE_EXPORT QgsTopologicalMesh
48{
49 public:
50
51 using FaceNeighbors = QVector<int>;
52
62 class CORE_EXPORT TopologicalFaces
63 {
64 public:
65
67 QVector<QgsMeshFace> meshFaces() const {return mFaces;}
68
70 void clear();
71
73 QVector<FaceNeighbors> facesNeighborhood() const;
74
76 int vertexToFace( int vertexIndex ) const;
77
78 private:
79 QVector<QgsMeshFace> mFaces; // the faces containing the vertices indexes in the mesh
80 QVector<FaceNeighbors> mFacesNeighborhood; // neighborhood of the faces, face indexes are local
81 QMultiHash<int, int> mVerticesToFace; // map of vertices to incident face, face indexes are local
82 QList<int> mBoundaries; // list of boundary vertices indexes in the mesh
83
84 friend class QgsTopologicalMesh;
86 };
87
88
96 class CORE_EXPORT Changes
97 {
98 public:
99
101 QVector<QgsMeshFace> addedFaces() const;
102
104 QVector<QgsMeshFace> removedFaces() const;
105
107 QList<int> removedFaceIndexes() const;
108
110 QVector<QgsMeshVertex> addedVertices() const;
111
113 QList<int> verticesToRemoveIndexes() const;
114
116 QList<int> changedCoordinatesVerticesIndexes() const;
117
119 QList<double> newVerticesZValues() const;
120
122 QList<QgsPointXY> newVerticesXYValues() const;
123
125 QList<QgsPointXY> oldVerticesXYValues() const;
126
128 QList<int> nativeFacesIndexesGeometryChanged() const;
129
131 bool isEmpty() const;
132
133 protected:
134 int mAddedFacesFirstIndex = 0;
135 QList<int> mFaceIndexesToRemove; // the removed faces indexes in the mesh
136 QVector<QgsMeshFace> mFacesToAdd;
137 QVector<FaceNeighbors> mFacesNeighborhoodToAdd;
138 QVector<QgsMeshFace> mFacesToRemove;
139 QVector<FaceNeighbors> mFacesNeighborhoodToRemove;
140 QList<std::array<int, 4>> mNeighborhoodChanges; // {index of concerned face, neighbor position, previous value, changed value}
141
142 QVector<QgsMeshVertex> mVerticesToAdd;
143 QVector<int> mVertexToFaceToAdd;
145 QList<QgsMeshVertex> mRemovedVertices;
147 QList<std::array<int, 3>> mVerticesToFaceChanges; // {index of concerned vertex, previous value, changed value}
148
150 QList<double> mNewZValues;
151 QList<double> mOldZValues;
152 QList<QgsPointXY> mNewXYValues;
153 QList<QgsPointXY> mOldXYValues;
155
157 void clearChanges();
158
159 private:
160 int addedFaceIndexInMesh( int internalIndex ) const;
161 int removedFaceIndexInMesh( int internalIndex ) const;
162
163 friend class QgsTopologicalMesh;
164 };
165
170 static QgsTopologicalMesh createTopologicalMesh( QgsMesh *mesh, int maxVerticesPerFace, QgsMeshEditingError &error );
171
173 static TopologicalFaces createNewTopologicalFaces( const QVector<QgsMeshFace> &faces, bool uniqueSharedVertexAllowed, QgsMeshEditingError &error );
174
175 //----------- access element methods
176
178 QVector<int> neighborsOfFace( int faceIndex ) const;
179
181 QList<int> facesAroundVertex( int vertexIndex ) const;
182
184 QgsMesh *mesh() const;
185
187 int firstFaceLinked( int vertexIndex ) const;
188
190 bool isVertexOnBoundary( int vertexIndex ) const;
191
193 bool isVertexFree( int vertexIndex ) const;
194
196 QList<int> freeVerticesIndexes() const;
197
199 QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const;
200
201 //----------- editing methods
202
204 QgsMeshEditingError facesCanBeAdded( const TopologicalFaces &topologicalFaces ) const;
205
210 Changes addFaces( const TopologicalFaces &topologicFaces );
211
216 QgsMeshEditingError facesCanBeRemoved( const QList<int> &facesIndexes );
217
222 Changes removeFaces( const QList<int> &facesIndexes );
223
227 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
228
233 Changes flipEdge( int vertexIndex1, int vertexIndex2 );
234
238 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
239
244 Changes merge( int vertexIndex1, int vertexIndex2 );
245
249 bool canBeSplit( int faceIndex ) const;
250
255 Changes splitFace( int faceIndex );
256
261 Changes addVertexInFace( int faceIndex, const QgsMeshVertex &vertex );
262
267 Changes insertVertexInFacesEdge( int faceIndex, int position, const QgsMeshVertex &vertex );
268
273 Changes addFreeVertex( const QgsMeshVertex &vertex );
274
280 Changes removeVertexFillHole( int vertexIndex );
281
287 Changes removeVertices( const QList<int> &vertices );
288
292 Changes changeZValue( const QList<int> &verticesIndexes, const QList<double> &newValues );
293
297 Changes changeXYValue( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
298
299
301 void applyChanges( const Changes &changes );
302
304 void reverseChanges( const Changes &changes );
305
308
315 static QgsMeshEditingError checkTopologyOfVerticesAsFace( const QVector<QgsMeshVertex> &vertices, bool &clockwise );
316
321 void reindex();
322
326 bool renumber();
327
330
332 static QgsMeshEditingError checkTopology( const QgsMesh &mesh, int maxVerticesPerFace );
333
334 private:
335
337 static TopologicalFaces createTopologicalFaces(
338 const QVector<QgsMeshFace> &faces,
339 QVector<int> *globalVertexToFace,
340 QgsMeshEditingError &error,
341 bool allowUniqueSharedVertex );
342
344 QSet<int> concernedFacesBy( const QList<int> &faceIndexes ) const;
345
347 void referenceAsFreeVertex( int vertexIndex );
349 void dereferenceAsFreeVertex( int vertexIndex );
350
355 bool eitherSideFacesAndVertices( int vertexIndex1,
356 int vertexIndex2,
357 int &face1,
358 int &face2,
359 int &neighborVertex1InFace1,
360 int &neighborVertex1InFace2,
361 int &neighborVertex2inFace1,
362 int &neighborVertex2inFace2 ) const;
363
364 bool renumberVertices( QVector<int> &oldToNewIndex ) const;
365 bool renumberFaces( QVector<int> &oldToNewIndex ) const;
366
367 //Attributes
368 QgsMesh *mMesh = nullptr;
369 QVector<int> mVertexToFace;
370 QVector<FaceNeighbors> mFacesNeighborhood;
371
372 QSet<int> mFreeVertices;
373
374 int mMaximumVerticesPerFace = 0;
375
377
378};
379
387class CORE_EXPORT QgsMeshVertexCirculator
388{
389 public:
390
392 QgsMeshVertexCirculator( const QgsTopologicalMesh &topologicalMesh, int vertexIndex );
393
399 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int faceIndex, int vertexIndex );
400
406 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int vertexIndex );
407
409 int turnCounterClockwise() const;
410
412 int turnClockwise() const;
413
415 int currentFaceIndex() const;
416
418 QgsMeshFace currentFace() const;
419
421 bool goBoundaryClockwise() const;
422
424 bool goBoundaryCounterClockwise() const;
425
427 int oppositeVertexClockwise() const;
428
430 int oppositeVertexCounterClockwise() const;
431
433 bool isValid() const;
434
436 QList<int> facesAround() const;
437
439 int degree() const;
440
441 private:
442 const QVector<QgsMeshFace> mFaces;
443 const QVector<QgsTopologicalMesh::FaceNeighbors> mFacesNeighborhood;
444 const int mVertexIndex = -1;
445 mutable int mCurrentFace = -1;
446 mutable int mLastValidFace = -1;
447 bool mIsValid = false;
448 mutable int mDegree = -1;
449
450 int positionInCurrentFace() const;
451};
452
453#endif // QGSTOPOLOGICALMESH_H
Class that represents an error during mesh editing.
Definition: qgsmesheditor.h:43
Convenient class that turn around a vertex and provide information about faces and vertices.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Class that contains topological differences between two states of a topological mesh,...
QList< int > mChangeCoordinateVerticesIndexes
QVector< FaceNeighbors > mFacesNeighborhoodToRemove
QList< QgsPointXY > mNewXYValues
QList< QgsMeshVertex > mRemovedVertices
QList< std::array< int, 4 > > mNeighborhoodChanges
QList< int > mNativeFacesIndexesGeometryChanged
QVector< QgsMeshFace > mFacesToAdd
QVector< FaceNeighbors > mFacesNeighborhoodToAdd
QList< std::array< int, 3 > > mVerticesToFaceChanges
QList< QgsPointXY > mOldXYValues
QVector< QgsMeshVertex > mVerticesToAdd
QVector< QgsMeshFace > mFacesToRemove
Class that contains independent faces an topological information about this faces.
QVector< QgsMeshFace > meshFaces() const
Returns faces.
Class that wraps a QgsMesh to ensure the consistency of the mesh during editing and help to access to...
static QgsMeshEditingError checkTopologyOfVerticesAsFace(const QVector< QgsMeshVertex > &vertices, bool &clockwise)
Checks the topology of the vertices as they are contained in a face and returns indication on directi...
Changes changeZValue(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.
static QgsTopologicalMesh createTopologicalMesh(QgsMesh *mesh, int maxVerticesPerFace, QgsMeshEditingError &error)
Creates a topologicaly consistent mesh with mesh, this static method modifies mesh to be topological ...
bool isVertexFree(int vertexIndex) const
Returns whether the vertex is a free vertex.
static QgsMeshEditingError counterClockwiseFaces(QgsMeshFace &face, QgsMesh *mesh)
Checks the topology of the face and sets it counter clockwise if necessary.
Changes removeVertexFillHole(int vertexIndex)
Removes the vertex with index vertexIndex.
static QgsMeshEditingError checkTopology(const QgsMesh &mesh, int maxVerticesPerFace)
Checks the topology of the mesh mesh, if error occurs, this mesh can't be edited.
void applyChanges(const Changes &changes)
Applies the changes.
int firstFaceLinked(int vertexIndex) const
Returns the index of the first face linked, returns -1 if it is a free vertex or out of range index.
QgsMeshEditingError checkConsistency() const
Checks the consistency of the topological mesh and return false if there is a consistency issue.
Changes removeVertices(const QList< int > &vertices)
Removes all the vertices with index in the list vertices If vertices in linked with faces,...
Changes changeXYValue(const QList< int > &verticesIndexes, const QList< QgsPointXY > &newValues)
Changes the (X,Y) values of the vertices with indexes in vertices indexes with the values in newValue...
void reindex()
Reindexes faces and vertices, after this operation, the topological mesh can't be edited anymore and ...
QVector< int > neighborsOfFace(int faceIndex) const
Returns the indexes of neighbor faces of the face with index faceIndex.
QgsMeshEditingError facesCanBeAdded(const TopologicalFaces &topologicalFaces) const
Returns whether the faces can be added to the mesh.
bool renumber()
Renumbers the indexes of vertices and faces using the Reverse CutHill McKee Algorithm.
Changes flipEdge(int vertexIndex1, int vertexIndex2)
Flips edge (vertexIndex1, vertexIndex2) The method returns a instance of the class QgsTopologicalMesh...
QgsMeshEditingError facesCanBeRemoved(const QList< int > &facesIndexes)
Returns whether faces with index in faceIndexes can be removed/ The method an error object with type ...
QVector< int > FaceNeighbors
void reverseChanges(const Changes &changes)
Reverses the changes.
Changes addFaces(const TopologicalFaces &topologicFaces)
Adds faces topologicFaces to the topologic mesh.
Changes merge(int vertexIndex1, int vertexIndex2)
Merges faces separated by vertices with indexes vertexIndex1 and vertexIndex2 The method returns a in...
Changes removeFaces(const QList< int > &facesIndexes)
Removes faces with index in faceIndexes.
QList< int > freeVerticesIndexes() const
Returns a list of vertices are not linked to any faces.
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)
Changes addVertexInFace(int faceIndex, const QgsMeshVertex &vertex)
Adds a vertex in the face with index faceIndex.
bool canBeMerged(int vertexIndex1, int vertexIndex2) const
Returns true if faces separated by vertices with indexes vertexIndex1 and vertexIndex2 can be merged.
QList< int > facesAroundVertex(int vertexIndex) const
Returns the indexes of faces that are around the vertex with index vertexIndex.
bool canBeSplit(int faceIndex) const
Returns true if face with index faceIndex can be split.
Changes addFreeVertex(const QgsMeshVertex &vertex)
Adds a free vertex in the face, that is a vertex that is not included or linked with any faces.
Changes insertVertexInFacesEdge(int faceIndex, int position, const QgsMeshVertex &vertex)
Inserts a vertex in the edge of face with index faceIndex at position .
QgsMesh * mesh() const
Returns a pointer to the wrapped mesh.
bool isVertexOnBoundary(int vertexIndex) const
Returns whether the vertex is on a boundary.
Changes splitFace(int faceIndex)
Splits face with index faceIndex The method returns a instance of the class QgsTopologicalMesh::Chang...
static TopologicalFaces createNewTopologicalFaces(const QVector< QgsMeshFace > &faces, bool uniqueSharedVertexAllowed, QgsMeshEditingError &error)
Creates new topological faces that are not yet included in the mesh.
QgsMeshVertexCirculator vertexCirculator(int vertexIndex) const
Returns a vertex circulator linked to this mesh around the vertex with index vertexIndex.
#define SIP_NO_FILE
#define SIP_SKIP
Definition: qgis_sip.h:126
QVector< int > QgsMeshFace
List of vertex indexes.
Mesh - vertices, edges and faces.