diff --git a/ApplicationLibCode/Commands/EclipseCommands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/EclipseCommands/CMakeLists_files.cmake index c2c13c30694..b829a338142 100644 --- a/ApplicationLibCode/Commands/EclipseCommands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/EclipseCommands/CMakeLists_files.cmake @@ -21,6 +21,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicRenameCaseFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportRoffCaseFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicAddGridCalculationFeature.h + ${CMAKE_CURRENT_LIST_DIR}/RicCreateGridCaseEnsemblesFromFilesFeature.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -46,6 +47,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicRenameCaseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportRoffCaseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicAddGridCalculationFeature.cpp + ${CMAKE_CURRENT_LIST_DIR}/RicCreateGridCaseEnsemblesFromFilesFeature.cpp ) list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp b/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp new file mode 100644 index 00000000000..2c5c4e81df5 --- /dev/null +++ b/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.cpp @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 "RicCreateGridCaseEnsemblesFromFilesFeature.h" + +#include "RiaApplication.h" +#include "RiaImportEclipseCaseTools.h" + +#include "RicCreateGridCaseGroupFromFilesFeature.h" +#include "RicRecursiveFileSearchDialog.h" + +#include "RimEclipseCaseCollection.h" +#include "RimEclipseCaseEnsemble.h" +#include "RimEclipseResultCase.h" + +#include "RimOilField.h" +#include "RimProject.h" +#include "cafProgressInfo.h" +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT( RicCreateGridCaseEnsemblesFromFilesFeature, "RicCreateGridCaseEnsemblesFromFilesFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateGridCaseEnsemblesFromFilesFeature::onActionTriggered( bool isChecked ) +{ + QString pathCacheName = "INPUT_FILES"; + auto [fileNames, groupByEnsemble] = runRecursiveFileSearchDialog( "Import Grid Ensembles", pathCacheName ); + + if ( groupByEnsemble == RiaEnsembleNameTools::EnsembleGroupingMode::NONE ) + { + importSingleGridCaseEnsemble( fileNames ); + } + else + { + std::vector groupedByEnsemble = RiaEnsembleNameTools::groupFilesByEnsemble( fileNames, groupByEnsemble ); + for ( const QStringList& groupedFileNames : groupedByEnsemble ) + { + importSingleGridCaseEnsemble( groupedFileNames ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateGridCaseEnsemblesFromFilesFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setIcon( QIcon( ":/CreateGridCaseGroup16x16.png" ) ); + actionToSetup->setText( "&Create Grid Case Ensembles" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateGridCaseEnsemblesFromFilesFeature::importSingleGridCaseEnsemble( const QStringList& fileNames ) +{ + auto eclipseCaseEnsemble = new RimEclipseCaseEnsemble; + QString ensembleNameSuggestion = + RiaEnsembleNameTools::findSuitableEnsembleName( fileNames, RiaEnsembleNameTools::EnsembleGroupingMode::FMU_FOLDER_STRUCTURE ); + eclipseCaseEnsemble->setName( ensembleNameSuggestion ); + + caf::ProgressInfo progInfo( fileNames.size() + 1, "Creating Grid Ensembles" ); + + RimProject* project = RimProject::current(); + CVF_ASSERT( project ); + + RimOilField* oilfield = project->activeOilField(); + if ( !oilfield ) return; + + for ( auto caseFileName : fileNames ) + { + auto task = progInfo.task( "Loading files", 1 ); + + QFileInfo gridFileName( caseFileName ); + + QString caseName = gridFileName.completeBaseName(); + + auto* rimResultReservoir = new RimEclipseResultCase(); + rimResultReservoir->setCaseInfo( caseName, caseFileName ); + eclipseCaseEnsemble->addCase( rimResultReservoir ); + } + + oilfield->analysisModels()->caseEnsembles.push_back( eclipseCaseEnsemble ); + oilfield->analysisModels()->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair + RicCreateGridCaseEnsemblesFromFilesFeature::runRecursiveFileSearchDialog( const QString& dialogTitle, const QString& pathCacheName ) +{ + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->lastUsedDialogDirectory( pathCacheName ); + + RicRecursiveFileSearchDialogResult result = + RicRecursiveFileSearchDialog::runRecursiveSearchDialog( nullptr, + dialogTitle, + defaultDir, + m_pathFilter, + m_fileNameFilter, + { RicRecursiveFileSearchDialog::FileType::EGRID } ); + + // Remember filters + m_pathFilter = result.pathFilter; + m_fileNameFilter = result.fileNameFilter; + + if ( !result.ok ) return std::make_pair( QStringList(), RiaEnsembleNameTools::EnsembleGroupingMode::NONE ); + + // Remember the path to next time + app->setLastUsedDialogDirectory( pathCacheName, QFileInfo( result.rootDir ).absoluteFilePath() ); + + return std::make_pair( result.files, result.groupingMode ); +} diff --git a/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.h b/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.h new file mode 100644 index 00000000000..a32681e5488 --- /dev/null +++ b/ApplicationLibCode/Commands/EclipseCommands/RicCreateGridCaseEnsemblesFromFilesFeature.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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" + +#include "RiaEnsembleNameTools.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicCreateGridCaseEnsemblesFromFilesFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + + RicCreateGridCaseEnsemblesFromFilesFeature() + : m_pathFilter( "*" ) + , m_fileNameFilter( "*" ) + { + } + +protected: + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; + + void importSingleGridCaseEnsemble( const QStringList& fileNames ); + std::pair runRecursiveFileSearchDialog( const QString& dialogTitle, + const QString& pathCacheName ); + +private: + QString m_pathFilter; + QString m_fileNameFilter; +}; diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index d0367832393..32e4f3a61f3 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -226,6 +226,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicImportEclipseCasesFeature"; menuBuilder << "RicImportInputEclipseCaseFeature"; menuBuilder << "RicCreateGridCaseGroupFromFilesFeature"; + menuBuilder << "RicCreateGridCaseEnsemblesFromFilesFeature"; menuBuilder.subMenuEnd(); menuBuilder << "RicEclipseCaseNewGroupFeature"; }