2019-01-11 15:11:38 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Copyright (C) 2018- Equinor ASA
|
|
|
|
|
//
|
|
|
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
//
|
|
|
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
|
|
|
// for more details.
|
|
|
|
|
//
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#include "RimContourMapProjection.h"
|
|
|
|
|
|
2022-12-19 13:49:03 +01:00
|
|
|
#include "RiaOpenMPTools.h"
|
2019-01-11 15:11:38 +01:00
|
|
|
|
|
|
|
|
#include "RigCellGeometryTools.h"
|
2024-10-17 14:29:59 +02:00
|
|
|
#include "RigContourMapCalculator.h"
|
2024-10-16 14:59:24 +02:00
|
|
|
#include "RigContourMapGrid.h"
|
2024-10-25 15:11:42 +02:00
|
|
|
#include "RigContourMapProjection.h"
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2019-01-18 13:32:05 +01:00
|
|
|
#include "RimCase.h"
|
2019-01-11 15:11:38 +01:00
|
|
|
#include "RimGridView.h"
|
|
|
|
|
#include "RimProject.h"
|
|
|
|
|
#include "RimRegularLegendConfig.h"
|
|
|
|
|
#include "RimTextAnnotation.h"
|
|
|
|
|
|
|
|
|
|
#include "cafContourLines.h"
|
|
|
|
|
#include "cafPdmUiDoubleSliderEditor.h"
|
|
|
|
|
#include "cafPdmUiTreeOrdering.h"
|
2019-02-08 12:40:38 +01:00
|
|
|
#include "cafProgressInfo.h"
|
2019-01-11 15:11:38 +01:00
|
|
|
|
|
|
|
|
#include "cvfArray.h"
|
|
|
|
|
#include "cvfGeometryUtils.h"
|
|
|
|
|
#include "cvfScalarMapper.h"
|
|
|
|
|
#include "cvfStructGridGeometryGenerator.h"
|
2024-10-25 15:11:42 +02:00
|
|
|
#include "cvfVector2.h"
|
2019-01-11 15:11:38 +01:00
|
|
|
|
|
|
|
|
#include <algorithm>
|
2020-09-11 18:38:39 +02:00
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
namespace caf
|
|
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
template <>
|
2019-01-11 15:11:38 +01:00
|
|
|
void RimContourMapProjection::ResultAggregation::setUp()
|
|
|
|
|
{
|
2024-10-17 14:29:59 +02:00
|
|
|
addItem( RigContourMapCalculator::RESULTS_OIL_COLUMN, "OIL_COLUMN", "Oil Column" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_GAS_COLUMN, "GAS_COLUMN", "Gas Column" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_HC_COLUMN, "HC_COLUMN", "Hydrocarbon Column" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2024-10-17 14:29:59 +02:00
|
|
|
addItem( RigContourMapCalculator::RESULTS_MEAN_VALUE, "MEAN_VALUE", "Arithmetic Mean" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_HARM_VALUE, "HARM_VALUE", "Harmonic Mean" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_GEOM_VALUE, "GEOM_VALUE", "Geometric Mean" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_VOLUME_SUM, "VOLUME_SUM", "Volume Weighted Sum" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_SUM, "SUM", "Sum" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2024-10-17 14:29:59 +02:00
|
|
|
addItem( RigContourMapCalculator::RESULTS_TOP_VALUE, "TOP_VALUE", "Top Value" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_MIN_VALUE, "MIN_VALUE", "Min Value" );
|
|
|
|
|
addItem( RigContourMapCalculator::RESULTS_MAX_VALUE, "MAX_VALUE", "Max Value" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2024-10-17 14:29:59 +02:00
|
|
|
setDefault( RigContourMapCalculator::RESULTS_MEAN_VALUE );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
} // namespace caf
|
2024-10-25 15:11:42 +02:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
CAF_PDM_ABSTRACT_SOURCE_INIT( RimContourMapProjection, "RimContourMapProjection" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RimContourMapProjection::RimContourMapProjection()
|
2019-09-06 10:40:57 +02:00
|
|
|
: m_pickPoint( cvf::Vec2d::UNDEFINED )
|
|
|
|
|
, m_currentResultTimestep( -1 )
|
|
|
|
|
, m_minResultAllTimeSteps( std::numeric_limits<double>::infinity() )
|
|
|
|
|
, m_maxResultAllTimeSteps( -std::numeric_limits<double>::infinity() )
|
2024-10-25 15:11:42 +02:00
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2022-01-07 08:31:52 +01:00
|
|
|
CAF_PDM_InitObject( "RimContourMapProjection", ":/2DMapProjection16x16.png" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2021-11-14 14:15:12 +01:00
|
|
|
CAF_PDM_InitField( &m_relativeSampleSpacing, "SampleSpacing", 0.9, "Sample Spacing Factor" );
|
2019-09-06 10:40:57 +02:00
|
|
|
m_relativeSampleSpacing.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2021-11-14 14:15:12 +01:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_resultAggregation, "ResultAggregation", "Result Aggregation" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2021-11-14 14:15:12 +01:00
|
|
|
CAF_PDM_InitField( &m_showContourLines, "ContourLines", true, "Show Contour Lines" );
|
|
|
|
|
CAF_PDM_InitField( &m_showContourLabels, "ContourLabels", true, "Show Contour Labels" );
|
|
|
|
|
CAF_PDM_InitField( &m_smoothContourLines, "SmoothContourLines", true, "Smooth Contour Lines" );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
setName( "Map Projection" );
|
|
|
|
|
nameField()->uiCapability()->setUiReadOnly( true );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-12 11:13:38 +01:00
|
|
|
RimContourMapProjection::~RimContourMapProjection()
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2019-01-11 16:06:08 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
void RimContourMapProjection::generateResultsIfNecessary( int timeStep )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
caf::ProgressInfo progress( 100, "Generate Results", true );
|
2019-02-08 12:40:38 +01:00
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( !m_contourMapGrid || !m_contourMapProjection ) updateGridInformation();
|
|
|
|
|
|
|
|
|
|
auto cellVisibility = getCellVisibility();
|
|
|
|
|
m_contourMapProjection->setCellVisibility( cellVisibility );
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 10 );
|
2019-01-11 16:06:08 +01:00
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( gridMappingNeedsUpdating() || mapCellVisibilityNeedsUpdating( timeStep ) || resultVariableChanged() )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-01-21 15:45:35 +01:00
|
|
|
clearResults();
|
2019-05-27 09:23:44 +02:00
|
|
|
clearTimeStepRange();
|
|
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
auto cellVisibility = getCellVisibility();
|
|
|
|
|
m_contourMapProjection->setCellVisibility( cellVisibility );
|
2024-10-17 14:29:59 +02:00
|
|
|
|
|
|
|
|
if ( gridMappingNeedsUpdating() )
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
m_contourMapProjection->generateGridMapping( m_resultAggregation(), retrieveParameterWeights() );
|
2024-10-17 14:29:59 +02:00
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 20 );
|
2024-10-25 15:11:42 +02:00
|
|
|
m_mapCellVisibility = m_contourMapProjection->getMapCellVisibility( timeStep, m_resultAggregation() );
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 30 );
|
2019-02-08 12:40:38 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 30 );
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( resultsNeedsUpdating( timeStep ) )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-01-18 13:32:05 +01:00
|
|
|
clearGeometry();
|
2024-10-25 15:11:42 +02:00
|
|
|
generateAndSaveResults( timeStep );
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 80 );
|
2019-01-16 10:51:43 +01:00
|
|
|
generateVertexResults();
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 100 );
|
2020-12-07 09:30:09 +01:00
|
|
|
updateAfterResultGeneration( timeStep );
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RimContourMapProjection::generateGeometryIfNecessary()
|
|
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
caf::ProgressInfo progress( 100, "Generate Geometry", true );
|
2019-02-08 12:40:38 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( geometryNeedsUpdating() )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
|
|
|
|
generateContourPolygons();
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 25 );
|
2019-01-11 16:06:08 +01:00
|
|
|
generateTrianglesWithVertexValues();
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
progress.setProgress( 100 );
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<cvf::Vec3d> RimContourMapProjection::generatePickPointPolygon()
|
|
|
|
|
{
|
|
|
|
|
std::vector<cvf::Vec3d> points;
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( !m_pickPoint.isUndefined() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2020-04-14 08:15:21 +02:00
|
|
|
#ifndef NDEBUG
|
2024-10-16 16:08:42 +02:00
|
|
|
cvf::Vec2d cellDiagonal( sampleSpacing() * 0.5, sampleSpacing() * 0.5 );
|
|
|
|
|
cvf::Vec2ui pickedCell = m_contourMapGrid->ijFromLocalPos( m_pickPoint );
|
|
|
|
|
cvf::Vec2d cellCenter = m_contourMapGrid->cellCenterPosition( pickedCell.x(), pickedCell.y() );
|
|
|
|
|
cvf::Vec2d cellCorner = cellCenter - cellDiagonal;
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner, 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner + cvf::Vec2d( sampleSpacing(), 0.0 ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner + cvf::Vec2d( sampleSpacing(), 0.0 ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner + cvf::Vec2d( sampleSpacing(), sampleSpacing() ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner + cvf::Vec2d( sampleSpacing(), sampleSpacing() ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner + cvf::Vec2d( 0.0, sampleSpacing() ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner + cvf::Vec2d( 0.0, sampleSpacing() ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( cellCorner, 0.0 ) );
|
2019-01-11 15:11:38 +01:00
|
|
|
#endif
|
2024-10-16 16:08:42 +02:00
|
|
|
points.push_back( cvf::Vec3d( m_pickPoint - cvf::Vec2d( 0.5 * sampleSpacing(), 0.0 ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( m_pickPoint + cvf::Vec2d( 0.5 * sampleSpacing(), 0.0 ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( m_pickPoint - cvf::Vec2d( 0.0, 0.5 * sampleSpacing() ), 0.0 ) );
|
|
|
|
|
points.push_back( cvf::Vec3d( m_pickPoint + cvf::Vec2d( 0.0, 0.5 * sampleSpacing() ), 0.0 ) );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
return points;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
void RimContourMapProjection::clearGeometry()
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-01-11 16:06:08 +01:00
|
|
|
m_contourPolygons.clear();
|
|
|
|
|
m_trianglesWithVertexValues.clear();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
const std::vector<RimContourMapProjection::ContourPolygons>& RimContourMapProjection::contourPolygons() const
|
|
|
|
|
{
|
|
|
|
|
return m_contourPolygons;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
const std::vector<cvf::Vec4d>& RimContourMapProjection::trianglesWithVertexValues()
|
|
|
|
|
{
|
|
|
|
|
return m_trianglesWithVertexValues;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-09-25 11:48:41 +02:00
|
|
|
double RimContourMapProjection::sampleSpacingFactor() const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2020-09-25 11:48:41 +02:00
|
|
|
return m_relativeSampleSpacing();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-09-25 11:48:41 +02:00
|
|
|
void RimContourMapProjection::setSampleSpacingFactor( double spacingFactor )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2020-09-25 11:48:41 +02:00
|
|
|
m_relativeSampleSpacing = spacingFactor;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
bool RimContourMapProjection::showContourLines() const
|
|
|
|
|
{
|
|
|
|
|
return m_showContourLines();
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-04 15:21:17 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
bool RimContourMapProjection::showContourLabels() const
|
|
|
|
|
{
|
|
|
|
|
return m_showContourLabels();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RimContourMapProjection::resultAggregationText() const
|
|
|
|
|
{
|
|
|
|
|
return m_resultAggregation().uiText();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-10-22 09:54:31 +02:00
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RimContourMapProjection::caseName() const
|
|
|
|
|
{
|
|
|
|
|
RimCase* rimCase = baseView()->ownerCase();
|
2024-10-16 16:08:42 +02:00
|
|
|
if ( !rimCase ) return QString();
|
2019-10-22 09:54:31 +02:00
|
|
|
|
2022-08-17 22:12:23 -07:00
|
|
|
return rimCase->caseUserDescription();
|
2019-10-22 09:54:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QString RimContourMapProjection::currentTimeStepName() const
|
|
|
|
|
{
|
|
|
|
|
RimCase* rimCase = baseView()->ownerCase();
|
2024-10-16 16:08:42 +02:00
|
|
|
if ( !rimCase || m_currentResultTimestep == -1 ) return QString();
|
2019-10-22 09:54:31 +02:00
|
|
|
|
|
|
|
|
return rimCase->timeStepName( m_currentResultTimestep );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 15:11:38 +01:00
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
double RimContourMapProjection::maxValue() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->maxValue();
|
|
|
|
|
return -std::numeric_limits<double>::infinity();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
double RimContourMapProjection::minValue() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->minValue();
|
|
|
|
|
return std::numeric_limits<double>::infinity();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
double RimContourMapProjection::meanValue() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->meanValue();
|
|
|
|
|
return std::numeric_limits<double>::infinity();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
double RimContourMapProjection::sumAllValues() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->sumAllValues();
|
|
|
|
|
return 0.0;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
cvf::Vec2ui RimContourMapProjection::numberOfVerticesIJ() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapGrid ) return m_contourMapGrid->numberOfVerticesIJ();
|
|
|
|
|
return cvf::Vec2ui( 0, 0 );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
bool RimContourMapProjection::isColumnResult() const
|
|
|
|
|
{
|
2024-10-17 14:29:59 +02:00
|
|
|
return RigContourMapCalculator::isColumnResult( m_resultAggregation() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
double RimContourMapProjection::valueAtVertex( uint i, uint j ) const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->valueAtVertex( i, j );
|
2019-01-11 15:11:38 +01:00
|
|
|
return std::numeric_limits<double>::infinity();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
uint RimContourMapProjection::numberOfCells() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapGrid ) return m_contourMapGrid->numberOfCells();
|
|
|
|
|
return 0u;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
uint RimContourMapProjection::numberOfValidCells() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->numberOfValidCells();
|
|
|
|
|
return 0u;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
size_t RimContourMapProjection::numberOfVertices() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapGrid ) return m_contourMapGrid->numberOfVertices();
|
|
|
|
|
return 0;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2024-04-17 11:53:29 +02:00
|
|
|
bool RimContourMapProjection::checkForMapIntersection( const cvf::Vec3d& domainPoint3d, cvf::Vec2d* contourMapPoint, double* valueAtPoint ) const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return m_contourMapProjection->checkForMapIntersection( domainPoint3d, contourMapPoint, valueAtPoint );
|
2019-01-11 15:11:38 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
void RimContourMapProjection::setPickPoint( cvf::Vec2d globalPickPoint )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-16 14:59:24 +02:00
|
|
|
m_pickPoint = globalPickPoint - m_contourMapGrid->origin2d();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
cvf::Vec3d RimContourMapProjection::origin3d() const
|
|
|
|
|
{
|
2024-10-16 14:59:24 +02:00
|
|
|
return m_contourMapGrid->expandedBoundingBox().min();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-16 10:51:43 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
size_t RimContourMapProjection::gridResultIndex( size_t globalCellIdx ) const
|
2019-01-21 15:45:35 +01:00
|
|
|
{
|
|
|
|
|
return globalCellIdx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
double RimContourMapProjection::calculateValueInMapCell( uint i, uint j, const std::vector<double>& gridCellValues ) const
|
2019-01-16 10:51:43 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
const std::vector<std::pair<size_t, double>>& matchingCells = m_contourMapProjection->cellsAtIJ( i, j );
|
|
|
|
|
return RigContourMapCalculator::calculateValueInMapCell( *m_contourMapProjection, matchingCells, gridCellValues, m_resultAggregation() );
|
2019-01-16 10:51:43 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
bool RimContourMapProjection::gridMappingNeedsUpdating() const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( !m_contourMapProjection ) return true;
|
|
|
|
|
|
|
|
|
|
if ( m_contourMapProjection->projected3dGridIndices().size() != numberOfCells() ) return true;
|
2024-10-16 16:08:42 +02:00
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
auto cellGridIdxVisibility = m_contourMapProjection->getCellVisibility();
|
|
|
|
|
if ( cellGridIdxVisibility.isNull() ) return true;
|
2019-01-16 10:51:43 +01:00
|
|
|
|
|
|
|
|
cvf::ref<cvf::UByteArray> currentVisibility = getCellVisibility();
|
|
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
CVF_ASSERT( currentVisibility->size() == cellGridIdxVisibility->size() );
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t i = 0; i < currentVisibility->size(); ++i )
|
2019-01-16 10:51:43 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( ( *currentVisibility )[i] != ( *cellGridIdxVisibility )[i] ) return true;
|
2019-01-16 10:51:43 +01:00
|
|
|
}
|
2019-01-21 15:45:35 +01:00
|
|
|
|
2019-01-16 10:51:43 +01:00
|
|
|
return false;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
bool RimContourMapProjection::resultsNeedsUpdating( int timeStep ) const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( !m_contourMapProjection ) return true;
|
|
|
|
|
|
|
|
|
|
return ( m_contourMapProjection->aggregatedResults().size() != numberOfCells() ||
|
|
|
|
|
m_contourMapProjection->aggregatedVertexResults().size() != numberOfVertices() || timeStep != m_currentResultTimestep );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
bool RimContourMapProjection::geometryNeedsUpdating() const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-01-11 16:06:08 +01:00
|
|
|
return m_contourPolygons.empty() || m_trianglesWithVertexValues.empty();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
void RimContourMapProjection::clearGridMapping()
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-01-11 16:06:08 +01:00
|
|
|
clearResults();
|
2019-01-18 13:32:05 +01:00
|
|
|
clearTimeStepRange();
|
2024-10-25 15:11:42 +02:00
|
|
|
|
|
|
|
|
if ( m_contourMapProjection ) m_contourMapProjection->clearGridMapping();
|
2019-01-21 15:45:35 +01:00
|
|
|
m_mapCellVisibility.clear();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
void RimContourMapProjection::clearResults()
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-01-11 16:06:08 +01:00
|
|
|
clearGeometry();
|
|
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) m_contourMapProjection->clearResults();
|
2019-01-11 16:06:08 +01:00
|
|
|
m_currentResultTimestep = -1;
|
|
|
|
|
|
2019-01-16 10:51:43 +01:00
|
|
|
clearResultVariable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
cvf::ref<cvf::UByteArray> RimContourMapProjection::getCellVisibility() const
|
|
|
|
|
{
|
|
|
|
|
return baseView()->currentTotalCellVisibility();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2024-10-25 15:11:42 +02:00
|
|
|
bool RimContourMapProjection::mapCellVisibilityNeedsUpdating( int timestep )
|
2019-01-16 10:51:43 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) return true;
|
|
|
|
|
|
|
|
|
|
std::vector<bool> mapCellVisiblity = m_contourMapProjection->getMapCellVisibility( timestep, m_resultAggregation() );
|
2019-09-06 10:40:57 +02:00
|
|
|
return !( mapCellVisiblity == m_mapCellVisibility );
|
2019-01-21 15:45:35 +01:00
|
|
|
}
|
2019-01-16 10:51:43 +01:00
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RimContourMapProjection::generateVertexResults()
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapProjection ) m_contourMapProjection->generateVertexResults();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RimContourMapProjection::generateTrianglesWithVertexValues()
|
|
|
|
|
{
|
2024-10-16 14:59:24 +02:00
|
|
|
std::vector<cvf::Vec3d> vertices = m_contourMapGrid->generateVertices();
|
2019-01-11 15:11:38 +01:00
|
|
|
|
|
|
|
|
cvf::Vec2ui patchSize = numberOfVerticesIJ();
|
|
|
|
|
cvf::ref<cvf::UIntArray> faceList = new cvf::UIntArray;
|
2019-09-06 10:40:57 +02:00
|
|
|
cvf::GeometryUtils::tesselatePatchAsTriangles( patchSize.x(), patchSize.y(), 0u, true, faceList.p() );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
|
|
|
|
bool discrete = false;
|
|
|
|
|
std::vector<double> contourLevels;
|
2020-08-14 10:41:01 +02:00
|
|
|
if ( legendConfig()->mappingMode() != RimRegularLegendConfig::MappingType::CATEGORY_INTEGER )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
legendConfig()->scalarMapper()->majorTickValues( &contourLevels );
|
2020-08-14 10:41:01 +02:00
|
|
|
if ( legendConfig()->mappingMode() == RimRegularLegendConfig::MappingType::LINEAR_DISCRETE ||
|
|
|
|
|
legendConfig()->mappingMode() == RimRegularLegendConfig::MappingType::LOG10_DISCRETE )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
discrete = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-25 11:48:41 +02:00
|
|
|
const double cellArea = sampleSpacing() * sampleSpacing();
|
2019-01-17 19:27:49 +01:00
|
|
|
const double areaThreshold = 1.0e-5 * 0.5 * cellArea;
|
|
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
std::vector<std::vector<std::vector<cvf::Vec3d>>> subtractPolygons;
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( !m_contourPolygons.empty() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
subtractPolygons.resize( m_contourPolygons.size() );
|
|
|
|
|
for ( size_t i = 0; i < m_contourPolygons.size() - 1; ++i )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t j = 0; j < m_contourPolygons[i + 1].size(); ++j )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
subtractPolygons[i].push_back( m_contourPolygons[i + 1][j].vertices );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-11 18:38:39 +02:00
|
|
|
|
2022-12-19 13:49:03 +01:00
|
|
|
int numberOfThreads = RiaOpenMPTools::availableThreadCount();
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<std::vector<cvf::Vec4d>>> threadTriangles( numberOfThreads );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
const std::vector<double>& aggregatedVertexResults = m_contourMapProjection->aggregatedVertexResults();
|
|
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
#pragma omp parallel
|
|
|
|
|
{
|
2022-12-19 13:49:03 +01:00
|
|
|
int myThread = RiaOpenMPTools::currentThreadIndex();
|
2019-09-06 10:40:57 +02:00
|
|
|
threadTriangles[myThread].resize( std::max( (size_t)1, m_contourPolygons.size() ) );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
#pragma omp for schedule( dynamic )
|
|
|
|
|
for ( int64_t i = 0; i < (int64_t)faceList->size(); i += 3 )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
std::vector<cvf::Vec3d> triangle( 3 );
|
|
|
|
|
std::vector<cvf::Vec4d> triangleWithValues( 3 );
|
|
|
|
|
bool anyValidVertex = false;
|
|
|
|
|
for ( size_t n = 0; n < 3; ++n )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
uint vn = ( *faceList )[i + n];
|
|
|
|
|
double value = vn < aggregatedVertexResults.size() ? aggregatedVertexResults[vn] : std::numeric_limits<double>::infinity();
|
|
|
|
|
triangle[n] = vertices[vn];
|
2019-09-06 10:40:57 +02:00
|
|
|
triangleWithValues[n] = cvf::Vec4d( vertices[vn], value );
|
|
|
|
|
if ( value != std::numeric_limits<double>::infinity() )
|
2019-01-18 11:31:00 +01:00
|
|
|
{
|
|
|
|
|
anyValidVertex = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( !anyValidVertex )
|
2019-01-18 11:31:00 +01:00
|
|
|
{
|
|
|
|
|
continue;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( m_contourPolygons.empty() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2023-02-26 10:48:40 +01:00
|
|
|
threadTriangles[myThread][0].insert( threadTriangles[myThread][0].end(), triangleWithValues.begin(), triangleWithValues.end() );
|
2019-01-11 15:11:38 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-18 11:31:00 +01:00
|
|
|
bool outsideOuterLimit = false;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t c = 0; c < m_contourPolygons.size() && !outsideOuterLimit; ++c )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
std::vector<std::vector<cvf::Vec3d>> intersectPolygons;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t j = 0; j < m_contourPolygons[c].size(); ++j )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
bool containsAtLeastOne = false;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t t = 0; t < 3; ++t )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( m_contourPolygons[c][j].bbox.contains( triangle[t] ) )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
containsAtLeastOne = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( containsAtLeastOne )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
std::vector<std::vector<cvf::Vec3d>> clippedPolygons =
|
2020-12-03 09:19:32 +01:00
|
|
|
RigCellGeometryTools::intersectionWithPolygon( triangle, m_contourPolygons[c][j].vertices );
|
2019-09-06 10:40:57 +02:00
|
|
|
intersectPolygons.insert( intersectPolygons.end(), clippedPolygons.begin(), clippedPolygons.end() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( intersectPolygons.empty() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-01-18 11:31:00 +01:00
|
|
|
outsideOuterLimit = true;
|
2019-01-11 15:11:38 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
std::vector<std::vector<cvf::Vec3d>> clippedPolygons;
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( !subtractPolygons[c].empty() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( const std::vector<cvf::Vec3d>& polygon : intersectPolygons )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
std::vector<std::vector<cvf::Vec3d>> fullyClippedPolygons =
|
2019-09-06 10:40:57 +02:00
|
|
|
RigCellGeometryTools::subtractPolygons( polygon, subtractPolygons[c] );
|
2023-02-26 10:48:40 +01:00
|
|
|
clippedPolygons.insert( clippedPolygons.end(), fullyClippedPolygons.begin(), fullyClippedPolygons.end() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
clippedPolygons.swap( intersectPolygons );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
2019-01-17 19:27:49 +01:00
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
std::vector<cvf::Vec4d> clippedTriangles;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( std::vector<cvf::Vec3d>& clippedPolygon : clippedPolygons )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
std::vector<std::vector<cvf::Vec3d>> polygonTriangles;
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( clippedPolygon.size() == 3u )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
polygonTriangles.push_back( clippedPolygon );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cvf::Vec3d baryCenter = cvf::Vec3d::ZERO;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t v = 0; v < clippedPolygon.size(); ++v )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
cvf::Vec3d& clippedVertex = clippedPolygon[v];
|
|
|
|
|
baryCenter += clippedVertex;
|
|
|
|
|
}
|
|
|
|
|
baryCenter /= clippedPolygon.size();
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t v = 0; v < clippedPolygon.size(); ++v )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
std::vector<cvf::Vec3d> clippedTriangle;
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( v == clippedPolygon.size() - 1 )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2020-11-06 09:46:38 +00:00
|
|
|
clippedTriangle = { clippedPolygon[v], clippedPolygon[0], baryCenter };
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-11-06 09:46:38 +00:00
|
|
|
clippedTriangle = { clippedPolygon[v], clippedPolygon[v + 1], baryCenter };
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
polygonTriangles.push_back( clippedTriangle );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( const std::vector<cvf::Vec3d>& polygonTriangle : polygonTriangles )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-01-17 19:27:49 +01:00
|
|
|
// Check triangle area
|
2023-02-26 10:48:40 +01:00
|
|
|
double area =
|
|
|
|
|
0.5 * ( ( polygonTriangle[1] - polygonTriangle[0] ) ^ ( polygonTriangle[2] - polygonTriangle[0] ) ).length();
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( area < areaThreshold ) continue;
|
|
|
|
|
for ( const cvf::Vec3d& localVertex : polygonTriangle )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
double value = std::numeric_limits<double>::infinity();
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( discrete )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2023-02-26 10:48:40 +01:00
|
|
|
value = contourLevels[c] + 0.01 * ( contourLevels.back() - contourLevels.front() ) / contourLevels.size();
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t n = 0; n < 3; ++n )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2020-09-25 11:48:41 +02:00
|
|
|
if ( ( triangle[n] - localVertex ).length() < sampleSpacing() * 0.01 &&
|
2019-09-06 10:40:57 +02:00
|
|
|
triangleWithValues[n].w() != std::numeric_limits<double>::infinity() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
value = triangleWithValues[n].w();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( value == std::numeric_limits<double>::infinity() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
value = m_contourMapProjection->interpolateValue( cvf::Vec2d( localVertex.x(), localVertex.y() ) );
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( value == std::numeric_limits<double>::infinity() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
|
|
|
|
value = contourLevels[c];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
cvf::Vec4d globalVertex( localVertex, value );
|
|
|
|
|
clippedTriangles.push_back( globalVertex );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-08-24 09:39:15 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Add critical section here due to a weird bug when running in a single thread
|
|
|
|
|
// Running multi threaded does not require this critical section, as we use a thread local data
|
|
|
|
|
// structure
|
|
|
|
|
#pragma omp critical
|
|
|
|
|
threadTriangles[myThread][c].insert( threadTriangles[myThread][c].end(),
|
|
|
|
|
clippedTriangles.begin(),
|
|
|
|
|
clippedTriangles.end() );
|
|
|
|
|
}
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-17 19:27:49 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
std::vector<std::vector<cvf::Vec4d>> trianglesPerLevel( std::max( (size_t)1, m_contourPolygons.size() ) );
|
|
|
|
|
for ( size_t c = 0; c < trianglesPerLevel.size(); ++c )
|
2019-01-17 19:27:49 +01:00
|
|
|
{
|
|
|
|
|
std::vector<cvf::Vec4d> allTrianglesThisLevel;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t i = 0; i < threadTriangles.size(); ++i )
|
2019-01-17 19:27:49 +01:00
|
|
|
{
|
2023-02-26 10:48:40 +01:00
|
|
|
allTrianglesThisLevel.insert( allTrianglesThisLevel.end(), threadTriangles[i][c].begin(), threadTriangles[i][c].end() );
|
2019-01-17 19:27:49 +01:00
|
|
|
}
|
|
|
|
|
|
2024-10-25 15:11:42 +02:00
|
|
|
double triangleAreasThisLevel = RigContourMapProjection::sumTriangleAreas( allTrianglesThisLevel );
|
2023-02-26 10:48:40 +01:00
|
|
|
if ( c >= m_contourLevelCumulativeAreas.size() || triangleAreasThisLevel > 1.0e-3 * m_contourLevelCumulativeAreas[c] )
|
2019-01-17 19:27:49 +01:00
|
|
|
{
|
|
|
|
|
trianglesPerLevel[c] = allTrianglesThisLevel;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:11:38 +01:00
|
|
|
std::vector<cvf::Vec4d> finalTriangles;
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t i = 0; i < trianglesPerLevel.size(); ++i )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
finalTriangles.insert( finalTriangles.end(), trianglesPerLevel[i].begin(), trianglesPerLevel[i].end() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_trianglesWithVertexValues = finalTriangles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RimContourMapProjection::generateContourPolygons()
|
|
|
|
|
{
|
|
|
|
|
std::vector<ContourPolygons> contourPolygons;
|
|
|
|
|
|
2019-01-18 16:12:02 +01:00
|
|
|
std::vector<double> contourLevels;
|
2020-08-14 10:41:01 +02:00
|
|
|
if ( resultRangeIsValid() && legendConfig()->mappingMode() != RimRegularLegendConfig::MappingType::CATEGORY_INTEGER )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
const std::vector<double>& aggregatedVertexResults = m_contourMapProjection->aggregatedVertexResults();
|
|
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
legendConfig()->scalarMapper()->majorTickValues( &contourLevels );
|
|
|
|
|
int nContourLevels = static_cast<int>( contourLevels.size() );
|
2019-01-18 16:12:02 +01:00
|
|
|
|
2023-02-26 10:48:40 +01:00
|
|
|
if ( minValue() != std::numeric_limits<double>::infinity() && maxValue() != -std::numeric_limits<double>::infinity() &&
|
|
|
|
|
std::fabs( maxValue() - minValue() ) > 1.0e-8 )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( nContourLevels > 2 )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2020-09-28 14:22:07 +02:00
|
|
|
const size_t N = contourLevels.size();
|
|
|
|
|
// Adjust contour levels slightly to avoid weird visual artifacts due to numerical error.
|
|
|
|
|
double fudgeFactor = 1.0e-3;
|
|
|
|
|
double fudgeAmountMin = fudgeFactor * ( contourLevels[1] - contourLevels[0] );
|
|
|
|
|
double fudgeAmountMax = fudgeFactor * ( contourLevels[N - 1u] - contourLevels[N - 2u] );
|
|
|
|
|
|
|
|
|
|
contourLevels.front() += fudgeAmountMin;
|
|
|
|
|
contourLevels.back() -= fudgeAmountMax;
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2020-09-25 11:48:41 +02:00
|
|
|
double simplifyEpsilon = m_smoothContourLines() ? 5.0e-2 * sampleSpacing() : 1.0e-3 * sampleSpacing();
|
2019-03-22 08:49:39 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( nContourLevels >= 10 )
|
2019-03-22 08:49:39 +01:00
|
|
|
{
|
|
|
|
|
simplifyEpsilon *= 2.0;
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( numberOfCells() > 100000 )
|
2019-03-22 08:49:39 +01:00
|
|
|
{
|
|
|
|
|
simplifyEpsilon *= 2.0;
|
|
|
|
|
}
|
2020-12-03 09:22:07 +01:00
|
|
|
else if ( numberOfCells() > 1000000 )
|
|
|
|
|
{
|
|
|
|
|
simplifyEpsilon *= 4.0;
|
|
|
|
|
}
|
2019-03-22 08:49:39 +01:00
|
|
|
|
2019-01-18 16:12:02 +01:00
|
|
|
std::vector<caf::ContourLines::ListOfLineSegments> unorderedLineSegmentsPerLevel =
|
2024-10-25 15:11:42 +02:00
|
|
|
caf::ContourLines::create( aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels );
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
contourPolygons = std::vector<ContourPolygons>( unorderedLineSegmentsPerLevel.size() );
|
2024-10-17 09:19:52 +02:00
|
|
|
const double areaThreshold = 1.5 * ( sampleSpacing() * sampleSpacing() ) / ( sampleSpacingFactor() * sampleSpacingFactor() );
|
2019-01-18 16:12:02 +01:00
|
|
|
|
2019-03-21 18:26:35 +01:00
|
|
|
#pragma omp parallel for
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( int i = 0; i < (int)unorderedLineSegmentsPerLevel.size(); ++i )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-17 09:19:52 +02:00
|
|
|
contourPolygons[i] = RigContourPolygonsTools::createContourPolygonsFromLineSegments( unorderedLineSegmentsPerLevel[i],
|
|
|
|
|
contourLevels[i],
|
|
|
|
|
areaThreshold );
|
2019-09-06 10:40:57 +02:00
|
|
|
|
|
|
|
|
if ( m_smoothContourLines() )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-17 09:19:52 +02:00
|
|
|
RigContourPolygonsTools::smoothContourPolygons( contourPolygons[i], true, sampleSpacing() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
2019-03-21 18:26:35 +01:00
|
|
|
|
2024-10-17 09:19:52 +02:00
|
|
|
for ( RigContourPolygonsTools::ContourPolygon& polygon : contourPolygons[i] )
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
RigCellGeometryTools::simplifyPolygon( &polygon.vertices, simplifyEpsilon );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-17 19:27:49 +01:00
|
|
|
|
2020-11-25 10:42:20 +01:00
|
|
|
// The clipping of contour polygons is intended to detect and fix a smoothed contour polygons
|
|
|
|
|
// crossing into an outer contour line. The current implementation has some side effects causing
|
|
|
|
|
// several contour lines to disappear. Disable this clipping for now
|
|
|
|
|
/*
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( m_smoothContourLines() )
|
2019-01-18 11:31:00 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
for ( size_t i = 1; i < contourPolygons.size(); ++i )
|
2019-01-18 11:31:00 +01:00
|
|
|
{
|
2024-10-17 09:19:52 +02:00
|
|
|
RigContourPolygonsTools::clipContourPolygons(&contourPolygons[i], &contourPolygons[i - 1] );
|
2019-01-18 11:31:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-11-25 10:42:20 +01:00
|
|
|
*/
|
2019-03-21 18:26:35 +01:00
|
|
|
|
2019-09-06 10:40:57 +02:00
|
|
|
m_contourLevelCumulativeAreas.resize( contourPolygons.size(), 0.0 );
|
|
|
|
|
for ( int64_t i = (int64_t)contourPolygons.size() - 1; i >= 0; --i )
|
2019-01-17 19:27:49 +01:00
|
|
|
{
|
2024-10-17 09:19:52 +02:00
|
|
|
double levelOuterArea = RigContourPolygonsTools::sumPolygonArea( contourPolygons[i] );
|
2019-01-17 19:27:49 +01:00
|
|
|
m_contourLevelCumulativeAreas[i] = levelOuterArea;
|
|
|
|
|
}
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_contourPolygons = contourPolygons;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-16 10:51:43 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
bool RimContourMapProjection::isMeanResult() const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-17 14:29:59 +02:00
|
|
|
return RigContourMapCalculator::isMeanResult( m_resultAggregation() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-01-11 16:06:08 +01:00
|
|
|
bool RimContourMapProjection::isStraightSummationResult() const
|
2019-01-11 15:11:38 +01:00
|
|
|
{
|
2024-10-17 14:29:59 +02:00
|
|
|
return RigContourMapCalculator::isStraightSummationResult( m_resultAggregation() );
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-10-15 15:42:43 +02:00
|
|
|
/// Vertex positions in local coordinates (add origin2d.x() for UTM x)
|
2019-01-11 15:11:38 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<double> RimContourMapProjection::xVertexPositions() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapGrid ) return m_contourMapGrid->xVertexPositions();
|
|
|
|
|
return {};
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-10-15 15:42:43 +02:00
|
|
|
/// Vertex positions in local coordinates (add origin2d.y() for UTM y)
|
2019-01-11 15:11:38 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
std::vector<double> RimContourMapProjection::yVertexPositions() const
|
|
|
|
|
{
|
2024-10-25 15:11:42 +02:00
|
|
|
if ( m_contourMapGrid ) return m_contourMapGrid->yVertexPositions();
|
|
|
|
|
return {};
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
double RimContourMapProjection::gridEdgeOffset() const
|
|
|
|
|
{
|
2020-09-25 11:48:41 +02:00
|
|
|
return sampleSpacing() * 2.0;
|
2019-01-11 15:11:38 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 16:06:08 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2023-02-26 10:48:40 +01:00
|
|
|
void RimContourMapProjection::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( changedField == &m_resultAggregation )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2024-10-17 14:29:59 +02:00
|
|
|
ResultAggregation previousAggregation = static_cast<RigContourMapCalculator::ResultAggregationEnum>( oldValue.toInt() );
|
|
|
|
|
if ( RigContourMapCalculator::isStraightSummationResult( previousAggregation ) != isStraightSummationResult() )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
|
|
|
|
clearGridMapping();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
clearResults();
|
|
|
|
|
}
|
2019-01-18 13:32:05 +01:00
|
|
|
clearTimeStepRange();
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
else if ( changedField == &m_smoothContourLines )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
|
|
|
|
clearGeometry();
|
|
|
|
|
}
|
2019-09-06 10:40:57 +02:00
|
|
|
else if ( changedField == &m_relativeSampleSpacing )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-01-18 13:32:05 +01:00
|
|
|
clearGridMapping();
|
2019-01-11 16:06:08 +01:00
|
|
|
clearResults();
|
2019-01-18 13:32:05 +01:00
|
|
|
clearTimeStepRange();
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
baseView()->updateConnectedEditors();
|
|
|
|
|
|
2023-05-12 21:41:34 +02:00
|
|
|
RimProject* proj = RimProject::current();
|
2019-01-11 16:06:08 +01:00
|
|
|
proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2023-02-26 10:48:40 +01:00
|
|
|
void RimContourMapProjection::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
if ( &m_relativeSampleSpacing == field )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
|
|
|
|
|
if ( myAttr )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
myAttr->m_minimum = 0.2;
|
|
|
|
|
myAttr->m_maximum = 2.0;
|
|
|
|
|
myAttr->m_sliderTickCount = 9;
|
2019-01-22 15:48:21 +01:00
|
|
|
myAttr->m_delaySliderUpdateUntilRelease = true;
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-11 15:11:38 +01:00
|
|
|
|
2019-01-11 16:06:08 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 10:40:57 +02:00
|
|
|
void RimContourMapProjection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
caf::PdmUiGroup* mainGroup = uiOrdering.addNewGroup( "Projection Settings" );
|
|
|
|
|
mainGroup->add( &m_resultAggregation );
|
|
|
|
|
legendConfig()->uiOrdering( "NumLevelsOnly", *mainGroup );
|
|
|
|
|
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() );
|
|
|
|
|
uiOrdering.skipRemainingFields( true );
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-12 11:43:15 +01:00
|
|
|
void RimContourMapProjection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/ )
|
2019-01-11 16:06:08 +01:00
|
|
|
{
|
2019-09-06 10:40:57 +02:00
|
|
|
uiTreeOrdering.skipRemainingChildren( true );
|
2019-01-11 16:06:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-12 11:13:38 +01:00
|
|
|
void RimContourMapProjection::initAfterRead()
|
|
|
|
|
{
|
|
|
|
|
}
|
2024-10-25 15:11:42 +02:00
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
///
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
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();
|
|
|
|
|
}
|