#3807 Tidy up contour map code after splitting out Eclipse specific code

This commit is contained in:
Gaute Lindkvist 2019-01-11 16:06:08 +01:00
parent bad98b81ad
commit 9a6d0ab9ef
4 changed files with 431 additions and 432 deletions

View File

@ -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<cvf::Vec3d> 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<cvf::Vec3d> 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<std::vector<cvf::Vec3d>> 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<cvf::Vec3d, 4> 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<cvf::Vec2ui, 4> 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<double, 4> 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<double>::infinity())
{
baryCentricCoords[i] = 0.0;
vertexValues[i] = 0.0;
return std::numeric_limits<double>::infinity();
}
else
{
vertexValues[i] = vertexValue;
validBarycentricCoordsSum += baryCentricCoords[i];
}
}
if (validBarycentricCoordsSum < 1.0e-8)
{
return std::numeric_limits<double>::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<ResultAggregationEnum>(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<caf::PdmUiDoubleSliderEditorAttribute*>(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<cvf::Vec3d> 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<std::vector<cvf::Vec3d>> 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<cvf::Vec3d, 4> 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<cvf::Vec2ui, 4> 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<double, 4> 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<double>::infinity())
{
baryCentricCoords[i] = 0.0;
vertexValues[i] = 0.0;
return std::numeric_limits<double>::infinity();
}
else
{
vertexValues[i] = vertexValue;
validBarycentricCoordsSum += baryCentricCoords[i];
}
}
if (m_aggregatedVertexResults.size() != numberOfVertices())
if (validBarycentricCoordsSum < 1.0e-8)
{
return true;
return std::numeric_limits<double>::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<std::pair<size_t, double>> RimContourMapProjection::cellsAtIJ(uint i
return std::vector<std::pair<size_t, double>>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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<double> 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<ResultAggregationEnum>(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<caf::PdmUiDoubleSliderEditorAttribute*>(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());
}

View File

@ -42,6 +42,8 @@ class RimContourMapProjection : public RimCheckableNamedObject
CAF_PDM_HEADER_INIT;
public:
typedef std::pair<size_t, double> CellIndexAndResult;
struct ContourPolygon
{
std::vector<cvf::Vec3d> 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<size_t, double> 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<cvf::Vec3d> 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<CellIndexAndResult> 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<double> xVertexPositions() const;
std::vector<double> 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<cvf::Vec3d> 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<CellIndexAndResult> 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<double> xVertexPositions() const;
std::vector<double> yVertexPositions() const;
bool getLegendRangeFrom3dGrid() const;
virtual void updateGridInformation() = 0;
cvf::Vec2ui calculateMapSize() const;
double gridEdgeOffset() const;
virtual RimGridView* baseView() const = 0;
protected:
caf::PdmField<double> m_relativeSampleSpacing;
caf::PdmField<ResultAggregation> m_resultAggregation;
@ -180,13 +182,11 @@ protected:
caf::PdmField<bool> m_showContourLabels;
caf::PdmField<bool> m_smoothContourLines;
std::vector<double> m_aggregatedResults;
std::vector<double> m_aggregatedVertexResults;
std::vector<double> m_aggregatedResults;
std::vector<double> m_aggregatedVertexResults;
std::vector<std::vector<std::pair<size_t, double>>> m_projected3dGridIndices;
cvf::Vec2d m_pickPoint;
cvf::Vec2d m_pickPoint;
cvf::Vec2ui m_mapSize;
cvf::BoundingBox m_expandedBoundingBox;
cvf::BoundingBox m_gridBoundingBox;

View File

@ -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<double>::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<double>::infinity();
}
const std::vector<double>& poroResults = resultData->cellScalarResults(poroResultIndex)[0];
const std::vector<double>& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0];
const std::vector<double>& 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<double>::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<double>& 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<double>& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep];
if (cellResultIdx < sgasResults.size())
{
resultValue += sgasResults.at(cellResultIdx);
}
}
return resultValue * poro * ntg * dz;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -663,62 +718,6 @@ std::vector<std::pair<size_t, double>> 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<double>::infinity();
}
const std::vector<double>& poroResults = resultData->cellScalarResults(poroResultIndex)[0];
const std::vector<double>& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0];
const std::vector<double>& 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<double>::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<double>& 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<double>& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep];
if (cellResultIdx < sgasResults.size())
{
resultValue += sgasResults.at(cellResultIdx);
}
}
return resultValue * poro * ntg * dz;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -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<CellIndexAndResult> visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector<double>* weightingResultValues = nullptr) const;
std::vector<CellIndexAndResult> visibleCellsAndLengthInCellFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector<double>* 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<bool> m_weightByParameter;
caf::PdmChildField<RimEclipseResultDefinition*> m_weightingResult;