18#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) 
   19#include <Qt3DRender/QAttribute> 
   20#include <Qt3DRender/QBuffer> 
   21#include <Qt3DRender/QGeometry> 
   27#include <Qt3DCore/QAttribute> 
   28#include <Qt3DCore/QBuffer> 
   29#include <Qt3DCore/QGeometry> 
   36#include <Qt3DRender/QEffect> 
   37#include <Qt3DRender/QGraphicsApiFilter> 
   38#include <Qt3DRender/QParameter> 
   39#include <Qt3DRender/QTechnique> 
   41#include <Qt3DExtras/QCylinderGeometry> 
   42#include <Qt3DExtras/QConeGeometry> 
   43#include <Qt3DExtras/QCuboidGeometry> 
   44#include <Qt3DExtras/QPlaneGeometry> 
   45#include <Qt3DExtras/QSphereGeometry> 
   46#include <Qt3DExtras/QTorusGeometry> 
   47#include <Qt3DExtras/QPhongMaterial> 
   48#include <Qt3DRender/QSceneLoader> 
   49#include <Qt3DRender/QPaintedTextureImage> 
   51#include <Qt3DRender/QMesh> 
   53#include <Qt3DExtras/QExtrudedTextGeometry> 
   73class QgsInstancedPoint3DSymbolHandler : 
public QgsFeature3DHandler
 
   78      , mSelectedIds( selectedIds ) {}
 
   82    void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
 
   86    static Qt3DRender::QGeometryRenderer *renderer( 
const QgsPoint3DSymbol *symbol, 
const QVector<QVector3D> &positions );
 
   92        QVector<QVector3D> positions; 
 
   95    void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PointData &out, 
bool selected );
 
   98    std::unique_ptr<QgsPoint3DSymbol> mSymbol;
 
  107    PointData outSelected; 
 
  111bool QgsInstancedPoint3DSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames, 
const QgsVector3D &chunkOrigin )
 
  114  Q_UNUSED( attributeNames )
 
  116  mChunkOrigin = chunkOrigin;
 
  123  PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
 
  132void QgsInstancedPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
 
  134  makeEntity( parent, context, outNormal, 
false );
 
  135  makeEntity( parent, context, outSelected, 
true );
 
  137  updateZRangeFromPositions( outNormal.positions );
 
  138  updateZRangeFromPositions( outSelected.positions );
 
  141  const float symbolOffset = mSymbol->transform().data()[14];
 
  145  switch ( mSymbol->shape() )
 
  149      const float length = mSymbol->shapeProperty( QStringLiteral( 
"length" ) ).toFloat();
 
  150      mZMin -= length * 0.5f;
 
  151      mZMax += length * 0.5f;
 
  157      const float radius = mSymbol->shapeProperty( QStringLiteral( 
"radius" ) ).toFloat();
 
  165      const float length = mSymbol->shapeProperty( QStringLiteral( 
"length" ) ).toFloat();
 
  166      mZMin -= length * 0.5f;
 
  167      mZMax += length * 0.5f;
 
  173      const float size = mSymbol->shapeProperty( QStringLiteral( 
"size" ) ).toFloat();
 
  174      mZMin -= size * 0.5f;
 
  175      mZMax += size * 0.5f;
 
  181      const float radius = mSymbol->shapeProperty( QStringLiteral( 
"radius" ) ).toFloat();
 
  191      const float size = mSymbol->shapeProperty( QStringLiteral( 
"size" ) ).toFloat();
 
  192      mZMin -= size * 0.5f;
 
  193      mZMax += size * 0.5f;
 
  203  mZMin += symbolOffset;
 
  204  mZMax += symbolOffset;
 
  207void QgsInstancedPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PointData &out, 
bool selected )
 
  213  QgsMaterial *mat = material( mSymbol.get(), materialContext );
 
  216  QgsGeoTransform *tr = 
