diff --git a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake index 2b8c567426..9e8e867fcf 100644 --- a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake @@ -3,6 +3,7 @@ set (SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicImportWellPaths.h ${CMAKE_CURRENT_LIST_DIR}/RicImportGroupedWellPaths.h ${CMAKE_CURRENT_LIST_DIR}/RicToggleWellPathGrouping.h +${CMAKE_CURRENT_LIST_DIR}/RicAutomaticWellPathGrouping.h ${CMAKE_CURRENT_LIST_DIR}/RicNewEditableWellPathFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicShowWellPlanFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathListTargetFeature.h @@ -32,6 +33,7 @@ set (SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicImportWellPaths.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportGroupedWellPaths.cpp ${CMAKE_CURRENT_LIST_DIR}/RicToggleWellPathGrouping.cpp +${CMAKE_CURRENT_LIST_DIR}/RicAutomaticWellPathGrouping.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewEditableWellPathFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicShowWellPlanFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathListTargetFeature.cpp diff --git a/ApplicationCode/Commands/WellPathCommands/RicAutomaticWellPathGrouping.cpp b/ApplicationCode/Commands/WellPathCommands/RicAutomaticWellPathGrouping.cpp new file mode 100644 index 0000000000..8c4ab814f2 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicAutomaticWellPathGrouping.cpp @@ -0,0 +1,121 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RicAutomaticWellPathGrouping.h" + +#include "RigWellPath.h" + +#include "RimOilField.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellPathGroup.h" + +#include "cafPdmFieldScriptingCapability.h" +#include "cafSelectionManager.h" + +#include + +RICF_SOURCE_INIT( RicAutomaticWellPathGrouping, "RicAutomaticWellPathGroupingFeature", "autoGroupWellPaths" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicAutomaticWellPathGrouping::RicAutomaticWellPathGrouping() +{ + CAF_PDM_InitScriptableFieldNoDefault( &m_wellPaths, "wellPaths", "", "", "", "" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmScriptResponse RicAutomaticWellPathGrouping::execute() +{ + caf::PdmScriptResponse response; + + auto wellPaths = m_wellPaths.ptrReferencedObjects(); + if ( wellPaths.empty() ) + { + return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_WARNING, "No well paths provided" ); + } + + RimProject* project = RimProject::current(); + + if ( project ) + { + project->scheduleCreateDisplayModelAndRedrawAllViews(); + RimOilField* oilField = project->activeOilField(); + + if ( oilField ) + { + oilField->wellPathCollection->groupWellPaths( wellPaths, true ); + return caf::PdmScriptResponse(); + } + } + return caf::PdmScriptResponse( caf::PdmScriptResponse::COMMAND_ERROR, "No project open" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicAutomaticWellPathGrouping::isCommandEnabled() +{ + return !selectedWellPaths().empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAutomaticWellPathGrouping::onActionTriggered( bool isChecked ) +{ + m_wellPaths.setValue( selectedWellPaths() ); + execute(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAutomaticWellPathGrouping::setupActionLook( QAction* actionToSetup ) +{ + auto wellPathCollection = caf::SelectionManager::instance()->selectedItemOfType(); + if ( wellPathCollection ) + { + actionToSetup->setText( "Automatically Group All Well Paths" ); + actionToSetup->setIcon( QIcon( ":/WellPathGroup.svg" ) ); + } + else + { + actionToSetup->setText( "Automatically Group Selected Well Paths" ); + actionToSetup->setIcon( QIcon( ":/WellPathGroup.svg" ) ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicAutomaticWellPathGrouping::selectedWellPaths() +{ + auto wellPathCollection = caf::SelectionManager::instance()->selectedItemOfType(); + if ( wellPathCollection ) + { + return wellPathCollection->allWellPaths(); + } + + std::vector wellPaths; + caf::SelectionManager::instance()->objectsByTypeStrict( &wellPaths ); + return wellPaths; +} diff --git a/ApplicationCode/Commands/WellPathCommands/RicAutomaticWellPathGrouping.h b/ApplicationCode/Commands/WellPathCommands/RicAutomaticWellPathGrouping.h new file mode 100644 index 0000000000..1f531b32d7 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicAutomaticWellPathGrouping.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "CommandFileInterface/Core/RicfCommandObject.h" + +#include "cafCmdFeature.h" +#include "cafPdmField.h" +#include "cafPdmPtrArrayField.h" + +#include + +class RimWellPath; + +//================================================================================================== +/// +//================================================================================================== +class RicAutomaticWellPathGrouping : public caf::CmdFeature, public RicfCommandObject +{ + RICF_HEADER_INIT; + +public: + RicAutomaticWellPathGrouping(); + caf::PdmScriptResponse execute() override; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; + + static std::vector selectedWellPaths(); + +protected: + caf::PdmPtrArrayField m_wellPaths; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicToggleWellPathGrouping.cpp b/ApplicationCode/Commands/WellPathCommands/RicToggleWellPathGrouping.cpp index ec6dce00f9..ef0c583e96 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicToggleWellPathGrouping.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicToggleWellPathGrouping.cpp @@ -128,7 +128,7 @@ void RicToggleWellPathGrouping::setupActionLook( QAction* actionToSetup ) auto wellPaths = selectedWellPaths(); if ( containsUngroupedWellPathsWithCommonGeometry( wellPaths ) ) { - actionToSetup->setText( "Group the selected well paths into a Well Tree" ); + actionToSetup->setText( "Group the selected well paths" ); actionToSetup->setIcon( QIcon( ":/WellPathGroup.svg" ) ); } else if ( containsGroupedWellPaths( wellPaths ) ) diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index b03269a01a..9703d7ca77 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -1164,6 +1164,12 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicToggleWellPathGroupingFeature"; } + if ( caf::CmdFeatureManager::instance()->getCommandFeature( "RicAutomaticWellPathGroupingFeature" )->canFeatureBeExecuted() ) + { + menuBuilder << "Separator"; + menuBuilder << "RicAutomaticWellPathGroupingFeature"; + } + if ( caf::CmdFeatureManager::instance()->getCommandFeature( "RicDeleteItemFeature" )->canFeatureBeExecuted() ) { menuBuilder << "Separator"; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index b1efce8259..ad0e98bc7a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -409,11 +409,13 @@ void RimWellPathCollection::readAndAddWellPaths( std::vector& { wellPath->setWellPathColor( RiaColorTables::wellPathsPaletteColors().cycledColor3f( m_wellPaths.size() ) ); wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) ); - addWellPath( wellPath, importGrouped ); + addWellPath( wellPath, false ); } progress.incrementProgress(); } + groupWellPaths( allWellPaths(), true ); + wellPathArray.clear(); // This should not be used again. We may have deleted items this->sortWellsByName(); } @@ -651,18 +653,39 @@ void RimWellPathCollection::deleteAllWellPaths() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathCollection::groupWellPaths( const std::vector& wellPaths ) +void RimWellPathCollection::groupWellPaths( const std::vector& wellPaths, bool allowAddingToExistingGroups ) { - auto detachedWellPaths = detachWellPaths( wellPaths ); - std::vector allWellPathsToGroupWith = detachedWellPaths; + auto detachedWellPaths = detachWellPaths( wellPaths ); + + if ( allowAddingToExistingGroups ) + { + for ( auto wellPath : allWellPaths() ) + { + if ( dynamic_cast( wellPath ) ) + { + auto existingGroupPaths = detachWellPaths( {wellPath} ); + detachedWellPaths.insert( detachedWellPaths.end(), existingGroupPaths.begin(), existingGroupPaths.end() ); + } + } + } + + auto wellPathsToGroupWith = detachedWellPaths; for ( auto wellPath : detachedWellPaths ) { - auto parentGroup = findOrCreateWellPathGroup( wellPath, allWellPathsToGroupWith ); - if ( parentGroup && std::find( allWellPathsToGroupWith.begin(), allWellPathsToGroupWith.end(), parentGroup ) == - allWellPathsToGroupWith.end() ) + auto parentGroup = findOrCreateWellPathGroup( wellPath, wellPathsToGroupWith ); + if ( parentGroup ) { - allWellPathsToGroupWith.push_back( parentGroup ); + auto groupIsNew = std::find( wellPathsToGroupWith.begin(), wellPathsToGroupWith.end(), parentGroup ) == + wellPathsToGroupWith.end(); + if ( groupIsNew ) + { + wellPathsToGroupWith.push_back( parentGroup ); + } + } + else + { + m_wellPaths.push_back( wellPath ); } } this->sortWellsByName(); @@ -737,7 +760,7 @@ void RimWellPathCollection::reloadAllWellPathFormations() //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::removeWellPath( gsl::not_null wellPath ) { - bool removed = detachWellPath( wellPath ); + detachWellPath( wellPath ); RimFileWellPath* fileWellPath = dynamic_cast( wellPath.get() ); if ( fileWellPath ) @@ -843,7 +866,7 @@ RimWellPathGroup* RimWellPathCollection::findOrCreateWellPathGroup( gsl::not_nul detachWellPath( wellPath ); mostSimilarWellPathGroup->addChildWellPath( wellPath.get() ); } - else if ( !wellPathsWithCommonGeometry.empty() ) + else if ( wellPathsWithCommonGeometry.size() > 1u ) { RimWellPathGroup* group = new RimWellPathGroup; m_wellPaths.push_back( group ); diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h index 536d59d895..ac16b7f740 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h @@ -99,7 +99,7 @@ public: void removeWellPath( gsl::not_null wellPath ); void deleteAllWellPaths(); - void groupWellPaths( const std::vector& wellPaths ); + void groupWellPaths( const std::vector& wellPaths, bool allowAddingToExistingGroups = false ); void ungroupWellPaths( const std::vector& wellPaths ); RimWellPath* mostRecentlyUpdatedWellPath();