Improve handling of LGRs in cell filters (#7783)

* Improve handling of LGRs in cell filters
This commit is contained in:
jonjenssen 2021-06-16 17:31:25 +02:00 committed by GitHub
parent 24c2eeb022
commit a4fd24a15a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 163 additions and 83 deletions

View File

@ -72,10 +72,9 @@ void RicNewRangeFilterSlice3dviewFeature::onActionTriggered( bool isChecked )
int sliceStart = list[1].toInt();
int gridIndex = list[2].toInt();
RimCellFilter* newFilter = filtColl->addNewCellRangeFilter( sourceCase, direction, sliceStart );
RimCellFilter* newFilter = filtColl->addNewCellRangeFilter( sourceCase, gridIndex, direction, sliceStart );
if ( newFilter )
{
newFilter->setGridIndex( gridIndex );
Riu3DMainWindowTools::selectAsCurrentItem( newFilter );
activeView->setSurfaceDrawstyle();
}

View File

@ -56,7 +56,8 @@ void RicNewRangeFilterSliceFeature::onActionTriggered( bool isChecked )
RimCase* sourceCase = nullptr;
filtColl->firstAncestorOrThisOfTypeAsserted( sourceCase );
RimCellFilter* lastCreatedOrUpdated = filtColl->addNewCellRangeFilter( sourceCase, m_sliceDirection );
int gridIndex = 0;
RimCellFilter* lastCreatedOrUpdated = filtColl->addNewCellRangeFilter( sourceCase, gridIndex, m_sliceDirection );
if ( lastCreatedOrUpdated )
{
Riu3DMainWindowTools::selectAsCurrentItem( lastCreatedOrUpdated );

View File

@ -262,7 +262,8 @@ void RicAdvancedSnapshotExportFeature::exportViewVariationsToFolder( RimGridView
}
else
{
RimCellRangeFilter* rangeFilter = rimView->cellFilterCollection()->addNewCellRangeFilter( rimCase );
int gridIndex = 0;
RimCellRangeFilter* rangeFilter = rimView->cellFilterCollection()->addNewCellRangeFilter( rimCase, gridIndex );
bool rangeFilterInitState = rimView->cellFilterCollection()->isActive();
rimView->cellFilterCollection()->setActive( true );

View File

@ -210,7 +210,6 @@ void RimCellFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
auto group = uiOrdering.addNewGroup( "General" );
group->add( &m_filterMode );
group->add( &m_gridIndex );
group->add( &m_propagateToSubGrids );
bool readOnlyState = isFilterControlled();

View File

@ -69,7 +69,7 @@ public:
void updateIconState();
void updateActiveState( bool isControlled );
virtual void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter ) = 0;
virtual void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) = 0;
virtual QString fullName() const;
protected:

View File

@ -263,10 +263,12 @@ RimUserDefinedFilter* RimCellFilterCollection::addNewUserDefinedFilter( RimCase*
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellRangeFilter* RimCellFilterCollection::addNewCellRangeFilter( RimCase* srcCase, int sliceDirection, int defaultSlice )
RimCellRangeFilter*
RimCellFilterCollection::addNewCellRangeFilter( RimCase* srcCase, int gridIndex, int sliceDirection, int defaultSlice )
{
RimCellRangeFilter* pFilter = new RimCellRangeFilter();
addFilter( pFilter );
pFilter->setGridIndex( gridIndex );
pFilter->setDefaultValues( sliceDirection, defaultSlice );
onFilterUpdated( pFilter );
return pFilter;
@ -369,11 +371,13 @@ void RimCellFilterCollection::compoundCellRangeFilter( cvf::CellRangeFilter* cel
{
CVF_ASSERT( cellRangeFilter );
int gIndx = static_cast<int>( gridIndex );
for ( RimCellFilter* filter : m_cellFilters )
{
if ( filter->isFilterEnabled() && static_cast<size_t>( filter->gridIndex() ) == gridIndex )
if ( filter->isFilterEnabled() )
{
filter->updateCompundFilter( cellRangeFilter );
filter->updateCompundFilter( cellRangeFilter, gIndx );
}
}
}

View File

@ -47,7 +47,8 @@ public:
RimPolygonFilter* addNewPolygonFilter( RimCase* srcCase );
RimUserDefinedFilter* addNewUserDefinedFilter( RimCase* srcCase );
RimCellRangeFilter* addNewCellRangeFilter( RimCase* srcCase, int sliceDirection = -1, int defaultSlice = -1 );
RimCellRangeFilter*
addNewCellRangeFilter( RimCase* srcCase, int gridIndex, int sliceDirection = -1, int defaultSlice = -1 );
void removeFilter( RimCellFilter* filter );
@ -71,12 +72,12 @@ public:
void setCase( RimCase* theCase );
protected:
// Overridden methods
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
caf::PdmFieldHandle* objectToggleField() override;
void initAfterRead() override;
void onFilterUpdated( const SignalEmitter* emitter );
void onFilterUpdated( const SignalEmitter* emitter );
private:
void setAutoName( RimCellFilter* pFilter );

View File

@ -58,6 +58,8 @@ RimCellRangeFilter::RimCellRangeFilter()
CAF_PDM_InitField( &cellCountK, "CellCountK", 1, "Cell Count K", "", "", "" );
cellCountK.uiCapability()->setUiEditorTypeName( caf::PdmUiSliderEditor::uiEditorTypeName() );
m_propagateToSubGrids = true;
updateIconState();
setDeletable( true );
}
@ -265,6 +267,8 @@ void RimCellRangeFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
{
RimCellFilter::defineUiOrdering( uiConfigName, uiOrdering );
m_gridIndex.uiCapability()->setUiReadOnly( true );
const cvf::StructGridInterface* grid = selectedGrid();
RimCase* rimCase = nullptr;
@ -332,10 +336,12 @@ void RimCellRangeFilter::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrd
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellRangeFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter )
void RimCellRangeFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex )
{
CVF_ASSERT( cellRangeFilter );
if ( gridIndex != m_gridIndex ) return;
if ( filterMode() == RimCellFilter::INCLUDE )
{
cellRangeFilter->addCellIncludeRange( static_cast<size_t>( startIndexI ) - 1,

View File

@ -57,7 +57,7 @@ public:
void setDefaultValues( int sliceDirection = -1, int defaultSlice = -1 );
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter ) override;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) override;
protected:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;

View File

@ -26,6 +26,7 @@
#include "RigGeoMechCaseData.h"
#include "RigMainGrid.h"
#include "RigPolyLinesData.h"
#include "RigReservoirGridTools.h"
#include "Rim3dView.h"
#include "RimCase.h"
@ -161,6 +162,8 @@ RimPolygonFilter::RimPolygonFilter()
this->setUi3dEditorTypeName( RicPolyline3dEditor::uiEditorTypeName() );
this->uiCapability()->setUiTreeChildrenHidden( true );
m_propagateToSubGrids = false;
updateIconState();
setDeletable( true );
}
@ -237,7 +240,12 @@ QString RimPolygonFilter::fullName() const
{
if ( m_enableFiltering )
{
return QString( "%1 [%2 cells]" ).arg( RimCellFilter::fullName(), QString::number( m_cells.size() ) );
int cells = 0;
for ( const auto& item : m_cells )
{
cells += (int)item.size();
}
return QString( "%1 [%2 cells]" ).arg( RimCellFilter::fullName(), QString::number( cells ) );
}
return QString( "%1 [off]" ).arg( RimCellFilter::fullName() );
}
@ -399,8 +407,6 @@ void RimPolygonFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin
auto group3 = uiOrdering.addNewGroup( "Advanced Filter Settings" );
group3->add( &m_enableKFilter );
group3->add( &m_kFilterStr );
group3->add( &m_gridIndex );
group3->add( &m_propagateToSubGrids );
group3->setCollapsedByDefault( true );
uiOrdering.skipRemainingFields( true );
@ -468,18 +474,24 @@ caf::PickEventHandler* RimPolygonFilter::pickEventHandler() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter )
void RimPolygonFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex )
{
CVF_ASSERT( cellRangeFilter );
if ( !m_enableFiltering ) return;
if ( m_cells.size() == 0 ) updateCells();
const int noofgrids = static_cast<int>( m_cells.size() );
if ( ( noofgrids == 0 ) || ( gridIndex >= noofgrids ) )
{
updateCells();
}
const auto grid = selectedGrid();
if ( gridIndex >= static_cast<int>( m_cells.size() ) ) return;
const auto grid = RigReservoirGridTools::gridByIndex( m_srcCase, gridIndex );
size_t i, j, k;
for ( size_t cellidx : m_cells )
for ( size_t cellidx : m_cells[gridIndex] )
{
grid->ijkFromCellIndex( cellidx, &i, &j, &k );
if ( this->filterMode() == RimCellFilter::INCLUDE )
@ -531,14 +543,15 @@ bool RimPolygonFilter::cellInsidePolygon2D( cvf::Vec3d center,
return bInside;
}
void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& points, const RigMainGrid* grid )
void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& points, const RigGridBase* grid )
{
// we should look in depth using Z coordinate
const int gIdx = static_cast<int>( grid->gridIndex() );
// loop over all cells
for ( size_t n = 0; n < grid->cellCount(); n++ )
{
// valid cell?
RigCell cell = grid->cellByGridAndGridLocalCellIdx( gridIndex(), n );
RigCell cell = grid->cell( n );
if ( cell.isInvalid() ) continue;
// get corner coordinates
@ -553,7 +566,7 @@ void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& p
// check if the polygon includes the cell
if ( cellInsidePolygon2D( cell.center(), hexCorners, points ) )
{
m_cells.push_back( n );
m_cells[gIdx].push_back( n );
}
}
}
@ -564,50 +577,19 @@ void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& p
// 2. find all cells in this K layer that matches the selection criteria
// 3. extend those cells to all K layers
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>& points, const RigMainGrid* grid )
void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>& points, const RigGridBase* grid, int K )
{
// we need to find the K layer we hit with the first point
size_t ni, nj, nk;
// move the point a bit downwards to make sure it is inside something
cvf::Vec3d point = points[0];
point.z() += 0.2;
bool cellFound = false;
// loop over all points to find at least one point with a valid K layer
for ( size_t p = 0; p < points.size() - 1; p++ )
{
// loop over all cells to find the correct one
for ( size_t i = 0; i < grid->cellCount(); i++ )
{
// valid cell?
RigCell cell = grid->cellByGridAndGridLocalCellIdx( gridIndex(), i );
if ( cell.isInvalid() ) continue;
// is the point inside?
cvf::BoundingBox bb = cell.boundingBox();
if ( !bb.contains( points[p] ) ) continue;
// found the cell, get the IJK
grid->ijkFromCellIndexUnguarded( cell.mainGridCellIndex(), &ni, &nj, &nk );
cellFound = true;
break;
}
if ( cellFound ) break;
}
// should not really happen, but just to be sure
if ( !cellFound ) return;
const int gIdx = static_cast<int>( grid->gridIndex() );
std::list<size_t> foundCells;
// find all cells in this K layer that matches the polygon
// find all cells in the K layer that matches the polygon
for ( size_t i = 0; i < grid->cellCountI(); i++ )
{
for ( size_t j = 0; j < grid->cellCountJ(); j++ )
{
size_t cellIdx = grid->cellIndexFromIJK( i, j, nk );
RigCell cell = grid->cellByGridAndGridLocalCellIdx( gridIndex(), cellIdx );
size_t cellIdx = grid->cellIndexFromIJK( i, j, K );
RigCell cell = grid->cell( cellIdx );
// valid cell?
if ( cell.isInvalid() ) continue;
@ -636,10 +618,10 @@ void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>&
// get the cell index
size_t newIdx = grid->cellIndexFromIJK( ci, cj, k );
// valid cell?
RigCell cell = grid->cellByGridAndGridLocalCellIdx( gridIndex(), newIdx );
RigCell cell = grid->cell( newIdx );
if ( cell.isInvalid() ) continue;
m_cells.push_back( newIdx );
m_cells[gIdx].push_back( newIdx );
}
}
}
@ -652,16 +634,24 @@ void RimPolygonFilter::updateCellsForEclipse( const std::vector<cvf::Vec3d>& poi
RigEclipseCaseData* data = eCase->eclipseCaseData();
if ( !data ) return;
RigMainGrid* grid = data->mainGrid();
if ( !grid ) return;
if ( m_polyFilterMode == PolygonFilterModeType::DEPTH_Z )
{
updateCellsDepthEclipse( points, grid );
for ( size_t gridIndex = 0; gridIndex < data->gridCount(); gridIndex++ )
{
auto grid = data->grid( gridIndex );
updateCellsDepthEclipse( points, grid );
}
}
else if ( m_polyFilterMode == PolygonFilterModeType::INDEX_K )
{
updateCellsKIndexEclipse( points, grid );
int K = findEclipseKLayer( points, data );
if ( K < 0 ) return;
for ( size_t gridIndex = 0; gridIndex < data->gridCount(); gridIndex++ )
{
auto grid = data->grid( gridIndex );
updateCellsKIndexEclipse( points, grid, K );
}
}
}
@ -693,7 +683,7 @@ void RimPolygonFilter::updateCellsDepthGeoMech( const std::vector<cvf::Vec3d>& p
// check if the polygon includes the cell
if ( cellInsidePolygon2D( center, corners, points ) )
{
m_cells.push_back( cellIdx );
m_cells[0].push_back( cellIdx );
}
}
}
@ -787,7 +777,7 @@ void RimPolygonFilter::updateCellsKIndexGeoMech( const std::vector<cvf::Vec3d>&
// get the cell index
size_t newIdx = grid->cellIndexFromIJK( ci, cj, k );
m_cells.push_back( newIdx );
m_cells[0].push_back( newIdx );
}
}
}
@ -813,12 +803,12 @@ void RimPolygonFilter::updateCellsForGeoMech( const std::vector<cvf::Vec3d>& poi
}
//--------------------------------------------------------------------------------------------------
/// Update the cell index list with the cells that are inside our polygon, if any
/// Update the cell index map with the cells that are inside our polygon, if any
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::updateCells()
{
// reset
m_cells.clear();
// reset cell map for all grids
initializeCellList();
// get optional k-cell filter
m_intervalTool.setInterval( m_enableKFilter, m_kFilterStr );
@ -833,7 +823,7 @@ void RimPolygonFilter::updateCells()
// We need at least three points to make a sensible polygon
if ( points.size() < 3 ) return;
// make sure first and last point is the same (req. by polygon methods later)
// make sure first and last point is the same (req. by polygon methods used later)
points.push_back( points.front() );
RimEclipseCase* eCase = dynamic_cast<RimEclipseCase*>( m_srcCase() );
@ -877,3 +867,72 @@ cvf::ref<RigPolyLinesData> RimPolygonFilter::polyLinesData() const
return pld;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::initializeCellList()
{
m_cells.clear();
int gridCount = RigReservoirGridTools::gridCount( m_srcCase() );
for ( int i = 0; i < gridCount; i++ )
{
m_cells.push_back( std::vector<size_t>() );
}
}
//--------------------------------------------------------------------------------------------------
/// Find which K layer we hit, in any of the grids, for any of the selected points
//--------------------------------------------------------------------------------------------------
int RimPolygonFilter::findEclipseKLayer( const std::vector<cvf::Vec3d>& points, RigEclipseCaseData* data )
{
size_t ni, nj, nk;
// look for a hit in the main grid frist
RigMainGrid* mainGrid = data->mainGrid();
for ( size_t p = 0; p < points.size() - 1; p++ )
{
size_t cIdx = mainGrid->findReservoirCellIndexFromPoint( points[p] );
if ( cIdx != cvf::UNDEFINED_SIZE_T )
{
mainGrid->ijkFromCellIndexUnguarded( cIdx, &ni, &nj, &nk );
if ( mainGrid->isCellValid( ni, nj, nk ) ) return static_cast<int>( nk );
}
}
// loop over all sub-grids to find one with a cell hit in case main grid search failed
for ( size_t gridIndex = 1; gridIndex < data->gridCount(); gridIndex++ )
{
auto grid = data->grid( gridIndex );
// loop over all cells to find the correct one
for ( size_t i = 0; i < grid->cellCount(); i++ )
{
// valid cell?
RigCell cell = grid->cell( i );
if ( cell.isInvalid() ) continue;
// is the point inside cell bb?
cvf::BoundingBox bb;
std::array<cvf::Vec3d, 8> hexCorners;
grid->cellCornerVertices( i, hexCorners.data() );
for ( const auto& corner : hexCorners )
{
bb.add( corner );
}
// loop over all points to find at least one point with a valid K layer
for ( size_t p = 0; p < points.size() - 1; p++ )
{
if ( bb.contains( points[p] ) )
{
// found the cell, get the IJK
grid->ijkFromCellIndexUnguarded( i, &ni, &nj, &nk );
return static_cast<int>( nk );
}
}
}
}
return -1;
}

View File

@ -42,9 +42,11 @@ class RimPolylineTarget;
class RimCase;
class RimEclipseCase;
class RimGeoMechCase;
class RigGridBase;
class RigMainGrid;
class RigFemPartGrid;
class RigPolylinesData;
class RigEclipseCaseData;
//==================================================================================================
///
@ -87,7 +89,7 @@ public:
bool pickingEnabled() const override;
caf::PickEventHandler* pickEventHandler() const override;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter ) override;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) override;
cvf::ref<RigPolyLinesData> polyLinesData() const override;
@ -108,13 +110,17 @@ private:
void updateCellsForEclipse( const std::vector<cvf::Vec3d>& points, RimEclipseCase* eCase );
void updateCellsForGeoMech( const std::vector<cvf::Vec3d>& points, RimGeoMechCase* gCase );
void updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& points, const RigMainGrid* grid );
void updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>& points, const RigMainGrid* grid );
void updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& points, const RigGridBase* grid );
void updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>& points, const RigGridBase* grid, int K );
int findEclipseKLayer( const std::vector<cvf::Vec3d>& points, RigEclipseCaseData* data );
void updateCellsDepthGeoMech( const std::vector<cvf::Vec3d>& points, const RigFemPartGrid* grid );
void updateCellsKIndexGeoMech( const std::vector<cvf::Vec3d>& points, const RigFemPartGrid* grid );
bool cellInsidePolygon2D( cvf::Vec3d center, std::array<cvf::Vec3d, 8>& corners, std::vector<cvf::Vec3d> polygon );
void initializeCellList();
caf::PdmField<bool> m_enablePicking;
caf::PdmChildArrayField<RimPolylineTarget*> m_targets;
caf::PdmField<caf::AppEnum<PolygonFilterModeType>> m_polyFilterMode;
@ -134,7 +140,7 @@ private:
std::shared_ptr<RicPolylineTargetsPickEventHandler> m_pickTargetsEventHandler;
std::list<size_t> m_cells;
std::vector<std::vector<size_t>> m_cells;
RimCellFilterIntervalTool m_intervalTool;
};

