Skip to content

Commit 51cde6f

Browse files
committedAug 3, 2020
[3d][FEATURE] Add CAD style ("Gooch") material for polygons/extruded lines
From the qt docs: "The Gooch lighting model uses both color and brightness to help show the curvature of 3D surfaces. This is often better than models such as Phong that rely purely upon changes in brightness. In situations such as in CAD and CAM applications where photorealism is not a goal, the Gooch shading model in conjunction with some kind of silhouette edge inking is a popular solution. The Gooch lighting model is explained fully in the original Gooch paper. The Gooch model mixes a diffuse object color with a user-provided cool color and warm color to produce the end points of a color ramp that is used to shade the object based upon the cosine of the angle between the vector from the fragment to the light source and the fragment's normal vector. Optionally, a specular highlight can be added on top. The relative contributions to the cool and warm colors by the diffuse color are controlled by the alpha and beta properties respecitvely.""" The TLDR: the shader works well for revealing 3d details of objects which may otherwise be hidden due to the scene's lighting. Ultimately, it's an easier material to work with as you don't need to worry about setting up appropriate scene lighting in order to visualise features.
1 parent d9af7f7 commit 51cde6f

File tree

10 files changed

+249
-76
lines changed

10 files changed

+249
-76
lines changed
 

‎images/images.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@
881881
<file>themes/default/mIconAlignTop.svg</file>
882882
<file>themes/default/mIconAlignVCenter.svg</file>
883883
<file>themes/default/mIconPhongMaterial.svg</file>
884+
<file>themes/default/mIconGoochMaterial.svg</file>
884885
</qresource>
885886
<qresource prefix="/images/tips">
886887
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
Lines changed: 85 additions & 0 deletions
Loading

‎python/3d/auto_generated/qgsphongmaterialsettings.sip.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ Constructor for QgsPhongMaterialSettings.
3636

3737
virtual QString type() const;
3838

39+
3940
static bool supportsTechnique( QgsMaterialSettingsRenderingTechnique technique );
41+
%Docstring
42+
Returns ``True`` if the specified ``technique`` is suppored by the Phong material.
43+
%End
4044

4145
static QgsAbstractMaterialSettings *create() /Factory/;
4246
%Docstring

‎src/3d/qgs3d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void Qgs3D::initialize()
6969
instance()->materialRegistry()->addMaterialSettingsType( new QgsMaterialSettingsMetadata( QStringLiteral( "phong" ), QObject::tr( "Realistic (Phong)" ),
7070
QgsPhongMaterialSettings::create, QgsPhongMaterialSettings::supportsTechnique, nullptr, QgsApplication::getThemeIcon( QStringLiteral( "/mIconPhongMaterial.svg" ) ) ) );
7171
instance()->materialRegistry()->addMaterialSettingsType( new QgsMaterialSettingsMetadata( QStringLiteral( "gooch" ), QObject::tr( "CAD (Gooch)" ),
72-
QgsGoochMaterialSettings::create, nullptr ) );
72+
QgsGoochMaterialSettings::create, QgsGoochMaterialSettings::supportsTechnique, nullptr, QgsApplication::getThemeIcon( QStringLiteral( "/mIconGoochMaterial.svg" ) ) ) );
7373

7474
// because we are usually populating the 3d registry AFTER QgsApplication initialisation, we need to defer creation
7575
// of 3d symbols in the default style until now

‎src/3d/qgsgoochmaterialsettings.cpp

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ QgsAbstractMaterialSettings *QgsGoochMaterialSettings::create()
2929
return new QgsGoochMaterialSettings();
3030
}
3131

