Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgstriangularmesh.h 3 : : ------------------- 4 : : begin : April 2018 5 : : copyright : (C) 2018 by Peter Petrik 6 : : email : zilolv at gmail dot com 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #ifndef QGSTRIANGULARMESH_H 19 : : #define QGSTRIANGULARMESH_H 20 : : 21 : : 22 : : #define SIP_NO_FILE 23 : : 24 : : #include <QVector> 25 : : #include <QVector3D> 26 : : #include <QSet> 27 : : #include <QList> 28 : : #include <memory> 29 : : #include "qgis_core.h" 30 : : #include "qgsmeshdataprovider.h" 31 : : #include "qgsgeometry.h" 32 : : #include "qgsmeshspatialindex.h" 33 : : 34 : : class QgsRenderContext; 35 : : class QgsCoordinateTransform; 36 : : class QgsRectangle; 37 : : 38 : : /** 39 : : * \ingroup core 40 : : * 41 : : * \brief Triangular/Derived Mesh is mesh with vertices in map coordinates. 42 : : * 43 : : * It creates spatial index for identification of a triangle that contains a particular point 44 : : * on the map. 45 : : * 46 : : * \note The API is considered EXPERIMENTAL and can be changed without a notice 47 : : * 48 : : * \since QGIS 3.2 49 : : */ 50 : 0 : class CORE_EXPORT QgsTriangularMesh // TODO rename to QgsRendererMesh in QGIS 4 51 : : { 52 : : public: 53 : : //! Ctor 54 : : QgsTriangularMesh(); 55 : : //! Dtor 56 : : ~QgsTriangularMesh(); 57 : : 58 : : /** 59 : : * Constructs triangular mesh from layer's native mesh and transform to destination CRS. Populates spatial index. 60 : : * \param nativeMesh QgsMesh to access native vertices and faces 61 : : * \param transform Transformation from layer CRS to destination (e.g. map) CRS. With invalid transform, it keeps the native mesh CRS 62 : : * \returns TRUE if the mesh is effectivly updated, and FALSE if not 63 : : */ 64 : : bool update( QgsMesh *nativeMesh, const QgsCoordinateTransform &transform = QgsCoordinateTransform() ); 65 : : 66 : : /** 67 : : * Returns vertices in map coordinate system 68 : : * 69 : : * The list of consist of vertices from native mesh (0-N) and 70 : : * extra vertices needed to create triangles (N+1 - len) 71 : : */ 72 : : const QVector<QgsMeshVertex> &vertices() const ; 73 : : 74 : : //! Returns triangles 75 : : const QVector<QgsMeshFace> &triangles() const ; 76 : : 77 : : //! Returns edges 78 : : const QVector<QgsMeshEdge> &edges() const ; 79 : : 80 : : /** 81 : : * Returns centroids of the native faces in map CRS 82 : : * 83 : : * \deprecated since QGIS 3.14 use faceCentroids() instead 84 : : */ 85 : : Q_DECL_DEPRECATED const QVector<QgsMeshVertex> ¢roids() const ; 86 : : 87 : : /** 88 : : * Returns centroids of the native faces in map CRS 89 : : * \since QGIS 3.14 90 : : */ 91 : : const QVector<QgsMeshVertex> &faceCentroids() const ; 92 : : 93 : : /** 94 : : * Returns centroids of the native edges in map CRS 95 : : * \since QGIS 3.14 96 : : */ 97 : : const QVector<QgsMeshVertex> &edgeCentroids() const ; 98 : : 99 : : //! Returns mapping between triangles and original faces 100 : : const QVector<int> &trianglesToNativeFaces() const ; 101 : : 102 : : //! Returns mapping between edges and original edges 103 : : const QVector<int> &edgesToNativeEdges() const ; 104 : : 105 : : /** 106 : : * Finds index of triangle at given point 107 : : * It uses spatial indexing 108 : : * 109 : : * \param point point in map coordinate system 110 : : * \returns triangle index that contains the given point, -1 if no such triangle exists 111 : : * 112 : : * \since QGIS 3.4 113 : : */ 114 : : int faceIndexForPoint( const QgsPointXY &point ) const ; 115 : : 116 : : /** 117 : : * Finds index of triangle at given point 118 : : * It uses spatial indexing and don't use geos to be faster 119 : : * 120 : : * \param point point in map coordinate system 121 : : * \returns triangle index that contains the given point, -1 if no such triangle exists 122 : : * 123 : : * \since QGIS 3.12 124 : : */ 125 : : int faceIndexForPoint_v2( const QgsPointXY &point ) const; 126 : : 127 : : /** 128 : : * Finds indexes of triangles intersecting given bounding box 129 : : * It uses spatial indexing 130 : : * 131 : : * \param rectangle bounding box in map coordinate system 132 : : * \returns triangle indexes that intersect the rectangle 133 : : * 134 : : * \since QGIS 3.4 135 : : */ 136 : : QList<int> faceIndexesForRectangle( const QgsRectangle &rectangle ) const ; 137 : : 138 : : /** 139 : : * Finds indexes of edges intersecting given bounding box 140 : : * It uses spatial indexing 141 : : * 142 : : * \param rectangle bounding box in map coordinate system 143 : : * \returns edges indexes that intersect the rectangle 144 : : */ 145 : : QList<int> edgeIndexesForRectangle( const QgsRectangle &rectangle ) const ; 146 : : 147 : : /** 148 : : * Calculates and returns normale vector on each vertex that is part of any face 149 : : * 150 : : * \returns all normales at vertices 151 : : * 152 : : * \since QGIS 3.12 153 : : */ 154 : : 155 : : QVector<QVector3D> vertexNormals( float vertScale ) const; 156 : : 157 : : /** 158 : : * Returns simplified meshes. 159 : : * The first simplified mesh is simplified with a goal of a number of triangles equals to the 160 : : * number of triangles of the base mesh divised by the reduction factor. For the following mesh the same reduction factor is used with 161 : : * the prededent goal of number of triangles. 162 : : * There are as many simplified meshes as necessary to have a the minimum triangles count on the last simplified mesh. 163 : : * 164 : : * The caller has to take the ownership of returned meshes. 165 : : * 166 : : * Not implemented for Edge meshes and Mixed meshes 167 : : * 168 : : * \param reductionFactor is the factor used to reduce the number of triangles of the mesh 169 : : * \param minimumTrianglesCount is the minimal faces count on simplified mesh 170 : : * \since QGIS 3.14 171 : : */ 172 : : QVector<QgsTriangularMesh *> simplifyMesh( double reductionFactor, int minimumTrianglesCount = 10 ) const; 173 : : 174 : : /** 175 : : * Returns the average size of triangles in map unit. It is calculated using the maximum of the height/width of the 176 : : * bounding box of each triangles. 177 : : * 178 : : * \since QGIS 3.14 179 : : */ 180 : : double averageTriangleSize() const; 181 : : 182 : : /** 183 : : * Returns the corresponding index of level of detail on which this mesh is associated 184 : : * 185 : : * - 0: base mesh 186 : : * - 1: first simplified mesh 187 : : * - 2: second simplified mesh (lower level of detail) 188 : : * - ... 189 : : * 190 : : * \since QGIS 3.14 191 : : */ 192 : : int levelOfDetail() const; 193 : : 194 : : /** 195 : : * Returns the extent of the triangular mesh in map coordinates 196 : : * 197 : : * \returns bounding box of the triangular mesh 198 : : * 199 : : * \since QGIS 3.14 200 : : */ 201 : : QgsRectangle extent() const; 202 : : 203 : : /** 204 : : * Returns whether the mesh contains at mesh elements of given type 205 : : * \since QGIS 3.14 206 : : */ 207 : : bool contains( const QgsMesh::ElementType &type ) const; 208 : : 209 : : private: 210 : : 211 : : /** 212 : : * Triangulates native face to triangles 213 : : * 214 : : * Triangulation does not create any new vertices and uses 215 : : * "Ear clipping method". Number of vertices in face is usually 216 : : * less than 10 and the faces are usually convex and without holes 217 : : * 218 : : * Skips the input face if it is not possible to triangulate 219 : : * with the given algorithm (e.g. only 2 vertices, polygon with holes) 220 : : */ 221 : : void triangulate( const QgsMeshFace &face, int nativeIndex ); 222 : : 223 : : // check clock wise and calculate average size of triangles 224 : : void finalizeTriangles(); 225 : : 226 : : // vertices: map CRS; 0-N ... native vertices, N+1 - len ... extra vertices 227 : : // faces are derived triangles 228 : : QgsMesh mTriangularMesh; 229 : : QVector<int> mTrianglesToNativeFaces; //len(mTrianglesToNativeFaces) == len(mTriangles). Mapping derived -> native 230 : : QVector<int> mEdgesToNativeEdges; //len(mEdgesToNativeEdges) == len(mEdges). Mapping derived -> native 231 : : 232 : : // centroids of the native faces in map CRS 233 : : QVector<QgsMeshVertex> mNativeMeshFaceCentroids; 234 : : 235 : : // centroids of the native edges in map CRS 236 : : QVector<QgsMeshVertex> mNativeMeshEdgeCentroids; 237 : : 238 : : QgsMeshSpatialIndex mSpatialFaceIndex; 239 : : QgsMeshSpatialIndex mSpatialEdgeIndex; 240 : : QgsCoordinateTransform mCoordinateTransform; //coordinate transform used to convert native mesh vertices to map vertices 241 : : 242 : : QgsRectangle mExtent; 243 : : 244 : : // average size of the triangles 245 : : double mAverageTriangleSize = 0; 246 : : int mLod = 0; 247 : : 248 : : const QgsTriangularMesh *mBaseTriangularMesh = nullptr; 249 : : 250 : : friend class TestQgsTriangularMesh; 251 : : }; 252 : : 253 : : namespace QgsMeshUtils 254 : : { 255 : : //! Returns face as polygon geometry 256 : : CORE_EXPORT QgsGeometry toGeometry( const QgsMeshFace &face, const QVector<QgsMeshVertex> &vertices ); 257 : : 258 : : //! Returns face as polygon geometry, caller is responsible for delete 259 : : CORE_EXPORT std::unique_ptr< QgsPolygon > toPolygon( const QgsMeshFace &face, const QVector<QgsMeshVertex> &vertices ); 260 : : 261 : : /** 262 : : * Returns unique native faces indexes from list of triangle indexes 263 : : * \since QGIS 3.4 264 : : */ 265 : : CORE_EXPORT QSet<int> nativeFacesFromTriangles( const QList<int> &triangleIndexes, const QVector<int> &trianglesToNativeFaces ); 266 : : 267 : : /** 268 : : * Returns unique native faces indexes from list of triangle indexes 269 : : * \since QGIS 3.14 270 : : */ 271 : : CORE_EXPORT QSet<int> nativeEdgesFromEdges( const QList<int> &edgesIndexes, const QVector<int> &edgesToNativeEdges ); 272 : : 273 : : /** 274 : : * Returns unique native vertex indexes from list of vertices of triangles 275 : : * \since QGIS 3.14 276 : : */ 277 : : CORE_EXPORT QSet<int> nativeVerticesFromTriangles( const QList<int> &triangleIndexes, const QVector<QgsMeshFace> &triangles ); 278 : : 279 : : /** 280 : : * Returns unique native faces indexes from list of vertices of triangles 281 : : * \since QGIS 3.14 282 : : */ 283 : : CORE_EXPORT QSet<int> nativeVerticesFromEdges( const QList<int> &edgesIndexes, const QVector<QgsMeshEdge> &edges ); 284 : : 285 : : /** 286 : : * Tests if point p is on the face defined with vertices 287 : : * \since QGIS 3.12 288 : : */ 289 : : bool isInTriangleFace( const QgsPointXY point, const QgsMeshFace &face, const QVector<QgsMeshVertex> &vertices ); 290 : : 291 : : }; 292 : : 293 : : #endif // QGSTRIANGULARMESH_H