new QgsGeoTransform;
 
  217  tr->setGeoTranslation( mChunkOrigin );
 
  220  Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  221  entity->addComponent( renderer( mSymbol.get(), out.positions ) );
 
  222  entity->addComponent( mat );
 
  223  entity->addComponent( tr );
 
  224  entity->setParent( parent );
 
  233  Qt3DRender::QFilterKey *filterKey = 
new Qt3DRender::QFilterKey;
 
  234  filterKey->setName( QStringLiteral( 
"renderingStyle" ) );
 
  235  filterKey->setValue( 
"forward" );
 
  237  Qt3DRender::QShaderProgram *shaderProgram = 
new Qt3DRender::QShaderProgram;
 
  238  shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( 
"qrc:/shaders/instanced.vert" ) ) ) );
 
  239  shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( 
"qrc:/shaders/phong.frag" ) ) ) );
 
  241  Qt3DRender::QRenderPass *renderPass = 
new Qt3DRender::QRenderPass;
 
  242  renderPass->setShaderProgram( shaderProgram );
 
  244  Qt3DRender::QTechnique *technique = 
new Qt3DRender::QTechnique;
 
  245  technique->addFilterKey( filterKey );
 
  246  technique->addRenderPass( renderPass );
 
  247  technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
 
  248  technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
 
  249  technique->graphicsApiFilter()->setMajorVersion( 3 );
 
  250  technique->graphicsApiFilter()->setMinorVersion( 2 );
 
  252  const QMatrix4x4 transformMatrix = symbol->
