32  : QObject( meshLayer )
 
   33  , mMesh( meshLayer ? meshLayer->nativeMesh() : nullptr )
 
   34  , mTriangularMesh( meshLayer ? meshLayer->triangularMeshByLodIndex( 0 ) : nullptr )
 
   35  , mUndoStack( meshLayer ? meshLayer->undoStack() : nullptr )
 
   47  , mTriangularMesh( triangularMesh )
 
   49  mUndoStack = 
new QUndoStack( 
this );
 
   55  std::unique_ptr<QgsMeshDatasetGroup> zValueDatasetGroup = std::make_unique<QgsMeshVerticesElevationDatasetGroup>( tr( 
"vertices Z value" ), mMesh );
 
   56  mZValueDatasetGroup = zValueDatasetGroup.get();
 
   57  return zValueDatasetGroup.release();
 
   72    for ( 
int vi : freeVertices )
 
  100    mTriangularMesh->
update( mMesh );
 
  127      auto faceIt = mMesh->
faces.begin();
 
  128      while ( faceIt != mMesh->
faces.end() )
 
  131          faceIt = mMesh->
faces.erase( faceIt );
 
  158  geomEngine->prepareGeometry();
 
  161  QList<int> newFaceVerticesIndexes( face.toList() );
 
  162  int newFaceSize = face.count();
 
  164  if ( !concernedFaceIndex.isEmpty() )
 
  168    for ( 
const int faceIndex : concernedFaceIndex )
 
  171      int existingFaceSize = existingFace.count();
 
  172      bool shareVertex = 
false;
 
  173      for ( 
int i = 0; i < existingFaceSize; ++i )
 
  175        if ( newFaceVerticesIndexes.contains( existingFace.at( i ) ) )
 
  184        for ( 
int i = 0; i < existingFaceSize; ++i )
 
  186          int index1 = existingFace.at( i );
 
  187          int index2 = existingFace.at( ( i + 1 ) % existingFaceSize );
 
  192          if ( ! newFaceVerticesIndexes.contains( index1 )  && !newFaceVerticesIndexes.contains( index2 ) )
 
  195            if ( geomEngine->intersects( edgeGeom.
constGet() ) )
 
  200            for ( 
int vi = 0; vi < newFaceVerticesIndexes.count(); ++vi )
 
  202              int vertInNewFace1 = newFaceVerticesIndexes.at( vi );
 
  203              int vertInNewFace2 = newFaceVerticesIndexes.at( ( vi + 1 ) % newFaceSize );
 
  204              if ( vertInNewFace1 != index1 && vertInNewFace2 != index2 && vertInNewFace1 != index2 && vertInNewFace2 != index1 )
 
  220        if ( geomEngine->intersects( existingFaceGeom.
constGet() ) )
 
  229  for ( 
const int freeVertexIndex : freeVertices )
 
  231    if ( newFaceVerticesIndexes.contains( freeVertexIndex ) )
 
  235    if ( geomEngine->contains( &vertex ) )
 
  248  QVector<QgsMeshFace> facesToAdd = prepareFaces( {face}, error );
 
  268void QgsMeshEditor::applyEdit( QgsMeshEditor::Edit &edit )
 
  270  mTopologicalMesh.
applyChanges( edit.topologicalChanges );
 
  271  mTriangularMesh->
applyChanges( edit.triangularMeshChanges );
 
  273  if ( mZValueDatasetGroup &&
 
  274       ( !edit.topologicalChanges.newVerticesZValues().isEmpty() ||
 
  275         !edit.topologicalChanges.verticesToRemoveIndexes().isEmpty() ||
 
  276         !edit.topologicalChanges.addedVertices().isEmpty() ) )
 
  279  updateElementsCount( edit.topologicalChanges );
 
  282void QgsMeshEditor::reverseEdit( QgsMeshEditor::Edit &edit )
 
  285  mTriangularMesh->
