diff --git a/ApplicationLibCode/Application/Tools/RiaStdStringTools.cpp b/ApplicationLibCode/Application/Tools/RiaStdStringTools.cpp index f1f25a80d1..3a51395503 100644 --- a/ApplicationLibCode/Application/Tools/RiaStdStringTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaStdStringTools.cpp @@ -18,7 +18,10 @@ #include "RiaStdStringTools.h" +#include "fast_float/include/fast_float/fast_float.h" + #include +#include //-------------------------------------------------------------------------------------------------- /// @@ -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() ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/Tools/RiaStdStringTools.h b/ApplicationLibCode/Application/Tools/RiaStdStringTools.h index 5202c189fd..9023a01857 100644 --- a/ApplicationLibCode/Application/Tools/RiaStdStringTools.h +++ b/ApplicationLibCode/Application/Tools/RiaStdStringTools.h @@ -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 ); diff --git a/ApplicationLibCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.cpp b/ApplicationLibCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.cpp index 9a5e263fa0..4e3414d5f7 100644 --- a/ApplicationLibCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.cpp +++ b/ApplicationLibCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.cpp @@ -63,6 +63,11 @@ void RicImportEclipseCaseFeature::onActionTriggered( bool isChecked ) std::vector caseIds; std::shared_ptr readerSettings; openEclipseCaseFromFileNames( fileNames, createDefaultView, caseIds, readerSettings ); + + for ( const auto& f : fileNames ) + { + RiaApplication::instance()->addToRecentFiles( f ); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp b/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp index 1d4533ad6a..4f476abb57 100644 --- a/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp +++ b/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp @@ -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( vertices.size() - 1 ); + double value = std::numeric_limits::infinity(); for ( size_t i = 0; i < propertyNames.size(); i++ ) { - float value = std::numeric_limits::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( 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 ) { diff --git a/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.cpp b/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.cpp index 806457c554..5d5fd5f8fd 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.cpp @@ -69,41 +69,51 @@ bool RigSurfaceResampler::resamplePoint( RigSurface* surface, bb.add( pointAbove ); bb.add( pointBelow ); - std::vector triangleStartIndices; - surface->findIntersectingTriangles( bb, &triangleStartIndices ); + const std::vector& triIndices = surface->triangleIndices(); + const std::vector& vertices = surface->vertices(); - const std::vector& indices = surface->triangleIndices(); - const std::vector& vertices = surface->vertices(); - - if ( !triangleStartIndices.empty() ) { - for ( auto triangleStartIndex : triangleStartIndices ) + std::vector 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 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& vertices, - double maxDistance, - cvf::Vec3d& intersectionPoint ) +bool RigSurfaceResampler::findClosestPointXY( const cvf::Vec3d& targetPoint, + const std::vector& vertices, + const std::vector& triangleIndices, + const std::vector& 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::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; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.h b/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.h index ceb1af445d..9590b8115d 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.h +++ b/ApplicationLibCode/ReservoirDataModel/RigSurfaceResampler.h @@ -35,10 +35,12 @@ public: cvf::Vec3d& intersectionPoint ); private: - static bool findClosestPointXY( const cvf::Vec3d& targetPoint, - const std::vector& vertices, - double maxDistance, - cvf::Vec3d& intersectionPoint ); + static bool findClosestPointXY( const cvf::Vec3d& targetPoint, + const std::vector& vertices, + const std::vector& triangleIndices, + const std::vector& triangleStartIndices, + double maxDistance, + cvf::Vec3d& intersectionPoint ); static double computeMaxDistance( RigSurface* surface ); };