QGIS API Documentation 4.3.0-Master (0ff9723465c)
Loading...
Searching...
No Matches
qgsrubberband3d.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrubberband3d.cpp
3 --------------------------------------
4 Date : June 2021
5 Copyright : (C) 2021 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 "qgsrubberband3d.h"
17
18#include "qgs3d.h"
19#include "qgs3dmapscene.h"
20#include "qgs3dmapsettings.h"
21#include "qgs3dutils.h"
22#include "qgsabstract3dengine.h"
24#include "qgsframegraph.h"
25#include "qgsgeotransform.h"
26#include "qgslinematerial_p.h"
27#include "qgslinestring.h"
28#include "qgslinevertexdata_p.h"
29#include "qgsmarkersymbol.h"
31#include "qgsmessagelog.h"
33#include "qgspolygon.h"
35#include "qgssymbollayer.h"
36#include "qgssymbollayerutils.h"
38#include "qgstessellator.h"
39#include "qgsunlitmaterial.h"
40#include "qgsvertexid.h"
41
42#include <QColor>
43#include <QString>
44#include <Qt3DCore/QAttribute>
45#include <Qt3DCore/QBuffer>
46#include <Qt3DCore/QEntity>
47#include <Qt3DCore/QGeometry>
48#include <Qt3DRender/QGeometryRenderer>
49
50using namespace Qt::StringLiterals;
51
53
54
55QgsRubberBand3D::QgsRubberBand3D( Qgs3DMapScene *scene, const Qgis::GeometryType geometryType )
56 : mMapSettings( scene->mapSettings() )
57 , mEngine( scene->engine() )
58 , mGeometryType( geometryType )
59{
60 Qt3DCore::QEntity *parentEntity = mEngine->frameGraph()->rubberBandRenderView().rubberBandEntity();
61
62 switch ( mGeometryType )
63 {
65 setupMarker( parentEntity );
66 break;
68 setupLine( parentEntity );
69 setupMarker( parentEntity );
70 break;
72 setupMarker( parentEntity );
73 setupLine( parentEntity );
74 setupPolygon( parentEntity );
75 break;
78 QgsDebugError( "Unknown GeometryType used in QgsRubberband3D" );
79 break;
80 }
81}
82
83void QgsRubberBand3D::setupMarker( Qt3DCore::QEntity *parentEntity )
84{
85 mMarkerEntity = make_qobject_unique<Qt3DCore::QEntity>( parentEntity );
86 mMarkerGeometry = new QgsBillboardGeometry();
87 mMarkerGeometryRenderer = new Qt3DRender::QGeometryRenderer;
88 mMarkerGeometryRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::TriangleStrip );
89 mMarkerGeometryRenderer->setGeometry( mMarkerGeometry );
90 mMarkerGeometryRenderer->setVertexCount( 4 );
91 mMarkerGeometryRenderer->setInstanceCount( 0 );
92
93 setMarkerType( mMarkerType );
94 mMarkerEntity->addComponent( mMarkerGeometryRenderer );
95
96 mMarkerTransform = new QgsGeoTransform;
97 mMarkerTransform->setOrigin( mMapSettings->origin() );
98 mMarkerEntity->addComponent( mMarkerTransform );
99}
100
101void QgsRubberBand3D::setupLine( Qt3DCore::QEntity *parentEntity )
102{
103 mLineEntity = make_qobject_unique<Qt3DCore::QEntity>( parentEntity );
104
105 QgsLineVertexData dummyLineData;
106 mLineGeometry = dummyLineData.createGeometry( mLineEntity );
107
108 Q_ASSERT( mLineGeometry->attributes().count() == 5 );
109 mPointAAttribute = mLineGeometry->attributes().at( 1 );
110 mPointBAttribute = mLineGeometry->attributes().at( 2 );
111 mPointPrevAttribute = mLineGeometry->attributes().at( 3 );
112 mPointNextAttribute = mLineGeometry->attributes().at( 4 );
113
114 mLineGeometryRenderer = new Qt3DRender::QGeometryRenderer;
115 mLineGeometryRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::Triangles );
116 mLineGeometryRenderer->setGeometry( mLineGeometry );
117 mLineGeometryRenderer->setVertexCount( 6 );
118 mLineGeometryRenderer->setInstanceCount( 0 );
119
120 mLineEntity->addComponent( mLineGeometryRenderer );
121
122 mLineMaterial = new QgsLineMaterial;
123 mLineMaterial->setLineWidth( mWidth );
124 mLineMaterial->setLineColor( mColor );
125
126 QObject::connect( mEngine, &QgsAbstract3DEngine::sizeChanged, mLineMaterial, [this] { mLineMaterial->setViewportSize( mEngine->size() ); } );
127 mLineMaterial->setViewportSize( mEngine->size() );
128
129 mLineEntity->addComponent( mLineMaterial );
130
131 mLineTransform = new QgsGeoTransform;
132 mLineTransform->setOrigin( mMapSettings->origin() );
133 mLineEntity->addComponent( mLineTransform );
134
135 mJoinEntity = make_qobject_unique<Qt3DCore::QEntity>( parentEntity );
136
137 mJoinGeometry = dummyLineData.createJoinGeometry( mJoinEntity );
138
139 mJoinPointAAttribute = mJoinGeometry->attributes().at( 1 );
140 mJoinPointBAttribute = mJoinGeometry->attributes().at( 2 );
141 mJoinPointCAttribute = mJoinGeometry->attributes().at( 3 );
142
143 mJoinGeometryRenderer = new Qt3DRender::QGeometryRenderer;
144 mJoinGeometryRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::Triangles );
145 mJoinGeometryRenderer->setGeometry( mJoinGeometry );
146 mJoinGeometryRenderer->setVertexCount( 6 );
147 mJoinGeometryRenderer->setInstanceCount( 0 );
148
149 mJoinEntity->addComponent( mJoinGeometryRenderer );
150
151 mJoinMaterial = new QgsLineMaterial( QgsLineMaterial::LinePart::Join );
152 mJoinMaterial->setLineWidth( mWidth );
153 mJoinMaterial->setLineColor( mColor );
154
155 QObject::connect( mEngine, &QgsAbstract3DEngine::sizeChanged, mJoinMaterial, [this] { mJoinMaterial->setViewportSize( mEngine->size() ); } );
156 mJoinMaterial->setViewportSize( mEngine->size() );
157
158 mJoinEntity->addComponent( mJoinMaterial );
159
160 mJoinTransform = new QgsGeoTransform;
161 mJoinTransform->setOrigin( mMapSettings->origin() );
162 mJoinEntity->addComponent( mJoinTransform );
163}
164
165void QgsRubberBand3D::setupPolygon( Qt3DCore::QEntity *parentEntity )
166{
167 mPolygonEntity = make_qobject_unique<Qt3DCore::QEntity>( parentEntity );
168
169 mPolygonGeometry = new QgsTessellatedPolygonGeometry();
170
171 Qt3DRender::QGeometryRenderer *polygonGeometryRenderer = new Qt3DRender::QGeometryRenderer;
172 polygonGeometryRenderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::Triangles );
173 polygonGeometryRenderer->setGeometry( mPolygonGeometry );
174 mPolygonEntity->addComponent( polygonGeometryRenderer );
175
176 QColor color = mColor;
177 color.setAlphaF( DEFAULT_POLYGON_OPACITY );
178 mPolygonMaterial = new QgsUnlitMaterial();
179 mPolygonMaterial->setColor( color );
180
181 mPolygonEntity->addComponent( mPolygonMaterial );
182
183 mPolygonTransform = new QgsGeoTransform;
184 mPolygonTransform->setOrigin( mMapSettings->origin() );
185 mPolygonEntity->addComponent( mPolygonTransform );
186}
187
188void QgsRubberBand3D::removePoint( int index )
189{
190 if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometry.get() ) )
191 {
192 QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( polygon->exteriorRing() );
193 const int vertexIndex = index < 0 ? lineString->numPoints() - 1 + index : index;
194 lineString->deleteVertex( QgsVertexId( 0, 0, vertexIndex ) );
195
196 if ( lineString->numPoints() < 3 )
197 {
198 mGeometry.set( new QgsLineString( *lineString ) );
199 }
200 }
201 else if ( QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( mGeometry.get() ) )
202 {
203 const int vertexIndex = index < 0 ? lineString->numPoints() + index : index;
204 lineString->deleteVertex( QgsVertexId( 0, 0, vertexIndex ) );
205 }
206 else
207 {
208 return;
209 }
210
211 updateGeometry();
212}
213
214QgsRubberBand3D::~QgsRubberBand3D()
215{
216 if ( mPolygonEntity )
217 {
218 mPolygonEntity.reset();
219 }
220 if ( mLineEntity )
221 {
222 mLineEntity.reset();
223 }
224 if ( mJoinEntity )
225 {
226 mJoinEntity.reset();
227 }
228 if ( mMarkerEntity )
229 {
230 mMarkerEntity.reset();
231 }
232}
233
234
235float QgsRubberBand3D::width() const
236{
237 return mWidth;
238}
239
240void QgsRubberBand3D::setWidth( float width )
241{
242 const bool isLineOrPolygon = mGeometryType == Qgis::GeometryType::Line || mGeometryType == Qgis::GeometryType::Polygon;
243 mWidth = width;
244
245 if ( isLineOrPolygon && mEdgesEnabled )
246 {
247 // when highlighting lines, the vertex markers should be wider
248 mLineMaterial->setLineWidth( width );
249 mJoinMaterial->setLineWidth( width );
250 width *= 3;
251 }
252
253 mMarkerSymbol->setSize( width );
254 updateMarkerMaterial();
255}
256
257QColor QgsRubberBand3D::color() const
258{
259 return mColor;
260}
261
262void QgsRubberBand3D::setColor( const QColor color )
263{
264 const bool isLineOrPolygon = mGeometryType == Qgis::GeometryType::Line || mGeometryType == Qgis::GeometryType::Polygon;
265 mColor = color;
266
267 if ( mEdgesEnabled && isLineOrPolygon )
268 {
269 mLineMaterial->setLineColor( color );
270 mJoinMaterial->setLineColor( color );
271 }
272
273 if ( isLineOrPolygon )
274 {
275 mMarkerSymbol->setColor( color.lighter( 130 ) );
276 }
277 else
278 {
279 mMarkerSymbol->setColor( color );
280 }
281
282 if ( mMarkerSymbol->symbolLayerCount() > 0 && mMarkerSymbol->symbolLayer( 0 )->layerType() == "SimpleMarker"_L1 && !mOutlineColor.value() )
283 {
284 mMarkerSymbol->symbolLayer( 0 )->setStrokeColor( color );
285 }
286 updateMarkerMaterial();
287
288 if ( mGeometryType == Qgis::GeometryType::Polygon )
289 {
290 if ( mPolygonMaterial )
291 mPolygonEntity->removeComponent( mPolygonMaterial );
292
293 if ( mPolygonFillEnabled )
294 {
295 QColor color = mColor;
296 color.setAlphaF( DEFAULT_POLYGON_OPACITY );
297 mPolygonMaterial = new QgsUnlitMaterial();
298 mPolygonMaterial->setColor( color );
299 mPolygonEntity->addComponent( mPolygonMaterial );
300 }
301 }
302}
303
304QColor QgsRubberBand3D::outlineColor() const
305{
306 return mOutlineColor;
307}
308
309void QgsRubberBand3D::setOutlineColor( const QColor color )
310{
311 mOutlineColor = color;
312
313 if ( mMarkerSymbol->symbolLayerCount() > 0 && mMarkerSymbol->symbolLayer( 0 )->layerType() == "SimpleMarker"_L1 )
314 {
315 mMarkerSymbol->symbolLayer( 0 )->setStrokeColor( color );
316 }
317 updateMarkerMaterial();
318}
319
320void QgsRubberBand3D::setMarkerType( const MarkerType marker )
321{
322 mMarkerType = marker;
323
324 const bool lineOrPolygon = mGeometryType == Qgis::GeometryType::Line || mGeometryType == Qgis::GeometryType::Polygon;
325
326 const QVariantMap props {
327 { u"color"_s, lineOrPolygon ? mColor.lighter( 130 ).name() : mColor.name() },
328 { u"size_unit"_s, u"pixel"_s },
329 { u"size"_s, QString::number( lineOrPolygon ? mWidth * 3.f : mWidth ) },
330 { u"outline_color"_s, mOutlineColor.value() ? mOutlineColor.name() : mColor.name() },
331 { u"outline_style"_s, QgsSymbolLayerUtils::encodePenStyle( mMarkerOutlineStyle ) },
332 { u"outline_width"_s, QString::number( lineOrPolygon ? 0.5 : 1 ) },
333 { u"name"_s, mMarkerType == Square ? u"square"_s : u"circle"_s }
334 };
335
336 mMarkerSymbol = QgsMarkerSymbol::createSimple( props );
337 updateMarkerMaterial();
338}
339
340QgsRubberBand3D::MarkerType QgsRubberBand3D::markerType() const
341{
342 return mMarkerType;
343}
344
345void QgsRubberBand3D::setMarkerOutlineStyle( const Qt::PenStyle style )
346{
347 mMarkerOutlineStyle = style;
348 setMarkerType( markerType() );
349}
350
351Qt::PenStyle QgsRubberBand3D::markerOutlineStyle() const
352{
353 return mMarkerOutlineStyle;
354}
355
356void QgsRubberBand3D::setMarkersEnabled( const bool enable )
357{
358 mMarkerEnabled = enable;
359 updateMarkerMaterial();
360}
361
362bool QgsRubberBand3D::hasMarkersEnabled() const
363{
364 return mMarkerEnabled;
365}
366
367void QgsRubberBand3D::setEdgesEnabled( const bool enable )
368{
369 mEdgesEnabled = enable;
370 setColor( mColor );
371}
372
373bool QgsRubberBand3D::hasEdgesEnabled() const
374{
375 return mEdgesEnabled;
376}
377
378void QgsRubberBand3D::setFillEnabled( const bool enable )
379{
380 mPolygonFillEnabled = enable;
381 setColor( mColor );
382}
383
384bool QgsRubberBand3D::hasFillEnabled() const
385{
386 return mPolygonFillEnabled;
387}
388
389void QgsRubberBand3D::reset()
390{
391 mGeometry.set( nullptr );
392 updateGeometry();
393}
394
395void QgsRubberBand3D::addPoint( const QgsPoint &pt )
396{
397 if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometry.get() ) )
398 {
399 QgsLineString *exteriorRing = qgsgeometry_cast<QgsLineString *>( polygon->exteriorRing() );
400 const int lastVertexIndex = exteriorRing->numPoints() - 1;
401 exteriorRing->insertVertex( QgsVertexId( 0, 0, lastVertexIndex ), pt );
402 }
403 else if ( QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( mGeometry.get() ) )
404 {
405 lineString->addVertex( pt );
406 // transform linestring to polygon if we have enough vertices
407 if ( mGeometryType == Qgis::GeometryType::Polygon && lineString->numPoints() >= 3 )
408 {
409 mGeometry.set( new QgsPolygon( lineString->clone() ) );
410 }
411 }
412 else if ( !mGeometry.constGet() )
413 {
414 mGeometry.set( new QgsLineString( QVector<QgsPoint> { pt } ) );
415 }
416
417 updateGeometry();
418}
419
420void QgsRubberBand3D::setGeometry( const QgsGeometry &geometry )
421{
422 mGeometry = geometry;
423 mGeometryType = geometry.type();
424
425 updateGeometry();
426}
427
428void QgsRubberBand3D::removeLastPoint()
429{
430 removePoint( -1 );
431}
432
433void QgsRubberBand3D::removePenultimatePoint()
434{
435 removePoint( -2 );
436}
437
438void QgsRubberBand3D::moveLastPoint( const QgsPoint &pt )
439{
440 if ( QgsPolygon *polygon = qgsgeometry_cast<QgsPolygon *>( mGeometry.get() ) )
441 {
442 QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( polygon->exteriorRing() );
443 const int lastVertexIndex = lineString->numPoints() - 2;
444 lineString->moveVertex( QgsVertexId( 0, 0, lastVertexIndex ), pt );
445 }
446 else if ( QgsLineString *lineString = qgsgeometry_cast<QgsLineString *>( mGeometry.get() ) )
447 {
448 const int lastVertexIndex = lineString->numPoints() - 1;
449 lineString->moveVertex( QgsVertexId( 0, 0, lastVertexIndex ), pt );
450 }
451 else
452 {
453 return;
454 }
455
456 updateGeometry();
457}
458
459void QgsRubberBand3D::updateGeometry()
460{
461 // figure out a reasonable origin for the coordinates to keep them as small as possible
462 const QgsBox3D box = mGeometry.constGet() ? mGeometry.constGet()->boundingBox3D() : QgsBox3D();
463 const QgsVector3D dataOrigin = box.isNull() ? mMapSettings->origin() : box.center();
464
465 QgsLineVertexData lineData;
466 lineData.geocentricCoordinates = mMapSettings->sceneMode() == Qgis::SceneMode::Globe;
468 if ( const QgsPolygon *polygon = qgsgeometry_cast<const QgsPolygon *>( mGeometry.constGet() ) )
469 {
470 std::unique_ptr< QgsLineString > lineString( qgsgeometry_cast<QgsLineString *>( polygon->exteriorRing()->clone() ) );
471 const int lastVertexIndex = lineString->numPoints() - 1;
472 lineString->deleteVertex( QgsVertexId( 0, 0, lastVertexIndex ) );
473 lineData.addLineString( *lineString, 0, true );
474 }
475 else if ( const QgsLineString *lineString = qgsgeometry_cast<const QgsLineString *>( mGeometry.constGet() ) )
476 {
477 lineData.addLineString( *lineString, 0, false );
478 }
479
480
481 if ( mEdgesEnabled && ( mGeometryType == Qgis::GeometryType::Line || mGeometryType == Qgis::GeometryType::Polygon ) )
482 {
483 mPointAAttribute->buffer()->setData( lineData.createPointABuffer() );
484 mPointBAttribute->buffer()->setData( lineData.createPointBBuffer() );
485 mPointPrevAttribute->buffer()->setData( lineData.createPointPrevBuffer() );
486 mPointNextAttribute->buffer()->setData( lineData.createPointNextBuffer() );
487 mLineGeometryRenderer->setInstanceCount( lineData.pointsA.size() );
488 mLineTransform->setGeoTranslation( dataOrigin );
489
490 mJoinPointAAttribute->buffer()->setData( lineData.createJoinPointABuffer() );
491 mJoinPointBAttribute->buffer()->setData( lineData.createJoinPointBBuffer() );
492 mJoinPointCAttribute->buffer()->setData( lineData.createJoinPointCBuffer() );
493 mJoinGeometryRenderer->setInstanceCount( lineData.joinPointA.size() );
494 mJoinTransform->setGeoTranslation( dataOrigin );
495 }
496
497 // we may not want a marker on the last point as it's tracked by the mouse cursor
498 if ( mHideLastMarker && !lineData.vertices.isEmpty() )
499 lineData.vertices.pop_back();
500
501 mMarkerGeometry->setPositions( lineData.vertices );
502 mMarkerGeometryRenderer->setVertexCount( 4 );
503 mMarkerGeometryRenderer->setInstanceCount( lineData.vertices.count() );
504 mMarkerTransform->setGeoTranslation( dataOrigin );
505
506 if ( mGeometryType == Qgis::GeometryType::Polygon )
507 {
508 if ( const QgsPolygon *polygon = qgsgeometry_cast<const QgsPolygon *>( mGeometry.constGet() ) )
509 {
510 QgsTessellator tessellator;
511 tessellator.setOrigin( mMapSettings->origin() );
512 tessellator.setAddNormals( true );
513 tessellator.addPolygon( *polygon, 0 );
514 if ( !tessellator.error().isEmpty() )
515 {
516 QgsMessageLog::logMessage( tessellator.error(), QObject::tr( "3D" ) );
517 }
518 // extract vertex buffer data from tessellator
519 const QByteArray vertexBuffer = tessellator.vertexBuffer();
520 const QByteArray indexBuffer = tessellator.indexBuffer();
521 const size_t vertexCount = tessellator.uniqueVertexCount();
522 const size_t indexCount = tessellator.dataVerticesCount();
523
524 mPolygonGeometry->setVertexBufferData( vertexBuffer, vertexCount, QVector<QgsFeatureId>(), QVector<uint>() );
525 mPolygonGeometry->setIndexBufferData( indexBuffer, indexCount );
526 mPolygonTransform->setGeoTranslation( mMapSettings->origin() );
527 }
528 else
529 {
530 mPolygonGeometry->setVertexBufferData( QByteArray(), 0, QVector<QgsFeatureId>(), QVector<uint>() );
531 mPolygonGeometry->setIndexBufferData( QByteArray(), 0 );
532 }
533 }
534}
535
536void QgsRubberBand3D::updateMarkerMaterial()
537{
538 if ( mMarkerEnabled )
539 {
540 if ( !mMarkerMaterial )
541 {
542 mMarkerMaterial = new QgsPoint3DBillboardMaterial();
543 mMarkerEntity->addComponent( mMarkerMaterial );
544 //TODO: QgsAbstract3DEngine::sizeChanged should have const QSize &size param
545 QObject::connect( mEngine, &QgsAbstract3DEngine::sizeChanged, mMarkerMaterial, [material = mMarkerMaterial, engine = mEngine] { material->setViewportSize( engine->size() ); } );
546 }
547
548 mMarkerMaterial->setTexture2DFromSymbol( mMarkerSymbol.get(), Qgs3DRenderContext::fromMapSettings( mMapSettings ) );
549 mMarkerMaterial->setViewportSize( mEngine->size() );
550 }
551 else if ( !mMarkerEnabled && mMarkerMaterial )
552 {
553 mMarkerEntity->removeComponent( mMarkerMaterial );
554 mMarkerMaterial->setParent( static_cast<Qt3DCore::QEntity *>( nullptr ) );
555 mMarkerMaterial->deleteLater();
556 mMarkerMaterial = nullptr;
557 }
558}
@ Absolute
Elevation is taken directly from feature and is independent of terrain height (final elevation = feat...
Definition qgis.h:4226
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:379
@ Point
Points.
Definition qgis.h:380
@ Line
Lines.
Definition qgis.h:381
@ Polygon
Polygons.
Definition qgis.h:382
@ Unknown
Unknown types.
Definition qgis.h:383
@ Null
No geometry.
Definition qgis.h:384
@ Vertex
Clamp every vertex of feature.
Definition qgis.h:4239
@ Globe
Scene is represented as a globe using a geocentric CRS.
Definition qgis.h:4574
Entity that encapsulates our 3D scene - contains all other entities (such as terrain) as children.
static Qgs3DRenderContext fromMapSettings(const Qgs3DMapSettings *mapSettings)
Creates an initialized Qgs3DRenderContext instance from given Qgs3DMapSettings.
void sizeChanged()
Emitted after a call to setSize().
Geometry of the billboard rendering for points in 3D map view.
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:45
QgsVector3D center() const
Returns the center of the box as a vector.
Definition qgsbox3d.cpp:124
bool isNull() const
Test if the box is null (holding no spatial information).
Definition qgsbox3d.cpp:311
A geometry is the spatial representation of a feature.
Qgis::GeometryType type
Line string geometry type, with support for z-dimension and m-values.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
static std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
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).
Material of the billboard rendering for points in 3D map view.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
Polygon geometry type.
Definition qgspolygon.h:37
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
int numPoints() const override
Returns the number of points in the curve.
static QString encodePenStyle(Qt::PenStyle style)
Qt3DRender::QGeometry subclass that represents polygons tessellated into 3D geometry.
Tessellates polygons into triangles.
void setOrigin(const QgsVector3D &origin)
Sets the origin point of the map.
QByteArray vertexBuffer() const
Returns vertex buffer for the generated points.
void addPolygon(const QgsPolygon &polygon, float extrusionHeight)
Tessellates a triangle and adds its vertex entries to the output data array.
int uniqueVertexCount() const
Returns unique vertex count.
QByteArray indexBuffer() const
Returns index buffer for the generated points.
QString error() const
Returns a descriptive error string if the tessellation failed.
int dataVerticesCount() const
Returns the number of vertices stored in the output data array.
void setAddNormals(bool addNormals)
Sets whether normals should be added to the output data.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Definition qgsvector3d.h:33
T qgsgeometry_cast(QgsAbstractGeometry *geom)
#define QgsDebugError(str)
Definition qgslogger.h:71
constexpr QObjectUniquePtr< Tp > make_qobject_unique(Args &&...args)
Create an object owned by a QObjectUniquePtr.
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:35