#11799 Add support for user defined 3D View

From the View menu, add Store and Apply User Defined View
Show Apply User Defined View in the View toolbar

Rename Look Down -> Top View and Look Up -> Bottom View
Update keyboard shortcuts to new naming
This commit is contained in:
Magne Sjaastad 2025-01-27 07:38:19 +01:00
parent ca0179d118
commit 41aed338ab
9 changed files with 347 additions and 7 deletions

View File

@ -297,6 +297,7 @@
<file>pinned-remove.svg</file>
<file>Select.svg</file>
<file>NavigationProperty.svg</file>
<file>user-defined-view.svg</file>
</qresource>
<qresource prefix="/Shader">
<file>fs_CellFace.glsl</file>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
<path d="M 13.744 12.017 C 16.574 7.997 14.479 2.561 10.026 1.246 L 10.026 2.586 C 11.421 3.11 12.581 4.165 13.224 5.554 C 15.09 9.576 11.901 14.109 7.486 13.712 C 5.436 13.529 3.64 12.265 2.775 10.399 C 1.295 7.206 2.999 3.692 5.973 2.576 L 5.973 1.252 C 4.492 1.698 3.174 2.629 2.255 3.935 C -0.856 8.357 1.988 14.488 7.373 14.972 C 9.872 15.196 12.3 14.07 13.744 12.017 Z" style="fill: rgb(128, 128, 128);"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M 8.928 4.353 C 8.683 4.576 8.352 4.702 8.006 4.705 L 7.994 4.705 C 7.648 4.702 7.318 4.576 7.073 4.353 C 6.828 4.132 6.689 3.833 6.685 3.519 C 6.68 3.298 6.748 3.078 6.883 2.892 L 7.913 1 L 8.088 1 L 9.118 2.892 C 9.251 3.078 9.32 3.298 9.316 3.519 C 9.311 3.833 9.172 4.132 8.928 4.353 Z" style="fill: rgb(117, 190, 255);"/>
<text transform="matrix(0.997982, 0, 0, 1.028913, 4.966925, 0.845102)" style="fill: rgb(251, 176, 0); font-family: Arial; font-size: 7.22325px; font-weight: 900; stroke-width: 0.34715px; white-space: pre;" x="0.306" y="9.548">U</text>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,12 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicApplyUserDefinedCameraFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicStoreUserDefinedCameraFeature.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicApplyUserDefinedCameraFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicStoreUserDefinedCameraFeature.cpp
)
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list(APPEND COMMAND_CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})

View File

