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.