24 #include <Qt3DCore/QTransform>    25 #include <Qt3DExtras/QPhongMaterial>    26 #include <Qt3DRender/QEffect>    27 #include <Qt3DRender/QTechnique>    28 #include <Qt3DRender/QCullFace>    29 #include <Qt3DRender/QGeometryRenderer>    41 class QgsPolygon3DSymbolHandler : 
public QgsFeature3DHandler
    45       : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
    47     bool prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames ) 
override;
    48     void processFeature( 
QgsFeature &feature, 
const Qgs3DRenderContext &context ) 
override;
    49     void finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context ) 
override;
    56       std::unique_ptr<QgsTessellator> tessellator;
    57       QVector<QgsFeatureId> triangleIndexFids;
    58       QVector<uint> triangleIndexStartingIndices;
    61     void processPolygon( 
QgsPolygon *polyClone, 
QgsFeatureId fid, 
float height, 
float extrusionHeight, 
const Qgs3DRenderContext &context, PolygonData &out );
    62     void makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PolygonData &out, 
bool selected );
    71     PolygonData outNormal;  
    72     PolygonData outSelected;  
    74     QgsLineVertexData outEdges;  
    78 bool QgsPolygon3DSymbolHandler::prepare( 
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
    80   outEdges.withAdjacency = 
true;
    81   outEdges.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
    83   outNormal.tessellator.reset( 
new QgsTessellator( context.map().origin().x(), context.map().origin().y(), 
true, mSymbol.invertNormals(), mSymbol.addBackFaces() ) );
    84   outSelected.tessellator.reset( 
new QgsTessellator( context.map().origin().x(), context.map().origin().y(), 
true, mSymbol.invertNormals(), mSymbol.addBackFaces() ) );
    87   attributeNames.unite( attrs );
    91 void QgsPolygon3DSymbolHandler::processPolygon( 
QgsPolygon *polyClone, 
QgsFeatureId fid, 
float height, 
float extrusionHeight, 
const Qgs3DRenderContext &context, PolygonData &out )
    93   if ( mSymbol.edgesEnabled() )
    96     outEdges.addLineString( *static_cast<const QgsLineString *>( polyClone->
exteriorRing() ) );
    98       outEdges.addLineString( *static_cast<const QgsLineString *>( polyClone->
interiorRing( i ) ) );
   100     if ( extrusionHeight )
   104       outEdges.addLineString( *exterior, extrusionHeight );
   105       outEdges.addVerticalLines( *exterior, extrusionHeight );
   109         outEdges.addLineString( *interior, extrusionHeight );
   110         outEdges.addVerticalLines( *interior, extrusionHeight );
   117   Q_ASSERT( out.tessellator->dataVerticesCount() % 3 == 0 );
   118   uint startingTriangleIndex = 
static_cast<uint
>( out.tessellator->dataVerticesCount() / 3 );
   119   out.triangleIndexStartingIndices.append( startingTriangleIndex );
   120   out.triangleIndexFids.append( fid );
   121   out.tessellator->addPolygon( *polyClone, extrusionHeight );
   125 void QgsPolygon3DSymbolHandler::processFeature( 
QgsFeature &f, 
const Qgs3DRenderContext &context )
   130   PolygonData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
   144   float height = mSymbol.height();
   145   float extrusionHeight = mSymbol.extrusionHeight();
   148   if ( hasDDExtrusion )
   151   if ( 
const QgsPolygon *poly = qgsgeometry_cast< const QgsPolygon *>( g ) )
   154     processPolygon( polyClone, f.
id(), height, extrusionHeight, context, out );
   156   else if ( 
const QgsMultiPolygon *mpoly = qgsgeometry_cast< const QgsMultiPolygon *>( g ) )
   158     for ( 
int i = 0; i < mpoly->numGeometries(); ++i )
   163       processPolygon( polyClone, f.
id(), height, extrusionHeight, context, out );
   168     for ( 
int i = 0; i < gc->numGeometries(); ++i )
   174         processPolygon( polyClone, f.
id(), height, extrusionHeight, context, out );
   179     qDebug() << 
"not a polygon";
   183 void QgsPolygon3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context )
   186   makeEntity( parent, context, outNormal, 
false );
   187   makeEntity( parent, context, outSelected, 
true );
   189   mZMin = std::min( outNormal.tessellator->zMinimum(), outSelected.tessellator->zMinimum() );
   190   mZMax = std::max( outNormal.tessellator->zMaximum(), outSelected.tessellator->zMaximum() );
   193   if ( mSymbol.edgesEnabled() && !outEdges.indexes.isEmpty() )
   195     QgsLineMaterial *mat = 
