27#include "meshOptimizer/meshoptimizer.h" 
   29static void triangulateFaces( 
const QgsMeshFace &face,
 
   31                              QVector<QgsMeshFace> &destinationFaces,
 
   32                              QVector<int> &triangularToNative,
 
   33                              const QgsMesh &verticesMeshSource )
 
   35  int vertexCount = face.size();
 
   36  if ( vertexCount < 3 )
 
   39  while ( vertexCount > 3 )
 
   42    const QgsMeshFace ear = { face[vertexCount - 2], face[vertexCount - 1], face[0] };
 
   43    if ( !( std::isnan( verticesMeshSource.
vertex( ear[0] ).
x() )  ||
 
   44            std::isnan( verticesMeshSource.
vertex( ear[1] ).
x() )  ||
 
   45            std::isnan( verticesMeshSource.
vertex( ear[2] ).
x() ) ) )
 
   47      destinationFaces.push_back( ear );
 
   48      triangularToNative.push_back( nativeIndex );
 
   53  const QgsMeshFace triangle = { face[1], face[2], face[0] };
 
   54  if ( !( std::isnan( verticesMeshSource.
vertex( triangle[0] ).
x() )  ||
 
   55          std::isnan( verticesMeshSource.
vertex( triangle[1] ).
x() )  ||
 
   56          std::isnan( verticesMeshSource.
vertex( triangle[2] ).
x() ) ) )
 
   58    destinationFaces.push_back( triangle );
 
   59    triangularToNative.push_back( nativeIndex );
 
   63void QgsTriangularMesh::triangulate( 
const QgsMeshFace &face, 
int nativeIndex )
 
   65  triangulateFaces( face, nativeIndex, mTriangularMesh.
faces, mTrianglesToNativeFaces, mTriangularMesh );
 
   72  if ( mCoordinateTransform.
isValid() )
 
   76      transformedVertex.
transform( mCoordinateTransform, direction );
 
   86  return transformedVertex;
 
   96  return mAverageTriangleSize;
 
 
  104  Q_ASSERT( nativeMesh );
 
  106  bool needUpdateVerticesCoordinates = mTriangularMesh.
vertices.size() != nativeMesh->
vertices.size() ||
 
  112  bool needUpdateFrame =  mTriangularMesh.
vertices.size() != nativeMesh->
vertices.size() ||
 
  113                          mNativeMeshFaceCentroids.size() != nativeMesh->
faces.size() ||
 
  114                          mTriangularMesh.
faces.size() < nativeMesh->
faces.size() ||
 
  115                          mTriangularMesh.
edges.size() != nativeMesh->
edges.size();
 
  119  if ( ! needUpdateVerticesCoordinates  && !needUpdateFrame )
 
  124  if ( needUpdateFrame )
 
  126    mTriangularMesh.
faces.clear();
 
  127    mTriangularMesh.
edges.clear();
 
  128    mEdgesToNativeEdges.clear();
 
  129    mTrianglesToNativeFaces.clear();
 
  133  mCoordinateTransform = transform;
 
  136  for ( 
int i = 0; i < nativeMesh->
vertices.size(); ++i )
 
  142  if ( needUpdateFrame )
 
  145    for ( 
int i = 0; i < nativeMesh->
faces.size(); ++i )
 
  148      triangulate( face, i );
 
  153  mNativeMeshFaceCentroids.resize( nativeMesh->
faces.size() );
 
  154  for ( 
int i = 0; i < nativeMesh->
faces.size(); ++i )
 
  157    mNativeMeshFaceCentroids[i] = calculateCentroid( face );
 
  163  if ( needUpdateFrame )
 
  171  if ( needUpdateFrame )
 
  173    const QVector<QgsMeshEdge> 
edges = nativeMesh->
edges;
 
  174    for ( 
int nativeIndex = 0; nativeIndex < 
edges.size(); ++nativeIndex )
 
  177      if ( !( std::isnan( mTriangularMesh.
vertex( edge.first ).
x() )  ||
 
  178              std::isnan( mTriangularMesh.
vertex( edge.second ).
x() ) ) )
 
  180        mTriangularMesh.
edges.push_back( edge );
 
  181        mEdgesToNativeEdges.push_back( nativeIndex );
 
  187  mNativeMeshEdgeCentroids.resize( nativeMesh->
edgeCount() );
 
  188  for ( 
int i = 0; i < nativeMesh->
edgeCount(); ++i )
 
  193    mNativeMeshEdgeCentroids[i] = 
