37#include <Qt3DCore/QTransform> 
   38#include <Qt3DExtras/QPhongMaterial> 
   39#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) 
   40#include <Qt3DRender/QAttribute> 
   41#include <Qt3DRender/QBuffer> 
   47#include <Qt3DCore/QAttribute> 
   48#include <Qt3DCore/QBuffer> 
   54#include <Qt3DRender/QGeometryRenderer> 
   61class QgsBufferedLine3DSymbolHandler : 
public QgsFeature3DHandler
 
   66      , mSelectedIds( selectedIds ) {}
 
   70    void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
 
   76        std::unique_ptr<QgsTessellator> tessellator;
 
   77        QVector<QgsFeatureId> triangleIndexFids;
 
   78        QVector<uint> triangleIndexStartingIndices;
 
   83    void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, LineData &lineData, 
bool selected );
 
   86    std::unique_ptr<QgsLine3DSymbol> mSymbol;
 
   94    LineData mLineDataNormal;   
 
   95    LineData mLineDataSelected; 
 
  101  Q_UNUSED( attributeNames )
 
  103  mChunkOrigin = chunkOrigin;
 
  107  const float textureRotation = texturedMaterialSettings ? 
static_cast<float>( texturedMaterialSettings->
textureRotation() ) : 0;
 
  108  const bool requiresTextureCoordinates = texturedMaterialSettings ? texturedMaterialSettings->
requiresTextureCoordinates() : 
false;
 
  109  mLineDataNormal.tessellator.reset( 
new QgsTessellator( chunkOrigin.
x(), chunkOrigin.
y(), 
true, 
false, 
false, 
false, requiresTextureCoordinates, 3, textureRotation ) );
 
  110  mLineDataSelected.tessellator.reset( 
new QgsTessellator( chunkOrigin.
x(), chunkOrigin.
y(), 
true, 
false, 
false, 
false, requiresTextureCoordinates, 3, textureRotation ) );
 
  112  mLineDataNormal.tessellator->setOutputZUp( 
true );
 
  113  mLineDataSelected.tessellator->setOutputZUp( 
true );
 
  123  LineData &lineData = mSelectedIds.contains( feature.
id() ) ? mLineDataSelected : mLineDataNormal;
 
  136  const int nSegments = 4;
 
  139  const double mitreLimit = 0;
 
  141  const QgsGeos engine( abstractGeom );
 
  143  double width = mSymbol->width();
 
  151  QgsAbstractGeometry *buffered = engine.buffer( width / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); 
 
  157    QgsPolygon *polyBuffered = qgsgeometry_cast<QgsPolygon *>( buffered );
 
  158    processPolygon( polyBuffered, feature.
id(), mSymbol->offset(), mSymbol->extrusionHeight(), context, lineData );
 
  162    QgsMultiPolygon *mpolyBuffered = qgsgeometry_cast<QgsMultiPolygon *>( buffered );
 
  166      processPolygon( polyBuffered, feature.
id(), mSymbol->offset(), mSymbol->extrusionHeight(), context, lineData );
 
  177  Q_ASSERT( lineData.tessellator->dataVerticesCount() % 3 == 0 );
 
  178  const uint startingTriangleIndex = 
static_cast<uint
>( lineData.tessellator->dataVerticesCount() / 3 );
 
  179  lineData.triangleIndexStartingIndices.append( startingTriangleIndex );
 
  180  lineData.triangleIndexFids.append( fid );
 
  181  lineData.tessellator->addPolygon( *polyBuffered, extrusionHeight );
 
  182  if ( !lineData.tessellator->error().isEmpty() )
 
  190void QgsBufferedLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
 
  193  makeEntity( parent, context, mLineDataNormal, 
false );
 
  194  makeEntity( parent, context, mLineDataSelected, 
true );
 
  196  mZMin = std::min( mLineDataNormal.tessellator->zMinimum(), mLineDataSelected.tessellator->zMinimum() );
 
  197  mZMax = std::max( mLineDataNormal.tessellator->zMaximum(), mLineDataSelected.tessellator->zMaximum() );
 
  201void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, LineData &lineData, 
