32 #include <Qt3DExtras/QPhongMaterial>    33 #include <Qt3DRender/QAttribute>    34 #include <Qt3DRender/QBuffer>    35 #include <Qt3DRender/QGeometryRenderer>    40 static Qt3DExtras::QPhongMaterial *_material( 
const QgsLine3DSymbol &symbol )
    42   Qt3DExtras::QPhongMaterial *material = 
new Qt3DExtras::QPhongMaterial;
    56 class QgsBufferedLine3DSymbolHandler : 
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;
    71       std::unique_ptr<QgsTessellator> tessellator;
    72       QVector<QgsFeatureId> triangleIndexFids;
    73       QVector<uint> triangleIndexStartingIndices;
    76     void processPolygon( 
QgsPolygon *polyBuffered, 
QgsFeatureId fid, 
float height, 
float extrusionHeight, 
const Qgs3DRenderContext &context, LineData &out );
    78     void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, LineData &out, 
bool selected );
    92 bool QgsBufferedLine3DSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
    94   Q_UNUSED( attributeNames )
    96   outNormal.tessellator.reset( 
new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true ) );
    97   outSelected.tessellator.reset( 
new QgsTessellator( context.map().origin().x(), context.map().origin().y(), true ) );
   102 void QgsBufferedLine3DSymbolHandler::processFeature( 
QgsFeature &f, 
const Qgs3DRenderContext &context )
   107   LineData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
   118   const int nSegments = 4;
   121   const double mitreLimit = 0;
   124   QgsAbstractGeometry *buffered = engine.buffer( mSymbol.width() / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); 
   129     processPolygon( polyBuffered, f.
id(), mSymbol.height(), mSymbol.extrusionHeight(), context, out );
   139       processPolygon( polyBuffered, f.
id(), mSymbol.height(), mSymbol.extrusionHeight(), context, out );
   145 void QgsBufferedLine3DSymbolHandler::processPolygon( 
QgsPolygon *polyBuffered, 
QgsFeatureId fid, 
float height, 
float extrusionHeight, 
const Qgs3DRenderContext &context, LineData &out )
   149   Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 );
   150   uint startingTriangleIndex = 
static_cast<uint
>( out.tessellator->dataVerticesCount() / 3 );
   151   out.triangleIndexStartingIndices.append( startingTriangleIndex );
   152   out.triangleIndexFids.append( fid );
   153   out.tessellator->addPolygon( *polyBuffered, extrusionHeight );
   157 void QgsBufferedLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
   160   makeEntity( parent, context, outNormal, 
false );
   161   makeEntity( parent, context, outSelected, 
true );
   163   mZMin = std::min( outNormal.tessellator->zMinimum(), outSelected.tessellator->zMinimum() );
   164   mZMax = std::max( outNormal.tessellator->zMaximum(), outSelected.tessellator->zMaximum() );
   168 void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, LineData &out, 
bool selected )
   170   if ( out.tessellator->dataVerticesCount() == 0 )
   173   Qt3DExtras::QPhongMaterial *mat = _material( mSymbol );
   177     mat->setDiffuse( context.map().selectionColor() );
   178     mat->setAmbient( context.map().selectionColor().darker() );
   182   QByteArray data( ( 
const char * )out.tessellator->data().constData(), out.tessellator->data().count() * 
sizeof( float ) );
   183   int nVerts = data.count() / out.tessellator->stride();
   186   geometry->
setData( data, nVerts, out.triangleIndexFids, out.triangleIndexStartingIndices );
   188   Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
   189   renderer->setGeometry( geometry );
   192   Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
   193   entity->addComponent( renderer );
   194   entity->addComponent( mat );
   195   entity->setParent( parent );
   198     entity->findChild<Qt3DRender::QGeometryRenderer *>()->setObjectName( QStringLiteral( 
"main" ) ); 
   205 class QgsSimpleLine3DSymbolHandler : 
public QgsFeature3DHandler
   209       : mSymbol( symbol ), mSelectedIds( selectedIds )
   213     bool prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames ) 
override;
   214     void processFeature( 
QgsFeature &feature, 
const Qgs3DRenderContext &context ) 
override;
   215     void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
   219     void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, QgsLineVertexData &out, 
