QGIS API Documentation 4.3.0-Master (91d4a333d5d)
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
81 std::unique_ptr< QgsMeshDatasetGroup > createZValueDatasetGroup();
82
85
93
99 bool fixError( const QgsMeshEditingError &error );
100
103
109 bool faceCanBeAdded( const QgsMeshFace &face ) const;
110
119 bool faceCanBeAddedWithNewVertices( const QList<int> &verticesIndex, const QList<QgsMeshVertex> &newVertices ) const SIP_SKIP;
120
125 bool isFaceGeometricallyCompatible( const QgsMeshFace &face ) const;
126
128 QgsMeshEditingError addFaces( const QVector<QgsMeshFace> &faces ) SIP_SKIP;
129
131 QgsMeshEditingError addFace( const QVector<int> &vertexIndexes );
132
141 QgsMeshEditingError addFaceWithNewVertices( const QList<int> &vertexIndexes, const QList<QgsMeshVertex> &newVertices ) SIP_SKIP;
142
144 QgsMeshEditingError removeFaces( const QList<int> &facesToRemove );
145
147 bool edgeCanBeFlipped( int vertexIndex1, int vertexIndex2 ) const;
148
150 void flipEdge( int vertexIndex1, int vertexIndex2 );
151
155 bool canBeMerged( int vertexIndex1, int vertexIndex2 ) const;
156
158 void merge( int vertexIndex1, int vertexIndex2 );
159
163 bool faceCanBeSplit( int faceIndex ) const;
164
169 int splitFaces( const QList<int> &faceIndexes );
170
179 int addVertices( const QVector<QgsMeshVertex> &vertices, double tolerance ) SIP_SKIP;
180
189 int addPointsAsVertices( const QVector<QgsPoint> &point, double tolerance );
190
196 QgsMeshEditingError removeVerticesWithoutFillHoles( const QList<int> &verticesToRemoveIndexes );
197
205 QList<int> removeVerticesFillHoles( const QList<int> &verticesToRemoveIndexes );
206
210 void changeZValues( const QList<int> &verticesIndexes, const QList<double> &newValues );
211
223 bool canBeTransformed( const QList<int> &facesToCheck, const std::function<const QgsMeshVertex( int )> &transformFunction ) const SIP_SKIP;
224
230 void changeXYValues( const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
231
237 void changeCoordinates( const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
238
242 void advancedEdit( QgsMeshAdvancedEditing *editing );
243
245 void stopEditing();
246
248 QgsRectangle extent() const;
249
251 bool isModified() const;
252
260 bool reindex( bool renumbering );
261
262 //----------- access element methods
263
265 QList<int> freeVerticesIndexes() const;
266
268 bool isVertexOnBoundary( int vertexIndex ) const;
269
271 bool isVertexFree( int vertexIndex ) const;
272
280 QgsMeshVertexCirculator vertexCirculator( int vertexIndex ) const SIP_SKIP;
281
284
287
289 bool checkConsistency( QgsMeshEditingError &error ) const;
290
295 bool edgeIsClose( QgsPointXY point, double tolerance, int &faceIndex, int &edgePosition );
296
298 int validFacesCount() const;
299
301 int validVerticesCount() const;
302
304 int maximumVerticesPerFace() const;
305
312 void addVertexWithDelaunayRefinement( const QgsMeshVertex &vertex, const double tolerance );
313
314 signals:
317
318 private:
319 QgsMesh *mMesh = nullptr;
320 QgsTopologicalMesh mTopologicalMesh;
321 QgsTriangularMesh *mTriangularMesh = nullptr;
322 int mMaximumVerticesPerFace = 0;
323 int mValidVerticesCount = 0;
324 int mValidFacesCount = 0;
325
326 QVector<QgsMeshFace> prepareFaces( const QVector<QgsMeshFace> &faces, QgsMeshEditingError &error ) const;
327 QList<int> prepareFaceWithNewVertices( const QList<int> &vertices, const QList<QgsMeshVertex> &newVertices, QgsMeshEditingError &error ) const;
328 bool isFaceGeometricallyCompatible( const QList<int> &vertexIndex, const QList<QgsMeshVertex> &vertices ) const;
329
331 QUndoStack *mUndoStack = nullptr;
332
333 struct Edit
334 {
335 QgsTopologicalMesh::Changes topologicalChanges;
336 QgsTriangularMesh::Changes triangularMeshChanges;
337 };
338 void applyEdit( Edit &edit );
339 void reverseEdit( Edit &edit );
340
341 void applyAddVertex( Edit &edit, const QgsMeshVertex &vertex, double tolerance );
342 bool applyRemoveVertexFillHole( Edit &edit, int vertexIndex );
343 void applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, const QList<int> &verticesIndexes );
344 void applyAddFaces( Edit &edit, const QgsTopologicalMesh::TopologicalFaces &faces );
345 void applyRemoveFaces( Edit &edit, const QList<int> &faceToRemoveIndex );
346 void applyChangeZValue( Edit &edit, const QList<int> &verticesIndexes, const QList<double> &newValues );
347 void applyChangeXYValue( Edit &edit, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
348 void applyFlipEdge( Edit &edit, int vertexIndex1, int vertexIndex2 );
349 void applyMerge( Edit &edit, int vertexIndex1, int vertexIndex2 );
350 void applySplit( QgsMeshEditor::Edit &edit, int faceIndex );
351 void applyAdvancedEdit( Edit &edit, QgsMeshAdvancedEditing *editing );
352
353 void applyEditOnTriangularMesh( Edit &edit, const QgsTopologicalMesh::Changes &topologicChanges );
354
355 void updateElementsCount( const QgsTopologicalMesh::Changes &changes, bool apply = true );
356
357 friend class TestQgsMeshEditor;
372
374};
375
376#ifndef SIP_RUN
377
385class QgsMeshLayerUndoCommandMeshEdit : public QUndoCommand
386{
387 public:
388 void undo() override;
389 void redo() override;
390
391 protected:
394 QPointer<QgsMeshEditor> mMeshEditor;
395 QList<QgsMeshEditor::Edit> mEdits;
396};
397
406{
407 public:
409 QgsMeshLayerUndoCommandAddVertices( QgsMeshEditor *meshEditor, const QVector<QgsMeshVertex> &vertices, double tolerance );
410 void redo() override;
411
412 private:
413 QVector<QgsMeshVertex> mVertices;
414 double mTolerance = 0;
415};
416
425{
426 public:
430 QgsMeshLayerUndoCommandRemoveVerticesWithoutFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes );
431 void redo() override;
432
433 private:
434 QList<int> mVerticesToRemoveIndexes;
435};
436
445{
446 public:
455 QgsMeshLayerUndoCommandRemoveVerticesFillHoles( QgsMeshEditor *meshEditor, const QList<int> &verticesToRemoveIndexes, QList<int> *remainingVerticesPointer = nullptr );
456 void redo() override;
457
458 private:
459 QList<int> mVerticesToRemoveIndexes;
460 QList<int> *mRemainingVerticesPointer = nullptr;
461};
462
471{
472 public:
475
476 void redo() override;
477
478 private:
480};
481
490{
491 public:
493 QgsMeshLayerUndoCommandRemoveFaces( QgsMeshEditor *meshEditor, const QList<int> &facesToRemoveIndexes );
494
495 void redo() override;
496
497 private:
498 QList<int> mfacesToRemoveIndexes;
499};
500
509{
510 public:
515 QgsMeshLayerUndoCommandChangeZValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<double> &newValues );
516 void redo() override;
517
518 private:
519 QList<int> mVerticesIndexes;
520 QList<double> mNewValues;
521};
522
531{
532 public:
537 QgsMeshLayerUndoCommandChangeXYValue( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPointXY> &newValues );
538 void redo() override;
539
540 private:
541 QList<int> mVerticesIndexes;
542 QList<QgsPointXY> mNewValues;
543};
544
553{
554 public:
559 QgsMeshLayerUndoCommandChangeCoordinates( QgsMeshEditor *meshEditor, const QList<int> &verticesIndexes, const QList<QgsPoint> &newCoordinates );
560 void redo() override;
561
562 private:
563 QList<int> mVerticesIndexes;
564 QList<QgsPoint> mNewCoordinates;
565};
566
575{
576 public:
580 QgsMeshLayerUndoCommandFlipEdge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
581 void redo() override;
582
583 private:
584 int mVertexIndex1 = -1;
585 int mVertexIndex2 = -1;
586};
587
596{
597 public:
602 QgsMeshLayerUndoCommandMerge( QgsMeshEditor *meshEditor, int vertexIndex1, int vertexIndex2 );
603 void redo() override;
604
605 private:
606 int mVertexIndex1 = -1;
607 int mVertexIndex2 = -1;
608};
609
618{
619 public:
623 QgsMeshLayerUndoCommandSplitFaces( QgsMeshEditor *meshEditor, const QList<int> &faceIndexes );
624 void redo() override;
625
626 private:
627 QList<int> mFaceIndexes;
628};
629
630
638{
639 public:
642 void redo() override;
643
644 private:
645 QgsMeshAdvancedEditing *mAdvancedEditing = nullptr;
646};
647
648
657{
658 public:
661
662 void redo() override;
663
664 private:
665 QList<std::pair<int, int>> innerEdges( const QSet<int> &faces );
666 QSet<int> secondNeighboringTriangularFaces();
667
668 QgsMeshVertex mVertex;
669 double mTolerance;
670};
671
672#endif //SIP_RUN
673
674#endif // QGSMESHEDITOR_H
MeshEditingErrorType
Type of error that can occur during mesh frame editing.
Definition qgis.h:1829
Abstract class that can be derived to implement advanced editing on mesh.
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:138
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.