32+
bool QgsGoochMaterialSettings::supportsTechnique( QgsMaterialSettingsRenderingTechnique technique )
33+
{
34+
switch ( technique )
35+
{
36+
case QgsMaterialSettingsRenderingTechnique::Triangles:
37+
return true;
38+
39+
case QgsMaterialSettingsRenderingTechnique::Lines:
40+
case QgsMaterialSettingsRenderingTechnique::InstancedPoints:
41+
case QgsMaterialSettingsRenderingTechnique::Points:
42+
return false;
43+
}
44+
return false;
45+
}
46+
3247
QgsGoochMaterialSettings *QgsGoochMaterialSettings::clone() const
3348
{
3449
return new QgsGoochMaterialSettings( *this );
@@ -40,7 +55,9 @@ void QgsGoochMaterialSettings::readXml( const QDomElement &elem, const QgsReadWr
4055
mCool = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "cool" ), QStringLiteral( "255,130,0" ) ) );
4156
mDiffuse = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "diffuse" ), QStringLiteral( "178,178,178" ) ) );
4257
mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ) ) );
43-
mShininess = elem.attribute( QStringLiteral( "shininess" ) ).toFloat();
58+
mShininess = elem.attribute( QStringLiteral( "shininess2" ), QStringLiteral( "100" ) ).toFloat();
59+
mAlpha = elem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "0.25" ) ).toFloat();
60+
mBeta = elem.attribute( QStringLiteral( "beta" ), QStringLiteral( "0.5" ) ).toFloat();
4461
}
4562

4663
void QgsGoochMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteContext & ) const
@@ -49,37 +66,41 @@ void QgsGoochMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteCo
4966
elem.setAttribute( QStringLiteral( "cool" ), QgsSymbolLayerUtils::encodeColor( mCool ) );
5067
elem.setAttribute( QStringLiteral( "diffuse" ), QgsSymbolLayerUtils::encodeColor( mDiffuse ) );
5168
elem.setAttribute( QStringLiteral( "specular" ), QgsSymbolLayerUtils::encodeColor( mSpecular ) );
52-
elem.setAttribute( QStringLiteral( "shininess" ), mShininess );
69+
elem.setAttribute( QStringLiteral( "shininess2" ), mShininess );
70+
elem.setAttribute( QStringLiteral( "alpha" ), mAlpha );
71+
elem.setAttribute( QStringLiteral( "beta" ), mBeta );
5372
}
5473

