#14439 Create 2D intersection views for views in a grid ensemble

Rim2dIntersectionViewCollection::syncFromExistingIntersections() found the
intersections by walking the PDM child tree of the case. Views located in a
grid ensemble view collection or in the project level view collection are not
children of the case, so no 2D intersection view was created for their
intersections and "Show 2D Intersection View" did nothing.

Collect the intersections from the grid views displaying the case instead.

Display the 2D intersection views as a child of RimReservoirGridEnsemble, next
to the 3D views they are created from, and skip the node on the case to avoid
showing the same object twice in the project tree.
This commit is contained in:
Magne Sjaastad
2026-08-06 12:42:54 +02:00
parent 20404bdca8
commit 91d3ae8f3a
4 changed files with 80 additions and 5 deletions
@@ -22,9 +22,37 @@
#include "RimCase.h"
#include "RimExtrudedCurveIntersection.h"
#include "RimGridView.h"
#include "RimIntersectionCollection.h"
#include "RimReservoirGridEnsemble.h"
#include <algorithm>
CAF_PDM_SOURCE_INIT( Rim2dIntersectionViewCollection, "Intersection2dViewCollection" );
namespace
{
//--------------------------------------------------------------------------------------------------
/// Views displaying a case are not necessarily children of the case. Views can be located in the project level
/// view collection or in the view collection of a grid ensemble. Collect all grid views displaying the case.
//--------------------------------------------------------------------------------------------------
std::vector<RimGridView*> gridViewsForCase( RimCase* rimCase )
{
std::vector<RimGridView*> gridViews = rimCase->gridViews();
// Views in a view collection are not children of the case, and are not reported by gridViews(). These views refer to
// the case using a ptr field, and can be found by inspecting the objects referring to the case.
for ( auto view : rimCase->objectsWithReferringPtrFieldsOfType<RimGridView>() )
{
if ( !view || view->ownerCase() != rimCase ) continue;
if ( std::find( gridViews.begin(), gridViews.end(), view ) != gridViews.end() ) continue;
gridViews.push_back( view );
}
return gridViews;
}
} // namespace
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -57,8 +85,16 @@ void Rim2dIntersectionViewCollection::syncFromExistingIntersections( bool doUpda
{
auto parentCase = firstAncestorOrThisOfTypeAsserted<RimCase>();
std::vector<RimExtrudedCurveIntersection*> allOrderedIntersectionsInCase =
parentCase->descendantsIncludingThisOfType<RimExtrudedCurveIntersection>();
std::vector<RimExtrudedCurveIntersection*> allOrderedIntersectionsInCase;
for ( auto gridView : gridViewsForCase( parentCase ) )
{
if ( !gridView || !gridView->intersectionCollection() ) continue;
for ( auto intersection : gridView->intersectionCollection()->intersections() )
{
if ( intersection ) allOrderedIntersectionsInCase.push_back( intersection );
}
}
// Delete views without a valid intersection
@@ -119,7 +155,11 @@ void Rim2dIntersectionViewCollection::syncFromExistingIntersections( bool doUpda
if ( doUpdate ) updateConnectedEditors();
auto rimCase = firstAncestorOrThisOfType<RimCase>();
parentCase->updateConnectedEditors();
if ( rimCase ) rimCase->updateConnectedEditors();
// For a case in a grid ensemble, this collection is displayed as a child of the ensemble
if ( auto ensemble = parentCase->firstAncestorOfType<RimReservoirGridEnsemble>() )
{
ensemble->updateConnectedEditors();
}
}
@@ -73,6 +73,7 @@
#include "RimProject.h"
#include "RimReloadCaseTools.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimReservoirGridEnsemble.h"
#include "RimReservoirGridEnsembleBase.h"
#include "RimResultNameAlias.h"
#include "RimStimPlanColors.h"
@@ -692,7 +693,9 @@ void RimEclipseCase::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrderin
uiTreeOrdering.add( view );
}
if ( !m_2dIntersectionViewCollection->views().empty() )
// For a case in a grid ensemble, the 2D intersection views are displayed as a child of the ensemble, as the
// 3D views are located in the ensemble and not in the case
if ( !m_2dIntersectionViewCollection->views().empty() && !firstAncestorOfType<RimReservoirGridEnsemble>() )
{
uiTreeOrdering.add( &m_2dIntersectionViewCollection );
}
@@ -35,6 +35,7 @@
#include "EnsembleFileSet/RimEnsembleFileSetTools.h"
#include "Formations/RimFormationNames.h"
#include "Formations/RimFormationNamesCollection.h"
#include "Rim2dIntersectionViewCollection.h"
#include "RimCaseCollection.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
@@ -51,6 +52,7 @@
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiTreeAttributes.h"
#include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h"
#include "RigCaseCellResultsData.h"
@@ -699,6 +701,35 @@ void RimReservoirGridEnsemble::defineUiOrdering( QString uiConfigName, caf::PdmU
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
/// The 2D intersection views are owned by the case, but the views of an ensemble are located in the ensemble.
/// Show the 2D intersection views next to the views they are created from.
//--------------------------------------------------------------------------------------------------
void RimReservoirGridEnsemble::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName )
{
if ( uiConfigName != "MainWindow.ProjectTree" ) return;
uiTreeOrdering.add( &m_caseCollection );
uiTreeOrdering.add( &m_statisticsCaseCollection );
uiTreeOrdering.add( &m_viewCollection );
for ( auto eclipseCase : cases() )
{
if ( !eclipseCase ) continue;
auto intersectionViewCollection = eclipseCase->intersectionViewCollection();
if ( intersectionViewCollection && !intersectionViewCollection->views().empty() )
{
uiTreeOrdering.add( intersectionViewCollection );
}
}
uiTreeOrdering.add( &m_wellTargetMappings );
uiTreeOrdering.add( &m_statisticsContourMaps );
uiTreeOrdering.skipRemainingChildren( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -123,6 +123,7 @@ public:
protected:
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void createDerivedObjects() override;