18 #include <Qt3DRender/QAttribute> 19 #include <Qt3DRender/QBuffer> 20 #include <Qt3DRender/QEffect> 21 #include <Qt3DRender/QGraphicsApiFilter> 22 #include <Qt3DRender/QParameter> 23 #include <Qt3DRender/QTechnique> 25 #include <Qt3DExtras/QCylinderGeometry> 26 #include <Qt3DExtras/QConeGeometry> 27 #include <Qt3DExtras/QCuboidGeometry> 28 #include <Qt3DExtras/QPlaneGeometry> 29 #include <Qt3DExtras/QSphereGeometry> 30 #include <Qt3DExtras/QTorusGeometry> 31 #include <Qt3DExtras/QPhongMaterial> 32 #include <Qt3DRender/QSceneLoader> 34 #include <Qt3DRender/QMesh> 36 #if QT_VERSION >= 0x050900 37 #include <Qt3DExtras/QExtrudedTextGeometry> 56 class QgsInstancedPoint3DSymbolHandler :
public QgsFeature3DHandler
60 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
62 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
63 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
64 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
69 static Qt3DRender::QGeometryRenderer *renderer(
const QgsPoint3DSymbol &symbol,
const QVector<QVector3D> &positions );
70 static Qt3DRender::QGeometry *symbolGeometry(
QgsPoint3DSymbol::Shape shape,
const QVariantMap &shapeProperties );
75 QVector<QVector3D> positions;
78 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected );
87 PointData outSelected;
91 bool QgsInstancedPoint3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
94 Q_UNUSED( attributeNames )
98 void QgsInstancedPoint3DSymbolHandler::processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
100 PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
108 void QgsInstancedPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
110 makeEntity( parent, context, outNormal,
false );
111 makeEntity( parent, context, outSelected,
true );
114 void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected )
117 Qt3DRender::QMaterial *mat = material( mSymbol );
122 for ( Qt3DRender::QParameter *param : mat->effect()->parameters() )
124 if ( param->name() == QLatin1String(
"kd" ) )
125 param->setValue( context.map().selectionColor() );
126 else if ( param->name() == QLatin1String(
"ka" ) )
127 param->setValue( context.map().selectionColor().darker() );
132 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
133 entity->addComponent( renderer( mSymbol, out.positions ) );
134 entity->addComponent( mat );
135 entity->setParent( parent );
140 Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material(
const QgsPoint3DSymbol &symbol )
142 Qt3DRender::QFilterKey *filterKey =
new Qt3DRender::QFilterKey;
143 filterKey->setName( QStringLiteral(
"renderingStyle" ) );
144 filterKey->setValue(
"forward" );
149 Qt3DRender::QShaderProgram *shaderProgram =
new Qt3DRender::QShaderProgram;
150 shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral(
"qrc:/shaders/instanced.vert" ) ) ) );
151 shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral(
"qrc:/shaders/instanced.frag" ) ) ) );
153 Qt3DRender::QRenderPass *renderPass =
new Qt3DRender::QRenderPass;
154 renderPass->setShaderProgram( shaderProgram );
156 Qt3DRender::QTechnique *technique =
new Qt3DRender::QTechnique;
157 technique->addFilterKey( filterKey );
158 technique->addRenderPass( renderPass );
159 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
160 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
161 technique->graphicsApiFilter()->setMajorVersion( 3 );
162 technique->graphicsApiFilter()->setMinorVersion( 2 );
164 Qt3DRender::QParameter *ambientParameter =
new Qt3DRender::QParameter( QStringLiteral(
"ka" ), QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) );
165 Qt3DRender::QParameter *diffuseParameter =
new Qt3DRender::QParameter( QStringLiteral(
"kd" ), QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) );
166 Qt3DRender::QParameter *specularParameter =
new Qt3DRender::QParameter( QStringLiteral(
"ks" ), QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) );
167 Qt3DRender::QParameter *shininessParameter =
new Qt3DRender::QParameter( QStringLiteral(
"shininess" ), 150.0f );
174 QMatrix4x4 transformMatrix = symbol.
transform();
175 QMatrix3x3 normalMatrix = transformMatrix.normalMatrix();
178 float *n = normalMatrix.data();
179 QMatrix4x4 normalMatrix4(
185 Qt3DRender::QParameter *paramInst =
new Qt3DRender::QParameter;
186 paramInst->setName( QStringLiteral(
"inst" ) );
187 paramInst->setValue( transformMatrix );
189 Qt3DRender::QParameter *paramInstNormal =
new Qt3DRender::QParameter;
190 paramInstNormal->setName( QStringLiteral(
"instNormal" ) );
191 paramInstNormal->setValue( normalMatrix4 );
193 Qt3DRender::QEffect *effect =
new Qt3DRender::QEffect;
194 effect->addTechnique( technique );
195 effect->addParameter( paramInst );
196 effect->addParameter( paramInstNormal );
198 effect->addParameter( ambientParameter );
199 effect->addParameter( diffuseParameter );
200 effect->addParameter( specularParameter );
201 effect->addParameter( shininessParameter );
203 Qt3DRender::QMaterial *material =
new Qt3DRender::QMaterial;
204 material->setEffect( effect );
209 Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer(
const QgsPoint3DSymbol &symbol,
const QVector<QVector3D> &positions )
211 int count = positions.count();
212 int byteCount = positions.count() *
sizeof( QVector3D );
214 ba.resize( byteCount );
215 memcpy( ba.data(), positions.constData(), byteCount );
217 Qt3DRender::QBuffer *instanceBuffer =
new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer );
218 instanceBuffer->setData( ba );
220 Qt3DRender::QAttribute *instanceDataAttribute =
new Qt3DRender::QAttribute;
221 instanceDataAttribute->setName( QStringLiteral(
"pos" ) );
222 instanceDataAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
223 instanceDataAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
224 instanceDataAttribute->setVertexSize( 3 );
225 instanceDataAttribute->setDivisor( 1 );
226 instanceDataAttribute->setBuffer( instanceBuffer );
227 instanceDataAttribute->setCount( count );
228 instanceDataAttribute->setByteStride( 3 *
sizeof(
float ) );
231 geometry->addAttribute( instanceDataAttribute );
232 geometry->setBoundingVolumePositionAttribute( instanceDataAttribute );
234 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
235 renderer->setGeometry( geometry );
236 renderer->setInstanceCount( count );
241 Qt3DRender::QGeometry *QgsInstancedPoint3DSymbolHandler::symbolGeometry(
QgsPoint3DSymbol::Shape shape,
const QVariantMap &shapeProperties )
247 float radius = shapeProperties[QStringLiteral(
"radius" )].toFloat();
248 float length = shapeProperties[QStringLiteral(
"length" )].toFloat();
249 Qt3DExtras::QCylinderGeometry *g =
new Qt3DExtras::QCylinderGeometry;
252 g->setRadius( radius ? radius : 10 );
253 g->setLength( length ? length : 10 );
259 float radius = shapeProperties[QStringLiteral(
"radius" )].toFloat();
260 Qt3DExtras::QSphereGeometry *g =
new Qt3DExtras::QSphereGeometry;
261 g->setRadius( radius ? radius : 10 );
267 float length = shapeProperties[QStringLiteral(
"length" )].toFloat();
268 float bottomRadius = shapeProperties[QStringLiteral(
"bottomRadius" )].toFloat();
269 float topRadius = shapeProperties[QStringLiteral(
"topRadius" )].toFloat();
270 Qt3DExtras::QConeGeometry *g =
new Qt3DExtras::QConeGeometry;
271 g->setLength( length ? length : 10 );
272 g->setBottomRadius( bottomRadius );
273 g->setTopRadius( topRadius );
281 float size = shapeProperties[QStringLiteral(
"size" )].toFloat();
282 Qt3DExtras::QCuboidGeometry *g =
new Qt3DExtras::QCuboidGeometry;
283 g->setXExtent( size ? size : 10 );
284 g->setYExtent( size ? size : 10 );
285 g->setZExtent( size ? size : 10 );
291 float radius = shapeProperties[QStringLiteral(
"radius" )].toFloat();
292 float minorRadius = shapeProperties[QStringLiteral(
"minorRadius" )].toFloat();
293 Qt3DExtras::QTorusGeometry *g =
new Qt3DExtras::QTorusGeometry;
294 g->setRadius( radius ? radius : 10 );
295 g->setMinorRadius( minorRadius ? minorRadius : 5 );
301 float size = shapeProperties[QStringLiteral(
"size" )].toFloat();
302 Qt3DExtras::QPlaneGeometry *g =
new Qt3DExtras::QPlaneGeometry;
303 g->setWidth( size ? size : 10 );
304 g->setHeight( size ? size : 10 );
308 #if QT_VERSION >= 0x050900 311 float depth = shapeProperties[QStringLiteral(
"depth" )].toFloat();
312 QString text = shapeProperties[QStringLiteral(
"text" )].toString();
313 Qt3DExtras::QExtrudedTextGeometry *g =
new Qt3DExtras::QExtrudedTextGeometry;
314 g->setDepth( depth ? depth : 1 );
329 class QgsModelPoint3DSymbolHandler :
public QgsFeature3DHandler
333 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
335 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
336 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
337 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
341 static void addSceneEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent );
342 static void addMeshEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent,
bool are_selected );
343 static Qt3DCore::QTransform *transform( QVector3D position,
const QgsPoint3DSymbol &symbol );
348 QVector<QVector3D> positions;
351 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected );
360 PointData outSelected;
363 bool QgsModelPoint3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
366 Q_UNUSED( attributeNames )
370 void QgsModelPoint3DSymbolHandler::processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
372 PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
380 void QgsModelPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
382 makeEntity( parent, context, outNormal,
false );
383 makeEntity( parent, context, outSelected,
true );
386 void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected )
390 addMeshEntities( context.map(), out.positions, mSymbol, parent, true );
394 if ( mSymbol.shapeProperties()[QStringLiteral(
"overwriteMaterial" )].toBool() )
396 addMeshEntities( context.map(), out.positions, mSymbol, parent, false );
400 addSceneEntities( context.map(), out.positions, mSymbol, parent );
407 void QgsModelPoint3DSymbolHandler::addSceneEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent )
410 for (
const QVector3D &position : positions )
413 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
415 QUrl url = QUrl::fromLocalFile( symbol.
shapeProperties()[QStringLiteral(
"model" )].toString() );
416 Qt3DRender::QSceneLoader *modelLoader =
new Qt3DRender::QSceneLoader;
417 modelLoader->setSource( url );
419 entity->addComponent( modelLoader );
420 entity->addComponent( transform( position, symbol ) );
421 entity->setParent( parent );
425 void QgsModelPoint3DSymbolHandler::addMeshEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent,
bool are_selected )
437 for (
const QVector3D &position : positions )
440 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
442 QUrl url = QUrl::fromLocalFile( symbol.
shapeProperties()[QStringLiteral(
"model" )].toString() );
443 Qt3DRender::QMesh *mesh =
new Qt3DRender::QMesh;
444 mesh->setSource( url );
446 entity->addComponent( mesh );
447 entity->addComponent( mat );
448 entity->addComponent( transform( position, symbol ) );
449 entity->setParent( parent );
453 Qt3DCore::QTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position,
const QgsPoint3DSymbol &symbol )
455 Qt3DCore::QTransform *tr =
new Qt3DCore::QTransform;
457 tr->setTranslation( position + tr->translation() );
464 namespace Qgs3DSymbolImpl
477 QgsFeature3DHandler *handler = handlerForPoint3DSymbol( layer, symbol );
478 Qt3DCore::QEntity *e = entityFromHandler( handler, map, layer );
float shininess() const
Returns shininess of the surface.
QSet< QgsFeatureId > QgsFeatureIds
QColor selectionColor() const
Returns color used for selected features.
QColor specular() const
Returns specular color component.
static Qt3DExtras::QPhongMaterial * phongMaterial(const QgsPhongMaterialSettings &settings)
Returns phong material object based on the material settings.
Shape shape() const
Returns 3D shape for points.
QVariantMap shapeProperties() const
Returns a key-value dictionary of point shape properties.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
3 Definition of the world
QMatrix4x4 transform() const
Returns transform for individual objects represented by the symbol.
static void extractPointPositions(QgsFeature &f, const Qgs3DMapSettings &map, Qgs3DTypes::AltitudeClamping altClamp, QVector< QVector3D > &positions)
Calculates (x,y,z) positions of (multi)point from the given feature.
const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
3 3D symbol that draws point geometries as 3D objects using one of the predefined shapes...
QgsPhongMaterialSettings material() const
Returns material used for shading of the symbol.
Shape
3D shape types supported by the symbol
QColor ambient() const
Returns ambient color component.
QColor diffuse() const
Returns diffuse color component.
Represents a vector layer which manages a vector based data sets.