QgsMeshVertex( ( a.
x() + b.
x() ) / 2.0, ( a.
y() + b.
y() ) / 2.0, ( a.
z() + b.
z() ) / 2.0 );
 
 
  204  return update( nativeMesh, mCoordinateTransform );
 
 
  207void QgsTriangularMesh::finalizeTriangles()
 
  209  mAverageTriangleSize = 0;
 
  210  for ( 
int i = 0; i < mTriangularMesh.
faceCount(); ++i )
 
  218    QgsRectangle bbox = QgsMeshLayerUtils::triangleBoundingBox( v0, v1, v2 );
 
  220    mAverageTriangleSize += std::fmax( bbox.
width(), bbox.
height() );
 
  224  mAverageTriangleSize /= mTriangularMesh.
faceCount();
 
  262  if ( !mIsExtentValid )
 
  265    for ( 
int i = 0; i < mTriangularMesh.
vertices.size(); ++i )
 
  266      if ( !mTriangularMesh.
vertices.at( i ).isEmpty() )
 
  269    mIsExtentValid = 
true;
 
 
  294void QgsTriangularMesh::addVertex( 
const QgsMeshVertex &vertex )
 
  297  mTriangularMesh.
vertices.append( vertexInTriangularCoordinates );
 
  298  if ( !vertexInTriangularCoordinates.
isEmpty() )
 
  299    mExtent.
include( vertexInTriangularCoordinates );
 
  309  return mTriangularMesh.
faces;
 
 
  314  return mTriangularMesh.
edges;
 
 
  324  return mNativeMeshFaceCentroids;
 
 
  329  return mNativeMeshEdgeCentroids;
 
 
  334  return mTrianglesToNativeFaces;
 
 
  339  return mEdgesToNativeEdges;
 
 
  345  if ( mCoordinateTransform.
isValid() )
 
  349      mapPoint = mCoordinateTransform.
transform( point );
 
 
  367  for ( 
const int faceIndex : faceIndexes )
 
 
  380  if ( triangleIndex == -1 )
 
  383  if ( triangleIndex < mTrianglesToNativeFaces.count() )
 
  384    return mTrianglesToNativeFaces.at( triangleIndex );
 
 
  394  return concernedFaceIndex.values();
 
 
  401  for ( 
const int faceIndex : faceIndexes )
 
 
  412  return mSpatialFaceIndex.
intersects( rectangle );
 
 
  417  return mSpatialEdgeIndex.
intersects( rectangle );
 
 
  422  QVector<QVector3D> normals( 
vertices().count(), QVector3D( 0, 0, 0 ) );
 
  426    if ( face.isEmpty() )
 
  429    for ( 
int i = 0; i < 3; i++ )
 
  431      int index1( face.at( i ) );
 
  432      int index2( face.at( ( i + 1 ) % 3 ) );
 
  433      int index3( face.at( ( i + 2 ) % 3 ) );
 
  439      QVector3D v1( 
float( otherVert1.
x() - vert.
x() ), 
float( otherVert1.
y() - vert.
y() ), vertScale * 
float( otherVert1.
z() - vert.
z() ) );
 
  440      QVector3D v2( 
float( otherVert2.
x() - vert.
x() ), 
float( otherVert2.
y() - vert.
y() ), vertScale * 
float( otherVert2.
z() - vert.
z() ) );
 
  442      normals[index1] += QVector3D::crossProduct( v1, v2 );
 
 
  450  QVector<QgsTriangularMesh *> simplifiedMeshes;
 
  453    return simplifiedMeshes;
 
  455  if ( !( reductionFactor > 1 ) )
 
  456    return simplifiedMeshes;
 
  458  size_t verticesCount = size_t( mTriangularMesh.
vertices.count() );
 
  460  unsigned int baseIndexCount = mTriangularMesh.
faceCount() * 3;
 
  462  QVector<unsigned int> indexes( mTriangularMesh.
faces.count() * 3 );
 
  463  for ( 
int i = 0; i < mTriangularMesh.
faceCount(); ++i )
 
  466    for ( 
int j = 0; j < 3; ++j )
 
  467      indexes[i * 3 + j] = f.at( j );
 
  471  for ( 
int i = 0; i < mTriangularMesh.
vertices.count(); ++i )
 
  483    size_t maxNumberOfIndexes = baseIndexCount / pow( reductionFactor, path + 1 );
 
  485    if ( indexes.size() <= 
int( maxNumberOfIndexes ) )
 
  487      delete simplifiedMesh;
 
  491    QVector<unsigned int> returnIndexes( indexes.size() );
 
  493    size_t size = meshopt_simplifySloppy(
 
  494                    returnIndexes.data(),
 
  500                    maxNumberOfIndexes );
 
  503    returnIndexes.resize( size );
 
  505    if ( size == 0 || 
int( size ) >= indexes.size() )
 
  507      QgsDebugError( QStringLiteral( 
"Mesh simplification failed after %1 path" ).arg( path + 1 ) );
 
  508      delete simplifiedMesh;
 
  515    newMesh.
