31 #include <Qt3DExtras/QPhongMaterial> 32 #include <Qt3DRender/QAttribute> 33 #include <Qt3DRender/QBuffer> 34 #include <Qt3DRender/QGeometryRenderer> 39 static Qt3DExtras::QPhongMaterial *_material(
const QgsLine3DSymbol &symbol )
41 Qt3DExtras::QPhongMaterial *material =
new Qt3DExtras::QPhongMaterial;
55 class QgsBufferedLine3DSymbolHandler :
public QgsFeature3DHandler
59 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
61 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
62 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
63 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
70 QList<QgsPolygon *> polygons;
71 QList<QgsFeatureId> fids;
74 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, LineData &out,
bool selected );
88 bool QgsBufferedLine3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
91 Q_UNUSED( attributeNames )
95 void QgsBufferedLine3DSymbolHandler::processFeature(
QgsFeature &f,
const Qgs3DRenderContext &context )
100 LineData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
111 const int nSegments = 4;
114 const double mitreLimit = 0;
117 QgsAbstractGeometry *buffered = engine.buffer( mSymbol.width() / 2., nSegments, endCapStyle, joinStyle, mitreLimit );
122 Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), context.map() );
123 out.polygons.append( polyBuffered );
124 out.fids.append( f.
id() );
134 Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), context.map() );
135 out.polygons.append( polyBuffered );
136 out.fids.append( f.
id() );
143 void QgsBufferedLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
146 makeEntity( parent, context, outNormal,
false );
147 makeEntity( parent, context, outSelected,
true );
151 void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, LineData &out,
bool selected )
153 if ( out.polygons.isEmpty() )
156 Qt3DExtras::QPhongMaterial *mat = _material( mSymbol );
160 mat->setDiffuse( context.map().selectionColor() );
161 mat->setAmbient( context.map().selectionColor().darker() );
164 QgsPointXY origin( context.map().origin().x(), context.map().origin().y() );
166 geometry->
setPolygons( out.polygons, out.fids, origin, mSymbol.extrusionHeight() );
168 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
169 renderer->setGeometry( geometry );
172 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
173 entity->addComponent( renderer );
174 entity->addComponent( mat );
175 entity->setParent( parent );
178 entity->findChild<Qt3DRender::QGeometryRenderer *>()->setObjectName( QStringLiteral(
"main" ) );
185 class QgsSimpleLine3DSymbolHandler :
public QgsFeature3DHandler
189 : mSymbol( symbol ), mSelectedIds( selectedIds )
193 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
194 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
195 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
199 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, QgsLineVertexData &out,
bool selected );
200 Qt3DExtras::QPhongMaterial *material(
const QgsLine3DSymbol &symbol )
const;
208 QgsLineVertexData outNormal;
209 QgsLineVertexData outSelected;
214 bool QgsSimpleLine3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
216 Q_UNUSED( attributeNames )
218 outNormal.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
219 outSelected.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
224 void QgsSimpleLine3DSymbolHandler::processFeature(
QgsFeature &f,
const Qgs3DRenderContext &context )
230 QgsLineVertexData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
234 if (
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) )
236 out.addLineString( *ls );
238 else if (
const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( g ) )
240 for (
int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
243 out.addLineString( *ls );
248 void QgsSimpleLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
251 makeEntity( parent, context, outNormal,
false );
252 makeEntity( parent, context, outSelected,
true );
256 void QgsSimpleLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, QgsLineVertexData &out,
bool selected )
258 if ( out.indexes.isEmpty() )
263 Qt3DExtras::QPhongMaterial *mat = _material( mSymbol );
267 mat->setAmbient( context.map().selectionColor() );
272 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
274 Qt3DRender::QGeometry *geom = out.createGeometry( entity );
276 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
277 renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStrip );
278 renderer->setGeometry( geom );
279 renderer->setVertexCount( out.indexes.count() );
280 renderer->setPrimitiveRestartEnabled(
true );
281 renderer->setRestartIndexValue( 0 );
284 entity->addComponent( renderer );
285 entity->addComponent( mat );
286 entity->setParent( parent );
294 class QgsThickLine3DSymbolHandler :
public QgsFeature3DHandler
298 : mSymbol( symbol ), mSelectedIds( selectedIds )
302 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
303 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
304 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
309 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, QgsLineVertexData &out,
bool selected );
310 Qt3DExtras::QPhongMaterial *material(
const QgsLine3DSymbol &symbol )
const;
318 QgsLineVertexData outNormal;
319 QgsLineVertexData outSelected;
324 bool QgsThickLine3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
326 Q_UNUSED( attributeNames )
328 outNormal.withAdjacency =
true;
329 outSelected.withAdjacency =
true;
330 outNormal.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
331 outSelected.init( mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), &context.map() );
336 void QgsThickLine3DSymbolHandler::processFeature(
QgsFeature &f,
const Qgs3DRenderContext &context )
342 QgsLineVertexData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
346 if (
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) )
348 out.addLineString( *ls );
350 else if (
const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( g ) )
352 for (
int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
355 out.addLineString( *ls );
360 void QgsThickLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
363 makeEntity( parent, context, outNormal,
false );
364 makeEntity( parent, context, outSelected,
true );
368 void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, QgsLineVertexData &out,
bool selected )
370 if ( out.indexes.isEmpty() )
375 QgsLineMaterial *mat =
new QgsLineMaterial;
376 mat->setLineColor( mSymbol.material().ambient() );
377 mat->setLineWidth( mSymbol.width() );
381 mat->setLineColor( context.map().selectionColor() );
384 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
387 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
388 renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
389 renderer->setGeometry( out.createGeometry( entity ) );
390 renderer->setVertexCount( out.indexes.count() );
391 renderer->setPrimitiveRestartEnabled(
true );
392 renderer->setRestartIndexValue( 0 );
395 entity->addComponent( renderer );
396 entity->addComponent( mat );
397 entity->setParent( parent );
404 namespace Qgs3DSymbolImpl
418 QgsFeature3DHandler *handler = handlerForLine3DSymbol( layer, symbol );
419 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.
A class to represent a 2D point.
Multi line string geometry collection.
A geometry is the spatial representation of a feature.
void setPolygons(const QList< QgsPolygon *> &polygons, const QList< QgsFeatureId > &featureIds, const QgsPointXY &origin, float extrusionHeight, const QList< float > &extrusionHeightPerPolygon=QList< float >())
Initializes vertex buffer from given polygons. Takes ownership of passed polygon geometries.
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
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.
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.