Skip to content

Commit

Permalink
Gooch shading!
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 3, 2020
1 parent daf38a9 commit d9af7f7
Show file tree
Hide file tree
Showing 10 changed files with 460 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/3d/CMakeLists.txt
Expand Up @@ -13,6 +13,7 @@ SET(QGIS_3D_SRCS
qgscameracontroller.cpp
qgscamerapose.cpp
qgsfeature3dhandler_p.cpp
qgsgoochmaterialsettings.cpp
qgslayoutitem3dmap.cpp
qgsmaterialregistry.cpp
qgsoffscreen3dengine.cpp
Expand Down Expand Up @@ -89,6 +90,7 @@ SET(QGIS_3D_HDRS
qgsabstractvectorlayer3drenderer.h
qgscameracontroller.h
qgscamerapose.h
qgsgoochmaterialsettings.h
qgslayoutitem3dmap.h
qgsmaterialregistry.h
qgsmeshlayer3drenderer.h
Expand Down
3 changes: 3 additions & 0 deletions src/3d/qgs3d.cpp
Expand Up @@ -34,6 +34,7 @@
#include "qgspolygon3dsymbol_p.h"
#include "qgspoint3dsymbol_p.h"
#include "qgsline3dsymbol_p.h"
#include "qgsgoochmaterialsettings.h"

#include "qgsstyle.h"

Expand Down Expand Up @@ -67,6 +68,8 @@ void Qgs3D::initialize()

instance()->materialRegistry()->addMaterialSettingsType( new QgsMaterialSettingsMetadata( QStringLiteral( "phong" ), QObject::tr( "Realistic (Phong)" ),
QgsPhongMaterialSettings::create, QgsPhongMaterialSettings::supportsTechnique, nullptr, QgsApplication::getThemeIcon( QStringLiteral( "/mIconPhongMaterial.svg" ) ) ) );
instance()->materialRegistry()->addMaterialSettingsType( new QgsMaterialSettingsMetadata( QStringLiteral( "gooch" ), QObject::tr( "CAD (Gooch)" ),
QgsGoochMaterialSettings::create, nullptr ) );

// because we are usually populating the 3d registry AFTER QgsApplication initialisation, we need to defer creation
// of 3d symbols in the default style until now
Expand Down
87 changes: 87 additions & 0 deletions src/3d/qgsgoochmaterialsettings.cpp
@@ -0,0 +1,87 @@
/***************************************************************************
qgsgoochmaterialsettings.cpp
--------------------------------------
Date : July 2020
Copyright : (C) 2020 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsgoochmaterialsettings.h"

#include "qgssymbollayerutils.h"
#include "qgslinematerial_p.h"
#include <Qt3DExtras/QGoochMaterial>

QString QgsGoochMaterialSettings::type() const
{
return QStringLiteral( "gooch" );
}

QgsAbstractMaterialSettings *QgsGoochMaterialSettings::create()
{
return new QgsGoochMaterialSettings();
}

QgsGoochMaterialSettings *QgsGoochMaterialSettings::clone() const
{
return new QgsGoochMaterialSettings( *this );
}

void QgsGoochMaterialSettings::readXml( const QDomElement &elem, const QgsReadWriteContext & )
{
mWarm = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "warm" ), QStringLiteral( "107,0,107" ) ) );
mCool = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "cool" ), QStringLiteral( "255,130,0" ) ) );
mDiffuse = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "diffuse" ), QStringLiteral( "178,178,178" ) ) );
mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ) ) );
mShininess = elem.attribute( QStringLiteral( "shininess" ) ).toFloat();
}

void QgsGoochMaterialSettings::writeXml( QDomElement &elem, const QgsReadWriteContext & ) const
{
elem.setAttribute( QStringLiteral( "warm" ), QgsSymbolLayerUtils::encodeColor( mWarm ) );
elem.setAttribute( QStringLiteral( "cool" ), QgsSymbolLayerUtils::encodeColor( mCool ) );
elem.setAttribute( QStringLiteral( "diffuse" ), QgsSymbolLayerUtils::encodeColor( mDiffuse ) );
elem.setAttribute( QStringLiteral( "specular" ), QgsSymbolLayerUtils::encodeColor( mSpecular ) );
elem.setAttribute( QStringLiteral( "shininess" ), mShininess );
}

Qt3DRender::QMaterial *QgsGoochMaterialSettings::toMaterial( const QgsMaterialContext &context ) const
{
Qt3DExtras::QGoochMaterial *material = new Qt3DExtras::QGoochMaterial;
material->setDiffuse( mDiffuse );
material->setWarm( mWarm );
material->setCool( mCool );

material->setSpecular( mSpecular );
material->setShininess( mShininess );

if ( context.isSelected() )
{
// update the material with selection colors
material->setDiffuse( context.selectionColor() );
}
return material;
}

QgsLineMaterial *QgsGoochMaterialSettings::toLineMaterial( const QgsMaterialContext &context ) const
{
QgsLineMaterial *mat = new QgsLineMaterial;
mat->setLineColor( mDiffuse );
if ( context.isSelected() )
{
// update the material with selection colors
mat->setLineColor( context.selectionColor() );
}
return mat;
}

void QgsGoochMaterialSettings::addParametersToEffect( Qt3DRender::QEffect * ) const
{
}
106 changes: 106 additions & 0 deletions src/3d/qgsgoochmaterialsettings.h
@@ -0,0 +1,106 @@
/***************************************************************************
qgsgoochmaterialsettings.h
--------------------------------------
Date : July 2020
Copyright : (C) 2020 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSGOOCHMATERIALSETTINGS_H
#define QGSGOOCHMATERIALSETTINGS_H

#include "qgis_3d.h"
#include "qgsabstractmaterialsettings.h"

#include <QColor>

class QDomElement;

/**
* \ingroup 3d
* Basic shading material used for rendering based on the Phong shading model
* with three color components: ambient, diffuse and specular.
*
* \warning This is not considered stable API, and may change in future QGIS releases. It is
* exposed to the Python bindings as a tech preview only.
*
* \since QGIS 3.16
*/
class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings
{
public:

/**
* Constructor for QgsGoochMaterialSettings.
*/
QgsGoochMaterialSettings() = default;

QString type() const override;

/**
* Returns a new instance of QgsGoochMaterialSettings.
*/
static QgsAbstractMaterialSettings *create() SIP_FACTORY;

QgsGoochMaterialSettings *clone() const override SIP_FACTORY;

//! Returns warm color component
QColor warm() const { return mWarm; }

//! Returns cool color component
QColor cool() const { return mCool; }

//! Returns diffuse color component
QColor diffuse() const { return mDiffuse; }
//! Returns specular color component
QColor specular() const { return mSpecular; }
//! Returns shininess of the surface
float shininess() const { return mShininess; }

//! Sets warm color component
void setWarm( const QColor &warm ) { mWarm = warm; }

//! Sets cool color component
void setCool( const QColor &cool ) { mCool = cool; }

//! Sets diffuse color component
void setDiffuse( const QColor &diffuse ) { mDiffuse = diffuse; }
//! Sets specular color component
void setSpecular( const QColor &specular ) { mSpecular = specular; }
//! Sets shininess of the surface
void setShininess( float shininess ) { mShininess = shininess; }

void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override;
#ifndef SIP_RUN
Qt3DRender::QMaterial *toMaterial( const QgsMaterialContext &context ) const override SIP_FACTORY;
QgsLineMaterial *toLineMaterial( const QgsMaterialContext &context ) const override SIP_FACTORY;
void addParametersToEffect( Qt3DRender::QEffect *effect ) const override;
#endif

bool operator==( const QgsGoochMaterialSettings &other ) const
{
return mDiffuse == other.mDiffuse &&
mSpecular == other.mSpecular &&
mWarm == other.mWarm &&
mCool == other.mCool &&
mShininess == other.mShininess;
}

private:
QColor mDiffuse{ QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) };
QColor mSpecular{ QColor::fromRgbF( 1.0f, 1.0f, 1.0f, 1.0f ) };
QColor mWarm { QColor( 107, 0, 107 )};
QColor mCool { QColor( 255, 130, 0 )};
float mShininess = 0.0f;
};


#endif // QGSGOOCHMATERIALSETTINGS_H
6 changes: 3 additions & 3 deletions src/3d/qgsphongmaterialsettings.cpp
Expand Up @@ -58,9 +58,9 @@ QgsPhongMaterialSettings *QgsPhongMaterialSettings::clone() const

void QgsPhongMaterialSettings::readXml( const QDomElement &elem, const QgsReadWriteContext & )
{
mAmbient = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "ambient" ) ) );
mDiffuse = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "diffuse" ) ) );
mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ) ) );
mAmbient = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "ambient" ), QStringLiteral( "25,25,25" ) ) );
mDiffuse = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "diffuse" ), QStringLiteral( "178,178,178" ) ) );
mSpecular = QgsSymbolLayerUtils::decodeColor( elem.attribute( QStringLiteral( "specular" ), QStringLiteral( "255,255,255" ) ) );
mShininess = elem.attribute( QStringLiteral( "shininess" ) ).toFloat();
mDiffuseTextureEnabled = elem.attribute( QStringLiteral( "is_using_diffuse_texture" ), QStringLiteral( "0" ) ).toInt();
mTexturePath = elem.attribute( QStringLiteral( "diffuse_texture_path" ), QString() );
Expand Down
2 changes: 2 additions & 0 deletions src/app/3d/qgs3dapputils.cpp
Expand Up @@ -22,6 +22,7 @@
#include "qgspolygon3dsymbolwidget.h"
#include "qgsline3dsymbolwidget.h"
#include "qgsphongmaterialwidget.h"
#include "qgsgoochmaterialwidget.h"
#include "qgs3dicongenerator.h"

