2012-05-18 09:45:23 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
2014-09-23 15:04:57 +02:00
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
2012-05-18 09:45:23 +02:00
//
// 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 "RigMainGrid.h"
2017-03-31 11:10:22 +02:00
#include "RiaLogging.h"
2017-06-13 15:41:52 +02:00
#include "RiaDefines.h"
2014-08-18 18:30:52 +02:00
#include "RigFault.h"
2016-08-22 13:24:46 +02:00
#include "RigActiveCellInfo.h"
2014-08-18 18:30:52 +02:00
2017-03-31 11:10:22 +02:00
#include "cvfBoundingBoxTree.h"
#include "cvfAssert.h"
2012-05-18 09:45:23 +02:00
RigMainGrid :: RigMainGrid ( void )
2013-02-12 14:00:39 +01:00
: RigGridBase ( this )
2012-05-18 09:45:23 +02:00
{
2013-02-13 11:04:45 +01:00
m_displayModelOffset = cvf :: Vec3d :: ZERO ;
2012-05-18 09:45:23 +02:00
m_gridIndex = 0 ;
2013-09-05 13:03:53 +02:00
m_gridId = 0 ;
m_gridIdToIndexMapping . push_back ( 0 );
2013-04-26 13:19:34 +02:00
m_flipXAxis = false ;
m_flipYAxis = false ;
2013-02-13 11:04:45 +01:00
}
2012-05-18 09:45:23 +02:00
RigMainGrid ::~ RigMainGrid ( void )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: addLocalGrid ( RigLocalGrid * localGrid )
{
2013-09-05 13:03:53 +02:00
CVF_ASSERT ( localGrid && localGrid -> gridId () != cvf :: UNDEFINED_INT ); // The grid ID must be set.
CVF_ASSERT ( localGrid -> gridId () >= 0 ); // We cant handle negative ID's if they exist.
2012-05-18 09:45:23 +02:00
m_localGrids . push_back ( localGrid );
localGrid -> setGridIndex ( m_localGrids . size ()); // Maingrid itself has grid index 0
2013-09-05 13:03:53 +02:00
2013-09-10 08:47:28 +02:00
if ( m_gridIdToIndexMapping . size () <= static_cast < size_t > ( localGrid -> gridId ()))
2013-09-05 13:03:53 +02:00
{
m_gridIdToIndexMapping . resize ( localGrid -> gridId () + 1 , cvf :: UNDEFINED_SIZE_T );
}
m_gridIdToIndexMapping [ localGrid -> gridId ()] = localGrid -> gridIndex ();
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: initAllSubGridsParentGridPointer ()
{
initSubGridParentPointer ();
size_t i ;
for ( i = 0 ; i < m_localGrids . size (); ++ i )
{
m_localGrids [ i ] -> initSubGridParentPointer ();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: initAllSubCellsMainGridCellIndex ()
{
initSubCellsMainGridCellIndex ();
size_t i ;
for ( i = 0 ; i < m_localGrids . size (); ++ i )
{
m_localGrids [ i ] -> initSubCellsMainGridCellIndex ();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf :: Vec3d RigMainGrid :: displayModelOffset () const
{
2013-02-13 11:04:45 +01:00
return m_displayModelOffset ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-02-13 11:04:45 +01:00
void RigMainGrid :: setDisplayModelOffset ( cvf :: Vec3d offset )
2012-05-18 09:45:23 +02:00
{
2013-02-13 11:04:45 +01:00
m_displayModelOffset = offset ;
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Initialize pointers from grid to parent grid
/// Compute cell ranges for active and valid cells
/// Compute bounding box in world coordinates based on node coordinates
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: computeCachedData ()
{
initAllSubGridsParentGridPointer ();
initAllSubCellsMainGridCellIndex ();
2015-12-09 15:36:37 +01:00
buildCellSearchTree ();
2012-05-18 09:45:23 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Returns the grid with index \a localGridIndex. Main Grid itself has index 0. First LGR starts on 1
//--------------------------------------------------------------------------------------------------
RigGridBase * RigMainGrid :: gridByIndex ( size_t localGridIndex )
{
if ( localGridIndex == 0 ) return this ;
CVF_ASSERT ( localGridIndex - 1 < m_localGrids . size ()) ;
return m_localGrids [ localGridIndex - 1 ]. p ();
}
//--------------------------------------------------------------------------------------------------
/// Returns the grid with index \a localGridIndex. Main Grid itself has index 0. First LGR starts on 1
//--------------------------------------------------------------------------------------------------
const RigGridBase * RigMainGrid :: gridByIndex ( size_t localGridIndex ) const
{
if ( localGridIndex == 0 ) return this ;
CVF_ASSERT ( localGridIndex - 1 < m_localGrids . size ()) ;
return m_localGrids [ localGridIndex - 1 ]. p ();
}
2013-01-30 14:13:50 +01:00
2013-04-26 13:19:34 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: setFlipAxis ( bool flipXAxis , bool flipYAxis )
{
bool needFlipX = false ;
bool needFlipY = false ;
if ( m_flipXAxis != flipXAxis )
{
needFlipX = true ;
}
if ( m_flipYAxis != flipYAxis )
{
needFlipY = true ;
}
if ( needFlipX || needFlipY )
{
for ( size_t i = 0 ; i < m_nodes . size (); i ++ )
{
if ( needFlipX )
{
m_nodes [ i ]. x () *= - 1.0 ;
}
if ( needFlipY )
{
m_nodes [ i ]. y () *= - 1.0 ;
}
}
m_flipXAxis = flipXAxis ;
m_flipYAxis = flipYAxis ;
}
}
2013-09-05 13:03:53 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGridBase * RigMainGrid :: gridById ( int localGridId )
{
2013-09-10 08:47:28 +02:00
CVF_ASSERT ( localGridId >= 0 && static_cast < size_t > ( localGridId ) < m_gridIdToIndexMapping . size ());
2013-09-05 13:03:53 +02:00
return this -> gridByIndex ( m_gridIdToIndexMapping [ localGridId ]);
}
2013-12-10 22:44:40 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigNNCData * RigMainGrid :: nncData ()
{
if ( m_nncData . isNull ())
{
m_nncData = new RigNNCData ;
}
return m_nncData . p ();
}
2013-12-12 22:15:14 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: setFaults ( const cvf :: Collection < RigFault >& faults )
{
m_faults = faults ;
#pragma omp parallel for
2013-12-14 09:38:55 +01:00
for ( int i = 0 ; i < static_cast < int > ( m_faults . size ()); i ++ )
2013-12-12 22:15:14 +01:00
{
m_faults [ i ] -> computeFaultFacesFromCellRanges ( this -> mainGrid ());
}
}
2017-03-31 11:10:22 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigMainGrid :: hasFaultWithName ( const QString & name ) const
{
for ( auto fault : m_faults )
{
if ( fault -> name () == name )
{
return true ;
}
}
return false ;
}
2013-12-12 22:15:14 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-08-22 13:24:46 +02:00
void RigMainGrid :: calculateFaults ( const RigActiveCellInfo * activeCellInfo )
2013-12-12 22:15:14 +01:00
{
2017-06-13 15:41:52 +02:00
if ( hasFaultWithName ( RiaDefines :: undefinedGridFaultName ())
&& hasFaultWithName ( RiaDefines :: undefinedGridFaultWithInactiveName ()))
2017-03-31 11:10:22 +02:00
{
2017-04-27 14:14:06 +02:00
//RiaLogging::debug(QString("Calculate faults already run for grid."));
2017-03-31 11:10:22 +02:00
return ;
}
2014-08-18 18:30:52 +02:00
m_faultsPrCellAcc = new RigFaultsPrCellAccumulator ( m_cells . size ());
2013-12-12 22:15:14 +01:00
// Spread fault idx'es on the cells from the faults
for ( size_t fIdx = 0 ; fIdx < m_faults . size (); ++ fIdx )
{
2014-08-18 18:30:52 +02:00
m_faults [ fIdx ] -> accumulateFaultsPrCell ( m_faultsPrCellAcc . p (), static_cast < int > ( fIdx ));
2013-12-12 22:15:14 +01:00
}
2016-08-22 10:48:40 +02:00
// Find the geometrical faults that is in addition: Has no user defined (eclipse) fault assigned.
// Separate the grid faults that has an inactive cell as member
2013-12-12 22:15:14 +01:00
2016-11-18 14:40:42 +01:00
RigFault * unNamedFault = new RigFault ;
2017-06-13 15:41:52 +02:00
unNamedFault -> setName ( RiaDefines :: undefinedGridFaultName ());
2013-12-12 22:15:14 +01:00
int unNamedFaultIdx = static_cast < int > ( m_faults . size ());
2016-11-18 14:40:42 +01:00
m_faults . push_back ( unNamedFault );
2013-12-12 22:15:14 +01:00
2016-11-18 14:40:42 +01:00
RigFault * unNamedFaultWithInactive = new RigFault ;
2017-06-13 15:41:52 +02:00
unNamedFaultWithInactive -> setName ( RiaDefines :: undefinedGridFaultWithInactiveName ());
2016-08-22 13:24:46 +02:00
int unNamedFaultWithInactiveIdx = static_cast < int > ( m_faults . size ());
2016-11-18 14:40:42 +01:00
m_faults . push_back ( unNamedFaultWithInactive );
2016-08-22 13:24:46 +02:00
2016-08-22 10:48:40 +02:00
const std :: vector < cvf :: Vec3d >& vxs = m_mainGrid -> nodes ();
2014-04-24 09:53:40 +02:00
for ( int gcIdx = 0 ; gcIdx < static_cast < int > ( m_cells . size ()); ++ gcIdx )
2013-12-12 22:15:14 +01:00
{
if ( m_cells [ gcIdx ]. isInvalid ())
{
continue ;
}
2014-08-08 10:51:39 +02:00
size_t neighborReservoirCellIdx ;
2013-12-12 22:15:14 +01:00
size_t neighborGridCellIdx ;
size_t i , j , k ;
2013-12-16 14:25:27 +01:00
RigGridBase * hostGrid = NULL ;
2013-12-12 22:15:14 +01:00
bool firstNO_FAULTFaceForCell = true ;
2016-08-22 13:24:46 +02:00
bool isCellActive = true ;
2013-12-12 22:15:14 +01:00
2017-10-19 12:54:44 +02:00
char upperLimitForFaceType = cvf :: StructGridInterface :: FaceType :: POS_K ;
// Compare only I and J faces
for ( char faceIdx = 0 ; faceIdx < upperLimitForFaceType ; ++ faceIdx )
2013-12-12 22:15:14 +01:00
{
cvf :: StructGridInterface :: FaceType face = cvf :: StructGridInterface :: FaceType ( faceIdx );
2016-08-22 10:48:40 +02:00
// For faces that has no used defined Fault assigned:
2014-08-18 18:30:52 +02:00
if ( m_faultsPrCellAcc -> faultIdx ( gcIdx , face ) == RigFaultsPrCellAccumulator :: NO_FAULT )
2013-12-12 22:15:14 +01:00
{
// Find neighbor cell
if ( firstNO_FAULTFaceForCell ) // To avoid doing this for every face, and only when detecting a NO_FAULT
{
hostGrid = m_cells [ gcIdx ]. hostGrid ();
2014-08-22 08:01:31 +02:00
hostGrid -> ijkFromCellIndex ( m_cells [ gcIdx ]. gridLocalCellIndex (), & i , & j , & k );
2016-08-22 13:24:46 +02:00
isCellActive = activeCellInfo -> isActive ( gcIdx );
2013-12-12 22:15:14 +01:00
firstNO_FAULTFaceForCell = false ;
}
if ( ! hostGrid -> cellIJKNeighbor ( i , j , k , face , & neighborGridCellIdx ))
{
continue ;
}
2014-08-08 10:51:39 +02:00
neighborReservoirCellIdx = hostGrid -> reservoirCellIndex ( neighborGridCellIdx );
if ( m_cells [ neighborReservoirCellIdx ]. isInvalid ())
2013-12-12 22:15:14 +01:00
{
continue ;
}
2016-08-22 13:24:46 +02:00
bool isNeighborCellActive = activeCellInfo -> isActive ( neighborReservoirCellIdx );
2013-12-12 22:15:14 +01:00
double tolerance = 1e-6 ;
caf :: SizeTArray4 faceIdxs ;
m_cells [ gcIdx ]. faceIndices ( face , & faceIdxs );
caf :: SizeTArray4 nbFaceIdxs ;
2014-08-08 10:51:39 +02:00
m_cells [ neighborReservoirCellIdx ]. faceIndices ( StructGridInterface :: oppositeFace ( face ), & nbFaceIdxs );
2013-12-12 22:15:14 +01:00
bool sharedFaceVertices = true ;
if ( sharedFaceVertices && vxs [ faceIdxs [ 0 ]]. pointDistance ( vxs [ nbFaceIdxs [ 0 ]]) > tolerance ) sharedFaceVertices = false ;
if ( sharedFaceVertices && vxs [ faceIdxs [ 1 ]]. pointDistance ( vxs [ nbFaceIdxs [ 3 ]]) > tolerance ) sharedFaceVertices = false ;
if ( sharedFaceVertices && vxs [ faceIdxs [ 2 ]]. pointDistance ( vxs [ nbFaceIdxs [ 2 ]]) > tolerance ) sharedFaceVertices = false ;
if ( sharedFaceVertices && vxs [ faceIdxs [ 3 ]]. pointDistance ( vxs [ nbFaceIdxs [ 1 ]]) > tolerance ) sharedFaceVertices = false ;
if ( sharedFaceVertices )
{
continue ;
}
2016-08-22 13:24:46 +02:00
// To avoid doing this calculation for the opposite face
int faultIdx = unNamedFaultIdx ;
if ( ! ( isCellActive && isNeighborCellActive )) faultIdx = unNamedFaultWithInactiveIdx ;
2013-12-12 22:15:14 +01:00
2016-08-22 13:24:46 +02:00
m_faultsPrCellAcc -> setFaultIdx ( gcIdx , face , faultIdx );
m_faultsPrCellAcc -> setFaultIdx ( neighborReservoirCellIdx , StructGridInterface :: oppositeFace ( face ), faultIdx );
2013-12-17 13:27:22 +01:00
2013-12-12 22:15:14 +01:00
// Add as fault face only if the grid index is less than the neighbors
2014-08-08 10:51:39 +02:00
if ( static_cast < size_t > ( gcIdx ) < neighborReservoirCellIdx )
2013-12-12 22:15:14 +01:00
{
2016-11-18 14:40:42 +01:00
RigFault :: FaultFace ff ( gcIdx , cvf :: StructGridInterface :: FaceType ( faceIdx ), neighborReservoirCellIdx );
if ( isCellActive && isNeighborCellActive )
2014-04-24 09:53:40 +02:00
{
2016-11-18 14:40:42 +01:00
unNamedFault -> faultFaces (). push_back ( ff );
}
else
{
unNamedFaultWithInactive -> faultFaces (). push_back ( ff );
2014-04-24 09:53:40 +02:00
}
2013-12-12 22:15:14 +01:00
}
else
{
2013-12-19 10:13:55 +01:00
CVF_FAIL_MSG ( "Found fault with global neighbor index less than the native index. " ); // Should never occur. because we flag the opposite face in the faultsPrCellAcc
2013-12-12 22:15:14 +01:00
}
}
}
}
2016-11-18 14:40:42 +01:00
distributeNNCsToFaults ();
}
2013-12-14 09:30:27 +01:00
2016-11-18 14:40:42 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: distributeNNCsToFaults ()
{
2013-12-17 11:40:06 +01:00
const std :: vector < RigConnection >& nncs = this -> nncData () -> connections ();
2016-11-18 14:40:42 +01:00
for ( size_t nncIdx = 0 ; nncIdx < nncs . size (); ++ nncIdx )
2013-12-14 09:30:27 +01:00
{
// Find the fault for each side of the nnc
const RigConnection & conn = nncs [ nncIdx ];
2016-11-18 14:40:42 +01:00
int fIdx1 = RigFaultsPrCellAccumulator :: NO_FAULT ;
int fIdx2 = RigFaultsPrCellAccumulator :: NO_FAULT ;
2013-12-16 15:56:57 +01:00
if ( conn . m_c1Face != StructGridInterface :: NO_FACE )
{
2014-08-18 18:30:52 +02:00
fIdx1 = m_faultsPrCellAcc -> faultIdx ( conn . m_c1GlobIdx , conn . m_c1Face );
fIdx2 = m_faultsPrCellAcc -> faultIdx ( conn . m_c2GlobIdx , StructGridInterface :: oppositeFace ( conn . m_c1Face ));
2013-12-16 15:56:57 +01:00
}
2013-12-16 14:25:27 +01:00
if ( fIdx1 < 0 && fIdx2 < 0 )
{
2016-11-18 14:40:42 +01:00
cvf :: String lgrString ( "Same Grid" );
if ( m_cells [ conn . m_c1GlobIdx ]. hostGrid () != m_cells [ conn . m_c2GlobIdx ]. hostGrid ())
2013-12-16 14:25:27 +01:00
{
lgrString = "Different Grid" ;
}
2016-11-18 14:40:42 +01:00
//cvf::Trace::show("NNC: No Fault for NNC C1: " + cvf::String((int)conn.m_c1GlobIdx) + " C2: " + cvf::String((int)conn.m_c2GlobIdx) + " Grid: " + lgrString);
2013-12-16 14:25:27 +01:00
}
2013-12-16 11:26:29 +01:00
if ( fIdx1 >= 0 )
2013-12-14 09:30:27 +01:00
{
2013-12-16 11:26:29 +01:00
// Add the connection to both, if they are different.
m_faults [ fIdx1 ] -> connectionIndices (). push_back ( nncIdx );
2013-12-16 14:25:27 +01:00
}
if ( fIdx2 != fIdx1 )
{
if ( fIdx2 >= 0 )
2013-12-16 11:26:29 +01:00
{
2013-12-16 14:25:27 +01:00
m_faults [ fIdx2 ] -> connectionIndices (). push_back ( nncIdx );
2013-12-16 11:26:29 +01:00
}
2013-12-14 09:30:27 +01:00
}
}
2013-12-12 22:15:14 +01:00
}
2013-12-19 08:48:36 +01:00
//--------------------------------------------------------------------------------------------------
/// The cell is normally inverted due to Depth becoming -Z at import,
2014-08-22 13:38:03 +02:00
/// but if (only) one of the flipX/Y is done, the cell is back to normal
2013-12-19 08:48:36 +01:00
//--------------------------------------------------------------------------------------------------
2014-09-23 12:24:48 +02:00
bool RigMainGrid :: isFaceNormalsOutwards () const
2013-12-19 08:48:36 +01:00
{
2014-09-23 12:24:48 +02:00
for ( int gcIdx = 0 ; gcIdx < static_cast < int > ( m_cells . size ()); ++ gcIdx )
{
if ( ! m_cells [ gcIdx ]. isInvalid ())
{
cvf :: Vec3d cellCenter = m_cells [ gcIdx ]. center ();
cvf :: Vec3d faceCenter = m_cells [ gcIdx ]. faceCenter ( StructGridInterface :: POS_I );
cvf :: Vec3d faceNormal = m_cells [ gcIdx ]. faceNormalWithAreaLenght ( StructGridInterface :: POS_I );
double typicalIJCellSize = characteristicIJCellSize ();
double dummy , dummy2 , typicalKSize ;
characteristicCellSizes ( & dummy , & dummy2 , & typicalKSize );
if ( ( faceCenter - cellCenter ). length () > 0.2 * typicalIJCellSize
&& ( faceNormal . length () > ( 0.2 * typicalIJCellSize * 0.2 * typicalKSize )))
{
// Cell is assumed ok to use, so calculate whether the normals are outwards or inwards
if (( faceCenter - cellCenter ) * faceNormal >= 0 )
{
return true ;
}
else
{
return false ;
}
}
}
}
return false ;
2013-12-19 08:48:36 +01:00
}
2014-07-25 14:48:37 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2014-08-18 18:30:52 +02:00
const RigFault * RigMainGrid :: findFaultFromCellIndexAndCellFace ( size_t reservoirCellIndex , cvf :: StructGridInterface :: FaceType face ) const
2014-07-25 14:48:37 +02:00
{
2014-09-26 08:15:22 +02:00
CVF_ASSERT ( m_faultsPrCellAcc . notNull ());
2015-11-26 16:00:08 +01:00
if ( face == cvf :: StructGridInterface :: NO_FACE ) return NULL ;
2014-08-18 18:30:52 +02:00
int faultIdx = m_faultsPrCellAcc -> faultIdx ( reservoirCellIndex , face );
if ( faultIdx != RigFaultsPrCellAccumulator :: NO_FAULT )
{
return m_faults . at ( faultIdx );
}
#if 0
2014-07-25 14:48:37 +02:00
for (size_t i = 0; i < m_faults.size(); i++)
{
const RigFault* rigFault = m_faults.at(i);
const std::vector<RigFault::FaultFace>& faultFaces = rigFault->faultFaces();
for (size_t fIdx = 0; fIdx < faultFaces.size(); fIdx++)
{
2014-08-08 10:51:39 +02:00
if (faultFaces[fIdx].m_nativeReservoirCellIndex == cellIndex)
2014-07-25 14:48:37 +02:00
{
if (face == faultFaces[fIdx].m_nativeFace )
{
return rigFault;
}
}
2014-08-08 10:51:39 +02:00
if (faultFaces[fIdx].m_oppositeReservoirCellIndex == cellIndex)
2014-07-25 14:48:37 +02:00
{
if (face == cvf::StructGridInterface::oppositeFace(faultFaces[fIdx].m_nativeFace))
{
return rigFault;
}
}
}
}
2014-08-18 18:30:52 +02:00
#endif
2014-07-25 14:48:37 +02:00
return NULL ;
}
2015-09-07 10:32:54 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2015-09-07 16:15:37 +02:00
void RigMainGrid :: findIntersectingCells ( const cvf :: BoundingBox & inputBB , std :: vector < size_t >* cellIndices ) const
2015-12-09 15:36:37 +01:00
{
CVF_ASSERT ( m_cellSearchTree . notNull ());
m_cellSearchTree -> findIntersections ( inputBB , cellIndices );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid :: buildCellSearchTree ()
2015-09-07 10:32:54 +02:00
{
if ( m_cellSearchTree . isNull ())
{
// build tree
size_t cellCount = m_cells . size ();
std :: vector < cvf :: BoundingBox > cellBoundingBoxes ;
cellBoundingBoxes . resize ( cellCount );
for ( size_t cIdx = 0 ; cIdx < cellCount ; ++ cIdx )
{
const caf :: SizeTArray8 & cellIndices = m_cells [ cIdx ]. cornerIndices ();
2015-12-15 13:50:59 +01:00
if ( m_cells [ cIdx ]. isInvalid ()) continue ;
2015-09-07 10:32:54 +02:00
cvf :: BoundingBox & cellBB = cellBoundingBoxes [ cIdx ];
cellBB . add ( m_nodes [ cellIndices [ 0 ]]);
cellBB . add ( m_nodes [ cellIndices [ 1 ]]);
cellBB . add ( m_nodes [ cellIndices [ 2 ]]);
cellBB . add ( m_nodes [ cellIndices [ 3 ]]);
cellBB . add ( m_nodes [ cellIndices [ 4 ]]);
cellBB . add ( m_nodes [ cellIndices [ 5 ]]);
cellBB . add ( m_nodes [ cellIndices [ 6 ]]);
cellBB . add ( m_nodes [ cellIndices [ 7 ]]);
}
m_cellSearchTree = new cvf :: BoundingBoxTree ;
m_cellSearchTree -> buildTreeFromBoundingBoxes ( cellBoundingBoxes , NULL );
}
}
2015-10-24 11:56:15 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf :: BoundingBox RigMainGrid :: boundingBox () const
{
if ( m_boundingBox . isValid ()) return m_boundingBox ;
for ( size_t i = 0 ; i < m_nodes . size (); ++ i )
{
m_boundingBox . add ( m_nodes [ i ]);
}
return m_boundingBox ;
}