Move GeoMech PDM files into subfolder

This commit is contained in:
jonjenssen
2021-03-10 13:56:28 +01:00
committed by jonjenssen
parent 207f72c37e
commit df53e80913
20 changed files with 35 additions and 17 deletions

View File

@@ -0,0 +1,32 @@
set (SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechModels.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechCase.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechView.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechResultDefinition.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechCellColors.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapProjection.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapView.h
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapViewCollection.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechModels.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechCase.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechView.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechResultDefinition.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechCellColors.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapProjection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapView.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGeoMechContourMapViewCollection.cpp
)
list(APPEND CODE_HEADER_FILES
${SOURCE_GROUP_HEADER_FILES}
)
list(APPEND CODE_SOURCE_FILES
${SOURCE_GROUP_SOURCE_FILES}
)
source_group( "ProjectDataModel\\GeoMech" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimCase.h"
#include "cafFilePath.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "cvfObject.h"
#include <QDateTime>
class RimGeoMechView;
class RigGeoMechCaseData;
class RifGeoMechReaderInterface;
class RimGeoMechContourMapView;
class RimGeoMechContourMapViewCollection;
class RimMudWeightWindowParameters;
//==================================================================================================
///
///
//==================================================================================================
class RimGeoMechCase : public RimCase
{
CAF_PDM_HEADER_INIT;
public:
enum CaseOpenStatus
{
CASE_OPEN_OK = 0,
CASE_OPEN_CANCELLED,
CASE_OPEN_ERROR
};
enum class BiotCoefficientType
{
BIOT_NONE = 0,
BIOT_FIXED,
BIOT_PER_ELEMENT
};
enum class InitialPermeabilityType
{
INITIAL_PERMEABILITY_FIXED = 0,
INITIAL_PERMEABILITY_PER_ELEMENT
};
RimGeoMechCase( void );
~RimGeoMechCase( void ) override;
CaseOpenStatus openGeoMechCase( std::string* errorMessage );
RimGeoMechCase* createCopy( const QString& newInputFileName );
RigGeoMechCaseData* geoMechData();
const RigGeoMechCaseData* geoMechData() const;
RimGeoMechContourMapViewCollection* contourMapCollection();
void reloadDataAndUpdate();
RimGeoMechView* createAndAddReservoirView();
RimGeoMechView* createCopyAndAddView( const RimGeoMechView* sourceView );
void updateFilePathsFromProjectPath( const QString& projectPath, const QString& oldProjectPath ) override;
std::vector<QDateTime> timeStepDates() const override;
QStringList timeStepStrings() const override;
QString timeStepName( int frameIdx ) const override;
cvf::BoundingBox reservoirBoundingBox() override;
cvf::BoundingBox activeCellsBoundingBox() const override;
cvf::BoundingBox allCellsBoundingBox() const override;
double characteristicCellSize() const override;
void addElementPropertyFiles( const std::vector<caf::FilePath>& filenames );
double cohesion() const;
double frictionAngleDeg() const;
void setApplyTimeFilter( bool applyTimeFilter );
// Fields:
caf::PdmChildArrayField<RimGeoMechView*> geoMechViews;
BiotCoefficientType biotCoefficientType() const;
double biotFixedCoefficient() const;
QString biotResultAddress() const;
InitialPermeabilityType initialPermeabilityType() const;
double initialPermeabilityFixed() const;
QString initialPermeabilityAddress() const;
double permeabilityExponent() const;
std::vector<std::string> possibleElementPropertyFieldNames();
std::vector<caf::FilePath> elementPropertyFileNames() const;
QString findFileNameForElementProperty( const std::string& elementProperty,
const std::map<std::string, QString> addressesInFiles ) const;
void updateConnectedViews();
private:
cvf::Vec3d displayModelOffset() const override;
static std::vector<QDateTime> vectorOfValidDateTimesFromTimeStepStrings( const QStringList& timeStepStrings );
static QDateTime dateTimeFromTimeStepString( const QString& timeStepString );
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void updateFormationNamesData() override;
void initAfterRead() override;
static QString subStringOfDigits( const QString& timeStepString, int numberOfDigitsToFind );
void importElementPropertyFile();
void closeSelectedElementPropertyFiles();
void reloadSelectedElementPropertyFiles();
std::vector<Rim3dView*> allSpecialViews() const override;
private:
cvf::ref<RigGeoMechCaseData> m_geoMechCaseData;
caf::PdmField<double> m_cohesion;
caf::PdmField<double> m_frictionAngleDeg;
caf::PdmField<std::vector<caf::FilePath>> m_elementPropertyFileNames;
caf::PdmField<std::vector<int>> m_elementPropertyFileNameIndexUiSelection;
caf::PdmField<bool> m_importElementPropertyFileCommand;
caf::PdmField<bool> m_closeElementPropertyFileCommand;
caf::PdmField<bool> m_reloadElementPropertyFileCommand;
caf::PdmField<caf::AppEnum<BiotCoefficientType>> m_biotCoefficientType;
caf::PdmField<double> m_biotFixedCoefficient;
caf::PdmField<QString> m_biotResultAddress;
caf::PdmField<caf::AppEnum<InitialPermeabilityType>> m_initialPermeabilityType;
caf::PdmField<double> m_initialPermeabilityFixed;
caf::PdmField<QString> m_initialPermeabilityResultAddress;
caf::PdmField<double> m_permeabilityExponent;
caf::PdmField<double> m_waterDensityShearSlipIndicator;
caf::PdmChildField<RimGeoMechContourMapViewCollection*> m_contourMapCollection;
caf::PdmChildField<RimMudWeightWindowParameters*> m_mudWeightWindowParameters;
bool m_applyTimeFilter;
};

View File

@@ -0,0 +1,116 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimGeoMechCellColors.h"
#include "Rim3dView.h"
#include "RimRegularLegendConfig.h"
#include "RimViewController.h"
#include "RimViewLinker.h"
CAF_PDM_SOURCE_INIT( RimGeoMechCellColors, "GeoMechResultSlot" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCellColors::RimGeoMechCellColors( void )
: legendConfigChanged( this )
{
CAF_PDM_InitFieldNoDefault( &legendConfig, "LegendDefinition", "Color Legend", "", "", "" );
this->legendConfig = new RimRegularLegendConfig();
legendConfig.uiCapability()->setUiHidden( true );
legendConfig->changed.connect( this, &RimGeoMechCellColors::onLegendConfigChanged );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCellColors::~RimGeoMechCellColors( void )
{
delete legendConfig;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechCellColors::updateIconState()
{
Rim3dView* rimView = nullptr;
this->firstAncestorOrThisOfType( rimView );
CVF_ASSERT( rimView );
if ( rimView )
{
RimViewController* viewController = rimView->viewController();
if ( viewController && viewController->isResultColorControlled() )
{
updateUiIconFromState( false );
}
else
{
updateUiIconFromState( true );
}
}
uiCapability()->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechCellColors::initAfterRead()
{
RimGeoMechResultDefinition::initAfterRead();
updateIconState();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechCellColors::updateLegendCategorySettings()
{
if ( this->hasCategoryResult() )
{
legendConfig->setMappingMode( RimRegularLegendConfig::MappingType::CATEGORY_INTEGER );
legendConfig->setColorLegend(
RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::CATEGORY ) );
}
else
{
if ( legendConfig->mappingMode() == RimRegularLegendConfig::MappingType::CATEGORY_INTEGER )
{
legendConfig->setMappingMode( RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS );
}
if ( legendConfig->colorLegend() ==
RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::CATEGORY ) )
{
legendConfig->setColorLegend(
RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::NORMAL ) );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechCellColors::onLegendConfigChanged( const caf::SignalEmitter* emitter, RimLegendConfigChangeType changeType )
{
legendConfigChanged.send( changeType );
}

View File

@@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimGeoMechResultDefinition.h"
#include "RimLegendConfigChangeType.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
class RimRegularLegendConfig;
//==================================================================================================
///
///
//==================================================================================================
class RimGeoMechCellColors : public RimGeoMechResultDefinition
{
CAF_PDM_HEADER_INIT;
public:
caf::Signal<RimLegendConfigChangeType> legendConfigChanged;
public:
RimGeoMechCellColors( void );
~RimGeoMechCellColors( void ) override;
caf::PdmChildField<RimRegularLegendConfig*> legendConfig;
void updateIconState();
void initAfterRead() override;
protected:
void updateLegendCategorySettings() override;
void onLegendConfigChanged( const caf::SignalEmitter* emitter, RimLegendConfigChangeType changeType );
};

View File

@@ -0,0 +1,665 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimGeoMechContourMapProjection.h"
#include "RiaImageTools.h"
#include "RiaWeightedGeometricMeanCalculator.h"
#include "RiaWeightedHarmonicMeanCalculator.h"
#include "RiaWeightedMeanCalculator.h"
#include "RigCellGeometryTools.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigGeoMechCaseData.h"
#include "RigHexIntersectionTools.h"
#include "RimCellFilterCollection.h"
#include "RimGeoMechCellColors.h"
#include "RimGeoMechContourMapView.h"
#include "RimGeoMechPropertyFilterCollection.h"
#include "RivFemElmVisibilityCalculator.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cvfArray.h"
#include "cvfCellRange.h"
#include "cvfGeometryTools.h"
#include "cvfGeometryUtils.h"
#include "cvfScalarMapper.h"
#include "cvfStructGridGeometryGenerator.h"
#include "cvfVector3.h"
#include <QDebug>
#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", "", "", "" );
CAF_PDM_InitField( &m_applyPPRegionLimitVertically, "VerticalLimit", false, "Apply Limit Vertically", "", "", "" );
CAF_PDM_InitField( &m_paddingAroundPorePressureRegion,
"PaddingAroundPorRegion",
0.0,
"Horizontal Padding around PP regions",
"",
"",
"" );
m_paddingAroundPorePressureRegion.uiCapability()->setUiEditorTypeName(
caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
setName( "Map Projection" );
nameField()->uiCapability()->setUiReadOnly( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapProjection::~RimGeoMechContourMapProjection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGeoMechContourMapProjection::resultDescriptionText() const
{
QString resultText =
QString( "%1, %2" ).arg( resultAggregationText() ).arg( view()->cellResult()->resultFieldUiName() );
return resultText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimRegularLegendConfig* RimGeoMechContourMapProjection::legendConfig() const
{
return view()->cellResult()->legendConfig();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::updateLegend()
{
RimGeoMechCellColors* cellColors = view()->cellResult();
double minVal = minValue( m_aggregatedResults );
double maxVal = maxValue( m_aggregatedResults );
std::pair<double, double> minmaxValAllTimeSteps = minmaxValuesAllTimeSteps();
legendConfig()->setAutomaticRanges( minmaxValAllTimeSteps.first, minmaxValAllTimeSteps.second, minVal, maxVal );
QString projectionLegendText = QString( "Map Projection\n%1" ).arg( m_resultAggregation().uiText() );
if ( cellColors->resultAddress().isValid() )
{
projectionLegendText += QString( "\nResult: %1" ).arg( cellColors->resultFieldUiName() );
if ( !cellColors->resultComponentUiName().isEmpty() )
{
projectionLegendText += QString( ", %1" ).arg( cellColors->resultComponentUiName() );
}
}
else
{
projectionLegendText += QString( "\nNo Result Selected" );
}
legendConfig()->setTitle( projectionLegendText );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimGeoMechContourMapProjection::sampleSpacing() const
{
RimGeoMechCase* geoMechCase = this->geoMechCase();
if ( geoMechCase )
{
return m_relativeSampleSpacing * geoMechCase->characteristicCellSize();
}
return 0.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::UByteArray> RimGeoMechContourMapProjection::getCellVisibility() const
{
cvf::ref<cvf::UByteArray> cellGridIdxVisibility = new cvf::UByteArray( m_femPart->elementCount() );
RivFemElmVisibilityCalculator::computeAllVisible( cellGridIdxVisibility.p(), m_femPart.p() );
if ( view()->cellFilterCollection()->isActive() )
{
cvf::CellRangeFilter cellRangeFilter;
view()->cellFilterCollection()->compoundCellRangeFilter( &cellRangeFilter, 0 );
RivFemElmVisibilityCalculator::computeRangeVisibility( cellGridIdxVisibility.p(), m_femPart.p(), cellRangeFilter );
}
if ( view()->propertyFilterCollection()->isActive() )
{
RivFemElmVisibilityCalculator::computePropertyVisibility( cellGridIdxVisibility.p(),
m_femPart.p(),
view()->currentTimeStep(),
cellGridIdxVisibility.p(),
view()->geoMechPropertyFilterCollection() );
}
return cellGridIdxVisibility;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox RimGeoMechContourMapProjection::calculateExpandedPorBarBBox( int timeStep ) const
{
RigFemResultAddress porBarAddr( RigFemResultPosEnum::RIG_ELEMENT_NODAL,
"POR-Bar",
view()->cellResult()->resultComponentName().toStdString() );
RigGeoMechCaseData* caseData = geoMechCase()->geoMechData();
RigFemPartResultsCollection* resultCollection = caseData->femPartResults();
const std::vector<float>& resultValues = resultCollection->resultValues( porBarAddr, 0, timeStep );
cvf::BoundingBox 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();
m_femPart->ensureIntersectionSearchTreeIsBuilt();
m_gridBoundingBox = geoMechCase->activeCellsBoundingBox();
if ( m_limitToPorePressureRegions )
{
m_expandedBoundingBox = calculateExpandedPorBarBBox( view()->currentTimeStep() );
}
else
{
m_expandedBoundingBox = m_gridBoundingBox;
}
cvf::Vec3d minExpandedPoint = m_expandedBoundingBox.min() - cvf::Vec3d( gridEdgeOffset(), gridEdgeOffset(), 0.0 );
cvf::Vec3d maxExpandedPoint = m_expandedBoundingBox.max() + cvf::Vec3d( gridEdgeOffset(), gridEdgeOffset(), 0.0 );
if ( m_limitToPorePressureRegions && !m_applyPPRegionLimitVertically )
{
minExpandedPoint.z() = m_gridBoundingBox.min().z();
maxExpandedPoint.z() = m_gridBoundingBox.max().z();
}
m_expandedBoundingBox = cvf::BoundingBox( minExpandedPoint, maxExpandedPoint );
m_mapSize = calculateMapSize();
// Re-jig max point to be an exact multiple of cell size
cvf::Vec3d minPoint = m_expandedBoundingBox.min();
cvf::Vec3d maxPoint = m_expandedBoundingBox.max();
maxPoint.x() = minPoint.x() + m_mapSize.x() * sampleSpacing();
maxPoint.y() = minPoint.y() + m_mapSize.y() * sampleSpacing();
m_expandedBoundingBox = cvf::BoundingBox( minPoint, maxPoint );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 = RigFemResultAddress( RigFemResultPosEnum::RIG_ELEMENT_NODAL, "POR-Bar", "" );
}
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 = ijFromCellIndex( cellIndex );
if ( cellResults[cellIndex] != std::numeric_limits<double>::infinity() )
{
distanceImage[ij.x()][ij.y()] = 1u;
validResBoundingBox.add( cvf::Vec3d( 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 = ijFromCellIndex( cellIndex );
if ( distanceImage[ij.x()][ij.y()] < cellPadding * cellPadding )
{
mapCellVisibility[cellIndex] = true;
}
}
}
}
}
return mapCellVisibility;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGeoMechContourMapProjection::retrieveParameterWeights()
{
return std::vector<double>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGeoMechContourMapProjection::generateResults( int timeStep )
{
RimGeoMechCellColors* cellColors = view()->cellResult();
RigFemResultAddress resultAddress = cellColors->resultAddress();
std::vector<double> aggregatedResults = generateResultsFromAddress( resultAddress, m_mapCellVisibility, timeStep );
return aggregatedResults;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RimGeoMechContourMapProjection::generateResultsFromAddress( RigFemResultAddress resultAddress,
const std::vector<bool>& mapCellVisibility,
int timeStep )
{
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() );
bool wasInvalid = false;
if ( !resultAddress.isValid() )
{
wasInvalid = true;
resultAddress = RigFemResultAddress( RigFemResultPosEnum::RIG_ELEMENT_NODAL, "POR-Bar", "" );
}
if ( resultAddress.fieldName == "PP" )
{
resultAddress.fieldName = "POR-Bar"; // More likely to be in memory than POR
}
if ( resultAddress.fieldName == "POR-Bar" )
{
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, timeStep );
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 = ijFromCellIndex( index );
aggregatedResults[index] = calculateValueInMapCell( ij.x(), ij.y(), resultValues );
}
}
return aggregatedResults;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGeoMechContourMapProjection::resultVariableChanged() const
{
RimGeoMechCellColors* cellColors = view()->cellResult();
RigFemResultAddress resAddr = cellColors->resultAddress();
return !m_currentResultAddr.isValid() || !( m_currentResultAddr == resAddr );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::clearResultVariable()
{
m_currentResultAddr = RigFemResultAddress();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridView* RimGeoMechContourMapProjection::baseView() const
{
return view();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<size_t> RimGeoMechContourMapProjection::findIntersectingCells( const cvf::BoundingBox& bbox ) const
{
std::vector<size_t> allCellIndices;
m_femPart->findIntersectingCellsWithExistingSearchTree( bbox, &allCellIndices );
return allCellIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
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 ( !( elmType == HEX8 || elmType == HEX8P ) ) 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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCase* RimGeoMechContourMapProjection::geoMechCase() const
{
RimGeoMechCase* geoMechCase = nullptr;
firstAncestorOrThisOfType( geoMechCase );
return geoMechCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapView* RimGeoMechContourMapProjection::view() const
{
RimGeoMechContourMapView* view = nullptr;
firstAncestorOrThisOfTypeAsserted( view );
return view;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::updateAfterResultGeneration( int timeStep )
{
m_currentResultTimestep = timeStep;
RimGeoMechCellColors* cellColors = view()->cellResult();
RigFemResultAddress resAddr = cellColors->resultAddress();
m_currentResultAddr = resAddr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimContourMapProjection::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_limitToPorePressureRegions || changedField == &m_applyPPRegionLimitVertically ||
changedField == &m_paddingAroundPorePressureRegion )
{
clearGridMapping();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RimGeoMechContourMapProjection::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_resultAggregation )
{
std::vector<ResultAggregationEnum> validOptions = { RESULTS_TOP_VALUE,
RESULTS_MEAN_VALUE,
RESULTS_GEOM_VALUE,
RESULTS_HARM_VALUE,
RESULTS_MIN_VALUE,
RESULTS_MAX_VALUE,
RESULTS_SUM };
for ( ResultAggregationEnum option : validOptions )
{
options.push_back( caf::PdmOptionItemInfo( ResultAggregation::uiText( option ), option ) );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
RimContourMapProjection::defineUiOrdering( uiConfigName, uiOrdering );
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Map Boundaries" );
group->add( &m_limitToPorePressureRegions );
group->add( &m_applyPPRegionLimitVertically );
group->add( &m_paddingAroundPorePressureRegion );
m_applyPPRegionLimitVertically.uiCapability()->setUiReadOnly( !m_limitToPorePressureRegions() );
m_paddingAroundPorePressureRegion.uiCapability()->setUiReadOnly( !m_limitToPorePressureRegions() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapProjection::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
RimContourMapProjection::defineEditorAttribute( field, uiConfigName, attribute );
if ( field == &m_paddingAroundPorePressureRegion )
{
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
if ( myAttr )
{
myAttr->m_minimum = 0.0;
myAttr->m_maximum = 2.0;
myAttr->m_sliderTickCount = 4;
myAttr->m_delaySliderUpdateUntilRelease = true;
}
}
}

View File

@@ -0,0 +1,109 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemPart.h"
#include "RigFemResultAddress.h"
#include "RimCheckableNamedObject.h"
#include "RimContourMapProjection.h"
#include "RimGeoMechCase.h"
#include "RimRegularLegendConfig.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 RimGeoMechContourMapProjection : public RimContourMapProjection
{
CAF_PDM_HEADER_INIT;
public:
RimGeoMechContourMapProjection();
~RimGeoMechContourMapProjection() override;
// GeoMech case overrides for contour map methods
QString resultDescriptionText() const override;
RimRegularLegendConfig* legendConfig() const override;
void updateLegend() override;
double sampleSpacing() const override;
protected:
typedef RimContourMapProjection::CellIndexAndResult CellIndexAndResult;
// GeoMech implementation specific data generation methods
cvf::ref<cvf::UByteArray> getCellVisibility() const override;
cvf::BoundingBox calculateExpandedPorBarBBox( int timeStep ) const;
void updateGridInformation() override;
std::vector<bool> getMapCellVisibility() override;
std::vector<double> retrieveParameterWeights() override;
std::vector<double> generateResults( int timeStep ) override;
std::vector<double> generateResultsFromAddress( RigFemResultAddress resultAddress,
const std::vector<bool>& mapCellVisibility,
int timeStep );
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;
RimGeoMechCase* geoMechCase() const;
RimGeoMechContourMapView* view() const;
void updateAfterResultGeneration( int timeStep ) override;
protected:
// Framework overrides
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
protected:
caf::PdmField<bool> m_limitToPorePressureRegions;
caf::PdmField<bool> m_applyPPRegionLimitVertically;
caf::PdmField<double> m_paddingAroundPorePressureRegion;
cvf::ref<RigFemPart> m_femPart;
cvf::cref<RigFemPartGrid> m_femPartGrid;
RigFemResultAddress m_currentResultAddr;
size_t m_kLayers;
};

View File

@@ -0,0 +1,527 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimGeoMechContourMapView.h"
#include "RiuViewer.h"
#include "RivContourMapProjectionPartMgr.h"
#include "RicfCommandObject.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimCase.h"
#include "RimCellFilterCollection.h"
#include "RimGeoMechCellColors.h"
#include "RimGeoMechContourMapProjection.h"
#include "RimGeoMechPropertyFilterCollection.h"
#include "RimGridCollection.h"
#include "RimRegularLegendConfig.h"
#include "RimSimWellInViewCollection.h"
#include "RimViewNameConfig.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h"
#include "cvfCamera.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfScene.h"
CAF_PDM_SOURCE_INIT( RimGeoMechContourMapView, "RimGeoMechContourMapView" );
const cvf::Mat4d RimGeoMechContourMapView::sm_defaultViewMatrix =
cvf::Mat4d( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1000, 0, 0, 0, 1 );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapView::RimGeoMechContourMapView()
: m_cameraPositionLastUpdate( cvf::Vec3d::UNDEFINED )
{
CAF_PDM_InitScriptableObjectWithNameAndComment( "GeoMech Contour Map View",
":/2DMap16x16.png",
"",
"",
"GeoMechContourMap",
"A contour map for GeoMech cases" );
CAF_PDM_InitFieldNoDefault( &m_contourMapProjection, "ContourMapProjection", "Contour Map Projection", "", "", "" );
m_contourMapProjection = new RimGeoMechContourMapProjection();
CAF_PDM_InitField( &m_showAxisLines, "ShowAxisLines", true, "Show Axis Lines", "", "", "" );
CAF_PDM_InitField( &m_showScaleLegend, "ShowScaleLegend", true, "Show Scale Legend", "", "", "" );
m_gridCollection->setActive( false ); // This is also not added to the tree view, so cannot be enabled.
setDefaultCustomName();
m_contourMapProjectionPartMgr = new RivContourMapProjectionPartMgr( contourMapProjection(), this );
( (RiuViewerToViewInterface*)this )->setCameraPosition( sm_defaultViewMatrix );
cellResult()->legendConfigChanged.connect( this, &RimGeoMechContourMapView::onLegendConfigChanged );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapProjection* RimGeoMechContourMapView::contourMapProjection() const
{
return m_contourMapProjection().p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGeoMechContourMapView::createAutoName() const
{
QStringList autoName;
if ( !nameConfig()->customName().isEmpty() )
{
autoName.push_back( nameConfig()->customName() );
}
QStringList generatedAutoTags;
RimCase* ownerCase = nullptr;
this->firstAncestorOrThisOfTypeAsserted( ownerCase );
if ( nameConfig()->addCaseName() )
{
generatedAutoTags.push_back( ownerCase->caseUserDescription() );
}
if ( nameConfig()->addAggregationType() )
{
generatedAutoTags.push_back( contourMapProjection()->resultAggregationText() );
}
if ( nameConfig()->addProperty() && !contourMapProjection()->isColumnResult() )
{
generatedAutoTags.push_back( cellResult()->resultFieldUiName() );
}
if ( nameConfig()->addSampleSpacing() )
{
generatedAutoTags.push_back( QString( "%1" ).arg( contourMapProjection()->sampleSpacingFactor(), 3, 'f', 2 ) );
}
if ( !generatedAutoTags.empty() )
{
autoName.push_back( generatedAutoTags.join( ", " ) );
}
return autoName.join( ": " );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::setDefaultCustomName()
{
nameConfig()->setCustomName( "Contour Map" );
nameConfig()->hideCaseNameField( false );
nameConfig()->hideAggregationTypeField( false );
nameConfig()->hidePropertyField( false );
nameConfig()->hideSampleSpacingField( false );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::updatePickPointAndRedraw()
{
appendPickPointVisToModel();
if ( nativeOrOverrideViewer() )
{
nativeOrOverrideViewer()->update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGeoMechContourMapView::isGridVisualizationMode() const
{
return m_contourMapProjection->isChecked();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGeoMechContourMapView::isTimeStepDependentDataVisible() const
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::initAfterRead()
{
RimGeoMechView::initAfterRead();
m_gridCollection->setActive( false ); // This is also not added to the tree view, so cannot be enabled.
disablePerspectiveProjectionField();
setShowGridBox( false );
meshMode.setValue( RiaDefines::MeshModeType::NO_MESH );
surfaceMode.setValue( FAULTS );
scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::onCreateDisplayModel()
{
RimGeoMechView::onCreateDisplayModel();
if ( !this->isTimeStepDependentDataVisible() )
{
// Need to add geometry even if it hasn't happened during dynamic time step update.
updateGeometry();
}
if ( this->viewer()->mainCamera()->viewMatrix() == sm_defaultViewMatrix )
{
this->zoomAll();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
caf::PdmUiGroup* viewGroup = uiOrdering.addNewGroup( "Viewer" );
viewGroup->add( this->userDescriptionField() );
viewGroup->add( this->backgroundColorField() );
viewGroup->add( &m_showAxisLines );
viewGroup->add( &m_showScaleLegend );
caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "Contour Map Name" );
nameConfig()->uiOrdering( uiConfigName, *nameGroup );
uiOrdering.skipRemainingFields( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering,
QString uiConfigName /*= ""*/ )
{
uiTreeOrdering.add( m_overlayInfoConfig() );
uiTreeOrdering.add( m_contourMapProjection );
uiTreeOrdering.add( cellResult() );
cellResult()->uiCapability()->setUiReadOnly( m_contourMapProjection->isColumnResult() );
uiTreeOrdering.add( m_cellFilterCollection() );
uiTreeOrdering.add( nativePropertyFilterCollection() );
uiTreeOrdering.skipRemainingChildren();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::onUpdateDisplayModelForCurrentTimeStep()
{
updateGeometry();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::updateGeometry()
{
caf::ProgressInfo progress( 100, "Generate Contour Map", true );
{ // Step 1: generate results. About 30% of the time.
if ( m_contourMapProjection->isChecked() )
{
m_contourMapProjection->generateResultsIfNecessary( m_currentTimeStep() );
}
onUpdateLegends();
progress.setProgress( 30 );
}
{ // Step 2: generate geometry. Takes about 60% of the time.
createContourMapGeometry();
progress.setProgress( 90 );
}
{ // Step 3: generate drawables. About 10% of the time.
appendContourMapProjectionToModel();
appendContourLinesToModel();
appendPickPointVisToModel();
progress.setProgress( 100 );
}
m_overlayInfoConfig->update3DInfo();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::createContourMapGeometry()
{
if ( nativeOrOverrideViewer() && m_contourMapProjection->isChecked() )
{
m_contourMapProjectionPartMgr->createProjectionGeometry();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::appendContourMapProjectionToModel()
{
if ( nativeOrOverrideViewer() && m_contourMapProjection->isChecked() )
{
cvf::Scene* frameScene = nativeOrOverrideViewer()->frame( m_currentTimeStep, isUsingOverrideViewer() );
if ( frameScene )
{
cvf::String name = "ContourMapProjection";
this->removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> contourMapProjectionModelBasicList = new cvf::ModelBasicList;
contourMapProjectionModelBasicList->setName( name );
cvf::ref<caf::DisplayCoordTransform> transForm = this->displayCoordTransform();
m_contourMapProjectionPartMgr->appendProjectionToModel( contourMapProjectionModelBasicList.p(), transForm.p() );
contourMapProjectionModelBasicList->updateBoundingBoxesRecursive();
frameScene->addModel( contourMapProjectionModelBasicList.p() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::appendContourLinesToModel()
{
if ( nativeOrOverrideViewer() && m_contourMapProjection->isChecked() )
{
cvf::Scene* frameScene = nativeOrOverrideViewer()->frame( m_currentTimeStep, isUsingOverrideViewer() );
if ( frameScene )
{
cvf::String name = "ContourMapLines";
this->removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> contourMapLabelModelBasicList = new cvf::ModelBasicList;
contourMapLabelModelBasicList->setName( name );
cvf::ref<caf::DisplayCoordTransform> transForm = this->displayCoordTransform();
m_contourMapProjectionPartMgr->appendContourLinesToModel( viewer()->mainCamera(),
contourMapLabelModelBasicList.p(),
transForm.p() );
contourMapLabelModelBasicList->updateBoundingBoxesRecursive();
frameScene->addModel( contourMapLabelModelBasicList.p() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::appendPickPointVisToModel()
{
if ( nativeOrOverrideViewer() && m_contourMapProjection->isChecked() )
{
cvf::Scene* frameScene = nativeOrOverrideViewer()->frame( m_currentTimeStep, isUsingOverrideViewer() );
if ( frameScene )
{
cvf::String name = "ContourMapPickPoint";
this->removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> contourMapProjectionModelBasicList = new cvf::ModelBasicList;
contourMapProjectionModelBasicList->setName( name );
cvf::ref<caf::DisplayCoordTransform> transForm = this->displayCoordTransform();
m_contourMapProjectionPartMgr->appendPickPointVisToModel( contourMapProjectionModelBasicList.p(),
transForm.p() );
contourMapProjectionModelBasicList->updateBoundingBoxesRecursive();
frameScene->addModel( contourMapProjectionModelBasicList.p() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::onUpdateLegends()
{
if ( nativeOrOverrideViewer() )
{
if ( !isUsingOverrideViewer() )
{
nativeOrOverrideViewer()->removeAllColorLegends();
}
else if ( m_contourMapProjection && m_contourMapProjection->legendConfig() )
{
nativeOrOverrideViewer()->removeColorLegend( m_contourMapProjection->legendConfig()->titledOverlayFrame() );
}
if ( m_contourMapProjection && m_contourMapProjection->isChecked() )
{
RimRegularLegendConfig* projectionLegend = m_contourMapProjection->legendConfig();
if ( projectionLegend )
{
m_contourMapProjection->updateLegend();
if ( projectionLegend->showLegend() )
{
nativeOrOverrideViewer()->addColorLegendToBottomLeftCorner( projectionLegend->titledOverlayFrame(),
isUsingOverrideViewer() );
}
}
}
nativeOrOverrideViewer()->showScaleLegend( m_showScaleLegend() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::updateViewWidgetAfterCreation()
{
if ( viewer() )
{
viewer()->showAxisCross( false );
viewer()->showEdgeTickMarksXY( true, m_showAxisLines() );
viewer()->enableNavigationRotation( false );
}
Rim3dView::updateViewWidgetAfterCreation();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::updateViewFollowingCellFilterUpdates()
{
m_contourMapProjection->setCheckState( true );
scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::onLoadDataAndUpdate()
{
RimGeoMechView::onLoadDataAndUpdate();
if ( nativeOrOverrideViewer() )
{
nativeOrOverrideViewer()->setView( cvf::Vec3d( 0, 0, -1 ), cvf::Vec3d( 0, 1, 0 ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimGeoMechView::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_showAxisLines )
{
viewer()->showEdgeTickMarksXY( true, m_showAxisLines() );
scheduleCreateDisplayModelAndRedraw();
}
else if ( changedField == backgroundColorField() )
{
scheduleCreateDisplayModelAndRedraw();
}
else if ( changedField == &m_showScaleLegend )
{
onUpdateLegends();
scheduleCreateDisplayModelAndRedraw();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimGeoMechContourMapView::userDescriptionField()
{
return nameConfig()->nameField();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RimGeoMechContourMapView::createViewWidget( QWidget* mainWindowParent )
{
auto widget = Rim3dView::createViewWidget( mainWindowParent );
if ( viewer() )
{
viewer()->showZScaleLabel( false );
viewer()->hideZScaleCheckbox( true );
}
return widget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::onViewNavigationChanged()
{
cvf::Vec3d currentCameraPosition = viewer()->mainCamera()->position();
if ( m_cameraPositionLastUpdate.isUndefined() || zoomChangeAboveTreshold( currentCameraPosition ) )
{
appendContourLinesToModel();
m_cameraPositionLastUpdate = currentCameraPosition;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGeoMechContourMapView::zoomChangeAboveTreshold( const cvf::Vec3d& currentCameraPosition ) const
{
double distance = std::max( std::fabs( m_cameraPositionLastUpdate.z() ), std::fabs( currentCameraPosition.z() ) );
const double threshold = 0.05 * distance;
return std::fabs( m_cameraPositionLastUpdate.z() - currentCameraPosition.z() ) > threshold;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::scheduleGeometryRegen( RivCellSetEnum geometryType )
{
m_contourMapProjection->clearGeometry();
RimGeoMechView::scheduleGeometryRegen( geometryType );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapView::onLegendConfigChanged( const caf::SignalEmitter* emitter,
RimLegendConfigChangeType changeType )
{
using ChangeType = RimLegendConfigChangeType;
if ( changeType == ChangeType::LEVELS || changeType == ChangeType::COLOR_MODE || changeType == ChangeType::RANGE ||
changeType == ChangeType::ALL )
{
m_contourMapProjection->clearGeometry();
}
}

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimGeoMechView.h"
#include "RimNameConfig.h"
enum class RimLegendConfigChangeType;
class RimGeoMechContourMapProjection;
class RimRegularLegendConfig;
class RimViewNameConfig;
class RimScaleLegendConfig;
class RivContourMapProjectionPartMgr;
class RimGeoMechContourMapView : public RimGeoMechView
{
CAF_PDM_HEADER_INIT;
public:
RimGeoMechContourMapView();
RimGeoMechContourMapProjection* contourMapProjection() const;
QString createAutoName() const override;
void setDefaultCustomName();
void updatePickPointAndRedraw();
bool isGridVisualizationMode() const override;
bool isTimeStepDependentDataVisible() const override;
protected:
void initAfterRead() override;
void onCreateDisplayModel() override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void onUpdateDisplayModelForCurrentTimeStep() override;
void updateGeometry();
void createContourMapGeometry();
void appendContourMapProjectionToModel();
void appendContourLinesToModel();
void appendPickPointVisToModel();
void onUpdateLegends() override;
void updateViewWidgetAfterCreation() override;
void updateViewFollowingCellFilterUpdates() override;
void onLoadDataAndUpdate() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
caf::PdmFieldHandle* userDescriptionField() override;
QWidget* createViewWidget( QWidget* mainWindowParent ) override;
void onViewNavigationChanged() override;
bool zoomChangeAboveTreshold( const cvf::Vec3d& currentCameraPosition ) const;
void scheduleGeometryRegen( RivCellSetEnum geometryType ) override;
void onLegendConfigChanged( const caf::SignalEmitter* emitter, RimLegendConfigChangeType changeType );
private:
cvf::ref<RivContourMapProjectionPartMgr> m_contourMapProjectionPartMgr;
caf::PdmChildField<RimGeoMechContourMapProjection*> m_contourMapProjection;
caf::PdmField<bool> m_showAxisLines;
caf::PdmField<bool> m_showScaleLegend;
cvf::Vec3d m_cameraPositionLastUpdate;
const static cvf::Mat4d sm_defaultViewMatrix;
};

View File

@@ -0,0 +1,40 @@
#include "RimGeoMechContourMapViewCollection.h"
#include "RimCase.h"
#include "RimGeoMechContourMapView.h"
CAF_PDM_SOURCE_INIT( RimGeoMechContourMapViewCollection, "GeoMech2dViewCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapViewCollection::RimGeoMechContourMapViewCollection()
{
CAF_PDM_InitObject( "GeoMech Contour Maps", ":/2DMaps16x16.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_contourMapViews, "GeoMechViews", "Contour Maps", ":/CrossSection16x16.png", "", "" );
m_contourMapViews.uiCapability()->setUiTreeHidden( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechContourMapViewCollection::~RimGeoMechContourMapViewCollection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimGeoMechContourMapView*> RimGeoMechContourMapViewCollection::views()
{
return m_contourMapViews.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechContourMapViewCollection::push_back( RimGeoMechContourMapView* contourMap )
{
m_contourMapViews.push_back( contourMap );
}

View File

@@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
class RimGeoMechContourMapView;
class RimGeoMechContourMapViewCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimGeoMechContourMapViewCollection();
~RimGeoMechContourMapViewCollection() override;
std::vector<RimGeoMechContourMapView*> views();
void push_back( RimGeoMechContourMapView* contourMap );
private:
caf::PdmChildArrayField<RimGeoMechContourMapView*> m_contourMapViews;
};

View File

@@ -0,0 +1,125 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimGeoMechModels.h"
#include "RiaLogging.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechView.h"
#include "RimGridView.h"
#include "RimIntersectionCollection.h"
#include "RimIntersectionResultDefinition.h"
#include "RimIntersectionResultsDefinitionCollection.h"
CAF_PDM_SOURCE_INIT( RimGeoMechModels, "ResInsightGeoMechModels" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechModels::RimGeoMechModels( void )
{
CAF_PDM_InitObject( "Geomechanical Models", ":/GeoMechCases48x48.png", "", "" );
CAF_PDM_InitFieldNoDefault( &m_cases, "Cases", "", "", "", "" );
m_cases.uiCapability()->setUiHidden( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechModels::~RimGeoMechModels( void )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimGeoMechCase*> RimGeoMechModels::cases() const
{
return m_cases.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechModels::addCase( RimGeoMechCase* thecase )
{
m_cases.push_back( thecase );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechModels::removeCase( RimGeoMechCase* thecase )
{
m_cases.removeChildObject( thecase );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCase* RimGeoMechModels::copyCase( RimGeoMechCase* thecase, const QString& newInputFileName )
{
for ( auto gmcase : m_cases() )
{
if ( gmcase->gridFileName() == newInputFileName )
{
RiaLogging::warning( "File has already been opened. Cannot open the file twice! - " + newInputFileName );
return nullptr;
}
}
RimGeoMechCase* copy = thecase->createCopy( newInputFileName );
if ( !copy )
{
RiaLogging::warning( "Could not create a copy of the geomech case" + thecase->caseUserDescription() +
" using the new input file " + newInputFileName );
return nullptr;
}
m_cases.push_back( copy );
copy->resolveReferencesRecursively();
copy->updateConnectedEditors();
this->updateConnectedEditors();
for ( auto riv : copy->views() )
{
RimGridView* rgv = dynamic_cast<RimGridView*>( riv );
if ( rgv )
{
rgv->loadDataAndUpdate();
rgv->scheduleCreateDisplayModelAndRedraw();
rgv->intersectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews();
for ( auto coll : rgv->separateIntersectionResultsCollection()->intersectionResultsDefinitions() )
{
coll->update2dIntersectionViews();
}
for ( auto coll : rgv->separateSurfaceResultsCollection()->intersectionResultsDefinitions() )
{
coll->update2dIntersectionViews();
}
}
}
return copy;
}

View File

@@ -0,0 +1,49 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
class RimGeoMechCase;
//==================================================================================================
///
///
//==================================================================================================
class RimGeoMechModels : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimGeoMechModels( void );
~RimGeoMechModels( void ) override;
RimGeoMechCase* copyCase( RimGeoMechCase* thecase, const QString& newInputFileName );
void removeCase( RimGeoMechCase* thecase );
void addCase( RimGeoMechCase* thecase );
std::vector<RimGeoMechCase*> cases() const;
private:
caf::PdmChildArrayField<RimGeoMechCase*> m_cases;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Equinor ASA
// Copyright (C) 2015-2018 Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigFemResultPosEnum.h"
#include "RimFemResultObserver.h"
#include "cafAppEnum.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
class RimGeoMechView;
class RimGeoMechPropertyFilter;
class RifGeoMechReaderInterface;
class RigGeoMechCaseData;
class RimGeoMechCase;
class RimRegularLegendConfig;
//==================================================================================================
///
///
//==================================================================================================
class RimGeoMechResultDefinition : public RimFemResultObserver
{
CAF_PDM_HEADER_INIT;
public:
RimGeoMechResultDefinition( void );
~RimGeoMechResultDefinition( void ) override;
void setGeoMechCase( RimGeoMechCase* geomCase );
RimGeoMechCase* geoMechCase() const;
RigGeoMechCaseData* ownerCaseData() const;
bool hasResult();
void loadResult();
void setAddWellPathDerivedResults( bool addWellPathDerivedResults );
RigFemResultAddress resultAddress() const;
std::vector<RigFemResultAddress> observedResults() const override;
RigFemResultPosEnum resultPositionType() const;
QString resultFieldName() const;
QString resultComponentName() const;
QString diffResultUiName() const;
QString diffResultUiShortName() const;
void setResultAddress( const RigFemResultAddress& resultAddress );
QString resultFieldUiName() const;
QString resultComponentUiName() const;
QString resultVariableUiName() const;
QString resultVariableName() const;
QString currentResultUnits() const;
QString defaultLasUnits() const;
double normalizationAirGap() const;
void setNormalizationAirGap( double airGap );
bool hasCategoryResult() const { return m_resultPositionType() == RIG_FORMATION_NAMES; }
void updateLegendTextAndRanges( RimRegularLegendConfig* legendConfigToUpdate,
const QString& legendHeading,
int timeStepIndex );
bool isBiotCoefficientDependent() const;
protected:
virtual void updateLegendCategorySettings(){};
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
friend class RimIntersectionResultDefinition;
private:
// Overridden PDM methods
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void calculateNormalizationAirGapDefault();
void initAfterRead() override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
// Metadata and option build tools
std::map<std::string, std::vector<std::string>> getResultMetaDataForUIFieldSetting();
static void getUiAndResultVariableStringList( QStringList* uiNames,
QStringList* variableNames,
const std::map<std::string, std::vector<std::string>>& fieldCompNames );
static QString composeFieldCompString( const QString& resultFieldName, const QString& resultComponentName );
static QString convertToUiResultFieldName( QString resultFieldName );
bool normalizableResultSelected() const;
bool referenceCaseDependentResultSelected() const;
// Data Fields
caf::PdmField<caf::AppEnum<RigFemResultPosEnum>> m_resultPositionType;
caf::PdmField<QString> m_resultFieldName;
caf::PdmField<QString> m_resultComponentName;
caf::PdmField<int> m_timeLapseBaseTimestep;
caf::PdmField<int> m_compactionRefLayer;
caf::PdmField<bool> m_normalizeByHydrostaticPressure;
caf::PdmField<double> m_normalizationAirGap;
caf::PdmField<int> m_referenceTimeStep;
// UI Fields only
friend class RimGeoMechPropertyFilter; // Property filter needs the ui fields
friend class RimWellLogExtractionCurve; // Curve needs the ui fields
friend class RimGeoMechCellColors; // Needs the ui fields
caf::PdmField<caf::AppEnum<RigFemResultPosEnum>> m_resultPositionTypeUiField;
caf::PdmField<QString> m_resultVariableUiField;
caf::PdmField<int> m_compactionRefLayerUiField;
caf::PdmPointer<RimGeoMechCase> m_geomCase;
bool m_isChangedByField;
bool m_addWellPathDerivedResults;
};

View File

@@ -0,0 +1,988 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimGeoMechView.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
#include "RiaRegressionTestRunner.h"
#include "RicfCommandObject.h"
#include "RigFemPartCollection.h"
#include "RigFemPartGrid.h"
#include "RigFemPartResultsCollection.h"
#include "RigFormationNames.h"
#include "RigGeoMechCaseData.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimCellFilterCollection.h"
#include "RimEclipseResultDefinition.h"
#include "RimEclipseView.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechCellColors.h"
#include "RimGeoMechPropertyFilterCollection.h"
#include "RimGridCollection.h"
#include "RimIntersectionCollection.h"
#include "RimIntersectionResultDefinition.h"
#include "RimIntersectionResultsDefinitionCollection.h"
#include "RimRegularLegendConfig.h"
#include "RimSurfaceInViewCollection.h"
#include "RimTensorResults.h"
#include "RimTernaryLegendConfig.h"
#include "RimViewLinker.h"
#include "RimViewNameConfig.h"
#include "RimWellMeasurementInView.h"
#include "RimWellMeasurementInViewCollection.h"
#include "Riu3DMainWindowTools.h"
#include "Riu3dSelectionManager.h"
#include "RiuViewer.h"
#include "RivGeoMechPartMgr.h"
#include "RivGeoMechPartMgrCache.h"
#include "RivGeoMechVizLogic.h"
#include "RivSingleCellPartGenerator.h"
#include "RivTensorResultPartMgr.h"
#include "cafCadNavigation.h"
#include "cafCeetronPlusNavigation.h"
#include "cafDisplayCoordTransform.h"
#include "cafFrameAnimationControl.h"
#include "cafOverlayScalarMapperLegend.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h"
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfScene.h"
#include "cvfTransform.h"
#include "cvfViewport.h"
#include "cvfqtUtils.h"
CAF_PDM_SOURCE_INIT( RimGeoMechView, "GeoMechView" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechView::RimGeoMechView( void )
{
CAF_PDM_InitScriptableObject( "Geomechanical View", ":/3DViewGeoMech16x16.png", "", "The Geomechanical 3d View" );
CAF_PDM_InitFieldNoDefault( &cellResult, "GridCellResult", "Color Result", ":/CellResult.png", "", "" );
cellResult = new RimGeoMechCellColors();
cellResult.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_tensorResults, "TensorResults", "Tensor Results", "", "", "" );
m_tensorResults = new RimTensorResults();
m_tensorResults.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_propertyFilterCollection, "PropertyFilters", "Property Filters", "", "", "" );
m_propertyFilterCollection = new RimGeoMechPropertyFilterCollection();
m_propertyFilterCollection.uiCapability()->setUiHidden( true );
m_scaleTransform = new cvf::Transform();
m_vizLogic = new RivGeoMechVizLogic( this );
m_tensorPartMgr = new RivTensorResultPartMgr( this );
nameConfig()->setCustomName( "GeoMech View" );
nameConfig()->hideCaseNameField( false );
nameConfig()->hideAggregationTypeField( true );
nameConfig()->hidePropertyField( false );
nameConfig()->hideSampleSpacingField( true );
setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechView::~RimGeoMechView( void )
{
m_geomechCase = nullptr;
delete m_tensorResults;
delete cellResult;
delete m_propertyFilterCollection;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onLoadDataAndUpdate()
{
caf::ProgressInfo progress( 7, "" );
progress.setNextProgressIncrement( 5 );
onUpdateScaleTransform();
this->updateSurfacesInViewTreeItems();
if ( m_geomechCase )
{
std::string errorMessage;
RimGeoMechCase::CaseOpenStatus status = m_geomechCase->openGeoMechCase( &errorMessage );
if ( status == RimGeoMechCase::CASE_OPEN_CANCELLED )
{
m_geomechCase = nullptr;
return;
}
else if ( status == RimGeoMechCase::CASE_OPEN_ERROR )
{
if ( !RiaRegressionTestRunner::instance()->isRunningRegressionTests() )
{
QString displayMessage = errorMessage.empty()
? "Could not open the Odb file: \n" + m_geomechCase->gridFileName()
: QString::fromStdString( errorMessage );
RiaLogging::errorInMessageBox( Riu3DMainWindowTools::mainWindowWidget(), "File open error", displayMessage );
}
m_geomechCase = nullptr;
return;
}
}
progress.incrementProgress();
progress.setProgressDescription( "Reading Current Result" );
CVF_ASSERT( this->cellResult() != nullptr );
if ( this->hasUserRequestedAnimation() )
{
m_geomechCase->geoMechData()->femPartResults()->setNormalizationAirGap( this->cellResult()->normalizationAirGap() );
m_geomechCase->geoMechData()->femPartResults()->assertResultsLoaded( this->cellResult()->resultAddress() );
}
progress.incrementProgress();
progress.setProgressDescription( "Create Display model" );
updateMdiWindowVisibility();
this->geoMechPropertyFilterCollection()->loadAndInitializePropertyFilters();
m_wellMeasurementCollection->syncWithChangesInWellMeasurementCollection();
if ( this->m_surfaceCollection ) this->m_surfaceCollection->loadData();
this->scheduleCreateDisplayModelAndRedraw();
progress.incrementProgress();
}
//--------------------------------------------------------------------------------------------------
///
/// Todo: Work in progress
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onUpdateScaleTransform()
{
cvf::Mat4d scale = cvf::Mat4d::IDENTITY;
scale( 2, 2 ) = scaleZ();
this->scaleTransform()->setLocalTransform( scale );
if ( nativeOrOverrideViewer() ) nativeOrOverrideViewer()->updateCachedValuesInScene();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGeoMechView::createAutoName() const
{
QStringList autoName;
if ( !nameConfig()->customName().isEmpty() )
{
autoName.push_back( nameConfig()->customName() );
}
QStringList generatedAutoTags;
RimCase* ownerCase = nullptr;
this->firstAncestorOrThisOfTypeAsserted( ownerCase );
if ( nameConfig()->addCaseName() )
{
generatedAutoTags.push_back( ownerCase->caseUserDescription() );
}
if ( nameConfig()->addProperty() )
{
auto resultName = cellResultResultDefinition()->resultFieldName();
if ( !resultName.isEmpty() ) generatedAutoTags.push_back( resultName );
}
if ( !generatedAutoTags.empty() )
{
autoName.push_back( generatedAutoTags.join( ", " ) );
}
return autoName.join( ": " );
}
//--------------------------------------------------------------------------------------------------
/// Create display model,
/// or at least empty scenes as frames that is delivered to the viewer
/// The real geometry generation is done inside RivReservoirViewGeometry and friends
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onCreateDisplayModel()
{
if ( nativeOrOverrideViewer() == nullptr ) return;
if ( !( m_geomechCase && m_geomechCase->geoMechData() && m_geomechCase->geoMechData()->femParts() ) ) return;
int partCount = m_geomechCase->geoMechData()->femParts()->partCount();
if ( partCount <= 0 ) return;
// Remove all existing animation frames from the viewer.
// The parts are still cached in the RivReservoir geometry and friends
nativeOrOverrideViewer()->removeAllFrames( isUsingOverrideViewer() );
if ( isTimeStepDependentDataVisibleInThisOrComparisonView() )
{
// Create empty frames in the viewer
int frameCount = geoMechCase()->geoMechData()->femPartResults()->frameCount();
for ( int frameIndex = 0; frameIndex < frameCount; frameIndex++ )
{
cvf::ref<cvf::Scene> scene = new cvf::Scene;
cvf::ref<cvf::ModelBasicList> emptyModel = new cvf::ModelBasicList;
emptyModel->setName( "EmptyModel" );
scene->addModel( emptyModel.p() );
nativeOrOverrideViewer()->addFrame( scene.p(), isUsingOverrideViewer() );
}
}
// Set the Main scene in the viewer. Used when the animation is in "Stopped" state
cvf::ref<cvf::Scene> mainScene = new cvf::Scene;
// Grid model
cvf::ref<cvf::ModelBasicList> mainSceneGridVizModel = new cvf::ModelBasicList;
mainSceneGridVizModel->setName( "GridModel" );
m_vizLogic->appendNoAnimPartsToModel( mainSceneGridVizModel.p() );
mainSceneGridVizModel->updateBoundingBoxesRecursive();
mainScene->addModel( mainSceneGridVizModel.p() );
nativeOrOverrideViewer()->setMainScene( mainScene.p(), isUsingOverrideViewer() );
// Well path model
cvf::BoundingBox femBBox = femParts()->boundingBox();
m_wellPathPipeVizModel->removeAllParts();
addWellPathsToModel( m_wellPathPipeVizModel.p(), femBBox );
nativeOrOverrideViewer()->addStaticModelOnce( m_wellPathPipeVizModel.p(), isUsingOverrideViewer() );
// Cross sections
m_intersectionVizModel->removeAllParts();
m_intersectionCollection->rebuildGeometry();
m_intersectionCollection->appendPartsToModel( *this, m_intersectionVizModel.p(), scaleTransform() );
nativeOrOverrideViewer()->addStaticModelOnce( m_intersectionVizModel.p(), isUsingOverrideViewer() );
// Surfaces
m_surfaceVizModel->removeAllParts();
if ( m_surfaceCollection )
{
m_surfaceCollection->appendPartsToModel( m_surfaceVizModel.p(), scaleTransform() );
nativeOrOverrideViewer()->addStaticModelOnce( m_surfaceVizModel.p(), isUsingOverrideViewer() );
}
// If the animation was active before recreating everything, make viewer view current frame
if ( isTimeStepDependentDataVisibleInThisOrComparisonView() )
{
if ( viewer() && !isUsingOverrideViewer() ) viewer()->setCurrentFrame( m_currentTimeStep );
}
else
{
onUpdateLegends();
m_vizLogic->updateStaticCellColors( -1 );
m_intersectionCollection->applySingleColorEffect();
if ( m_surfaceCollection )
{
m_surfaceCollection->applySingleColorEffect();
}
m_overlayInfoConfig()->update3DInfo();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimPropertyFilterCollection* RimGeoMechView::nativePropertyFilterCollection()
{
return m_propertyFilterCollection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onUpdateDisplayModelForCurrentTimeStep()
{
onUpdateLegends();
if ( this->isTimeStepDependentDataVisibleInThisOrComparisonView() )
{
if ( nativeOrOverrideViewer() )
{
cvf::Scene* frameScene = nativeOrOverrideViewer()->frame( m_currentTimeStep, isUsingOverrideViewer() );
if ( frameScene )
{
{
// Grid model
cvf::String name = "GridModel";
this->removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> frameParts = new cvf::ModelBasicList;
frameParts->setName( name );
m_vizLogic->appendPartsToModel( m_currentTimeStep, frameParts.p() );
frameParts->updateBoundingBoxesRecursive();
frameScene->addModel( frameParts.p() );
}
// Well Paths
{
cvf::String name = "WellPathMod";
this->removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> wellPathModelBasicList = new cvf::ModelBasicList;
wellPathModelBasicList->setName( name );
cvf::BoundingBox femBBox = femParts()->boundingBox();
addDynamicWellPathsToModel( wellPathModelBasicList.p(), femBBox );
frameScene->addModel( wellPathModelBasicList.p() );
}
{
// Tensors
cvf::String name = "Tensor";
this->removeModelByName( frameScene, name );
cvf::ref<cvf::ModelBasicList> frameParts = new cvf::ModelBasicList;
frameParts->setName( name );
m_tensorPartMgr->appendDynamicGeometryPartsToModel( frameParts.p(), m_currentTimeStep );
frameParts->updateBoundingBoxesRecursive();
if ( frameParts->partCount() != 0 )
{
frameScene->addModel( frameParts.p() );
}
}
}
}
if ( this->cellResult()->hasResult() )
m_vizLogic->updateCellResultColor( m_currentTimeStep(), this->cellResult() );
else
m_vizLogic->updateStaticCellColors( m_currentTimeStep() );
bool hasGeneralCellResult = this->cellResult()->hasResult();
m_intersectionCollection->updateCellResultColor( hasGeneralCellResult, m_currentTimeStep );
if ( m_surfaceCollection )
{
m_surfaceCollection->updateCellResultColor( hasGeneralCellResult, m_currentTimeStep );
}
}
else
{
m_vizLogic->updateStaticCellColors( -1 );
m_intersectionCollection->updateCellResultColor( false, m_currentTimeStep );
if ( m_surfaceCollection ) m_surfaceCollection->updateCellResultColor( false, m_currentTimeStep );
nativeOrOverrideViewer()->animationControl()->slotPause(); // To avoid animation timer spinning in the background
}
m_overlayInfoConfig()->update3DInfo();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onUpdateStaticCellColors()
{
m_vizLogic->updateStaticCellColors( -1 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::setGeoMechCase( RimGeoMechCase* gmCase )
{
m_geomechCase = gmCase;
cellResult()->setGeoMechCase( gmCase );
cellFilterCollection()->setCase( gmCase );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onResetLegendsInViewer()
{
for ( auto legendConfig : legendConfigs() )
{
if ( legendConfig )
{
legendConfig->recreateLegend();
}
}
nativeOrOverrideViewer()->removeAllColorLegends();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onUpdateLegends()
{
if ( nativeOrOverrideViewer() )
{
if ( !isUsingOverrideViewer() )
{
nativeOrOverrideViewer()->removeAllColorLegends();
}
else
{
std::vector<RimLegendConfig*> legendConfs = this->legendConfigs();
for ( auto legendConf : legendConfs )
{
nativeOrOverrideViewer()->removeColorLegend( legendConf->titledOverlayFrame() );
}
}
this->updateLegendTextAndRanges( cellResult()->legendConfig(), m_currentTimeStep() );
if ( cellResult()->hasResult() && cellResult()->legendConfig()->showLegend() )
{
nativeOrOverrideViewer()->addColorLegendToBottomLeftCorner( cellResult()->legendConfig->titledOverlayFrame(),
isUsingOverrideViewer() );
}
for ( RimIntersectionResultDefinition* sepInterResDef :
this->separateIntersectionResultsCollection()->intersectionResultsDefinitions() )
{
sepInterResDef->updateLegendRangesTextAndVisibility( "Intersection Results:\n",
nativeOrOverrideViewer(),
isUsingOverrideViewer() );
}
for ( RimIntersectionResultDefinition* sepInterResDef :
this->separateSurfaceResultsCollection()->intersectionResultsDefinitions() )
{
sepInterResDef->updateLegendRangesTextAndVisibility( "Surface Results:\n",
nativeOrOverrideViewer(),
isUsingOverrideViewer() );
}
if ( tensorResults()->showTensors() )
{
updateTensorLegendTextAndRanges( m_tensorResults->arrowColorLegendConfig(), m_currentTimeStep() );
if ( tensorResults()->vectorColors() == RimTensorResults::RESULT_COLORS &&
tensorResults()->arrowColorLegendConfig()->showLegend() )
{
nativeOrOverrideViewer()
->addColorLegendToBottomLeftCorner( m_tensorResults->arrowColorLegendConfig->titledOverlayFrame(),
isUsingOverrideViewer() );
}
}
if ( m_wellMeasurementCollection->isChecked() )
{
for ( RimWellMeasurementInView* wellMeasurement : m_wellMeasurementCollection->measurements() )
{
if ( wellMeasurement->isChecked() && wellMeasurement->legendConfig()->showLegend() )
{
wellMeasurement->updateLegendRangesTextAndVisibility( nativeOrOverrideViewer(),
isUsingOverrideViewer() );
}
}
}
if ( m_surfaceCollection && m_surfaceCollection->isChecked() )
{
m_surfaceCollection->updateLegendRangesTextAndVisibility( nativeOrOverrideViewer(), isUsingOverrideViewer() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::updateTensorLegendTextAndRanges( RimRegularLegendConfig* legendConfig, int timeStepIndex )
{
if ( !m_geomechCase || !m_geomechCase->geoMechData() ) return;
double localMin, localMax;
double localPosClosestToZero, localNegClosestToZero;
double globalMin, globalMax;
double globalPosClosestToZero, globalNegClosestToZero;
RigGeoMechCaseData* gmCase = m_geomechCase->geoMechData();
CVF_ASSERT( gmCase );
RigFemResultPosEnum resPos = tensorResults()->resultPositionType();
QString resFieldName = tensorResults()->resultFieldName();
RigFemResultAddress resVarAddress( resPos, resFieldName.toStdString(), "" );
gmCase->femPartResults()->minMaxScalarValuesOverAllTensorComponents( resVarAddress, timeStepIndex, &localMin, &localMax );
gmCase->femPartResults()->posNegClosestToZeroOverAllTensorComponents( resVarAddress,
timeStepIndex,
&localPosClosestToZero,
&localNegClosestToZero );
gmCase->femPartResults()->minMaxScalarValuesOverAllTensorComponents( resVarAddress, &globalMin, &globalMax );
gmCase->femPartResults()->posNegClosestToZeroOverAllTensorComponents( resVarAddress,
&globalPosClosestToZero,
&globalNegClosestToZero );
legendConfig->setClosestToZeroValues( globalPosClosestToZero,
globalNegClosestToZero,
localPosClosestToZero,
localNegClosestToZero );
legendConfig->setAutomaticRanges( globalMin, globalMax, localMin, localMax );
QString legendTitle = "Tensors:\n" + RimTensorResults::uiFieldName( resFieldName );
legendConfig->setTitle( legendTitle );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::updateLegendTextAndRanges( RimRegularLegendConfig* legendConfig, int timeStepIndex )
{
if ( !this->isTimeStepDependentDataVisible() )
{
return;
}
cellResult()->updateLegendTextAndRanges( legendConfig, "Cell Result:\n", timeStepIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::ref<RivGeoMechVizLogic> RimGeoMechView::vizLogic() const
{
return m_vizLogic;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimTensorResults* RimGeoMechView::tensorResults() const
{
return m_tensorResults;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTensorResults* RimGeoMechView::tensorResults()
{
return m_tensorResults;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimLegendConfig*> RimGeoMechView::legendConfigs() const
{
std::vector<RimLegendConfig*> absLegendConfigs;
absLegendConfigs.push_back( cellResult()->legendConfig() );
absLegendConfigs.push_back( tensorResults()->arrowColorLegendConfig() );
for ( RimIntersectionResultDefinition* sepInterResDef :
this->separateIntersectionResultsCollection()->intersectionResultsDefinitions() )
{
absLegendConfigs.push_back( sepInterResDef->regularLegendConfig() );
}
for ( RimIntersectionResultDefinition* sepInterResDef :
this->separateSurfaceResultsCollection()->intersectionResultsDefinitions() )
{
absLegendConfigs.push_back( sepInterResDef->regularLegendConfig() );
}
for ( RimWellMeasurementInView* wellMeasurement : m_wellMeasurementCollection->measurements() )
{
absLegendConfigs.push_back( wellMeasurement->legendConfig() );
}
if ( m_surfaceCollection )
{
for ( auto legendConfig : m_surfaceCollection->legendConfigs() )
{
absLegendConfigs.push_back( legendConfig );
}
}
absLegendConfigs.erase( std::remove( absLegendConfigs.begin(), absLegendConfigs.end(), nullptr ),
absLegendConfigs.end() );
return absLegendConfigs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigFemPartCollection* RimGeoMechView::femParts() const
{
if ( m_geomechCase && m_geomechCase->geoMechData() )
{
return m_geomechCase->geoMechData()->femParts();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemPartCollection* RimGeoMechView::femParts()
{
if ( m_geomechCase && m_geomechCase->geoMechData() )
{
return m_geomechCase->geoMechData()->femParts();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::convertCameraPositionFromOldProjectFiles()
{
auto geoMechCase = this->geoMechCase();
if ( geoMechCase )
{
// Up-cast to get access to public interface for camera functions
RimCase* rimCase = geoMechCase;
RiuViewerToViewInterface* viewerToViewInterface = this;
cvf::Vec3d offset = rimCase->displayModelOffset();
auto diplayCoordTrans = this->displayCoordTransform();
{
cvf::Mat4d cameraMx = this->cameraPosition().getInverted();
cvf::Vec3d translation = cameraMx.translation();
cvf::Vec3d translationDomainCoord = diplayCoordTrans->scaleToDomainSize( translation );
translationDomainCoord -= offset;
cvf::Vec3d newCameraTranslation = diplayCoordTrans->scaleToDisplaySize( translationDomainCoord );
cameraMx.setTranslation( newCameraTranslation );
viewerToViewInterface->setCameraPosition( cameraMx.getInverted() );
}
{
cvf::Vec3d pointOfInterest = this->cameraPointOfInterest();
cvf::Vec3d pointOfInterestDomain = diplayCoordTrans->scaleToDomainSize( pointOfInterest );
pointOfInterestDomain -= offset;
cvf::Vec3d newPointOfInterest = diplayCoordTrans->scaleToDisplaySize( pointOfInterestDomain );
viewerToViewInterface->setCameraPointOfInterest( newPointOfInterest );
}
if ( viewer() )
{
viewer()->mainCamera()->setViewMatrix( this->cameraPosition() );
viewer()->setPointOfInterest( this->cameraPointOfInterest() );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechCase* RimGeoMechView::geoMechCase() const
{
return m_geomechCase;
}
//--------------------------------------------------------------------------------------------------
/// Clamp the current timestep to actual possibilities
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::onClampCurrentTimestep()
{
int maxFrameCount = 0;
if ( m_geomechCase )
{
maxFrameCount = m_geomechCase->geoMechData()->femPartResults()->frameCount();
}
if ( m_currentTimeStep >= maxFrameCount ) m_currentTimeStep = maxFrameCount - 1;
if ( m_currentTimeStep < 0 ) m_currentTimeStep = 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGeoMechView::onTimeStepCountRequested()
{
if ( m_geomechCase )
{
return m_geomechCase->geoMechData()->femPartResults()->frameCount();
}
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGeoMechView::isTimeStepDependentDataVisible() const
{
if ( this->hasUserRequestedAnimation() &&
( this->cellResult()->hasResult() || this->geoMechPropertyFilterCollection()->hasActiveFilters() ) )
{
return true;
}
if ( this->hasVisibleTimeStepDependent3dWellLogCurves() )
{
return true;
}
if ( this->intersectionCollection()->hasAnyActiveSeparateResults() )
{
return true;
}
if ( this->surfaceInViewCollection() && this->surfaceInViewCollection()->hasAnyActiveSeparateResults() )
{
return true;
}
if ( m_wellMeasurementCollection->isChecked() )
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Transform* RimGeoMechView::scaleTransform()
{
return m_scaleTransform.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimGridView::fieldChangedByUi( changedField, oldValue, newValue );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::initAfterRead()
{
RimGridView::initAfterRead();
this->cellResult()->setGeoMechCase( m_geomechCase );
this->updateUiIconFromToggleField();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCase* RimGeoMechView::ownerCase() const
{
return m_geomechCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::scheduleGeometryRegen( RivCellSetEnum geometryType )
{
m_vizLogic->scheduleGeometryRegen( geometryType );
if ( this->isMasterView() )
{
RimViewLinker* viewLinker = this->assosiatedViewLinker();
if ( viewLinker )
{
viewLinker->scheduleGeometryRegenForDepViews( geometryType );
}
}
clearReservoirCellVisibilities();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::setOverridePropertyFilterCollection( RimGeoMechPropertyFilterCollection* pfc )
{
m_overridePropertyFilterCollection = pfc;
if ( m_overridePropertyFilterCollection )
{
m_propertyFilterCollection->isActive = m_overridePropertyFilterCollection->isActive;
}
m_propertyFilterCollection.uiCapability()->updateConnectedEditors();
this->scheduleGeometryRegen( PROPERTY_FILTERED );
this->scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechPropertyFilterCollection* RimGeoMechView::geoMechPropertyFilterCollection()
{
if ( m_overridePropertyFilterCollection )
{
return m_overridePropertyFilterCollection;
}
else
{
return m_propertyFilterCollection;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimGeoMechPropertyFilterCollection* RimGeoMechView::geoMechPropertyFilterCollection() const
{
if ( m_overridePropertyFilterCollection )
{
return m_overridePropertyFilterCollection;
}
else
{
return m_propertyFilterCollection;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::calculateCurrentTotalCellVisibility( cvf::UByteArray* totalVisibility, int timeStep )
{
m_vizLogic->calculateCurrentTotalCellVisibility( totalVisibility, timeStep );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::updateIconStateForFilterCollections()
{
m_cellFilterCollection()->updateIconState();
m_cellFilterCollection()->uiCapability()->updateConnectedEditors();
// NB - notice that it is the filter collection managed by this view that the icon update applies to
m_propertyFilterCollection()->updateIconState();
m_propertyFilterCollection()->uiCapability()->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::defineAxisLabels( cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel )
{
CVF_ASSERT( xLabel && yLabel && zLabel );
*xLabel = "E(x,1)";
*yLabel = "N(y,2)";
*zLabel = "Z(3)";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGeoMechView::isUsingFormationNames() const
{
if ( cellResult()->hasCategoryResult() ) return true; // Correct for now
return geoMechPropertyFilterCollection()->isUsingFormationNames();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
RimGridView::defineUiOrdering( uiConfigName, uiOrdering );
caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "View Name" );
nameConfig()->uiOrdering( uiConfigName, *nameGroup );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechView::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/ )
{
uiTreeOrdering.add( m_overlayInfoConfig() );
uiTreeOrdering.add( m_gridCollection() );
uiTreeOrdering.add( cellResult() );
uiTreeOrdering.add( m_tensorResults() );
addRequiredUiTreeObjects( uiTreeOrdering );
uiTreeOrdering.add( m_intersectionCollection() );
if ( surfaceInViewCollection() ) uiTreeOrdering.add( surfaceInViewCollection() );
uiTreeOrdering.add( m_cellFilterCollection() );
uiTreeOrdering.add( m_propertyFilterCollection() );
uiTreeOrdering.skipRemainingChildren( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGeoMechResultDefinition* RimGeoMechView::cellResultResultDefinition() const
{
return cellResult();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimPropertyFilterCollection* RimGeoMechView::propertyFilterCollection() const
{
return geoMechPropertyFilterCollection();
}

View File

@@ -0,0 +1,142 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimGridView.h"
#include "cafAppEnum.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "cvfObject.h"
class RigFemPart;
class RigFemPartCollection;
class Rim3dOverlayInfoConfig;
class RimCellRangeFilterCollection;
class RimGeoMechCase;
class RimGeoMechCellColors;
class RimGeoMechPropertyFilterCollection;
class RimGeoMechResultDefinition;
class RimRegularLegendConfig;
class RimTensorResults;
class RiuViewer;
class RivGeoMechPartMgr;
class RivGeoMechVizLogic;
class RivTensorResultPartMgr;
namespace cvf
{
class CellRangeFilter;
class Transform;
} // namespace cvf
//==================================================================================================
///
///
//==================================================================================================
class RimGeoMechView : public RimGridView
{
CAF_PDM_HEADER_INIT;
public:
RimGeoMechView( void );
~RimGeoMechView( void ) override;
void setGeoMechCase( RimGeoMechCase* gmCase );
RimGeoMechCase* geoMechCase() const;
RimCase* ownerCase() const override;
caf::PdmChildField<RimGeoMechCellColors*> cellResult;
RimGeoMechResultDefinition* cellResultResultDefinition() const;
const RimPropertyFilterCollection* propertyFilterCollection() const override;
RimGeoMechPropertyFilterCollection* geoMechPropertyFilterCollection();
const RimGeoMechPropertyFilterCollection* geoMechPropertyFilterCollection() const;
void setOverridePropertyFilterCollection( RimGeoMechPropertyFilterCollection* pfc );
bool isTimeStepDependentDataVisible() const override;
cvf::Transform* scaleTransform() override;
void scheduleGeometryRegen( RivCellSetEnum geometryType ) override;
void updateIconStateForFilterCollections();
void defineAxisLabels( cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel ) override;
bool isUsingFormationNames() const override;
void calculateCurrentTotalCellVisibility( cvf::UByteArray* totalVisibility, int timeStep ) override;
void updateLegendTextAndRanges( RimRegularLegendConfig* legendConfig, int timeStepIndex );
const cvf::ref<RivGeoMechVizLogic> vizLogic() const;
const RimTensorResults* tensorResults() const;
RimTensorResults* tensorResults();
std::vector<RimLegendConfig*> legendConfigs() const override;
const RigFemPartCollection* femParts() const;
RigFemPartCollection* femParts();
void convertCameraPositionFromOldProjectFiles();
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void onLoadDataAndUpdate() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void initAfterRead() override;
void onCreateDisplayModel() override;
RimPropertyFilterCollection* nativePropertyFilterCollection();
private:
QString createAutoName() const override;
void onUpdateScaleTransform() override;
void onClampCurrentTimestep() override;
size_t onTimeStepCountRequested() override;
void onUpdateDisplayModelForCurrentTimeStep() override;
void onUpdateStaticCellColors() override;
void onResetLegendsInViewer() override;
void onUpdateLegends() override;
void updateTensorLegendTextAndRanges( RimRegularLegendConfig* legendConfig, int timeStepIndex );
caf::PdmChildField<RimTensorResults*> m_tensorResults;
caf::PdmChildField<RimGeoMechPropertyFilterCollection*> m_propertyFilterCollection;
caf::PdmPointer<RimGeoMechPropertyFilterCollection> m_overridePropertyFilterCollection;
caf::PdmPointer<RimGeoMechCase> m_geomechCase;
cvf::ref<RivGeoMechVizLogic> m_vizLogic;
cvf::ref<cvf::Transform> m_scaleTransform;
cvf::ref<RivTensorResultPartMgr> m_tensorPartMgr;
};