reverseChanges( edit.triangularMeshChanges, *mMesh );
 
  287  if ( mZValueDatasetGroup &&
 
  288       ( !edit.topologicalChanges.newVerticesZValues().isEmpty() ||
 
  289         !edit.topologicalChanges.verticesToRemoveIndexes().isEmpty() ||
 
  290         !edit.topologicalChanges.addedVertices().isEmpty() ) )
 
  293  updateElementsCount( edit.topologicalChanges, 
false );
 
  296void QgsMeshEditor::applyAddVertex( QgsMeshEditor::Edit &edit, 
const QgsMeshVertex &vertex, 
double tolerance )
 
  301  int faceEdgeIntersect = -1;
 
  302  int edgePosition = -1;
 
  306  if ( 
edgeIsClose( vertexInTriangularCoordinate, tolerance, faceEdgeIntersect, edgePosition ) )
 
  314    if ( includingFaceIndex != -1 )
 
  315      topologicChanges = mTopologicalMesh.
addVertexInFace( includingFaceIndex, vertex );
 
  320  applyEditOnTriangularMesh( edit, topologicChanges );
 
  322  if ( mZValueDatasetGroup )
 
  325  updateElementsCount( edit.topologicalChanges );
 
  328bool QgsMeshEditor::applyRemoveVertexFillHole( QgsMeshEditor::Edit &edit, 
int vertexIndex )
 
  334    applyEditOnTriangularMesh( edit, changes );
 
  336    if ( mZValueDatasetGroup )
 
  339    updateElementsCount( edit.topologicalChanges );
 
  346void QgsMeshEditor::applyRemoveVerticesWithoutFillHole( QgsMeshEditor::Edit &edit, 
const QList<int> &verticesIndexes )
 
  348  applyEditOnTriangularMesh( edit, mTopologicalMesh.
removeVertices( verticesIndexes ) );
 
  350  if ( mZValueDatasetGroup )
 
  353  updateElementsCount( edit.topologicalChanges );
 
  358  applyEditOnTriangularMesh( edit,  mTopologicalMesh.
addFaces( faces ) );
 
  360  updateElementsCount( edit.topologicalChanges );
 
  363void QgsMeshEditor::applyRemoveFaces( QgsMeshEditor::Edit &edit, 
const QList<int> &faceToRemoveIndex )
 
  365  applyEditOnTriangularMesh( edit, mTopologicalMesh.
removeFaces( faceToRemoveIndex ) );
 
  367  updateElementsCount( edit.topologicalChanges );
 
  370void QgsMeshEditor::applyChangeZValue( QgsMeshEditor::Edit &edit, 
const QList<int> &verticesIndexes, 
const QList<double> &newValues )
 
  372  applyEditOnTriangularMesh( edit, mTopologicalMesh.
changeZValue( verticesIndexes, newValues ) );
 
  374  if ( mZValueDatasetGroup )
 
  378void QgsMeshEditor::applyChangeXYValue( QgsMeshEditor::Edit &edit, 
const QList<int> &verticesIndexes, 
const QList<QgsPointXY> &newValues )
 
  380  applyEditOnTriangularMesh( edit, mTopologicalMesh.
changeXYValue( verticesIndexes, newValues ) );
 
  383void QgsMeshEditor::applyFlipEdge( QgsMeshEditor::Edit &edit, 
int vertexIndex1, 
int vertexIndex2 )
 
  385  applyEditOnTriangularMesh( edit, mTopologicalMesh.
flipEdge( vertexIndex1, vertexIndex2 ) );
 
  387  updateElementsCount( edit.topologicalChanges );
 
  390void QgsMeshEditor::applyMerge( QgsMeshEditor::Edit &edit, 
int vertexIndex1, 
int vertexIndex2 )
 
  392  applyEditOnTriangularMesh( edit, mTopologicalMesh.
merge( vertexIndex1, vertexIndex2 ) );
 
  394  updateElementsCount( edit.topologicalChanges );
 
  397void QgsMeshEditor::applySplit( QgsMeshEditor::Edit &edit, 
int faceIndex )
 
  399  applyEditOnTriangularMesh( edit, mTopologicalMesh.
splitFace( faceIndex ) );
 
  401  updateElementsCount( edit.topologicalChanges );
 
  406  applyEditOnTriangularMesh( edit, editing->
apply( 
this ) );
 
  408  updateElementsCount( edit.topologicalChanges );
 
  410  if ( mZValueDatasetGroup )
 
  419  edit.topologicalChanges = topologicChanges;
 
  420  edit.triangularMeshChanges = triangularChanges;
 
  466                              point.
