ResInsight/ApplicationLibCode/Commands/WellPathCommands/RicNewWellPathLateralAtDepthFeature.cpp
Magne Sjaastad 51331facac
Improve how wells are connected during import
When importing new wells, consider all wells when connecting multi segment wells
Make sure that import of individual well paths will give the same ordering as importing all wells in a single operation.
2023-03-07 12:51:14 +01:00

195 lines
6.9 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020- 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 "RicNewWellPathLateralAtDepthFeature.h"
#include "WellPathCommands/RicWellPathsUnitSystemSettingsImpl.h"
#include "RigWellPath.h"
#include "RimFishbones.h"
#include "RimFishbonesCollection.h"
#include "RimModeledWellPath.h"
#include "RimProject.h"
#include "RimTools.h"
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimWellPathGeometryDef.h"
#include "RimWellPathTarget.h"
#include "Riu3DMainWindowTools.h"
#include "Riu3dSelectionManager.h"
#include "cafSelectionManager.h"
#include <QAction>
#include "RiaTextStringTools.h"
#include <cmath>
CAF_CMD_SOURCE_INIT( RicNewWellPathLateralAtDepthFeature, "RicNewWellPathLateralAtDepthFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicNewWellPathLateralAtDepthFeature::isCommandEnabled()
{
if ( RiuWellPathSelectionItem::wellPathSelectionItem() )
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellPathLateralAtDepthFeature::onActionTriggered( bool isChecked )
{
RiuWellPathSelectionItem* wellPathSelItem = RiuWellPathSelectionItem::wellPathSelectionItem();
CVF_ASSERT( wellPathSelItem );
RimWellPath* parentWellPath = wellPathSelItem->m_wellpath;
CVF_ASSERT( parentWellPath );
double parentWellMD = wellPathSelItem->m_measuredDepth;
createLateralAtMeasuredDepth( parentWellPath, parentWellMD );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellPathLateralAtDepthFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setText( "Create Well Path Lateral at this Depth" );
actionToSetup->setIcon( QIcon( ":/Well.svg" ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimModeledWellPath* RicNewWellPathLateralAtDepthFeature::createLateralAtMeasuredDepth( RimWellPath* parentWellPath, double parentWellMD )
{
RimProject* project = RimProject::current();
RimWellPathCollection* wellPathColl = RimTools::wellPathCollection();
if ( project && wellPathColl )
{
auto newModeledWellPath = new RimModeledWellPath();
newModeledWellPath->geometryDefinition()->enableReferencePointFromTopLevelWell( true );
if ( parentWellPath->wellPathGeometry() && parentWellPath->wellPathGeometry()->measuredDepths().size() > 2 )
{
auto [pointVector, measuredDepths] =
parentWellPath->wellPathGeometry()->clippedPointSubset( parentWellPath->wellPathGeometry()->measuredDepths().front(),
parentWellMD );
newModeledWellPath->geometryDefinition()->setMdAtFirstTarget( measuredDepths.back() );
newModeledWellPath->geometryDefinition()->setFixedWellPathPoints( pointVector );
newModeledWellPath->geometryDefinition()->setFixedMeasuredDepths( measuredDepths );
}
newModeledWellPath->geometryDefinition()->setIsAttachedToParentWell( true );
newModeledWellPath->geometryDefinition()->setUseAutoGeneratedTargetAtSeaLevel( false );
auto nameOfNewWell = updateNameOfParentAndFindNameOfSideStep( parentWellPath );
newModeledWellPath->setName( nameOfNewWell );
newModeledWellPath->connectWellPaths( parentWellPath, parentWellMD );
newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true );
newModeledWellPath->setUnitSystem( parentWellPath->unitSystem() );
newModeledWellPath->createWellPathGeometry();
wellPathColl->addWellPath( newModeledWellPath );
wellPathColl->updateAllRequiredEditors();
project->scheduleCreateDisplayModelAndRedrawAllViews();
Riu3DMainWindowTools::selectAsCurrentItem( newModeledWellPath->geometryDefinition() );
return newModeledWellPath;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicNewWellPathLateralAtDepthFeature::updateNameOfParentAndFindNameOfSideStep( RimWellPath* parentWellPath )
{
if ( !parentWellPath ) return "";
QString nameOfNewWell;
auto topLevelWell = parentWellPath->topLevelWellPath();
QStringList allNames;
{
RimProject* proj = RimProject::current();
const std::vector<RimWellPath*>& wellPaths = proj->allWellPaths();
for ( auto wellPath : wellPaths )
{
if ( wellPath )
{
auto currentTopLevelWell = wellPath->topLevelWellPath();
if ( topLevelWell == currentTopLevelWell )
{
allNames.push_back( wellPath->name() );
}
}
}
}
if ( allNames.size() == 1 )
{
QString name = parentWellPath->name();
if ( name.contains( "Y1" ) )
{
nameOfNewWell = name.replace( "Y1", "Y2" );
}
else
{
parentWellPath->setNameNoUpdateOfExportName( name + " Y1" );
nameOfNewWell = name + " Y2";
}
return nameOfNewWell;
}
{
QString commonRoot = RiaTextStringTools::commonRoot( allNames );
int maxYValue = 0;
for ( auto n : allNames )
{
auto suffix = n.replace( commonRoot, "" );
int candidate = suffix.toInt();
maxYValue = std::max( maxYValue, candidate );
}
nameOfNewWell = QString( "%1%2" ).arg( commonRoot ).arg( maxYValue + 1 );
}
return nameOfNewWell;
}