diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp index a7e86ca762..7af842aff8 100644 --- a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp @@ -25,6 +25,7 @@ #include "RigCellGeometryTools.h" #include "RigHexIntersectionTools.h" +#include "RimCase.h" #include "RimGridView.h" #include "RimProject.h" #include "RimRegularLegendConfig.h" @@ -78,6 +79,8 @@ RimContourMapProjection::RimContourMapProjection() , m_mapSize(cvf::Vec2ui(0u, 0u)) , m_sampleSpacing(-1.0) , m_currentResultTimestep(-1) + , m_minResultAllTimeSteps(std::numeric_limits::infinity()) + , m_maxResultAllTimeSteps(-std::numeric_limits::infinity()) { CAF_PDM_InitObject("RimContourMapProjection", ":/2DMapProjection16x16.png", "", ""); @@ -111,11 +114,19 @@ void RimContourMapProjection::generateResultsIfNecessary(int timeStep) generateGridMapping(); } + if (resultVariableChanged()) + { + clearResults(); + clearTimeStepRange(); + } + if (resultsNeedsUpdating(timeStep)) { - generateResults(timeStep); + clearGeometry(); + m_aggregatedResults = generateResults(timeStep); generateVertexResults(); } + m_currentResultTimestep = timeStep; } //-------------------------------------------------------------------------------------------------- @@ -241,33 +252,16 @@ QString RimContourMapProjection::resultAggregationText() const //-------------------------------------------------------------------------------------------------- double RimContourMapProjection::maxValue() const { - double maxV = -std::numeric_limits::infinity(); - - for (size_t index = 0; index < m_aggregatedResults.size(); ++index) - { - if (m_aggregatedResults[index] != std::numeric_limits::infinity()) - { - maxV = std::max(maxV, m_aggregatedResults[index]); - } - } - return maxV; + return maxValue(m_aggregatedResults); } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RimContourMapProjection::minValue() const { - double minV = std::numeric_limits::infinity(); - - for (size_t index = 0; index < m_aggregatedResults.size(); ++index) - { - if (m_aggregatedResults[index] != std::numeric_limits::infinity()) - { - minV = std::min(minV, m_aggregatedResults[index]); - } - } - return minV; + return minValue(m_aggregatedResults); } //-------------------------------------------------------------------------------------------------- @@ -589,7 +583,7 @@ bool RimContourMapProjection::resultsNeedsUpdating(int timeStep) const { return true; } - return resultVariableChanged(); + return false; } //-------------------------------------------------------------------------------------------------- @@ -600,13 +594,26 @@ bool RimContourMapProjection::geometryNeedsUpdating() const return m_contourPolygons.empty() || m_trianglesWithVertexValues.empty(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::timestepRangeNeedsUpdating() const +{ + if (m_minResultAllTimeSteps == std::numeric_limits::infinity() || + m_maxResultAllTimeSteps == -std::numeric_limits::infinity()) + { + return true; + } + return false; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimContourMapProjection::clearGridMapping() { clearResults(); - + clearTimeStepRange(); m_projected3dGridIndices.clear(); } @@ -624,6 +631,76 @@ void RimContourMapProjection::clearResults() clearResultVariable(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::clearTimeStepRange() +{ + m_minResultAllTimeSteps = std::numeric_limits::infinity(); + m_maxResultAllTimeSteps = -std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::maxValue(const std::vector& aggregatedResults) const +{ + double maxV = -std::numeric_limits::infinity(); + + for (size_t index = 0; index < aggregatedResults.size(); ++index) + { + if (aggregatedResults[index] != std::numeric_limits::infinity()) + { + maxV = std::max(maxV, aggregatedResults[index]); + } + } + return maxV; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::minValue(const std::vector& aggregatedResults) const +{ + double minV = std::numeric_limits::infinity(); + + for (size_t index = 0; index < aggregatedResults.size(); ++index) + { + if (aggregatedResults[index] != std::numeric_limits::infinity()) + { + minV = std::min(minV, aggregatedResults[index]); + } + } + return minV; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RimContourMapProjection::minmaxValuesAllTimeSteps() +{ + if (timestepRangeNeedsUpdating()) + { + clearTimeStepRange(); + + for (int i = 0; i < (int)baseView()->ownerCase()->timeStepStrings().size(); ++i) + { + if (i == m_currentResultTimestep) + { + m_minResultAllTimeSteps = std::min(m_minResultAllTimeSteps, minValue(m_aggregatedResults)); + m_maxResultAllTimeSteps = std::max(m_maxResultAllTimeSteps, maxValue(m_aggregatedResults)); + } + else + { + std::vector aggregatedResults = generateResults(i, 10); + m_minResultAllTimeSteps = std::min(m_minResultAllTimeSteps, minValue(aggregatedResults)); + m_maxResultAllTimeSteps = std::max(m_maxResultAllTimeSteps, maxValue(aggregatedResults)); + } + } + } + return std::make_pair(m_minResultAllTimeSteps, m_maxResultAllTimeSteps); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1506,22 +1583,6 @@ std::vector RimContourMapProjection::yVertexPositions() const return positions; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::use2dMapLegendRange() const -{ - return !use3dGridLegendRange(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::use3dGridLegendRange() const -{ - return (isMeanResult() || m_resultAggregation == RESULTS_TOP_VALUE); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1550,8 +1611,6 @@ void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* change const QVariant& oldValue, const QVariant& newValue) { - legendConfig()->disableAllTimeStepsRange(use2dMapLegendRange()); - if (changedField == &m_resultAggregation) { ResultAggregation previousAggregation = static_cast(oldValue.toInt()); @@ -1563,6 +1622,7 @@ void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* change { clearResults(); } + clearTimeStepRange(); } else if (changedField == &m_smoothContourLines) { @@ -1570,7 +1630,9 @@ void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* change } else if (changedField == &m_relativeSampleSpacing) { + clearGridMapping(); clearResults(); + clearTimeStepRange(); } baseView()->updateConnectedEditors(); @@ -1628,5 +1690,4 @@ void RimContourMapProjection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTre //-------------------------------------------------------------------------------------------------- void RimContourMapProjection::initAfterRead() { - legendConfig()->disableAllTimeStepsRange(use2dMapLegendRange()); } diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h index 67521c83d3..1eb0ef462b 100644 --- a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h @@ -92,6 +92,7 @@ public: double maxValue() const; double minValue() const; + double meanValue() const; double sumAllValues() const; @@ -120,7 +121,7 @@ protected: // Protected virtual methods to be overridden by Eclipse and Geo-mechanical contour map implementations virtual void updateGridInformation() = 0; virtual std::vector retrieveParameterWeights() = 0; - virtual void generateResults(int timeStep) = 0; + virtual std::vector generateResults(int timeStep, int everyNCells = 1) = 0; virtual bool resultVariableChanged() const = 0; virtual void clearResultVariable() = 0; virtual RimGridView* baseView() const = 0; @@ -137,8 +138,14 @@ protected: bool gridMappingNeedsUpdating() const; bool resultsNeedsUpdating(int timeStep) const; bool geometryNeedsUpdating() const; + bool timestepRangeNeedsUpdating() const; void clearGridMapping(); void clearResults(); + void clearTimeStepRange(); + + double maxValue(const std::vector& aggregatedResults) const; + double minValue(const std::vector& aggregatedResults) const; + std::pair minmaxValuesAllTimeSteps(); virtual cvf::ref getCellVisibility() const; void generateGridMapping(); @@ -178,8 +185,6 @@ protected: std::vector xVertexPositions() const; std::vector yVertexPositions() const; - bool use2dMapLegendRange() const; - bool use3dGridLegendRange() const; cvf::Vec2ui calculateMapSize() const; double gridEdgeOffset() const; @@ -215,4 +220,6 @@ protected: std::vector m_trianglesWithVertexValues; int m_currentResultTimestep; + double m_minResultAllTimeSteps; + double m_maxResultAllTimeSteps; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp index 85bd3d71e3..d43dbfbd3a 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp @@ -128,19 +128,12 @@ void RimEclipseContourMapProjection::updateLegend() { RimEclipseCellColors* cellColors = view()->cellResult(); - if (use3dGridLegendRange()) - { - cellColors->updateLegendData(view()->currentTimeStep(), legendConfig()); - } - else - { - CVF_ASSERT(use2dMapLegendRange()); + double minVal = minValue(m_aggregatedResults); + double maxVal = maxValue(m_aggregatedResults); - double minVal = minValue(); - double maxVal = maxValue(); + std::pair minmaxValAllTimeSteps = minmaxValuesAllTimeSteps(); - legendConfig()->setAutomaticRanges(minVal, maxVal, minVal, maxVal); - } + legendConfig()->setAutomaticRanges(minmaxValAllTimeSteps.first, minmaxValAllTimeSteps.second, minVal, maxVal); if (m_resultAggregation() == RESULTS_OIL_COLUMN || m_resultAggregation() == RESULTS_GAS_COLUMN || @@ -179,15 +172,13 @@ void RimEclipseContourMapProjection::updatedWeightingResult() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseContourMapProjection::generateResults(int timeStep) +std::vector RimEclipseContourMapProjection::generateResults(int timeStep, int everyNCells) { - clearGeometry(); - m_weightingResult->loadResult(); size_t nCells = numberOfCells(); - m_aggregatedResults = std::vector(nCells, std::numeric_limits::infinity()); + std::vector aggregatedResults = std::vector(nCells, std::numeric_limits::infinity()); RimEclipseCellColors* cellColors = view()->cellResult(); RimEclipseResultCase* eclipseCase = this->eclipseCase(); @@ -224,14 +215,14 @@ void RimEclipseContourMapProjection::generateResults(int timeStep) } #pragma omp parallel for - for (int index = 0; index < static_cast(nCells); ++index) + for (int index = 0; index < static_cast(nCells); index += everyNCells) { - cvf::Vec2ui ij = ijFromCellIndex(index); - m_aggregatedResults[index] = calculateValueInMapCell(ij.x(), ij.y()); + cvf::Vec2ui ij = ijFromCellIndex(index); + aggregatedResults[index] = calculateValueInMapCell(ij.x(), ij.y()); } } } - m_currentResultTimestep = timeStep; + return aggregatedResults; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h index 624c7a658b..c3476d61f2 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h @@ -63,7 +63,7 @@ protected: void updateGridInformation() override; std::vector retrieveParameterWeights() override; - void generateResults(int timeStep) override; + std::vector generateResults(int timeStep, int everyNCells = 1) override; bool resultVariableChanged() const override; void clearResultVariable() override; RimGridView* baseView() const override; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.cpp index 5769eff8ef..233af5618b 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.cpp @@ -91,18 +91,12 @@ void RimGeoMechContourMapProjection::updateLegend() { RimGeoMechCellColors* cellColors = view()->cellResult(); - if (use3dGridLegendRange()) - { - view()->updateLegendTextAndRanges(cellColors->legendConfig(), view()->currentTimeStep()); - } - else - { - CVF_ASSERT(use2dMapLegendRange()); + double minVal = minValue(m_aggregatedResults); + double maxVal = maxValue(m_aggregatedResults); - double minVal = minValue(); - double maxVal = maxValue(); - legendConfig()->setAutomaticRanges(minVal, maxVal, minVal, maxVal); - } + std::pair minmaxValAllTimeSteps = minmaxValuesAllTimeSteps(); + + legendConfig()->setAutomaticRanges(minmaxValAllTimeSteps.first, minmaxValAllTimeSteps.second, minVal, maxVal); QString projectionLegendText = QString("Map Projection\n%1").arg(m_resultAggregation().uiText()); projectionLegendText += QString("\nResult: %1").arg(cellColors->resultFieldUiName()); @@ -184,16 +178,17 @@ std::vector RimGeoMechContourMapProjection::retrieveParameterWeights() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimGeoMechContourMapProjection::generateResults(int timeStep) +std::vector RimGeoMechContourMapProjection::generateResults(int timeStep, int everyNCells) { - clearGeometry(); - RigGeoMechCaseData* caseData = geoMechCase()->geoMechData(); RigFemPartResultsCollection* resultCollection = caseData->femPartResults(); RimGeoMechCellColors* cellColors = view()->cellResult(); RigFemResultAddress resAddr = cellColors->resultAddress(); + size_t nCells = numberOfCells(); + std::vector aggregatedResults = std::vector(nCells, std::numeric_limits::infinity()); + if (!resAddr.isValid()) - return; + return aggregatedResults; if (resAddr.fieldName == "PP") { @@ -203,17 +198,16 @@ void RimGeoMechContourMapProjection::generateResults(int timeStep) m_resultValues = resultCollection->resultValues(resAddr, 0, timeStep); - size_t nCells = numberOfCells(); - m_aggregatedResults = std::vector(nCells, std::numeric_limits::infinity()); - #pragma omp parallel for - for (int index = 0; index < static_cast(nCells); ++index) + for (int index = 0; index < static_cast(nCells); index += everyNCells) { cvf::Vec2ui ij = ijFromCellIndex(index); - m_aggregatedResults[index] = calculateValueInMapCell(ij.x(), ij.y()); + aggregatedResults[index] = calculateValueInMapCell(ij.x(), ij.y()); } m_currentResultAddr = resAddr; + + return aggregatedResults; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.h index d417cbf59f..477f86ef54 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechContourMapProjection.h @@ -62,8 +62,8 @@ protected: cvf::ref getCellVisibility() const override; void ensureOnlyValidPorBarVisible(cvf::UByteArray* visibility, int timeStep) const; void updateGridInformation() override; - virtual std::vector retrieveParameterWeights() override; - void generateResults(int timeStep) override; + std::vector retrieveParameterWeights() override; + std::vector generateResults(int timeStep, int everyNCells = 1) override; bool resultVariableChanged() const override; void clearResultVariable() override; RimGridView* baseView() const override;