QGIS API Documentation 4.1.0-Master (3fcefe620d1)
Loading...
Searching...
No Matches
qgsmaterial3dhandler.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaterial3dhandler.cpp
3 --------------------------------------
4 Date : March 2026
5 Copyright : (C) 2026 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 "qgs3drendercontext.h"
19
20#include <QPropertyAnimation>
21#include <QSequentialAnimationGroup>
22#include <QString>
23#include <Qt3DCore/QEntity>
24#include <Qt3DCore/QTransform>
25#include <Qt3DExtras/QConeMesh>
26#include <Qt3DExtras/QCuboidMesh>
27#include <Qt3DExtras/QSphereMesh>
28#include <Qt3DRender/QParameter>
29#include <Qt3DRender/QPointLight>
30#include <Qt3DRender/QTechnique>
31
32using namespace Qt::StringLiterals;
33
34
36{
38 res.mSelectedColor = context.selectionColor();
39 res.mTextureFilterQuality = context.textureFilterQuality();
40 return res;
41}
42
44{
45 return mIsPreview;
46}
47
49{
50 mIsPreview = isPreview;
51}
52
54 const QgsAbstractMaterialSettings *settings, const QgsMaterialContext &context, Qgis::InstancedMaterialFlags flags, const QMatrix4x4 &transform
55) const
56{
57 Q_UNUSED( flags )
58 Q_UNUSED( settings )
59 Q_UNUSED( context )
60 Q_UNUSED( transform )
61 return nullptr;
62}
63
65{
66 Q_UNUSED( settings )
67 Q_UNUSED( expressionContext )
68 return QByteArray();
69}
70
71void QgsAbstractMaterial3DHandler::applyDataDefinedToGeometry( const QgsAbstractMaterialSettings *settings, Qt3DCore::QGeometry *geometry, int vertexCount, const QByteArray &dataDefinedBytes ) const
72{
73 Q_UNUSED( settings )
74 Q_UNUSED( geometry )
75 Q_UNUSED( vertexCount )
76 Q_UNUSED( dataDefinedBytes )
77}
78
79QList<QgsAbstractMaterial3DHandler::PreviewMeshType> QgsAbstractMaterial3DHandler::previewMeshTypes() const
80{
81 PreviewMeshType sphere;
82 sphere.type = u"sphere"_s;
83 sphere.displayName = QObject::tr( "Sphere" );
84
85 PreviewMeshType cube;
86 cube.type = u"cube"_s;
87 cube.displayName = QObject::tr( "Cube" );
88
89 PreviewMeshType cone;
90 cone.type = u"cone"_s;
91 cone.displayName = QObject::tr( "Cone" );
92
93 return { sphere, cube, cone };
94}
95
96Qt3DRender::QParameter *QgsAbstractMaterial3DHandler::findParameter( Qt3DRender::QEffect *effect, const QString &name )
97{
98 const QList<Qt3DRender::QParameter *> parameters = effect->parameters();
99 for ( Qt3DRender::QParameter *parameter : parameters )
100 {
101 if ( parameter->name() == name )
102 {
103 return parameter;
104 }
105 }
106
107 const QList< Qt3DRender::QTechnique *> techniques = effect->techniques();
108 for ( Qt3DRender::QTechnique *technique : techniques )
109 {
110 const QList<Qt3DRender::QParameter *> parameters = technique->parameters();
111 for ( Qt3DRender::QParameter *parameter : parameters )
112 {
113 if ( parameter->name() == name )
114 {
115 return parameter;
116 }
117 }
118 }
119
120 return nullptr;
121}
122
123Qt3DCore::QEntity *QgsAbstractMaterial3DHandler::createPreviewMesh( const QString &type, Qt3DCore::QEntity *parent ) const
124{
125 auto *entity = new Qt3DCore::QEntity( parent );
126 if ( type == "sphere"_L1 )
127 {
128 auto *mesh = new Qt3DExtras::QSphereMesh( entity );
129 mesh->setRadius( 1.0f );
130 mesh->setRings( 32 );
131 mesh->setSlices( 32 );
132 mesh->setGenerateTangents( true );
133 entity->addComponent( mesh );
134 }
135 else if ( type == "cube"_L1 )
136 {
137 auto *mesh = new Qt3DExtras::QCuboidMesh( entity );
138 mesh->setXExtent( 1.8f );
139 mesh->setYExtent( 1.8f );
140 mesh->setZExtent( 1.8f );
141
142 auto *transform = new Qt3DCore::QTransform( mesh );
143 transform->setRotation( QQuaternion::fromEulerAngles( 15, 35, 15 ) );
144
145 entity->addComponent( mesh );
146 entity->addComponent( transform );
147 }
148 else if ( type == "cone"_L1 )
149 {
150 auto *mesh = new Qt3DExtras::QConeMesh( entity );
151 mesh->setBottomRadius( 1.2f );
152 mesh->setLength( 1.8f );
153 mesh->setRings( 32 );
154 mesh->setSlices( 32 );
155 auto *transform = new Qt3DCore::QTransform( mesh );
156 transform->setRotation( QQuaternion::fromEulerAngles( 5, 0, 0 ) );
157
158 entity->addComponent( mesh );
159 entity->addComponent( transform );
160 }
161 return entity;
162}
163
165 const QgsAbstractMaterialSettings *settings, const QString &type, const QgsMaterialContext &context, QWindow *, Qt3DCore::QEntity *parent
166) const
167{
168 auto *root = new Qt3DCore::QEntity( parent );
169
170 Qt3DCore::QEntity *meshEntity = createPreviewMesh( type, root );
171 Q_ASSERT( meshEntity );
172 meshEntity->setObjectName( "mesh" );
173 if ( QgsMaterial *mat = toMaterial( settings, Qgis::MaterialRenderingTechnique::Triangles, context ) )
174 {
175 mat->setParent( meshEntity );
176 meshEntity->addComponent( mat );
177 }
178
179 auto *lightEntity = new Qt3DCore::QEntity( root );
180 auto *light = new Qt3DRender::QPointLight( lightEntity );
181 light->setColor( Qt::white );
182 light->setIntensity( 1.0f );
183 auto *lightTransform = new Qt3DCore::QTransform( lightEntity );
184 lightTransform->setTranslation( QVector3D( 3, 3, 3 ) );
185 lightEntity->addComponent( light );
186 lightEntity->addComponent( lightTransform );
187
188 auto *animGroup = new QSequentialAnimationGroup( lightEntity );
189 animGroup->setLoopCount( -1 );
190
191 auto *swingLeft = new QPropertyAnimation( lightTransform, "translation", animGroup );
192 swingLeft->setDuration( 8000 );
193 swingLeft->setStartValue( QVector3D( 3, 3, 3 ) );
194 swingLeft->setEndValue( QVector3D( -5, 5, 3 ) );
195 swingLeft->setEasingCurve( QEasingCurve::InOutSine );
196
197 auto *swingRight = new QPropertyAnimation( lightTransform, "translation", animGroup );
198 swingRight->setDuration( 8000 );
199 swingRight->setStartValue( QVector3D( -5, 5, 3 ) );
200 swingRight->setEndValue( QVector3D( 3, 3, 3 ) );
201 swingRight->setEasingCurve( QEasingCurve::InOutSine );
202
203 animGroup->addAnimation( swingLeft );
204 animGroup->addAnimation( swingRight );
205 animGroup->start();
206
207 return root;
208}
@ Triangles
Triangle based rendering (default).
Definition qgis.h:4376
QFlags< InstancedMaterialFlag > InstancedMaterialFlags
Definition qgis.h:4398
Rendering context for preparation of 3D entities.
QColor selectionColor() const
Returns color used for selected features.
Qgis::TextureFilterQuality textureFilterQuality() const
Returns the texture filtering quality.
virtual Qt3DCore::QEntity * createPreviewScene(const QgsAbstractMaterialSettings *settings, const QString &type, const QgsMaterialContext &context, QWindow *window, Qt3DCore::QEntity *parent) const
Builds a complete self-contained scene for previewing the material, using the specified mesh type.
static Qt3DRender::QParameter * findParameter(Qt3DRender::QEffect *effect, const QString &name)
Finds an existing parameter in an effect by name.
virtual void applyDataDefinedToGeometry(const QgsAbstractMaterialSettings *settings, Qt3DCore::QGeometry *geometry, int vertexCount, const QByteArray &dataDefinedBytes) const
Applies the data defined bytes, dataDefinedBytes, on the geometry by filling a specific vertex buffer...
virtual Qt3DCore::QEntity * createPreviewMesh(const QString &type, Qt3DCore::QEntity *parent) const
Creates a new entity representing a suitable preview mesh for this material type.
virtual QgsMaterial * toMaterial(const QgsAbstractMaterialSettings *settings, Qgis::MaterialRenderingTechnique technique, const QgsMaterialContext &context) const =0
Creates a new QgsMaterial object representing the material settings.
virtual QList< PreviewMeshType > previewMeshTypes() const
Returns a list of available preview mesh types for the material.
virtual QByteArray dataDefinedVertexColorsAsByte(const QgsAbstractMaterialSettings *settings, const QgsExpressionContext &expressionContext) const
Returns byte array corresponding to the data defined colors depending of the expressionContext,...
virtual QgsMaterial * toInstancedMaterial(const QgsAbstractMaterialSettings *settings, const QgsMaterialContext &context, Qgis::InstancedMaterialFlags flags, const QMatrix4x4 &transform=QMatrix4x4()) const
Creates a QgsMaterial for instanced point rendering.
Abstract base class for material settings.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Context settings for a material.
void setIsPreview(bool isPreview)
Sets whether the material is being shown in a preview widget.
bool isPreview() const
Returns true if the material is being shown in a preview widget.
static QgsMaterialContext fromRenderContext(const Qgs3DRenderContext &context)
Constructs a material context from the settings in a 3D render context.
Base class for all materials used within QGIS 3D views.
Definition qgsmaterial.h:40
Encapsulates information about available preview meshes.
QString displayName
Translated, user-friendly name.