faces.resize( returnIndexes.size() / 3 );
 
  516    for ( 
int i = 0; i < newMesh.
faces.size(); ++i )
 
  519      for ( 
size_t j = 0; j < 3 ; ++j )
 
  520        f[j] = returnIndexes.at( i * 3 + j ) ;
 
  521      newMesh.
faces[i ] = f;
 
  524    simplifiedMesh->mTriangularMesh = newMesh;
 
  525    simplifiedMesh->mSpatialFaceIndex = 
QgsMeshSpatialIndex( simplifiedMesh->mTriangularMesh );
 
  526    simplifiedMesh->finalizeTriangles();
 
  527    simplifiedMeshes.push_back( simplifiedMesh );
 
  531    simplifiedMesh->mTrianglesToNativeFaces = QVector<int>( simplifiedMesh->
triangles().count(), 0 );
 
  532    for ( 
int i = 0; i < simplifiedMesh->mTrianglesToNativeFaces.count(); ++i )
 
  537      for ( 
size_t j = 0; j < 3 ; ++j )
 
  539        x += mTriangularMesh.
vertex( triangle[j] ).
x();
 
  540        y += mTriangularMesh.
vertex( triangle[j] ).
y();
 
  547      if ( indexInBaseMesh == -1 )
 
  552        while ( indexInBaseMesh == -1 && j < 3 )
 
  556      if ( indexInBaseMesh > -1 && indexInBaseMesh < mTrianglesToNativeFaces.count() )
 
  557        simplifiedMesh->mTrianglesToNativeFaces[i] = mTrianglesToNativeFaces[indexInBaseMesh];
 
  560    simplifiedMesh->mLod = path + 1;
 
  561    simplifiedMesh->mBaseTriangularMesh = 
this;
 
  563    if ( simplifiedMesh->
triangles().count() <  minimumTrianglesCount )
 
  566    indexes = returnIndexes;
 
  570  return simplifiedMeshes;
 
 
  576  if ( changes.mRemovedTriangleIndexes.isEmpty() && !changes.mNativeFaceIndexesToRemove.isEmpty() )
 
  578    for ( 
int nf = 0; nf < changes.mNativeFaceIndexesToRemove.count(); ++nf )
 
  580      int nativeIndex = changes.mNativeFaceIndexesToRemove.at( nf );
 
  581      const QgsMeshFace &nativeFace = changes.mNativeFacesToRemove.at( nf );
 
  582      Q_ASSERT( !nativeFace.isEmpty() );
 
  584      QgsRectangle nativeFaceExtent( mTriangularMesh.
vertex( nativeFace.at( 0 ) ), mTriangularMesh.
vertex( nativeFace.at( 0 ) ) );
 
  585      for ( 
int i = 1; i < nativeFace.count(); ++i )
 
  588        nativeFaceExtent.
include( triangularVertex );
 
  593      for ( 
int i = 0; i < concernedTriangle.count(); ++i )
 
  595        int triangleIndex = concernedTriangle.at( i );
 
  596        if ( mTrianglesToNativeFaces.at( triangleIndex ) == nativeIndex )
 
  597          changes.mRemovedTriangleIndexes.append( triangleIndex );
 
  602  if ( changes.mOldZValue.isEmpty() && !changes.mNewZValue.isEmpty() )
 
  604    changes.mOldZValue.reserve( changes.mNewZValue.count() );
 
  605    for ( 
int i = 0; i < changes.mNewZValue.count(); ++i )
 
  606      changes.mOldZValue.append( mTriangularMesh.
vertices.at( changes.mChangedVerticesCoordinates.at( i ) ).z() );
 
  609  if ( changes.mTriangleIndexesGeometryChanged.isEmpty() && !changes.mNativeFaceIndexesGeometryChanged.isEmpty() )
 
  611    for ( 
int i = 0; i < changes.mNativeFaceIndexesGeometryChanged.count(); ++i )
 
  613      const QgsMeshFace &nativeFace = changes.mNativeFacesGeometryChanged.at( i );
 
  614      if ( nativeFace.count() < 2 )
 
  618      for ( 
int i = 2; i < nativeFace.count(); ++i )
 
  623      while ( pos < triangleIndexes.count() )
 
  626             changes.mNativeFaceIndexesGeometryChanged.at( i ) )
 
  627          triangleIndexes.removeAt( pos );
 
  631      changes.mTriangleIndexesGeometryChanged.append( triangleIndexes );
 
  636  for ( 
const QgsMeshVertex &vertex : std::as_const( changes.mAddedVertices ) )
 
  640  if ( !changes.mNativeFacesToAdd.isEmpty() )
 
  642    changes.mTrianglesAddedStartIndex = mTriangularMesh.