bool selected );
   220     Qt3DExtras::QPhongMaterial *material( 
const QgsLine3DSymbol &symbol ) 
const;
   228     QgsLineVertexData outNormal;  
   229     QgsLineVertexData outSelected;  
   234 bool QgsSimpleLine3DSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
   236   Q_UNUSED( attributeNames )
   238   outNormal.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
   239   outSelected.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
   244 void QgsSimpleLine3DSymbolHandler::processFeature( 
QgsFeature &f, 
const Qgs3DRenderContext &context )
   250   QgsLineVertexData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
   254   if ( 
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) )
   256     out.addLineString( *ls );
   258   else if ( 
const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( g ) )
   260     for ( 
int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
   263       out.addLineString( *ls );
   268 void QgsSimpleLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
   271   makeEntity( parent, context, outNormal, 
false );
   272   makeEntity( parent, context, outSelected, 
true );
   274   updateZRangeFromPositions( outNormal.vertices );
   275   updateZRangeFromPositions( outSelected.vertices );
   279 void QgsSimpleLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, QgsLineVertexData &out, 
bool selected )
   281   if ( out.indexes.isEmpty() )
   286   Qt3DExtras::QPhongMaterial *mat = _material( mSymbol );
   290     mat->setAmbient( context.map().selectionColor() );
   295   Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
   297   Qt3DRender::QGeometry *geom = out.createGeometry( entity );
   299   Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
   300   renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStrip );
   301   renderer->setGeometry( geom );
   302   renderer->setVertexCount( out.indexes.count() );
   303   renderer->setPrimitiveRestartEnabled( 
true );
   304   renderer->setRestartIndexValue( 0 );
   307   entity->addComponent( renderer );
   308   entity->addComponent( mat );
   309   entity->setParent( parent );
   317 class QgsThickLine3DSymbolHandler : 
public QgsFeature3DHandler
   321       : mSymbol( symbol ), mSelectedIds( selectedIds )
   325     bool prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames ) 
override;
   326     void processFeature( 
QgsFeature &feature, 
const Qgs3DRenderContext &context ) 
override;
   327     void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
   332     void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, QgsLineVertexData &out, 
bool selected );
   333     Qt3DExtras::QPhongMaterial *material( 
const QgsLine3DSymbol &symbol ) 
const;
   341     QgsLineVertexData outNormal;  
   342     QgsLineVertexData outSelected;  
   347 bool QgsThickLine3DSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
   349   Q_UNUSED( attributeNames )
   351   outNormal.withAdjacency = 
true;
   352   outSelected.withAdjacency = 
true;
   353   outNormal.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
   354   outSelected.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
   359 void QgsThickLine3DSymbolHandler::processFeature( 
QgsFeature &f, 
const Qgs3DRenderContext &context )
   365   QgsLineVertexData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
   369   if ( 
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) )
   371     out.addLineString( *ls );
   373   else if ( 
const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( g ) )
   375     for ( 
int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
   378       out.addLineString( *ls );
   383 void QgsThickLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
   386   makeEntity( parent, context, outNormal, 
false );
   387   makeEntity( parent, context, outSelected, 
true );
   389   updateZRangeFromPositions( outNormal.vertices );
   390   updateZRangeFromPositions( outSelected.vertices );
   394 void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, QgsLineVertexData &out, 
bool selected )
   396   if ( out.indexes.isEmpty() )
   401   QgsLineMaterial *mat = 
new QgsLineMaterial;
   402   mat->setLineColor( mSymbol.material().ambient() );
   403   mat->setLineWidth( mSymbol.width() );
   407     mat->setLineColor( context.map().selectionColor() );
   410   Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
   413   Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
   414   renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
   415   renderer->setGeometry( out.createGeometry( entity ) );
   416   renderer->setVertexCount( out.indexes.count() );
   417   renderer->setPrimitiveRestartEnabled( 
true );
   418   renderer->setRestartIndexValue( 0 );
   421   entity->addComponent( renderer );
   422   entity->addComponent( mat );
   423   entity->setParent( parent );
   430 namespace Qgs3DSymbolImpl
   444     QgsFeature3DHandler *handler = handlerForLine3DSymbol( layer, symbol );
   445     Qt3DCore::QEntity *e = entityFromHandler( handler, map, layer );
 
float shininess() const
Returns shininess of the surface. 
 
QSet< QgsFeatureId > QgsFeatureIds
 
QColor specular() const
Returns specular color component. 
 
Multi line string geometry collection. 
 
A geometry is the spatial representation of a feature. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
EndCapStyle
End cap styles for buffers. 
 
3 Definition of the world 
 
Class that takes care of tessellation of polygons into triangles. 
 
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer. 
 
3 Class derived from Qt3DRender::QGeometry that represents polygons tessellated into 3D geometry...
 
QgsPhongMaterialSettings material() const
Returns material used for shading of the symbol. 
 
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
 
3 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer wi...
 
Abstract base class for all geometries. 
 
Does vector analysis using the geos library and handles import, export, exception handling*...
 
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the 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. 
 
int numGeometries() const
Returns the number of geometries within the collection. 
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive. 
 
bool renderAsSimpleLines() const
Returns whether the renderer will render data with simple lines (otherwise it uses buffer) ...
 
Multi polygon geometry collection. 
 
static bool isCurvedType(Type type)
Returns true if the WKB type is a curved type or can contain curved geometries. 
 
Line string geometry type, with support for z-dimension and m-values. 
 
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection. 
 
QColor ambient() const
Returns ambient color component. 
 
static void clampAltitudes(QgsLineString *lineString, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, const QgsPoint ¢roid, float height, const Qgs3DMapSettings &map)
Clamps altitude of vertices of a linestring according to the settings. 
 
QColor diffuse() const
Returns diffuse color component. 
 
JoinStyle
Join styles for buffers. 
 
Represents a vector layer which manages a vector based data sets. 
 
static Type flatType(Type type)
Returns the flat type for a WKB type. 
 
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.