bool selected )
 
  203  if ( lineData.tessellator->dataVerticesCount() == 0 )
 
  212  const QByteArray data( ( 
const char * ) lineData.tessellator->data().constData(), 
static_cast<int>( lineData.tessellator->data().count() * 
sizeof( 
float ) ) );
 
  213  const int nVerts = data.count() / lineData.tessellator->stride();
 
  218  geometry->
setData( data, nVerts, lineData.triangleIndexFids, lineData.triangleIndexStartingIndices );
 
  220  Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
 
  221  renderer->setGeometry( geometry );
 
  224  QgsGeoTransform *transform = 
new QgsGeoTransform;
 
  225  transform->setGeoTranslation( mChunkOrigin );
 
  228  Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  229  entity->addComponent( renderer );
 
  230  entity->addComponent( material );
 
  231  entity->addComponent( transform );
 
  232  entity->setParent( parent );
 
  245class QgsThickLine3DSymbolHandler : 
public QgsFeature3DHandler
 
  250      , mSelectedIds( selectedIds )
 
  256    void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
 
  259    void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, QgsLineVertexData &lineVertexData, 
bool selected );
 
  260    Qt3DExtras::QPhongMaterial *material( 
const QgsLine3DSymbol &symbol ) 
const;
 
  261    void processMaterialDatadefined( uint verticesCount, 
const QgsExpressionContext &context, QgsLineVertexData &lineVertexData );
 
  264    std::unique_ptr<QgsLine3DSymbol> mSymbol;
 
  272    QgsLineVertexData mLineDataNormal;   
 
  273    QgsLineVertexData mLineDataSelected; 
 
  279  Q_UNUSED( attributeNames )
 
  281  mChunkOrigin = chunkOrigin;
 
  283  mLineDataNormal.withAdjacency = 
true;
 
  284  mLineDataSelected.withAdjacency = 
true;
 
  285  mLineDataNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context, chunkOrigin );
 
  286  mLineDataSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context, chunkOrigin );
 
  288  QSet<QString> attrs = mSymbol->dataDefinedProperties().referencedFields( context.
expressionContext() );
 
  289  attributeNames.unite( attrs );
 
  290  attrs = mSymbol->materialSettings()->dataDefinedProperties().referencedFields( context.
expressionContext() );
 
  291  attributeNames.unite( attrs );
 
  295    processMaterialDatadefined( mLineDataNormal.vertices.size(), context.
expressionContext(), mLineDataNormal );
 
  296    processMaterialDatadefined( mLineDataSelected.vertices.size(), context.
expressionContext(), mLineDataSelected );
 
  308  QgsLineVertexData &lineVertexData = mSelectedIds.contains( feature.
id() ) ? mLineDataSelected : mLineDataNormal;
 
  310  const int oldVerticesCount = lineVertexData.vertices.size();
 
  322  if ( 
const QgsLineString *lineString = qgsgeometry_cast<const QgsLineString *>( abstractGeom ) )
 
  324    lineVertexData.addLineString( *lineString );
 
  326  else if ( 
const QgsMultiLineString *multiLineString = qgsgeometry_cast<const QgsMultiLineString *>( abstractGeom ) )
 
  328    for ( 
int nGeom = 0; nGeom < multiLineString->numGeometries(); ++nGeom )
 
  330      const QgsLineString *lineString = multiLineString->lineStringN( nGeom );
 
  331      lineVertexData.addLineString( *lineString );
 
  336    processMaterialDatadefined( lineVertexData.vertices.size() - oldVerticesCount, context.
expressionContext(), lineVertexData );
 
  341void QgsThickLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
 
  344  makeEntity( parent, context, mLineDataNormal, 
false );
 
  345  makeEntity( parent, context, mLineDataSelected, 
true );
 
  347  updateZRangeFromPositions( mLineDataNormal.vertices );
 
  348  updateZRangeFromPositions( mLineDataSelected.vertices );
 
  352void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, QgsLineVertexData &lineVertexData, 
bool selected )
 
  354  if ( lineVertexData.indexes.isEmpty() )
 
  368  if ( QgsLineMaterial *lineMaterial = 
dynamic_cast<QgsLineMaterial *
>( material ) )
 
  369    lineMaterial->setLineWidth( mSymbol->width() );
 
  371  Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
 
  374  Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
 
  375  renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
 
  376  Qt3DQGeometry *geometry = lineVertexData.createGeometry( entity );
 
  379    mSymbol->materialSettings()->applyDataDefinedToGeometry( geometry, lineVertexData.vertices.size(), lineVertexData.materialDataDefined );
 
  381  renderer->setGeometry( geometry );
 
  383  renderer->setVertexCount( lineVertexData.indexes.count() );
 
  384  renderer->setPrimitiveRestartEnabled( 
true );
 
  385  renderer->setRestartIndexValue( 0 );
 
  388  QgsGeoTransform *transform = 