y() - tolerance,
 
  467                              point.
x() + tolerance,
 
  468                              point.
y() + tolerance );
 
  471  double minDist = std::numeric_limits<double>::max();
 
  473  double epsilon = std::numeric_limits<double>::epsilon() * tolerance;
 
  474  for ( 
const int nativeFaceIndex : nativeFaces )
 
  477    const int faceSize = face.size();
 
  478    for ( 
int i = 0; i < faceSize; ++i )
 
  494      if ( dist < tolerance && dist < minDist )
 
  496        faceIndex = nativeFaceIndex;
 
  503  if ( edgePosition != -1 )
 
  512  return mValidFacesCount;
 
  517  return mValidVerticesCount;
 
  522  return mMaximumVerticesPerFace;
 
  551  return mTopologicalMesh.
canBeMerged( vertexIndex1, vertexIndex2 );
 
  564  return mTopologicalMesh.
canBeSplit( faceIndex );
 
  569  QList<int> faceIndexesSplittable;
 
  571  for ( 
const int faceIndex : faceIndexes )
 
  573      faceIndexesSplittable.append( faceIndex );
 
  575  if ( faceIndexesSplittable.isEmpty() )
 
  580  return faceIndexesSplittable.count();
 
  583QVector<QgsMeshFace> QgsMeshEditor::prepareFaces( 
const QVector<QgsMeshFace> &faces, 
QgsMeshEditingError &error )
 
  585  QVector<QgsMeshFace> treatedFaces = faces;
 
  589  for ( 
int i = 0; i < treatedFaces.count(); ++i )
 
  592    if ( mMaximumVerticesPerFace != 0 && face.count() > mMaximumVerticesPerFace )
 
  609  QVector<QgsMeshFace> facesToAdd = prepareFaces( faces, error );
 
  633  QVector<QgsMeshVertex> verticesInLayerCoordinate( vertices.count() );
 
  634  int ignoredVertex = 0;
 
  635  for ( 
int i = 0; i < vertices.count(); ++i )
 
  637    const QgsPointXY &pointInTriangularMesh = vertices.at( i );
 
  638    bool isTooClose = 
false;
 
  640    if ( triangleIndex != -1 )
 
  643      for ( 
int j = 0; j < 3; ++j )
 
  646        double dist = pointInTriangularMesh.
distance( facePoint );
 
  647        if ( dist < tolerance )
 
  660    if ( verticesInLayerCoordinate.at( i ).isEmpty() )
 
  664  if ( ignoredVertex < vertices.count() )
 
  669  int effectivlyAddedVertex = vertices.count() - ignoredVertex;
 
  671  return effectivlyAddedVertex;
 
  683  QList<int> verticesIndexes = verticesToRemoveIndexes;
 
  685  QSet<int> concernedNativeFaces;
 
  686  for ( 
const int vi : std::as_const( verticesIndexes ) )
 
  689    concernedNativeFaces.unite( QSet< int >( faces.begin(), faces.end() ) );
 
  703  QList<int> remainingVertices;
 
  706  return remainingVertices;
 
  717  for ( 
const int faceIndex : facesToCheck )
 
  720    int faceSize = face.count();
 
  721    QVector<QgsPointXY> pointsInTriangularMeshCoordinate( faceSize );
 
  722    QVector<QgsPointXY> points( faceSize );
 
  723    for ( 
int i = 0; i < faceSize; ++i )
 
  726      int ip1 = face[( i + 1 ) % faceSize];
 
  727      int ip2 = face[( i + 2 ) % faceSize];
 
  733      double ux = p0.x() - p1.
x();
 
  734      double uy = p0.y() - p1.
y();
 
  735      double vx = p2.
x() - p1.
x();
 
  736      double vy = p2.
