QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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, neigbor 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
313 void reindex();
314
318 bool renumber();
319
322
324 static QgsMeshEditingError checkTopology( const QgsMesh &mesh, int maxVerticesPerFace );
325
326 private:
327
329 static TopologicalFaces createTopologicalFaces(
330 const QVector<QgsMeshFace> &faces,
331 QVector<int> *globalVertexToFace,
332 QgsMeshEditingError &error,
333 bool allowUniqueSharedVertex );
334
336 QSet<int> concernedFacesBy( const QList<int> faceIndexes ) const;
337
339 void referenceAsFreeVertex( int vertexIndex );
341 void dereferenceAsFreeVertex( int vertexIndex );
342
347 bool eitherSideFacesAndVertices( int vertexIndex1,
348 int vertexIndex2,
349 int &face1,
350 int &face2,
351 int &neighborVertex1InFace1,
352 int &neighborVertex1InFace2,
353 int &neighborVertex2inFace1,
354 int &neighborVertex2inFace2 ) const;
355
356 bool renumberVertices( QVector<int> &oldToNewIndex ) const;
357 bool renumberFaces( QVector<int> &oldToNewIndex ) const;
358
359 //Attributes
360 QgsMesh *mMesh = nullptr;
361 QVector<int> mVertexToFace;
362 QVector<FaceNeighbors> mFacesNeighborhood;
363
364 QSet<int> mFreeVertices;
365
366 int mMaximumVerticesPerFace = 0;
367
369
370};
371
379class CORE_EXPORT QgsMeshVertexCirculator
380{
381 public:
382
384 QgsMeshVertexCirculator( const QgsTopologicalMesh &topologicalMesh, int vertexIndex );
385
391 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int faceIndex, int vertexIndex );
392
398 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int vertexIndex );
399
401 int turnCounterClockwise() const;
402
404 int turnClockwise() const;
405
407 int currentFaceIndex() const;
408
410 QgsMeshFace currentFace() const;
411
413 bool goBoundaryClockwise() const;
414
416 bool goBoundaryCounterClockwise() const;
417
419 int oppositeVertexClockwise() const;
420
422 int oppositeVertexCounterClockwise() const;
423
425 bool isValid() const;
426
428 QList<int> facesAround() const;
429
431 int degree() const;
432
433 private:
434 const QVector<QgsMeshFace> mFaces;
435 const QVector<QgsTopologicalMesh::FaceNeighbors> mFacesNeighborhood;
436 const int mVertexIndex = -1;
437 mutable int mCurrentFace = -1;
438 mutable int mLastValidFace = -1;
439 bool mIsValid = false;
440 mutable int mDegree = -1;
441
442 int positionInCurrentFace() const;
443};
444
445#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...
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 facesCanBeRemoved(const QList< int > facesIndexes)
Returns whether faces with index in faceIndexes can be removed/ The method an error object with type ...
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...
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...
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.
Changes removeFaces(const QList< int > facesIndexes)
Removes faces with index in faceIndexes.
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 tha tis 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.