new QgsGeoTransform;
 
  389  transform->setGeoTranslation( mChunkOrigin );
 
  392  entity->addComponent( renderer );
 
  393  entity->addComponent( material );
 
  394  entity->addComponent( transform );
 
  395  entity->setParent( parent );
 
  398void QgsThickLine3DSymbolHandler::processMaterialDatadefined( uint verticesCount, 
const QgsExpressionContext &context, QgsLineVertexData &lineVertexData )
 
  400  const QByteArray bytes = mSymbol->materialSettings()->dataDefinedVertexColorsAsByte( context );
 
  401  lineVertexData.materialDataDefined.append( bytes.repeated( 
static_cast<int>( verticesCount ) ) );
 
  408namespace Qgs3DSymbolImpl
 
JoinStyle
Join styles for buffers.
 
@ Round
Use rounded joins.
 
EndCapStyle
End cap styles for buffers.
 
@ MultiPolygon
MultiPolygon.
 
Rendering context for preparation of 3D entities.
 
QColor selectionColor() const
Returns color used for selected features.
 
QgsExpressionContext & expressionContext()
Gets the expression context.
 
@ Main3DRenderer
Renderer for normal entities.
 
static const char * PROP_NAME_3D_RENDERER_FLAG
Qt property name to hold the 3D geometry renderer flag.
 
static void clampAltitudes(QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint ¢roid, float offset, const Qgs3DRenderContext &context)
Clamps altitude of vertices of a linestring according to the settings.
 
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
 
Abstract base class for all geometries.
 
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
 
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
 
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
 
@ Ambient
Ambient color (phong material)
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
int numGeometries() const
Returns the number of geometries within the collection.
 
A geometry is the spatial representation of a feature.
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
Does vector analysis using the GEOS library and handles import, export, and exception handling.
 
3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer with...
 
bool renderAsSimpleLines() const
Returns whether the renderer will render data with simple lines (otherwise it uses buffer)
 
QgsAbstract3DSymbol * clone() const override SIP_FACTORY
 
Line string geometry type, with support for z-dimension and m-values.
 
Context settings for a material.
 
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.
 
Base class for all materials used within QGIS 3D views.
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
 
Multi line string geometry collection.
 
Multi polygon geometry collection.
 
QgsPolygon * polygonN(int index)
Returns the polygon with the specified index.
 
A Phong shading model with diffuse texture map.
 
bool requiresTextureCoordinates() const
Returns true if the material requires texture coordinates to be generated during triangulation....
 
double textureRotation() const
Returns the texture rotation, in degrees.
 
QgsPolygon * clone() const override
Clones the geometry by performing a deep copy.
 
Basic shading material used for rendering simple lines as solid line components.
 
QgsMaterial * toMaterial(QgsMaterialSettingsRenderingTechnique technique, const QgsMaterialContext &context) const override
Creates a new QgsMaterial object representing the material settings.
 
Qt3DRender::QGeometry subclass that represents polygons tessellated into 3D geometry.
 
void setData(const QByteArray &vertexBufferData, int vertexCount, const QVector< QgsFeatureId > &triangleIndexFids, const QVector< uint > &triangleIndexStartingIndices)
Initializes vertex buffer (and other members) from data that were already tessellated.
 
Tessellates polygons into triangles.
 
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
 
double y() const
Returns Y coordinate.
 
double x() const
Returns X coordinate.
 
Represents a vector layer which manages a vector based dataset.
 
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
 
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
 
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
 
@ Triangles
Triangle based rendering (default)
 
@ Lines
Line based rendering, requires line data.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
Qt3DCore::QGeometry Qt3DQGeometry
 
QSet< QgsFeatureId > QgsFeatureIds
 
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
 
Qt3DCore::QAttribute Qt3DQAttribute
 
Qt3DCore::QBuffer Qt3DQBuffer
 
Qt3DCore::QGeometry Qt3DQGeometry