mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
- Change extent to trapezoid shape
- Visualize the viewed area using QgsRubberBand - Address reviews
This commit is contained in:
parent
e38a879378
commit
9141d05d59
@ -27,13 +27,6 @@ Definition of the world.
|
||||
#include "qgs3dmapsettings.h"
|
||||
%End
|
||||
public:
|
||||
enum ViewSyncMode
|
||||
{
|
||||
NoSync,
|
||||
Sync3DTo2D,
|
||||
Sync2DTo3D
|
||||
};
|
||||
|
||||
Qgs3DMapSettings();
|
||||
%Docstring
|
||||
Constructor for Qgs3DMapSettings
|
||||
@ -628,17 +621,31 @@ Sets the renderer usage
|
||||
.. versionadded:: 3.24
|
||||
%End
|
||||
|
||||
ViewSyncMode viewSyncMode() const;
|
||||
Qgis::ViewSyncMode viewSyncMode() const;
|
||||
%Docstring
|
||||
Returns the view sync mode (used to syncronize the 2D main map canvas and the 3D camera navigation)
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
void setViewSyncMode( ViewSyncMode mode );
|
||||
void setViewSyncMode( Qgis::ViewSyncMode mode );
|
||||
%Docstring
|
||||
Sets the view sync mode (used to syncronize the 2D main map canvas and the 3D camera navigation)
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
bool viewFrustumVisualizationEnabled() const;
|
||||
%Docstring
|
||||
Returns whether the camera's view frustum is visualized on the 2D map canvas
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
void setViewFrustumVisualizationEnabled( bool enabled );
|
||||
%Docstring
|
||||
Sets whether the camera's view frustum is visualized on the 2D map canvas
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
@ -849,6 +856,13 @@ Emitted when shadow rendering settings are changed
|
||||
Emitted when the FPS counter is enabled or disabled
|
||||
|
||||
.. versionadded:: 3.18
|
||||
%End
|
||||
|
||||
void viewFrustumVisualizationEnabledChanged();
|
||||
%Docstring
|
||||
Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
private:
|
||||
|
@ -1303,6 +1303,14 @@ Qgis.RendererUsage.__doc__ = 'Usage of the renderer.\n\n.. versionadded:: 3.24\n
|
||||
# --
|
||||
Qgis.RendererUsage.baseClass = Qgis
|
||||
# monkey patching scoped based enum
|
||||
Qgis.ViewSyncMode.NoSync.__doc__ = ""
|
||||
Qgis.ViewSyncMode.Sync3DTo2D.__doc__ = ""
|
||||
Qgis.ViewSyncMode.Sync2DTo3D.__doc__ = ""
|
||||
Qgis.ViewSyncMode.BothWaysSync.__doc__ = ""
|
||||
Qgis.ViewSyncMode.__doc__ = '\n\n' + '* ``NoSync``: ' + Qgis.ViewSyncMode.NoSync.__doc__ + '\n' + '* ``Sync3DTo2D``: ' + Qgis.ViewSyncMode.Sync3DTo2D.__doc__ + '\n' + '* ``Sync2DTo3D``: ' + Qgis.ViewSyncMode.Sync2DTo3D.__doc__ + '\n' + '* ``BothWaysSync``: ' + Qgis.ViewSyncMode.BothWaysSync.__doc__
|
||||
# --
|
||||
Qgis.ViewSyncMode.baseClass = Qgis
|
||||
# monkey patching scoped based enum
|
||||
Qgis.HistoryProviderBackend.LocalProfile.__doc__ = "Local profile"
|
||||
Qgis.HistoryProviderBackend.__doc__ = 'History provider backends.\n\n.. versionadded:: 3.24\n\n' + '* ``LocalProfile``: ' + Qgis.HistoryProviderBackend.LocalProfile.__doc__
|
||||
# --
|
||||
|
@ -835,6 +835,14 @@ The development version
|
||||
Unknown,
|
||||
};
|
||||
|
||||
enum class ViewSyncMode
|
||||
{
|
||||
NoSync,
|
||||
Sync3DTo2D,
|
||||
Sync2DTo3D,
|
||||
BothWaysSync
|
||||
};
|
||||
|
||||
enum class HistoryProviderBackend
|
||||
{
|
||||
LocalProfile,
|
||||
|
@ -146,6 +146,7 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *
|
||||
connect( &map, &Qgs3DMapSettings::fpsCounterEnabledChanged, this, &Qgs3DMapScene::fpsCounterEnabledChanged );
|
||||
connect( &map, &Qgs3DMapSettings::cameraMovementSpeedChanged, this, &Qgs3DMapScene::onCameraMovementSpeedChanged );
|
||||
|
||||
|
||||
connect( QgsApplication::sourceCache(), &QgsSourceCache::remoteSourceFetched, this, [ = ]( const QString & url )
|
||||
{
|
||||
const QList<QgsMapLayer *> modelVectorLayers = mModelVectorLayers;
|
||||
@ -247,32 +248,56 @@ void Qgs3DMapScene::viewZoomFull()
|
||||
mCameraController->resetView( 1.5 * std::sqrt( a * a - side * side ) ); // assuming FOV being 45 degrees
|
||||
}
|
||||
|
||||
void Qgs3DMapScene::viewExtent( const QgsRectangle &extent )
|
||||
void Qgs3DMapScene::setViewFrom2DExtent( const QgsRectangle &extent )
|
||||
{
|
||||
QgsPointXY center = extent.center();
|
||||
QgsVector3D centerWrld = mMap.mapToWorldCoordinates( QVector3D( center.x(), center.y(), 0 ) );
|
||||
QgsVector3D centerWorld = mMap.mapToWorldCoordinates( QVector3D( center.x(), center.y(), 0 ) );
|
||||
QgsVector3D p1 = mMap.mapToWorldCoordinates( QVector3D( extent.xMinimum(), extent.yMinimum(), 0 ) );
|
||||
QgsVector3D p2 = mMap.mapToWorldCoordinates( QVector3D( extent.xMaximum(), extent.yMaximum(), 0 ) );
|
||||
|
||||
float side = std::max( std::abs( p1.x() - p2.x() ), std::abs( p1.z() - p2.z() ) );
|
||||
float a = side / 2.0f / std::sin( qDegreesToRadians( cameraController()->camera()->fieldOfView() ) / 2.0f );
|
||||
mCameraController->setViewFromTop( centerWrld.x(), centerWrld.z(), std::sqrt( a * a - side * side ) );
|
||||
float xSide = std::abs( p1.x() - p2.x() );
|
||||
float ySide = std::abs( p1.z() - p2.z() );
|
||||
if ( xSide < ySide )
|
||||
{
|
||||
float fov = 2 * std::atan( std::tan( qDegreesToRadians( cameraController()->camera()->fieldOfView() ) / 2 ) * cameraController()->camera()->aspectRatio() );
|
||||
float r = xSide / 2.0f / std::tan( fov / 2.0f );
|
||||
mCameraController->setViewFromTop( centerWorld.x(), centerWorld.z(), r );
|
||||
}
|
||||
else
|
||||
{
|
||||
float fov = qDegreesToRadians( cameraController()->camera()->fieldOfView() );
|
||||
float r = ySide / 2.0f / std::tan( fov / 2.0f );
|
||||
mCameraController->setViewFromTop( centerWorld.x(), centerWorld.z(), r );
|
||||
}
|
||||
}
|
||||
|
||||
QgsRectangle Qgs3DMapScene::viewFrustum2DExtent()
|
||||
QVector<QgsPointXY> Qgs3DMapScene::viewFrustum2DExtent()
|
||||
{
|
||||
QVector4D p = mCameraController->camera()->projectionMatrix() * mCameraController->camera()->viewMatrix() * mCameraController->camera()->viewCenter();
|
||||
double maxDepth = p.z();// p.w();
|
||||
Qt3DRender::QCamera *camera = mCameraController->camera();
|
||||
const QRect viewport = mCameraController->viewport();
|
||||
QgsRectangle extent;
|
||||
extent.setMinimal();
|
||||
for ( int i = 0; i < 8; ++i )
|
||||
QVector<QgsPointXY> extent;
|
||||
QVector<int> pointsOrder = { 0, 1, 3, 2 };
|
||||
for ( int i : pointsOrder )
|
||||
{
|
||||
const QPoint p( ( ( i >> 0 ) & 1 ) ? 0 : viewport.width(), ( ( i >> 1 ) & 1 ) ? 0 : viewport.height() );
|
||||
const double depth = ( ( i >> 2 ) & 1 ) ? 0 : maxDepth;
|
||||
QVector3D pWorld = Qgs3DUtils::screenPointToWorldPos( p, depth, viewport.size(), mCameraController->camera() );
|
||||
QgsVector3D pMap = mMap.worldToMapCoordinates( pWorld );
|
||||
extent.include( QgsPointXY( pMap.x(), pMap.y() ) );
|
||||
QgsRay3D ray = Qgs3DUtils::rayFromScreenPoint( p, viewport.size(), camera );
|
||||
QVector3D dir = ray.direction();
|
||||
if ( dir.y() == 0.0 )
|
||||
dir.setY( 0.0001 );
|
||||
double t = - ray.origin().y() / dir.y();
|
||||
if ( t < 0 )
|
||||
{
|
||||
// If the projected point is on the back of the camera we choose the farthest point in the front
|
||||
t = camera->farPlane();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the projected point is on the front of the camera we choose the closest between it and farthest point in the front
|
||||
t = std::min<float>( t, camera->farPlane() );
|
||||
}
|
||||
QVector3D planePoint = ray.origin() + t * dir;
|
||||
QgsVector3D pMap = mMap.worldToMapCoordinates( planePoint );
|
||||
extent.push_back( QgsPointXY( pMap.x(), pMap.y() ) );
|
||||
}
|
||||
return extent;
|
||||
}
|
||||
@ -385,7 +410,7 @@ void Qgs3DMapScene::onCameraChanged()
|
||||
|
||||
onShadowSettingsChanged();
|
||||
|
||||
QgsRectangle extent2D = viewFrustum2DExtent();
|
||||
QVector<QgsPointXY> extent2D = viewFrustum2DExtent();
|
||||
emit viewed2DExtentFrom3DChanged( extent2D );
|
||||
}
|
||||
|
||||
|
@ -86,14 +86,14 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void viewExtent( const QgsRectangle &extent );
|
||||
void setViewFrom2DExtent( const QgsRectangle &extent );
|
||||
|
||||
/**
|
||||
* Calculates the 2D extent viewed by the 3D camera
|
||||
* Calculates the 2D extent viewed by the 3D camera as the vertices of the viewed trapezoid
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
QgsRectangle viewFrustum2DExtent();
|
||||
QVector<QgsPointXY> viewFrustum2DExtent();
|
||||
|
||||
//! Returns number of pending jobs of the terrain entity
|
||||
int terrainPendingJobsCount() const;
|
||||
@ -165,7 +165,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void viewed2DExtentFrom3DChanged( QgsRectangle extent );
|
||||
void viewed2DExtentFrom3DChanged( QVector<QgsPointXY> extent );
|
||||
|
||||
public slots:
|
||||
//! Updates the temporale entities
|
||||
|
@ -84,6 +84,7 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other )
|
||||
, mEyeDomeLightingStrength( other.mEyeDomeLightingStrength )
|
||||
, mEyeDomeLightingDistance( other.mEyeDomeLightingDistance )
|
||||
, mViewSyncMode( other.mViewSyncMode )
|
||||
, mVisualizeViewFrustum( other.mVisualizeViewFrustum )
|
||||
, mDebugShadowMapEnabled( other.mDebugShadowMapEnabled )
|
||||
, mDebugShadowMapCorner( other.mDebugShadowMapCorner )
|
||||
, mDebugShadowMapSize( other.mDebugShadowMapSize )
|
||||
@ -273,7 +274,8 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
|
||||
mEyeDomeLightingDistance = elemEyeDomeLighting.attribute( "eye-dome-lighting-distance", QStringLiteral( "1" ) ).toInt();
|
||||
|
||||
QDomElement elemNavigationSync = elem.firstChildElement( QStringLiteral( "navigation-sync" ) );
|
||||
mViewSyncMode = ( Qgs3DMapSettings::ViewSyncMode )( elemNavigationSync.attribute( QStringLiteral( "view-sync-mode" ), QStringLiteral( "0" ) ).toInt() );
|
||||
mViewSyncMode = ( Qgis::ViewSyncMode )( elemNavigationSync.attribute( QStringLiteral( "view-sync-mode" ), QStringLiteral( "0" ) ).toInt() );
|
||||
mVisualizeViewFrustum = elemNavigationSync.attribute( QStringLiteral( "view-frustum-visualization-enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
|
||||
QDomElement elemDebugSettings = elem.firstChildElement( QStringLiteral( "debug-settings" ) );
|
||||
mDebugShadowMapEnabled = elemDebugSettings.attribute( QStringLiteral( "shadowmap-enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
@ -414,6 +416,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon
|
||||
|
||||
QDomElement elemNavigationSync = doc.createElement( QStringLiteral( "navigation-sync" ) );
|
||||
elemNavigationSync.setAttribute( QStringLiteral( "view-sync-mode" ), ( int )mViewSyncMode );
|
||||
elemNavigationSync.setAttribute( QStringLiteral( "view-frustum-visualization-enabled" ), mVisualizeViewFrustum ? QStringLiteral( "0" ) : QStringLiteral( "1" ) );
|
||||
elem.appendChild( elemNavigationSync );
|
||||
|
||||
QDomElement elemDebugSettings = doc.createElement( QStringLiteral( "debug-settings" ) );
|
||||
@ -879,11 +882,21 @@ void Qgs3DMapSettings::setRendererUsage( Qgis::RendererUsage rendererUsage )
|
||||
mRendererUsage = rendererUsage;
|
||||
}
|
||||
|
||||
void Qgs3DMapSettings::setViewSyncMode( ViewSyncMode mode )
|
||||
void Qgs3DMapSettings::setViewSyncMode( Qgis::ViewSyncMode mode )
|
||||
{
|
||||
mViewSyncMode = mode;
|
||||
}
|
||||
|
||||
void Qgs3DMapSettings::setViewFrustumVisualizationEnabled( bool enabled )
|
||||
{
|
||||
if ( mVisualizeViewFrustum != enabled )
|
||||
{
|
||||
mVisualizeViewFrustum = enabled;
|
||||
emit viewFrustumVisualizationEnabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Qgs3DMapSettings::connectChangedSignalsToSettingsChanged()
|
||||
{
|
||||
connect( this, &Qgs3DMapSettings::selectionColorChanged, this, &Qgs3DMapSettings::settingsChanged );
|
||||
|
@ -57,13 +57,6 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ViewSyncMode
|
||||
{
|
||||
NoSync, //! No syncronisation will happen
|
||||
Sync3DTo2D, //! Syncronize 3D view camera to the main map canvas extent
|
||||
Sync2DTo3D //! Update the 2D main canvas extent to include the viewed area from the 3D view
|
||||
};
|
||||
|
||||
//! Constructor for Qgs3DMapSettings
|
||||
Qgs3DMapSettings();
|
||||
//! Copy constructor
|
||||
@ -603,14 +596,28 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
ViewSyncMode viewSyncMode() const { return mViewSyncMode; }
|
||||
Qgis::ViewSyncMode viewSyncMode() const { return mViewSyncMode; }
|
||||
|
||||
/**
|
||||
* Sets the view sync mode (used to syncronize the 2D main map canvas and the 3D camera navigation)
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void setViewSyncMode( ViewSyncMode mode );
|
||||
void setViewSyncMode( Qgis::ViewSyncMode mode );
|
||||
|
||||
/**
|
||||
* Returns whether the camera's view frustum is visualized on the 2D map canvas
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
bool viewFrustumVisualizationEnabled() const { return mVisualizeViewFrustum; }
|
||||
|
||||
/**
|
||||
* Sets whether the camera's view frustum is visualized on the 2D map canvas
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void setViewFrustumVisualizationEnabled( bool enabled );
|
||||
|
||||
signals:
|
||||
|
||||
@ -779,6 +786,13 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
*/
|
||||
void fpsCounterEnabledChanged( bool fpsCounterEnabled );
|
||||
|
||||
/**
|
||||
* Emitted when the camera's view frustum visualization on the main 2D map canvas is enabled or disabled
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void viewFrustumVisualizationEnabledChanged();
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
Qgs3DMapSettings &operator=( const Qgs3DMapSettings & );
|
||||
@ -832,7 +846,8 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
double mEyeDomeLightingStrength = 1000.0;
|
||||
int mEyeDomeLightingDistance = 1;
|
||||
|
||||
ViewSyncMode mViewSyncMode = ViewSyncMode::NoSync;
|
||||
Qgis::ViewSyncMode mViewSyncMode = Qgis::ViewSyncMode::NoSync;
|
||||
bool mVisualizeViewFrustum = false;
|
||||
|
||||
bool mDebugShadowMapEnabled = false;
|
||||
Qt::Corner mDebugShadowMapCorner = Qt::Corner::TopLeftCorner;
|
||||
|
@ -353,12 +353,12 @@ void Qgs3DMapCanvas::onNavigationModeHotKeyPressed( QgsCameraController::Navigat
|
||||
mScene->cameraController()->setCameraNavigationMode( mode );
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvas::viewExtent( const QgsRectangle &extent )
|
||||
void Qgs3DMapCanvas::setViewFrom2DExtent( const QgsRectangle &extent )
|
||||
{
|
||||
mScene->viewExtent( extent );
|
||||
mScene->setViewFrom2DExtent( extent );
|
||||
}
|
||||
|
||||
QgsRectangle Qgs3DMapCanvas::viewFrustum2DExtent()
|
||||
QVector<QgsPointXY> Qgs3DMapCanvas::viewFrustum2DExtent()
|
||||
{
|
||||
return mScene->viewFrustum2DExtent();
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class QgsWindow3DEngine;
|
||||
class QgsPointXY;
|
||||
class Qgs3DNavigationWidget;
|
||||
class QgsTemporalController;
|
||||
|
||||
class QgsRubberBand;
|
||||
|
||||
class Qgs3DMapCanvas : public QWidget
|
||||
{
|
||||
@ -105,14 +105,14 @@ class Qgs3DMapCanvas : public QWidget
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void viewExtent( const QgsRectangle &extent );
|
||||
void setViewFrom2DExtent( const QgsRectangle &extent );
|
||||
|
||||
/**
|
||||
* Calculates the 2D extent viewed by the 3D camera
|
||||
* Calculates the 2D extent viewed by the 3D camera as the vertices of the viewed trapezoid
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
QgsRectangle viewFrustum2DExtent();
|
||||
QVector<QgsPointXY> viewFrustum2DExtent();
|
||||
|
||||
signals:
|
||||
//! Emitted when the 3D map canvas was successfully saved as image
|
||||
@ -131,7 +131,7 @@ class Qgs3DMapCanvas : public QWidget
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
void viewed2DExtentFrom3DChanged( QgsRectangle extent );
|
||||
void viewed2DExtentFrom3DChanged( QVector<QgsPointXY> extent );
|
||||
|
||||
/**
|
||||
* Emitted when the camera navigation \a speed is changed.
|
||||
|
@ -50,12 +50,14 @@
|
||||
#include "qgs3dmapexportsettings.h"
|
||||
|
||||
#include "qgsdockablewidgethelper.h"
|
||||
#include "qgsrubberband.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked )
|
||||
: QWidget( nullptr )
|
||||
, mCanvasName( name )
|
||||
, mViewFrustumHighlight( nullptr )
|
||||
{
|
||||
const QgsSettings setting;
|
||||
|
||||
@ -230,6 +232,8 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked )
|
||||
Qgs3DMapCanvasWidget::~Qgs3DMapCanvasWidget()
|
||||
{
|
||||
delete mDockableWidgetHelper;
|
||||
if ( mViewFrustumHighlight )
|
||||
delete mViewFrustumHighlight;
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasWidget::resizeEvent( QResizeEvent *event )
|
||||
@ -322,6 +326,8 @@ void Qgs3DMapCanvasWidget::setMapSettings( Qgs3DMapSettings *map )
|
||||
// Disable button for switching the map theme if the terrain generator is a mesh, or if there is no terrain
|
||||
mBtnMapThemes->setDisabled( !mCanvas->map()->terrainGenerator() || mCanvas->map()->terrainGenerator()->type() == QgsTerrainGenerator::Mesh );
|
||||
mLabelFpsCounter->setVisible( map->isFpsCounterEnabled() );
|
||||
|
||||
connect( map, &Qgs3DMapSettings::viewFrustumVisualizationEnabledChanged, this, &Qgs3DMapCanvasWidget::onViewFrustumVisualizationEnabledChanged );
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasWidget::setMainCanvas( QgsMapCanvas *canvas )
|
||||
@ -331,6 +337,11 @@ void Qgs3DMapCanvasWidget::setMainCanvas( QgsMapCanvas *canvas )
|
||||
connect( mMainCanvas, &QgsMapCanvas::layersChanged, this, &Qgs3DMapCanvasWidget::onMainCanvasLayersChanged );
|
||||
connect( mMainCanvas, &QgsMapCanvas::canvasColorChanged, this, &Qgs3DMapCanvasWidget::onMainCanvasColorChanged );
|
||||
connect( mMainCanvas, &QgsMapCanvas::extentsChanged, this, &Qgs3DMapCanvasWidget::onMainMapCanvasExtentChanged );
|
||||
|
||||
if ( mViewFrustumHighlight )
|
||||
delete mViewFrustumHighlight;
|
||||
mViewFrustumHighlight = new QgsRubberBand( canvas, QgsWkbTypes::PolygonGeometry );
|
||||
mViewFrustumHighlight->setColor( QColor::fromRgba( qRgba( 0, 0, 255, 50 ) ) );
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasWidget::resetView()
|
||||
@ -507,27 +518,50 @@ void Qgs3DMapCanvasWidget::onMainMapCanvasExtentChanged()
|
||||
{
|
||||
switch ( mCanvas->map()->viewSyncMode() )
|
||||
{
|
||||
case Qgs3DMapSettings::NoSync:
|
||||
case Qgis::ViewSyncMode::NoSync:
|
||||
break;
|
||||
case Qgs3DMapSettings::Sync3DTo2D:
|
||||
mCanvas->viewExtent( mMainCanvas->extent() );
|
||||
case Qgis::ViewSyncMode::Sync3DTo2D:
|
||||
mCanvas->setViewFrom2DExtent( mMainCanvas->extent() );
|
||||
break;
|
||||
case Qgs3DMapSettings::Sync2DTo3D:
|
||||
case Qgis::ViewSyncMode::Sync2DTo3D:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasWidget::onViewed2DExtentFrom3DChanged( QgsRectangle extent )
|
||||
void Qgs3DMapCanvasWidget::onViewed2DExtentFrom3DChanged( QVector<QgsPointXY> extent )
|
||||
{
|
||||
switch ( mCanvas->map()->viewSyncMode() )
|
||||
{
|
||||
case Qgs3DMapSettings::NoSync:
|
||||
case Qgis::ViewSyncMode::NoSync:
|
||||
break;
|
||||
case Qgs3DMapSettings::Sync3DTo2D:
|
||||
case Qgis::ViewSyncMode::Sync3DTo2D:
|
||||
break;
|
||||
case Qgs3DMapSettings::Sync2DTo3D:
|
||||
mMainCanvas->setExtent( extent );
|
||||
case Qgis::ViewSyncMode::Sync2DTo3D:
|
||||
{
|
||||
QgsRectangle extentRect;
|
||||
extentRect.setMinimal();
|
||||
for ( QgsPointXY &pt : extent )
|
||||
{
|
||||
extentRect.include( pt );
|
||||
}
|
||||
mMainCanvas->setExtent( extentRect );
|
||||
mMainCanvas->refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onViewFrustumVisualizationEnabledChanged();
|
||||
}
|
||||
|
||||
void Qgs3DMapCanvasWidget::onViewFrustumVisualizationEnabledChanged()
|
||||
{
|
||||
mViewFrustumHighlight->reset( QgsWkbTypes::PolygonGeometry );
|
||||
if ( mCanvas->map()->viewFrustumVisualizationEnabled() )
|
||||
{
|
||||
for ( QgsPointXY &pt : mCanvas->viewFrustum2DExtent() )
|
||||
{
|
||||
mViewFrustumHighlight->addPoint( pt, false );
|
||||
}
|
||||
mViewFrustumHighlight->closePoints();
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ class Qgs3DMapToolIdentify;
|
||||
class Qgs3DMapToolMeasureLine;
|
||||
class QgsMapCanvas;
|
||||
class QgsDockableWidgetHelper;
|
||||
class QgsRubberBand;
|
||||
|
||||
class APP_EXPORT Qgs3DMapCanvasWidget : public QWidget
|
||||
{
|
||||
@ -86,7 +87,8 @@ class APP_EXPORT Qgs3DMapCanvasWidget : public QWidget
|
||||
void currentMapThemeRenamed( const QString &theme, const QString &newTheme );
|
||||
|
||||
void onMainMapCanvasExtentChanged();
|
||||
void onViewed2DExtentFrom3DChanged( QgsRectangle extent );
|
||||
void onViewed2DExtentFrom3DChanged( QVector<QgsPointXY> extent );
|
||||
void onViewFrustumVisualizationEnabledChanged();
|
||||
|
||||
private:
|
||||
QString mCanvasName;
|
||||
@ -108,6 +110,7 @@ class APP_EXPORT Qgs3DMapCanvasWidget : public QWidget
|
||||
QAction *mActionEnableEyeDome = nullptr;
|
||||
QToolButton *mBtnOptions = nullptr;
|
||||
QgsDockableWidgetHelper *mDockableWidgetHelper = nullptr;
|
||||
QgsRubberBand *mViewFrustumHighlight = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGS3DMAPCANVASWIDGET_H
|
||||
|
@ -193,6 +193,7 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas
|
||||
edlDistanceSpinBox->setValue( map->eyeDomeLightingDistance() );
|
||||
|
||||
mSyncModeComboBox->setCurrentIndex( ( int )map->viewSyncMode() );
|
||||
mVisualizeExtentCheckBox->setChecked( map->viewFrustumVisualizationEnabled() );
|
||||
|
||||
mDebugShadowMapCornerComboBox->addItem( tr( "Top Left" ) );
|
||||
mDebugShadowMapCornerComboBox->addItem( tr( "Top Right" ) );
|
||||
@ -360,7 +361,8 @@ void Qgs3DMapConfigWidget::apply()
|
||||
mMap->setEyeDomeLightingStrength( edlStrengthSpinBox->value() );
|
||||
mMap->setEyeDomeLightingDistance( edlDistanceSpinBox->value() );
|
||||
|
||||
mMap->setViewSyncMode( static_cast<Qgs3DMapSettings::ViewSyncMode>( mSyncModeComboBox->currentIndex() ) );
|
||||
mMap->setViewSyncMode( static_cast<Qgis::ViewSyncMode>( mSyncModeComboBox->currentIndex() ) );
|
||||
mMap->setViewFrustumVisualizationEnabled( mVisualizeExtentCheckBox->isChecked() );
|
||||
|
||||
mMap->setDebugDepthMapSettings( mDebugDepthMapGroupBox->isChecked(), static_cast<Qt::Corner>( mDebugDepthMapCornerComboBox->currentIndex() ), mDebugDepthMapSizeSpinBox->value() );
|
||||
mMap->setDebugShadowMapSettings( mDebugShadowMapGroupBox->isChecked(), static_cast<Qt::Corner>( mDebugShadowMapCornerComboBox->currentIndex() ), mDebugShadowMapSizeSpinBox->value() );
|
||||
|
@ -1373,6 +1373,15 @@ class CORE_EXPORT Qgis
|
||||
};
|
||||
Q_ENUM( RendererUsage )
|
||||
|
||||
enum class ViewSyncMode : int
|
||||
{
|
||||
NoSync = 0, //! No syncronisation will happen
|
||||
Sync3DTo2D = 1, //! Syncronize 3D view camera to the main map canvas extent
|
||||
Sync2DTo3D = 2, //! Update the 2D main canvas extent to include the viewed area from the 3D view
|
||||
BothWaysSync = 3
|
||||
};
|
||||
Q_ENUM( ViewSyncMode )
|
||||
|
||||
/**
|
||||
* History provider backends.
|
||||
*
|
||||
|
@ -94,7 +94,7 @@
|
||||
<string>Terrain settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mLayoutItem3DMap.svg</normaloff>:/images/themes/default/mLayoutItem3DMap.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
@ -106,7 +106,7 @@
|
||||
<string>Lights settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionHighlightFeature.svg</normaloff>:/images/themes/default/mActionHighlightFeature.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
@ -118,7 +118,7 @@
|
||||
<string>Shadow settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mIconShadow.svg</normaloff>:/images/themes/default/mIconShadow.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
@ -130,7 +130,7 @@
|
||||
<string>Camera and skybox settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mIconCamera.svg</normaloff>:/images/themes/default/mIconCamera.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
@ -147,7 +147,7 @@
|
||||
<string>Advanced settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/propertyicons/system.svg</normaloff>:/images/themes/default/propertyicons/system.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
@ -184,7 +184,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="m3DOptionsStackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="mPageTerrain">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_61">
|
||||
@ -421,7 +421,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<width>77</width>
|
||||
<height>43</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -595,8 +595,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>234</width>
|
||||
<height>220</height>
|
||||
<width>721</width>
|
||||
<height>604</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutCameraSkybox">
|
||||
@ -723,11 +723,31 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>707</width>
|
||||
<width>710</width>
|
||||
<height>584</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Sync mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="mSyncModeComboBox">
|
||||
<item>
|
||||
@ -747,23 +767,10 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mVisualizeExtentCheckBox">
|
||||
<property name="text">
|
||||
<string>Sync mode</string>
|
||||
<string>Visualize viewed 3D area in main 2D map canvas</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -797,7 +804,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>408</width>
|
||||
<width>707</width>
|
||||
<height>690</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -1199,9 +1206,6 @@
|
||||
<tabstop>mDebugDepthMapCornerComboBox</tabstop>
|
||||
<tabstop>mDebugDepthMapSizeSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../images/images.qrc"/>
|
||||
<include location="../../../images/images.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
Loading…
x
Reference in New Issue
Block a user