VTK: Read geometry only on first timestep, log displacements per timestep

Move points and connectivity reading inside the isFirst guard to avoid redundant parsing on subsequent timesteps. Move displacements reading outside the guard so they are read for every timestep, and update the log message accordingly.
This commit is contained in:
Magne Sjaastad committed 2026-04-14 14:56:43 +02:00
1 parent 9ff69a2089
commit e3d5b05125
2 files changed
+49 -29

No files matched your search

@@ -20,9 +20,11 @@
#include "RiaStdStringTools.h"
#include "fast_float/fast_float.h"
#include <cstring>
#include <filesystem>
#include <spanstream>
#include <sstream>
#include <string>
#include <vector>
@@ -114,24 +116,41 @@ std::map<std::string, std::vector<float>> RifVtkImportUtil::readProperties( cons
if ( name && *name )
{
std::vector<float> values;
std::istringstream iss( dataArray.text().get() );
const char* text = dataArray.text().get();
const char* ptr = text;
const char* textEnd = text + std::strlen( text );
std::string token;
while ( iss >> token )
while ( *ptr != '\0' )
{
if ( token == "nan" || token == "NaN" || token == "NAN" )
// Skip whitespace
while ( *ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\r' )
++ptr;
if ( *ptr == '\0' ) break;
// Check for NaN (case-insensitive). ptr[3] is safe because text is null-terminated,
// so if ptr points to the last three chars "nan", ptr[3] == '\0' which matches the condition.
if ( ( *ptr == 'n' || *ptr == 'N' ) && ( ptr[1] == 'a' || ptr[1] == 'A' ) && ( ptr[2] == 'n' || ptr[2] == 'N' ) &&
( ptr[3] == '\0' || ptr[3] == ' ' || ptr[3] == '\t' || ptr[3] == '\n' || ptr[3] == '\r' ) )
{
values.push_back( std::numeric_limits<float>::quiet_NaN() );
ptr += 3;
continue;
}
else
// Parse float directly using fast_float
float fValue = 0.0f;
auto result = fast_float::from_chars( ptr, textEnd, fValue );
auto* parsedEndPtr = result.ptr;
if ( result.ec != std::errc() || parsedEndPtr == ptr )
{
double value = 0.0;
bool isOk = RiaStdStringTools::toDouble( token, value );
if ( isOk )
values.push_back( static_cast<float>( value ) );
else
return {};
// Failed to parse
return {};
}
values.push_back( fValue );
ptr = parsedEndPtr;
}
if ( !values.empty() )
@@ -256,27 +256,18 @@ std::expected<RigElementType, std::string>
auto piece = grid.child( "Piece" );
if ( !piece ) return std::unexpected( "Missing Piece tag: " + d.filepath.string() );
// Read points
std::vector<cvf::Vec3d> vertices = RifVtkImportUtil::readPoints( piece );
if ( vertices.empty() ) return std::unexpected( "No points found: " + d.filepath.string() );
// Read connectivity
std::vector<unsigned> connectivity = RifVtkImportUtil::readConnectivity( piece );
if ( connectivity.empty() ) return std::unexpected( "No connectivity found: " + d.filepath.string() );
// Read connectivity
std::vector<cvf::Vec3f> partDisplacements = RifVtkImportUtil::readDisplacements( piece );
if ( partDisplacements.empty() ) return std::unexpected( "No displacements found: " + d.filepath.string() );
RiaLogging::info( QString( "Found %1 vertices, %2 connectivities, and %3 displacements." )
.arg( vertices.size() )
.arg( connectivity.size() )
.arg( partDisplacements.size() ) );
// Use the geometry from the first time step only.
// The geometry is assumed to not change between time steps.
if ( isFirst )
{
// Read points
std::vector<cvf::Vec3d> vertices = RifVtkImportUtil::readPoints( piece );
if ( vertices.empty() ) return std::unexpected( "No points found: " + d.filepath.string() );
// Read connectivity
std::vector<unsigned> connectivity = RifVtkImportUtil::readConnectivity( piece );
if ( connectivity.empty() ) return std::unexpected( "No connectivity found: " + d.filepath.string() );
std::vector<std::pair<int, cvf::Vec3d>> partNodes;
for ( int i = 0; i < static_cast<int>( vertices.size() ); i++ )
{
@@ -303,8 +294,18 @@ std::expected<RigElementType, std::string>
elementType = RigElementType::HEX8P;
}
// Read displacements for all timesteps
std::vector<cvf::Vec3f> partDisplacements = RifVtkImportUtil::readDisplacements( piece );
if ( partDisplacements.empty() ) return std::unexpected( "No displacements found: " + d.filepath.string() );
const std::map<std::string, std::vector<float>> partProperties = RifVtkImportUtil::readProperties( piece );
RiaLogging::info( QString( "Found %1 displacements and %2 properties for timestep %3." )
.arg( partDisplacements.size() )
.arg( partProperties.size() )
.arg( d.timestep ) );
properties[partId].push_back( partProperties );
displacements[partId].push_back( partDisplacements );