transform();
 
  253  QMatrix3x3 normalMatrix = transformMatrix.normalMatrix(); 
 
  256  float *n = normalMatrix.data();
 
  257  const QMatrix4x4 normalMatrix4(
 
  264  Qt3DRender::QParameter *paramInst = 
new Qt3DRender::QParameter;
 
  265  paramInst->setName( QStringLiteral( 
"inst" ) );
 
  266  paramInst->setValue( transformMatrix );
 
  268  Qt3DRender::QParameter *paramInstNormal = 
new Qt3DRender::QParameter;
 
  269  paramInstNormal->setName( QStringLiteral( 
"instNormal" ) );
 
  270  paramInstNormal->setValue( normalMatrix4 );
 
  272  Qt3DRender::QEffect *effect = 
new Qt3DRender::QEffect;
 
  273  effect->addTechnique( technique );
 
  274  effect->addParameter( paramInst );
 
  275  effect->addParameter( paramInstNormal );
 
  280  material->setEffect( effect );
 
  285Qt3DRender::QGeometryRenderer *QgsInstancedPoint3DSymbolHandler::renderer( 
const QgsPoint3DSymbol *symbol, 
const QVector<QVector3D> &positions )
 
  287  const int count = positions.count();
 
  288  const int byteCount = positions.count() * 
sizeof( QVector3D );
 
  290  ba.resize( byteCount );
 
  291  memcpy( ba.data(), positions.constData(), byteCount );
 
  294  instanceBuffer->setData( ba );
 
  297  instanceDataAttribute->setName( QStringLiteral( 
"pos" ) );
 
  298  instanceDataAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
 
  299  instanceDataAttribute->setVertexBaseType( Qt3DQAttribute::Float );
 
  300  instanceDataAttribute->setVertexSize( 3 );
 
  301  instanceDataAttribute->setByteOffset( 0 );
 
  302  instanceDataAttribute->setDivisor( 1 );
 
  303  instanceDataAttribute->setBuffer( instanceBuffer );
 
  304  instanceDataAttribute->setCount( count );
 
  305  instanceDataAttribute->setByteStride( 3 * 
sizeof( 
float ) );
 
  308  geometry->addAttribute( instanceDataAttribute );
 
  309  geometry->setBoundingVolumePositionAttribute( instanceDataAttribute );
 
  311  Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
 
  312  renderer->setGeometry( geometry );
 
  313  renderer->setInstanceCount( count );
 
  320  switch ( symbol->
shape() )
 
  324      const float radius = symbol->
shapeProperty( QStringLiteral( 
"radius" ) ).toFloat();
 
  325      const float length = symbol->
shapeProperty( QStringLiteral( 
"length" ) ).toFloat();
 
  326      Qt3DExtras::QCylinderGeometry *g = 
new Qt3DExtras::QCylinderGeometry;
 
  329      g->setRadius( radius );
 
  330      g->setLength( length );
 
  336      const float radius = symbol->
shapeProperty( QStringLiteral( 
"radius" ) ).toFloat();
 
  337      Qt3DExtras::QSphereGeometry *g = 
new Qt3DExtras::QSphereGeometry;
 
  338      g->setRadius( radius );
 
  344      const float length = symbol->
shapeProperty( QStringLiteral( 
"length" ) ).toFloat();
 
  345      const float bottomRadius = symbol->
shapeProperty( QStringLiteral( 
"bottomRadius" ) ).toFloat();
 
  346      const float topRadius = symbol->
shapeProperty( QStringLiteral( 
"topRadius" ) ).toFloat();
 
  348      Qt3DExtras::QConeGeometry *g = 
new Qt3DExtras::QConeGeometry;
 
  349      g->setLength( length );
 
  350      g->setBottomRadius( bottomRadius );
 
  351      g->setTopRadius( topRadius );
 
  359      const float size = symbol->
shapeProperty( QStringLiteral( 
"size" ) ).toFloat();
 
  360      Qt3DExtras::QCuboidGeometry *g = 
new Qt3DExtras::QCuboidGeometry;
 
  361      g->setXExtent( size );
 
  362      g->setYExtent( size );
 
  363      g->setZExtent( size );
 
  369      const float radius = symbol->
shapeProperty( QStringLiteral( 
"radius" ) ).toFloat();
 
  370      const float minorRadius = symbol->
shapeProperty( QStringLiteral( 
"minorRadius" ) ).toFloat();
 
  371      Qt3DExtras::QTorusGeometry *g = 
new Qt3DExtras::QTorusGeometry;
 
  372      g->setRadius( radius );
 
  373      g->setMinorRadius( minorRadius );
 
  379      const float size = symbol->
shapeProperty( QStringLiteral( 
"size" ) ).toFloat();
 
  380      Qt3DExtras::QPlaneGeometry *g = 
new Qt3DExtras::QPlaneGeometry;
 
  382      g->setHeight( size );
 
  388      const float depth = symbol->
shapeProperty( QStringLiteral( 
"depth" ) ).toFloat();
 
  389      const QString text = symbol->
shapeProperty( QStringLiteral( 
"text" ) ).toString();
 
  390      Qt3DExtras::QExtrudedTextGeometry *g = 
new Qt3DExtras::QExtrudedTextGeometry;
 
  391      g->setDepth( depth );
 
  407class QgsModelPoint3DSymbolHandler : 
public QgsFeature3DHandler
 
  412      , mSelectedIds( selectedIds ) {}
 
  416    void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
 
  426        QVector<QVector3D> positions; 
 
  429    void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PointData &out, 
bool selected );
 
  432    std::unique_ptr<QgsPoint3DSymbol> mSymbol;
 
  441    PointData outSelected; 
 
  444bool QgsModelPoint3DSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames, 
const QgsVector3D &chunkOrigin )
 
  447  Q_UNUSED( attributeNames )
 
  449  mChunkOrigin = chunkOrigin;
 
  456  PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
 
  465void QgsModelPoint3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
 
  467  makeEntity( parent, context, outNormal, 
false );
 
  468  makeEntity( parent, context, outSelected, 
true );
 
  470  updateZRangeFromPositions( outNormal.positions );
 
  471  updateZRangeFromPositions( outSelected.positions );
 
  474  const float symbolHeight = mSymbol->transform().data()[14];
 
  475  mZMin += symbolHeight;
 
  476  mZMax += symbolHeight;
 
  479void QgsModelPoint3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PointData &out, 