y() - p1.
y();
 
  738      double crossProduct = ux * vy - uy * vx;
 
  739      if ( crossProduct >= 0 ) 
 
  748    QList<int> otherFaceIndexes =
 
  751    for ( 
const int otherFaceIndex : otherFaceIndexes )
 
  754      int existingFaceSize = otherFace.count();
 
  755      bool shareVertex = 
false;
 
  756      for ( 
int i = 0; i < existingFaceSize; ++i )
 
  758        if ( face.contains( otherFace.at( i ) ) )
 
  767        for ( 
int i = 0; i < existingFaceSize; ++i )
 
  769          int index1 = otherFace.at( i );
 
  770          int index2 = otherFace.at( ( i + 1 ) % existingFaceSize );
 
  771          if ( ! face.contains( index1 )  && !face.contains( index2 ) )
 
  773            const QgsPointXY &v1 = transformFunction( index1 );
 
  774            const QgsPointXY &v2 =  transformFunction( index2 );
 
  783        QVector<QgsPointXY> otherPoints( existingFaceSize );
 
  784        for ( 
int i = 0; i < existingFaceSize; ++i )
 
  785          otherPoints[i] = transformFunction( otherFace.at( i ) );
 
  787        if ( deformedFace.
intersects( existingFaceGeom ) )
 
  793    for ( 
const int vertexIndex : freeVerticesIndex )
 
  795      const QgsPointXY &mapPoint = transformFunction( vertexIndex ); 
 
  796      if ( deformedFace.
contains( &mapPoint ) )
 
  803  for ( 
const int vertexIndex : freeVerticesIndex )
 
  805    const QgsMeshVertex &newFreeVertexPosition = transformFunction( vertexIndex ); 
 
  809    if ( originalIncludingFace != -1 )
 
  814      int faceSize = face.count();
 
  815      QVector<QgsPointXY> points( faceSize );
 
  816      for ( 
int i = 0; i < faceSize; ++i )
 
  817        points[i] = transformFunction( face.at( i ) );
 
  820      const QgsPointXY ptXY( newFreeVertexPosition );
 
  821      if ( deformedFace.
contains( &ptXY ) )
 
  852  : mMeshEditor( meshEditor )
 
  861  for ( 
int i = 
mEdits.count() - 1; i >= 0; --i )
 
  870  for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
  876  , mVertices( vertices )
 
  877  , mTolerance( tolerance )
 
  879  setText( QObject::tr( 
"Add %n vertices", 
nullptr, mVertices.count() ) );
 
  884  if ( !mVertices.isEmpty() )
 
  886    for ( 
int i = 0; i < mVertices.count(); ++i )
 
  891      QgsMeshEditor::Edit edit;
 
  892      mMeshEditor->applyAddVertex( edit, vertex, mTolerance );
 
  899    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
  906  const QList<int> &verticesToRemoveIndexes,
 
  907  QList<int> *remainingVerticesPointer )
 
  909  , mVerticesToRemoveIndexes( verticesToRemoveIndexes )
 
  910  , mRemainingVerticesPointer( remainingVerticesPointer )
 
  912  setText( QObject::tr( 
"Remove %n vertices filling holes", 
nullptr, verticesToRemoveIndexes.count() ) );
 
  917  int initialVertexCount = mVerticesToRemoveIndexes.count();
 
  918  if ( !mVerticesToRemoveIndexes.isEmpty() )
 
  920    QgsMeshEditor::Edit edit;
 
  921    QList<int> vertexToRetry;
 
  922    while ( !mVerticesToRemoveIndexes.isEmpty() )
 
  925      for ( 
const int &vertex : std::as_const( mVerticesToRemoveIndexes ) )
 
  927        if ( 
mMeshEditor->applyRemoveVertexFillHole( edit, vertex ) )
 
  930          vertexToRetry.append( vertex );
 
  933      if ( vertexToRetry.count() == mVerticesToRemoveIndexes.count() )
 
  936        mVerticesToRemoveIndexes = vertexToRetry;
 
  939    if ( initialVertexCount == mVerticesToRemoveIndexes.count() )
 
  942    if ( mRemainingVerticesPointer != 
nullptr )
 
  943      *mRemainingVerticesPointer = mVerticesToRemoveIndexes;
 
  945    mRemainingVerticesPointer = 