new QgsLineMaterial;
   196     mat->setLineColor( mSymbol.edgeColor() );
   197     mat->setLineWidth( mSymbol.edgeWidth() );
   199     Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
   202     Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
   203     renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
   204     renderer->setGeometry( outEdges.createGeometry( entity ) );
   205     renderer->setVertexCount( outEdges.indexes.count() );
   206     renderer->setPrimitiveRestartEnabled( 
true );
   207     renderer->setRestartIndexValue( 0 );
   210     entity->addComponent( renderer );
   211     entity->addComponent( mat );
   212     entity->setParent( parent );
   217 void QgsPolygon3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, 
const Qgs3DRenderContext &context, PolygonData &out, 
bool selected )
   219   if ( out.tessellator->dataVerticesCount() == 0 )
   222   Qt3DExtras::QPhongMaterial *mat = material( mSymbol );
   226     mat->setDiffuse( context.map().selectionColor() );
   227     mat->setAmbient( context.map().selectionColor().darker() );
   231   QByteArray data( ( 
const char * )out.tessellator->data().constData(), out.tessellator->data().count() * 
sizeof( float ) );
   232   int nVerts = data.count() / out.tessellator->stride();
   237   geometry->
setData( data, nVerts, out.triangleIndexFids, out.triangleIndexStartingIndices );
   239   Qt3DRender::QGeometryRenderer *renderer = 
new Qt3DRender::QGeometryRenderer;
   240   renderer->setGeometry( geometry );
   243   Qt3DCore::QEntity *entity = 
new Qt3DCore::QEntity;
   244   entity->addComponent( renderer );
   245   entity->addComponent( mat );
   246   entity->setParent( parent );
   249     entity->findChild<Qt3DRender::QGeometryRenderer *>()->setObjectName( QStringLiteral( 
"main" ) ); 
   262   return Qt3DRender::QCullFace::NoCulling;
   265 Qt3DExtras::QPhongMaterial *QgsPolygon3DSymbolHandler::material( 
const QgsPolygon3DSymbol &symbol )
 const   267   Qt3DExtras::QPhongMaterial *material = 
new Qt3DExtras::QPhongMaterial;
   270   auto techniques = material->effect()->techniques();
   271   for ( 
auto tit = techniques.constBegin(); tit != techniques.constEnd(); ++tit )
   273     auto renderPasses = ( *tit )->renderPasses();
   274     for ( 
auto rpit = renderPasses.begin(); rpit != renderPasses.end(); ++rpit )
   276       Qt3DRender::QCullFace *cullFace = 
new Qt3DRender::QCullFace;
   277       cullFace->setMode( _qt3DcullingMode( symbol.
cullingMode() ) );
   278       ( *rpit )->addRenderState( cullFace );
   293 namespace Qgs3DSymbolImpl
   304     QgsFeature3DHandler *handler = handlerForPolygon3DSymbol( layer, symbol );
   305     Qt3DCore::QEntity *e = entityFromHandler( handler, map, layer );
 
float shininess() const
Returns shininess of the surface. 
 
QSet< QgsFeatureId > QgsFeatureIds
 
void setInvertNormals(bool invert)
Sets whether the normals of triangles will be inverted (useful for fixing clockwise / counter-clockwi...
 
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double...
 
QColor specular() const
Returns specular color component. 
 
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon. 
 
3 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls)...
 
CullingMode
Triangle culling mode. 
 
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
 
Extrusion height (zero means no extrusion) 
 
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...
 
Will not render anything. 
 
QgsPhongMaterialSettings material() const
Returns material used for shading of the symbol. 
 
3 Definition of the world 
 
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key. 
 
Class that takes care of tessellation of polygons into triangles. 
 
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon. 
 
Will render only front faces of triangles (recommended when input data are consistent) ...
 
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer. 
 
Will render only back faces of triangles. 
 
Will render both front and back faces of triangles. 
 
3 Class derived from Qt3DRender::QGeometry that represents polygons tessellated into 3D geometry...
 
void setAddBackFaces(bool add)
Sets whether also triangles facing the other side will be created. 
 
Abstract base class for all geometries. 
 
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry. 
 
Qgs3DTypes::CullingMode cullingMode() const
Returns front/back culling mode. 
 
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. 
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive. 
 
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const override
Returns the set of any fields referenced by the active properties from the collection. 
 
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. 
 
QgsPolygon * clone() const override
Clones the geometry by performing a deep copy. 
 
QColor ambient() const
Returns ambient color component. 
 
A grouped map of multiple QgsProperty objects, each referenced by a integer key value. 
 
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. 
 
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring. 
 
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.