QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgspoint3dsymbol.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspoint3dsymbol.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 "qgspoint3dsymbol.h"
17
18#include "qgs3dutils.h"
19#include "qgsreadwritecontext.h"
20#include "qgsxmlutils.h"
21#include "qgssymbollayerutils.h"
22#include "qgs3d.h"
23#include "qgsmaterialregistry.h"
24#include "qgs3dexportobject.h"
25#include "qgs3dsceneexporter.h"
26#include "qgsmarkersymbol.h"
27#include "qgsvectorlayer.h"
29
31{
32 return new QgsPoint3DSymbol( *this );
33}
34
36{
37 return new QgsPoint3DSymbol();
38}
39
41 : mMaterial( std::make_unique< QgsPhongMaterialSettings >() )
42{
44}
45
47 : mAltClamping( other.altitudeClamping() )
48 , mMaterial( other.material() ? other.material()->clone() : nullptr )
49 , mShape( other.shape() )
50 , mShapeProperties( other.shapeProperties() )
51 , mTransform( other.transform() )
52 , mBillboardSymbol( other.billboardSymbol() ? other.billboardSymbol()->clone() : nullptr )
53{
54 setDataDefinedProperties( other.dataDefinedProperties() );
55}
56
58
59void QgsPoint3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
60{
61 QDomDocument doc = elem.ownerDocument();
62
63 QDomElement elemDataProperties = doc.createElement( QStringLiteral( "data" ) );
64 elemDataProperties.setAttribute( QStringLiteral( "alt-clamping" ), Qgs3DUtils::altClampingToString( mAltClamping ) );
65 elem.appendChild( elemDataProperties );
66
67 elem.setAttribute( QStringLiteral( "material_type" ), mMaterial->type() );
68 QDomElement elemMaterial = doc.createElement( QStringLiteral( "material" ) );
69 mMaterial->writeXml( elemMaterial, context );
70 elem.appendChild( elemMaterial );
71
72 elem.setAttribute( QStringLiteral( "shape" ), shapeToString( mShape ) );
73
74 QVariantMap shapePropertiesCopy( mShapeProperties );
75 shapePropertiesCopy[QStringLiteral( "model" )] = QVariant( context.pathResolver().writePath( shapePropertiesCopy[QStringLiteral( "model" )].toString() ) );
76
77 QDomElement elemShapeProperties = doc.createElement( QStringLiteral( "shape-properties" ) );
78 elemShapeProperties.appendChild( QgsXmlUtils::writeVariant( shapePropertiesCopy, doc ) );
79 elem.appendChild( elemShapeProperties );
80
81 QDomElement elemTransform = doc.createElement( QStringLiteral( "transform" ) );
82 elemTransform.setAttribute( QStringLiteral( "matrix" ), Qgs3DUtils::matrix4x4toString( mTransform ) );
83 elem.appendChild( elemTransform );
84
85 if ( billboardSymbol() )
86 {
87 const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), billboardSymbol(), doc, context );
88
89 elem.appendChild( symbolElem );
90 }
91}
92
93void QgsPoint3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
94{
95 const QDomElement elemDataProperties = elem.firstChildElement( QStringLiteral( "data" ) );
96 mAltClamping = Qgs3DUtils::altClampingFromString( elemDataProperties.attribute( QStringLiteral( "alt-clamping" ) ) );
97
98 const QDomElement elemMaterial = elem.firstChildElement( QStringLiteral( "material" ) );
99 const QString materialType = elem.attribute( QStringLiteral( "material_type" ), QStringLiteral( "phong" ) );
100 mMaterial.reset( Qgs3D::materialRegistry()->createMaterialSettings( materialType ) );
101 if ( !mMaterial )
102 mMaterial.reset( Qgs3D::materialRegistry()->createMaterialSettings( QStringLiteral( "phong" ) ) );
103 mMaterial->readXml( elemMaterial, context );
104
105 mShape = shapeFromString( elem.attribute( QStringLiteral( "shape" ) ) );
106
107 const QDomElement elemShapeProperties = elem.firstChildElement( QStringLiteral( "shape-properties" ) );
108 mShapeProperties = QgsXmlUtils::readVariant( elemShapeProperties.firstChildElement() ).toMap();
109 mShapeProperties[QStringLiteral( "model" )] = QVariant( context.pathResolver().readPath( mShapeProperties[QStringLiteral( "model" )].toString() ) );
110
111 const QDomElement elemTransform = elem.firstChildElement( QStringLiteral( "transform" ) );
112 mTransform = Qgs3DUtils::stringToMatrix4x4( elemTransform.attribute( QStringLiteral( "matrix" ) ) );
113
114 const QDomElement symbolElem = elem.firstChildElement( QStringLiteral( "symbol" ) );
115
116 setBillboardSymbol( QgsSymbolLayerUtils::loadSymbol< QgsMarkerSymbol >( symbolElem, context ) );
117}
118
119QList<QgsWkbTypes::GeometryType> QgsPoint3DSymbol::compatibleGeometryTypes() const
120{
121 return QList< QgsWkbTypes::GeometryType >() << QgsWkbTypes::PointGeometry;
122}
123
125{
126 const QgsVectorLayerElevationProperties *props = qgis::down_cast< const QgsVectorLayerElevationProperties * >( const_cast< QgsVectorLayer *>( layer )->elevationProperties() );
127
128 mAltClamping = props->clamping();
129 mTransform.data()[13] = static_cast< float >( props->zOffset() );
130 mShapeProperties[QStringLiteral( "length" )] = props->extrusionEnabled() ? static_cast< float>( props->extrusionHeight() ) : 0.0f;
131}
132
134{
135 if ( shape == QStringLiteral( "sphere" ) )
136 return Sphere;
137 else if ( shape == QLatin1String( "cone" ) )
138 return Cone;
139 else if ( shape == QLatin1String( "cube" ) )
140 return Cube;
141 else if ( shape == QLatin1String( "torus" ) )
142 return Torus;
143 else if ( shape == QLatin1String( "plane" ) )
144 return Plane;
145 else if ( shape == QLatin1String( "extruded-text" ) )
146 return ExtrudedText;
147 else if ( shape == QLatin1String( "model" ) )
148 return Model;
149 else if ( shape == QLatin1String( "billboard" ) )
150 return Billboard;
151 else // "cylinder" (default)
152 return Cylinder;
153}
154
156{
157 switch ( shape )
158 {
159 case Cylinder: return QStringLiteral( "cylinder" );
160 case Sphere: return QStringLiteral( "sphere" );
161 case Cone: return QStringLiteral( "cone" );
162 case Cube: return QStringLiteral( "cube" );
163 case Torus: return QStringLiteral( "torus" );
164 case Plane: return QStringLiteral( "plane" );
165 case ExtrudedText: return QStringLiteral( "extruded-text" );
166 case Model: return QStringLiteral( "model" );
167 case Billboard: return QStringLiteral( "billboard" );
168 default: Q_ASSERT( false ); return QString();
169 }
170}
171
173{
174 QMatrix4x4 billboardTransformMatrix;
175 billboardTransformMatrix.translate( QVector3D( 0, mTransform.data()[13], 0 ) );
176
177 return billboardTransformMatrix;
178}
179
181{
182 return mMaterial.get();
183}
184
186{
187 if ( material == mMaterial.get() )
188 return;
189
190 mMaterial.reset( material );
191}
192
193bool QgsPoint3DSymbol::exportGeometries( Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) const
194{
196 {
197 Qt3DRender::QSceneLoader *sceneLoader = entity->findChild<Qt3DRender::QSceneLoader *>();
198 if ( sceneLoader != nullptr )
199 {
200 const QVector<Qgs3DExportObject *> objects = exporter->processSceneLoaderGeometries( sceneLoader, objectNamePrefix );
201 for ( Qgs3DExportObject *obj : objects )
202 {
203 obj->setSmoothEdges( exporter->smoothEdges() );
204 obj->setupMaterial( material() );
205 }
206 exporter->mObjects << objects;
207 }
208 else
209 {
210 const QList<Qt3DRender::QMesh *> meshes = entity->findChildren<Qt3DRender::QMesh *>();
211 for ( Qt3DRender::QMesh *mesh : meshes )
212 {
213 Qgs3DExportObject *object = exporter->processGeometryRenderer( mesh, objectNamePrefix );
214 if ( object == nullptr ) continue;
215 object->setSmoothEdges( exporter->smoothEdges() );
216 object->setupMaterial( material() );
217 exporter->mObjects << object;
218 }
219 }
220 return true;
221 }
222 else if ( shape() == QgsPoint3DSymbol::Billboard )
223 {
224 Qgs3DExportObject *obj = exporter->processPoints( entity, objectNamePrefix );
225 if ( obj != nullptr )
226 {
227 exporter->mObjects << obj;
228 return true;
229 }
230 }
231 else
232 {
233 const QVector<Qgs3DExportObject *> objects = exporter->processInstancedPointGeometry( entity, objectNamePrefix );
234 for ( Qgs3DExportObject *obj : objects )
235 {
236 obj->setupMaterial( material() );
237 exporter->mObjects << obj;
238 }
239 return true;
240 }
241 return false;
242}
243
245{
246 return mBillboardSymbol.get();
247}
248
250{
251 mBillboardSymbol.reset( symbol );
252}
Manages the data of each object of the scene (positions, normals, texture coordinates ....
void setSmoothEdges(bool smoothEdges)
Sets whether triangles edges will look smooth.
Entity that handles the exporting of 3D scene.
bool smoothEdges() const
Returns whether the triangles will look smooth.
static Qgis::AltitudeClamping altClampingFromString(const QString &str)
Converts a string to a value from AltitudeClamping enum.
Definition: qgs3dutils.cpp:255
static QString matrix4x4toString(const QMatrix4x4 &m)
Converts a 4x4 transform matrix to a string.
Definition: qgs3dutils.cpp:437
static QString altClampingToString(Qgis::AltitudeClamping altClamp)
Converts a value from AltitudeClamping enum to a string.
Definition: qgs3dutils.cpp:240
static QMatrix4x4 stringToMatrix4x4(const QString &str)
Convert a string to a 4x4 transform matrix.
Definition: qgs3dutils.cpp:447
static QgsMaterialRegistry * materialRegistry()
Returns the material registry, used for managing 3D materials.
Definition: qgs3d.cpp:90
double zOffset() const
Returns the z offset, which is a fixed offset amount which should be added to z values from the layer...
A marker symbol type, for rendering Point and MultiPoint geometries.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Shape
3D shape types supported by the symbol
@ ExtrudedText
Supported in Qt 5.9+.
~QgsPoint3DSymbol() override
void setDefaultPropertiesFromLayer(const QgsVectorLayer *layer) override
QgsAbstractMaterialSettings * material() const
Returns material used for shading of the symbol.
QMatrix4x4 billboardTransform() const
Returns transform for billboards.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
QgsPoint3DSymbol()
Constructor for QgsPoint3DSymbol with default QgsMarkerSymbol as the billboardSymbol.
QgsMarkerSymbol * billboardSymbol() const
Returns a symbol for billboard.
bool exportGeometries(Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix) const override SIP_SKIP
Exports the geometries contained within the hierarchy of entity.
void setMaterial(QgsAbstractMaterialSettings *material SIP_TRANSFER)
Sets the material settings used for shading of the symbol.
QgsAbstract3DSymbol * clone() const override SIP_FACTORY
Shape shape() const
Returns 3D shape for points.
void setBillboardSymbol(QgsMarkerSymbol *symbol)
Set symbol for billboard and the ownership is transferred.
static QString shapeToString(Shape shape)
Returns string from a shape enum value.
static QgsAbstract3DSymbol * create() SIP_FACTORY
Creates a new QgsPoint3DSymbol.
static Shape shapeFromString(const QString &shape)
Returns shape enum value from a string.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
QList< QgsWkbTypes::GeometryType > compatibleGeometryTypes() const override
The class is used as a container of context for various read/write operations on other objects.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:704
Vector layer specific subclass of QgsMapLayerElevationProperties.
double extrusionHeight() const
Returns the feature extrusion height.
Qgis::AltitudeClamping clamping() const
Returns the altitude clamping method, which dictates how feature heights are interpreted with respect...
bool extrusionEnabled() const
Returns true if extrusion is enabled.
Represents a vector layer which manages a vector based data sets.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.