Cell filter performance improvement (#10550)

* Speed up eclipse and geomech cell filters
This commit is contained in:
jonjenssen 2023-08-29 14:41:55 +02:00 committed by GitHub
parent 81809efee9
commit 0a807618b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 217 additions and 50 deletions

View File

@ -54,34 +54,61 @@ void RivFemElmVisibilityCalculator::computeAllVisible( cvf::UByteArray* elmVisib
//--------------------------------------------------------------------------------------------------
void RivFemElmVisibilityCalculator::computeRangeVisibility( cvf::UByteArray* elmVisibilities,
const RigFemPart* femPart,
const cvf::CellRangeFilter& rangeFilter )
const cvf::CellRangeFilter& rangeFilter,
const cvf::UByteArray* indexIncludeVisibility,
const cvf::UByteArray* indexExcludeVisibility,
bool useIndexInclude )
{
elmVisibilities->resize( femPart->elementCount() );
const RigFemPartGrid* grid = femPart->getOrCreateStructGrid();
size_t mainGridI;
size_t mainGridJ;
size_t mainGridK;
if ( rangeFilter.hasIncludeRanges() )
{
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
if ( useIndexInclude )
{
size_t mainGridI;
size_t mainGridJ;
size_t mainGridK;
grid->ijkFromCellIndex( elmIdx, &mainGridI, &mainGridJ, &mainGridK );
( *elmVisibilities )[elmIdx] = rangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, false );
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
{
grid->ijkFromCellIndex( elmIdx, &mainGridI, &mainGridJ, &mainGridK );
( *elmVisibilities )[elmIdx] =
( ( *indexIncludeVisibility )[elmIdx] || rangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, false ) ) &&
( *indexExcludeVisibility )[elmIdx];
}
}
else
{
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
{
grid->ijkFromCellIndex( elmIdx, &mainGridI, &mainGridJ, &mainGridK );
( *elmVisibilities )[elmIdx] = rangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, false ) &&
( *indexExcludeVisibility )[elmIdx];
}
}
}
else
{
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
if ( useIndexInclude )
{
size_t mainGridI;
size_t mainGridJ;
size_t mainGridK;
grid->ijkFromCellIndex( elmIdx, &mainGridI, &mainGridJ, &mainGridK );
( *elmVisibilities )[elmIdx] = !rangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, false );
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
{
grid->ijkFromCellIndex( elmIdx, &mainGridI, &mainGridJ, &mainGridK );
( *elmVisibilities )[elmIdx] = ( *indexIncludeVisibility )[elmIdx] &&
!rangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, false ) &&
( *indexExcludeVisibility )[elmIdx];
}
}
else
{
for ( int elmIdx = 0; elmIdx < femPart->elementCount(); ++elmIdx )
{
grid->ijkFromCellIndex( elmIdx, &mainGridI, &mainGridJ, &mainGridK );
( *elmVisibilities )[elmIdx] = !rangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, false ) &&
( *indexExcludeVisibility )[elmIdx];
}
}
}
}

View File

