From 4b3ebd2a95e5f4d0c85a7400e026b60c2d358efa Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 19 Jan 2026 20:00:21 +0100 Subject: [PATCH] Add MSW segment support to well path completions/collection Introduce MSW segment collection to RimWellPathCompletions, including UI tree integration and completion list updates. Add MSW Eclipse case and show bands fields to RimWellPathCollection, with new UI controls and update logic. Implement segment update and visualization methods, option calculation for Eclipse case selection, and update headers and includes accordingly. --- .../Completions/RimWellPathCompletions.cpp | 34 +++++++++ .../Completions/RimWellPathCompletions.h | 3 + .../WellPath/RimWellPathCollection.cpp | 72 ++++++++++++++++++- .../WellPath/RimWellPathCollection.h | 24 ++++--- 4 files changed, 121 insertions(+), 12 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp index 272e15fbc6..094deea1e7 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp @@ -22,6 +22,8 @@ #include "RimFishbones.h" #include "RimFishbonesCollection.h" +#include "RimMswSegment.h" +#include "RimMswSegmentCollection.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" #include "RimProject.h" @@ -65,6 +67,9 @@ RimWellPathCompletions::RimWellPathCompletions() CAF_PDM_InitFieldNoDefault( &m_stimPlanModelCollection, "StimPlanModels", "StimPlan Models" ); m_stimPlanModelCollection = new RimStimPlanModelCollection; + CAF_PDM_InitFieldNoDefault( &m_mswSegmentCollection, "MswSegments", "MSW Segments" ); + m_mswSegmentCollection = new RimMswSegmentCollection; + CAF_PDM_InitField( &m_wellNameForExport_OBSOLETE, "WellNameForExport", QString(), "Well Name" ); m_wellNameForExport_OBSOLETE.xmlCapability()->setIOWritable( false ); CAF_PDM_InitField( &m_wellGroupName_OBSOLETE, "WellGroupNameForExport", QString(), "Well Group Name" ); @@ -129,6 +134,14 @@ RimStimPlanModelCollection* RimWellPathCompletions::stimPlanModelCollection() co return m_stimPlanModelCollection; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswSegmentCollection* RimWellPathCompletions::mswSegmentCollection() const +{ + return m_mswSegmentCollection; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -187,6 +200,14 @@ std::vector RimWellPathCompletions::allCompletio completions.push_back( valve ); } + if ( m_mswSegmentCollection && m_mswSegmentCollection->isChecked() ) + { + for ( const RimMswSegment* segment : m_mswSegmentCollection->segments() ) + { + completions.push_back( const_cast( segment ) ); + } + } + return completions; } @@ -216,6 +237,14 @@ std::vector RimWellPathCompletions::allCom completions.push_back( valve ); } + if ( m_mswSegmentCollection && m_mswSegmentCollection->isChecked() ) + { + for ( const RimMswSegment* segment : m_mswSegmentCollection->segments() ) + { + completions.push_back( segment ); + } + } + return completions; } @@ -274,6 +303,11 @@ void RimWellPathCompletions::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTre { uiTreeOrdering.add( &m_stimPlanModelCollection ); } + + if ( m_mswSegmentCollection && m_mswSegmentCollection->hasSegments() ) + { + uiTreeOrdering.add( &m_mswSegmentCollection ); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h index 4dcf699966..e0fe3293e7 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimWellPathCompletions.h @@ -27,6 +27,7 @@ #include "gsl/gsl" class RimFishbonesCollection; +class RimMswSegmentCollection; class RimPerforationCollection; class RimStimPlanModelCollection; class RimWellPathComponentInterface; @@ -49,6 +50,7 @@ public: RimPerforationCollection* perforationCollection() const; RimWellPathFractureCollection* fractureCollection() const; RimStimPlanModelCollection* stimPlanModelCollection() const; + RimMswSegmentCollection* mswSegmentCollection() const; std::vector allCompletionsNoConst() const; std::vector allCompletions() const; @@ -72,6 +74,7 @@ private: caf::PdmChildField m_perforationCollection; caf::PdmChildField m_fractureCollection; caf::PdmChildField m_stimPlanModelCollection; + caf::PdmChildField m_mswSegmentCollection; private: ///////////////////// diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp index c73c574acf..c74341c855 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp @@ -41,9 +41,11 @@ #include "RimEclipseCase.h" #include "RimEclipseCaseCollection.h" +#include "RimEclipseCaseTools.h" #include "RimEclipseView.h" #include "RimFileWellPath.h" #include "RimModeledWellPath.h" +#include "RimMswSegmentCollection.h" #include "RimOilField.h" #include "RimOsduWellLog.h" #include "RimOsduWellPath.h" @@ -55,6 +57,7 @@ #include "RimWellMeasurementCollection.h" #include "RimWellPath.h" #include "RimWellPathCompletionSettings.h" +#include "RimWellPathCompletions.h" #include "RimWellPathTieIn.h" #include "RiuMainWindow.h" @@ -67,6 +70,7 @@ #include "cafDataLoader.h" #include "cafPdmFieldScriptingCapability.h" #include "cafPdmObjectScriptingCapability.h" +#include "cafPdmUiButton.h" #include "cafPdmUiEditorHandle.h" #include "cafPdmUiTreeOrdering.h" #include "cafProgressInfo.h" @@ -140,6 +144,9 @@ RimWellPathCollection::RimWellPathCollection() CAF_PDM_InitFieldNoDefault( &m_mswNameGrouping, "MswWellNameGrouping", "Grouping" ); CAF_PDM_InitFieldNoDefault( &m_mswNameGroupingPattern, "MswWellNameGroupingPattern", "Grouping Pattern" ); + CAF_PDM_InitFieldNoDefault( &m_mswEclipseCase, "MswEclipseCase", "Eclipse Case" ); + CAF_PDM_InitField( &m_mswShowBands, "MseShowBands", true, "Show Bands" ); + m_wellPathImporter = std::make_unique(); m_wellPathFormationsImporter = std::make_unique(); } @@ -159,6 +166,27 @@ void RimWellPathCollection::fieldChangedByUi( const caf::PdmFieldHandle* changed scheduleRedrawAffectedViews(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellPathCollection::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) +{ + QList options; + + if ( fieldNeedingOptions == &m_mswEclipseCase ) + { + options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) ); + + auto cases = RimEclipseCaseTools::eclipseCases(); + for ( auto* c : cases ) + { + options.push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); + } + } + + return options; +} + //-------------------------------------------------------------------------------------------------- /// Read files containing well path data, or create geometry based on the targets //-------------------------------------------------------------------------------------------------- @@ -514,17 +542,23 @@ void RimWellPathCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOr advancedGroup->add( &wellPathClip ); advancedGroup->add( &wellPathClipZDistance ); - caf::PdmUiGroup* mswGroupingGroup = uiOrdering.addNewGroup( "MSW Settings" ); - mswGroupingGroup->add( &m_mswNameGrouping ); + caf::PdmUiGroup* wellGrouping = uiOrdering.addNewGroup( "MSW Grouping" ); + wellGrouping->add( &m_mswNameGrouping ); if ( m_mswNameGrouping() != MswGroupingMode::DISABLED ) { if ( m_mswNameGrouping() == MswGroupingMode::USE_PREFERENCES ) { m_mswNameGroupingPattern = RiaPreferences::current()->multiLateralWellNamePattern(); } - mswGroupingGroup->add( &m_mswNameGroupingPattern ); + wellGrouping->add( &m_mswNameGroupingPattern ); m_mswNameGroupingPattern.uiCapability()->setUiReadOnly( m_mswNameGrouping() == MswGroupingMode::USE_PREFERENCES ); } + + caf::PdmUiGroup* mswSegmentGroup = uiOrdering.addNewGroup( "MSW Segment Visualization" ); + mswSegmentGroup->add( &m_mswShowBands ); + mswSegmentGroup->add( &m_mswEclipseCase ); + auto updateButton = mswSegmentGroup->addNewButton( "Update Segments", [this]() { updateMswSegments(); } ); + updateButton->setAlignment( Qt::AlignRight ); uiOrdering.skipRemainingFields(); } @@ -554,6 +588,38 @@ caf::PdmFieldHandle* RimWellPathCollection::objectToggleField() return &isActive; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::updateMswSegments() +{ + for ( const auto& wellPath : m_wellPaths ) + { + if ( !wellPath ) continue; + + auto* completions = wellPath->completions(); + if ( !completions ) continue; + + auto* segmentCollection = completions->mswSegmentCollection(); + if ( !segmentCollection ) continue; + + segmentCollection->updateSegments( m_mswEclipseCase() ); + } + + if ( RimProject* project = RimProject::current() ) + { + project->scheduleCreateDisplayModelAndRedrawAllViews(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathCollection::showMswSegmentBands() const +{ + return m_mswShowBands(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h index ae5bda888e..fa66399c18 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h @@ -29,6 +29,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" +#include "cafPdmPtrField.h" // Include to make Pdm work for cvf::Color #include "cafPdmChildField.h" @@ -121,6 +122,8 @@ public: std::vector connectedWellPathLaterals( const RimWellPath* parentWellPath ) const; + bool showMswSegmentBands() const; + RimWellPath* mostRecentlyUpdatedWellPath(); void readWellPathFormationFiles(); @@ -155,9 +158,10 @@ protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; private: - void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; - void initAfterRead() override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; + void initAfterRead() override; + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; caf::PdmFieldHandle* objectToggleField() override; @@ -168,16 +172,15 @@ private: caf::AppEnum findUnitSystemForWellPath( const RimWellPath* wellPath ); - cafTreeNode* addWellToWellNode( cafTreeNode* parent, RimWellPath* wellPath ); - - std::vector wellPathsWithNoParent( const std::vector& sourceWellPaths ) const; - + std::vector wellPathsWithNoParent( const std::vector& sourceWellPaths ) const; std::map> wellPathsForWellNameStem( const std::vector& sourceWellPaths ) const; - static void buildUiTreeOrdering( cafTreeNode* treeNode, caf::PdmUiTreeOrdering* parentUiTreeNode, const QString& uiConfigName ); - + cafTreeNode* addWellToWellNode( cafTreeNode* parent, RimWellPath* wellPath ); + static void buildUiTreeOrdering( cafTreeNode* treeNode, caf::PdmUiTreeOrdering* parentUiTreeNode, const QString& uiConfigName ); static QString unGroupedText(); + void updateMswSegments(); + private: std::unique_ptr m_wellPathImporter; std::unique_ptr m_wellPathFormationsImporter; @@ -190,4 +193,7 @@ private: caf::PdmField m_mswNameGrouping; caf::PdmField m_mswNameGroupingPattern; + + caf::PdmPtrField m_mswEclipseCase; + caf::PdmField m_mswShowBands; };