#5529 Surface : Add reader for GOCAD file format

wip
This commit is contained in:
Magne Sjaastad
2020-02-19 09:17:25 +01:00
parent 90a835545f
commit 3aa4ffb0da
9 changed files with 4359 additions and 124 deletions

View File

@@ -15,19 +15,17 @@
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimSurface.h"
#include "RimSurfaceCollection.h"
#include "RigSurface.h"
#include "RifSurfaceReader.h"
#include <QFileInfo>
#include <cmath>
#include <fstream>
#include <sstream>
CAF_PDM_SOURCE_INIT( RimSurface, "Surface" );
//--------------------------------------------------------------------------------------------------
@@ -130,139 +128,38 @@ void RimSurface::fieldChangedByUi( const caf::PdmFieldHandle* changedField, cons
}
}
struct SurfacePointData
{
int i;
int j;
cvf::Vec3d point;
std::vector<double> values;
};
//--------------------------------------------------------------------------------------------------
/// Returns false for fatal failure
//--------------------------------------------------------------------------------------------------
bool RimSurface::updateSurfaceDataFromFile()
{
std::ifstream stream( this->surfaceFilePath().toLatin1().data() );
QString filePath = this->surfaceFilePath();
std::vector<SurfacePointData> surfaceDataPoints;
int minI = std::numeric_limits<int>::max();
int minJ = std::numeric_limits<int>::max();
int maxI = std::numeric_limits<int>::min();
int maxJ = std::numeric_limits<int>::min();
while ( stream.good() )
{
std::string line;
std::getline( stream, line );
std::istringstream lineStream( line );
double x( HUGE_VAL ), y( HUGE_VAL ), z( HUGE_VAL );
int i( -1 ), j( -1 );
std::vector<double> values;
// First check if we can read a number
lineStream >> x;
if ( lineStream.good() ) // If we can, assume this line is a surface point
{
lineStream >> y >> z >> i >> j;
if ( x != HUGE_VAL && y != HUGE_VAL && z != HUGE_VAL && i != -1 && j != -1 )
{
// Check for extra data
while ( lineStream.good() )
{
double d;
lineStream >> d;
if ( lineStream.good() ) values.push_back( d );
}
// Add point
surfaceDataPoints.push_back( {i, j, {x, y, z}, values} );
minI = std::min( minI, i );
minJ = std::min( minJ, j );
maxI = std::max( maxI, i );
maxJ = std::max( maxJ, j );
}
}
else // Probably a comment line, skip
{
}
}
// clang-format off
if ( surfaceDataPoints.empty()
|| minI == std::numeric_limits<int>::max()
|| minJ == std::numeric_limits<int>::max()
|| maxI == std::numeric_limits<int>::min()
|| maxJ == std::numeric_limits<int>::min() )
{
return false;
}
// clang-format on
// Create full size grid matrix
size_t iCount = maxI - minI + 1;
size_t jCount = maxJ - minJ + 1;
if ( iCount < 2 || jCount < 2 )
{
return false;
}
std::vector<std::vector<unsigned>> indexToPointData;
indexToPointData.resize( iCount, std::vector<unsigned>( jCount, -1 ) );
std::vector<unsigned> tringleIndices;
std::vector<cvf::Vec3d> vertices;
for ( unsigned pIdx = 0; pIdx < surfaceDataPoints.size(); ++pIdx )
if ( filePath.endsWith( "ptl", Qt::CaseInsensitive ) )
{
const auto& pointData = surfaceDataPoints[pIdx];
auto surface = RifSurfaceReader::readPetrelFile( filePath );
indexToPointData[pointData.i - minI][pointData.j - minJ] = pIdx;
vertices = surface.first;
tringleIndices = surface.second;
}
else if ( filePath.endsWith( "ts", Qt::CaseInsensitive ) )
{
auto surface = RifSurfaceReader::readGocadFile( filePath );
vertices.push_back( pointData.point );
// Todo: Move result values for each point into the
vertices = surface.first;
tringleIndices = surface.second;
}
std::vector<unsigned> triangleIndices;
if ( indexToPointData.size() < 2 )
if ( !vertices.empty() && !tringleIndices.empty() )
{
return false;
m_surfaceData = new RigSurface();
m_surfaceData->setTriangleData( tringleIndices, vertices );
return true;
}
for ( size_t iIdx = 0; iIdx < indexToPointData.size() - 1; ++iIdx )
{
for ( size_t jIdx = 0; jIdx < indexToPointData[iIdx].size() - 1; ++jIdx )
{
{
unsigned q1 = indexToPointData[iIdx + 0][jIdx + 0];
unsigned q2 = indexToPointData[iIdx + 0][jIdx + 1];
unsigned q3 = indexToPointData[iIdx + 1][jIdx + 0];
unsigned q4 = indexToPointData[iIdx + 1][jIdx + 1];
if ( q1 != ( (unsigned)-1 ) && q2 != ( (unsigned)-1 ) && q4 != ( (unsigned)-1 ) )
{
triangleIndices.push_back( q1 );
triangleIndices.push_back( q2 );
triangleIndices.push_back( q4 );
}
if ( q1 != ( (unsigned)-1 ) && q2 != ( (unsigned)-1 ) && q3 != ( (unsigned)-1 ) )
{
triangleIndices.push_back( q1 );
triangleIndices.push_back( q4 );
triangleIndices.push_back( q3 );
}
}
}
}
m_surfaceData = new RigSurface();
m_surfaceData->setTriangleData( triangleIndices, vertices );
return true;
return false;
}