Refactor: extract computation for contour map projection.

This commit is contained in:
Kristian Bendiksen committed 2024-11-07 13:13:20 +01:00
1 parent d2cd425ad0
commit f5437e6c72
16 files changed
+1738 -994

No files matched your search

@@ -17,19 +17,16 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RimGeoMechContourMapProjection.h"
#include "RiaImageTools.h"
#include "RiaWeightedMeanCalculator.h"
#include "RigCellGeometryTools.h"
#include "RigContourMapCalculator.h"
#include "RigContourMapGrid.h"
#include "RigContourMapProjection.h"
#include "RigFemAddressDefines.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigGeoMechCaseData.h"
#include "RigHexIntersectionTools.h"
#include "RigGeoMechContourMapProjection.h"
#include "RimCellFilterCollection.h"
#include "RimGeoMechCase.h"
@@ -46,16 +43,12 @@
#include "cvfStructGridGeometryGenerator.h"
#include "cvfVector3.h"
#include <algorithm>
#include <array>
CAF_PDM_SOURCE_INIT( RimGeoMechContourMapProjection, "RimGeoMechContourMapProjection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapProjection::RimGeoMechContourMapProjection()
: m_kLayers( 0u )
{
CAF_PDM_InitObject( "RimContourMapProjection", ":/2DMapProjection16x16.png" );
CAF_PDM_InitField( &m_limitToPorePressureRegions, "LimitToPorRegion", true, "Limit to Pore Pressure regions" );
@@ -97,8 +90,8 @@ void RimGeoMechContourMapProjection::updateLegend()
{
RimGeoMechCellColors* cellColors = view()->cellResult();
double minVal = minValue( m_aggregatedResults );
double maxVal = maxValue( m_aggregatedResults );
double minVal = m_contourMapProjection->minValue();
double maxVal = m_contourMapProjection->maxValue();
std::pair<double, double> minmaxValAllTimeSteps = minmaxValuesAllTimeSteps();
@@ -174,61 +167,16 @@ cvf::ref<cvf::UByteArray> RimGeoMechContourMapProjection::getCellVisibility() co
return cellGridIdxVisibility;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox RimGeoMechContourMapProjection::calculateExpandedPorBarBBox( int timeStep, int frameIndex ) const
{
RigFemResultAddress porBarAddr( RigFemResultPosEnum::RIG_ELEMENT_NODAL,
RigFemAddressDefines::porBar(),
view()->cellResult()->resultComponentName().toStdString() );
RigGeoMechCaseData* caseData = geoMechCase()->geoMechData();
RigFemPartResultsCollection* resultCollection = caseData->femPartResults();
const std::vector<float>& resultValues = resultCollection->resultValues( porBarAddr, 0, timeStep, frameIndex );
cvf::BoundingBox boundingBox;
if ( resultValues.empty() )
{
return boundingBox;
}
for ( int i = 0; i < m_femPart->elementCount(); ++i )
{
size_t resValueIdx = m_femPart->elementNodeResultIdx( (int)i, 0 );
CVF_ASSERT( resValueIdx < resultValues.size() );
double scalarValue = resultValues[resValueIdx];
bool validPorValue = scalarValue != std::numeric_limits<double>::infinity();
if ( validPorValue )
{
std::array<cvf::Vec3d, 8> hexCorners;
m_femPartGrid->cellCornerVertices( i, hexCorners.data() );
for ( size_t c = 0; c < 8; ++c )
{
boundingBox.add( hexCorners[c] );
}
}
}
cvf::Vec3d boxMin = boundingBox.min();
cvf::Vec3d boxMax = boundingBox.max();
cvf::Vec3d boxExtent = boundingBox.extent();
boxMin.x() -= boxExtent.x() * 0.5 * m_paddingAroundPorePressureRegion();
boxMin.y() -= boxExtent.y() * 0.5 * m_paddingAroundPorePressureRegion();
boxMax.x() += boxExtent.x() * 0.5 * m_paddingAroundPorePressureRegion();
boxMax.y() += boxExtent.y() * 0.5 * m_paddingAroundPorePressureRegion();
return cvf::BoundingBox( boxMin, boxMax );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::updateGridInformation()
{
RimGeoMechCase* geoMechCase = this->geoMechCase();
m_femPart = geoMechCase->geoMechData()->femParts()->part( 0 );
m_femPartGrid = m_femPart->getOrCreateStructGrid();
m_kLayers = m_femPartGrid->cellCountK();
if ( !geoMechCase ) return;
m_femPart = geoMechCase->geoMechData()->femParts()->part( 0 );
m_femPartGrid = m_femPart->getOrCreateStructGrid();
m_femPart->ensureIntersectionSearchTreeIsBuilt();
cvf::BoundingBox gridBoundingBox = geoMechCase->activeCellsBoundingBox();
@@ -238,7 +186,12 @@ void RimGeoMechContourMapProjection::updateGridInformation()
{
auto [stepIdx, frameIdx] = view()->currentStepAndDataFrame();
expandedBoundingBox = calculateExpandedPorBarBBox( stepIdx, frameIdx );
expandedBoundingBox =
RigGeoMechContourMapProjection::calculateExpandedPorBarBBox( *geoMechCase->geoMechData(),
view()->cellResult()->resultComponentName().toStdString(),
stepIdx,
frameIdx,
m_paddingAroundPorePressureRegion() );
if ( !expandedBoundingBox.isValid() )
{
m_limitToPorePressureRegions = false;
@@ -259,68 +212,11 @@ void RimGeoMechContourMapProjection::updateGridInformation()
}
expandedBoundingBox = cvf::BoundingBox( minExpandedPoint, maxExpandedPoint );
m_contourMapGrid = std::make_unique<RigContourMapGrid>( gridBoundingBox, expandedBoundingBox, sampleSpacing() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<bool> RimGeoMechContourMapProjection::getMapCellVisibility()
{
cvf::Vec2ui nCellsIJ = numberOfElementsIJ();
std::vector<std::vector<unsigned int>> distanceImage( nCellsIJ.x(), std::vector<unsigned int>( nCellsIJ.y(), 0u ) );
std::vector<bool> mapCellVisibility;
RigFemResultAddress resAddr = view()->cellResult()->resultAddress();
if ( m_limitToPorePressureRegions )
{
resAddr = RigFemAddressDefines::elementNodalPorBarAddress();
}
std::vector<double> cellResults = generateResultsFromAddress( resAddr, mapCellVisibility, view()->currentTimeStep() );
mapCellVisibility.resize( numberOfCells(), true );
CVF_ASSERT( mapCellVisibility.size() == cellResults.size() );
{
cvf::BoundingBox validResBoundingBox;
for ( size_t cellIndex = 0; cellIndex < cellResults.size(); ++cellIndex )
{
cvf::Vec2ui ij = m_contourMapGrid->ijFromCellIndex( cellIndex );
if ( cellResults[cellIndex] != std::numeric_limits<double>::infinity() )
{
distanceImage[ij.x()][ij.y()] = 1u;
validResBoundingBox.add( cvf::Vec3d( m_contourMapGrid->cellCenterPosition( ij.x(), ij.y() ), 0.0 ) );
}
else
{
mapCellVisibility[cellIndex] = false;
}
}
if ( m_limitToPorePressureRegions && m_paddingAroundPorePressureRegion > 0.0 )
{
RiaImageTools::distanceTransform2d( distanceImage );
cvf::Vec3d porExtent = validResBoundingBox.extent();
double radius = std::max( porExtent.x(), porExtent.y() ) * 0.25;
double expansion = m_paddingAroundPorePressureRegion * radius;
size_t cellPadding = std::ceil( expansion / sampleSpacing() );
for ( size_t cellIndex = 0; cellIndex < cellResults.size(); ++cellIndex )
{
if ( !mapCellVisibility[cellIndex] )
{
cvf::Vec2ui ij = m_contourMapGrid->ijFromCellIndex( cellIndex );
if ( distanceImage[ij.x()][ij.y()] < cellPadding * cellPadding )
{
mapCellVisibility[cellIndex] = true;
}
}
}
}
}
return mapCellVisibility;
m_contourMapGrid = std::make_unique<RigContourMapGrid>( gridBoundingBox, expandedBoundingBox, sampleSpacing() );
m_contourMapProjection = std::make_unique<RigGeoMechContourMapProjection>( *geoMechCase->geoMechData(),
*m_contourMapGrid,
m_limitToPorePressureRegions,
m_paddingAroundPorePressureRegion );
}
//--------------------------------------------------------------------------------------------------
@@ -334,14 +230,30 @@ std::vector<double> RimGeoMechContourMapProjection::retrieveParameterWeights()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGeoMechContourMapProjection::generateResults( int viewerStepIndex )
std::vector<double> RimGeoMechContourMapProjection::generateResults( int viewerStepIndex ) const
{
RimGeoMechCellColors* cellColors = view()->cellResult();
RigFemResultAddress resultAddress = cellColors->resultAddress();
if ( m_contourMapProjection )
{
RimGeoMechCellColors* cellColors = view()->cellResult();
RigFemResultAddress resultAddress = cellColors->resultAddress();
return generateResultsFromAddress( resultAddress, m_mapCellVisibility, viewerStepIndex );
}
std::vector<double> aggregatedResults = generateResultsFromAddress( resultAddress, m_mapCellVisibility, viewerStepIndex );
return {};
}
return aggregatedResults;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::generateAndSaveResults( int timeStep )
{
if ( m_contourMapProjection )
{
RimGeoMechCellColors* cellColors = view()->cellResult();
RigFemResultAddress resultAddress = cellColors->resultAddress();
dynamic_cast<RigGeoMechContourMapProjection*>( m_contourMapProjection.get() )
->generateAndSaveResults( resultAddress, m_resultAggregation(), timeStep );
}
}
//--------------------------------------------------------------------------------------------------
@@ -349,64 +261,10 @@ std::vector<double> RimGeoMechContourMapProjection::generateResults( int viewerS
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGeoMechContourMapProjection::generateResultsFromAddress( RigFemResultAddress resultAddress,
const std::vector<bool>& mapCellVisibility,
int viewerStepIndex )
int viewerStepIndex ) const
{
RigGeoMechCaseData* caseData = geoMechCase()->geoMechData();
RigFemPartResultsCollection* resultCollection = caseData->femPartResults();
size_t nCells = numberOfCells();
std::vector<double> aggregatedResults = std::vector<double>( nCells, std::numeric_limits<double>::infinity() );
auto [stepIdx, frameIdx] = caseData->femPartResults()->stepListIndexToTimeStepAndDataFrameIndex( viewerStepIndex );
bool wasInvalid = false;
if ( !resultAddress.isValid() )
{
wasInvalid = true;
resultAddress = RigFemAddressDefines::elementNodalPorBarAddress();
}
if ( resultAddress.fieldName == "PP" )
{
resultAddress.fieldName = RigFemAddressDefines::porBar(); // More likely to be in memory than POR
}
if ( resultAddress.fieldName == RigFemAddressDefines::porBar() )
{
resultAddress.resultPosType = RIG_ELEMENT_NODAL;
}
else if ( resultAddress.resultPosType == RIG_FORMATION_NAMES )
{
resultAddress.resultPosType = RIG_ELEMENT_NODAL; // formation indices are stored per element node result.
}
std::vector<float> resultValuesF = resultCollection->resultValues( resultAddress, 0, stepIdx, frameIdx );
if ( resultValuesF.empty() ) return aggregatedResults;
std::vector<double> resultValues = gridCellValues( resultAddress, resultValuesF );
if ( wasInvalid )
{
// For invalid result addresses we just use the POR-Bar result to get the reservoir region
// And display a dummy 0-result in the region.
for ( double& value : resultValues )
{
if ( value != std::numeric_limits<double>::infinity() )
{
value = 0.0;
}
}
}
#pragma omp parallel for
for ( int index = 0; index < static_cast<int>( nCells ); ++index )
{
if ( mapCellVisibility.empty() || mapCellVisibility[index] )
{
cvf::Vec2ui ij = m_contourMapGrid->ijFromCellIndex( index );
aggregatedResults[index] = calculateValueInMapCell( ij.x(), ij.y(), resultValues );
}
}
return aggregatedResults;
return dynamic_cast<RigGeoMechContourMapProjection*>( m_contourMapProjection.get() )
->generateResultsFromAddress( resultAddress, mapCellVisibility, m_resultAggregation(), viewerStepIndex );
}
//--------------------------------------------------------------------------------------------------
@@ -436,132 +294,6 @@ RimGridView* RimGeoMechContourMapProjection::baseView() const
return view();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RimGeoMechContourMapProjection::findIntersectingCells( const cvf::BoundingBox& bbox ) const
{
return m_femPart->findIntersectingElementsWithExistingSearchTree( bbox );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGeoMechContourMapProjection::kLayer( size_t globalCellIdx ) const
{
size_t i, j, k;
m_femPartGrid->ijkFromCellIndex( globalCellIdx, &i, &j, &k );
return k;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGeoMechContourMapProjection::kLayers() const
{
return m_kLayers;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimGeoMechContourMapProjection::calculateOverlapVolume( size_t globalCellIdx, const cvf::BoundingBox& bbox ) const
{
std::array<cvf::Vec3d, 8> hexCorners;
m_femPartGrid->cellCornerVertices( globalCellIdx, hexCorners.data() );
cvf::BoundingBox overlapBBox;
std::array<cvf::Vec3d, 8> overlapCorners;
if ( RigCellGeometryTools::estimateHexOverlapWithBoundingBox( hexCorners, bbox, &overlapCorners, &overlapBBox ) )
{
double overlapVolume = RigCellGeometryTools::calculateCellVolume( overlapCorners );
return overlapVolume;
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimGeoMechContourMapProjection::calculateRayLengthInCell( size_t globalCellIdx,
const cvf::Vec3d& highestPoint,
const cvf::Vec3d& lowestPoint ) const
{
std::array<cvf::Vec3d, 8> hexCorners;
const std::vector<cvf::Vec3f>& nodeCoords = m_femPart->nodes().coordinates;
const int* cornerIndices = m_femPart->connectivities( globalCellIdx );
hexCorners[0] = cvf::Vec3d( nodeCoords[cornerIndices[0]] );
hexCorners[1] = cvf::Vec3d( nodeCoords[cornerIndices[1]] );
hexCorners[2] = cvf::Vec3d( nodeCoords[cornerIndices[2]] );
hexCorners[3] = cvf::Vec3d( nodeCoords[cornerIndices[3]] );
hexCorners[4] = cvf::Vec3d( nodeCoords[cornerIndices[4]] );
hexCorners[5] = cvf::Vec3d( nodeCoords[cornerIndices[5]] );
hexCorners[6] = cvf::Vec3d( nodeCoords[cornerIndices[6]] );
hexCorners[7] = cvf::Vec3d( nodeCoords[cornerIndices[7]] );
std::vector<HexIntersectionInfo> intersections;
if ( RigHexIntersectionTools::lineHexCellIntersection( highestPoint, lowestPoint, hexCorners.data(), 0, &intersections ) )
{
double lengthInCell = ( intersections.back().m_intersectionPoint - intersections.front().m_intersectionPoint ).length();
return lengthInCell;
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimGeoMechContourMapProjection::getParameterWeightForCell( size_t globalCellIdx, const std::vector<double>& parameterWeights ) const
{
if ( parameterWeights.empty() ) return 1.0;
return parameterWeights[globalCellIdx];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGeoMechContourMapProjection::gridCellValues( RigFemResultAddress resAddr, std::vector<float>& resultValues ) const
{
std::vector<double> gridCellValues( m_femPart->elementCount(), std::numeric_limits<double>::infinity() );
for ( size_t globalCellIdx = 0; globalCellIdx < static_cast<size_t>( m_femPart->elementCount() ); ++globalCellIdx )
{
RigElementType elmType = m_femPart->elementType( globalCellIdx );
if ( !RigFemTypes::is8NodeElement( elmType ) ) continue;
if ( resAddr.resultPosType == RIG_ELEMENT )
{
gridCellValues[globalCellIdx] = static_cast<double>( resultValues[globalCellIdx] );
}
else if ( resAddr.resultPosType == RIG_ELEMENT_NODAL )
{
RiaWeightedMeanCalculator<float> cellAverage;
for ( int i = 0; i < 8; ++i )
{
size_t gridResultValueIdx =
m_femPart->resultValueIdxFromResultPosType( resAddr.resultPosType, static_cast<int>( globalCellIdx ), i );
cellAverage.addValueAndWeight( resultValues[gridResultValueIdx], 1.0 );
}
gridCellValues[globalCellIdx] = static_cast<double>( cellAverage.weightedMean() );
}
else
{
RiaWeightedMeanCalculator<float> cellAverage;
const int* elmNodeIndices = m_femPart->connectivities( globalCellIdx );
for ( int i = 0; i < 8; ++i )
{
cellAverage.addValueAndWeight( resultValues[elmNodeIndices[i]], 1.0 );
}
gridCellValues[globalCellIdx] = static_cast<double>( cellAverage.weightedMean() );
}
}
return gridCellValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -672,20 +404,14 @@ std::pair<double, double> RimGeoMechContourMapProjection::minmaxValuesAllTimeSte
{
clearTimeStepRange();
m_minResultAllTimeSteps = std::min( m_minResultAllTimeSteps, minValue( m_aggregatedResults ) );
m_maxResultAllTimeSteps = std::max( m_maxResultAllTimeSteps, maxValue( m_aggregatedResults ) );
if ( geoMechCase() && geoMechCase()->geoMechData() && geoMechCase()->geoMechData()->femPartResults() )
if ( geoMechCase()->geoMechData()->femPartResults() )
{
int steps = geoMechCase()->geoMechData()->femPartResults()->totalSteps();
for ( int stepIdx = 0; stepIdx < steps; stepIdx++ )
{
if ( stepIdx == m_currentResultTimestep ) continue;
std::vector<double> aggregatedResults = generateResults( stepIdx );
m_minResultAllTimeSteps = std::min( m_minResultAllTimeSteps, minValue( aggregatedResults ) );
m_maxResultAllTimeSteps = std::max( m_maxResultAllTimeSteps, maxValue( aggregatedResults ) );
m_minResultAllTimeSteps = std::min( m_minResultAllTimeSteps, RigContourMapProjection::minValue( aggregatedResults ) );
m_maxResultAllTimeSteps = std::max( m_maxResultAllTimeSteps, RigContourMapProjection::maxValue( aggregatedResults ) );
}
}
}
@@ -21,19 +21,13 @@
#include "RigFemPart.h"
#include "RigFemResultAddress.h"
#include "RimCheckableNamedObject.h"
#include "RimContourMapProjection.h"
#include "cafDisplayCoordTransform.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cvfArray.h"
#include "cvfBoundingBox.h"
#include "cvfGeometryBuilderFaceList.h"
#include "cvfString.h"
#include "cvfVector2.h"
class RimGeoMechContourMapView;
class RimGeoMechCase;
@@ -58,27 +52,19 @@ public:
double sampleSpacing() const override;
protected:
using CellIndexAndResult = RimContourMapProjection::CellIndexAndResult;
// GeoMech implementation specific data generation methods
cvf::ref<cvf::UByteArray> getCellVisibility() const override;
cvf::BoundingBox calculateExpandedPorBarBBox( int timeStep, int frameIndex ) const;
void updateGridInformation() override;
std::vector<bool> getMapCellVisibility() override;
std::vector<double> retrieveParameterWeights() override;
std::vector<double> generateResults( int viewerStepIndex ) override;
std::vector<double> retrieveParameterWeights() override;
std::vector<double> generateResults( int timeStep ) const override;
void generateAndSaveResults( int timeStep ) override;
std::vector<double>
generateResultsFromAddress( RigFemResultAddress resultAddress, const std::vector<bool>& mapCellVisibility, int viewerStepIndex );
bool resultVariableChanged() const override;
void clearResultVariable() override;
RimGridView* baseView() const override;
std::vector<size_t> findIntersectingCells( const cvf::BoundingBox& bbox ) const override;
size_t kLayer( size_t globalCellIdx ) const override;
size_t kLayers() const override;
double calculateOverlapVolume( size_t globalCellIdx, const cvf::BoundingBox& bbox ) const override;
double calculateRayLengthInCell( size_t globalCellIdx, const cvf::Vec3d& highestPoint, const cvf::Vec3d& lowestPoint ) const override;
double getParameterWeightForCell( size_t globalCellIdx, const std::vector<double>& parameterWeights ) const override;
std::vector<double> gridCellValues( RigFemResultAddress resAddr, std::vector<float>& resultValues ) const;
generateResultsFromAddress( RigFemResultAddress resultAddress, const std::vector<bool>& mapCellVisibility, int viewerStepIndex ) const;
bool resultVariableChanged() const override;
void clearResultVariable() override;
RimGridView* baseView() const override;
RimGeoMechCase* geoMechCase() const;
RimGeoMechContourMapView* view() const;
@@ -100,5 +86,4 @@ protected:
cvf::ref<RigFemPart> m_femPart;
cvf::cref<RigFemPartGrid> m_femPartGrid;
RigFemResultAddress m_currentResultAddr;
size_t m_kLayers;
};
@@ -19,11 +19,11 @@
#include "RimContourMapProjection.h"
#include "RiaOpenMPTools.h"
#include "RiaWeightedMeanCalculator.h"
#include "RigCellGeometryTools.h"
#include "RigContourMapCalculator.h"
#include "RigContourMapGrid.h"
#include "RigContourMapProjection.h"
#include "RimCase.h"
#include "RimGridView.h"
@@ -37,10 +37,10 @@
#include "cafProgressInfo.h"
#include "cvfArray.h"
#include "cvfGeometryTools.h"
#include "cvfGeometryUtils.h"
#include "cvfScalarMapper.h"
#include "cvfStructGridGeometryGenerator.h"
#include "cvfVector2.h"
#include <algorithm>
@@ -66,6 +66,7 @@ void RimContourMapProjection::ResultAggregation::setUp()
setDefault( RigContourMapCalculator::RESULTS_MEAN_VALUE );
}
} // namespace caf
CAF_PDM_ABSTRACT_SOURCE_INIT( RimContourMapProjection, "RimContourMapProjection" );
//--------------------------------------------------------------------------------------------------
@@ -76,6 +77,7 @@ RimContourMapProjection::RimContourMapProjection()
, m_currentResultTimestep( -1 )
, m_minResultAllTimeSteps( std::numeric_limits<double>::infinity() )
, m_maxResultAllTimeSteps( -std::numeric_limits<double>::infinity() )
{
CAF_PDM_InitObject( "RimContourMapProjection", ":/2DMapProjection16x16.png" );
@@ -106,22 +108,27 @@ void RimContourMapProjection::generateResultsIfNecessary( int timeStep )
{
caf::ProgressInfo progress( 100, "Generate Results", true );
updateGridInformation();
if ( !m_contourMapGrid || !m_contourMapProjection ) updateGridInformation();
auto cellVisibility = getCellVisibility();
m_contourMapProjection->setCellVisibility( cellVisibility );
progress.setProgress( 10 );
if ( gridMappingNeedsUpdating() || mapCellVisibilityNeedsUpdating() || resultVariableChanged() )
if ( gridMappingNeedsUpdating() || mapCellVisibilityNeedsUpdating( timeStep ) || resultVariableChanged() )
{
clearResults();
clearTimeStepRange();
m_cellGridIdxVisibility = getCellVisibility();
auto cellVisibility = getCellVisibility();
m_contourMapProjection->setCellVisibility( cellVisibility );
if ( gridMappingNeedsUpdating() )
{
m_projected3dGridIndices = RigContourMapCalculator::generateGridMapping( *this, *m_contourMapGrid );
m_contourMapProjection->generateGridMapping( m_resultAggregation(), retrieveParameterWeights() );
}
progress.setProgress( 20 );
m_mapCellVisibility = getMapCellVisibility();
m_mapCellVisibility = m_contourMapProjection->getMapCellVisibility( timeStep, m_resultAggregation() );
progress.setProgress( 30 );
}
else
@@ -132,7 +139,8 @@ void RimContourMapProjection::generateResultsIfNecessary( int timeStep )
if ( resultsNeedsUpdating( timeStep ) )
{
clearGeometry();
m_aggregatedResults = generateResults( timeStep );
generateAndSaveResults( timeStep );
progress.setProgress( 80 );
generateVertexResults();
}
@@ -279,7 +287,8 @@ QString RimContourMapProjection::currentTimeStepName() const
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::maxValue() const
{
return maxValue( m_aggregatedResults );
if ( m_contourMapProjection ) return m_contourMapProjection->maxValue();
return -std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
@@ -287,7 +296,8 @@ double RimContourMapProjection::maxValue() const
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::minValue() const
{
return minValue( m_aggregatedResults );
if ( m_contourMapProjection ) return m_contourMapProjection->minValue();
return std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
@@ -295,7 +305,8 @@ double RimContourMapProjection::minValue() const
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::meanValue() const
{
return sumAllValues() / numberOfValidCells();
if ( m_contourMapProjection ) return m_contourMapProjection->meanValue();
return std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
@@ -303,24 +314,8 @@ double RimContourMapProjection::meanValue() const
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::sumAllValues() const
{
double sum = 0.0;
for ( size_t index = 0; index < m_aggregatedResults.size(); ++index )
{
if ( m_aggregatedResults[index] != std::numeric_limits<double>::infinity() )
{
sum += m_aggregatedResults[index];
}
}
return sum;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui RimContourMapProjection::numberOfElementsIJ() const
{
return m_contourMapGrid->numberOfElementsIJ();
if ( m_contourMapProjection ) return m_contourMapProjection->sumAllValues();
return 0.0;
}
//--------------------------------------------------------------------------------------------------
@@ -328,7 +323,8 @@ cvf::Vec2ui RimContourMapProjection::numberOfElementsIJ() const
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui RimContourMapProjection::numberOfVerticesIJ() const
{
return m_contourMapGrid->numberOfVerticesIJ();
if ( m_contourMapGrid ) return m_contourMapGrid->numberOfVerticesIJ();
return cvf::Vec2ui( 0, 0 );
}
//--------------------------------------------------------------------------------------------------
@@ -344,11 +340,7 @@ bool RimContourMapProjection::isColumnResult() const
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::valueAtVertex( uint i, uint j ) const
{
size_t index = m_contourMapGrid->vertexIndexFromIJ( i, j );
if ( index < numberOfVertices() )
{
return m_aggregatedVertexResults.at( index );
}
if ( m_contourMapProjection ) return m_contourMapProjection->valueAtVertex( i, j );
return std::numeric_limits<double>::infinity();
}
@@ -357,7 +349,8 @@ double RimContourMapProjection::valueAtVertex( uint i, uint j ) const
//--------------------------------------------------------------------------------------------------
uint RimContourMapProjection::numberOfCells() const
{
return m_contourMapGrid->numberOfCells();
if ( m_contourMapGrid ) return m_contourMapGrid->numberOfCells();
return 0u;
}
//--------------------------------------------------------------------------------------------------
@@ -365,16 +358,8 @@ uint RimContourMapProjection::numberOfCells() const
//--------------------------------------------------------------------------------------------------
uint RimContourMapProjection::numberOfValidCells() const
{
uint validCount = 0u;
for ( uint i = 0; i < numberOfCells(); ++i )
{
cvf::Vec2ui ij = m_contourMapGrid->ijFromCellIndex( i );
if ( hasResultInCell( ij.x(), ij.y() ) )
{
validCount++;
}
}
return validCount;
if ( m_contourMapProjection ) return m_contourMapProjection->numberOfValidCells();
return 0u;
}
//--------------------------------------------------------------------------------------------------
@@ -382,8 +367,8 @@ uint RimContourMapProjection::numberOfValidCells() const
//--------------------------------------------------------------------------------------------------
size_t RimContourMapProjection::numberOfVertices() const
{
cvf::Vec2ui gridSize = numberOfVerticesIJ();
return static_cast<size_t>( gridSize.x() ) * static_cast<size_t>( gridSize.y() );
if ( m_contourMapGrid ) return m_contourMapGrid->numberOfVertices();
return 0;
}
//--------------------------------------------------------------------------------------------------
@@ -391,22 +376,7 @@ size_t RimContourMapProjection::numberOfVertices() const
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::checkForMapIntersection( const cvf::Vec3d& domainPoint3d, cvf::Vec2d* contourMapPoint, double* valueAtPoint ) const
{
CVF_TIGHT_ASSERT( contourMapPoint );
CVF_TIGHT_ASSERT( valueAtPoint );
const cvf::Vec3d& minPoint = m_contourMapGrid->expandedBoundingBox().min();
cvf::Vec3d mapPos3d = domainPoint3d - minPoint;
cvf::Vec2d mapPos2d( mapPos3d.x(), mapPos3d.y() );
cvf::Vec2d gridorigin( minPoint.x(), minPoint.y() );
double value = interpolateValue( mapPos2d );
if ( value != std::numeric_limits<double>::infinity() )
{
*valueAtPoint = value;
*contourMapPoint = mapPos2d + gridorigin;
return true;
}
if ( m_contourMapProjection ) return m_contourMapProjection->checkForMapIntersection( domainPoint3d, contourMapPoint, valueAtPoint );
return false;
}
@@ -439,8 +409,8 @@ size_t RimContourMapProjection::gridResultIndex( size_t globalCellIdx ) const
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::calculateValueInMapCell( uint i, uint j, const std::vector<double>& gridCellValues ) const
{
const std::vector<std::pair<size_t, double>>& matchingCells = cellsAtIJ( i, j );
return RigContourMapCalculator::calculateValueInMapCell( *this, matchingCells, gridCellValues, m_resultAggregation() );
const std::vector<std::pair<size_t, double>>& matchingCells = m_contourMapProjection->cellsAtIJ( i, j );
return RigContourMapCalculator::calculateValueInMapCell( *m_contourMapProjection, matchingCells, gridCellValues, m_resultAggregation() );
}
//--------------------------------------------------------------------------------------------------
@@ -448,16 +418,19 @@ double RimContourMapProjection::calculateValueInMapCell( uint i, uint j, const s
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::gridMappingNeedsUpdating() const
{
if ( m_projected3dGridIndices.size() != numberOfCells() ) return true;
if ( !m_contourMapProjection ) return true;
if ( m_cellGridIdxVisibility.isNull() ) return true;
if ( m_contourMapProjection->projected3dGridIndices().size() != numberOfCells() ) return true;
auto cellGridIdxVisibility = m_contourMapProjection->getCellVisibility();
if ( cellGridIdxVisibility.isNull() ) return true;
cvf::ref<cvf::UByteArray> currentVisibility = getCellVisibility();
CVF_ASSERT( currentVisibility->size() == m_cellGridIdxVisibility->size() );
CVF_ASSERT( currentVisibility->size() == cellGridIdxVisibility->size() );
for ( size_t i = 0; i < currentVisibility->size(); ++i )
{
if ( ( *currentVisibility )[i] != ( *m_cellGridIdxVisibility )[i] ) return true;
if ( ( *currentVisibility )[i] != ( *cellGridIdxVisibility )[i] ) return true;
}
return false;
@@ -468,8 +441,10 @@ bool RimContourMapProjection::gridMappingNeedsUpdating() const
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::resultsNeedsUpdating( int timeStep ) const
{
return ( m_aggregatedResults.size() != numberOfCells() || m_aggregatedVertexResults.size() != numberOfVertices() ||
timeStep != m_currentResultTimestep );
if ( !m_contourMapProjection ) return true;
return ( m_contourMapProjection->aggregatedResults().size() != numberOfCells() ||
m_contourMapProjection->aggregatedVertexResults().size() != numberOfVertices() || timeStep != m_currentResultTimestep );
}
//--------------------------------------------------------------------------------------------------
@@ -480,15 +455,6 @@ bool RimContourMapProjection::geometryNeedsUpdating() const
return m_contourPolygons.empty() || m_trianglesWithVertexValues.empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::resultRangeIsValid() const
{
return m_minResultAllTimeSteps != std::numeric_limits<double>::infinity() &&
m_maxResultAllTimeSteps != -std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -496,7 +462,8 @@ void RimContourMapProjection::clearGridMapping()
{
clearResults();
clearTimeStepRange();
m_projected3dGridIndices.clear();
if ( m_contourMapProjection ) m_contourMapProjection->clearGridMapping();
m_mapCellVisibility.clear();
}
@@ -507,81 +474,12 @@ void RimContourMapProjection::clearResults()
{
clearGeometry();
m_aggregatedResults.clear();
m_aggregatedVertexResults.clear();
if ( m_contourMapProjection ) m_contourMapProjection->clearResults();
m_currentResultTimestep = -1;
clearResultVariable();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimContourMapProjection::clearTimeStepRange()
{
m_minResultAllTimeSteps = std::numeric_limits<double>::infinity();
m_maxResultAllTimeSteps = -std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::maxValue( const std::vector<double>& aggregatedResults ) const
{
double maxV = -std::numeric_limits<double>::infinity();
for ( size_t index = 0; index < aggregatedResults.size(); ++index )
{
if ( aggregatedResults[index] != std::numeric_limits<double>::infinity() )
{
maxV = std::max( maxV, aggregatedResults[index] );
}
}
return maxV;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::minValue( const std::vector<double>& aggregatedResults ) const
{
double minV = std::numeric_limits<double>::infinity();
for ( size_t index = 0; index < aggregatedResults.size(); ++index )
{
if ( aggregatedResults[index] != std::numeric_limits<double>::infinity() )
{
minV = std::min( minV, aggregatedResults[index] );
}
}
return minV;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RimContourMapProjection::minmaxValuesAllTimeSteps()
{
if ( !resultRangeIsValid() )
{
clearTimeStepRange();
m_minResultAllTimeSteps = std::min( m_minResultAllTimeSteps, minValue( m_aggregatedResults ) );
m_maxResultAllTimeSteps = std::max( m_maxResultAllTimeSteps, maxValue( m_aggregatedResults ) );
for ( int i = 0; i < (int)baseView()->ownerCase()->timeStepStrings().size() - 1; ++i )
{
if ( i != m_currentResultTimestep )
{
std::vector<double> aggregatedResults = generateResults( i );
m_minResultAllTimeSteps = std::min( m_minResultAllTimeSteps, minValue( aggregatedResults ) );
m_maxResultAllTimeSteps = std::max( m_maxResultAllTimeSteps, maxValue( aggregatedResults ) );
}
}
}
return std::make_pair( m_minResultAllTimeSteps, m_maxResultAllTimeSteps );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -590,20 +488,14 @@ cvf::ref<cvf::UByteArray> RimContourMapProjection::getCellVisibility() const
return baseView()->currentTotalCellVisibility();
}
//--------------------------------------------------------------------------------------------------
/// Empty default implementation
//--------------------------------------------------------------------------------------------------
std::vector<bool> RimContourMapProjection::getMapCellVisibility()
{
return std::vector<bool>( numberOfCells(), true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::mapCellVisibilityNeedsUpdating()
bool RimContourMapProjection::mapCellVisibilityNeedsUpdating( int timestep )
{
std::vector<bool> mapCellVisiblity = getMapCellVisibility();
if ( m_contourMapProjection ) return true;
std::vector<bool> mapCellVisiblity = m_contourMapProjection->getMapCellVisibility( timestep, m_resultAggregation() );
return !( mapCellVisiblity == m_mapCellVisibility );
}
@@ -612,17 +504,7 @@ bool RimContourMapProjection::mapCellVisibilityNeedsUpdating()
//--------------------------------------------------------------------------------------------------
void RimContourMapProjection::generateVertexResults()
{
size_t nCells = numberOfCells();
if ( nCells != m_aggregatedResults.size() ) return;
size_t nVertices = numberOfVertices();
m_aggregatedVertexResults = std::vector<double>( nVertices, std::numeric_limits<double>::infinity() );
#pragma omp parallel for
for ( int index = 0; index < static_cast<int>( nVertices ); ++index )
{
cvf::Vec2ui ij = m_contourMapGrid->ijFromVertexIndex( index );
m_aggregatedVertexResults[index] = calculateValueAtVertex( ij.x(), ij.y() );
}
if ( m_contourMapProjection ) m_contourMapProjection->generateVertexResults();
}
//--------------------------------------------------------------------------------------------------
@@ -668,6 +550,8 @@ void RimContourMapProjection::generateTrianglesWithVertexValues()
std::vector<std::vector<std::vector<cvf::Vec4d>>> threadTriangles( numberOfThreads );
const std::vector<double>& aggregatedVertexResults = m_contourMapProjection->aggregatedVertexResults();
#pragma omp parallel
{
int myThread = RiaOpenMPTools::currentThreadIndex();
@@ -681,9 +565,9 @@ void RimContourMapProjection::generateTrianglesWithVertexValues()
bool anyValidVertex = false;
for ( size_t n = 0; n < 3; ++n )
{
uint vn = ( *faceList )[i + n];
double value = vn < m_aggregatedVertexResults.size() ? m_aggregatedVertexResults[vn] : std::numeric_limits<double>::infinity();
triangle[n] = vertices[vn];
uint vn = ( *faceList )[i + n];
double value = vn < aggregatedVertexResults.size() ? aggregatedVertexResults[vn] : std::numeric_limits<double>::infinity();
triangle[n] = vertices[vn];
triangleWithValues[n] = cvf::Vec4d( vertices[vn], value );
if ( value != std::numeric_limits<double>::infinity() )
{
@@ -804,7 +688,7 @@ void RimContourMapProjection::generateTrianglesWithVertexValues()
}
if ( value == std::numeric_limits<double>::infinity() )
{
value = interpolateValue( cvf::Vec2d( localVertex.x(), localVertex.y() ) );
value = m_contourMapProjection->interpolateValue( cvf::Vec2d( localVertex.x(), localVertex.y() ) );
if ( value == std::numeric_limits<double>::infinity() )
{
value = contourLevels[c];
@@ -841,7 +725,7 @@ void RimContourMapProjection::generateTrianglesWithVertexValues()
allTrianglesThisLevel.insert( allTrianglesThisLevel.end(), threadTriangles[i][c].begin(), threadTriangles[i][c].end() );
}
double triangleAreasThisLevel = sumTriangleAreas( allTrianglesThisLevel );
double triangleAreasThisLevel = RigContourMapProjection::sumTriangleAreas( allTrianglesThisLevel );
if ( c >= m_contourLevelCumulativeAreas.size() || triangleAreasThisLevel > 1.0e-3 * m_contourLevelCumulativeAreas[c] )
{
trianglesPerLevel[c] = allTrianglesThisLevel;
@@ -867,6 +751,8 @@ void RimContourMapProjection::generateContourPolygons()
std::vector<double> contourLevels;
if ( resultRangeIsValid() && legendConfig()->mappingMode() != RimRegularLegendConfig::MappingType::CATEGORY_INTEGER )
{
const std::vector<double>& aggregatedVertexResults = m_contourMapProjection->aggregatedVertexResults();
legendConfig()->scalarMapper()->majorTickValues( &contourLevels );
int nContourLevels = static_cast<int>( contourLevels.size() );
@@ -900,7 +786,7 @@ void RimContourMapProjection::generateContourPolygons()
}
std::vector<caf::ContourLines::ListOfLineSegments> unorderedLineSegmentsPerLevel =
caf::ContourLines::create( m_aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels );
caf::ContourLines::create( aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels );
contourPolygons = std::vector<ContourPolygons>( unorderedLineSegmentsPerLevel.size() );
const double areaThreshold = 1.5 * ( sampleSpacing() * sampleSpacing() ) / ( sampleSpacingFactor() * sampleSpacingFactor() );
@@ -948,23 +834,6 @@ void RimContourMapProjection::generateContourPolygons()
m_contourPolygons = contourPolygons;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::sumTriangleAreas( const std::vector<cvf::Vec4d>& triangles )
{
double sumArea = 0.0;
for ( size_t i = 0; i < triangles.size(); i += 3 )
{
cvf::Vec3d v1( triangles[i].x(), triangles[i].y(), triangles[i].z() );
cvf::Vec3d v2( triangles[i + 1].x(), triangles[i + 1].y(), triangles[i + 1].z() );
cvf::Vec3d v3( triangles[i + 2].x(), triangles[i + 2].y(), triangles[i + 2].z() );
double area = 0.5 * ( ( v3 - v1 ) ^ ( v2 - v1 ) ).length();
sumArea += area;
}
return sumArea;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -981,130 +850,13 @@ bool RimContourMapProjection::isStraightSummationResult() const
return RigContourMapCalculator::isStraightSummationResult( m_resultAggregation() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::interpolateValue( const cvf::Vec2d& gridPos2d ) const
{
cvf::Vec2ui cellContainingPoint = m_contourMapGrid->ijFromLocalPos( gridPos2d );
cvf::Vec2d cellCenter = m_contourMapGrid->cellCenterPosition( cellContainingPoint.x(), cellContainingPoint.y() );
std::array<cvf::Vec3d, 4> x;
x[0] = cvf::Vec3d( cellCenter + cvf::Vec2d( -sampleSpacing() * 0.5, -sampleSpacing() * 0.5 ), 0.0 );
x[1] = cvf::Vec3d( cellCenter + cvf::Vec2d( sampleSpacing() * 0.5, -sampleSpacing() * 0.5 ), 0.0 );
x[2] = cvf::Vec3d( cellCenter + cvf::Vec2d( sampleSpacing() * 0.5, sampleSpacing() * 0.5 ), 0.0 );
x[3] = cvf::Vec3d( cellCenter + cvf::Vec2d( -sampleSpacing() * 0.5, 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() )
{
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::valueInCell( uint i, uint j ) const
{
size_t index = m_contourMapGrid->cellIndexFromIJ( i, j );
if ( index < numberOfCells() )
{
return m_aggregatedResults.at( index );
}
return std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::hasResultInCell( uint i, uint j ) const
{
return !cellsAtIJ( i, j ).empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimContourMapProjection::calculateValueAtVertex( uint vi, uint vj ) const
{
std::vector<uint> averageIs;
std::vector<uint> averageJs;
if ( vi > 0u ) averageIs.push_back( vi - 1 );
if ( vj > 0u ) averageJs.push_back( vj - 1 );
if ( vi < m_contourMapGrid->mapSize().x() ) averageIs.push_back( vi );
if ( vj < m_contourMapGrid->mapSize().y() ) averageJs.push_back( vj );
RiaWeightedMeanCalculator<double> calc;
for ( uint j : averageJs )
{
for ( uint i : averageIs )
{
if ( hasResultInCell( i, j ) )
{
calc.addValueAndWeight( valueInCell( i, j ), 1.0 );
}
}
}
if ( calc.validAggregatedWeight() )
{
return calc.weightedMean();
}
return std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<size_t, double>> RimContourMapProjection::cellsAtIJ( uint i, uint j ) const
{
size_t cellIndex = m_contourMapGrid->cellIndexFromIJ( i, j );
if ( cellIndex < m_projected3dGridIndices.size() )
{
return m_projected3dGridIndices[cellIndex];
}
return std::vector<std::pair<size_t, double>>();
}
//--------------------------------------------------------------------------------------------------
/// Vertex positions in local coordinates (add origin2d.x() for UTM x)
//--------------------------------------------------------------------------------------------------
std::vector<double> RimContourMapProjection::xVertexPositions() const
{
return m_contourMapGrid->xVertexPositions();
if ( m_contourMapGrid ) return m_contourMapGrid->xVertexPositions();
return {};
}
//--------------------------------------------------------------------------------------------------
@@ -1112,7 +864,8 @@ std::vector<double> RimContourMapProjection::xVertexPositions() const
//--------------------------------------------------------------------------------------------------
std::vector<double> RimContourMapProjection::yVertexPositions() const
{
return m_contourMapGrid->yVertexPositions();
if ( m_contourMapGrid ) return m_contourMapGrid->yVertexPositions();
return {};
}
//--------------------------------------------------------------------------------------------------
@@ -1207,3 +960,21 @@ void RimContourMapProjection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTr
void RimContourMapProjection::initAfterRead()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimContourMapProjection::resultRangeIsValid() const
{
return m_minResultAllTimeSteps != std::numeric_limits<double>::infinity() &&
m_maxResultAllTimeSteps != -std::numeric_limits<double>::infinity();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimContourMapProjection::clearTimeStepRange()
{
m_minResultAllTimeSteps = std::numeric_limits<double>::infinity();
m_maxResultAllTimeSteps = -std::numeric_limits<double>::infinity();
}
@@ -27,12 +27,12 @@
#include "cafPdmObject.h"
#include "cvfArray.h"
#include "cvfBoundingBox.h"
#include "cvfVector2.h"
class RigContourMapGrid;
class RimGridView;
class RimRegularLegendConfig;
class RigContourMapProjection;
//==================================================================================================
///
@@ -43,8 +43,6 @@ class RimContourMapProjection : public RimCheckableNamedObject
CAF_PDM_HEADER_INIT;
public:
using CellIndexAndResult = std::pair<size_t, double>;
using ResultAggregation = caf::AppEnum<RigContourMapCalculator::ResultAggregationEnum>;
using ContourPolygons = std::vector<RigContourPolygonsTools::ContourPolygon>;
@@ -78,7 +76,6 @@ public:
double meanValue() const;
double sumAllValues() const;
cvf::Vec2ui numberOfElementsIJ() const;
cvf::Vec2ui numberOfVerticesIJ() const;
bool isColumnResult() const;
@@ -108,26 +105,19 @@ public:
virtual std::vector<double> retrieveParameterWeights() = 0;
virtual size_t kLayer( size_t globalCellIdx ) const = 0;
virtual size_t kLayers() const = 0;
virtual std::vector<size_t> findIntersectingCells( const cvf::BoundingBox& bbox ) const = 0;
virtual double calculateOverlapVolume( size_t globalCellIdx, const cvf::BoundingBox& bbox ) const = 0;
virtual double calculateRayLengthInCell( size_t globalCellIdx, const cvf::Vec3d& highestPoint, const cvf::Vec3d& lowestPoint ) const = 0;
virtual double getParameterWeightForCell( size_t globalCellIdx, const std::vector<double>& parameterWeights ) const = 0;
virtual cvf::ref<cvf::UByteArray> getCellVisibility() const;
protected:
// Protected virtual methods to be overridden by Eclipse and Geo-mechanical contour map implementations
virtual void updateGridInformation() = 0;
virtual std::vector<double> generateResults( int timeStep ) = 0;
virtual bool resultVariableChanged() const = 0;
virtual void clearResultVariable() = 0;
virtual RimGridView* baseView() const = 0;
virtual void updateGridInformation() = 0;
virtual std::vector<double> generateResults( int timeStep ) const = 0;
virtual void generateAndSaveResults( int timeStep ) = 0;
virtual bool resultVariableChanged() const = 0;
virtual void clearResultVariable() = 0;
virtual RimGridView* baseView() const = 0;
double calculateValueInMapCell( uint i, uint j, const std::vector<double>& gridCellValues ) const;
protected:
// Keep track of whether cached data needs updating
bool gridMappingNeedsUpdating() const;
bool resultsNeedsUpdating( int timeStep ) const;
@@ -137,30 +127,14 @@ protected:
void clearResults();
void clearTimeStepRange();
double maxValue( const std::vector<double>& aggregatedResults ) const;
double minValue( const std::vector<double>& aggregatedResults ) const;
virtual std::pair<double, double> minmaxValuesAllTimeSteps() = 0;
virtual std::pair<double, double> minmaxValuesAllTimeSteps();
virtual std::vector<bool> getMapCellVisibility();
bool mapCellVisibilityNeedsUpdating();
static std::vector<std::vector<std::pair<size_t, double>>> generateGridMapping( RimContourMapProjection& contourMapProjection,
const RigContourMapGrid& contourMapGrid );
bool mapCellVisibilityNeedsUpdating( int timeStep );
void generateVertexResults();
void generateTrianglesWithVertexValues();
void generateContourPolygons();
static double sumTriangleAreas( const std::vector<cvf::Vec4d>& triangles );
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;
double gridEdgeOffset() const;
virtual void updateAfterResultGeneration( int timeStep ) = 0;
@@ -180,11 +154,6 @@ protected:
caf::PdmField<bool> m_showContourLabels;
caf::PdmField<bool> m_smoothContourLines;
cvf::ref<cvf::UByteArray> m_cellGridIdxVisibility;
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;
std::vector<ContourPolygons> m_contourPolygons;
std::vector<double> m_contourLevelCumulativeAreas;
@@ -195,5 +164,6 @@ protected:
double m_minResultAllTimeSteps;
double m_maxResultAllTimeSteps;
std::unique_ptr<RigContourMapGrid> m_contourMapGrid;
std::unique_ptr<RigContourMapGrid> m_contourMapGrid;
std::unique_ptr<RigContourMapProjection> m_contourMapProjection;
};
@@ -18,15 +18,13 @@
#include "RimEclipseContourMapProjection.h"
#include "RigActiveCellInfo.h"
#include "RiaPorosityModel.h"
#include "RigCaseCellResultsData.h"
#include "RigCell.h"
#include "RigCellGeometryTools.h"
#include "RigContourMapCalculator.h"
#include "RigContourMapGrid.h"
#include "RigEclipseCaseData.h"
#include "RigEclipseContourMapProjection.h"
#include "RigEclipseResultAddress.h"
#include "RigHexIntersectionTools.h"
#include "RigMainGrid.h"
#include "Rim3dView.h"
@@ -37,8 +35,6 @@
#include "RimEclipseView.h"
#include "RimRegularLegendConfig.h"
#include <algorithm>
CAF_PDM_SOURCE_INIT( RimEclipseContourMapProjection, "RimEclipseContourMapProjection" );
//--------------------------------------------------------------------------------------------------
@@ -46,8 +42,6 @@ CAF_PDM_SOURCE_INIT( RimEclipseContourMapProjection, "RimEclipseContourMapProjec
//--------------------------------------------------------------------------------------------------
RimEclipseContourMapProjection::RimEclipseContourMapProjection()
: RimContourMapProjection()
, m_kLayers( 0u )
, m_useActiveCellInfo( true )
{
CAF_PDM_InitObject( "RimEclipseContourMapProjection", ":/2DMapProjection16x16.png" );
@@ -109,8 +103,8 @@ void RimEclipseContourMapProjection::updateLegend()
{
RimEclipseCellColors* cellColors = view()->cellResult();
double minVal = minValue( m_aggregatedResults );
double maxVal = maxValue( m_aggregatedResults );
double minVal = minValue();
double maxVal = maxValue();
auto [minValAllTimeSteps, maxValAllTimeSteps] = minmaxValuesAllTimeSteps();
@@ -138,13 +132,16 @@ void RimEclipseContourMapProjection::updateLegend()
//--------------------------------------------------------------------------------------------------
double RimEclipseContourMapProjection::sampleSpacing() const
{
if ( m_mainGrid.notNull() )
if ( auto ec = eclipseCase() )
{
return m_relativeSampleSpacing * m_mainGrid->characteristicIJCellSize();
if ( auto mainGrid = ec->mainGrid() )
{
return m_relativeSampleSpacing * mainGrid->characteristicIJCellSize();
}
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -162,76 +159,43 @@ void RimEclipseContourMapProjection::clearGridMappingAndRedraw()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimEclipseContourMapProjection::generateResults( int timeStep )
std::vector<double> RimEclipseContourMapProjection::generateResults( int timeStep ) const
{
m_weightingResult->loadResult();
size_t nCells = numberOfCells();
std::vector<double> aggregatedResults = std::vector<double>( nCells, std::numeric_limits<double>::infinity() );
RimEclipseCellColors* cellColors = view()->cellResult();
auto gridCellResult = view()->currentGridCellResults();
if ( m_contourMapProjection )
{
{
auto resultAdr = cellColors->eclipseResultAddress();
if ( resultAdr.isValid() && gridCellResult->hasResultEntry( resultAdr ) )
m_useActiveCellInfo = gridCellResult->isUsingGlobalActiveIndex( resultAdr );
}
RimEclipseCellColors* cellColors = view()->cellResult();
RigEclipseResultAddress resAddr( cellColors->resultType(),
cellColors->resultVariable(),
cellColors->timeLapseBaseTimeStep(),
cellColors->caseDiffIndex() );
if ( !cellColors->isTernarySaturationSelected() )
{
std::vector<double> gridResultValues;
if ( isColumnResult() )
{
m_currentResultName = "";
gridCellResult->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PORO" ) );
gridCellResult->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ) );
gridCellResult->ensureKnownResultLoaded( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DZ" ) );
if ( m_resultAggregation == RigContourMapCalculator::RESULTS_OIL_COLUMN ||
m_resultAggregation == RigContourMapCalculator::RESULTS_HC_COLUMN )
{
gridCellResult->ensureKnownResultLoaded(
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::soil() ) );
}
if ( m_resultAggregation == RigContourMapCalculator::RESULTS_GAS_COLUMN ||
m_resultAggregation == RigContourMapCalculator::RESULTS_HC_COLUMN )
{
gridCellResult->ensureKnownResultLoaded(
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::sgas() ) );
}
gridResultValues = calculateColumnResult( m_resultAggregation() );
}
else
{
if ( cellColors->hasStaticResult() && timeStep > 0 ) timeStep = 0;
m_currentResultName = cellColors->resultVariable();
RigEclipseResultAddress resAddr( cellColors->resultType(),
cellColors->resultVariable(),
cellColors->timeLapseBaseTimeStep(),
cellColors->caseDiffIndex() );
// When loading a project file, grid calculator results are not computed the first time this function is
// called. Must check if result is loaded. See RimReloadCaseTools::updateAll3dViews()
if ( resAddr.isValid() && gridCellResult->hasResultEntry( resAddr ) && gridCellResult->isResultLoaded( resAddr ) )
{
gridResultValues = gridCellResult->cellScalarResults( resAddr, timeStep );
}
}
if ( !gridResultValues.empty() )
{
#pragma omp parallel for
for ( int index = 0; index < static_cast<int>( nCells ); ++index )
{
cvf::Vec2ui ij = m_contourMapGrid->ijFromCellIndex( index );
aggregatedResults[index] = calculateValueInMapCell( ij.x(), ij.y(), gridResultValues );
}
}
}
return dynamic_cast<RigEclipseContourMapProjection*>( m_contourMapProjection.get() )
->generateResults( resAddr, m_resultAggregation(), timeStep );
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseContourMapProjection::generateAndSaveResults( int timeStep )
{
m_weightingResult->loadResult();
if ( m_contourMapProjection )
{
RimEclipseCellColors* cellColors = view()->cellResult();
RigEclipseResultAddress resAddr( cellColors->resultType(),
cellColors->resultVariable(),
cellColors->timeLapseBaseTimeStep(),
cellColors->caseDiffIndex() );
dynamic_cast<RigEclipseContourMapProjection*>( m_contourMapProjection.get() )
->generateAndSaveResults( resAddr, m_resultAggregation(), timeStep );
}
return aggregatedResults;
}
//--------------------------------------------------------------------------------------------------
@@ -258,80 +222,18 @@ void RimEclipseContourMapProjection::clearResultVariable()
m_currentResultName = "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimEclipseContourMapProjection::calculateColumnResult( ResultAggregation resultAggregation ) const
{
const RigCaseCellResultsData* resultData = eclipseCase()->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
bool hasPoroResult = resultData->hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PORO" ) );
bool hasNtgResult = resultData->hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ) );
bool hasDzResult = resultData->hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DZ" ) );
if ( !( hasPoroResult && hasNtgResult && hasDzResult ) )
{
return std::vector<double>();
}
const std::vector<double>& poroResults =
resultData->cellScalarResults( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "PORO" ), 0 );
const std::vector<double>& ntgResults =
resultData->cellScalarResults( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "NTG" ), 0 );
const std::vector<double>& dzResults =
resultData->cellScalarResults( RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "DZ" ), 0 );
CVF_ASSERT( poroResults.size() == ntgResults.size() && ntgResults.size() == dzResults.size() );
int timeStep = view()->currentTimeStep();
std::vector<double> resultValues( poroResults.size(), 0.0 );
if ( resultAggregation == RigContourMapCalculator::RESULTS_OIL_COLUMN || resultAggregation == RigContourMapCalculator::RESULTS_HC_COLUMN )
{
const std::vector<double>& soilResults =
resultData->cellScalarResults( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::soil() ),
timeStep );
for ( size_t cellResultIdx = 0; cellResultIdx < resultValues.size(); ++cellResultIdx )
{
resultValues[cellResultIdx] = soilResults[cellResultIdx];
}
}
if ( resultAggregation == RigContourMapCalculator::RESULTS_GAS_COLUMN || resultAggregation == RigContourMapCalculator::RESULTS_HC_COLUMN )
{
bool hasGasResult =
resultData->hasResultEntry( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::sgas() ) );
if ( hasGasResult )
{
const std::vector<double>& sgasResults =
resultData->cellScalarResults( RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, RiaResultNames::sgas() ),
timeStep );
for ( size_t cellResultIdx = 0; cellResultIdx < resultValues.size(); ++cellResultIdx )
{
resultValues[cellResultIdx] += sgasResults[cellResultIdx];
}
}
}
for ( size_t cellResultIdx = 0; cellResultIdx < resultValues.size(); ++cellResultIdx )
{
resultValues[cellResultIdx] *= poroResults[cellResultIdx] * ntgResults[cellResultIdx] * dzResults[cellResultIdx];
}
return resultValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseContourMapProjection::updateGridInformation()
{
auto eclipseCase = this->eclipseCase();
m_mainGrid = eclipseCase->eclipseCaseData()->mainGrid();
m_activeCellInfo = eclipseCase->eclipseCaseData()->activeCellInfo( RiaDefines::PorosityModelType::MATRIX_MODEL );
m_kLayers = m_mainGrid->cellCountK();
auto eclipseCase = this->eclipseCase();
auto eclipseCaseData = eclipseCase->eclipseCaseData();
auto resultData = eclipseCaseData->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
cvf::BoundingBox gridBoundingBox = eclipseCase->activeCellsBoundingBox();
m_contourMapGrid = std::make_unique<RigContourMapGrid>( gridBoundingBox, sampleSpacing() );
m_contourMapProjection = std::make_unique<RigEclipseContourMapProjection>( *m_contourMapGrid, *eclipseCaseData, *resultData );
}
//--------------------------------------------------------------------------------------------------
@@ -376,108 +278,6 @@ RimGridView* RimEclipseContourMapProjection::baseView() const
return view();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RimEclipseContourMapProjection::findIntersectingCells( const cvf::BoundingBox& bbox ) const
{
return m_mainGrid->findIntersectingCells( bbox );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimEclipseContourMapProjection::kLayer( size_t globalCellIdx ) const
{
const RigCell& cell = m_mainGrid->cell( globalCellIdx );
size_t mainGridCellIdx = cell.mainGridCellIndex();
size_t i, j, k;
m_mainGrid->ijkFromCellIndex( mainGridCellIdx, &i, &j, &k );
return k;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimEclipseContourMapProjection::kLayers() const
{
return m_kLayers;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimEclipseContourMapProjection::calculateOverlapVolume( size_t globalCellIdx, const cvf::BoundingBox& bbox ) const
{
std::array<cvf::Vec3d, 8> hexCorners;
const RigCell& cell = m_mainGrid->cell( globalCellIdx );
size_t localCellIdx = cell.gridLocalCellIndex();
RigGridBase* localGrid = cell.hostGrid();
localGrid->cellCornerVertices( localCellIdx, hexCorners.data() );
cvf::BoundingBox overlapBBox;
std::array<cvf::Vec3d, 8> overlapCorners;
if ( RigCellGeometryTools::estimateHexOverlapWithBoundingBox( hexCorners, bbox, &overlapCorners, &overlapBBox ) )
{
double overlapVolume = RigCellGeometryTools::calculateCellVolume( overlapCorners );
return overlapVolume;
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimEclipseContourMapProjection::calculateRayLengthInCell( size_t globalCellIdx,
const cvf::Vec3d& highestPoint,
const cvf::Vec3d& lowestPoint ) const
{
std::array<cvf::Vec3d, 8> hexCorners;
RigCell cell = m_mainGrid->cell( globalCellIdx );
size_t localCellIdx = cell.gridLocalCellIndex();
RigGridBase* localGrid = cell.hostGrid();
localGrid->cellCornerVertices( localCellIdx, hexCorners.data() );
std::vector<HexIntersectionInfo> intersections;
if ( RigHexIntersectionTools::lineHexCellIntersection( highestPoint, lowestPoint, hexCorners.data(), 0, &intersections ) )
{
double lengthInCell = ( intersections.back().m_intersectionPoint - intersections.front().m_intersectionPoint ).length();
return lengthInCell;
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimEclipseContourMapProjection::getParameterWeightForCell( size_t cellResultIdx, const std::vector<double>& cellWeights ) const
{
if ( cellWeights.empty() ) return 1.0;
double result = std::max( cellWeights[cellResultIdx], 0.0 );
if ( result < 1.0e-6 )
{
result = 0.0;
}
return result;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimEclipseContourMapProjection::gridResultIndex( size_t globalCellIdx ) const
{
if ( m_useActiveCellInfo ) return m_activeCellInfo->cellResultIndex( globalCellIdx );
return globalCellIdx;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -545,3 +345,23 @@ void RimEclipseContourMapProjection::initAfterRead()
m_weightingResult->setEclipseCase( eclipseCase() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<double, double> RimEclipseContourMapProjection::minmaxValuesAllTimeSteps()
{
if ( !resultRangeIsValid() )
{
clearTimeStepRange();
int timeStepCount = static_cast<int>( eclipseCase()->timeStepStrings().size() );
for ( int i = 0; i < (int)timeStepCount; ++i )
{
std::vector<double> aggregatedResults = generateResults( i );
m_minResultAllTimeSteps = std::min( m_minResultAllTimeSteps, RigContourMapProjection::minValue( aggregatedResults ) );
m_maxResultAllTimeSteps = std::max( m_maxResultAllTimeSteps, RigContourMapProjection::maxValue( aggregatedResults ) );
}
}
return std::make_pair( m_minResultAllTimeSteps, m_maxResultAllTimeSteps );
}
@@ -24,8 +24,6 @@
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cvfBoundingBox.h"
class RigActiveCellInfo;
class RigMainGrid;
class RigContourMapGrid;
@@ -57,28 +55,19 @@ public:
double sampleSpacing() const override;
protected:
using CellIndexAndResult = RimContourMapProjection::CellIndexAndResult;
void updateGridInformation() override;
std::vector<double> retrieveParameterWeights() override;
std::vector<double> generateResults( int timeStep ) override;
std::vector<double> generateResults( int timeStep ) const override;
void generateAndSaveResults( int timeStep ) override;
bool resultVariableChanged() const override;
void clearResultVariable() override;
RimGridView* baseView() const override;
std::vector<size_t> findIntersectingCells( const cvf::BoundingBox& bbox ) const override;
size_t kLayer( size_t globalCellIdx ) const override;
size_t kLayers() const override;
double calculateOverlapVolume( size_t globalCellIdx, const cvf::BoundingBox& bbox ) const override;
double calculateRayLengthInCell( size_t globalCellIdx, const cvf::Vec3d& highestPoint, const cvf::Vec3d& lowestPoint ) const override;
double getParameterWeightForCell( size_t cellResultIdx, const std::vector<double>& parameterWeights ) const override;
size_t gridResultIndex( size_t globalCellIdx ) const override;
// Eclipse implementation specific data generation methods
std::vector<double> calculateColumnResult( ResultAggregation resultAggregation ) const;
RimEclipseCase* eclipseCase() const;
RimEclipseContourMapView* view() const;
std::pair<double, double> minmaxValuesAllTimeSteps() override;
void updateAfterResultGeneration( int timeStep ) override;
protected:
@@ -91,10 +80,5 @@ protected:
caf::PdmField<bool> m_weightByParameter;
caf::PdmChildField<RimEclipseResultDefinition*> m_weightingResult;
cvf::ref<RigMainGrid> m_mainGrid;
cvf::ref<RigActiveCellInfo> m_activeCellInfo;
size_t m_kLayers;
bool m_useActiveCellInfo;
QString m_currentResultName;
};
@@ -272,6 +272,7 @@ void RimEclipseContourMapView::updateGeometry()
{
m_contourMapProjection->generateResultsIfNecessary( m_currentTimeStep() );
}
onUpdateLegends();
progress.setProgress( 30 );
}