1 /***************************************************************************
2   qgspointcloud3dsymbol.h
3   ------------------------------
4   Date                 : November 2020
5   Copyright            : (C) 2020 by Nedjima Belgacem
6   Email                : belgacem dot nedjima at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #ifndef QGSPOINTCLOUD3DSYMBOL_H
17 #define QGSPOINTCLOUD3DSYMBOL_H
18 
19 #include "qgis_3d.h"
20 
21 #include <Qt3DRender/QMaterial>
22 
23 #include "qgsabstract3dsymbol.h"
24 #include "qgscolorrampshader.h"
25 #include "qgspointcloudlayer.h"
26 #include "qgscontrastenhancement.h"
27 #include "qgspointcloudclassifiedrenderer.h"
28 
29 /**
30  * \ingroup 3d
31  * \brief 3D symbol that draws point cloud geometries as 3D objects.
32  *
33  * \warning This is not considered stable API, and may change in future QGIS releases. It is
34  * exposed to the Python bindings as a tech preview only.
35  *
36  * \since QGIS 3.18
37  */
38 class _3D_EXPORT QgsPointCloud3DSymbol : public QgsAbstract3DSymbol SIP_ABSTRACT
39 {
40   public:
41 
42     /**
43      * How to render the point cloud
44      */
45     enum RenderingStyle
46     {
47       // Do not render anything
48       NoRendering = 0,
49       //! Render the point cloud with a single color
50       SingleColor,
51       //! Render the point cloud with a color ramp
52       ColorRamp,
53       //! Render the RGB colors of the point cloud
54       RgbRendering
55     };
56 
57     //! Constructor for QgsPointCloud3DSymbol
58     QgsPointCloud3DSymbol();
59     //! Destructor for QgsPointCloud3DSymbol
60     ~QgsPointCloud3DSymbol() override;
61 
type()62     QString type() const override { return "pointcloud"; }
63 
64     /**
65      * Returns a unique string identifier of the symbol type.
66      */
67     virtual QString symbolType() const = 0;
68 
69     /**
70      * Returns the point size of the point cloud
71      * \see setPointSize( float size )
72      */
pointSize()73     float pointSize() const { return mPointSize; }
74 
75     /**
76      * Sets the point size
77      * \see pointSize()
78      */
79     void setPointSize( float size );
80 
81     //! Returns the byte stride for the geometries used to for the vertex buffer
82     virtual unsigned int byteStride() = 0;
83     //! Used to fill material object with necessary QParameters (and consequently opengl uniforms)
84     virtual void fillMaterial( Qt3DRender::QMaterial *material ) = 0 SIP_SKIP;
85 
86   protected:
87     float mPointSize = 2.0;
88 };
89 
90 /**
91  * \ingroup 3d
92  * \brief 3D symbol that draws point cloud geometries as 3D objects.using one color
93  *
94  * \warning This is not considered stable API, and may change in future QGIS releases. It is
95  * exposed to the Python bindings as a tech preview only.
96  *
97  * \since QGIS 3.18
98  */
99 class _3D_EXPORT QgsSingleColorPointCloud3DSymbol : public QgsPointCloud3DSymbol
100 {
101   public:
102     //! Constructor for QgsSingleColorPointCloud3DSymbol
103     QgsSingleColorPointCloud3DSymbol();
104 
105     QString symbolType() const override;
106     QgsAbstract3DSymbol *clone() const override SIP_FACTORY;
107 
108     void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
109     void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
110 
111     /**
112     * Returns the color used by the renderer when using SingleColor rendering mode
113     * \see setSingleColor( QColor color )
114     */
singleColor()115     QColor singleColor() const { return mSingleColor; }
116 
117     /**
118     * Sets the color used by the renderer when using SingleColor rendering mode
119     * \see singleColor()
120     */
121     void setSingleColor( QColor color );
122 
byteStride()123     unsigned int byteStride() override { return 3 * sizeof( float ); }
124     void fillMaterial( Qt3DRender::QMaterial *material ) override SIP_SKIP;
125 
126 
127   private:
128     QColor mSingleColor = QColor( 0, 0, 255 );
129 };
130 
131 /**
132  * \ingroup 3d
133  * \brief 3D symbol that draws point cloud geometries as 3D objects.using color ramp shader
134  *
135  * \warning This is not considered stable API, and may change in future QGIS releases. It is
136  * exposed to the Python bindings as a tech preview only.
137  *
138  * \since QGIS 3.18
139  */
140 class _3D_EXPORT QgsColorRampPointCloud3DSymbol : public QgsPointCloud3DSymbol
141 {
142   public:
143     //! Constructor for QgsColorRampPointCloud3DSymbol
144     QgsColorRampPointCloud3DSymbol();
145 
146     QgsAbstract3DSymbol *clone() const override SIP_FACTORY;
147     QString symbolType() const override;
148 
149     void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
150     void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
151 
152     /**
153     * Returns the attribute used to select the color of the point cloud.
154     * \see setAttribute()
155     */
156     QString attribute() const;
157 
158     /**
159     * Sets the \a attribute used to select the color of the point cloud.
160     * \see attribute()
161     */
162     void setAttribute( const QString &attribute );
163 
164     /**
165     * Returns the color ramp shader used to render the color
166     * \see setColorRampShader( const QgsColorRampShader &colorRampShader )
167     */
168     QgsColorRampShader colorRampShader() const;
169 
170     /**
171      * Sets the color ramp shader used to render the point cloud
172      * \see colorRampShader()
173      */
174     void setColorRampShader( const QgsColorRampShader &colorRampShader );
175 
176     /**
177      * Returns the minimum value used when classifying colors in the color ramp shader
178      * \see setColorRampShaderMinMax( double min, double max )
179      */
colorRampShaderMin()180     double colorRampShaderMin() const { return mColorRampShaderMin; }
181 
182     /**
183      * Returns the maximum value used when classifying colors in the color ramp shader
184      * \see setColorRampShaderMinMax( double min, double max )
185      */
colorRampShaderMax()186     double colorRampShaderMax() const { return mColorRampShaderMax; }
187 
188     /**
189      * Sets the minimum and maximum values used when classifying colors in the color ramp shader
190      * \see colorRampShaderMin() colorRampShaderMax()
191      */
192     void setColorRampShaderMinMax( double min, double max );
193 
byteStride()194     unsigned int byteStride() override { return 4 * sizeof( float ); }
195     void fillMaterial( Qt3DRender::QMaterial *material ) override SIP_SKIP;
196 
197   private:
198     QString mRenderingParameter;
199     QgsColorRampShader mColorRampShader;
200     double mColorRampShaderMin = 0.0;
201     double mColorRampShaderMax = 1.0;
202 };
203 
204 /**
205  * \ingroup 3d
206  * \brief 3D symbol that draws point cloud geometries as 3D objects using RGB colors in the dataset
207  *
208  * \warning This is not considered stable API, and may change in future QGIS releases. It is
209  * exposed to the Python bindings as a tech preview only.
210  *
211  * \since QGIS 3.18
212  */
213 class _3D_EXPORT QgsRgbPointCloud3DSymbol : public QgsPointCloud3DSymbol
214 {
215   public:
216     //! Constructor for QgsRGBPointCloud3DSymbol
217     QgsRgbPointCloud3DSymbol();
218 
219     //! QgsRgbPointCloud3DSymbol cannot be copied - use clone() instead
220     QgsRgbPointCloud3DSymbol( const QgsRgbPointCloud3DSymbol &other ) = delete;
221 
222     //! QgsRgbPointCloud3DSymbol cannot be copied - use clone() instead
223     QgsRgbPointCloud3DSymbol &operator=( const QgsRgbPointCloud3DSymbol &other ) = delete;
224 
225     QString symbolType() const override;
226     QgsAbstract3DSymbol *clone() const override SIP_FACTORY;
227 
228     void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
229     void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
230 
byteStride()231     unsigned int byteStride() override { return 6 * sizeof( float ); }
232     void fillMaterial( Qt3DRender::QMaterial *material ) override SIP_SKIP;
233 
234     /**
235      * Returns the attribute to use for the red channel.
236      *
237      * \see greenAttribute()
238      * \see blueAttribute()
239      * \see setRedAttribute()
240      */
241     QString redAttribute() const;
242 
243     /**
244      * Sets the \a attribute to use for the red channel.
245      *
246      * \see setGreenAttribute()
247      * \see setBlueAttribute()
248      * \see redAttribute()
249      */
250     void setRedAttribute( const QString &attribute );
251 
252     /**
253      * Returns the attribute to use for the green channel.
254      *
255      * \see redAttribute()
256      * \see blueAttribute()
257      * \see setGreenAttribute()
258      */
259     QString greenAttribute() const;
260 
261     /**
262      * Sets the \a attribute to use for the green channel.
263      *
264      * \see setRedAttribute()
265      * \see setBlueAttribute()
266      * \see greenAttribute()
267      */
268     void setGreenAttribute( const QString &attribute );
269 
270     /**
271      * Returns the attribute to use for the blue channel.
272      *
273      * \see greenAttribute()
274      * \see redAttribute()
275      * \see setBlueAttribute()
276      */
277     QString blueAttribute() const;
278 
279     /**
280      * Sets the \a attribute to use for the blue channel.
281      *
282      * \see setRedAttribute()
283      * \see setGreenAttribute()
284      * \see blueAttribute()
285      */
286     void setBlueAttribute( const QString &attribute );
287 
288     /**
289      * Returns the contrast enhancement to use for the red channel.
290      *
291      * \see setRedContrastEnhancement()
292      * \see greenContrastEnhancement()
293      * \see blueContrastEnhancement()
294      */
295     QgsContrastEnhancement *redContrastEnhancement();
296 
297     /**
298      * Sets the contrast \a enhancement to use for the red channel.
299      *
300      * Ownership of \a enhancement is transferred.
301      *
302      * \see redContrastEnhancement()
303      * \see setGreenContrastEnhancement()
304      * \see setBlueContrastEnhancement()
305      */
306     void setRedContrastEnhancement( QgsContrastEnhancement *enhancement SIP_TRANSFER );
307 
308     /**
309      * Returns the contrast enhancement to use for the green channel.
310      *
311      * \see setGreenContrastEnhancement()
312      * \see redContrastEnhancement()
313      * \see blueContrastEnhancement()
314      */
315     QgsContrastEnhancement *greenContrastEnhancement();
316 
317     /**
318      * Sets the contrast \a enhancement to use for the green channel.
319      *
320      * Ownership of \a enhancement is transferred.
321      *
322      * \see greenContrastEnhancement()
323      * \see setRedContrastEnhancement()
324      * \see setBlueContrastEnhancement()
325      */
326     void setGreenContrastEnhancement( QgsContrastEnhancement *enhancement SIP_TRANSFER );
327 
328     /**
329      * Returns the contrast enhancement to use for the blue channel.
330      *
331      * \see setBlueContrastEnhancement()
332      * \see redContrastEnhancement()
333      * \see greenContrastEnhancement()
334      */
335     QgsContrastEnhancement *blueContrastEnhancement();
336 
337     /**
338      * Sets the contrast \a enhancement to use for the blue channel.
339      *
340      * Ownership of \a enhancement is transferred.
341      *
342      * \see blueContrastEnhancement()
343      * \see setRedContrastEnhancement()
344      * \see setGreenContrastEnhancement()
345      */
346     void setBlueContrastEnhancement( QgsContrastEnhancement *enhancement SIP_TRANSFER );
347 
348   private:
349 
350 #ifdef SIP_RUN
351     QgsRgbPointCloud3DSymbol( const QgsRgbPointCloud3DSymbol &other );
352 #endif
353 
354     QString mRedAttribute = QStringLiteral( "Red" );
355     QString mGreenAttribute = QStringLiteral( "Green" );
356     QString mBlueAttribute = QStringLiteral( "Blue" );
357 
358     std::unique_ptr< QgsContrastEnhancement > mRedContrastEnhancement;
359     std::unique_ptr< QgsContrastEnhancement > mGreenContrastEnhancement;
360     std::unique_ptr< QgsContrastEnhancement > mBlueContrastEnhancement;
361 
362 };
363 
364 /**
365  * \ingroup 3d
366  * \brief 3D symbol that draws point cloud geometries as 3D objects using classification of the dataset
367  *
368  * \warning This is not considered stable API, and may change in future QGIS releases. It is
369  * exposed to the Python bindings as a tech preview only.
370  *
371  * \since QGIS 3.18
372  */
373 class _3D_EXPORT QgsClassificationPointCloud3DSymbol : public QgsPointCloud3DSymbol
374 {
375   public:
376     //! Constructor for QgsClassificationPointCloud3DSymbol
377     QgsClassificationPointCloud3DSymbol();
378 
379     QgsAbstract3DSymbol *clone() const override SIP_FACTORY;
380     QString symbolType() const override;
381 
382     void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
383     void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
384 
385     /**
386     * Returns the attribute used to select the color of the point cloud.
387     * \see setAttribute()
388     */
389     QString attribute() const;
390 
391     /**
392     * Sets the \a attribute used to select the color of the point cloud.
393     * \see attribute()
394     */
395     void setAttribute( const QString &attribute );
396 
397     /**
398      * Returns the list of categories of the classification
399      * \see setCategoriesList()
400      */
categoriesList()401     QgsPointCloudCategoryList categoriesList() const { return mCategoriesList; }
402 
403     /**
404      * Sets the list of categories of the classification
405      * \see categoriesList()
406      */
407     void setCategoriesList( const QgsPointCloudCategoryList &categories );
408 
409     /**
410      * Gets the list of categories of the classification that should not be rendered
411      * \see categoriesList() setCategoriesList()
412      */
413     QgsPointCloudCategoryList getFilteredOutCategories() const;
414 
byteStride()415     unsigned int byteStride() override { return 4 * sizeof( float ); }
416     void fillMaterial( Qt3DRender::QMaterial *material ) override SIP_SKIP;
417 
418   private:
419     QString mRenderingParameter;
420     QgsPointCloudCategoryList mCategoriesList;
421 
422     QgsColorRampShader colorRampShader() const;
423 };
424 
425 #endif // QGSPOINTCLOUD3DSYMBOL_H
426