bool selected )
 
  483    addMeshEntities( context, out.positions, mChunkOrigin, mSymbol.get(), parent, 
true );
 
  488    if ( mSymbol->shapeProperty( QStringLiteral( 
"overwriteMaterial" ) ).toBool()
 
  489         || ( mSymbol->materialSettings() && mSymbol->materialSettings()->type() != QLatin1String( 
"null" ) ) )
 
  491      addMeshEntities( context, out.positions, mChunkOrigin, mSymbol.get(), parent, 
false );
 
  495      addSceneEntities( context, out.positions, mChunkOrigin, mSymbol.get(), parent );
 
  504  for ( 
const QVector3D &position : positions )
 
  508    if ( !source.isEmpty() )
 
  511      Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  513      const QUrl url = QUrl::fromLocalFile( source );
 
  514      Qt3DRender::QSceneLoader *modelLoader = 
new Qt3DRender::QSceneLoader;
 
  515      modelLoader->setSource( url );
 
  517      entity->addComponent( modelLoader );
 
  518      entity->addComponent( transform( position, symbol, chunkOrigin ) );
 
  519      entity->setParent( parent );
 
  527void QgsModelPoint3DSymbolHandler::addMeshEntities( 
const Qgs3DRenderContext &context, 
const QVector<QVector3D> &positions, 
const QgsVector3D &chunkOrigin, 
const QgsPoint3DSymbol *symbol, Qt3DCore::QEntity *parent, 
bool are_selected )
 
  529  if ( positions.empty() )
 
  539  for ( 
const QVector3D &position : positions )
 
  542    if ( !source.isEmpty() )
 
  545      Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  547      const QUrl url = QUrl::fromLocalFile( source );
 
  548      Qt3DRender::QMesh *mesh = 
new Qt3DRender::QMesh;
 
  549      mesh->setSource( url );
 
  551      entity->addComponent( mesh );
 
  552      entity->addComponent( mat );
 
  553      entity->addComponent( transform( position, symbol, chunkOrigin ) );
 
  554      entity->setParent( parent );
 
  562QgsGeoTransform *QgsModelPoint3DSymbolHandler::transform( QVector3D position, 
const QgsPoint3DSymbol *symbol, 
const QgsVector3D &chunkOrigin )
 
  565  QgsGeoTransform *tr = 
new QgsGeoTransform;
 
  567  tr->setGeoTranslation( chunkOrigin + position + tr->translation() );
 
  575class QgsPoint3DBillboardSymbolHandler : 
public QgsFeature3DHandler
 
  580      , mSelectedIds( selectedIds ) {}
 
  584    void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
 
  590        QVector<QVector3D> positions; 
 
  593    void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PointData &out, 
bool selected );
 
  596    std::unique_ptr<QgsPoint3DSymbol> mSymbol;
 
  605    PointData outSelected; 
 
  608bool QgsPoint3DBillboardSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames, 
const QgsVector3D &chunkOrigin )
 
  611  Q_UNUSED( attributeNames )
 
  613  mChunkOrigin = chunkOrigin;
 
  620  PointData &out = mSelectedIds.contains( feature.
id() ) ? outSelected : outNormal;
 
  629void QgsPoint3DBillboardSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
 
  631  makeEntity( parent, context, outNormal, 
false );
 
  632  makeEntity( parent, context, outSelected, 
true );
 
  634  updateZRangeFromPositions( outNormal.positions );
 
  635  updateZRangeFromPositions( outSelected.positions );
 
  638  const float billboardHeight = mSymbol->billboardHeight();
 
  639  mZMin += billboardHeight;
 
  640  mZMax += billboardHeight;
 
  643void QgsPoint3DBillboardSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PointData &out, 