55-
Qt3DRender::QMaterial *QgsGoochMaterialSettings::toMaterial( const QgsMaterialContext &context ) const
74+
Qt3DRender::QMaterial *QgsGoochMaterialSettings::toMaterial( QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context ) const
5675
{
57-
Qt3DExtras::QGoochMaterial *material = new Qt3DExtras::QGoochMaterial;
58-
material->setDiffuse( mDiffuse );
59-
material->setWarm( mWarm );
60-
material->setCool( mCool );
76+
switch ( technique )
77+
{
78+
case QgsMaterialSettingsRenderingTechnique::Triangles:
79+
{
80+
Qt3DExtras::QGoochMaterial *material = new Qt3DExtras::QGoochMaterial;
81+
material->setDiffuse( mDiffuse );
82+
material->setWarm( mWarm );
83+
material->setCool( mCool );
6184

62-
material->setSpecular( mSpecular );
63-
material->setShininess( mShininess );
85+
material->setSpecular( mSpecular );
86+
material->setShininess( mShininess );
87+
material->setAlpha( mAlpha );
88+
material->setBeta( mBeta );
6489

65-
if ( context.isSelected() )
66-
{
67-
// update the material with selection colors
68-
material->setDiffuse( context.selectionColor() );
69-
}
70-
return material;
71-
}
90+
if ( context.isSelected() )
91+
{
92+
// update the material with selection colors
93+
material->setDiffuse( context.selectionColor() );
94+
}
95+
return material;
96+
}
7297

73-
QgsLineMaterial *QgsGoochMaterialSettings::toLineMaterial( const QgsMaterialContext &context ) const
74-
{
75-
QgsLineMaterial *mat = new QgsLineMaterial;
76-
mat->setLineColor( mDiffuse );
77-
if ( context.isSelected() )
78-
{
79-
// update the material with selection colors
80-
mat->setLineColor( context.selectionColor() );
98+
case QgsMaterialSettingsRenderingTechnique::Lines:
99+
case QgsMaterialSettingsRenderingTechnique::InstancedPoints:
100+
case QgsMaterialSettingsRenderingTechnique::Points:
101+
return nullptr;
81102
}
82-
return mat;
103+
return nullptr;
83104
}
84105

85106
void QgsGoochMaterialSettings::addParametersToEffect( Qt3DRender::QEffect * ) const

‎src/3d/qgsgoochmaterialsettings.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings
4949
*/
5050
static QgsAbstractMaterialSettings *create() SIP_FACTORY;
5151

52+
/**
53+
* Returns TRUE if the specified \a technique is suppored by the Gooch material.
54+
*/
55+
static bool supportsTechnique( QgsMaterialSettingsRenderingTechnique technique );
56+
5257
QgsGoochMaterialSettings *clone() const override SIP_FACTORY;
5358

5459
//! Returns warm color component
@@ -64,6 +69,12 @@ class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings
6469
//! Returns shininess of the surface
6570
float shininess() const { return mShininess; }
6671

72+
//! Returns the alpha value
73+
float alpha() const { return mAlpha; }
74+
75+
//! Returns the beta value
76+
float beta() const { return mBeta; }
77+
6778
//! Sets warm color component
6879
void setWarm( const QColor &warm ) { mWarm = warm; }
6980

@@ -77,11 +88,16 @@ class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings
7788
//! Sets shininess of the surface
7889
void setShininess( float shininess ) { mShininess = shininess; }
7990

91+
//! Sets alpha value
92+
void setAlpha( float alpha ) { mAlpha = alpha; }
93+
94+
//! Sets beta value
95+
void setBeta( float beta ) { mBeta = beta; }
96+
8097
void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
8198
void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
8299
#ifndef SIP_RUN
83-
Qt3DRender::QMaterial *toMaterial( const QgsMaterialContext &context ) const override SIP_FACTORY;
84-
QgsLineMaterial *toLineMaterial( const QgsMaterialContext &context ) const override SIP_FACTORY;
100+
Qt3DRender::QMaterial *toMaterial( QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context ) const override;
85101
void addParametersToEffect( Qt3DRender::QEffect *effect ) const override;
86102
#endif
87103

@@ -91,15 +107,19 @@ class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings
91107
mSpecular == other.mSpecular &&
92108
mWarm == other.mWarm &&
93109
mCool == other.mCool &&
94-
mShininess == other.mShininess;
110+
mShininess == other.mShininess &&
111+
mAlpha == other.mAlpha &&
112+
mBeta == other.mBeta;
95113
}
96114

97115
private:
98116
QColor mDiffuse{ QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) };
99117
QColor mSpecular{ QColor::fromRgbF( 1.0f, 1.0f, 1.0f, 1.0f ) };
100-
QColor mWarm { QColor( 107, 0, 107 )};
101-
QColor mCool { QColor( 255, 130, 0 )};
102-
float mShininess = 0.0f;
118+
QColor mWarm {QColor( 107, 0, 107 ) };
119+
QColor mCool {QColor( 255, 130, 0 )};
120+
float mShininess = 100.0f;
121+
float mAlpha = 0.25f;
122+
float mBeta = 0.5f;
103123
};
104124

105125

‎src/3d/qgsphongmaterialsettings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class _3D_EXPORT QgsPhongMaterialSettings : public QgsAbstractMaterialSettings
4343
QgsPhongMaterialSettings() = default;
4444

4545
QString type() const override;
46+
47+
/**
48+
* Returns TRUE if the specified \a technique is suppored by the Phong material.
49+
*/
4650
static bool supportsTechnique( QgsMaterialSettingsRenderingTechnique technique );
4751