faceCount();
 
  643    int firstNewNativeFacesIndex = mNativeMeshFaceCentroids.count();
 
  644    for ( 
int i = 0; i < changes.mNativeFacesToAdd.count(); ++i )
 
  646      const QgsMeshFace &nativeFace = changes.mNativeFacesToAdd.at( i );
 
  647      triangulate( nativeFace, firstNewNativeFacesIndex + i );
 
  648      mNativeMeshFaceCentroids.append( calculateCentroid( nativeFace ) );
 
  651    for ( 
int i = changes.mTrianglesAddedStartIndex; i < mTriangularMesh.
faceCount(); ++i )
 
  652      mSpatialFaceIndex.
addFace( i, mTriangularMesh );
 
  656  for ( 
int i = 0; i < changes.mRemovedTriangleIndexes.count(); ++i )
 
  658    int triangleIndex = changes.mRemovedTriangleIndexes.at( i );
 
  659    mTrianglesToNativeFaces[triangleIndex] = -1;
 
  660    mSpatialFaceIndex.
removeFace( triangleIndex, mTriangularMesh );
 
  664  for ( 
int i = 0; i < changes.mNativeFaceIndexesToRemove.count(); ++i )
 
  665    mNativeMeshFaceCentroids[changes.mNativeFaceIndexesToRemove.at( i )] = 
QgsMeshVertex();
 
  668  for ( 
int i = 0; i < changes.mVerticesIndexesToRemove.count(); ++i )
 
  671  if ( !changes.mVerticesIndexesToRemove.isEmpty() )
 
  672    mIsExtentValid = 
false;
 
  675  for ( 
int i = 0; i < changes.mNewZValue.count(); ++i )
 
  677    int vertexIndex = changes.mChangedVerticesCoordinates.at( i );
 
  678    mTriangularMesh.
vertices[vertexIndex].setZ( changes.mNewZValue.at( i ) );
 
  682  for ( 
const int triangleIndex : std::as_const( changes.mTriangleIndexesGeometryChanged ) )
 
  683    mSpatialFaceIndex.
removeFace( triangleIndex, mTriangularMesh );
 
  686  for ( 
int i = 0; i < changes.mNewXYValue.count(); ++i )
 
  688    const QgsPointXY &nativeCoordinates = changes.mNewXYValue.at( i );
 
  690                                      nativeCoordinates.
y(),
 
  691                                      mTriangularMesh.
vertices.at( changes.mChangedVerticesCoordinates.at( i ) ).z() );
 
  697  for ( 
const int triangleIndex : std::as_const( changes.mTriangleIndexesGeometryChanged ) )
 
  698    mSpatialFaceIndex.
addFace( triangleIndex, mTriangularMesh );
 
  701  for ( 
int i = 0; i < changes.mNativeFaceIndexesGeometryChanged.count(); ++i )
 
  702    mNativeMeshFaceCentroids[changes.mNativeFaceIndexesGeometryChanged.at( i )] = calculateCentroid( changes.mNativeFacesGeometryChanged.at( i ) );
 
 
  708  if ( !changes.mNativeFacesToAdd.isEmpty() )
 
  710    for ( 
int i = changes.mTrianglesAddedStartIndex; i < mTriangularMesh.
faceCount(); ++i )
 
  711      mSpatialFaceIndex.
removeFace( i, mTriangularMesh );
 
  713    int initialNativeFacesCount = mNativeMeshFaceCentroids.count() - changes.mNativeFacesToAdd.count();
 
  715    mTriangularMesh.
faces.resize( changes.mTrianglesAddedStartIndex );
 
  716    mTrianglesToNativeFaces.resize( changes.mTrianglesAddedStartIndex );
 
  717    mNativeMeshFaceCentroids.resize( initialNativeFacesCount );
 
  720  int initialVerticesCount = mTriangularMesh.
