mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-08 15:14:07 -06:00
f8c5cf389f
* Set column width to 140 * Use c++20 * Remove redundant virtual
241 lines
9.7 KiB
C++
241 lines
9.7 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) Statoil ASA
|
|
// Copyright (C) Ceetron Solutions 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 "RivFaultGeometryGenerator.h"
|
|
|
|
#include "RiaOpenMPTools.h"
|
|
|
|
#include "RigFault.h"
|
|
#include "RigNNCData.h"
|
|
#include "RigNncConnection.h"
|
|
|
|
#include "cvfDrawableGeo.h"
|
|
#include "cvfOutlineEdgeExtractor.h"
|
|
#include "cvfPrimitiveSetIndexedUInt.h"
|
|
#include "cvfStructGridGeometryGenerator.h"
|
|
|
|
#include "cvfScalarMapper.h"
|
|
|
|
#include <cmath>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RivFaultGeometryGenerator::RivFaultGeometryGenerator( const cvf::StructGridInterface* grid,
|
|
const RigFault* fault,
|
|
RigNNCData* nncData,
|
|
bool computeNativeFaultFaces )
|
|
: m_grid( grid )
|
|
, m_fault( fault )
|
|
, m_computeNativeFaultFaces( computeNativeFaultFaces )
|
|
, m_nncData( nncData )
|
|
{
|
|
m_quadMapper = new cvf::StructGridQuadToCellFaceMapper;
|
|
m_triangleMapper = new cvf::StuctGridTriangleToCellFaceMapper( m_quadMapper.p() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RivFaultGeometryGenerator::~RivFaultGeometryGenerator()
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Generate surface drawable geo from the specified region
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::generateSurface( bool onlyShowFacesWithDefinedNeighbors )
|
|
{
|
|
computeArrays( onlyShowFacesWithDefinedNeighbors );
|
|
|
|
CVF_ASSERT( m_vertices.notNull() );
|
|
|
|
if ( m_vertices->size() == 0 ) return nullptr;
|
|
|
|
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
|
geo->setFromQuadVertexArray( m_vertices.p() );
|
|
|
|
return geo;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Generates simplified mesh as line drawing
|
|
/// Must call generateSurface first
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createMeshDrawable()
|
|
{
|
|
if ( !( m_vertices.notNull() && m_vertices->size() != 0 ) ) return nullptr;
|
|
|
|
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
|
geo->setVertexArray( m_vertices.p() );
|
|
|
|
cvf::ref<cvf::UIntArray> indices = cvf::StructGridGeometryGenerator::lineIndicesFromQuadVertexArray( m_vertices.p() );
|
|
|
|
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt( cvf::PT_LINES );
|
|
prim->setIndices( indices.p() );
|
|
|
|
geo->addPrimitiveSet( prim.p() );
|
|
return geo;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
cvf::ref<cvf::DrawableGeo> RivFaultGeometryGenerator::createOutlineMeshDrawable( double creaseAngle )
|
|
{
|
|
if ( !( m_vertices.notNull() && m_vertices->size() != 0 ) ) return nullptr;
|
|
|
|
cvf::OutlineEdgeExtractor ee( creaseAngle, *m_vertices );
|
|
|
|
cvf::ref<cvf::UIntArray> indices = cvf::StructGridGeometryGenerator::lineIndicesFromQuadVertexArray( m_vertices.p() );
|
|
ee.addPrimitives( 4, *indices );
|
|
|
|
cvf::ref<cvf::UIntArray> lineIndices = ee.lineIndices();
|
|
if ( lineIndices->size() == 0 )
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
cvf::ref<cvf::PrimitiveSetIndexedUInt> prim = new cvf::PrimitiveSetIndexedUInt( cvf::PT_LINES );
|
|
prim->setIndices( lineIndices.p() );
|
|
|
|
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
|
geo->setVertexArray( m_vertices.p() );
|
|
geo->addPrimitiveSet( prim.p() );
|
|
|
|
return geo;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RivFaultGeometryGenerator::hasConnection( size_t cellIdx,
|
|
cvf::StructGridInterface::FaceType face,
|
|
const RigConnectionContainer& conns,
|
|
const std::vector<size_t>& nncConnectionIndices )
|
|
{
|
|
cvf::StructGridInterface::FaceType oppositeFace = cvf::StructGridInterface::oppositeFace( face );
|
|
|
|
for ( auto i : nncConnectionIndices )
|
|
{
|
|
if ( i >= conns.size() ) continue;
|
|
|
|
const auto& r = conns[i];
|
|
|
|
if ( ( r.c1GlobIdx() == cellIdx ) && ( r.face() == face ) && r.hasCommonArea() ) return true;
|
|
|
|
if ( ( r.c2GlobIdx() == cellIdx ) && ( r.face() == oppositeFace ) && r.hasCommonArea() ) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RivFaultGeometryGenerator::computeArrays( bool onlyShowFacesWithDefinedNeighbors )
|
|
{
|
|
std::vector<cvf::Vec3f> vertices;
|
|
m_quadMapper->quadToCellIndexMap().clear();
|
|
m_quadMapper->quadToCellFaceMap().clear();
|
|
|
|
cvf::Vec3d offset = m_grid->displayModelOffset();
|
|
|
|
if ( onlyShowFacesWithDefinedNeighbors )
|
|
{
|
|
// Make sure the connection polygon is computed, as this is used as criteria for visibility
|
|
m_nncData->ensureAllConnectionDataIsProcessed();
|
|
}
|
|
|
|
auto connIndices = m_fault->connectionIndices();
|
|
auto& connections = m_nncData->availableConnections();
|
|
|
|
const std::vector<RigFault::FaultFace>& faultFaces = m_fault->faultFaces();
|
|
|
|
int numberOfThreads = RiaOpenMPTools::availableThreadCount();
|
|
|
|
std::vector<std::vector<cvf::Vec3f>> threadVertices( numberOfThreads );
|
|
std::vector<std::vector<size_t>> threadCellIndices( numberOfThreads );
|
|
std::vector<std::vector<cvf::StructGridInterface::FaceType>> threadFaceTypes( numberOfThreads );
|
|
|
|
#pragma omp parallel
|
|
{
|
|
int myThread = RiaOpenMPTools::currentThreadIndex();
|
|
|
|
cvf::Vec3d cornerVerts[8];
|
|
cvf::ubyte faceConn[4];
|
|
|
|
// NB! We are inside a parallel section, do not use "parallel for" here
|
|
#pragma omp for
|
|
for ( int fIdx = 0; fIdx < static_cast<int>( faultFaces.size() ); fIdx++ )
|
|
{
|
|
size_t cellIndex = faultFaces[fIdx].m_nativeReservoirCellIndex;
|
|
cvf::StructGridInterface::FaceType face = faultFaces[fIdx].m_nativeFace;
|
|
|
|
if ( !m_computeNativeFaultFaces )
|
|
{
|
|
cellIndex = faultFaces[fIdx].m_oppositeReservoirCellIndex;
|
|
face = cvf::StructGridInterface::oppositeFace( face );
|
|
}
|
|
|
|
if ( cellIndex >= m_cellVisibility->size() ) continue;
|
|
|
|
if ( !( *m_cellVisibility )[cellIndex] ) continue;
|
|
|
|
if ( onlyShowFacesWithDefinedNeighbors && !hasConnection( cellIndex, face, connections, connIndices ) ) continue;
|
|
|
|
m_grid->cellCornerVertices( cellIndex, cornerVerts );
|
|
m_grid->cellFaceVertexIndices( face, faceConn );
|
|
|
|
for ( int n = 0; n < 4; n++ )
|
|
{
|
|
threadVertices[myThread].emplace_back( cvf::Vec3f( cornerVerts[faceConn[n]] - offset ) );
|
|
}
|
|
|
|
// Keep track of the source cell index per quad
|
|
threadCellIndices[myThread].emplace_back( cellIndex );
|
|
threadFaceTypes[myThread].emplace_back( face );
|
|
}
|
|
}
|
|
|
|
for ( int threadIndex = 0; threadIndex < numberOfThreads; threadIndex++ )
|
|
{
|
|
vertices.insert( vertices.end(), threadVertices[threadIndex].begin(), threadVertices[threadIndex].end() );
|
|
|
|
m_quadMapper->quadToCellIndexMap().insert( m_quadMapper->quadToCellIndexMap().end(),
|
|
threadCellIndices[threadIndex].begin(),
|
|
threadCellIndices[threadIndex].end() );
|
|
|
|
m_quadMapper->quadToCellFaceMap().insert( m_quadMapper->quadToCellFaceMap().end(),
|
|
threadFaceTypes[threadIndex].begin(),
|
|
threadFaceTypes[threadIndex].end() );
|
|
}
|
|
|
|
m_vertices = new cvf::Vec3fArray;
|
|
m_vertices->assign( vertices );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RivFaultGeometryGenerator::setCellVisibility( const cvf::UByteArray* cellVisibility )
|
|
{
|
|
m_cellVisibility = cellVisibility;
|
|
}
|