mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-08 23:23:01 -06:00
f8c5cf389f
* Set column width to 140 * Use c++20 * Remove redundant virtual
185 lines
7.5 KiB
C++
185 lines
7.5 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2021- Equinor ASA
|
|
//
|
|
// 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 "RimcExtractSurfaces.h"
|
|
|
|
#include "RiaLogging.h"
|
|
#include "RifSurfaceExporter.h"
|
|
#include "RimCommandRouter.h"
|
|
|
|
#include "opm/io/eclipse/EGrid.hpp"
|
|
|
|
#include "cafPdmAbstractFieldScriptingCapability.h"
|
|
#include "cafPdmFieldScriptingCapability.h"
|
|
#include "cafPdmObjectHandle.h"
|
|
|
|
#include <QDir>
|
|
#include <QFileInfo>
|
|
|
|
#include <memory>
|
|
|
|
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimCommandRouter, RimcCommandRouter_extractSurfaces, "ExtractSurfaces" );
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimcCommandRouter_extractSurfaces::RimcCommandRouter_extractSurfaces( caf::PdmObjectHandle* self )
|
|
: RimCommandRouterMethod( self )
|
|
{
|
|
CAF_PDM_InitObject( "Extract Layer Surface", "", "", "Extract Layer Surface" );
|
|
|
|
CAF_PDM_InitScriptableField( &m_gridModelFilename, "GridModelFilename", QString(), "Grid Model Case Filename" );
|
|
CAF_PDM_InitScriptableField( &m_layers, "Layers", std::vector<int>(), "Layers" );
|
|
CAF_PDM_InitScriptableField( &m_minimumI, "MinimumI", -1, "Minimum I" );
|
|
CAF_PDM_InitScriptableField( &m_maximumI, "MaximumI", -1, "Maximum I" );
|
|
CAF_PDM_InitScriptableField( &m_minimumJ, "MinimumJ", -1, "Minimum J" );
|
|
CAF_PDM_InitScriptableField( &m_maximumJ, "MaximumJ", -1, "Maximum J" );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::PdmObjectHandle* RimcCommandRouter_extractSurfaces::execute()
|
|
{
|
|
extractSurfaces( m_gridModelFilename, m_layers(), m_minimumI(), m_maximumI(), m_minimumJ(), m_maximumJ() );
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::pair<bool, QStringList> RimcCommandRouter_extractSurfaces::extractSurfaces( const QString& gridModelFilename,
|
|
const std::vector<int>& layers,
|
|
int minI,
|
|
int maxI,
|
|
int minJ,
|
|
int maxJ )
|
|
{
|
|
QStringList surfaceFileNames;
|
|
|
|
try
|
|
{
|
|
std::string filename = gridModelFilename.toStdString();
|
|
Opm::EclIO::EGrid grid1( filename );
|
|
|
|
auto dims = grid1.dimension();
|
|
minI = minI == -1 ? 0 : minI;
|
|
maxI = maxI == -1 ? dims[0] - 1 : maxI;
|
|
minJ = minJ == -1 ? 0 : minJ;
|
|
maxJ = maxJ == -1 ? dims[1] - 1 : maxJ;
|
|
|
|
std::array<int, 4> range = { minI, maxI, minJ, maxJ };
|
|
|
|
for ( auto layer : layers )
|
|
{
|
|
bool bottom = false;
|
|
auto xyz_data = grid1.getXYZ_layer( layer, range, bottom );
|
|
auto mapAxis = grid1.get_mapaxes();
|
|
|
|
// Create surface from coords
|
|
|
|
std::vector<unsigned> triangleIndices;
|
|
std::vector<cvf::Vec3d> vertices;
|
|
|
|
unsigned startOfCellCoordIndex = 0;
|
|
while ( startOfCellCoordIndex + 4 < xyz_data.size() )
|
|
{
|
|
for ( size_t cornerIdx = 0; cornerIdx < 4; cornerIdx++ )
|
|
{
|
|
auto coord1 = xyz_data[startOfCellCoordIndex + cornerIdx];
|
|
auto cvfCoord = cvf::Vec3d( coord1[0], coord1[1], -coord1[2] );
|
|
|
|
if ( !mapAxis.empty() )
|
|
{
|
|
cvfCoord[0] += mapAxis[2];
|
|
cvfCoord[1] += mapAxis[3];
|
|
}
|
|
vertices.push_back( cvfCoord );
|
|
}
|
|
|
|
triangleIndices.push_back( startOfCellCoordIndex );
|
|
triangleIndices.push_back( startOfCellCoordIndex + 3 );
|
|
triangleIndices.push_back( startOfCellCoordIndex + 2 );
|
|
|
|
triangleIndices.push_back( startOfCellCoordIndex );
|
|
triangleIndices.push_back( startOfCellCoordIndex + 1 );
|
|
triangleIndices.push_back( startOfCellCoordIndex + 3 );
|
|
|
|
// Coordinates are given for each four corners for each cell of the surface
|
|
startOfCellCoordIndex += 4;
|
|
}
|
|
|
|
QString surfaceExportDirName = "surfaceexport";
|
|
|
|
// Create missing directories
|
|
QFileInfo fi( gridModelFilename );
|
|
if ( !fi.absoluteDir().exists( surfaceExportDirName ) )
|
|
{
|
|
if ( !fi.absoluteDir().mkpath( surfaceExportDirName ) )
|
|
{
|
|
RiaLogging::error( "Unable to create directory for surface export: " + fi.absoluteDir().absolutePath() );
|
|
return std::make_pair( false, surfaceFileNames );
|
|
}
|
|
}
|
|
|
|
// Write to TS file on disk
|
|
QString surfaceFilename = fi.absoluteDir().absolutePath() + QString( "/%1/layer-%2.ts" ).arg( surfaceExportDirName ).arg( layer );
|
|
|
|
// TODO: Add more info in surface comment
|
|
if ( !RifSurfaceExporter::writeGocadTSurfFile( surfaceFilename, "Surface comment", vertices, triangleIndices ) )
|
|
{
|
|
RiaLogging::error( "Failed to export surface data to " + surfaceFilename );
|
|
return std::make_pair( false, surfaceFileNames );
|
|
}
|
|
else
|
|
{
|
|
surfaceFileNames << surfaceFilename;
|
|
RiaLogging::info( "Successfully exported surface data to " + surfaceFilename );
|
|
}
|
|
}
|
|
|
|
return std::make_pair( true, surfaceFileNames );
|
|
}
|
|
catch ( ... )
|
|
{
|
|
RiaLogging::error( "Error during creation of surface data for model " + gridModelFilename );
|
|
return std::make_pair( false, surfaceFileNames );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimcCommandRouter_extractSurfaces::readMinMaxLayerFromGridFile( const QString& gridFileName, int& minK, int& maxK )
|
|
{
|
|
try
|
|
{
|
|
Opm::EclIO::EGrid grid1( gridFileName.toStdString() );
|
|
|
|
auto dims = grid1.dimension();
|
|
minK = 1;
|
|
maxK = dims[2];
|
|
return true;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
RiaLogging::error( "Unable to read dimensions from " + gridFileName );
|
|
return false;
|
|
}
|
|
}
|