CellFilters: Invert dependency in RimCombinedFilter

Replace the six typed addNewXxxFilter factories with a single generic
addNewFilter<T>(init) template. The combined filter no longer references
any concrete RimCellFilter subclass; callers supply the type and an init
lambda for type-specific configuration, while the combined filter handles
cycle checks, parent-case propagation, signal wiring, and host notification.

Addresses PR #13911 review feedback.
This commit is contained in:
Kristian Bendiksen
2026-04-29 11:40:18 +02:00
parent 9d5a8c28f4
commit 5989785daf
8 changed files with 42 additions and 107 deletions
@@ -26,7 +26,6 @@
#include "RimCombinedFilter.h"
#include "RimGeoMechCase.h"
#include "RimGridView.h"
#include "RimUserDefinedFilter.h"
#include "Riu3DMainWindowTools.h"
#include "cafSelectionManagerTools.h"
@@ -59,9 +58,9 @@ void RicNewCellIndexFilterFeature::onActionTriggered( bool isChecked )
if ( !combined.empty() )
{
RimCombinedFilter* target = combined.front();
if ( RimCase* srcCase = target->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase() )
if ( target->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase() )
{
RimCellIndexFilter* created = target->addNewCellIndexFilter( srcCase );
RimCellIndexFilter* created = target->addNewFilter<RimCellIndexFilter>( []( RimCellIndexFilter* ) {} );
if ( created ) Riu3DMainWindowTools::selectAsCurrentItem( created );
}
return;
@@ -75,16 +75,30 @@ void RicNewPolygonFilterFeature::onActionTriggered( bool isChecked )
RimCase* srcCase = combined->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase();
if ( !srcCase ) return;
auto addOne = [combined]( RimPolygon* polygon )
{
return combined->addNewFilter<RimPolygonFilter>(
[polygon]( RimPolygonFilter* f )
{
f->setPolygon( polygon );
f->configurePolygonEditor();
if ( polygon )
f->enableFilter( true );
else
f->enablePicking( true );
} );
};
RimPolygonFilter* lastItem = nullptr;
if ( polygons.empty() )
{
lastItem = combined->addNewPolygonFilter( srcCase, nullptr );
lastItem = addOne( nullptr );
}
else
{
for ( auto polygon : polygons )
{
lastItem = combined->addNewPolygonFilter( srcCase, polygon );
lastItem = addOne( polygon );
}
}
if ( lastItem ) Riu3DMainWindowTools::selectAsCurrentItem( lastItem );
@@ -58,7 +58,13 @@ void RicNewRangeFilterSliceFeature::onActionTriggered( bool isChecked )
RimCase* srcCase = target->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase();
if ( srcCase )
{
RimCellFilter* created = target->addNewCellRangeFilter( srcCase, 0, m_sliceDirection );
const int sliceDir = m_sliceDirection;
auto* created = target->addNewFilter<RimCellRangeFilter>(
[sliceDir]( RimCellRangeFilter* f )
{
f->setGridIndex( 0 );
f->setDefaultValues( sliceDir, -1 );
} );
if ( created ) Riu3DMainWindowTools::selectAsCurrentItem( created );
}
return;
@@ -45,7 +45,7 @@ void RicNewUserDefinedFilterFeature::onActionTriggered( bool isChecked )
RimCase* srcCase = target->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase();
if ( srcCase )
{
RimUserDefinedFilter* created = target->addNewUserDefinedFilter( srcCase );
RimUserDefinedFilter* created = target->addNewFilter<RimUserDefinedFilter>( []( RimUserDefinedFilter* ) {} );
if ( created ) Riu3DMainWindowTools::selectAsCurrentItem( created );
}
return;
@@ -45,7 +45,7 @@ void RicNewUserDefinedIndexFilterFeature::onActionTriggered( bool isChecked )
RimCase* srcCase = target->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase();
if ( srcCase )
{
auto* created = target->addNewUserDefinedIndexFilter( srcCase );
auto* created = target->addNewFilter<RimUserDefinedIndexFilter>( []( RimUserDefinedIndexFilter* ) {} );
if ( created ) Riu3DMainWindowTools::selectAsCurrentItem( created );
}
return;
@@ -66,7 +66,7 @@ void RicEclipseCombinedPropertyFilterNewFeature::onActionTriggered( bool isCheck
RimCase* srcCase = parent->firstAncestorOrThisOfTypeAsserted<Rim3dView>()->ownerCase();
if ( srcCase )
{
RimCombinedFilter* created = parent->addNewCombinedFilter( srcCase );
RimCombinedFilter* created = parent->addNewFilter<RimCombinedFilter>( []( RimCombinedFilter* ) {} );
parent->updateConnectedEditors();
if ( created ) Riu3DMainWindowTools::selectAsCurrentItem( created );
}
@@ -21,11 +21,6 @@
#include "RigGridBase.h"
#include "RigReservoirGridTools.h"
#include "RimCase.h"
#include "RimCellIndexFilter.h"
#include "RimCellRangeFilter.h"
#include "RimPolygonFilter.h"
#include "RimUserDefinedFilter.h"
#include "RimUserDefinedIndexFilter.h"
#include "Polygons/RimPolygon.h"
#include "Polygons/RimPolygonCollection.h"
@@ -232,85 +227,6 @@ std::vector<RimCellFilter*> RimCombinedFilter::filters() const
return m_filters.childrenByType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellRangeFilter* RimCombinedFilter::addNewCellRangeFilter( RimCase* srcCase, int gridIndex, int sliceDirection, int defaultSlice )
{
auto* f = new RimCellRangeFilter();
addFilter( f );
f->setCase( srcCase );
f->setGridIndex( gridIndex );
f->setDefaultValues( sliceDirection, defaultSlice );
return f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPolygonFilter* RimCombinedFilter::addNewPolygonFilter( RimCase* srcCase, RimPolygon* polygon )
{
auto* f = new RimPolygonFilter();
addFilter( f );
f->setCase( srcCase );
f->setPolygon( polygon );
f->configurePolygonEditor();
if ( polygon )
{
f->enableFilter( true );
}
else
{
f->enablePicking( true );
}
return f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellIndexFilter* RimCombinedFilter::addNewCellIndexFilter( RimCase* srcCase )
{
auto* f = new RimCellIndexFilter();
addFilter( f );
f->setCase( srcCase );
return f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedFilter* RimCombinedFilter::addNewUserDefinedFilter( RimCase* srcCase )
{
auto* f = new RimUserDefinedFilter();
addFilter( f );
f->setCase( srcCase );
return f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedIndexFilter* RimCombinedFilter::addNewUserDefinedIndexFilter( RimCase* srcCase, const std::vector<size_t>& defCellIndexes )
{
auto* f = new RimUserDefinedIndexFilter();
addFilter( f );
f->setCase( srcCase );
f->setCellIndexes( defCellIndexes );
return f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCombinedFilter* RimCombinedFilter::addNewCombinedFilter( RimCase* srcCase )
{
auto* f = new RimCombinedFilter();
addFilter( f );
f->setCase( srcCase );
return f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -25,12 +25,7 @@
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
class RimCellIndexFilter;
class RimCellRangeFilter;
class RimPolygon;
class RimPolygonFilter;
class RimUserDefinedFilter;
class RimUserDefinedIndexFilter;
#include <type_traits>
//==================================================================================================
/// A filter whose result is a boolean combination (AND / OR) of its child filters' results.
@@ -73,14 +68,19 @@ public:
bool hasActiveDynamicPropertyDescendant() const;
bool hasActiveFormationNamesPropertyDescendant() const;
// Typed factory methods — mirror the ones on RimCellFilterCollection so features can add
// children of the correct type directly.
RimCellRangeFilter* addNewCellRangeFilter( RimCase* srcCase, int gridIndex, int sliceDirection = -1, int defaultSlice = -1 );
RimPolygonFilter* addNewPolygonFilter( RimCase* srcCase, RimPolygon* polygon );
RimCellIndexFilter* addNewCellIndexFilter( RimCase* srcCase );
RimUserDefinedFilter* addNewUserDefinedFilter( RimCase* srcCase );
RimUserDefinedIndexFilter* addNewUserDefinedIndexFilter( RimCase* srcCase, const std::vector<size_t>& defCellIndexes = {} );
RimCombinedFilter* addNewCombinedFilter( RimCase* srcCase );
// Generic factory: caller supplies the concrete filter type T and an init callable that
// configures the new instance. The combined filter handles cycle checks, parent-case
// propagation, signal wiring, and host notification — keeping it free of dependencies on
// any specific RimCellFilter subclass.
template <typename T, typename Init>
T* addNewFilter( Init&& init )
{
static_assert( std::is_base_of_v<RimCellFilter, T>, "T must derive from RimCellFilter" );
auto* f = new T();
addFilter( f );
std::forward<Init>( init )( f );
return f;
}
void setCombineMode( CombineMode mode );
CombineMode combineMode() const;