Surface Import : import of properties from TS files #5995

This commit is contained in:
Stein Inge Dale 2020-05-29 17:18:09 +02:00 committed by Magne Sjaastad
parent 66037da9d5
commit e5f3a3b67d
9 changed files with 15595 additions and 76 deletions

View File

@ -17,13 +17,16 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RifSurfaceReader.h"
#include "RigGocadData.h"
#include "cvfVector3.h"
#include "QStringList"
#include <fstream>
#include <limits>
#include <map>
#include <sstream>
#include <string>
#include <vector>
//--------------------------------------------------------------------------------------------------
@ -31,11 +34,8 @@
/// Import vertices and triangle IDs from the first TFACE section in the file
/// Returns vertices with z-value as depth, z is increasing downwards
///
///
///
///
//--------------------------------------------------------------------------------------------------
std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> RifSurfaceReader::readGocadFile( const QString& filename )
void RifSurfaceReader::readGocadFile( const QString& filename, RigGocadData* gocadData )
{
enum class GocadZPositive
{
@ -48,6 +48,10 @@ std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> RifSurfaceReader::read
std::map<int, unsigned> vertexIdToIndex;
std::vector<unsigned> trianglesByIds;
std::vector<QString> propertyNames;
std::vector<std::vector<float>> propertyValues;
size_t propertyRow = 0;
{
std::ifstream stream( filename.toLatin1().data() );
@ -66,72 +70,104 @@ std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> RifSurfaceReader::read
std::string firstToken;
lineStream >> firstToken;
if ( lineStream.good() ) // If we can, assume this line is a surface point
if ( isInTfaceSection )
{
if ( isInTfaceSection )
if ( firstToken.compare( "VRTX" ) == 0 )
{
if ( firstToken.compare( "VRTX" ) == 0 )
int vertexId = -1;
double x{ std::numeric_limits<double>::infinity() };
double y{ std::numeric_limits<double>::infinity() };
double z{ std::numeric_limits<double>::infinity() };
std::string endVertex;
lineStream >> vertexId >> x >> y >> z >> endVertex;
if ( vertexId > -1 )
{
int vertexId = -1;
double x{std::numeric_limits<double>::infinity()};
double y{std::numeric_limits<double>::infinity()};
double z{std::numeric_limits<double>::infinity()};
std::string endVertex;
lineStream >> vertexId >> x >> y >> z >> endVertex;
if ( vertexId > -1 )
if ( zDir == GocadZPositive::Depth )
{
if ( zDir == GocadZPositive::Depth )
{
z = -z;
}
vertices.emplace_back( cvf::Vec3d( x, y, z ) );
vertexIdToIndex[vertexId] = static_cast<unsigned>( vertices.size() - 1 );
z = -z;
}
}
else if ( firstToken.compare( "TRGL" ) == 0 )
{
int id1{-1};
int id2{-1};
int id3{-1};
lineStream >> id1 >> id2 >> id3;
if ( id1 >= 0 && id2 >= 0 && id3 >= 0 )
{
trianglesByIds.emplace_back( static_cast<unsigned int>( id1 ) );
trianglesByIds.emplace_back( static_cast<unsigned int>( id2 ) );
trianglesByIds.emplace_back( static_cast<unsigned int>( id3 ) );
}
}
else if ( firstToken.compare( "END" ) == 0 )
{
isInTfaceSection = false;
vertices.emplace_back( cvf::Vec3d( x, y, z ) );
vertexIdToIndex[vertexId] = static_cast<unsigned>( vertices.size() - 1 );
}
}
else if ( firstToken.compare( "TFACE" ) == 0 )
else if ( firstToken.compare( "PVRTX" ) == 0 )
{
isInTfaceSection = true;
}
else if ( firstToken.compare( "ZPOSITIVE" ) == 0 )
{
std::string secondToken;
lineStream >> secondToken;
int vertexId = -1;
double x{ std::numeric_limits<double>::infinity() };
double y{ std::numeric_limits<double>::infinity() };
double z{ std::numeric_limits<double>::infinity() };
if ( secondToken == "DEPTH" )
lineStream >> vertexId >> x >> y >> z;
if ( vertexId > -1 )
{
zDir = GocadZPositive::Depth;
if ( zDir == GocadZPositive::Depth ) z = -z;
vertices.emplace_back( cvf::Vec3d( x, y, z ) );
vertexIdToIndex[vertexId] = static_cast<unsigned>( vertices.size() - 1 );
}
else if ( secondToken == "ELEVATION" )
propertyValues.push_back( std::vector<float>( propertyNames.size() ) );
for ( size_t i = 0; i < propertyNames.size(); i++ )
{
zDir = GocadZPositive::Elevation;
lineStream >> propertyValues[propertyRow][i];
}
propertyRow++;
}
else if ( firstToken.compare( "TRGL" ) == 0 )
{
int id1{ -1 };
int id2{ -1 };
int id3{ -1 };
lineStream >> id1 >> id2 >> id3;
if ( id1 >= 0 && id2 >= 0 && id3 >= 0 )
{
trianglesByIds.emplace_back( static_cast<unsigned int>( id1 ) );
trianglesByIds.emplace_back( static_cast<unsigned int>( id2 ) );
trianglesByIds.emplace_back( static_cast<unsigned int>( id3 ) );
}
}
else if ( firstToken.compare( "END" ) == 0 )
{
isInTfaceSection = false;
}
}
else // Probably a comment line, skip
else if ( firstToken.compare( "TFACE" ) == 0 )
{
isInTfaceSection = true;
}
else if ( firstToken.compare( "PROPERTIES" ) == 0 )
{
QString qstringLine = QString::fromStdString( line );
qstringLine.remove( "PROPERTIES" );
QStringList words = qstringLine.split( " ", QString::SkipEmptyParts );
for ( auto w : words )
{
propertyNames.push_back( w );
}
}
else if ( firstToken.compare( "ZPOSITIVE" ) == 0 )
{
std::string secondToken;
lineStream >> secondToken;
if ( secondToken == "DEPTH" )
{
zDir = GocadZPositive::Depth;
}
else if ( secondToken == "ELEVATION" )
{
zDir = GocadZPositive::Elevation;
}
}
}
}
@ -148,7 +184,8 @@ std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> RifSurfaceReader::read
}
}
return std::make_pair( vertices, triangleIndices );
gocadData->setGeometryData( vertices, triangleIndices );
gocadData->addPropertyData( propertyNames, propertyValues );
}
//--------------------------------------------------------------------------------------------------
@ -206,7 +243,7 @@ std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> RifSurfaceReader::read
// Add point
surfaceDataPoints.push_back( {i, j, {x, y, z}, values} );
surfaceDataPoints.push_back( { i, j, { x, y, z }, values } );
minI = std::min( minI, i );
minJ = std::min( minJ, j );

