29 #include <Qt3DExtras/QPhongMaterial> 30 #include <Qt3DRender/QAttribute> 31 #include <Qt3DRender/QBuffer> 32 #include <Qt3DRender/QGeometryRenderer> 37 static Qt3DExtras::QPhongMaterial *_material(
const QgsLine3DSymbol &symbol )
39 Qt3DExtras::QPhongMaterial *material =
new Qt3DExtras::QPhongMaterial;
53 class QgsBufferedLine3DSymbolHandler :
public QgsFeature3DHandler
57 : mSymbol( symbol ), mSelectedIds( selectedIds ) {}
59 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
60 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
61 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
68 QList<QgsPolygon *> polygons;
69 QList<QgsFeatureId> fids;
72 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, LineData &out,
bool selected );
86 bool QgsBufferedLine3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
89 Q_UNUSED( attributeNames );
93 void QgsBufferedLine3DSymbolHandler::processFeature(
QgsFeature &f,
const Qgs3DRenderContext &context )
98 LineData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
109 const int nSegments = 4;
112 const double mitreLimit = 0;
115 QgsAbstractGeometry *buffered = engine.buffer( mSymbol.width() / 2., nSegments, endCapStyle, joinStyle, mitreLimit );
120 Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), context.map() );
121 out.polygons.append( polyBuffered );
122 out.fids.append( f.
id() );
132 Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), context.map() );
133 out.polygons.append( polyBuffered );
134 out.fids.append( f.
id() );
141 void QgsBufferedLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
144 makeEntity( parent, context, outNormal,
false );
145 makeEntity( parent, context, outSelected,
true );
149 void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, LineData &out,
bool selected )
151 if ( out.polygons.isEmpty() )
154 Qt3DExtras::QPhongMaterial *mat = _material( mSymbol );
158 mat->setDiffuse( context.map().selectionColor() );
159 mat->setAmbient( context.map().selectionColor().darker() );
162 QgsPointXY origin( context.map().origin().x(), context.map().origin().y() );
164 geometry->
setPolygons( out.polygons, out.fids, origin, mSymbol.extrusionHeight() );
166 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
167 renderer->setGeometry( geometry );
170 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
171 entity->addComponent( renderer );
172 entity->addComponent( mat );
173 entity->setParent( parent );
176 entity->findChild<Qt3DRender::QGeometryRenderer *>()->setObjectName( QStringLiteral(
"main" ) );
183 class QgsSimpleLine3DSymbolHandler :
public QgsFeature3DHandler
187 : mSymbol( symbol ), mSelectedIds( selectedIds )
190 outNormal.vertices << QVector3D();
191 outSelected.vertices << QVector3D();
194 bool prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
override;
195 void processFeature(
QgsFeature &feature,
const Qgs3DRenderContext &context )
override;
196 void finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
override;
203 QVector<QVector3D> vertices;
204 QVector<unsigned int> indexes;
207 void makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, LineData &out,
bool selected );
208 Qt3DExtras::QPhongMaterial *material(
const QgsLine3DSymbol &symbol )
const;
217 LineData outSelected;
222 bool QgsSimpleLine3DSymbolHandler::prepare(
const Qgs3DRenderContext &context, QSet<QString> &attributeNames )
225 Q_UNUSED( attributeNames );
229 void QgsSimpleLine3DSymbolHandler::processFeature(
QgsFeature &f,
const Qgs3DRenderContext &context )
234 LineData &out = mSelectedIds.contains( f.
id() ) ? outSelected : outNormal;
242 if (
const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) )
244 for (
int i = 0; i < ls->vertexCount(); ++i )
247 float z =
Qgs3DUtils::clampAltitude( p, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), centroid, context.map() );
248 out.vertices << QVector3D( p.
x() - context.map().origin().x(), z, -( p.
y() - context.map().origin().y() ) );
249 out.indexes << out.vertices.count() - 1;
252 else if (
const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( g ) )
254 for (
int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom )
260 float z =
Qgs3DUtils::clampAltitude( p, mSymbol.altitudeClamping(), mSymbol.altitudeBinding(), mSymbol.height(), centroid, context.map() );
261 out.vertices << QVector3D( p.
x() - context.map().origin().x(), z, -( p.
y() - context.map().origin().y() ) );
262 out.indexes << out.vertices.count() - 1;
271 void QgsSimpleLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context )
274 makeEntity( parent, context, outNormal,
false );
275 makeEntity( parent, context, outSelected,
true );
279 void QgsSimpleLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent,
const Qgs3DRenderContext &context, LineData &out,
bool selected )
281 if ( out.indexes.isEmpty() )
286 Qt3DExtras::QPhongMaterial *mat = _material( mSymbol );
290 mat->setAmbient( context.map().selectionColor() );
295 QByteArray vertexBufferData;
296 vertexBufferData.resize( out.vertices.size() * 3 *
sizeof( float ) );
297 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
299 for (
const auto &v : qgis::as_const( out.vertices ) )
301 rawVertexArray[idx++] = v.x();
302 rawVertexArray[idx++] = v.y();
303 rawVertexArray[idx++] = v.z();
306 QByteArray indexBufferData;
307 indexBufferData.resize( out.indexes.size() *
sizeof( int ) );
308 unsigned int *rawIndexArray =
reinterpret_cast<unsigned int *
>( indexBufferData.data() );
310 for (
unsigned int indexVal : qgis::as_const( out.indexes ) )
312 rawIndexArray[idx++] = indexVal;
315 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
317 Qt3DRender::QBuffer *vertexBuffer =
new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer, entity );
318 vertexBuffer->setData( vertexBufferData );
320 Qt3DRender::QBuffer *indexBuffer =
new Qt3DRender::QBuffer( Qt3DRender::QBuffer::IndexBuffer, entity );
321 indexBuffer->setData( indexBufferData );
323 Qt3DRender::QAttribute *positionAttribute =
new Qt3DRender::QAttribute( entity );
324 positionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute );
325 positionAttribute->setBuffer( vertexBuffer );
326 positionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float );
327 positionAttribute->setVertexSize( 3 );
328 positionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() );
330 Qt3DRender::QAttribute *indexAttribute =
new Qt3DRender::QAttribute( entity );
331 indexAttribute->setAttributeType( Qt3DRender::QAttribute::IndexAttribute );
332 indexAttribute->setBuffer( indexBuffer );
333 indexAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedInt );
335 Qt3DRender::QGeometry *geom =
new Qt3DRender::QGeometry;
336 geom->addAttribute( positionAttribute );
337 geom->addAttribute( indexAttribute );
339 Qt3DRender::QGeometryRenderer *renderer =
new Qt3DRender::QGeometryRenderer;
340 renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStrip );
341 renderer->setGeometry( geom );
342 renderer->setVertexCount( out.vertices.count() );
343 renderer->setPrimitiveRestartEnabled(
true );
344 renderer->setRestartIndexValue( 0 );
347 entity->addComponent( renderer );
348 entity->addComponent( mat );
349 entity->setParent( parent );
356 namespace Qgs3DSymbolImpl
369 QgsFeature3DHandler *handler = handlerForLine3DSymbol( layer, symbol );
370 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.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
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.
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
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)
static float clampAltitude(const QgsPoint &p, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, float height, const QgsPoint ¢roid, const Qgs3DMapSettings &map)
Clamps altitude of a vertex according to the settings, returns Z value.
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.
Point geometry type, with support for z-dimension and m-values.
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) ...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
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.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
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.
Clamp just centroid of feature.