vertices.count() - changes.mAddedVertices.count();
 
  721  mTriangularMesh.
vertices.resize( initialVerticesCount );
 
  723  if ( !changes.mAddedVertices.isEmpty() )
 
  724    mIsExtentValid = 
false;
 
  727  for ( 
const int i : std::as_const( changes.mVerticesIndexesToRemove ) )
 
  730  if ( !changes.mVerticesIndexesToRemove.isEmpty() )
 
  731    mIsExtentValid = 
false;
 
  734  QVector<QgsMeshFace> restoredTriangles;
 
  735  QVector<int> restoredTriangularToNative;
 
  736  for ( 
int i = 0; i < changes.mNativeFacesToRemove.count(); ++i )
 
  738    const QgsMeshFace &nativeFace = changes.mNativeFacesToRemove.at( i );
 
  739    triangulateFaces( nativeFace,
 
  740                      changes.mNativeFaceIndexesToRemove.at( i ),
 
  742                      restoredTriangularToNative,
 
  744    mNativeMeshFaceCentroids[changes.mNativeFaceIndexesToRemove.at( i )] = calculateCentroid( nativeFace );
 
  746  for ( 
int i = 0; i < changes.mRemovedTriangleIndexes.count(); ++i )
 
  748    int triangleIndex = changes.mRemovedTriangleIndexes.at( i );
 
  749    mTriangularMesh.
faces[triangleIndex] = restoredTriangles.at( i );
 
  750    mSpatialFaceIndex.
addFace( triangleIndex, mTriangularMesh );
 
  751    mTrianglesToNativeFaces[triangleIndex] = restoredTriangularToNative.at( i );
 
  755  for ( 
int i = 0; i < changes.mOldZValue.count(); ++i )
 
  757    int vertexIndex = changes.mChangedVerticesCoordinates.at( i );
 
  758    mTriangularMesh.
vertices[vertexIndex].setZ( changes.mOldZValue.at( i ) );
 
  762  for ( 
const int triangleIndex : std::as_const( changes.mTriangleIndexesGeometryChanged ) )
 
  763    mSpatialFaceIndex.
removeFace( triangleIndex, mTriangularMesh );
 
  766  for ( 
int i = 0; i < changes.mOldXYValue.count(); ++i )
 
  768    const QgsPointXY &nativeCoordinates = changes.mOldXYValue.at( i );
 
  770                                      nativeCoordinates.
y(),
 
  771                                      mTriangularMesh.
vertices.at( changes.mChangedVerticesCoordinates.at( i ) ).z() );
 
  777  for ( 
const int triangleIndex : std::as_const( changes.mTriangleIndexesGeometryChanged ) )
 
  778    mSpatialFaceIndex.
addFace( triangleIndex, mTriangularMesh );
 
  781  for ( 
int i = 0; i < changes.mNativeFaceIndexesGeometryChanged.count(); ++i )
 
  782    mNativeMeshFaceCentroids[changes.mNativeFaceIndexesGeometryChanged.at( i )] = calculateCentroid( changes.mNativeFacesGeometryChanged.at( i ) );
 
 
  790  mNativeFacesToAdd = topologicalChanges.
addedFaces();
 
  791  mNativeFacesToRemove = topologicalChanges.
removedFaces();
 
  799  mNativeFacesGeometryChanged.resize( mNativeFaceIndexesGeometryChanged.count() );
 
  800  for ( 
int i = 0; i < mNativeFaceIndexesGeometryChanged.count(); ++i )
 
  801    mNativeFacesGeometryChanged[i] = nativeMesh.
face( mNativeFaceIndexesGeometryChanged.at( i ) );
 
 
TransformDirection
Indicates the direction (forward or inverse) of a transform.
 
@ Forward
Forward transform (from source to destination)
 
@ Reverse
Reverse/inverse transform (from destination to source)
 
Custom exception class for Coordinate Reference System related exceptions.
 
A geometry is the spatial representation of a feature.
 
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
 
A spatial index for QgsMeshFace or QgsMeshEdge objects.
 
QList< int > intersects(const QgsRectangle &rectangle) const
Returns a list of face ids with a bounding box which intersects the specified rectangle.
 
void addFace(int faceIndex, const QgsMesh &mesh)
Adds a face with faceIndex from the mesh in the spatial index.
 
void removeFace(int faceIndex, const QgsMesh &mesh)
Removes a face with faceIndex from the mesh in the spatial index.
 
