QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgsmesheditor.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsmesheditor.h - QgsMeshEditor
3
4 ---------------------
5 begin : 8.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 QGSMESHEDITOR_H
17#define QGSMESHEDITOR_H
18
19#include "qgis.h"
20#include "qgsmeshdataprovider.h"
21#include "qgsmeshdataset.h"
22#include "qgstopologicalmesh.h"
23#include "qgstriangularmesh.h"
24
25#include <QObject>
26#include <QPointer>
27#include <QUndoCommand>
28
30
31#if defined( _MSC_VER )
32template CORE_EXPORT QVector<QVector<int>> SIP_SKIP;
33#endif
34
42class CORE_EXPORT QgsMeshEditingError
43{
44 public:
47
50
52
53 int elementIndex = -1;
54
55 bool operator==( const QgsMeshEditingError &other ) const { return ( other.errorType == errorType && other.elementIndex == elementIndex ); }
56 bool operator!=( const QgsMeshEditingError &other ) const { return !operator==( other ); }
57};
58
66class CORE_EXPORT QgsMeshEditor : public QObject
67{
68 Q_OBJECT
69 public:
71 QgsMeshEditor( QgsMeshLayer *meshLayer );
72
74 QgsMeshEditor( QgsMesh *nativeMesh, QgsTriangularMesh *triangularMesh, QObject *parent = nullptr ) SIP_SKIP;
75 ~QgsMeshEditor() override;
76
77 // TODO QGIS 5.0 -- fix this mess
78
86 std::unique_ptr< QgsMeshDatasetGroup > createZValueDatasetGroup();
87
90
98
104 bool fixError( const QgsMeshEditingError &error );
105
108
114 bool faceCanBeAdded( const QgsMeshFace &face ) const;
115
124 bool faceCanBeAddedWithNewVertices( const QList<int> &verticesIndex, const QList<QgsMeshVertex> &newVertices ) const SIP_SKIP;
125
130 bool isFaceGeometricallyCompatible( const QgsMeshFace &face ) const;
131
133 QgsMeshEditingError addFaces( const QVector<QgsMeshFace> &faces ) SIP_SKIP;
134
136 QgsMeshEditingError addFace( const QVector<int> &vertexIndexes );
137
146 QgsMeshEditingError addFaceWithNewVertices( const QList<int> &vertexIndexes, const QList<QgsMeshVertex> &newVertices ) SIP_SKIP;
147
149 QgsMeshEditingError removeFaces( const QList<int> &facesToRemove );
150
152 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
153
155 void flipEdge( int vertexIndex1, int vertexIndex2 );
156
160 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
161
163 void merge( int vertexIndex1, int vertexIndex2 );
164
168 bool faceCanBeSplit( int faceIndex ) const;
169
174 int splitFaces( const QList<int> &faceIndexes );
175
184 int addVertices( const QVector<QgsMeshVertex> &vertices, double tolerance ) SIP_SKIP;
185
194 int addPointsAsVertices( const QVector<QgsPoint> &point, double tolerance );
195
201 QgsMeshEditingError removeVerticesWithoutFillHoles( const QList<int> &verticesToRemoveIndexes );
202
210 QList<int> removeVerticesFillHoles( const QList<int> &verticesToRemoveIndexes );
211
215 void changeZValues( const QList<int> &verticesIndexes, const QList<double> &newValues );
216
228 bool canBeTransformed( const QList<int> &facesToCheck, const std::function<const QgsMeshVertex( int )> &transformFunction ) const SIP_SKIP;
229
235 void changeXYValues( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
236
242 void changeCoordinates( const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
243
247 void advancedEdit( QgsMeshAdvancedEditing *editing );
248
250 void stopEditing();
251
253 QgsRectangle extent() const;
254
256 bool isModified() const;
257
265 bool reindex( bool renumbering );
266
267 //----------- access element methods
268
270 QList<int> freeVerticesIndexes() const;
271
273 bool isVertexOnBoundary( int vertexIndex ) const;
274
276 bool isVertexFree( int vertexIndex ) const;
277
285 QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const SIP_SKIP;
286
289
292
294 bool checkConsistency( QgsMeshEditingError &error ) const;
295
300 bool edgeIsClose( QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition );
301
303 int validFacesCount() const;
304
306 int validVerticesCount() const;
307
309 int maximumVerticesPerFace() const;
310
317 void addVertexWithDelaunayRefinement( const QgsMeshVertex &vertex, const double tolerance );
318
319 signals:
322
323 private:
324 QgsMesh *mMesh = nullptr;
325 QgsTopologicalMesh mTopologicalMesh;
326 QgsTriangularMesh *mTriangularMesh = nullptr;
327 int mMaximumVerticesPerFace = 0;
328 QgsMeshDatasetGroup *mZValueDatasetGroup = nullptr;
329 int mValidVerticesCount = 0;
330 int mValidFacesCount = 0;
331
332 QVector<QgsMeshFace> prepareFaces( const QVector<QgsMeshFace> &faces, QgsMeshEditingError &error ) const;
333 QList<int> prepareFaceWithNewVertices( const QList<int> &vertices, const QList<QgsMeshVertex> &newVertices, QgsMeshEditingError &error ) const;
334 bool isFaceGeometricallyCompatible( const QList<int> &vertexIndex, const QList<QgsMeshVertex> &vertices ) const;
335
337 QUndoStack *mUndoStack = nullptr;
338
339 struct Edit
340 {
341 QgsTopologicalMesh::Changes topologicalChanges;
342 QgsTriangularMesh::Changes triangularMeshChanges;
343 };
344 void applyEdit( Edit &edit );
345 void reverseEdit( Edit &edit );
346
347 void applyAddVertex( Edit &edit, const QgsMeshVertex &vertex, double tolerance );
348 bool applyRemoveVertexFillHole( Edit &edit, int vertexIndex );
349 void applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes );
350 void applyAddFaces( Edit &edit, const QgsTopologicalMesh::TopologicalFaces &faces );
351 void applyRemoveFaces( Edit &edit, const QList<int> &faceToRemoveIndex );
352 void applyChangeZValue( Edit &edit, const QList<int> &verticesIndexes, const QList<double> &newValues );
353 void applyChangeXYValue( Edit &edit, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
354 void applyFlipEdge( Edit &edit, int vertexIndex1, int vertexIndex2 );
355 void applyMerge( Edit &edit, int vertexIndex1, int vertexIndex2 );
356 void applySplit( QgsMeshEditor::Edit &edit, int faceIndex );
357 void applyAdvancedEdit( Edit &edit, QgsMeshAdvancedEditing *editing );
358
359 void applyEditOnTriangularMesh( Edit &edit, const QgsTopologicalMesh::Changes &topologicChanges );
360
361 void updateElementsCount( const QgsTopologicalMesh::Changes &changes, bool apply = true );
362
363 friend class TestQgsMeshEditor;
378
380};
381
382#ifndef SIP_RUN
383
391class QgsMeshLayerUndoCommandMeshEdit : public QUndoCommand
392{
393 public:
394 void undo() override;
395 void redo() override;
396
397 protected:
400 QPointer<QgsMeshEditor> mMeshEditor;
401 QList<QgsMeshEditor::Edit> mEdits;
402};
403
412{
413 public:
415 QgsMeshLayerUndoCommandAddVertices( QgsMeshEditor *meshEditor, const QVector<QgsMeshVertex> &vertices, double tolerance );
416 void redo() override;
417
418 private:
419 QVector<QgsMeshVertex> mVertices;
420 double mTolerance = 0;
421};
422
431{
432 public:
436 QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes );
437 void redo() override;
438
439 private:
440 QList<int> mVerticesToRemoveIndexes;
441};
442
451{
452 public:
461 QgsMeshLayerUndoCommandRemoveVerticesFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes, QList<int> *remainingVerticesPointer = nullptr );
462 void redo() override;
463
464 private:
465 QList<int> mVerticesToRemoveIndexes;
466 QList<int> *mRemainingVerticesPointer = nullptr;
467};
468
477{
478 public:
481
482 void redo() override;
483
484 private:
486};
487
496{
497 public:
499 QgsMeshLayerUndoCommandRemoveFaces( QgsMeshEditor *meshEditor, const QList<int> &facesToRemoveIndexes );
500
501 void redo() override;
502
503 private:
504 QList<int> mfacesToRemoveIndexes;
505};
506
515{
516 public:
521 QgsMeshLayerUndoCommandChangeZValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<double> &newValues );
522 void redo() override;
523
524 private:
525 QList<int> mVerticesIndexes;
526 QList<double> mNewValues;
527};
528
537{
538 public:
543 QgsMeshLayerUndoCommandChangeXYValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
544 void redo() override;
545
546 private:
547 QList<int> mVerticesIndexes;
548 QList<QgsPointXY> mNewValues;
549};
550
559{
560 public:
565 QgsMeshLayerUndoCommandChangeCoordinates( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
566 void redo() override;
567
568 private:
569 QList<int> mVerticesIndexes;
570 QList<QgsPoint> mNewCoordinates;
571};
572
581{
582 public:
586 QgsMeshLayerUndoCommandFlipEdge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
587 void redo() override;
588
589 private:
590 int mVertexIndex1 = -1;
591 int mVertexIndex2 = -1;
592};
593
602{
603 public:
608 QgsMeshLayerUndoCommandMerge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
609 void redo() override;
610
611 private:
612 int mVertexIndex1 = -1;
613 int mVertexIndex2 = -1;
614};
615
624{
625 public:
629 QgsMeshLayerUndoCommandSplitFaces( QgsMeshEditor *meshEditor, const QList<int> &faceIndexes );
630 void redo() override;
631
632 private:
633 QList<int> mFaceIndexes;
634};
635
636
644{
645 public:
648 void redo() override;
649
650 private:
651 QgsMeshAdvancedEditing *mAdvancedEditing = nullptr;
652};
653
654
663{
664 public:
667
668 void redo() override;
669
670 private:
671 QList<std::pair<int, int>> innerEdges( const QSet<int> &faces );
672 QSet<int> secondNeighboringTriangularFaces();
673
674 QgsMeshVertex mVertex;
675 double mTolerance;
676};
677
678#endif //SIP_RUN
679
680#endif // QGSMESHEDITOR_H
MeshEditingErrorType
Type of error that can occur during mesh frame editing.
Definition qgis.h:1738
Abstract class that can be derived to implement advanced editing on mesh.
Abstract class that represents a dataset group.
Represents an error which occurred during mesh editing.
Qgis::MeshEditingErrorType errorType
bool operator==(const QgsMeshEditingError &other) const
bool operator!=(const QgsMeshEditingError &other) const
QgsMeshEditingError()
Constructor of the default error, that is NoError.
Handles edit operations on a mesh layer.
friend class QgsMeshLayerUndoCommandSplitFaces
QgsMeshEditingError initialize()
Initializes the mesh editor and returns first error if the internal native mesh has topological error...
friend class QgsMeshLayerUndoCommandMeshEdit
friend class QgsMeshLayerUndoCommandMerge
void changeXYValues(const QList< int > &verticesIndexes, const QList< QgsPointXY > &newValues)
Changes the (X,Y) coordinates values of the vertices with indexes in verticesIndexes with the values ...
int validFacesCount() const
Returns the count of valid faces, that is non void faces in the mesh.
friend class QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles
QgsMeshEditingError removeFaces(const QList< int > &facesToRemove)
Removes faces faces to the mesh, returns topological errors if this operation fails (operation is not...
QgsMeshEditingError addFaces(const QVector< QgsMeshFace > &faces)
Adds faces faces to the mesh, returns topological errors if this operation fails (operation is not re...
bool checkConsistency(QgsMeshEditingError &error) const
Return true if the edited mesh is consistent.
QList< int > removeVerticesFillHoles(const QList< int > &verticesToRemoveIndexes)
Removes vertices with indexes in the list verticesToRemoveIndexes in the mesh the surrounding faces A...
void flipEdge(int vertexIndex1, int vertexIndex2)
Flips edge (vertexIndex1, vertexIndex2).
QgsRectangle extent() const
Returns the extent of the edited mesh.
friend class QgsMeshLayerUndoCommandAddVertices
bool faceCanBeSplit(int faceIndex) const
Returns true if face with index faceIndex can be split.
QgsMeshEditingError initializeWithErrorsFix()
Initializes the mesh editor.
int maximumVerticesPerFace() const
Returns the maximum count of vertices per face that the mesh can support.
QgsMeshEditingError addFace(const QVector< int > &vertexIndexes)
Adds a face face to the mesh with vertex indexes vertexIndexes, returns topological errors if this op...
QgsMeshEditor(QgsMeshLayer *meshLayer)
Constructor with a specified layer meshLayer.
void merge(int vertexIndex1, int vertexIndex2)
Merges faces separated by vertices with indexes vertexIndex1 and vertexIndex2.
bool edgeIsClose(QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition)
Returns true if an edge of face is closest than the tolerance from the point in triangular mesh coord...
QgsMeshEditingError removeVerticesWithoutFillHoles(const QList< int > &verticesToRemoveIndexes)
Removes vertices with indexes in the list verticesToRemoveIndexes in the mesh removing the surroundin...
bool isFaceGeometricallyCompatible(const QgsMeshFace &face) const
Returns true if the face does not intersect or contains any other elements (faces or vertices) The to...
QList< int > freeVerticesIndexes() const
Returns all the free vertices indexes.
friend class QgsMeshLayerUndoCommandChangeXYValue
void addVertexWithDelaunayRefinement(const QgsMeshVertex &vertex, const double tolerance)
Add a vertex in a face with Delaunay refinement of neighboring faces All neighboring faces sharing a ...
bool isVertexOnBoundary(int vertexIndex) const
Returns whether the vertex with index vertexIndex is on a boundary.
friend class QgsMeshLayerUndoCommandFlipEdge
bool faceCanBeAdded(const QgsMeshFace &face) const
Returns true if a face can be added to the mesh.
void changeCoordinates(const QList< int > &verticesIndexes, const QList< QgsPoint > &newCoordinates)
Changes the (X,Y,Z) coordinates values of the vertices with indexes in vertices indexes with the valu...
void stopEditing()
Stops editing.
friend class QgsMeshLayerUndoCommandAdvancedEditing
bool canBeMerged(int vertexIndex1, int vertexIndex2) const
Returns true if faces separated by vertices with indexes vertexIndex1 and vertexIndex2 can be merged.
friend class QgsMeshLayerUndoCommandAddFaces
QgsMeshEditingError addFaceWithNewVertices(const QList< int > &vertexIndexes, const QList< QgsMeshVertex > &newVertices)
Adds a face formed by some vertices vertexIndexes to the mesh, returns topological errors if this ope...
friend class QgsMeshLayerUndoCommandSetZValue
friend class QgsMeshLayerUndoCommandChangeCoordinates
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)...
int splitFaces(const QList< int > &faceIndexes)
Splits faces with index faceIndexes.
QgsMeshVertexCirculator vertexCirculator(int vertexIndex) const
Returns a vertex circulator linked to this mesh around the vertex with index vertexIndex.
bool faceCanBeAddedWithNewVertices(const QList< int > &verticesIndex, const QList< QgsMeshVertex > &newVertices) const
Returns true if a face formed by some vertices can be added to the mesh.
void meshEdited()
Emitted when the mesh is edited.
friend class QgsMeshLayerUndoCommandAddVertexInFaceWithDelaunayRefinement
void changeZValues(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.
void resetTriangularMesh(QgsTriangularMesh *triangularMesh)
Resets the triangular mesh.
bool isModified() const
Returns whether the mesh has been modified.
void advancedEdit(QgsMeshAdvancedEditing *editing)
Applies an advance editing on the edited mesh, see QgsMeshAdvancedEditing.
bool canBeTransformed(const QList< int > &facesToCheck, const std::function< const QgsMeshVertex(int)> &transformFunction) const
Returns true if faces with index in transformedFaces can be transformed without obtaining topologic o...
int addVertices(const QVector< QgsMeshVertex > &vertices, double tolerance)
Adds vertices in triangular mesh coordinate in the mesh.
int validVerticesCount() const
Returns the count of valid vertices, that is non void vertices in the mesh.
friend class QgsMeshLayerUndoCommandRemoveVerticesFillHoles
bool isVertexFree(int vertexIndex) const
Returns whether the vertex with index vertexIndex is a free vertex.
bool reindex(bool renumbering)
Reindexes the mesh, that is remove unusued index of face and vertices, this operation void the undo/r...
std::unique_ptr< QgsMeshDatasetGroup > createZValueDatasetGroup()
Creates and returns a scalar dataset group with value on vertex that is can be used to access the Z v...
friend class QgsMeshLayerUndoCommandChangeZValue
QgsTriangularMesh * triangularMesh()
Returns a pointer to the triangular mesh.
bool fixError(const QgsMeshEditingError &error)
Tries to fix the topological error in the mesh.
friend class QgsMeshLayerUndoCommandRemoveFaces
QgsTopologicalMesh & topologicalMesh()
Returns a reference to the topological mesh.
~QgsMeshEditor() override
friend class TestQgsMeshEditor
int addPointsAsVertices(const QVector< QgsPoint > &point, double tolerance)
Adds points as vertices in triangular mesh coordinate in the mesh.
QgsMeshLayerUndoCommandAddFaces(QgsMeshEditor *meshEditor, QgsTopologicalMesh::TopologicalFaces &faces)
Constructor with the associated meshEditor and faces that will be added.
QgsMeshLayerUndoCommandAddVertexInFaceWithDelaunayRefinement(QgsMeshEditor *meshEditor, const QgsMeshVertex &vertex, double tolerance)
Constructor with the associated meshEditor and indexes vertex and tolerance.
QgsMeshLayerUndoCommandAddVertices(QgsMeshEditor *meshEditor, const QVector< QgsMeshVertex > &vertices, double tolerance)
Constructor with the associated meshEditor and vertices that will be added.
QgsMeshLayerUndoCommandAdvancedEditing(QgsMeshEditor *meshEditor, QgsMeshAdvancedEditing *advancdEdit)
Constructor with the associated meshEditor.
QgsMeshLayerUndoCommandChangeCoordinates(QgsMeshEditor *meshEditor, const QList< int > &verticesIndexes, const QList< QgsPoint > &newCoordinates)
Constructor with the associated meshEditor and indexes verticesIndexes of the vertices that will have...
QgsMeshLayerUndoCommandChangeXYValue(QgsMeshEditor *meshEditor, const QList< int > &verticesIndexes, const QList< QgsPointXY > &newValues)
Constructor with the associated meshEditor and indexes verticesIndexes of the vertices that will have...
QgsMeshLayerUndoCommandChangeZValue(QgsMeshEditor *meshEditor, const QList< int > &verticesIndexes, const QList< double > &newValues)
Constructor with the associated meshEditor and indexes verticesIndexes of the vertices that will have...
QgsMeshLayerUndoCommandFlipEdge(QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2)
Constructor with the associated meshEditor and the vertex indexes of the edge (vertexIndex1,...
QgsMeshLayerUndoCommandMerge(QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2)
Constructor with the associated meshEditor and the vertex indexes of the edge (vertexIndex1,...
QList< QgsMeshEditor::Edit > mEdits
QgsMeshLayerUndoCommandMeshEdit(QgsMeshEditor *meshEditor)
Constructor for the base class.
QPointer< QgsMeshEditor > mMeshEditor
QgsMeshLayerUndoCommandRemoveFaces(QgsMeshEditor *meshEditor, const QList< int > &facesToRemoveIndexes)
Constructor with the associated meshEditor and indexes facesToRemoveIndexes of the faces that will be...
QgsMeshLayerUndoCommandRemoveVerticesFillHoles(QgsMeshEditor *meshEditor, const QList< int > &verticesToRemoveIndexes, QList< int > *remainingVerticesPointer=nullptr)
Constructor with the associated meshEditor and vertices that will be removed.
QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles(QgsMeshEditor *meshEditor, const QList< int > &verticesToRemoveIndexes)
Constructor with the associated meshEditor and vertices that will be removed.
QgsMeshLayerUndoCommandSplitFaces(QgsMeshEditor *meshEditor, const QList< int > &faceIndexes)
Constructor with the associated meshEditor and indexes faceIndexes of the faces to split.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Convenience class that turns around a vertex and provides information about faces and vertices.
Represents a 2D point.
Definition qgspointxy.h:62
A rectangle specified with double values.
Contains topological differences between two states of a topological mesh, only accessible from the Q...
Contains independent faces and topological information about these faces.
Wraps a QgsMesh to ensure the consistency of the mesh during editing and helps to access elements fro...
Makes changes to a triangular mesh and keeps track of these changes.
A triangular/derived mesh with vertices in map coordinates.
#define SIP_SKIP
Definition qgis_sip.h:133
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QVector< int > QgsMeshFace
List of vertex indexes.
QgsPoint QgsMeshVertex
xyz coords of vertex
Mesh - vertices, edges and faces.