mirror of
				https://github.com/OPM/ResInsight.git
				synced 2025-02-25 18:55:39 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			503 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			503 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
//  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 "RigGridBase.h"
 | 
						|
#include "RigMainGrid.h"
 | 
						|
#include "RigCell.h"
 | 
						|
#include "RigCaseCellResultsData.h"
 | 
						|
#include "RigResultAccessorFactory.h"
 | 
						|
 | 
						|
#include "cvfAssert.h"
 | 
						|
 | 
						|
 | 
						|
RigGridBase::RigGridBase(RigMainGrid* mainGrid):
 | 
						|
    m_gridPointDimensions(0,0,0),
 | 
						|
    m_indexToStartOfCells(0),
 | 
						|
    m_mainGrid(mainGrid)
 | 
						|
{
 | 
						|
    if (mainGrid == nullptr)
 | 
						|
    {
 | 
						|
        m_gridIndex = 0;
 | 
						|
        m_gridId    = 0;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m_gridIndex = cvf::UNDEFINED_SIZE_T;
 | 
						|
        m_gridId = cvf::UNDEFINED_INT;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
RigGridBase::~RigGridBase(void)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigGridBase::setGridName(const std::string& gridName)
 | 
						|
{
 | 
						|
    m_gridName = gridName;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
std::string RigGridBase::gridName() const
 | 
						|
{
 | 
						|
    return m_gridName;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// Do we need this ?
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
RigCell& RigGridBase::cell(size_t gridLocalCellIndex)
 | 
						|
{
 | 
						|
     CVF_ASSERT(m_mainGrid);
 | 
						|
 | 
						|
     CVF_ASSERT(m_indexToStartOfCells + gridLocalCellIndex < m_mainGrid->globalCellArray().size());
 | 
						|
 | 
						|
     return m_mainGrid->globalCellArray()[m_indexToStartOfCells + gridLocalCellIndex];
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
const RigCell& RigGridBase::cell(size_t gridLocalCellIndex) const
 | 
						|
{
 | 
						|
    CVF_ASSERT(m_mainGrid);
 | 
						|
 | 
						|
    return m_mainGrid->globalCellArray()[m_indexToStartOfCells + gridLocalCellIndex];
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigGridBase::initSubGridParentPointer()
 | 
						|
{
 | 
						|
    RigGridBase* grid = this;
 | 
						|
 | 
						|
    size_t cellIdx;
 | 
						|
    for (cellIdx = 0; cellIdx < grid->cellCount(); ++cellIdx)
 | 
						|
    {
 | 
						|
        RigCell& cell = grid->cell(cellIdx);
 | 
						|
        if (cell.subGrid())
 | 
						|
        {
 | 
						|
            cell.subGrid()->setParentGrid(grid);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// Find the cell index to the maingrid cell containing this cell, and store it as 
 | 
						|
/// m_mainGridCellIndex in each cell.
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigGridBase::initSubCellsMainGridCellIndex()
 | 
						|
{
 | 
						|
    RigGridBase* grid = this;
 | 
						|
    if (grid->isMainGrid())
 | 
						|
    {
 | 
						|
        size_t cellIdx;
 | 
						|
        for (cellIdx = 0; cellIdx < grid->cellCount(); ++cellIdx)
 | 
						|
        {
 | 
						|
            RigCell& cell = grid->cell(cellIdx);
 | 
						|
            cell.setMainGridCellIndex(cellIdx);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        size_t cellIdx;
 | 
						|
        for (cellIdx = 0; cellIdx < grid->cellCount(); ++cellIdx)
 | 
						|
        {
 | 
						|
            RigLocalGrid* localGrid = static_cast<RigLocalGrid*>(grid);
 | 
						|
            RigGridBase* parentGrid = localGrid->parentGrid();
 | 
						|
 | 
						|
            RigCell& cell = localGrid->cell(cellIdx);
 | 
						|
            size_t parentCellIndex = cell.parentCellIndex();
 | 
						|
 | 
						|
            while (!parentGrid->isMainGrid())
 | 
						|
            {
 | 
						|
                const RigCell& parentCell = parentGrid->cell(parentCellIndex);
 | 
						|
                parentCellIndex = parentCell.parentCellIndex();
 | 
						|
 | 
						|
                localGrid = static_cast<RigLocalGrid*>(parentGrid);
 | 
						|
                parentGrid = localGrid->parentGrid();
 | 
						|
            }
 | 
						|
 | 
						|
            cell.setMainGridCellIndex(parentCellIndex);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// For main grid, this will work with reservoirCellIndices retreiving the correct lgr cells as well.
 | 
						|
/// the cell() call retreives correct cell, because main grid has offset of 0, and we access the global 
 | 
						|
/// cell array in main grid.
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigGridBase::cellCornerVertices(size_t cellIndex, cvf::Vec3d vertices[8]) const
 | 
						|
{
 | 
						|
    const std::array<size_t, 8>& indices = cell(cellIndex).cornerIndices();
 | 
						|
    
 | 
						|
    vertices[0].set(m_mainGrid->nodes()[indices[0]]);
 | 
						|
    vertices[1].set(m_mainGrid->nodes()[indices[1]]);
 | 
						|
    vertices[2].set(m_mainGrid->nodes()[indices[2]]);
 | 
						|
    vertices[3].set(m_mainGrid->nodes()[indices[3]]);
 | 
						|
    vertices[4].set(m_mainGrid->nodes()[indices[4]]);
 | 
						|
    vertices[5].set(m_mainGrid->nodes()[indices[5]]);
 | 
						|
    vertices[6].set(m_mainGrid->nodes()[indices[6]]);
 | 
						|
    vertices[7].set(m_mainGrid->nodes()[indices[7]]);
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::cellIndexFromIJK(size_t i, size_t j, size_t k) const
 | 
						|
{
 | 
						|
    CVF_TIGHT_ASSERT(i != cvf::UNDEFINED_SIZE_T && j != cvf::UNDEFINED_SIZE_T && k != cvf::UNDEFINED_SIZE_T );
 | 
						|
    CVF_TIGHT_ASSERT(i < m_gridPointDimensions.x() && j < m_gridPointDimensions.y() && k < m_gridPointDimensions.z()  );
 | 
						|
 | 
						|
    size_t ci = i + j*(m_gridPointDimensions.x() - 1) + k*((m_gridPointDimensions.x() - 1)*(m_gridPointDimensions.y() - 1));
 | 
						|
    return ci;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigGridBase::cellMinMaxCordinates(size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate) const
 | 
						|
{
 | 
						|
    
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigGridBase::ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const
 | 
						|
{
 | 
						|
    CVF_TIGHT_ASSERT(cellIndex < cellCount());
 | 
						|
 | 
						|
    size_t index = cellIndex;
 | 
						|
 | 
						|
    if (cellCountI() <= 0 || cellCountJ() <= 0)
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    *k      = index/(cellCountI()*cellCountJ());
 | 
						|
    index   -= (*k)*(cellCountI()*cellCountJ());
 | 
						|
    *j      = index/cellCountI();
 | 
						|
    index   -= (*j)*cellCountI();
 | 
						|
    *i      = index;
 | 
						|
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::gridPointIndexFromIJK(size_t i, size_t j, size_t k) const
 | 
						|
{
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigGridBase::cellIJKFromCoordinate(const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k) const
 | 
						|
{
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
cvf::Vec3d RigGridBase::gridPointCoordinate(size_t i, size_t j, size_t k) const
 | 
						|
{
 | 
						|
    cvf::Vec3d pos;
 | 
						|
 | 
						|
    return pos;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
cvf::Vec3d RigGridBase::minCoordinate() const
 | 
						|
{
 | 
						|
    cvf::Vec3d v;
 | 
						|
 | 
						|
    return v;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::gridPointCountI() const
 | 
						|
{
 | 
						|
    return m_gridPointDimensions.x();
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::gridPointCountJ() const
 | 
						|
{
 | 
						|
    return m_gridPointDimensions.y();
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::gridPointCountK() const
 | 
						|
{
 | 
						|
    return m_gridPointDimensions.z();
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
cvf::Vec3d RigGridBase::cellCentroid(size_t cellIndex) const
 | 
						|
{
 | 
						|
    cvf::Vec3d v;
 | 
						|
 | 
						|
    return v;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
cvf::Vec3d RigGridBase::maxCoordinate() const
 | 
						|
{
 | 
						|
    cvf::Vec3d v;
 | 
						|
 | 
						|
    return v;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigGridBase::isCellValid(size_t i, size_t j, size_t k) const
 | 
						|
{
 | 
						|
    if (i >= cellCountI() || j >= cellCountJ() || k >= cellCountK())
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    size_t idx = cellIndexFromIJK(i, j, k);
 | 
						|
    const RigCell& c = cell(idx);
 | 
						|
    return !c.isInvalid();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigGridBase::cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex) const
 | 
						|
{
 | 
						|
    size_t ni, nj, nk;
 | 
						|
    neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk);
 | 
						|
 | 
						|
    if (!isCellValid(ni, nj, nk))
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (neighborCellIndex)
 | 
						|
    {
 | 
						|
        *neighborCellIndex = cellIndexFromIJK(ni, nj, nk);
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigGridBase::isMainGrid() const
 | 
						|
{
 | 
						|
    return this == m_mainGrid;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// Models with large absolute values for coordinate scalars will often end up with z-fighting due
 | 
						|
/// to numerical limits in float used by OpenGL to represent a position. displayModelOffset() is intended
 | 
						|
//  to be subtracted from domain model coordinate when building geometry for visualization
 | 
						|
//
 | 
						|
//  Vec3d domainModelCoord
 | 
						|
//  Vec3d coordForVisualization
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
cvf::Vec3d RigGridBase::displayModelOffset() const
 | 
						|
{
 | 
						|
    return m_mainGrid->displayModelOffset();
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// Returns the min size of the I and J charactristic cell sizes
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
double RigGridBase::characteristicIJCellSize() const
 | 
						|
{
 | 
						|
    double characteristicCellSize = HUGE_VAL;
 | 
						|
 | 
						|
    double cellSizeI, cellSizeJ, cellSizeK;
 | 
						|
    this->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK);
 | 
						|
 | 
						|
    if (cellSizeI < characteristicCellSize) characteristicCellSize = cellSizeI;
 | 
						|
    if (cellSizeJ < characteristicCellSize) characteristicCellSize = cellSizeJ;
 | 
						|
   
 | 
						|
 | 
						|
    return characteristicCellSize;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::reservoirCellIndex(size_t gridLocalCellIndex) const
 | 
						|
{
 | 
						|
    return m_indexToStartOfCells + gridLocalCellIndex;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
size_t RigGridBase::addCoarseningBox(size_t i1, size_t i2, size_t j1, size_t j2, size_t k1, size_t k2)
 | 
						|
{
 | 
						|
    std::array<size_t, 6> box;
 | 
						|
    box[0] = i1;
 | 
						|
    box[1] = i2;
 | 
						|
    box[2] = j1;
 | 
						|
    box[3] = j2;
 | 
						|
    box[4] = k1;
 | 
						|
    box[5] = k2;
 | 
						|
 | 
						|
    m_coarseningBoxInfo.push_back(box);
 | 
						|
 | 
						|
    size_t coarseningBoxIndex = m_coarseningBoxInfo.size() - 1;
 | 
						|
 | 
						|
    for (size_t k = k1; k <= k2; k++)
 | 
						|
    {
 | 
						|
        for (size_t j = j1; j <= j2; j++)
 | 
						|
        {
 | 
						|
            for (size_t i = i1; i <= i2; i++)
 | 
						|
            {
 | 
						|
                size_t cellIdx = this->cellIndexFromIJK(i, j, k);
 | 
						|
 | 
						|
                RigCell& c = this->cell(cellIdx);
 | 
						|
                CVF_ASSERT(c.coarseningBoxIndex() == cvf::UNDEFINED_SIZE_T);
 | 
						|
 | 
						|
                c.setCoarseningBoxIndex(coarseningBoxIndex);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return coarseningBoxIndex;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
void RigGridBase::coarseningBox(size_t coarseningBoxIndex, size_t* i1, size_t* i2, size_t* j1, size_t* j2, size_t* k1, size_t* k2) const
 | 
						|
{
 | 
						|
    CVF_ASSERT(coarseningBoxIndex < m_coarseningBoxInfo.size());
 | 
						|
 | 
						|
    CVF_ASSERT(i1 && i2 && j1 && j2 && k1 && k2);
 | 
						|
 | 
						|
    const std::array<size_t, 6>& box = m_coarseningBoxInfo[coarseningBoxIndex];
 | 
						|
    *i1 = box[0];
 | 
						|
    *i2 = box[1];
 | 
						|
    *j1 = box[2];
 | 
						|
    *j2 = box[3];
 | 
						|
    *k1 = box[4];
 | 
						|
    *k2 = box[5];
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
cvf::BoundingBox RigGridBase::boundingBox()
 | 
						|
{
 | 
						|
    if (!m_boundingBox.isValid())
 | 
						|
    {
 | 
						|
        cvf::Vec3d cornerVerts[8];
 | 
						|
 | 
						|
        for (size_t i = 0; i < cellCount(); i++)
 | 
						|
        {
 | 
						|
            cellCornerVertices(i, cornerVerts);
 | 
						|
 | 
						|
            for (size_t j = 0; j < 8; j++)
 | 
						|
            {
 | 
						|
                m_boundingBox.add(cornerVerts[j]);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    return m_boundingBox;
 | 
						|
}
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
/// 
 | 
						|
//--------------------------------------------------------------------------------------------------
 | 
						|
bool RigGridCellFaceVisibilityFilter::isFaceVisible(size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility) const
 | 
						|
{
 | 
						|
    CVF_TIGHT_ASSERT(m_grid);
 | 
						|
 | 
						|
    size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k);
 | 
						|
    if (m_grid->cell(cellIndex).subGrid())
 | 
						|
    {
 | 
						|
        // Do not show any faces in the place where a LGR is present
 | 
						|
        return false; 
 | 
						|
    }
 | 
						|
 | 
						|
    size_t ni, nj, nk;
 | 
						|
    cvf::StructGridInterface::neighborIJKAtCellFace(i, j, k, face, &ni, &nj, &nk);
 | 
						|
 | 
						|
    // If the cell is on the edge of the grid, Interpret as having an invisible neighbour
 | 
						|
    if (ni >= m_grid->cellCountI() || nj >= m_grid->cellCountJ() || nk >= m_grid->cellCountK())
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
       
 | 
						|
    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;
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 |