QGIS API Documentation 4.1.0-Master (64dc32379c2)
Loading...
Searching...
No Matches
qgsline3dsymbol_p.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsline3dsymbol_p.cpp
3 --------------------------------------
4 Date : July 2017
5 Copyright : (C) 2017 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsline3dsymbol_p.h"
17
18#include "qgs3d.h"
19#include "qgs3dutils.h"
21#include "qgsgeos.h"
22#include "qgsgeotransform.h"
24#include "qgsline3dsymbol.h"
25#include "qgslinematerial_p.h"
26#include "qgslinevertexdata_p.h"
28#include "qgsmessagelog.h"
29#include "qgsmultilinestring.h"
30#include "qgsmultipolygon.h"
32#include "qgspolygon.h"
35#include "qgstessellator.h"
36#include "qgsvectorlayer.h"
37
38#include <QString>
39#include <Qt3DCore/QAttribute>
40#include <Qt3DCore/QBuffer>
41#include <Qt3DCore/QTransform>
42#include <Qt3DExtras/QPhongMaterial>
43#include <Qt3DRender/QGeometryRenderer>
44
45using namespace Qt::StringLiterals;
46
48
49// -----------
50
51
52class QgsBufferedLine3DSymbolHandler : public QgsFeature3DHandler
53{
54 public:
55 QgsBufferedLine3DSymbolHandler( const QgsLine3DSymbol *symbol, const QgsFeatureIds &selectedIds )
56 : mSymbol( static_cast<QgsLine3DSymbol *>( symbol->clone() ) )
57 , mSelectedIds( selectedIds )
58 {}
59
60 bool prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames, const QgsBox3D &chunkExtent ) override;
61 void processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context ) override;
62 void finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) override;
63
64 private:
66 struct LineData
67 {
68 std::unique_ptr<QgsTessellator> tessellator;
69 QVector<QgsFeatureId> triangleIndexFids;
70 QVector<uint> triangleIndexStartingIndices;
71 };
72
73 void processPolygon( QgsPolygon *polyBuffered, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, LineData &lineData );
74
75 void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, LineData &lineData, bool selected );
76
77 // input specific for this class
78 std::unique_ptr<QgsLine3DSymbol> mSymbol;
79 // inputs - generic
80 QgsFeatureIds mSelectedIds;
81 // outputs
82 LineData mLineDataNormal;
83 LineData mLineDataSelected;
84};
85
86
87bool QgsBufferedLine3DSymbolHandler::prepare( const Qgs3DRenderContext &, QSet<QString> &attributeNames, const QgsBox3D &chunkExtent )
88{
89 Q_UNUSED( attributeNames )
90
91 mChunkOrigin = chunkExtent.center();
92 mChunkOrigin.setZ( 0. ); // set the chunk origin to the bottom of the box, as the tessellator currently always considers origin z to be zero
93 mChunkExtent = chunkExtent;
94
95 const bool requiresTextureCoordinates = mSymbol->materialSettings() && mSymbol->materialSettings()->requiresTextureCoordinates();
96 const bool requiresTangents = mSymbol->materialSettings() && mSymbol->materialSettings()->requiresTangents();
97
98 auto lineDataNormalTessellator = std::make_unique<QgsTessellator>();
99 lineDataNormalTessellator->setOrigin( mChunkOrigin );
100 lineDataNormalTessellator->setAddNormals( true );
101 lineDataNormalTessellator->setAddTextureUVs( requiresTextureCoordinates );
102 lineDataNormalTessellator->setAddTangents( requiresTangents );
103 lineDataNormalTessellator->setExtrusionFaces( Qgis::ExtrusionFace::Walls | Qgis::ExtrusionFace::Roof );
104 lineDataNormalTessellator->setTriangulationAlgorithm( Qgis::TriangulationAlgorithm::Earcut );
105
106 mLineDataNormal.tessellator = std::move( lineDataNormalTessellator );
107
108 auto lineDataSelectedTessellator = std::make_unique<QgsTessellator>();
109 lineDataSelectedTessellator->setOrigin( mChunkOrigin );
110 lineDataSelectedTessellator->setAddNormals( true );
111 lineDataSelectedTessellator->setAddTextureUVs( requiresTextureCoordinates );
112 lineDataSelectedTessellator->setAddTangents( requiresTangents );
113 lineDataSelectedTessellator->setExtrusionFaces( Qgis::ExtrusionFace::Walls | Qgis::ExtrusionFace::Roof );
114 lineDataSelectedTessellator->setTriangulationAlgorithm( Qgis::TriangulationAlgorithm::Earcut );
115
116 mLineDataSelected.tessellator = std::move( lineDataSelectedTessellator );
117
118 return true;
119}
120
121void QgsBufferedLine3DSymbolHandler::processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context )
122{
123 if ( feature.geometry().isNull() )
124 return;
125
126 LineData &lineData = mSelectedIds.contains( feature.id() ) ? mLineDataSelected : mLineDataNormal;
127
128 QgsGeometry geom = feature.geometry();
129 clipGeometryIfTooLarge( geom );
130
131 if ( geom.isEmpty() )
132 return;
133
134 const QgsAbstractGeometry *abstractGeom = geom.constGet()->simplifiedTypeRef();
135
136 // segmentize curved geometries if necessary
137 if ( QgsWkbTypes::isCurvedType( abstractGeom->wkbType() ) )
138 {
139 geom = QgsGeometry( abstractGeom->segmentize() );
140 abstractGeom = geom.constGet()->simplifiedTypeRef();
141 }
142
143 // TODO: configurable
144 const int nSegments = 4;
146 const Qgis::JoinStyle joinStyle = Qgis::JoinStyle::Round;
147 const double mitreLimit = 0;
148
149 const QgsGeos engine( abstractGeom );
150
151 double width = mSymbol->width();
152 if ( qgsDoubleNear( width, 0 ) )
153 {
154 // a zero-width buffered line should be treated like a "wall" or "fence" -- we fake this by bumping the width to a very tiny amount,
155 // so that we get a very narrow polygon shape to work with...
156 width = 0.001;
157 }
158
159 QgsAbstractGeometry *buffered = engine.buffer( width / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); // factory
160 if ( !buffered )
161 return;
162
164 {
165 QgsPolygon *polyBuffered = qgsgeometry_cast<QgsPolygon *>( buffered );
166 processPolygon( polyBuffered, feature.id(), mSymbol->offset(), mSymbol->extrusionHeight(), context, lineData );
167 }
168 else if ( QgsWkbTypes::flatType( buffered->wkbType() ) == Qgis::WkbType::MultiPolygon )
169 {
170 QgsMultiPolygon *mpolyBuffered = qgsgeometry_cast<QgsMultiPolygon *>( buffered );
171 for ( int i = 0; i < mpolyBuffered->numGeometries(); ++i )
172 {
173 QgsPolygon *polyBuffered = qgsgeometry_cast<QgsPolygon *>( mpolyBuffered->polygonN( i ) )->clone(); // need to clone individual geometry parts
174 processPolygon( polyBuffered, feature.id(), mSymbol->offset(), mSymbol->extrusionHeight(), context, lineData );
175 }
176 delete buffered;
177 }
178 mFeatureCount++;
179}
180
181void QgsBufferedLine3DSymbolHandler::processPolygon( QgsPolygon *polyBuffered, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, LineData &lineData )
182{
183 Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context );
184
185 Q_ASSERT( lineData.tessellator->dataVerticesCount() % 3 == 0 );
186 const uint startingTriangleIndex = static_cast<uint>( lineData.tessellator->dataVerticesCount() / 3 );
187 lineData.triangleIndexStartingIndices.append( startingTriangleIndex );
188 lineData.triangleIndexFids.append( fid );
189 lineData.tessellator->addPolygon( *polyBuffered, extrusionHeight );
190 if ( !lineData.tessellator->error().isEmpty() )
191 {
192 QgsMessageLog::logMessage( lineData.tessellator->error(), QObject::tr( "3D" ) );
193 }
194
195 delete polyBuffered;
196}
197
198void QgsBufferedLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
199{
200 // create entity for selected and not selected
201 makeEntity( parent, context, mLineDataNormal, false );
202 makeEntity( parent, context, mLineDataSelected, true );
203
204 mZMin = std::min( mLineDataNormal.tessellator->zMinimum(), mLineDataSelected.tessellator->zMinimum() );
205 mZMax = std::max( mLineDataNormal.tessellator->zMaximum(), mLineDataSelected.tessellator->zMaximum() );
206}
207
208
209void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, LineData &lineData, bool selected )
210{
211 if ( lineData.tessellator->dataVerticesCount() == 0 )
212 return; // nothing to show - no need to create the entity
213
215 materialContext.setIsSelected( selected );
216 materialContext.setIsHighlighted( mHighlightingEnabled );
217
218 QgsMaterial *material = Qgs3D::toMaterial( mSymbol->materialSettings(), Qgis::MaterialRenderingTechnique::Triangles, materialContext );
219
220 // extract vertex buffer data from tessellator
221 const QByteArray vertexBuffer = lineData.tessellator->vertexBuffer();
222 const QByteArray indexBuffer = lineData.tessellator->indexBuffer();
223 const int vertexCount = vertexBuffer.count() / lineData.tessellator->stride();
224 const size_t indexCount = lineData.tessellator->dataVerticesCount();
225
227 true, false, false, mSymbol->materialSettings() && mSymbol->materialSettings()->requiresTextureCoordinates(), mSymbol->materialSettings() && mSymbol->materialSettings()->requiresTangents()
228 );
229 geometry->setVertexBufferData( vertexBuffer, vertexCount, lineData.triangleIndexFids, lineData.triangleIndexStartingIndices );
230 geometry->setIndexBufferData( indexBuffer, indexCount );
231
232 Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer;
233 renderer->setGeometry( geometry );
234
235 // add transform (our geometry has coordinates relative to mChunkOrigin)
236 QgsGeoTransform *transform = new QgsGeoTransform;
237 transform->setGeoTranslation( mChunkOrigin );
238
239 // make entity
240 Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
241 entity->addComponent( renderer );
242 entity->addComponent( material );
243 entity->addComponent( transform );
244 entity->setParent( parent );
245
246 if ( !selected )
247 renderer->setProperty( Qgs3DTypes::PROP_NAME_3D_RENDERER_FLAG, Qgs3DTypes::Main3DRenderer ); // temporary measure to distinguish between "selected" and "main"
248
249 // cppcheck wrongly believes entity will leak
250 // cppcheck-suppress memleak
251}
252
253
254// --------------
255
256
257class QgsThickLine3DSymbolHandler : public QgsFeature3DHandler
258{
259 public:
260 QgsThickLine3DSymbolHandler( const QgsLine3DSymbol *symbol, const QgsFeatureIds &selectedIds )
261 : mSymbol( static_cast<QgsLine3DSymbol *>( symbol->clone() ) )
262 , mSelectedIds( selectedIds )
263 {}
264
265 bool prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames, const QgsBox3D &chunkExtent ) override;
266 void processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context ) override;
267 void finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) override;
268
269 private:
270 void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, QgsLineVertexData &lineVertexData, bool selected );
271 Qt3DExtras::QPhongMaterial *material( const QgsLine3DSymbol &symbol ) const;
272 void processMaterialDatadefined( uint verticesCount, const QgsExpressionContext &context, QgsLineVertexData &lineVertexData );
273
274 // input specific for this class
275 std::unique_ptr<QgsLine3DSymbol> mSymbol;
276 // inputs - generic
277 QgsFeatureIds mSelectedIds;
278 // outputs
279 QgsLineVertexData mLineDataNormal;
280 QgsLineVertexData mLineDataSelected;
281};
282
283
284bool QgsThickLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames, const QgsBox3D &chunkExtent )
285{
286 Q_UNUSED( attributeNames )
287
288 mChunkOrigin = chunkExtent.center();
289 mChunkExtent = chunkExtent;
290
291 mLineDataNormal.withAdjacency = true;
292 mLineDataSelected.withAdjacency = true;
293 mLineDataNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context, mChunkOrigin );
294 mLineDataSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context, mChunkOrigin );
295
296 QSet<QString> attrs = mSymbol->dataDefinedProperties().referencedFields( context.expressionContext() );
297 attributeNames.unite( attrs );
298 attrs = mSymbol->materialSettings()->dataDefinedProperties().referencedFields( context.expressionContext() );
299 attributeNames.unite( attrs );
300
301 if ( mSymbol->materialSettings()->dataDefinedProperties().isActive( QgsAbstractMaterialSettings::Property::Ambient ) )
302 {
303 processMaterialDatadefined( mLineDataNormal.vertices.size(), context.expressionContext(), mLineDataNormal );
304 processMaterialDatadefined( mLineDataSelected.vertices.size(), context.expressionContext(), mLineDataSelected );
305 }
306
307 return true;
308}
309
310void QgsThickLine3DSymbolHandler::processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context )
311{
312 Q_UNUSED( context )
313 if ( feature.geometry().isNull() )
314 return;
315
316 QgsLineVertexData &lineVertexData = mSelectedIds.contains( feature.id() ) ? mLineDataSelected : mLineDataNormal;
317
318 const int oldVerticesCount = lineVertexData.vertices.size();
319
320 QgsGeometry geom = feature.geometry();
321 ( void ) clipGeometryIfTooLarge( geom );
322
323 if ( geom.isEmpty() )
324 return;
325
326 const QgsAbstractGeometry *abstractGeom = geom.constGet()->simplifiedTypeRef();
327
328 // segmentize curved geometries if necessary
329 if ( QgsWkbTypes::isCurvedType( abstractGeom->wkbType() ) )
330 {
331 geom = QgsGeometry( abstractGeom->segmentize() );
332 abstractGeom = geom.constGet()->simplifiedTypeRef();
333 }
334
335 if ( const QgsLineString *lineString = qgsgeometry_cast<const QgsLineString *>( abstractGeom ) )
336 {
337 lineVertexData.addLineString( *lineString );
338 }
339 else if ( const QgsMultiLineString *multiLineString = qgsgeometry_cast<const QgsMultiLineString *>( abstractGeom ) )
340 {
341 for ( int nGeom = 0; nGeom < multiLineString->numGeometries(); ++nGeom )
342 {
343 const QgsLineString *lineString = multiLineString->lineStringN( nGeom );
344 lineVertexData.addLineString( *lineString );
345 }
346 }
347
348 if ( mSymbol->materialSettings()->dataDefinedProperties().isActive( QgsAbstractMaterialSettings::Property::Ambient ) )
349 processMaterialDatadefined( lineVertexData.vertices.size() - oldVerticesCount, context.expressionContext(), lineVertexData );
350
351 mFeatureCount++;
352}
353
354void QgsThickLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
355{
356 // create entity for selected and not selected
357 makeEntity( parent, context, mLineDataNormal, false );
358 makeEntity( parent, context, mLineDataSelected, true );
359
360 updateZRangeFromPositions( mLineDataNormal.vertices );
361 updateZRangeFromPositions( mLineDataSelected.vertices );
362}
363
364
365void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, QgsLineVertexData &lineVertexData, bool selected )
366{
367 if ( lineVertexData.indexes.isEmpty() )
368 return;
369
370 // material (only ambient color is used for the color)
372 materialContext.setIsSelected( selected );
373
374 QgsMaterial *material = Qgs3D::toMaterial( mSymbol->materialSettings(), Qgis::MaterialRenderingTechnique::Lines, materialContext );
375 if ( !material )
376 {
377 const QgsSimpleLineMaterialSettings defaultMaterial;
378 material = Qgs3D::toMaterial( &defaultMaterial, Qgis::MaterialRenderingTechnique::Lines, materialContext );
379 }
380
381 if ( QgsLineMaterial *lineMaterial = dynamic_cast<QgsLineMaterial *>( material ) )
382 {
383 float width = mSymbol->width();
384 if ( mHighlightingEnabled )
385 {
386 const QgsSettings settings;
387 const QColor color = QColor( settings.value( u"Map/highlight/color"_s, Qgis::DEFAULT_HIGHLIGHT_COLOR.name() ).toString() );
388 lineMaterial->setLineColor( color );
389 // This is a workaround, make lines thicker to avoid rendering thin lines as three parallel lines with a gap between them
390 // Ideally we would want highlighted lines to be:
391 // - Rendered with an increased line width during highlights render view first pass
392 // - Not rendered during highlights render view second pass (multi-viewport one)
393 width = std::max<float>( static_cast<float>( QgsHighlightsRenderView::silhouetteWidth() * 2 ), mSymbol->width() );
394 }
395 lineMaterial->setLineWidth( width );
396 }
397
398 Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
399
400 // geometry renderer
401 Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer;
402 renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
403 Qt3DCore::QGeometry *geometry = lineVertexData.createGeometry( entity );
404
405 if ( mSymbol->materialSettings()->dataDefinedProperties().isActive( QgsAbstractMaterialSettings::Property::Ambient ) )
406 {
407 Qgs3D::applyMaterialDataDefinedToGeometry( mSymbol->materialSettings(), geometry, lineVertexData.vertices.size(), lineVertexData.materialDataDefined );
408 }
409
410 renderer->setGeometry( geometry );
411
412 renderer->setVertexCount( lineVertexData.indexes.count() );
413 renderer->setPrimitiveRestartEnabled( true );
414 renderer->setRestartIndexValue( 0 );
415
416 // add transform (our geometry has coordinates relative to mChunkOrigin)
417 QgsGeoTransform *transform = new QgsGeoTransform;
418 transform->setGeoTranslation( mChunkOrigin );
419
420 // make entity
421 entity->addComponent( renderer );
422 entity->addComponent( material );
423 entity->addComponent( transform );
424 entity->setParent( parent );
425}
426
427void QgsThickLine3DSymbolHandler::processMaterialDatadefined( uint verticesCount, const QgsExpressionContext &context, QgsLineVertexData &lineVertexData )
428{
429 const QByteArray bytes = Qgs3D::materialDataDefinedVertexColorsAsByte( mSymbol->materialSettings(), context );
430 lineVertexData.materialDataDefined.append( bytes.repeated( static_cast<int>( verticesCount ) ) );
431}
432
433
434// --------------
435
436
437namespace Qgs3DSymbolImpl
438{
439
440 QgsFeature3DHandler *handlerForLine3DSymbol( QgsVectorLayer *layer, const QgsAbstract3DSymbol *symbol )
441 {
442 const QgsLine3DSymbol *lineSymbol = dynamic_cast<const QgsLine3DSymbol *>( symbol );
443 if ( !lineSymbol )
444 return nullptr;
445
446 if ( lineSymbol->renderAsSimpleLines() )
447 return new QgsThickLine3DSymbolHandler( lineSymbol, layer->selectedFeatureIds() );
448 else
449 return new QgsBufferedLine3DSymbolHandler( lineSymbol, layer->selectedFeatureIds() );
450 }
451} // namespace Qgs3DSymbolImpl
452
static const QColor DEFAULT_HIGHLIGHT_COLOR
Default highlight color.
Definition qgis.h:6723
JoinStyle
Join styles for buffers.
Definition qgis.h:2242
@ Round
Use rounded joins.
Definition qgis.h:2243
EndCapStyle
End cap styles for buffers.
Definition qgis.h:2229
@ Round
Round cap.
Definition qgis.h:2230
@ Triangles
Triangle based rendering (default).
Definition qgis.h:4343
@ Lines
Line based rendering, requires line data.
Definition qgis.h:4344
@ Polygon
Polygon.
Definition qgis.h:298
@ MultiPolygon
MultiPolygon.
Definition qgis.h:302
Rendering context for preparation of 3D entities.
QgsExpressionContext & expressionContext()
Gets the expression context.
@ Main3DRenderer
Renderer for normal entities.
Definition qgs3dtypes.h:48
static const char * PROP_NAME_3D_RENDERER_FLAG
Qt property name to hold the 3D geometry renderer flag.
Definition qgs3dtypes.h:43
static void clampAltitudes(QgsLineString *lineString, Qgis::AltitudeClamping altClamp, Qgis::AltitudeBinding altBind, const QgsPoint &centroid, float offset, const Qgs3DRenderContext &context)
Clamps altitude of vertices of a linestring according to the settings.
static QgsMaterial * toMaterial(const QgsAbstractMaterialSettings *settings, Qgis::MaterialRenderingTechnique technique, const QgsMaterialContext &context)
Creates a new QgsMaterial object representing the material settings.
Definition qgs3d.cpp:148
static QByteArray materialDataDefinedVertexColorsAsByte(const QgsAbstractMaterialSettings *settings, const QgsExpressionContext &expressionContext)
Returns byte array corresponding to the data defined colors depending of the expressionContext,...
Definition qgs3d.cpp:182
static void applyMaterialDataDefinedToGeometry(const QgsAbstractMaterialSettings *settings, Qt3DCore::QGeometry *geometry, int vertexCount, const QByteArray &dataDefinedBytes)
Applies the data defined bytes, dataDefinedBytes, on the geometry by filling a specific vertex buffer...
Definition qgs3d.cpp:174
Abstract base class for all geometries.
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:45
bool contains(const QgsBox3D &other) const
Returns true when box contains other box.
Definition qgsbox3d.cpp:164
QgsVector3D center() const
Returns the center of the box as a vector.
Definition qgsbox3d.cpp:124
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsFeatureId id
Definition qgsfeature.h:68
QgsGeometry geometry
Definition qgsfeature.h:71
int numGeometries() const
Returns the number of geometries within the collection.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Does vector analysis using the GEOS library and handles import, export, and exception handling.
Definition qgsgeos.h:175
static int silhouetteWidth()
Returns the width of the generated silhouette effect in pixels.
bool renderAsSimpleLines() const
Returns whether the renderer will render data with simple lines (otherwise it uses buffer).
Line string geometry type, with support for z-dimension and m-values.
Context settings for a material.
void setIsSelected(bool isSelected)
Sets whether the material should represent a selected state.
void setIsHighlighted(bool isHighlighted)
Sets whether the material should represent a highlighted state.
static QgsMaterialContext fromRenderContext(const Qgs3DRenderContext &context)
Constructs a material context from the settings in a 3D render context.
Base class for all materials used within QGIS 3D views.
Definition qgsmaterial.h:40
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
Multi line string geometry collection.
Multi polygon geometry collection.
QgsPolygon * polygonN(int index)
Returns the polygon with the specified index.
Polygon geometry type.
Definition qgspolygon.h:37
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Basic shading material used for rendering simple lines as solid line components.
Qt3DRender::QGeometry subclass that represents polygons tessellated into 3D geometry.
void setVertexBufferData(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.
void setIndexBufferData(const QByteArray &indexBufferData, size_t indexCount)
Sets index buffer data.
void setZ(double z)
Sets Z coordinate.
Definition qgsvector3d.h:80
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7148
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features