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 "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() );
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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 );
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user