/////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2011-     Statoil ASA
//  Copyright (C) 2013-     Ceetron Solutions AS
//  Copyright (C) 2011-2012 Ceetron AS
//
//  ResInsight is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
//  FITNESS FOR A PARTICULAR PURPOSE.
//
//  See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
//  for more details.
//
/////////////////////////////////////////////////////////////////////////////////

#include "RivReservoirViewPartMgr.h"

#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigCaseToCaseCellMapper.h"
#include "RigCell.h"
#include "RigEclipseCaseData.h"
#include "RigGridBase.h"
#include "RigResultAccessorFactory.h"

#include "Rim3dOverlayInfoConfig.h"
#include "RimCellEdgeColors.h"
#include "RimCellFilterCollection.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilter.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseResultDefinition.h"
#include "RimEclipseView.h"
#include "RimFaultInViewCollection.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimSimWellInViewCollection.h"
#include "RimViewController.h"
#include "RimViewLinker.h"

#include "RivElementVectorResultPartMgr.h"
#include "RivGridPartMgr.h"
#include "RivReservoirFaultsPartMgr.h"

#include <QDebug>

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivReservoirViewPartMgr::RivReservoirViewPartMgr( RimEclipseView* resv )
    : m_reservoirView( resv )
{
    m_scaleTransform = new cvf::Transform();
    clearGeometryCache();
}

