From 6c922068936220874b1eb244d4c2c11ee16d0c0e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 11 Feb 2022 13:18:36 +0100 Subject: [PATCH] Make curve drawing more robust (#8537) * Janitor : Improve robustness * Guard nullptr access * Limit the curve points to incoming from/to curve point index range Co-authored-by: magnesj --- .../Application/Tools/RiaWellLogUnitTools.inl | 14 +++++++++ .../RimGridTimeHistoryCurve.cpp | 2 +- .../UserInterface/RiuQwtPlotCurve.cpp | 31 +++++++++---------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/ApplicationLibCode/Application/Tools/RiaWellLogUnitTools.inl b/ApplicationLibCode/Application/Tools/RiaWellLogUnitTools.inl index 97e0893743..45c345ca30 100644 --- a/ApplicationLibCode/Application/Tools/RiaWellLogUnitTools.inl +++ b/ApplicationLibCode/Application/Tools/RiaWellLogUnitTools.inl @@ -178,6 +178,8 @@ std::vector> RiaDefines::DepthUnitType unitsIn, RiaDefines::DepthUnitType unitsOut ) { + if ( depthsIn.empty() ) return {}; + std::vector> convertedDepths( depthsIn.size() ); double factor = 1.0; if ( unitsOut == RiaDefines::DepthUnitType::UNIT_METER && unitsIn == RiaDefines::DepthUnitType::UNIT_FEET ) @@ -335,6 +337,8 @@ template std::vector RiaWellLogUnitTools::tvdRKBs( const std::vector& measuredDepths, const RigWellPath* wellPath ) { + if ( measuredDepths.empty() ) return {}; + std::vector tvdRKBs( measuredDepths.size(), 0.0 ); for ( size_t i = 0; i < measuredDepths.size(); ++i ) { @@ -351,6 +355,8 @@ template std::vector RiaWellLogUnitTools::convertGpcm3ToBar( const std::vector& tvdRKBs, const std::vector& valuesInGpcm3 ) { + if ( tvdRKBs.empty() ) return {}; + CAF_ASSERT( tvdRKBs.size() == valuesInGpcm3.size() ); std::vector valuesInBar( valuesInGpcm3.size(), 0.0 ); @@ -378,6 +384,8 @@ template std::vector RiaWellLogUnitTools::convertBarToGpcm3( const std::vector& tvdRKBs, const std::vector& valuesInBar ) { + if ( tvdRKBs.empty() ) return {}; + CAF_ASSERT( tvdRKBs.size() == valuesInBar.size() ); std::vector valuesInGpcm3( valuesInBar.size(), 0.0 ); @@ -406,6 +414,8 @@ std::vector RiaWellLogUnitTools::convertNormalizedByPPToBar( const std::vector& tvdRKBs, const std::vector& normalizedValues ) { + if ( tvdRKBs.empty() ) return {}; + CAF_ASSERT( tvdRKBs.size() == normalizedValues.size() ); std::vector valuesInBar( tvdRKBs.size(), 0.0 ); @@ -424,6 +434,8 @@ std::vector RiaWellLogUnitTools::convertBarToNormalizedByPP( const std::vector& tvdRKBs, const std::vector& valuesInBar ) { + if ( tvdRKBs.empty() ) return {}; + CAF_ASSERT( tvdRKBs.size() == valuesInBar.size() ); std::vector normalizedValues( tvdRKBs.size(), 0.0 ); @@ -440,6 +452,8 @@ std::vector template std::vector RiaWellLogUnitTools::multiply( const std::vector& valuesIn, FloatType factor ) { + if ( valuesIn.empty() ) return {}; + std::vector valuesOut( valuesIn.size(), std::numeric_limits::infinity() ); for ( size_t i = 0; i < valuesIn.size(); ++i ) { diff --git a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp index 0dd04af733..654b6e88f9 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp @@ -388,7 +388,7 @@ void RimGridTimeHistoryCurve::onLoadDataAndUpdate( bool updateParentPlot ) { this->RimPlotCurve::updateCurvePresentation( updateParentPlot ); - if ( isCurveVisible() ) + if ( isCurveVisible() && m_plotCurve ) { std::vector values; diff --git a/ApplicationLibCode/UserInterface/RiuQwtPlotCurve.cpp b/ApplicationLibCode/UserInterface/RiuQwtPlotCurve.cpp index 56bd6311dc..fbc9ac951c 100644 --- a/ApplicationLibCode/UserInterface/RiuQwtPlotCurve.cpp +++ b/ApplicationLibCode/UserInterface/RiuQwtPlotCurve.cpp @@ -93,9 +93,17 @@ void RiuQwtPlotCurve::drawCurve( QPainter* p, size_t intervalCount = m_polyLineStartStopIndices.size(); if ( intervalCount > 0 ) { - for ( size_t intIdx = 0; intIdx < intervalCount; intIdx++ ) + for ( const auto& [segmentFromCandiate, segmentToCandidate] : m_polyLineStartStopIndices ) { - if ( m_polyLineStartStopIndices[intIdx].first == m_polyLineStartStopIndices[intIdx].second ) + // Skip segments outside the requested index range + if ( static_cast( segmentToCandidate ) < from ) continue; + if ( static_cast( segmentFromCandiate ) > to ) continue; + + // Draw the curve points limited to incoming from/to indices + auto actualFromIndex = std::max( from, static_cast( segmentFromCandiate ) ); + auto actualToIndex = std::min( to, static_cast( segmentToCandidate ) ); + + if ( actualFromIndex == actualToIndex ) { // Use a symbol to draw a single value, as a single value will not be visible // when using QwtPlotCurve::drawCurve without symbols activated @@ -103,23 +111,14 @@ void RiuQwtPlotCurve::drawCurve( QPainter* p, QwtSymbol symbol( QwtSymbol::XCross ); symbol.setSize( 10, 10 ); - QwtPlotCurve::drawSymbols( p, - symbol, - xMap, - yMap, - canvasRect, - (int)m_polyLineStartStopIndices[intIdx].first, - (int)m_polyLineStartStopIndices[intIdx].second ); + QwtPlotCurve::drawSymbols( p, symbol, xMap, yMap, canvasRect, actualFromIndex, actualToIndex ); } else { - QwtPlotCurve::drawCurve( p, - style, - xMap, - yMap, - canvasRect, - (int)m_polyLineStartStopIndices[intIdx].first, - (int)m_polyLineStartStopIndices[intIdx].second ); + if ( actualFromIndex < actualToIndex ) + { + QwtPlotCurve::drawCurve( p, style, xMap, yMap, canvasRect, actualFromIndex, actualToIndex ); + } } } }