From 4bf438e473f2302780df8f2d176896344b344e27 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 15 Mar 2024 09:32:45 +0100 Subject: [PATCH 1/6] Refactor connection between cases and views. Eclipse grid views and contour maps are not longer a child of the case. The views are not separate collections (one for grid and one for contour maps) on root level. --- .../RicNewCellIndexFilterFeature.cpp | 11 +- .../RicNewPolygonFilterFeature.cpp | 10 +- .../RicNewRangeFilterSliceFeature.cpp | 15 +- .../RicNewUserDefinedFilterFeature.cpp | 13 +- .../RicNewUserDefinedIndexFilterFeature.cpp | 12 +- .../RicNewAzimuthDipIntersectionFeature.cpp | 6 +- .../RicAdvancedSnapshotExportFeature.cpp | 22 ++- .../RicAdvancedSnapshotExportFeature.h | 2 + .../RicPasteCellFiltersFeature.cpp | 19 +-- .../RicPasteEclipseCasesFeature.cpp | 3 +- .../Commands/RicNewContourMapViewFeature.cpp | 29 +++- .../Commands/RicVec3dPickEventHandler.cpp | 5 +- .../ModelVisualization/RivWellPathPartMgr.cpp | 2 +- .../Surfaces/RivSurfacePartMgr.cpp | 9 +- .../RimAnnotationInViewCollection.cpp | 22 +-- .../ProjectDataModel/CMakeLists_files.cmake | 2 + .../CellFilters/RimCellFilter.cpp | 3 +- .../CellFilters/RimCellFilterCollection.cpp | 5 +- .../Flow/RimFlowCharacteristicsPlot.cpp | 6 +- .../Flow/RimWellConnectivityTable.cpp | 2 +- .../GeoMech/RimGeoMechContourMapView.cpp | 6 +- .../GeoMech/RimGeoMechView.cpp | 6 +- .../RimGridCrossPlotDataSet.cpp | 2 +- .../Intersections/RimBoxIntersection.cpp | 2 +- .../RimIntersectionCollection.cpp | 2 +- ...ntersectionResultsDefinitionCollection.cpp | 9 +- .../Rim2dIntersectionView.cpp | 2 +- .../Rim3dOverlayInfoConfig.cpp | 10 +- .../RimAdvancedSnapshotExportDefinition.cpp | 8 +- .../ProjectDataModel/RimEclipseCase.cpp | 154 ++++++++++++------ .../ProjectDataModel/RimEclipseCase.h | 28 ++-- .../RimEclipseContourMapProjection.cpp | 6 +- .../RimEclipseContourMapView.cpp | 6 +- .../RimEclipseContourMapViewCollection.cpp | 16 ++ .../RimEclipseContourMapViewCollection.h | 3 + .../ProjectDataModel/RimEclipseResultCase.cpp | 3 +- .../RimEclipseResultDefinition.cpp | 21 ++- .../RimEclipseStatisticsCase.cpp | 31 ++-- .../RimEclipseStatisticsCaseEvaluator.cpp | 2 +- .../ProjectDataModel/RimEclipseView.cpp | 38 ++--- .../ProjectDataModel/RimEclipseView.h | 4 +- .../RimEclipseViewCollection.cpp | 122 ++++++++++++++ .../RimEclipseViewCollection.h | 49 ++++++ .../RimGridStatisticsPlot.cpp | 6 +- .../ProjectDataModel/RimGridView.cpp | 3 +- .../RimIdenticalGridCaseGroup.cpp | 5 +- .../ProjectDataModel/RimOilField.cpp | 8 + .../ProjectDataModel/RimOilField.h | 32 ++-- .../ProjectDataModel/RimProject.cpp | 4 + .../RimSimWellInViewCollection.cpp | 3 +- .../SocketInterface/RiaNNCCommands.cpp | 17 +- .../RiaPropertyDataCommands.cpp | 34 ++-- .../RiuAdvancedSnapshotExportWidget.cpp | 2 +- GrpcInterface/Python/rips/case.py | 26 ++- GrpcInterface/Python/rips/simulation_well.py | 7 +- GrpcInterface/Python/rips/view.py | 20 ++- GrpcInterface/RiaGrpcNNCPropertiesService.cpp | 17 +- 57 files changed, 626 insertions(+), 286 deletions(-) create mode 100644 ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp create mode 100644 ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.h diff --git a/ApplicationLibCode/Commands/CellFilterCommands/RicNewCellIndexFilterFeature.cpp b/ApplicationLibCode/Commands/CellFilterCommands/RicNewCellIndexFilterFeature.cpp index 95121dd465..88584f7830 100644 --- a/ApplicationLibCode/Commands/CellFilterCommands/RicNewCellIndexFilterFeature.cpp +++ b/ApplicationLibCode/Commands/CellFilterCommands/RicNewCellIndexFilterFeature.cpp @@ -59,12 +59,15 @@ void RicNewCellIndexFilterFeature::onActionTriggered( bool isChecked ) RimCellFilterCollection* filtColl = colls[0]; // and the case to use - RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted(); + RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted()->ownerCase(); - RimCellIndexFilter* lastCreatedOrUpdated = filtColl->addNewCellIndexFilter( sourceCase ); - if ( lastCreatedOrUpdated ) + if ( sourceCase ) { - Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + RimCellIndexFilter* lastCreatedOrUpdated = filtColl->addNewCellIndexFilter( sourceCase ); + if ( lastCreatedOrUpdated ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + } } } diff --git a/ApplicationLibCode/Commands/CellFilterCommands/RicNewPolygonFilterFeature.cpp b/ApplicationLibCode/Commands/CellFilterCommands/RicNewPolygonFilterFeature.cpp index 8ffa493ef8..80a329c593 100644 --- a/ApplicationLibCode/Commands/CellFilterCommands/RicNewPolygonFilterFeature.cpp +++ b/ApplicationLibCode/Commands/CellFilterCommands/RicNewPolygonFilterFeature.cpp @@ -64,11 +64,13 @@ void RicNewPolygonFilterFeature::onActionTriggered( bool isChecked ) } } - auto sourceCase = cellFilterCollection->firstAncestorOrThisOfTypeAsserted(); - - if ( auto lastCreatedOrUpdated = cellFilterCollection->addNewPolygonFilter( sourceCase, polygon ) ) + auto sourceCase = cellFilterCollection->firstAncestorOrThisOfTypeAsserted()->ownerCase(); + if ( sourceCase ) { - Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + if ( auto lastCreatedOrUpdated = cellFilterCollection->addNewPolygonFilter( sourceCase, polygon ) ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + } } } diff --git a/ApplicationLibCode/Commands/CellFilterCommands/RicNewRangeFilterSliceFeature.cpp b/ApplicationLibCode/Commands/CellFilterCommands/RicNewRangeFilterSliceFeature.cpp index 124d299f63..a0d6b7772f 100644 --- a/ApplicationLibCode/Commands/CellFilterCommands/RicNewRangeFilterSliceFeature.cpp +++ b/ApplicationLibCode/Commands/CellFilterCommands/RicNewRangeFilterSliceFeature.cpp @@ -18,9 +18,11 @@ #include "RicNewRangeFilterSliceFeature.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimCellFilterCollection.h" #include "RimCellRangeFilter.h" + #include "Riu3DMainWindowTools.h" #include "cafCmdExecCommandManager.h" @@ -45,13 +47,16 @@ void RicNewRangeFilterSliceFeature::onActionTriggered( bool isChecked ) RimCellFilterCollection* filtColl = colls[0]; // and the case to use - RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted(); + RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted()->ownerCase(); - int gridIndex = 0; - RimCellFilter* lastCreatedOrUpdated = filtColl->addNewCellRangeFilter( sourceCase, gridIndex, m_sliceDirection ); - if ( lastCreatedOrUpdated ) + if ( sourceCase ) { - Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + int gridIndex = 0; + RimCellFilter* lastCreatedOrUpdated = filtColl->addNewCellRangeFilter( sourceCase, gridIndex, m_sliceDirection ); + if ( lastCreatedOrUpdated ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + } } } diff --git a/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedFilterFeature.cpp b/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedFilterFeature.cpp index db2ab3d874..414d96d9d0 100644 --- a/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedFilterFeature.cpp +++ b/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedFilterFeature.cpp @@ -18,9 +18,11 @@ #include "RicNewUserDefinedFilterFeature.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimCellFilterCollection.h" #include "RimUserDefinedFilter.h" + #include "Riu3DMainWindowTools.h" #include "cafSelectionManagerTools.h" @@ -41,12 +43,15 @@ void RicNewUserDefinedFilterFeature::onActionTriggered( bool isChecked ) RimCellFilterCollection* filtColl = colls[0]; // and the case to use - RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted(); + RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted()->ownerCase(); - RimUserDefinedFilter* lastCreatedOrUpdated = filtColl->addNewUserDefinedFilter( sourceCase ); - if ( lastCreatedOrUpdated ) + if ( sourceCase ) { - Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + RimUserDefinedFilter* lastCreatedOrUpdated = filtColl->addNewUserDefinedFilter( sourceCase ); + if ( lastCreatedOrUpdated ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + } } } diff --git a/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedIndexFilterFeature.cpp b/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedIndexFilterFeature.cpp index ec90f7893d..3e41191ae9 100644 --- a/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedIndexFilterFeature.cpp +++ b/ApplicationLibCode/Commands/CellFilterCommands/RicNewUserDefinedIndexFilterFeature.cpp @@ -18,6 +18,7 @@ #include "RicNewUserDefinedIndexFilterFeature.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimCellFilterCollection.h" #include "RimUserDefinedIndexFilter.h" @@ -42,12 +43,15 @@ void RicNewUserDefinedIndexFilterFeature::onActionTriggered( bool isChecked ) RimCellFilterCollection* filtColl = colls[0]; // and the case to use - RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted(); + RimCase* sourceCase = filtColl->firstAncestorOrThisOfTypeAsserted()->ownerCase(); - auto* lastCreatedOrUpdated = filtColl->addNewUserDefinedIndexFilter( sourceCase ); - if ( lastCreatedOrUpdated ) + if ( sourceCase ) { - Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + auto* lastCreatedOrUpdated = filtColl->addNewUserDefinedIndexFilter( sourceCase ); + if ( lastCreatedOrUpdated ) + { + Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated ); + } } } diff --git a/ApplicationLibCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.cpp b/ApplicationLibCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.cpp index 65a2d59a56..e24c88e6e1 100644 --- a/ApplicationLibCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.cpp +++ b/ApplicationLibCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.cpp @@ -103,8 +103,10 @@ void RicNewAzimuthDipIntersectionFeatureCmd::redo() intersection->setName( "Azimuth and Dip" ); intersection->configureForAzimuthLine(); - RimCase* rimCase = m_intersectionCollection->firstAncestorOrThisOfTypeAsserted(); - cvf::BoundingBox bBox = rimCase->allCellsBoundingBox(); + RimCase* rimCase = m_intersectionCollection->firstAncestorOrThisOfTypeAsserted()->ownerCase(); + if ( !rimCase ) return; + + cvf::BoundingBox bBox = rimCase->allCellsBoundingBox(); if ( bBox.isValid() ) { intersection->setLengthUp( cvf::Math::floor( bBox.extent()[2] / 2 ) ); diff --git a/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.cpp index 0a4085f80f..f0951bac66 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.cpp @@ -33,10 +33,12 @@ #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" +#include "RimEclipseViewCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" #include "RimGeoMechResultDefinition.h" #include "RimGeoMechView.h" +#include "RimOilField.h" #include "RimProject.h" #include "RiuAdvancedSnapshotExportWidget.h" @@ -146,7 +148,7 @@ void RicAdvancedSnapshotExportFeature::exportMultipleSnapshots( const QString& f exportViewVariations( copyOfEclipseView, msd, folder ); - eclCase->reservoirViews().removeChild( copyOfEclipseView ); + removeViewFromViewCollection( copyOfEclipseView ); delete copyOfEclipseView; } @@ -207,7 +209,7 @@ void RicAdvancedSnapshotExportFeature::exportViewVariations( Rim3dView* rimView, exportViewVariationsToFolder( copyOfView, msd, folder ); } - eclCase->reservoirViews().removeChild( copyOfView ); + removeViewFromViewCollection( copyOfView ); delete copyOfView; } @@ -338,3 +340,19 @@ QString RicAdvancedSnapshotExportFeature::resultName( Rim3dView* rimView ) return ""; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAdvancedSnapshotExportFeature::removeViewFromViewCollection( RimEclipseView* view ) +{ + RimProject* project = RimProject::current(); + if ( !project ) return; + + RimOilField* oilField = project->activeOilField(); + if ( !oilField ) return; + + RimEclipseViewCollection* viewColl = oilField->eclipseViewCollection(); + if ( !viewColl ) return; + viewColl->removeView( view ); +} diff --git a/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.h b/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.h index 760b714b87..b5a0549b16 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.h +++ b/ApplicationLibCode/Commands/ExportCommands/RicAdvancedSnapshotExportFeature.h @@ -24,6 +24,7 @@ class RimAdvancedSnapshotExportDefinition; class RimProject; class Rim3dView; class RimGridView; +class RimEclipseView; //================================================================================================== /// @@ -45,4 +46,5 @@ class RicAdvancedSnapshotExportFeature : public caf::CmdFeature private: static void exportViewVariationsToFolder( RimGridView* rimView, RimAdvancedSnapshotExportDefinition* msd, const QString& folder ); static QString resultName( Rim3dView* rimView ); + static void removeViewFromViewCollection( RimEclipseView* view ); }; diff --git a/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteCellFiltersFeature.cpp b/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteCellFiltersFeature.cpp index c809985609..d2b68bd085 100644 --- a/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteCellFiltersFeature.cpp +++ b/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteCellFiltersFeature.cpp @@ -20,6 +20,7 @@ #include "RicPasteFeatureImpl.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimCellFilter.h" #include "RimCellFilterCollection.h" @@ -42,17 +43,9 @@ bool RicPasteCellFiltersFeature::isCommandEnabled() const std::vector> typedObjects; objectGroup.objectsByType( &typedObjects ); - if ( typedObjects.empty() ) - { - return false; - } - - if ( dynamic_cast( caf::SelectionManager::instance()->selectedItem() ) ) - { - return true; - } + if ( typedObjects.empty() ) return false; - return false; + return dynamic_cast( caf::SelectionManager::instance()->selectedItem() ) != nullptr; } //-------------------------------------------------------------------------------------------------- @@ -63,7 +56,11 @@ void RicPasteCellFiltersFeature::onActionTriggered( bool isChecked ) auto cellFilterCollection = dynamic_cast( caf::SelectionManager::instance()->selectedItem() ); if ( !cellFilterCollection ) return; - auto eclipseCase = cellFilterCollection->firstAncestorOfType(); + auto view = cellFilterCollection->firstAncestorOfType(); + if ( !view ) return; + + auto eclipseCase = view->ownerCase(); + if ( !eclipseCase ) return; caf::PdmObjectGroup objectGroup; RicPasteFeatureImpl::findObjectsFromClipboardRefs( &objectGroup ); diff --git a/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp b/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp index 72c540ace8..0b94768e3b 100644 --- a/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp +++ b/ApplicationLibCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp @@ -186,9 +186,8 @@ void RicPasteEclipseCasesFeature::addCasesToGridCaseGroup( caf::PdmObjectGroup& gridCaseGroup->updateConnectedEditors(); - for ( size_t rvIdx = 0; rvIdx < rimResultReservoir->reservoirViews.size(); rvIdx++ ) + for ( RimEclipseView* riv : rimResultReservoir->reservoirViews() ) { - RimEclipseView* riv = rimResultReservoir->reservoirViews()[rvIdx]; riv->loadDataAndUpdate(); } } diff --git a/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp b/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp index 55d36360da..c5b496630f 100644 --- a/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp +++ b/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp @@ -24,21 +24,22 @@ #include "Rim3dView.h" #include "RimCellEdgeColors.h" +#include "RimCellFilterCollection.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseContourMapProjection.h" #include "RimEclipseContourMapView.h" #include "RimEclipseContourMapViewCollection.h" #include "RimEclipseView.h" +#include "RimFaultInViewCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" #include "RimGeoMechContourMapView.h" #include "RimGeoMechContourMapViewCollection.h" #include "RimGeoMechView.h" +#include "RimOilField.h" +#include "RimProject.h" #include "RimRegularLegendConfig.h" - -#include "RimCellFilterCollection.h" -#include "RimFaultInViewCollection.h" #include "RimSimWellInViewCollection.h" #include "RimSurfaceInViewCollection.h" @@ -86,7 +87,7 @@ void RicNewContourMapViewFeature::onActionTriggered( bool isChecked ) { RimEclipseView* reservoirView = caf::SelectionManager::instance()->selectedItemOfType(); RimEclipseContourMapView* existingEclipseContourMap = caf::SelectionManager::instance()->selectedItemOfType(); - RimEclipseCase* eclipseCase = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + RimEclipseCase* eclipseCase = caf::SelectionManager::instance()->selectedItemOfType(); RimEclipseContourMapView* eclipseContourMap = nullptr; RimGeoMechView* geoMechView = caf::SelectionManager::instance()->selectedItemOfType(); @@ -97,11 +98,19 @@ void RicNewContourMapViewFeature::onActionTriggered( bool isChecked ) // Find case to insert into if ( existingEclipseContourMap ) { - eclipseContourMap = createEclipseContourMapFromExistingContourMap( eclipseCase, existingEclipseContourMap ); + eclipseCase = existingEclipseContourMap->eclipseCase(); + if ( eclipseCase ) + { + eclipseContourMap = createEclipseContourMapFromExistingContourMap( eclipseCase, existingEclipseContourMap ); + } } else if ( reservoirView ) { - eclipseContourMap = createEclipseContourMapFrom3dView( eclipseCase, reservoirView ); + eclipseCase = reservoirView->eclipseCase(); + if ( eclipseCase ) + { + eclipseContourMap = createEclipseContourMapFrom3dView( eclipseCase, reservoirView ); + } } else if ( eclipseCase ) { @@ -138,6 +147,12 @@ void RicNewContourMapViewFeature::onActionTriggered( bool isChecked ) eclipseContourMap->createDisplayModelAndRedraw(); eclipseContourMap->zoomAll(); + RimProject* project = RimProject::current(); + + RimOilField* oilField = project->activeOilField(); + + oilField->eclipseContourMapCollection()->updateConnectedEditors(); + Riu3DMainWindowTools::setExpanded( eclipseContourMap ); } else if ( geoMechContourMap ) @@ -268,6 +283,8 @@ RimEclipseContourMapView* RicNewContourMapViewFeature::createEclipseContourMapFr contourMap->initAfterReadRecursively(); + eclipseCase->contourMapCollection()->updateConnectedEditors(); + return contourMap; } diff --git a/ApplicationLibCode/Commands/RicVec3dPickEventHandler.cpp b/ApplicationLibCode/Commands/RicVec3dPickEventHandler.cpp index 995f59c40b..652a0e772f 100644 --- a/ApplicationLibCode/Commands/RicVec3dPickEventHandler.cpp +++ b/ApplicationLibCode/Commands/RicVec3dPickEventHandler.cpp @@ -42,10 +42,9 @@ bool RicVec3dPickEventHandler::handle3dPickEvent( const Ric3dPickEvent& eventObj cvf::Vec3d pickedPosition = eventObject.m_pickItemInfos.front().globalPickedPoint(); - RimCase* ownerCase = rimView->firstAncestorOrThisOfType(); - if ( ownerCase ) + if ( rimView->ownerCase() ) { - double zPickOffset = ownerCase->characteristicCellSize() * m_zOffsetFactor; + double zPickOffset = rimView->ownerCase()->characteristicCellSize() * m_zOffsetFactor; pickedPosition.z() += zPickOffset; } diff --git a/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp index 8b84699cb0..97dfdaaf22 100644 --- a/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivWellPathPartMgr.cpp @@ -388,7 +388,7 @@ void RivWellPathPartMgr::appendPerforationsToModel( cvf::ModelBasicList* QDateTime currentTimeStamp; if ( m_rimView ) { - auto rimCase = m_rimView->firstAncestorOrThisOfType(); + auto rimCase = m_rimView->ownerCase(); if ( rimCase ) { diff --git a/ApplicationLibCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp b/ApplicationLibCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp index 36ab921eb7..42d72709e2 100644 --- a/ApplicationLibCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp @@ -382,8 +382,13 @@ void RivSurfacePartMgr::generatePartGeometry() void RivSurfacePartMgr::generateNativePartGeometry() { cvf::Vec3d displayModOffset( 0, 0, 0 ); - auto ownerCase = m_surfaceInView->firstAncestorOrThisOfType(); - if ( ownerCase ) displayModOffset = ownerCase->displayModelOffset(); + + auto view = m_surfaceInView->firstAncestorOrThisOfType(); + if ( view ) + { + auto ownerCase = view->ownerCase(); + if ( ownerCase ) displayModOffset = ownerCase->displayModelOffset(); + } m_usedSurfaceData = m_surfaceInView->surface()->surfaceData(); if ( m_usedSurfaceData.isNull() ) return; diff --git a/ApplicationLibCode/ProjectDataModel/Annotations/RimAnnotationInViewCollection.cpp b/ApplicationLibCode/ProjectDataModel/Annotations/RimAnnotationInViewCollection.cpp index b8234e9da9..55d43e08cd 100644 --- a/ApplicationLibCode/ProjectDataModel/Annotations/RimAnnotationInViewCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Annotations/RimAnnotationInViewCollection.cpp @@ -279,17 +279,19 @@ void RimAnnotationInViewCollection::defineEditorAttribute( const caf::PdmFieldHa if ( attr ) { - auto rimCase = firstAncestorOrThisOfType(); - if ( rimCase ) + if ( auto view = firstAncestorOrThisOfType() ) { - auto bb = rimCase->allCellsBoundingBox(); - attr->m_minimum = -bb.max().z(); - attr->m_maximum = -bb.min().z(); - } - else - { - attr->m_minimum = 0; - attr->m_maximum = 10000; + if ( auto rimCase = view->ownerCase() ) + { + auto bb = rimCase->allCellsBoundingBox(); + attr->m_minimum = -bb.max().z(); + attr->m_maximum = -bb.min().z(); + } + else + { + attr->m_minimum = 0; + attr->m_maximum = 10000; + } } } } diff --git a/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake index d3366768f1..b132ac136d 100644 --- a/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake @@ -134,6 +134,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimResultSelectionUi.h ${CMAKE_CURRENT_LIST_DIR}/RimPlotRectAnnotation.h ${CMAKE_CURRENT_LIST_DIR}/RimEmCase.h + ${CMAKE_CURRENT_LIST_DIR}/RimEclipseViewCollection.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -268,6 +269,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RimPlotRectAnnotation.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEmCase.cpp ${CMAKE_CURRENT_LIST_DIR}/RimPolylinePickerInterface.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimEclipseViewCollection.cpp ) if(RESINSIGHT_USE_QT_CHARTS) diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp index c78d1a630f..691d23a2ed 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp @@ -298,7 +298,8 @@ QString RimCellFilter::modeString() const //-------------------------------------------------------------------------------------------------- const cvf::StructGridInterface* RimCellFilter::selectedGrid() const { - auto rimCase = firstAncestorOrThisOfTypeAsserted(); + auto rimCase = firstAncestorOrThisOfTypeAsserted()->ownerCase(); + if ( !rimCase ) return nullptr; int clampedIndex = gridIndex(); if ( clampedIndex >= RigReservoirGridTools::gridCount( rimCase ) ) diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp index 5fe2bb0774..a2074e16a4 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp @@ -160,7 +160,10 @@ void RimCellFilterCollection::initAfterRead() // Copy by xml serialization does not give a RimCase parent the first time initAfterRead is called here when creating a new a contour // view from a 3d view. The second time we get called it is ok, so just skip setting up the filter connections if we have no case. - auto rimCase = firstAncestorOrThisOfType(); + auto rimView = firstAncestorOrThisOfType(); + if ( rimView == nullptr ) return; + + auto rimCase = rimView->ownerCase(); if ( rimCase == nullptr ) return; for ( const auto& filter : m_cellFilters ) diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp index 805a5dde6e..a22bed1f95 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.cpp @@ -145,7 +145,7 @@ void RimFlowCharacteristicsPlot::setFromFlowSolution( RimFlowDiagSolution* flowS { auto eclCase = flowSolution->firstAncestorOrThisOfType(); m_case = eclCase; - if ( !eclCase->reservoirViews.empty() ) + if ( !eclCase->reservoirViews().empty() ) { m_cellFilterView = eclCase->reservoirViews()[0]; } @@ -399,7 +399,7 @@ void RimFlowCharacteristicsPlot::defineUiOrdering( QString uiConfigName, caf::Pd { m_case = defaultCase; m_flowDiagSolution = m_case->defaultFlowDiagSolution(); - if ( !m_case()->reservoirViews.empty() ) + if ( !m_case()->reservoirViews().empty() ) { m_cellFilterView = m_case()->reservoirViews()[0]; } @@ -506,7 +506,7 @@ void RimFlowCharacteristicsPlot::fieldChangedByUi( const caf::PdmFieldHandle* ch { m_flowDiagSolution = m_case->defaultFlowDiagSolution(); m_currentlyPlottedTimeSteps.clear(); - if ( !m_case()->reservoirViews.empty() ) + if ( !m_case()->reservoirViews().empty() ) { m_cellFilterView = m_case()->reservoirViews()[0]; } diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp index 2788a18535..ff0208564f 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellConnectivityTable.cpp @@ -706,7 +706,7 @@ QList RimWellConnectivityTable::calculateValueOptions( c else if ( fieldNeedingOptions == &m_cellFilterView && m_case() ) { options.push_back( caf::PdmOptionItemInfo( "Disabled", nullptr ) ); - for ( RimEclipseView* view : m_case()->reservoirViews.childrenByType() ) + for ( RimEclipseView* view : m_case()->reservoirViews() ) { CVF_ASSERT( view && "Really always should have a valid view pointer in ReservoirViews" ); options.push_back( caf::PdmOptionItemInfo( view->name(), view, false, view->uiIconProvider() ) ); diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp index c047e8c101..d7eaf4b47f 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechContourMapView.cpp @@ -104,11 +104,9 @@ QString RimGeoMechContourMapView::createAutoName() const QStringList generatedAutoTags; - auto ownerCase = firstAncestorOrThisOfTypeAsserted(); - - if ( nameConfig()->addCaseName() ) + if ( nameConfig()->addCaseName() && ownerCase() ) { - generatedAutoTags.push_back( ownerCase->caseUserDescription() ); + generatedAutoTags.push_back( ownerCase()->caseUserDescription() ); } if ( nameConfig()->addAggregationType() ) diff --git a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp index 293eea1334..7b9777b9b6 100644 --- a/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp +++ b/ApplicationLibCode/ProjectDataModel/GeoMech/RimGeoMechView.cpp @@ -226,11 +226,9 @@ QString RimGeoMechView::createAutoName() const QStringList generatedAutoTags; - RimCase* ownerCase = firstAncestorOrThisOfTypeAsserted(); - - if ( nameConfig()->addCaseName() ) + if ( nameConfig()->addCaseName() && ownerCase() ) { - generatedAutoTags.push_back( ownerCase->caseUserDescription() ); + generatedAutoTags.push_back( ownerCase()->caseUserDescription() ); } if ( nameConfig()->addProperty() ) diff --git a/ApplicationLibCode/ProjectDataModel/GridCrossPlots/RimGridCrossPlotDataSet.cpp b/ApplicationLibCode/ProjectDataModel/GridCrossPlots/RimGridCrossPlotDataSet.cpp index 6d51700cc6..6c42e23180 100644 --- a/ApplicationLibCode/ProjectDataModel/GridCrossPlots/RimGridCrossPlotDataSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/GridCrossPlots/RimGridCrossPlotDataSet.cpp @@ -1136,7 +1136,7 @@ QList RimGridCrossPlotDataSet::calculateValueOptions( co if ( eclipseCase ) { options.push_back( caf::PdmOptionItemInfo( "Disabled", nullptr ) ); - for ( RimEclipseView* view : eclipseCase->reservoirViews.childrenByType() ) + for ( RimEclipseView* view : eclipseCase->reservoirViews() ) { CVF_ASSERT( view && "Really always should have a valid view pointer in ReservoirViews" ); options.push_back( caf::PdmOptionItemInfo( view->name(), view, false, view->uiIconProvider() ) ); diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimBoxIntersection.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimBoxIntersection.cpp index 3633f6a7f1..6ec5f151c7 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimBoxIntersection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimBoxIntersection.cpp @@ -656,7 +656,7 @@ void RimBoxIntersection::switchSingelPlaneState() //-------------------------------------------------------------------------------------------------- cvf::BoundingBox RimBoxIntersection::currentCellBoundingBox() { - auto rimCase = firstAncestorOrThisOfTypeAsserted(); + auto rimCase = firstAncestorOrThisOfTypeAsserted()->ownerCase(); return rimCase->activeCellsBoundingBox(); } diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp index f5845391b8..81d138bd53 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp @@ -328,7 +328,7 @@ void RimIntersectionCollection::appendIntersectionNoUpdate( RimExtrudedCurveInte //-------------------------------------------------------------------------------------------------- void RimIntersectionCollection::synchronize2dIntersectionViews() { - auto ownerCase = firstAncestorOrThisOfTypeAsserted(); + auto ownerCase = firstAncestorOrThisOfTypeAsserted()->ownerCase(); ownerCase->intersectionViewCollection()->syncFromExistingIntersections( true ); } diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionResultsDefinitionCollection.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionResultsDefinitionCollection.cpp index adaa8a426c..2769f569bb 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionResultsDefinitionCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionResultsDefinitionCollection.cpp @@ -72,8 +72,13 @@ void RimIntersectionResultsDefinitionCollection::appendIntersectionResultDefinit if ( interResDef->activeCase() == nullptr ) { - auto ownerCase = firstAncestorOrThisOfType(); - interResDef->setActiveCase( ownerCase ); + if ( auto gridView = firstAncestorOrThisOfType() ) + { + if ( auto ownerCase = gridView->ownerCase() ) + { + interResDef->setActiveCase( ownerCase ); + } + } } } diff --git a/ApplicationLibCode/ProjectDataModel/Rim2dIntersectionView.cpp b/ApplicationLibCode/ProjectDataModel/Rim2dIntersectionView.cpp index 4fc6d0bd04..43b10d393e 100644 --- a/ApplicationLibCode/ProjectDataModel/Rim2dIntersectionView.cpp +++ b/ApplicationLibCode/ProjectDataModel/Rim2dIntersectionView.cpp @@ -176,7 +176,7 @@ RimCase* Rim2dIntersectionView::ownerCase() const if ( !rimCase ) { - rimCase = firstAncestorOrThisOfTypeAsserted(); + rimCase = firstAncestorOrThisOfTypeAsserted()->ownerCase(); } return rimCase; diff --git a/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index d81b519916..86f6ef7e2e 100644 --- a/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -1013,12 +1013,14 @@ void Rim3dOverlayInfoConfig::updateSeismicInfo( RimSeismicView* seisView ) //-------------------------------------------------------------------------------------------------- void Rim3dOverlayInfoConfig::update3DInfoIn2dViews() const { - RimCase* rimCase = firstAncestorOrThisOfType(); - if ( rimCase ) + if ( auto rimView = firstAncestorOrThisOfType() ) { - for ( Rim2dIntersectionView* view : rimCase->intersectionViewCollection()->views() ) + if ( RimCase* rimCase = rimView->ownerCase() ) { - view->update3dInfo(); + for ( Rim2dIntersectionView* view : rimCase->intersectionViewCollection()->views() ) + { + view->update3dInfo(); + } } } } diff --git a/ApplicationLibCode/ProjectDataModel/RimAdvancedSnapshotExportDefinition.cpp b/ApplicationLibCode/ProjectDataModel/RimAdvancedSnapshotExportDefinition.cpp index 046c5e7b7d..e02f198250 100644 --- a/ApplicationLibCode/ProjectDataModel/RimAdvancedSnapshotExportDefinition.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimAdvancedSnapshotExportDefinition.cpp @@ -190,9 +190,11 @@ void RimAdvancedSnapshotExportDefinition::fieldChangedByUi( const caf::PdmFieldH { actCellInfo = RigReservoirGridTools::activeCellInfo( view() ); - auto rimCase = view()->firstAncestorOrThisOfTypeAsserted(); - - mainGrid = RigReservoirGridTools::mainGrid( rimCase ); + auto rimCase = view()->ownerCase(); + if ( rimCase ) + { + mainGrid = RigReservoirGridTools::mainGrid( rimCase ); + } } if ( mainGrid && actCellInfo ) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp index 17c2c98d8a..c0a904e64b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp @@ -58,6 +58,7 @@ #include "RimEclipseResultAddressCollection.h" #include "RimEclipseStatisticsCase.h" #include "RimEclipseView.h" +#include "RimEclipseViewCollection.h" #include "RimFaultInViewCollection.h" #include "RimFormationNames.h" #include "RimGridCollection.h" @@ -91,7 +92,7 @@ RimEclipseCase::RimEclipseCase() { CAF_PDM_InitScriptableObjectWithNameAndComment( "EclipseCase", ":/Case48x48.png", "", "", "Reservoir", "Abstract base class for Eclipse Cases" ); - CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &reservoirViews, "ReservoirViews", "Views", "", "", "", "All Eclipse Views in the case" ); + CAF_PDM_InitFieldNoDefault( &m_reservoirViews_OBSOLETE, "ReservoirViews", "Views", "", "", "", "All Eclipse Views in the case" ); CAF_PDM_InitFieldNoDefault( &m_matrixModelResults, "MatrixModelResults", "" ); CAF_PDM_InitFieldNoDefault( &m_fractureModelResults, "FractureModelResults", "" ); @@ -105,8 +106,8 @@ RimEclipseCase::RimEclipseCase() // https://github.com/OPM/ResInsight/issues/7308 m_filesContainingFaults.xmlCapability()->disableIO(); - CAF_PDM_InitFieldNoDefault( &m_contourMapCollection, "ContourMaps", "2d Contour Maps" ); - m_contourMapCollection = new RimEclipseContourMapViewCollection; + CAF_PDM_InitFieldNoDefault( &m_contourMapCollection_OBSOLETE, "ContourMaps", "2d Contour Maps" ); + m_contourMapCollection_OBSOLETE = new RimEclipseContourMapViewCollection; CAF_PDM_InitFieldNoDefault( &m_inputPropertyCollection, "InputPropertyCollection", "" ); m_inputPropertyCollection = new RimEclipseInputPropertyCollection; @@ -132,8 +133,6 @@ RimEclipseCase::RimEclipseCase() //-------------------------------------------------------------------------------------------------- RimEclipseCase::~RimEclipseCase() { - reservoirViews.deleteChildren(); - delete m_matrixModelResults(); delete m_fractureModelResults(); delete m_inputPropertyCollection; @@ -276,17 +275,32 @@ void RimEclipseCase::initAfterRead() { RimCase::initAfterRead(); - size_t j; - for ( j = 0; j < reservoirViews().size(); j++ ) + if ( RimProject::current()->isProjectFileVersionEqualOrOlderThan( "2024.03.0" ) ) { - RimEclipseView* riv = reservoirViews()[j]; - CVF_ASSERT( riv ); + // Move views to view collection. + RimEclipseViewCollection* viewColl = viewCollection(); + for ( size_t j = 0; j < m_reservoirViews_OBSOLETE.size(); j++ ) + { + RimEclipseView* riv = m_reservoirViews_OBSOLETE()[j]; + CVF_ASSERT( riv ); - riv->setEclipseCase( this ); - } - for ( RimEclipseContourMapView* contourMap : m_contourMapCollection->views() ) - { - contourMap->setEclipseCase( this ); + riv->setEclipseCase( this ); + m_reservoirViews_OBSOLETE.removeChild( riv ); + viewColl->addView( riv ); + } + + m_reservoirViews_OBSOLETE.clearWithoutDelete(); + + // Move contour maps + auto mapViewColl = contourMapCollection(); + for ( RimEclipseContourMapView* contourMap : m_contourMapCollection_OBSOLETE->views() ) + { + contourMap->setEclipseCase( this ); + m_contourMapCollection_OBSOLETE->removeChild( contourMap ); + mapViewColl->push_back( contourMap ); + } + + m_contourMapCollection_OBSOLETE->clearWithoutDelete(); } } @@ -295,29 +309,10 @@ void RimEclipseCase::initAfterRead() //-------------------------------------------------------------------------------------------------- RimEclipseView* RimEclipseCase::createAndAddReservoirView() { - RimEclipseView* rimEclipseView = new RimEclipseView(); - - rimEclipseView->setEclipseCase( this ); - - // Set default values - if ( rimEclipseView->currentGridCellResults() ) - { - auto defaultResult = rimEclipseView->currentGridCellResults()->defaultResult(); - rimEclipseView->cellResult()->setFromEclipseResultAddress( defaultResult ); - } - - auto prefs = RiaPreferences::current(); - rimEclipseView->faultCollection()->setActive( prefs->enableFaultsByDefault() ); - - rimEclipseView->cellEdgeResult()->setResultVariable( "MULT" ); - rimEclipseView->cellEdgeResult()->setActive( false ); - rimEclipseView->fractureColors()->setDefaultResultName(); + RimEclipseViewCollection* viewColl = viewCollection(); + if ( !viewColl ) return nullptr; - caf::PdmDocument::updateUiIconStateRecursively( rimEclipseView ); - - reservoirViews().push_back( rimEclipseView ); - - return rimEclipseView; + return viewColl->addView( this ); } //-------------------------------------------------------------------------------------------------- @@ -334,7 +329,10 @@ RimEclipseView* RimEclipseCase::createCopyAndAddView( const RimEclipseView* sour caf::PdmDocument::updateUiIconStateRecursively( rimEclipseView ); - reservoirViews().push_back( rimEclipseView ); + RimEclipseViewCollection* viewColl = viewCollection(); + if ( !viewColl ) return nullptr; + + viewColl->addView( rimEclipseView ); // Resolve references after reservoir view has been inserted into Rim structures rimEclipseView->resolveReferencesRecursively(); @@ -468,10 +466,8 @@ void RimEclipseCase::fieldChangedByUi( const caf::PdmFieldHandle* changedField, computeCachedData(); - for ( size_t i = 0; i < reservoirViews().size(); i++ ) + for ( RimEclipseView* reservoirView : reservoirViews() ) { - RimEclipseView* reservoirView = reservoirViews()[i]; - reservoirView->scheduleReservoirGridGeometryRegen(); reservoirView->scheduleSimWellGeometryRegen(); reservoirView->createDisplayModelAndRedraw(); @@ -554,20 +550,10 @@ void RimEclipseCase::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin { if ( uiConfigName == "MainWindow.ProjectTree" ) { - std::vector children = reservoirViews.children(); - - for ( auto child : children ) - uiTreeOrdering.add( child ); - if ( !m_2dIntersectionViewCollection->views().empty() ) { uiTreeOrdering.add( &m_2dIntersectionViewCollection ); } - - if ( !m_contourMapCollection->views().empty() ) - { - uiTreeOrdering.add( &m_contourMapCollection ); - } } else if ( uiConfigName == "MainWindow.DataSources" ) { @@ -668,9 +654,15 @@ RimCaseCollection* RimEclipseCase::parentCaseCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimEclipseContourMapViewCollection* RimEclipseCase::contourMapCollection() +RimEclipseContourMapViewCollection* RimEclipseCase::contourMapCollection() const { - return m_contourMapCollection; + RimProject* project = RimProject::current(); + if ( !project ) return nullptr; + + RimOilField* oilField = project->activeOilField(); + if ( !oilField ) return nullptr; + + return oilField->eclipseContourMapCollection(); } //-------------------------------------------------------------------------------------------------- @@ -1080,12 +1072,12 @@ bool RimEclipseCase::openReserviorCase() std::vector RimEclipseCase::allSpecialViews() const { std::vector views; - for ( RimEclipseView* view : reservoirViews ) + for ( RimEclipseView* view : reservoirViews() ) { views.push_back( view ); } - for ( RimEclipseContourMapView* view : m_contourMapCollection->views() ) + for ( RimEclipseContourMapView* view : contourMapViews() ) { views.push_back( view ); } @@ -1198,3 +1190,57 @@ void RimEclipseCase::updateResultAddressCollection() m_resultAddressCollections.deleteChildren(); updateConnectedEditors(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseViewCollection* RimEclipseCase::viewCollection() const +{ + RimProject* project = RimProject::current(); + if ( !project ) return nullptr; + + RimOilField* oilField = project->activeOilField(); + if ( !oilField ) return nullptr; + + return oilField->eclipseViewCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEclipseCase::reservoirViews() const +{ + std::vector views; + if ( RimEclipseViewCollection* viewColl = viewCollection() ) + { + for ( auto view : viewColl->views() ) + { + if ( view && view->eclipseCase() && view->eclipseCase() == this ) + { + views.push_back( view ); + } + } + } + + return views; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEclipseCase::contourMapViews() const +{ + std::vector views; + if ( RimEclipseContourMapViewCollection* viewColl = contourMapCollection() ) + { + for ( auto view : viewColl->views() ) + { + if ( view && view->eclipseCase() && view->eclipseCase() == this ) + { + views.push_back( view ); + } + } + } + + return views; +} diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h index dad144c78d..bcd29f88df 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h @@ -52,6 +52,7 @@ class RimIdenticalGridCaseGroup; class RimReservoirCellResultsStorage; class RimEclipseResultAddressCollection; class RifReaderSettings; +class RimEclipseViewCollection; //================================================================================================== // @@ -66,8 +67,7 @@ class RimEclipseCase : public RimCase RimEclipseCase(); ~RimEclipseCase() override; - // Fields: - caf::PdmChildArrayField reservoirViews; + std::vector reservoirViews() const; std::vector filesContainingFaults() const; void setFilesContainingFaults( const std::vector& val ); @@ -99,7 +99,7 @@ class RimEclipseCase : public RimCase virtual QString locationOnDisc() const { return QString(); } RimCaseCollection* parentCaseCollection(); - RimEclipseContourMapViewCollection* contourMapCollection(); + RimEclipseContourMapViewCollection* contourMapCollection() const; RimEclipseInputPropertyCollection* inputPropertyCollection() const; QStringList timeStepStrings() const override; @@ -137,14 +137,18 @@ class RimEclipseCase : public RimCase // Internal methods protected: - void computeCachedData(); - void setReservoirData( RigEclipseCaseData* eclipseCase ); - std::vector additionalFiles() const; + void computeCachedData(); + void setReservoirData( RigEclipseCaseData* eclipseCase ); + std::vector additionalFiles() const; + RimEclipseViewCollection* viewCollection() const; + RimEclipseContourMapViewCollection* contourMapViewCollection() const; private: - void createTimeStepFormatString(); - std::vector allSpecialViews() const override; - void buildResultChildNodes(); + void createTimeStepFormatString(); + std::vector allSpecialViews() const override; + std::vector contourMapViews() const; + + void buildResultChildNodes(); protected: caf::PdmField m_flipXAxis; @@ -156,8 +160,6 @@ class RimEclipseCase : public RimCase private: caf::PdmField m_releaseResultMemory; - caf::PdmChildField m_contourMapCollection; - cvf::ref m_rigEclipseCase; QString m_timeStepFormatString; std::map m_wellToColorMap; @@ -168,4 +170,8 @@ class RimEclipseCase : public RimCase caf::PdmChildField m_fractureModelResults; caf::PdmField> m_filesContainingFaults; + + // Obsolete fields: + caf::PdmChildArrayField m_reservoirViews_OBSOLETE; + caf::PdmChildField m_contourMapCollection_OBSOLETE; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapProjection.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapProjection.cpp index bda217ec3c..5fd2902241 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapProjection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapProjection.cpp @@ -31,6 +31,7 @@ #include "RigHexIntersectionTools.h" #include "RigMainGrid.h" +#include "Rim3dView.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseContourMapView.h" @@ -385,7 +386,10 @@ std::vector RimEclipseContourMapProjection::retrieveParameterWeights() //-------------------------------------------------------------------------------------------------- RimEclipseCase* RimEclipseContourMapProjection::eclipseCase() const { - return firstAncestorOrThisOfType(); + auto view = firstAncestorOrThisOfType(); + if ( !view ) return nullptr; + + return dynamic_cast( view->ownerCase() ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp index 67e3b0f960..ab7d42a662 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp @@ -108,11 +108,9 @@ QString RimEclipseContourMapView::createAutoName() const QStringList generatedAutoTags; - RimCase* ownerCase = firstAncestorOrThisOfTypeAsserted(); - - if ( nameConfig()->addCaseName() ) + if ( nameConfig()->addCaseName() && ownerCase() ) { - generatedAutoTags.push_back( ownerCase->caseUserDescription() ); + generatedAutoTags.push_back( ownerCase()->caseUserDescription() ); } if ( nameConfig()->addAggregationType() ) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.cpp index 317765fca5..e688d7763b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.cpp @@ -47,3 +47,19 @@ void RimEclipseContourMapViewCollection::onChildDeleted( caf::PdmChildArrayField auto eclipseCase = firstAncestorOrThisOfType(); if ( eclipseCase ) eclipseCase->updateConnectedEditors(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseContourMapViewCollection::clearWithoutDelete() +{ + m_contourMapViews.clearWithoutDelete(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseContourMapViewCollection::removeChild( RimEclipseContourMapView* contourMap ) +{ + m_contourMapViews.removeChild( contourMap ); +} diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.h b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.h index ef7f60a1cf..1a7290a7de 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapViewCollection.h @@ -37,6 +37,9 @@ class RimEclipseContourMapViewCollection : public caf::PdmObject void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector& referringObjects ) override; + void clearWithoutDelete(); + void removeChild( RimEclipseContourMapView* contourMap ); + private: caf::PdmChildArrayField m_contourMapViews; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp index 5cb28a8360..63540ec2ab 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -500,12 +500,11 @@ RimEclipseResultCase::~RimEclipseResultCase() { // Disconnect all comparison views. In debug build on Windows, a crash occurs. The comparison view is also set to zero in the destructor // of Rim3dView() - for ( auto v : reservoirViews ) + for ( auto v : reservoirViews() ) { if ( v ) v->setComparisonView( nullptr ); } - reservoirViews.deleteChildren(); m_flowDiagSolutions.deleteChildren(); } diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp index ee64dffbd6..c5dea97ccf 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -769,7 +769,9 @@ QList RimEclipseResultDefinition::calculateValueOptions( { options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) ); - auto eclipseCase = firstAncestorOrThisOfTypeAsserted(); + RimEclipseView* eclView = firstAncestorOrThisOfTypeAsserted(); + + auto eclipseCase = eclView->eclipseCase(); if ( eclipseCase && eclipseCase->eclipseCaseData() && eclipseCase->eclipseCaseData()->mainGrid() ) { RimProject* proj = RimProject::current(); @@ -792,7 +794,9 @@ QList RimEclipseResultDefinition::calculateValueOptions( } else if ( fieldNeedingOptions == &m_timeLapseBaseTimestep ) { - RimEclipseCase* currentCase = firstAncestorOrThisOfTypeAsserted(); + RimEclipseView* eclView = firstAncestorOrThisOfTypeAsserted(); + + RimEclipseCase* currentCase = eclView->eclipseCase(); RimEclipseCase* baseCase = currentCase; if ( m_differenceCase ) @@ -802,13 +806,16 @@ QList RimEclipseResultDefinition::calculateValueOptions( options.push_back( caf::PdmOptionItemInfo( "Disabled", RigEclipseResultAddress::noTimeLapseValue() ) ); - std::vector stepDates = baseCase->timeStepDates(); - for ( size_t stepIdx = 0; stepIdx < stepDates.size(); ++stepIdx ) + if ( baseCase ) { - QString displayString = stepDates[stepIdx].toString( RiaQDateTimeTools::dateFormatString() ); - displayString += QString( " (#%1)" ).arg( stepIdx ); + std::vector stepDates = baseCase->timeStepDates(); + for ( size_t stepIdx = 0; stepIdx < stepDates.size(); ++stepIdx ) + { + QString displayString = stepDates[stepIdx].toString( RiaQDateTimeTools::dateFormatString() ); + displayString += QString( " (#%1)" ).arg( stepIdx ); - options.push_back( caf::PdmOptionItemInfo( displayString, static_cast( stepIdx ) ) ); + options.push_back( caf::PdmOptionItemInfo( displayString, static_cast( stepIdx ) ) ); + } } } } diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp index 1feb6ca34b..1309f4709c 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp @@ -444,11 +444,9 @@ void RimEclipseStatisticsCase::computeStatistics() //-------------------------------------------------------------------------------------------------- void RimEclipseStatisticsCase::scheduleACTIVEGeometryRegenOnReservoirViews() { - for ( size_t i = 0; i < reservoirViews().size(); i++ ) + for ( RimEclipseView* reservoirView : reservoirViews() ) { - RimEclipseView* reservoirView = reservoirViews()[i]; CVF_ASSERT( reservoirView ); - reservoirView->scheduleGeometryRegen( ACTIVE ); } } @@ -755,9 +753,8 @@ void RimEclipseStatisticsCase::fieldChangedByUi( const caf::PdmFieldHandle* chan caf::ProgressInfo progInfo( reservoirViews().size() + 1, "Updating Well Data for Views" ); // Update views - for ( size_t i = 0; i < reservoirViews().size(); i++ ) + for ( RimEclipseView* reservoirView : reservoirViews() ) { - RimEclipseView* reservoirView = reservoirViews()[i]; CVF_ASSERT( reservoirView ); reservoirView->wellCollection()->wells.deleteChildren(); @@ -961,18 +958,16 @@ bool RimEclipseStatisticsCase::hasComputedStatistics() const //-------------------------------------------------------------------------------------------------- void RimEclipseStatisticsCase::updateConnectedEditorsAndReservoirViews() { - for ( size_t i = 0; i < reservoirViews.size(); ++i ) + auto views = reservoirViews(); + for ( RimEclipseView* view : reservoirViews() ) { - if ( reservoirViews[i] ) - { - // As new result might have been introduced, update all editors connected - reservoirViews[i]->cellResult()->updateConnectedEditors(); + // As new result might have been introduced, update all editors connected + view->cellResult()->updateConnectedEditors(); - // It is usually not needed to create new display model, but if any derived geometry based on generated data - // (from Octave) a full display model rebuild is required - reservoirViews[i]->scheduleCreateDisplayModelAndRedraw(); - reservoirViews[i]->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } + // It is usually not needed to create new display model, but if any derived geometry based on generated data + // (from Octave) a full display model rebuild is required + view->scheduleCreateDisplayModelAndRedraw(); + view->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } updateConnectedEditors(); @@ -1007,18 +1002,18 @@ void RimEclipseStatisticsCase::computeStatisticsAndUpdateViews() scheduleACTIVEGeometryRegenOnReservoirViews(); updateConnectedEditorsAndReservoirViews(); - if ( reservoirViews.empty() ) + if ( reservoirViews().empty() ) { RicNewViewFeature::addReservoirView( this, nullptr ); } - if ( reservoirViews.size() == 1 ) + if ( reservoirViews().size() == 1 ) { // If only one view, set the first result as active if ( auto cellResultsData = results( RiaDefines::PorosityModelType::MATRIX_MODEL ) ) { - auto firstView = reservoirViews[0]; + auto firstView = reservoirViews()[0]; std::vector resAddresses = cellResultsData->existingResults(); if ( firstView && !resAddresses.empty() ) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp index 3fcf0c53fd..23339631e6 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp @@ -327,7 +327,7 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults( const QList for ( RimEclipseCase* eclipseCase : m_sourceCases ) { - if ( eclipseCase->reservoirViews.empty() ) + if ( eclipseCase->reservoirViews().empty() ) { eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL )->freeAllocatedResultsData( categoriesToExclude, timeStepIdx ); eclipseCase->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->freeAllocatedResultsData( categoriesToExclude, timeStepIdx ); diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp index 20df13f052..ac89e2a377 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp @@ -144,7 +144,9 @@ RimEclipseView::RimEclipseView() "EclipseView", "The Eclipse 3d Reservoir View" ); - CAF_PDM_InitFieldNoDefault( &m_customEclipseCase, "CustomEclipseCase", "Custom Case" ); + CAF_PDM_InitFieldNoDefault( &m_customEclipseCase_OBSOLETE, "CustomEclipseCase", "Custom Case" ); + + CAF_PDM_InitScriptableFieldNoDefault( &m_eclipseCase, "EclipseCase", "Eclipse Case" ); CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &m_cellResult, "GridCellResult", "CellResult", "Cell Result", ":/CellResult.png" ); m_cellResult = new RimEclipseCellColors(); @@ -392,7 +394,7 @@ void RimEclipseView::fieldChangedByUi( const caf::PdmFieldHandle* changedField, { RimGridView::fieldChangedByUi( changedField, oldValue, newValue ); - if ( changedField == &m_customEclipseCase ) + if ( changedField == &m_eclipseCase ) { propagateEclipseCaseToChildObjects(); @@ -1262,11 +1264,9 @@ QString RimEclipseView::createAutoName() const QStringList generatedAutoTags; - RimCase* ownerCase = firstAncestorOrThisOfTypeAsserted(); - - if ( nameConfig()->addCaseName() ) + if ( m_eclipseCase && nameConfig()->addCaseName() ) { - generatedAutoTags.push_back( ownerCase->caseUserDescription() ); + generatedAutoTags.push_back( m_eclipseCase->caseUserDescription() ); } if ( nameConfig()->addProperty() ) @@ -1568,8 +1568,6 @@ void RimEclipseView::setEclipseCase( RimEclipseCase* reservoir ) //-------------------------------------------------------------------------------------------------- RimEclipseCase* RimEclipseView::eclipseCase() const { - if ( m_customEclipseCase() != nullptr ) return m_customEclipseCase(); - return m_eclipseCase; } @@ -1897,6 +1895,8 @@ void RimEclipseView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& { Rim3dView::defineUiOrdering( uiConfigName, uiOrdering ); + uiOrdering.add( &m_eclipseCase ); + caf::PdmUiGroup* cellGroup = uiOrdering.addNewGroup( "Cell Visibility" ); cellGroup->add( &m_showInactiveCells ); cellGroup->add( &m_showInvalidCells ); @@ -1904,10 +1904,6 @@ void RimEclipseView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "View Name" ); nameConfig()->uiOrdering( uiConfigName, *nameGroup ); - caf::PdmUiGroup* advancedGroup = uiOrdering.addNewGroup( "Advanced" ); - advancedGroup->setCollapsedByDefault(); - advancedGroup->add( &m_customEclipseCase ); - uiOrdering.skipRemainingFields( true ); } @@ -1984,27 +1980,15 @@ std::set RimEclipseView::allVisibleFaultGeometryTypes() const //-------------------------------------------------------------------------------------------------- QList RimEclipseView::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) { - if ( fieldNeedingOptions == &m_customEclipseCase ) + if ( fieldNeedingOptions == &m_eclipseCase ) { QList options; options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) ); - if ( m_eclipseCase && m_eclipseCase->mainGrid() ) + for ( auto eclCase : RimEclipseCaseTools::allEclipseGridCases() ) { - auto currentGridCount = m_eclipseCase->mainGrid()->gridCount(); - - for ( auto eclCase : RimEclipseCaseTools::allEclipseGridCases() ) - { - // Find all grid cases with same number of LGRs. If the grid count differs, a crash will happen related to - // RimGridCollection::mainEclipseGrid(). This function is using firstAncestorOrThisOfType() to find the Eclipse case. If the - // custom case in RimEclipseView has a different number of LGRs, a crash will happen - - if ( eclCase && ( eclCase != m_eclipseCase ) && eclCase->mainGrid() && eclCase->mainGrid()->gridCount() == currentGridCount ) - { - options.push_back( caf::PdmOptionItemInfo( eclCase->caseUserDescription(), eclCase, false, eclCase->uiIconProvider() ) ); - } - } + options.push_back( caf::PdmOptionItemInfo( eclCase->caseUserDescription(), eclCase, false, eclCase->uiIconProvider() ) ); } return options; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.h b/ApplicationLibCode/ProjectDataModel/RimEclipseView.h index 573dad6557..4ff0b550b4 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.h @@ -245,8 +245,8 @@ class RimEclipseView : public RimGridView caf::PdmChildField m_propertyFilterCollection; caf::PdmPointer m_overridePropertyFilterCollection; - caf::PdmPointer m_eclipseCase; - caf::PdmPtrField m_customEclipseCase; + caf::PdmPtrField m_eclipseCase; + caf::PdmPtrField m_customEclipseCase_OBSOLETE; cvf::ref m_reservoirGridPartManager; cvf::ref m_simWellsPartManager; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp new file mode 100644 index 0000000000..aa67681149 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.cpp @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimEclipseViewCollection.h" + +#include "RiaLogging.h" +#include "RiaPreferences.h" + +#include "RigCaseCellResultsData.h" + +#include "Rim3dView.h" +#include "RimCellEdgeColors.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" +#include "RimFaultInViewCollection.h" +#include "RimGridView.h" +#include "RimProject.h" +#include "RimStimPlanColors.h" + +CAF_PDM_SOURCE_INIT( RimEclipseViewCollection, "EclipseViewCollection", "EclipseViewCollection" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseViewCollection::RimEclipseViewCollection() +{ + CAF_PDM_InitObject( "Views", ":/3DView16x16.png" ); + + CAF_PDM_InitFieldNoDefault( &m_views, "Views", "Eclipse Views" ); + + setDeletable( false ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseViewCollection::~RimEclipseViewCollection() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEclipseViewCollection::views() const +{ + return m_views.childrenByType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseViewCollection::isEmpty() +{ + return !m_views.hasChildren(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RimEclipseViewCollection::addView( RimEclipseCase* eclipseCase ) +{ + RimEclipseView* view = new RimEclipseView(); + + view->setEclipseCase( eclipseCase ); + + // Set default values + if ( view->currentGridCellResults() ) + { + auto defaultResult = view->currentGridCellResults()->defaultResult(); + view->cellResult()->setFromEclipseResultAddress( defaultResult ); + } + + auto prefs = RiaPreferences::current(); + view->faultCollection()->setActive( prefs->enableFaultsByDefault() ); + + view->cellEdgeResult()->setResultVariable( "MULT" ); + view->cellEdgeResult()->setActive( false ); + view->fractureColors()->setDefaultResultName(); + + caf::PdmDocument::updateUiIconStateRecursively( view ); + + m_views.push_back( view ); + + view->loadDataAndUpdate(); + + updateConnectedEditors(); + + return view; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseViewCollection::addView( RimEclipseView* view ) +{ + m_views.push_back( view ); + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseViewCollection::removeView( RimEclipseView* view ) +{ + m_views.removeChild( view ); + updateConnectedEditors(); +} diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.h b/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.h new file mode 100644 index 0000000000..024b6b5e03 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseViewCollection.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cafPdmField.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmObject.h" + +#include + +class RimEclipseView; +class RimEclipseCase; + +class RimEclipseViewCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimEclipseViewCollection(); + ~RimEclipseViewCollection() override; + + bool isEmpty(); + + RimEclipseView* addView( RimEclipseCase* eclipseCase ); + void addView( RimEclipseView* view ); + + void removeView( RimEclipseView* view ); + + std::vector views() const; + +private: + caf::PdmChildArrayField m_views; +}; diff --git a/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlot.cpp b/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlot.cpp index 0325337b75..868447158d 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridStatisticsPlot.cpp @@ -96,9 +96,9 @@ void RimGridStatisticsPlot::setDefaults() m_property->setResultType( RiaDefines::ResultCatType::STATIC_NATIVE ); m_property->setResultVariable( "PORO" ); - if ( eclipseCase && !eclipseCase->reservoirViews.children().empty() ) + if ( eclipseCase && !eclipseCase->reservoirViews().empty() ) { - m_cellFilterView.setValue( eclipseCase->reservoirViews.childrenByType().front() ); + m_cellFilterView.setValue( eclipseCase->reservoirViews().front() ); } m_numHistogramBins = 15; @@ -196,7 +196,7 @@ QList RimGridStatisticsPlot::calculateValueOptions( cons if ( eclipseCase ) { options.push_back( caf::PdmOptionItemInfo( "Disabled", nullptr ) ); - for ( RimEclipseView* view : eclipseCase->reservoirViews.childrenByType() ) + for ( RimEclipseView* view : eclipseCase->reservoirViews() ) { CVF_ASSERT( view && "Really always should have a valid view pointer in ReservoirViews" ); options.push_back( caf::PdmOptionItemInfo( view->name(), view, false, view->uiIconProvider() ) ); diff --git a/ApplicationLibCode/ProjectDataModel/RimGridView.cpp b/ApplicationLibCode/ProjectDataModel/RimGridView.cpp index d9074993b9..0de0fb62b9 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridView.cpp @@ -378,9 +378,8 @@ void RimGridView::onCreatePartCollectionFromSelection( cvf::Collection( items[i] ); - if ( eclipseSelItem && eclipseSelItem->m_view == this ) + if ( eclipseSelItem && eclipseSelItem->m_view == this && eclipseSelItem->m_resultDefinition->eclipseCase() ) { - CVF_ASSERT( eclipseSelItem->m_resultDefinition->eclipseCase() ); CVF_ASSERT( eclipseSelItem->m_resultDefinition->eclipseCase()->eclipseCaseData() ); RivSingleCellPartGenerator partGen( eclipseSelItem->m_resultDefinition->eclipseCase()->eclipseCaseData(), diff --git a/ApplicationLibCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationLibCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp index 8b740585af..8fce6f1add 100644 --- a/ApplicationLibCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -398,9 +398,10 @@ void RimIdenticalGridCaseGroup::clearStatisticsResults() rimStaticsCase->results( RiaDefines::PorosityModelType::FRACTURE_MODEL )->clearAllResults(); } - for ( size_t j = 0; j < rimStaticsCase->reservoirViews.size(); j++ ) + auto views = rimStaticsCase->reservoirViews(); + for ( size_t j = 0; j < views.size(); j++ ) { - RimEclipseView* rimReservoirView = rimStaticsCase->reservoirViews[j]; + RimEclipseView* rimReservoirView = views[j]; rimReservoirView->cellResult()->setResultVariable( RiaResultNames::undefinedResultName() ); rimReservoirView->cellEdgeResult()->setResultVariable( RiaResultNames::undefinedResultName() ); rimReservoirView->loadDataAndUpdate(); diff --git a/ApplicationLibCode/ProjectDataModel/RimOilField.cpp b/ApplicationLibCode/ProjectDataModel/RimOilField.cpp index ac36308e79..0497cf065f 100644 --- a/ApplicationLibCode/ProjectDataModel/RimOilField.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimOilField.cpp @@ -23,6 +23,8 @@ #include "RimAnnotationCollection.h" #include "RimCompletionTemplateCollection.h" #include "RimEclipseCaseCollection.h" +#include "RimEclipseContourMapViewCollection.h" +#include "RimEclipseViewCollection.h" #include "RimEnsembleWellLogsCollection.h" #include "RimFormationNamesCollection.h" #include "RimFractureTemplateCollection.h" @@ -75,6 +77,12 @@ RimOilField::RimOilField() CAF_PDM_InitFieldNoDefault( &seismicViewCollection, "SeismicViewCollection", "Seismic Views" ); seismicViewCollection = new RimSeismicViewCollection(); + CAF_PDM_InitFieldNoDefault( &eclipseViewCollection, "EclipseViewCollection", "Eclipse Views", ":/3DView16x16.png" ); + eclipseViewCollection = new RimEclipseViewCollection(); + + CAF_PDM_InitFieldNoDefault( &eclipseContourMapCollection, "ContourMaps", "2d Contour Maps" ); + eclipseContourMapCollection = new RimEclipseContourMapViewCollection; + completionTemplateCollection = new RimCompletionTemplateCollection; analysisModels = new RimEclipseCaseCollection(); wellPathCollection = new RimWellPathCollection(); diff --git a/ApplicationLibCode/ProjectDataModel/RimOilField.h b/ApplicationLibCode/ProjectDataModel/RimOilField.h index 60b17c698b..246ad5ea0f 100644 --- a/ApplicationLibCode/ProjectDataModel/RimOilField.h +++ b/ApplicationLibCode/ProjectDataModel/RimOilField.h @@ -42,6 +42,8 @@ class RimSeismicViewCollection; class RimSurfaceCollection; class RimEnsembleWellLogsCollection; class RimPolygonCollection; +class RimEclipseViewCollection; +class RimEclipseContourMapViewCollection; //================================================================================================== /// @@ -61,20 +63,22 @@ class RimOilField : public caf::PdmObject RimValveTemplateCollection* valveTemplateCollection(); const RimValveTemplateCollection* valveTemplateCollection() const; - caf::PdmChildField analysisModels; - caf::PdmChildField geoMechModels; - caf::PdmChildField wellPathCollection; - caf::PdmChildField completionTemplateCollection; - caf::PdmChildField summaryCaseMainCollection; - caf::PdmChildField observedDataCollection; - caf::PdmChildField formationNamesCollection; - caf::PdmChildField annotationCollection; - caf::PdmChildField measurement; - caf::PdmChildField surfaceCollection; - caf::PdmChildField seismicDataCollection; - caf::PdmChildField seismicViewCollection; - caf::PdmChildField ensembleWellLogsCollection; - caf::PdmChildField polygonCollection; + caf::PdmChildField analysisModels; + caf::PdmChildField geoMechModels; + caf::PdmChildField wellPathCollection; + caf::PdmChildField completionTemplateCollection; + caf::PdmChildField summaryCaseMainCollection; + caf::PdmChildField observedDataCollection; + caf::PdmChildField formationNamesCollection; + caf::PdmChildField annotationCollection; + caf::PdmChildField measurement; + caf::PdmChildField surfaceCollection; + caf::PdmChildField seismicDataCollection; + caf::PdmChildField seismicViewCollection; + caf::PdmChildField eclipseViewCollection; + caf::PdmChildField ensembleWellLogsCollection; + caf::PdmChildField polygonCollection; + caf::PdmChildField eclipseContourMapCollection; protected: void initAfterRead() override; diff --git a/ApplicationLibCode/ProjectDataModel/RimProject.cpp b/ApplicationLibCode/ProjectDataModel/RimProject.cpp index ab1945d156..4494e782aa 100644 --- a/ApplicationLibCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimProject.cpp @@ -49,6 +49,8 @@ #include "RimDialogData.h" #include "RimEclipseCase.h" #include "RimEclipseCaseCollection.h" +#include "RimEclipseContourMapViewCollection.h" +#include "RimEclipseViewCollection.h" #include "RimEnsembleWellLogsCollection.h" #include "RimFileWellPath.h" #include "RimFlowPlotCollection.h" @@ -1490,6 +1492,7 @@ void RimProject::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, Q if ( oilField ) { if ( oilField->analysisModels() ) uiTreeOrdering.add( oilField->analysisModels() ); + if ( oilField->eclipseViewCollection() ) uiTreeOrdering.add( oilField->eclipseViewCollection() ); if ( oilField->geoMechModels() ) uiTreeOrdering.add( oilField->geoMechModels() ); if ( oilField->wellPathCollection() ) uiTreeOrdering.add( oilField->wellPathCollection() ); if ( oilField->polygonCollection() ) uiTreeOrdering.add( oilField->polygonCollection() ); @@ -1503,6 +1506,7 @@ void RimProject::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, Q if ( oilField->formationNamesCollection() ) uiTreeOrdering.add( oilField->formationNamesCollection() ); if ( oilField->completionTemplateCollection() ) uiTreeOrdering.add( oilField->completionTemplateCollection() ); if ( oilField->annotationCollection() ) uiTreeOrdering.add( oilField->annotationCollection() ); + if ( oilField->eclipseContourMapCollection() ) uiTreeOrdering.add( oilField->eclipseContourMapCollection() ); } uiTreeOrdering.add( colorLegendCollection() ); diff --git a/ApplicationLibCode/ProjectDataModel/RimSimWellInViewCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimSimWellInViewCollection.cpp index 4124a28645..00519da768 100644 --- a/ApplicationLibCode/ProjectDataModel/RimSimWellInViewCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimSimWellInViewCollection.cpp @@ -567,8 +567,7 @@ void RimSimWellInViewCollection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& u //-------------------------------------------------------------------------------------------------- void RimSimWellInViewCollection::assignDefaultWellColors() { - auto ownerCase = firstAncestorOrThisOfTypeAsserted(); - + auto ownerCase = m_reservoirView->eclipseCase(); for ( size_t wIdx = 0; wIdx < wells.size(); ++wIdx ) { RimSimWellInView* well = wells[wIdx]; diff --git a/ApplicationLibCode/SocketInterface/RiaNNCCommands.cpp b/ApplicationLibCode/SocketInterface/RiaNNCCommands.cpp index aa567a5f91..b46b1d114b 100644 --- a/ApplicationLibCode/SocketInterface/RiaNNCCommands.cpp +++ b/ApplicationLibCode/SocketInterface/RiaNNCCommands.cpp @@ -554,18 +554,15 @@ class RiaSetNNCProperty : public RiaSocketCommand m_currentReservoir->eclipseCaseData()->results( m_porosityModelEnum )->recalculateStatistics( m_currentEclResultAddress ); } - for ( size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i ) + for ( RimEclipseView* view : m_currentReservoir->reservoirViews() ) { - if ( m_currentReservoir->reservoirViews[i] ) - { - // As new result might have been introduced, update all editors connected - m_currentReservoir->reservoirViews[i]->cellResult()->updateConnectedEditors(); + // As new result might have been introduced, update all editors connected + view->cellResult()->updateConnectedEditors(); - // It is usually not needed to create new display model, but if any derived geometry based on - // generated data (from Octave) a full display model rebuild is required - m_currentReservoir->reservoirViews[i]->scheduleCreateDisplayModelAndRedraw(); - m_currentReservoir->reservoirViews[i]->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } + // It is usually not needed to create new display model, but if any derived geometry based on + // generated data (from Octave) a full display model rebuild is required + view->scheduleCreateDisplayModelAndRedraw(); + view->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } } diff --git a/ApplicationLibCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationLibCode/SocketInterface/RiaPropertyDataCommands.cpp index 0d7380a81e..5f91a374d9 100644 --- a/ApplicationLibCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationLibCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -658,18 +658,15 @@ class RiaSetActiveCellProperty : public RiaSocketCommand m_currentReservoir->eclipseCaseData()->results( m_porosityModelEnum )->recalculateStatistics( m_currentEclResultAddress ); } - for ( size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i ) + for ( RimEclipseView* view : m_currentReservoir->reservoirViews() ) { - if ( m_currentReservoir->reservoirViews[i] ) - { - // As new result might have been introduced, update all editors connected - m_currentReservoir->reservoirViews[i]->cellResult()->updateConnectedEditors(); + // As new result might have been introduced, update all editors connected + view->cellResult()->updateConnectedEditors(); - // It is usually not needed to create new display model, but if any derived geometry based on - // generated data (from Octave) a full display model rebuild is required - m_currentReservoir->reservoirViews[i]->scheduleCreateDisplayModelAndRedraw(); - m_currentReservoir->reservoirViews[i]->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } + // It is usually not needed to create new display model, but if any derived geometry based on + // generated data (from Octave) a full display model rebuild is required + view->scheduleCreateDisplayModelAndRedraw(); + view->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } } @@ -1033,18 +1030,15 @@ class RiaSetGridProperty : public RiaSocketCommand ->recalculateStatistics( RigEclipseResultAddress( m_currentResultAddress ) ); } - for ( size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i ) + for ( RimEclipseView* view : m_currentReservoir->reservoirViews() ) { - if ( m_currentReservoir->reservoirViews[i] ) - { - // As new result might have been introduced, update all editors connected - m_currentReservoir->reservoirViews[i]->cellResult()->updateConnectedEditors(); + // As new result might have been introduced, update all editors connected + view->cellResult()->updateConnectedEditors(); - // It is usually not needed to create new display model, but if any derived geometry based on - // generated data (from Octave) a full display model rebuild is required - m_currentReservoir->reservoirViews[i]->scheduleCreateDisplayModelAndRedraw(); - m_currentReservoir->reservoirViews[i]->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } + // It is usually not needed to create new display model, but if any derived geometry based on + // generated data (from Octave) a full display model rebuild is required + view->scheduleCreateDisplayModelAndRedraw(); + view->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } } diff --git a/ApplicationLibCode/UserInterface/RiuAdvancedSnapshotExportWidget.cpp b/ApplicationLibCode/UserInterface/RiuAdvancedSnapshotExportWidget.cpp index f4ea30066e..9889804058 100644 --- a/ApplicationLibCode/UserInterface/RiuAdvancedSnapshotExportWidget.cpp +++ b/ApplicationLibCode/UserInterface/RiuAdvancedSnapshotExportWidget.cpp @@ -147,7 +147,7 @@ void RiuAdvancedSnapshotExportWidget::addSnapshotItemFromActiveView() multiSnapshot->timeStepStart = activeView->currentTimeStep(); multiSnapshot->timeStepEnd = activeView->currentTimeStep(); - auto sourceCase = activeView->firstAncestorOrThisOfType(); + auto sourceCase = activeView->ownerCase(); if ( sourceCase ) { multiSnapshot->additionalCases().push_back( sourceCase ); diff --git a/GrpcInterface/Python/rips/case.py b/GrpcInterface/Python/rips/case.py index 695ec6b22b..6b36fdc80a 100644 --- a/GrpcInterface/Python/rips/case.py +++ b/GrpcInterface/Python/rips/case.py @@ -325,13 +325,31 @@ def view(self, view_id): Returns: :class:`rips.generated.generated_classes.View` """ - views = self.views() + project = self.ancestor(rips.project.Project) + views = project.views() for view_object in views: if view_object.id == view_id: return view_object return None +@add_method(Case) +def views(self): + """Get all views of a case + + Returns: + List of :class:`rips.generated.generated_classes.View` + """ + project = self.ancestor(rips.project.Project) + views = project.views() + views_for_case = [] + for view_object in views: + view_object.print_object_info() + if view_object.id == self.id: + views_for_case.append(view_object) + return views_for_case + + @add_method(Case) def create_view(self): """Create a new view in the current case @@ -990,8 +1008,10 @@ def simulation_wells(self): :class:`rips.generated.generated_classes.SimulationWell` """ - wells = self.descendants(SimulationWell) - return wells + if self.views(): + # Use the first view to get simulation wells. + return self.views()[0].descendants(SimulationWell) + return [] @add_method(Case) diff --git a/GrpcInterface/Python/rips/simulation_well.py b/GrpcInterface/Python/rips/simulation_well.py index 7c29d1c4e0..9b6f1b3e81 100644 --- a/GrpcInterface/Python/rips/simulation_well.py +++ b/GrpcInterface/Python/rips/simulation_well.py @@ -14,6 +14,7 @@ from .resinsight_classes import SimulationWell from .case import Case +from .view import View from .pdmobject import PdmObjectBase, add_method from typing import List, Optional @@ -80,4 +81,8 @@ def cells( @add_method(SimulationWell) def case(self: SimulationWell) -> Optional[Case]: - return self.ancestor(Case) + view = self.ancestor(View) + if view: + return view.case() + else: + return None diff --git a/GrpcInterface/Python/rips/view.py b/GrpcInterface/Python/rips/view.py index b034d2be1e..cf7cb53bd2 100644 --- a/GrpcInterface/Python/rips/view.py +++ b/GrpcInterface/Python/rips/view.py @@ -187,12 +187,24 @@ def export_property(self, undefined_value=0.0): ) -@add_method(ViewWindow) +def extract_address(address) -> int: + # Address form: "RimReservoir:123345345345435" + parts = address.split(":") + return int(parts[1]) + + +@add_method(View) def case(self): """Get the case the view belongs to""" - mycase = self.ancestor(rips.case.Case) - assert mycase is not None - return mycase + project = self.ancestor(rips.project.Project) + + eclipse_case_addr = extract_address(self.eclipse_case) + + cases = project.cases() + for c in cases: + if c.address() == eclipse_case_addr: + return c + return None @add_method(ViewWindow) diff --git a/GrpcInterface/RiaGrpcNNCPropertiesService.cpp b/GrpcInterface/RiaGrpcNNCPropertiesService.cpp index 4ffcf58c52..ef9075635f 100644 --- a/GrpcInterface/RiaGrpcNNCPropertiesService.cpp +++ b/GrpcInterface/RiaGrpcNNCPropertiesService.cpp @@ -462,18 +462,15 @@ void RiaNNCInputValuesStateHandler::finish() inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED; } - for ( size_t i = 0; i < m_eclipseCase->reservoirViews.size(); ++i ) + for ( RimEclipseView* view : m_eclipseCase->reservoirViews() ) { - if ( m_eclipseCase->reservoirViews[i] ) - { - // As new result might have been introduced, update all editors connected - m_eclipseCase->reservoirViews[i]->cellResult()->updateConnectedEditors(); + // As new result might have been introduced, update all editors connected + view->cellResult()->updateConnectedEditors(); - // It is usually not needed to create new display model, but if any derived geometry based on - // generated data (from Octave) a full display model rebuild is required - m_eclipseCase->reservoirViews[i]->scheduleCreateDisplayModelAndRedraw(); - m_eclipseCase->reservoirViews[i]->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } + // It is usually not needed to create new display model, but if any derived geometry based on + // generated data (from Octave) a full display model rebuild is required + view->scheduleCreateDisplayModelAndRedraw(); + view->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } } } From 520e5520db99c589476f78c12156f26c98cb42f6 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 12 Apr 2024 12:43:16 +0200 Subject: [PATCH 2/6] Support global and local views. --- .../Commands/RicNewViewFeature.cpp | 39 ++++++++++++++++--- .../Commands/RicNewViewFeature.h | 14 ++++--- .../RimContextCommandBuilder.cpp | 5 +++ .../ProjectDataModel/RimEclipseCase.cpp | 36 ++++++++++++++--- .../ProjectDataModel/RimEclipseCase.h | 5 ++- .../ProjectDataModel/RimGridCollection.cpp | 6 ++- 6 files changed, 86 insertions(+), 19 deletions(-) diff --git a/ApplicationLibCode/Commands/RicNewViewFeature.cpp b/ApplicationLibCode/Commands/RicNewViewFeature.cpp index 1907f42cd3..eed089898a 100644 --- a/ApplicationLibCode/Commands/RicNewViewFeature.cpp +++ b/ApplicationLibCode/Commands/RicNewViewFeature.cpp @@ -23,8 +23,10 @@ #include "Rim3dView.h" #include "RimEclipseCase.h" +#include "RimEclipseCaseTools.h" #include "RimEclipseContourMapView.h" #include "RimEclipseView.h" +#include "RimEclipseViewCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechView.h" @@ -39,9 +41,9 @@ CAF_CMD_SOURCE_INIT( RicNewViewFeature, "RicNewViewFeature" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicNewViewFeature::addReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase ) +void RicNewViewFeature::addReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase, bool useGlobalViewCollection ) { - Rim3dView* newView = createReservoirView( eclipseCase, geomCase ); + Rim3dView* newView = createReservoirView( eclipseCase, geomCase, useGlobalViewCollection ); if ( newView ) { @@ -58,7 +60,7 @@ void RicNewViewFeature::addReservoirView( RimEclipseCase* eclipseCase, RimGeoMec bool RicNewViewFeature::isCommandEnabled() const { return selectedEclipseCase() != nullptr || selectedEclipseView() != nullptr || selectedGeoMechCase() != nullptr || - selectedGeoMechView() != nullptr; + selectedGeoMechView() != nullptr || selectedEclipseViewCollection() != nullptr; } //-------------------------------------------------------------------------------------------------- @@ -76,7 +78,21 @@ void RicNewViewFeature::onActionTriggered( bool isChecked ) if ( geoMechView ) geomCase = geoMechView->geoMechCase(); if ( reservoirView ) eclipseCase = reservoirView->eclipseCase(); - addReservoirView( eclipseCase, geomCase ); + bool useGlobalViewCollection = false; + if ( selectedEclipseViewCollection() ) + { + // Use global view collection if view collection is not descendant of Eclipse case. + useGlobalViewCollection = selectedEclipseViewCollection()->firstAncestorOrThisOfType() == nullptr; + if ( !eclipseCase ) + { + auto eclipseCases = RimEclipseCaseTools::allEclipseGridCases(); + if ( !eclipseCases.empty() ) + { + eclipseCase = eclipseCases[0]; + } + } + } + addReservoirView( eclipseCase, geomCase, useGlobalViewCollection ); } //-------------------------------------------------------------------------------------------------- @@ -91,13 +107,13 @@ void RicNewViewFeature::setupActionLook( QAction* actionToSetup ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Rim3dView* RicNewViewFeature::createReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase ) +Rim3dView* RicNewViewFeature::createReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase, bool useGlobalViewCollection ) { RimGridView* insertedView = nullptr; if ( eclipseCase ) { - insertedView = eclipseCase->createAndAddReservoirView(); + insertedView = eclipseCase->createAndAddReservoirView( useGlobalViewCollection ); } else if ( geomCase ) { @@ -171,6 +187,17 @@ RimEclipseView* RicNewViewFeature::selectedEclipseView() return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseViewCollection* RicNewViewFeature::selectedEclipseViewCollection() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType( &selection ); + if ( !selection.empty() ) return selection[0]; + return nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Commands/RicNewViewFeature.h b/ApplicationLibCode/Commands/RicNewViewFeature.h index f5a6645e9a..c145641072 100644 --- a/ApplicationLibCode/Commands/RicNewViewFeature.h +++ b/ApplicationLibCode/Commands/RicNewViewFeature.h @@ -26,6 +26,7 @@ class RimEclipseView; class RimGeoMechCase; class RimGeoMechView; class Rim3dView; +class RimEclipseViewCollection; //================================================================================================== /// @@ -35,7 +36,7 @@ class RicNewViewFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; public: - static void addReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase ); + static void addReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase, bool useGlobalViewCollection = false ); protected: bool isCommandEnabled() const override; @@ -43,10 +44,11 @@ class RicNewViewFeature : public caf::CmdFeature void setupActionLook( QAction* actionToSetup ) override; private: - static Rim3dView* createReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase ); + static Rim3dView* createReservoirView( RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase, bool useGlobalViewCollectin ); - static RimEclipseCase* selectedEclipseCase(); - static RimGeoMechCase* selectedGeoMechCase(); - static RimEclipseView* selectedEclipseView(); - static RimGeoMechView* selectedGeoMechView(); + static RimEclipseCase* selectedEclipseCase(); + static RimGeoMechCase* selectedGeoMechCase(); + static RimEclipseView* selectedEclipseView(); + static RimGeoMechView* selectedGeoMechView(); + static RimEclipseViewCollection* selectedEclipseViewCollection(); }; diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index 5eb216b2d5..5cf14ed840 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -60,6 +60,7 @@ #include "RimEclipseResultCase.h" #include "RimEclipseStatisticsCase.h" #include "RimEclipseView.h" +#include "RimEclipseViewCollection.h" #include "RimElasticProperties.h" #include "RimEllipseFractureTemplate.h" #include "RimEnsembleCurveFilterCollection.h" @@ -282,6 +283,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicComputeStatisticsFeature"; menuBuilder << "Separator"; } + else if ( dynamic_cast( firstUiItem ) ) + { + menuBuilder << "RicNewViewFeature"; + } else if ( dynamic_cast( firstUiItem ) ) { menuBuilder << "RicRenameCaseFeature"; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp index c0a904e64b..e8fe32a5e9 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp @@ -117,6 +117,9 @@ RimEclipseCase::RimEclipseCase() m_resultAddressCollections.uiCapability()->setUiHidden( true ); m_resultAddressCollections.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault( &m_viewCollection, "ViewCollection", "Views" ); + m_viewCollection = new RimEclipseViewCollection; + // Init m_matrixModelResults = new RimReservoirCellResultsStorage; @@ -136,6 +139,7 @@ RimEclipseCase::~RimEclipseCase() delete m_matrixModelResults(); delete m_fractureModelResults(); delete m_inputPropertyCollection; + delete m_viewCollection; RimProject* project = RimProject::current(); if ( project ) @@ -307,9 +311,9 @@ void RimEclipseCase::initAfterRead() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimEclipseView* RimEclipseCase::createAndAddReservoirView() +RimEclipseView* RimEclipseCase::createAndAddReservoirView( bool useGlobalViewCollection ) { - RimEclipseViewCollection* viewColl = viewCollection(); + RimEclipseViewCollection* viewColl = useGlobalViewCollection ? globalViewCollection() : viewCollection(); if ( !viewColl ) return nullptr; return viewColl->addView( this ); @@ -550,6 +554,11 @@ void RimEclipseCase::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin { if ( uiConfigName == "MainWindow.ProjectTree" ) { + for ( auto view : m_viewCollection->views() ) + { + uiTreeOrdering.add( view ); + } + if ( !m_2dIntersectionViewCollection->views().empty() ) { uiTreeOrdering.add( &m_2dIntersectionViewCollection ); @@ -1195,6 +1204,14 @@ void RimEclipseCase::updateResultAddressCollection() /// //-------------------------------------------------------------------------------------------------- RimEclipseViewCollection* RimEclipseCase::viewCollection() const +{ + return m_viewCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseViewCollection* RimEclipseCase::globalViewCollection() const { RimProject* project = RimProject::current(); if ( !project ) return nullptr; @@ -1211,7 +1228,18 @@ RimEclipseViewCollection* RimEclipseCase::viewCollection() const std::vector RimEclipseCase::reservoirViews() const { std::vector views; - if ( RimEclipseViewCollection* viewColl = viewCollection() ) + + addViewsFromViewCollection( views, viewCollection() ); + addViewsFromViewCollection( views, globalViewCollection() ); + return views; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseCase::addViewsFromViewCollection( std::vector& views, const RimEclipseViewCollection* viewColl ) const +{ + if ( viewColl ) { for ( auto view : viewColl->views() ) { @@ -1221,8 +1249,6 @@ std::vector RimEclipseCase::reservoirViews() const } } } - - return views; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h index bcd29f88df..933fc62742 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.h @@ -91,7 +91,7 @@ class RimEclipseCase : public RimCase RimReservoirCellResultsStorage* resultsStorage( RiaDefines::PorosityModelType porosityModel ); const RimReservoirCellResultsStorage* resultsStorage( RiaDefines::PorosityModelType porosityModel ) const; - RimEclipseView* createAndAddReservoirView(); + RimEclipseView* createAndAddReservoirView( bool useGlobalViewCollection = false ); RimEclipseView* createCopyAndAddView( const RimEclipseView* sourceView ); const RigVirtualPerforationTransmissibilities* computeAndGetVirtualPerforationTransmissibilities(); @@ -141,7 +141,9 @@ class RimEclipseCase : public RimCase void setReservoirData( RigEclipseCaseData* eclipseCase ); std::vector additionalFiles() const; RimEclipseViewCollection* viewCollection() const; + RimEclipseViewCollection* globalViewCollection() const; RimEclipseContourMapViewCollection* contourMapViewCollection() const; + void addViewsFromViewCollection( std::vector& views, const RimEclipseViewCollection* viewColl ) const; private: void createTimeStepFormatString(); @@ -168,6 +170,7 @@ class RimEclipseCase : public RimCase caf::PdmChildField m_matrixModelResults; caf::PdmChildField m_fractureModelResults; + caf::PdmChildField m_viewCollection; caf::PdmField> m_filesContainingFaults; diff --git a/ApplicationLibCode/ProjectDataModel/RimGridCollection.cpp b/ApplicationLibCode/ProjectDataModel/RimGridCollection.cpp index 6afed2a8bb..3de30778da 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridCollection.cpp @@ -19,6 +19,7 @@ #include "RimGridCollection.h" #include "RimEclipseCase.h" +#include "RimEclipseView.h" #include "RimGridView.h" #include "RigMainGrid.h" @@ -479,7 +480,10 @@ void RimGridCollection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrde //-------------------------------------------------------------------------------------------------- const RigMainGrid* RimGridCollection::mainEclipseGrid() const { - auto eclipseCase = firstAncestorOrThisOfType(); + RimEclipseView* gridView = firstAncestorOrThisOfType(); + if ( !gridView ) return nullptr; + + auto eclipseCase = gridView->eclipseCase(); return eclipseCase ? eclipseCase->mainGrid() : nullptr; } From 6a9beb5f21f7aa2138655263014c93e6a6b82e95 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 12 Apr 2024 13:36:29 +0200 Subject: [PATCH 3/6] Fix crash when creating contour map from 3d view. --- .../Commands/RicNewContourMapViewFeature.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp b/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp index c5b496630f..38efadedc4 100644 --- a/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp +++ b/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp @@ -273,14 +273,6 @@ RimEclipseContourMapView* RicNewContourMapViewFeature::createEclipseContourMapFr contourMap->synchronizeLocalAnnotationsFromGlobal(); - // Resolve references after contour map has been inserted into Rim structures - std::vector fieldsWithFailingResolve; - contourMap->resolveReferencesRecursively( &fieldsWithFailingResolve ); - - // TODO: Introduce the assert when code is stable - // If we have intersections on well paths, the resolving is now failing - // CVF_ASSERT(fieldsWithFailingResolve.empty()); - contourMap->initAfterReadRecursively(); eclipseCase->contourMapCollection()->updateConnectedEditors(); From 3896f6b350ef7e41d37a1a03efea1d5318ae65f4 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 12 Apr 2024 14:01:45 +0200 Subject: [PATCH 4/6] Show case option in contour map view. --- .../ProjectDataModel/RimEclipseContourMapView.cpp | 2 ++ ApplicationLibCode/ProjectDataModel/RimEclipseView.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp index ab7d42a662..56a6407ede 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseContourMapView.cpp @@ -212,6 +212,8 @@ void RimEclipseContourMapView::defineUiOrdering( QString uiConfigName, caf::PdmU viewGroup->add( &m_showAxisLines ); viewGroup->add( &m_showScaleLegend ); + uiOrdering.add( &m_eclipseCase ); + caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "Contour Map Name" ); nameConfig()->uiOrdering( uiConfigName, *nameGroup ); diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.h b/ApplicationLibCode/ProjectDataModel/RimEclipseView.h index 4ff0b550b4..a5730e9a4b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.h @@ -222,7 +222,8 @@ class RimEclipseView : public RimGridView void propagateEclipseCaseToChildObjects(); protected: - cvf::ref m_faultReactVizModel; + cvf::ref m_faultReactVizModel; + caf::PdmPtrField m_eclipseCase; private: caf::PdmField m_showInvalidCells; @@ -245,7 +246,6 @@ class RimEclipseView : public RimGridView caf::PdmChildField m_propertyFilterCollection; caf::PdmPointer m_overridePropertyFilterCollection; - caf::PdmPtrField m_eclipseCase; caf::PdmPtrField m_customEclipseCase_OBSOLETE; cvf::ref m_reservoirGridPartManager; From 2e3d4e279310907d3dea558c1fbc182bfb52149c Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 12 Apr 2024 14:29:41 +0200 Subject: [PATCH 5/6] Show case option when not in the tree. --- ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp index ac89e2a377..5500a07395 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp @@ -1895,7 +1895,8 @@ void RimEclipseView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& { Rim3dView::defineUiOrdering( uiConfigName, uiOrdering ); - uiOrdering.add( &m_eclipseCase ); + // Only show case option when not under a case in the project tree. + if ( !firstAncestorOrThisOfType() ) uiOrdering.add( &m_eclipseCase ); caf::PdmUiGroup* cellGroup = uiOrdering.addNewGroup( "Cell Visibility" ); cellGroup->add( &m_showInactiveCells ); From 00bacd5a2474f19a9f1355c1f535a422f0335bed Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 12 Apr 2024 14:56:32 +0200 Subject: [PATCH 6/6] Fix update of grid nodes. --- ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp | 9 --------- ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp index e8fe32a5e9..0be60bdcb4 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseCase.cpp @@ -1063,15 +1063,6 @@ bool RimEclipseCase::openReserviorCase() } } - // Update grids node - { - std::vector gridColls = descendantsIncludingThisOfType(); - for ( RimGridCollection* gridCollection : gridColls ) - { - gridCollection->syncFromMainEclipseGrid(); - } - } - return true; } diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp index 5500a07395..1b5edba896 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp @@ -385,6 +385,13 @@ void RimEclipseView::propagateEclipseCaseToChildObjects() faultResultSettings()->customFaultResult()->setEclipseCase( currentEclipseCase ); cellFilterCollection()->setCase( currentEclipseCase ); m_streamlineCollection->setEclipseCase( currentEclipseCase ); + + // Update grids node + std::vector gridColls = descendantsIncludingThisOfType(); + for ( RimGridCollection* gridCollection : gridColls ) + { + gridCollection->syncFromMainEclipseGrid(); + } } //--------------------------------------------------------------------------------------------------