static bool isInTriangleFace(const QgsPointXY point, const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Tests if point p is on the face defined with vertices.
 
static QgsGeometry toGeometry(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns face as polygon geometry.
 
static void setCounterClockwise(QgsMeshFace &triangle, const QgsMeshVertex &v0, const QgsMeshVertex &v1, const QgsMeshVertex &v2)
Checks if the triangle is counter clockwise, if not sets it counter clockwise.
 
static QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
 
static QSet< int > nativeFacesFromTriangles(const QList< int > &triangleIndexes, const QVector< int > &trianglesToNativeFaces)
Returns unique native faces indexes from list of triangle indexes.
 
Point geometry type, with support for z-dimension and m-values.
 
bool isEmpty() const override
Returns true if the geometry is empty.
 
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
 
A rectangle specified with double values.
 
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
 
void setNull()
Mark a rectangle as being null (holding no spatial information).
 
Contains topological differences between two states of a topological mesh, only accessible from the Q...
 
QVector< QgsMeshFace > removedFaces() const
Returns the faces that are removed with this changes.
 
QVector< QgsMeshVertex > addedVertices() const
Returns the added vertices with this changes.
 
QList< int > changedCoordinatesVerticesIndexes() const
Returns the indexes of vertices that have changed coordinates.
 
QList< int > removedFaceIndexes() const
Returns the indexes of the faces that are removed with this changes.
 
QList< double > newVerticesZValues() const
Returns the new Z values of vertices that have changed their coordinates.
 
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.
 
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.
 
Makes changes to a triangular mesh and keeps track of these changes.
 
Changes()=default
Default constructor, no changes.
 
A triangular/derived mesh with vertices in map coordinates.
 
const QVector< QgsMeshVertex > & edgeCentroids() const
Returns centroids of the native edges in map CRS.
 
const QVector< QgsMeshFace > & triangles() const
Returns triangles.
 
QVector< QgsTriangularMesh * > simplifyMesh(double reductionFactor, int minimumTrianglesCount=10) const
Returns simplified meshes.
 
QgsRectangle nativeExtent()
Returns the extent of the mesh in the native mesh coordinates system, returns empty extent if the tra...
 
QgsPointXY transformFromLayerToTrianglesCoordinates(const QgsPointXY &point) const
Transforms a point from layer coordinates system to triangular Mesh coordinates system.
 
int levelOfDetail() const
Returns the corresponding index of level of detail on which this mesh is associated.
 
QgsRectangle extent() const
Returns the extent of the triangular mesh in map coordinates.
 
int faceIndexForPoint(const QgsPointXY &point) const
Finds index of triangle at given point It uses spatial indexing.
 
int nativeFaceIndexForPoint(const QgsPointXY &point) const
Finds index of native face at given point It uses spatial indexing.
 
double averageTriangleSize() const
Returns the average size of triangles in map unit.
 
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)
 
QList< int > edgeIndexesForRectangle(const QgsRectangle &rectangle) const
Finds indexes of edges intersecting given bounding box It uses spatial indexing.
 
Q_DECL_DEPRECATED const QVector< QgsMeshVertex > & centroids() const
Returns centroids of the native faces in map CRS.
 
const QVector< QgsMeshVertex > & vertices() const
Returns vertices in map coordinate system.
 
const QVector< QgsMeshEdge > & edges() const
Returns edges.
 
bool contains(const QgsMesh::ElementType &type) const
Returns whether the mesh contains mesh elements of given type.
 
QgsMeshVertex triangularToNativeCoordinates(const QgsMeshVertex &vertex) const
Transforms the vertex from triangular mesh coordinates system to native coordinates system.
 
QVector< QVector3D > vertexNormals(float vertScale) const
Calculates and returns normal vector on each vertex that is part of any face.
 
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...
 
const QVector< int > & trianglesToNativeFaces() const
Returns mapping between triangles and original faces.
 
const QVector< int > & edgesToNativeEdges() const
Returns mapping between edges and original edges.
 
QList< int > faceIndexesForRectangle(const QgsRectangle &rectangle) const
Finds indexes of triangles intersecting given bounding box It uses spatial indexing.
 
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.
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)
 
QVector< int > QgsMeshFace
List of vertex indexes.
 
QPair< int, int > QgsMeshEdge
Edge is a straight line seqment between 2 points.
 
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.
 
ElementType
Defines type of mesh elements.
 
QgsMeshVertex vertex(int index) const
Returns a vertex at the index.
 
int edgeCount() const
Returns number of edge.
 
QVector< QgsMeshEdge > edges