From fc43c42f1026ca9466d71d8377ce1b726ca29512 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Tue, 14 Jan 2020 14:04:01 +0100 Subject: [PATCH] #5111 Add command to reload well measurements from file --- .../Commands/CMakeLists_files.cmake | 4 + .../RicReloadWellMeasurementsFeature.cpp | 65 +++++++ .../RicReloadWellMeasurementsFeature.h | 31 ++++ .../RicWellMeasurementImportTools.cpp | 163 ++++++++++++++++++ .../Commands/RicWellMeasurementImportTools.h | 44 +++++ .../RicImportWellMeasurementsFeature.cpp | 96 +---------- .../RicImportWellMeasurementsFeature.h | 5 - .../RimContextCommandBuilder.cpp | 1 + 8 files changed, 312 insertions(+), 97 deletions(-) create mode 100644 ApplicationCode/Commands/RicReloadWellMeasurementsFeature.cpp create mode 100644 ApplicationCode/Commands/RicReloadWellMeasurementsFeature.h create mode 100644 ApplicationCode/Commands/RicWellMeasurementImportTools.cpp create mode 100644 ApplicationCode/Commands/RicWellMeasurementImportTools.h diff --git a/ApplicationCode/Commands/CMakeLists_files.cmake b/ApplicationCode/Commands/CMakeLists_files.cmake index e7309f18d7..43f9618bed 100644 --- a/ApplicationCode/Commands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CMakeLists_files.cmake @@ -61,6 +61,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicDeleteItemFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicDeleteSubItemsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicDeleteSummaryCaseCollectionFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellMeasurementFilePathFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicReloadWellMeasurementsFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicWellMeasurementImportTools.h ${CMAKE_CURRENT_LIST_DIR}/RicCloseSourSimDataFeature.h @@ -149,6 +151,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicDeleteItemFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicDeleteSubItemsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicDeleteSummaryCaseCollectionFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellMeasurementFilePathFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicReloadWellMeasurementsFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicWellMeasurementImportTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RicCloseSourSimDataFeature.cpp diff --git a/ApplicationCode/Commands/RicReloadWellMeasurementsFeature.cpp b/ApplicationCode/Commands/RicReloadWellMeasurementsFeature.cpp new file mode 100644 index 0000000000..c538c6d21e --- /dev/null +++ b/ApplicationCode/Commands/RicReloadWellMeasurementsFeature.cpp @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicReloadWellMeasurementsFeature.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RimWellMeasurementFilePath.h" + +#include "RicWellMeasurementImportTools.h" + +#include "cafPdmObject.h" +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT( RicReloadWellMeasurementsFeature, "RicReloadWellMeasurementsFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicReloadWellMeasurementsFeature::isCommandEnabled() +{ + std::vector filePaths; + caf::SelectionManager::instance()->objectsByType( &filePaths ); + return !filePaths.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicReloadWellMeasurementsFeature::onActionTriggered( bool isChecked ) +{ + std::vector filePaths; + caf::SelectionManager::instance()->objectsByType( &filePaths ); + if ( filePaths.empty() ) return; + + RicWellMeasurementImportTools::removeWellMeasurementsFromFiles( filePaths ); + RicWellMeasurementImportTools::importWellMeasurementsFromFiles( filePaths ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicReloadWellMeasurementsFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setText( "Reload" ); + actionToSetup->setIcon( QIcon( ":/Refresh-32.png" ) ); +} diff --git a/ApplicationCode/Commands/RicReloadWellMeasurementsFeature.h b/ApplicationCode/Commands/RicReloadWellMeasurementsFeature.h new file mode 100644 index 0000000000..145d45edcd --- /dev/null +++ b/ApplicationCode/Commands/RicReloadWellMeasurementsFeature.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RicReloadWellMeasurementsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/RicWellMeasurementImportTools.cpp b/ApplicationCode/Commands/RicWellMeasurementImportTools.cpp new file mode 100644 index 0000000000..977dc73a21 --- /dev/null +++ b/ApplicationCode/Commands/RicWellMeasurementImportTools.cpp @@ -0,0 +1,163 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellMeasurementImportTools.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "Rim3dView.h" +#include "RimGridView.h" +#include "RimProject.h" +#include "RimWellMeasurement.h" +#include "RimWellMeasurementCollection.h" +#include "RimWellMeasurementFilePath.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "RifFileParseTools.h" +#include "RifWellMeasurementReader.h" + +#include "Riu3DMainWindowTools.h" +#include "Riu3dSelectionManager.h" + +#include "cafSelectionManager.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellMeasurementImportTools::importWellMeasurementsFromFiles( const std::vector& filePaths ) +{ + if ( filePaths.empty() ) return; + + QStringList files; + for ( RimWellMeasurementFilePath* filePath : filePaths ) + { + files.append( filePath->filePath() ); + } + + // This assumes that the filepaths have the same well path collection + RimWellPathCollection* wellPathCollection = nullptr; + filePaths[0]->firstAncestorOrThisOfType( wellPathCollection ); + if ( wellPathCollection ) + { + importWellMeasurementsFromFiles( files, wellPathCollection ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellMeasurementImportTools::importWellMeasurementsFromFiles( const QStringList& filePaths, + RimWellPathCollection* wellPathCollection ) +{ + std::vector wellMeasurements; + try + { + RifWellMeasurementReader::readWellMeasurements( wellMeasurements, filePaths ); + } + catch ( FileParseException& exception ) + { + RiaLogging::warning( QString( "Well measurement import failed: '%1'." ).arg( exception.message ) ); + return; + } + + RimWellMeasurement* lastWellMeasurement = nullptr; + for ( auto& measurement : wellMeasurements ) + { + RimWellMeasurement* wellMeasurement = new RimWellMeasurement; + wellMeasurement->setWellName( measurement.wellName ); + wellMeasurement->setMD( measurement.MD ); + wellMeasurement->setValue( measurement.value ); + wellMeasurement->setDate( measurement.date ); + wellMeasurement->setQuality( measurement.quality ); + wellMeasurement->setKind( measurement.kind ); + wellMeasurement->setRemark( measurement.remark ); + wellMeasurement->setFilePath( measurement.filePath ); + + // Ignore values for kinds which is known to not have values + if ( !RimWellMeasurement::kindHasValue( measurement.kind ) ) + { + wellMeasurement->setValue( 0.0 ); + } + + wellPathCollection->measurementCollection()->appendMeasurement( wellMeasurement ); + lastWellMeasurement = wellMeasurement; + } + wellPathCollection->uiCapability()->updateConnectedEditors(); + + RiaApplication* app = RiaApplication::instance(); + if ( app->project() ) + { + std::vector views; + app->project()->allViews( views ); + for ( auto& view : views ) + { + RimGridView* gridView = dynamic_cast( view ); + if ( gridView ) + { + gridView->updateWellMeasurements(); + } + } + + app->project()->scheduleCreateDisplayModelAndRedrawAllViews(); + } + + if ( lastWellMeasurement ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastWellMeasurement ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellMeasurementImportTools::removeWellMeasurementsFromFiles( const std::vector& filePaths ) +{ + for ( RimWellMeasurementFilePath* filePath : filePaths ) + { + RimWellMeasurementCollection* wellMeasurementCollection = nullptr; + filePath->firstAncestorOrThisOfType( wellMeasurementCollection ); + if ( wellMeasurementCollection ) + { + wellMeasurementCollection->removeMeasurementsForFilePath( filePath ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathCollection* RicWellMeasurementImportTools::selectedWellPathCollection() +{ + std::vector objects; + caf::SelectionManager::instance()->objectsByType( &objects ); + + if ( objects.size() == 1 ) + { + return objects[0]; + } + + auto measurementColl = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + if ( measurementColl ) + { + return caf::SelectionManager::instance()->selectedItemAncestorOfType(); + } + + return nullptr; +} diff --git a/ApplicationCode/Commands/RicWellMeasurementImportTools.h b/ApplicationCode/Commands/RicWellMeasurementImportTools.h new file mode 100644 index 0000000000..f4337eeb50 --- /dev/null +++ b/ApplicationCode/Commands/RicWellMeasurementImportTools.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2020- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +#include + +class RimWellPathCollection; +class RimWellMeasurementFilePath; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RicWellMeasurementImportTools +{ +public: + static void importWellMeasurementsFromFiles( const std::vector& filePaths ); + static void removeWellMeasurementsFromFiles( const std::vector& filePaths ); + + static void importWellMeasurementsFromFiles( const QStringList& filePaths, RimWellPathCollection* wellPathCollection ); + + static RimWellPathCollection* selectedWellPathCollection(); + +private: + // Hidden to avoid instantiation + RicWellMeasurementImportTools(); +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.cpp index 4e2a51a5fa..5b5a57be27 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.cpp @@ -19,25 +19,13 @@ #include "RicImportWellMeasurementsFeature.h" #include "RiaApplication.h" -#include "RiaLogging.h" -#include "Rim3dView.h" -#include "RimGridView.h" -#include "RimPerforationCollection.h" -#include "RimPerforationInterval.h" -#include "RimProject.h" -#include "RimWellMeasurement.h" -#include "RimWellMeasurementCollection.h" -#include "RimWellPath.h" #include "RimWellPathCollection.h" -#include "RifFileParseTools.h" -#include "RifWellMeasurementReader.h" +#include "RicWellMeasurementImportTools.h" #include "Riu3DMainWindowTools.h" -#include "cafSelectionManager.h" - #include #include @@ -48,7 +36,7 @@ CAF_CMD_SOURCE_INIT( RicImportWellMeasurementsFeature, "RicImportWellMeasurement //-------------------------------------------------------------------------------------------------- bool RicImportWellMeasurementsFeature::isCommandEnabled() { - return ( RicImportWellMeasurementsFeature::selectedWellPathCollection() != nullptr ); + return ( RicWellMeasurementImportTools::selectedWellPathCollection() != nullptr ); } //-------------------------------------------------------------------------------------------------- @@ -56,7 +44,7 @@ bool RicImportWellMeasurementsFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicImportWellMeasurementsFeature::onActionTriggered( bool isChecked ) { - RimWellPathCollection* wellPathCollection = RicImportWellMeasurementsFeature::selectedWellPathCollection(); + RimWellPathCollection* wellPathCollection = RicWellMeasurementImportTools::selectedWellPathCollection(); CVF_ASSERT( wellPathCollection ); // Open dialog box to select well path files @@ -72,61 +60,7 @@ void RicImportWellMeasurementsFeature::onActionTriggered( bool isChecked ) // Remember the path to next time app->setLastUsedDialogDirectory( "WELLPATH_DIR", QFileInfo( wellPathFilePaths.last() ).absolutePath() ); - std::vector wellMeasurements; - try - { - RifWellMeasurementReader::readWellMeasurements( wellMeasurements, wellPathFilePaths ); - } - catch ( FileParseException& exception ) - { - RiaLogging::warning( QString( "Well measurement import failed: '%1'." ).arg( exception.message ) ); - return; - } - - RimWellMeasurement* lastWellMeasurement = nullptr; - for ( auto& measurement : wellMeasurements ) - { - RimWellMeasurement* wellMeasurement = new RimWellMeasurement; - wellMeasurement->setWellName( measurement.wellName ); - wellMeasurement->setMD( measurement.MD ); - wellMeasurement->setValue( measurement.value ); - wellMeasurement->setDate( measurement.date ); - wellMeasurement->setQuality( measurement.quality ); - wellMeasurement->setKind( measurement.kind ); - wellMeasurement->setRemark( measurement.remark ); - wellMeasurement->setFilePath( measurement.filePath ); - - // Ignore values for kinds which is known to not have values - if ( !RimWellMeasurement::kindHasValue( measurement.kind ) ) - { - wellMeasurement->setValue( 0.0 ); - } - - wellPathCollection->measurementCollection()->appendMeasurement( wellMeasurement ); - lastWellMeasurement = wellMeasurement; - } - wellPathCollection->uiCapability()->updateConnectedEditors(); - - if ( app->project() ) - { - std::vector views; - app->project()->allViews( views ); - for ( auto& view : views ) - { - RimGridView* gridView = dynamic_cast( view ); - if ( gridView ) - { - gridView->updateWellMeasurements(); - } - } - - app->project()->scheduleCreateDisplayModelAndRedrawAllViews(); - } - - if ( lastWellMeasurement ) - { - Riu3DMainWindowTools::selectAsCurrentItem( lastWellMeasurement ); - } + RicWellMeasurementImportTools::importWellMeasurementsFromFiles( wellPathFilePaths, wellPathCollection ); } //-------------------------------------------------------------------------------------------------- @@ -136,25 +70,3 @@ void RicImportWellMeasurementsFeature::setupActionLook( QAction* actionToSetup ) { actionToSetup->setText( "Import Measurements" ); } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPathCollection* RicImportWellMeasurementsFeature::selectedWellPathCollection() -{ - std::vector objects; - caf::SelectionManager::instance()->objectsByType( &objects ); - - if ( objects.size() == 1 ) - { - return objects[0]; - } - - auto measurementColl = caf::SelectionManager::instance()->selectedItemAncestorOfType(); - if ( measurementColl ) - { - return caf::SelectionManager::instance()->selectedItemAncestorOfType(); - } - - return nullptr; -} diff --git a/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.h b/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.h index d4776c1ac4..a73e0dc463 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.h +++ b/ApplicationCode/Commands/WellPathCommands/RicImportWellMeasurementsFeature.h @@ -20,8 +20,6 @@ #include "cafCmdFeature.h" -class RimWellPathCollection; - //================================================================================================== /// //================================================================================================== @@ -34,7 +32,4 @@ protected: bool isCommandEnabled() override; void onActionTriggered( bool isChecked ) override; void setupActionLook( QAction* actionToSetup ) override; - -private: - static RimWellPathCollection* selectedWellPathCollection(); }; diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index 26d45f08e1..cbba896492 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -330,6 +330,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() } else if ( dynamic_cast( firstUiItem ) ) { + menuBuilder << "RicReloadWellMeasurementsFeature"; menuBuilder << "RicDeleteWellMeasurementFilePathFeature"; menuBuilder << "RicImportWellMeasurementsFeature"; }