Improve draw performance for active cell grid

* Show timing for geoBuilder.generateSurface()
* Check state of element vector result before geometry is created

* Improve performance for isFaceVisible
Avoid calling costly function cell() when possible
Remove check on fault geometry as this does not affect the visualization

* Performance: Avoid traversal of all cells when computing visibility
When we have an active cell grid, we can skip checking for inactive and invalid state.
Use the list of active grid cells when looping through cells.
This commit is contained in:
Magne Sjaastad 2024-11-03 13:38:03 +01:00 committed by GitHub
parent 9a1c54c7d6
commit 4cf6a26083
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 92 additions and 27 deletions

View File

@ -20,6 +20,7 @@
#include "RivGridPartMgr.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
#include "RiaRegressionTestRunner.h"
@ -66,6 +67,32 @@
#include "cvfTransform.h"
#include "cvfUniform.h"
namespace caf
{
template <>
void caf::AppEnum<RivCellSetEnum>::setUp()
{
addItem( RivCellSetEnum::OVERRIDDEN_CELL_VISIBILITY, "OVERRIDDEN_CELL_VISIBILITY", "OVERRIDDEN_CELL_VISIBILITY" );
addItem( RivCellSetEnum::ALL_CELLS, "ALL_CELLS", "ALL_CELLS" );
addItem( RivCellSetEnum::ACTIVE, "ACTIVE", "ACTIVE" );
addItem( RivCellSetEnum::ALL_WELL_CELLS, "ALL_WELL_CELLS", "ALL_WELL_CELLS" );
addItem( RivCellSetEnum::VISIBLE_WELL_CELLS, "VISIBLE_WELL_CELLS", "VISIBLE_WELL_CELLS" );
addItem( RivCellSetEnum::VISIBLE_WELL_FENCE_CELLS, "VISIBLE_WELL_FENCE_CELLS", "VISIBLE_WELL_FENCE_CELLS" );
addItem( RivCellSetEnum::INACTIVE, "INACTIVE", "INACTIVE" );
addItem( RivCellSetEnum::RANGE_FILTERED, "RANGE_FILTERED", "RANGE_FILTERED" );
addItem( RivCellSetEnum::RANGE_FILTERED_INACTIVE, "RANGE_FILTERED_INACTIVE", "RANGE_FILTERED_INACTIVE" );
addItem( RivCellSetEnum::RANGE_FILTERED_WELL_CELLS, "RANGE_FILTERED_WELL_CELLS", "RANGE_FILTERED_WELL_CELLS" );
addItem( RivCellSetEnum::VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER,
"VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER",
"VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER" );
addItem( RivCellSetEnum::VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER,
"VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER",
"VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER" );
addItem( RivCellSetEnum::PROPERTY_FILTERED, "PROPERTY_FILTERED", "PROPERTY_FILTERED" );
addItem( RivCellSetEnum::PROPERTY_FILTERED_WELL_CELLS, "PROPERTY_FILTERED_WELL_CELLS", "PROPERTY_FILTERED_WELL_CELLS" );
}
} // namespace caf
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -117,7 +144,11 @@ void RivGridPartMgr::generatePartGeometry( cvf::StructGridGeometryGenerator& geo
// Surface geometry
{
auto text = caf::AppEnum<RivCellSetEnum>::text( m_cellSetType );
RiaLogging::resetTimer( "Compute surface for " + text );
cvf::ref<cvf::DrawableGeo> geo = geoBuilder.generateSurface();
RiaLogging::logTimeElapsed( "" );
if ( geo.notNull() )
{
geo->computeNormals();

View File

@ -20,6 +20,7 @@
#include "RivReservoirViewPartMgr.h"
#include "RigActiveCellGrid.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigCaseToCaseCellMapper.h"
@ -601,6 +602,27 @@ void RivReservoirViewPartMgr::computeNativeVisibility( cvf::UByteArray*
cellVisibility->resize( grid->cellCount() );
if ( auto activeGrid = dynamic_cast<const RigActiveCellGrid*>( grid ) )
{
auto reservoirIndices = activeGrid->activeReservoirCellIndices();
#pragma omp parallel for
for ( int i = 0; i < static_cast<int>( reservoirIndices.size() ); i++ )
{
size_t cellIndex = reservoirIndices[i];
if ( ( !activeCellsIsVisible ) || ( *cellIsInWellStatuses )[cellIndex] )
{
( *cellVisibility )[cellIndex] = false;
}
else
{
( *cellVisibility )[cellIndex] = true;
}
}
return;
}
#pragma omp parallel for
for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
{

View File

@ -1139,19 +1139,22 @@ void RimEclipseView::appendElementVectorResultToModel()
cvf::String name = "ElementVectorModelMod";
RimEclipseView::removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> frameParts = new cvf::ModelBasicList;
frameParts->setName( name );
if ( m_elementVectorResult->showResult() )
{
cvf::ref<cvf::ModelBasicList> frameParts = new cvf::ModelBasicList;
frameParts->setName( name );
m_reservoirGridPartManager->appendElementVectorResultDynamicGeometryPartsToModel( frameParts.p(),
PROPERTY_FILTERED,
m_currentTimeStep );
m_reservoirGridPartManager->appendElementVectorResultDynamicGeometryPartsToModel( frameParts.p(),
PROPERTY_FILTERED,
m_currentTimeStep );
// TODO: should this be ACTIVE?
m_reservoirGridPartManager->appendElementVectorResultDynamicGeometryPartsToModel( frameParts.p(),
PROPERTY_FILTERED_WELL_CELLS,
m_currentTimeStep );
// TODO: should this be ACTIVE?
m_reservoirGridPartManager->appendElementVectorResultDynamicGeometryPartsToModel( frameParts.p(),
PROPERTY_FILTERED_WELL_CELLS,
m_currentTimeStep );
frameScene->addModel( frameParts.p() );
frameScene->addModel( frameParts.p() );
}
}
}
}

View File

@ -109,6 +109,22 @@ size_t RigActiveCellGrid::totalActiveCellCount() const
return m_totalActiveCellCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RigActiveCellGrid::activeReservoirCellIndices() const
{
std::vector<size_t> indices;
indices.reserve( m_nativeCells.size() );
for ( const auto& [index, cell] : m_nativeCells )
{
indices.emplace_back( index );
}
return indices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -34,6 +34,8 @@ public:
size_t totalCellCount() const override;
size_t totalActiveCellCount() const;
std::vector<size_t> activeReservoirCellIndices() const;
protected: // only for use by file readers!
friend class RifReaderOpmCommonActive;
std::map<size_t, RigCell>& nativeCells();

View File

@ -535,7 +535,7 @@ bool RigGridCellFaceVisibilityFilter::isFaceVisible( size_t
CVF_TIGHT_ASSERT( m_grid );
size_t cellIndex = m_grid->cellIndexFromIJK( i, j, k );
if ( m_grid->cell( cellIndex ).subGrid() )
if ( m_grid->mainGrid()->gridCount() > 1 && m_grid->cell( cellIndex ).subGrid() )
{
// Do not show any faces in the place where a LGR is present
return false;
@ -552,27 +552,18 @@ bool RigGridCellFaceVisibilityFilter::isFaceVisible( size_t
size_t neighborCellIndex = m_grid->cellIndexFromIJK( ni, nj, nk );
// Do show the faces in the boarder between this grid and a possible LGR. Some of the LGR cells
// might not be visible.
if ( m_grid->cell( neighborCellIndex ).subGrid() )
{
return true;
}
// Do not show cell geometry if a fault is present to avoid z fighting between surfaces
// It will always be a better solution to avoid geometry creation instead of part priority and polygon offset
size_t nativeResvCellIndex = m_grid->reservoirCellIndex( cellIndex );
const RigFault* fault = m_grid->mainGrid()->findFaultFromCellIndexAndCellFace( nativeResvCellIndex, face );
if ( fault )
{
return false;
}
// If the neighbour cell is invisible, we need to draw the face
if ( ( cellVisibility != nullptr ) && !( *cellVisibility )[neighborCellIndex] )
{
return true;
}
// Do show the faces in the boarder between this grid and a possible LGR. Some of the LGR cells
// might not be visible.
if ( m_grid->mainGrid()->gridCount() > 1 && m_grid->cell( neighborCellIndex ).subGrid() )
{
return true;
}
return false;
}