Merge pull request #5467 from OPM/well-measurement-ui-improvements-5368

Well measurement ui improvements 5368
This commit is contained in:
Kristian Bendiksen 2020-02-07 12:37:43 +01:00 committed by GitHub
commit 1a9b1bf95c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 169 additions and 20 deletions

View File

@ -24,6 +24,7 @@
#include "Rim3dView.h"
#include "RimGridView.h"
#include "RimProject.h"
#include "RimTools.h"
#include "RimWellMeasurement.h"
#include "RimWellMeasurementCollection.h"
#include "RimWellMeasurementFilePath.h"
@ -159,5 +160,5 @@ RimWellPathCollection* RicWellMeasurementImportTools::selectedWellPathCollection
return caf::SelectionManager::instance()->selectedItemAncestorOfType<RimWellPathCollection>();
}
return nullptr;
return RimTools::wellPathCollection();
}

View File

@ -304,6 +304,10 @@ void RivWellPathPartMgr::appendWellMeasurementsToModel( cvf::ModelBasicList*
double startMD = wellMeasurement->MD() - wellPathRadius * 0.5;
double endMD = wellMeasurement->MD() + wellPathRadius * 0.5;
double wellMeasurementRadius = this->wellMeasurementRadius( characteristicCellSize,
this->wellPathCollection(),
wellMeasurementInView );
std::vector<cvf::Vec3d> displayCoords;
displayCoords.push_back( displayCoordTransform->transformToDisplayCoord(
m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath( startMD ) ) );
@ -315,10 +319,10 @@ void RivWellPathPartMgr::appendWellMeasurementsToModel( cvf::ModelBasicList*
m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath( endMD ) ) );
std::vector<double> radii;
radii.push_back( wellPathRadius );
radii.push_back( wellPathRadius * 2.5 );
radii.push_back( wellPathRadius * 2.5 );
radii.push_back( wellPathRadius );
radii.push_back( std::min( wellPathRadius, wellMeasurementRadius ) );
radii.push_back( wellMeasurementRadius );
radii.push_back( wellMeasurementRadius );
radii.push_back( std::min( wellPathRadius, wellMeasurementRadius ) );
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo( wellMeasurement );
@ -853,18 +857,21 @@ void RivWellPathPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList*
if ( m_rimWellPath.isNull() ) return;
if ( wellPathCollection->wellPathVisibility() == RimWellPathCollection::FORCE_ALL_OFF ) return;
if ( wellPathCollection->wellPathVisibility() != RimWellPathCollection::FORCE_ALL_ON &&
m_rimWellPath->showWellPath() == false )
{
return;
}
bool showWellPath = ( wellPathCollection->isActive() &&
( ( wellPathCollection->wellPathVisibility() != RimWellPathCollection::FORCE_ALL_OFF ) ||
( wellPathCollection->wellPathVisibility() == RimWellPathCollection::FORCE_ALL_ON &&
m_rimWellPath->showWellPath() ) ) );
if ( !isWellPathWithinBoundingBox( wellPathClipBoundingBox ) ) return;
appendPerforationsToModel( model, timeStepIndex, displayCoordTransform, characteristicCellSize, false );
appendVirtualTransmissibilitiesToModel( model, timeStepIndex, displayCoordTransform, characteristicCellSize );
if ( showWellPath )
{
// Only show perforations and virtual transmissibilities when well path is shown
appendPerforationsToModel( model, timeStepIndex, displayCoordTransform, characteristicCellSize, false );
appendVirtualTransmissibilitiesToModel( model, timeStepIndex, displayCoordTransform, characteristicCellSize );
}
// Well measurements visibility is independent of well path visibility
appendWellMeasurementsToModel( model, displayCoordTransform, characteristicCellSize );
RimGridView* gridView = dynamic_cast<RimGridView*>( m_rimView.p() );
@ -932,3 +939,14 @@ double RivWellPathPartMgr::wellPathRadius( double characteristicCellSize, RimWel
return wellPathCollection->wellPathRadiusScaleFactor() * m_rimWellPath->wellPathRadiusScaleFactor() *
characteristicCellSize;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RivWellPathPartMgr::wellMeasurementRadius( double characteristicCellSize,
const RimWellPathCollection* wellPathCollection,
const RimWellMeasurementInView* wellMeasurementInView )
{
return wellPathCollection->wellPathRadiusScaleFactor() * wellMeasurementInView->radiusScaleFactor() *
characteristicCellSize;
}

View File

@ -48,6 +48,7 @@ class RimWellPathCollection;
class Rim3dView;
class Riv3dWellLogPlanePartMgr;
class RivWellConnectionFactorPartMgr;
class RimWellMeasurementInView;
class QDateTime;
@ -126,6 +127,9 @@ private:
void clearAllBranchData();
inline RimWellPathCollection* wellPathCollection() const;
inline double wellPathRadius( double characteristicCellSize, RimWellPathCollection* wellPathCollection );
double wellMeasurementRadius( double characteristicCellSize,
const RimWellPathCollection* wellPathCollection,
const RimWellMeasurementInView* wellMeasurementInView );
bool isWellPathWithinBoundingBox( const cvf::BoundingBox& wellPathClipBoundingBox ) const;

View File

@ -86,8 +86,6 @@ void RivWellPathsPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList
double characteristicCellSize,
const cvf::BoundingBox& wellPathClipBoundingBox )
{
if ( !isWellPathVisible() ) return;
createPartManagersIfRequired();
for ( auto& partMgr : m_wellPathsPartMgrs )

View File

@ -33,6 +33,7 @@
#include "cafCmdFeatureMenuBuilder.h"
#include "cafPdmUiDoubleSliderEditor.h"
#include "cafPdmUiDoubleValueEditor.h"
#include "cafPdmUiTableViewEditor.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafPdmUiTreeSelectionEditor.h"
@ -58,6 +59,22 @@ RimWellMeasurementInView::RimWellMeasurementInView()
CAF_PDM_InitFieldNoDefault( &m_wells, "Wells", "Wells", "", "", "" );
m_wells.uiCapability()->setAutoAddingOptionFromValue( false );
m_wells.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
m_wells.xmlCapability()->disableIO();
// The m_wells field does not serialize in a suitable format, so we work around it by
// serializing to a pipe-delimited string.
CAF_PDM_InitFieldNoDefault( &m_wellsSerialized, "WellsSerialized", "WellsSerialized", "", "", "" );
m_wellsSerialized.uiCapability()->setUiHidden( true );
// Keep track of the wells which has a given measurement in order to automatically select
// new wells when they appear in new measurements
CAF_PDM_InitFieldNoDefault( &m_availableWellsSerialized,
"AvailableWellsSerialized",
"AvailableWellsSerialized",
"",
"",
"" );
// m_availableWellsSerialized.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_lowerBound, "LowerBound", -HUGE_VAL, "Min", "", "", "" );
m_lowerBound.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
@ -69,6 +86,9 @@ RimWellMeasurementInView::RimWellMeasurementInView()
m_qualityFilter.uiCapability()->setAutoAddingOptionFromValue( false );
m_qualityFilter.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_radiusScaleFactor, "RadiusScaleFactor", 2.5, "Radius Scale", "", "", "" );
m_radiusScaleFactor.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
this->setName( "Well Measurement" );
m_minimumResultValue = cvf::UNDEFINED_DOUBLE;
@ -110,6 +130,8 @@ void RimWellMeasurementInView::defineUiOrdering( QString uiConfigName, caf::PdmU
uiOrdering.add( &m_qualityFilter );
uiOrdering.add( &m_radiusScaleFactor );
uiOrdering.skipRemainingFields();
}
@ -128,13 +150,22 @@ void RimWellMeasurementInView::defineEditorAttribute( const caf::PdmFieldHandle*
if ( field == &m_lowerBound || field == &m_upperBound )
{
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
if ( !myAttr )
if ( myAttr )
{
return;
myAttr->m_minimum = m_minimumResultValue;
myAttr->m_maximum = m_maximumResultValue;
}
}
myAttr->m_minimum = m_minimumResultValue;
myAttr->m_maximum = m_maximumResultValue;
if ( field == &m_radiusScaleFactor )
{
caf::PdmUiDoubleValueEditorAttribute* uiDoubleValueEditorAttr =
dynamic_cast<caf::PdmUiDoubleValueEditorAttribute*>( attribute );
if ( uiDoubleValueEditorAttr )
{
uiDoubleValueEditorAttr->m_decimals = 2;
uiDoubleValueEditorAttr->m_validator = new QDoubleValidator( 0.001, 100.0, 2 );
}
}
}
@ -145,12 +176,25 @@ void RimWellMeasurementInView::fieldChangedByUi( const caf::PdmFieldHandle* chan
const QVariant& oldValue,
const QVariant& newValue )
{
if ( changedField == &m_wells )
{
m_wellsSerialized = convertToSerializableString( m_wells.v() );
}
updateLegendData();
RimGridView* rimGridView = nullptr;
this->firstAncestorOrThisOfTypeAsserted( rimGridView );
rimGridView->scheduleCreateDisplayModelAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementInView::initAfterRead()
{
m_wells = convertFromSerializableString( m_wellsSerialized );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -305,6 +349,9 @@ QList<caf::PdmOptionItemInfo>
{
options.push_back( caf::PdmOptionItemInfo( wellName, wellName ) );
}
selectNewWells( wellsWithMeasurementKind );
setAvailableWells( wellsWithMeasurementKind );
}
}
else if ( fieldNeedingOptions == &m_qualityFilter )
@ -385,6 +432,8 @@ void RimWellMeasurementInView::setAllWellsSelected()
{
m_wells.v().push_back( wellName );
}
m_wellsSerialized = convertToSerializableString( m_wells.v() );
}
}
@ -411,3 +460,69 @@ void RimWellMeasurementInView::setAllQualitiesSelected()
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellMeasurementInView::convertToSerializableString( const std::vector<QString>& strings )
{
QStringList stringList = QVector<QString>::fromStdVector( strings ).toList();
return stringList.join( '|' );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RimWellMeasurementInView::convertFromSerializableString( const QString& string )
{
QStringList stringList = string.split( '|' );
return stringList.toVector().toStdVector();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementInView::selectNewWells( const std::set<QString>& wells )
{
// Check if there are new wells on the measurement kind
std::set<QString> currentAvailableWells = getAvailableWells();
std::set<QString> newWells;
std::set_difference( wells.begin(),
wells.end(),
currentAvailableWells.begin(),
currentAvailableWells.end(),
std::inserter( newWells, newWells.end() ) );
// Select the new wells
for ( const QString& newWell : newWells )
{
m_wells.v().push_back( newWell );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementInView::setAvailableWells( const std::set<QString>& wells )
{
std::vector<QString> v( wells.begin(), wells.end() );
m_availableWellsSerialized = convertToSerializableString( v );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RimWellMeasurementInView::getAvailableWells() const
{
std::vector<QString> v = convertFromSerializableString( m_availableWellsSerialized );
std::set<QString> s( v.begin(), v.end() );
return s;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellMeasurementInView::radiusScaleFactor() const
{
return m_radiusScaleFactor;
}

View File

@ -54,6 +54,7 @@ public:
void rangeValues( double* lowerBound, double* upperBound ) const;
std::vector<int> qualityFilter() const;
double radiusScaleFactor() const;
protected:
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
@ -62,6 +63,7 @@ protected:
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void initAfterRead() override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
@ -76,12 +78,22 @@ protected:
const QString& measurementKind );
private:
static QString convertToSerializableString( const std::vector<QString>& strings );
static std::vector<QString> convertFromSerializableString( const QString& string );
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
caf::PdmField<QString> m_measurementKind;
caf::PdmField<std::vector<QString>> m_wells;
caf::PdmField<double> m_lowerBound;
caf::PdmField<double> m_upperBound;
caf::PdmField<std::vector<int>> m_qualityFilter;
caf::PdmField<QString> m_wellsSerialized;
caf::PdmField<QString> m_availableWellsSerialized;
caf::PdmField<double> m_radiusScaleFactor;
void selectNewWells( const std::set<QString>& wells );
void setAvailableWells( const std::set<QString>& wells );
std::set<QString> getAvailableWells() const;
double m_minimumResultValue;
double m_maximumResultValue;

View File

@ -451,6 +451,7 @@ void RiuMainWindow::createMenus()
importWellMenu->addAction( cmdFeatureMgr->action( "RicWellPathsImportSsihubFeature" ) );
importWellMenu->addAction( cmdFeatureMgr->action( "RicWellLogsImportFileFeature" ) );
importWellMenu->addAction( cmdFeatureMgr->action( "RicWellPathFormationsImportFileFeature" ) );
importWellMenu->addAction( cmdFeatureMgr->action( "RicImportWellMeasurementsFeature" ) );
importMenu->addSeparator();
importMenu->addAction( cmdFeatureMgr->action( "RicImportObservedDataInMenuFeature" ) );