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