QGIS API Documentation  3.23.0-Master (22c16f2067)
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)
24 template CORE_EXPORT QVector<int> SIP_SKIP;
25 template CORE_EXPORT QList<int> SIP_SKIP;
26 template CORE_EXPORT QVector<QVector<int>> SIP_SKIP;
27 #endif
28 
30 
33 
47 class 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 
379 class 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.