View File

@ -25,10 +25,12 @@
#include <QString>
class RigGocadData;
class RifSurfaceReader
{
public:
static std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> readGocadFile( const QString& filename );
static void readGocadFile( const QString& filename, RigGocadData* gocadData );
static std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> readPetrelFile( const QString& filename );
};

View File

@ -19,6 +19,7 @@
#include "RimFileSurface.h"
#include "RifSurfaceReader.h"
#include "RigGocadData.h"
#include "RigSurface.h"
#include "RimSurfaceCollection.h"
@ -92,7 +93,7 @@ void RimFileSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
RimSurfaceCollection* surfColl;
this->firstAncestorOrThisOfTypeAsserted( surfColl );
surfColl->updateViews( {this} );
surfColl->updateViews( { this } );
}
}
@ -107,8 +108,8 @@ bool RimFileSurface::updateSurfaceDataFromFile()
result = loadDataFromFile();
}
std::vector<cvf::Vec3d> vertices{m_vertices};
std::vector<unsigned> tringleIndices{m_tringleIndices};
std::vector<cvf::Vec3d> vertices{ m_vertices };
std::vector<unsigned> tringleIndices{ m_tringleIndices };
auto surface = new RigSurface;
if ( !vertices.empty() && !tringleIndices.empty() )
@ -137,29 +138,25 @@ void RimFileSurface::clearCachedNativeFileData()
//--------------------------------------------------------------------------------------------------
bool RimFileSurface::loadDataFromFile()
{
std::vector<cvf::Vec3d> vertices;
std::vector<unsigned> tringleIndices;
std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> surface;
QString filePath = this->surfaceFilePath();
if ( filePath.endsWith( "ptl", Qt::CaseInsensitive ) )
{
auto surface = RifSurfaceReader::readPetrelFile( filePath );
vertices = surface.first;
tringleIndices = surface.second;
surface = RifSurfaceReader::readPetrelFile( filePath );
}
else if ( filePath.endsWith( "ts", Qt::CaseInsensitive ) )
{
auto surface = RifSurfaceReader::readGocadFile( filePath );
RigGocadData gocadData;
RifSurfaceReader::readGocadFile( filePath, &gocadData );
vertices = surface.first;
tringleIndices = surface.second;
surface = gocadData.gocadGeometry();
}
m_vertices = vertices;
m_tringleIndices = tringleIndices;
m_vertices = surface.first;
m_tringleIndices = surface.second;
if ( vertices.empty() || tringleIndices.empty() ) return false;
if ( m_vertices.empty() || m_tringleIndices.empty() ) return false;
return true;
}