4852
/**

‎src/app/3d/qgsgoochmaterialwidget.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,27 @@ QgsGoochMaterialWidget::QgsGoochMaterialWidget( QWidget *parent )
2626
QgsGoochMaterialSettings defaultMaterial;
2727
setSettings( &defaultMaterial, nullptr );
2828

29+
spinShininess->setClearValue( 100 );
30+
spinAlpha->setClearValue( 0.25 );
31+
spinBeta->setClearValue( 0.5 );
32+
33+
btnWarm->setDefaultColor( QColor( 107, 0, 107 ) );
34+
btnCool->setDefaultColor( QColor( 255, 130, 0 ) );
35+
2936
connect( btnDiffuse, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
3037
connect( btnWarm, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
3138
connect( btnCool, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
3239
connect( btnSpecular, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
3340
connect( spinShininess, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGoochMaterialWidget::changed );
41+
connect( spinAlpha, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGoochMaterialWidget::changed );
42+
connect( spinBeta, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGoochMaterialWidget::changed );
3443
}
3544

3645
QgsMaterialSettingsWidget *QgsGoochMaterialWidget::create()
3746
{
3847
return new QgsGoochMaterialWidget();
3948
}
4049

41-
void QgsGoochMaterialWidget::setDiffuseVisible( bool visible )
42-
{
43-
lblDiffuse->setVisible( visible );
44-
btnDiffuse->setVisible( visible );
45-
}
46-
47-
bool QgsGoochMaterialWidget::isDiffuseVisible() const
48-
{
49-
return btnDiffuse->isVisible();
50-
}
51-
5250
void QgsGoochMaterialWidget::setSettings( const QgsAbstractMaterialSettings *settings, QgsVectorLayer * )
5351
{
5452
const QgsGoochMaterialSettings *goochMaterial = dynamic_cast< const QgsGoochMaterialSettings * >( settings );
@@ -59,6 +57,8 @@ void QgsGoochMaterialWidget::setSettings( const QgsAbstractMaterialSettings *set
5957
btnCool->setColor( goochMaterial->cool() );
6058
btnSpecular->setColor( goochMaterial->specular() );
6159
spinShininess->setValue( goochMaterial->shininess() );
60+
spinAlpha->setValue( goochMaterial->alpha() );
61+
spinBeta->setValue( goochMaterial->beta() );
6262
}
6363

6464
QgsAbstractMaterialSettings *QgsGoochMaterialWidget::settings()
@@ -69,5 +69,7 @@ QgsAbstractMaterialSettings *QgsGoochMaterialWidget::settings()
6969
m->setCool( btnCool->color() );
7070
m->setSpecular( btnSpecular->color() );
7171
m->setShininess( spinShininess->value() );
72+
m->setAlpha( spinAlpha->value() );
73+
m->setBeta( spinBeta->value() );
7274
return m.release();
7375
}

‎src/app/3d/qgsgoochmaterialwidget.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ class QgsGoochMaterialWidget : public QgsMaterialSettingsWidget, private Ui::Goo
3131
explicit QgsGoochMaterialWidget( QWidget *parent = nullptr );
3232

3333
static QgsMaterialSettingsWidget *create();
34-
35-
void setDiffuseVisible( bool visible );
36-
bool isDiffuseVisible() const;
37-
3834
void setSettings( const QgsAbstractMaterialSettings *settings, QgsVectorLayer *layer ) override;
3935
QgsAbstractMaterialSettings *settings() override;
4036

‎src/ui/3d/goochmaterialwidget.ui

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,40 @@
77
<x>0</x>
88
<y>0</y>
99
<width>394</width>
10-
<height>162</height>
10+
<height>230</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
1414
<string notr="true">Form</string>
1515
</property>
1616
<layout class="QGridLayout" name="gridLayout">
17+
<item row="4" column="1">
18+
<widget class="QgsDoubleSpinBox" name="spinShininess">
19+
<property name="minimum">
20+
<double>1.000000000000000</double>
21+
</property>
22+
<property name="maximum">
23+
<double>1000.000000000000000</double>
24+
</property>
25+
<property name="value">
26+
<double>100.000000000000000</double>
27+
</property>
28+
</widget>
29+
</item>
30+
<item row="3" column="0">
31+
<widget class="QLabel" name="lblSpecular">
32+
<property name="text">
33+
<string>Specular</string>
34+
</property>
35+
</widget>
36+
</item>
37+
<item row="0" column="0">
38+
<widget class="QLabel" name="lblDiffuse">
39+
<property name="text">
40+
<string>Diffuse</string>
41+
</property>
42+
</widget>
43+
</item>
1744
<item row="1" column="1">
1845
<widget class="QgsColorButton" name="btnWarm">
1946
<property name="sizePolicy">
@@ -46,10 +73,10 @@
4673
</property>
4774
</widget>
4875
</item>
49-
<item row="1" column="0">
50-
<widget class="QLabel" name="lblAmbient">
76+
<item row="5" column="0">
77+
<widget class="QLabel" name="lblShininess_2">
5178
<property name="text">
52-
<string>Warm</string>
79+
<string>Alpha</string>
5380
</property>
5481
</widget>
5582
</item>
@@ -60,15 +87,8 @@
6087
</property>
6188
</widget>
6289
</item>
63-
<item row="4" column="1">
64-
<widget class="QgsDoubleSpinBox" name="spinShininess">
65-
<property name="maximum">
66-
<double>1000.000000000000000</double>
67-
</property>
68-
</widget>
69-
</item>
70-
<item row="3" column="1">
71-
<widget class="QgsColorButton" name="btnSpecular">
90+
<item row="0" column="1">
91+
<widget class="QgsColorButton" name="btnDiffuse">
7292
<property name="sizePolicy">
7393
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
7494
<horstretch>0</horstretch>
@@ -83,15 +103,15 @@
83103
</property>
84104
</widget>
85105
</item>
86-
<item row="0" column="0">
87-
<widget class="QLabel" name="lblDiffuse">
106+
<item row="1" column="0">
107+
<widget class="QLabel" name="lblAmbient">
88108
<property name="text">
89-
<string>Diffuse</string>
109+
<string>Warm</string>
90110
</property>
91111
</widget>
92112
</item>
93-
<item row="0" column="1">
94-
<widget class="QgsColorButton" name="btnDiffuse">
113+
<item row="3" column="1">
114+
<widget class="QgsColorButton" name="btnSpecular">
95115
<property name="sizePolicy">
96116
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
97117
<horstretch>0</horstretch>
@@ -106,34 +126,54 @@
106126
</property>
107127
</widget>
108128
</item>
109-
<item row="3" column="0">
110-
<widget class="QLabel" name="lblSpecular">
129+
<item row="2" column="0">
130+
<widget class="QLabel" name="lblAmbient_2">
111131
<property name="text">
112-
<string>Specular</string>
132+
<string>Cool</string>
113133
</property>
114134
</widget>
115135
</item>
116-
<item row="2" column="0">
117-
<widget class="QLabel" name="lblAmbient_2">
136+
<item row="6" column="0">
137+
<widget class="QLabel" name="lblShininess_3">
118138
<property name="text">
119-
<string>Cool</string>
139+
<string>Beta</string>
140+
</property>
141+
</widget>
142+
</item>
143+
<item row="5" column="1">
144+
<widget class="QgsDoubleSpinBox" name="spinAlpha">
145+
<property name="maximum">
146+
<double>1000.000000000000000</double>
147+
</property>
148+
<property name="singleStep">
149+
<double>0.100000000000000</double>
150+
</property>
151+
</widget>
152+
</item>
153+
<item row="6" column="1">
154+
<widget class="QgsDoubleSpinBox" name="spinBeta">
155+
<property name="maximum">
156+
<double>1000.000000000000000</double>
157+
</property>
158+
<property name="singleStep">
159+
<double>0.100000000000000</double>
120160
</property>
121161
</widget>
122162
</item>
123163
</layout>
124164
</widget>
125165
<customwidgets>
126-
<customwidget>
127-
<class>QgsDoubleSpinBox</class>
128-
<extends>QDoubleSpinBox</extends>
129-
<header>qgsdoublespinbox.h</header>
130-
</customwidget>
131166
<customwidget>
132167
<class>QgsColorButton</class>
133168
<extends>QToolButton</extends>
134169
<header>qgscolorbutton.h</header>
135170
<container>1</container>
136171
</customwidget>
172+
<customwidget>
173+
<class>QgsDoubleSpinBox</class>
174+
<extends>QDoubleSpinBox</extends>
175+
<header>qgsdoublespinbox.h</header>
176+
</customwidget>
137177
</customwidgets>
138178
<resources/>
139179
<connections/>

0 commit comments

Comments
 (0)
Please sign in to comment.