QGIS API Documentation 4.1.0-Master (3b8ef1f72a3)
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() : false;
96
97 auto lineDataNormalTessellator = std::make_unique<QgsTessellator>();
98 lineDataNormalTessellator->setOrigin( mChunkOrigin );
99 lineDataNormalTessellator->setAddNormals( true );
100 lineDataNormalTessellator->setAddTextureUVs( requiresTextureCoordinates );
101 lineDataNormalTessellator->setExtrusionFaces( Qgis::ExtrusionFace::Walls | Qgis::ExtrusionFace::Roof );
102 lineDataNormalTessellator->setTriangulationAlgorithm( Qgis::TriangulationAlgorithm::Earcut );
103
104 mLineDataNormal.tessellator = std::move( lineDataNormalTessellator );
105
106 auto lineDataSelectedTessellator = std::make_unique<QgsTessellator>();
107 lineDataSelectedTessellator->setOrigin( mChunkOrigin );
108 lineDataSelectedTessellator->setAddNormals( true );
109 lineDataSelectedTessellator->setAddTextureUVs( requiresTextureCoordinates );
110 lineDataSelectedTessellator->setExtrusionFaces( Qgis::ExtrusionFace::Walls | Qgis::ExtrusionFace::Roof );
111 lineDataSelectedTessellator->setTriangulationAlgorithm( Qgis::TriangulationAlgorithm::Earcut );
112
113 mLineDataSelected.tessellator = std::move( lineDataSelectedTessellator );
114
115 return true;
116}
117
118void QgsBufferedLine3DSymbolHandler::processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context )
119{
120 if ( feature.geometry().isNull() )
121 return;
122
123 LineData &lineData = mSelectedIds.contains( feature.id() ) ? mLineDataSelected : mLineDataNormal;
124
125 QgsGeometry geom = feature.geometry();
126 clipGeometryIfTooLarge( geom );
127
128 if ( geom.isEmpty() )
129 return;
130
131 const QgsAbstractGeometry *abstractGeom = geom.constGet()->simplifiedTypeRef();
132
133 // segmentize curved geometries if necessary
134 if ( QgsWkbTypes::isCurvedType( abstractGeom->wkbType() ) )
135 {
136 geom = QgsGeometry( abstractGeom->segmentize() );
137 abstractGeom = geom.constGet()->simplifiedTypeRef();
138 }
139
140 // TODO: configurable
141 const int nSegments = 4;
143 const Qgis::JoinStyle joinStyle = Qgis::JoinStyle::Round;
144 const double mitreLimit = 0;
145
146 const QgsGeos engine( abstractGeom );
147
148 double width = mSymbol->width();
149 if ( qgsDoubleNear( width, 0 ) )
150 {
151 // 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,
152 // so that we get a very narrow polygon shape to work with...
153 width = 0.001;
154 }
155
156 QgsAbstractGeometry *buffered = engine.buffer( width / 2., nSegments, endCapStyle, joinStyle, mitreLimit ); // factory
157 if ( !buffered )
158 return;
159
161 {
162 QgsPolygon *polyBuffered = qgsgeometry_cast<QgsPolygon *>( buffered );
163 processPolygon( polyBuffered, feature.id(), mSymbol->offset(), mSymbol->extrusionHeight(), context, lineData );
164 }
165 else if ( QgsWkbTypes::flatType( buffered->wkbType() ) == Qgis::WkbType::MultiPolygon )
166 {
167 QgsMultiPolygon *mpolyBuffered = qgsgeometry_cast<QgsMultiPolygon *>( buffered );
168 for ( int i = 0; i < mpolyBuffered->numGeometries(); ++i )
169 {
170 QgsPolygon *polyBuffered = qgsgeometry_cast<QgsPolygon *>( mpolyBuffered->polygonN( i ) )->clone(); // need to clone individual geometry parts
171 processPolygon( polyBuffered, feature.id(), mSymbol->offset(), mSymbol->extrusionHeight(), context, lineData );
172 }
173 delete buffered;
174 }
175 mFeatureCount++;
176}
177
178void QgsBufferedLine3DSymbolHandler::processPolygon( QgsPolygon *polyBuffered, QgsFeatureId fid, float height, float extrusionHeight, const Qgs3DRenderContext &context, LineData &lineData )
179{
180 Qgs3DUtils::clampAltitudes( polyBuffered, mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), height, context );
181
182 Q_ASSERT( lineData.tessellator->dataVerticesCount() % 3 == 0 );
183 const uint startingTriangleIndex = static_cast<uint>( lineData.tessellator->dataVerticesCount() / 3 );
184 lineData.triangleIndexStartingIndices.append( startingTriangleIndex );
185 lineData.triangleIndexFids.append( fid );
186 lineData.tessellator->addPolygon( *polyBuffered, extrusionHeight );
187 if ( !lineData.tessellator->error().isEmpty() )
188 {
189 QgsMessageLog::logMessage( lineData.tessellator->error(), QObject::tr( "3D" ) );
190 }
191
192 delete polyBuffered;
193}
194
195void QgsBufferedLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
196{
197 // create entity for selected and not selected
198 makeEntity( parent, context, mLineDataNormal, false );
199 makeEntity( parent, context, mLineDataSelected, true );
200
201 mZMin = std::min( mLineDataNormal.tessellator->zMinimum(), mLineDataSelected.tessellator->zMinimum() );
202 mZMax = std::max( mLineDataNormal.tessellator->zMaximum(), mLineDataSelected.tessellator->zMaximum() );
203}
204
205
206void QgsBufferedLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, LineData &lineData, bool selected )
207{
208 if ( lineData.tessellator->dataVerticesCount() == 0 )
209 return; // nothing to show - no need to create the entity
210
211 QgsMaterialContext materialContext;
212 materialContext.setIsSelected( selected );
213 materialContext.setSelectionColor( context.selectionColor() );
214 materialContext.setIsHighlighted( mHighlightingEnabled );
215
216 QgsMaterial *material = Qgs3D::toMaterial( mSymbol->materialSettings(), Qgis::MaterialRenderingTechnique::Triangles, materialContext );
217
218 // extract vertex buffer data from tessellator
219 const QByteArray vertexBuffer = lineData.tessellator->vertexBuffer();
220 const QByteArray indexBuffer = lineData.tessellator->indexBuffer();
221 const int vertexCount = vertexBuffer.count() / lineData.tessellator->stride();
222 const size_t indexCount = lineData.tessellator->dataVerticesCount();
223
224 QgsTessellatedPolygonGeometry *geometry = new QgsTessellatedPolygonGeometry( true, false, false, mSymbol->materialSettings() ? mSymbol->materialSettings()->requiresTextureCoordinates() : false );
225 geometry->setVertexBufferData( vertexBuffer, vertexCount, lineData.triangleIndexFids, lineData.triangleIndexStartingIndices );
226 geometry->setIndexBufferData( indexBuffer, indexCount );
227
228 Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer;
229 renderer->setGeometry( geometry );
230
231 // add transform (our geometry has coordinates relative to mChunkOrigin)
232 QgsGeoTransform *transform = new QgsGeoTransform;
233 transform->setGeoTranslation( mChunkOrigin );
234
235 // make entity
236 Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
237 entity->addComponent( renderer );
238 entity->addComponent( material );
239 entity->addComponent( transform );
240 entity->setParent( parent );
241
242 if ( !selected )
243 renderer->setProperty( Qgs3DTypes::PROP_NAME_3D_RENDERER_FLAG, Qgs3DTypes::Main3DRenderer ); // temporary measure to distinguish between "selected" and "main"
244
245 // cppcheck wrongly believes entity will leak
246 // cppcheck-suppress memleak
247}
248
249
250// --------------
251
252
253class QgsThickLine3DSymbolHandler : public QgsFeature3DHandler
254{
255 public:
256 QgsThickLine3DSymbolHandler( const QgsLine3DSymbol *symbol, const QgsFeatureIds &selectedIds )
257 : mSymbol( static_cast<QgsLine3DSymbol *>( symbol->clone() ) )
258 , mSelectedIds( selectedIds )
259 {}
260
261 bool prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames, const QgsBox3D &chunkExtent ) override;
262 void processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context ) override;
263 void finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context ) override;
264
265 private:
266 void makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, QgsLineVertexData &lineVertexData, bool selected );
267 Qt3DExtras::QPhongMaterial *material( const QgsLine3DSymbol &symbol ) const;
268 void processMaterialDatadefined( uint verticesCount, const QgsExpressionContext &context, QgsLineVertexData &lineVertexData );
269
270 // input specific for this class
271 std::unique_ptr<QgsLine3DSymbol> mSymbol;
272 // inputs - generic
273 QgsFeatureIds mSelectedIds;
274 // outputs
275 QgsLineVertexData mLineDataNormal;
276 QgsLineVertexData mLineDataSelected;
277};
278
279
280bool QgsThickLine3DSymbolHandler::prepare( const Qgs3DRenderContext &context, QSet<QString> &attributeNames, const QgsBox3D &chunkExtent )
281{
282 Q_UNUSED( attributeNames )
283
284 mChunkOrigin = chunkExtent.center();
285 mChunkExtent = chunkExtent;
286
287 mLineDataNormal.withAdjacency = true;
288 mLineDataSelected.withAdjacency = true;
289 mLineDataNormal.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context, mChunkOrigin );
290 mLineDataSelected.init( mSymbol->altitudeClamping(), mSymbol->altitudeBinding(), mSymbol->offset(), context, mChunkOrigin );
291
292 QSet<QString> attrs = mSymbol->dataDefinedProperties().referencedFields( context.expressionContext() );
293 attributeNames.unite( attrs );
294 attrs = mSymbol->materialSettings()->dataDefinedProperties().referencedFields( context.expressionContext() );
295 attributeNames.unite( attrs );
296
297 if ( mSymbol->materialSettings()->dataDefinedProperties().isActive( QgsAbstractMaterialSettings::Property::Ambient ) )
298 {
299 processMaterialDatadefined( mLineDataNormal.vertices.size(), context.expressionContext(), mLineDataNormal );
300 processMaterialDatadefined( mLineDataSelected.vertices.size(), context.expressionContext(), mLineDataSelected );
301 }
302
303 return true;
304}
305
306void QgsThickLine3DSymbolHandler::processFeature( const QgsFeature &feature, const Qgs3DRenderContext &context )
307{
308 Q_UNUSED( context )
309 if ( feature.geometry().isNull() )
310 return;
311
312 QgsLineVertexData &lineVertexData = mSelectedIds.contains( feature.id() ) ? mLineDataSelected : mLineDataNormal;
313
314 const int oldVerticesCount = lineVertexData.vertices.size();
315
316 QgsGeometry geom = feature.geometry();
317 ( void ) clipGeometryIfTooLarge( geom );
318
319 if ( geom.isEmpty() )
320 return;
321
322 const QgsAbstractGeometry *abstractGeom = geom.constGet()->simplifiedTypeRef();
323
324 // segmentize curved geometries if necessary
325 if ( QgsWkbTypes::isCurvedType( abstractGeom->wkbType() ) )
326 {
327 geom = QgsGeometry( abstractGeom->segmentize() );
328 abstractGeom = geom.constGet()->simplifiedTypeRef();
329 }
330
331 if ( const QgsLineString *lineString = qgsgeometry_cast<const QgsLineString *>( abstractGeom ) )
332 {
333 lineVertexData.addLineString( *lineString );
334 }
335 else if ( const QgsMultiLineString *multiLineString = qgsgeometry_cast<const QgsMultiLineString *>( abstractGeom ) )
336 {
337 for ( int nGeom = 0; nGeom < multiLineString->numGeometries(); ++nGeom )
338 {
339 const QgsLineString *lineString = multiLineString->lineStringN( nGeom );
340 lineVertexData.addLineString( *lineString );
341 }
342 }
343
344 if ( mSymbol->materialSettings()->dataDefinedProperties().isActive( QgsAbstractMaterialSettings::Property::Ambient ) )
345 processMaterialDatadefined( lineVertexData.vertices.size() - oldVerticesCount, context.expressionContext(), lineVertexData );
346
347 mFeatureCount++;
348}
349
350void QgsThickLine3DSymbolHandler::finalize( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context )
351{
352 // create entity for selected and not selected
353 makeEntity( parent, context, mLineDataNormal, false );
354 makeEntity( parent, context, mLineDataSelected, true );
355
356 updateZRangeFromPositions( mLineDataNormal.vertices );
357 updateZRangeFromPositions( mLineDataSelected.vertices );
358}
359
360
361void QgsThickLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, QgsLineVertexData &lineVertexData, bool selected )
362{
363 if ( lineVertexData.indexes.isEmpty() )
364 return;
365
366 // material (only ambient color is used for the color)
367 QgsMaterialContext materialContext;
368 materialContext.setIsSelected( selected );
369 materialContext.setSelectionColor( context.selectionColor() );
370
371 QgsMaterial *material = Qgs3D::toMaterial( mSymbol->materialSettings(), Qgis::MaterialRenderingTechnique::Lines, materialContext );
372 if ( !material )
373 {
374 const QgsSimpleLineMaterialSettings defaultMaterial;
375 material = Qgs3D::toMaterial( &defaultMaterial, Qgis::MaterialRenderingTechnique::Lines, materialContext );
376 }
377
378 if ( QgsLineMaterial *lineMaterial = dynamic_cast<QgsLineMaterial *>( material ) )
379 {
380 float width = mSymbol->width();
381 if ( mHighlightingEnabled )
382 {
383 const QgsSettings settings;
384 const QColor color = QColor( settings.value( u"Map/highlight/color"_s, Qgis::DEFAULT_HIGHLIGHT_COLOR.name() ).toString() );
385 lineMaterial->setLineColor( color );
386 // This is a workaround, make lines thicker to avoid rendering thin lines as three parallel lines with a gap between them
387 // Ideally we would want highlighted lines to be:
388 // - Rendered with an increased line width during highlights render view first pass
389 // - Not rendered during highlights render view second pass (multi-viewport one)
390 width = std::max<float>( static_cast<float>( QgsHighlightsRenderView::silhouetteWidth() * 2 ), mSymbol->width() );
391 }
392 lineMaterial->setLineWidth( width );
393 }
394
395 Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
396
397 // geometry renderer
398 Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer;
399 renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStripAdjacency );
400 Qt3DCore::QGeometry *geometry = lineVertexData.createGeometry( entity );
401
402 if ( mSymbol->materialSettings()->dataDefinedProperties().isActive( QgsAbstractMaterialSettings::Property::Ambient ) )
403 {
404 Qgs3D::applyMaterialDataDefinedToGeometry( mSymbol->materialSettings(), geometry, lineVertexData.vertices.size(), lineVertexData.materialDataDefined );
405 }
406
407 renderer->setGeometry( geometry );
408
409 renderer->setVertexCount( lineVertexData.indexes.count() );
410 renderer->setPrimitiveRestartEnabled( true );
411 renderer->setRestartIndexValue( 0 );
412
413 // add transform (our geometry has coordinates relative to mChunkOrigin)
414 QgsGeoTransform *transform = new QgsGeoTransform;
415 transform->setGeoTranslation( mChunkOrigin );
416
417 // make entity
418 entity->addComponent( renderer );
419 entity->addComponent( material );
420 entity->addComponent( transform );
421 entity->setParent( parent );
422}
423
424void QgsThickLine3DSymbolHandler::processMaterialDatadefined( uint verticesCount, const QgsExpressionContext &context, QgsLineVertexData &lineVertexData )
425{
426 const QByteArray bytes = Qgs3D::materialDataDefinedVertexColorsAsByte( mSymbol->materialSettings(), context );
427 lineVertexData.materialDataDefined.append( bytes.repeated( static_cast<int>( verticesCount ) ) );
428}
429
430
431// --------------
432
433
434namespace Qgs3DSymbolImpl
435{
436
437 QgsFeature3DHandler *handlerForLine3DSymbol( QgsVectorLayer *layer, const QgsAbstract3DSymbol *symbol )
438 {
439 const QgsLine3DSymbol *lineSymbol = dynamic_cast<const QgsLine3DSymbol *>( symbol );
440 if ( !lineSymbol )
441 return nullptr;
442
443 if ( lineSymbol->renderAsSimpleLines() )
444 return new QgsThickLine3DSymbolHandler( lineSymbol, layer->selectedFeatureIds() );
445 else
446 return new QgsBufferedLine3DSymbolHandler( lineSymbol, layer->selectedFeatureIds() );
447 }
448} // namespace Qgs3DSymbolImpl
449
static const QColor DEFAULT_HIGHLIGHT_COLOR
Default highlight color.
Definition qgis.h:6652
JoinStyle
Join styles for buffers.
Definition qgis.h:2241
@ Round
Use rounded joins.
Definition qgis.h:2242
EndCapStyle
End cap styles for buffers.
Definition qgis.h:2228
@ Round
Round cap.
Definition qgis.h:2229
@ Triangles
Triangle based rendering (default).
Definition qgis.h:4328
@ Lines
Line based rendering, requires line data.
Definition qgis.h:4329
@ Polygon
Polygon.
Definition qgis.h:298
@ MultiPolygon
MultiPolygon.
Definition qgis.h:302
Rendering context for preparation of 3D entities.
QColor selectionColor() const
Returns color used for selected features.
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:141
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:175
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:167
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 setSelectionColor(const QColor &color)
Sets the color for representing materials in a selected state.
void setIsHighlighted(bool isHighlighted)
Sets whether the material should represent a highlighted state.
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:7077
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features