nullptr;
 
  947    mVerticesToRemoveIndexes.clear(); 
 
  951    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
  959  const QList<int> &verticesToRemoveIndexes )
 
  961  , mVerticesToRemoveIndexes( verticesToRemoveIndexes )
 
  963  setText( QObject::tr( 
"Remove %n vertices without filling holes", 
nullptr, verticesToRemoveIndexes.count() ) ) ;
 
  968  if ( !mVerticesToRemoveIndexes.isEmpty() )
 
  970    QgsMeshEditor::Edit edit;
 
  972    mMeshEditor->applyRemoveVerticesWithoutFillHole( edit, mVerticesToRemoveIndexes );
 
  975    mVerticesToRemoveIndexes.clear(); 
 
  979    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
  988  setText( QObject::tr( 
"Add %n face(s)", 
nullptr, faces.
meshFaces().count() ) );
 
  995    QgsMeshEditor::Edit edit;
 
 1003    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1010  , mfacesToRemoveIndexes( facesToRemoveIndexes )
 
 1012  setText( QObject::tr( 
"Remove %n face(s)", 
nullptr, facesToRemoveIndexes.count() ) );
 
 1017  if ( !mfacesToRemoveIndexes.isEmpty() )
 
 1019    QgsMeshEditor::Edit edit;
 
 1020    mMeshEditor->applyRemoveFaces( edit, mfacesToRemoveIndexes );
 
 1023    mfacesToRemoveIndexes.clear(); 
 
 1027    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1044    return !mUndoStack->isClean();
 
 1052  mUndoStack->clear();
 
 1062    if ( !mTopologicalMesh.
renumber() )
 
 1097  return mTopologicalMesh;
 
 1102  return mTriangularMesh;
 
 1107  , mVerticesIndexes( verticesIndexes )
 
 1108  , mNewValues( newValues )
 
 1110  setText( QObject::tr( 
"Change %n vertices Z Value", 
nullptr, verticesIndexes.count() ) );
 
 1115  if ( !mVerticesIndexes.isEmpty() )
 
 1117    QgsMeshEditor::Edit edit;
 
 1118    mMeshEditor->applyChangeZValue( edit, mVerticesIndexes, mNewValues );
 
 1120    mVerticesIndexes.clear();
 
 1125    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1132  , mVerticesIndexes( verticesIndexes )
 
 1133  , mNewValues( newValues )
 
 1135  setText( QObject::tr( 
"Move %n vertices", 
nullptr, verticesIndexes.count() ) );
 
 1140  if ( !mVerticesIndexes.isEmpty() )
 
 1142    QgsMeshEditor::Edit edit;
 
 1143    mMeshEditor->applyChangeXYValue( edit, mVerticesIndexes, mNewValues );
 
 1145    mVerticesIndexes.clear();
 
 1150    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1158  , mVerticesIndexes( verticesIndexes )
 
 1159  , mNewCoordinates( newCoordinates )
 
 1161  setText( QObject::tr( 
"Transform %n vertices coordinates", 
nullptr, verticesIndexes.count() ) );
 
 1166  if ( !mVerticesIndexes.isEmpty() )
 
 1168    QgsMeshEditor::Edit editXY;
 
 1169    QList<QgsPointXY> newXY;
 
 1170    newXY.reserve( mNewCoordinates.count() );
 
 1171    QgsMeshEditor::Edit editZ;
 
 1173    newZ.reserve( mNewCoordinates.count() );
 
 1175    for ( 
const QgsPoint &pt : std::as_const( mNewCoordinates ) )
 
 1178      newZ.append( pt.z() );
 
 1181    mMeshEditor->applyChangeXYValue( editXY, mVerticesIndexes, newXY );
 
 1183    mMeshEditor->applyChangeZValue( editZ, mVerticesIndexes, newZ );
 
 1185    mVerticesIndexes.clear();
 
 1186    mNewCoordinates.clear();
 
 1190    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1199  , mVertexIndex1( vertexIndex1 )
 
 1200  , mVertexIndex2( vertexIndex2 )
 
 1202  setText( QObject::tr( 
"Flip edge" ) );
 
 1207  if ( mVertexIndex1 >= 0 && mVertexIndex2 >= 0 )
 
 1209    QgsMeshEditor::Edit edit;
 
 1210    mMeshEditor->applyFlipEdge( edit, mVertexIndex1, mVertexIndex2 );
 
 1217    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1224  , mVertexIndex1( vertexIndex1 )
 
 1225  , mVertexIndex2( vertexIndex2 )
 
 1227  setText( QObject::tr( 
"Merge faces" ) );
 
 1232  if ( mVertexIndex1 >= 0 && mVertexIndex2 >= 0 )
 
 1234    QgsMeshEditor::Edit edit;
 
 1235    mMeshEditor->applyMerge( edit, mVertexIndex1, mVertexIndex2 );
 
 1242    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1249  , mFaceIndexes( faceIndexes )
 
 1251  setText( QObject::tr( 
"Split %n face(s)", 
nullptr, faceIndexes.count() ) );
 
 1256  if ( !mFaceIndexes.isEmpty() )
 
 1258    for ( 
int faceIndex : std::as_const( mFaceIndexes ) )
 
 1260      QgsMeshEditor::Edit edit;
 
 1264    mFaceIndexes.clear();
 
 1268    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
 1275  , mAdvancedEditing( advancdEdit )
 
 1277  setText( advancdEdit->
text() );
 
 1282  if ( mAdvancedEditing )
 
 1284    QgsMeshEditor::Edit edit;
 
 1287      mMeshEditor->applyAdvancedEdit( edit, mAdvancedEditing );
 
 1291    mAdvancedEditing = 