void Qgs3DAppUtils::initialize()
Expand All @@ -31,6 +32,7 @@ void Qgs3DAppUtils::initialize()
dynamic_cast< Qgs3DSymbolMetadata * >( QgsApplication::symbol3DRegistry()->symbolMetadata( QStringLiteral( "polygon" ) ) )->setWidgetFunction( QgsPolygon3DSymbolWidget::create );

dynamic_cast< QgsMaterialSettingsMetadata * >( Qgs3D::materialRegistry()->materialSettingsMetadata( QStringLiteral( "phong" ) ) )->setWidgetFunction( QgsPhongMaterialWidget::create );
dynamic_cast< QgsMaterialSettingsMetadata * >( Qgs3D::materialRegistry()->materialSettingsMetadata( QStringLiteral( "gooch" ) ) )->setWidgetFunction( QgsGoochMaterialWidget::create );

QgsStyleModel::setIconGenerator( new Qgs3DIconGenerator( QgsApplication::defaultStyleModel() ) );
}
73 changes: 73 additions & 0 deletions src/app/3d/qgsgoochmaterialwidget.cpp
@@ -0,0 +1,73 @@
/***************************************************************************
qgsgoochmaterialwidget.cpp
--------------------------------------
Date : July 2020
Copyright : (C) 2020 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsgoochmaterialwidget.h"

#include "qgsgoochmaterialsettings.h"
#include "qgis.h"

QgsGoochMaterialWidget::QgsGoochMaterialWidget( QWidget *parent )
: QgsMaterialSettingsWidget( parent )
{
setupUi( this );

QgsGoochMaterialSettings defaultMaterial;
setSettings( &defaultMaterial, nullptr );

connect( btnDiffuse, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
connect( btnWarm, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
connect( btnCool, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
connect( btnSpecular, &QgsColorButton::colorChanged, this, &QgsGoochMaterialWidget::changed );
connect( spinShininess, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsGoochMaterialWidget::changed );
}

QgsMaterialSettingsWidget *QgsGoochMaterialWidget::create()
{
return new QgsGoochMaterialWidget();
}

void QgsGoochMaterialWidget::setDiffuseVisible( bool visible )
{
lblDiffuse->setVisible( visible );
btnDiffuse->setVisible( visible );
}

bool QgsGoochMaterialWidget::isDiffuseVisible() const
{
return btnDiffuse->isVisible();
}

void QgsGoochMaterialWidget::setSettings( const QgsAbstractMaterialSettings *settings, QgsVectorLayer * )
{
const QgsGoochMaterialSettings *goochMaterial = dynamic_cast< const QgsGoochMaterialSettings * >( settings );
if ( !goochMaterial )
return;
btnDiffuse->setColor( goochMaterial->diffuse() );
btnWarm->setColor( goochMaterial->warm() );
btnCool->setColor( goochMaterial->cool() );
btnSpecular->setColor( goochMaterial->specular() );
spinShininess->setValue( goochMaterial->shininess() );
}

QgsAbstractMaterialSettings *QgsGoochMaterialWidget::settings()
{
std::unique_ptr< QgsGoochMaterialSettings > m = qgis::make_unique< QgsGoochMaterialSettings >();
m->setDiffuse( btnDiffuse->color() );
m->setWarm( btnWarm->color() );
m->setCool( btnCool->color() );
m->setSpecular( btnSpecular->color() );
m->setShininess( spinShininess->value() );
return m.release();
}
43 changes: 43 additions & 0 deletions src/app/3d/qgsgoochmaterialwidget.h
@@ -0,0 +1,43 @@
/***************************************************************************
qgsgoochmaterialwidget.h
--------------------------------------
Date : July 2020
Copyright : (C) 2020 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSGOOCHMATERIALWIDGET_H
#define QGSGOOCHMATERIALWIDGET_H

#include "qgsmaterialsettingswidget.h"

#include <ui_goochmaterialwidget.h>

class QgsGoochMaterialSettings;


//! Widget for configuration of Gooch material settings
class QgsGoochMaterialWidget : public QgsMaterialSettingsWidget, private Ui::GoochMaterialWidget
{
Q_OBJECT
public:
explicit QgsGoochMaterialWidget( QWidget *parent = nullptr );

static QgsMaterialSettingsWidget *create();

void setDiffuseVisible( bool visible );
bool isDiffuseVisible() const;

void setSettings( const QgsAbstractMaterialSettings *settings, QgsVectorLayer *layer ) override;
QgsAbstractMaterialSettings *settings() override;

};

#endif // QGSGOOCHMATERIALWIDGET_H
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -272,6 +272,7 @@ IF (WITH_3D)
3d/qgs3dmeasuredialog.cpp
3d/qgs3dmodelsourcelineedit.cpp
3d/qgs3dnavigationwidget.cpp
3d/qgsgoochmaterialwidget.cpp
3d/qgslightswidget.cpp
3d/qgsline3dsymbolwidget.cpp
3d/qgsmaterialwidget.cpp
Expand Down

0 comments on commit d9af7f7

Please sign in to comment.