QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgstiledscenewireframerenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstiledscenewireframerenderer.h
3 --------------------
4 begin : August 2023
5 copyright : (C) 2023 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "qgsfillsymbol.h"
20#include "qgssymbollayerutils.h"
21#include "qgslinesymbol.h"
22
24{
25 mFillSymbol.reset( createDefaultFillSymbol() );
26 mLineSymbol.reset( createDefaultLineSymbol() );
27}
28
30
32{
33 return QStringLiteral( "wireframe" );
34}
35
37{
38 std::unique_ptr< QgsTiledSceneWireframeRenderer > res = std::make_unique< QgsTiledSceneWireframeRenderer >();
39
40 res->setFillSymbol( mFillSymbol->clone() );
41 res->setLineSymbol( mLineSymbol->clone() );
42 res->setUseTextureColors( mUseTextureColors );
43
44 copyCommonProperties( res.get() );
45
46 return res.release();
47}
48
50{
51 std::unique_ptr< QgsTiledSceneWireframeRenderer > r = std::make_unique< QgsTiledSceneWireframeRenderer >();
52 {
53 const QDomElement fillSymbolElem = element.firstChildElement( QStringLiteral( "fillSymbol" ) );
54 if ( !fillSymbolElem.isNull() )
55 {
56 const QDomElement symbolElem = fillSymbolElem.firstChildElement( QStringLiteral( "symbol" ) );
57 std::unique_ptr< QgsFillSymbol > fillSymbol( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context ) );
58 if ( fillSymbol )
59 r->mFillSymbol = std::move( fillSymbol );
60 }
61 }
62 {
63 const QDomElement lineSymbolElem = element.firstChildElement( QStringLiteral( "lineSymbol" ) );
64 if ( !lineSymbolElem.isNull() )
65 {
66 const QDomElement symbolElem = lineSymbolElem.firstChildElement( QStringLiteral( "symbol" ) );
67 std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) );
68 if ( lineSymbol )
69 r->mLineSymbol = std::move( lineSymbol );
70 }
71 }
72
73 r->setUseTextureColors( element.attribute( QStringLiteral( "useTextureColors" ), QStringLiteral( "0" ) ).toInt() );
74
75 r->restoreCommonProperties( element, context );
76 return r.release();
77}
78
80{
81 QVariantMap properties;
82 properties.insert( QStringLiteral( "color" ), QStringLiteral( "white" ) );
83 properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
84 properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
85 properties.insert( QStringLiteral( "color_border" ), QStringLiteral( "black" ) );
86 properties.insert( QStringLiteral( "width_border" ), QStringLiteral( "0.3" ) );
87 properties.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
88
89 return QgsFillSymbol::createSimple( properties );
90}
91
93{
94 return mFillSymbol.get();
95}
96
98{
99 mFillSymbol.reset( symbol );
100}
101
103{
104 QVariantMap properties;
105 properties.insert( QStringLiteral( "color" ), QStringLiteral( "red" ) );
106
107 return QgsLineSymbol::createSimple( properties );
108}
109
111{
112 return mLineSymbol.get();
113}
114
116{
117 mLineSymbol.reset( symbol );
118}
119
121{
122 return mUseTextureColors;
123}
124
126{
127 mUseTextureColors = newUseTextureColors;
128}
129
130QDomElement QgsTiledSceneWireframeRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
131{
132 QDomElement rendererElem = doc.createElement( QStringLiteral( "renderer" ) );
133
134 rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "wireframe" ) );
135 rendererElem.setAttribute( QStringLiteral( "useTextureColors" ), mUseTextureColors ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
136
137 {
138 QDomElement fillSymbolElem = doc.createElement( QStringLiteral( "fillSymbol" ) );
139 const QDomElement symbolElement = QgsSymbolLayerUtils::saveSymbol( QString(),
140 mFillSymbol.get(),
141 doc,
142 context );
143 fillSymbolElem.appendChild( symbolElement );
144 rendererElem.appendChild( fillSymbolElem );
145 }
146 {
147 QDomElement lineSymbolElem = doc.createElement( QStringLiteral( "lineSymbol" ) );
148 const QDomElement symbolElement = QgsSymbolLayerUtils::saveSymbol( QString(),
149 mLineSymbol.get(),
150 doc,
151 context );
152 lineSymbolElem.appendChild( symbolElement );
153 rendererElem.appendChild( lineSymbolElem );
154 }
155 saveCommonProperties( rendererElem, context );
156
157 return rendererElem;
158}
159
161{
162 if ( mUseTextureColors )
163 {
164 std::unique_ptr< QgsFillSymbol > s( mFillSymbol->clone() );
165 const QImage textureImage = context.textureImage();
166 if ( !textureImage.isNull() )
167 {
168 float textureX1;
169 float textureY1;
170 float textureX2;
171 float textureY2;
172 float textureX3;
173 float textureY3;
174 context.textureCoordinates( textureX1, textureY1, textureX2, textureY2, textureX3, textureY3 );
175
176 const QColor centerColor( textureImage.pixelColor(
177 static_cast<int>( ( ( textureX1 + textureX2 + textureX3 ) / 3 ) * ( textureImage.width() - 1 ) ),
178 static_cast< int >( ( ( textureY1 + textureY2 + textureY3 ) / 3 ) * ( textureImage.height() - 1 ) ) )
179 );
180 s->setColor( centerColor );
181 }
182 s->startRender( context.renderContext() );
183 s->renderPolygon( triangle, nullptr, nullptr, context.renderContext() );
184 s->stopRender( context.renderContext() );
185 }
186 else
187 {
188 mFillSymbol->renderPolygon( triangle, nullptr, nullptr, context.renderContext() );
189 }
190}
191
193{
194 mLineSymbol->renderPolyline( line, nullptr, context.renderContext() );
195}
196
198{
200
201 if ( !mUseTextureColors )
202 mFillSymbol->startRender( context.renderContext() );
203
204 mLineSymbol->startRender( context.renderContext() );
205}
206
208{
209 if ( !mUseTextureColors )
210 mFillSymbol->stopRender( context.renderContext() );
211
212 mLineSymbol->stopRender( context.renderContext() );
213
215}
216
218{
221
222 if ( mUseTextureColors )
224
225 return flags;
226}
@ RendersLines
Renderer can render line primitives.
@ RequiresTextures
Renderer requires textures.
@ RendersTriangles
Renderer can render triangle primitives.
QFlags< TiledSceneRendererFlag > TiledSceneRendererFlags
Flags which control how tiled scene 2D renderers behave.
Definition: qgis.h:4633
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
static QgsLineSymbol * createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
The class is used as a container of context for various read/write operations on other objects.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Encapsulates the render context for a 2D tiled scene rendering operation.
void textureCoordinates(float &textureX1, float &textureY1, float &textureX2, float &textureY2, float &textureX3, float &textureY3) const
Returns the current texture coordinates.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
QImage textureImage() const
Returns the current texture image.
Abstract base class for 2d tiled scene renderers.
void saveCommonProperties(QDomElement &element, const QgsReadWriteContext &context) const
Saves common renderer properties (such as point size and screen error) to the specified DOM element.
virtual void stopRender(QgsTiledSceneRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
virtual void startRender(QgsTiledSceneRenderContext &context)
Must be called when a new render cycle is started.
void copyCommonProperties(QgsTiledSceneRenderer *destination) const
Copies common tiled scene renderer properties (such as screen error) to the destination renderer.
Qgis::TiledSceneRendererFlags flags() const override
Returns flags which control how the renderer behaves.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Saves the renderer configuration to an XML element.
void startRender(QgsTiledSceneRenderContext &context) override
Must be called when a new render cycle is started.
QString type() const override
Returns the identifier of the renderer type.
void renderTriangle(QgsTiledSceneRenderContext &context, const QPolygonF &triangle) override
Renders a triangle.
void setFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to render triangles in the wireframe.
static QgsLineSymbol * createDefaultLineSymbol()
Returns a copy of the default line symbol used to render lines in the wireframe.
void renderLine(QgsTiledSceneRenderContext &context, const QPolygonF &line) override
Renders a line.
void stopRender(QgsTiledSceneRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
static QgsTiledSceneRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a textured renderer from an XML element.
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render lines in the wireframe.
QgsTiledSceneWireframeRenderer()
Constructor for QgsTiledSceneWireframeRenderer.
QgsFillSymbol * fillSymbol() const
Returns the fill symbol used to render triangles in the wireframe.
QgsLineSymbol * lineSymbol() const
Returns the line symbol used to render lines in the wireframe.
void setUseTextureColors(bool enabled)
Sets whether representative colors from the textures should be used to recolor the symbols used to re...
bool useTextureColors() const
Returns true if representative colors from the textures will be used to recolor the symbols used to r...
QgsTiledSceneRenderer * clone() const override
Create a deep copy of this renderer.
static QgsFillSymbol * createDefaultFillSymbol()
Returns a copy of the default fill symbol used to render triangles in the wireframe.