diff --git a/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp b/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp index cb8689f0c6..c7a08a4d1c 100644 --- a/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp +++ b/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp @@ -18,7 +18,7 @@ #include "RifSurfaceImporter.h" #include "RiaStdStringTools.h" -#include "RigGocadData.h" +#include "RigTriangleMeshData.h" #include "cafProgressInfo.h" @@ -43,9 +43,9 @@ /// Returns vertices with z-value as depth, z is increasing downwards /// //-------------------------------------------------------------------------------------------------- -void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* gocadData ) +void RifSurfaceImporter::readGocadFile( const QString& filename, RigTriangleMeshData* triangleMeshData ) { - CVF_ASSERT( gocadData ); + CVF_ASSERT( triangleMeshData ); enum class GocadZPositive { @@ -204,10 +204,10 @@ void RifSurfaceImporter::readGocadFile( const QString& filename, RigGocadData* g } } - if ( gocadData ) + if ( triangleMeshData ) { - gocadData->setGeometryData( vertices, triangleIndices ); - gocadData->setPropertyData( propertyNames, propertyValues ); + triangleMeshData->setGeometryData( vertices, triangleIndices ); + triangleMeshData->setPropertyData( propertyNames, propertyValues ); } } diff --git a/ApplicationLibCode/FileInterface/RifSurfaceImporter.h b/ApplicationLibCode/FileInterface/RifSurfaceImporter.h index cbfe26fcd4..3e85ae3846 100644 --- a/ApplicationLibCode/FileInterface/RifSurfaceImporter.h +++ b/ApplicationLibCode/FileInterface/RifSurfaceImporter.h @@ -26,12 +26,12 @@ #include -class RigGocadData; +class RigTriangleMeshData; class RifSurfaceImporter { public: - static void readGocadFile( const QString& filename, RigGocadData* gocadData ); + static void readGocadFile( const QString& filename, RigTriangleMeshData* triangleMeshData ); static std::pair, std::vector> readPetrelFile( const QString& filename ); static std::pair, std::vector> readOpenWorksXyzFile( const QString& filename, double preferredPointDistance ); diff --git a/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.cpp b/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.cpp index 898e1261a0..3364a3ce1a 100644 --- a/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.cpp +++ b/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.cpp @@ -18,8 +18,7 @@ #include "RifVtkSurfaceImporter.h" -#include "../../Fwk/VizFwk/LibIo/cvfTinyXmlFused.hpp" -#include "RigGocadData.h" +#include "RigTriangleMeshData.h" #include #include @@ -27,60 +26,39 @@ #include #include -namespace RifVtkSurfaceImporter +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::unique_ptr RifVtkSurfaceImporter::importFromFile( const std::filesystem::path& filepath ) { -using namespace cvf_tinyXML; + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file( filepath.string().c_str() ); + if ( !result ) return nullptr; -bool importFromFile( std::string filename, RigGocadData* gocadData ) -{ - TiXmlDocument doc; - if ( !doc.LoadFile( filename.c_str() ) ) - { - return false; - } - - return importFromXmlDoc( doc, gocadData ); + return importFromXmlDoc( doc ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool importFromPvdFile( const std::string& filename, RigGocadData* gocadData ) +std::unique_ptr RifVtkSurfaceImporter::importFromXmlDoc( const pugi::xml_document& doc ) { - auto datasets = parsePvdDatasets( filename ); + auto root = doc.child( "VTKFile" ); + if ( !root ) return nullptr; - if ( datasets.empty() ) return false; + auto grid = root.child( "UnstructuredGrid" ); + if ( !grid ) return nullptr; - // Sort and import the most recent dataset - std::sort( datasets.begin(), datasets.end(), []( const PvdDataset& a, const PvdDataset& b ) { return a.timestep < b.timestep; } ); - - return importDataset( datasets.back(), gocadData ); -} - -bool importFromXmlDoc( const TiXmlDocument& doc, RigGocadData* gocadData ) -{ - auto* root = doc.FirstChildElement( "VTKFile" ); - if ( !root ) return false; - - auto* grid = root->FirstChildElement( "UnstructuredGrid" ); - if ( !grid ) return false; - - auto* piece = grid->FirstChildElement( "Piece" ); - if ( !piece ) return false; + auto piece = grid.child( "Piece" ); + if ( !piece ) return nullptr; // Read points - std::vector vertices; - if ( !readPoints( piece, vertices ) ) - { - return false; - } + std::vector vertices = readPoints( piece ); + if ( vertices.empty() ) return nullptr; // Read connectivity - std::vector connectivity; - if ( !readConnectivity( piece, connectivity ) ) - { - return false; - } + std::vector connectivity = readConnectivity( piece ); + if ( connectivity.empty() ) return nullptr; // Avoid shared nodes std::vector nonSharedVertices; @@ -99,69 +77,70 @@ bool importFromXmlDoc( const TiXmlDocument& doc, RigGocadData* gocadData ) } // Set geometry data - gocadData->setGeometryData( nonSharedVertices, nonSharedConnectivity ); + auto triangleMeshData = std::make_unique(); + triangleMeshData->setGeometryData( nonSharedVertices, nonSharedConnectivity ); // Read properties - std::vector propertyNamesOnFile; - std::vector> propertyValuesOnFile; - - readProperties( piece, propertyNamesOnFile, propertyValuesOnFile ); - - if ( propertyNamesOnFile.size() == propertyValuesOnFile.size() ) + const std::map> properties = readProperties( piece ); + for ( const auto& [name, values] : properties ) { - for ( size_t i = 0; i < propertyValuesOnFile.size(); i++ ) + // These values are per element, so we need to duplicate them for each node + if ( values.size() * 3 == nonSharedVertices.size() ) { - // These values are per element, so we need to duplicate them for each node - auto values = propertyValuesOnFile[i]; - if ( values.size() * 3 == nonSharedVertices.size() ) + std::vector valuesForEachNode; + for ( auto value : values ) { - std::vector valuesForEachNode; - for ( auto value : values ) - { - valuesForEachNode.push_back( value ); - valuesForEachNode.push_back( value ); - valuesForEachNode.push_back( value ); - } - - gocadData->addPropertyData( QString::fromStdString( propertyNamesOnFile[i] ), valuesForEachNode ); + valuesForEachNode.push_back( value ); + valuesForEachNode.push_back( value ); + valuesForEachNode.push_back( value ); } + + triangleMeshData->addPropertyData( QString::fromStdString( name ), valuesForEachNode ); } } - return true; + return triangleMeshData; } -bool readPoints( const TiXmlElement* piece, std::vector& vertices ) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifVtkSurfaceImporter::readPoints( const pugi::xml_node& piece ) { - auto* points = piece->FirstChildElement( "Points" ); - if ( !points ) return false; + auto points = piece.child( "Points" ); + if ( !points ) return {}; - auto* coords = points->FirstChildElement( "DataArray" ); - if ( !coords || strcmp( coords->Attribute( "Name" ), "Coordinates" ) != 0 ) return false; + auto coords = points.child( "DataArray" ); + if ( !coords || std::string( coords.attribute( "Name" ).value() ) != "Coordinates" ) return {}; - std::string coordsText = coords->GetText(); - std::istringstream iss( coordsText ); + std::vector vertices; + std::istringstream iss( coords.text().get() ); double x, y, z; while ( iss >> x >> y >> z ) { - vertices.push_back( cvf::Vec3d( x, y, -z ) ); + vertices.emplace_back( x, y, -z ); } - return !vertices.empty(); + return vertices; } -bool readConnectivity( const TiXmlElement* piece, std::vector& connectivity ) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifVtkSurfaceImporter::readConnectivity( const pugi::xml_node& piece ) { - auto* cells = piece->FirstChildElement( "Cells" ); - if ( !cells ) return false; + auto cells = piece.child( "Cells" ); + if ( !cells ) return {}; + + std::vector connectivity; + auto connectivityArray = cells.child( "DataArray" ); - auto* connectivityArray = cells->FirstChildElement( "DataArray" ); while ( connectivityArray ) { - if ( strcmp( connectivityArray->Attribute( "Name" ), "connectivity" ) == 0 ) + if ( std::string( connectivityArray.attribute( "Name" ).value() ) == "connectivity" ) { - std::string connectivityText = connectivityArray->GetText(); + std::string connectivityText = connectivityArray.text().get(); std::istringstream iss( connectivityText ); unsigned index; @@ -171,26 +150,29 @@ bool readConnectivity( const TiXmlElement* piece, std::vector& connect } break; } - connectivityArray = connectivityArray->NextSiblingElement( "DataArray" ); + connectivityArray = connectivityArray.next_sibling( "DataArray" ); } - return !connectivity.empty(); + return connectivity; } -void readProperties( const TiXmlElement* piece, std::vector& propertyNames, std::vector>& propertyValues ) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> RifVtkSurfaceImporter::readProperties( const pugi::xml_node& piece ) { - auto* cellData = piece->FirstChildElement( "CellData" ); - if ( !cellData ) return; + auto cellData = piece.child( "CellData" ); + if ( !cellData ) return {}; - auto* dataArray = cellData->FirstChildElement( "DataArray" ); - while ( dataArray ) + std::map> properties; + + for ( const auto& dataArray : cellData.children( "DataArray" ) ) { - const char* name = dataArray->Attribute( "Name" ); - if ( name ) + const char* name = dataArray.attribute( "Name" ).value(); + if ( name && *name ) { std::vector values; - std::string valuesText = dataArray->GetText(); - std::istringstream iss( valuesText ); + std::istringstream iss( dataArray.text().get() ); float value; while ( iss >> value ) @@ -200,64 +182,46 @@ void readProperties( const TiXmlElement* piece, std::vector& proper if ( !values.empty() ) { - propertyNames.push_back( name ); - propertyValues.push_back( values ); + properties[name] = std::move( values ); } } - dataArray = dataArray->NextSiblingElement( "DataArray" ); } + + return properties; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector parsePvdDatasets( const std::string& filename ) +std::vector RifVtkSurfaceImporter::parsePvdDatasets( const std::filesystem::path& filepath ) { + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file( filepath.string().c_str() ); + if ( !result ) return {}; + + auto root = doc.child( "VTKFile" ); + if ( !root ) return {}; + + auto collection = root.child( "Collection" ); + if ( !collection ) return {}; + + std::filesystem::path baseDir = filepath.parent_path(); + std::vector datasets; - TiXmlDocument doc; - if ( !doc.LoadFile( filename.c_str() ) ) return datasets; - - auto* root = doc.FirstChildElement( "VTKFile" ); - if ( !root ) return datasets; - - auto* collection = root->FirstChildElement( "Collection" ); - if ( !collection ) return datasets; - - std::string baseDir = std::filesystem::path( filename ).parent_path().string(); - - auto* datasetElem = collection->FirstChildElement( "DataSet" ); - while ( datasetElem ) + for ( const auto& datasetElem : collection.children( "DataSet" ) ) { - const char* file = datasetElem->Attribute( "file" ); - const char* timestepStr = datasetElem->Attribute( "timestep" ); + const char* file = datasetElem.attribute( "file" ).value(); + const char* timestepStr = datasetElem.attribute( "timestep" ).value(); if ( file && timestepStr ) { - double timestep = std::stod( timestepStr ); - std::string fullPath = std::filesystem::absolute( std::filesystem::path( baseDir ) / file ).string(); + double timestep = std::stod( timestepStr ); + std::filesystem::path fullPath = std::filesystem::absolute( baseDir / file ); datasets.push_back( { timestep, fullPath } ); } - - datasetElem = datasetElem->NextSiblingElement( "DataSet" ); } return datasets; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool importDataset( const PvdDataset& dataset, RigGocadData* gocadData ) -{ - TiXmlDocument doc; - if ( !doc.LoadFile( dataset.filename.c_str() ) ) - { - return false; - } - - return importFromXmlDoc( doc, gocadData ); -} - -}; // namespace RifVtkSurfaceImporter diff --git a/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.h b/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.h index 1987a0013f..3e93e2ad88 100644 --- a/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.h +++ b/ApplicationLibCode/FileInterface/RifVtkSurfaceImporter.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include #include @@ -25,38 +26,29 @@ #include "cvfVector3.h" -class RigGocadData; +#include "pugixml.hpp" -namespace cvf_tinyXML -{ -class TiXmlDocument; -class TiXmlElement; -} // namespace cvf_tinyXML +class RigTriangleMeshData; //================================================================================================== /// //================================================================================================== -namespace RifVtkSurfaceImporter +class RifVtkSurfaceImporter { +public: + struct PvdDataset + { + double timestep; + std::filesystem::path filepath; + }; -struct PvdDataset -{ - double timestep; - std::string filename; + static std::unique_ptr importFromFile( const std::filesystem::path& filepath ); + + static std::vector parsePvdDatasets( const std::filesystem::path& filepath ); + +private: + static std::unique_ptr importFromXmlDoc( const pugi::xml_document& doc ); + static std::vector readPoints( const pugi::xml_node& piece ); + static std::vector readConnectivity( const pugi::xml_node& piece ); + static std::map> readProperties( const pugi::xml_node& piece ); }; - -bool importFromFile( std::string filename, RigGocadData* gocadData ); - -bool importFromPvdFile( const std::string& filename, RigGocadData* gocadData ); -bool importFromXmlDoc( const cvf_tinyXML::TiXmlDocument& doc, RigGocadData* gocadData ); - -bool readPoints( const cvf_tinyXML::TiXmlElement* piece, std::vector& vertices ); -bool readConnectivity( const cvf_tinyXML::TiXmlElement* piece, std::vector& connectivity ); -void readProperties( const cvf_tinyXML::TiXmlElement* piece, - std::vector& propertyNames, - std::vector>& propertyValues ); - -std::vector parsePvdDatasets( const std::string& filename ); -bool importDataset( const PvdDataset& dataset, RigGocadData* gocadData ); - -}; // namespace RifVtkSurfaceImporter diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.cpp b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.cpp index dd20bd55dc..9e92dcedb4 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.cpp +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.cpp @@ -25,8 +25,8 @@ #include "RifSurfaceImporter.h" #include "RifVtkSurfaceImporter.h" -#include "RigGocadData.h" #include "RigSurface.h" +#include "RigTriangleMeshData.h" #include "cafPdmFieldScriptingCapability.h" #include "cafPdmObjectScriptingCapability.h" @@ -135,12 +135,12 @@ bool RimFileSurface::updateSurfaceData() surface->setTriangleData( tringleIndices, vertices ); } - if ( m_gocadData ) + if ( m_triangleMeshData ) { - auto propertyNames = m_gocadData->propertyNames(); + auto propertyNames = m_triangleMeshData->propertyNames(); for ( const auto& name : propertyNames ) { - auto values = m_gocadData->propertyValues( name ); + auto values = m_triangleMeshData->propertyValues( name ); surface->addVerticeResult( name, values ); } } @@ -173,18 +173,17 @@ bool RimFileSurface::loadDataFromFile() } else if ( filePath.endsWith( "ts", Qt::CaseInsensitive ) ) { - m_gocadData = std::make_unique(); + m_triangleMeshData = std::make_unique(); - RifSurfaceImporter::readGocadFile( filePath, m_gocadData.get() ); + RifSurfaceImporter::readGocadFile( filePath, m_triangleMeshData.get() ); - surface = m_gocadData->gocadGeometry(); + surface = m_triangleMeshData->geometry(); } else if ( filePath.endsWith( "vtu", Qt::CaseInsensitive ) ) { - m_gocadData = std::make_unique(); - RifVtkSurfaceImporter::importFromFile( filePath.toStdString(), m_gocadData.get() ); + m_triangleMeshData = RifVtkSurfaceImporter::importFromFile( filePath.toStdString() ); - surface = m_gocadData->gocadGeometry(); + surface = m_triangleMeshData->geometry(); } else if ( filePath.endsWith( "dat", Qt::CaseInsensitive ) || filePath.endsWith( "xyz", Qt::CaseInsensitive ) ) { diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.h b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.h index 2ad4af6b08..d7586b1b88 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.h +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFileSurface.h @@ -22,7 +22,7 @@ #include -class RigGocadData; +class RigTriangleMeshData; class RimFileSurface : public RimSurface { @@ -53,5 +53,5 @@ private: std::vector m_tringleIndices; std::vector m_vertices; - std::unique_ptr m_gocadData; + std::unique_ptr m_triangleMeshData; }; diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.cpp b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.cpp index 0aee561d0b..d3d0ba108d 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.cpp +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2020- Equinor ASA +// Copyright (C) 2025- Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,22 +18,18 @@ #include "RimFractureSurface.h" -#include "RiaPreferences.h" +#include "RigStatisticsMath.h" +#include "RigSurface.h" +#include "RigTriangleMeshData.h" +#include "RimRegularLegendConfig.h" #include "RimSurfaceCollection.h" #include "RifSurfaceImporter.h" #include "RifVtkSurfaceImporter.h" -#include "RigGocadData.h" -#include "RigSurface.h" - -#include "cafPdmFieldScriptingCapability.h" #include "cafPdmObjectScriptingCapability.h" -#include -#include - CAF_PDM_SOURCE_INIT( RimFractureSurface, "RimFractureSurface" ); //-------------------------------------------------------------------------------------------------- @@ -108,14 +104,14 @@ void RimFractureSurface::loadSurfaceDataForTimeStep( int timeStep ) auto surface = new RigSurface; - auto gocadData = m_surfacePerTimeStep[timeStep]; - const auto& [coordinates, indices] = gocadData.gocadGeometry(); + auto triangleMeshData = m_surfacePerTimeStep[timeStep].get(); + const auto& [coordinates, indices] = triangleMeshData->geometry(); surface->setTriangleData( indices, coordinates ); - auto propertyNames = gocadData.propertyNames(); + auto propertyNames = triangleMeshData->propertyNames(); for ( const auto& name : propertyNames ) { - auto values = gocadData.propertyValues( name ); + auto values = triangleMeshData->propertyValues( name ); surface->addVerticeResult( name, values ); } setSurfaceData( surface ); @@ -127,11 +123,11 @@ void RimFractureSurface::loadSurfaceDataForTimeStep( int timeStep ) std::vector> RimFractureSurface::valuesForProperty( const QString& propertyName ) const { std::vector> values; - for ( auto allTimeStepValues : m_surfacePerTimeStep ) + for ( const auto& allTimeStepValues : m_surfacePerTimeStep ) { - const auto& [coordinates, indices] = allTimeStepValues.gocadGeometry(); + const auto& [coordinates, indices] = allTimeStepValues->geometry(); - auto valuesOneTimeStep = allTimeStepValues.propertyValues( propertyName ); + auto valuesOneTimeStep = allTimeStepValues->propertyValues( propertyName ); // convert to double vector std::vector valuesOneTimeStepDouble( valuesOneTimeStep.begin(), valuesOneTimeStep.end() ); @@ -178,11 +174,6 @@ void RimFractureSurface::clearCachedNativeData() { m_secondsSinceSimulationStart.clear(); m_surfacePerTimeStep.clear(); - - /* - m_vertices.clear(); - m_tringleIndices.clear(); - */ } //-------------------------------------------------------------------------------------------------- @@ -190,17 +181,61 @@ void RimFractureSurface::clearCachedNativeData() //-------------------------------------------------------------------------------------------------- bool RimFractureSurface::loadDataFromFile() { - auto surfaceInfo = RifVtkSurfaceImporter::parsePvdDatasets( m_surfaceDefinitionFilePath().path().toStdString() ); + std::filesystem::path filepath = m_surfaceDefinitionFilePath().path().toLocal8Bit().constData(); + auto surfaceInfo = RifVtkSurfaceImporter::parsePvdDatasets( filepath ); for ( const auto& s : surfaceInfo ) { - RigGocadData gocadData; - if ( RifVtkSurfaceImporter::importFromFile( s.filename, &gocadData ) ) + if ( auto triangleMeshData = RifVtkSurfaceImporter::importFromFile( s.filepath ) ) { m_secondsSinceSimulationStart.push_back( s.timestep ); - m_surfacePerTimeStep.push_back( gocadData ); + m_surfacePerTimeStep.push_back( std::move( triangleMeshData ) ); } } return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureSurface::updateMinMaxValues( RimRegularLegendConfig* legendConfig, const QString& propertyName, int currentTimeStep ) const +{ + double localMin = 0.0; + double localMax = 0.0; + double localPosClosestToZero = 0.0; + double localNegClosestToZero = 0.0; + + auto valuesForTimeSteps = valuesForProperty( propertyName ); + + MinMaxAccumulator minMaxAccumulator; + PosNegAccumulator posNegAccumulator; + + for ( size_t timeIndex = 0; timeIndex < valuesForTimeSteps.size(); timeIndex++ ) + { + auto values = valuesForTimeSteps[timeIndex]; + minMaxAccumulator.addData( values ); + posNegAccumulator.addData( values ); + + if ( static_cast( timeIndex ) == currentTimeStep ) + { + MinMaxAccumulator localMinMaxAccumulator; + PosNegAccumulator localPosNegAccumulator; + localMinMaxAccumulator.addData( values ); + localPosNegAccumulator.addData( values ); + + localPosClosestToZero = localPosNegAccumulator.pos; + localNegClosestToZero = localPosNegAccumulator.neg; + localMin = localMinMaxAccumulator.min; + localMax = localMinMaxAccumulator.max; + } + } + + double globalPosClosestToZero = posNegAccumulator.pos; + double globalNegClosestToZero = posNegAccumulator.neg; + double globalMin = minMaxAccumulator.min; + double globalMax = minMaxAccumulator.max; + + legendConfig->setClosestToZeroValues( globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero ); + legendConfig->setAutomaticRanges( globalMin, globalMax, localMin, localMax ); +} diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.h b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.h index ab25a3339b..1a6e8ad807 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.h +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimFractureSurface.h @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2020- Equinor ASA +// Copyright (C) 2025- Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,10 +20,7 @@ #include "RimSurface.h" -#include "cafPdmChildArrayField.h" - -class RimFileSurface; -class RigGocadData; +class RigTriangleMeshData; class RimFractureSurface : public RimSurface { @@ -43,6 +40,8 @@ public: std::vector> valuesForProperty( const QString& propertyName ) const; + void updateMinMaxValues( RimRegularLegendConfig* legend, const QString& propertyName, int currentTimeStep ) const override; + protected: bool updateSurfaceData() override; void clearCachedNativeData() override; @@ -55,6 +54,6 @@ private: caf::PdmField m_surfaceDefinitionFilePath; - std::vector m_secondsSinceSimulationStart; - std::vector m_surfacePerTimeStep; + std::vector m_secondsSinceSimulationStart; + std::vector> m_surfacePerTimeStep; }; diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.cpp b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.cpp index b5244177f5..9828cd3407 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.cpp +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.cpp @@ -19,14 +19,15 @@ #include "RimSurface.h" #include "RiaApplication.h" + #include "RimCase.h" #include "RimProject.h" +#include "RimRegularLegendConfig.h" #include "RimSurfaceCollection.h" +#include "RigStatisticsMath.h" #include "RigSurface.h" -#include "RifSurfaceImporter.h" - #include "cafPdmFieldScriptingCapability.h" #include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiDoubleSliderEditor.h" @@ -322,3 +323,27 @@ void RimSurface::defineEditorAttribute( const caf::PdmFieldHandle* field, QStrin } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSurface::updateMinMaxValues( RimRegularLegendConfig* legend, const QString& propertyName, int currentTimeStep ) const +{ + if ( !m_surfaceData.isNull() ) + { + MinMaxAccumulator minMaxAccumulator; + PosNegAccumulator posNegAccumulator; + + auto values = m_surfaceData->propertyValues( propertyName ); + minMaxAccumulator.addData( values ); + posNegAccumulator.addData( values ); + + double globalPosClosestToZero = posNegAccumulator.pos; + double globalNegClosestToZero = posNegAccumulator.neg; + double globalMin = minMaxAccumulator.min; + double globalMax = minMaxAccumulator.max; + + legend->setClosestToZeroValues( globalPosClosestToZero, globalNegClosestToZero, globalPosClosestToZero, globalNegClosestToZero ); + legend->setAutomaticRanges( globalMin, globalMax, globalMin, globalMax ); + } +} diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.h b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.h index 0385fc43ad..db9a615ec8 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.h +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurface.h @@ -28,6 +28,7 @@ #include +class RimRegularLegendConfig; class RigSurface; class RimSurface : public caf::PdmObject @@ -68,6 +69,8 @@ public: void loadDataIfRequired(); void reloadData(); + virtual void updateMinMaxValues( RimRegularLegendConfig* legend, const QString& propertyName, int currentTimeStep ) const; + protected: void setSurfaceData( RigSurface* surface ); diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.cpp b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.cpp index cb6fd90f7d..7841b0b5f6 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.cpp +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.cpp @@ -18,14 +18,11 @@ #include "RimSurfaceResultDefinition.h" -#include "RiaDefines.h" #include "RiaResultNames.h" -#include "RigStatisticsMath.h" #include "RigSurface.h" #include "Rim3dView.h" -#include "RimFractureSurface.h" #include "RimRegularLegendConfig.h" #include "RimSurface.h" #include "RimSurfaceInView.h" @@ -90,82 +87,11 @@ RimRegularLegendConfig* RimSurfaceResultDefinition::legendConfig() //-------------------------------------------------------------------------------------------------- void RimSurfaceResultDefinition::updateMinMaxValues( int currentTimeStep ) { + if ( !m_surfaceInView ) return; + if ( currentTimeStep < 0 ) currentTimeStep = 0; - // TODO: This is a hack, we need to find a better way to handle time dependent data for a surface - if ( auto fractureSurface = dynamic_cast( m_surfaceInView->surface() ) ) - { - double localMin = 0.0; - double localMax = 0.0; - double localPosClosestToZero = 0.0; - double localNegClosestToZero = 0.0; - double globalMin = 0.0; - double globalMax = 0.0; - double globalPosClosestToZero = 0.0; - double globalNegClosestToZero = 0.0; - - auto valuesForTimeSteps = fractureSurface->valuesForProperty( m_propertyName ); - - MinMaxAccumulator minMaxAccumulator; - PosNegAccumulator posNegAccumulator; - - for ( size_t timeIndex = 0; timeIndex < valuesForTimeSteps.size(); timeIndex++ ) - { - auto values = valuesForTimeSteps[timeIndex]; - minMaxAccumulator.addData( values ); - posNegAccumulator.addData( values ); - - if ( static_cast( timeIndex ) == currentTimeStep ) - { - MinMaxAccumulator localMinMaxAccumulator; - PosNegAccumulator localPosNegAccumulator; - localMinMaxAccumulator.addData( values ); - localPosNegAccumulator.addData( values ); - - localPosClosestToZero = localPosNegAccumulator.pos; - localNegClosestToZero = localPosNegAccumulator.neg; - localMin = localMinMaxAccumulator.min; - localMax = localMinMaxAccumulator.max; - } - } - - globalPosClosestToZero = posNegAccumulator.pos; - globalNegClosestToZero = posNegAccumulator.neg; - globalMin = minMaxAccumulator.min; - globalMax = minMaxAccumulator.max; - - m_legendConfig->setClosestToZeroValues( globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero ); - m_legendConfig->setAutomaticRanges( globalMin, globalMax, localMin, localMax ); - - return; - } - - RigSurface* surfData = surfaceData(); - if ( surfData ) - { - double globalMin = 0.0; - double globalMax = 0.0; - double globalPosClosestToZero = 0.0; - double globalNegClosestToZero = 0.0; - - { - MinMaxAccumulator minMaxAccumulator; - PosNegAccumulator posNegAccumulator; - - auto values = surfData->propertyValues( m_propertyName ); - minMaxAccumulator.addData( values ); - posNegAccumulator.addData( values ); - - globalPosClosestToZero = posNegAccumulator.pos; - globalNegClosestToZero = posNegAccumulator.neg; - globalMin = minMaxAccumulator.min; - globalMax = minMaxAccumulator.max; - } - - m_legendConfig->setClosestToZeroValues( globalPosClosestToZero, globalNegClosestToZero, globalPosClosestToZero, globalNegClosestToZero ); - - m_legendConfig->setAutomaticRanges( globalMin, globalMax, globalMin, globalMax ); - } + if ( auto surface = m_surfaceInView->surface() ) surface->updateMinMaxValues( m_legendConfig, m_propertyName, currentTimeStep ); } //-------------------------------------------------------------------------------------------------- @@ -173,12 +99,12 @@ void RimSurfaceResultDefinition::updateMinMaxValues( int currentTimeStep ) //-------------------------------------------------------------------------------------------------- void RimSurfaceResultDefinition::assignDefaultProperty() { - if ( m_surfaceInView->surface() && m_surfaceInView->surface()->surfaceData() ) + if ( auto surface = surfaceData() ) { - auto propNames = m_surfaceInView->surface()->surfaceData()->propertyNames(); + auto propNames = surface->propertyNames(); if ( !propNames.empty() ) { - m_propertyName = m_surfaceInView->surface()->surfaceData()->propertyNames().front(); + m_propertyName = propNames.front(); } } } diff --git a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.h b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.h index 3fae4a405a..7c59e61e71 100644 --- a/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.h +++ b/ApplicationLibCode/ProjectDataModel/Surfaces/RimSurfaceResultDefinition.h @@ -24,8 +24,6 @@ #include "cafPdmObject.h" #include "cafPdmPtrField.h" -#include "cvfObject.h" - class RimRegularLegendConfig; class RimSurfaceInView; class RigSurface; diff --git a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake index fe6706bed5..39aca84d77 100644 --- a/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ReservoirDataModel/CMakeLists_files.cmake @@ -41,7 +41,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RigFractureCell.h ${CMAKE_CURRENT_LIST_DIR}/RigFractureGrid.h ${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.h - ${CMAKE_CURRENT_LIST_DIR}/RigGocadData.h + ${CMAKE_CURRENT_LIST_DIR}/RigTriangleMeshData.h ${CMAKE_CURRENT_LIST_DIR}/RigGridBase.h ${CMAKE_CURRENT_LIST_DIR}/RigGridCrossPlotCurveGrouping.h ${CMAKE_CURRENT_LIST_DIR}/RigGriddedPart3d.h @@ -124,7 +124,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RigFractureCell.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFractureGrid.cpp ${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.cpp - ${CMAKE_CURRENT_LIST_DIR}/RigGocadData.cpp + ${CMAKE_CURRENT_LIST_DIR}/RigTriangleMeshData.cpp ${CMAKE_CURRENT_LIST_DIR}/RigGridBase.cpp ${CMAKE_CURRENT_LIST_DIR}/RigGriddedPart3d.cpp ${CMAKE_CURRENT_LIST_DIR}/RigGridManager.cpp diff --git a/ApplicationLibCode/ReservoirDataModel/RigGocadData.cpp b/ApplicationLibCode/ReservoirDataModel/RigTriangleMeshData.cpp similarity index 80% rename from ApplicationLibCode/ReservoirDataModel/RigGocadData.cpp rename to ApplicationLibCode/ReservoirDataModel/RigTriangleMeshData.cpp index ba2fe06639..0b7501ce6e 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGocadData.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigTriangleMeshData.cpp @@ -16,26 +16,26 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RigGocadData.h" +#include "RigTriangleMeshData.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigGocadData::RigGocadData() +RigTriangleMeshData::RigTriangleMeshData() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigGocadData::~RigGocadData() +RigTriangleMeshData::~RigTriangleMeshData() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigGocadData::propertyNames() +std::vector RigTriangleMeshData::propertyNames() { return m_propertyNames; } @@ -43,7 +43,7 @@ std::vector RigGocadData::propertyNames() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair, std::vector> RigGocadData::gocadGeometry() +std::pair, std::vector> RigTriangleMeshData::geometry() { return std::make_pair( m_vertices, m_tringleIndices ); } @@ -51,7 +51,7 @@ std::pair, std::vector> RigGocadData::gocadGeo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigGocadData::propertyValues( const QString& property ) +std::vector RigTriangleMeshData::propertyValues( const QString& property ) { for ( size_t propertyIdx = 0; propertyIdx < m_propertyNames.size(); propertyIdx++ ) { @@ -67,7 +67,7 @@ std::vector RigGocadData::propertyValues( const QString& property ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigGocadData::setGeometryData( const std::vector& nodeCoord, const std::vector& connectivities ) +void RigTriangleMeshData::setGeometryData( const std::vector& nodeCoord, const std::vector& connectivities ) { m_vertices = nodeCoord; m_tringleIndices = connectivities; @@ -76,7 +76,7 @@ void RigGocadData::setGeometryData( const std::vector& nodeCoord, co //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigGocadData::setPropertyData( const std::vector& propertyNames, std::vector>& propertyValues ) +void RigTriangleMeshData::setPropertyData( const std::vector& propertyNames, std::vector>& propertyValues ) { m_propertyNames = propertyNames; m_propertyValues = propertyValues; @@ -85,7 +85,7 @@ void RigGocadData::setPropertyData( const std::vector& propertyNames, s //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigGocadData::addPropertyData( const QString& propertyName, std::vector& propertyValues ) +void RigTriangleMeshData::addPropertyData( const QString& propertyName, std::vector& propertyValues ) { m_propertyNames.push_back( propertyName ); m_propertyValues.push_back( propertyValues ); diff --git a/ApplicationLibCode/ReservoirDataModel/RigGocadData.h b/ApplicationLibCode/ReservoirDataModel/RigTriangleMeshData.h similarity index 91% rename from ApplicationLibCode/ReservoirDataModel/RigGocadData.h rename to ApplicationLibCode/ReservoirDataModel/RigTriangleMeshData.h index ff1aa593af..0467e3ef6e 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigGocadData.h +++ b/ApplicationLibCode/ReservoirDataModel/RigTriangleMeshData.h @@ -23,14 +23,14 @@ #include "cvfVector3.h" -class RigGocadData +class RigTriangleMeshData { public: - RigGocadData(); - ~RigGocadData(); + RigTriangleMeshData(); + ~RigTriangleMeshData(); std::vector propertyNames(); - std::pair, std::vector> gocadGeometry(); + std::pair, std::vector> geometry(); std::vector propertyValues( const QString& property ); void setGeometryData( const std::vector& nodeCoord, const std::vector& connectivities ); diff --git a/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp b/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp index 5b23f12d26..11d696e78c 100644 --- a/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp +++ b/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp @@ -3,7 +3,7 @@ #include "RifSurfaceImporter.h" #include "RiaTestDataDirectory.h" -#include "RigGocadData.h" +#include "RigTriangleMeshData.h" #include "QDir" #include @@ -17,10 +17,10 @@ TEST( RifSurfaceImporter, GocadReadValidFile ) QString filePath = baseFolder.absoluteFilePath( filename ); EXPECT_TRUE( QFile::exists( filePath ) ); - RigGocadData gocadData; - RifSurfaceImporter::readGocadFile( filePath, &gocadData ); + RigTriangleMeshData triangleMeshData; + RifSurfaceImporter::readGocadFile( filePath, &triangleMeshData ); - auto surface = gocadData.gocadGeometry(); + auto surface = triangleMeshData.geometry(); auto vertices = surface.first; auto indices = surface.second; @@ -39,10 +39,10 @@ TEST( RifSurfaceImporter, GocadReadWrongIndices ) QString filePath = baseFolder.absoluteFilePath( filename ); EXPECT_TRUE( QFile::exists( filePath ) ); - RigGocadData gocadData; - RifSurfaceImporter::readGocadFile( filePath, &gocadData ); + RigTriangleMeshData triangleMeshData; + RifSurfaceImporter::readGocadFile( filePath, &triangleMeshData ); - auto surface = gocadData.gocadGeometry(); + auto surface = triangleMeshData.geometry(); auto vertices = surface.first; auto indices = surface.second; @@ -58,19 +58,19 @@ TEST( RifSurfaceImporter, GocadReadProperties ) QString filePath = baseFolder.absoluteFilePath( filename ); EXPECT_TRUE( QFile::exists( filePath ) ); - RigGocadData gocadData; - RifSurfaceImporter::readGocadFile( filePath, &gocadData ); + RigTriangleMeshData triangleMeshData; + RifSurfaceImporter::readGocadFile( filePath, &triangleMeshData ); - auto surface = gocadData.gocadGeometry(); + auto surface = triangleMeshData.geometry(); auto vertices = surface.first; auto indices = surface.second; - std::vector propNames = gocadData.propertyNames(); + std::vector propNames = triangleMeshData.propertyNames(); EXPECT_TRUE( propNames.size() == 3 ); EXPECT_TRUE( propNames[0] == "SX" ); - std::vector propValues_SX = gocadData.propertyValues( propNames[0] ); + std::vector propValues_SX = triangleMeshData.propertyValues( propNames[0] ); float SX_first = propValues_SX[0]; float SX_second = propValues_SX[1]; @@ -80,7 +80,7 @@ TEST( RifSurfaceImporter, GocadReadProperties ) EXPECT_NEAR( 0.000972, SX_second, 1e-4 ); EXPECT_NEAR( 0.004293, SX_last, 1e-4 ); - std::vector propValues_SY = gocadData.propertyValues( "SY" ); + std::vector propValues_SY = triangleMeshData.propertyValues( "SY" ); float SY_first = propValues_SY[0]; float SY_second = propValues_SY[1]; @@ -99,11 +99,11 @@ TEST( RifSurfaceImporter, GocadReadNoProperty ) QString filePath = baseFolder.absoluteFilePath( filename ); EXPECT_TRUE( QFile::exists( filePath ) ); - RigGocadData gocadData; - RifSurfaceImporter::readGocadFile( filePath, &gocadData ); + RigTriangleMeshData triangleMeshData; + RifSurfaceImporter::readGocadFile( filePath, &triangleMeshData ); - std::vector propNames = gocadData.propertyNames(); - std::vector propValues = gocadData.propertyValues( "" ); + std::vector propNames = triangleMeshData.propertyNames(); + std::vector propValues = triangleMeshData.propertyValues( "" ); EXPECT_TRUE( propNames.empty() ); EXPECT_TRUE( propValues.empty() ); @@ -117,10 +117,10 @@ TEST( RifSurfaceImporter, GocadReadNonExistingProperty ) QString filePath = baseFolder.absoluteFilePath( filename ); EXPECT_TRUE( QFile::exists( filePath ) ); - RigGocadData gocadData; - RifSurfaceImporter::readGocadFile( filePath, &gocadData ); + RigTriangleMeshData triangleMeshData; + RifSurfaceImporter::readGocadFile( filePath, &triangleMeshData ); - std::vector propValues = gocadData.propertyValues( "NonExistingProperty" ); + std::vector propValues = triangleMeshData.propertyValues( "NonExistingProperty" ); EXPECT_TRUE( propValues.empty() ); } @@ -134,10 +134,10 @@ TEST( RifSurfaceImporter, ReadWrongFileType ) QString filePath = baseFolder.absoluteFilePath( filename ); EXPECT_TRUE( QFile::exists( filePath ) ); - RigGocadData gocadData; - RifSurfaceImporter::readGocadFile( filePath, &gocadData ); + RigTriangleMeshData triangleMeshData; + RifSurfaceImporter::readGocadFile( filePath, &triangleMeshData ); - auto surface = gocadData.gocadGeometry(); + auto surface = triangleMeshData.geometry(); auto vertices = surface.first; auto indices = surface.second; diff --git a/CMakeLists.txt b/CMakeLists.txt index 83a2655ac8..df5527e723 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -717,6 +717,16 @@ else() list(APPEND THIRD_PARTY_LIBRARIES Parquet::parquet_static) endif() +# ############################################################################## +# pugixml +# ############################################################################## +find_package(pugixml CONFIG REQUIRED) +if(MSVC) + list(APPEND THIRD_PARTY_LIBRARIES pugixml::pugixml) +else() + list(APPEND THIRD_PARTY_LIBRARIES pugixml::static) +endif() + # ############################################################################## # nonstd::type-lite # ############################################################################## diff --git a/vcpkg.json b/vcpkg.json index 23ef9faf66..c47ca375d4 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -8,7 +8,8 @@ "grpc", "type-lite", "fast-float", - "spdlog" + "spdlog", + "pugixml" ], "overrides": [ {