@ -36,7 +36,12 @@ class RivFemElmVisibilityCalculator
{
public:
static void computeAllVisible( cvf::UByteArray* elmVisibilities, const RigFemPart* femPart );
static void computeRangeVisibility( cvf::UByteArray* elmVisibilities, const RigFemPart* femPart, const cvf::CellRangeFilter& rangeFilter );
static void computeRangeVisibility( cvf::UByteArray* elmVisibilities,
const RigFemPart* femPart,
const cvf::CellRangeFilter& rangeFilter,
const cvf::UByteArray* indexIncludeVisibility,
const cvf::UByteArray* indexExcludeVisibility,
bool useIndexInclude );
static void computePropertyVisibility( cvf::UByteArray* cellVisibility,
const RigFemPart* grid,

View File

@ -239,7 +239,19 @@ RivGeoMechPartMgr* RivGeoMechVizLogic::getUpdatedPartMgr( RivGeoMechPartMgrCache
{
cvf::CellRangeFilter cellRangeFilter;
m_geomechView->cellFilterCollection()->compoundCellRangeFilter( &cellRangeFilter, femPartIdx );
RivFemElmVisibilityCalculator::computeRangeVisibility( elmVisibility.p(), caseData->femParts()->part( femPartIdx ), cellRangeFilter );
auto femPart = caseData->femParts()->part( femPartIdx );
cvf::UByteArray indexIncludeVisibility( femPart->elementCount() );
cvf::UByteArray indexExcludeVisibility( femPart->elementCount() );
m_geomechView->cellFilterCollection()->updateCellVisibilityByIndex( &indexIncludeVisibility, &indexExcludeVisibility, femPartIdx );
RivFemElmVisibilityCalculator::computeRangeVisibility( elmVisibility.p(),
femPart,
cellRangeFilter,
&indexIncludeVisibility,
&indexExcludeVisibility,
m_geomechView->cellFilterCollection()->hasActiveIncludeIndexFilters() );
}
else if ( pMgrKey.geometryType() == PROPERTY_FILTERED )
{

View File

@ -720,9 +720,13 @@ void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum
if ( cellFilterColl->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells() )
{
cvf::UByteArray indexIncludeVisibility = ( *cellVisibility );
cvf::UByteArray indexExcludeVisibility = ( *cellVisibility );
// Build cell filter for current grid
cvf::CellRangeFilter gridCellRangeFilter;
cellFilterColl->compoundCellRangeFilter( &gridCellRangeFilter, grid->gridIndex() );
cellFilterColl->updateCellVisibilityByIndex( &indexIncludeVisibility, &indexExcludeVisibility, grid->gridIndex() );
const RigLocalGrid* lgr = nullptr;
cvf::ref<cvf::UByteArray> parentGridVisibilities;
@ -745,7 +749,9 @@ void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum
parentGridVisibilities = reservoirGridPartMgr->cellVisibility( parentGridIndex );
}
bool hasAdditiveFilters = cellFilterColl->hasActiveIncludeFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells();
bool hasAdditiveRangeFilters = cellFilterColl->hasActiveIncludeRangeFilters() ||
m_reservoirView->wellCollection()->hasVisibleWellCells();
bool hasAdditiveIndexFilters = cellFilterColl->hasActiveIncludeIndexFilters();
#pragma omp parallel for
for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
@ -770,18 +776,26 @@ void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum
bool nativeRangeVisibility = false;
if ( hasAdditiveFilters )
if ( hasAdditiveRangeFilters )
{
nativeRangeVisibility = gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
if ( hasAdditiveIndexFilters )
{
nativeRangeVisibility = indexIncludeVisibility[cellIndex] ||
gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
}
else
{
nativeRangeVisibility = gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
}
}
else
{
// Special handling when no include filters are present. Use native visibility
nativeRangeVisibility = ( *nativeVisibility )[cellIndex];
nativeRangeVisibility = indexIncludeVisibility[cellIndex];
}
( *cellVisibility )[cellIndex] = ( visibleDueToParentGrid || nativeRangeVisibility ) &&
!gridCellRangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
!gridCellRangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, isInSubGridArea ) &&
indexExcludeVisibility[cellIndex];
}
}
}

View File

@ -42,8 +42,9 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimCellFilter, "CellFilter", "CellFilter" ); /
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCellFilter::RimCellFilter()
RimCellFilter::RimCellFilter( FilterDefinitionType defType )
: filterChanged( this )
, m_filterDefinitionType( defType )
{
CAF_PDM_InitObject( "Cell Filter" );
@ -130,6 +131,22 @@ bool RimCellFilter::isFilterEnabled() const
return m_isActive();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCellFilter::isRangeFilter() const
{
return m_filterDefinitionType == FilterDefinitionType::RANGE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCellFilter::isIndexFilter() const
{
return m_filterDefinitionType == FilterDefinitionType::INDEX;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -24,6 +24,8 @@
#include "cafPdmProxyValueField.h"
#include "cafSignal.h"
#include "cvfArray.h"
namespace cvf
{
class StructGridInterface;
@ -45,9 +47,16 @@ public:
EXCLUDE
};
enum FilterDefinitionType
{
RANGE,
INDEX,
PROPERTY
};
caf::Signal<> filterChanged;
RimCellFilter();
RimCellFilter( FilterDefinitionType defType );
~RimCellFilter() override;
QString name() const;
@ -56,6 +65,9 @@ public:
bool isActive() const;
void setActive( bool active );
bool isRangeFilter() const;
bool isIndexFilter() const;
virtual bool isFilterEnabled() const;
caf::AppEnum<FilterModeType> filterMode() const;
@ -69,7 +81,8 @@ public:
void updateIconState();
void updateActiveState( bool isControlled );
virtual void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) = 0;
virtual void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ){};
virtual void updateCellIndexFilter( cvf::UByteArray* includeVisibility, cvf::UByteArray* excludeVisibility, int gridIndex ){};
virtual QString fullName() const;
protected:
@ -88,4 +101,7 @@ protected:
caf::PdmField<caf::AppEnum<FilterModeType>> m_filterMode;
caf::PdmField<int> m_gridIndex;
caf::PdmField<bool> m_propagateToSubGrids;
private:
FilterDefinitionType m_filterDefinitionType;
};