@ -0,0 +1,102 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicApplyUserDefinedCameraFeature.h"
#include "RicStoreUserDefinedCameraFeature.h"
#include "RiaApplication.h"
#include "RimGridView.h"
#include "RiuViewer.h"
#include "cvfCamera.h"
#include <QAction>
#include <QSettings>
CAF_CMD_SOURCE_INIT( RicApplyUserDefinedCameraFeature, "RicApplyUserDefinedCameraFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicApplyUserDefinedCameraFeature::isCommandEnabled() const
{
if ( !RicStoreUserDefinedCameraFeature::activeCamera() ) return false;
cvf::Vec3d eye = cvf::Vec3d::UNDEFINED;
cvf::Vec3d vrp = cvf::Vec3d::UNDEFINED;
cvf::Vec3d up = cvf::Vec3d::UNDEFINED;
readCameraFromSettings( eye, vrp, up );
if ( eye.isUndefined() || vrp.isUndefined() || up.isUndefined() ) return false;
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicApplyUserDefinedCameraFeature::onActionTriggered( bool isChecked )
{
if ( auto camera = RicStoreUserDefinedCameraFeature::activeCamera() )
{
cvf::Vec3d eye = cvf::Vec3d::UNDEFINED;
cvf::Vec3d vrp = cvf::Vec3d::UNDEFINED;
cvf::Vec3d up = cvf::Vec3d::UNDEFINED;
readCameraFromSettings( eye, vrp, up );
if ( eye.isUndefined() || vrp.isUndefined() || up.isUndefined() ) return;
RicStoreUserDefinedCameraFeature::activeCamera()->setFromLookAt( eye, vrp, up );
RiaApplication::instance()->activeReservoirView()->updateDisplayModelForCurrentTimeStepAndRedraw();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicApplyUserDefinedCameraFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setText( "User Defined View" );
actionToSetup->setToolTip( "User Defined View (Ctrl+Alt+U)" );
actionToSetup->setIcon( QIcon( ":/user-defined-view.svg" ) );
applyShortcutWithHintToAction( actionToSetup, QKeySequence( tr( "Ctrl+Alt+U" ) ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicApplyUserDefinedCameraFeature::readCameraFromSettings( cvf::Vec3d& eye, cvf::Vec3d& vrp, cvf::Vec3d& up )
{
eye = cvf::Vec3d::UNDEFINED;
vrp = cvf::Vec3d::UNDEFINED;
up = cvf::Vec3d::UNDEFINED;
QSettings settings;
settings.beginGroup( RicStoreUserDefinedCameraFeature::groupName() );
QVariant eyeVariant = settings.value( RicStoreUserDefinedCameraFeature::eyeName() );
QVariant vrpVariant = settings.value( RicStoreUserDefinedCameraFeature::viewReferencePointName() );
QVariant upVariant = settings.value( RicStoreUserDefinedCameraFeature::upName() );
if ( eyeVariant.isNull() || vrpVariant.isNull() || upVariant.isNull() ) return;
caf::PdmValueFieldSpecialization<cvf::Vec3d>::setFromVariant( eyeVariant, eye );
caf::PdmValueFieldSpecialization<cvf::Vec3d>::setFromVariant( vrpVariant, vrp );
caf::PdmValueFieldSpecialization<cvf::Vec3d>::setFromVariant( upVariant, up );
}

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
#include "cvfVector3.h"
//==================================================================================================
///
//==================================================================================================
class RicApplyUserDefinedCameraFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
bool isCommandEnabled() const override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
private:
static void readCameraFromSettings( cvf::Vec3d& eye, cvf::Vec3d& vrp, cvf::Vec3d& up );
};

View File

@ -0,0 +1,127 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicStoreUserDefinedCameraFeature.h"
#include "RiaApplication.h"
#include "RimGridView.h"
#include "RiuMainWindow.h"
#include "RiuViewer.h"
#include "cvfCamera.h"
#include <QAction>
#include <QSettings>
CAF_CMD_SOURCE_INIT( RicStoreUserDefinedCameraFeature, "RicStoreUserDefinedCameraFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicStoreUserDefinedCameraFeature::groupName()
{
return "UserDefinedCamera";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicStoreUserDefinedCameraFeature::eyeName()
{
return "Eye";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicStoreUserDefinedCameraFeature::viewReferencePointName()
{
return "ViewReferencePoint";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicStoreUserDefinedCameraFeature::upName()
{
return "Up";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Camera* RicStoreUserDefinedCameraFeature::activeCamera()
{
if ( auto activeView = RiaApplication::instance()->activeReservoirView() )
{
if ( activeView->viewer() && activeView->viewer()->mainCamera() )
{
return activeView->viewer()->mainCamera();
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicStoreUserDefinedCameraFeature::isCommandEnabled() const
{
return activeCamera() != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicStoreUserDefinedCameraFeature::onActionTriggered( bool isChecked )
{
if ( auto camera = activeCamera() )
{
QSettings settings;
settings.beginGroup( RicStoreUserDefinedCameraFeature::groupName() );
cvf::Vec3d eye;
cvf::Vec3d vrp;
cvf::Vec3d up;
camera->toLookAt( &eye, &vrp, &up );
QVariant eyeVariant = caf::PdmValueFieldSpecialization<cvf::Vec3d>::convert( eye );
settings.setValue( RicStoreUserDefinedCameraFeature::eyeName(), eyeVariant );
QVariant vrpVariant = caf::PdmValueFieldSpecialization<cvf::Vec3d>::convert( vrp );
settings.setValue( RicStoreUserDefinedCameraFeature::viewReferencePointName(), vrpVariant );
QVariant upVariant = caf::PdmValueFieldSpecialization<cvf::Vec3d>::convert( up );
settings.setValue( RicStoreUserDefinedCameraFeature::upName(), upVariant );
RiuMainWindow::instance()->refreshViewActions();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicStoreUserDefinedCameraFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setText( "Store User Defined View" );
actionToSetup->setIcon( QIcon( ":/user-defined-view.svg" ) );
}

View File

@ -0,0 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
namespace cvf
{
class Camera;
};
//==================================================================================================
///
//==================================================================================================
class RicStoreUserDefinedCameraFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
static QString groupName();
static QString eyeName();
static QString viewReferencePointName();
static QString upName();
static cvf::Camera* activeCamera();
protected:
bool isCommandEnabled() const override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -60,6 +60,7 @@ set(COMMAND_REFERENCED_CMAKE_FILES
PolygonCommands/CMakeLists_files.cmake
Sumo/CMakeLists_files.cmake
ToolCommands/CMakeLists_files.cmake
3dView/CMakeLists_files.cmake
)
# Include source file lists from *.cmake files

View File

@ -406,13 +406,13 @@ void RiuMainWindow::createActions()
m_viewFromWest->setToolTip( "Look East (Ctrl+Alt+E)" );
caf::CmdFeature::applyShortcutWithHintToAction( m_viewFromWest, QKeySequence( tr( "Ctrl+Alt+E" ) ) );
m_viewFromAbove = new QAction( QIcon( ":/DownView.svg" ), "Look Down", this );
m_viewFromAbove->setToolTip( "Look Down (Ctrl+Alt+D)" );
caf::CmdFeature::applyShortcutWithHintToAction( m_viewFromAbove, QKeySequence( tr( "Ctrl+Alt+D" ) ) );
m_viewFromAbove = new QAction( QIcon( ":/DownView.svg" ), "Top View", this );
m_viewFromAbove->setToolTip( "Top View (Ctrl+Alt+T)" );
caf::CmdFeature::applyShortcutWithHintToAction( m_viewFromAbove, QKeySequence( tr( "Ctrl+Alt+T" ) ) );
m_viewFromBelow = new QAction( QIcon( ":/UpView.svg" ), "Look Up", this );
m_viewFromBelow->setToolTip( "Look Up (Ctrl+Alt+U)" );
caf::CmdFeature::applyShortcutWithHintToAction( m_viewFromBelow, QKeySequence( tr( "Ctrl+Alt+U" ) ) );
m_viewFromBelow = new QAction( QIcon( ":/UpView.svg" ), "Bottom View", this );
m_viewFromBelow->setToolTip( "Bottom View (Ctrl+Alt+B)" );
caf::CmdFeature::applyShortcutWithHintToAction( m_viewFromBelow, QKeySequence( tr( "Ctrl+Alt+B" ) ) );
connect( m_viewFromNorth, SIGNAL( triggered() ), SLOT( slotViewFromNorth() ) );
connect( m_viewFromSouth, SIGNAL( triggered() ), SLOT( slotViewFromSouth() ) );
@ -532,6 +532,9 @@ void RiuMainWindow::createMenus()
viewMenu->addAction( m_viewFromEast );
viewMenu->addAction( m_viewFromBelow );
viewMenu->addAction( m_viewFromAbove );
viewMenu->addSeparator();
viewMenu->addAction( cmdFeatureMgr->action( "RicApplyUserDefinedCameraFeature" ) );
viewMenu->addAction( cmdFeatureMgr->action( "RicStoreUserDefinedCameraFeature" ) );
connect( viewMenu, SIGNAL( aboutToShow() ), SLOT( slotRefreshViewActions() ) );
@ -640,6 +643,7 @@ void RiuMainWindow::createToolBars()
toolbar->addAction( m_viewFromWest );
toolbar->addAction( m_viewFromAbove );
toolbar->addAction( m_viewFromBelow );
toolbar->addAction( cmdFeatureMgr->action( "RicApplyUserDefinedCameraFeature" ) );
QLabel* scaleLabel = new QLabel( toolbar );
scaleLabel->setText( "Scale" );
@ -968,7 +972,9 @@ void RiuMainWindow::slotRefreshViewActions()
commandIds << "RicLinkVisibleViewsFeature"
<< "RicTileWindowsFeature"
<< "RicTogglePerspectiveViewFeature"
<< "RicViewZoomAllFeature";
<< "RicViewZoomAllFeature"
<< "RicApplyUserDefinedCameraFeature"
<< "RicStoreUserDefinedCameraFeature";
caf::CmdFeatureManager::instance()->refreshEnabledState( commandIds );
}