44#include <QPainterPath>
47using namespace Qt::StringLiterals;
56 constexpr double MM_PER_INCH = 25.4;
57 constexpr double POINTS_PER_INCH = 72.0;
58 constexpr double DEFAULT_DPI = 96.0;
60 constexpr double MM_TO_3D_UNITS = 10.0;
72 result = size * MM_TO_3D_UNITS;
75 result = size * MM_PER_INCH / POINTS_PER_INCH * MM_TO_3D_UNITS;
78 result = size * MM_PER_INCH * MM_TO_3D_UNITS;
81 result = size * 25.4 / DEFAULT_DPI * MM_TO_3D_UNITS;
93 QColor color = QColor();
101 if ( materialSettings )
107 QgsDebugError( u
"Qgs3DSymbolUtils::vectorMaterialAverageColor: unable to retrieve material from symbol"_s );
115 if ( !symbol || ( symbol->
type() !=
"line"_L1 && symbol->
type() ==
"point"_L1 && symbol->
type() ==
"polygon"_L1 ) )
117 QgsDebugError( u
"A vector symbol is expected by the Qgs3DSymbolUtils::vectorSymbolPreviewIcon function"_s );
122 QPixmap pixmap( size * devicePixelRatio );
123 pixmap.setDevicePixelRatio( devicePixelRatio );
124 pixmap.fill( Qt::transparent );
126 QPainter painter( &pixmap );
127 painter.setRenderHint( QPainter::Antialiasing );
128 painter.setPen( Qt::NoPen );
131 painter.setBrush( QBrush( baseColor ) );
133 if ( symbol->
type() ==
"line"_L1 )
138 const int lineHeight = std::min(
static_cast<int>( lineSymbol->
width() ), size.height() - 2 * padding );
139 const int y = ( size.height() - lineHeight ) / 2;
140 painter.drawRect( padding, y, size.width() - 2 * padding, lineHeight );
142 else if ( symbol->
type() ==
"point"_L1 )
146 switch ( pointSymbol->
shape() )
151 float bottomRadius = pointSymbol->
shapeProperty( u
"bottomRadius"_s ).toFloat();
152 float topRadius = 2 * pointSymbol->
shapeProperty( u
"topRadius"_s ).toFloat();
153 float length = pointSymbol->
shapeProperty( u
"length"_s ).toFloat();
155 const float maxRadius =
static_cast<float>( size.width() ) / 2.0f -
static_cast<float>( padding );
156 const float maxLength =
static_cast<float>( size.height() ) - 2.0f *
static_cast<float>( padding );
158 bottomRadius = std::min( bottomRadius, maxRadius );
159 topRadius = std::min( topRadius, maxRadius );
160 length = std::min( length, maxLength );
162 const float centerX =
static_cast<float>( size.width() ) / 2.0f;
163 const float availableHeight =
static_cast<float>( size.height() - 2 * padding );
164 const float topY =
static_cast<float>( padding ) + ( availableHeight - length ) / 2.0f;
165 const float bottomY = topY + length;
168 const QPointF topLeft( centerX - topRadius, topY );
169 const QPointF topRight( centerX + topRadius, topY );
170 const QPointF bottomLeft( centerX - bottomRadius, bottomY );
171 const QPointF bottomRight( centerX + bottomRadius, bottomY );
173 path.moveTo( topLeft );
174 path.lineTo( bottomLeft );
175 path.lineTo( bottomRight );
176 path.lineTo( topRight );
178 painter.fillPath( path, painter.brush() );
185 const int pointSize =
static_cast<int>( pointSymbol->
shapeProperty( u
"size"_s ).toFloat() );
186 const int rectSize = std::min( std::min( pointSize, size.height() ), size.width() ) - 2 * padding;
187 const int rectX = ( size.width() - rectSize ) / 2;
188 const int rectY = ( size.height() - rectSize ) / 2;
189 painter.drawRect( rectX, rectY, rectSize, rectSize );
195 float radius = pointSymbol->
shapeProperty( u
"radius"_s ).toFloat();
196 float length = pointSymbol->
shapeProperty( u
"length"_s ).toFloat();
197 float centerX =
static_cast<float>( size.width() ) / 2.0f;
199 float maxRadius =
static_cast<float>( size.width() ) / 2.0f -
static_cast<float>( padding );
200 float maxLength =
static_cast<float>( size.height() - 2 * padding );
201 radius = std::min( radius, maxRadius );
202 length = std::min( length, maxLength );
204 float availableHeight =
static_cast<float>( size.height() - 2 * padding );
205 float topY =
static_cast<float>( padding ) + ( availableHeight - length ) / 2.0f;
206 float bottomY = topY + length;
209 QPointF topLeft( centerX - radius, topY );
210 QPointF topRight( centerX + radius, topY );
211 QPointF bottomLeft( centerX - radius, bottomY );
212 QPointF bottomRight( centerX + radius, bottomY );
214 path.moveTo( topLeft );
215 path.lineTo( bottomLeft );
216 path.lineTo( bottomRight );
217 path.lineTo( topRight );
220 painter.fillPath( path, painter.brush() );
221 painter.drawPath( path );
227 const float pointSize = 2 * pointSymbol->
shapeProperty( u
"radius"_s ).toFloat();
228 const int diameter = std::min( std::min(
static_cast<int>( pointSize ), size.width() ), size.height() ) - 2 * padding;
229 const int x = ( size.width() - diameter ) / 2;
230 const int y = ( size.height() - diameter ) / 2;
231 painter.drawEllipse( x, y, diameter, diameter );
237 float radius = pointSymbol->
shapeProperty( u
"radius"_s ).toFloat();
238 float minorRadius = pointSymbol->
shapeProperty( u
"minorRadius"_s ).toFloat();
240 float maxRadius = std::min(
static_cast<float>( size.width() ),
static_cast<float>( size.height() ) ) / 2.0f -
static_cast<float>( padding );
241 radius = std::min( radius, maxRadius );
242 minorRadius = std::min( minorRadius, radius );
245 const float centerX =
static_cast<float>( size.width() ) / 2.0f;
246 const float centerY =
static_cast<float>( size.height() ) / 2.0f;
247 painter.drawEllipse( QPointF( centerX, centerY ), radius, radius );
251 painter.setCompositionMode( QPainter::CompositionMode_Clear );
252 painter.drawEllipse( QPointF( centerX, centerY ), minorRadius, minorRadius );
260 const int shapeSize = 10;
261 const int rectSize = std::min( std::min( shapeSize, size.height() ), size.width() ) - 2 * padding;
262 const int rectX = ( size.width() - rectSize ) / 2;
263 const int rectY = ( size.height() - rectSize ) / 2;
264 painter.drawRect( rectX, rectY, rectSize, rectSize );
269 else if ( symbol->
type() ==
"polygon"_L1 )
277 painter.drawRect( padding, padding, size.width() - 2 * padding, size.height() - 2 * padding );
281 return QIcon( pixmap );
291 bool colorSet =
false;
293 if ( materialSettings )
300 QgsDebugError( u
"Qgs3DSymbolUtils::setVectorSymbolBaseColor: unable to retrieve material from symbol"_s );
310 if ( fromSymbol && toSymbol )
317 QgsDebugError( u
"Qgs3DSymbolUtils::copyVectorSymbolMaterial: unable to retrieve material from symbols"_s );
325 if ( !symbol2D || !vLayer )
336 symbol3D->setDefaultPropertiesFromLayer( vLayer );
340 if ( symbol3D->type() ==
"line"_L1 )
342 QgsLine3DSymbol *lineSymbol3D = qgis::down_cast<QgsLine3DSymbol *>( symbol3D.get() );
344 if (
const QgsLineSymbol *lineSymbol = qgis::down_cast<const QgsLineSymbol *>( symbol2D ) )
346 if ( lineSymbol->symbolLayerCount() > 0 )
349 if (
const QgsSimpleLineSymbolLayer *simpleLineLayer = qgis::down_cast<const QgsSimpleLineSymbolLayer *>( symbolLayer ) )
352 lineSymbol3D->
setWidth(
static_cast<float>( lineWidthPixels ) );
357 else if ( symbol3D->type() ==
"point"_L1 )
359 QgsPoint3DSymbol *pointSymbol3D = qgis::down_cast<QgsPoint3DSymbol *>( symbol3D.get() );
360 if (
const QgsMarkerSymbol *markerSymbol = qgis::down_cast<const QgsMarkerSymbol *>( symbol2D ) )
362 if ( markerSymbol->symbolLayerCount() > 0 )
364 const QgsSymbolLayer *symbolLayer = markerSymbol->symbolLayer( 0 );
365 if (
const QgsSimpleMarkerSymbolLayer *simpleMarkerLayer = qgis::down_cast<const QgsSimpleMarkerSymbolLayer *>( symbolLayer ) )
369 switch ( simpleMarkerLayer->shape() )
374 QVariantMap vmSphere;
375 vmSphere[u
"radius"_s] = sizeMapUnits / 2.;
383 vmCube[u
"size"_s] = sizeMapUnits;
392 vmCone[u
"length"_s] = sizeMapUnits;
393 vmCone[u
"topRadius"_s] = sizeMapUnits / 10.;
394 vmCone[u
"bottomRadius"_s] = sizeMapUnits / 2.;
410 if ( materialSettings->
type() ==
"phong"_L1 )
415 else if ( materialSettings->
type() ==
"phongtextured"_L1 )
420 else if ( materialSettings->
type() ==
"metalroughtextured"_L1 )
425 else if ( materialSettings->
type() ==
"metalrough"_L1 )
@ ExtrudedText
Extruded text.
DistanceUnit
Units of distance.
@ EquilateralTriangle
Equilateral triangle.
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes).
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
std::unique_ptr< QgsAbstract3DSymbol > defaultSymbolForGeometryType(Qgis::GeometryType type)
Creates a new instance of the default 3D symbol for the specified geometry type.
static std::unique_ptr< QgsAbstract3DSymbol > create3DSymbolFrom2D(const QgsVectorLayer *vLayer, const QgsSymbol *symbol2D)
Creates a 3D symbol from a 2D symbol.
static QColor vectorSymbolAverageColor(const QgsAbstract3DSymbol *symbol)
Computes an approximate color from a 3D vector symbol.
static bool copyVectorSymbolMaterial(const QgsAbstract3DSymbol *fromSymbol, QgsAbstract3DSymbol *toSymbol)
Copies the material properties of a vector 3D symbol from one symbol to another.
static QIcon vectorSymbolPreviewIcon(const QgsAbstract3DSymbol *symbol, const QSize &size, const QgsScreenProperties &screen, int padding)
Returns an icon preview for a 3D vector symbol.
static bool setVectorSymbolBaseColor(QgsAbstract3DSymbol *symbol, const QColor &baseColor)
Sets the base color of the material settings associated with a 3D vector symbol.
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
virtual void setMaterialSettings(QgsAbstractMaterialSettings *materialSettings)=0
Sets the material settings used for shading of the symbol.
virtual QgsAbstractMaterialSettings * materialSettings() const
Returns the 3D material settings associated with this symbol.
virtual QString type() const =0
Returns identifier of symbol type. Each 3D symbol implementation should return a different type.
Abstract base class for material settings.
virtual QgsAbstractMaterialSettings * clone() const =0
Clones the material settings.
virtual QColor averageColor() const =0
Returns an approximate color representing the blended material color.
virtual QString type() const =0
Returns the unique type name for the material.
virtual void setColorsFromBase(const QColor &baseColor)=0
Decomposes a base color into the material's color components, and sets the material's colors accordin...
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
Represents a coordinate reference system (CRS).
Qgis::DistanceUnit mapUnits
3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer with...
float width() const
Returns width of the line symbol (in map units).
void setWidth(float width)
Sets width of the line symbol (in map units).
A line symbol type, for rendering LineString and MultiLineString geometries.
QgsCoordinateReferenceSystem crs
QgsProject * project() const
Returns the parent project if this map layer is added to a project.
A marker symbol type, for rendering Point and MultiPoint geometries.
A PBR metal rough shading material used for rendering with support for image texture maps.
void setOpacity(double opacity)
Sets the opacity of the surface.
Basic shading material used for rendering based on the Phong shading model with three color component...
void setOpacity(double opacity)
Sets opacity of the surface.
A Phong shading model with diffuse texture map.
void setOpacity(double opacity)
Sets opacity of the surface.
3D symbol that draws point geometries as 3D objects using one of the predefined shapes.
void setShape(Qgis::Point3DShape shape)
Sets 3D shape for points.
void setShapeProperties(const QVariantMap &properties)
Sets a key-value dictionary of point shape properties.
Qgis::Point3DShape shape() const
Returns 3D shape for points.
QVariant shapeProperty(const QString &property) const
Returns the value for a specific shape property.
3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls).
QColor edgeColor() const
Returns edge lines color.
bool edgesEnabled() const
Returns whether edge highlighting is enabled.
float edgeWidth() const
Returns width of edge lines (in pixels).
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
QgsCoordinateReferenceSystem crs3D() const
Returns the CRS to use for the project when transforming 3D data, or when z/elevation value handling ...
QgsCoordinateReferenceSystem crs
Scoped object for saving and restoring a QPainter object's state.
Stores properties relating to a screen.
double devicePixelRatio() const
Returns the ratio between physical pixels and device-independent pixels for the screen.
bool isValid() const
Returns true if the properties are valid.
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
Simple marker symbol layer, consisting of a rendered shape with solid fill color and a stroke.
Abstract base class for symbol layers.
Abstract base class for all rendered symbols.
qreal opacity() const
Returns the opacity for the symbol.
QColor color() const
Returns the symbol's color.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
double convert2DSizeTo3DSceneUnits(double size, Qgis::RenderUnit unit, Qgis::DistanceUnit units2D, Qgis::DistanceUnit units3D)
#define QgsDebugError(str)