1 /***************************************************************************
2                          qgsmeshlayerrenderer.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 QGSMESHLAYERRENDERER_H
19 #define QGSMESHLAYERRENDERER_H
20 
21 class QgsMeshLayer;
22 
23 #define SIP_NO_FILE
24 
25 #include <memory>
26 #include <limits>
27 
28 #include "qgis.h"
29 
30 #include "qgsmaplayerrenderer.h"
31 #include "qgsrasterinterface.h"
32 #include "qgstriangularmesh.h"
33 #include "qgsmeshlayer.h"
34 #include "qgssymbol.h"
35 #include "qgsmeshdataprovider.h"
36 #include "qgsmeshtracerenderer.h"
37 #include "qgsmapclippingregion.h"
38 
39 class QgsRenderContext;
40 
41 ///@cond PRIVATE
42 
43 /**
44  * Feedback for mesh layer rendering - right now derived from raster block feedback so that we
45  * can pass it to block reading in the raster interface.
46  */
47 class QgsMeshLayerRendererFeedback : public QgsRasterBlockFeedback
48 {
49     Q_OBJECT
50 };
51 
52 
53 /**
54  * Cache for data needed to render active datasets
55  */
56 struct CORE_NO_EXPORT QgsMeshLayerRendererCache
57 {
58   int mDatasetGroupsCount = 0;
59 
60   // scalar dataset
61   QgsMeshDatasetIndex mActiveScalarDatasetIndex;
62   QVector<double> mScalarDatasetValues;
63   QgsMeshDataBlock mScalarActiveFaceFlagValues;
64   QgsMeshDatasetGroupMetadata::DataType mScalarDataType = QgsMeshDatasetGroupMetadata::DataType::DataOnVertices;
65   double mScalarDatasetMinimum = std::numeric_limits<double>::quiet_NaN();
66   double mScalarDatasetMaximum = std::numeric_limits<double>::quiet_NaN();
67   QgsMeshRendererScalarSettings::DataResamplingMethod mDataInterpolationMethod = QgsMeshRendererScalarSettings::None;
68   std::unique_ptr<QgsMesh3dAveragingMethod> mScalarAveragingMethod;
69 
70   // vector dataset
71   QgsMeshDatasetIndex mActiveVectorDatasetIndex;
72   QgsMeshDataBlock mVectorDatasetValues;
73   QVector<double> mVectorDatasetValuesMag;
74   double mVectorDatasetMagMinimum = std::numeric_limits<double>::quiet_NaN();
75   double mVectorDatasetMagMaximum = std::numeric_limits<double>::quiet_NaN();
76   double mVectorDatasetGroupMagMinimum = std::numeric_limits<double>::quiet_NaN();
77   double mVectorDatasetGroupMagMaximum = std::numeric_limits<double>::quiet_NaN();
78   QgsMeshDatasetGroupMetadata::DataType mVectorDataType = QgsMeshDatasetGroupMetadata::DataType::DataOnVertices;
79   std::unique_ptr<QgsMesh3dAveragingMethod> mVectorAveragingMethod;
80 };
81 
82 
83 ///@endcond
84 
85 /**
86  * \ingroup core
87  * \brief Implementation of threaded rendering for mesh layers.
88  *
89  * \note not available in Python bindings
90  * \since QGIS 3.2
91  */
92 class QgsMeshLayerRenderer : public QgsMapLayerRenderer
93 {
94   public:
95     //! Ctor
96     QgsMeshLayerRenderer( QgsMeshLayer *layer, QgsRenderContext &context );
97     ~QgsMeshLayerRenderer() override = default;
98     QgsFeedback *feedback() const override;
99     bool render() override;
100 
101   private:
102     void renderMesh();
103     void renderEdgeMesh( const QgsMeshRendererMeshSettings &settings, const QList<int> &edgesInExtent );
104     void renderFaceMesh( const QgsMeshRendererMeshSettings &settings, const QVector<QgsMeshFace> &faces, const QList<int> &facesInExtent );
105     void renderScalarDataset();
106     void renderScalarDatasetOnEdges( const QgsMeshRendererScalarSettings &scalarSettings );
107     void renderScalarDatasetOnFaces( const QgsMeshRendererScalarSettings &scalarSettings );
108 
109     void renderVectorDataset();
110     void copyTriangularMeshes( QgsMeshLayer *layer, QgsRenderContext &context );
111     void copyScalarDatasetValues( QgsMeshLayer *layer );
112     void copyVectorDatasetValues( QgsMeshLayer *layer );
113     void calculateOutputSize();
114     QgsPointXY fractionPoint( const QgsPointXY &p1, const QgsPointXY &p2, double fraction ) const;
115     bool mIsMeshSimplificationActive = false;
116     QColor colorAt( QgsColorRampShader *shader, double val ) const;
117 
118   protected:
119     //! feedback class for cancellation
120     std::unique_ptr<QgsMeshLayerRendererFeedback> mFeedback;
121 
122     // copy from mesh layer
123     QgsMesh mNativeMesh;
124 
125     // copy from mesh layer
126     QgsTriangularMesh mTriangularMesh;
127 
128     // copy from mesh layer
129     QgsRectangle mLayerExtent;
130 
131     // copy of the scalar dataset
132     QVector<double> mScalarDatasetValues;
133     QgsMeshDataBlock mScalarActiveFaceFlagValues;
134     QgsMeshDatasetGroupMetadata::DataType mScalarDataType = QgsMeshDatasetGroupMetadata::DataOnVertices;
135     double mScalarDatasetMinimum = std::numeric_limits<double>::quiet_NaN();
136     double mScalarDatasetMaximum = std::numeric_limits<double>::quiet_NaN();
137 
138     // copy of the vector dataset
139     QgsMeshDataBlock mVectorDatasetValues;
140     QVector<double> mVectorDatasetValuesMag;
141     double mVectorDatasetMagMinimum = std::numeric_limits<double>::quiet_NaN();
142     double mVectorDatasetMagMaximum = std::numeric_limits<double>::quiet_NaN();
143     double mVectorDatasetGroupMagMinimum = std::numeric_limits<double>::quiet_NaN();
144     double mVectorDatasetGroupMagMaximum = std::numeric_limits<double>::quiet_NaN();
145     QgsMeshDatasetGroupMetadata::DataType mVectorDataType = QgsMeshDatasetGroupMetadata::DataOnVertices;
146 
147     // copy of rendering settings
148     QgsMeshRendererSettings mRendererSettings;
149 
150     QList< QgsMapClippingRegion > mClippingRegions;
151 
152     // output screen size
153     QSize mOutputSize;
154 };
155 
156 
157 #endif // QGSMESHLAYERRENDERER_H
158