//--------------------------------------------------------------------------------------------------
/// Clears the geometry cache for the given, and the dependent geometryTypes (from a visibility standpoint)
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::scheduleGeometryRegen( RivCellSetEnum geometryType )
{
    switch ( geometryType )
    {
        case OVERRIDDEN_CELL_VISIBILITY:
            clearGeometryCache( OVERRIDDEN_CELL_VISIBILITY );
            break;
        case INACTIVE:
            clearGeometryCache( INACTIVE );
            clearGeometryCache( RANGE_FILTERED_INACTIVE );
            break;
        case RANGE_FILTERED_INACTIVE:
            clearGeometryCache( RANGE_FILTERED_INACTIVE );
            break;
        case ACTIVE:
            clearGeometryCache( ACTIVE );
            clearGeometryCache( ALL_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS );
            clearGeometryCache( RANGE_FILTERED );
            clearGeometryCache( RANGE_FILTERED_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case ALL_WELL_CELLS:
            clearGeometryCache( ALL_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS );
            clearGeometryCache( RANGE_FILTERED );
            clearGeometryCache( RANGE_FILTERED_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case VISIBLE_WELL_CELLS:
            clearGeometryCache( VISIBLE_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS );
            clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case VISIBLE_WELL_FENCE_CELLS:
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case RANGE_FILTERED:
            clearGeometryCache( RANGE_FILTERED );
            clearGeometryCache( RANGE_FILTERED_INACTIVE );
            clearGeometryCache( RANGE_FILTERED_WELL_CELLS );
            clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case RANGE_FILTERED_WELL_CELLS:
            clearGeometryCache( RANGE_FILTERED_WELL_CELLS );
            clearGeometryCache( RANGE_FILTERED );
            clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER:
            clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER:
            clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case PROPERTY_FILTERED:
            clearGeometryCache( PROPERTY_FILTERED );
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
        case PROPERTY_FILTERED_WELL_CELLS:
            clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
            break;
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::clearGeometryCache( RivCellSetEnum geomType )
{
    RimEclipseCase* rimEclipseCase = nullptr;

    if ( m_reservoirView )
    {
        m_reservoirView->firstAncestorOrThisOfType( rimEclipseCase );
    }

    if ( geomType == PROPERTY_FILTERED )
    {
        for ( size_t i = 0; i < m_propFilteredGeometryFramesNeedsRegen.size(); ++i )
        {
            m_propFilteredGeometryFramesNeedsRegen[i] = true;
        }
    }
    else if ( geomType == PROPERTY_FILTERED_WELL_CELLS )
    {
        for ( size_t i = 0; i < m_propFilteredWellGeometryFramesNeedsRegen.size(); ++i )
        {
            m_propFilteredWellGeometryFramesNeedsRegen[i] = true;
        }
    }
    else
    {
        m_geometriesNeedsRegen[geomType] = true;
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::clearGeometryCache()
{
    clearGeometryCache( OVERRIDDEN_CELL_VISIBILITY );
    clearGeometryCache( ACTIVE );
    clearGeometryCache( ALL_WELL_CELLS );
    clearGeometryCache( VISIBLE_WELL_CELLS );
    clearGeometryCache( VISIBLE_WELL_FENCE_CELLS );
    clearGeometryCache( INACTIVE );
    clearGeometryCache( RANGE_FILTERED );
    clearGeometryCache( RANGE_FILTERED_WELL_CELLS );
    clearGeometryCache( RANGE_FILTERED_INACTIVE );
    clearGeometryCache( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
    clearGeometryCache( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
    clearGeometryCache( PROPERTY_FILTERED );
    clearGeometryCache( PROPERTY_FILTERED_WELL_CELLS );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendStaticGeometryPartsToModel( cvf::ModelBasicList*       model,
                                                                RivCellSetEnum             geometryType,
                                                                const std::vector<size_t>& gridIndices )
{
    ensureStaticGeometryPartsCreated( geometryType );

    m_geometries[geometryType].appendGridPartsToModel( model, gridIndices );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::ensureStaticGeometryPartsCreated( RivCellSetEnum geometryType )
{
    if ( geometryType < PROPERTY_FILTERED && m_geometriesNeedsRegen[geometryType] )
    {
        createGeometry( geometryType );
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList*       model,
                                                                 RivCellSetEnum             geometryType,
                                                                 size_t                     frameIndex,
                                                                 const std::vector<size_t>& gridIndices )
{
    ensureDynamicGeometryPartsCreated( geometryType, frameIndex );

    if ( geometryType == PROPERTY_FILTERED )
    {
        m_propFilteredGeometryFrames[frameIndex]->appendGridPartsToModel( model, gridIndices );
    }
    else if ( geometryType == PROPERTY_FILTERED_WELL_CELLS )
    {
        m_propFilteredWellGeometryFrames[frameIndex]->appendGridPartsToModel( model, gridIndices );
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::ensureDynamicGeometryPartsCreated( RivCellSetEnum geometryType, size_t frameIndex )
{
    if ( geometryType == PROPERTY_FILTERED )
    {
        if ( frameIndex >= m_propFilteredGeometryFramesNeedsRegen.size() || m_propFilteredGeometryFramesNeedsRegen[frameIndex] )
        {
            createPropertyFilteredNoneWellCellGeometry( frameIndex );
        }
    }
    else if ( geometryType == PROPERTY_FILTERED_WELL_CELLS )
    {
        if ( frameIndex >= m_propFilteredWellGeometryFramesNeedsRegen.size() || m_propFilteredWellGeometryFramesNeedsRegen[frameIndex] )
        {
            createPropertyFilteredWellGeometry( frameIndex );
        }
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::createGeometry( RivCellSetEnum geometryType )
{
    RigEclipseCaseData* res = m_reservoirView->eclipseCase()->eclipseCaseData();

    m_geometries[geometryType].clearAndSetReservoir( geometryType, m_reservoirView->eclipseCase(), m_reservoirView );
    m_geometries[geometryType].setTransform( m_scaleTransform.p() );

    std::vector<RigGridBase*> grids;
    res->allGrids( &grids );

    for ( size_t i = 0; i < grids.size(); ++i )
    {
        cvf::ref<cvf::UByteArray> cellVisibility = m_geometries[geometryType].cellVisibility( i );
        computeVisibility( cellVisibility.p(), geometryType, grids[i], i );

        m_geometries[geometryType].setCellVisibility( i, cellVisibility.p() );
    }

    m_geometriesNeedsRegen[geometryType] = false;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::computeVisibility( cvf::UByteArray* cellVisibility, RivCellSetEnum geometryType, RigGridBase* grid, size_t gridIdx )
{
    RigEclipseCaseData* eclipseCase    = m_reservoirView->eclipseCase()->eclipseCaseData();
    auto                activeCellInfo = m_reservoirView->currentActiveCellInfo();

    switch ( geometryType )
    {
        case OVERRIDDEN_CELL_VISIBILITY:
            computeOverriddenCellVisibility( cellVisibility, grid );
            break;
        case ACTIVE:
            computeNativeVisibility( cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid( gridIdx ), false, false, true );
            break;
        case ALL_WELL_CELLS:
            copyByteArray( cellVisibility, eclipseCase->wellCellsInGrid( gridIdx ) );
            break;
        case VISIBLE_WELL_CELLS:
        {
            cvf::ref<cvf::UByteArray> allWellCellsVisibility;
            ensureStaticGeometryPartsCreated( ALL_WELL_CELLS );

            allWellCellsVisibility = m_geometries[ALL_WELL_CELLS].cellVisibility( gridIdx );

            m_reservoirView->calculateVisibleWellCellsIncFence( cellVisibility, grid );

#pragma omp parallel for
            for ( int cellIdx = 0; cellIdx < static_cast<int>( cellVisibility->size() ); ++cellIdx )
            {
                ( *cellVisibility )[cellIdx] = ( *allWellCellsVisibility )[cellIdx] && ( *cellVisibility )[cellIdx];
            }
        }
        break;
        case VISIBLE_WELL_FENCE_CELLS:
        {
            cvf::ref<cvf::UByteArray> allWellCellsVisibility;
            ensureStaticGeometryPartsCreated( ALL_WELL_CELLS );

            allWellCellsVisibility = m_geometries[ALL_WELL_CELLS].cellVisibility( gridIdx );

            m_reservoirView->calculateVisibleWellCellsIncFence( cellVisibility, grid );

#pragma omp parallel for
            for ( int cellIdx = 0; cellIdx < static_cast<int>( cellVisibility->size() ); ++cellIdx )
            {
                ( *cellVisibility )[cellIdx] = !( *allWellCellsVisibility )[cellIdx] && ( *cellVisibility )[cellIdx];
            }
        }
        break;
        case INACTIVE:
            computeNativeVisibility( cellVisibility,
                                     grid,
                                     activeCellInfo,
                                     eclipseCase->wellCellsInGrid( gridIdx ),
                                     m_reservoirView->showInvalidCells(),
                                     true,
                                     false );
            break;
        case RANGE_FILTERED:
        {
            cvf::ref<cvf::UByteArray> nativeVisibility;
            ensureStaticGeometryPartsCreated( ACTIVE );

            nativeVisibility = m_geometries[ACTIVE].cellVisibility( gridIdx );
            computeFilterVisibility( geometryType, cellVisibility, grid, nativeVisibility.p(), m_reservoirView->cellFilterCollection() );
        }
        break;
        case RANGE_FILTERED_INACTIVE:
        {
            cvf::ref<cvf::UByteArray> nativeVisibility;
            ensureStaticGeometryPartsCreated( INACTIVE );

            nativeVisibility = m_geometries[INACTIVE].cellVisibility( gridIdx );
            computeFilterVisibility( geometryType, cellVisibility, grid, nativeVisibility.p(), m_reservoirView->cellFilterCollection() );
        }
        break;
        case RANGE_FILTERED_WELL_CELLS:
        {
            cvf::ref<cvf::UByteArray> nativeVisibility;
            ensureStaticGeometryPartsCreated( ALL_WELL_CELLS );

            nativeVisibility = m_geometries[ALL_WELL_CELLS].cellVisibility( gridIdx );
            computeFilterVisibility( geometryType, cellVisibility, grid, nativeVisibility.p(), m_reservoirView->cellFilterCollection() );
        }
        break;
        case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER:
        {
            cvf::ref<cvf::UByteArray> visibleWellCells;
            cvf::ref<cvf::UByteArray> rangeFilteredWellCells;

            ensureStaticGeometryPartsCreated( VISIBLE_WELL_CELLS );
            ensureStaticGeometryPartsCreated( RANGE_FILTERED_WELL_CELLS );

            visibleWellCells       = m_geometries[VISIBLE_WELL_CELLS].cellVisibility( gridIdx );
            rangeFilteredWellCells = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility( gridIdx );

            cellVisibility->resize( visibleWellCells->size() );

#pragma omp parallel for
            for ( int cellIdx = 0; cellIdx < static_cast<int>( cellVisibility->size() ); ++cellIdx )
            {
                ( *cellVisibility )[cellIdx] = ( *visibleWellCells )[cellIdx] && !( *rangeFilteredWellCells )[cellIdx];
            }
        }
        break;
        case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER:
        {
            cvf::ref<cvf::UByteArray> visibleWellCells;
            cvf::ref<cvf::UByteArray> rangeFilteredWellCells;

            ensureStaticGeometryPartsCreated( VISIBLE_WELL_FENCE_CELLS );
            ensureStaticGeometryPartsCreated( RANGE_FILTERED );

            visibleWellCells       = m_geometries[VISIBLE_WELL_FENCE_CELLS].cellVisibility( gridIdx );
            rangeFilteredWellCells = m_geometries[RANGE_FILTERED].cellVisibility( gridIdx );

            cellVisibility->resize( visibleWellCells->size() );

#pragma omp parallel for
            for ( int cellIdx = 0; cellIdx < static_cast<int>( cellVisibility->size() ); ++cellIdx )
            {
                ( *cellVisibility )[cellIdx] = ( *visibleWellCells )[cellIdx] && !( *rangeFilteredWellCells )[cellIdx];
            }
        }
        break;
        default:
            CVF_ASSERT( false ); // Call special function for property filtered stuff
            break;
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::createPropertyFilteredNoneWellCellGeometry( size_t frameIndex )
{
    RigEclipseCaseData* res = m_reservoirView->eclipseCase()->eclipseCaseData();

    if ( frameIndex >= m_propFilteredGeometryFrames.size() )
    {
        m_propFilteredGeometryFrames.resize( frameIndex + 1 );
        m_propFilteredGeometryFramesNeedsRegen.resize( frameIndex + 1, true );
    }

    if ( m_propFilteredGeometryFrames[frameIndex].isNull() ) m_propFilteredGeometryFrames[frameIndex] = new RivReservoirPartMgr;

    m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir( PROPERTY_FILTERED, m_reservoirView->eclipseCase(), m_reservoirView );
    m_propFilteredGeometryFrames[frameIndex]->setTransform( m_scaleTransform.p() );

    std::vector<RigGridBase*> grids;
    res->allGrids( &grids );

    bool hasActiveCellFilters = m_reservoirView->cellFilterCollection()->hasActiveFilters();
    bool hasVisibleWellCells  = m_reservoirView->wellCollection()->hasVisibleWellCells();

    for ( size_t gIdx = 0; gIdx < grids.size(); ++gIdx )
    {
        cvf::ref<cvf::UByteArray> cellVisibility = m_propFilteredGeometryFrames[frameIndex]->cellVisibility( gIdx );
        cvf::ref<cvf::UByteArray> rangeVisibility;
        cvf::ref<cvf::UByteArray> fenceVisibility;

        if ( hasActiveCellFilters && hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( RANGE_FILTERED );
            ensureStaticGeometryPartsCreated( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );

            rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility( gIdx );
            fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility( gIdx );
        }
        else if ( hasActiveCellFilters && !hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( RANGE_FILTERED );

            rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility( gIdx );
            fenceVisibility = m_geometries[RANGE_FILTERED].cellVisibility( gIdx );
        }
        else if ( !hasActiveCellFilters && hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( VISIBLE_WELL_FENCE_CELLS );

            rangeVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS].cellVisibility( gIdx );
            fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS].cellVisibility( gIdx );
        }
        else if ( !hasActiveCellFilters && !hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( ACTIVE );

            rangeVisibility = m_geometries[ACTIVE].cellVisibility( gIdx );
            fenceVisibility = m_geometries[ACTIVE].cellVisibility( gIdx );
        }

        cellVisibility->resize( rangeVisibility->size() );

#pragma omp parallel for
        for ( int cellIdx = 0; cellIdx < static_cast<int>( cellVisibility->size() ); ++cellIdx )
        {
            ( *cellVisibility )[cellIdx] = ( *rangeVisibility )[cellIdx] || ( *fenceVisibility )[cellIdx];
        }

        computePropertyVisibility( cellVisibility.p(),
                                   grids[gIdx],
                                   frameIndex,
                                   cellVisibility.p(),
                                   m_reservoirView->eclipsePropertyFilterCollection() );

        m_propFilteredGeometryFrames[frameIndex]->setCellVisibility( gIdx, cellVisibility.p() );
    }

    m_propFilteredGeometryFramesNeedsRegen[frameIndex] = false;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry( size_t frameIndex )
{
    RigEclipseCaseData* res = m_reservoirView->eclipseCase()->eclipseCaseData();

    if ( frameIndex >= m_propFilteredWellGeometryFrames.size() )
    {
        m_propFilteredWellGeometryFrames.resize( frameIndex + 1 );
        m_propFilteredWellGeometryFramesNeedsRegen.resize( frameIndex + 1, true );
    }

    if ( m_propFilteredWellGeometryFrames[frameIndex].isNull() ) m_propFilteredWellGeometryFrames[frameIndex] = new RivReservoirPartMgr;

    m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir( PROPERTY_FILTERED_WELL_CELLS,
                                                                        m_reservoirView->eclipseCase(),
                                                                        m_reservoirView );
    m_propFilteredWellGeometryFrames[frameIndex]->setTransform( m_scaleTransform.p() );

    std::vector<RigGridBase*> grids;
    res->allGrids( &grids );

    bool hasActiveCellFilters = m_reservoirView->cellFilterCollection()->hasActiveFilters();
    bool hasVisibleWellCells  = m_reservoirView->wellCollection()->hasVisibleWellCells();

    for ( size_t gIdx = 0; gIdx < grids.size(); ++gIdx )
    {
        cvf::ref<cvf::UByteArray> cellVisibility = m_propFilteredWellGeometryFrames[frameIndex]->cellVisibility( gIdx );
        cvf::ref<cvf::UByteArray> rangeVisibility;
        cvf::ref<cvf::UByteArray> wellCellsOutsideRange;
        cvf::ref<cvf::UByteArray> wellFenceCells;

        if ( hasActiveCellFilters && hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( RANGE_FILTERED_WELL_CELLS );
            rangeVisibility = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility( gIdx );

            ensureStaticGeometryPartsCreated( VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER );
            wellCellsOutsideRange = m_geometries[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility( gIdx );

            ensureStaticGeometryPartsCreated( VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER );
            wellFenceCells = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility( gIdx );
        }
        else if ( hasActiveCellFilters && !hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( RANGE_FILTERED_WELL_CELLS );
            rangeVisibility       = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility( gIdx );
            wellCellsOutsideRange = rangeVisibility;
            wellFenceCells        = rangeVisibility;
        }
        else if ( !hasActiveCellFilters && hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( VISIBLE_WELL_CELLS );
            wellCellsOutsideRange = m_geometries[VISIBLE_WELL_CELLS].cellVisibility( gIdx );

            ensureStaticGeometryPartsCreated( VISIBLE_WELL_FENCE_CELLS );
            wellFenceCells = m_geometries[VISIBLE_WELL_FENCE_CELLS].cellVisibility( gIdx );

            rangeVisibility = wellCellsOutsideRange;
        }
        else if ( !hasActiveCellFilters && !hasVisibleWellCells )
        {
            ensureStaticGeometryPartsCreated( ALL_WELL_CELLS );
            wellFenceCells        = m_geometries[ALL_WELL_CELLS].cellVisibility( gIdx );
            wellCellsOutsideRange = wellFenceCells;
            rangeVisibility       = wellFenceCells;
        }

        cellVisibility->resize( rangeVisibility->size() );

#pragma omp parallel for
        for ( int cellIdx = 0; cellIdx < static_cast<int>( cellVisibility->size() ); ++cellIdx )
        {
            ( *cellVisibility )[cellIdx] = ( *wellFenceCells )[cellIdx] || ( *rangeVisibility )[cellIdx] ||
                                           ( *wellCellsOutsideRange )[cellIdx];
        }

        computePropertyVisibility( cellVisibility.p(),
                                   grids[gIdx],
                                   frameIndex,
                                   cellVisibility.p(),
                                   m_reservoirView->eclipsePropertyFilterCollection() );

        m_propFilteredWellGeometryFrames[frameIndex]->setCellVisibility( gIdx, cellVisibility.p() );
    }

    m_propFilteredWellGeometryFramesNeedsRegen[frameIndex] = false;
}

//--------------------------------------------------------------------------------------------------
/// Evaluate visibility based on cell state
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::computeNativeVisibility( cvf::UByteArray*         cellVisibility,
                                                       const RigGridBase*       grid,
                                                       const RigActiveCellInfo* activeCellInfo,
                                                       const cvf::UByteArray*   cellIsInWellStatuses,
                                                       bool                     invalidCellsIsVisible,
                                                       bool                     inactiveCellsIsVisible,
                                                       bool                     activeCellsIsVisible )
{
    CVF_ASSERT( cellVisibility != nullptr );
    CVF_ASSERT( grid != nullptr );
    CVF_ASSERT( activeCellInfo != nullptr );
    CVF_ASSERT( cellIsInWellStatuses != nullptr );
    CVF_ASSERT( cellIsInWellStatuses->size() >= grid->cellCount() );

    cellVisibility->resize( grid->cellCount() );

#pragma omp parallel for
    for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
    {
        const RigCell& cell               = grid->cell( cellIndex );
        size_t         reservoirCellIndex = grid->reservoirCellIndex( cellIndex );
        bool           isCellActive       = activeCellInfo->isActive( reservoirCellIndex );

        if ( ( !invalidCellsIsVisible && cell.isInvalid() ) || ( !inactiveCellsIsVisible && !isCellActive ) ||
             ( !activeCellsIsVisible && isCellActive ) || ( *cellIsInWellStatuses )[cellIndex] )
        {
            ( *cellVisibility )[cellIndex] = false;
        }
        else
        {
            ( *cellVisibility )[cellIndex] = true;
        }
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::computeOverriddenCellVisibility( cvf::UByteArray* cellVisibility, const RigGridBase* grid )
{
    RimViewController* masterViewLink = m_reservoirView->viewController();

    CVF_ASSERT( masterViewLink );

    RimGridView* masterView = dynamic_cast<RimGridView*>( masterViewLink->ownerViewLinker()->masterView() );
    if ( !masterView ) return;

// get cell visibility
#if 1
    cvf::ref<cvf::UByteArray> totCellVisibility = masterView->currentTotalCellVisibility();
#else
    // Could get something more like
    std::vector<std::vector<cvf::UByteArray*>> gridsWithCellSetVisibility = masterView->getAllGridsCurrentCellSetsCellVisibility();
#endif

    CVF_ASSERT( cellVisibility != nullptr );
    CVF_ASSERT( grid != nullptr );

    size_t gridCellCount = grid->cellCount();
    cellVisibility->resize( gridCellCount );
    cellVisibility->setAll( false );

    const RigCaseToCaseCellMapper* cellMapper = masterViewLink->cellMapper();

    for ( size_t lcIdx = 0; lcIdx < gridCellCount; ++lcIdx )
    {
#if 1
        int        reservoirCellIdx        = static_cast<int>( grid->reservoirCellIndex( lcIdx ) );
        int        cellCount               = 0;
        const int* cellIndicesInMasterCase = cellMapper->masterCaseCellIndices( reservoirCellIdx, &cellCount );

        for ( int mcIdx = 0; mcIdx < cellCount; ++mcIdx )
        {
            ( *cellVisibility )[lcIdx] |= ( *totCellVisibility )[cellIndicesInMasterCase[mcIdx]]; // If any is
                                                                                                  // visible, show
        }

#else

        const RigGridCells& masterCaseCells = cellMapper->masterCaseGridAndLocalCellIndex( grid->gridIndex, lcIdx );

        for ( int mcIdx = 0; mcIdx < masterCaseCells.cellCount(); ++mcIdx )
        {
            int cellSetCount = gridsWithCellSetVisibility[masterCaseCells.gridIndex[mcIdx]].size();
            for ( int csIdx = 0; csIdx < cellSetCount; ++csIdx )
            {
                ( *cellVisibility )[lcIdx] |= gridsWithCellSetVisibility[masterCaseCells.gridIndex[mcIdx]][masterCaseCells.cellIndex[mcIdx]];
            }
        }
#endif
    }
}

//--------------------------------------------------------------------------------------------------
/// Copy the data from source into destination. This is not trivial to do using cvf::Array ...
/// using parallelized operator [] and not memcopy. Do not know what is faster.
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::copyByteArray( cvf::UByteArray* destination, const cvf::UByteArray* source )
{
    CVF_ASSERT( destination != nullptr );
    CVF_ASSERT( source != nullptr );

    if ( destination->size() != source->size() )
    {
        destination->resize( source->size() );
    }

#pragma omp parallel for
    for ( int cellIndex = 0; cellIndex < static_cast<int>( source->size() ); cellIndex++ )
    {
        ( *destination )[cellIndex] = ( *source )[cellIndex];
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::computeFilterVisibility( RivCellSetEnum                 geometryType,
                                                       cvf::UByteArray*               cellVisibility,
                                                       const RigGridBase*             grid,
                                                       const cvf::UByteArray*         nativeVisibility,
                                                       const RimCellFilterCollection* cellFilterColl )
{
    CVF_ASSERT( cellVisibility != nullptr );
    CVF_ASSERT( nativeVisibility != nullptr );
    CVF_ASSERT( cellFilterColl != nullptr );

    CVF_ASSERT( grid != nullptr );
    CVF_ASSERT( nativeVisibility->size() == grid->cellCount() );

    // Initialize filter with native visibility
    if ( cellVisibility != nativeVisibility ) ( *cellVisibility ) = ( *nativeVisibility );

    if ( cellFilterColl->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells() )
    {
        // Build cell filter for current grid
        cvf::CellRangeFilter gridCellRangeFilter;
        cellFilterColl->compoundCellRangeFilter( &gridCellRangeFilter, grid->gridIndex() );

        const RigLocalGrid*       lgr = nullptr;
        cvf::ref<cvf::UByteArray> parentGridVisibilities;

        if ( !grid->isMainGrid() )
        {
            lgr = static_cast<const RigLocalGrid*>( grid );

            size_t parentGridIndex = lgr->parentGrid()->gridIndex();
            CVF_ASSERT( parentGridIndex < grid->gridIndex() );

            if ( geometryType == RANGE_FILTERED_WELL_CELLS )
            {
                geometryType = RANGE_FILTERED; // Use the range filtering in the parent grid, not the well cells in
                                               // the parent grid
            }

            RivReservoirPartMgr* reservoirGridPartMgr = &m_geometries[geometryType];

            parentGridVisibilities = reservoirGridPartMgr->cellVisibility( parentGridIndex );
        }

        bool hasAdditiveFilters = cellFilterColl->hasActiveIncludeFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells();

#pragma omp parallel for
        for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
        {
            if ( ( *nativeVisibility )[cellIndex] )
            {
                const RigCell& cell                   = grid->cell( cellIndex );
                bool           visibleDueToParentGrid = false;
                if ( lgr )
                {
                    size_t parentGridCellIndex = cell.parentCellIndex();
                    visibleDueToParentGrid     = parentGridVisibilities->get( parentGridCellIndex );
                }

                // Normal grid visibility
                size_t mainGridI;
                size_t mainGridJ;
                size_t mainGridK;

                bool isInSubGridArea = cell.subGrid() != nullptr;
                grid->ijkFromCellIndex( cellIndex, &mainGridI, &mainGridJ, &mainGridK );

                bool nativeRangeVisibility = false;

                if ( hasAdditiveFilters )
                {
                    nativeRangeVisibility = gridCellRangeFilter.isCellVisible( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
                }
                else
                {
                    // Special handling when no include filters are present. Use native visibility
                    nativeRangeVisibility = ( *nativeVisibility )[cellIndex];
                }

                ( *cellVisibility )[cellIndex] = ( visibleDueToParentGrid || nativeRangeVisibility ) &&
                                                 !gridCellRangeFilter.isCellExcluded( mainGridI, mainGridJ, mainGridK, isInSubGridArea );
            }
        }
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::computePropertyVisibility( cvf::UByteArray*                    cellVisibility,
                                                         const RigGridBase*                  grid,
                                                         size_t                              timeStepIndex,
                                                         const cvf::UByteArray*              rangeFilterVisibility,
                                                         RimEclipsePropertyFilterCollection* propFilterColl )
{
    CVF_ASSERT( cellVisibility != nullptr );
    CVF_ASSERT( rangeFilterVisibility != nullptr );
    CVF_ASSERT( propFilterColl != nullptr );

    CVF_ASSERT( grid->cellCount() > 0 );
    CVF_ASSERT( rangeFilterVisibility->size() == grid->cellCount() );

    // Copy if not equal
    if ( cellVisibility != rangeFilterVisibility ) ( *cellVisibility ) = *rangeFilterVisibility;

    if ( propFilterColl->hasActiveFilters() )
    {
        for ( size_t i = 0; i < propFilterColl->propertyFilters().size(); i++ )
        {
            RimEclipsePropertyFilter* propertyFilter = propFilterColl->propertyFilters()[i];

            if ( propertyFilter->isActive() && propertyFilter->resultDefinition()->hasResult() )
            {
                propertyFilter->resultDefinition()->loadResult();

                const RimCellFilter::FilterModeType filterType = propertyFilter->filterMode();

                RigEclipseCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->eclipseCaseData();

                cvf::ref<RigResultAccessor> resultAccessor =
                    RigResultAccessorFactory::createFromResultDefinition( eclipseCase,
                                                                          grid->gridIndex(),
                                                                          timeStepIndex,
                                                                          propertyFilter->resultDefinition() );

                CVF_ASSERT( resultAccessor.notNull() );

                if ( propertyFilter->isCategorySelectionActive() )
                {
                    std::vector<int> integerVector = propertyFilter->selectedCategoryValues();
                    std::set<int>    integerSet;
                    for ( auto val : integerVector )
                    {
                        integerSet.insert( val );
                    }

                    for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
                    {
                        if ( ( *cellVisibility )[cellIndex] )
                        {
                            size_t resultValueIndex = cellIndex;

                            double scalarValue = resultAccessor->cellScalar( resultValueIndex );
                            if ( integerSet.find( scalarValue ) != integerSet.end() )
                            {
                                if ( filterType == RimCellFilter::EXCLUDE )
                                {
                                    ( *cellVisibility )[cellIndex] = false;
                                }
                            }
                            else
                            {
                                if ( filterType == RimCellFilter::INCLUDE )
                                {
                                    ( *cellVisibility )[cellIndex] = false;
                                }
                            }
                        }
                    }
                }
                else
                {
                    double lowerBound = 0.0;
                    double upperBound = 0.0;
                    propertyFilter->rangeValues( &lowerBound, &upperBound );

                    for ( int cellIndex = 0; cellIndex < static_cast<int>( grid->cellCount() ); cellIndex++ )
                    {
                        if ( ( *cellVisibility )[cellIndex] )
                        {
                            size_t resultValueIndex = cellIndex;

                            double scalarValue = resultAccessor->cellScalar( resultValueIndex );
                            if ( lowerBound <= scalarValue && scalarValue <= upperBound )
                            {
                                if ( filterType == RimCellFilter::EXCLUDE )
                                {
                                    ( *cellVisibility )[cellIndex] = false;
                                }
                            }
                            else
                            {
                                if ( filterType == RimCellFilter::INCLUDE )
                                {
                                    ( *cellVisibility )[cellIndex] = false;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::updateCellColor( RivCellSetEnum geometryType, size_t timeStepIndex, cvf::Color4f color )
{
    RivReservoirPartMgr* pmgr = reservoirPartManager( geometryType, timeStepIndex );
    pmgr->updateCellColor( color );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::updateCellResultColor( RivCellSetEnum geometryType, size_t timeStepIndex, RimEclipseCellColors* cellResultColors )
{
    RivReservoirPartMgr* pmgr = reservoirPartManager( geometryType, timeStepIndex );
    pmgr->updateCellResultColor( timeStepIndex, cellResultColors );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::updateCellEdgeResultColor( RivCellSetEnum        geometryType,
                                                         size_t                timeStepIndex,
                                                         RimEclipseCellColors* cellResultColors,
                                                         RimCellEdgeColors*    cellEdgeResultColors )
{
    RivReservoirPartMgr* pmgr = reservoirPartManager( geometryType, timeStepIndex );
    pmgr->updateCellEdgeResultColor( timeStepIndex, cellResultColors, cellEdgeResultColors );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::updateFaultCellEdgeResultColor( RivCellSetEnum        geometryType,
                                                              size_t                timeStepIndex,
                                                              RimEclipseCellColors* cellResultColors,
                                                              RimCellEdgeColors*    cellEdgeResultColors )
{
    RivReservoirPartMgr* pmgr = reservoirPartManager( geometryType, timeStepIndex );
    pmgr->updateFaultCellEdgeResultColor( timeStepIndex, cellResultColors, cellEdgeResultColors );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::UByteArray* RivReservoirViewPartMgr::cellVisibility( RivCellSetEnum geometryType, size_t gridIndex, size_t timeStepIndex )
{
    ensureDynamicGeometryPartsCreated( geometryType, timeStepIndex );
    ensureStaticGeometryPartsCreated( geometryType );

    RivReservoirPartMgr* pmgr = ( const_cast<RivReservoirViewPartMgr*>( this ) )->reservoirPartManager( geometryType, timeStepIndex );

    return pmgr->cellVisibility( gridIndex ).p();
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivReservoirPartMgr* RivReservoirViewPartMgr::reservoirPartManager( RivCellSetEnum geometryType, size_t timeStepIndex )
{
    if ( geometryType == PROPERTY_FILTERED )
    {
        return m_propFilteredGeometryFrames[timeStepIndex].p();
    }
    else if ( geometryType == PROPERTY_FILTERED_WELL_CELLS )
    {
        return m_propFilteredWellGeometryFrames[timeStepIndex].p();
    }
    else
    {
        return &m_geometries[geometryType];
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::updateFaultColors( RivCellSetEnum geometryType, size_t timeStepIndex, RimEclipseCellColors* cellResultColors )
{
    if ( geometryType == PROPERTY_FILTERED && timeStepIndex >= m_propFilteredGeometryFrames.size() )
    {
        return;
    }

    if ( geometryType == PROPERTY_FILTERED_WELL_CELLS && timeStepIndex >= m_propFilteredWellGeometryFrames.size() )
    {
        return;
    }

    RivReservoirPartMgr* pmgr = reservoirPartManager( geometryType, timeStepIndex );
    pmgr->updateFaultColors( timeStepIndex, cellResultColors );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendFaultsStaticGeometryPartsToModel( cvf::ModelBasicList* model, RivCellSetEnum geometryType )
{
    if ( geometryType >= PROPERTY_FILTERED ) return;

    ensureStaticGeometryPartsCreated( geometryType );

    /*
        QString text;
        switch (geometryType)
        {
        case OVERRIDDEN_CELL_VISIBILITY:
            text = "OVERRIDDEN_CELL_VISIBILITY";
            break;
        case ALL_CELLS:
            text = "ALL_CELLS";
            break;
        case ACTIVE:
            text = "ACTIVE";
            break;
        case ALL_WELL_CELLS:
            text = "ALL_WELL_CELLS";
            break;
        case VISIBLE_WELL_CELLS:
            text = "VISIBLE_WELL_CELLS";
            break;
        case VISIBLE_WELL_FENCE_CELLS:
            text = "VISIBLE_WELL_FENCE_CELLS";
            break;
        case INACTIVE:
            text = "INACTIVE";
            break;
        case RANGE_FILTERED:
            text = "RANGE_FILTERED";
            break;
        case RANGE_FILTERED_INACTIVE:
            text = "RANGE_FILTERED_INACTIVE";
            break;
        case RANGE_FILTERED_WELL_CELLS:
            text = "RANGE_FILTERED_WELL_CELLS";
            break;
        case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER:
            text = "VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER";
            break;
        case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER:
            text = "VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER";
            break;
        case PROPERTY_FILTERED:
            text = "PROPERTY_FILTERED";
            break;
        case PROPERTY_FILTERED_WELL_CELLS:
            text = "PROPERTY_FILTERED_WELL_CELLS";
            break;
        default:
            break;
        }

        qDebug() << text;
    */

    m_geometries[geometryType].appendFaultPartsToModel( model );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendFaultsDynamicGeometryPartsToModel( cvf::ModelBasicList* model, RivCellSetEnum geometryType, size_t frameIndex )
{
    if ( geometryType == PROPERTY_FILTERED )
    {
        // qDebug() << "PROPERTY_FILTERED";

        m_propFilteredGeometryFrames[frameIndex]->appendFaultPartsToModel( model );
    }
    else if ( geometryType == PROPERTY_FILTERED_WELL_CELLS )
    {
        // qDebug() << "PROPERTY_FILTERED_WELL_CELLS";

        m_propFilteredWellGeometryFrames[frameIndex]->appendFaultPartsToModel( model );
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivCellSetEnum RivReservoirViewPartMgr::geometryTypeForFaultLabels( const std::set<RivCellSetEnum>& geometryTypes,
                                                                    bool                            showFaultsOutsideFilters ) const
{
    for ( RivCellSetEnum cellSetType : geometryTypes )
    {
        if ( !showFaultsOutsideFilters )
        {
            if ( cellSetType == PROPERTY_FILTERED )
            {
                return PROPERTY_FILTERED;
            }

            if ( cellSetType == RANGE_FILTERED )
            {
                return RANGE_FILTERED;
            }
        }
    }

    return ACTIVE;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendFaultLabelsStaticGeometryPartsToModel( cvf::ModelBasicList* model, RivCellSetEnum geometryType )
{
    ensureStaticGeometryPartsCreated( geometryType );
    m_geometries[geometryType].appendFaultLabelPartsToModel( model );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendFaultLabelsDynamicGeometryPartsToModel( cvf::ModelBasicList* model,
                                                                            RivCellSetEnum       geometryType,
                                                                            size_t               frameIndex )
{
    m_propFilteredGeometryFrames[frameIndex]->appendFaultLabelPartsToModel( model );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::appendElementVectorResultDynamicGeometryPartsToModel( cvf::ModelBasicList* model,
                                                                                    RivCellSetEnum       geometryType,
                                                                                    size_t               frameIndex )
{
    ensureDynamicGeometryPartsCreated( geometryType, frameIndex );
    if ( geometryType == PROPERTY_FILTERED )
    {
        m_propFilteredGeometryFrames[frameIndex]->appendElementVectorResultPartsToModel( model, frameIndex );
    }
    else if ( geometryType == PROPERTY_FILTERED_WELL_CELLS )
    {
        m_propFilteredWellGeometryFrames[frameIndex]->appendElementVectorResultPartsToModel( model, frameIndex );
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::forceWatertightGeometryOnForType( RivCellSetEnum geometryType )
{
    if ( geometryType == PROPERTY_FILTERED )
    {
        for ( size_t i = 0; i < m_propFilteredGeometryFrames.size(); ++i )
        {
            if ( m_propFilteredGeometryFrames[i].p() ) m_propFilteredGeometryFrames[i]->forceWatertightGeometryOn();
        }
    }
    else if ( geometryType == PROPERTY_FILTERED_WELL_CELLS )
    {
        for ( size_t i = 0; i < m_propFilteredWellGeometryFrames.size(); ++i )
        {
            if ( m_propFilteredWellGeometryFrames[i].p() ) m_propFilteredWellGeometryFrames[i]->forceWatertightGeometryOn();
        }
    }
    else
    {
        ensureStaticGeometryPartsCreated( geometryType );
        m_geometries[geometryType].forceWatertightGeometryOn();
    }
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirViewPartMgr::clearWatertightGeometryFlags()
{
    for ( size_t i = 0; i < m_propFilteredGeometryFrames.size(); ++i )
    {
        if ( m_propFilteredGeometryFrames[i].p() ) m_propFilteredGeometryFrames[i]->clearWatertightGeometryFlag();
    }

    for ( size_t i = 0; i < m_propFilteredWellGeometryFrames.size(); ++i )
    {
        if ( m_propFilteredWellGeometryFrames[i].p() ) m_propFilteredWellGeometryFrames[i]->clearWatertightGeometryFlag();
    }

    for ( int i = 0; i < PROPERTY_FILTERED; i++ )
    {
        m_geometries[RivCellSetEnum( i )].clearWatertightGeometryFlag();
    }
}
