QGIS API Documentation 4.1.0-Master (31622b25bb0)
Loading...
Searching...
No Matches
qgspointcloud3dsymbol.cpp
Go to the documentation of this file.
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
17
18#include "qgs3dutils.h"
19#include "qgscolorramptexture.h"
20#include "qgscolorutils.h"
21#include "qgsmaterial.h"
22
23#include <QString>
24#include <Qt3DRender/QParameter>
25#include <Qt3DRender/QTexture>
26
27using namespace Qt::StringLiterals;
28
29// QgsPointCloud3DSymbol
30
31
35
38
40{
41 mPointSize = size;
42}
43
48
50{
51 mRenderAsTriangles = asTriangles;
52}
53
58
63
68
73
78
83
88
93
94void QgsPointCloud3DSymbol::writeBaseXml( QDomElement &elem, const QgsReadWriteContext &context ) const
95{
96 Q_UNUSED( context )
97
98 elem.setAttribute( u"point-size"_s, mPointSize );
99 elem.setAttribute( u"render-as-triangles"_s, mRenderAsTriangles ? 1 : 0 );
100 elem.setAttribute( u"horizontal-triangle-filter"_s, mHorizontalTriangleFilter ? 1 : 0 );
101 elem.setAttribute( u"horizontal-filter-threshold"_s, mHorizontalFilterThreshold );
102 elem.setAttribute( u"vertical-triangle-filter"_s, mVerticalTriangleFilter ? 1 : 0 );
103 elem.setAttribute( u"vertical-filter-threshold"_s, mVerticalFilterThreshold );
104}
105
106void QgsPointCloud3DSymbol::readBaseXml( const QDomElement &elem, const QgsReadWriteContext &context )
107{
108 Q_UNUSED( context )
109
110 mPointSize = elem.attribute( u"point-size"_s, u"3.0"_s ).toFloat();
111 mRenderAsTriangles = elem.attribute( u"render-as-triangles"_s, u"0"_s ).toInt() == 1;
112 mHorizontalTriangleFilter = elem.attribute( u"horizontal-triangle-filter"_s, u"0"_s ).toInt() == 1;
113 mHorizontalFilterThreshold = elem.attribute( u"horizontal-filter-threshold"_s, u"10.0"_s ).toFloat();
114 mVerticalTriangleFilter = elem.attribute( u"vertical-triangle-filter"_s, u"0"_s ).toInt() == 1;
115 mVerticalFilterThreshold = elem.attribute( u"vertical-filter-threshold"_s, u"10.0"_s ).toFloat();
116}
117
129
131{
132 Q_UNUSED( materialSettings );
133 throw QgsNotSupportedException( u"QgsPointCloud3DSymbol does not support material settings"_s );
134}
135
136
137// QgsSingleColorPointCloud3DSymbol
138
142
144{
145 return u"single-color"_s;
146}
147
149{
151 result->mSingleColor = mSingleColor;
152 copyBaseSettings( result );
153 return result;
154}
155
156void QgsSingleColorPointCloud3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
157{
158 Q_UNUSED( context )
159
160 writeBaseXml( elem, context );
161 elem.setAttribute( u"single-color"_s, QgsColorUtils::colorToString( mSingleColor ) );
162}
163
164void QgsSingleColorPointCloud3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
165{
166 Q_UNUSED( context )
167
168 readBaseXml( elem, context );
169 mSingleColor = QgsColorUtils::colorFromString( elem.attribute( u"single-color"_s, u"0,0,255"_s ) );
170}
171
173{
174 mSingleColor = color;
175}
176
178{
179 Qt3DRender::QParameter *pointSizeParameter = new Qt3DRender::QParameter( "u_pointSize", QVariant::fromValue( mPointSize ) );
180 mat->addParameter( pointSizeParameter );
181 const QColor linearColor = Qgs3DUtils::srgbToLinear( mSingleColor );
182 Qt3DRender::QParameter *singleColorParameter = new Qt3DRender::QParameter( "u_singleColor", QVector3D( linearColor.redF(), linearColor.greenF(), linearColor.blueF() ) );
183 mat->addParameter( singleColorParameter );
184}
185
186// QgsColorRampPointCloud3DSymbol
187
191
193{
195 result->mRenderingParameter = mRenderingParameter;
196 result->mColorRampShader = mColorRampShader;
197 result->mColorRampShaderMin = mColorRampShaderMin;
198 result->mColorRampShaderMax = mColorRampShaderMax;
199 copyBaseSettings( result );
200 return result;
201}
202
204{
205 return u"color-ramp"_s;
206}
207
208void QgsColorRampPointCloud3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
209{
210 Q_UNUSED( context )
211
212 writeBaseXml( elem, context );
213 elem.setAttribute( u"rendering-parameter"_s, mRenderingParameter );
214 elem.setAttribute( u"color-ramp-shader-min"_s, mColorRampShaderMin );
215 elem.setAttribute( u"color-ramp-shader-max"_s, mColorRampShaderMax );
216 QDomDocument doc = elem.ownerDocument();
217 const QDomElement elemColorRampShader = mColorRampShader.writeXml( doc );
218 elem.appendChild( elemColorRampShader );
219}
220
221void QgsColorRampPointCloud3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
222{
223 Q_UNUSED( context )
224
225 readBaseXml( elem, context );
226 mRenderingParameter = elem.attribute( "rendering-parameter", QString() );
227 mColorRampShaderMin = elem.attribute( u"color-ramp-shader-min"_s, u"0.0"_s ).toDouble();
228 mColorRampShaderMax = elem.attribute( u"color-ramp-shader-max"_s, u"1.0"_s ).toDouble();
229 mColorRampShader.readXml( elem );
230}
231
233{
234 return mRenderingParameter;
235}
236
237void QgsColorRampPointCloud3DSymbol::setAttribute( const QString &parameter )
238{
239 mRenderingParameter = parameter;
240}
241
243{
244 return mColorRampShader;
245}
246
251
253{
254 mColorRampShaderMin = min;
255 mColorRampShaderMax = max;
256}
257
259{
260 Qt3DRender::QParameter *pointSizeParameter = new Qt3DRender::QParameter( "u_pointSize", QVariant::fromValue( mPointSize ) );
261 mat->addParameter( pointSizeParameter );
262 // Create the texture to pass the color ramp
263 Qt3DRender::QTexture1D *colorRampTexture = nullptr;
264 if ( mColorRampShader.colorRampItemList().count() > 0 )
265 {
266 colorRampTexture = new Qt3DRender::QTexture1D( mat );
267 colorRampTexture->addTextureImage( new QgsColorRampTexture( mColorRampShader, 1 ) );
268 colorRampTexture->setMinificationFilter( Qt3DRender::QTexture1D::Linear );
269 colorRampTexture->setMagnificationFilter( Qt3DRender::QTexture1D::Linear );
270 // note -- this texture is an exception, we do NOT set it to srgb format as we do NOT want
271 // it linearised before sampling. That is because we need to do the interpolation on the ramp
272 // in SRGB color space. The shader converts the result after sampling the ramp to linear.
273 }
274
275 // Parameters
276 Qt3DRender::QParameter *colorRampTextureParameter = new Qt3DRender::QParameter( "u_colorRampTexture", colorRampTexture );
277 mat->addParameter( colorRampTextureParameter );
278 Qt3DRender::QParameter *colorRampCountParameter = new Qt3DRender::QParameter( "u_colorRampCount", mColorRampShader.colorRampItemList().count() );
279 mat->addParameter( colorRampCountParameter );
280 const Qgis::ShaderInterpolationMethod colorRampType = mColorRampShader.colorRampType();
281 Qt3DRender::QParameter *colorRampTypeParameter = new Qt3DRender::QParameter( "u_colorRampType", static_cast<int>( colorRampType ) );
282 mat->addParameter( colorRampTypeParameter );
283}
284
285// QgsRgbPointCloud3DSymbol
286
290
292{
293 return u"rgb"_s;
294}
295
297{
299 result->mRedAttribute = mRedAttribute;
300 result->mGreenAttribute = mGreenAttribute;
301 result->mBlueAttribute = mBlueAttribute;
302
303 if ( mRedContrastEnhancement )
304 {
305 result->setRedContrastEnhancement( new QgsContrastEnhancement( *mRedContrastEnhancement ) );
306 }
307 if ( mGreenContrastEnhancement )
308 {
309 result->setGreenContrastEnhancement( new QgsContrastEnhancement( *mGreenContrastEnhancement ) );
310 }
311 if ( mBlueContrastEnhancement )
312 {
313 result->setBlueContrastEnhancement( new QgsContrastEnhancement( *mBlueContrastEnhancement ) );
314 }
315 copyBaseSettings( result );
316 return result;
317}
318
319void QgsRgbPointCloud3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
320{
321 Q_UNUSED( context )
322
323 writeBaseXml( elem, context );
324
325 elem.setAttribute( u"red"_s, mRedAttribute );
326 elem.setAttribute( u"green"_s, mGreenAttribute );
327 elem.setAttribute( u"blue"_s, mBlueAttribute );
328
329 QDomDocument doc = elem.ownerDocument();
330
331 //contrast enhancement
332 if ( mRedContrastEnhancement )
333 {
334 QDomElement redContrastElem = doc.createElement( u"redContrastEnhancement"_s );
335 mRedContrastEnhancement->writeXml( doc, redContrastElem );
336 elem.appendChild( redContrastElem );
337 }
338 if ( mGreenContrastEnhancement )
339 {
340 QDomElement greenContrastElem = doc.createElement( u"greenContrastEnhancement"_s );
341 mGreenContrastEnhancement->writeXml( doc, greenContrastElem );
342 elem.appendChild( greenContrastElem );
343 }
344 if ( mBlueContrastEnhancement )
345 {
346 QDomElement blueContrastElem = doc.createElement( u"blueContrastEnhancement"_s );
347 mBlueContrastEnhancement->writeXml( doc, blueContrastElem );
348 elem.appendChild( blueContrastElem );
349 }
350}
351
352void QgsRgbPointCloud3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
353{
354 Q_UNUSED( context )
355
356 readBaseXml( elem, context );
357
358 setRedAttribute( elem.attribute( u"red"_s, u"Red"_s ) );
359 setGreenAttribute( elem.attribute( u"green"_s, u"Green"_s ) );
360 setBlueAttribute( elem.attribute( u"blue"_s, u"Blue"_s ) );
361
362 //contrast enhancements
364 const QDomElement redContrastElem = elem.firstChildElement( u"redContrastEnhancement"_s );
365 if ( !redContrastElem.isNull() )
366 {
368 redContrastEnhancement->readXml( redContrastElem );
370 }
371
373 const QDomElement greenContrastElem = elem.firstChildElement( u"greenContrastEnhancement"_s );
374 if ( !greenContrastElem.isNull() )
375 {
377 greenContrastEnhancement->readXml( greenContrastElem );
379 }
380
382 const QDomElement blueContrastElem = elem.firstChildElement( u"blueContrastEnhancement"_s );
383 if ( !blueContrastElem.isNull() )
384 {
386 blueContrastEnhancement->readXml( blueContrastElem );
388 }
389}
390
392{
393 Qt3DRender::QParameter *pointSizeParameter = new Qt3DRender::QParameter( "u_pointSize", QVariant::fromValue( mPointSize ) );
394 mat->addParameter( pointSizeParameter );
395}
396
397
399{
400 return mRedAttribute;
401}
402
404{
405 mRedAttribute = redAttribute;
406}
407
409{
410 return mGreenAttribute;
411}
412
414{
415 mGreenAttribute = greenAttribute;
416}
417
419{
420 return mBlueAttribute;
421}
422
424{
425 mBlueAttribute = blueAttribute;
426}
427
429{
430 return mRedContrastEnhancement.get();
431}
432
434{
435 mRedContrastEnhancement.reset( enhancement );
436}
437
439{
440 return mGreenContrastEnhancement.get();
441}
442
444{
445 mGreenContrastEnhancement.reset( enhancement );
446}
447
449{
450 return mBlueContrastEnhancement.get();
451}
452
454{
455 mBlueContrastEnhancement.reset( enhancement );
456}
457
458// QgsClassificationPointCloud3DSymbol
459
460
464
466{
468 result->mRenderingParameter = mRenderingParameter;
469 result->mCategoriesList = mCategoriesList;
470 copyBaseSettings( result );
471 return result;
472}
473
475{
476 return u"classification"_s;
477}
478
479void QgsClassificationPointCloud3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
480{
481 Q_UNUSED( context )
482 QDomDocument doc = elem.ownerDocument();
483
484 writeBaseXml( elem, context );
485
486 elem.setAttribute( u"rendering-parameter"_s, mRenderingParameter );
487
488 // categories
489 QDomElement catsElem = doc.createElement( u"categories"_s );
490 for ( const QgsPointCloudCategory &category : mCategoriesList )
491 {
492 QDomElement catElem = doc.createElement( u"category"_s );
493 catElem.setAttribute( u"value"_s, QString::number( category.value() ) );
494 catElem.setAttribute( u"pointSize"_s, category.pointSize() );
495 catElem.setAttribute( u"label"_s, category.label() );
496 catElem.setAttribute( u"color"_s, QgsColorUtils::colorToString( category.color() ) );
497 catElem.setAttribute( u"render"_s, category.renderState() ? "true" : "false" );
498 catsElem.appendChild( catElem );
499 }
500 elem.appendChild( catsElem );
501}
502
503void QgsClassificationPointCloud3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
504{
505 Q_UNUSED( context )
506
507 readBaseXml( elem, context );
508 mRenderingParameter = elem.attribute( "rendering-parameter", QString() );
509
510 const QDomElement catsElem = elem.firstChildElement( u"categories"_s );
511 if ( !catsElem.isNull() )
512 {
513 mCategoriesList.clear();
514 QDomElement catElem = catsElem.firstChildElement();
515 while ( !catElem.isNull() )
516 {
517 if ( catElem.tagName() == "category"_L1 )
518 {
519 const int value = catElem.attribute( u"value"_s ).toInt();
520 const double size = catElem.attribute( u"pointSize"_s, u"0"_s ).toDouble();
521 const QString label = catElem.attribute( u"label"_s );
522 const bool render = catElem.attribute( u"render"_s ) != "false"_L1;
523 const QColor color = QgsColorUtils::colorFromString( catElem.attribute( u"color"_s ) );
524 mCategoriesList.append( QgsPointCloudCategory( value, color, label, render, size ) );
525 }
526 catElem = catElem.nextSiblingElement();
527 }
528 }
529}
530
532{
533 return mRenderingParameter;
534}
535
537{
538 mRenderingParameter = attribute;
539}
540
542{
543 mCategoriesList = categories;
544}
545
547{
548 QgsPointCloudCategoryList filteredOut;
549 for ( const QgsPointCloudCategory &category : mCategoriesList )
550 {
551 if ( !category.renderState() )
552 filteredOut.push_back( category );
553 }
554 return filteredOut;
555}
556
557QgsColorRampShader QgsClassificationPointCloud3DSymbol::colorRampShader() const
558{
559 QgsColorRampShader colorRampShader;
562 QList<QgsColorRampShader::ColorRampItem> colorRampItemList;
563 for ( const QgsPointCloudCategory &category : mCategoriesList )
564 {
565 const QColor color = category.color();
566 const QgsColorRampShader::ColorRampItem item( category.value(), color, category.label() );
567 colorRampItemList.push_back( item );
568 }
569 colorRampShader.setColorRampItemList( colorRampItemList );
570 return colorRampShader;
571}
572
573
575{
576 const QgsColorRampShader mColorRampShader = colorRampShader();
577 // Create the texture to pass the color ramp
578 Qt3DRender::QTexture1D *colorRampTexture = nullptr;
579 if ( mColorRampShader.colorRampItemList().count() > 0 )
580 {
581 colorRampTexture = new Qt3DRender::QTexture1D( mat );
582 colorRampTexture->addTextureImage( new QgsColorRampTexture( mColorRampShader, 1 ) );
583 colorRampTexture->setMinificationFilter( Qt3DRender::QTexture1D::Linear );
584 colorRampTexture->setMagnificationFilter( Qt3DRender::QTexture1D::Linear );
585 // note -- this texture is an exception, we do NOT set it to srgb format as we do NOT want
586 // it linearised before sampling. That is because we need to do the interpolation on the ramp
587 // in SRGB color space. The shader converts the result after sampling the ramp to linear.
588 }
589
590 // Parameters
591 Qt3DRender::QParameter *colorRampTextureParameter = new Qt3DRender::QParameter( "u_colorRampTexture", colorRampTexture );
592 mat->addParameter( colorRampTextureParameter );
593 Qt3DRender::QParameter *colorRampCountParameter = new Qt3DRender::QParameter( "u_colorRampCount", mColorRampShader.colorRampItemList().count() );
594 mat->addParameter( colorRampCountParameter );
595 const Qgis::ShaderInterpolationMethod colorRampType = mColorRampShader.colorRampType();
596 Qt3DRender::QParameter *colorRampTypeParameter = new Qt3DRender::QParameter( "u_colorRampType", static_cast<int>( colorRampType ) );
597 mat->addParameter( colorRampTypeParameter );
598}
ShaderInterpolationMethod
Color ramp shader interpolation methods.
Definition qgis.h:1544
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
Definition qgis.h:1547
@ Continuous
Uses breaks from color palette.
Definition qgis.h:1560
@ UnknownDataType
Unknown or unspecified type.
Definition qgis.h:394
static QColor srgbToLinear(const QColor &color)
Converts a SRGB color to a linear color.
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
virtual void copyBaseSettings(QgsAbstract3DSymbol *destination) const
Copies base class settings from this object to a destination object.
Abstract base class for material settings.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
void fillMaterial(QgsMaterial *material) override SIP_SKIP
Used to fill material object with necessary QParameters (and consequently opengl uniforms).
QString attribute() const
Returns the attribute used to select the color of the point cloud.
void setCategoriesList(const QgsPointCloudCategoryList &categories)
Sets the list of categories of the classification.
QgsPointCloudCategoryList getFilteredOutCategories() const
Gets the list of categories of the classification that should not be rendered.
void setAttribute(const QString &attribute)
Sets the attribute used to select the color of the point cloud.
QString symbolType() const override
Returns a unique string identifier of the symbol type.
QgsClassificationPointCloud3DSymbol * clone() const override SIP_FACTORY
QgsColorRampPointCloud3DSymbol * clone() const override SIP_FACTORY
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
void setAttribute(const QString &attribute)
Sets the attribute used to select the color of the point cloud.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
void setColorRampShaderMinMax(double min, double max)
Sets the minimum and maximum values used when classifying colors in the color ramp shader.
QString attribute() const
Returns the attribute used to select the color of the point cloud.
QString symbolType() const override
Returns a unique string identifier of the symbol type.
QgsColorRampShader colorRampShader() const
Returns the color ramp shader used to render the color.
void setColorRampShader(const QgsColorRampShader &colorRampShader)
Sets the color ramp shader used to render the point cloud.
void fillMaterial(QgsMaterial *material) override SIP_SKIP
Used to fill material object with necessary QParameters (and consequently opengl uniforms).
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
Qgis::ShaderInterpolationMethod colorRampType() const
Returns the color ramp interpolation method.
void setClassificationMode(Qgis::ShaderClassificationMethod classificationMode)
Sets the classification mode.
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Returns the custom color map.
void setColorRampType(Qgis::ShaderInterpolationMethod colorRampType)
Sets the color ramp interpolation method.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
Handles contrast enhancement and clipping.
Base class for all materials used within QGIS 3D views.
Definition qgsmaterial.h:40
Custom exception class which is raised when an operation is not supported.
bool verticalTriangleFilter() const
Returns whether triangles are filtered by vertical height for rendering.
float verticalFilterThreshold() const
Returns the threshold vertical height value for filtering triangles.
void setVerticalTriangleFilter(bool verticalTriangleFilter)
Sets whether triangles are filtered by vertical height for rendering.
void setHorizontalFilterThreshold(float horizontalFilterThreshold)
Sets the threshold horizontal size value for filtering triangles.
void setRenderAsTriangles(bool asTriangles)
Sets whether points are triangulated to render solid surface.
float horizontalFilterThreshold() const
Returns the threshold horizontal size value for filtering triangles.
void copyBaseSettings(QgsAbstract3DSymbol *destination) const override
bool renderAsTriangles() const
Returns whether points are triangulated to render solid surface.
void setPointSize(float size)
Sets the point size.
void writeBaseXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes symbol configuration of this class to the given DOM element.
void setHorizontalTriangleFilter(bool horizontalTriangleFilter)
Sets whether whether triangles are filtered by horizontal size for rendering.
bool horizontalTriangleFilter() const
Returns whether triangles are filtered by horizontal size for rendering.
void readBaseXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads symbol configuration of this class from the given DOM element.
void setMaterialSettings(QgsAbstractMaterialSettings *materialSettings SIP_TRANSFER) override SIP_SKIP
This function has no effect.
void setVerticalFilterThreshold(float verticalFilterThreshold)
Sets the threshold vertical height value for filtering triangles.
Represents an individual category (class) from a QgsPointCloudClassifiedRenderer.
A container for the context for various read/write operations on objects.
QString blueAttribute() const
Returns the attribute to use for the blue channel.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
void setBlueAttribute(const QString &attribute)
Sets the attribute to use for the blue channel.
void setGreenContrastEnhancement(QgsContrastEnhancement *enhancement SIP_TRANSFER)
Sets the contrast enhancement to use for the green channel.
QString greenAttribute() const
Returns the attribute to use for the green channel.
QgsContrastEnhancement * blueContrastEnhancement()
Returns the contrast enhancement to use for the blue channel.
void setGreenAttribute(const QString &attribute)
Sets the attribute to use for the green channel.
QString redAttribute() const
Returns the attribute to use for the red channel.
void setBlueContrastEnhancement(QgsContrastEnhancement *enhancement SIP_TRANSFER)
Sets the contrast enhancement to use for the blue channel.
QgsContrastEnhancement * greenContrastEnhancement()
Returns the contrast enhancement to use for the green channel.
QgsContrastEnhancement * redContrastEnhancement()
Returns the contrast enhancement to use for the red channel.
void setRedContrastEnhancement(QgsContrastEnhancement *enhancement SIP_TRANSFER)
Sets the contrast enhancement to use for the red channel.
QString symbolType() const override
Returns a unique string identifier of the symbol type.
QgsRgbPointCloud3DSymbol * clone() const override SIP_FACTORY
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
void fillMaterial(QgsMaterial *material) override SIP_SKIP
Used to fill material object with necessary QParameters (and consequently opengl uniforms).
void setRedAttribute(const QString &attribute)
Sets the attribute to use for the red channel.
QString symbolType() const override
Returns a unique string identifier of the symbol type.
void fillMaterial(QgsMaterial *material) override SIP_SKIP
Used to fill material object with necessary QParameters (and consequently opengl uniforms).
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
QgsSingleColorPointCloud3DSymbol * clone() const override SIP_FACTORY
void setSingleColor(QColor color)
Sets the color used by the renderer when using SingleColor rendering mode.
QList< QgsPointCloudCategory > QgsPointCloudCategoryList