QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 
59 void 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 
93 void 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 
119 QList<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 
193 bool QgsPoint3DSymbol::exportGeometries( Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) const
194 {
195  if ( shape() == QgsPoint3DSymbol::Model )
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 }
qgs3dexportobject.h
QgsPoint3DSymbol::billboardTransform
QMatrix4x4 billboardTransform() const
Returns transform for billboards.
Definition: qgspoint3dsymbol.cpp:172
qgs3d.h
Qgs3DExportObject::setSmoothEdges
void setSmoothEdges(bool smoothEdges)
Sets whether triangles edges will look smooth.
Definition: qgs3dexportobject.h:71
QgsPoint3DSymbol::Cube
@ Cube
Definition: qgspoint3dsymbol.h:85
QgsPoint3DSymbol::shapeFromString
static Shape shapeFromString(const QString &shape)
Returns shape enum value from a string.
Definition: qgspoint3dsymbol.cpp:133
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsSymbol::defaultSymbol
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:673
Qgs3D::materialRegistry
static QgsMaterialRegistry * materialRegistry()
Returns the material registry, used for managing 3D materials.
Definition: qgs3d.cpp:90
qgsmaterialregistry.h
qgsreadwritecontext.h
QgsPoint3DSymbol::Shape
Shape
3D shape types supported by the symbol
Definition: qgspoint3dsymbol.h:80
qgs3dsceneexporter.h
Qgs3DExportObject
Manages the data of each object of the scene (positions, normals, texture coordinates ....
Definition: qgs3dexportobject.h:40
qgssymbollayerutils.h
QgsPoint3DSymbol::setBillboardSymbol
void setBillboardSymbol(QgsMarkerSymbol *symbol)
Set symbol for billboard and the ownership is transferred.
Definition: qgspoint3dsymbol.cpp:249
QgsVectorLayerElevationProperties::extrusionHeight
double extrusionHeight() const
Returns the feature extrusion height.
Definition: qgsvectorlayerelevationproperties.h:133
QgsPoint3DSymbol::Sphere
@ Sphere
Definition: qgspoint3dsymbol.h:83
QgsPoint3DSymbol::material
QgsAbstractMaterialSettings * material() const
Returns material used for shading of the symbol.
Definition: qgspoint3dsymbol.cpp:180
QgsPoint3DSymbol::writeXml
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Definition: qgspoint3dsymbol.cpp:59
QgsVectorLayerElevationProperties::clamping
Qgis::AltitudeClamping clamping() const
Returns the altitude clamping method, which dictates how feature heights are interpreted with respect...
Definition: qgsvectorlayerelevationproperties.h:67
Qgs3DUtils::stringToMatrix4x4
static QMatrix4x4 stringToMatrix4x4(const QString &str)
Convert a string to a 4x4 transform matrix.
Definition: qgs3dutils.cpp:447
QgsPoint3DSymbol::shapeToString
static QString shapeToString(Shape shape)
Returns string from a shape enum value.
Definition: qgspoint3dsymbol.cpp:155
QgsPhongMaterialSettings
Basic shading material used for rendering based on the Phong shading model with three color component...
Definition: qgsphongmaterialsettings.h:44
QgsAbstract3DSymbol
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
Definition: qgsabstract3dsymbol.h:46
QgsPathResolver::writePath
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
Definition: qgspathresolver.cpp:225
Qgs3DSceneExporter
Entity that handles the exporting of 3D scene.
Definition: qgs3dsceneexporter.h:55
QgsPoint3DSymbol::Cone
@ Cone
Definition: qgspoint3dsymbol.h:84
QgsPoint3DSymbol::create
static QgsAbstract3DSymbol * create() SIP_FACTORY
Creates a new QgsPoint3DSymbol.
Definition: qgspoint3dsymbol.cpp:35
QgsPoint3DSymbol::QgsPoint3DSymbol
QgsPoint3DSymbol()
Constructor for QgsPoint3DSymbol with default QgsMarkerSymbol as the billboardSymbol.
Definition: qgspoint3dsymbol.cpp:40
QgsPoint3DSymbol::readXml
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Definition: qgspoint3dsymbol.cpp:93
QgsAbstractMaterialSettings
Abstract base class for material settings.
Definition: qgsabstractmaterialsettings.h:114
QgsVectorLayerElevationProperties::extrusionEnabled
bool extrusionEnabled() const
Returns true if extrusion is enabled.
Definition: qgsvectorlayerelevationproperties.h:115
QgsXmlUtils::readVariant
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
Definition: qgsxmlutils.cpp:251
qgs3dutils.h
QgsMarkerSymbol
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgsmarkersymbol.h:30
Qgs3DUtils::matrix4x4toString
static QString matrix4x4toString(const QMatrix4x4 &m)
Converts a 4x4 transform matrix to a string.
Definition: qgs3dutils.cpp:437
QgsPoint3DSymbol::Model
@ Model
Definition: qgspoint3dsymbol.h:89
Qgs3DUtils::altClampingFromString
static Qgis::AltitudeClamping altClampingFromString(const QString &str)
Converts a string to a value from AltitudeClamping enum.
Definition: qgs3dutils.cpp:255
QgsPoint3DSymbol::billboardSymbol
QgsMarkerSymbol * billboardSymbol() const
Returns a symbol for billboard.
Definition: qgspoint3dsymbol.cpp:244
QgsVectorLayerElevationProperties
Vector layer specific subclass of QgsMapLayerElevationProperties.
Definition: qgsvectorlayerelevationproperties.h:38
QgsPoint3DSymbol::~QgsPoint3DSymbol
~QgsPoint3DSymbol() override
QgsPoint3DSymbol::Cylinder
@ Cylinder
Definition: qgspoint3dsymbol.h:82
Qgs3DUtils::altClampingToString
static QString altClampingToString(Qgis::AltitudeClamping altClamp)
Converts a value from AltitudeClamping enum to a string.
Definition: qgs3dutils.cpp:240
Qgs3DSceneExporter::smoothEdges
bool smoothEdges() const
Returns whether the triangles will look smooth.
Definition: qgs3dsceneexporter.h:84
QgsPoint3DSymbol::Torus
@ Torus
Definition: qgspoint3dsymbol.h:86
qgsxmlutils.h
qgsvectorlayer.h
QgsPoint3DSymbol::shape
Shape shape() const
Returns 3D shape for points.
Definition: qgspoint3dsymbol.h:99
QgsPoint3DSymbol::Plane
@ Plane
Definition: qgspoint3dsymbol.h:87
QgsPathResolver::readPath
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Definition: qgspathresolver.cpp:37
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
qgsvectorlayerelevationproperties.h
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
qgspoint3dsymbol.h
qgsmarkersymbol.h
QgsPoint3DSymbol::ExtrudedText
@ ExtrudedText
Supported in Qt 5.9+.
Definition: qgspoint3dsymbol.h:88
QgsPoint3DSymbol::setMaterial
void setMaterial(QgsAbstractMaterialSettings *material SIP_TRANSFER)
Sets the material settings used for shading of the symbol.
Definition: qgspoint3dsymbol.cpp:185
QgsMapLayerElevationProperties::zOffset
double zOffset() const
Returns the z offset, which is a fixed offset amount which should be added to z values from the layer...
Definition: qgsmaplayerelevationproperties.h:180
QgsPoint3DSymbol::compatibleGeometryTypes
QList< QgsWkbTypes::GeometryType > compatibleGeometryTypes() const override
Definition: qgspoint3dsymbol.cpp:119
QgsPoint3DSymbol::setDefaultPropertiesFromLayer
void setDefaultPropertiesFromLayer(const QgsVectorLayer *layer) override
Definition: qgspoint3dsymbol.cpp:124
QgsXmlUtils::writeVariant
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
Definition: qgsxmlutils.cpp:106
QgsPoint3DSymbol::Billboard
@ Billboard
Definition: qgspoint3dsymbol.h:90
QgsSymbolLayerUtils::saveSymbol
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Definition: qgssymbollayerutils.cpp:1397
QgsPoint3DSymbol::clone
QgsAbstract3DSymbol * clone() const override SIP_FACTORY
Definition: qgspoint3dsymbol.cpp:30
QgsPoint3DSymbol
3D symbol that draws point geometries as 3D objects using one of the predefined shapes.
Definition: qgspoint3dsymbol.h:38
QgsPoint3DSymbol::exportGeometries
bool exportGeometries(Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix) const override SIP_SKIP
Exports the geometries contained within the hierarchy of entity.
Definition: qgspoint3dsymbol.cpp:193
QgsReadWriteContext::pathResolver
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
Definition: qgsreadwritecontext.cpp:47