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