mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Custom vfp plot (#11450)
* AppFwk: When clearing a tree selection, make sure all values are cleared * Fix deprecated implicit lambda * Add support for using the closest value in addition to exact match * Add table data source object and add plot with multiple data sources Delete the temporary RimVfpDeck class Add RimVfpTable to represent a table in a data source Add plot able to show data from multiple tables * AppFwk: Make it possible to call resolveReferences multiple times Use case: Vfp tables are stored in files. Multiple tables can be present in one file. Pdm table objects are created after resolve references is done as part of parsing file. When the Pdm object are created, resolveReferences can be called once more. * Call resolveReferencesRecursively() after RimVfpTable objects are created
This commit is contained in:
parent
2fb54ac1ec
commit
1d57b9032b
@ -92,6 +92,8 @@
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathFracture.h"
|
||||
#include "VerticalFlowPerformance/RimVfpDataCollection.h"
|
||||
#include "VerticalFlowPerformance/RimVfpPlotCollection.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
#include "RiuGuiTheme.h"
|
||||
@ -539,6 +541,7 @@ bool RiaApplication::loadProject( const QString& projectFileName, ProjectLoadAct
|
||||
// Initialize well paths
|
||||
oilField->wellPathCollection->loadDataAndUpdate();
|
||||
oilField->ensembleWellLogsCollection->loadDataAndUpdate();
|
||||
oilField->vfpDataCollection->loadDataAndUpdate();
|
||||
|
||||
// Initialize seismic data
|
||||
auto& seisDataColl = oilField->seismicDataCollection();
|
||||
@ -553,6 +556,10 @@ bool RiaApplication::loadProject( const QString& projectFileName, ProjectLoadAct
|
||||
{
|
||||
RimMainPlotCollection* mainPlotColl = RimMainPlotCollection::current();
|
||||
mainPlotColl->ensureDefaultFlowPlotsAreCreated();
|
||||
|
||||
// RimVfpTable are not presisted in the project file, and are created in vfpDataCollection->loadDataAndUpdate(). Existing VFP
|
||||
// plots will have references to RimVfpTables. Call resolveReferencesRecursively() to update the references to RimVfpTable objects.
|
||||
mainPlotColl->vfpPlotCollection()->resolveReferencesRecursively();
|
||||
}
|
||||
|
||||
for ( RimOilField* oilField : m_project->oilFields )
|
||||
|
@ -25,7 +25,7 @@ void RiaFileDownloader::downloadFile( const QUrl& url, const QString& filePath )
|
||||
|
||||
connect( reply,
|
||||
&QNetworkReply::finished,
|
||||
[=]()
|
||||
[=, this]()
|
||||
{
|
||||
if ( reply->error() )
|
||||
{
|
||||
|
@ -96,6 +96,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportWellLogCsvFileFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewViewForGridEnsembleFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewVfpPlotFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewCustomVfpPlotFeature.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@ -195,6 +196,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportWellLogCsvFileFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewViewForGridEnsembleFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewVfpPlotFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewCustomVfpPlotFeature.cpp
|
||||
)
|
||||
|
||||
if(RESINSIGHT_USE_QT_CHARTS)
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "RimWellPathFracture.h"
|
||||
#include "RimWellPathFractureCollection.h"
|
||||
|
||||
#include "VerticalFlowPerformance/RimVfpDataCollection.h"
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
#include "cafSelectionManager.h"
|
||||
@ -124,6 +126,11 @@ bool RicDeleteSubItemsFeature::hasDeletableSubItems( caf::PdmUiItem* uiItem )
|
||||
}
|
||||
}
|
||||
|
||||
if ( dynamic_cast<RimVfpDataCollection*>( uiItem ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,113 +148,108 @@ void RicDeleteSubItemsFeature::deleteSubItems( bool onlyDeleteUnchecked )
|
||||
{
|
||||
if ( !RicDeleteSubItemsFeature::hasDeletableSubItems( item ) ) continue;
|
||||
|
||||
if ( auto multiPlot = dynamic_cast<RimSummaryMultiPlot*>( item ) )
|
||||
{
|
||||
auto multiPlot = dynamic_cast<RimSummaryMultiPlot*>( item );
|
||||
if ( multiPlot )
|
||||
if ( onlyDeleteUnchecked )
|
||||
{
|
||||
if ( onlyDeleteUnchecked )
|
||||
auto plots = multiPlot->plots();
|
||||
for ( auto plot : plots )
|
||||
{
|
||||
auto plots = multiPlot->plots();
|
||||
for ( auto plot : plots )
|
||||
{
|
||||
if ( plot->showWindow() ) continue;
|
||||
multiPlot->removePlotNoUpdate( plot );
|
||||
delete plot;
|
||||
}
|
||||
if ( plot->showWindow() ) continue;
|
||||
multiPlot->removePlotNoUpdate( plot );
|
||||
delete plot;
|
||||
}
|
||||
else
|
||||
{
|
||||
multiPlot->deleteAllPlots();
|
||||
}
|
||||
|
||||
multiPlot->updateConnectedEditors();
|
||||
}
|
||||
else
|
||||
{
|
||||
multiPlot->deleteAllPlots();
|
||||
}
|
||||
|
||||
multiPlot->updateConnectedEditors();
|
||||
}
|
||||
|
||||
if ( auto collection = dynamic_cast<RimSummaryMultiPlotCollection*>( item ) )
|
||||
{
|
||||
auto collection = dynamic_cast<RimSummaryMultiPlotCollection*>( item );
|
||||
if ( collection )
|
||||
if ( onlyDeleteUnchecked )
|
||||
{
|
||||
if ( onlyDeleteUnchecked )
|
||||
auto plots = collection->multiPlots();
|
||||
for ( auto plot : plots )
|
||||
{
|
||||
auto plots = collection->multiPlots();
|
||||
for ( auto plot : plots )
|
||||
{
|
||||
if ( plot->showWindow() ) continue;
|
||||
collection->removePlotNoUpdate( plot );
|
||||
delete plot;
|
||||
}
|
||||
if ( plot->showWindow() ) continue;
|
||||
collection->removePlotNoUpdate( plot );
|
||||
delete plot;
|
||||
}
|
||||
else
|
||||
{
|
||||
collection->deleteAllPlots();
|
||||
}
|
||||
|
||||
collection->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto collection = dynamic_cast<RimWellPathCollection*>( item );
|
||||
if ( collection )
|
||||
{
|
||||
if ( onlyDeleteUnchecked )
|
||||
{
|
||||
auto paths = collection->allWellPaths();
|
||||
for ( auto path : paths )
|
||||
{
|
||||
if ( path->showWellPath() ) continue;
|
||||
collection->removeWellPath( path );
|
||||
delete path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
collection->deleteAllWellPaths();
|
||||
}
|
||||
|
||||
collection->updateConnectedEditors();
|
||||
collection->scheduleRedrawAffectedViews();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto collection = dynamic_cast<RimWellPathFractureCollection*>( item );
|
||||
if ( collection )
|
||||
{
|
||||
if ( onlyDeleteUnchecked )
|
||||
{
|
||||
auto items = collection->allFractures();
|
||||
for ( auto item : items )
|
||||
{
|
||||
if ( item->isChecked() ) continue;
|
||||
collection->removeFracture( item );
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
collection->deleteFractures();
|
||||
}
|
||||
|
||||
collection->updateConnectedEditors();
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
if ( proj ) proj->reloadCompletionTypeResultsInAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto collection = dynamic_cast<RimPlotCollection*>( item );
|
||||
if ( collection )
|
||||
else
|
||||
{
|
||||
collection->deleteAllPlots();
|
||||
}
|
||||
|
||||
if ( auto objHandle = dynamic_cast<caf::PdmUiObjectHandle*>( item ) )
|
||||
collection->updateConnectedEditors();
|
||||
}
|
||||
|
||||
if ( auto collection = dynamic_cast<RimWellPathCollection*>( item ) )
|
||||
{
|
||||
if ( onlyDeleteUnchecked )
|
||||
{
|
||||
auto paths = collection->allWellPaths();
|
||||
for ( auto path : paths )
|
||||
{
|
||||
objHandle->updateConnectedEditors();
|
||||
if ( path->showWellPath() ) continue;
|
||||
collection->removeWellPath( path );
|
||||
delete path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
collection->deleteAllWellPaths();
|
||||
}
|
||||
|
||||
collection->updateConnectedEditors();
|
||||
collection->scheduleRedrawAffectedViews();
|
||||
}
|
||||
|
||||
if ( auto collection = dynamic_cast<RimWellPathFractureCollection*>( item ) )
|
||||
{
|
||||
if ( onlyDeleteUnchecked )
|
||||
{
|
||||
auto items = collection->allFractures();
|
||||
for ( auto item : items )
|
||||
{
|
||||
if ( item->isChecked() ) continue;
|
||||
collection->removeFracture( item );
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
collection->deleteFractures();
|
||||
}
|
||||
|
||||
collection->updateConnectedEditors();
|
||||
|
||||
RimProject* proj = RimProject::current();
|
||||
if ( proj ) proj->reloadCompletionTypeResultsInAllViews();
|
||||
}
|
||||
|
||||
if ( auto collection = dynamic_cast<RimPlotCollection*>( item ) )
|
||||
{
|
||||
collection->deleteAllPlots();
|
||||
|
||||
if ( auto objHandle = dynamic_cast<caf::PdmUiObjectHandle*>( item ) )
|
||||
{
|
||||
objHandle->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
if ( auto collection = dynamic_cast<RimVfpDataCollection*>( item ) )
|
||||
{
|
||||
collection->deleteAllData();
|
||||
|
||||
if ( auto objHandle = dynamic_cast<caf::PdmUiObjectHandle*>( item ) )
|
||||
{
|
||||
objHandle->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "RimMainPlotCollection.h"
|
||||
|
||||
#include "VerticalFlowPerformance/RimVfpDataCollection.h"
|
||||
#include "VerticalFlowPerformance/RimVfpDeck.h"
|
||||
#include "VerticalFlowPerformance/RimVfpPlot.h"
|
||||
#include "VerticalFlowPerformance/RimVfpPlotCollection.h"
|
||||
|
||||
@ -72,9 +71,6 @@ void RicImportVfpDataFeature::onActionTriggered( bool isChecked )
|
||||
|
||||
app->setLastUsedDialogDirectory( vfpDataKey, QFileInfo( fileNames.last() ).absolutePath() );
|
||||
|
||||
std::vector<RimVfpPlot*> vfpPlots;
|
||||
std::vector<RimVfpDeck*> vfpDecks;
|
||||
|
||||
auto vfpDataColl = RimVfpDataCollection::instance();
|
||||
|
||||
for ( const auto& fileName : fileNames )
|
||||
|
66
ApplicationLibCode/Commands/RicNewCustomVfpPlotFeature.cpp
Normal file
66
ApplicationLibCode/Commands/RicNewCustomVfpPlotFeature.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024 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 "RicNewCustomVfpPlotFeature.h"
|
||||
|
||||
#include "RicNewVfpPlotFeature.h"
|
||||
|
||||
#include "RimMainPlotCollection.h"
|
||||
|
||||
#include "VerticalFlowPerformance/RimCustomVfpPlot.h"
|
||||
#include "VerticalFlowPerformance/RimVfpDataCollection.h"
|
||||
#include "VerticalFlowPerformance/RimVfpPlotCollection.h"
|
||||
#include "VerticalFlowPerformance/RimVfpTable.h"
|
||||
#include "VerticalFlowPerformance/RimVfpTableData.h"
|
||||
|
||||
#include "cafSelectionManagerTools.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewCustomVfpPlotFeature, "RicNewCustomVfpPlotFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewCustomVfpPlotFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
RimVfpPlotCollection* vfpPlotColl = RimMainPlotCollection::current()->vfpPlotCollection();
|
||||
if ( !vfpPlotColl ) return;
|
||||
|
||||
auto selectedTables = RicNewVfpPlotFeature::selectedTables();
|
||||
if ( selectedTables.empty() ) return;
|
||||
|
||||
auto mainDataSource = selectedTables.front();
|
||||
std::vector<RimVfpTable*> additionalDataSources;
|
||||
std::copy( selectedTables.begin() + 1, selectedTables.end(), std::back_inserter( additionalDataSources ) );
|
||||
|
||||
auto firstPlot = vfpPlotColl->createAndAppendPlots( mainDataSource, additionalDataSources );
|
||||
vfpPlotColl->updateConnectedEditors();
|
||||
RiuPlotMainWindowTools::onObjectAppended( firstPlot, firstPlot );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewCustomVfpPlotFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "Create Custom VFP Plot" );
|
||||
actionToSetup->setIcon( QIcon( ":/VfpPlot.svg" ) );
|
||||
}
|
33
ApplicationLibCode/Commands/RicNewCustomVfpPlotFeature.h
Normal file
33
ApplicationLibCode/Commands/RicNewCustomVfpPlotFeature.h
Normal file
@ -0,0 +1,33 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024 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 "cafCmdFeature.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicNewCustomVfpPlotFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
private:
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "VerticalFlowPerformance/RimVfpDataCollection.h"
|
||||
#include "VerticalFlowPerformance/RimVfpPlotCollection.h"
|
||||
#include "VerticalFlowPerformance/RimVfpTable.h"
|
||||
#include "VerticalFlowPerformance/RimVfpTableData.h"
|
||||
|
||||
#include "cafSelectionManagerTools.h"
|
||||
@ -32,6 +33,22 @@
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewVfpPlotFeature, "RicNewVfpPlotFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimVfpTable*> RicNewVfpPlotFeature::selectedTables()
|
||||
{
|
||||
auto tables = caf::selectedObjectsByTypeStrict<RimVfpTable*>();
|
||||
auto selectedTableData = caf::selectedObjectsByTypeStrict<RimVfpTableData*>();
|
||||
for ( auto tableData : selectedTableData )
|
||||
{
|
||||
auto tableDataSources = tableData->tableDataSources();
|
||||
tables.insert( tables.end(), tableDataSources.begin(), tableDataSources.end() );
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -40,10 +57,9 @@ void RicNewVfpPlotFeature::onActionTriggered( bool isChecked )
|
||||
RimVfpPlotCollection* vfpPlotColl = RimMainPlotCollection::current()->vfpPlotCollection();
|
||||
if ( !vfpPlotColl ) return;
|
||||
|
||||
auto selectedTableData = caf::selectedObjectsByTypeStrict<RimVfpTableData*>();
|
||||
for ( auto tableData : selectedTableData )
|
||||
for ( auto table : selectedTables() )
|
||||
{
|
||||
RimVfpPlot* firstPlot = vfpPlotColl->createAndAppendPlots( tableData );
|
||||
RimVfpPlot* firstPlot = vfpPlotColl->createAndAppendPlots( table );
|
||||
vfpPlotColl->updateConnectedEditors();
|
||||
RiuPlotMainWindowTools::onObjectAppended( firstPlot, firstPlot );
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
class RimVfpTable;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -27,6 +29,9 @@ class RicNewVfpPlotFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
public:
|
||||
static std::vector<RimVfpTable*> selectedTables();
|
||||
|
||||
private:
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
|
@ -1,18 +1,20 @@
|
||||
set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpDefines.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpDeck.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomVfpPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpPlotCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpTableData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpTable.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpDataCollection.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpDeck.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpDefines.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCustomVfpPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpPlotCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpTableData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpTable.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimVfpDataCollection.cpp
|
||||
)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,172 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024 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 "RimPlot.h"
|
||||
#include "RimVfpDefines.h"
|
||||
|
||||
#include "cafPdmPtrArrayField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
class RiuPlotWidget;
|
||||
class VfpPlotData;
|
||||
class RimPlotAxisProperties;
|
||||
class RigVfpTables;
|
||||
class RimVfpTableData;
|
||||
class RimVfpTable;
|
||||
class RiuPlotCurveInfoTextProvider;
|
||||
|
||||
struct VfpValueSelection;
|
||||
struct VfpTableInitialData;
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
class VFPInjTable;
|
||||
class VFPProdTable;
|
||||
} // namespace Opm
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Vertical Flow Performance Plot
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RimCustomVfpPlot : public RimPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCustomVfpPlot();
|
||||
~RimCustomVfpPlot() override;
|
||||
|
||||
void selectDataSource( RimVfpTable* mainDataSource, const std::vector<RimVfpTable*>& vfpTableData );
|
||||
void setTableNumber( int tableNumber );
|
||||
void initializeObject();
|
||||
|
||||
// RimPlot implementations
|
||||
RiuPlotWidget* plotWidget() override;
|
||||
bool isCurveHighlightSupported() const override;
|
||||
|
||||
void setAutoScaleXEnabled( bool enabled ) override;
|
||||
void setAutoScaleYEnabled( bool enabled ) override;
|
||||
void updateAxes() override;
|
||||
void updateLegend() override;
|
||||
QString asciiDataForPlotExport() const override;
|
||||
void reattachAllCurves() override;
|
||||
void detachAllCurves() override;
|
||||
|
||||
// RimPlotWindow implementations
|
||||
QString description() const override;
|
||||
QString infoForCurve( RimPlotCurve* plotCurve ) const;
|
||||
|
||||
// RimViewWindow implementations
|
||||
QWidget* viewWidget() override;
|
||||
QImage snapshotWindowContent() override;
|
||||
void zoomAll() override;
|
||||
|
||||
private:
|
||||
void onChildrenUpdated( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& updatedObjects ) override;
|
||||
void deleteViewWidget() override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
void scheduleReplot();
|
||||
|
||||
private:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void initAfterRead() override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
|
||||
VfpValueSelection tableSelection( RimVfpTable* table ) const;
|
||||
void initializeFromInitData( const VfpTableInitialData& table );
|
||||
|
||||
RiuPlotWidget* doCreatePlotViewWidget( QWidget* mainWindowParent ) override;
|
||||
|
||||
void calculateTableValueOptions( RimVfpDefines::ProductionVariableType variableType, QList<caf::PdmOptionItemInfo>& options );
|
||||
|
||||
void setFixedVariableUiEditability( caf::PdmFieldHandle& field, RimVfpDefines::ProductionVariableType variableType );
|
||||
|
||||
void updatePlotTitle( const QString& plotTitle );
|
||||
static QString generatePlotTitle( const QString& wellName,
|
||||
int tableNumber,
|
||||
RimVfpDefines::TableType tableType,
|
||||
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
RimVfpDefines::ProductionVariableType familyVariable );
|
||||
|
||||
static double convertToDisplayUnit( double value, RimVfpDefines::ProductionVariableType variableType );
|
||||
static void convertToDisplayUnit( std::vector<double>& values, RimVfpDefines::ProductionVariableType variableType );
|
||||
static QString getDisplayUnit( RimVfpDefines::ProductionVariableType variableType );
|
||||
static QString getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType );
|
||||
|
||||
void populatePlotWidgetWithPlotData( RiuPlotWidget* plotWidget, const VfpPlotData& plotData, const QColor& color );
|
||||
|
||||
static QString axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase );
|
||||
|
||||
void connectAxisSignals( RimPlotAxisProperties* axis );
|
||||
void axisSettingsChanged( const caf::SignalEmitter* emitter );
|
||||
void axisLogarithmicChanged( const caf::SignalEmitter* emitter, bool isLogarithmic );
|
||||
void updatePlotWidgetFromAxisRanges() override;
|
||||
void updateAxisRangesFromPlotWidget() override;
|
||||
|
||||
void onPlotZoomed();
|
||||
void curveAppearanceChanged( const caf::SignalEmitter* emitter );
|
||||
|
||||
std::vector<double> availableValues( RimVfpDefines::ProductionVariableType variableType ) const;
|
||||
|
||||
static RiuPlotCurveInfoTextProvider* curveTextProvider();
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_plotTitle;
|
||||
|
||||
caf::PdmPtrField<RimVfpTable*> m_mainDataSource;
|
||||
caf::PdmPtrArrayField<RimVfpTable*> m_additionalDataSources;
|
||||
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::CurveMatchingType>> m_curveMatchingType;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::CurveOptionValuesType>> m_curveOptionFiltering;
|
||||
|
||||
caf::PdmField<int> m_tableNumber;
|
||||
caf::PdmField<double> m_referenceDepth;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::FlowingPhaseType>> m_flowingPhase;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::FlowingWaterFractionType>> m_flowingWaterFraction;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::FlowingGasFractionType>> m_flowingGasFraction;
|
||||
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::TableType>> m_tableType;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::InterpolatedVariableType>> m_interpolatedVariable;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::ProductionVariableType>> m_primaryVariable;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::ProductionVariableType>> m_familyVariable;
|
||||
|
||||
caf::PdmField<double> m_flowRateIdx;
|
||||
caf::PdmField<double> m_thpIdx;
|
||||
caf::PdmField<double> m_articifialLiftQuantityIdx;
|
||||
caf::PdmField<double> m_waterCutIdx;
|
||||
caf::PdmField<double> m_gasLiquidRatioIdx;
|
||||
|
||||
caf::PdmField<std::vector<double>> m_familyValues;
|
||||
|
||||
caf::PdmChildField<RimPlotAxisProperties*> m_yAxisProperties;
|
||||
caf::PdmChildField<RimPlotAxisProperties*> m_xAxisProperties;
|
||||
|
||||
caf::PdmChildArrayField<RimPlotCurve*> m_plotCurves;
|
||||
|
||||
std::vector<VfpPlotData> m_plotData;
|
||||
|
||||
QPointer<RiuPlotWidget> m_plotWidget;
|
||||
};
|
@ -46,22 +46,58 @@ RimVfpDataCollection* RimVfpDataCollection::instance()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpTableData* RimVfpDataCollection::appendTableDataObject( const QString& fileName )
|
||||
RimVfpTable* RimVfpDataCollection::appendTableDataObject( const QString& fileName )
|
||||
{
|
||||
auto* vfpTableData = new RimVfpTableData();
|
||||
vfpTableData->setFileName( fileName );
|
||||
|
||||
m_vfpTableData.push_back( vfpTableData );
|
||||
|
||||
return vfpTableData;
|
||||
vfpTableData->ensureDataIsImported();
|
||||
auto dataSources = vfpTableData->tableDataSources();
|
||||
|
||||
if ( !dataSources.empty() )
|
||||
{
|
||||
return dataSources.front();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimVfpTableData*> RimVfpDataCollection::vfpTableData() const
|
||||
std::vector<RimVfpTable*> RimVfpDataCollection::vfpTableData() const
|
||||
{
|
||||
return m_vfpTableData.childrenByType();
|
||||
std::vector<RimVfpTable*> tableDataSources;
|
||||
|
||||
for ( auto vfpTableData : m_vfpTableData.childrenByType() )
|
||||
{
|
||||
for ( auto table : vfpTableData->tableDataSources() )
|
||||
{
|
||||
tableDataSources.push_back( table );
|
||||
}
|
||||
}
|
||||
|
||||
return tableDataSources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpDataCollection::loadDataAndUpdate()
|
||||
{
|
||||
for ( auto vfpTableData : m_vfpTableData.childrenByType() )
|
||||
{
|
||||
vfpTableData->ensureDataIsImported();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpDataCollection::deleteAllData()
|
||||
{
|
||||
m_vfpTableData.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
class RimVfpTable;
|
||||
class RimVfpTableData;
|
||||
|
||||
//==================================================================================================
|
||||
@ -35,8 +36,13 @@ public:
|
||||
|
||||
static RimVfpDataCollection* instance();
|
||||
|
||||
RimVfpTableData* appendTableDataObject( const QString& fileName );
|
||||
std::vector<RimVfpTableData*> vfpTableData() const;
|
||||
RimVfpTable* appendTableDataObject( const QString& fileName );
|
||||
|
||||
std::vector<RimVfpTable*> vfpTableData() const;
|
||||
|
||||
void loadDataAndUpdate();
|
||||
|
||||
void deleteAllData();
|
||||
|
||||
private:
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
@ -1,155 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024 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 "RimVfpDeck.h"
|
||||
|
||||
#include "RigVfpTables.h"
|
||||
|
||||
#include "RimVfpDataCollection.h"
|
||||
#include "RimVfpPlotCollection.h"
|
||||
#include "RimVfpTableData.h"
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimVfpDeck, "RimVfpDeck" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpDeck::RimVfpDeck()
|
||||
{
|
||||
CAF_PDM_InitObject( "VFP Plot", ":/VfpPlot.svg" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_vfpTableData, "VfpTableData", "VFP Data Source" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_vfpPlotCollection, "VfpPlotCollection", "Plot Collection" );
|
||||
m_vfpPlotCollection = new RimVfpPlotCollection();
|
||||
|
||||
setDeletable( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpDeck::setDataSource( RimVfpTableData* tableData )
|
||||
{
|
||||
m_vfpTableData = tableData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpDeck::loadDataAndUpdate()
|
||||
{
|
||||
updateObjectName();
|
||||
|
||||
std::vector<RimVfpPlot*> currentPlots = m_vfpPlotCollection->plots();
|
||||
|
||||
if ( m_vfpTableData )
|
||||
{
|
||||
m_vfpTableData->ensureDataIsImported();
|
||||
|
||||
if ( m_vfpTableData->vfpTables() )
|
||||
{
|
||||
auto tables = m_vfpTableData->vfpTables();
|
||||
|
||||
auto allTableNumbers = tables->productionTableNumbers();
|
||||
auto injTableNumbers = tables->injectionTableNumbers();
|
||||
allTableNumbers.insert( allTableNumbers.end(), injTableNumbers.begin(), injTableNumbers.end() );
|
||||
|
||||
for ( const auto& number : allTableNumbers )
|
||||
{
|
||||
RimVfpPlot* plot = m_vfpPlotCollection->plotForTableNumber( number );
|
||||
if ( !plot )
|
||||
{
|
||||
plot = new RimVfpPlot();
|
||||
plot->setDataSource( m_vfpTableData );
|
||||
plot->setTableNumber( number );
|
||||
plot->initializeObject();
|
||||
|
||||
m_vfpPlotCollection->addPlot( plot );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::erase( currentPlots, plot );
|
||||
}
|
||||
plot->setDeletable( false );
|
||||
plot->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto plotToDelete : currentPlots )
|
||||
{
|
||||
m_vfpPlotCollection->removePlot( plotToDelete );
|
||||
delete plotToDelete;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimVfpPlot*> RimVfpDeck::plots() const
|
||||
{
|
||||
return m_vfpPlotCollection->plots();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpDeck::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName )
|
||||
{
|
||||
for ( auto p : m_vfpPlotCollection->plots() )
|
||||
{
|
||||
uiTreeOrdering.add( p );
|
||||
}
|
||||
|
||||
uiTreeOrdering.skipRemainingChildren( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpDeck::updateObjectName()
|
||||
{
|
||||
QString name = "VFP Deck";
|
||||
|
||||
if ( m_vfpTableData )
|
||||
{
|
||||
name = m_vfpTableData->name();
|
||||
}
|
||||
|
||||
setName( name );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimVfpDeck::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
if ( fieldNeedingOptions == &m_vfpTableData )
|
||||
{
|
||||
RimVfpDataCollection* vfpDataCollection = RimVfpDataCollection::instance();
|
||||
for ( auto table : vfpDataCollection->vfpTableData() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( table->name(), table ) );
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
@ -79,4 +79,20 @@ void caf::AppEnum<RimVfpDefines::FlowingGasFractionType>::setUp()
|
||||
addItem( RimVfpDefines::FlowingGasFractionType::INVALID, "INVALID", "Invalid" );
|
||||
setDefault( RimVfpDefines::FlowingGasFractionType::INVALID );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimVfpDefines::CurveMatchingType>::setUp()
|
||||
{
|
||||
addItem( RimVfpDefines::CurveMatchingType::EXACT, "EXACT", "Exact" );
|
||||
addItem( RimVfpDefines::CurveMatchingType::CLOSEST_MATCH_FAMILY, "CLOSEST_MATCH_FAMILY", "Family Closest Match" );
|
||||
setDefault( RimVfpDefines::CurveMatchingType::EXACT );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimVfpDefines::CurveOptionValuesType>::setUp()
|
||||
{
|
||||
addItem( RimVfpDefines::CurveOptionValuesType::MAIN_TABLE, "MAIN_TABLE", "Values from Main Table" );
|
||||
addItem( RimVfpDefines::CurveOptionValuesType::UNION_OF_SELECTED_TABLES, "UNION_OF_SELECTED_TABLES", "Union of Selected Table Values" );
|
||||
setDefault( RimVfpDefines::CurveOptionValuesType::MAIN_TABLE );
|
||||
}
|
||||
} // namespace caf
|
||||
|
@ -65,4 +65,17 @@ enum class FlowingGasFractionType
|
||||
OGR,
|
||||
INVALID
|
||||
};
|
||||
|
||||
enum class CurveMatchingType
|
||||
{
|
||||
EXACT,
|
||||
CLOSEST_MATCH_FAMILY,
|
||||
};
|
||||
|
||||
enum class CurveOptionValuesType
|
||||
{
|
||||
MAIN_TABLE,
|
||||
UNION_OF_SELECTED_TABLES,
|
||||
};
|
||||
|
||||
}; // namespace RimVfpDefines
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "RimProject.h"
|
||||
#include "RimVfpDataCollection.h"
|
||||
#include "RimVfpDefines.h"
|
||||
#include "RimVfpTable.h"
|
||||
#include "RimVfpTableData.h"
|
||||
#include "Tools/RimPlotAxisTools.h"
|
||||
|
||||
@ -72,7 +73,7 @@ RimVfpPlot::RimVfpPlot()
|
||||
CAF_PDM_InitFieldNoDefault( &m_filePath_OBSOLETE, "FilePath", "File Path" );
|
||||
m_filePath_OBSOLETE.xmlCapability()->setIOWritable( false );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_vfpTableData, "VfpTableData", "VFP Data Source" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_vfpTable, "VfpTableData", "VFP Data Source" );
|
||||
|
||||
caf::AppEnum<RimVfpDefines::TableType> defaultTableType = RimVfpDefines::TableType::INJECTION;
|
||||
CAF_PDM_InitField( &m_tableType, "TableType", defaultTableType, "Table Type" );
|
||||
@ -140,8 +141,6 @@ RimVfpPlot::RimVfpPlot()
|
||||
setAsPlotMdiWindow();
|
||||
|
||||
setDeletable( true );
|
||||
|
||||
m_vfpTables = std::make_unique<RigVfpTables>();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -156,9 +155,9 @@ RimVfpPlot::~RimVfpPlot()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpPlot::setDataSource( RimVfpTableData* vfpTableData )
|
||||
void RimVfpPlot::setDataSource( RimVfpTable* vfpTableData )
|
||||
{
|
||||
m_vfpTableData = vfpTableData;
|
||||
m_vfpTable = vfpTableData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -176,7 +175,7 @@ void RimVfpPlot::initializeObject()
|
||||
{
|
||||
if ( !vfpTables() ) return;
|
||||
|
||||
auto tableNumber = m_tableNumber();
|
||||
auto tableNumber = m_vfpTable->tableNumber();
|
||||
|
||||
// Always use the available table number if only one table is available
|
||||
auto prodTableNumbers = vfpTables()->productionTableNumbers();
|
||||
@ -284,9 +283,9 @@ QString RimVfpPlot::asciiDataForPlotExport() const
|
||||
|
||||
QString wellName;
|
||||
|
||||
if ( m_vfpTableData )
|
||||
if ( m_vfpTable )
|
||||
{
|
||||
wellName = m_vfpTableData->name();
|
||||
wellName = m_vfpTable->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -423,10 +422,10 @@ RiuPlotWidget* RimVfpPlot::doCreatePlotViewWidget( QWidget* mainWindowParent )
|
||||
auto wheelZoomer = new RiuQwtPlotWheelZoomer( qwtPlot );
|
||||
|
||||
// Use lambda functions to connect signals to functions instead of slots
|
||||
connect( wheelZoomer, &RiuQwtPlotWheelZoomer::zoomUpdated, [=]() { onPlotZoomed(); } );
|
||||
connect( plotZoomer, &RiuQwtPlotZoomer::zoomed, [=]() { onPlotZoomed(); } );
|
||||
connect( panner, &QwtPlotPanner::panned, [=]() { onPlotZoomed(); } );
|
||||
connect( qwtPlotWidget, &RiuQwtPlotWidget::plotZoomed, [=]() { onPlotZoomed(); } );
|
||||
connect( wheelZoomer, &RiuQwtPlotWheelZoomer::zoomUpdated, [=, this]() { onPlotZoomed(); } );
|
||||
connect( plotZoomer, &RiuQwtPlotZoomer::zoomed, [=, this]() { onPlotZoomed(); } );
|
||||
connect( panner, &QwtPlotPanner::panned, [=, this]() { onPlotZoomed(); } );
|
||||
connect( qwtPlotWidget, &RiuQwtPlotWidget::plotZoomed, [=, this]() { onPlotZoomed(); } );
|
||||
|
||||
// Remove event filter to disable unwanted highlighting on left click in plot.
|
||||
qwtPlotWidget->removeEventFilter();
|
||||
@ -479,7 +478,7 @@ void RimVfpPlot::onLoadDataAndUpdate()
|
||||
|
||||
if ( vfpTables() )
|
||||
{
|
||||
wellName = m_vfpTableData->baseFileName();
|
||||
wellName = vfpTableData()->baseFileName();
|
||||
|
||||
auto vfpPlotData = vfpTables()->populatePlotData( m_tableNumber(),
|
||||
m_primaryVariable(),
|
||||
@ -663,20 +662,25 @@ void RimVfpPlot::initializeFromInitData( const VfpTableInitialData& table )
|
||||
m_flowingWaterFraction = table.waterFraction;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpTableData* RimVfpPlot::vfpTableData() const
|
||||
{
|
||||
if ( m_vfpTable ) return m_vfpTable->dataSource();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RigVfpTables* RimVfpPlot::vfpTables() const
|
||||
{
|
||||
if ( m_vfpTableData )
|
||||
if ( vfpTableData() )
|
||||
{
|
||||
m_vfpTableData->ensureDataIsImported();
|
||||
return m_vfpTableData->vfpTables();
|
||||
}
|
||||
|
||||
if ( m_vfpTables )
|
||||
{
|
||||
return m_vfpTables.get();
|
||||
vfpTableData()->ensureDataIsImported();
|
||||
return vfpTableData()->vfpTables();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -739,7 +743,7 @@ QString RimVfpPlot::getDisplayUnit( RimVfpDefines::ProductionVariableType variab
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_vfpTableData );
|
||||
uiOrdering.add( &m_vfpTable );
|
||||
|
||||
uiOrdering.add( &m_tableType );
|
||||
uiOrdering.add( &m_tableNumber );
|
||||
@ -813,7 +817,7 @@ QList<caf::PdmOptionItemInfo> RimVfpPlot::calculateValueOptions( const caf::PdmF
|
||||
calculateTableValueOptions( RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO, options );
|
||||
}
|
||||
|
||||
else if ( fieldNeedingOptions == &m_vfpTableData )
|
||||
else if ( fieldNeedingOptions == &m_vfpTable )
|
||||
{
|
||||
RimVfpDataCollection* vfpDataCollection = RimVfpDataCollection::instance();
|
||||
for ( auto table : vfpDataCollection->vfpTableData() )
|
||||
@ -850,6 +854,11 @@ void RimVfpPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField, cons
|
||||
{
|
||||
RimPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
|
||||
if ( changedField == &m_vfpTable )
|
||||
{
|
||||
initializeObject();
|
||||
}
|
||||
|
||||
loadDataAndUpdate();
|
||||
updateLayout();
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ class RiuPlotWidget;
|
||||
class VfpPlotData;
|
||||
class RimPlotAxisProperties;
|
||||
class RigVfpTables;
|
||||
class RimVfpTable;
|
||||
class RimVfpTableData;
|
||||
|
||||
struct VfpTableSelection;
|
||||
@ -52,7 +53,7 @@ public:
|
||||
RimVfpPlot();
|
||||
~RimVfpPlot() override;
|
||||
|
||||
void setDataSource( RimVfpTableData* vfpTableData );
|
||||
void setDataSource( RimVfpTable* vfpTableData );
|
||||
void setTableNumber( int tableNumber );
|
||||
void initializeObject();
|
||||
|
||||
@ -94,8 +95,10 @@ private:
|
||||
void initAfterRead() override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
|
||||
VfpTableSelection tableSelection() const;
|
||||
void initializeFromInitData( const VfpTableInitialData& table );
|
||||
VfpTableSelection tableSelection() const;
|
||||
void initializeFromInitData( const VfpTableInitialData& table );
|
||||
|
||||
RimVfpTableData* vfpTableData() const;
|
||||
const RigVfpTables* vfpTables() const;
|
||||
|
||||
RiuPlotWidget* doCreatePlotViewWidget( QWidget* mainWindowParent ) override;
|
||||
@ -132,7 +135,7 @@ private:
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_plotTitle;
|
||||
caf::PdmPtrField<RimVfpTableData*> m_vfpTableData;
|
||||
caf::PdmPtrField<RimVfpTable*> m_vfpTable;
|
||||
caf::PdmField<int> m_tableNumber;
|
||||
caf::PdmField<double> m_referenceDepth;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::FlowingPhaseType>> m_flowingPhase;
|
||||
@ -157,8 +160,7 @@ private:
|
||||
|
||||
QPointer<RiuPlotWidget> m_plotWidget;
|
||||
|
||||
std::unique_ptr<RigVfpTables> m_vfpTables;
|
||||
caf::PdmField<caf::FilePath> m_filePath_OBSOLETE;
|
||||
caf::PdmField<caf::FilePath> m_filePath_OBSOLETE;
|
||||
|
||||
bool m_dataIsImportedExternally;
|
||||
};
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
#include "RimVfpPlotCollection.h"
|
||||
|
||||
#include "RimVfpDeck.h"
|
||||
#include "RimVfpTableData.h"
|
||||
#include "RimCustomVfpPlot.h"
|
||||
#include "RimVfpTable.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
|
||||
@ -33,51 +33,48 @@ RimVfpPlotCollection::RimVfpPlotCollection()
|
||||
CAF_PDM_InitObject( "VFP Plots", ":/VfpPlotCollection.svg" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_vfpPlots, "VfpPlots", "Vertical Flow Performance Plots" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_vfpDecks, "VfpDecks", "Vertical Flow Performance Decks" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_customVfpPlots, "CustomVfpPlots", "Vertical Flow Performance Plots" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpPlot* RimVfpPlotCollection::createAndAppendPlots( RimVfpTableData* tableData )
|
||||
RimVfpPlot* RimVfpPlotCollection::createAndAppendPlots( RimVfpTable* tableData )
|
||||
{
|
||||
if ( !tableData ) return nullptr;
|
||||
|
||||
tableData->ensureDataIsImported();
|
||||
|
||||
if ( !tableData->vfpTables() ) return nullptr;
|
||||
|
||||
RimVfpPlot* firstPlot = nullptr;
|
||||
|
||||
if ( tableData->tableCount() > 1 )
|
||||
{
|
||||
auto* deck = new RimVfpDeck();
|
||||
deck->setDataSource( tableData );
|
||||
addDeck( deck );
|
||||
deck->loadDataAndUpdate();
|
||||
deck->updateAllRequiredEditors();
|
||||
auto vfpPlot = new RimVfpPlot();
|
||||
vfpPlot->setDataSource( tableData );
|
||||
vfpPlot->initializeObject();
|
||||
|
||||
auto plots = deck->plots();
|
||||
if ( !plots.empty() )
|
||||
{
|
||||
firstPlot = plots.front();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto vfpPlot = new RimVfpPlot();
|
||||
vfpPlot->setDataSource( tableData );
|
||||
vfpPlot->initializeObject();
|
||||
addPlot( vfpPlot );
|
||||
vfpPlot->loadDataAndUpdate();
|
||||
|
||||
addPlot( vfpPlot );
|
||||
vfpPlot->loadDataAndUpdate();
|
||||
|
||||
firstPlot = vfpPlot;
|
||||
}
|
||||
firstPlot = vfpPlot;
|
||||
|
||||
return firstPlot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCustomVfpPlot* RimVfpPlotCollection::createAndAppendPlots( RimVfpTable* mainDataSource, std::vector<RimVfpTable*> tableData )
|
||||
{
|
||||
auto vfpPlot = new RimCustomVfpPlot();
|
||||
vfpPlot->selectDataSource( mainDataSource, tableData );
|
||||
vfpPlot->initializeObject();
|
||||
|
||||
m_customVfpPlots.push_back( vfpPlot );
|
||||
|
||||
vfpPlot->loadDataAndUpdate();
|
||||
|
||||
return vfpPlot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -135,21 +132,13 @@ void RimVfpPlotCollection::removePlot( RimVfpPlot* vfpPlot )
|
||||
updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpPlotCollection::addDeck( RimVfpDeck* deck )
|
||||
{
|
||||
m_vfpDecks.push_back( deck );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpPlotCollection::deleteAllPlots()
|
||||
{
|
||||
m_vfpPlots.deleteChildren();
|
||||
m_vfpDecks.deleteChildren();
|
||||
m_customVfpPlots.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -185,9 +174,9 @@ void RimVfpPlotCollection::loadDataAndUpdateAllPlots()
|
||||
plot->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
for ( auto deck : m_vfpDecks.childrenByType() )
|
||||
for ( auto customPlot : m_customVfpPlots.childrenByType() )
|
||||
{
|
||||
deck->loadDataAndUpdate();
|
||||
customPlot->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
class RimVfpDeck;
|
||||
class RimCustomVfpPlot;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -36,8 +36,9 @@ class RimVfpPlotCollection : public caf::PdmObject, public RimTypedPlotCollectio
|
||||
public:
|
||||
RimVfpPlotCollection();
|
||||
|
||||
RimVfpPlot* createAndAppendPlots( RimVfpTableData* tableData );
|
||||
RimVfpPlot* plotForTableNumber( int tableNumber ) const;
|
||||
RimVfpPlot* createAndAppendPlots( RimVfpTable* tableData );
|
||||
RimVfpPlot* plotForTableNumber( int tableNumber ) const;
|
||||
RimCustomVfpPlot* createAndAppendPlots( RimVfpTable* mainDataSource, std::vector<RimVfpTable*> tableData );
|
||||
|
||||
void addPlot( RimVfpPlot* newPlot ) override;
|
||||
std::vector<RimVfpPlot*> plots() const override;
|
||||
@ -55,9 +56,7 @@ private:
|
||||
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
||||
void addDeck( RimVfpDeck* deck );
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimVfpPlot*> m_vfpPlots;
|
||||
caf::PdmChildArrayField<RimVfpDeck*> m_vfpDecks;
|
||||
caf::PdmChildArrayField<RimVfpPlot*> m_vfpPlots;
|
||||
caf::PdmChildArrayField<RimCustomVfpPlot*> m_customVfpPlots;
|
||||
};
|
||||
|
@ -0,0 +1,146 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024 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 "RimVfpTable.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimVfpTable, "RimVfpTable" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpTable::RimVfpTable()
|
||||
{
|
||||
CAF_PDM_InitObject( "VFP Table", ":/VfpPlot.svg" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_dataSource, "DataSource", "Data Source" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_tableNumber, "TableNumber", "Table Number" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_tableType, "TableType", "Table Type" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpTable::setDataSource( RimVfpTableData* dataSource )
|
||||
{
|
||||
m_dataSource = dataSource;
|
||||
|
||||
updateObjectName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpTable::setTableNumber( int tableNumber )
|
||||
{
|
||||
m_tableNumber = tableNumber;
|
||||
|
||||
updateObjectName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpTable::setTableType( RimVfpDefines::TableType tableType )
|
||||
{
|
||||
m_tableType = tableType;
|
||||
|
||||
updateObjectName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpTable::ensureDataIsImported()
|
||||
{
|
||||
if ( m_dataSource )
|
||||
{
|
||||
m_dataSource->ensureDataIsImported();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpTableData* RimVfpTable::dataSource() const
|
||||
{
|
||||
return m_dataSource;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimVfpTable::tableNumber() const
|
||||
{
|
||||
return m_tableNumber;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimVfpDefines::TableType RimVfpTable::tableType() const
|
||||
{
|
||||
return m_tableType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpTable::updateObjectName()
|
||||
{
|
||||
if ( m_dataSource )
|
||||
{
|
||||
QString name;
|
||||
|
||||
if ( m_tableNumber >= 0 )
|
||||
{
|
||||
if ( !name.isEmpty() ) name += " - ";
|
||||
name += QString( "Table %1" ).arg( m_tableNumber );
|
||||
}
|
||||
|
||||
if ( m_tableType() == RimVfpDefines::TableType::INJECTION )
|
||||
{
|
||||
if ( !name.isEmpty() ) name += " - ";
|
||||
name += QString( "INJ" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !name.isEmpty() ) name += " - ";
|
||||
name += QString( "PROD" );
|
||||
}
|
||||
|
||||
if ( !name.isEmpty() ) name += " - ";
|
||||
name += m_dataSource->name();
|
||||
|
||||
setName( name );
|
||||
}
|
||||
else
|
||||
{
|
||||
setName( "VFP Table" );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimVfpTable::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
||||
{
|
||||
menuBuilder << "RicNewVfpPlotFeature";
|
||||
menuBuilder << "RicNewCustomVfpPlotFeature";
|
||||
}
|
@ -20,34 +20,39 @@
|
||||
|
||||
#include "RimNamedObject.h"
|
||||
|
||||
#include "cafFilePath.h"
|
||||
#include "RimVfpDefines.h"
|
||||
#include "RimVfpTableData.h"
|
||||
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimVfpPlotCollection;
|
||||
class RimVfpTableData;
|
||||
class RimVfpPlot;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// RimVfpDeck parses a deck file (*.DATA) containing VFP data and creates a collection of VFP plots.
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RimVfpDeck : public RimNamedObject
|
||||
class RimVfpTable : public RimNamedObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimVfpDeck();
|
||||
RimVfpTable();
|
||||
|
||||
void setDataSource( RimVfpTableData* tableData );
|
||||
void loadDataAndUpdate();
|
||||
RimVfpTableData* dataSource() const;
|
||||
int tableNumber() const;
|
||||
RimVfpDefines::TableType tableType() const;
|
||||
|
||||
std::vector<RimVfpPlot*> plots() const;
|
||||
void setDataSource( RimVfpTableData* dataSource );
|
||||
void setTableNumber( int tableNumber );
|
||||
void setTableType( RimVfpDefines::TableType tableType );
|
||||
|
||||
void ensureDataIsImported();
|
||||
|
||||
private:
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
void updateObjectName();
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
void updateObjectName();
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimVfpTableData*> m_vfpTableData;
|
||||
caf::PdmChildField<RimVfpPlotCollection*> m_vfpPlotCollection;
|
||||
caf::PdmPtrField<RimVfpTableData*> m_dataSource;
|
||||
caf::PdmField<int> m_tableNumber;
|
||||
caf::PdmField<caf::AppEnum<RimVfpDefines::TableType>> m_tableType;
|
||||
};
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "RigVfpTables.h"
|
||||
|
||||
#include "RimVfpTable.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
@ -36,6 +38,8 @@ RimVfpTableData::RimVfpTableData()
|
||||
CAF_PDM_InitObject( "VFP Plot", ":/VfpPlot.svg" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_filePath, "FilePath", "File Path" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_tables, "Tables", "Tables" );
|
||||
m_tables.xmlCapability()->disableIO();
|
||||
|
||||
setDeletable( true );
|
||||
}
|
||||
@ -66,20 +70,42 @@ void RimVfpTableData::ensureDataIsImported()
|
||||
|
||||
updateObjectName();
|
||||
|
||||
m_tables.deleteChildren();
|
||||
|
||||
m_vfpTables = std::make_unique<RigVfpTables>();
|
||||
|
||||
const auto [vfpProdTables, vfpInjTables] = RiaOpmParserTools::extractVfpTablesFromDataFile( m_filePath().path().toStdString() );
|
||||
for ( const auto& prod : vfpProdTables )
|
||||
{
|
||||
m_vfpTables->addProductionTable( prod );
|
||||
|
||||
auto table = new RimVfpTable;
|
||||
table->setDataSource( this );
|
||||
table->setTableNumber( prod.getTableNum() );
|
||||
table->setTableType( RimVfpDefines::TableType::PRODUCTION );
|
||||
m_tables.push_back( table );
|
||||
}
|
||||
|
||||
for ( const auto& inj : vfpInjTables )
|
||||
{
|
||||
m_vfpTables->addInjectionTable( inj );
|
||||
|
||||
auto table = new RimVfpTable;
|
||||
table->setDataSource( this );
|
||||
table->setTableNumber( inj.getTableNum() );
|
||||
table->setTableType( RimVfpDefines::TableType::INJECTION );
|
||||
m_tables.push_back( table );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimVfpTable*> RimVfpTableData::tableDataSources() const
|
||||
{
|
||||
return m_tables.childrenByType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -123,4 +149,5 @@ void RimVfpTableData::updateObjectName()
|
||||
void RimVfpTableData::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
||||
{
|
||||
menuBuilder << "RicNewVfpPlotFeature";
|
||||
menuBuilder << "RicNewCustomVfpPlotFeature";
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <memory>
|
||||
|
||||
class RigVfpTables;
|
||||
class RimVfpTable;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@ -40,6 +41,8 @@ public:
|
||||
QString baseFileName();
|
||||
void ensureDataIsImported();
|
||||
|
||||
std::vector<RimVfpTable*> tableDataSources() const;
|
||||
|
||||
size_t tableCount() const;
|
||||
|
||||
const RigVfpTables* vfpTables() const;
|
||||
@ -49,7 +52,8 @@ private:
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
||||
private:
|
||||
caf::PdmField<caf::FilePath> m_filePath;
|
||||
caf::PdmField<caf::FilePath> m_filePath;
|
||||
caf::PdmChildArrayField<RimVfpTable*> m_tables;
|
||||
|
||||
std::unique_ptr<RigVfpTables> m_vfpTables;
|
||||
};
|
||||
|
@ -173,6 +173,130 @@ VfpPlotData RigVfpTables::populatePlotData( int
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VfpPlotData RigVfpTables::populatePlotData( int tableIndex,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpValueSelection& valueSelection ) const
|
||||
{
|
||||
auto prodTable = productionTable( tableIndex );
|
||||
if ( prodTable.has_value() )
|
||||
{
|
||||
return populatePlotData( *prodTable, primaryVariable, familyVariable, interpolatedVariable, flowingPhase, valueSelection );
|
||||
}
|
||||
|
||||
auto injContainer = injectionTable( tableIndex );
|
||||
if ( injContainer.has_value() )
|
||||
{
|
||||
return populatePlotData( *injContainer, interpolatedVariable, flowingPhase );
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
VfpPlotData RigVfpTables::populatePlotData( const Opm::VFPProdTable& table,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpValueSelection& valueSelection )
|
||||
{
|
||||
VfpPlotData plotData;
|
||||
|
||||
QString xAxisTitle = axisTitle( primaryVariable, flowingPhase );
|
||||
plotData.setXAxisTitle( xAxisTitle );
|
||||
|
||||
QString yAxisTitle = QString( "%1 %2" ).arg( caf::AppEnum<RimVfpDefines::InterpolatedVariableType>::uiText( interpolatedVariable ),
|
||||
getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType::THP ) );
|
||||
plotData.setYAxisTitle( yAxisTitle );
|
||||
|
||||
std::vector<double> familyFilterValues = valueSelection.familyValues;
|
||||
|
||||
size_t numFamilyValues = getProductionTableData( table, familyVariable ).size();
|
||||
for ( size_t familyIdx = 0; familyIdx < numFamilyValues; familyIdx++ )
|
||||
{
|
||||
std::vector<double> primaryAxisValues = getProductionTableData( table, primaryVariable );
|
||||
std::vector<double> familyVariableValues = getProductionTableData( table, familyVariable );
|
||||
std::vector<double> thpValues = getProductionTableData( table, RimVfpDefines::ProductionVariableType::THP );
|
||||
|
||||
// Skip if the family value is not in the filter
|
||||
auto currentFamilyValue = familyVariableValues[familyIdx];
|
||||
auto it = std::find( familyFilterValues.begin(), familyFilterValues.end(), currentFamilyValue );
|
||||
if ( it == familyFilterValues.end() ) continue;
|
||||
|
||||
size_t numValues = primaryAxisValues.size();
|
||||
std::vector<double> yVals( numValues, 0.0 );
|
||||
|
||||
for ( size_t y = 0; y < numValues; y++ )
|
||||
{
|
||||
auto currentPrimaryValue = primaryAxisValues[y];
|
||||
|
||||
size_t wfr_idx = getVariableIndexForValue( table,
|
||||
RimVfpDefines::ProductionVariableType::WATER_CUT,
|
||||
primaryVariable,
|
||||
currentPrimaryValue,
|
||||
familyVariable,
|
||||
currentFamilyValue,
|
||||
valueSelection );
|
||||
size_t gfr_idx = getVariableIndexForValue( table,
|
||||
RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO,
|
||||
primaryVariable,
|
||||
currentPrimaryValue,
|
||||
familyVariable,
|
||||
currentFamilyValue,
|
||||
valueSelection );
|
||||
size_t alq_idx = getVariableIndexForValue( table,
|
||||
RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY,
|
||||
primaryVariable,
|
||||
currentPrimaryValue,
|
||||
familyVariable,
|
||||
currentFamilyValue,
|
||||
valueSelection );
|
||||
size_t flo_idx = getVariableIndexForValue( table,
|
||||
RimVfpDefines::ProductionVariableType::FLOW_RATE,
|
||||
primaryVariable,
|
||||
currentPrimaryValue,
|
||||
familyVariable,
|
||||
currentFamilyValue,
|
||||
valueSelection );
|
||||
size_t thp_idx = getVariableIndexForValue( table,
|
||||
RimVfpDefines::ProductionVariableType::THP,
|
||||
primaryVariable,
|
||||
currentPrimaryValue,
|
||||
familyVariable,
|
||||
currentFamilyValue,
|
||||
valueSelection );
|
||||
|
||||
yVals[y] = table( thp_idx, wfr_idx, gfr_idx, alq_idx, flo_idx );
|
||||
if ( interpolatedVariable == RimVfpDefines::InterpolatedVariableType::BHP_THP_DIFF )
|
||||
{
|
||||
yVals[y] -= thpValues[thp_idx];
|
||||
}
|
||||
}
|
||||
|
||||
double familyValue = convertToDisplayUnit( currentFamilyValue, familyVariable );
|
||||
QString familyUnit = getDisplayUnit( familyVariable );
|
||||
QString familyTitle = QString( "%1: %2 %3" )
|
||||
.arg( caf::AppEnum<RimVfpDefines::ProductionVariableType>::uiText( familyVariable ) )
|
||||
.arg( familyValue )
|
||||
.arg( familyUnit );
|
||||
|
||||
convertToDisplayUnit( yVals, RimVfpDefines::ProductionVariableType::THP );
|
||||
convertToDisplayUnit( primaryAxisValues, primaryVariable );
|
||||
|
||||
plotData.appendCurve( familyTitle, primaryAxisValues, yVals );
|
||||
}
|
||||
|
||||
return plotData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -201,6 +325,89 @@ QString RigVfpTables::asciiDataForTable( int
|
||||
return textForPlotData( plotData );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> RigVfpTables::findClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch )
|
||||
{
|
||||
std::vector<int> result( sourceValues.size(), -1 );
|
||||
|
||||
// Returns the indices of the closest values in valuesToMatch for each value in sourceValues.
|
||||
for ( size_t i = 0; i < sourceValues.size(); ++i )
|
||||
{
|
||||
double minDistance = std::numeric_limits<double>::max();
|
||||
int closestIndex = -1;
|
||||
|
||||
for ( size_t j = 0; j < valuesToMatch.size(); ++j )
|
||||
{
|
||||
double distance = std::abs( sourceValues[i] - valuesToMatch[j] );
|
||||
if ( distance < minDistance )
|
||||
{
|
||||
minDistance = distance;
|
||||
closestIndex = static_cast<int>( j );
|
||||
}
|
||||
}
|
||||
|
||||
if ( closestIndex < static_cast<int>( valuesToMatch.size() ) )
|
||||
{
|
||||
result[i] = closestIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> RigVfpTables::uniqueClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch )
|
||||
{
|
||||
// Find the closest value in valuesForMatch for each value in sourceValues
|
||||
std::vector<double> distances( sourceValues.size(), std::numeric_limits<double>::max() );
|
||||
|
||||
auto closestIndices = findClosestIndices( sourceValues, valuesToMatch );
|
||||
|
||||
for ( size_t i = 0; i < sourceValues.size(); i++ )
|
||||
{
|
||||
if ( closestIndices[i] >= 0 )
|
||||
{
|
||||
distances[i] = std::abs( sourceValues[i] - valuesToMatch[closestIndices[i]] );
|
||||
}
|
||||
}
|
||||
|
||||
while ( std::any_of( distances.begin(), distances.end(), []( double val ) { return val != std::numeric_limits<double>::max(); } ) )
|
||||
{
|
||||
// find the index of the smallest value in minDistance
|
||||
auto minDistanceIt = std::min_element( distances.begin(), distances.end() );
|
||||
if ( minDistanceIt == distances.end() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
auto minDistanceIndex = std::distance( distances.begin(), minDistanceIt );
|
||||
auto matchingIndex = closestIndices[minDistanceIndex];
|
||||
|
||||
if ( matchingIndex > -1 )
|
||||
{
|
||||
// Remove all references to the matching index
|
||||
for ( size_t i = 0; i < sourceValues.size(); i++ )
|
||||
{
|
||||
if ( i == static_cast<size_t>( minDistanceIndex ) )
|
||||
{
|
||||
distances[i] = std::numeric_limits<double>::max();
|
||||
}
|
||||
else if ( closestIndices[i] == matchingIndex )
|
||||
{
|
||||
distances[i] = std::numeric_limits<double>::max();
|
||||
closestIndices[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestIndices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -385,6 +592,90 @@ size_t RigVfpTables::getVariableIndex( const Opm::VFPProdTable& tab
|
||||
return getProductionTableData( table, targetVariable ).size() - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigVfpTables::getVariableIndexForValue( const Opm::VFPProdTable& table,
|
||||
RimVfpDefines::ProductionVariableType targetVariable,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
double primaryValue,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
double familyValue,
|
||||
const VfpValueSelection& valueSelection )
|
||||
{
|
||||
auto findClosestIndex = []( const std::vector<double>& values, const double value )
|
||||
{
|
||||
auto it = std::lower_bound( values.begin(), values.end(), value );
|
||||
if ( it == values.begin() )
|
||||
{
|
||||
return (size_t)0;
|
||||
}
|
||||
if ( it == values.end() )
|
||||
{
|
||||
return values.size() - 1;
|
||||
}
|
||||
if ( *it == value )
|
||||
{
|
||||
return (size_t)std::distance( values.begin(), it );
|
||||
}
|
||||
|
||||
auto prev = it - 1;
|
||||
if ( std::abs( *prev - value ) < std::abs( *it - value ) )
|
||||
{
|
||||
return (size_t)std::distance( values.begin(), prev );
|
||||
}
|
||||
|
||||
return (size_t)std::distance( values.begin(), it );
|
||||
};
|
||||
|
||||
if ( targetVariable == primaryVariable )
|
||||
{
|
||||
const auto values = getProductionTableData( table, targetVariable );
|
||||
return findClosestIndex( values, primaryValue );
|
||||
}
|
||||
|
||||
if ( targetVariable == familyVariable )
|
||||
{
|
||||
const auto values = getProductionTableData( table, targetVariable );
|
||||
return findClosestIndex( values, familyValue );
|
||||
}
|
||||
|
||||
auto findClosestIndexForVariable =
|
||||
[&]( RimVfpDefines::ProductionVariableType targetVariable, const double selectedValue, const Opm::VFPProdTable& table )
|
||||
{
|
||||
const auto values = getProductionTableData( table, targetVariable );
|
||||
return findClosestIndex( values, selectedValue );
|
||||
};
|
||||
|
||||
switch ( targetVariable )
|
||||
{
|
||||
case RimVfpDefines::ProductionVariableType::WATER_CUT:
|
||||
{
|
||||
return findClosestIndexForVariable( targetVariable, valueSelection.waterCutValue, table );
|
||||
}
|
||||
case RimVfpDefines::ProductionVariableType::GAS_LIQUID_RATIO:
|
||||
{
|
||||
return findClosestIndexForVariable( targetVariable, valueSelection.gasLiquidRatioValue, table );
|
||||
}
|
||||
case RimVfpDefines::ProductionVariableType::ARTIFICIAL_LIFT_QUANTITY:
|
||||
{
|
||||
return findClosestIndexForVariable( targetVariable, valueSelection.articifialLiftQuantityValue, table );
|
||||
}
|
||||
case RimVfpDefines::ProductionVariableType::FLOW_RATE:
|
||||
{
|
||||
return findClosestIndexForVariable( targetVariable, valueSelection.flowRateValue, table );
|
||||
}
|
||||
case RimVfpDefines::ProductionVariableType::THP:
|
||||
{
|
||||
return findClosestIndexForVariable( targetVariable, valueSelection.thpValue, table );
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -73,6 +73,17 @@ struct VfpTableSelection
|
||||
int gasLiquidRatioIdx;
|
||||
};
|
||||
|
||||
struct VfpValueSelection
|
||||
{
|
||||
double flowRateValue;
|
||||
double thpValue;
|
||||
double articifialLiftQuantityValue;
|
||||
double waterCutValue;
|
||||
double gasLiquidRatioValue;
|
||||
|
||||
std::vector<double> familyValues;
|
||||
};
|
||||
|
||||
struct VfpTableInitialData
|
||||
{
|
||||
bool isProductionTable;
|
||||
@ -106,6 +117,13 @@ public:
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpTableSelection& tableSelection ) const;
|
||||
|
||||
VfpPlotData populatePlotData( int tableIndex,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpValueSelection& valueSelection ) const;
|
||||
|
||||
QString asciiDataForTable( int tableNumber,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
@ -113,6 +131,10 @@ public:
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpTableSelection& tableSelection ) const;
|
||||
|
||||
// Returns the indices of the closest values in valuesToMatch for each value in sourceValues. Returned index value -1 indicates no
|
||||
// match. A index value is only returned once.
|
||||
static std::vector<int> uniqueClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch );
|
||||
|
||||
private:
|
||||
static VfpPlotData populatePlotData( const Opm::VFPInjTable& table,
|
||||
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
||||
@ -125,6 +147,13 @@ private:
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpTableSelection& tableSelection );
|
||||
|
||||
static VfpPlotData populatePlotData( const Opm::VFPProdTable& table,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
RimVfpDefines::InterpolatedVariableType interpolatedVariable,
|
||||
RimVfpDefines::FlowingPhaseType flowingPhase,
|
||||
const VfpValueSelection& valueSelection );
|
||||
|
||||
static QString axisTitle( RimVfpDefines::ProductionVariableType variableType, RimVfpDefines::FlowingPhaseType flowingPhase );
|
||||
static QString getDisplayUnit( RimVfpDefines::ProductionVariableType variableType );
|
||||
static QString getDisplayUnitWithBracket( RimVfpDefines::ProductionVariableType variableType );
|
||||
@ -143,6 +172,14 @@ private:
|
||||
size_t familyValue,
|
||||
const VfpTableSelection& tableSelection );
|
||||
|
||||
static size_t getVariableIndexForValue( const Opm::VFPProdTable& table,
|
||||
RimVfpDefines::ProductionVariableType targetVariable,
|
||||
RimVfpDefines::ProductionVariableType primaryVariable,
|
||||
double primaryValue,
|
||||
RimVfpDefines::ProductionVariableType familyVariable,
|
||||
double familyValue,
|
||||
const VfpValueSelection& valueSelection );
|
||||
|
||||
std::optional<Opm::VFPInjTable> injectionTable( int tableNumber ) const;
|
||||
std::optional<Opm::VFPProdTable> productionTable( int tableNumber ) const;
|
||||
|
||||
@ -151,6 +188,9 @@ private:
|
||||
static RimVfpDefines::FlowingWaterFractionType getFlowingWaterFractionType( const Opm::VFPProdTable& table );
|
||||
static RimVfpDefines::FlowingGasFractionType getFlowingGasFractionType( const Opm::VFPProdTable& table );
|
||||
|
||||
// Returns the indices of the closest values in valuesToMatch for each value in sourceValues. Returned index value -1 indicates no match.
|
||||
static std::vector<int> findClosestIndices( const std::vector<double>& sourceValues, const std::vector<double>& valuesToMatch );
|
||||
|
||||
private:
|
||||
std::vector<Opm::VFPInjTable> m_injectionTables;
|
||||
std::vector<Opm::VFPProdTable> m_productionTables;
|
||||
|
@ -104,6 +104,7 @@ set(SOURCE_UNITTEST_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifPolygonReader-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifParquetReader-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifOsduWellPathReader-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigVfpTables-Test.cpp
|
||||
)
|
||||
|
||||
if(RESINSIGHT_ENABLE_GRPC)
|
||||
|
83
ApplicationLibCode/UnitTests/RigVfpTables-Test.cpp
Normal file
83
ApplicationLibCode/UnitTests/RigVfpTables-Test.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2024- 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 "gtest/gtest.h"
|
||||
|
||||
#include "RigVfpTables.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigVfpTables, MatchingValues )
|
||||
{
|
||||
std::vector<double> sourceValues = { 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||
std::vector<double> valuesForMatch = { 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||
std::vector<int> closestIndices = RigVfpTables::uniqueClosestIndices( sourceValues, valuesForMatch );
|
||||
for ( int i = 0; i < sourceValues.size(); i++ )
|
||||
{
|
||||
EXPECT_EQ( i, closestIndices[i] );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigVfpTables, MoreDestinationValues )
|
||||
{
|
||||
std::vector<double> sourceValues = { 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||
std::vector<double> valuesForMatch = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
|
||||
std::vector<int> closestIndices = RigVfpTables::uniqueClosestIndices( sourceValues, valuesForMatch );
|
||||
for ( int i = 0; i < sourceValues.size(); i++ )
|
||||
{
|
||||
EXPECT_EQ( i, closestIndices[i] );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigVfpTables, MatchInBetweenValues )
|
||||
{
|
||||
std::vector<double> sourceValues = { 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||
std::vector<double> valuesForMatch = { 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0 };
|
||||
std::vector<int> closestIndices = RigVfpTables::uniqueClosestIndices( sourceValues, valuesForMatch );
|
||||
|
||||
EXPECT_EQ( 5, (int)closestIndices.size() );
|
||||
|
||||
EXPECT_EQ( 0, closestIndices[0] );
|
||||
EXPECT_EQ( 2, closestIndices[1] );
|
||||
EXPECT_EQ( 3, closestIndices[2] );
|
||||
EXPECT_EQ( 4, closestIndices[3] );
|
||||
EXPECT_EQ( 5, closestIndices[4] );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigVfpTables, SingleValue )
|
||||
{
|
||||
std::vector<double> sourceValues = { 1.0, 2.0, 3.0 };
|
||||
std::vector<double> valuesForMatch = { 2.1 };
|
||||
std::vector<int> closestIndices = RigVfpTables::uniqueClosestIndices( sourceValues, valuesForMatch );
|
||||
|
||||
EXPECT_EQ( 3, (int)closestIndices.size() );
|
||||
|
||||
EXPECT_EQ( -1, closestIndices[0] );
|
||||
EXPECT_EQ( 0, closestIndices[1] );
|
||||
EXPECT_EQ( -1, closestIndices[2] );
|
||||
}
|
@ -39,10 +39,7 @@ class PdmPtrField<DataType*> : public PdmValueField
|
||||
public:
|
||||
typedef PdmPointer<DataType> FieldDataType;
|
||||
|
||||
PdmPtrField()
|
||||
: m_isResolved( false )
|
||||
{
|
||||
}
|
||||
PdmPtrField() {}
|
||||
explicit PdmPtrField( const DataTypePtr& fieldValue );
|
||||
~PdmPtrField() override;
|
||||
|
||||
@ -81,7 +78,6 @@ private:
|
||||
|
||||
// Resolving
|
||||
QString m_referenceString;
|
||||
bool m_isResolved;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
@ -29,7 +29,6 @@ void caf::PdmPtrField<DataType*>::setFromQVariant( const QVariant& variant )
|
||||
template <typename DataType>
|
||||
caf::PdmPtrField<DataType*>::PdmPtrField( const DataTypePtr& fieldValue )
|
||||
{
|
||||
m_isResolved = true;
|
||||
m_fieldValue = fieldValue;
|
||||
if ( m_fieldValue != NULL ) m_fieldValue->addReferencingPtrField( this );
|
||||
}
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
{
|
||||
m_field = field;
|
||||
m_dataTypeName = DataType::classKeywordStatic();
|
||||
m_isResolved = false;
|
||||
m_referenceString = "";
|
||||
}
|
||||
|
||||
@ -70,7 +69,6 @@ private:
|
||||
|
||||
// Resolving
|
||||
QString m_referenceString;
|
||||
bool m_isResolved;
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
@ -87,7 +85,6 @@ public:
|
||||
{
|
||||
m_field = field;
|
||||
m_dataTypeName = DataType::classKeywordStatic();
|
||||
m_isResolved = false;
|
||||
m_referenceString = "";
|
||||
}
|
||||
|
||||
@ -103,7 +100,6 @@ private:
|
||||
|
||||
// Resolving
|
||||
QString m_referenceString;
|
||||
bool m_isResolved;
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
|
@ -90,7 +90,6 @@ void caf::PdmFieldXmlCap<caf::PdmPtrField<DataType*>>::readFieldData( QXmlStream
|
||||
//
|
||||
// and then we need a traversal of the object hierarchy to resolve all references before initAfterRead.
|
||||
|
||||
m_isResolved = false;
|
||||
m_referenceString = dataString;
|
||||
m_field->setRawPtr( NULL );
|
||||
}
|
||||
@ -117,12 +116,11 @@ void caf::PdmFieldXmlCap<caf::PdmPtrField<DataType*>>::writeFieldData( QXmlStrea
|
||||
template <typename DataType>
|
||||
bool caf::PdmFieldXmlCap<PdmPtrField<DataType*>>::resolveReferences()
|
||||
{
|
||||
if ( m_isResolved ) return true;
|
||||
if ( m_field->m_fieldValue.rawPtr() != nullptr ) return true;
|
||||
if ( m_referenceString.isEmpty() ) return true;
|
||||
|
||||
PdmObjectHandle* objHandle = PdmReferenceHelper::objectFromFieldReference( this->fieldHandle(), m_referenceString );
|
||||
m_field->setRawPtr( objHandle );
|
||||
m_isResolved = true;
|
||||
|
||||
return objHandle != nullptr;
|
||||
}
|
||||
@ -163,7 +161,6 @@ void caf::PdmFieldXmlCap<caf::PdmPtrArrayField<DataType*>>::readFieldData( QXmlS
|
||||
// It must be done when we know that the complete hierarchy is read and created,
|
||||
// and then we need a traversal of the object hierarchy to resolve all references before initAfterRead.
|
||||
|
||||
m_isResolved = false;
|
||||
m_referenceString = dataString;
|
||||
m_field->clearWithoutDelete();
|
||||
}
|
||||
@ -193,7 +190,6 @@ void caf::PdmFieldXmlCap<caf::PdmPtrArrayField<DataType*>>::writeFieldData( QXml
|
||||
template <typename DataType>
|
||||
bool caf::PdmFieldXmlCap<PdmPtrArrayField<DataType*>>::resolveReferences()
|
||||
{
|
||||
if ( m_isResolved ) return true;
|
||||
if ( m_referenceString.isEmpty() ) return true;
|
||||
m_field->clearWithoutDelete();
|
||||
|
||||
@ -211,8 +207,6 @@ bool caf::PdmFieldXmlCap<PdmPtrArrayField<DataType*>>::resolveReferences()
|
||||
m_field->m_pointers.back().setRawPtr( objHandle );
|
||||
}
|
||||
|
||||
m_isResolved = true;
|
||||
|
||||
return foundValidObjectFromString;
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,11 @@ TEST( AdvancedObjectTest, FieldWrite )
|
||||
|
||||
a->readObjectFromXmlString( serializedString, caf::PdmDefaultObjectFactory::instance() );
|
||||
a->xmlCapability()->resolveReferencesRecursively();
|
||||
ASSERT_TRUE( a->m_pointerToItem() == container->m_items[1] );
|
||||
|
||||
// Set pointer to null. The reference string is still valid, and the resolving will restore the pointer.
|
||||
a->m_pointerToItem = nullptr;
|
||||
a->xmlCapability()->resolveReferencesRecursively();
|
||||
ASSERT_TRUE( a->m_pointerToItem() == container->m_items[1] );
|
||||
}
|
||||
}
|
||||
|
@ -551,11 +551,18 @@ void PdmUiTreeSelectionEditor::slotToggleAll()
|
||||
{
|
||||
if ( m_toggleAllCheckBox->isChecked() )
|
||||
{
|
||||
checkAllItems();
|
||||
checkAllItemsMatchingFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
unCheckAllItems();
|
||||
if ( m_textFilterLineEdit->text().isEmpty() )
|
||||
{
|
||||
m_model->unselectAllItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
unCheckAllItemsMatchingFilter();
|
||||
}
|
||||
|
||||
// Apply integer filtering if the model contains only integers
|
||||
if ( hasOnlyIntegers( m_model ) )
|
||||
@ -788,7 +795,7 @@ void PdmUiTreeSelectionEditor::currentChanged( const QModelIndex& current )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::checkAllItems()
|
||||
void PdmUiTreeSelectionEditor::checkAllItemsMatchingFilter()
|
||||
{
|
||||
QModelIndexList indices = allVisibleSourceModelIndices();
|
||||
|
||||
@ -798,7 +805,7 @@ void PdmUiTreeSelectionEditor::checkAllItems()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::unCheckAllItems()
|
||||
void PdmUiTreeSelectionEditor::unCheckAllItemsMatchingFilter()
|
||||
{
|
||||
QModelIndexList indices = allVisibleSourceModelIndices();
|
||||
|
||||
|
@ -127,8 +127,8 @@ private:
|
||||
|
||||
void setCheckedStateOfSelected( bool checked );
|
||||
void setCheckedStateForSubItemsOfSelected( bool checked );
|
||||
void checkAllItems();
|
||||
void unCheckAllItems();
|
||||
void checkAllItemsMatchingFilter();
|
||||
void unCheckAllItemsMatchingFilter();
|
||||
void setCheckedStateForIntegerItemsMatchingFilter();
|
||||
|
||||
QModelIndexList allVisibleSourceModelIndices() const;
|
||||
|
@ -173,6 +173,14 @@ void caf::PdmUiTreeSelectionQModel::invertCheckedStateForItems( const QModelInde
|
||||
PdmUiCommandSystemProxy::instance()->setUiValueToField( m_uiFieldHandle->uiField(), fieldValueSelection );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void caf::PdmUiTreeSelectionQModel::unselectAllItems()
|
||||
{
|
||||
PdmUiCommandSystemProxy::instance()->setUiValueToField( m_uiFieldHandle->uiField(), {} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
|
||||
void setCheckedStateForItems( const QModelIndexList& indices, bool checked );
|
||||
void invertCheckedStateForItems( const QModelIndexList& indices );
|
||||
void unselectAllItems();
|
||||
|
||||
void enableSingleSelectionMode( bool enable );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user