From 85abd0c51b92a3e4ee695d49977b5391b8b6cc88 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 24 Feb 2025 14:20:13 +0100 Subject: [PATCH] #12181 Grid Cell Curve: Allow stacking of grid cell curves in summary plot * Add stacking to grid cell curves in summary plot * Add spacing in label text "Cell I J K" * Add padlock icons and do not delete locked curves * Show padlock icons only when summary plot is automated --- ApplicationExeCode/Resources/ResInsight.qrc | 1 + .../Resources/padlock-unlocked.svg | 10 ++ ApplicationExeCode/Resources/padlock.svg | 19 +-- .../RicNewGridTimeHistoryCurveFeature.cpp | 5 + .../RimEclipseGeometrySelectionItem.cpp | 2 +- .../RimGridTimeHistoryCurve.cpp | 101 ++++++++++-- .../RimGridTimeHistoryCurve.h | 16 +- .../ProjectDataModel/RimPlotCurve.h | 4 +- .../ProjectDataModel/RimTools.cpp | 8 + .../ProjectDataModel/RimTools.h | 6 +- .../Summary/RimSummaryPlot.cpp | 156 ++++++++++-------- .../ProjectDataModel/Summary/RimSummaryPlot.h | 9 +- .../Tools/RimAutomationSettings.cpp | 8 + .../Tools/RimAutomationSettings.h | 2 + .../WellLog/RimWellLogTrack.cpp | 2 + .../RiuSelectionChangedHandler.cpp | 8 +- 16 files changed, 247 insertions(+), 110 deletions(-) create mode 100644 ApplicationExeCode/Resources/padlock-unlocked.svg diff --git a/ApplicationExeCode/Resources/ResInsight.qrc b/ApplicationExeCode/Resources/ResInsight.qrc index 5c13fc23ba7..27f80da905c 100644 --- a/ApplicationExeCode/Resources/ResInsight.qrc +++ b/ApplicationExeCode/Resources/ResInsight.qrc @@ -286,6 +286,7 @@ decline-curve.svg regression-curve.svg padlock.svg + padlock-unlocked.svg warning.svg cloud-and-server.svg Cloud.svg diff --git a/ApplicationExeCode/Resources/padlock-unlocked.svg b/ApplicationExeCode/Resources/padlock-unlocked.svg new file mode 100644 index 00000000000..5d485726277 --- /dev/null +++ b/ApplicationExeCode/Resources/padlock-unlocked.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/ApplicationExeCode/Resources/padlock.svg b/ApplicationExeCode/Resources/padlock.svg index 5009f6cebf8..2fe5d5b683b 100644 --- a/ApplicationExeCode/Resources/padlock.svg +++ b/ApplicationExeCode/Resources/padlock.svg @@ -1,11 +1,10 @@ - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.cpp index 0e4232055bb..69d437e69f6 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.cpp @@ -39,6 +39,8 @@ #include "RimSummaryMultiPlot.h" #include "RimSummaryMultiPlotCollection.h" #include "RimSummaryPlot.h" +#include "RimTools.h" +#include "Tools/RimAutomationSettings.h" #include "Riu3dSelectionManager.h" #include "RiuPlotMainWindowTools.h" @@ -123,6 +125,9 @@ RimSummaryPlot* RicNewGridTimeHistoryCurveFeature::userSelectedSummaryPlot() QString refFromProjectToView = caf::PdmReferenceHelper::referenceFromRootToObject( app->project(), summaryPlot ); app->setCacheDataObject( lastUsedSummaryPlotKey, refFromProjectToView ); + auto automationSettings = RimTools::automationSettings(); + automationSettings->setDestinationPlot( summaryPlot ); + return summaryPlot; } diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp index 78eb66d2d92..0884d4cc6b7 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp @@ -44,7 +44,7 @@ RimEclipseGeometrySelectionItem::RimEclipseGeometrySelectionItem() CAF_PDM_InitFieldNoDefault( &m_gridIndex, "GridIndex", "Grid Index" ); CAF_PDM_InitFieldNoDefault( &m_cellIndex, "CellIndex", "Cell Index" ); - CAF_PDM_InitFieldNoDefault( &m_ijkText, "CellText", "IJK" ); + CAF_PDM_InitFieldNoDefault( &m_ijkText, "CellText", "Cell I J K" ); m_ijkText.registerGetMethod( this, &RimEclipseGeometrySelectionItem::ijkTextFromCell ); m_ijkText.registerSetMethod( this, &RimEclipseGeometrySelectionItem::setCellFromIjkText ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp index 84b44d5425f..a9b60ae2473 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp @@ -18,7 +18,7 @@ #include "RimGridTimeHistoryCurve.h" -#include +#include "Tools/Summary/RiaSummaryTools.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" @@ -37,12 +37,16 @@ #include "RimReservoirCellResultsStorage.h" #include "RimSummaryPlot.h" #include "RimSummaryTimeAxisProperties.h" +#include "RimTools.h" +#include "Tools/RimAutomationSettings.h" #include "Riu3dSelectionManager.h" #include "RiuFemTimeHistoryResultAccessor.h" #include "RiuPlotCurve.h" #include "RiuPlotMainWindowTools.h" +#include "cafPdmUiTreeAttributes.h" + CAF_PDM_SOURCE_INIT( RimGridTimeHistoryCurve, "GridTimeHistoryCurve" ); //-------------------------------------------------------------------------------------------------- @@ -56,6 +60,8 @@ RimGridTimeHistoryCurve::RimGridTimeHistoryCurve() m_geometrySelectionText.registerGetMethod( this, &RimGridTimeHistoryCurve::geometrySelectionText ); m_geometrySelectionText.uiCapability()->setUiReadOnly( true ); + CAF_PDM_InitField( &m_isLocked, "IsLocked", false, "Lock Curve" ); + CAF_PDM_InitFieldNoDefault( &m_eclipseResultDefinition, "EclipseResultDefinition", "Eclipse Result Definition" ); m_eclipseResultDefinition.uiCapability()->setUiTreeChildrenHidden( true ); @@ -295,6 +301,22 @@ RimCase* RimGridTimeHistoryCurve::gridCase() const return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridTimeHistoryCurve::setLocked( bool locked ) +{ + m_isLocked = locked; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridTimeHistoryCurve::isLocked() const +{ + return m_isLocked(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -302,8 +324,8 @@ void RimGridTimeHistoryCurve::createCurveFromSelectionItem( const RiuSelectionIt { if ( !selectionItem || !plot ) return; - RimGridTimeHistoryCurve* newCurve = new RimGridTimeHistoryCurve(); - bool updateResultDefinition = true; + auto newCurve = new RimGridTimeHistoryCurve(); + bool updateResultDefinition = true; newCurve->setFromSelectionItem( selectionItem, updateResultDefinition ); newCurve->setLineThickness( 2 ); @@ -320,6 +342,19 @@ void RimGridTimeHistoryCurve::createCurveFromSelectionItem( const RiuSelectionIt RiuPlotMainWindowTools::selectAsCurrentItem( newCurve ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::PhaseType RimGridTimeHistoryCurve::phaseType() const +{ + if ( m_eclipseResultDefinition ) + { + return m_eclipseResultDefinition->resultPhaseType(); + } + + return RiaDefines::PhaseType::PHASE_NOT_APPLICABLE; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -359,6 +394,8 @@ void RimGridTimeHistoryCurve::onLoadDataAndUpdate( bool updateParentPlot ) if ( isChecked() && m_plotCurve ) { + updateResultDefinitionFromCase(); + std::vector values; RimEclipseGeometrySelectionItem* eclTopItem = eclipseGeomSelectionItem(); @@ -530,6 +567,8 @@ void RimGridTimeHistoryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUi { RimPlotCurve::updateFieldUiState(); + uiOrdering.add( &m_isLocked ); + caf::PdmUiGroup* dataSource = uiOrdering.addNewGroup( "Data Source" ); dataSource->add( &m_geometrySelectionText ); eclipseGeomSelectionItem()->uiOrdering( uiConfigName, *dataSource ); @@ -549,6 +588,9 @@ void RimGridTimeHistoryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUi uiOrdering.add( &m_plotAxis ); + caf::PdmUiGroup* stackingGroup = uiOrdering.addNewGroup( "Stacking" ); + RimStackablePlotCurve::stackingUiOrdering( *stackingGroup ); + caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup( "Appearance" ); RimPlotCurve::appearanceUiOrdering( *appearanceGroup ); appearanceGroup->setCollapsedByDefault(); @@ -576,6 +618,8 @@ void RimGridTimeHistoryCurve::initAfterRead() //-------------------------------------------------------------------------------------------------- void RimGridTimeHistoryCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) { + RimStackablePlotCurve::fieldChangedByUi( changedField, oldValue, newValue ); + if ( changedField == &m_plotAxis ) { updateQwtPlotAxis(); @@ -595,12 +639,39 @@ void RimGridTimeHistoryCurve::fieldChangedByUi( const caf::PdmFieldHandle* chang //-------------------------------------------------------------------------------------------------- void RimGridTimeHistoryCurve::childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField ) { - if ( m_eclipseDataSource() && m_eclipseResultDefinition() ) + onLoadDataAndUpdate( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridTimeHistoryCurve::defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) +{ + bool isUpdatedByAutomation = false; + + if ( auto parentPlot = RiaSummaryTools::parentSummaryPlot( this ) ) { - m_eclipseResultDefinition->setEclipseCase( m_eclipseDataSource->eclipseCase() ); + for ( auto plot : RimTools::automationSettings()->summaryPlots() ) + { + if ( parentPlot == plot ) isUpdatedByAutomation = true; + } } - onLoadDataAndUpdate( true ); + // The padlock icon is only shown if the curve is updated by automation + if ( isUpdatedByAutomation ) + { + QString iconResourceString = m_isLocked ? ":/padlock.svg" : ":/padlock-unlocked.svg"; + + if ( auto* treeItemAttribute = dynamic_cast( attribute ) ) + { + auto tag = caf::PdmUiTreeViewItemAttribute::createTag(); + tag->icon = caf::IconProvider( iconResourceString ); + + tag->clicked.connect( this, &RimGridTimeHistoryCurve::onPadlockClicked ); + + treeItemAttribute->tags.push_back( std::move( tag ) ); + } + } } //-------------------------------------------------------------------------------------------------- @@ -638,17 +709,13 @@ RimGeoMechGeometrySelectionItem* RimGridTimeHistoryCurve::geoMechGeomSelectionIt //-------------------------------------------------------------------------------------------------- void RimGridTimeHistoryCurve::updateResultDefinitionFromCase() { - if ( eclipseGeomSelectionItem() ) + if ( eclipseGeomSelectionItem() && m_eclipseResultDefinition() ) { - CVF_ASSERT( m_eclipseResultDefinition() ); - m_eclipseResultDefinition->setEclipseCase( eclipseGeomSelectionItem()->eclipseCase() ); } - if ( geoMechGeomSelectionItem() ) + if ( geoMechGeomSelectionItem() && m_geoMechResultDefinition() ) { - CVF_ASSERT( m_geoMechResultDefinition() ); - m_geoMechResultDefinition->setGeoMechCase( geoMechGeomSelectionItem()->geoMechCase() ); } } @@ -688,6 +755,16 @@ void RimGridTimeHistoryCurve::updateQwtPlotAxis() if ( m_plotCurve ) updateYAxisInPlot( yAxis() ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridTimeHistoryCurve::onPadlockClicked( const SignalEmitter* emitter, size_t index ) +{ + m_isLocked = !m_isLocked(); + + updateConnectedEditors(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.h b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.h index 29eeadf67df..2ad8e182a7f 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.h +++ b/ApplicationLibCode/ProjectDataModel/RimGridTimeHistoryCurve.h @@ -17,7 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RimPlotCurve.h" +#include "RimStackablePlotCurve.h" #include "RiaDefines.h" @@ -43,7 +43,7 @@ class RimSummaryPlot; /// /// //================================================================================================== -class RimGridTimeHistoryCurve : public RimPlotCurve +class RimGridTimeHistoryCurve : public RimStackablePlotCurve { CAF_PDM_HEADER_INIT; @@ -51,6 +51,8 @@ class RimGridTimeHistoryCurve : public RimPlotCurve RimGridTimeHistoryCurve(); ~RimGridTimeHistoryCurve() override; + static void createCurveFromSelectionItem( const RiuSelectionItem* selectionItem, RimSummaryPlot* plot ); + void setFromSelectionItem( const RiuSelectionItem* selectionItem, bool updateResultDefinition ); void setFromEclipseCellAndResult( RimEclipseCase* eclCase, size_t gridIdx, size_t i, size_t j, size_t k, const RigEclipseResultAddress& resAddr ); RiuPlotAxis yAxis() const; @@ -64,7 +66,10 @@ class RimGridTimeHistoryCurve : public RimPlotCurve QString caseName() const; RimCase* gridCase() const; - static void createCurveFromSelectionItem( const RiuSelectionItem* selectionItem, RimSummaryPlot* plot ); + void setLocked( bool locked ); + bool isLocked() const; + + RiaDefines::PhaseType phaseType() const override; protected: QString createCurveAutoName() override; @@ -75,6 +80,7 @@ class RimGridTimeHistoryCurve : public RimPlotCurve void initAfterRead() override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField ) override; + void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; private: RigMainGrid* mainGrid(); @@ -84,9 +90,13 @@ class RimGridTimeHistoryCurve : public RimPlotCurve QString geometrySelectionText() const; void updateQwtPlotAxis(); + void onPadlockClicked( const SignalEmitter* emitter, size_t index ); + std::unique_ptr femTimeHistoryResultAccessor() const; private: + caf::PdmField m_isLocked; + caf::PdmProxyValueField m_geometrySelectionText; caf::PdmChildField m_eclipseResultDefinition; diff --git a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h index 14a6d94ac42..14a744559f6 100644 --- a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h +++ b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.h @@ -140,6 +140,8 @@ class RimPlotCurve : public caf::PdmObject std::vector rectAnnotations() const; + void setSamplesFromXYValues( const std::vector& xValues, const std::vector& yValues, bool useLogarithmicScale ); + protected: virtual QString createCurveAutoName(); @@ -160,8 +162,6 @@ class RimPlotCurve : public caf::PdmObject bool useLogarithmicScale, RiaCurveDataTools::ErrorAxis errorAxis = RiaCurveDataTools::ErrorAxis::ERROR_ALONG_Y_AXIS ); - void setSamplesFromXYValues( const std::vector& xValues, const std::vector& yValues, bool useLogarithmicScale ); - void setSamplesFromDatesAndYValues( const std::vector& dateTimes, const std::vector& yValues, bool useLogarithmicScale ); void setSamplesFromTimeTAndYValues( const std::vector& dateTimes, const std::vector& yValues, bool useLogarithmicScale ); diff --git a/ApplicationLibCode/ProjectDataModel/RimTools.cpp b/ApplicationLibCode/ProjectDataModel/RimTools.cpp index cda19095110..35d6d5cd495 100644 --- a/ApplicationLibCode/ProjectDataModel/RimTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimTools.cpp @@ -569,6 +569,14 @@ RimPolygonCollection* RimTools::polygonCollection() return RimProject::current()->activeOilField()->polygonCollection(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimAutomationSettings* RimTools::automationSettings() +{ + return RimProject::current()->automationSettings(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimTools.h b/ApplicationLibCode/ProjectDataModel/RimTools.h index 89854043249..50ba08ead87 100644 --- a/ApplicationLibCode/ProjectDataModel/RimTools.h +++ b/ApplicationLibCode/ProjectDataModel/RimTools.h @@ -42,6 +42,7 @@ class RimWellPath; class RimSurfaceCollection; class RimFaultInViewCollection; class RimPolygonCollection; +class RimAutomationSettings; //-------------------------------------------------------------------------------------------------- /// @@ -77,8 +78,9 @@ class RimTools static RimWellPathCollection* wellPathCollection(); static RimWellPath* firstWellPath(); - static RimSurfaceCollection* surfaceCollection(); - static RimPolygonCollection* polygonCollection(); + static RimSurfaceCollection* surfaceCollection(); + static RimPolygonCollection* polygonCollection(); + static RimAutomationSettings* automationSettings(); static void timeStepsForCase( RimCase* gridCase, QList* options ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index 0ae0ff122b3..d3dbec85279 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -20,6 +20,7 @@ #include "RiaColorTables.h" #include "RiaColorTools.h" +#include "RiaCurveMerger.h" #include "RiaDefines.h" #include "RiaLogging.h" #include "RiaPlotDefines.h" @@ -467,23 +468,6 @@ RimSummaryCurveCollection* RimSummaryPlot::summaryCurveCollection() const return m_summaryCurveCollection(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimSummaryPlot::visibleStackedSummaryCurvesForAxis( RiuPlotAxis plotAxis ) -{ - auto visibleCurves = visibleSummaryCurvesForAxis( plotAxis ); - - std::vector visibleStackedCurves; - - std::copy_if( visibleCurves.begin(), - visibleCurves.end(), - std::back_inserter( visibleStackedCurves ), - []( RimSummaryCurve* curve ) { return curve->isStacked(); } ); - - return visibleStackedCurves; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1567,6 +1551,8 @@ void RimSummaryPlot::addGridTimeHistoryCurve( RimGridTimeHistoryCurve* curve ) CVF_ASSERT( curve ); m_gridTimeHistoryCurves.push_back( curve ); + connectCurveSignals( curve ); + if ( plotWidget() ) { curve->setParentPlotAndReplot( plotWidget() ); @@ -1574,20 +1560,6 @@ void RimSummaryPlot::addGridTimeHistoryCurve( RimGridTimeHistoryCurve* curve ) } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimSummaryPlot::addGridTimeHistoryCurveNoUpdate( RimGridTimeHistoryCurve* curve ) -{ - CVF_ASSERT( curve ); - - m_gridTimeHistoryCurves.push_back( curve ); - if ( plotWidget() ) - { - curve->setParentPlotNoReplot( plotWidget() ); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1733,58 +1705,86 @@ bool RimSummaryPlot::updateStackedCurveDataForRelevantAxes() //-------------------------------------------------------------------------------------------------- bool RimSummaryPlot::updateStackedCurveDataForAxis( RiuPlotAxis plotAxis ) { - auto stackedCurves = visibleStackedSummaryCurvesForAxis( plotAxis ); - if ( stackedCurves.empty() ) return false; + // See RimWellLogTrack::updateStackedCurveData() for vertical plots - std::map curvePhaseCount; - for ( RimSummaryCurve* curve : stackedCurves ) + struct CurveStackingItem { - curve->loadDataAndUpdate( false ); + RimStackablePlotCurve* curve; + RiaDefines::PhaseType phase; + std::vector xValues; + std::vector yValues; + }; - curvePhaseCount[curve->phaseType()]++; - } + std::vector stackingItems; + for ( auto summaryCurve : visibleSummaryCurvesForAxis( plotAxis ) ) { - // Z-position of curve, to draw them in correct order - double zPos = -10000.0; - - std::vector allTimeSteps; - for ( RimSummaryCurve* curve : stackedCurves ) + if ( summaryCurve->isStacked() ) { - auto timeSteps = curve->timeStepsY(); - if ( !timeSteps.empty() ) + auto xValues = RiuPlotCurve::fromTime_t( summaryCurve->timeStepsY() ); + auto yValues = summaryCurve->valuesY(); + + if ( !xValues.empty() && xValues.size() == yValues.size() ) { - // https://github.com/OPM/ResInsight/issues/10438 - allTimeSteps.insert( allTimeSteps.end(), timeSteps.begin(), timeSteps.end() ); + stackingItems.push_back( { summaryCurve, summaryCurve->phaseType(), xValues, yValues } ); } } - std::sort( allTimeSteps.begin(), allTimeSteps.end() ); - allTimeSteps.erase( std::unique( allTimeSteps.begin(), allTimeSteps.end() ), allTimeSteps.end() ); - - std::vector allStackedValues( allTimeSteps.size(), 0.0 ); + } - size_t stackIndex = 0u; - for ( RimSummaryCurve* curve : stackedCurves ) + // Add stack data for time history curves + for ( auto gridCurve : gridTimeHistoryCurves() ) + { + if ( gridCurve->yAxis() == plotAxis && gridCurve->isStacked() && gridCurve->isChecked() ) { - for ( size_t i = 0; i < allTimeSteps.size(); ++i ) + auto xValues = RiuPlotCurve::fromTime_t( gridCurve->timeStepValues() ); + auto yValues = gridCurve->yValues(); + + if ( !xValues.empty() && xValues.size() == yValues.size() ) { - double value = curve->yValueAtTimeT( allTimeSteps[i] ); - if ( value != std::numeric_limits::infinity() ) - { - allStackedValues[i] += value; - } + stackingItems.push_back( { gridCurve, gridCurve->phaseType(), xValues, yValues } ); } + } + } + + if ( stackingItems.empty() ) return true; + + RiaCurveMerger curveMerger; + std::map curvePhaseCount; + + for ( auto stackingItem : stackingItems ) + { + curveMerger.addCurveData( stackingItem.xValues, stackingItem.yValues ); + curvePhaseCount[stackingItem.phase]++; + } + curveMerger.computeInterpolatedValues( true ); + + std::vector allXValues = curveMerger.allXValues(); + std::vector allStackedValues( allXValues.size(), 0.0 ); + + // Z-position of curve, to draw them in correct order + double zPos = -10000.0; - curve->setOverrideCurveDataY( allTimeSteps, allStackedValues ); - curve->setZOrder( zPos ); - if ( curve->isStackedWithPhaseColors() ) + for ( size_t index = 0; index < stackingItems.size(); index++ ) + { + auto yValues = curveMerger.interpolatedYValuesForAllXValues( index ); + for ( size_t i = 0; i < allXValues.size(); ++i ) + { + double value = yValues[i]; + if ( value != std::numeric_limits::infinity() ) { - curve->assignStackColor( stackIndex, curvePhaseCount[curve->phaseType()] ); + allStackedValues[i] += value; } - zPos -= 1.0; } - } + auto curve = stackingItems[index].curve; + curve->setSamplesFromXYValues( allXValues, allStackedValues, false ); + curve->setZOrder( zPos ); + if ( curve->isStackedWithPhaseColors() ) + { + curve->assignStackColor( index, curvePhaseCount[curve->phaseType()] ); + } + zPos -= 1.0; + } return true; } @@ -1974,7 +1974,7 @@ void RimSummaryPlot::deletePlotCurvesAndPlotWidget() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlot::connectCurveSignals( RimSummaryCurve* curve ) +void RimSummaryPlot::connectCurveSignals( RimStackablePlotCurve* curve ) { curve->dataChanged.connect( this, &RimSummaryPlot::curveDataChanged ); curve->visibilityChanged.connect( this, &RimSummaryPlot::curveVisibilityChanged ); @@ -1986,7 +1986,7 @@ void RimSummaryPlot::connectCurveSignals( RimSummaryCurve* curve ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlot::disconnectCurveSignals( RimSummaryCurve* curve ) +void RimSummaryPlot::disconnectCurveSignals( RimStackablePlotCurve* curve ) { curve->dataChanged.disconnect( this ); curve->visibilityChanged.disconnect( this ); @@ -2204,9 +2204,18 @@ void RimSummaryPlot::axisPositionChanged( const caf::SignalEmitter* emitter, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlot::deleteAllGridTimeHistoryCurves() +void RimSummaryPlot::deleteUnlockedGridTimeHistoryCurves() { - m_gridTimeHistoryCurves.deleteChildren(); + auto allGridCurves = m_gridTimeHistoryCurves.childrenByType(); + for ( auto c : allGridCurves ) + { + if ( c->isLocked() ) continue; + + disconnectCurveSignals( c ); + + m_gridTimeHistoryCurves.removeChild( c ); + delete c; + } } //-------------------------------------------------------------------------------------------------- @@ -2573,8 +2582,8 @@ RimSummaryCurve* RimSummaryPlot::addNewCurve( const RifEclipseSummaryAddress& ad { auto newCurve = RiaSummaryPlotTools::createCurve( summaryCase, address ); - // This address is RifEclipseSummaryAddress::time() if the curve is a time plot. Otherwise it is the address of the summary vector used - // for the x-axis + // This address is RifEclipseSummaryAddress::time() if the curve is a time plot. Otherwise it is the address of the summary vector + // used for the x-axis if ( addressX.category() != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_TIME ) { newCurve->setAxisTypeX( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ); @@ -2786,7 +2795,10 @@ void RimSummaryPlot::initAfterRead() connectCurveSignals( curve ); } - updateStackedCurveData(); + for ( auto curve : gridTimeHistoryCurves() ) + { + connectCurveSignals( curve ); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h index 790f218976f..bf4c34f59de 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.h @@ -63,6 +63,7 @@ class RimTimeAxisAnnotation; class RiaSummaryCurveDefinition; class RifEclipseSummaryAddress; class RiaSummaryCurveAddress; +class RimStackablePlotCurve; class QwtInterval; class QwtPlotCurve; @@ -108,12 +109,11 @@ class RimSummaryPlot : public RimPlot, public RimSummaryDataSourceStepping void deleteCurves( const std::vector& curves ); void deleteCurvesAssosiatedWithCase( RimSummaryCase* summaryCase ); - void deleteAllGridTimeHistoryCurves(); RimEnsembleCurveSetCollection* ensembleCurveSetCollection() const; void addGridTimeHistoryCurve( RimGridTimeHistoryCurve* curve ); - void addGridTimeHistoryCurveNoUpdate( RimGridTimeHistoryCurve* curve ); + void deleteUnlockedGridTimeHistoryCurves(); std::vector gridTimeHistoryCurves() const; @@ -260,7 +260,6 @@ private slots: std::vector visibleTimeHistoryCurvesForAxis( RiuPlotAxis plotAxis ) const; std::vector visibleAsciiDataCurvesForAxis( RiuPlotAxis plotAxis ) const; bool hasVisibleCurvesForAxis( RiuPlotAxis plotAxis ) const; - std::vector visibleStackedSummaryCurvesForAxis( RiuPlotAxis plotAxis ); void updateNumericalAxis( RiaDefines::PlotAxis plotAxis ); void updateZoomForAxis( RimPlotAxisPropertiesInterface* axisProperties ); @@ -273,8 +272,8 @@ private slots: void deletePlotCurvesAndPlotWidget(); - void connectCurveSignals( RimSummaryCurve* curve ); - void disconnectCurveSignals( RimSummaryCurve* curve ); + void connectCurveSignals( RimStackablePlotCurve* curve ); + void disconnectCurveSignals( RimStackablePlotCurve* curve ); void curveDataChanged( const caf::SignalEmitter* emitter ); void curveVisibilityChanged( const caf::SignalEmitter* emitter, bool visible ); diff --git a/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.cpp b/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.cpp index 7a3191239b2..1032c760f3b 100644 --- a/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.cpp +++ b/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.cpp @@ -62,6 +62,14 @@ std::vector RimAutomationSettings::summaryPlots() const return {}; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimAutomationSettings::setDestinationPlot( RimPlotWindow* plotWindow ) +{ + m_cellSelectionDestination = plotWindow; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.h b/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.h index 4645633899b..10c50e37798 100644 --- a/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.h +++ b/ApplicationLibCode/ProjectDataModel/Tools/RimAutomationSettings.h @@ -38,6 +38,8 @@ class RimAutomationSettings : public caf::PdmObject std::vector summaryPlots() const; + void setDestinationPlot( RimPlotWindow* plotWindow ); + private: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; diff --git a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp index c6adb07a5e1..4a2ac2032b7 100644 --- a/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellLog/RimWellLogTrack.cpp @@ -2692,6 +2692,8 @@ std::vector RimWellLogTrack::formationNamesVector( RimCase* rimCase ) //-------------------------------------------------------------------------------------------------- void RimWellLogTrack::updateStackedCurveData() { + // See RimSummaryPlot::updateStackedCurveDataForAxis() horizontal plots + RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted(); RimWellLogPlot::DepthTypeEnum depthType = wellLogPlot->depthType(); diff --git a/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp b/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp index 0469451423a..53082175357 100644 --- a/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp +++ b/ApplicationLibCode/UserInterface/RiuSelectionChangedHandler.cpp @@ -41,6 +41,7 @@ #include "RimGridTimeHistoryCurve.h" #include "RimProject.h" #include "RimSummaryPlot.h" +#include "RimTools.h" #include "Tools/RimAutomationSettings.h" #include "Riu3dSelectionManager.h" @@ -431,7 +432,7 @@ void RiuSelectionChangedHandler::updateGridCellCurvesFromSelection() Riu3dSelectionManager::instance()->selectedItems( items ); if ( items.empty() ) return; - auto autoSettings = RimProject::current()->automationSettings(); + auto autoSettings = RimTools::automationSettings(); for ( auto summaryPlot : autoSettings->summaryPlots() ) { // if no curves present, create from selection @@ -469,7 +470,8 @@ void RiuSelectionChangedHandler::updateGridCellCurvesFromSelection() int index = 0; for ( auto item : items ) { - auto newCurve = curve->copyObject(); + auto newCurve = curve->copyObject(); + newCurve->setLocked( false ); bool updateResultDefinition = false; newCurve->setFromSelectionItem( item, updateResultDefinition ); @@ -484,7 +486,7 @@ void RiuSelectionChangedHandler::updateGridCellCurvesFromSelection() } } - summaryPlot->deleteAllGridTimeHistoryCurves(); + summaryPlot->deleteUnlockedGridTimeHistoryCurves(); for ( auto c : newCurves ) { summaryPlot->addGridTimeHistoryCurve( c );