Merge pull request #8159 from OPM/performance-surface

Performance Surface import and resampling
This commit is contained in:
Magne Sjaastad
2021-10-15 16:55:58 +02:00
committed by GitHub
parent 6b3ad20587
commit afadaf27d5
6 changed files with 113 additions and 58 deletions

View File

@@ -18,7 +18,10 @@
#include "RiaStdStringTools.h" #include "RiaStdStringTools.h"
#include "fast_float/include/fast_float/fast_float.h"
#include <cctype> #include <cctype>
#include <charconv>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
@@ -107,6 +110,26 @@ bool RiaStdStringTools::startsWithAlphabetic( const std::string& s )
return isalpha( s[0] ) != 0; return isalpha( s[0] ) != 0;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaStdStringTools::toDouble( const std::string_view& s, double& value )
{
auto resultObject = fast_float::from_chars( s.data(), s.data() + s.size(), value );
return ( resultObject.ec == std::errc() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaStdStringTools::toInt( const std::string_view& s, int& value )
{
auto resultObject = std::from_chars( s.data(), s.data() + s.size(), value );
return ( resultObject.ec == std::errc() );
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -39,6 +39,10 @@ public:
static bool containsAlphabetic( const std::string& s ); static bool containsAlphabetic( const std::string& s );
static bool startsWithAlphabetic( const std::string& s ); static bool startsWithAlphabetic( const std::string& s );
// Conversion using fastest known approach
static bool toDouble( const std::string_view& s, double& value );
static bool toInt( const std::string_view& s, int& value );
static std::string toUpper( const std::string& s ); static std::string toUpper( const std::string& s );
static bool endsWith( const std::string& mainStr, const std::string& toMatch ); static bool endsWith( const std::string& mainStr, const std::string& toMatch );

View File

@@ -63,6 +63,11 @@ void RicImportEclipseCaseFeature::onActionTriggered( bool isChecked )
std::vector<int> caseIds; std::vector<int> caseIds;
std::shared_ptr<RifReaderSettings> readerSettings; std::shared_ptr<RifReaderSettings> readerSettings;
openEclipseCaseFromFileNames( fileNames, createDefaultView, caseIds, readerSettings ); openEclipseCaseFromFileNames( fileNames, createDefaultView, caseIds, readerSettings );
for ( const auto& f : fileNames )
{
RiaApplication::instance()->addToRecentFiles( f );
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -72,6 +72,15 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
bool isInTfaceSection = false; bool isInTfaceSection = false;
GocadZPositive zDir = GocadZPositive::Unknown; GocadZPositive zDir = GocadZPositive::Unknown;
int vertexId = -1;
double x = 0.0;
double y = 0.0;
double z = 0.0;
int id1 = -1;
int id2 = -1;
int id3 = -1;
while ( stream.good() ) while ( stream.good() )
{ {
std::string line; std::string line;
@@ -88,10 +97,10 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
{ {
if ( tokens.size() > 4 ) if ( tokens.size() > 4 )
{ {
int vertexId = RiaStdStringTools::toInt( tokens[1] ); RiaStdStringTools::toInt( tokens[1], vertexId );
double x = RiaStdStringTools::toDouble( tokens[2] ); RiaStdStringTools::toDouble( tokens[2], x );
double y = RiaStdStringTools::toDouble( tokens[3] ); RiaStdStringTools::toDouble( tokens[3], y );
double z = RiaStdStringTools::toDouble( tokens[4] ); RiaStdStringTools::toDouble( tokens[4], z );
if ( vertexId > -1 ) if ( vertexId > -1 )
{ {
@@ -109,10 +118,10 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
{ {
if ( tokens.size() > 4 ) if ( tokens.size() > 4 )
{ {
int vertexId = RiaStdStringTools::toInt( tokens[1] ); RiaStdStringTools::toInt( tokens[1], vertexId );
double x = RiaStdStringTools::toDouble( tokens[2] ); RiaStdStringTools::toDouble( tokens[2], x );
double y = RiaStdStringTools::toDouble( tokens[3] ); RiaStdStringTools::toDouble( tokens[3], y );
double z = RiaStdStringTools::toDouble( tokens[4] ); RiaStdStringTools::toDouble( tokens[4], z );
if ( vertexId > -1 ) if ( vertexId > -1 )
{ {
@@ -121,15 +130,14 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
vertices.emplace_back( cvf::Vec3d( x, y, z ) ); vertices.emplace_back( cvf::Vec3d( x, y, z ) );
vertexIdToIndex[vertexId] = static_cast<unsigned>( vertices.size() - 1 ); vertexIdToIndex[vertexId] = static_cast<unsigned>( vertices.size() - 1 );
double value = std::numeric_limits<double>::infinity();
for ( size_t i = 0; i < propertyNames.size(); i++ ) for ( size_t i = 0; i < propertyNames.size(); i++ )
{ {
float value = std::numeric_limits<double>::infinity();
auto tokenIndex = 5 + i; auto tokenIndex = 5 + i;
if ( tokenIndex < tokens.size() ) if ( tokenIndex < tokens.size() )
value = RiaStdStringTools::toDouble( tokens[tokenIndex] ); RiaStdStringTools::toDouble( tokens[tokenIndex], value );
propertyValues[i].push_back( value ); propertyValues[i].push_back( static_cast<float>( value ) );
} }
} }
} }
@@ -138,9 +146,9 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
{ {
if ( tokens.size() > 3 ) if ( tokens.size() > 3 )
{ {
auto id1 = RiaStdStringTools::toInt( tokens[1] ); RiaStdStringTools::toInt( tokens[1], id1 );
auto id2 = RiaStdStringTools::toInt( tokens[2] ); RiaStdStringTools::toInt( tokens[2], id2 );
auto id3 = RiaStdStringTools::toInt( tokens[3] ); RiaStdStringTools::toInt( tokens[3], id3 );
if ( id1 >= 0 && id2 >= 0 && id3 >= 0 ) if ( id1 >= 0 && id2 >= 0 && id3 >= 0 )
{ {

View File

@@ -69,41 +69,51 @@ bool RigSurfaceResampler::resamplePoint( RigSurface* surface,
bb.add( pointAbove ); bb.add( pointAbove );
bb.add( pointBelow ); bb.add( pointBelow );
std::vector<size_t> triangleStartIndices; const std::vector<unsigned int>& triIndices = surface->triangleIndices();
surface->findIntersectingTriangles( bb, &triangleStartIndices ); const std::vector<cvf::Vec3d>& vertices = surface->vertices();
const std::vector<unsigned int>& indices = surface->triangleIndices();
const std::vector<cvf::Vec3d>& vertices = surface->vertices();
if ( !triangleStartIndices.empty() )
{ {
for ( auto triangleStartIndex : triangleStartIndices ) std::vector<size_t> triangleStartIndices;
surface->findIntersectingTriangles( bb, &triangleStartIndices );
if ( !triangleStartIndices.empty() )
{ {
bool isLineDirDotNormalNegative = false; for ( auto triangleStartIndex : triangleStartIndices )
if ( cvf::GeometryTools::intersectLineSegmentTriangle( pointAbove, {
pointBelow, bool isLineDirDotNormalNegative = false;
vertices[indices[triangleStartIndex + 0]], if ( cvf::GeometryTools::intersectLineSegmentTriangle( pointAbove,
vertices[indices[triangleStartIndex + 1]], pointBelow,
vertices[indices[triangleStartIndex + 2]], vertices[triIndices[triangleStartIndex + 0]],
&intersectionPoint, vertices[triIndices[triangleStartIndex + 1]],
&isLineDirDotNormalNegative ) == 1 ) vertices[triIndices[triangleStartIndex + 2]],
return true; &intersectionPoint,
&isLineDirDotNormalNegative ) == 1 )
return true;
}
} }
} }
double maxDistance = computeMaxDistance( surface ); double maxDistance = computeMaxDistance( surface );
return findClosestPointXY( pointAbove, vertices, maxDistance, intersectionPoint ); // Expand the bounding box to cover a larger volume. Use this volume to find intersections.
bb.expand( maxDistance );
std::vector<size_t> triangleStartIndices;
surface->findIntersectingTriangles( bb, &triangleStartIndices );
return findClosestPointXY( pointAbove, vertices, triIndices, triangleStartIndices, maxDistance, intersectionPoint );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Find the closest vertex to targetPoint (must be closer than maxDistance) in XY plane. /// Find the closest vertex to targetPoint (must be closer than maxDistance) in XY plane.
/// Unit maxDistance: meter. /// Unit maxDistance: meter.
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& targetPoint, bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& targetPoint,
const std::vector<cvf::Vec3d>& vertices, const std::vector<cvf::Vec3d>& vertices,
double maxDistance, const std::vector<unsigned int>& triangleIndices,
cvf::Vec3d& intersectionPoint ) const std::vector<size_t>& triangleStartIndices,
double maxDistance,
cvf::Vec3d& intersectionPoint )
{ {
double maxDistanceSquared = maxDistance * maxDistance; double maxDistanceSquared = maxDistance * maxDistance;
@@ -112,22 +122,27 @@ bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& tar
double closestZ = std::numeric_limits<double>::infinity(); double closestZ = std::numeric_limits<double>::infinity();
cvf::Vec3d p; cvf::Vec3d p;
double distanceSquared = 0.0; double distanceSquared = 0.0;
for ( const auto& v : vertices ) for ( auto triangleStartIndex : triangleStartIndices )
{ {
if ( std::fabs( targetPoint.x() - v.x() ) > maxDistance ) continue; for ( size_t localIdx = 0; localIdx < 3; localIdx++ )
if ( std::fabs( targetPoint.y() - v.y() ) > maxDistance ) continue;
// Ignore height (z) component when finding closest by
// moving point to same height as target point above
p.x() = v.x();
p.y() = v.y();
p.z() = targetPoint.z();
distanceSquared = p.pointDistanceSquared( targetPoint );
if ( distanceSquared < shortestDistanceSquared )
{ {
shortestDistanceSquared = distanceSquared; const auto& v = vertices[triangleIndices[triangleStartIndex + localIdx]];
closestZ = v.z();
if ( std::fabs( targetPoint.x() - v.x() ) > maxDistance ) continue;
if ( std::fabs( targetPoint.y() - v.y() ) > maxDistance ) continue;
// Ignore height (z) component when finding closest by
// moving point to same height as target point above
p.x() = v.x();
p.y() = v.y();
p.z() = targetPoint.z();
distanceSquared = p.pointDistanceSquared( targetPoint );
if ( distanceSquared < shortestDistanceSquared )
{
shortestDistanceSquared = distanceSquared;
closestZ = v.z();
}
} }
} }
@@ -137,10 +152,8 @@ bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& tar
intersectionPoint = cvf::Vec3d( targetPoint.x(), targetPoint.y(), closestZ ); intersectionPoint = cvf::Vec3d( targetPoint.x(), targetPoint.y(), closestZ );
return true; return true;
} }
else
{ return false;
return false;
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -35,10 +35,12 @@ public:
cvf::Vec3d& intersectionPoint ); cvf::Vec3d& intersectionPoint );
private: private:
static bool findClosestPointXY( const cvf::Vec3d& targetPoint, static bool findClosestPointXY( const cvf::Vec3d& targetPoint,
const std::vector<cvf::Vec3d>& vertices, const std::vector<cvf::Vec3d>& vertices,
double maxDistance, const std::vector<unsigned int>& triangleIndices,
cvf::Vec3d& intersectionPoint ); const std::vector<size_t>& triangleStartIndices,
double maxDistance,
cvf::Vec3d& intersectionPoint );
static double computeMaxDistance( RigSurface* surface ); static double computeMaxDistance( RigSurface* surface );
}; };