38#define TINYGLTF_NO_STB_IMAGE
39#define TINYGLTF_NO_STB_IMAGE_WRITE
44 , mLayerName( layer->name() )
46 , mEnableProfile( context.flags() &
Qgis::RenderContextFlag::RecordProfile )
64 mRenderTileBorders = mRenderer->isTileBorderRenderingEnabled();
68 mPreparationTime = timer.elapsed();
78 std::unique_ptr< QgsScopedRuntimeProfile > profile;
81 profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral(
"rendering" ),
layerId() );
82 if ( mPreparationTime > 0 )
86 std::unique_ptr< QgsScopedRuntimeProfile > preparingProfile;
89 preparingProfile = std::make_unique< QgsScopedRuntimeProfile >( QObject::tr(
"Preparing render" ), QStringLiteral(
"rendering" ) );
96 QPainter *painter = rc->
painter();
101 if ( !mClippingRegions.empty() )
103 bool needsPainterClipPath =
false;
105 if ( needsPainterClipPath )
106 rc->
painter()->setClipPath( path, Qt::IntersectClip );
109 mElapsedTimer.start();
113 mRenderer->startRender( context );
115 preparingProfile.reset();
116 std::unique_ptr< QgsScopedRuntimeProfile > renderingProfile;
117 if ( mEnableProfile )
119 renderingProfile = std::make_unique< QgsScopedRuntimeProfile >( QObject::tr(
"Rendering" ), QStringLiteral(
"rendering" ) );
122 const bool result = renderTiles( context );
123 mRenderer->stopRender( context );
150 const double maximumErrorPixels = context->
convertToPainterUnits( mRenderer->maximumScreenError(), mRenderer->maximumScreenErrorUnit() );
152 const double mapYCenter = 0.5 * ( mapExtent.
yMinimum() + mapExtent.
yMaximum() );
157 const double mapMetersPerPixel = mapWidthMeters / context->
outputSize().width();
158 const double maximumErrorInMeters = maximumErrorPixels * mapMetersPerPixel;
164 const QVector< QgsVector3D > corners =
QgsBox3D( mapExtent, -10000, 10000 ).
corners();
171 for (
int i = 0; i < 8; ++i )
174 x.append( corner.
x() );
175 y.append( corner.
y() );
176 z.append( corner.
z() );
180 const auto minMaxX = std::minmax_element( x.constBegin(), x.constEnd() );
181 const auto minMaxY = std::minmax_element( y.constBegin(), y.constEnd() );
182 const auto minMaxZ = std::minmax_element( z.constBegin(), z.constEnd() );
195 auto tileIsVisibleInMap = [mapExtent,
this](
const QgsTiledSceneTile & tile )->
bool
201 const QgsGeometry tileGeometry( tile.boundingVolume().as2DGeometry( mSceneToMapTransform ) );
202 return tileGeometry.intersects( mapExtent );
206 QVector< long long > tileIds = mIndex.
getTiles( request );
207 while ( !tileIds.empty() )
212 const long long tileId = tileIds.first();
216 if ( !tile.
isValid() || !tileIsVisibleInMap( tile ) )
224 renderTile( tile, context );
233 const QVector< long long > newTileIdsToRender = mIndex.
getTiles( request );
234 tileIds.append( newTileIdsToRender );
245 renderTile( tile, context );
259 std::sort( mPrimitiveData.begin(), mPrimitiveData.end(), [](
const PrimitiveData & a,
const PrimitiveData & b )
262 if ( qgsDoubleNear( a.z, b.z, 0.001 ) )
265 if ( a.type == PrimitiveType::Line )
267 else if ( b.type == PrimitiveType::Line )
272 for (
const PrimitiveData &data : std::as_const( mPrimitiveData ) )
276 case PrimitiveType::Line:
277 mRenderer->renderLine( context, data.coordinates );
280 case PrimitiveType::Triangle:
285 data.textureCoords[2], data.textureCoords[3],
286 data.textureCoords[4], data.textureCoords[5] );
288 mRenderer->renderTriangle( context, data.coordinates );
293 if ( mRenderTileBorders )
295 QPainter *painter = renderContext()->painter();
296 for (
const TileDetails &tile : std::as_const( mTileDetails ) )
300 if ( tile.hasContent )
302 brush = QBrush( QColor( 0, 0, 255, 10 ) );
303 pen = QPen( QColor( 0, 0, 255, 150 ) );
307 brush = QBrush( QColor( 255, 0, 255, 10 ) );
308 pen = QPen( QColor( 255, 0, 255, 150 ) );
311 painter->setPen( pen );
312 painter->setBrush( brush );
313 painter->drawPolygon( tile.boundary );
316 format.
setColor( QColor( 255, 0, 0 ) );
319 QgsTextRenderer::drawText( QRectF( QPoint( 0, 0 ), renderContext()->outputSize() ).intersected( tile.boundary.boundingRect() ),
331 const bool hasContent = renderTileContent( tile, context );
333 if ( mRenderTileBorders )
338 std::unique_ptr< QgsAbstractGeometry > volumeGeometry( volume.
as2DGeometry( mSceneToMapTransform ) );
339 if (
QgsCurvePolygon *polygon = qgsgeometry_cast< QgsCurvePolygon * >( volumeGeometry.get() ) )
341 QPolygonF volumePolygon = polygon->exteriorRing()->asQPolygonF( );
344 volumePolygon.erase( std::remove_if( volumePolygon.begin(), volumePolygon.end(),
345 [](
const QPointF point )
347 return !std::isfinite( point.x() ) || !std::isfinite( point.y() );
348 } ), volumePolygon.end() );
350 QPointF *ptr = volumePolygon.data();
351 for (
int i = 0; i < volumePolygon.size(); ++i, ++ptr )
357 details.boundary = volumePolygon;
358 details.hasContent = hasContent;
359 details.id = QString::number( tile.
id() );
360 mTileDetails.append( details );
365 QgsDebugError( QStringLiteral(
"Error transforming bounding volume" ) );
372 const QString contentUri = tile.
resources().value( QStringLiteral(
"content" ) ).toString();
373 if ( contentUri.isEmpty() )
378 if ( content.
gltf.isEmpty() )
383 tinygltf::Model model;
385 QString gltfWarnings;
387 const bool res = QgsGltfUtils::loadGltfModel( content.
gltf, model, &gltfErrors, &gltfWarnings );
390 const QgsVector3D tileTranslationEcef = content.
rtcCenter + QgsGltfUtils::extractTileTranslation( model,
392 const tinygltf::Scene &scene = model.scenes[model.defaultScene];
393 for (
int nodeIndex : scene.nodes )
395 const tinygltf::Node &gltfNode = model.nodes[nodeIndex];
396 const std::unique_ptr< QMatrix4x4 > gltfLocalTransform = QgsGltfUtils::parseNodeTransform( gltfNode );
398 if ( gltfNode.mesh >= 0 )
400 const tinygltf::Mesh &mesh = model.meshes[gltfNode.mesh];
402 for (
const tinygltf::Primitive &primitive : mesh.primitives )
407 renderPrimitive( model, primitive, tile, tileTranslationEcef, gltfLocalTransform.get(), contentUri, context );
412 else if ( !gltfErrors.isEmpty() )
414 if ( !
mErrors.contains( gltfErrors ) )
416 QgsDebugError( QStringLiteral(
"Error raised reading %1: %2" ).arg( contentUri, gltfErrors ) );
418 if ( !gltfWarnings.isEmpty() )
420 QgsDebugError( QStringLiteral(
"Warnings raised reading %1: %2" ).arg( contentUri, gltfWarnings ) );
425void QgsTiledSceneLayerRenderer::renderPrimitive(
const tinygltf::Model &model,
const tinygltf::Primitive &primitive,
const QgsTiledSceneTile &tile,
const QgsVector3D &tileTranslationEcef,
const QMatrix4x4 *gltfLocalTransform,
const QString &contentUri,
QgsTiledSceneRenderContext &context )
427 switch ( primitive.mode )
429 case TINYGLTF_MODE_TRIANGLES:
431 renderTrianglePrimitive( model, primitive, tile, tileTranslationEcef, gltfLocalTransform, contentUri, context );
434 case TINYGLTF_MODE_LINE:
436 renderLinePrimitive( model, primitive, tile, tileTranslationEcef, gltfLocalTransform, contentUri, context );
439 case TINYGLTF_MODE_POINTS:
440 if ( !mWarnedPrimitiveTypes.contains( TINYGLTF_MODE_POINTS ) )
442 mErrors << QObject::tr(
"Point objects in tiled scenes are not supported" );
443 mWarnedPrimitiveTypes.insert( TINYGLTF_MODE_POINTS );
447 case TINYGLTF_MODE_LINE_LOOP:
448 if ( !mWarnedPrimitiveTypes.contains( TINYGLTF_MODE_LINE_LOOP ) )
450 mErrors << QObject::tr(
"Line loops in tiled scenes are not supported" );
451 mWarnedPrimitiveTypes.insert( TINYGLTF_MODE_LINE_LOOP );
455 case TINYGLTF_MODE_LINE_STRIP:
456 if ( !mWarnedPrimitiveTypes.contains( TINYGLTF_MODE_LINE_STRIP ) )
458 mErrors << QObject::tr(
"Line strips in tiled scenes are not supported" );
459 mWarnedPrimitiveTypes.insert( TINYGLTF_MODE_LINE_STRIP );
463 case TINYGLTF_MODE_TRIANGLE_STRIP:
464 if ( !mWarnedPrimitiveTypes.contains( TINYGLTF_MODE_TRIANGLE_STRIP ) )
466 mErrors << QObject::tr(
"Triangular strips in tiled scenes are not supported" );
467 mWarnedPrimitiveTypes.insert( TINYGLTF_MODE_TRIANGLE_STRIP );
471 case TINYGLTF_MODE_TRIANGLE_FAN:
472 if ( !mWarnedPrimitiveTypes.contains( TINYGLTF_MODE_TRIANGLE_FAN ) )
474 mErrors << QObject::tr(
"Triangular fans in tiled scenes are not supported" );
475 mWarnedPrimitiveTypes.insert( TINYGLTF_MODE_TRIANGLE_FAN );
480 if ( !mWarnedPrimitiveTypes.contains( primitive.mode ) )
482 mErrors << QObject::tr(
"Primitive type %1 in tiled scenes are not supported" ).arg( primitive.mode );
483 mWarnedPrimitiveTypes.insert( primitive.mode );
489void QgsTiledSceneLayerRenderer::renderTrianglePrimitive(
const tinygltf::Model &model,
const tinygltf::Primitive &primitive,
const QgsTiledSceneTile &tile,
const QgsVector3D &tileTranslationEcef,
const QMatrix4x4 *gltfLocalTransform,
const QString &contentUri,
QgsTiledSceneRenderContext &context )
491 auto posIt = primitive.attributes.find(
"POSITION" );
492 if ( posIt == primitive.attributes.end() )
494 mErrors << QObject::tr(
"Could not find POSITION attribute for primitive" );
497 int positionAccessorIndex = posIt->second;
502 QgsGltfUtils::accessorToMapCoordinates(
504 &mSceneToMapTransform,
507 static_cast<
Qgis::Axis >( tile.metadata().value( QStringLiteral(
"gltfUpAxis" ), static_cast< int >(
Qgis::Axis::Y ) ).toInt() ),
516 QVector< float > texturePointX;
517 QVector< float > texturePointY;
518 QPair< int, int > textureId{ -1, -1 };
521 const tinygltf::Material &material = model.materials[primitive.material];
522 const tinygltf::PbrMetallicRoughness &pbr = material.pbrMetallicRoughness;
524 if ( pbr.baseColorTexture.index >= 0
525 &&
static_cast< int >( model.textures.size() ) > pbr.baseColorTexture.index )
527 const tinygltf::Texture &tex = model.textures[pbr.baseColorTexture.index];
529 switch ( QgsGltfUtils::imageResourceType( model, tex.source ) )
531 case QgsGltfUtils::ResourceType::Embedded:
532 textureImage = QgsGltfUtils::extractEmbeddedImage( model, tex.source );
535 case QgsGltfUtils::ResourceType::Linked:
537 const QString linkedPath = QgsGltfUtils::linkedImagePath( model, tex.source );
538 const QString textureUri = QUrl( contentUri ).resolved( linkedPath ).toString();
540 if ( !rep.isEmpty() )
542 textureImage = QImage::fromData( rep );
548 if ( !textureImage.isNull() )
550 auto texIt = primitive.attributes.find(
"TEXCOORD_0" );
551 if ( texIt != primitive.attributes.end() )
553 QgsGltfUtils::extractTextureCoordinates(
554 model, texIt->second, texturePointX, texturePointY
558 textureId = qMakePair( mCurrentModelId, pbr.baseColorTexture.index );
564 auto needTriangle = [&outputRect](
const QPolygonF & triangle ) ->
bool
566 return triangle.boundingRect().intersects( outputRect );
569 const bool useTexture = !textureImage.isNull();
570 bool hasStoredTexture =
false;
572 QVector< PrimitiveData > thisTileTriangleData;
574 if ( primitive.indices == -1 )
576 Q_ASSERT( x.size() % 3 == 0 );
578 thisTileTriangleData.reserve( x.size() );
579 for (
int i = 0; i < x.size(); i += 3 )
585 data.type = PrimitiveType::Triangle;
586 data.textureId = textureId;
589 data.textureCoords[0] = texturePointX[i];
590 data.textureCoords[1] = texturePointY[i];
591 data.textureCoords[2] = texturePointX[i + 1];
592 data.textureCoords[3] = texturePointY[i + 1];
593 data.textureCoords[4] = texturePointX[i + 2];
594 data.textureCoords[5] = texturePointY[i + 2];
596 data.coordinates = QVector<QPointF> { QPointF( x[i], y[i] ), QPointF( x[i + 1], y[i + 1] ), QPointF( x[i + 2], y[i + 2] ), QPointF( x[i], y[i] ) };
597 data.z = ( z[i] + z[i + 1] + z[i + 2] ) / 3;
598 if ( needTriangle( data.coordinates ) )
600 thisTileTriangleData.push_back( data );
601 if ( !hasStoredTexture && !textureImage.isNull() )
604 mTextures.insert( textureId, textureImage.copy() );
605 hasStoredTexture =
true;
612 const tinygltf::Accessor &primitiveAccessor = model.accessors[primitive.indices];
613 const tinygltf::BufferView &bvPrimitive = model.bufferViews[primitiveAccessor.bufferView];
614 const tinygltf::Buffer &bPrimitive = model.buffers[bvPrimitive.buffer];
616 Q_ASSERT( ( primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT
617 || primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT
618 || primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE )
619 && primitiveAccessor.type == TINYGLTF_TYPE_SCALAR );
621 const char *primitivePtr =
reinterpret_cast< const char *
>( bPrimitive.data.data() ) + bvPrimitive.byteOffset + primitiveAccessor.byteOffset;
623 thisTileTriangleData.reserve( primitiveAccessor.count / 3 );
624 for ( std::size_t i = 0; i < primitiveAccessor.count / 3; i++ )
629 unsigned int index1 = 0;
630 unsigned int index2 = 0;
631 unsigned int index3 = 0;
634 data.type = PrimitiveType::Triangle;
635 data.textureId = textureId;
637 if ( primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT )
639 const unsigned short *usPtrPrimitive =
reinterpret_cast< const unsigned short *
>( primitivePtr );
640 if ( bvPrimitive.byteStride )
641 primitivePtr += bvPrimitive.byteStride;
643 primitivePtr += 3 *
sizeof(
unsigned short );
645 index1 = usPtrPrimitive[0];
646 index2 = usPtrPrimitive[1];
647 index3 = usPtrPrimitive[2];
649 else if ( primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE )
651 const unsigned char *usPtrPrimitive =
reinterpret_cast< const unsigned char *
>( primitivePtr );
652 if ( bvPrimitive.byteStride )
653 primitivePtr += bvPrimitive.byteStride;
655 primitivePtr += 3 *
sizeof(
unsigned char );
657 index1 = usPtrPrimitive[0];
658 index2 = usPtrPrimitive[1];
659 index3 = usPtrPrimitive[2];
663 const unsigned int *uintPtrPrimitive =
reinterpret_cast< const unsigned int *
>( primitivePtr );
664 if ( bvPrimitive.byteStride )
665 primitivePtr += bvPrimitive.byteStride;
667 primitivePtr += 3 *
sizeof(
unsigned int );
669 index1 = uintPtrPrimitive[0];
670 index2 = uintPtrPrimitive[1];
671 index3 = uintPtrPrimitive[2];
676 data.textureCoords[0] = texturePointX[index1];
677 data.textureCoords[1] = texturePointY[index1];
678 data.textureCoords[2] = texturePointX[index2];
679 data.textureCoords[3] = texturePointY[index2];
680 data.textureCoords[4] = texturePointX[index3];
681 data.textureCoords[5] = texturePointY[index3];
684 data.coordinates = { QVector<QPointF>{ QPointF( x[index1], y[index1] ), QPointF( x[index2], y[index2] ), QPointF( x[index3], y[index3] ), QPointF( x[index1], y[index1] ) } };
685 data.z = ( z[index1] + z[index2] + z[index3] ) / 3;
686 if ( needTriangle( data.coordinates ) )
688 thisTileTriangleData.push_back( data );
689 if ( !hasStoredTexture && !textureImage.isNull() )
692 mTextures.insert( textureId, textureImage.copy() );
693 hasStoredTexture =
true;
706 std::sort( thisTileTriangleData.begin(), thisTileTriangleData.end(), [](
const PrimitiveData & a,
const PrimitiveData & b )
711 for (
const PrimitiveData &data : std::as_const( thisTileTriangleData ) )
713 if ( useTexture && data.textureId.first >= 0 )
717 data.textureCoords[2], data.textureCoords[3],
718 data.textureCoords[4], data.textureCoords[5] );
720 mRenderer->renderTriangle( context, data.coordinates );
725 mPrimitiveData.append( thisTileTriangleData );
736void QgsTiledSceneLayerRenderer::renderLinePrimitive(
const tinygltf::Model &model,
const tinygltf::Primitive &primitive,
const QgsTiledSceneTile &tile,
const QgsVector3D &tileTranslationEcef,
const QMatrix4x4 *gltfLocalTransform,
const QString &,
QgsTiledSceneRenderContext &context )
738 auto posIt = primitive.attributes.find(
"POSITION" );
739 if ( posIt == primitive.attributes.end() )
741 mErrors << QObject::tr(
"Could not find POSITION attribute for primitive" );
744 int positionAccessorIndex = posIt->second;
749 QgsGltfUtils::accessorToMapCoordinates(
751 &mSceneToMapTransform,
754 static_cast<
Qgis::Axis >( tile.metadata().value( QStringLiteral(
"gltfUpAxis" ), static_cast< int >(
Qgis::Axis::Y ) ).toInt() ),
761 auto needLine = [&outputRect](
const QPolygonF & line ) ->
bool
763 return line.boundingRect().intersects( outputRect );
766 QVector< PrimitiveData > thisTileLineData;
768 if ( primitive.indices == -1 )
770 Q_ASSERT( x.size() % 2 == 0 );
772 thisTileLineData.reserve( x.size() );
773 for (
int i = 0; i < x.size(); i += 2 )
779 data.type = PrimitiveType::Line;
780 data.coordinates = QVector<QPointF> { QPointF( x[i], y[i] ), QPointF( x[i + 1], y[i + 1] ) };
782 data.z = std::max( z[i], z[i + 1] );
783 if ( needLine( data.coordinates ) )
785 thisTileLineData.push_back( data );
791 const tinygltf::Accessor &primitiveAccessor = model.accessors[primitive.indices];
792 const tinygltf::BufferView &bvPrimitive = model.bufferViews[primitiveAccessor.bufferView];
793 const tinygltf::Buffer &bPrimitive = model.buffers[bvPrimitive.buffer];
795 Q_ASSERT( ( primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT
796 || primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT
797 || primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE )
798 && primitiveAccessor.type == TINYGLTF_TYPE_SCALAR );
800 const char *primitivePtr =
reinterpret_cast< const char *
>( bPrimitive.data.data() ) + bvPrimitive.byteOffset + primitiveAccessor.byteOffset;
802 thisTileLineData.reserve( primitiveAccessor.count / 2 );
803 for ( std::size_t i = 0; i < primitiveAccessor.count / 2; i++ )
808 unsigned int index1 = 0;
809 unsigned int index2 = 0;
812 data.type = PrimitiveType::Line;
814 if ( primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT )
816 const unsigned short *usPtrPrimitive =
reinterpret_cast< const unsigned short *
>( primitivePtr );
817 if ( bvPrimitive.byteStride )
818 primitivePtr += bvPrimitive.byteStride;
820 primitivePtr += 2 *
sizeof(
unsigned short );
822 index1 = usPtrPrimitive[0];
823 index2 = usPtrPrimitive[1];
825 else if ( primitiveAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE )
827 const unsigned char *usPtrPrimitive =
reinterpret_cast< const unsigned char *
>( primitivePtr );
828 if ( bvPrimitive.byteStride )
829 primitivePtr += bvPrimitive.byteStride;
831 primitivePtr += 2 *
sizeof(
unsigned char );
833 index1 = usPtrPrimitive[0];
834 index2 = usPtrPrimitive[1];
838 const unsigned int *uintPtrPrimitive =
reinterpret_cast< const unsigned int *
>( primitivePtr );
839 if ( bvPrimitive.byteStride )
840 primitivePtr += bvPrimitive.byteStride;
842 primitivePtr += 2 *
sizeof(
unsigned int );
844 index1 = uintPtrPrimitive[0];
845 index2 = uintPtrPrimitive[1];
848 data.coordinates = { QVector<QPointF>{ QPointF( x[index1], y[index1] ), QPointF( x[index2], y[index2] ) } };
850 data.z = std::max( z[index1], z[index2] );
851 if ( needLine( data.coordinates ) )
853 thisTileLineData.push_back( data );
865 std::sort( thisTileLineData.begin(), thisTileLineData.end(), [](
const PrimitiveData & a,
const PrimitiveData & b )
870 for (
const PrimitiveData &data : std::as_const( thisTileLineData ) )
872 mRenderer->renderLine( context, data.coordinates );
877 mPrimitiveData.append( thisTileLineData );
The Qgis class provides global constants for use throughout the application.
@ RendersLines
Renderer can render line primitives.
@ RequiresTextures
Renderer requires textures.
@ ForceRasterRender
Layer should always be rendered as a raster image.
@ RendersTriangles
Renderer can render triangle primitives.
@ Available
Tile children are already available.
@ NeedFetching
Tile has children, but they are not yet available and must be fetched.
@ NoChildren
Tile is known to have no children.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ RenderPartialOutputOverPreviousCachedImage
When rendering temporary in-progress preview renders, these preview renders can be drawn over any pre...
@ RenderPartialOutputs
The renderer benefits from rendering temporary in-progress preview renders. These are temporary resul...
@ VerticalCenter
Center align.
@ Additive
When tile is refined its content should be used alongside its children simultaneously.
@ Replacement
When tile is refined then its children should be used in place of itself.
@ Reverse
Reverse/inverse transform (from destination to source)
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
A 3-dimensional box composed of x, y, z coordinates.
QVector< QgsVector3D > corners() const
Returns an array of all box corners as 3D vectors.
static TileContents extractGltfFromTileContent(const QByteArray &tileContent)
Parses tile content.
Custom exception class for Coordinate Reference System related exceptions.
Curve polygon geometry type.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
A geometry is the spatial representation of a feature.
static QPainterPath calculatePainterClipRegion(const QList< QgsMapClippingRegion > ®ions, const QgsRenderContext &context, Qgis::LayerType layerType, bool &shouldClip)
Returns a QPainterPath representing the intersection of clipping regions from context which should be...
static QList< QgsMapClippingRegion > collectClippingRegionsForLayer(const QgsRenderContext &context, const QgsMapLayer *layer)
Collects the list of map clipping regions from a context which apply to a map layer.
Base class for utility classes that encapsulate information necessary for rendering of map layers.
bool mReadyToCompose
The flag must be set to false in renderer's constructor if wants to use the smarter map redraws funct...
static constexpr int MAX_TIME_TO_USE_CACHED_PREVIEW_IMAGE
Maximum time (in ms) to allow display of a previously cached preview image while rendering layers,...
QString layerId() const
Gets access to the ID of the layer rendered by this class.
QgsRenderContext * renderContext()
Returns the render context associated with the renderer.
void transformInPlace(double &x, double &y) const
Transforms device coordinates to map coordinates.
A simple 4x4 matrix implementation useful for transformation in 3D space.
static QgsOrientedBox3D fromBox3D(const QgsBox3D &box)
Constructs an oriented box from an axis-aligned bounding box.
A class to represent a 2D point.
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
const QgsDistanceArea & distanceArea() const
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsCoordinateTransformContext transformContext() const
Returns the context's coordinate transform context, which stores various information regarding which ...
QSize outputSize() const
Returns the size of the resulting rendered image, in pixels.
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
QPainter * previewRenderPainter()
Returns the const destination QPainter for temporary in-progress preview renders.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
void record(const QString &name, double time, const QString &group="startup", const QString &id=QString())
Manually adds a profile event with the given name and total time (in seconds).
Scoped object for saving and restoring a QPainter object's state.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
Represents a bounding volume for a tiled scene.
QgsAbstractGeometry * as2DGeometry(const QgsCoordinateTransform &transform=QgsCoordinateTransform(), Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Returns a new geometry representing the 2-dimensional X/Y center slice of the volume.
virtual const QgsCoordinateReferenceSystem sceneCrs() const =0
Returns the original coordinate reference system for the tiled scene data.
virtual QgsTiledSceneIndex index() const =0
Returns the provider's tile index.
virtual const QgsTiledSceneBoundingVolume & boundingVolume() const =0
Returns the bounding volume for the data provider.
Qgis::TileChildrenAvailability childAvailability(long long id) const
Returns the availability for a tile's children.
QByteArray retrieveContent(const QString &uri, QgsFeedback *feedback=nullptr)
Retrieves index content for the specified uri.
bool fetchHierarchy(long long id, QgsFeedback *feedback=nullptr)
Populates the tile with the given id by fetching any sub datasets attached to the tile.
QgsTiledSceneTile getTile(long long id)
Returns the tile with matching id, or an invalid tile if the matching tile is not available.
QVector< long long > getTiles(const QgsTiledSceneRequest &request)
Returns the list of tile IDs which match the given request.
bool isValid() const
Returns true if the index is valid.
bool forceRasterRender() const override
Returns true if the renderer must be rendered to a raster paint device (e.g.
QgsTiledSceneLayerRenderer(QgsTiledSceneLayer *layer, QgsRenderContext &context)
Ctor.
QgsFeedback * feedback() const override
Access to feedback object of the layer renderer (may be nullptr)
bool render() override
Do the rendering (based on data stored in the class).
~QgsTiledSceneLayerRenderer()
Qgis::MapLayerRendererFlags flags() const override
Returns flags which control how the map layer rendering behaves.
Represents a map layer supporting display of tiled scene objects.
QgsTiledSceneDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsTiledSceneRenderer * renderer()
Returns the 2D renderer for the tiled scene.
Encapsulates the render context for a 2D tiled scene rendering operation.
void setTextureImage(const QImage &image)
Sets the current texture image.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void setTextureCoordinates(float textureX1, float textureY1, float textureX2, float textureY2, float textureX3, float textureY3)
Sets the current texture coordinates.
virtual QgsTiledSceneRenderer * clone() const =0
Create a deep copy of this renderer.
Tiled scene data request.
void setParentTileId(long long id)
Sets the parent tile id, if filtering is to be limited to children of a specific tile.
void setFilterBox(const QgsOrientedBox3D &box)
Sets the box from which data will be taken.
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the request to check if it should be cancel...
void setRequiredGeometricError(double error)
Sets the required geometric error threshold for the returned tiles, in scene CRS units.
Represents an individual tile from a tiled scene data source.
bool isValid() const
Returns true if the tile is a valid tile (i.e.
Qgis::TileRefinementProcess refinementProcess() const
Returns the tile's refinement process.
QVariantMap resources() const
Returns the resources attached to the tile.
const QgsTiledSceneBoundingVolume & boundingVolume() const
Returns the bounding volume for the tile.
QVariantMap metadata() const
Returns additional metadata attached to the tile.
long long id() const
Returns the tile's unique ID.
const QgsMatrix4x4 * transform() const
Returns the tile's transform.
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
double x() const
Returns X coordinate.
#define QgsDebugError(str)
Encapsulates the contents of a 3D tile.
QgsVector3D rtcCenter
Optional RTC center.
QByteArray gltf
GLTF binary content.