QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 <Qt3DCore/QEntity>
19
20#include "qgs3dutils.h"
21#include "qgs3d.h"
22#include "qgscolorutils.h"
23#include "qgsmaterialregistry.h"
24#include "qgs3dsceneexporter.h"
26#include "qgsvectorlayer.h"
28
30 : mMaterialSettings( std::make_unique< QgsPhongMaterialSettings >() )
31{
32
33}
34
36
38{
39 std::unique_ptr< QgsPolygon3DSymbol > result = std::make_unique< QgsPolygon3DSymbol >();
40 result->mAltClamping = mAltClamping;
41 result->mAltBinding = mAltBinding;
42 result->mOffset = mOffset;
43 result->mExtrusionHeight = mExtrusionHeight;
44 result->mMaterialSettings.reset( mMaterialSettings->clone() );
45 result->mCullingMode = mCullingMode;
46 result->mInvertNormals = mInvertNormals;
47 result->mAddBackFaces = mAddBackFaces;
48 result->mRenderedFacade = mRenderedFacade;
49 result->mEdgesEnabled = mEdgesEnabled;
50 result->mEdgeWidth = mEdgeWidth;
51 result->mEdgeColor = mEdgeColor;
52 copyBaseSettings( result.get() );
53 return result.release();
54}
55
56void QgsPolygon3DSymbol::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
57{
58 Q_UNUSED( context )
59
60 QDomDocument doc = elem.ownerDocument();
61
62 QDomElement elemDataProperties = doc.createElement( QStringLiteral( "data" ) );
63 elemDataProperties.setAttribute( QStringLiteral( "alt-clamping" ), Qgs3DUtils::altClampingToString( mAltClamping ) );
64 elemDataProperties.setAttribute( QStringLiteral( "alt-binding" ), Qgs3DUtils::altBindingToString( mAltBinding ) );
65 elemDataProperties.setAttribute( QStringLiteral( "offset" ), mOffset );
66 elemDataProperties.setAttribute( QStringLiteral( "extrusion-height" ), mExtrusionHeight );
67 elemDataProperties.setAttribute( QStringLiteral( "culling-mode" ), Qgs3DUtils::cullingModeToString( mCullingMode ) );
68 elemDataProperties.setAttribute( QStringLiteral( "invert-normals" ), mInvertNormals ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
69 elemDataProperties.setAttribute( QStringLiteral( "add-back-faces" ), mAddBackFaces ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
70 elemDataProperties.setAttribute( QStringLiteral( "rendered-facade" ), mRenderedFacade );
71 elem.appendChild( elemDataProperties );
72
73 elem.setAttribute( QStringLiteral( "material_type" ), mMaterialSettings->type() );
74 QDomElement elemMaterial = doc.createElement( QStringLiteral( "material" ) );
75 mMaterialSettings->writeXml( elemMaterial, context );
76 elem.appendChild( elemMaterial );
77
78 QDomElement elemDDP = doc.createElement( QStringLiteral( "data-defined-properties" ) );
79 mDataDefinedProperties.writeXml( elemDDP, propertyDefinitions() );
80 elem.appendChild( elemDDP );
81
82 QDomElement elemEdges = doc.createElement( QStringLiteral( "edges" ) );
83 elemEdges.setAttribute( QStringLiteral( "enabled" ), mEdgesEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
84 elemEdges.setAttribute( QStringLiteral( "width" ), mEdgeWidth );
85 elemEdges.setAttribute( QStringLiteral( "color" ), QgsColorUtils::colorToString( mEdgeColor ) );
86 elem.appendChild( elemEdges );
87}
88
89void QgsPolygon3DSymbol::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
90{
91 Q_UNUSED( context )
92
93 const QDomElement elemDataProperties = elem.firstChildElement( QStringLiteral( "data" ) );
94 mAltClamping = Qgs3DUtils::altClampingFromString( elemDataProperties.attribute( QStringLiteral( "alt-clamping" ) ) );
95 mAltBinding = Qgs3DUtils::altBindingFromString( elemDataProperties.attribute( QStringLiteral( "alt-binding" ) ) );
96 mOffset = elemDataProperties.attribute( QStringLiteral( "offset" ) ).toFloat();
97 mExtrusionHeight = elemDataProperties.attribute( QStringLiteral( "extrusion-height" ) ).toFloat();
98 mCullingMode = Qgs3DUtils::cullingModeFromString( elemDataProperties.attribute( QStringLiteral( "culling-mode" ) ) );
99 mInvertNormals = elemDataProperties.attribute( QStringLiteral( "invert-normals" ) ).toInt();
100 mAddBackFaces = elemDataProperties.attribute( QStringLiteral( "add-back-faces" ) ).toInt();
101 mRenderedFacade = elemDataProperties.attribute( QStringLiteral( "rendered-facade" ), "3" ).toInt();
102
103 const QDomElement elemMaterial = elem.firstChildElement( QStringLiteral( "material" ) );
104 const QString materialType = elem.attribute( QStringLiteral( "material_type" ), QStringLiteral( "phong" ) );
105 mMaterialSettings.reset( Qgs3D::materialRegistry()->createMaterialSettings( materialType ) );
106 if ( !mMaterialSettings )
107 mMaterialSettings.reset( Qgs3D::materialRegistry()->createMaterialSettings( QStringLiteral( "phong" ) ) );
108 mMaterialSettings->readXml( elemMaterial, context );
109
110 const QDomElement elemDDP = elem.firstChildElement( QStringLiteral( "data-defined-properties" ) );
111 if ( !elemDDP.isNull() )
112 mDataDefinedProperties.readXml( elemDDP, propertyDefinitions() );
113
114 const QDomElement elemEdges = elem.firstChildElement( QStringLiteral( "edges" ) );
115 if ( !elemEdges.isNull() )
116 {
117 mEdgesEnabled = elemEdges.attribute( QStringLiteral( "enabled" ) ).toInt();
118 mEdgeWidth = elemEdges.attribute( QStringLiteral( "width" ) ).toFloat();
119 mEdgeColor = QgsColorUtils::colorFromString( elemEdges.attribute( QStringLiteral( "color" ) ) );
120 }
121}
122
123QList<Qgis::GeometryType> QgsPolygon3DSymbol::compatibleGeometryTypes() const
124{
125 return QList< Qgis::GeometryType >() << Qgis::GeometryType::Polygon;
126}
127
129{
130 const QgsVectorLayerElevationProperties *props = qgis::down_cast< const QgsVectorLayerElevationProperties * >( const_cast< QgsVectorLayer *>( layer )->elevationProperties() );
131
132 mAltClamping = props->clamping();
133 mAltBinding = props->binding();
134 mExtrusionHeight = props->extrusionEnabled() ? static_cast< float>( props->extrusionHeight() ) : 0.0f;
136 {
138 }
139 else
140 {
141 mDataDefinedProperties.setProperty( QgsAbstract3DSymbol::Property::ExtrusionHeight, QgsProperty() );
142 }
144 {
146 }
147 else
148 {
149 mDataDefinedProperties.setProperty( QgsAbstract3DSymbol::Property::Height, QgsProperty() );
150 }
151 mOffset = static_cast< float >( props->zOffset() );
152}
153
155{
156 return new QgsPolygon3DSymbol();
157}
158
160{
161 return mMaterialSettings.get();
162}
163
165{
166 if ( materialSettings == mMaterialSettings.get() )
167 return;
168
169 mMaterialSettings.reset( materialSettings );
170}
171
172bool QgsPolygon3DSymbol::exportGeometries( Qgs3DSceneExporter *exporter, Qt3DCore::QEntity *entity, const QString &objectNamePrefix ) const
173{
174 QList<Qt3DCore::QEntity *> subEntities = entity->findChildren<Qt3DCore::QEntity *>( QString(), Qt::FindDirectChildrenOnly );
175 // sort geometries by their name in order to always export them in the same way:
176 std::sort( subEntities.begin(), subEntities.end(), []( const Qt3DCore::QEntity * a, const Qt3DCore::QEntity * b )
177 {
178 return a->objectName() < b->objectName();
179 } );
180
181 if ( subEntities.isEmpty() )
182 {
183 const QList<Qt3DRender::QGeometryRenderer *> renderers = entity->findChildren<Qt3DRender::QGeometryRenderer *>();
184 const int startSize = exporter->mObjects.size();
185 for ( Qt3DRender::QGeometryRenderer *renderer : renderers )
186 {
187 Qgs3DExportObject *object = exporter->processGeometryRenderer( renderer, objectNamePrefix );
188 if ( object )
189 {
190 exporter->processEntityMaterial( entity, object );
191 exporter->mObjects.push_back( object );
192 }
193 }
194 return exporter->mObjects.size() > startSize;
195 }
196 else
197 {
198 bool out = false;
199 QString prefix;
200 for ( Qt3DCore::QEntity *e : subEntities )
201 {
202 if ( e->objectName().isEmpty() )
203 prefix = objectNamePrefix;
204 else
205 prefix = e->objectName() + "_";
206
207 out |= exportGeometries( exporter, e, prefix );
208 }
209 return out;
210 }
211}
@ Polygon
Polygons.
Manages the data of each object of the scene (positions, normals, texture coordinates ....
Entity that handles the exporting of 3D scene.
static Qgs3DTypes::CullingMode cullingModeFromString(const QString &str)
Converts a string to a value from CullingMode enum.
Definition: qgs3dutils.cpp:342
static Qgis::AltitudeClamping altClampingFromString(const QString &str)
Converts a string to a value from AltitudeClamping enum.
Definition: qgs3dutils.cpp:294
static Qgis::AltitudeBinding altBindingFromString(const QString &str)
Converts a string to a value from AltitudeBinding enum.
Definition: qgs3dutils.cpp:318
static QString cullingModeToString(Qgs3DTypes::CullingMode mode)
Converts a value from CullingMode enum to a string.
Definition: qgs3dutils.cpp:326
static QString altClampingToString(Qgis::AltitudeClamping altClamp)
Converts a value from AltitudeClamping enum to a string.
Definition: qgs3dutils.cpp:279
static QString altBindingToString(Qgis::AltitudeBinding altBind)
Converts a value from AltitudeBinding enum to a string.
Definition: qgs3dutils.cpp:305
static QgsMaterialRegistry * materialRegistry()
Returns the material registry, used for managing 3D materials.
Definition: qgs3d.cpp:95
@ ExtrusionHeight
Extrusion height (zero means no extrusion)
@ Height
Height (altitude)
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...
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.
QgsPolygon3DSymbol()
Constructor for QgsPolygon3DSymbol.
QgsAbstract3DSymbol * clone() const override SIP_FACTORY
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
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.
Definition: qgsproperty.h:228
The class is used as a container of context for various read/write operations on other 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 data sets.