nullptr;
 
 1295    for ( QgsMeshEditor::Edit &edit : 
mEdits )
 
The Qgis class provides global constants for use throughout the application.
 
MeshEditingErrorType
Flags which control behavior of raster renderers.
 
@ TooManyVerticesInFace
A face has more vertices than the maximum number supported per face.
 
@ InvalidFace
An error occurs due to an invalid face (for example, vertex indexes are unordered)
 
@ UniqueSharedVertex
A least two faces share only one vertices.
 
@ ManifoldFace
ManifoldFace.
 
@ InvalidVertex
An error occurs due to an invalid vertex (for example, vertex index is out of range the available ver...
 
@ FlatFace
A flat face is present.
 
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon) SIP_HOLDGIL
Returns the squared distance between a point and a line.
 
A geometry is the spatial representation of a feature.
 
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
 
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
 
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygonXY.
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
 
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
 
Line string geometry type, with support for z-dimension and m-values.
 
Abstract class that can be derived to implement advanced editing on mesh.
 
virtual QgsTopologicalMesh::Changes apply(QgsMeshEditor *meshEditor)=0
Apply a change to mesh Editor.
 
virtual bool isFinished() const
Returns whether the advanced edit is finished, if not, this edit has to be applied again with QgsMesh...
 
virtual QString text() const
Returns a short text string describing what this advanced edit does. Default implementation return a ...
 
virtual int maximumVerticesCountPerFace() const
Returns the maximum number of vertices per face supported by the current mesh, if returns 0,...
 
Abstract class that represents a dataset group.
 
void setStatisticObsolete() const
Sets statistic obsolete, that means statistic will be recalculated when requested.
 
Class that represents an error during mesh editing.
 
Qgis::MeshEditingErrorType errorType
 
QgsMeshEditingError()
Constructor of the default error, that is NoError.
 
Class that makes edit operation on a mesh.
 
friend class QgsMeshLayerUndoCommandSplitFaces
 
QgsMeshEditingError initialize()
Initializes the mesh editor and returns first error if the internal native mesh has topological error...
 
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...
 
QList< int > freeVerticesIndexes() const
Returns all the free vertices indexes.
 
friend class QgsMeshLayerUndoCommandChangeXYValue
 
bool isVertexOnBoundary(int vertexIndex) const
Returns whether the vertex with index vertexIndex is on a boundary.
 
