mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge pull request #8159 from OPM/performance-surface
Performance Surface import and resampling
This commit is contained in:
@@ -18,7 +18,10 @@
|
||||
|
||||
#include "RiaStdStringTools.h"
|
||||
|
||||
#include "fast_float/include/fast_float/fast_float.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <charconv>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -107,6 +110,26 @@ bool RiaStdStringTools::startsWithAlphabetic( const std::string& s )
|
||||
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() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -39,6 +39,10 @@ public:
|
||||
static bool containsAlphabetic( 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 bool endsWith( const std::string& mainStr, const std::string& toMatch );
|
||||
|
||||
@@ -63,6 +63,11 @@ void RicImportEclipseCaseFeature::onActionTriggered( bool isChecked )
|
||||
std::vector<int> caseIds;
|
||||
std::shared_ptr<RifReaderSettings> readerSettings;
|
||||
openEclipseCaseFromFileNames( fileNames, createDefaultView, caseIds, readerSettings );
|
||||
|
||||
for ( const auto& f : fileNames )
|
||||
{
|
||||
RiaApplication::instance()->addToRecentFiles( f );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -72,6 +72,15 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
|
||||
bool isInTfaceSection = false;
|
||||
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() )
|
||||
{
|
||||
std::string line;
|
||||
@@ -88,10 +97,10 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
|
||||
{
|
||||
if ( tokens.size() > 4 )
|
||||
{
|
||||
int vertexId = RiaStdStringTools::toInt( tokens[1] );
|
||||
double x = RiaStdStringTools::toDouble( tokens[2] );
|
||||
double y = RiaStdStringTools::toDouble( tokens[3] );
|
||||
double z = RiaStdStringTools::toDouble( tokens[4] );
|
||||
RiaStdStringTools::toInt( tokens[1], vertexId );
|
||||
RiaStdStringTools::toDouble( tokens[2], x );
|
||||
RiaStdStringTools::toDouble( tokens[3], y );
|
||||
RiaStdStringTools::toDouble( tokens[4], z );
|
||||
|
||||
if ( vertexId > -1 )
|
||||
{
|
||||
@@ -109,10 +118,10 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
|
||||
{
|
||||
if ( tokens.size() > 4 )
|
||||
{
|
||||
int vertexId = RiaStdStringTools::toInt( tokens[1] );
|
||||
double x = RiaStdStringTools::toDouble( tokens[2] );
|
||||
double y = RiaStdStringTools::toDouble( tokens[3] );
|
||||
double z = RiaStdStringTools::toDouble( tokens[4] );
|
||||
RiaStdStringTools::toInt( tokens[1], vertexId );
|
||||
RiaStdStringTools::toDouble( tokens[2], x );
|
||||
RiaStdStringTools::toDouble( tokens[3], y );
|
||||
RiaStdStringTools::toDouble( tokens[4], z );
|
||||
|
||||
if ( vertexId > -1 )
|
||||
{
|
||||
@@ -121,15 +130,14 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g
|
||||
vertices.emplace_back( cvf::Vec3d( x, y, z ) );
|
||||
vertexIdToIndex[vertexId] = static_cast<unsigned>( vertices.size() - 1 );
|
||||
|
||||
double value = std::numeric_limits<double>::infinity();
|
||||
for ( size_t i = 0; i < propertyNames.size(); i++ )
|
||||
{
|
||||
float value = std::numeric_limits<double>::infinity();
|
||||
|
||||
auto tokenIndex = 5 + i;
|
||||
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 )
|
||||
{
|
||||
auto id1 = RiaStdStringTools::toInt( tokens[1] );
|
||||
auto id2 = RiaStdStringTools::toInt( tokens[2] );
|
||||
auto id3 = RiaStdStringTools::toInt( tokens[3] );
|
||||
RiaStdStringTools::toInt( tokens[1], id1 );
|
||||
RiaStdStringTools::toInt( tokens[2], id2 );
|
||||
RiaStdStringTools::toInt( tokens[3], id3 );
|
||||
|
||||
if ( id1 >= 0 && id2 >= 0 && id3 >= 0 )
|
||||
{
|
||||
|
||||
@@ -69,41 +69,51 @@ bool RigSurfaceResampler::resamplePoint( RigSurface* surface,
|
||||
bb.add( pointAbove );
|
||||
bb.add( pointBelow );
|
||||
|
||||
std::vector<size_t> triangleStartIndices;
|
||||
surface->findIntersectingTriangles( bb, &triangleStartIndices );
|
||||
const std::vector<unsigned int>& triIndices = surface->triangleIndices();
|
||||
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;
|
||||
if ( cvf::GeometryTools::intersectLineSegmentTriangle( pointAbove,
|
||||
pointBelow,
|
||||
vertices[indices[triangleStartIndex + 0]],
|
||||
vertices[indices[triangleStartIndex + 1]],
|
||||
vertices[indices[triangleStartIndex + 2]],
|
||||
&intersectionPoint,
|
||||
&isLineDirDotNormalNegative ) == 1 )
|
||||
return true;
|
||||
for ( auto triangleStartIndex : triangleStartIndices )
|
||||
{
|
||||
bool isLineDirDotNormalNegative = false;
|
||||
if ( cvf::GeometryTools::intersectLineSegmentTriangle( pointAbove,
|
||||
pointBelow,
|
||||
vertices[triIndices[triangleStartIndex + 0]],
|
||||
vertices[triIndices[triangleStartIndex + 1]],
|
||||
vertices[triIndices[triangleStartIndex + 2]],
|
||||
&intersectionPoint,
|
||||
&isLineDirDotNormalNegative ) == 1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
/// Unit maxDistance: meter.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& targetPoint,
|
||||
const std::vector<cvf::Vec3d>& vertices,
|
||||
double maxDistance,
|
||||
cvf::Vec3d& intersectionPoint )
|
||||
bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& targetPoint,
|
||||
const std::vector<cvf::Vec3d>& vertices,
|
||||
const std::vector<unsigned int>& triangleIndices,
|
||||
const std::vector<size_t>& triangleStartIndices,
|
||||
double maxDistance,
|
||||
cvf::Vec3d& intersectionPoint )
|
||||
{
|
||||
double maxDistanceSquared = maxDistance * maxDistance;
|
||||
|
||||
@@ -112,22 +122,27 @@ bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& tar
|
||||
double closestZ = std::numeric_limits<double>::infinity();
|
||||
cvf::Vec3d p;
|
||||
double distanceSquared = 0.0;
|
||||
for ( const auto& v : vertices )
|
||||
for ( auto triangleStartIndex : triangleStartIndices )
|
||||
{
|
||||
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 )
|
||||
for ( size_t localIdx = 0; localIdx < 3; localIdx++ )
|
||||
{
|
||||
shortestDistanceSquared = distanceSquared;
|
||||
closestZ = v.z();
|
||||
const auto& v = vertices[triangleIndices[triangleStartIndex + localIdx]];
|
||||
|
||||
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 );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -35,10 +35,12 @@ public:
|
||||
cvf::Vec3d& intersectionPoint );
|
||||
|
||||
private:
|
||||
static bool findClosestPointXY( const cvf::Vec3d& targetPoint,
|
||||
const std::vector<cvf::Vec3d>& vertices,
|
||||
double maxDistance,
|
||||
cvf::Vec3d& intersectionPoint );
|
||||
static bool findClosestPointXY( const cvf::Vec3d& targetPoint,
|
||||
const std::vector<cvf::Vec3d>& vertices,
|
||||
const std::vector<unsigned int>& triangleIndices,
|
||||
const std::vector<size_t>& triangleStartIndices,
|
||||
double maxDistance,
|
||||
cvf::Vec3d& intersectionPoint );
|
||||
|
||||
static double computeMaxDistance( RigSurface* surface );
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user