QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsgoochmaterialsettings.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgoochmaterialsettings.cpp
3  --------------------------------------
4  Date : July 2020
5  Copyright : (C) 2020 by Nyall Dawson
6  Email : nyall dot dawson 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 "qgssymbollayerutils.h"
19 #include "qgslinematerial_p.h"
20 #include <Qt3DExtras/QGoochMaterial>
21 #include <Qt3DRender/QAttribute>
22 #include <Qt3DRender/QBuffer>
23 #include <Qt3DRender/QGeometry>
24 #include <Qt3DRender/QParameter>
25 #include <Qt3DRender/QEffect>
26 #include <Qt3DRender/QTechnique>
27 #include <Qt3DRender/QGraphicsApiFilter>
28 #include <QUrl>
29 
31 {
32  return QStringLiteral( "gooch" );
33 }
34 
36 {
37  return new QgsGoochMaterialSettings();
38 }
39 
41 {
42  switch ( technique )
43  {
48  return true;
49 
53  return false;
54  }
55  return false;
56 }
57 
59 {
60  return new QgsGoochMaterialSettings( *this );
61 }
62 
63 void QgsGoochMaterialSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
64 {
65  mWarm = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "warm" ), QStringLiteral( "107,0,107" ) ) );
66  mCool = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "cool" ), QStringLiteral( "255,130,0" ) ) );
67  mDiffuse = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "diffuse" ), QStringLiteral( "178,178,178" ) ) );
68  mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ) ) );
69  mShininess = elem.attribute( QStringLiteral( "shininess2" ), QStringLiteral( "100" ) ).toFloat();
70  mAlpha = elem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "0.25" ) ).toFloat();
71  mBeta = elem.attribute( QStringLiteral( "beta" ), QStringLiteral( "0.5" ) ).toFloat();
72 
73  QgsAbstractMaterialSettings::readXml( elem, context );
74 }
75 
76 void QgsGoochMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
77 {
78  elem.setAttribute( QStringLiteral( "warm" ), QgsSymbolLayerUtils::encodeColor( mWarm ) );
79  elem.setAttribute( QStringLiteral( "cool" ), QgsSymbolLayerUtils::encodeColor( mCool ) );
80  elem.setAttribute( QStringLiteral( "diffuse" ), QgsSymbolLayerUtils::encodeColor( mDiffuse ) );
81  elem.setAttribute( QStringLiteral( "specular" ), QgsSymbolLayerUtils::encodeColor( mSpecular ) );
82  elem.setAttribute( QStringLiteral( "shininess2" ), mShininess );
83  elem.setAttribute( QStringLiteral( "alpha" ), mAlpha );
84  elem.setAttribute( QStringLiteral( "beta" ), mBeta );
85 
87 }
88 
89 QMap<QString, QString> QgsGoochMaterialSettings::toExportParameters() const
90 {
91  return QMap<QString, QString>();
92 }
93 
95 {
96  switch ( technique )
97  {
102  {
103  if ( dataDefinedProperties().hasActiveProperties() )
104  return dataDefinedMaterial();
105  Qt3DExtras::QGoochMaterial *material = new Qt3DExtras::QGoochMaterial;
106  material->setDiffuse( mDiffuse );
107  material->setWarm( mWarm );
108  material->setCool( mCool );
109 
110  material->setSpecular( mSpecular );
111  material->setShininess( mShininess );
112  material->setAlpha( mAlpha );
113  material->setBeta( mBeta );
114 
115  if ( context.isSelected() )
116  {
117  // update the material with selection colors
118  material->setDiffuse( context.selectionColor() );
119  }
120  return material;
121  }
122 
126  return nullptr;
127  }
128  return nullptr;
129 }
130 
131 void QgsGoochMaterialSettings::addParametersToEffect( Qt3DRender::QEffect * ) const
132 {
133 }
134 
136 {
137 
138  const QColor diffuse = dataDefinedProperties().valueAsColor( Diffuse, expressionContext, mDiffuse );
139  const QColor warm = dataDefinedProperties().valueAsColor( Warm, expressionContext, mWarm );
140  const QColor cool = dataDefinedProperties().valueAsColor( Cool, expressionContext, mCool );
141  const QColor specular = dataDefinedProperties().valueAsColor( Specular, expressionContext, mSpecular );
142 
143 
144  QByteArray array;
145  array.resize( sizeof( unsigned char ) * 12 );
146  unsigned char *fptr = reinterpret_cast<unsigned char *>( array.data() );
147 
148  *fptr++ = static_cast<unsigned char>( diffuse.red() );
149  *fptr++ = static_cast<unsigned char>( diffuse.green() );
150  *fptr++ = static_cast<unsigned char>( diffuse.blue() );
151 
152  *fptr++ = static_cast<unsigned char>( warm.red() );
153  *fptr++ = static_cast<unsigned char>( warm.green() );
154  *fptr++ = static_cast<unsigned char>( warm.blue() );
155 
156  *fptr++ = static_cast<unsigned char>( cool.red() );
157  *fptr++ = static_cast<unsigned char>( cool.green() );
158  *fptr++ = static_cast<unsigned char>( cool.blue() );
159 
160  *fptr++ = static_cast<unsigned char>( specular.red() );
161  *fptr++ = static_cast<unsigned char>( specular.green() );
162  *fptr++ = static_cast<unsigned char>( specular.blue() );
163 
164  return array;
165 }
166 
168 {
169  return 12 * sizeof( unsigned char );
170 }
171 
172 void QgsGoochMaterialSettings::applyDataDefinedToGeometry( Qt3DRender::QGeometry *geometry, int vertexCount, const QByteArray &data ) const
173 {
174  Qt3DRender::QBuffer *dataBuffer = new Qt3DRender::QBuffer( geometry );
175 
176  Qt3DRender::QAttribute *diffuseAttribute = new Qt3DRender::QAttribute( geometry );
177  diffuseAttribute->setName( QStringLiteral( "dataDefinedDiffuseColor" ) );
178  diffuseAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedByte );
179  diffuseAttribute->setVertexSize( 3 );
180  diffuseAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
181  diffuseAttribute->setBuffer( dataBuffer );
182  diffuseAttribute->setByteStride( 12 * sizeof( unsigned char ) );
183  diffuseAttribute->setByteOffset( 0 );
184  diffuseAttribute->setCount( vertexCount );
185  geometry->addAttribute( diffuseAttribute );
186 
187  Qt3DRender::QAttribute *warmAttribute = new Qt3DRender::QAttribute( geometry );
188  warmAttribute->setName( QStringLiteral( "dataDefinedWarmColor" ) );
189  warmAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedByte );
190  warmAttribute->setVertexSize( 3 );
191  warmAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
192  warmAttribute->setBuffer( dataBuffer );
193  warmAttribute->setByteStride( 12 * sizeof( unsigned char ) );
194  warmAttribute->setByteOffset( 3 * sizeof( unsigned char ) );
195  warmAttribute->setCount( vertexCount );
196  geometry->addAttribute( warmAttribute
197  );
198 
199  Qt3DRender::QAttribute *coolAttribute = new Qt3DRender::QAttribute( geometry );
200  coolAttribute->setName( QStringLiteral( "dataDefinedCoolColor" ) );
201  coolAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedByte );
202  coolAttribute->setVertexSize( 3 );
203  coolAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
204  coolAttribute->setBuffer( dataBuffer );
205  coolAttribute->setByteStride( 12 * sizeof( unsigned char ) );
206  coolAttribute->setByteOffset( 6 * sizeof( unsigned char ) );
207  coolAttribute->setCount( vertexCount );
208  geometry->addAttribute( coolAttribute );
209 
210 
211  Qt3DRender::QAttribute *specularAttribute = new Qt3DRender::QAttribute( geometry );
212  specularAttribute->setName( QStringLiteral( "dataDefinedSpecularColor" ) );
213  specularAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedByte );
214  specularAttribute->setVertexSize( 3 );
215  specularAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
216  specularAttribute->setBuffer( dataBuffer );
217  specularAttribute->setByteStride( 12 * sizeof( unsigned char ) );
218  specularAttribute->setByteOffset( 9 * sizeof( unsigned char ) );
219  specularAttribute->setCount( vertexCount );
220  geometry->addAttribute( specularAttribute );
221 
222  dataBuffer->setData( data );
223 }
224 
225 Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const
226 {
227  Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial;
228 
229  Qt3DRender::QEffect *eff = new Qt3DRender::QEffect( material );
230 
231  Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
232  technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
233  technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
234  technique->graphicsApiFilter()->setMajorVersion( 3 );
235  technique->graphicsApiFilter()->setMinorVersion( 3 );
236  Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey();
237  filterKey->setName( QStringLiteral( "renderingStyle" ) );
238  filterKey->setValue( QStringLiteral( "forward" ) );
239  technique->addFilterKey( filterKey );
240 
241  Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
242  Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram();
243 
244  //Load shader programs
245  const QUrl urlVert( QStringLiteral( "qrc:/shaders/goochDataDefined.vert" ) );
246  shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
247  const QUrl urlFrag( QStringLiteral( "qrc:/shaders/goochDataDefined.frag" ) );
248  shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) );
249 
250  renderPass->setShaderProgram( shaderProgram );
251  technique->addRenderPass( renderPass );
252 
253  technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "shininess" ), mShininess ) );
254  technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "alpha" ), mAlpha ) );
255  technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "beta" ), mBeta ) );
256 
257  eff->addTechnique( technique );
258  material->setEffect( eff );
259 
260  return material;
261 }
QgsGoochMaterialSettings::specular
QColor specular() const
Returns specular color component.
Definition: qgsgoochmaterialsettings.h:68
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
QgsGoochMaterialSettings::toMaterial
Qt3DRender::QMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QMaterial object representing the material settings.
Definition: qgsgoochmaterialsettings.cpp:94
qgsgoochmaterialsettings.h
QgsSymbolLayerUtils::encodeColor
static QString encodeColor(const QColor &color)
Definition: qgssymbollayerutils.cpp:64
QgsGoochMaterialSettings::cool
QColor cool() const
Returns cool color component.
Definition: qgsgoochmaterialsettings.h:63
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
qgssymbollayerutils.h
QgsAbstractMaterialSettings::Specular
@ Specular
Specular color.
Definition: qgsabstractmaterialsettings.h:195
QgsGoochMaterialSettings::toExportParameters
QMap< QString, QString > toExportParameters() const override
Returns the parameters to be exported to .mtl file.
Definition: qgsgoochmaterialsettings.cpp:89
QgsMaterialSettingsRenderingTechnique::InstancedPoints
@ InstancedPoints
Instanced based rendering, requiring triangles and point data.
QgsSymbolLayerUtils::decodeColor
static QColor decodeColor(const QString &str)
Definition: qgssymbollayerutils.cpp:69
QgsAbstractMaterialSettings::Warm
@ Warm
Warm color (gooch material)
Definition: qgsabstractmaterialsettings.h:193
QgsMaterialContext::selectionColor
QColor selectionColor() const
Returns the color for representing materials in a selected state.
Definition: qgsabstractmaterialsettings.h:87
QgsAbstractMaterialSettings::Cool
@ Cool
Cool color (gooch material)
Definition: qgsabstractmaterialsettings.h:194
QgsMaterialContext
Context settings for a material.
Definition: qgsabstractmaterialsettings.h:64
qgslinematerial_p.h
QgsAbstractMaterialSettings::Diffuse
@ Diffuse
Diffuse color.
Definition: qgsabstractmaterialsettings.h:191
QgsGoochMaterialSettings::type
QString type() const override
Returns the unique type name for the material.
Definition: qgsgoochmaterialsettings.cpp:30
QgsGoochMaterialSettings::readXml
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
Definition: qgsgoochmaterialsettings.cpp:63
QgsAbstractMaterialSettings
Abstract base class for material settings.
Definition: qgsabstractmaterialsettings.h:114
QgsMaterialSettingsRenderingTechnique::Lines
@ Lines
Line based rendering, requires line data.
QgsGoochMaterialSettings::QgsGoochMaterialSettings
QgsGoochMaterialSettings()=default
Constructor for QgsGoochMaterialSettings.
QgsGoochMaterialSettings::dataDefinedVertexColorsAsByte
QByteArray dataDefinedVertexColorsAsByte(const QgsExpressionContext &expressionContext) const override
Returns byte array corresponding to the data defined colors depending of the expressionContext,...
Definition: qgsgoochmaterialsettings.cpp:135
QgsGoochMaterialSettings::applyDataDefinedToGeometry
void applyDataDefinedToGeometry(Qt3DRender::QGeometry *geometry, int vertexCount, const QByteArray &data) const override
Applies the data defined bytes, dataDefinedBytes, on the geometry by filling a specific vertex buffer...
Definition: qgsgoochmaterialsettings.cpp:172
QgsMaterialSettingsRenderingTechnique::Triangles
@ Triangles
Triangle based rendering (default)
QgsMaterialSettingsRenderingTechnique::TrianglesWithFixedTexture
@ TrianglesWithFixedTexture
Triangle based rendering, using a fixed, non-user-configurable texture (e.g. for terrain rendering)
QgsAbstractMaterialSettings::dataDefinedProperties
QgsPropertyCollection dataDefinedProperties() const
Returns the symbol material property collection, used for data defined overrides.
Definition: qgsabstractmaterialsettings.cpp:39
QgsGoochMaterialSettings::dataDefinedByteStride
int dataDefinedByteStride() const override
Returns byte stride of the data defined colors,used to fill the vertex colors data defined buffer for...
Definition: qgsgoochmaterialsettings.cpp:167
QgsAbstractMaterialSettings::writeXml
virtual void writeXml(QDomElement &element, const QgsReadWriteContext &) const
Writes settings to a DOM element.
Definition: qgsabstractmaterialsettings.cpp:27
QgsMaterialSettingsRenderingTechnique
QgsMaterialSettingsRenderingTechnique
Material rendering techniques.
Definition: qgsabstractmaterialsettings.h:43
QgsGoochMaterialSettings::writeXml
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
Definition: qgsgoochmaterialsettings.cpp:76
QgsGoochMaterialSettings::addParametersToEffect
void addParametersToEffect(Qt3DRender::QEffect *effect) const override
Adds parameters from the material to a destination effect.
Definition: qgsgoochmaterialsettings.cpp:131
QgsMaterialSettingsRenderingTechnique::TrianglesDataDefined
@ TrianglesDataDefined
Triangle based rendering with possibility of datadefined color.
QgsMaterialSettingsRenderingTechnique::TrianglesFromModel
@ TrianglesFromModel
Triangle based rendering, using a model object source.
QgsGoochMaterialSettings::create
static QgsAbstractMaterialSettings * create()
Returns a new instance of QgsGoochMaterialSettings.
Definition: qgsgoochmaterialsettings.cpp:35
QgsGoochMaterialSettings::supportsTechnique
static bool supportsTechnique(QgsMaterialSettingsRenderingTechnique technique)
Returns true if the specified technique is supported by the Gooch material.
Definition: qgsgoochmaterialsettings.cpp:40
QgsGoochMaterialSettings::clone
QgsGoochMaterialSettings * clone() const override
Clones the material settings.
Definition: qgsgoochmaterialsettings.cpp:58
QgsAbstractMaterialSettings::readXml
virtual void readXml(const QDomElement &element, const QgsReadWriteContext &)
Reads settings from a DOM element.
Definition: qgsabstractmaterialsettings.cpp:20
QgsGoochMaterialSettings
Basic shading material used for rendering based on the Phong shading model with three color component...
Definition: qgsgoochmaterialsettings.h:36
QgsMaterialSettingsRenderingTechnique::Points
@ Points
Point based rendering, requires point data.
QgsGoochMaterialSettings::diffuse
QColor diffuse() const
Returns diffuse color component.
Definition: qgsgoochmaterialsettings.h:66
QgsGoochMaterialSettings::warm
QColor warm() const
Returns warm color component.
Definition: qgsgoochmaterialsettings.h:60
QgsMaterialContext::isSelected
bool isSelected() const
Returns true if the material should represent a selected state.
Definition: qgsabstractmaterialsettings.h:73
QgsAbstractPropertyCollection::valueAsColor
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
Definition: qgspropertycollection.cpp:54