View File

@ -120,7 +120,7 @@ RimSurface* RimSurfaceCollection::importSurfacesFromFiles( const QStringList& fi
updateViews( surfacesToReload );
if ( !newFileNames.empty() )
if ( newSurfCount > 0 && !m_surfaces.empty() )
{
return m_surfaces[m_surfaces.size() - 1];
}

View File

@ -78,6 +78,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllanFaultsStatCalc.h
${CMAKE_CURRENT_LIST_DIR}/RigCellFaceGeometryTools.h
${CMAKE_CURRENT_LIST_DIR}/RigNncConnection.h
${CMAKE_CURRENT_LIST_DIR}/RigWellDiskData.h
${CMAKE_CURRENT_LIST_DIR}/RigGocadData.h
)
@ -153,6 +154,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigEclipseAllanFaultsStatCalc.cpp
${CMAKE_CURRENT_LIST_DIR}/RigCellFaceGeometryTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RigNncConnection.cpp
${CMAKE_CURRENT_LIST_DIR}/RigWellDiskData.cpp
${CMAKE_CURRENT_LIST_DIR}/RigGocadData.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,92 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 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 "RigGocadData.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGocadData::RigGocadData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGocadData::~RigGocadData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RigGocadData::propertyNames()
{
return m_propertyNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> RigGocadData::gocadGeometry()
{
return std::make_pair( m_vertices, m_tringleIndices );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<float> RigGocadData::propertyValues( const QString& property )
{
size_t propertyIdx = 0;
for ( propertyIdx = 0; propertyIdx < m_propertyNames.size(); propertyIdx++ )
{
if ( m_propertyNames[propertyIdx] == property ) break;
}
std::vector<float> propValues;
propValues.reserve( m_propertyValues.size() );
for ( size_t i = 0; i < m_propertyValues.size(); i++ )
{
propValues.push_back( m_propertyValues[i][propertyIdx] );
}
return propValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGocadData::setGeometryData( const std::vector<cvf::Vec3d>& nodeCoord, const std::vector<unsigned>& connectivities )
{
m_vertices = nodeCoord;
m_tringleIndices = connectivities;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGocadData::addPropertyData( const std::vector<QString>& propertyNames,
std::vector<std::vector<float>>& propertyValues )
{
m_propertyNames = propertyNames;
m_propertyValues = propertyValues;
}

View File

@ -0,0 +1,44 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
#include <vector>
#include "cvfVector3.h"
class RigGocadData
{
public:
RigGocadData();
~RigGocadData();
std::vector<QString> propertyNames();
std::pair<std::vector<cvf::Vec3d>, std::vector<unsigned>> gocadGeometry();
std::vector<float> propertyValues( const QString& property );
void setGeometryData( const std::vector<cvf::Vec3d>& nodeCoord, const std::vector<unsigned>& connectivities );
void addPropertyData( const std::vector<QString>& propertyNames, std::vector<std::vector<float>>& propertyValues );
private:
std::vector<cvf::Vec3d> m_vertices;
std::vector<unsigned> m_tringleIndices;
std::vector<QString> m_propertyNames;
std::vector<std::vector<float>> m_propertyValues;
};

View File

@ -2,8 +2,10 @@
#include "RifSurfaceReader.h"
#include "QDir"
#include "RiaTestDataDirectory.h"
#include "RigGocadData.h"
#include "QDir"
#include <QString>
#include <QStringList>
@ -15,8 +17,10 @@ TEST( RifSurfaceReader, GocadReadValidFile )
QString filePath = baseFolder.absoluteFilePath( filename );
EXPECT_TRUE( QFile::exists( filePath ) );
auto surface = RifSurfaceReader::readGocadFile( filePath );
RigGocadData gocadData;
RifSurfaceReader::readGocadFile( filePath, &gocadData );
auto surface = gocadData.gocadGeometry();
auto vertices = surface.first;
auto indices = surface.second;
@ -35,8 +39,10 @@ TEST( RifSurfaceReader, GocadReadWrongIndices )
QString filePath = baseFolder.absoluteFilePath( filename );
EXPECT_TRUE( QFile::exists( filePath ) );
auto surface = RifSurfaceReader::readGocadFile( filePath );
RigGocadData gocadData;
RifSurfaceReader::readGocadFile( filePath, &gocadData );
auto surface = gocadData.gocadGeometry();
auto vertices = surface.first;
auto indices = surface.second;
@ -44,6 +50,47 @@ TEST( RifSurfaceReader, GocadReadWrongIndices )
EXPECT_EQ( (size_t)15, indices.size() );
}
TEST( RifSurfaceReader, GocadReadProperties )
{
QDir baseFolder( TEST_DATA_DIR );
QString filename( "RifSurfaceReader/geom_with_properties.ts" );
QString filePath = baseFolder.absoluteFilePath( filename );
EXPECT_TRUE( QFile::exists( filePath ) );
RigGocadData gocadData;
RifSurfaceReader::readGocadFile( filePath, &gocadData );
auto surface = gocadData.gocadGeometry();
auto vertices = surface.first;
auto indices = surface.second;
std::vector<QString> propNames = gocadData.propertyNames();
EXPECT_TRUE( propNames.size() == 3 );
EXPECT_TRUE( propNames[0] == "SX" );
std::vector<float> propValues_SX = gocadData.propertyValues( propNames[0] );
float SX_first = propValues_SX[0];
float SX_second = propValues_SX[1];
float SX_last = propValues_SX[propValues_SX.size() - 1];
EXPECT_NEAR( 0.000907, SX_first, 1e-4 );
EXPECT_NEAR( 0.000972, SX_second, 1e-4 );
EXPECT_NEAR( 0.004293, SX_last, 1e-4 );
std::vector<float> propValues_SY = gocadData.propertyValues( "SY" );
float SY_first = propValues_SY[0];
float SY_second = propValues_SY[1];
float SY_last = propValues_SY[propValues_SX.size() - 1];
EXPECT_NEAR( 0.001550, SY_first, 1e-4 );
EXPECT_NEAR( 0.001620, SY_second, 1e-4 );
EXPECT_NEAR( 0.010476, SY_last, 1e-4 );
}
TEST( RifSurfaceReader, ReadWrongFileType )
{
QDir baseFolder( TEST_DATA_DIR );
@ -53,8 +100,10 @@ TEST( RifSurfaceReader, ReadWrongFileType )
QString filePath = baseFolder.absoluteFilePath( filename );
EXPECT_TRUE( QFile::exists( filePath ) );
auto surface = RifSurfaceReader::readGocadFile( filePath );
RigGocadData gocadData;
RifSurfaceReader::readGocadFile( filePath, &gocadData );
auto surface = gocadData.gocadGeometry();
auto vertices = surface.first;
auto indices = surface.second;

File diff suppressed because it is too large Load Diff