View File

@ -34,7 +34,7 @@ public:
std::vector<int> selectedCategoryValues() const;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter ) override{};
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) override{};
protected:
void setCategoryValues( const std::vector<int>& categoryValues );

View File

@ -35,6 +35,8 @@ RimUserDefinedFilter::RimUserDefinedFilter()
"Use Ctrl-C for copy and Ctrl-V for paste",
"" );
m_propagateToSubGrids = true;
updateIconState();
setDeletable( true );
}
@ -85,10 +87,12 @@ void RimUserDefinedFilter::fieldChangedByUi( const caf::PdmFieldHandle* changedF
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter )
void RimUserDefinedFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex )
{
CVF_ASSERT( cellRangeFilter );
if ( gridIndex != m_gridIndex ) return;
if ( this->filterMode() == RimCellFilter::INCLUDE )
{
for ( const auto& cellIndex : m_individualCellIndices() )

View File

@ -37,7 +37,7 @@ public:
RimUserDefinedFilter();
~RimUserDefinedFilter() override;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter ) override;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) override;
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;

View File

@ -430,9 +430,9 @@ cvf::BoundingBox RigCell::boundingBox() const
cvf::BoundingBox bb;
std::array<cvf::Vec3d, 8> hexCorners;
if ( m_hostGrid && m_hostGrid->mainGrid() )
if ( m_hostGrid )
{
m_hostGrid->mainGrid()->cellCornerVertices( mainGridCellIndex(), hexCorners.data() );
m_hostGrid->cellCornerVertices( m_gridLocalCellIndex, hexCorners.data() );
for ( const auto& corner : hexCorners )
{
bb.add( corner );
@ -442,7 +442,7 @@ cvf::BoundingBox RigCell::boundingBox() const
}
//--------------------------------------------------------------------------------------------------
/// Return the neighbor cell of the given face
/// Return the main grid neighbor cell of the given face
//--------------------------------------------------------------------------------------------------
RigCell RigCell::neighborCell( cvf::StructGridInterface::FaceType face ) const
{