QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
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 "qgsmeshdataprovider.h"
20
21#include <QSet>
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
31
45class CORE_EXPORT QgsTopologicalMesh
46{
47 public:
48
49 using FaceNeighbors = QVector<int>;
50
60 class CORE_EXPORT TopologicalFaces
61 {
62 public:
63
68 SIP_SKIP QVector<QgsMeshFace> meshFaces() const {return mFaces;}
69
71 void clear();
72
78 SIP_SKIP QVector<FaceNeighbors> facesNeighborhood() const;
79
81 int vertexToFace( int vertexIndex ) const;
82
83 private:
84 QVector<QgsMeshFace> mFaces; // the faces containing the vertices indexes in the mesh
85 QVector<FaceNeighbors> mFacesNeighborhood; // neighborhood of the faces, face indexes are local
86 QMultiHash<int, int> mVerticesToFace; // map of vertices to incident face, face indexes are local
87 QList<int> mBoundaries; // list of boundary vertices indexes in the mesh
88
89 friend class QgsTopologicalMesh;
91 };
92
93
101 class CORE_EXPORT Changes
102 {
103 public:
104
110 SIP_SKIP QVector<QgsMeshFace> addedFaces() const;
111
117 SIP_SKIP QVector<QgsMeshFace> removedFaces() const;
118
120 QList<int> removedFaceIndexes() const;
121
123#ifndef SIP_RUN
124 QVector<QgsMeshVertex> addedVertices() const;
125#else
126 QVector<QgsPoint> addedVertices() const;
127#endif
128
130 QList<int> verticesToRemoveIndexes() const;
131
133 QList<int> changedCoordinatesVerticesIndexes() const;
134
136 QList<double> newVerticesZValues() const;
137
139 QList<QgsPointXY> newVerticesXYValues() const;
140
142 QList<QgsPointXY> oldVerticesXYValues() const;
143
145 QList<int> nativeFacesIndexesGeometryChanged() const;
146
148 bool isEmpty() const;
149
150 protected:
152 QList<int> mFaceIndexesToRemove; // the removed faces indexes in the mesh
153 QVector<QgsMeshFace> mFacesToAdd;
154 QVector<FaceNeighbors> mFacesNeighborhoodToAdd;
155 QVector<QgsMeshFace> mFacesToRemove;
156 QVector<FaceNeighbors> mFacesNeighborhoodToRemove;
157 QList<std::array<int, 4>> mNeighborhoodChanges; // {index of concerned face, neighbor position, previous value, changed value}
158
159 QVector<QgsMeshVertex> mVerticesToAdd;
160 QVector<int> mVertexToFaceToAdd;
162 QList<QgsMeshVertex> mRemovedVertices;
164 QList<std::array<int, 3>> mVerticesToFaceChanges; // {index of concerned vertex, previous value, changed value}
165
167 QList<double> mNewZValues;
168 QList<double> mOldZValues;
169 QList<QgsPointXY> mNewXYValues;
170 QList<QgsPointXY> mOldXYValues;
172
174 void clearChanges();
175
176 private:
177 int addedFaceIndexInMesh( int internalIndex ) const;
178 int removedFaceIndexInMesh( int internalIndex ) const;
179
180 friend class QgsTopologicalMesh;
181 };
182
187 static QgsTopologicalMesh createTopologicalMesh( QgsMesh *mesh, int maxVerticesPerFace, QgsMeshEditingError &error );
188
194 SIP_SKIP static TopologicalFaces createNewTopologicalFaces( const QVector<QgsMeshFace> &faces, bool uniqueSharedVertexAllowed, QgsMeshEditingError &error );
195
196 //----------- access element methods
197
199 QVector<int> neighborsOfFace( int faceIndex ) const;
200
202 QList<int> facesAroundVertex( int vertexIndex ) const;
203
205 QgsMesh *mesh() const;
206
208 int firstFaceLinked( int vertexIndex ) const;
209
211 bool isVertexOnBoundary( int vertexIndex ) const;
212
214 bool isVertexFree( int vertexIndex ) const;
215
217 QList<int> freeVerticesIndexes() const;
218
224 SIP_SKIP QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const;
225
226 //----------- editing methods
227
229 QgsMeshEditingError facesCanBeAdded( const TopologicalFaces &topologicalFaces ) const;
230
235 Changes addFaces( const TopologicalFaces &topologicFaces );
236
241 QgsMeshEditingError facesCanBeRemoved( const QList<int> &facesIndexes );
242
247 Changes removeFaces( const QList<int> &facesIndexes );
248
252 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
253
258 Changes flipEdge( int vertexIndex1, int vertexIndex2 );
259
266 bool delaunayConditionForEdge( int vertexIndex1, int vertexIndex2 );
267
271 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
272
277 Changes merge( int vertexIndex1, int vertexIndex2 );
278
282 bool canBeSplit( int faceIndex ) const;
283
288 Changes splitFace( int faceIndex );
289
294 Changes addVertexInFace( int faceIndex, const QgsMeshVertex &vertex );
295
300 Changes insertVertexInFacesEdge( int faceIndex, int position, const QgsMeshVertex &vertex );
301
306 Changes addFreeVertex( const QgsMeshVertex &vertex );
307
313 Changes removeVertexFillHole( int vertexIndex );
314
320 Changes removeVertices( const QList<int> &vertices );
321
325 Changes changeZValue( const QList<int> &verticesIndexes, const QList<double> &newValues );
326
330 Changes changeXYValue( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
331
332
334 void applyChanges( const Changes &changes );
335
337 void reverseChanges( const Changes &changes );
338
341
349 SIP_SKIP static QgsMeshEditingError checkTopologyOfVerticesAsFace( const QVector<QgsMeshVertex> &vertices, bool &clockwise );
350
355 void reindex();
356
360 bool renumber();
361
364
366 static QgsMeshEditingError checkTopology( const QgsMesh &mesh, int maxVerticesPerFace );
367
369 static inline int vertexPositionInFace( int vertexIndex, const QgsMeshFace &face )
370 {
371 return face.indexOf( vertexIndex );
372 }
373
375 static int vertexPositionInFace( const QgsMesh &mesh, int vertexIndex, int faceIndex );
376
377 private:
378
380 static TopologicalFaces createTopologicalFaces(
381 const QVector<QgsMeshFace> &faces,
382 QVector<int> *globalVertexToFace,
383 QgsMeshEditingError &error,
384 bool allowUniqueSharedVertex );
385
387 QSet<int> concernedFacesBy( const QList<int> &faceIndexes ) const;
388
390 void referenceAsFreeVertex( int vertexIndex );
392 void dereferenceAsFreeVertex( int vertexIndex );
393
398 bool eitherSideFacesAndVertices( int vertexIndex1,
399 int vertexIndex2,
400 int &face1,
401 int &face2,
402 int &neighborVertex1InFace1,
403 int &neighborVertex1InFace2,
404 int &neighborVertex2inFace1,
405 int &neighborVertex2inFace2 ) const;
406
407 bool renumberVertices( QVector<int> &oldToNewIndex ) const;
408 bool renumberFaces( QVector<int> &oldToNewIndex ) const;
409
410 //Attributes
411 QgsMesh *mMesh = nullptr;
412 QVector<int> mVertexToFace;
413 QVector<FaceNeighbors> mFacesNeighborhood;
414
415 QSet<int> mFreeVertices;
416
417 int mMaximumVerticesPerFace = 0;
418
420
421};
422
423#ifndef SIP_RUN
424
434class CORE_EXPORT QgsMeshVertexCirculator
435{
436 public:
437
439 QgsMeshVertexCirculator( const QgsTopologicalMesh &topologicalMesh, int vertexIndex );
440
446 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int faceIndex, int vertexIndex );
447
453 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int vertexIndex );
454
456 int turnCounterClockwise() const;
457
459 int turnClockwise() const;
460
462 int currentFaceIndex() const;
463
465 QgsMeshFace currentFace() const;
466
468 bool goBoundaryClockwise() const;
469
471 bool goBoundaryCounterClockwise() const;
472
474 int oppositeVertexClockwise() const;
475
478
480 bool isValid() const;
481
483 QList<int> facesAround() const;
484
486 int degree() const;
487
488 private:
489 const QVector<QgsMeshFace> mFaces;
490 const QVector<QgsTopologicalMesh::FaceNeighbors> mFacesNeighborhood;
491 const int mVertexIndex = -1;
492 mutable int mCurrentFace = -1;
493 mutable int mLastValidFace = -1;
494 bool mIsValid = false;
495 mutable int mDegree = -1;
496
497 int positionInCurrentFace() const;
498};
499#endif
500
501#endif // QGSTOPOLOGICALMESH_H
Represents an error which occurred during mesh editing.
Convenience class that turns around a vertex and provides information about faces and vertices.
bool isValid() const
Returns whether the vertex circulator is valid.
int turnClockwise() const
Turns counter clockwise around the vertex and returns the new current face, -1 if the circulator pass...
bool goBoundaryCounterClockwise() const
Sets the circulator on the boundary face turning counter clockwise, return false is there isn't bound...
int oppositeVertexCounterClockwise() const
Returns the opposite vertex of the current face and on the edge on the side turning counter clockwise...
int turnCounterClockwise() const
Turns counter clockwise around the vertex and returns the new current face, -1 if the circulator pass...
int currentFaceIndex() const
Returns the current face index, -1 if the circulator has passed a boundary or circulator is invalid.
bool goBoundaryClockwise() const
Sets the circulator on the boundary face turning clockwise, return false is there isn't boundary face...
QgsMeshFace currentFace() const
Returns the current face, empty face if the circulator pass a boundary or circulator is invalid.
QgsMeshVertexCirculator(const QgsTopologicalMesh &topologicalMesh, int vertexIndex)
Constructor with topologicalMesh and vertexIndex.
int oppositeVertexClockwise() const
Returns the opposite vertex of the current face and on the edge on the side turning clockwise.
int degree() const
Returns the degree of the vertex, that is the count of other vertices linked.
QList< int > facesAround() const
Returns all the faces indexes around the vertex.
Contains topological differences between two states of a topological mesh, only accessible from the Q...
void clearChanges()
Clears all changes.
QVector< FaceNeighbors > mFacesNeighborhoodToRemove
QVector< QgsMeshFace > removedFaces() const
Returns the faces that are removed with this changes.
QList< QgsMeshVertex > mRemovedVertices
QVector< QgsMeshVertex > addedVertices() const
Returns the added vertices with this changes.
QList< std::array< int, 4 > > mNeighborhoodChanges
bool isEmpty() const
Returns whether changes are empty, that there is nothing to change.
QList< int > changedCoordinatesVerticesIndexes() const
Returns the indexes of vertices that have changed coordinates.
QList< int > mNativeFacesIndexesGeometryChanged
QVector< QgsMeshFace > mFacesToAdd
QList< int > removedFaceIndexes() const
Returns the indexes of the faces that are removed with this changes.
QVector< FaceNeighbors > mFacesNeighborhoodToAdd
QList< std::array< int, 3 > > mVerticesToFaceChanges
QList< double > newVerticesZValues() const
Returns the new Z values of vertices that have changed their coordinates.
QVector< QgsMeshVertex > mVerticesToAdd
QVector< QgsMeshFace > addedFaces() const
Returns the face that are added with this changes.
QList< QgsPointXY > oldVerticesXYValues() const
Returns the old (X,Y) values of vertices that have changed their coordinates.
QList< QgsPointXY > newVerticesXYValues() const
Returns the new (X,Y) values of vertices that have changed their coordinates.
QVector< QgsMeshFace > mFacesToRemove
QList< int > nativeFacesIndexesGeometryChanged() const
Returns a list of the native face indexes that have a geometry changed.
QList< int > verticesToRemoveIndexes() const
Returns the indexes of vertices to remove.
Contains independent faces and topological information about these faces.
QVector< QgsMeshFace > meshFaces() const
Returns faces.
Wraps a QgsMesh to ensure the consistency of the mesh during editing and helps to access elements fro...
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 int vertexPositionInFace(int vertexIndex, const QgsMeshFace &face)
Returns vertex position in face.
static QgsMeshEditingError checkTopology(const QgsMesh &mesh, int maxVerticesPerFace)
Checks the topology of the mesh mesh, if error occurs, this mesh can't be edited.
friend class QgsMeshVertexCirculator
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.
bool delaunayConditionForEdge(int vertexIndex1, int vertexIndex2)
Check if Delaunay condition holds for given edge returns true if delaunay condition holds false other...
#define SIP_SKIP
Definition qgis_sip.h:134
QVector< int > QgsMeshFace
List of vertex indexes.
QgsPoint QgsMeshVertex
xyz coords of vertex
Mesh - vertices, edges and faces.