diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp index f5912678d2..72a3507428 100644 --- a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp @@ -97,6 +97,36 @@ RimContourMapProjection::RimContourMapProjection() //-------------------------------------------------------------------------------------------------- RimContourMapProjection::~RimContourMapProjection() {} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::generateResultsIfNecessary(int timeStep) +{ + updateGridInformation(); + + if (gridMappingNeedsUpdating()) + { + generateGridMapping(); + } + + if (resultsNeedsUpdating(timeStep)) + { + generateResults(timeStep); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::generateGeometryIfNecessary() +{ + if (geometryNeedsUpdating()) + { + generateContourPolygons(); + generateTrianglesWithVertexValues(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -133,31 +163,10 @@ std::vector RimContourMapProjection::generatePickPointPolygon() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::generateResultsIfNecessary(int timeStep) +void RimContourMapProjection::clearGeometry() { - updateGridInformation(); - - if (gridMappingNeedsUpdating()) - { - generateGridMapping(); - } - - if (resultsNeedUpdating(timeStep)) - { - generateResults(timeStep); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::generateGeometryIfNecessary() -{ - if (geometryNeedsUpdating()) - { - generateContourPolygons(); - generateTrianglesWithVertexValues(); - } + m_contourPolygons.clear(); + m_trianglesWithVertexValues.clear(); } //-------------------------------------------------------------------------------------------------- @@ -398,124 +407,6 @@ bool RimContourMapProjection::checkForMapIntersection(const cvf::Vec3d& localPoi return false; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::smoothContourPolygons(ContourPolygons* contourPolygons, - const ContourPolygons* clipBy, - bool favourExpansion) -{ - CVF_ASSERT(contourPolygons); - for (size_t i = 0; i < contourPolygons->size(); ++i) - { - ContourPolygon& polygon = contourPolygons->at(i); - - for (size_t n = 0; n < 20; ++n) - { - std::vector newVertices; - newVertices.resize(polygon.vertices.size()); - double maxChange = 0.0; - for (size_t j = 0; j < polygon.vertices.size(); ++j) - { - cvf::Vec3d vm1 = polygon.vertices.back(); - cvf::Vec3d v = polygon.vertices[j]; - cvf::Vec3d vp1 = polygon.vertices.front(); - if (j > 0u) - { - vm1 = polygon.vertices[j - 1]; - } - if (j < polygon.vertices.size() - 1) - { - vp1 = polygon.vertices[j + 1]; - } - // Only expand. - cvf::Vec3d modifiedVertex = 0.5 * (v + 0.5 * (vm1 + vp1)); - cvf::Vec3d delta = (modifiedVertex - v).getNormalized(); - cvf::Vec3d tangent3d = vp1 - vm1; - cvf::Vec2d tangent2d(tangent3d.x(), tangent3d.y()); - cvf::Vec3d norm3d(tangent2d.getNormalized().perpendicularVector()); - if (delta * norm3d > 0 && favourExpansion) - { - // Normal is always inwards facing so a positive dot product means inward movement - // Favour expansion rather than contraction by only contracting by half the amount - modifiedVertex = v + 0.5 * delta; - } - newVertices[j] = modifiedVertex; - maxChange = std::max(maxChange, (modifiedVertex - v).length()); - } - polygon.vertices.swap(newVertices); - if (maxChange < m_sampleSpacing * 1.0e-2) break; - } - if (clipBy) - { - for (size_t j = 0; j < clipBy->size(); ++j) - { - std::vector> intersections = - RigCellGeometryTools::intersectPolygons(polygon.vertices, clipBy->at(j).vertices); - if (!intersections.empty()) - { - polygon.vertices = intersections.front(); - } - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimContourMapProjection::interpolateValue(const cvf::Vec2d& gridPos2d) const -{ - cvf::Vec2ui cellContainingPoint = ijFromLocalPos(gridPos2d); - cvf::Vec2d cellCenter = cellCenterPosition(cellContainingPoint.x(), cellContainingPoint.y()); - - std::array x; - x[0] = cvf::Vec3d(cellCenter + cvf::Vec2d(-m_sampleSpacing * 0.5, -m_sampleSpacing * 0.5), 0.0); - x[1] = cvf::Vec3d(cellCenter + cvf::Vec2d(m_sampleSpacing * 0.5, -m_sampleSpacing * 0.5), 0.0); - x[2] = cvf::Vec3d(cellCenter + cvf::Vec2d(m_sampleSpacing * 0.5, m_sampleSpacing * 0.5), 0.0); - x[3] = cvf::Vec3d(cellCenter + cvf::Vec2d(-m_sampleSpacing * 0.5, m_sampleSpacing * 0.5), 0.0); - - cvf::Vec4d baryCentricCoords = cvf::GeometryTools::barycentricCoords(x[0], x[1], x[2], x[3], cvf::Vec3d(gridPos2d, 0.0)); - - std::array v; - v[0] = cellContainingPoint; - v[1] = cvf::Vec2ui(cellContainingPoint.x() + 1u, cellContainingPoint.y()); - v[2] = cvf::Vec2ui(cellContainingPoint.x() + 1u, cellContainingPoint.y() + 1u); - v[3] = cvf::Vec2ui(cellContainingPoint.x(), cellContainingPoint.y() + 1u); - - std::array vertexValues; - double validBarycentricCoordsSum = 0.0; - for (int i = 0; i < 4; ++i) - { - double vertexValue = valueAtVertex(v[i].x(), v[i].y()); - if (vertexValue == std::numeric_limits::infinity()) - { - baryCentricCoords[i] = 0.0; - vertexValues[i] = 0.0; - return std::numeric_limits::infinity(); - } - else - { - vertexValues[i] = vertexValue; - validBarycentricCoordsSum += baryCentricCoords[i]; - } - } - - if (validBarycentricCoordsSum < 1.0e-8) - { - return std::numeric_limits::infinity(); - } - - // Calculate final value - double value = 0.0; - for (int i = 0; i < 4; ++i) - { - value += baryCentricCoords[i] / validBarycentricCoordsSum * vertexValues[i]; - } - - return value; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -535,89 +426,67 @@ cvf::Vec3d RimContourMapProjection::origin3d() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue) +bool RimContourMapProjection::gridMappingNeedsUpdating() const { - legendConfig()->disableAllTimeStepsRange(!getLegendRangeFrom3dGrid()); - - if (changedField == &m_resultAggregation) + if (m_projected3dGridIndices.size() != numberOfCells()) { - ResultAggregation previousAggregation = static_cast(oldValue.toInt()); - if (isStraightSummationResult(previousAggregation) != isStraightSummationResult()) - { - clearGridMapping(); - } - else - { - clearResults(); - } + return true; } - else if (changedField == &m_smoothContourLines) - { - clearGeometry(); - } - else if (changedField == &m_relativeSampleSpacing) - { - clearResults(); - } - - baseView()->updateConnectedEditors(); - - RimProject* proj; - firstAncestorOrThisOfTypeAsserted(proj); - proj->scheduleCreateDisplayModelAndRedrawAllViews(); + return gridMappingImplNeedsUpdating(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::defineEditorAttribute(const caf::PdmFieldHandle* field, - QString uiConfigName, - caf::PdmUiEditorAttribute* attribute) +bool RimContourMapProjection::resultsNeedsUpdating(int timeStep) const { - if (&m_relativeSampleSpacing == field) + if (m_aggregatedResults.size() != numberOfCells()) { - caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); - if (myAttr) - { - myAttr->m_minimum = 0.25; - myAttr->m_maximum = 2.0; - } + return true; } + + if (m_aggregatedVertexResults.size() != numberOfVertices()) + { + return true; + } + + if (timeStep != m_currentResultTimestep) + { + return true; + } + return resultsImplNeedsUpdating(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +bool RimContourMapProjection::geometryNeedsUpdating() const { - caf::PdmUiGroup* mainGroup = uiOrdering.addNewGroup("Projection Settings"); - mainGroup->add(&m_relativeSampleSpacing); - mainGroup->add(&m_showContourLines); - mainGroup->add(&m_showContourLabels); - m_showContourLabels.uiCapability()->setUiReadOnly(!m_showContourLines()); - mainGroup->add(&m_smoothContourLines); - m_smoothContourLines.uiCapability()->setUiReadOnly(!m_showContourLines()); - mainGroup->add(&m_resultAggregation); - - uiOrdering.skipRemainingFields(true); + return m_contourPolygons.empty() || m_trianglesWithVertexValues.empty(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +void RimContourMapProjection::clearGridMapping() { - uiTreeOrdering.skipRemainingChildren(true); + clearResults(); + + m_projected3dGridIndices.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::initAfterRead() +void RimContourMapProjection::clearResults() { - legendConfig()->disableAllTimeStepsRange(!getLegendRangeFrom3dGrid()); + clearGeometry(); + + m_aggregatedResults.clear(); + m_aggregatedVertexResults.clear(); + m_currentResultTimestep = -1; + + clearImplSpecificResultData(); } //-------------------------------------------------------------------------------------------------- @@ -900,72 +769,153 @@ void RimContourMapProjection::generateContourPolygons() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::gridMappingNeedsUpdating() const +void RimContourMapProjection::smoothContourPolygons(ContourPolygons* contourPolygons, + const ContourPolygons* clipBy, + bool favourExpansion) { - if (m_projected3dGridIndices.size() != numberOfCells()) + CVF_ASSERT(contourPolygons); + for (size_t i = 0; i < contourPolygons->size(); ++i) { - return true; + ContourPolygon& polygon = contourPolygons->at(i); + + for (size_t n = 0; n < 20; ++n) + { + std::vector newVertices; + newVertices.resize(polygon.vertices.size()); + double maxChange = 0.0; + for (size_t j = 0; j < polygon.vertices.size(); ++j) + { + cvf::Vec3d vm1 = polygon.vertices.back(); + cvf::Vec3d v = polygon.vertices[j]; + cvf::Vec3d vp1 = polygon.vertices.front(); + if (j > 0u) + { + vm1 = polygon.vertices[j - 1]; + } + if (j < polygon.vertices.size() - 1) + { + vp1 = polygon.vertices[j + 1]; + } + // Only expand. + cvf::Vec3d modifiedVertex = 0.5 * (v + 0.5 * (vm1 + vp1)); + cvf::Vec3d delta = (modifiedVertex - v).getNormalized(); + cvf::Vec3d tangent3d = vp1 - vm1; + cvf::Vec2d tangent2d(tangent3d.x(), tangent3d.y()); + cvf::Vec3d norm3d(tangent2d.getNormalized().perpendicularVector()); + if (delta * norm3d > 0 && favourExpansion) + { + // Normal is always inwards facing so a positive dot product means inward movement + // Favour expansion rather than contraction by only contracting by half the amount + modifiedVertex = v + 0.5 * delta; + } + newVertices[j] = modifiedVertex; + maxChange = std::max(maxChange, (modifiedVertex - v).length()); + } + polygon.vertices.swap(newVertices); + if (maxChange < m_sampleSpacing * 1.0e-2) break; + } + if (clipBy) + { + for (size_t j = 0; j < clipBy->size(); ++j) + { + std::vector> intersections = + RigCellGeometryTools::intersectPolygons(polygon.vertices, clipBy->at(j).vertices); + if (!intersections.empty()) + { + polygon.vertices = intersections.front(); + } + } + } } - return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::resultsNeedUpdating(int timeStep) const +bool RimContourMapProjection::isMeanResult() const { - if (m_aggregatedResults.size() != numberOfCells()) + return m_resultAggregation() == RESULTS_MEAN_VALUE || m_resultAggregation() == RESULTS_HARM_VALUE || + m_resultAggregation() == RESULTS_GEOM_VALUE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isSummationResult() const +{ + return isStraightSummationResult() || m_resultAggregation() == RESULTS_VOLUME_SUM; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isStraightSummationResult() const +{ + return isStraightSummationResult(m_resultAggregation()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isStraightSummationResult(ResultAggregationEnum aggregationType) +{ + return aggregationType == RESULTS_OIL_COLUMN || aggregationType == RESULTS_GAS_COLUMN || + aggregationType == RESULTS_HC_COLUMN || aggregationType == RESULTS_SUM; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::interpolateValue(const cvf::Vec2d& gridPos2d) const +{ + cvf::Vec2ui cellContainingPoint = ijFromLocalPos(gridPos2d); + cvf::Vec2d cellCenter = cellCenterPosition(cellContainingPoint.x(), cellContainingPoint.y()); + + std::array x; + x[0] = cvf::Vec3d(cellCenter + cvf::Vec2d(-m_sampleSpacing * 0.5, -m_sampleSpacing * 0.5), 0.0); + x[1] = cvf::Vec3d(cellCenter + cvf::Vec2d(m_sampleSpacing * 0.5, -m_sampleSpacing * 0.5), 0.0); + x[2] = cvf::Vec3d(cellCenter + cvf::Vec2d(m_sampleSpacing * 0.5, m_sampleSpacing * 0.5), 0.0); + x[3] = cvf::Vec3d(cellCenter + cvf::Vec2d(-m_sampleSpacing * 0.5, m_sampleSpacing * 0.5), 0.0); + + cvf::Vec4d baryCentricCoords = cvf::GeometryTools::barycentricCoords(x[0], x[1], x[2], x[3], cvf::Vec3d(gridPos2d, 0.0)); + + std::array v; + v[0] = cellContainingPoint; + v[1] = cvf::Vec2ui(cellContainingPoint.x() + 1u, cellContainingPoint.y()); + v[2] = cvf::Vec2ui(cellContainingPoint.x() + 1u, cellContainingPoint.y() + 1u); + v[3] = cvf::Vec2ui(cellContainingPoint.x(), cellContainingPoint.y() + 1u); + + std::array vertexValues; + double validBarycentricCoordsSum = 0.0; + for (int i = 0; i < 4; ++i) { - return true; + double vertexValue = valueAtVertex(v[i].x(), v[i].y()); + if (vertexValue == std::numeric_limits::infinity()) + { + baryCentricCoords[i] = 0.0; + vertexValues[i] = 0.0; + return std::numeric_limits::infinity(); + } + else + { + vertexValues[i] = vertexValue; + validBarycentricCoordsSum += baryCentricCoords[i]; + } } - if (m_aggregatedVertexResults.size() != numberOfVertices()) + if (validBarycentricCoordsSum < 1.0e-8) { - return true; + return std::numeric_limits::infinity(); } - if (timeStep != m_currentResultTimestep) + // Calculate final value + double value = 0.0; + for (int i = 0; i < 4; ++i) { - return true; + value += baryCentricCoords[i] / validBarycentricCoordsSum * vertexValues[i]; } - return false; -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::geometryNeedsUpdating() const -{ - return m_contourPolygons.empty() || m_trianglesWithVertexValues.empty(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::clearGridMapping() -{ - m_projected3dGridIndices.clear(); - clearResults(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::clearResults() -{ - m_aggregatedResults.clear(); - m_aggregatedVertexResults.clear(); - m_currentResultTimestep = -1; - clearGeometry(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimContourMapProjection::clearGeometry() -{ - m_contourPolygons.clear(); - m_trianglesWithVertexValues.clear(); + return value; } //-------------------------------------------------------------------------------------------------- @@ -1033,40 +983,6 @@ std::vector> RimContourMapProjection::cellsAtIJ(uint i return std::vector>(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isMeanResult() const -{ - return m_resultAggregation() == RESULTS_MEAN_VALUE || m_resultAggregation() == RESULTS_HARM_VALUE || - m_resultAggregation() == RESULTS_GEOM_VALUE; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isSummationResult() const -{ - return isStraightSummationResult() || m_resultAggregation() == RESULTS_VOLUME_SUM; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isStraightSummationResult() const -{ - return isStraightSummationResult(m_resultAggregation()); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::isStraightSummationResult(ResultAggregationEnum aggregationType) -{ - return aggregationType == RESULTS_OIL_COLUMN || aggregationType == RESULTS_GAS_COLUMN || - aggregationType == RESULTS_HC_COLUMN || aggregationType == RESULTS_SUM; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1180,17 +1096,17 @@ std::vector RimContourMapProjection::yVertexPositions() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimContourMapProjection::getLegendRangeFrom3dGrid() const +bool RimContourMapProjection::use2dMapLegendRange() const { - if (isMeanResult()) - { - return true; - } - else if (m_resultAggregation == RESULTS_TOP_VALUE) - { - return true; - } - return false; + return !use3dGridLegendRange(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::use3dGridLegendRange() const +{ + return (isMeanResult() || m_resultAggregation == RESULTS_TOP_VALUE); } //-------------------------------------------------------------------------------------------------- @@ -1214,4 +1130,90 @@ double RimContourMapProjection::gridEdgeOffset() const return m_sampleSpacing * 2.0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + legendConfig()->disableAllTimeStepsRange(use2dMapLegendRange()); + if (changedField == &m_resultAggregation) + { + ResultAggregation previousAggregation = static_cast(oldValue.toInt()); + if (isStraightSummationResult(previousAggregation) != isStraightSummationResult()) + { + clearGridMapping(); + } + else + { + clearResults(); + } + } + else if (changedField == &m_smoothContourLines) + { + clearGeometry(); + } + else if (changedField == &m_relativeSampleSpacing) + { + clearResults(); + } + + baseView()->updateConnectedEditors(); + + RimProject* proj; + firstAncestorOrThisOfTypeAsserted(proj); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + if (&m_relativeSampleSpacing == field) + { + caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + myAttr->m_minimum = 0.25; + myAttr->m_maximum = 2.0; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* mainGroup = uiOrdering.addNewGroup("Projection Settings"); + mainGroup->add(&m_relativeSampleSpacing); + mainGroup->add(&m_showContourLines); + mainGroup->add(&m_showContourLabels); + m_showContourLabels.uiCapability()->setUiReadOnly(!m_showContourLines()); + mainGroup->add(&m_smoothContourLines); + m_smoothContourLines.uiCapability()->setUiReadOnly(!m_showContourLines()); + mainGroup->add(&m_resultAggregation); + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.skipRemainingChildren(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::initAfterRead() +{ + legendConfig()->disableAllTimeStepsRange(use2dMapLegendRange()); +} diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h index 56a0495366..17acab447b 100644 --- a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h @@ -42,6 +42,8 @@ class RimContourMapProjection : public RimCheckableNamedObject CAF_PDM_HEADER_INIT; public: + typedef std::pair CellIndexAndResult; + struct ContourPolygon { std::vector vertices; @@ -85,7 +87,6 @@ public: bool showContourLabels() const; QString resultAggregationText() const; - virtual QString resultDescriptionText() const = 0; double maxValue() const; double minValue() const; @@ -100,9 +101,6 @@ public: double valueAtVertex(uint i, uint j) const; bool hasResultAtVertex(uint i, uint j) const; - virtual RimRegularLegendConfig* legendConfig() const = 0; - virtual void updateLegend() = 0; - uint numberOfCells() const; uint numberOfValidCells() const; size_t numberOfVertices() const; @@ -111,68 +109,72 @@ public: void setPickPoint(cvf::Vec2d globalPickPoint); cvf::Vec3d origin3d() const; -protected: - typedef std::pair CellIndexAndResult; + // Pure-virtual public methods which should be overridden by Eclipse and Geo-mechanical contour map implementations + virtual QString resultDescriptionText() const = 0; + virtual RimRegularLegendConfig* legendConfig() const = 0; + virtual void updateLegend() = 0; protected: - void smoothContourPolygons(ContourPolygons* contourPolygons, const ContourPolygons* clipBy, bool favourExpansion); + // Protected virtual methods to be overridden by Eclipse and Geo-mechanical contour map implementations + virtual void updateGridInformation() = 0; + virtual void generateGridMapping() = 0; + virtual void generateResults(int timeStep) = 0; + virtual bool gridMappingImplNeedsUpdating() const = 0; + virtual bool resultsImplNeedsUpdating() const = 0; + virtual void clearImplSpecificResultData() = 0; + virtual RimGridView* baseView() const = 0; + +protected: + // Keep track of whether cached data needs updating + bool gridMappingNeedsUpdating() const; + bool resultsNeedsUpdating(int timeStep) const; + bool geometryNeedsUpdating() const; + void clearGridMapping(); + void clearResults(); + + void generateTrianglesWithVertexValues(); + std::vector generateVertices() const; + void generateContourPolygons(); + void smoothContourPolygons(ContourPolygons* contourPolygons, const ContourPolygons* clipBy, bool favourExpansion); + + bool isMeanResult() const; + bool isSummationResult() const; + bool isStraightSummationResult() const; + static bool isStraightSummationResult(ResultAggregationEnum aggregationType); + double interpolateValue(const cvf::Vec2d& gridPosition2d) const; + double valueInCell(uint i, uint j) const; + bool hasResultInCell(uint i, uint j) const; + double calculateValueAtVertex(uint i, uint j) const; + // Cell index and position conversion + std::vector cellsAtIJ(uint i, uint j) const; + size_t cellIndexFromIJ(uint i, uint j) const; + size_t vertexIndexFromIJ(uint i, uint j) const; + cvf::Vec2ui ijFromVertexIndex(size_t gridIndex) const; + cvf::Vec2ui ijFromCellIndex(size_t mapIndex) const; + cvf::Vec2ui ijFromLocalPos(const cvf::Vec2d& localPos2d) const; + cvf::Vec2d cellCenterPosition(uint i, uint j) const; + cvf::Vec2d origin2d() const; + + std::vector xVertexPositions() const; + std::vector yVertexPositions() const; + + bool use2dMapLegendRange() const; + bool use3dGridLegendRange() const; + cvf::Vec2ui calculateMapSize() const; + double gridEdgeOffset() const; + + protected: + // Framework overrides void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - void initAfterRead() override; - - virtual void generateGridMapping() = 0; - virtual void generateResults(int timeStep) = 0; - - void generateTrianglesWithVertexValues(); - std::vector generateVertices() const; - void generateContourPolygons(); - - virtual bool gridMappingNeedsUpdating() const; - virtual bool resultsNeedUpdating(int timeStep) const; - - bool geometryNeedsUpdating() const; - void clearGridMapping(); - virtual void clearResults(); - - double valueInCell(uint i, uint j) const; - bool hasResultInCell(uint i, uint j) const; - - double calculateValueAtVertex(uint i, uint j) const; - - std::vector cellsAtIJ(uint i, uint j) const; - - bool isMeanResult() const; - bool isSummationResult() const; - bool isStraightSummationResult() const; - static bool isStraightSummationResult(ResultAggregationEnum aggregationType); - - size_t cellIndexFromIJ(uint i, uint j) const; - size_t vertexIndexFromIJ(uint i, uint j) const; - - cvf::Vec2ui ijFromVertexIndex(size_t gridIndex) const; - cvf::Vec2ui ijFromCellIndex(size_t mapIndex) const; - cvf::Vec2ui ijFromLocalPos(const cvf::Vec2d& localPos2d) const; - cvf::Vec2d cellCenterPosition(uint i, uint j) const; - cvf::Vec2d origin2d() const; - - std::vector xVertexPositions() const; - std::vector yVertexPositions() const; - - bool getLegendRangeFrom3dGrid() const; - virtual void updateGridInformation() = 0; - cvf::Vec2ui calculateMapSize() const; - - double gridEdgeOffset() const; - - virtual RimGridView* baseView() const = 0; - + protected: caf::PdmField m_relativeSampleSpacing; caf::PdmField m_resultAggregation; @@ -180,13 +182,11 @@ protected: caf::PdmField m_showContourLabels; caf::PdmField m_smoothContourLines; - std::vector m_aggregatedResults; - std::vector m_aggregatedVertexResults; - + std::vector m_aggregatedResults; + std::vector m_aggregatedVertexResults; std::vector>> m_projected3dGridIndices; - cvf::Vec2d m_pickPoint; - + cvf::Vec2d m_pickPoint; cvf::Vec2ui m_mapSize; cvf::BoundingBox m_expandedBoundingBox; cvf::BoundingBox m_gridBoundingBox; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp index a7bc918965..5faeaa007a 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.cpp @@ -128,12 +128,14 @@ void RimEclipseContourMapProjection::updateLegend() { RimEclipseCellColors* cellColors = view()->cellResult(); - if (getLegendRangeFrom3dGrid()) + if (use3dGridLegendRange()) { cellColors->updateLegendData(view()->currentTimeStep(), legendConfig()); } else { + CVF_ASSERT(use2dMapLegendRange()); + double minVal = minValue(); double maxVal = maxValue(); @@ -334,7 +336,7 @@ void RimEclipseContourMapProjection::generateResults(int timeStep) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimEclipseContourMapProjection::gridMappingNeedsUpdating() const +bool RimEclipseContourMapProjection::gridMappingImplNeedsUpdating() const { if (m_cellGridIdxVisibility.isNull()) { @@ -346,14 +348,13 @@ bool RimEclipseContourMapProjection::gridMappingNeedsUpdating() const { if ((*currentVisibility)[i] != (*m_cellGridIdxVisibility)[i]) return true; } - - return RimContourMapProjection::gridMappingNeedsUpdating(); + return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimEclipseContourMapProjection::resultsNeedUpdating(int timeStep) const +bool RimEclipseContourMapProjection::resultsImplNeedsUpdating() const { if (!m_currentResultName.isEmpty()) { @@ -363,16 +364,14 @@ bool RimEclipseContourMapProjection::resultsNeedUpdating(int timeStep) const return true; } } - - return RimContourMapProjection::resultsNeedUpdating(timeStep); + return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseContourMapProjection::clearResults() +void RimEclipseContourMapProjection::clearImplSpecificResultData() { - RimContourMapProjection::clearResults(); m_currentResultName = ""; } @@ -495,7 +494,7 @@ double RimEclipseContourMapProjection::calculateValueInCell(uint i, uint j) cons for (auto cellIdxAndWeight : matchingCells) { size_t cellIdx = cellIdxAndWeight.first; - double cellValue = findColumnResult(m_resultAggregation(), cellIdx); + double cellValue = calculateColumnResult(m_resultAggregation(), cellIdx); sum += cellValue * cellIdxAndWeight.second; } return sum; @@ -507,6 +506,62 @@ double RimEclipseContourMapProjection::calculateValueInCell(uint i, uint j) cons return std::numeric_limits::infinity(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimEclipseContourMapProjection::calculateColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const +{ + const RigCaseCellResultsData* resultData = eclipseCase()->results(RiaDefines::MATRIX_MODEL); + size_t poroResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORO"); + size_t ntgResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "NTG"); + size_t dzResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "DZ"); + + if (poroResultIndex == cvf::UNDEFINED_SIZE_T || ntgResultIndex == cvf::UNDEFINED_SIZE_T) + { + return std::numeric_limits::infinity(); + } + + const std::vector& poroResults = resultData->cellScalarResults(poroResultIndex)[0]; + const std::vector& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0]; + const std::vector& dzResults = resultData->cellScalarResults(dzResultIndex)[0]; + + const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + size_t cellResultIdx = activeCellInfo->cellResultIndex(cellGlobalIdx); + + if (cellResultIdx >= poroResults.size() || cellResultIdx >= ntgResults.size()) + { + return std::numeric_limits::infinity(); + } + + double poro = poroResults.at(cellResultIdx); + double ntg = ntgResults.at(cellResultIdx); + double dz = dzResults.at(cellResultIdx); + + int timeStep = view()->currentTimeStep(); + + double resultValue = 0.0; + if (resultAggregation == RESULTS_OIL_COLUMN || resultAggregation == RESULTS_HC_COLUMN) + { + size_t soilResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL"); + const std::vector& soilResults = resultData->cellScalarResults(soilResultIndex)[timeStep]; + if (cellResultIdx < soilResults.size()) + { + resultValue = soilResults.at(cellResultIdx); + } + } + if (resultAggregation == RESULTS_GAS_COLUMN || resultAggregation == RESULTS_HC_COLUMN) + { + size_t sgasResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SGAS"); + const std::vector& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep]; + if (cellResultIdx < sgasResults.size()) + { + resultValue += sgasResults.at(cellResultIdx); + } + } + + return resultValue * poro * ntg * dz; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -663,62 +718,6 @@ std::vector> RimEclipseContourMapProjection::visibleCe return matchingVisibleCellsAndWeight; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimEclipseContourMapProjection::findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const -{ - const RigCaseCellResultsData* resultData = eclipseCase()->results(RiaDefines::MATRIX_MODEL); - size_t poroResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORO"); - size_t ntgResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "NTG"); - size_t dzResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "DZ"); - - if (poroResultIndex == cvf::UNDEFINED_SIZE_T || ntgResultIndex == cvf::UNDEFINED_SIZE_T) - { - return std::numeric_limits::infinity(); - } - - const std::vector& poroResults = resultData->cellScalarResults(poroResultIndex)[0]; - const std::vector& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0]; - const std::vector& dzResults = resultData->cellScalarResults(dzResultIndex)[0]; - - const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); - size_t cellResultIdx = activeCellInfo->cellResultIndex(cellGlobalIdx); - - if (cellResultIdx >= poroResults.size() || cellResultIdx >= ntgResults.size()) - { - return std::numeric_limits::infinity(); - } - - double poro = poroResults.at(cellResultIdx); - double ntg = ntgResults.at(cellResultIdx); - double dz = dzResults.at(cellResultIdx); - - int timeStep = view()->currentTimeStep(); - - double resultValue = 0.0; - if (resultAggregation == RESULTS_OIL_COLUMN || resultAggregation == RESULTS_HC_COLUMN) - { - size_t soilResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL"); - const std::vector& soilResults = resultData->cellScalarResults(soilResultIndex)[timeStep]; - if (cellResultIdx < soilResults.size()) - { - resultValue = soilResults.at(cellResultIdx); - } - } - if (resultAggregation == RESULTS_GAS_COLUMN || resultAggregation == RESULTS_HC_COLUMN) - { - size_t sgasResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SGAS"); - const std::vector& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep]; - if (cellResultIdx < sgasResults.size()) - { - resultValue += sgasResults.at(cellResultIdx); - } - } - - return resultValue * poro * ntg * dz; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h index 5af38e12d2..2a1247428e 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapProjection.h @@ -50,41 +50,39 @@ public: RimEclipseContourMapProjection(); ~RimEclipseContourMapProjection() override; - QString resultDescriptionText() const override; - QString weightingParameter() const; - - void updatedWeightingResult(); + QString weightingParameter() const; + void updatedWeightingResult(); + // Eclipse case overrides for contour map methods + QString resultDescriptionText() const override; RimRegularLegendConfig* legendConfig() const override; void updateLegend() override; protected: - void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - void initAfterRead() override; - -private: typedef RimContourMapProjection::CellIndexAndResult CellIndexAndResult; + void updateGridInformation() override; void generateGridMapping() override; void generateResults(int timeStep) override; + bool gridMappingImplNeedsUpdating() const override; + bool resultsImplNeedsUpdating() const override; + void clearImplSpecificResultData() override; + RimGridView* baseView() const override; - bool gridMappingNeedsUpdating() const override; - bool resultsNeedUpdating(int timeStep) const override; - - void clearResults() override; - + // Eclipse implementation specific data generation methods double calculateValueInCell(uint i, uint j) const; - + double calculateColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const; std::vector visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; std::vector visibleCellsAndLengthInCellFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; - double findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const; - - void updateGridInformation() override; RimEclipseResultCase* eclipseCase() const; - RimGridView* baseView() const override; RimEclipseContourMapView* view() const; +protected: + // Framework overrides + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; + protected: caf::PdmField m_weightByParameter; caf::PdmChildField m_weightingResult;