friend class QgsMeshLayerUndoCommandFlipEdge
 
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.
 
bool isFaceGeometricallyCompatible(const QgsMeshFace &face)
Returns true if the face does not intersect or contains any other elements (faces or vertices) The to...
 
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
 
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.
 
void meshEdited()
Emitted when the mesh is edited.
 
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 faceCanBeAdded(const QgsMeshFace &face)
Returns true if a face can be added to the mesh.
 
bool reindex(bool renumbering)
Reindexes the mesh, that is remove unusued index of face and vertices, this operation void the undo/r...
 
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.
 
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 QgsMeshLayerUndoCommandRemoveFaces
 
QgsTopologicalMesh & topologicalMesh()
Returns a reference to the topological mesh.
 
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.
 
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,...
 
Base class for undo/redo command for mesh editing.
 
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.
 
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
 
Convenient class that turn around a vertex and provide information about faces and vertices.
 
A class to represent a 2D point.
 
double distance(double x, double y) const SIP_HOLDGIL
Returns the distance between this point and a specified x, y coordinate.
 
Point geometry type, with support for z-dimension and m-values.
 
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
 
A rectangle specified with double values.
 
Class that contains topological differences between two states of a topological mesh,...
 
QVector< QgsMeshFace > removedFaces() const
Returns the faces that are removed with this changes.
 
QVector< QgsMeshVertex > addedVertices() const
Returns the added vertices with this changes.
 
bool isEmpty() const
Returns whether changes are empty, that there is nothing to change.
 
QVector< QgsMeshFace > addedFaces() const
Returns the face that are added with this changes.
 
QList< int > verticesToRemoveIndexes() const
Returns the indexes of vertices to remove.
 
Class that contains independent faces an topological information about this faces.
 
void clear()
Clears all data contained in the instance.
 
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.
 
void applyChanges(const Changes &changes)
Applies the changes.
 
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 ...
 
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...
 
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 .
 
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.
 
The Changes class is used to make changes of the triangular and to keep traces of this changes If a C...
 
Triangular/Derived Mesh is mesh with vertices in map coordinates.
 
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
 
QgsRectangle nativeExtent()
Returns the extent of the mesh in the native mesh coordinates system, returns empty extent if the tra...
 
int nativeFaceIndexForPoint(const QgsPointXY &point) const
Finds index of native face at given point It uses spatial indexing.
 
void reverseChanges(const Changes &changes, const QgsMesh &nativeMesh)
Reverses the changes on the triangular mesh (see Changes)
 
void applyChanges(const Changes &changes)
Applies the changes on the triangular mesh (see Changes)
 
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
 
QgsMeshVertex triangularToNativeCoordinates(const QgsMeshVertex &vertex) const
Transforms the vertex from triangular mesh coordinates system to native coordinates system.
 
QgsMeshVertex nativeToTriangularCoordinates(const QgsMeshVertex &vertex) const
Transforms the vertex from native coordinates system to triangular mesh coordinates system.
 
bool update(QgsMesh *nativeMesh, const QgsCoordinateTransform &transform)
Constructs triangular mesh from layer's native mesh and transform to destination CRS.
 
const QVector< QgsMeshVertex > & faceCentroids() const
Returns centroids of the native faces in map CRS.
 
QList< int > nativeFaceIndexForRectangle(const QgsRectangle &rectangle) const
Finds indexes of native faces which bounding boxes intersect given bounding box It uses spatial index...
 
int faceIndexForPoint_v2(const QgsPointXY &point) const
Finds index of triangle at given point It uses spatial indexing and don't use geos to be faster.
 
CORE_EXPORT QgsGeometry toGeometry(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns face as polygon geometry.
 
QVector< int > QgsMeshFace
List of vertex indexes.
 
QgsPoint QgsMeshVertex
xyz coords of vertex
 
Mesh - vertices, edges and faces.
 
int vertexCount() const
Returns number of vertices.
 
QVector< QgsMeshVertex > vertices
 
QgsMeshFace face(int index) const
Returns a face at the index.
 
QVector< QgsMeshFace > faces
 
int faceCount() const
Returns number of faces.