bool selected )
 
  647  billboardGeometry->
setPoints( out.positions );
 
  650  Qt3DRender::QGeometryRenderer *billboardGeometryRenderer = 
new Qt3DRender::QGeometryRenderer;
 
  651  billboardGeometryRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::Points );
 
  652  billboardGeometryRenderer->setGeometry( billboardGeometry );
 
  653  billboardGeometryRenderer->setVertexCount( billboardGeometry->
count() );
 
  669  QgsGeoTransform *billboardTransform = 
new QgsGeoTransform;
 
  670  billboardTransform->setGeoTranslation( mChunkOrigin + 
QgsVector3D( 0, 0, mSymbol->billboardHeight() ) );
 
  673  Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  675  entity->addComponent( billboardMaterial );
 
  676  entity->addComponent( billboardTransform );
 
  677  entity->addComponent( billboardGeometryRenderer );
 
  678  entity->setParent( parent );
 
  685namespace Qgs3DSymbolImpl
 
  698      return new QgsPoint3DBillboardSymbolHandler( pointSymbol, layer->
selectedFeatureIds() );
 
  700      return new QgsInstancedPoint3DSymbolHandler( pointSymbol, layer->
selectedFeatureIds() );
 
@ ExtrudedText
Extruded text.
 
QColor selectionColor() const
Returns color used for selected features.
 
static void extractPointPositions(const QgsFeature &f, const Qgs3DRenderContext &context, const QgsVector3D &chunkOrigin, Qgis::AltitudeClamping altClamp, QVector< QVector3D > &positions)
Calculates (x,y,z) positions of (multi)point from the given feature.
 
virtual void addParametersToEffect(Qt3DRender::QEffect *effect, const QgsMaterialContext &materialContext) const =0
Adds parameters from the material to a destination effect.
 
virtual QgsMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const =0
Creates a new QgsMaterial object representing the material settings.
 
static QgsSourceCache * sourceCache()
Returns the application's source cache, used for caching embedded and remote source strings as local ...
 
void setPoints(const QVector< QVector3D > &vertices)
Set the points for the billboard with vertices.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
A marker symbol type, for rendering Point and MultiPoint geometries.
 
void setIsSelected(bool isSelected)
Sets whether the material should represent a selected state.
 
void setSelectionColor(const QColor &color)
Sets the color for representing materials in a selected state.
 
void useDefaultSymbol(const Qgs3DRenderContext &context, bool selected=false)
Set default symbol for the texture with context and selected parameter for rendering.
 
void setTexture2DFromSymbol(QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected=false)
Set markerSymbol for the texture with context and selected parameter for rendering.
 
QgsAbstractMaterialSettings * materialSettings() const
Returns material settings used for shading of the symbol.
 
QMatrix4x4 transform() const
Returns transform for individual objects represented by the symbol.
 
QgsMarkerSymbol * billboardSymbol() const
Returns a symbol for billboard.
 
Qgis::Point3DShape shape() const
Returns 3D shape for points.
 
QgsAbstract3DSymbol * clone() const override
Returns a new instance of the symbol with the same settings.
 
QVariant shapeProperty(const QString &property) const
Returns the value for a specific shape property.
 
QString localFilePath(const QString &path, bool blocking=false)
Returns a local file path reflecting the content of a specified source path.
 
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
 
Represents a vector layer which manages a vector based data sets.
 
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
 
@ Triangles
Triangle based rendering (default)
 
Qt3DCore::QAttribute Qt3DQAttribute
 
Qt3DCore::QBuffer Qt3DQBuffer
 
Qt3DCore::QGeometry Qt3DQGeometry
 
QSet< QgsFeatureId > QgsFeatureIds
 
Qt3DCore::QAttribute Qt3DQAttribute
 
Qt3DCore::QBuffer Qt3DQBuffer
 
Qt3DCore::QGeometry Qt3DQGeometry