QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgspolygon3dsymbol.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspolygon3dsymbol.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 "qgspolygon3dsymbol.h"
17
18#include "qgs3d.h"
19#include "qgs3dsceneexporter.h"
20#include "qgs3dutils.h"
21#include "qgscolorutils.h"
22#include "qgsmaterialregistry.h"
24#include "qgsvectorlayer.h"
26
27#include <QString>
28#include <Qt3DCore/QEntity>
29
30using namespace Qt::StringLiterals;
31
33 : mMaterialSettings( std::make_unique<QgsPhongMaterialSettings>() )
34{
35}
36
38
40{
41 auto result = std::make_unique<QgsPolygon3DSymbol>();
42 result->mAltClamping = mAltClamping;
43 result->mAltBinding = mAltBinding;
44 result->mOffset = mOffset;
45 result->mExtrusionHeight = mExtrusionHeight;
46 result->mMaterialSettings.reset( mMaterialSettings->clone() );
47 result->mCullingMode = mCullingMode;
48 result->mInvertNormals = mInvertNormals;
49 result->mAddBackFaces = mAddBackFaces;
50 result->mExtrusionFaces = mExtrusionFaces;
51 result->mEdgesEnabled = mEdgesEnabled;
52 result->mEdgeWidth = mEdgeWidth;
53 result->mEdgeColor = mEdgeColor;
54 copyBaseSettings( result.get() );
55 return result.release();
56}
57
58void QgsPolygon3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
59{
60 Q_UNUSED( context )
61
62 QDomDocument doc = elem.ownerDocument();
63
64 QDomElement elemDataProperties = doc.createElement( u"data"_s );
65 elemDataProperties.setAttribute( u"alt-clamping"_s, Qgs3DUtils::altClampingToString( mAltClamping ) );
66 elemDataProperties.setAttribute( u"alt-binding"_s, Qgs3DUtils::altBindingToString( mAltBinding ) );
67 elemDataProperties.setAttribute( u"offset"_s, mOffset );
68 elemDataProperties.setAttribute( u"extrusion-height"_s, mExtrusionHeight );
69 elemDataProperties.setAttribute( u"culling-mode"_s, Qgs3DUtils::cullingModeToString( mCullingMode ) );
70 elemDataProperties.setAttribute( u"invert-normals"_s, mInvertNormals ? u"1"_s : u"0"_s );
71 elemDataProperties.setAttribute( u"add-back-faces"_s, mAddBackFaces ? u"1"_s : u"0"_s );
72 elemDataProperties.setAttribute( u"rendered-facade"_s, qgsEnumValueToKey( mExtrusionFaces ) );
73 elem.appendChild( elemDataProperties );
74
75 elem.setAttribute( u"material_type"_s, mMaterialSettings->type() );
76 QDomElement elemMaterial = doc.createElement( u"material"_s );
77 mMaterialSettings->writeXml( elemMaterial, context );
78 elem.appendChild( elemMaterial );
79
80 QDomElement elemDDP = doc.createElement( u"data-defined-properties"_s );
81 mDataDefinedProperties.writeXml( elemDDP, propertyDefinitions() );
82 elem.appendChild( elemDDP );
83
84 QDomElement elemEdges = doc.createElement( u"edges"_s );
85 elemEdges.setAttribute( u"enabled"_s, mEdgesEnabled ? u"1"_s : u"0"_s );
86 elemEdges.setAttribute( u"width"_s, mEdgeWidth );
87 elemEdges.setAttribute( u"color"_s, QgsColorUtils::colorToString( mEdgeColor ) );
88 elem.appendChild( elemEdges );
89}
90
91void QgsPolygon3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
92{
93 Q_UNUSED( context )
94
95 const QDomElement elemDataProperties = elem.firstChildElement( u"data"_s );
96 mAltClamping = Qgs3DUtils::altClampingFromString( elemDataProperties.attribute( u"alt-clamping"_s ) );
97 mAltBinding = Qgs3DUtils::altBindingFromString( elemDataProperties.attribute( u"alt-binding"_s ) );
98 mOffset = elemDataProperties.attribute( u"offset"_s ).toFloat();
99 mExtrusionHeight = elemDataProperties.attribute( u"extrusion-height"_s ).toFloat();
100 mCullingMode = Qgs3DUtils::cullingModeFromString( elemDataProperties.attribute( u"culling-mode"_s ) );
101 mInvertNormals = elemDataProperties.attribute( u"invert-normals"_s ).toInt();
102 mAddBackFaces = elemDataProperties.attribute( u"add-back-faces"_s ).toInt();
103 mExtrusionFaces = qgsEnumKeyToValue( elemDataProperties.attribute( u"rendered-facade"_s ), Qgis::ExtrusionFace::Walls | Qgis::ExtrusionFace::Roof );
104
105 const QDomElement elemMaterial = elem.firstChildElement( u"material"_s );
106 const QString materialType = elem.attribute( u"material_type"_s, u"phong"_s );
107 mMaterialSettings.reset( Qgs3D::materialRegistry()->createMaterialSettings( materialType ) );
108 if ( !mMaterialSettings )
109 mMaterialSettings.reset( Qgs3D::materialRegistry()->createMaterialSettings( u"phong"_s ) );
110 mMaterialSettings->readXml( elemMaterial, context );
111
112 const QDomElement elemDDP = elem.firstChildElement( u"data-defined-properties"_s );
113 if ( !elemDDP.isNull() )
114 mDataDefinedProperties.readXml( elemDDP, propertyDefinitions() );
115
116 const QDomElement elemEdges = elem.firstChildElement( u"edges"_s );
117 if ( !elemEdges.isNull() )
118 {
119 mEdgesEnabled = elemEdges.attribute( u"enabled"_s ).toInt();
120 mEdgeWidth = elemEdges.attribute( u"width"_s ).toFloat();
121 mEdgeColor = QgsColorUtils::colorFromString( elemEdges.attribute( u"color"_s ) );
122 }
123}
124
125QList<Qgis::GeometryType> QgsPolygon3DSymbol::compatibleGeometryTypes() const
126{
127 return QList<Qgis::GeometryType>() << Qgis::GeometryType::Polygon;
128}
129
131{
132 const QgsVectorLayerElevationProperties *props = qgis::down_cast<const QgsVectorLayerElevationProperties *>( const_cast<QgsVectorLayer *>( layer )->elevationProperties() );
133
134 mAltClamping = props->clamping();
135 mAltBinding = props->binding();
136 mExtrusionHeight = props->extrusionEnabled() ? static_cast<float>( props->extrusionHeight() ) : 0.0f;
138 {
140 }
141 else
142 {
143 mDataDefinedProperties.setProperty( QgsAbstract3DSymbol::Property::ExtrusionHeight, QgsProperty() );
144 }
146 {
148 }
149 else
150 {
151 mDataDefinedProperties.setProperty( QgsAbstract3DSymbol::Property::Height, QgsProperty() );
152 }
153 mOffset = static_cast<float>( props->zOffset() );
154}
155
160
162{
163 return mMaterialSettings.get();
164}
165
167{
168 if ( materialSettings == mMaterialSettings.get() )
169 return;
170
171 mMaterialSettings.reset( materialSettings );
172}
173
174bool QgsPolygon3DSymbol::exportGeometries( Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) const
175{
176 QList<Qt3DCore::QEntity *> subEntities = entity->findChildren<Qt3DCore::QEntity *>( QString(), Qt::FindDirectChildrenOnly );
177 // sort geometries by their name in order to always export them in the same way:
178 std::sort( subEntities.begin(), subEntities.end(), []( const Qt3DCore::QEntity *a, const Qt3DCore::QEntity *b ) {
179 return a->objectName() < b->objectName();
180 } );
181
182 if ( subEntities.isEmpty() )
183 {
184 const QList<Qt3DRender::QGeometryRenderer *> renderers = entity->findChildren<Qt3DRender::QGeometryRenderer *>();
185 const int startSize = exporter->mObjects.size();
186 for ( Qt3DRender::QGeometryRenderer *renderer : renderers )
187 {
188 Qgs3DExportObject *object = exporter->processGeometryRenderer( renderer, objectNamePrefix );
189 if ( object )
190 {
191 exporter->processEntityMaterial( entity, object );
192 exporter->mObjects.push_back( object );
193 }
194 }
195 return exporter->mObjects.size() > startSize;
196 }
197 else
198 {
199 bool out = false;
200 QString prefix;
201 for ( Qt3DCore::QEntity *e : subEntities )
202 {
203 if ( e->objectName().isEmpty() )
204 prefix = objectNamePrefix;
205 else
206 prefix = e->objectName() + "_";
207
208 out |= exportGeometries( exporter, e, prefix );
209 }
210 return out;
211 }
212}
213
215{
216 switch ( side )
217 {
218 case 0:
219 mExtrusionFaces = Qgis::ExtrusionFace::NoFace;
220 break;
221 case 1:
222 mExtrusionFaces = Qgis::ExtrusionFace::Walls;
223 break;
224 case 2:
225 mExtrusionFaces = Qgis::ExtrusionFace::Roof;
226 break;
227 case 3:
229 break;
230 case 7:
232 break;
233 default:
234 break;
235 }
236}
237
239{
240 const int flags = static_cast<int>( mExtrusionFaces );
241
243 return 7;
244 else if ( flags == static_cast<int>( Qgis::ExtrusionFace::Walls | Qgis::ExtrusionFace::Roof ) )
245 return 3;
246 else if ( flags == static_cast<int>( Qgis::ExtrusionFace::Roof ) )
247 return 2;
248 else if ( flags == static_cast<int>( Qgis::ExtrusionFace::Walls ) )
249 return 1;
250 else
251 return 0;
252}
@ Polygon
Polygons.
Definition qgis.h:368
Manages the data of each object of the scene (positions, normals, texture coordinates ....
Entity that handles the exporting of 3D scenes.
static Qgs3DTypes::CullingMode cullingModeFromString(const QString &str)
Converts a string to a value from CullingMode enum.
static Qgis::AltitudeClamping altClampingFromString(const QString &str)
Converts a string to a value from AltitudeClamping enum.
static Qgis::AltitudeBinding altBindingFromString(const QString &str)
Converts a string to a value from AltitudeBinding enum.
static QString cullingModeToString(Qgs3DTypes::CullingMode mode)
Converts a value from CullingMode enum to a string.
static QString altClampingToString(Qgis::AltitudeClamping altClamp)
Converts a value from AltitudeClamping enum to a string.
static QString altBindingToString(Qgis::AltitudeBinding altBind)
Converts a value from AltitudeBinding enum to a string.
static QgsMaterialRegistry * materialRegistry()
Returns the material registry, used for managing 3D materials.
Definition qgs3d.cpp:89
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
@ ExtrusionHeight
Extrusion height (zero means no extrusion).
Abstract base class for material settings.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
double zOffset() const
Returns the z offset, which is a fixed offset amount which should be added to z values from the layer...
Basic shading material used for rendering based on the Phong shading model with three color component...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
static QgsAbstract3DSymbol * create() SIP_FACTORY
Creates a new QgsPolygon3DSymbol.
QgsAbstractMaterialSettings * materialSettings() const
Returns material settings used for shading of the symbol.
QgsAbstract3DSymbol * clone() const override SIP_FACTORY
Q_DECL_DEPRECATED void setRenderedFacade(int side) SIP_DEPRECATED
Sets which facade of the buildings is rendered (0 for None, 1 for Walls, 2 for Roof,...
void setMaterialSettings(QgsAbstractMaterialSettings *materialSettings SIP_TRANSFER)
Sets the material settings used for shading of the symbol.
~QgsPolygon3DSymbol() override
bool exportGeometries(Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix) const override SIP_SKIP
Exports the geometries contained within the hierarchy of entity.
void setDefaultPropertiesFromLayer(const QgsVectorLayer *layer) override
Q_DECL_DEPRECATED int renderedFacade() SIP_DEPRECATED
Returns which facade of the buildings is rendered (0 for None, 1 for Walls, 2 for Roof,...
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
QList< Qgis::GeometryType > compatibleGeometryTypes() const override
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
A store for object properties.
A container for the context for various read/write operations on objects.
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...
Qgis::AltitudeBinding binding() const
Returns the altitude binding method, which determines how altitude is bound to individual vertices in...
bool extrusionEnabled() const
Returns true if extrusion is enabled.
Represents a vector layer which manages a vector based dataset.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
Definition qgis.h:7110
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:7091