QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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 using FaceNeighbors = QVector<int>;
49
59 class CORE_EXPORT TopologicalFaces
60 {
61 public:
66 SIP_SKIP QVector<QgsMeshFace> meshFaces() const { return mFaces; }
67
69 void clear();
70
76 SIP_SKIP QVector<FaceNeighbors> facesNeighborhood() const;
77
79 int vertexToFace( int vertexIndex ) const;
80
81 private:
82 QVector<QgsMeshFace> mFaces; // the faces containing the vertices indexes in the mesh
83 QVector<FaceNeighbors> mFacesNeighborhood; // neighborhood of the faces, face indexes are local
84 QMultiHash<int, int> mVerticesToFace; // map of vertices to incident face, face indexes are local
85 QList<int> mBoundaries; // list of boundary vertices indexes in the mesh
86
87 friend class QgsTopologicalMesh;
89 };
90
91
99 class CORE_EXPORT Changes
100 {
101 public:
107 SIP_SKIP QVector<QgsMeshFace> addedFaces() const;
108
114 SIP_SKIP QVector<QgsMeshFace> removedFaces() const;
115
117 QList<int> removedFaceIndexes() const;
118
120#ifndef SIP_RUN
121 QVector<QgsMeshVertex> addedVertices() const;
122#else
123 QVector<QgsPoint> addedVertices() const;
124#endif
125
127 QList<int> verticesToRemoveIndexes() const;
128
130 QList<int> changedCoordinatesVerticesIndexes() const;
131
133 QList<double> newVerticesZValues() const;
134
136 QList<QgsPointXY> newVerticesXYValues() const;
137
139 QList<QgsPointXY> oldVerticesXYValues() const;
140
142 QList<int> nativeFacesIndexesGeometryChanged() const;
143
145 bool isEmpty() const;
146
147 protected:
149 QList<int> mFaceIndexesToRemove; // the removed faces indexes in the mesh
150 QVector<QgsMeshFace> mFacesToAdd;
151 QVector<FaceNeighbors> mFacesNeighborhoodToAdd;
152 QVector<QgsMeshFace> mFacesToRemove;
153 QVector<FaceNeighbors> mFacesNeighborhoodToRemove;
154 QList<std::array<int, 4>> mNeighborhoodChanges; // {index of concerned face, neighbor position, previous value, changed value}
155
156 QVector<QgsMeshVertex> mVerticesToAdd;
157 QVector<int> mVertexToFaceToAdd;
159 QList<QgsMeshVertex> mRemovedVertices;
161 QList<std::array<int, 3>> mVerticesToFaceChanges; // {index of concerned vertex, previous value, changed value}
162
164 QList<double> mNewZValues;
165 QList<double> mOldZValues;
166 QList<QgsPointXY> mNewXYValues;
167 QList<QgsPointXY> mOldXYValues;
169
171 void clearChanges();
172
173 private:
174 int addedFaceIndexInMesh( int internalIndex ) const;
175 int removedFaceIndexInMesh( int internalIndex ) const;
176
177 friend class QgsTopologicalMesh;
178 };
179
184 static QgsTopologicalMesh createTopologicalMesh( QgsMesh *mesh, int maxVerticesPerFace, QgsMeshEditingError &error );
185
191 SIP_SKIP static TopologicalFaces createNewTopologicalFaces( const QVector<QgsMeshFace> &faces, bool uniqueSharedVertexAllowed, QgsMeshEditingError &error );
192
193 //----------- access element methods
194
196 QVector<int> neighborsOfFace( int faceIndex ) const;
197
199 QList<int> facesAroundVertex( int vertexIndex ) const;
200
202 QgsMesh *mesh() const;
203
205 int firstFaceLinked( int vertexIndex ) const;
206
208 bool isVertexOnBoundary( int vertexIndex ) const;
209
211 bool isVertexFree( int vertexIndex ) const;
212
214 QList<int> freeVerticesIndexes() const;
215
221 SIP_SKIP QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const;
222
223 //----------- editing methods
224
226 QgsMeshEditingError facesCanBeAdded( const TopologicalFaces &topologicalFaces ) const;
227
232 Changes addFaces( const TopologicalFaces &topologicFaces );
233
238 QgsMeshEditingError facesCanBeRemoved( const QList<int> &facesIndexes );
239
244 Changes removeFaces( const QList<int> &facesIndexes );
245
249 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
250
255 Changes flipEdge( int vertexIndex1, int vertexIndex2 );
256
263 bool delaunayConditionForEdge( int vertexIndex1, int vertexIndex2 );
264
268 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
269
274 Changes merge( int vertexIndex1, int vertexIndex2 );
275
279 bool canBeSplit( int faceIndex ) const;
280
285 Changes splitFace( int faceIndex );
286
291 Changes addVertexInFace( int faceIndex, const QgsMeshVertex &vertex );
292
297 Changes insertVertexInFacesEdge( int faceIndex, int position, const QgsMeshVertex &vertex );
298
303 Changes addFreeVertex( const QgsMeshVertex &vertex );
304
310 Changes removeVertexFillHole( int vertexIndex );
311
317 Changes removeVertices( const QList<int> &vertices );
318
322 Changes changeZValue( const QList<int> &verticesIndexes, const QList<double> &newValues );
323
327 Changes changeXYValue( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
328
329
331 void applyChanges( const Changes &changes );
332
334 void reverseChanges( const Changes &changes );
335
338
346 SIP_SKIP static QgsMeshEditingError checkTopologyOfVerticesAsFace( const QVector<QgsMeshVertex> &vertices, bool &clockwise );
347
352 void reindex();
353
357 bool renumber();
358
361
363 static QgsMeshEditingError checkTopology( const QgsMesh &mesh, int maxVerticesPerFace );
364
366 static inline int vertexPositionInFace( int vertexIndex, const QgsMeshFace &face ) { return face.indexOf( vertexIndex ); }
367
369 static int vertexPositionInFace( const QgsMesh &mesh, int vertexIndex, int faceIndex );
370
371 private:
373 static TopologicalFaces createTopologicalFaces( const QVector<QgsMeshFace> &faces, QVector<int> *globalVertexToFace, QgsMeshEditingError &error, bool allowUniqueSharedVertex );
374
376 QSet<int> concernedFacesBy( const QList<int> &faceIndexes ) const;
377
379 void referenceAsFreeVertex( int vertexIndex );
381 void dereferenceAsFreeVertex( int vertexIndex );
382
387 bool eitherSideFacesAndVertices(
388 int vertexIndex1, int vertexIndex2, int &face1, int &face2, int &neighborVertex1InFace1, int &neighborVertex1InFace2, int &neighborVertex2inFace1, int &neighborVertex2inFace2
389 ) const;
390
391 bool renumberVertices( QVector<int> &oldToNewIndex ) const;
392 bool renumberFaces( QVector<int> &oldToNewIndex ) const;
393
394 //Attributes
395 QgsMesh *mMesh = nullptr;
396 QVector<int> mVertexToFace;
397 QVector<FaceNeighbors> mFacesNeighborhood;
398
399 QSet<int> mFreeVertices;
400
401 int mMaximumVerticesPerFace = 0;
402
404};
405
406#ifndef SIP_RUN
407
417class CORE_EXPORT QgsMeshVertexCirculator
418{
419 public:
421 QgsMeshVertexCirculator( const QgsTopologicalMesh &topologicalMesh, int vertexIndex );
422
428 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int faceIndex, int vertexIndex );
429
435 QgsMeshVertexCirculator( const QgsTopologicalMesh::TopologicalFaces &topologicalFaces, int vertexIndex );
436
438 int turnCounterClockwise() const;
439
441 int turnClockwise() const;
442
444 int currentFaceIndex() const;
445
447 QgsMeshFace currentFace() const;
448
450 bool goBoundaryClockwise() const;
451
453 bool goBoundaryCounterClockwise() const;
454
456 int oppositeVertexClockwise() const;
457
460
462 bool isValid() const;
463
465 QList<int> facesAround() const;
466
468 int degree() const;
469
470 private:
471 const QVector<QgsMeshFace> mFaces;
472 const QVector<QgsTopologicalMesh::FaceNeighbors> mFacesNeighborhood;
473 const int mVertexIndex = -1;
474 mutable int mCurrentFace = -1;
475 mutable int mLastValidFace = -1;
476 bool mIsValid = false;
477 mutable int mDegree = -1;
478
479 int positionInCurrentFace() const;
480};
481#endif
482
483#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:133
QVector< int > QgsMeshFace
List of vertex indexes.
QgsPoint QgsMeshVertex
xyz coords of vertex
Mesh - vertices, edges and faces.