diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.cpp index 0aae29a6b9..4bd29c1ca9 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.cpp @@ -24,6 +24,7 @@ #include "RimDataFilterInView.h" #include "RimEclipseCase.h" #include "RimEclipseView.h" +#include "RimReservoirGridEnsemble.h" #include "cafPdmUiTreeOrdering.h" @@ -159,13 +160,16 @@ bool RimDataFilterInViewCollection::hasActiveFilters() const //-------------------------------------------------------------------------------------------------- void RimDataFilterInViewCollection::initAfterRead() { - // Old project files (predating this branch) don't persist a SourceCollection reference, and - // setSourceCollection() is normally invoked from RimEclipseView::propagateEclipseCaseToChildObjects - // — which only runs when the case is assigned via the setter, not on plain XML load. Resolve the - // case-level data filter collection through the PDM ancestry so wrappers always sync on load. - if ( !m_sourceCollection() ) + // setSourceCollection() is normally invoked from RimEclipseView::propagateEclipseCaseToChildObjects, + // which only runs when the case is assigned via the setter, not on plain XML load. Resolve the + // data filter collection through the PDM ancestry so wrappers always sync with the correct owner. + if ( auto* view = firstAncestorOrThisOfType() ) { - if ( auto* view = firstAncestorOrThisOfType() ) + if ( auto* gridEnsemble = view->firstAncestorOfType() ) + { + m_sourceCollection = gridEnsemble->dataFilterCollection(); + } + else if ( !m_sourceCollection() ) { if ( auto* eclCase = view->eclipseCase() ) m_sourceCollection = eclCase->dataFilterCollection(); } diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.h b/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.h index 7cd4561965..555e07cd57 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.h +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimDataFilterInViewCollection.h @@ -29,10 +29,10 @@ class RimDataFilterCollection; class RimDataFilterInView; //================================================================================================== -/// View-level collection of RimDataFilterInView wrappers, one per case-level filter. Auto-syncs -/// with the case-level RimDataFilterCollection (mirroring RimSurfaceInViewCollection's pattern): -/// new wrappers default to checked, removed source filters drop their wrappers, and the wrapper -/// list follows the case order. +/// View-level collection of RimDataFilterInView wrappers, one per source filter. Auto-syncs with +/// the case- or ensemble-level RimDataFilterCollection (mirroring RimSurfaceInViewCollection's +/// pattern): new wrappers default to checked, removed source filters drop their wrappers, and the +/// wrapper list follows the source order. //================================================================================================== class RimDataFilterInViewCollection : public RimCheckableNamedObject { diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp index 861dbf1e01..ea19c3b416 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp @@ -90,6 +90,7 @@ #include "RimRefinementRegionCollection.h" #include "RimRegularLegendConfig.h" #include "RimReservoirCellResultsStorage.h" +#include "RimReservoirGridEnsemble.h" #include "RimSeismicSection.h" #include "RimSeismicSectionCollection.h" #include "RimSimWellInView.h" @@ -451,7 +452,12 @@ void RimEclipseView::propagateEclipseCaseToChildObjects() if ( m_dataFiltersInView() ) { - m_dataFiltersInView()->setSourceCollection( currentEclipseCase ? currentEclipseCase->dataFilterCollection() : nullptr ); + auto* sourceCollection = currentEclipseCase ? currentEclipseCase->dataFilterCollection() : nullptr; + if ( auto* gridEnsemble = firstAncestorOfType() ) + { + sourceCollection = gridEnsemble->dataFilterCollection(); + } + m_dataFiltersInView()->setSourceCollection( sourceCollection ); } // Update grids node diff --git a/ApplicationLibCode/ProjectDataModel/RimReservoirGridEnsemble.cpp b/ApplicationLibCode/ProjectDataModel/RimReservoirGridEnsemble.cpp index f5c178918a..75ef60947b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimReservoirGridEnsemble.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimReservoirGridEnsemble.cpp @@ -40,6 +40,7 @@ #include "Rim2dIntersectionViewCollection.h" #include "RimCaseCollection.h" #include "RimDataFilterCollection.h" +#include "RimDataFilterInViewCollection.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseResultCase.h" @@ -491,6 +492,7 @@ RimEclipseStatisticsCase* RimReservoirGridEnsemble::createAndAppendStatisticsCas void RimReservoirGridEnsemble::addView( RimEclipseView* view ) { m_viewCollection->addView( view ); + view->dataFiltersInView()->setSourceCollection( m_dataFilterCollection() ); } //-------------------------------------------------------------------------------------------------- @@ -498,7 +500,9 @@ void RimReservoirGridEnsemble::addView( RimEclipseView* view ) //-------------------------------------------------------------------------------------------------- RimEclipseView* RimReservoirGridEnsemble::addViewForCase( RimEclipseCase* eclipseCase ) { - return m_viewCollection->addView( eclipseCase ); + auto* view = m_viewCollection->addView( eclipseCase ); + view->dataFiltersInView()->setSourceCollection( m_dataFilterCollection() ); + return view; } //-------------------------------------------------------------------------------------------------- @@ -685,8 +689,8 @@ RimDataFilterCollection* RimReservoirGridEnsemble::dataFilterCollection() const //-------------------------------------------------------------------------------------------------- /// The filters in the collection need a source case for configuration (result meta data, grid -/// geometry). Use the main case of the ensemble. Evaluation of the filters is done per case, see -/// RimCellFilterTools::computeReservoirCellVisibility. +/// geometry). Use the main case of the ensemble. Ensemble views evaluate the filters using their +/// current case. //-------------------------------------------------------------------------------------------------- void RimReservoirGridEnsemble::updateDataFilterCollectionCase() { diff --git a/ApplicationLibCode/UnitTests/RimDataFilterCollection-Test.cpp b/ApplicationLibCode/UnitTests/RimDataFilterCollection-Test.cpp index e78a22f170..932ab3c9b7 100644 --- a/ApplicationLibCode/UnitTests/RimDataFilterCollection-Test.cpp +++ b/ApplicationLibCode/UnitTests/RimDataFilterCollection-Test.cpp @@ -18,10 +18,15 @@ #include "gtest/gtest.h" +#include "RigActiveCellInfo.h" #include "RimCellFilter.h" #include "RimCellRangeFilter.h" #include "RimCombinedFilter.h" #include "RimDataFilterCollection.h" +#include "RimDataFilterInViewCollection.h" +#include "RimEclipseResultCase.h" +#include "RimEclipseView.h" +#include "RimReservoirGridEnsemble.h" #include "cafSignal.h" @@ -225,3 +230,19 @@ TEST( RimDataFilterCollection, pdmRoundTripPreservesFilters ) EXPECT_NE( nullptr, dynamic_cast( items[0] ) ); EXPECT_NE( nullptr, dynamic_cast( items[1] ) ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RimDataFilterCollection, ensembleViewUsesEnsembleDataFilters ) +{ + auto eclipseCase = std::make_unique(); + auto ensemble = std::make_unique(); + auto* view = new RimEclipseView(); + + view->setEclipseCase( eclipseCase.get() ); + EXPECT_EQ( eclipseCase->dataFilterCollection(), view->dataFiltersInView()->sourceCollection() ); + + ensemble->addView( view ); + EXPECT_EQ( ensemble->dataFilterCollection(), view->dataFiltersInView()->sourceCollection() ); +}