diff --git a/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp index 1b98b62696..6da7f70823 100644 --- a/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp @@ -18,21 +18,24 @@ #include "RivWellFracturePartMgr.h" +#include "RiaApplication.h" + #include "RimEclipseView.h" #include "RimEclipseWell.h" #include "RimFracture.h" - -#include "cafEffectGenerator.h" +#include "RimLegendConfig.h" +#include "RimStimPlanColors.h" +#include "RimStimPlanFractureTemplate.h" #include "cafDisplayCoordTransform.h" +#include "cafEffectGenerator.h" + #include "cvfDrawableGeo.h" #include "cvfModelBasicList.h" #include "cvfPart.h" #include "cvfPrimitiveSet.h" #include "cvfPrimitiveSetIndexedUInt.h" #include "cvfScalarMapperContinuousLinear.h" -#include "RimStimPlanFractureTemplate.h" -#include "RimLegendConfig.h" //-------------------------------------------------------------------------------------------------- @@ -108,6 +111,15 @@ void RivWellFracturePartMgr::updatePartGeometryTexture(caf::DisplayCoordTransfor if (!m_rimFracture->hasValidGeometry()) return; + RimLegendConfig* legendConfig = nullptr; + RimEclipseView* activeView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); + if (activeView) + { + legendConfig = activeView->stimPlanColors->activeLegend(); + } + + // Note : If no legend is found, draw geo using a single color + RimFractureTemplate * fracTemplate = m_rimFracture->attachedFractureDefinition(); RimStimPlanFractureTemplate* stimPlanFracTemplate; @@ -118,10 +130,7 @@ void RivWellFracturePartMgr::updatePartGeometryTexture(caf::DisplayCoordTransfor else return; int timeStepIndex = m_rimFracture->stimPlanTimeIndexToPlot; - QString resultToPlot = m_rimFracture->stimPlanParameterToPlot; - std::vector > dataToPlot = stimPlanFracTemplate->getDataAtTimeIndex(resultToPlot, timeStepIndex); - - if (dataToPlot.empty()) return; //TODO: Set all values to undefined if no data available... + std::vector > dataToPlot = stimPlanFracTemplate->getDataAtTimeIndex(activeView->stimPlanColors->resultName(), activeView->stimPlanColors->unit(), timeStepIndex); const std::vector& nodeCoords = m_rimFracture->nodeCoords(); const std::vector& triangleIndices = m_rimFracture->triangleIndices(); @@ -139,30 +148,38 @@ void RivWellFracturePartMgr::updatePartGeometryTexture(caf::DisplayCoordTransfor m_part = new cvf::Part; m_part->setDrawable(geo.p()); - RimLegendConfig* legend = m_rimFracture->activeLegend(); - cvf::ScalarMapper* scalarMapper = legend->scalarMapper(); - - cvf::ref textureCoords = new cvf::Vec2fArray; - textureCoords->resize(nodeCoords.size()); - - int i = 0; - for (std::vector depthData : dataToPlot) + if (legendConfig) { - std::vector mirroredValuesAtDepth = mirrorDataAtSingleDepth(depthData); - for (double gridXdata : mirroredValuesAtDepth) + cvf::ScalarMapper* scalarMapper = legendConfig->scalarMapper(); + + cvf::ref textureCoords = new cvf::Vec2fArray; + textureCoords->resize(nodeCoords.size()); + + int i = 0; + for (std::vector depthData : dataToPlot) { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(gridXdata); - textureCoords->set(i, texCoord); - i++; + std::vector mirroredValuesAtDepth = mirrorDataAtSingleDepth(depthData); + for (double gridXdata : mirroredValuesAtDepth) + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(gridXdata); + textureCoords->set(i, texCoord); + i++; + } } - } - geo->setTextureCoordArray(textureCoords.p()); + geo->setTextureCoordArray(textureCoords.p()); - caf::ScalarMapperEffectGenerator scalarMapperEffectGenerator(scalarMapper, caf::PO_NEG_LARGE); - cvf::ref eff = scalarMapperEffectGenerator.generateUnCachedEffect(); + caf::ScalarMapperEffectGenerator scalarMapperEffectGenerator(scalarMapper, caf::PO_NEG_LARGE); + cvf::ref eff = scalarMapperEffectGenerator.generateCachedEffect(); - m_part->setEffect(eff.p()); + m_part->setEffect(eff.p()); + } + else + { + caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN)), caf::PO_1); + cvf::ref eff = surfaceGen.generateCachedEffect(); + m_part->setEffect(eff.p()); + } } } diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 0a06dbf445..67734912e0 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -95,6 +95,7 @@ ${CEE_CURRENT_LIST_DIR}RimFractureExportSettings.h ${CEE_CURRENT_LIST_DIR}RimFractureTemplate.h ${CEE_CURRENT_LIST_DIR}RimStimPlanFractureTemplate.h ${CEE_CURRENT_LIST_DIR}RimStimPlanLegendConfig.h +${CEE_CURRENT_LIST_DIR}RimStimPlanColors.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -188,6 +189,7 @@ ${CEE_CURRENT_LIST_DIR}RimFractureExportSettings.cpp ${CEE_CURRENT_LIST_DIR}RimFractureTemplate.cpp ${CEE_CURRENT_LIST_DIR}RimStimPlanFractureTemplate.cpp ${CEE_CURRENT_LIST_DIR}RimStimPlanLegendConfig.cpp +${CEE_CURRENT_LIST_DIR}RimStimPlanColors.cpp ) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index cb53dd087a..47d4bdc92b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -52,6 +52,7 @@ #include "RimLegendConfig.h" #include "RimOilField.h" #include "RimProject.h" +#include "RimStimPlanColors.h" #include "RimTernaryLegendConfig.h" #include "RimViewController.h" #include "RimViewLinker.h" @@ -113,6 +114,10 @@ RimEclipseView::RimEclipseView() faultResultSettings = new RimEclipseFaultColors(); faultResultSettings.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&stimPlanColors, "StimPlanColors", "Fracture Colors", "", "", ""); + stimPlanColors = new RimStimPlanColors(); + stimPlanColors.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&wellCollection, "WellCollection", "Simulation Wells", "", "", ""); wellCollection = new RimEclipseWellCollection; wellCollection.uiCapability()->setUiHidden(true); @@ -697,6 +702,7 @@ void RimEclipseView::loadDataAndUpdate() this->cellEdgeResult()->loadResult(); this->faultResultSettings()->customFaultResult()->loadResult(); + this->stimPlanColors->loadDataAndUpdate(); updateMdiWindowVisibility(); @@ -997,6 +1003,17 @@ void RimEclipseView::updateLegends() this->cellEdgeResult()->legendConfig()->setClosestToZeroValues(0, 0, 0, 0); this->cellEdgeResult()->legendConfig()->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); } + + RimLegendConfig* stimPlanLegend = stimPlanColors()->activeLegend(); + if (stimPlanLegend) + { + stimPlanColors->updateLegendData(); + + if (stimPlanLegend->legend()) + { + m_viewer->addColorLegendToBottomLeftCorner(stimPlanLegend->legend()); + } + } } //-------------------------------------------------------------------------------------------------- @@ -1332,6 +1349,7 @@ void RimEclipseView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering uiTreeOrdering.add(cellResult()); uiTreeOrdering.add(cellEdgeResult()); uiTreeOrdering.add(faultResultSettings()); + uiTreeOrdering.add(stimPlanColors()); uiTreeOrdering.add(wellCollection()); uiTreeOrdering.add(faultCollection()); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.h b/ApplicationCode/ProjectDataModel/RimEclipseView.h index 9b3f9eb1e4..491f2f3511 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.h @@ -42,23 +42,24 @@ class RigGridBase; class RigGridCellFaceVisibilityFilter; class RigMainGrid; class Rim3dOverlayInfoConfig; -class RimEclipseCase; -class RimEclipseWell; class RimCellEdgeColors; -class RimEclipsePropertyFilter; -class RimEclipsePropertyFilterCollection; class RimCellRangeFilter; class RimCellRangeFilterCollection; -class RimFaultCollection; -class RimEclipseFaultColors; -class RimReservoirCellResultsStorage; -class RimReservoirCellResultsStorage; +class RimEclipseCase; class RimEclipseCellColors; +class RimEclipseFaultColors; +class RimEclipsePropertyFilter; +class RimEclipsePropertyFilterCollection; +class RimEclipseWell; class RimEclipseWellCollection; +class RimFaultCollection; +class RimReservoirCellResultsStorage; +class RimReservoirCellResultsStorage; +class RimStimPlanColors; class RiuViewer; +class RivIntersectionPartMgr; class RivReservoirPipesPartMgr; class RivReservoirWellSpheresPartMgr; -class RivIntersectionPartMgr; namespace cvf { @@ -89,9 +90,10 @@ public: // Fields containing child objects : - caf::PdmChildField cellResult; - caf::PdmChildField cellEdgeResult; - caf::PdmChildField faultResultSettings; + caf::PdmChildField cellResult; + caf::PdmChildField cellEdgeResult; + caf::PdmChildField faultResultSettings; + caf::PdmChildField stimPlanColors; caf::PdmChildField wellCollection; caf::PdmChildField faultCollection; diff --git a/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.cpp b/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.cpp index 563ba77639..85e5c56c9d 100644 --- a/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.cpp @@ -50,6 +50,62 @@ RimFractureTemplateCollection::~RimFractureTemplateCollection() fractureDefinitions.deleteAllChildObjects(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector > RimFractureTemplateCollection::stimPlanResultNamesAndUnits() const +{ + std::set > nameSet; + + for (const RimFractureTemplate* f : fractureDefinitions()) + { + auto stimPlanFracture = dynamic_cast(f); + if (stimPlanFracture) + { + std::vector > namesAndUnits = stimPlanFracture->getStimPlanPropertyNamesUnits(); + + for (auto nameAndUnit : namesAndUnits) + { + nameSet.insert(nameAndUnit); + } + } + } + + std::vector> names(nameSet.begin(), nameSet.end()); + + return names; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimFractureTemplateCollection::stimPlanResultNames() const +{ + std::vector names; + + for (auto nameAndUnit : stimPlanResultNamesAndUnits()) + { + names.push_back(nameAndUnit.first); + } + + return names; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureTemplateCollection::computeMinMax(const QString& resultName, const QString& unit, double* minValue, double* maxValue) const +{ + for (const RimFractureTemplate* f : fractureDefinitions()) + { + auto stimPlanFracture = dynamic_cast(f); + if (stimPlanFracture) + { + stimPlanFracture->computeMinMax(resultName, unit, minValue, maxValue); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.h b/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.h index 521f662c8a..1b606fd31b 100644 --- a/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.h +++ b/ApplicationCode/ProjectDataModel/RimFractureTemplateCollection.h @@ -44,6 +44,9 @@ public: caf::PdmField< caf::AppEnum< RimDefines::UnitSystem > > defaultUnitsForFracTemplates; + std::vector > stimPlanResultNamesAndUnits() const; + std::vector stimPlanResultNames() const; + void computeMinMax(const QString& resultName, const QString& unit, double* minValue, double* maxValue) const; void deleteFractureDefinitions(); void loadAndUpdateData(); diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp b/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp new file mode 100644 index 0000000000..9ef3929a50 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp @@ -0,0 +1,278 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 - Statoil 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimStimPlanColors.h" + +#include "RimEclipseView.h" +#include "RimFractureTemplateCollection.h" +#include "RimLegendConfig.h" +#include "RimOilField.h" +#include "RimProject.h" + +#include "cafPdmUiItem.h" +#include "cafPdmUiTreeOrdering.h" + +#include "cvfqtUtils.h" + +#include // Needed for HUGE_VAL on Linux + + + +CAF_PDM_SOURCE_INIT(RimStimPlanColors, "RimStimPlanColors"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStimPlanColors::RimStimPlanColors() +{ + CAF_PDM_InitObject("StimPlan Colors", ":/draw_style_faults_24x24.png", "", ""); + + CAF_PDM_InitField(&m_resultNameAndUnit, "ResultName", QString(""), "Result Variable", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_legendConfigurations, "LegendConfigurations", "", "", "", ""); + m_legendConfigurations.uiCapability()->setUiTreeHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStimPlanColors::~RimStimPlanColors() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStimPlanColors::loadDataAndUpdate() +{ + RimFractureTemplateCollection* fractureTemplates = fractureTemplateCollection(); + + std::vector > resultNameAndUnits = fractureTemplates->stimPlanResultNamesAndUnits(); + + // Delete legends referencing results not present on file + { + std::vector toBeDeleted; + for (RimLegendConfig* legend : m_legendConfigurations) + { + QString legendVariableName = legend->resultVariableName(); + + bool found = false; + for (auto resultNameAndUnit : resultNameAndUnits) + { + if (RimStimPlanColors::toString(resultNameAndUnit) == legendVariableName) + { + found = true; + } + } + + if (!found) + { + toBeDeleted.push_back(legend); + } + } + + for (auto legend : toBeDeleted) + { + m_legendConfigurations.removeChildObject(legend); + + delete legend; + } + } + + // Create legend for result if not already present + for (auto resultNameAndUnit : resultNameAndUnits) + { + QString resultNameUnitString = RimStimPlanColors::toString(resultNameAndUnit); + bool foundResult = false; + + for (RimLegendConfig* legend : m_legendConfigurations) + { + if (legend->resultVariableName() == resultNameUnitString) + { + foundResult = true; + } + } + + if (!foundResult) + { + RimLegendConfig* legendConfig = new RimLegendConfig(); + legendConfig->resultVariableName = resultNameUnitString; + + m_legendConfigurations.push_back(legendConfig); + } + } + + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimStimPlanColors::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_resultNameAndUnit) + { + RimFractureTemplateCollection* fractureTemplates = fractureTemplateCollection(); + + options.push_back(caf::PdmOptionItemInfo("None", "None")); + + for (auto resultNameAndUnit : fractureTemplates->stimPlanResultNamesAndUnits()) + { + QString resultNameAndUnitString = RimStimPlanColors::toString(resultNameAndUnit); + options.push_back(caf::PdmOptionItemInfo(resultNameAndUnitString, resultNameAndUnitString)); + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStimPlanColors::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimEclipseView* sourceView = nullptr; + this->firstAncestorOrThisOfType(sourceView); + if (sourceView) + { + sourceView->scheduleCreateDisplayModelAndRedraw(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimLegendConfig* RimStimPlanColors::activeLegend() const +{ + for (RimLegendConfig* legendConfig : m_legendConfigurations) + { + if (m_resultNameAndUnit == legendConfig->resultVariableName()) + { + return legendConfig; + } + } + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimStimPlanColors::resultName() const +{ + return RimStimPlanColors::toResultName(m_resultNameAndUnit()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimStimPlanColors::unit() const +{ + return RimStimPlanColors::toUnit(m_resultNameAndUnit()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStimPlanColors::updateLegendData() +{ + RimLegendConfig* legendConfig = activeLegend(); + if (legendConfig) + { + double minValue = HUGE_VAL; + double maxValue = -HUGE_VAL; + + RimFractureTemplateCollection* fracTemplateColl = fractureTemplateCollection(); + + fracTemplateColl->computeMinMax(resultName(), unit(), &minValue, &maxValue); + + if (minValue != HUGE_VAL) + { + legendConfig->setAutomaticRanges(minValue, maxValue, minValue, maxValue); + } + + legendConfig->setTitle(cvfqt::Utils::toString(m_resultNameAndUnit())); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFractureTemplateCollection* RimStimPlanColors::fractureTemplateCollection() const +{ + RimProject* proj = nullptr; + this->firstAncestorOrThisOfType(proj); + + return proj->activeOilField()->fractureDefinitionCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimStimPlanColors::toString(const std::pair& resultNameAndUnit) +{ + return QString("%1 [%2]").arg(resultNameAndUnit.first).arg(resultNameAndUnit.second); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimStimPlanColors::toResultName(const QString& resultNameAndUnit) +{ + QStringList items = resultNameAndUnit.split("["); + + if (items.size() > 0) + { + return items[0].trimmed(); + } + + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimStimPlanColors::toUnit(const QString& resultNameAndUnit) +{ + int start = resultNameAndUnit.indexOf("["); + int end = resultNameAndUnit.indexOf("]"); + + if (start != -1 && end != -1) + { + return resultNameAndUnit.mid(start + 1, end - start - 1); + } + + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStimPlanColors::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + if (activeLegend()) + { + uiTreeOrdering.add(activeLegend()); + } + + uiTreeOrdering.setForgetRemainingFields(true); +} + diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanColors.h b/ApplicationCode/ProjectDataModel/RimStimPlanColors.h new file mode 100644 index 0000000000..b7105b43ac --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStimPlanColors.h @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017 - Statoil 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafAppEnum.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmChildArrayField.h" + +namespace caf { + class PdmOptionItemInfo; +} + +class RimLegendConfig; +class RimFractureTemplateCollection; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimStimPlanColors : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimStimPlanColors(); + virtual ~RimStimPlanColors(); + + RimLegendConfig* activeLegend() const; + + QString resultName() const; + QString unit() const; + + void loadDataAndUpdate(); + void updateLegendData(); + +protected: + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + +private: + RimFractureTemplateCollection* fractureTemplateCollection() const; + static QString toString(const std::pair& resultNameAndUnit); + + static QString toResultName(const QString& resultNameAndUnit); + static QString toUnit(const QString& resultNameAndUnit); + +private: + caf::PdmField m_resultNameAndUnit; + caf::PdmChildArrayField m_legendConfigurations; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.cpp b/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.cpp index bd55ad1063..4de5fbde04 100644 --- a/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.cpp +++ b/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.cpp @@ -306,9 +306,9 @@ void RimStimPlanFractureTemplate::loadDataAndUpdate() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector> RimStimPlanFractureTemplate::getDataAtTimeIndex(QString resultName, size_t timeStepIndex) +std::vector> RimStimPlanFractureTemplate::getDataAtTimeIndex(const QString& resultName, const QString& unitName, size_t timeStepIndex) const { - return m_stimPlanFractureDefinitionData->getDataAtTimeIndex(resultName, timeStepIndex); + return m_stimPlanFractureDefinitionData->getDataAtTimeIndex(resultName, unitName, timeStepIndex); } //-------------------------------------------------------------------------------------------------- @@ -348,8 +348,6 @@ void RimStimPlanFractureTemplate::readStimplanGridAndTimesteps(QXmlStreamReader } } } - - } //-------------------------------------------------------------------------------------------------- @@ -565,7 +563,6 @@ std::vector RimStimPlanFractureTemplate::adjustedDepthCoordsAroundWellP //-------------------------------------------------------------------------------------------------- std::vector RimStimPlanFractureTemplate::getStimPlanTimeValues() { - if (m_stimPlanFractureDefinitionData.isNull()) loadDataAndUpdate(); return m_stimPlanFractureDefinitionData->timeSteps; } @@ -573,7 +570,7 @@ std::vector RimStimPlanFractureTemplate::getStimPlanTimeValues() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector > RimStimPlanFractureTemplate::getStimPlanPropertyNamesUnits() +std::vector > RimStimPlanFractureTemplate::getStimPlanPropertyNamesUnits() const { std::vector allStimPlanData = m_stimPlanFractureDefinitionData->stimPlanData; std::vector > propertyNamesUnits; @@ -584,6 +581,17 @@ std::vector > RimStimPlanFractureTemplate::getStimPl return propertyNamesUnits; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStimPlanFractureTemplate::computeMinMax(const QString& resultName, const QString& unitName, double* minValue, double* maxValue) const +{ + if (m_stimPlanFractureDefinitionData.notNull()) + { + m_stimPlanFractureDefinitionData->computeMinMax(resultName, unitName, minValue, maxValue); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -592,7 +600,7 @@ std::vector RimStimPlanFractureTemplate::fracturePolygon() std::vector polygon; //TODO: Handle multiple time-step and properties - std::vector> dataAtTimeStep = m_stimPlanFractureDefinitionData->getDataAtTimeIndex(getStimPlanPropertyNamesUnits()[0].first, 0); + std::vector> dataAtTimeStep = m_stimPlanFractureDefinitionData->getDataAtTimeIndex(getStimPlanPropertyNamesUnits()[0].first, getStimPlanPropertyNamesUnits()[0].second, 0); for (int k = 0; k < dataAtTimeStep.size(); k++) { diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.h b/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.h index 5ee05e8703..fb6b7cb8f4 100644 --- a/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.h +++ b/ApplicationCode/ProjectDataModel/RimStimPlanFractureTemplate.h @@ -62,11 +62,13 @@ public: std::vector getNegAndPosXcoords(); std::vector adjustedDepthCoordsAroundWellPathPosition(); std::vector getStimPlanTimeValues(); - std::vector > getStimPlanPropertyNamesUnits(); + std::vector > getStimPlanPropertyNamesUnits() const; + void computeMinMax(const QString& resultName, const QString& unitName, double* minValue, double* maxValue) const; void loadDataAndUpdate(); - std::vector> getDataAtTimeIndex(QString resultName, size_t timeStepIndex); + std::vector> getDataAtTimeIndex(const QString& resultName, const QString& unitName, size_t timeStepIndex) const; + protected: virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; diff --git a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp index ca7342fed2..962fb0d378 100644 --- a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp +++ b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp @@ -20,6 +20,8 @@ #include +#include "cvfMath.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -90,20 +92,32 @@ size_t RigStimPlanFractureDefinition::getTimeStepIndex(double timeStepValue) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigStimPlanFractureDefinition::setDataAtTimeValue(QString resultName, QString unit, std::vector> data, double timeStepValue) +size_t RigStimPlanFractureDefinition::resultIndex(const QString& resultName, const QString& unit) const { - bool resultNameExists = false; - for (RigStimPlanData& resultData : stimPlanData) + + for (size_t i = 0; i < stimPlanData.size(); i++) { - if (resultData.resultName == resultName) + if (stimPlanData[i].resultName == resultName && stimPlanData[i].unit == unit) { - resultNameExists = true; - resultData.parameterValues[getTimeStepIndex(timeStepValue)] = data; - return; + return i; } } - if (!resultNameExists) + return cvf::UNDEFINED_SIZE_T; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStimPlanFractureDefinition::setDataAtTimeValue(QString resultName, QString unit, std::vector> data, double timeStepValue) +{ + size_t resIndex = resultIndex(resultName, unit); + + if (resIndex != cvf::UNDEFINED_SIZE_T) + { + stimPlanData[resIndex].parameterValues[getTimeStepIndex(timeStepValue)] = data; + } + else { RigStimPlanData resultData; @@ -116,21 +130,18 @@ void RigStimPlanFractureDefinition::setDataAtTimeValue(QString resultName, QStri stimPlanData.push_back(resultData); } - - } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector> RigStimPlanFractureDefinition::getDataAtTimeIndex(QString resultName, size_t timeStepIndex) +std::vector> RigStimPlanFractureDefinition::getDataAtTimeIndex(const QString& resultName, const QString& unit, size_t timeStepIndex) const { - for (RigStimPlanData& resultData : stimPlanData) + size_t resIndex = resultIndex(resultName, unit); + + if (resIndex != cvf::UNDEFINED_SIZE_T) { - if (resultData.resultName == resultName) - { - return resultData.parameterValues[timeStepIndex]; - } + return stimPlanData[resIndex].parameterValues[timeStepIndex]; } qDebug() << "ERROR: Requested parameter does not exists in stimPlan data"; @@ -138,6 +149,36 @@ std::vector> RigStimPlanFractureDefinition::getDataAtTimeInd return emptyVector; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStimPlanFractureDefinition::computeMinMax(const QString& resultName, const QString& unit, double* minValue, double* maxValue) const +{ + CVF_ASSERT(minValue && maxValue); + + size_t resIndex = resultIndex(resultName, unit); + if (resIndex == cvf::UNDEFINED_SIZE_T) return; + + for (auto timeValues : stimPlanData[resIndex].parameterValues) + { + for (auto values : timeValues) + { + for (auto resultValue : values) + { + if (resultValue < *minValue) + { + *minValue = resultValue; + } + + if (resultValue > *maxValue) + { + *maxValue = resultValue; + } + } + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h index 8a2f8dd4e4..cc2c3b0d13 100644 --- a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h +++ b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h @@ -58,10 +58,14 @@ public: size_t getTimeStepIndex(double timeStepValue); void setDataAtTimeValue(QString resultName, QString unit, std::vector> data, double timeStepValue); - std::vector> getDataAtTimeIndex(QString resultName, size_t timeStepIndex); + std::vector> getDataAtTimeIndex(const QString& resultName, const QString& unit, size_t timeStepIndex) const; + void computeMinMax(const QString& resultName, const QString& unit, double* minValue, double* maxValue) const; std::vector resultNames() const; +private: + size_t resultIndex(const QString& resultName, const QString& unit) const; + };