Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3D] qgs3dmapscene: Compute max clip planes #59328

Merged
merged 1 commit into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions python/3d/auto_generated/qgs3dmapscene.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ In mathematical terms, a 3d plane can be defined with the equation ``ax+by+cz+d=
The normal is ``(a, b, c)`` with ``|a, b, c| = 1``
The distance is ``-d``.

By default, OpenGL supports up to 8 additional clipping planes. If ``clipPlaneEquations``
contains more than 8 planes, only the first 8 ones will be used.
If ``clipPlaneEquations`` is empty, the clipping is disabled.
The number of available clip planes depends on the OpenGL implementation. It should at least handle
6 additional clip planes. When the map scene is created, this number is retrieved.
If ``clipPlaneEquations`` contains more than this maximum, only the first ones will be kept.

.. seealso:: :py:func:`disableClipping`

Expand Down
6 changes: 3 additions & 3 deletions python/PyQt6/3d/auto_generated/qgs3dmapscene.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ In mathematical terms, a 3d plane can be defined with the equation ``ax+by+cz+d=
The normal is ``(a, b, c)`` with ``|a, b, c| = 1``
The distance is ``-d``.

By default, OpenGL supports up to 8 additional clipping planes. If ``clipPlaneEquations``
contains more than 8 planes, only the first 8 ones will be used.
If ``clipPlaneEquations`` is empty, the clipping is disabled.
The number of available clip planes depends on the OpenGL implementation. It should at least handle
6 additional clip planes. When the map scene is created, this number is retrieved.
If ``clipPlaneEquations`` contains more than this maximum, only the first ones will be kept.

.. seealso:: :py:func:`disableClipping`

Expand Down
9 changes: 6 additions & 3 deletions src/3d/qgs3dmapscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ Qgs3DMapScene::Qgs3DMapScene( Qgs3DMapSettings &map, QgsAbstract3DEngine *engine

QRect viewportRect( QPoint( 0, 0 ), mEngine->size() );

// Get the maximum of clip planes available
mMaxClipPlanes = Qgs3DUtils::openGlMaxClipPlanes( mEngine->surface() );

// Camera
float aspectRatio = ( float )viewportRect.width() / viewportRect.height();
mEngine->camera()->lens()->setPerspectiveProjection( mMap.fieldOfView(), aspectRatio, 10.f, 10000.0f );
Expand Down Expand Up @@ -1223,11 +1226,11 @@ void Qgs3DMapScene::handleClippingOnAllEntities() const

void Qgs3DMapScene::enableClipping( const QList<QVector4D> &clipPlaneEquations )
{
if ( clipPlaneEquations.size() > 8 )
if ( clipPlaneEquations.size() > mMaxClipPlanes )
{
QgsDebugMsgLevel( QStringLiteral( "Qgs3DMapScene::enableClipping: it is not possible to use more than 8 clipping planes." ), 2 );
QgsDebugMsgLevel( QStringLiteral( "Qgs3DMapScene::enableClipping: it is not possible to use more than %1 clipping planes." ).arg( mMaxClipPlanes ), 2 );
}
mClipPlanesEquations = clipPlaneEquations.mid( 0, 8 );
mClipPlanesEquations = clipPlaneEquations.mid( 0, mMaxClipPlanes );

// enable the clip planes on the framegraph
QgsFrameGraph *frameGraph = mEngine->frameGraph();
Expand Down
7 changes: 4 additions & 3 deletions src/3d/qgs3dmapscene.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ class _3D_EXPORT Qgs3DMapScene : public QObject
* The normal is ``(a, b, c)`` with ``|a, b, c| = 1``
* The distance is ``-d``.
*
* By default, OpenGL supports up to 8 additional clipping planes. If \a clipPlaneEquations
* contains more than 8 planes, only the first 8 ones will be used.
* If \a clipPlaneEquations is empty, the clipping is disabled.
* The number of available clip planes depends on the OpenGL implementation. It should at least handle
* 6 additional clip planes. When the map scene is created, this number is retrieved.
* If \a clipPlaneEquations contains more than this maximum, only the first ones will be kept.
*
* \see disableClipping()
* \since QGIS 3.40
Expand Down Expand Up @@ -357,6 +357,7 @@ class _3D_EXPORT Qgs3DMapScene : public QObject
bool mSceneUpdatesEnabled = true;

QList<QVector4D> mClipPlanesEquations;
int mMaxClipPlanes = 6;

};
#endif // QGS3DMAPSCENE_H
19 changes: 19 additions & 0 deletions src/3d/qgs3dutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
#include <QtMath>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QRenderSettings>
#include <QOpenGLContext>
#include <QOpenGLFunctions>


#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <Qt3DRender/QBuffer>
Expand Down Expand Up @@ -974,3 +977,19 @@ void Qgs3DUtils::decomposeTransformMatrix( const QMatrix4x4 &matrix, QVector3D &
rotation = QQuaternion::fromRotationMatrix( rot3x3 );
translation = QVector3D( md[12], md[13], md[14] );
}

int Qgs3DUtils::openGlMaxClipPlanes( QSurface *surface )
{
int numPlanes = 6;

QOpenGLContext context;
context.setFormat( QSurfaceFormat::defaultFormat() );
if ( context.create() )
{
context.makeCurrent( surface );
QOpenGLFunctions *funcs = context.functions();
funcs->glGetIntegerv( GL_MAX_CLIP_PLANES, &numPlanes );
}

return numPlanes;
}
10 changes: 10 additions & 0 deletions src/3d/qgs3dutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace Qt3DExtras
class QPhongMaterial;
}

class QSurface;

#include "qgs3dmapsettings.h"
#include "qgs3danimationsettings.h"
#include "qgs3dtypes.h"
Expand Down Expand Up @@ -340,6 +342,14 @@ class _3D_EXPORT Qgs3DUtils
* \since QGIS 3.42
*/
static void decomposeTransformMatrix( const QMatrix4x4 &matrix, QVector3D &translation, QQuaternion &rotation, QVector3D &scale );

/**
* Gets the maximum number of clip planes that can be used.
* This value depends on the OpenGL implementation. It should be at least 6.
*
* \since QGIS 3.42
*/
static int openGlMaxClipPlanes( QSurface *surface );
};

#endif // QGS3DUTILS_H