diff --git a/ApplicationLibCode/Commands/EclipseCommands/EclipseWell/RicCreateWellPathFromSimulationWellFeature.cpp b/ApplicationLibCode/Commands/EclipseCommands/EclipseWell/RicCreateWellPathFromSimulationWellFeature.cpp index 32927134fd..fc81047ca7 100644 --- a/ApplicationLibCode/Commands/EclipseCommands/EclipseWell/RicCreateWellPathFromSimulationWellFeature.cpp +++ b/ApplicationLibCode/Commands/EclipseCommands/EclipseWell/RicCreateWellPathFromSimulationWellFeature.cpp @@ -110,7 +110,6 @@ void RicCreateWellPathFromSimulationWellFeature::onActionTriggered( bool isCheck auto newModeledWellPath = new RimModeledWellPath(); newModeledWellPath->geometryDefinition()->createAndInsertTargets( filteredWellPathPoints ); newModeledWellPath->createWellPathGeometry(); - newModeledWellPath->setUnitSystem( project->commonUnitSystemForAllCases() ); newModeledWellPath->setWellPathColor( RiaColorTables::editableWellPathsPaletteColors().cycledColor3f( modelledWellpathCount + numAddedWells ) ); diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicCreateMultipleWellPathLaterals.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicCreateMultipleWellPathLaterals.cpp index 1df39a2219..eef3c8ce2f 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicCreateMultipleWellPathLaterals.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicCreateMultipleWellPathLaterals.cpp @@ -149,7 +149,7 @@ void RicCreateMultipleWellPathLaterals::slotAppendFractures() newModeledWellPath->wellPathTieIn()->setTieInMeasuredDepth( measuredDepth ); - wellPathCollection->addWellPath( newModeledWellPath ); + wellPathCollection->addWellPath( newModeledWellPath, false ); newModeledWellPath->resolveReferencesRecursively(); newModeledWellPath->updateReferencePoint(); diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp index 718d59efb5..060130c8fa 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp @@ -78,8 +78,6 @@ void RicNewEditableWellPathFeature::onActionTriggered( bool isChecked ) auto newModeledWellPath = new RimModeledWellPath(); newWellPaths.push_back( newModeledWellPath ); - newModeledWellPath->setUnitSystem( project->commonUnitSystemForAllCases() ); - RimFileWellPath* sourceWellPath = caf::SelectionManager::instance()->selectedItemOfType(); bool enableTargetPointPicking = !copyWellPathGeometry( sourceWellPath, newModeledWellPath ); diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp index cdd7bc041d..d7cd6426e1 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp @@ -111,7 +111,6 @@ RimModeledWellPath* RicNewWellPathLateralAtDepthFeature::createLateralAtMeasured newModeledWellPath->connectWellPaths( parentWellPath, parentWellMD ); newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true ); - newModeledWellPath->setUnitSystem( parentWellPath->unitSystem() ); newModeledWellPath->createWellPathGeometry(); diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicPasteModeledWellPathFeature.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicPasteModeledWellPathFeature.cpp index 07c1ce9ac3..4ae649ef08 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicPasteModeledWellPathFeature.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicPasteModeledWellPathFeature.cpp @@ -148,7 +148,7 @@ RimModeledWellPath* RicPasteModeledWellPathFeature::duplicateAndInitializeWellPa QString name = sourceWellPath->name() + "(copy)"; destinationWellPath->setName( name ); - wpc->addWellPath( destinationWellPath ); + wpc->addWellPath( destinationWellPath, false ); // Resolve references, will connect to the fracture template destinationWellPath->resolveReferencesRecursively(); diff --git a/ApplicationLibCode/ProjectDataModel/RimProject.cpp b/ApplicationLibCode/ProjectDataModel/RimProject.cpp index 7ea25ff877..b640d00d5f 100644 --- a/ApplicationLibCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimProject.cpp @@ -1338,22 +1338,27 @@ std::vector RimProject::allValveTemplates() const //-------------------------------------------------------------------------------------------------- caf::AppEnum RimProject::commonUnitSystemForAllCases() const { - RiaDefines::EclipseUnitSystem commonUnitSystem = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN; + using Unit = RiaDefines::EclipseUnitSystem; + + Unit commonUnitSystem = Unit::UNITS_UNKNOWN; for ( const auto& c : allGridCases() ) { + // Cases that are not loaded, or have no unit information, do not take part in the comparison auto eclipseCase = dynamic_cast( c ); - if ( eclipseCase && eclipseCase->eclipseCaseData() ) + if ( !eclipseCase || !eclipseCase->eclipseCaseData() ) continue; + + const Unit caseUnit = eclipseCase->eclipseCaseData()->unitsType(); + if ( caseUnit == Unit::UNITS_UNKNOWN ) continue; + + if ( commonUnitSystem == Unit::UNITS_UNKNOWN ) { - if ( commonUnitSystem == RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN ) - { - commonUnitSystem = eclipseCase->eclipseCaseData()->unitsType(); - } - else if ( commonUnitSystem != eclipseCase->eclipseCaseData()->unitsType() ) - { - commonUnitSystem = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN; - break; - } + commonUnitSystem = caseUnit; + } + else if ( commonUnitSystem != caseUnit ) + { + // Mixed unit systems: there is no common unit system + return Unit::UNITS_UNKNOWN; } } diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp index 0f64abc3d2..13d8e9185f 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.cpp @@ -387,13 +387,45 @@ std::expected, QString> RimWellPathCollection::add //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathCollection::addWellPath( RimWellPath* wellPath ) +void RimWellPathCollection::addWellPath( RimWellPath* wellPath, bool assignUnit ) { + if ( assignUnit ) assignUnitSystem( wellPath ); m_wellPaths.push_back( wellPath ); rebuildWellPathNodes(); } +//-------------------------------------------------------------------------------------------------- +/// Single place where the unit system of a new well path is decided +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::assignUnitSystem( RimWellPath* wellPath ) +{ + if ( !wellPath ) return; + + using Unit = RiaDefines::EclipseUnitSystem; + + if ( dynamic_cast( wellPath ) ) + { + // Files have no unit information, so use the case the well path overlaps. This is unknown if there is no overlap. + wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) ); + return; + } + + Unit unitSystem = Unit::UNITS_UNKNOWN; + if ( wellPath->wellPathTieIn() && wellPath->wellPathTieIn()->parentWell() ) + { + // Laterals use the same unit system as their parent + unitSystem = wellPath->wellPathTieIn()->parentWell()->unitSystem(); + } + else if ( auto* project = firstAncestorOrThisOfType() ) + { + unitSystem = project->commonUnitSystemForAllCases(); + } + + // Keep the current unit system if it can not be determined + if ( unitSystem != Unit::UNITS_UNKNOWN ) wellPath->setUnitSystem( unitSystem ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -440,7 +472,6 @@ std::vector RimWellPathCollection::readAndAddWellPaths( std::vecto progress.setProgressDescription( QString( "Reading file %1" ).arg( wellPath->name() ) ); wellPath->setWellPathColor( RiaColorTables::wellPathsPaletteColors().cycledColor3f( m_wellPaths.size() ) ); - wellPath->setUnitSystem( findUnitSystemForWellPath( wellPath ) ); addWellPath( wellPath ); addedWellPaths.push_back( wellPath ); @@ -1309,6 +1340,12 @@ void RimWellPathCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* child //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::onChildAdded( caf::PdmFieldHandle* containerForNewObject ) { + // Well paths created from Python are added directly to the child field + if ( containerForNewObject == &m_wellPaths && !m_wellPaths.empty() ) + { + assignUnitSystem( m_wellPaths[m_wellPaths.size() - 1] ); + } + rebuildWellPathNodes(); scheduleRedrawAffectedViews(); diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h index bbd97ecdd0..3ee26a1d71 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathCollection.h @@ -129,7 +129,8 @@ public: RimWellPath* wellPathByName( const QString& wellPathName ) const; RimWellPath* tryFindMatchingWellPath( const QString& wellName ) const; void addWellPaths( const std::vector incomingWellPaths ); - void addWellPath( RimWellPath* wellPath ); + // Set assignUnit to false for copies of existing well paths, as they already carry unit specific settings + void addWellPath( RimWellPath* wellPath, bool assignUnit = true ); std::vector addWellLogs( const QStringList& filePaths, QStringList* errorMessages ); void addWellPathFormations( const QStringList& filePaths ); @@ -174,6 +175,7 @@ private: std::expected, QString> addWellPathsForFile( const QString& filePath ); caf::AppEnum findUnitSystemForWellPath( const RimWellPath* wellPath ); + void assignUnitSystem( RimWellPath* wellPath ); std::vector wellPathsWithNoParent( const std::vector& sourceWellPaths ) const; std::map> wellPathsForWellNameStem( const std::vector& sourceWellPaths ) const;