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> 33 #include <Qt3DRender/QPaintedTextureImage> 35 #include <Qt3DRender/QMesh> 37 #if QT_VERSION >= 0x050900 38 #include <Qt3DExtras/QExtrudedTextGeometry> 63 class QgsInstancedPoint3DSymbolHandler :
public QgsFeature3DHandler
67 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
69 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
70 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
71 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
76 static Qt3DRender::QGeometryRenderer *renderer(
const QgsPoint3DSymbol &symbol,
const QVector<QVector3D> &positions );
77 static Qt3DRender::QGeometry *symbolGeometry(
QgsPoint3DSymbol::Shape shape,
const QVariantMap &shapeProperties );
82 QVector<QVector3D> positions;
85 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected );
94 PointData outSelected;
98 bool QgsInstancedPoint3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
101 Q_UNUSED( attributeNames )
105 void QgsInstancedPoint3DSymbolHandler::processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
107 PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
115 void QgsInstancedPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
117 makeEntity( parent, context, outNormal,
false );
118 makeEntity( parent, context, outSelected,
true );
120 updateZRangeFromPositions( outNormal.positions );
121 updateZRangeFromPositions( outSelected.positions );
124 float symbolHeight = mSymbol.transform().data()[13];
125 mZMin += symbolHeight;
126 mZMax += symbolHeight;
129 void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected )
132 Qt3DRender::QMaterial *mat = material( mSymbol );
137 for ( Qt3DRender::QParameter *param : mat->effect()->parameters() )
139 if ( param->name() == QLatin1String(
"kd" ) )
140 param->setValue( context.map().selectionColor() );
141 else if ( param->name() == QLatin1String(
"ka" ) )
142 param->setValue( context.map().selectionColor().darker() );
147 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
148 entity->addComponent( renderer( mSymbol, out.positions ) );
149 entity->addComponent( mat );
150 entity->setParent( parent );
155 Qt3DRender::QMaterial *QgsInstancedPoint3DSymbolHandler::material(
const QgsPoint3DSymbol &symbol )
157 Qt3DRender::QFilterKey *filterKey =
new Qt3DRender::QFilterKey;
158 filterKey->setName( QStringLiteral(
"renderingStyle" ) );
159 filterKey->setValue(
"forward" );
164 Qt3DRender::QShaderProgram *shaderProgram =
new Qt3DRender::QShaderProgram;
165 shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral(
"qrc:/shaders/instanced.vert" ) ) ) );
166 shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral(
"qrc:/shaders/instanced.frag" ) ) ) );
168 Qt3DRender::QRenderPass *renderPass =
new Qt3DRender::QRenderPass;
169 renderPass->setShaderProgram( shaderProgram );
171 Qt3DRender::QTechnique *technique =
new Qt3DRender::QTechnique;
172 technique->addFilterKey( filterKey );
173 technique->addRenderPass( renderPass );
174 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
175 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
176 technique->graphicsApiFilter()->setMajorVersion( 3 );
177 technique->graphicsApiFilter()->setMinorVersion( 2 );
179 Qt3DRender::QParameter *ambientParameter =
new Qt3DRender::QParameter( QStringLiteral(
"ka" ), QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) );
180 Qt3DRender::QParameter *diffuseParameter =
new Qt3DRender::QParameter( QStringLiteral(
"kd" ), QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) );
181 Qt3DRender::QParameter *specularParameter =
new Qt3DRender::QParameter( QStringLiteral(
"ks" ), QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) );
182 Qt3DRender::QParameter *shininessParameter =
new Qt3DRender::QParameter( QStringLiteral(
"shininess" ), 150.0f );
189 QMatrix4x4 transformMatrix = symbol.
transform();
190 QMatrix3x3 normalMatrix = transformMatrix.normalMatrix();
193 float *n = normalMatrix.data();
194 QMatrix4x4 normalMatrix4(
200 Qt3DRender::QParameter *paramInst =
new Qt3DRender::QParameter;
201 paramInst->setName( QStringLiteral(
"inst" ) );
202 paramInst->setValue( transformMatrix );
204 Qt3DRender::QParameter *paramInstNormal =
new Qt3DRender::QParameter;
205 paramInstNormal->setName( QStringLiteral(
"instNormal" ) );
206 paramInstNormal->setValue( normalMatrix4 );
208 Qt3DRender::QEffect *effect =
new Qt3DRender::QEffect;
209 effect->addTechnique( technique );
210 effect->addParameter( paramInst );
211 effect->addParameter( paramInstNormal );
213 effect->addParameter( ambientParameter );
214 effect->addParameter( diffuseParameter );
215 effect->addParameter( specularParameter );
216 effect->addParameter( shininessParameter );
218 Qt3DRender::QMaterial *material =
new Qt3DRender::QMaterial;
219 material->setEffect( effect );
224 Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer(
const QgsPoint3DSymbol &symbol,
const QVector<QVector3D> &positions )
226 int count = positions.count();
227 int byteCount = positions.count() *
sizeof( QVector3D );
229 ba.resize( byteCount );
230 memcpy( ba.data(), positions.constData(), byteCount );
232 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) 233 Qt3DRender::QBuffer *instanceBuffer =
new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer );
235 Qt3DRender::QBuffer *instanceBuffer =
new Qt3DRender::QBuffer();
237 instanceBuffer->setData( ba );
239 Qt3DRender::QAttribute *instanceDataAttribute =
new Qt3DRender::QAttribute;
240 instanceDataAttribute->setName( QStringLiteral(
"pos" ) );
241 instanceDataAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
242 instanceDataAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
243 instanceDataAttribute->setVertexSize( 3 );
244 instanceDataAttribute->setDivisor( 1 );
245 instanceDataAttribute->setBuffer( instanceBuffer );
246 instanceDataAttribute->setCount( count );
247 instanceDataAttribute->setByteStride( 3 *
sizeof(
float ) );
250 geometry->addAttribute( instanceDataAttribute );
251 geometry->setBoundingVolumePositionAttribute( instanceDataAttribute );
253 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
254 renderer->setGeometry( geometry );
255 renderer->setInstanceCount( count );
260 Qt3DRender::QGeometry *QgsInstancedPoint3DSymbolHandler::symbolGeometry(
QgsPoint3DSymbol::Shape shape,
const QVariantMap &shapeProperties )
266 float radius = shapeProperties[QStringLiteral(
"radius" )].toFloat();
267 float length = shapeProperties[QStringLiteral(
"length" )].toFloat();
268 Qt3DExtras::QCylinderGeometry *g =
new Qt3DExtras::QCylinderGeometry;
271 g->setRadius( radius ? radius : 10 );
272 g->setLength( length ? length : 10 );
278 float radius = shapeProperties[QStringLiteral(
"radius" )].toFloat();
279 Qt3DExtras::QSphereGeometry *g =
new Qt3DExtras::QSphereGeometry;
280 g->setRadius( radius ? radius : 10 );
286 float length = shapeProperties[QStringLiteral(
"length" )].toFloat();
287 float bottomRadius = shapeProperties[QStringLiteral(
"bottomRadius" )].toFloat();
288 float topRadius = shapeProperties[QStringLiteral(
"topRadius" )].toFloat();
289 Qt3DExtras::QConeGeometry *g =
new Qt3DExtras::QConeGeometry;
290 g->setLength( length ? length : 10 );
291 g->setBottomRadius( bottomRadius );
292 g->setTopRadius( topRadius );
300 float size = shapeProperties[QStringLiteral(
"size" )].toFloat();
301 Qt3DExtras::QCuboidGeometry *g =
new Qt3DExtras::QCuboidGeometry;
302 g->setXExtent( size ? size : 10 );
303 g->setYExtent( size ? size : 10 );
304 g->setZExtent( size ? size : 10 );
310 float radius = shapeProperties[QStringLiteral(
"radius" )].toFloat();
311 float minorRadius = shapeProperties[QStringLiteral(
"minorRadius" )].toFloat();
312 Qt3DExtras::QTorusGeometry *g =
new Qt3DExtras::QTorusGeometry;
313 g->setRadius( radius ? radius : 10 );
314 g->setMinorRadius( minorRadius ? minorRadius : 5 );
320 float size = shapeProperties[QStringLiteral(
"size" )].toFloat();
321 Qt3DExtras::QPlaneGeometry *g =
new Qt3DExtras::QPlaneGeometry;
322 g->setWidth( size ? size : 10 );
323 g->setHeight( size ? size : 10 );
327 #if QT_VERSION >= 0x050900 330 float depth = shapeProperties[QStringLiteral(
"depth" )].toFloat();
331 QString text = shapeProperties[QStringLiteral(
"text" )].toString();
332 Qt3DExtras::QExtrudedTextGeometry *g =
new Qt3DExtras::QExtrudedTextGeometry;
333 g->setDepth( depth ? depth : 1 );
348 class QgsModelPoint3DSymbolHandler :
public QgsFeature3DHandler
352 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
354 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
355 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
356 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
360 static void addSceneEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent );
361 static void addMeshEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent,
bool are_selected );
362 static Qt3DCore::QTransform *transform( QVector3D position,
const QgsPoint3DSymbol &symbol );
367 QVector<QVector3D> positions;
370 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected );
379 PointData outSelected;
382 bool QgsModelPoint3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
385 Q_UNUSED( attributeNames )
389 void QgsModelPoint3DSymbolHandler::processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
391 PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
399 void QgsModelPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
401 makeEntity( parent, context, outNormal,
false );
402 makeEntity( parent, context, outSelected,
true );
404 updateZRangeFromPositions( outNormal.positions );
405 updateZRangeFromPositions( outSelected.positions );
408 float symbolHeight = mSymbol.transform().data()[13];
409 mZMin += symbolHeight;
410 mZMax += symbolHeight;
413 void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected )
417 addMeshEntities( context.map(), out.positions, mSymbol, parent, true );
421 if ( mSymbol.shapeProperties()[QStringLiteral(
"overwriteMaterial" )].toBool() )
423 addMeshEntities( context.map(), out.positions, mSymbol, parent, false );
427 addSceneEntities( context.map(), out.positions, mSymbol, parent );
434 void QgsModelPoint3DSymbolHandler::addSceneEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent )
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::QSceneLoader *modelLoader =
new Qt3DRender::QSceneLoader;
444 modelLoader->setSource( url );
446 entity->addComponent( modelLoader );
447 entity->addComponent( transform( position, symbol ) );
448 entity->setParent( parent );
452 void QgsModelPoint3DSymbolHandler::addMeshEntities(
const Qgs3DMapSettings &map,
const QVector<QVector3D> &positions,
const QgsPoint3DSymbol &symbol, Qt3DCore::QEntity *parent,
bool are_selected )
464 for (
const QVector3D &position : positions )
467 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
469 QUrl url = QUrl::fromLocalFile( symbol.
shapeProperties()[QStringLiteral(
"model" )].toString() );
470 Qt3DRender::QMesh *mesh =
new Qt3DRender::QMesh;
471 mesh->setSource( url );
473 entity->addComponent( mesh );
474 entity->addComponent( mat );
475 entity->addComponent( transform( position, symbol ) );
476 entity->setParent( parent );
480 Qt3DCore::QTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position,
const QgsPoint3DSymbol &symbol )
482 Qt3DCore::QTransform *tr =
new Qt3DCore::QTransform;
484 tr->setTranslation( position + tr->translation() );
492 class QgsPoint3DBillboardSymbolHandler :
public QgsFeature3DHandler
496 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
498 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
499 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
500 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
507 QVector<QVector3D> positions;
510 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected );
519 PointData outSelected;
522 bool QgsPoint3DBillboardSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
525 Q_UNUSED( attributeNames )
529 void QgsPoint3DBillboardSymbolHandler::processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
531 PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
539 void QgsPoint3DBillboardSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
541 makeEntity( parent, context, outNormal,
false );
542 makeEntity( parent, context, outSelected,
true );
544 updateZRangeFromPositions( outNormal.positions );
545 updateZRangeFromPositions( outSelected.positions );
548 float billboardHeight = mSymbol.transform().data()[13];
549 mZMin += billboardHeight;
550 mZMax += billboardHeight;
553 void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, PointData &out,
bool selected )
557 billboardGeometry->
setPoints( out.positions );
560 Qt3DRender::QGeometryRenderer *billboardGeometryRenderer =
new Qt3DRender::QGeometryRenderer;
561 billboardGeometryRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::Points );
562 billboardGeometryRenderer->setGeometry( billboardGeometry );
563 billboardGeometryRenderer->setVertexCount( billboardGeometry->
count() );
579 Qt3DCore::QTransform *billboardTransform =
new Qt3DCore::QTransform();
580 billboardTransform->setMatrix( mSymbol.billboardTransform() );
583 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
585 entity->addComponent( billboardMaterial );
586 entity->addComponent( billboardTransform );
587 entity->addComponent( billboardGeometryRenderer );
588 entity->setParent( parent );
592 namespace Qgs3DSymbolImpl
608 QgsFeature3DHandler *handler = handlerForPoint3DSymbol( layer, symbol );
609 Qt3DCore::QEntity *e = entityFromHandler( handler, map, layer );
3 Material of the billboard rendering for points in 3D map view.
float shininess() const
Returns shininess of the surface.
void useDefaultSymbol(const Qgs3DMapSettings &map, bool selected=false)
Set default symbol for the texture with map and selected parameter for rendering. ...
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.
3 Geometry of the billboard rendering for points in 3D map view.
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
A marker symbol type, for rendering Point and MultiPoint geometries.
QMatrix4x4 transform() const
Returns transform for individual objects represented by the symbol.
void setTexture2DFromSymbol(QgsMarkerSymbol *markerSymbol, const Qgs3DMapSettings &map, bool selected=false)
Set markerSymbol for the texture with map and selected parameter for rendering.
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.
Q_INVOKABLE 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.
QgsMarkerSymbol * billboardSymbol() const
Returns a symbol for billboard.
Shape
3D shape types supported by the symbol
void setPoints(const QVector< QVector3D > &vertices)
Set the points for the billboard with vertices.
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.