View File

@ -220,13 +220,28 @@ bool RimCellFilterCollection::hasActiveFilters() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCellFilterCollection::hasActiveIncludeFilters() const
bool RimCellFilterCollection::hasActiveIncludeIndexFilters() const
{
if ( !isActive() ) return false;
for ( const auto& filter : m_cellFilters )
{
if ( filter->isFilterEnabled() && filter->filterMode() == RimCellFilter::INCLUDE ) return true;
if ( filter->isFilterEnabled() && filter->isIndexFilter() && filter->filterMode() == RimCellFilter::INCLUDE ) return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCellFilterCollection::hasActiveIncludeRangeFilters() const
{
if ( !isActive() ) return false;
for ( const auto& filter : m_cellFilters )
{
if ( filter->isFilterEnabled() && filter->isRangeFilter() && filter->filterMode() == RimCellFilter::INCLUDE ) return true;
}
return false;
@ -360,7 +375,7 @@ void RimCellFilterCollection::onFilterUpdated( const SignalEmitter* emitter )
}
//--------------------------------------------------------------------------------------------------
/// Populate the given view filter with info from our filters
/// Populate the given view filter with info from our range filters
//--------------------------------------------------------------------------------------------------
void RimCellFilterCollection::compoundCellRangeFilter( cvf::CellRangeFilter* cellRangeFilter, size_t gridIndex ) const
{
@ -370,9 +385,40 @@ void RimCellFilterCollection::compoundCellRangeFilter( cvf::CellRangeFilter* cel
for ( RimCellFilter* filter : m_cellFilters )
{
if ( filter->isFilterEnabled() )
if ( filter->isFilterEnabled() && filter->isRangeFilter() )
{
filter->updateCompundFilter( cellRangeFilter, gIndx );
}
}
}
//--------------------------------------------------------------------------------------------------
/// Populate the given view filter with info from our cell index filters
/// - includeCellVisibility is set to the visibility from the include filters,
/// - excludeCellVisibility is set to the visibility from the exclude filters
//--------------------------------------------------------------------------------------------------
void RimCellFilterCollection::updateCellVisibilityByIndex( cvf::UByteArray* includeCellVisibility,
cvf::UByteArray* excludeCellVisibility,
size_t gridIndex ) const
{
CVF_ASSERT( includeCellVisibility );
CVF_ASSERT( excludeCellVisibility );
bool needIncludeVisibilityReset = true;
excludeCellVisibility->setAll( 1 );
for ( RimCellFilter* filter : m_cellFilters )
{
if ( filter->isFilterEnabled() && filter->isIndexFilter() )
{
if ( ( filter->filterMode() == RimCellFilter::INCLUDE ) && needIncludeVisibilityReset )
{
includeCellVisibility->setAll( 0 );
needIncludeVisibilityReset = false;
}
filter->updateCellIndexFilter( includeCellVisibility, excludeCellVisibility, (int)gridIndex );
}
}
}

View File

@ -23,6 +23,8 @@
#include "cafPdmObject.h"
#include "cafSignal.h"
#include "cvfArray.h"
class RimCellFilter;
class RimCellRangeFilter;
class RimPolygonFilter;
@ -59,11 +61,13 @@ public:
void setActive( bool bActive );
void compoundCellRangeFilter( cvf::CellRangeFilter* cellRangeFilter, size_t gridIndex ) const;
void updateCellVisibilityByIndex( cvf::UByteArray* cellsIncluded, cvf::UByteArray* cellsExcluded, size_t gridIndex ) const;
std::vector<RimCellFilter*> filters() const;
bool hasActiveFilters() const;
bool hasActiveIncludeFilters() const;
bool hasActiveIncludeIndexFilters() const;
bool hasActiveIncludeRangeFilters() const;
void updateIconState();
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& referringObjects ) override;

View File

@ -38,6 +38,7 @@ CAF_PDM_SOURCE_INIT( RimCellRangeFilter, "CellRangeFilter" );
///
//--------------------------------------------------------------------------------------------------
RimCellRangeFilter::RimCellRangeFilter()
: RimCellFilter( RimCellFilter::RANGE )
{
CAF_PDM_InitObject( "Cell Range Filter", ":/CellFilter_Range.png" );

View File

@ -119,7 +119,8 @@ CAF_PDM_SOURCE_INIT( RimPolygonFilter, "PolygonFilter", "PolyLineFilter" );
///
//--------------------------------------------------------------------------------------------------
RimPolygonFilter::RimPolygonFilter()
: m_pickTargetsEventHandler( new RicPolylineTargetsPickEventHandler( this ) )
: RimCellFilter( RimCellFilter::INDEX )
, m_pickTargetsEventHandler( new RicPolylineTargetsPickEventHandler( this ) )
, m_intervalTool( true )
{
CAF_PDM_InitObject( "Polyline Filter", ":/CellFilter_Polygon.png" );
@ -431,6 +432,12 @@ void RimPolygonFilter::fieldChangedByUi( const caf::PdmFieldHandle* changedField
enableFilter( !m_enablePicking() );
filterChanged.send();
}
else if ( ( changedField == &m_showLines ) || ( changedField == &m_showSpheres ) || ( changedField == &m_sphereColor ) ||
( changedField == &m_sphereRadiusFactor ) || ( changedField == &m_lineThickness ) || ( changedField == &m_lineColor ) ||
( changedField == &m_lockPolygonToPlane ) || ( changedField == &m_polygonPlaneDepth ) )
{
filterChanged.send();
}
else if ( changedField != &m_name )
{
updateCells();
@ -467,10 +474,8 @@ caf::PickEventHandler* RimPolygonFilter::pickEventHandler() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimPolygonFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex )
void RimPolygonFilter::updateCellIndexFilter( cvf::UByteArray* includeVisibility, cvf::UByteArray* excludeVisibility, int gridIndex )
{
CVF_ASSERT( cellRangeFilter );
if ( !m_enableFiltering ) return;
const int noofgrids = static_cast<int>( m_cells.size() );
@ -481,19 +486,18 @@ void RimPolygonFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilte
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[gridIndex] )
if ( m_filterMode == FilterModeType::INCLUDE )
{
grid->ijkFromCellIndex( cellidx, &i, &j, &k );
if ( filterMode() == RimCellFilter::INCLUDE )
for ( auto cellIdx : m_cells[gridIndex] )
{
cellRangeFilter->addCellInclude( i, j, k, propagateToSubGrids() );
( *includeVisibility )[cellIdx] = true;
}
else
}
else
{
for ( auto cellIdx : m_cells[gridIndex] )
{
cellRangeFilter->addCellExclude( i, j, k, propagateToSubGrids() );
( *excludeVisibility )[cellIdx] = false;
}
}
}
@ -539,7 +543,8 @@ void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& p
// 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++ )
#pragma omp parallel for
for ( int n = 0; n < (int)grid->cellCount(); n++ )
{
// valid cell?
RigCell cell = grid->cell( n );
@ -557,6 +562,7 @@ void RimPolygonFilter::updateCellsDepthEclipse( const std::vector<cvf::Vec3d>& p
// check if the polygon includes the cell
if ( cellInsidePolygon2D( cell.center(), hexCorners, points ) )
{
#pragma omp critical
m_cells[gIdx].push_back( n );
}
}
@ -574,8 +580,9 @@ void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>&
std::list<size_t> foundCells;
#pragma omp parallel for
// find all cells in the K layer that matches the polygon
for ( size_t i = 0; i < grid->cellCountI(); i++ )
for ( int i = 0; i < (int)grid->cellCountI(); i++ )
{
for ( size_t j = 0; j < grid->cellCountJ(); j++ )
{
@ -591,6 +598,7 @@ void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector<cvf::Vec3d>&
// check if the polygon includes the cell
if ( cellInsidePolygon2D( cell.center(), hexCorners, points ) )
{
#pragma omp critical
foundCells.push_back( cellIdx );
}
}
@ -653,7 +661,8 @@ void RimPolygonFilter::updateCellsDepthGeoMech( const std::vector<cvf::Vec3d>& p
{
// we should look in depth using Z coordinate
// loop over all cells
for ( size_t i = 0; i < grid->cellCountI(); i++ )
#pragma omp parallel for
for ( int i = 0; i < (int)grid->cellCountI(); i++ )
{
for ( size_t j = 0; j < grid->cellCountJ(); j++ )
{
@ -675,6 +684,7 @@ void RimPolygonFilter::updateCellsDepthGeoMech( const std::vector<cvf::Vec3d>& p
// check if the polygon includes the cell
if ( cellInsidePolygon2D( center, corners, points ) )
{
#pragma omp critical
m_cells[partId].push_back( cellIdx );
}
}
@ -740,7 +750,9 @@ void RimPolygonFilter::updateCellsKIndexGeoMech( const std::vector<cvf::Vec3d>&
// find all cells in this K layer that matches the polygon
std::list<size_t> foundCells;
for ( size_t i = 0; i < grid->cellCountI(); i++ )
#pragma omp parallel for
for ( int i = 0; i < (int)grid->cellCountI(); i++ )
{
for ( size_t j = 0; j < grid->cellCountJ(); j++ )
{
@ -755,6 +767,7 @@ void RimPolygonFilter::updateCellsKIndexGeoMech( const std::vector<cvf::Vec3d>&
// check if the polygon includes the cell
if ( cellInsidePolygon2D( center, hexCorners, points ) )
{
#pragma omp critical
foundCells.push_back( cellIdx );
}
}

View File

@ -89,7 +89,7 @@ public:
bool pickingEnabled() const override;
caf::PickEventHandler* pickEventHandler() const override;
void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter, int gridIndex ) override;
void updateCellIndexFilter( cvf::UByteArray* includeVisibility, cvf::UByteArray* excludeVisibility, int gridIndex ) override;
cvf::ref<RigPolyLinesData> polyLinesData() const override;

View File

@ -26,6 +26,7 @@ CAF_PDM_SOURCE_INIT( RimPropertyFilter, "PropertyFilter" );
///
//--------------------------------------------------------------------------------------------------
RimPropertyFilter::RimPropertyFilter()
: RimCellFilter( RimCellFilter::PROPERTY )
{
CAF_PDM_InitObject( "Property Filter" );

View File

@ -26,6 +26,7 @@ CAF_PDM_SOURCE_INIT( RimUserDefinedFilter, "UserDefinedFilter" );
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedFilter::RimUserDefinedFilter()
: RimCellFilter( RimCellFilter::RANGE )
{
CAF_PDM_InitObject( "User Defined Filter", ":/CellFilter_UserDefined.png" );
CAF_PDM_InitFieldNoDefault( &m_individualCellIndices, "IndividualCellIndices", "Cells", "", "Use Ctrl-C for copy and Ctrl-V for paste", "" );

View File

@ -151,7 +151,17 @@ cvf::ref<cvf::UByteArray> RimGeoMechContourMapProjection::getCellVisibility() co
{
cvf::CellRangeFilter cellRangeFilter;
view()->cellFilterCollection()->compoundCellRangeFilter( &cellRangeFilter, 0 );
RivFemElmVisibilityCalculator::computeRangeVisibility( cellGridIdxVisibility.p(), m_femPart.p(), cellRangeFilter );
cvf::UByteArray indexIncludeVis = ( *cellGridIdxVisibility.p() );
cvf::UByteArray indexExcludeVis = ( *cellGridIdxVisibility.p() );
view()->cellFilterCollection()->updateCellVisibilityByIndex( &indexIncludeVis, &indexExcludeVis, 0 );
RivFemElmVisibilityCalculator::computeRangeVisibility( cellGridIdxVisibility.p(),
m_femPart.p(),
cellRangeFilter,
&indexIncludeVis,
&indexExcludeVis,
view()->cellFilterCollection()->hasActiveIncludeIndexFilters() );
}
if ( view()->propertyFilterCollection()->isActive() )
{