From a18728b6e702be4511735e9e766650271f226092 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 12 Dec 2024 14:06:19 +0100 Subject: [PATCH 1/5] #11989 Check indices before accessing two-dimensional vector --- .../FileInterface/RifSurfaceImporter.cpp | 30 ++++++--- .../FileInterface/RifSurfaceImporter.h | 3 +- .../UnitTests/RifSurfaceImporter-Test.cpp | 64 +++++++++++++++++++ 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp b/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp index 0982f47799..6e107645e8 100644 --- a/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp +++ b/ApplicationLibCode/FileInterface/RifSurfaceImporter.cpp @@ -600,17 +600,33 @@ bool RifSurfaceImporter::generateTriangleIndices( const std::vector& triangleIndices, unsigned resolution /*= 1 */ ) { + if ( i >= indexToPointData.size() || j >= indexToPointData[i].size() ) + { + return false; + } + unsigned topI = unsigned( std::min( indexToPointData.size() - 1, i + resolution ) ); + if ( topI >= indexToPointData.size() ) + { + return false; + } + unsigned topJ = unsigned( std::min( indexToPointData[topI].size() - 1, j + resolution ) ); + if ( topJ >= indexToPointData[topI].size() || topJ >= indexToPointData[i].size() ) + { + return false; + } + // Prevent degenerate cases if ( topI == i || topJ == j ) return false; - unsigned q1 = indexToPointData[i + 0][j + 0]; - unsigned q2 = indexToPointData[i + 0][topJ]; - unsigned q3 = indexToPointData[topI][j + 0]; + unsigned q1 = indexToPointData[i][j]; + unsigned q2 = indexToPointData[i][topJ]; + unsigned q3 = indexToPointData[topI][j]; unsigned q4 = indexToPointData[topI][topJ]; - if ( q1 != ( (unsigned)-1 ) && q2 != ( (unsigned)-1 ) && q3 != ( (unsigned)-1 ) && q4 != ( (unsigned)-1 ) ) + const auto invalidIndex = static_cast( -1 ); + if ( q1 != invalidIndex && q2 != invalidIndex && q3 != invalidIndex && q4 != invalidIndex ) { triangleIndices.push_back( q1 ); triangleIndices.push_back( q2 ); @@ -620,10 +636,8 @@ bool RifSurfaceImporter::generateTriangleIndices( const std::vector, std::vector> readOpenWorksXyzFile( const QString& filename, double preferredPointDistance ); -private: static bool generateTriangleIndices( const std::vector>& indexToPointData, const size_t& i, const size_t& j, std::vector& triangleIndices, unsigned resolution = 1 ); + +private: static bool vectorFuzzyCompare( const cvf::Vec2d& vector1, const cvf::Vec2d& vector2, double epsilon = std::numeric_limits::epsilon() ); }; diff --git a/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp b/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp index 259630e40b..27b823d7f0 100644 --- a/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp +++ b/ApplicationLibCode/UnitTests/RifSurfaceImporter-Test.cpp @@ -260,3 +260,67 @@ TEST( RifSurfaceImporter, ReadLargeOpenWorksXyzFile ) } } } + +// Test fixture for RifSurfaceImporter +class RifSurfaceImporterTest : public ::testing::Test +{ +protected: + RifSurfaceImporter rifSurfaceImporter; + std::vector> indexToPointData; + std::vector triangleIndices; +}; + +TEST_F( RifSurfaceImporterTest, HandlesEmptyInput ) +{ + // Empty indexToPointData + indexToPointData = {}; + EXPECT_FALSE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 0, 0, triangleIndices ) ); + EXPECT_TRUE( triangleIndices.empty() ); +} + +TEST_F( RifSurfaceImporterTest, HandlesOutOfBoundsInput ) +{ + // Non-empty indexToPointData but invalid indices + indexToPointData = { { 0, 1 }, { 2, 3 } }; + EXPECT_FALSE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 2, 0, triangleIndices ) ); + EXPECT_FALSE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 0, 2, triangleIndices ) ); + EXPECT_TRUE( triangleIndices.empty() ); +} + +TEST_F( RifSurfaceImporterTest, HandlesSingleResolution ) +{ + // Valid input with resolution 1 + indexToPointData = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; + EXPECT_TRUE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 0, 0, triangleIndices, 1 ) ); + + // Check expected triangle indices + std::vector expected = { 0, 1, 4, 0, 4, 3 }; + EXPECT_EQ( triangleIndices, expected ); +} + +TEST_F( RifSurfaceImporterTest, HandlesLargerResolution ) +{ + // Valid input with larger resolution + indexToPointData = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; + EXPECT_TRUE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 0, 0, triangleIndices, 2 ) ); + + // Check expected triangle indices + std::vector expected = { 0, 2, 8, 0, 8, 6 }; + EXPECT_EQ( triangleIndices, expected ); +} + +TEST_F( RifSurfaceImporterTest, HandlesInvalidPoints ) +{ + // Input with invalid points (-1 as unsigned max value) + indexToPointData = { { 0, 1, 2 }, { 3, (unsigned)-1, 5 }, { 6, 7, 8 } }; + EXPECT_FALSE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 0, 1, triangleIndices ) ); + EXPECT_TRUE( triangleIndices.empty() ); +} + +TEST_F( RifSurfaceImporterTest, PreventsDegenerateTriangles ) +{ + // Degenerate case where resolution leads to topI == i or topJ == j + indexToPointData = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; + EXPECT_FALSE( rifSurfaceImporter.generateTriangleIndices( indexToPointData, 2, 2, triangleIndices, 1 ) ); + EXPECT_TRUE( triangleIndices.empty() ); +} From 37de8273272569316bf6ae8c8d0c2e58e3d6dbf0 Mon Sep 17 00:00:00 2001 From: jonjenssen Date: Fri, 13 Dec 2024 17:08:10 +0100 Subject: [PATCH 2/5] Rel perm plot legend adjustments --- .../RiuRelativePermeabilityPlotPanel.cpp | 55 ++++++++++++++++--- .../RiuRelativePermeabilityPlotPanel.h | 6 +- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp b/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp index 16b37542f2..0fde3bcf15 100644 --- a/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp +++ b/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp @@ -239,7 +239,7 @@ void RiuRelativePermeabilityPlotPanel::clearPlot() m_caseName.clear(); m_cellReferenceText.clear(); - plotCurvesInQwt( m_unitSystem, m_allCurvesArr, m_swat, m_sgas, m_cellReferenceText, false, true, true, m_qwtPlot, &m_myPlotMarkers, false ); + plotCurvesInQwt( m_unitSystem, m_allCurvesArr, m_swat, m_sgas, m_cellReferenceText, false, true, true, m_qwtPlot, &m_myPlotMarkers, false, false ); } //-------------------------------------------------------------------------------------------------- @@ -265,10 +265,9 @@ void RiuRelativePermeabilityPlotPanel::plotUiSelectedCurves() { std::vector selectedCurves = gatherUiSelectedCurves(); - const bool useLogScale = m_logarithmicScaleKrAxisCheckBox->isChecked(); - const bool fixedXAxis = m_fixedXAxisCheckBox->isChecked(); - const bool fixedYAxis = m_fixedLeftYAxisCheckBox->isChecked(); - const bool skipUnscaledLegend = m_showUnscaledCheckBox->isChecked() && m_showScaledCheckBox->isChecked(); + const bool useLogScale = m_logarithmicScaleKrAxisCheckBox->isChecked(); + const bool fixedXAxis = m_fixedXAxisCheckBox->isChecked(); + const bool fixedYAxis = m_fixedLeftYAxisCheckBox->isChecked(); plotCurvesInQwt( m_unitSystem, selectedCurves, m_swat, @@ -279,7 +278,8 @@ void RiuRelativePermeabilityPlotPanel::plotUiSelectedCurves() fixedYAxis, m_qwtPlot, &m_myPlotMarkers, - skipUnscaledLegend ); + m_showScaledCheckBox->isChecked(), + m_showUnscaledCheckBox->isChecked() ); } //-------------------------------------------------------------------------------------------------- @@ -342,8 +342,11 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS bool fixedLeftYAxis, QwtPlot* plot, std::vector* myPlotMarkers, - bool skipUnscaledLegends ) + bool showScaled, + bool showUnscaled ) { + bool skipUnscaledLegends = showScaled && showUnscaled; + plot->detachItems( QwtPlotItem::Rtti_PlotCurve ); // Workaround for detaching only plot markers that we have added @@ -421,7 +424,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS qwtCurve->setSymbol( curveSymbol ); qwtCurve->setLegendAttribute( QwtPlotCurve::LegendShowLine, true ); - qwtCurve->setLegendAttribute( QwtPlotCurve::LegendShowSymbol, true ); + qwtCurve->setLegendAttribute( QwtPlotCurve::LegendShowSymbol, false ); qwtCurve->setLegendAttribute( QwtPlotCurve::LegendShowBrush, true ); const bool showLegend = !( unscaledCurve && skipUnscaledLegends ); @@ -524,6 +527,18 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS plot->setAxisAutoScale( QwtAxis::YLeft, true ); } + if ( showScaled ) + { + QwtPlotCurve* curve = getLegendCurve( "Scaled", true /*scaled*/ ); + curve->attach( plot ); + } + + if ( showUnscaled ) + { + QwtPlotCurve* curve = getLegendCurve( "Unscaled", false /*scaled*/ ); + curve->attach( plot ); + } + QString titleStr = "Relative Permeability"; if ( !cellReferenceText.isEmpty() ) { @@ -537,6 +552,30 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt( RiaDefines::EclipseUnitS plot->replot(); } +QwtPlotCurve* RiuRelativePermeabilityPlotPanel::getLegendCurve( QString title, bool scaled ) +{ + QwtPlotCurve* curve = new QwtPlotCurve( title ); + + curve->setTitle( title ); + + curve->setStyle( QwtPlotCurve::Lines ); + + const QPen curvePen( QBrush(), 1, Qt::SolidLine ); + curve->setPen( curvePen ); + + auto* curveSymbol = scaled ? new RiuQwtSymbol( RiuPlotCurveSymbol::SYMBOL_ELLIPSE ) : new RiuQwtSymbol( RiuPlotCurveSymbol::SYMBOL_CROSS ); + curveSymbol->setSize( 6, 6 ); + curveSymbol->setBrush( QBrush() ); + curve->setSymbol( curveSymbol ); + + curve->setLegendAttribute( QwtPlotCurve::LegendShowLine, true ); + curve->setLegendAttribute( QwtPlotCurve::LegendShowSymbol, true ); + curve->setLegendAttribute( QwtPlotCurve::LegendShowBrush, false ); + curve->setItemAttribute( QwtPlotItem::Legend, true ); + + return curve; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.h b/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.h index 1c947085fd..5a7194ec2b 100644 --- a/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.h +++ b/ApplicationLibCode/UserInterface/RiuRelativePermeabilityPlotPanel.h @@ -32,6 +32,7 @@ class QButtonGroup; class QCheckBox; class QwtPlot; class QwtPlotMarker; +class QwtPlotCurve; class QPointF; class QGroupBox; @@ -88,7 +89,10 @@ class RiuRelativePermeabilityPlotPanel : public QWidget bool fixedLeftYAxis, QwtPlot* plot, std::vector* myPlotMarkers, - bool skipUnscaledLegends ); + bool showScaled, + bool showUnscaled ); + + static QwtPlotCurve* getLegendCurve( QString title, bool scaled ); static QString determineXAxisTitleFromCurveCollection( const std::vector& curveArr ); From e746e6b6374493744fb3f7b1d0171a7e18868d21 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Sat, 14 Dec 2024 13:17:57 +0100 Subject: [PATCH 3/5] Bump to 2024.12.1 --- ResInsightVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 648db53535..08c0ee4100 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,7 +1,7 @@ set(RESINSIGHT_MAJOR_VERSION 2024) set(RESINSIGHT_MINOR_VERSION 12) -set(RESINSIGHT_PATCH_VERSION 0) +set(RESINSIGHT_PATCH_VERSION 1) # Opional text with no restrictions #set(RESINSIGHT_VERSION_TEXT "-dev") From c32e669e569f38cc115f7b53858bbba0ca840691 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 16 Dec 2024 09:25:13 +0100 Subject: [PATCH 4/5] Bump to 2024.12.2-dev.01 --- ResInsightVersion.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 733f802169..43577b55be 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,7 +1,7 @@ set(RESINSIGHT_MAJOR_VERSION 2024) set(RESINSIGHT_MINOR_VERSION 12) -set(RESINSIGHT_PATCH_VERSION 1) +set(RESINSIGHT_PATCH_VERSION 2) # Opional text with no restrictions set(RESINSIGHT_VERSION_TEXT "-dev") @@ -11,7 +11,7 @@ set(RESINSIGHT_VERSION_TEXT "-dev") # Must be unique and increasing within one combination of major/minor/patch version # The uniqueness of this text is independent of RESINSIGHT_VERSION_TEXT # Format of text must be ".xx" -set(RESINSIGHT_DEV_VERSION ".02") +set(RESINSIGHT_DEV_VERSION ".01") # https://github.com/CRAVA/crava/tree/master/libs/nrlib set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f") From 6fea38e95b19ddb539a90e4a3e214192acd52244 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 16 Dec 2024 09:29:52 +0100 Subject: [PATCH 5/5] Reset RIPS_DIST_VERSION to 1 --- GrpcInterface/Python/setup.py.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GrpcInterface/Python/setup.py.cmake b/GrpcInterface/Python/setup.py.cmake index bd5f49adf5..8931ca8e89 100644 --- a/GrpcInterface/Python/setup.py.cmake +++ b/GrpcInterface/Python/setup.py.cmake @@ -6,7 +6,7 @@ with open('README.md') as f: with open('LICENSE') as f: license = f.read() -RIPS_DIST_VERSION = '3' +RIPS_DIST_VERSION = '1' setup( name='rips',