mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Create Well Path Laterals from existing well paths
* Add cmakebuild/ to .gitignore * Create Well Path Laterals from existing well paths * Move ValidRegExpValidator to RiaValidRegExpValidator.h|cpp * Minor code review fixups * More minor code review fixups * Another set of minor code review fixups
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,6 +25,7 @@ CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
CPack*.cmake
|
||||
CTest*.cmake
|
||||
cmakebuild/
|
||||
|
||||
#Unit test binaries
|
||||
*_UnitTests
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaValidRegExpValidator.h"
|
||||
#include "RifReaderSettings.h"
|
||||
#include "RiuGuiTheme.h"
|
||||
|
||||
@@ -31,10 +32,12 @@
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiFilePathEditor.h"
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
|
||||
#include <QDate>
|
||||
#include <QDir>
|
||||
#include <QLocale>
|
||||
#include <QRegExp>
|
||||
#include <QStandardPaths>
|
||||
|
||||
namespace caf
|
||||
@@ -386,6 +389,16 @@ RiaPreferences::RiaPreferences( void )
|
||||
"Defines preferred minimum distance between surface points in XY-plane",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitField( &m_multiLateralWellPattern,
|
||||
"MultiLateralWellPattern",
|
||||
defaultMultiLateralWellNamePattern(),
|
||||
"Multi Lateral Well Path Name Pattern",
|
||||
"",
|
||||
"Pattern to be used to decide if an imported well is part of a multi-lateral well. Allows use "
|
||||
"of ? and * as wildcards.",
|
||||
"" );
|
||||
m_multiLateralWellPattern.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_guiTheme, "guiTheme", "GUI theme", "", "", "" );
|
||||
}
|
||||
|
||||
@@ -457,6 +470,15 @@ void RiaPreferences::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
caf::PdmUiComboBoxEditorAttribute* myAttr = dynamic_cast<caf::PdmUiComboBoxEditorAttribute*>( attribute );
|
||||
myAttr->minimumContentsLength = 2;
|
||||
}
|
||||
if ( field == &m_multiLateralWellPattern )
|
||||
{
|
||||
caf::PdmUiLineEditorAttribute* myAttr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute );
|
||||
if ( myAttr )
|
||||
{
|
||||
myAttr->validator =
|
||||
new RiaValidRegExpValidator( RiaPreferences::current()->defaultMultiLateralWellNamePattern() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -577,6 +599,7 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
else if ( uiConfigName == RiaPreferences::tabNameImport() )
|
||||
{
|
||||
uiOrdering.add( &m_surfaceImportResamplingDistance );
|
||||
uiOrdering.add( &m_multiLateralWellPattern );
|
||||
}
|
||||
else if ( RiaApplication::enableDevelopmentFeatures() && uiConfigName == RiaPreferences::tabNameSystem() )
|
||||
{
|
||||
@@ -1056,6 +1079,22 @@ double RiaPreferences::surfaceImportResamplingDistance() const
|
||||
return m_surfaceImportResamplingDistance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaPreferences::multiLateralWellNamePattern() const
|
||||
{
|
||||
return m_multiLateralWellPattern;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaPreferences::defaultMultiLateralWellNamePattern()
|
||||
{
|
||||
return "?*Y*";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -122,6 +122,9 @@ public:
|
||||
|
||||
double surfaceImportResamplingDistance() const;
|
||||
|
||||
QString multiLateralWellNamePattern() const;
|
||||
static QString defaultMultiLateralWellNamePattern();
|
||||
|
||||
// 3D view
|
||||
RiaDefines::MeshModeType defaultMeshModeType() const;
|
||||
RiaGuiApplication::RINavigationPolicy navigationPolicy() const;
|
||||
@@ -235,6 +238,9 @@ private:
|
||||
// Surface Import
|
||||
caf::PdmField<double> m_surfaceImportResamplingDistance;
|
||||
|
||||
// Well Path Import
|
||||
caf::PdmField<QString> m_multiLateralWellPattern;
|
||||
|
||||
// 3d view
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::MeshModeType>> m_defaultMeshModeType;
|
||||
caf::PdmField<caf::AppEnum<RiaGuiApplication::RINavigationPolicy>> m_navigationPolicy;
|
||||
|
@@ -45,6 +45,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaBoundingBoxTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaWellLogUnitTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaWellLogUnitTools.inl
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeTTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaValidRegExpValidator.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@@ -86,6 +87,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaCellDividingTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaFieldHandleTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaBoundingBoxTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeTTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaValidRegExpValidator.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@@ -0,0 +1,73 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiaValidRegExpValidator.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaValidRegExpValidator::RiaValidRegExpValidator( const QString& defaultPattern )
|
||||
: QValidator( nullptr )
|
||||
, m_defaultPattern( defaultPattern )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaValidRegExpValidator::isValidCharacter( const QChar& character )
|
||||
{
|
||||
return character.isLetterOrNumber() || character == '-' || character == '_' || character == '.' || character == '[';
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QValidator::State RiaValidRegExpValidator::validate( QString& inputString, int& position ) const
|
||||
{
|
||||
QRegExp inputRe( inputString, Qt::CaseInsensitive, QRegExp::Wildcard );
|
||||
if ( inputRe.isValid() ) // A valid wildcard pattern is always acceptable
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
if ( position >= inputString.length() )
|
||||
{
|
||||
// This should probably never happen, but the Qt-documentation isn't clear on it.
|
||||
CAF_ASSERT( false );
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
|
||||
// Try to decide whether it can be fixed by typing further characters or not.
|
||||
if ( !isValidCharacter( inputString[position] ) )
|
||||
{
|
||||
// Contains a invalid character: the whole regexp is invalid.
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
|
||||
return QValidator::Intermediate;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaValidRegExpValidator::fixup( QString& inputString ) const
|
||||
{
|
||||
inputString = m_defaultPattern;
|
||||
}
|
39
ApplicationCode/Application/Tools/RiaValidRegExpValidator.h
Normal file
39
ApplicationCode/Application/Tools/RiaValidRegExpValidator.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include <QRegExp>
|
||||
#include <QString>
|
||||
#include <QValidator>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Validates a wild card pattern (simpler for user)
|
||||
// Has to use the older QRegExp because QRegularExpression didn't add any
|
||||
// support for wild cards until Qt 5.12.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class RiaValidRegExpValidator : public QValidator
|
||||
{
|
||||
public:
|
||||
RiaValidRegExpValidator( const QString& defaultPattern );
|
||||
static bool isValidCharacter( const QChar& character );
|
||||
State validate( QString& inputString, int& position ) const override;
|
||||
void fixup( QString& inputString ) const override;
|
||||
|
||||
private:
|
||||
QString m_defaultPattern;
|
||||
};
|
@@ -20,6 +20,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicPolylineTargetsPickEventHandler.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewPolylineTargetFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeletePolylineTargetFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportWellMeasurementsFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathLateralAtDepthFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/Ric3dObjectEditorHandle.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicWellTarget3dEditor.h
|
||||
@@ -50,6 +51,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicPolylineTargetsPickEventHandler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewPolylineTargetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicDeletePolylineTargetFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportWellMeasurementsFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathLateralAtDepthFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/Ric3dObjectEditorHandle.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicWellTarget3dEditor.cpp
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "RicWellTarget3dEditor.h"
|
||||
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathLateralGeometryDef.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
|
||||
#include "cafPickEventHandler.h"
|
||||
@@ -55,7 +56,7 @@ RicWellPathGeometry3dEditor::~RicWellPathGeometry3dEditor()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicWellPathGeometry3dEditor::configureAndUpdateUi( const QString& uiConfigName )
|
||||
{
|
||||
RimWellPathGeometryDef* geomDef = dynamic_cast<RimWellPathGeometryDef*>( this->pdmObject() );
|
||||
RimWellPathGeometryDefInterface* geomDef = dynamic_cast<RimWellPathGeometryDefInterface*>( this->pdmObject() );
|
||||
|
||||
for ( auto targetEditor : m_targetEditors )
|
||||
{
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "RimCase.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathLateralGeometryDef.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
|
||||
#include "RiuViewer.h"
|
||||
@@ -85,7 +86,7 @@ void RicWellTarget3dEditor::configureAndUpdateUi( const QString& uiConfigName )
|
||||
return;
|
||||
}
|
||||
|
||||
RimWellPathGeometryDef* geomDef;
|
||||
RimWellPathGeometryDefInterface* geomDef;
|
||||
target->firstAncestorOrThisOfTypeAsserted( geomDef );
|
||||
|
||||
target->m_targetType.uiCapability()->addFieldEditor( this );
|
||||
@@ -112,7 +113,7 @@ void RicWellTarget3dEditor::configureAndUpdateUi( const QString& uiConfigName )
|
||||
cvf::ref<caf::DisplayCoordTransform> dispXf = view->displayCoordTransform();
|
||||
double handleSize = 0.7 * view->ownerCase()->characteristicCellSize();
|
||||
|
||||
m_manipulator->setOrigin( dispXf->transformToDisplayCoord( target->targetPointXYZ() + geomDef->referencePointXyz() ) );
|
||||
m_manipulator->setOrigin( dispXf->transformToDisplayCoord( target->targetPointXYZ() + geomDef->anchorPointXyz() ) );
|
||||
m_manipulator->setTangent( target->tangent() );
|
||||
m_manipulator->setHandleSize( handleSize );
|
||||
|
||||
@@ -152,10 +153,10 @@ void RicWellTarget3dEditor::slotUpdated( const cvf::Vec3d& origin, const cvf::Ve
|
||||
|
||||
cvf::ref<caf::DisplayCoordTransform> dispXf = view->displayCoordTransform();
|
||||
|
||||
RimWellPathGeometryDef* geomDef;
|
||||
RimWellPathGeometryDefInterface* geomDef;
|
||||
target->firstAncestorOrThisOfTypeAsserted( geomDef );
|
||||
|
||||
cvf::Vec3d domainOrigin = dispXf->transformToDomainCoord( origin ) - geomDef->referencePointXyz();
|
||||
cvf::Vec3d domainOrigin = dispXf->transformToDomainCoord( origin ) - geomDef->anchorPointXyz();
|
||||
domainOrigin.z() = -domainOrigin.z();
|
||||
QVariant originVariant = caf::PdmValueFieldSpecialization<cvf::Vec3d>::convert( domainOrigin );
|
||||
|
||||
@@ -189,7 +190,5 @@ void RicWellTarget3dEditor::slotDragFinished()
|
||||
return;
|
||||
}
|
||||
|
||||
RimModeledWellPath* wellpath;
|
||||
target->firstAncestorOrThisOfTypeAsserted( wellpath );
|
||||
wellpath->scheduleUpdateOfDependentVisualization();
|
||||
target->onMoved();
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicAutomaticWellPathGrouping.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimOilField.h"
|
||||
@@ -29,6 +30,7 @@
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QRegExp>
|
||||
|
||||
RICF_SOURCE_INIT( RicAutomaticWellPathGrouping, "RicAutomaticWellPathGroupingFeature", "autoGroupWellPaths" );
|
||||
|
||||
@@ -94,12 +96,12 @@ void RicAutomaticWellPathGrouping::setupActionLook( QAction* actionToSetup )
|
||||
auto wellPathCollection = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCollection>();
|
||||
if ( wellPathCollection )
|
||||
{
|
||||
actionToSetup->setText( "Automatically Group All Well Paths" );
|
||||
actionToSetup->setText( "Automatically Create Multi-Lateral Wells" );
|
||||
actionToSetup->setIcon( QIcon( ":/WellPathGroup.svg" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
actionToSetup->setText( "Automatically Group Selected Well Paths" );
|
||||
actionToSetup->setText( "Automatically Create Multi-Lateral Wells from Selected Paths" );
|
||||
actionToSetup->setIcon( QIcon( ":/WellPathGroup.svg" ) );
|
||||
}
|
||||
}
|
||||
@@ -109,13 +111,29 @@ void RicAutomaticWellPathGrouping::setupActionLook( QAction* actionToSetup )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimWellPath*> RicAutomaticWellPathGrouping::selectedWellPaths()
|
||||
{
|
||||
std::vector<RimWellPath*> wellPaths;
|
||||
|
||||
auto wellPathCollection = caf::SelectionManager::instance()->selectedItemOfType<RimWellPathCollection>();
|
||||
if ( wellPathCollection )
|
||||
{
|
||||
return wellPathCollection->allWellPaths();
|
||||
wellPaths = wellPathCollection->allWellPaths();
|
||||
}
|
||||
else
|
||||
{
|
||||
caf::SelectionManager::instance()->objectsByTypeStrict( &wellPaths );
|
||||
}
|
||||
|
||||
std::vector<RimWellPath*> wellPaths;
|
||||
caf::SelectionManager::instance()->objectsByTypeStrict( &wellPaths );
|
||||
return wellPaths;
|
||||
QString multiLateralWellPathPattern = RiaPreferences::current()->multiLateralWellNamePattern();
|
||||
QRegExp re( multiLateralWellPathPattern, Qt::CaseInsensitive, QRegExp::Wildcard );
|
||||
|
||||
std::vector<RimWellPath*> multiLateralWellPaths;
|
||||
for ( auto wellPath : wellPaths )
|
||||
{
|
||||
if ( re.exactMatch( wellPath->name() ) )
|
||||
{
|
||||
multiLateralWellPaths.push_back( wellPath );
|
||||
}
|
||||
}
|
||||
|
||||
return multiLateralWellPaths;
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
#include "RimWellPathLateralGeometryDef.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
|
||||
#include "RiuViewerCommands.h"
|
||||
@@ -55,7 +56,8 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicCreateWellTargetsPickEventHandler::RicCreateWellTargetsPickEventHandler( gsl::not_null<RimWellPathGeometryDef*> wellGeometryDef )
|
||||
RicCreateWellTargetsPickEventHandler::RicCreateWellTargetsPickEventHandler(
|
||||
gsl::not_null<RimWellPathGeometryDefInterface*> wellGeometryDef )
|
||||
: m_geometryToAddTargetsTo( wellGeometryDef )
|
||||
{
|
||||
}
|
||||
@@ -95,94 +97,55 @@ bool RicCreateWellTargetsPickEventHandler::handle3dPickEvent( const Ric3dPickEve
|
||||
cvf::Vec3d targetPointInDomain = cvf::Vec3d::ZERO;
|
||||
|
||||
// If clicked on an other well path, snap target point to well path center line
|
||||
auto firstPickItem = eventObject.m_pickItemInfos.front();
|
||||
auto wellPathSourceInfo = dynamic_cast<const RivWellPathSourceInfo*>( firstPickItem.sourceInfo() );
|
||||
auto firstPickItem = eventObject.m_pickItemInfos.front();
|
||||
|
||||
auto intersectionPointInDomain =
|
||||
rimView->displayCoordTransform()->transformToDomainCoord( firstPickItem.globalPickedPoint() );
|
||||
bool doSetAzimuthAndInclination = false;
|
||||
double azimuth = 0.0;
|
||||
double inclination = 0.0;
|
||||
|
||||
if ( wellPathSourceInfo && wellPathSourceInfo->wellPath() && wellPathSourceInfo->wellPath()->wellPathGeometry() )
|
||||
double azimuth = std::numeric_limits<double>::infinity();
|
||||
double inclination = std::numeric_limits<double>::infinity();
|
||||
|
||||
auto wellPathSourceInfo = dynamic_cast<const RivWellPathSourceInfo*>( firstPickItem.sourceInfo() );
|
||||
|
||||
if ( isValidWellPathSourceObject( wellPathSourceInfo ) )
|
||||
{
|
||||
auto wellPathGeometry = wellPathSourceInfo->wellPath()->wellPathGeometry();
|
||||
|
||||
targetPointInDomain =
|
||||
wellPathSourceInfo->closestPointOnCenterLine( firstPickItem.faceIdx(), intersectionPointInDomain );
|
||||
double md = wellPathSourceInfo->measuredDepth( firstPickItem.faceIdx(), intersectionPointInDomain );
|
||||
doSetAzimuthAndInclination = calculateAzimuthAndInclinationAtMd( md, wellPathGeometry, &azimuth, &inclination );
|
||||
double rkbDiff = wellPathGeometry->rkbDiff();
|
||||
if ( m_geometryToAddTargetsTo->airGap() == 0.0 && rkbDiff != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
m_geometryToAddTargetsTo->setAirGap( rkbDiff );
|
||||
}
|
||||
calculateWellPathGeometryAtPickPoint( firstPickItem,
|
||||
wellPathSourceInfo,
|
||||
intersectionPointInDomain,
|
||||
&targetPointInDomain,
|
||||
&azimuth,
|
||||
&inclination );
|
||||
}
|
||||
else if ( isGridSourceObject( firstPickItem.sourceInfo() ) )
|
||||
{
|
||||
targetPointInDomain = intersectionPointInDomain;
|
||||
doSetAzimuthAndInclination = false;
|
||||
|
||||
cvf::Vec3d domainRayOrigin =
|
||||
rimView->displayCoordTransform()->transformToDomainCoord( firstPickItem.globalRayOrigin() );
|
||||
cvf::Vec3d domainRayEnd = targetPointInDomain + ( targetPointInDomain - domainRayOrigin );
|
||||
|
||||
cvf::Vec3d hexElementIntersection =
|
||||
findHexElementIntersection( rimView, firstPickItem, domainRayOrigin, domainRayEnd );
|
||||
CVF_TIGHT_ASSERT( !hexElementIntersection.isUndefined() );
|
||||
if ( !hexElementIntersection.isUndefined() )
|
||||
{
|
||||
targetPointInDomain = hexElementIntersection;
|
||||
}
|
||||
targetPointInDomain = calculateGridPickPoint( rimView, firstPickItem, intersectionPointInDomain );
|
||||
}
|
||||
else
|
||||
{
|
||||
targetPointInDomain = intersectionPointInDomain;
|
||||
doSetAzimuthAndInclination = false;
|
||||
targetPointInDomain = intersectionPointInDomain;
|
||||
}
|
||||
|
||||
if ( !m_geometryToAddTargetsTo->firstActiveTarget() )
|
||||
if ( auto wellPathGeometryDef = dynamic_cast<RimWellPathGeometryDef*>( m_geometryToAddTargetsTo.p() );
|
||||
wellPathGeometryDef )
|
||||
{
|
||||
m_geometryToAddTargetsTo->setReferencePointXyz( targetPointInDomain );
|
||||
|
||||
if ( wellPathSourceInfo )
|
||||
{
|
||||
double mdAtFirstTarget =
|
||||
wellPathSourceInfo->measuredDepth( firstPickItem.faceIdx(), intersectionPointInDomain );
|
||||
|
||||
RimModeledWellPath* modeledWellPath = dynamic_cast<RimModeledWellPath*>( wellPathSourceInfo->wellPath() );
|
||||
if ( modeledWellPath )
|
||||
{
|
||||
mdAtFirstTarget += modeledWellPath->geometryDefinition()->mdAtFirstTarget();
|
||||
}
|
||||
|
||||
m_geometryToAddTargetsTo->setMdAtFirstTarget( mdAtFirstTarget );
|
||||
}
|
||||
addNewTargetToModeledWellPath( firstPickItem,
|
||||
wellPathGeometryDef,
|
||||
intersectionPointInDomain,
|
||||
targetPointInDomain,
|
||||
azimuth,
|
||||
inclination );
|
||||
}
|
||||
|
||||
cvf::Vec3d referencePoint = m_geometryToAddTargetsTo->referencePointXyz();
|
||||
cvf::Vec3d relativeTagetPoint = targetPointInDomain - referencePoint;
|
||||
|
||||
RimWellPathTarget* newTarget = new RimWellPathTarget;
|
||||
|
||||
if ( doSetAzimuthAndInclination )
|
||||
else if ( auto wellPathLateralGeometryDef =
|
||||
dynamic_cast<RimWellPathLateralGeometryDef*>( m_geometryToAddTargetsTo.p() );
|
||||
wellPathLateralGeometryDef )
|
||||
{
|
||||
newTarget->setAsPointXYZAndTangentTarget( cvf::Vec3d( relativeTagetPoint.x(),
|
||||
relativeTagetPoint.y(),
|
||||
relativeTagetPoint.z() ),
|
||||
azimuth,
|
||||
inclination );
|
||||
addNewTargetToModeledWellPathLateral( firstPickItem,
|
||||
wellPathLateralGeometryDef,
|
||||
intersectionPointInDomain,
|
||||
targetPointInDomain,
|
||||
azimuth,
|
||||
inclination );
|
||||
}
|
||||
else
|
||||
{
|
||||
newTarget->setAsPointTargetXYD(
|
||||
cvf::Vec3d( relativeTagetPoint.x(), relativeTagetPoint.y(), -relativeTagetPoint.z() ) );
|
||||
}
|
||||
|
||||
m_geometryToAddTargetsTo->insertTarget( nullptr, newTarget );
|
||||
|
||||
m_geometryToAddTargetsTo->updateConnectedEditors();
|
||||
m_geometryToAddTargetsTo->updateWellPathVisualization();
|
||||
|
||||
return true; // Todo: See if we really should eat the event instead
|
||||
}
|
||||
@@ -243,6 +206,155 @@ bool RicCreateWellTargetsPickEventHandler::calculateAzimuthAndInclinationAtMd( d
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicCreateWellTargetsPickEventHandler::calculateWellPathGeometryAtPickPoint(
|
||||
const RiuPickItemInfo& pickItem,
|
||||
gsl::not_null<const RivWellPathSourceInfo*> wellPathSourceInfo,
|
||||
const cvf::Vec3d& intersectionPointInDomain,
|
||||
gsl::not_null<cvf::Vec3d*> targetPointInDomain,
|
||||
gsl::not_null<double*> azimuth,
|
||||
gsl::not_null<double*> inclination ) const
|
||||
{
|
||||
*targetPointInDomain = wellPathSourceInfo->closestPointOnCenterLine( pickItem.faceIdx(), intersectionPointInDomain );
|
||||
|
||||
bool doSetAzimuthAndInclination = false;
|
||||
|
||||
auto wellPathGeometry = wellPathSourceInfo->wellPath()->wellPathGeometry();
|
||||
if ( wellPathGeometry )
|
||||
{
|
||||
double md = wellPathSourceInfo->measuredDepth( pickItem.faceIdx(), intersectionPointInDomain );
|
||||
|
||||
doSetAzimuthAndInclination = calculateAzimuthAndInclinationAtMd( md, wellPathGeometry, azimuth, inclination );
|
||||
double rkbDiff = wellPathGeometry->rkbDiff();
|
||||
auto wellPathGeometryDef = dynamic_cast<RimWellPathGeometryDef*>( m_geometryToAddTargetsTo.p() );
|
||||
if ( wellPathGeometryDef && wellPathGeometryDef->airGap() == 0.0 &&
|
||||
rkbDiff != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
wellPathGeometryDef->setAirGap( rkbDiff );
|
||||
}
|
||||
}
|
||||
return doSetAzimuthAndInclination;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RicCreateWellTargetsPickEventHandler::calculateGridPickPoint( gsl::not_null<const Rim3dView*> rimView,
|
||||
const RiuPickItemInfo& pickItem,
|
||||
const cvf::Vec3d& intersectionPointInDomain ) const
|
||||
{
|
||||
auto targetPointInDomain = intersectionPointInDomain;
|
||||
|
||||
cvf::Vec3d domainRayOrigin = rimView->displayCoordTransform()->transformToDomainCoord( pickItem.globalRayOrigin() );
|
||||
cvf::Vec3d domainRayEnd = targetPointInDomain + ( targetPointInDomain - domainRayOrigin );
|
||||
|
||||
cvf::Vec3d hexElementIntersection = findHexElementIntersection( rimView, pickItem, domainRayOrigin, domainRayEnd );
|
||||
CVF_TIGHT_ASSERT( !hexElementIntersection.isUndefined() );
|
||||
if ( !hexElementIntersection.isUndefined() )
|
||||
{
|
||||
targetPointInDomain = hexElementIntersection;
|
||||
}
|
||||
return targetPointInDomain;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicCreateWellTargetsPickEventHandler::addNewTargetToModeledWellPath( const RiuPickItemInfo& pickItem,
|
||||
gsl::not_null<RimWellPathGeometryDef*> wellPathGeometryDef,
|
||||
const cvf::Vec3d& intersectionPointInDomain,
|
||||
const cvf::Vec3d& targetPointInDomain,
|
||||
double azimuth,
|
||||
double inclination )
|
||||
{
|
||||
if ( !m_geometryToAddTargetsTo->firstActiveTarget() )
|
||||
{
|
||||
wellPathGeometryDef->setReferencePointXyz( targetPointInDomain );
|
||||
|
||||
auto wellPathSourceInfo = dynamic_cast<const RivWellPathSourceInfo*>( pickItem.sourceInfo() );
|
||||
if ( wellPathSourceInfo )
|
||||
{
|
||||
double mdAtFirstTarget = wellPathSourceInfo->measuredDepth( pickItem.faceIdx(), intersectionPointInDomain );
|
||||
|
||||
RimModeledWellPath* modeledWellPath = dynamic_cast<RimModeledWellPath*>( wellPathSourceInfo->wellPath() );
|
||||
if ( modeledWellPath )
|
||||
{
|
||||
mdAtFirstTarget += modeledWellPath->geometryDefinition()->mdAtFirstTarget();
|
||||
}
|
||||
|
||||
wellPathGeometryDef->setMdAtFirstTarget( mdAtFirstTarget );
|
||||
}
|
||||
}
|
||||
|
||||
cvf::Vec3d referencePoint = wellPathGeometryDef->anchorPointXyz();
|
||||
cvf::Vec3d relativeTargetPoint = targetPointInDomain - referencePoint;
|
||||
|
||||
RimWellPathTarget* newTarget = new RimWellPathTarget;
|
||||
|
||||
bool doSetAzimuthAndInclination = azimuth != std::numeric_limits<double>::infinity() &&
|
||||
inclination != std::numeric_limits<double>::infinity();
|
||||
if ( doSetAzimuthAndInclination )
|
||||
{
|
||||
newTarget->setAsPointXYZAndTangentTarget( relativeTargetPoint, azimuth, inclination );
|
||||
}
|
||||
else
|
||||
{
|
||||
newTarget->setAsPointTargetXYD(
|
||||
cvf::Vec3d( relativeTargetPoint.x(), relativeTargetPoint.y(), -relativeTargetPoint.z() ) );
|
||||
}
|
||||
|
||||
m_geometryToAddTargetsTo->insertTarget( nullptr, newTarget );
|
||||
m_geometryToAddTargetsTo->updateConnectedEditors();
|
||||
m_geometryToAddTargetsTo->updateWellPathVisualization( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicCreateWellTargetsPickEventHandler::addNewTargetToModeledWellPathLateral(
|
||||
const RiuPickItemInfo& pickItem,
|
||||
gsl::not_null<RimWellPathLateralGeometryDef*> wellPathLateralGeometryDef,
|
||||
const cvf::Vec3d& intersectionPointInDomain,
|
||||
const cvf::Vec3d& targetPointInDomain,
|
||||
double azimuth,
|
||||
double inclination )
|
||||
{
|
||||
auto wellPathSourceInfo = dynamic_cast<const RivWellPathSourceInfo*>( pickItem.sourceInfo() );
|
||||
if ( wellPathSourceInfo )
|
||||
{
|
||||
double mdAtConnection = wellPathSourceInfo->measuredDepth( pickItem.faceIdx(), intersectionPointInDomain );
|
||||
|
||||
wellPathLateralGeometryDef->setParentGeometry( wellPathSourceInfo->wellPath()->wellPathGeometry() );
|
||||
wellPathLateralGeometryDef->setMdAtConnection( mdAtConnection );
|
||||
}
|
||||
cvf::Vec3d referencePoint = wellPathLateralGeometryDef->anchorPointXyz();
|
||||
cvf::Vec3d relativeTargetPoint = targetPointInDomain - referencePoint;
|
||||
|
||||
RimWellPathTarget* newTarget = new RimWellPathTarget;
|
||||
|
||||
bool doSetAzimuthAndInclination = azimuth != std::numeric_limits<double>::infinity() &&
|
||||
inclination != std::numeric_limits<double>::infinity();
|
||||
if ( doSetAzimuthAndInclination )
|
||||
{
|
||||
newTarget->setAsPointXYZAndTangentTarget( cvf::Vec3d( relativeTargetPoint.x(),
|
||||
relativeTargetPoint.y(),
|
||||
relativeTargetPoint.z() ),
|
||||
azimuth,
|
||||
inclination );
|
||||
}
|
||||
else
|
||||
{
|
||||
newTarget->setAsPointTargetXYD(
|
||||
cvf::Vec3d( relativeTargetPoint.x(), relativeTargetPoint.y(), -relativeTargetPoint.z() ) );
|
||||
}
|
||||
|
||||
m_geometryToAddTargetsTo->insertTarget( nullptr, newTarget );
|
||||
m_geometryToAddTargetsTo->updateConnectedEditors();
|
||||
m_geometryToAddTargetsTo->updateWellPathVisualization( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -256,10 +368,18 @@ bool RicCreateWellTargetsPickEventHandler::isGridSourceObject( const cvf::Object
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl::not_null<Rim3dView*> view,
|
||||
const RiuPickItemInfo& pickItem,
|
||||
const cvf::Vec3d& domainRayOrigin,
|
||||
const cvf::Vec3d& domainRayEnd )
|
||||
bool RicCreateWellTargetsPickEventHandler::isValidWellPathSourceObject( const RivWellPathSourceInfo* wellPathSourceInfo )
|
||||
{
|
||||
return wellPathSourceInfo && wellPathSourceInfo->wellPath() && wellPathSourceInfo->wellPath()->wellPathGeometry();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl::not_null<const Rim3dView*> view,
|
||||
const RiuPickItemInfo& pickItem,
|
||||
const cvf::Vec3d& domainRayOrigin,
|
||||
const cvf::Vec3d& domainRayEnd )
|
||||
{
|
||||
auto sourceInfo = dynamic_cast<const RivSourceInfo*>( pickItem.sourceInfo() );
|
||||
auto femSourceInfo = dynamic_cast<const RivFemPickSourceInfo*>( pickItem.sourceInfo() );
|
||||
@@ -273,7 +393,7 @@ cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl
|
||||
{
|
||||
cellIndex = sourceInfo->m_cellFaceFromTriangleMapper->cellIndex( pickItem.faceIdx() );
|
||||
|
||||
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>( view.get() );
|
||||
const RimEclipseView* eclipseView = dynamic_cast<const RimEclipseView*>( view.get() );
|
||||
if ( eclipseView && eclipseView->mainGrid() )
|
||||
{
|
||||
RigGridBase* hitGrid = eclipseView->mainGrid()->gridByIndex( gridIndex );
|
||||
@@ -288,11 +408,11 @@ cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection( gsl
|
||||
{
|
||||
size_t elementIndex = femSourceInfo->triangleToElmMapper()->elementIndex( pickItem.faceIdx() );
|
||||
|
||||
RimGeoMechView* geoMechView = dynamic_cast<RimGeoMechView*>( view.get() );
|
||||
const RimGeoMechView* geoMechView = dynamic_cast<const RimGeoMechView*>( view.get() );
|
||||
if ( geoMechView && geoMechView->femParts() )
|
||||
{
|
||||
RigFemPart* femPart = geoMechView->femParts()->part( femPartIndex );
|
||||
RigElementType elType = femPart->elementType( elementIndex );
|
||||
const RigFemPart* femPart = geoMechView->femParts()->part( femPartIndex );
|
||||
RigElementType elType = femPart->elementType( elementIndex );
|
||||
|
||||
if ( elType == HEX8 || elType == HEX8P )
|
||||
{
|
||||
|
@@ -24,8 +24,12 @@
|
||||
|
||||
#include <gsl/gsl>
|
||||
|
||||
class RimWellPathGeometryDef;
|
||||
class RimWellPathGeometryDefInterface;
|
||||
class RigWellPath;
|
||||
class RiuPickItemInfo;
|
||||
class RivWellPathSourceInfo;
|
||||
class RimWellPathGeometryDef;
|
||||
class RimWellPathLateralGeometryDef;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@@ -33,7 +37,7 @@ class RigWellPath;
|
||||
class RicCreateWellTargetsPickEventHandler : public Ric3dViewPickEventHandler
|
||||
{
|
||||
public:
|
||||
RicCreateWellTargetsPickEventHandler( gsl::not_null<RimWellPathGeometryDef*> wellGeometryDef );
|
||||
RicCreateWellTargetsPickEventHandler( gsl::not_null<RimWellPathGeometryDefInterface*> wellGeometryDef );
|
||||
~RicCreateWellTargetsPickEventHandler();
|
||||
|
||||
void registerAsPickEventHandler() override;
|
||||
@@ -47,13 +51,38 @@ private:
|
||||
gsl::not_null<const RigWellPath*> wellPathGeometry,
|
||||
double* azimuth,
|
||||
double* inclination ) const;
|
||||
bool calculateWellPathGeometryAtPickPoint( const RiuPickItemInfo& pickItem,
|
||||
gsl::not_null<const RivWellPathSourceInfo*> sourceInfo,
|
||||
const cvf::Vec3d& intersectionPointInDomain,
|
||||
gsl::not_null<cvf::Vec3d*> targetPointInDomain,
|
||||
gsl::not_null<double*> azimuth,
|
||||
gsl::not_null<double*> inclination ) const;
|
||||
|
||||
cvf::Vec3d calculateGridPickPoint( gsl::not_null<const Rim3dView*> rimView,
|
||||
const RiuPickItemInfo& pickItem,
|
||||
const cvf::Vec3d& intersectionPointInDomain ) const;
|
||||
|
||||
void addNewTargetToModeledWellPath( const RiuPickItemInfo& pickItem,
|
||||
gsl::not_null<RimWellPathGeometryDef*> wellPathGeometryDef,
|
||||
const cvf::Vec3d& intersectionPointInDomain,
|
||||
const cvf::Vec3d& targetPointInDomain,
|
||||
double azimuth,
|
||||
double inclination );
|
||||
|
||||
void addNewTargetToModeledWellPathLateral( const RiuPickItemInfo& pickItem,
|
||||
gsl::not_null<RimWellPathLateralGeometryDef*> wellPathLateralGeometryDef,
|
||||
const cvf::Vec3d& intersectionPointInDomain,
|
||||
const cvf::Vec3d& targetPointInDomain,
|
||||
double azimuth,
|
||||
double inclination );
|
||||
|
||||
static bool isGridSourceObject( const cvf::Object* object );
|
||||
static cvf::Vec3d findHexElementIntersection( gsl::not_null<Rim3dView*> view,
|
||||
const RiuPickItemInfo& pickItem,
|
||||
const cvf::Vec3d& domainRayOrigin,
|
||||
const cvf::Vec3d& domainRayEnd );
|
||||
static bool isValidWellPathSourceObject( const RivWellPathSourceInfo* sourceInfo );
|
||||
static cvf::Vec3d findHexElementIntersection( gsl::not_null<const Rim3dView*> view,
|
||||
const RiuPickItemInfo& pickItem,
|
||||
const cvf::Vec3d& domainRayOrigin,
|
||||
const cvf::Vec3d& domainRayEnd );
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimWellPathGeometryDef> m_geometryToAddTargetsTo;
|
||||
caf::PdmPointer<RimWellPathGeometryDefInterface> m_geometryToAddTargetsTo;
|
||||
};
|
||||
|
@@ -60,7 +60,7 @@ void RicDeleteWellPathTargetFeature::onActionTriggered( bool isChecked )
|
||||
}
|
||||
|
||||
wellGeomDef->updateConnectedEditors();
|
||||
wellGeomDef->updateWellPathVisualization();
|
||||
wellGeomDef->updateWellPathVisualization( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,129 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimFishbonesCollection.h"
|
||||
#include "RimFishbonesMultipleSubs.h"
|
||||
#include "RimModeledWellPathLateral.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPathGroup.h"
|
||||
#include "RimWellPathLateralGeometryDef.h"
|
||||
|
||||
#include "Riu3DMainWindowTools.h"
|
||||
#include "Riu3dSelectionManager.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicNewWellPathLateralAtDepthFeature, "RicNewWellPathLateralAtDepthFeature" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicNewWellPathLateralAtDepthFeature::isCommandEnabled()
|
||||
{
|
||||
if ( wellPathSelectionItem() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewWellPathLateralAtDepthFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
RiuWellPathSelectionItem* wellPathSelItem = wellPathSelectionItem();
|
||||
CVF_ASSERT( wellPathSelItem );
|
||||
|
||||
RimWellPath* wellPath = wellPathSelItem->m_wellpath;
|
||||
CVF_ASSERT( wellPath );
|
||||
RimWellPathGroup* wellPathGroup = nullptr;
|
||||
wellPath->firstAncestorOrThisOfType( wellPathGroup );
|
||||
|
||||
RimProject* project = RimProject::current();
|
||||
if ( project && RimProject::current()->activeOilField() )
|
||||
{
|
||||
RimWellPathCollection* wellPathCollection = RimProject::current()->activeOilField()->wellPathCollection();
|
||||
|
||||
if ( wellPathCollection )
|
||||
{
|
||||
auto newModeledWellPath = new RimModeledWellPathLateral();
|
||||
|
||||
auto [pointVector, measuredDepths] =
|
||||
wellPath->wellPathGeometry()->clippedPointSubset( wellPath->wellPathGeometry()->measuredDepths().front(),
|
||||
wellPathSelItem->m_measuredDepth );
|
||||
if ( pointVector.size() < 2u ) return;
|
||||
|
||||
newModeledWellPath->geometryDefinition()->setParentGeometry( wellPath->wellPathGeometry() );
|
||||
newModeledWellPath->geometryDefinition()->setMdAtConnection( wellPathSelItem->m_measuredDepth );
|
||||
newModeledWellPath->geometryDefinition()->createTargetAtConnectionPoint(
|
||||
pointVector[pointVector.size() - 1u] - pointVector[pointVector.size() - 2u] );
|
||||
|
||||
newModeledWellPath->geometryDefinition()->enableTargetPointPicking( true );
|
||||
newModeledWellPath->createWellPathGeometry();
|
||||
if ( wellPathGroup )
|
||||
{
|
||||
wellPathGroup->addChildWellPath( newModeledWellPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
wellPathCollection->addWellPath( newModeledWellPath, false );
|
||||
wellPathCollection->groupWellPaths( { wellPath, newModeledWellPath } );
|
||||
}
|
||||
newModeledWellPath->firstAncestorOrThisOfTypeAsserted( wellPathGroup );
|
||||
wellPathGroup->updateAllRequiredEditors();
|
||||
project->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
|
||||
Riu3DMainWindowTools::selectAsCurrentItem( newModeledWellPath->geometryDefinition() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicNewWellPathLateralAtDepthFeature::setupActionLook( QAction* actionToSetup )
|
||||
{
|
||||
actionToSetup->setText( "Create Well Path Lateral at this Depth" );
|
||||
actionToSetup->setIcon( QIcon( ":/Well.svg" ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuWellPathSelectionItem* RicNewWellPathLateralAtDepthFeature::wellPathSelectionItem()
|
||||
{
|
||||
Riu3dSelectionManager* riuSelManager = Riu3dSelectionManager::instance();
|
||||
RiuSelectionItem* selItem = riuSelManager->selectedItem( Riu3dSelectionManager::RUI_TEMPORARY );
|
||||
|
||||
RiuWellPathSelectionItem* wellPathItem = dynamic_cast<RiuWellPathSelectionItem*>( selItem );
|
||||
|
||||
return wellPathItem;
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
class RiuWellPathSelectionItem;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RicNewWellPathLateralAtDepthFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
|
||||
private:
|
||||
static RiuWellPathSelectionItem* wellPathSelectionItem();
|
||||
};
|
@@ -76,7 +76,7 @@ void RicNewWellPathListTargetFeature::onActionTriggered( bool isChecked )
|
||||
|
||||
if ( !afterBeforePair.first && afterBeforePair.second )
|
||||
{
|
||||
if ( afterBeforePair.second->targetPointXYZ().z() == -wellGeomDef->referencePointXyz().z() )
|
||||
if ( afterBeforePair.second->targetPointXYZ().z() == -wellGeomDef->anchorPointXyz().z() )
|
||||
{
|
||||
return; // We already have a target at sealevel.
|
||||
}
|
||||
@@ -93,7 +93,7 @@ void RicNewWellPathListTargetFeature::onActionTriggered( bool isChecked )
|
||||
double horizontalLengthFromTarget = radius - radius * cvf::Math::cos( inc );
|
||||
|
||||
newPos = afterBeforePair.second->targetPointXYZ() - horizontalLengthFromTarget * tangentInHorizontalPlane;
|
||||
newPos.z() = -wellGeomDef->referencePointXyz().z();
|
||||
newPos.z() = -wellGeomDef->anchorPointXyz().z();
|
||||
|
||||
isSeaLevelTarget = true;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ void RicNewWellPathListTargetFeature::onActionTriggered( bool isChecked )
|
||||
|
||||
wellGeomDef->insertTarget( firstTarget, newTarget );
|
||||
wellGeomDef->updateConnectedEditors();
|
||||
wellGeomDef->updateWellPathVisualization();
|
||||
wellGeomDef->updateWellPathVisualization( false );
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ void RicNewWellPathListTargetFeature::onActionTriggered( bool isChecked )
|
||||
}
|
||||
|
||||
wellGeomDef->updateConnectedEditors();
|
||||
wellGeomDef->updateWellPathVisualization();
|
||||
wellGeomDef->updateWellPathVisualization( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -128,12 +128,12 @@ void RicToggleWellPathGrouping::setupActionLook( QAction* actionToSetup )
|
||||
auto wellPaths = selectedWellPaths();
|
||||
if ( containsUngroupedWellPathsWithCommonGeometry( wellPaths ) )
|
||||
{
|
||||
actionToSetup->setText( "Group the selected well paths" );
|
||||
actionToSetup->setText( "Create Multi-Lateral Wells from Selected Well Paths" );
|
||||
actionToSetup->setIcon( QIcon( ":/WellPathGroup.svg" ) );
|
||||
}
|
||||
else if ( containsGroupedWellPaths( wellPaths ) )
|
||||
{
|
||||
actionToSetup->setText( "Ungroup the selected well paths" );
|
||||
actionToSetup->setText( "Detach Selected Well Paths from Multi-Lateral Wells" );
|
||||
actionToSetup->setIcon( QIcon( ":/Well.svg" ) );
|
||||
}
|
||||
}
|
||||
|
@@ -127,5 +127,7 @@ void RivWellPathSourceInfo::normalizedIntersection( size_t triangleIn
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RivWellPathSourceInfo::segmentIndex( size_t triangleIndex ) const
|
||||
{
|
||||
return m_pipeGeomGenerator->segmentIndexFromTriangleIndex( triangleIndex );
|
||||
CAF_ASSERT( m_wellPath.notNull() );
|
||||
return m_pipeGeomGenerator->segmentIndexFromTriangleIndex( triangleIndex ) +
|
||||
m_wellPath->wellPathGeometry()->uniqueStartIndex();
|
||||
}
|
||||
|
@@ -23,10 +23,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPath.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGroup.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPathLateral.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurement.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilePath.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDefInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDef.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathLateralGeometryDef.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttribute.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttributeCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.h
|
||||
@@ -187,10 +190,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPath.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGroup.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPathLateral.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurement.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementFilePath.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDefInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDef.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathLateralGeometryDef.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttribute.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttributeCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.cpp
|
||||
|
@@ -68,8 +68,8 @@ void RimFishboneWellPathCollection::importCompletionsFromFile( const QStringList
|
||||
RifWellPathImporter::WellData wellData = wellPathImporter.readWellData( filePath, i );
|
||||
RimFishboneWellPath* wellCompletion = new RimFishboneWellPath();
|
||||
wellCompletion->setName( wellData.m_name );
|
||||
wellCompletion->setCoordinates( wellData.m_wellPathGeometry->wellPathPoints() );
|
||||
wellCompletion->setMeasuredDepths( wellData.m_wellPathGeometry->measuredDepths() );
|
||||
wellCompletion->setCoordinates( wellData.m_wellPathGeometry->uniqueWellPathPoints() );
|
||||
wellCompletion->setMeasuredDepths( wellData.m_wellPathGeometry->uniqueMeasuredDepths() );
|
||||
appendCompletion( wellCompletion );
|
||||
}
|
||||
}
|
||||
|
@@ -401,8 +401,8 @@ void RimPerforationInterval::defineEditorAttribute( const caf::PdmFieldHandle* f
|
||||
this->firstAncestorOrThisOfType( wellPath );
|
||||
if ( !wellPath ) return;
|
||||
|
||||
myAttr->m_minimum = wellPath->startMD();
|
||||
myAttr->m_maximum = wellPath->endMD();
|
||||
myAttr->m_minimum = wellPath->uniqueStartMD();
|
||||
myAttr->m_maximum = wellPath->uniqueEndMD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -297,8 +297,8 @@ void RimWellPathFracture::defineEditorAttribute( const caf::PdmFieldHandle* fiel
|
||||
this->firstAncestorOrThisOfType( wellPath );
|
||||
if ( !wellPath ) return;
|
||||
|
||||
myAttr->m_minimum = wellPath->startMD();
|
||||
myAttr->m_maximum = wellPath->endMD();
|
||||
myAttr->m_minimum = wellPath->uniqueStartMD();
|
||||
myAttr->m_maximum = wellPath->uniqueEndMD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -55,6 +55,7 @@ RimModeledWellPath::RimModeledWellPath()
|
||||
"",
|
||||
"" );
|
||||
m_geometryDefinition = new RimWellPathGeometryDef;
|
||||
m_geometryDefinition->changed.connect( this, &RimModeledWellPath::onGeometryDefinitionChanged );
|
||||
|
||||
// Required, as these settings are set in RimWellPath()
|
||||
m_name.uiCapability()->setUiReadOnly( false );
|
||||
@@ -192,3 +193,15 @@ void RimModeledWellPath::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
|
||||
uiOrdering.add( &m_name );
|
||||
RimWellPath::defineUiOrdering( uiConfigName, uiOrdering );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPath::onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate )
|
||||
{
|
||||
updateWellPathVisualization();
|
||||
if ( fullUpdate )
|
||||
{
|
||||
scheduleUpdateOfDependentVisualization();
|
||||
}
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@ public:
|
||||
private:
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate );
|
||||
|
||||
caf::PdmChildField<RimWellPathGeometryDef*> m_geometryDefinition;
|
||||
};
|
||||
|
233
ApplicationCode/ProjectDataModel/RimModeledWellPathLateral.cpp
Normal file
233
ApplicationCode/ProjectDataModel/RimModeledWellPathLateral.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimModeledWellPathLateral.h"
|
||||
|
||||
#include "RiaCompletionTypeCalculationScheduler.h"
|
||||
#include "RicfCommandObject.h"
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPathGroup.h"
|
||||
#include "RimWellPathLateralGeometryDef.h"
|
||||
|
||||
#include "RimExtrudedCurveIntersection.h"
|
||||
#include "RimPlotCurve.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathFracture.h"
|
||||
#include "RimWellPathFractureCollection.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimModeledWellPathLateral, "ModeledWellPathLateral" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimModeledWellPathLateral::RimModeledWellPathLateral()
|
||||
{
|
||||
CAF_PDM_InitScriptableObject( "Modeled Well Path Lateral",
|
||||
":/EditableWell.png",
|
||||
"",
|
||||
"A Well Path Lateral created interactively" );
|
||||
|
||||
CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault( &m_geometryDefinition,
|
||||
"WellPathLateralGeometryDef",
|
||||
"WellPathLateralGeometry",
|
||||
"Trajectory",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
m_geometryDefinition = new RimWellPathLateralGeometryDef;
|
||||
m_geometryDefinition->changed.connect( this, &RimModeledWellPathLateral::onGeometryDefinitionChanged );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_lateralName, "LateralName", "Lateral Name", "", "", "" );
|
||||
m_lateralName.registerGetMethod( this, &RimModeledWellPathLateral::createName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimModeledWellPathLateral::~RimModeledWellPathLateral()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPathLateral::createWellPathGeometry()
|
||||
{
|
||||
this->setWellPathGeometry( m_geometryDefinition->createWellPathGeometry().p() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPathLateral::updateWellPathVisualization()
|
||||
{
|
||||
this->setWellPathGeometry( m_geometryDefinition->createWellPathGeometry().p() );
|
||||
|
||||
std::vector<RimPlotCurve*> refferingCurves;
|
||||
this->objectsWithReferringPtrFieldsOfType( refferingCurves );
|
||||
|
||||
for ( auto curve : refferingCurves )
|
||||
{
|
||||
curve->loadDataAndUpdate( false );
|
||||
}
|
||||
|
||||
for ( auto fracture : this->fractureCollection()->activeFractures() )
|
||||
{
|
||||
fracture->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
std::vector<RimExtrudedCurveIntersection*> refferingIntersections;
|
||||
this->objectsWithReferringPtrFieldsOfType( refferingIntersections );
|
||||
|
||||
for ( auto intersection : refferingIntersections )
|
||||
{
|
||||
intersection->rebuildGeometryAndScheduleCreateDisplayModel();
|
||||
}
|
||||
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfTypeAsserted( proj );
|
||||
proj->scheduleCreateDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPathLateral::scheduleUpdateOfDependentVisualization()
|
||||
{
|
||||
RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathLateralGeometryDef* RimModeledWellPathLateral::geometryDefinition() const
|
||||
{
|
||||
return m_geometryDefinition;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimModeledWellPathLateral::wellPlanText()
|
||||
{
|
||||
QString planText;
|
||||
QTextStream qtxtStream( &planText );
|
||||
|
||||
RifTextDataTableFormatter formatter( qtxtStream );
|
||||
formatter.setUnlimitedDataRowWidth();
|
||||
formatter.setTableRowPrependText( "" );
|
||||
formatter.setTableRowLineAppendText( "" );
|
||||
|
||||
std::vector<RifTextDataTableColumn> tableHeader;
|
||||
std::vector<QString> columns = { "MDRKB", "CL", "Inc", "Azi", "TVDMSL", "NS", "EW", "Dogleg", "Build", "Turn" };
|
||||
for ( QString column : columns )
|
||||
{
|
||||
tableHeader.push_back(
|
||||
RifTextDataTableColumn( column,
|
||||
RifTextDataTableDoubleFormatting( RifTextDataTableDoubleFormat::RIF_FLOAT, 2 ) ) );
|
||||
}
|
||||
|
||||
formatter.header( tableHeader );
|
||||
|
||||
double mdrkbAtFirstTarget = m_geometryDefinition->mdAtConnection() + parentGroup()->airGap();
|
||||
if ( m_geometryDefinition )
|
||||
{
|
||||
std::vector<RiaWellPlanCalculator::WellPlanSegment> wellPlan = m_geometryDefinition->wellPlan();
|
||||
for ( const auto& segment : wellPlan )
|
||||
{
|
||||
formatter.add( segment.MD + mdrkbAtFirstTarget );
|
||||
formatter.add( segment.CL );
|
||||
formatter.add( segment.inc );
|
||||
formatter.add( segment.azi );
|
||||
formatter.add( segment.TVD );
|
||||
formatter.add( segment.NS );
|
||||
formatter.add( segment.EW );
|
||||
formatter.add( segment.dogleg );
|
||||
formatter.add( segment.build );
|
||||
formatter.add( segment.turn );
|
||||
formatter.rowCompleted();
|
||||
}
|
||||
}
|
||||
formatter.tableCompleted();
|
||||
|
||||
return planText;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPathGroup* RimModeledWellPathLateral::parentGroup() const
|
||||
{
|
||||
const RimWellPathGroup* group = nullptr;
|
||||
this->firstAncestorOrThisOfTypeAsserted( group );
|
||||
return group;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPathLateral::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName )
|
||||
{
|
||||
uiTreeOrdering.add( m_geometryDefinition() );
|
||||
RimWellPath::defineUiTreeOrdering( uiTreeOrdering, uiConfigName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPathLateral::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_name );
|
||||
RimWellPath::defineUiOrdering( uiConfigName, uiOrdering );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimModeledWellPathLateral::onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate )
|
||||
{
|
||||
updateWellPathVisualization();
|
||||
if ( fullUpdate )
|
||||
{
|
||||
scheduleUpdateOfDependentVisualization();
|
||||
}
|
||||
updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimModeledWellPathLateral::userDescriptionField()
|
||||
{
|
||||
return &m_lateralName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimModeledWellPathLateral::createName() const
|
||||
{
|
||||
return QString( "%1 [branch md=%2]" ).arg( parentGroup()->createGroupName() ).arg( m_geometryDefinition->mdAtConnection() );
|
||||
}
|
55
ApplicationCode/ProjectDataModel/RimModeledWellPathLateral.h
Normal file
55
ApplicationCode/ProjectDataModel/RimModeledWellPathLateral.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimWellPath.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
|
||||
class RimWellPathTarget;
|
||||
class RimWellPath;
|
||||
class RimWellPathGroup;
|
||||
class RimWellPathLateralGeometryDef;
|
||||
|
||||
class RimModeledWellPathLateral : public RimWellPath
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimModeledWellPathLateral();
|
||||
~RimModeledWellPathLateral() override;
|
||||
|
||||
void createWellPathGeometry();
|
||||
void updateWellPathVisualization();
|
||||
void scheduleUpdateOfDependentVisualization();
|
||||
RimWellPathLateralGeometryDef* geometryDefinition() const;
|
||||
QString wellPlanText();
|
||||
|
||||
private:
|
||||
const RimWellPathGroup* parentGroup() const;
|
||||
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void onGeometryDefinitionChanged( const caf::SignalEmitter* emitter, bool fullUpdate );
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
QString createName() const;
|
||||
|
||||
caf::PdmChildField<RimWellPathLateralGeometryDef*> m_geometryDefinition;
|
||||
caf::PdmProxyValueField<QString> m_lateralName;
|
||||
};
|
@@ -362,6 +362,32 @@ double RimWellPath::endMD() const
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPath::uniqueStartMD() const
|
||||
{
|
||||
if ( wellPathGeometry() )
|
||||
{
|
||||
auto uniqueMDs = wellPathGeometry()->uniqueMeasuredDepths();
|
||||
if ( !uniqueMDs.empty() ) return uniqueMDs.front();
|
||||
}
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPath::uniqueEndMD() const
|
||||
{
|
||||
if ( wellPathGeometry() )
|
||||
{
|
||||
auto uniqueMDs = wellPathGeometry()->uniqueMeasuredDepths();
|
||||
if ( !uniqueMDs.empty() ) return uniqueMDs.back();
|
||||
}
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -100,6 +100,9 @@ public:
|
||||
double startMD() const override;
|
||||
double endMD() const override;
|
||||
|
||||
double uniqueStartMD() const;
|
||||
double uniqueEndMD() const;
|
||||
|
||||
void addWellLogFile( RimWellLogFile* logFileInfo );
|
||||
void deleteWellLogFile( RimWellLogFile* logFileInfo );
|
||||
void detachWellLogFile( RimWellLogFile* logFileInfo );
|
||||
|
@@ -86,8 +86,8 @@ bool RimWellPathAttribute::operator<( const RimWellPathAttribute& rhs ) const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathAttribute::setDepthsFromWellPath( gsl::not_null<const RimWellPath*> wellPath )
|
||||
{
|
||||
m_startMD = wellPath->startMD();
|
||||
m_endMD = wellPath->endMD();
|
||||
m_startMD = wellPath->uniqueStartMD();
|
||||
m_endMD = wellPath->uniqueEndMD();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -219,7 +219,6 @@ void RimWellPathCollection::loadDataAndUpdate()
|
||||
|
||||
RimFileWellPath* fWPath = dynamic_cast<RimFileWellPath*>( wellPath );
|
||||
RimModeledWellPath* mWPath = dynamic_cast<RimModeledWellPath*>( wellPath );
|
||||
RimWellPathGroup* branch = dynamic_cast<RimWellPathGroup*>( wellPath );
|
||||
if ( fWPath )
|
||||
{
|
||||
if ( !fWPath->filePath().isEmpty() )
|
||||
@@ -235,10 +234,6 @@ void RimWellPathCollection::loadDataAndUpdate()
|
||||
{
|
||||
mWPath->createWellPathGeometry();
|
||||
}
|
||||
else if ( branch )
|
||||
{
|
||||
branch->updateWellPathName();
|
||||
}
|
||||
|
||||
if ( wellPath )
|
||||
{
|
||||
@@ -393,6 +388,7 @@ void RimWellPathCollection::readAndAddWellPaths( std::vector<RimFileWellPath*>&
|
||||
|
||||
// If a well path with this name exists already, make it read the well path file
|
||||
RimFileWellPath* existingWellPath = dynamic_cast<RimFileWellPath*>( tryFindMatchingWellPath( wellPath->name() ) );
|
||||
|
||||
if ( existingWellPath )
|
||||
{
|
||||
existingWellPath->setFilepath( wellPath->filePath() );
|
||||
@@ -653,11 +649,11 @@ void RimWellPathCollection::deleteAllWellPaths()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathCollection::groupWellPaths( const std::vector<RimWellPath*>& wellPaths, bool allowAddingToExistingGroups )
|
||||
void RimWellPathCollection::groupWellPaths( const std::vector<RimWellPath*>& wellPaths, bool automaticGrouping )
|
||||
{
|
||||
auto detachedWellPaths = detachWellPaths( wellPaths );
|
||||
|
||||
if ( allowAddingToExistingGroups )
|
||||
if ( automaticGrouping )
|
||||
{
|
||||
for ( auto wellPath : allWellPaths() )
|
||||
{
|
||||
@@ -669,11 +665,33 @@ void RimWellPathCollection::groupWellPaths( const std::vector<RimWellPath*>& wel
|
||||
}
|
||||
}
|
||||
|
||||
auto wellPathsToGroupWith = detachedWellPaths;
|
||||
QString multiLateralWellPathPattern = RiaPreferences::current()->multiLateralWellNamePattern();
|
||||
QRegExp re( multiLateralWellPathPattern, Qt::CaseInsensitive, QRegExp::Wildcard );
|
||||
|
||||
std::vector<RimWellPath*> wellPathsToGroup;
|
||||
|
||||
for ( auto wellPath : detachedWellPaths )
|
||||
{
|
||||
auto parentGroup = findOrCreateWellPathGroup( wellPath, wellPathsToGroupWith );
|
||||
caf::PdmObject* parent = nullptr;
|
||||
wellPath->firstAncestorOfType( parent );
|
||||
CAF_ASSERT( !parent );
|
||||
|
||||
if ( !automaticGrouping || re.exactMatch( wellPath->name() ) )
|
||||
{
|
||||
wellPathsToGroup.push_back( wellPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wellPaths.push_back( wellPath );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<RimWellPath*> wellPathsToGroupWith = wellPathsToGroup;
|
||||
|
||||
for ( auto wellPath : wellPathsToGroup )
|
||||
{
|
||||
RimWellPathGroup* parentGroup = findOrCreateWellPathGroup( wellPath, wellPathsToGroupWith );
|
||||
|
||||
if ( parentGroup )
|
||||
{
|
||||
auto groupIsNew = std::find( wellPathsToGroupWith.begin(), wellPathsToGroupWith.end(), parentGroup ) ==
|
||||
@@ -683,7 +701,7 @@ void RimWellPathCollection::groupWellPaths( const std::vector<RimWellPath*>& wel
|
||||
wellPathsToGroupWith.push_back( parentGroup );
|
||||
}
|
||||
}
|
||||
else
|
||||
else if ( std::find( m_wellPaths.begin(), m_wellPaths.end(), wellPath ) == m_wellPaths.end() )
|
||||
{
|
||||
m_wellPaths.push_back( wellPath );
|
||||
}
|
||||
@@ -827,7 +845,7 @@ std::vector<RimWellPathGroup*> RimWellPathCollection::topLevelGroups() const
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathGroup* RimWellPathCollection::findOrCreateWellPathGroup( gsl::not_null<RimWellPath*> wellPath,
|
||||
const std::vector<RimWellPath*>& wellPathsToGroupWith )
|
||||
const std::vector<RimWellPath*>& wellPathsToGroup )
|
||||
{
|
||||
RimWellPathGroup* existingParent = nullptr;
|
||||
wellPath->firstAncestorOfType( existingParent );
|
||||
@@ -839,7 +857,7 @@ RimWellPathGroup* RimWellPathCollection::findOrCreateWellPathGroup( gsl::not_nul
|
||||
const double eps = 1.0e-3;
|
||||
std::map<RimWellPath*, double> wellPathsWithCommonGeometry;
|
||||
|
||||
for ( auto existingWellPath : wellPathsToGroupWith )
|
||||
for ( auto existingWellPath : wellPathsToGroup )
|
||||
{
|
||||
double identicalTubeLength = existingWellPath->wellPathGeometry()->identicalTubeLength( *wellPathGeometry );
|
||||
if ( identicalTubeLength > eps )
|
||||
|
@@ -99,7 +99,7 @@ public:
|
||||
void removeWellPath( gsl::not_null<RimWellPath*> wellPath );
|
||||
|
||||
void deleteAllWellPaths();
|
||||
void groupWellPaths( const std::vector<RimWellPath*>& wellPaths, bool allowAddingToExistingGroups = false );
|
||||
void groupWellPaths( const std::vector<RimWellPath*>& wellPaths, bool automaticGrouping = false );
|
||||
void ungroupWellPaths( const std::vector<RimWellPath*>& wellPaths );
|
||||
|
||||
RimWellPath* mostRecentlyUpdatedWellPath();
|
||||
|
@@ -52,7 +52,8 @@ CAF_PDM_SOURCE_INIT( RimWellPathGeometryDef, "WellPathGeometryDef", "WellPathGeo
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathGeometryDef::RimWellPathGeometryDef()
|
||||
: m_pickTargetsEventHandler( new RicCreateWellTargetsPickEventHandler( this ) )
|
||||
: changed( this )
|
||||
, m_pickTargetsEventHandler( new RicCreateWellTargetsPickEventHandler( this ) )
|
||||
{
|
||||
CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Targets",
|
||||
":/WellTargets.png",
|
||||
@@ -106,7 +107,7 @@ RimWellPathGeometryDef::~RimWellPathGeometryDef()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RimWellPathGeometryDef::referencePointXyz() const
|
||||
cvf::Vec3d RimWellPathGeometryDef::anchorPointXyz() const
|
||||
{
|
||||
cvf::Vec3d xyz( m_referencePointUtmXyd() );
|
||||
xyz.z() = -xyz.z();
|
||||
@@ -185,6 +186,7 @@ cvf::ref<RigWellPath> RimWellPathGeometryDef::createWellPathGeometry()
|
||||
|
||||
return wellPathGeometry;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -197,16 +199,6 @@ std::vector<RiaWellPlanCalculator::WellPlanSegment> RimWellPathGeometryDef::well
|
||||
return wpCalc.wellPlan();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGeometryDef::updateWellPathVisualization()
|
||||
{
|
||||
RimModeledWellPath* modWellPath;
|
||||
this->firstAncestorOrThisOfTypeAsserted( modWellPath );
|
||||
modWellPath->updateWellPathVisualization();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -242,6 +234,8 @@ void RimWellPathGeometryDef::insertTarget( const RimWellPathTarget* targetToInse
|
||||
m_wellTargets.insert( index, targetToInsert );
|
||||
else
|
||||
m_wellTargets.push_back( targetToInsert );
|
||||
|
||||
targetToInsert->moved.connect( this, &RimWellPathGeometryDef::onTargetMoved );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -264,7 +258,7 @@ void RimWellPathGeometryDef::deleteAllTargets()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGeometryDef::appendTarget()
|
||||
RimWellPathTarget* RimWellPathGeometryDef::appendTarget()
|
||||
{
|
||||
RimWellPathTarget* wellPathTarget = nullptr;
|
||||
|
||||
@@ -283,6 +277,8 @@ void RimWellPathGeometryDef::appendTarget()
|
||||
{
|
||||
m_wellTargets.push_back( wellPathTarget );
|
||||
}
|
||||
wellPathTarget->moved.connect( this, &RimWellPathGeometryDef::onTargetMoved );
|
||||
return wellPathTarget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -326,6 +322,14 @@ void RimWellPathGeometryDef::enableTargetPointPicking( bool isEnabling )
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGeometryDef::updateWellPathVisualization( bool fullUpdate )
|
||||
{
|
||||
changed.send( fullUpdate );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -344,16 +348,12 @@ void RimWellPathGeometryDef::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
if ( &m_referencePointUtmXyd == changedField )
|
||||
{
|
||||
std::cout << "fieldChanged" << std::endl;
|
||||
}
|
||||
else if ( changedField == &m_pickPointsEnabled )
|
||||
if ( changedField == &m_pickPointsEnabled )
|
||||
{
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
updateWellPathVisualization();
|
||||
changed.send( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -418,7 +418,7 @@ RiaLineArcWellPathCalculator RimWellPathGeometryDef::lineArcWellPathCalculator()
|
||||
targetDatas.push_back( wellTarget->wellTargetData() );
|
||||
}
|
||||
|
||||
RiaLineArcWellPathCalculator wellPathCalculator( referencePointXyz(), targetDatas );
|
||||
RiaLineArcWellPathCalculator wellPathCalculator( anchorPointXyz(), targetDatas );
|
||||
const std::vector<RiaLineArcWellPathCalculator::WellTargetStatus>& targetStatuses =
|
||||
wellPathCalculator.targetStatuses();
|
||||
|
||||
@@ -474,7 +474,7 @@ void RimWellPathGeometryDef::updateTargetAtSeaLevel()
|
||||
double horizontalLengthFromTarget = radius - radius * cvf::Math::cos( inc );
|
||||
|
||||
newPos = firstTarget->targetPointXYZ() - horizontalLengthFromTarget * tangentInHorizontalPlane;
|
||||
newPos.z() = -referencePointXyz().z();
|
||||
newPos.z() = -anchorPointXyz().z();
|
||||
|
||||
m_autoTargetAtSeaLevel->setAsPointXYZAndTangentTarget( { newPos[0], newPos[1], newPos[2] }, 0, 0 );
|
||||
m_autoTargetAtSeaLevel->setEnabled( true );
|
||||
@@ -571,6 +571,14 @@ void RimWellPathGeometryDef::defineObjectEditorAttribute( QString uiConfigName,
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGeometryDef::onTargetMoved( const caf::SignalEmitter* emitter, bool fullUpdate )
|
||||
{
|
||||
updateWellPathVisualization( fullUpdate );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -17,6 +17,8 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimWellPathGeometryDefInterface.h"
|
||||
|
||||
#include "RiaLineArcWellPathCalculator.h"
|
||||
#include "RiaWellPlanCalculator.h"
|
||||
|
||||
@@ -36,15 +38,18 @@ class RicCreateWellTargetsPickEventHandler;
|
||||
|
||||
class RigWellPath;
|
||||
|
||||
class RimWellPathGeometryDef : public caf::PdmObject
|
||||
class RimWellPathGeometryDef : public RimWellPathGeometryDefInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<bool> changed;
|
||||
|
||||
public:
|
||||
RimWellPathGeometryDef();
|
||||
~RimWellPathGeometryDef() override;
|
||||
|
||||
cvf::Vec3d referencePointXyz() const;
|
||||
cvf::Vec3d anchorPointXyz() const override;
|
||||
void setReferencePointXyz( const cvf::Vec3d& refPointXyz );
|
||||
|
||||
double airGap() const;
|
||||
@@ -52,26 +57,25 @@ public:
|
||||
double mdAtFirstTarget() const;
|
||||
void setMdAtFirstTarget( double mdrkb );
|
||||
|
||||
cvf::ref<RigWellPath> createWellPathGeometry();
|
||||
|
||||
void updateWellPathVisualization();
|
||||
std::pair<RimWellPathTarget*, RimWellPathTarget*>
|
||||
findActiveTargetsAroundInsertionPoint( const RimWellPathTarget* targetToInsertBefore );
|
||||
|
||||
void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert );
|
||||
void deleteTarget( RimWellPathTarget* targetTodelete );
|
||||
void deleteAllTargets();
|
||||
void appendTarget();
|
||||
cvf::ref<RigWellPath> createWellPathGeometry() override;
|
||||
void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert ) override;
|
||||
void deleteTarget( RimWellPathTarget* targetTodelete ) override;
|
||||
void deleteAllTargets() override;
|
||||
RimWellPathTarget* appendTarget() override;
|
||||
|
||||
const RimWellPathTarget* firstActiveTarget() const;
|
||||
const RimWellPathTarget* lastActiveTarget() const;
|
||||
const RimWellPathTarget* firstActiveTarget() const override;
|
||||
const RimWellPathTarget* lastActiveTarget() const override;
|
||||
std::vector<RimWellPathTarget*> activeWellTargets() const override;
|
||||
|
||||
void enableTargetPointPicking( bool isEnabling );
|
||||
void enableTargetPointPicking( bool isEnabling ) override;
|
||||
void updateWellPathVisualization( bool fullUpdate ) override;
|
||||
|
||||
void setUseAutoGeneratedTargetAtSeaLevel( bool autoGenerate );
|
||||
|
||||
std::vector<RiaWellPlanCalculator::WellPlanSegment> wellPlan() const;
|
||||
std::vector<RimWellPathTarget*> activeWellTargets() const;
|
||||
|
||||
protected:
|
||||
void defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget ) override;
|
||||
@@ -82,6 +86,8 @@ protected:
|
||||
|
||||
virtual void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
void onTargetMoved( const caf::SignalEmitter* emitter, bool fullUpdate );
|
||||
|
||||
private:
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
@@ -0,0 +1,21 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimWellPathGeometryDefInterface.h"
|
||||
|
||||
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimWellPathGeometryDefInterface, "WellPathGeometryDefInterface" );
|
@@ -0,0 +1,53 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
class RimWellPath;
|
||||
class RimWellPathTarget;
|
||||
class RicCreateWellTargetsPickEventHandler;
|
||||
|
||||
class RiaLineArcWellPathCalculator;
|
||||
class RigWellPath;
|
||||
|
||||
class RimWellPathGeometryDefInterface : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
virtual cvf::ref<RigWellPath> createWellPathGeometry() = 0;
|
||||
virtual cvf::Vec3d anchorPointXyz() const = 0;
|
||||
virtual void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert ) = 0;
|
||||
virtual void deleteTarget( RimWellPathTarget* targetTodelete ) = 0;
|
||||
virtual void deleteAllTargets() = 0;
|
||||
virtual RimWellPathTarget* appendTarget() = 0;
|
||||
|
||||
virtual const RimWellPathTarget* firstActiveTarget() const = 0;
|
||||
virtual const RimWellPathTarget* lastActiveTarget() const = 0;
|
||||
|
||||
virtual void enableTargetPointPicking( bool isEnabling ) = 0;
|
||||
virtual std::vector<RimWellPathTarget*> activeWellTargets() const = 0;
|
||||
virtual void updateWellPathVisualization( bool fullUpdate ) = 0;
|
||||
|
||||
private:
|
||||
virtual RiaLineArcWellPathCalculator lineArcWellPathCalculator() const = 0;
|
||||
};
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "RiaTextStringTools.h"
|
||||
#include "RigWellPath.h"
|
||||
#include "RimModeledWellPathLateral.h"
|
||||
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
@@ -41,6 +42,8 @@ RimWellPathGroup::RimWellPathGroup()
|
||||
"WellPathGroup",
|
||||
"A Group of Well Paths" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_childWellPaths, "ChildWellPaths", "Child Well Paths", "", "", "" );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_groupName, "GroupName", "Group Name", "", "", "" );
|
||||
m_groupName.registerGetMethod( this, &RimWellPathGroup::createGroupName );
|
||||
setWellPathGeometry( new RigWellPath );
|
||||
}
|
||||
|
||||
@@ -64,7 +67,7 @@ void RimWellPathGroup::addChildWellPath( RimWellPath* wellPath )
|
||||
}
|
||||
wellPath->nameChanged.connect( this, &RimWellPathGroup::onChildNameChanged );
|
||||
|
||||
updateWellPathName();
|
||||
updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -102,7 +105,7 @@ void RimWellPathGroup::removeChildWellPath( RimWellPath* wellPath )
|
||||
geometry->setUniqueStartIndex( 0u );
|
||||
}
|
||||
createWellPathGeometry();
|
||||
updateWellPathName();
|
||||
updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -116,7 +119,7 @@ void RimWellPathGroup::removeAllChildWellPaths()
|
||||
removeChildWellPath( wellPath );
|
||||
}
|
||||
setWellPathGeometry( cvf::ref<RigWellPath>( new RigWellPath ).p() );
|
||||
updateWellPathName();
|
||||
updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -159,6 +162,14 @@ void RimWellPathGroup::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrder
|
||||
uiTreeOrdering.skipRemainingChildren( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimWellPathGroup::userDescriptionField()
|
||||
{
|
||||
return &m_groupName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -175,23 +186,14 @@ std::vector<const RigWellPath*> RimWellPathGroup::wellPathGeometries() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGroup::updateWellPathName()
|
||||
{
|
||||
auto autoName = createWellPathName();
|
||||
setName( autoName );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimWellPathGroup::createWellPathName() const
|
||||
QString RimWellPathGroup::createGroupName() const
|
||||
{
|
||||
QStringList allNames;
|
||||
std::vector<RimWellPath*> descendantWellPaths;
|
||||
this->descendantsOfType( descendantWellPaths );
|
||||
for ( auto wellPath : descendantWellPaths )
|
||||
{
|
||||
if ( !dynamic_cast<RimWellPathGroup*>( wellPath ) )
|
||||
if ( !dynamic_cast<RimWellPathGroup*>( wellPath ) && !dynamic_cast<RimModeledWellPathLateral*>( wellPath ) )
|
||||
{
|
||||
allNames.push_back( wellPath->name() );
|
||||
}
|
||||
@@ -220,7 +222,7 @@ QString RimWellPathGroup::createWellPathName() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathGroup::onChildNameChanged( const caf::SignalEmitter* emitter )
|
||||
{
|
||||
updateWellPathName();
|
||||
updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@@ -36,19 +36,20 @@ public:
|
||||
void removeChildWellPath( RimWellPath* wellPath );
|
||||
void removeAllChildWellPaths();
|
||||
|
||||
void createWellPathGeometry();
|
||||
void updateWellPathName();
|
||||
void makeMoreLevelsIfNecessary();
|
||||
void createWellPathGeometry();
|
||||
void makeMoreLevelsIfNecessary();
|
||||
QString createGroupName() const;
|
||||
|
||||
protected:
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName );
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName );
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
private:
|
||||
std::vector<const RigWellPath*> wellPathGeometries() const;
|
||||
QString createWellPathName() const;
|
||||
|
||||
void onChildNameChanged( const caf::SignalEmitter* emitter );
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimWellPath*> m_childWellPaths;
|
||||
caf::PdmProxyValueField<QString> m_groupName;
|
||||
};
|
||||
|
@@ -0,0 +1,538 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimWellPathLateralGeometryDef.h"
|
||||
|
||||
#include "WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.h"
|
||||
#include "WellPathCommands/RicCreateWellTargetsPickEventHandler.h"
|
||||
|
||||
#include "RiaFieldHandleTools.h"
|
||||
#include "RiaJCurveCalculator.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaOffshoreSphericalCoords.h"
|
||||
#include "RiaPolyArcLineSampler.h"
|
||||
#include "RiaSCurveCalculator.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimWellPathGroup.h"
|
||||
#include "RimWellPathTarget.h"
|
||||
|
||||
#include "RiuViewerCommands.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
#include "cafPdmFieldScriptingCapabilityCvfVec3d.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiDoubleValueEditor.h"
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
#include "cafPdmUiTableViewEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
#include "cvfGeometryTools.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimWellPathLateralGeometryDef, "WellPathLateralGeometryDef", "WellPathLateralGeometry" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaLineArcWellPathCalculator::WellTarget> createTargetsFromPoints( const std::vector<cvf::Vec3d>& points )
|
||||
{
|
||||
CAF_ASSERT( points.size() >= 2u );
|
||||
|
||||
std::vector<RiaLineArcWellPathCalculator::WellTarget> targets;
|
||||
|
||||
for ( size_t i = 0; i < points.size(); ++i )
|
||||
{
|
||||
cvf::Vec3d tangent;
|
||||
if ( i < points.size() - 1u )
|
||||
{
|
||||
tangent = points[i + 1] - points[i];
|
||||
}
|
||||
else if ( i > 0u )
|
||||
{
|
||||
tangent = points[i] - points[i - 1];
|
||||
}
|
||||
RiaOffshoreSphericalCoords sphericalCoords( tangent );
|
||||
|
||||
RiaLineArcWellPathCalculator::WellTarget target =
|
||||
{ points[i], true, sphericalCoords.azi(), sphericalCoords.inc(), 0.0, 0.0 };
|
||||
targets.push_back( target );
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathLateralGeometryDef::RimWellPathLateralGeometryDef()
|
||||
: changed( this )
|
||||
, m_pickTargetsEventHandler( new RicCreateWellTargetsPickEventHandler( this ) )
|
||||
{
|
||||
CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Targets",
|
||||
":/WellTargets.png",
|
||||
"",
|
||||
"",
|
||||
"WellPathLateralGeometry",
|
||||
"Class containing the geometry of a modeled Well Path Lateral" );
|
||||
|
||||
this->setUi3dEditorTypeName( RicWellPathGeometry3dEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_connectionMdOnParentWellPath, "MdAtConnection", 0.0, "MD at Well Path Connection", "", "", "" );
|
||||
m_connectionMdOnParentWellPath.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
|
||||
CAF_PDM_InitScriptableFieldNoDefault( &m_wellTargets, "WellPathTargets", "Well Targets", "", "", "" );
|
||||
m_wellTargets.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
|
||||
m_wellTargets.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_wellTargets.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
|
||||
m_wellTargets.uiCapability()->setCustomContextMenuEnabled( true );
|
||||
|
||||
CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" );
|
||||
caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathLateralGeometryDef::~RimWellPathLateralGeometryDef()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellPathLateralGeometryDef::mdAtConnection() const
|
||||
{
|
||||
return m_connectionMdOnParentWellPath;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::setMdAtConnection( double md )
|
||||
{
|
||||
m_connectionMdOnParentWellPath = md;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RimWellPathLateralGeometryDef::anchorPointXyz() const
|
||||
{
|
||||
CAF_ASSERT( m_parentGeometry.notNull() );
|
||||
return m_parentGeometry->interpolatedPointAlongWellPath( m_connectionMdOnParentWellPath );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::createTargetAtConnectionPoint( const cvf::Vec3d& tangent )
|
||||
{
|
||||
auto target = appendTarget();
|
||||
target->setAsPointXYZAndTangentTarget( cvf::Vec3d::ZERO, tangent );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::setParentGeometry( const RigWellPath* parentGeometry )
|
||||
{
|
||||
m_parentGeometry = parentGeometry;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<RigWellPath> RimWellPathLateralGeometryDef::createWellPathGeometry()
|
||||
{
|
||||
CAF_ASSERT( m_parentGeometry.notNull() );
|
||||
|
||||
cvf::ref<RigWellPath> wellPathLateralGeometry = new RigWellPath;
|
||||
|
||||
RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator();
|
||||
|
||||
auto [allWellPathPoints, allMeasuredDepths] =
|
||||
m_parentGeometry->clippedPointSubset( m_parentGeometry->measuredDepths().front(), m_connectionMdOnParentWellPath );
|
||||
auto originalSize = allWellPathPoints.size();
|
||||
|
||||
if ( wellPathCalculator.lineArcEndpoints().size() >= 2 )
|
||||
{
|
||||
RiaPolyArcLineSampler arcLineSampler( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() );
|
||||
auto [wellPathPoints, measuredDepths] = arcLineSampler.sampledPointsAndMDs( 30, false );
|
||||
allWellPathPoints.insert( allWellPathPoints.end(), wellPathPoints.begin(), wellPathPoints.end() );
|
||||
std::transform( measuredDepths.begin(),
|
||||
measuredDepths.end(),
|
||||
std::back_inserter( allMeasuredDepths ),
|
||||
[this]( double md ) { return md + this->m_connectionMdOnParentWellPath; } );
|
||||
}
|
||||
wellPathLateralGeometry->setWellPathPoints( allWellPathPoints );
|
||||
wellPathLateralGeometry->setMeasuredDepths( allMeasuredDepths );
|
||||
wellPathLateralGeometry->setUniqueStartIndex( originalSize );
|
||||
|
||||
return wellPathLateralGeometry;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaWellPlanCalculator::WellPlanSegment> RimWellPathLateralGeometryDef::wellPlan() const
|
||||
{
|
||||
RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator();
|
||||
|
||||
RiaWellPlanCalculator wpCalc( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() );
|
||||
|
||||
return wpCalc.wellPlan();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::updateWellPathVisualization( bool fullUpdate )
|
||||
{
|
||||
changed.send( fullUpdate );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<RimWellPathTarget*, RimWellPathTarget*>
|
||||
RimWellPathLateralGeometryDef::findActiveTargetsAroundInsertionPoint( const RimWellPathTarget* targetToInsertBefore )
|
||||
{
|
||||
RimWellPathTarget* before = nullptr;
|
||||
RimWellPathTarget* after = nullptr;
|
||||
|
||||
bool foundTarget = false;
|
||||
for ( const auto& wt : m_wellTargets )
|
||||
{
|
||||
if ( wt == targetToInsertBefore )
|
||||
{
|
||||
foundTarget = true;
|
||||
}
|
||||
|
||||
if ( wt->isEnabled() && !after && foundTarget ) after = wt;
|
||||
|
||||
if ( wt->isEnabled() && !foundTarget ) before = wt;
|
||||
}
|
||||
|
||||
return { before, after };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::insertTarget( const RimWellPathTarget* targetToInsertBefore,
|
||||
RimWellPathTarget* targetToInsert )
|
||||
{
|
||||
size_t index = m_wellTargets.index( targetToInsertBefore );
|
||||
if ( index < m_wellTargets.size() )
|
||||
m_wellTargets.insert( index, targetToInsert );
|
||||
else
|
||||
m_wellTargets.push_back( targetToInsert );
|
||||
|
||||
targetToInsert->moved.connect( this, &RimWellPathLateralGeometryDef::onTargetMoved );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::deleteTarget( RimWellPathTarget* targetTodelete )
|
||||
{
|
||||
m_wellTargets.removeChildObject( targetTodelete );
|
||||
delete targetTodelete;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::deleteAllTargets()
|
||||
{
|
||||
m_wellTargets.deleteAllChildObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathTarget* RimWellPathLateralGeometryDef::appendTarget()
|
||||
{
|
||||
RimWellPathTarget* wellPathTarget = nullptr;
|
||||
|
||||
auto targets = m_wellTargets.childObjects();
|
||||
if ( targets.empty() )
|
||||
{
|
||||
wellPathTarget = new RimWellPathTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
wellPathTarget = dynamic_cast<RimWellPathTarget*>(
|
||||
targets.back()->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
|
||||
}
|
||||
|
||||
if ( wellPathTarget )
|
||||
{
|
||||
m_wellTargets.push_back( wellPathTarget );
|
||||
}
|
||||
wellPathTarget->moved.connect( this, &RimWellPathLateralGeometryDef::onTargetMoved );
|
||||
return wellPathTarget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPathTarget* RimWellPathLateralGeometryDef::firstActiveTarget() const
|
||||
{
|
||||
for ( const RimWellPathTarget* target : m_wellTargets )
|
||||
{
|
||||
if ( target->isEnabled() )
|
||||
{
|
||||
return target;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const RimWellPathTarget* RimWellPathLateralGeometryDef::lastActiveTarget() const
|
||||
{
|
||||
if ( !m_wellTargets.size() ) return nullptr;
|
||||
|
||||
for ( int tIdx = static_cast<int>( m_wellTargets.size() - 1 ); tIdx >= 0; --tIdx )
|
||||
{
|
||||
if ( m_wellTargets[tIdx]->isEnabled() )
|
||||
{
|
||||
return m_wellTargets[tIdx];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::enableTargetPointPicking( bool isEnabling )
|
||||
{
|
||||
m_pickPointsEnabled = isEnabling;
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
if ( changedField == &m_pickPointsEnabled )
|
||||
{
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
updateWellPathVisualization( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_connectionMdOnParentWellPath );
|
||||
uiOrdering.add( &m_wellTargets );
|
||||
uiOrdering.add( &m_pickPointsEnabled );
|
||||
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName )
|
||||
{
|
||||
uiTreeOrdering.skipRemainingChildren( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::initAfterRead()
|
||||
{
|
||||
RimWellPathGroup* group = nullptr;
|
||||
this->firstAncestorOrThisOfTypeAsserted( group );
|
||||
this->setParentGeometry( group->wellPathGeometry() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimWellPathTarget*> RimWellPathLateralGeometryDef::activeWellTargets() const
|
||||
{
|
||||
std::vector<RimWellPathTarget*> active;
|
||||
|
||||
for ( const auto& wt : m_wellTargets )
|
||||
{
|
||||
if ( wt->targetType() != RimWellPathTarget::LATERAL_ANCHOR_POINT_MD && wt->isEnabled() )
|
||||
{
|
||||
active.push_back( wt );
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaLineArcWellPathCalculator RimWellPathLateralGeometryDef::lineArcWellPathCalculator() const
|
||||
{
|
||||
std::vector<RiaLineArcWellPathCalculator::WellTarget> targetDatas;
|
||||
|
||||
auto [pointVector, measuredDepths] = m_parentGeometry->clippedPointSubset( 0.0, m_connectionMdOnParentWellPath );
|
||||
|
||||
auto N = pointVector.size();
|
||||
if ( N >= 2u )
|
||||
{
|
||||
targetDatas = createTargetsFromPoints( { pointVector[N - 2], pointVector[N - 1] } );
|
||||
}
|
||||
|
||||
std::vector<RimWellPathTarget*> activeTargets = activeWellTargets();
|
||||
|
||||
for ( auto wellTarget : activeTargets )
|
||||
{
|
||||
targetDatas.push_back( wellTarget->wellTargetData() );
|
||||
}
|
||||
|
||||
cvf::Vec3d connectionPoint = anchorPointXyz();
|
||||
|
||||
RiaLineArcWellPathCalculator wellPathCalculator( connectionPoint, targetDatas );
|
||||
|
||||
const std::vector<RiaLineArcWellPathCalculator::WellTargetStatus>& targetStatuses =
|
||||
wellPathCalculator.targetStatuses();
|
||||
|
||||
for ( size_t tIdx = 0; tIdx < activeTargets.size(); ++tIdx )
|
||||
{
|
||||
activeTargets[tIdx]->flagRadius1AsIncorrect( targetStatuses[tIdx].isRadius1Editable, false, 0 );
|
||||
activeTargets[tIdx]->flagRadius2AsIncorrect( targetStatuses[tIdx].isRadius2Editable, false, 0 );
|
||||
|
||||
if ( targetStatuses[tIdx].hasDerivedTangent )
|
||||
{
|
||||
activeTargets[tIdx]->setDerivedTangent( targetStatuses[tIdx].resultAzimuth,
|
||||
targetStatuses[tIdx].resultInclination );
|
||||
}
|
||||
|
||||
if ( targetStatuses[tIdx].hasOverriddenRadius1 )
|
||||
{
|
||||
activeTargets[tIdx]->flagRadius1AsIncorrect( targetStatuses[tIdx].isRadius1Editable,
|
||||
true,
|
||||
targetStatuses[tIdx].resultRadius1 );
|
||||
}
|
||||
|
||||
if ( targetStatuses[tIdx].hasOverriddenRadius2 )
|
||||
{
|
||||
activeTargets[tIdx]->flagRadius2AsIncorrect( targetStatuses[tIdx].isRadius2Editable,
|
||||
true,
|
||||
targetStatuses[tIdx].resultRadius2 );
|
||||
}
|
||||
}
|
||||
|
||||
return wellPathCalculator;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::onTargetMoved( const caf::SignalEmitter* moved, bool fullUpdate )
|
||||
{
|
||||
changed.send( fullUpdate );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu,
|
||||
QMenu* menu,
|
||||
QWidget* fieldEditorWidget )
|
||||
{
|
||||
caf::CmdFeatureMenuBuilder menuBuilder;
|
||||
|
||||
menuBuilder << "RicNewWellPathListTargetFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicDeleteWellPathTargetFeature";
|
||||
|
||||
menuBuilder.appendToMenu( menu );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
if ( field == &m_pickPointsEnabled )
|
||||
{
|
||||
caf::PdmUiPushButtonEditorAttribute* pbAttribute = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
||||
if ( pbAttribute )
|
||||
{
|
||||
if ( !m_pickPointsEnabled )
|
||||
{
|
||||
pbAttribute->m_buttonText = "Start Picking Targets";
|
||||
}
|
||||
else
|
||||
{
|
||||
pbAttribute->m_buttonText = "Stop Picking Targets";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( field = &m_connectionMdOnParentWellPath )
|
||||
{
|
||||
auto myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
|
||||
if ( myAttr )
|
||||
{
|
||||
myAttr->m_minimum = m_parentGeometry->uniqueMeasuredDepths().front();
|
||||
myAttr->m_maximum = m_parentGeometry->uniqueMeasuredDepths().back();
|
||||
}
|
||||
}
|
||||
else if ( field == &m_wellTargets )
|
||||
{
|
||||
auto tvAttribute = dynamic_cast<caf::PdmUiTableViewEditorAttribute*>( attribute );
|
||||
if ( tvAttribute )
|
||||
{
|
||||
tvAttribute->resizePolicy = caf::PdmUiTableViewEditorAttribute::RESIZE_TO_FIT_CONTENT;
|
||||
|
||||
if ( m_pickPointsEnabled )
|
||||
{
|
||||
tvAttribute->baseColor.setRgb( 255, 220, 255 );
|
||||
tvAttribute->alwaysEnforceResizePolicy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathLateralGeometryDef::defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
RicWellPathGeometry3dEditorAttribute* attrib = dynamic_cast<RicWellPathGeometry3dEditorAttribute*>( attribute );
|
||||
if ( attrib )
|
||||
{
|
||||
attrib->pickEventHandler = m_pickTargetsEventHandler;
|
||||
attrib->enablePicking = m_pickPointsEnabled;
|
||||
}
|
||||
}
|
107
ApplicationCode/ProjectDataModel/RimWellPathLateralGeometryDef.h
Normal file
107
ApplicationCode/ProjectDataModel/RimWellPathLateralGeometryDef.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimWellPathGeometryDefInterface.h"
|
||||
|
||||
#include "RiaLineArcWellPathCalculator.h"
|
||||
#include "RiaWellPlanCalculator.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmFieldCvfVec3d.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
class RimWellPath;
|
||||
class RimWellPathTarget;
|
||||
class RicCreateWellTargetsPickEventHandler;
|
||||
|
||||
class RigWellPath;
|
||||
|
||||
class RimWellPathLateralGeometryDef : public RimWellPathGeometryDefInterface
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<bool> changed;
|
||||
|
||||
public:
|
||||
RimWellPathLateralGeometryDef();
|
||||
~RimWellPathLateralGeometryDef() override;
|
||||
|
||||
double mdAtConnection() const;
|
||||
void setMdAtConnection( double mdrkb );
|
||||
|
||||
cvf::Vec3d anchorPointXyz() const override;
|
||||
|
||||
void createTargetAtConnectionPoint( const cvf::Vec3d& tangent );
|
||||
|
||||
void setParentGeometry( const RigWellPath* parentGeometry );
|
||||
cvf::ref<RigWellPath> createWellPathGeometry();
|
||||
|
||||
void updateWellPathVisualization( bool fullUpdate );
|
||||
std::pair<RimWellPathTarget*, RimWellPathTarget*>
|
||||
findActiveTargetsAroundInsertionPoint( const RimWellPathTarget* targetToInsertBefore );
|
||||
|
||||
void insertTarget( const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert );
|
||||
void deleteTarget( RimWellPathTarget* targetTodelete );
|
||||
void deleteAllTargets();
|
||||
RimWellPathTarget* appendTarget();
|
||||
|
||||
const RimWellPathTarget* firstActiveTarget() const;
|
||||
const RimWellPathTarget* lastActiveTarget() const;
|
||||
|
||||
void enableTargetPointPicking( bool isEnabling );
|
||||
|
||||
std::vector<RiaWellPlanCalculator::WellPlanSegment> wellPlan() const;
|
||||
std::vector<RimWellPathTarget*> activeWellTargets() const;
|
||||
|
||||
protected:
|
||||
void defineCustomContextMenu( const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget ) override;
|
||||
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
private:
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override;
|
||||
|
||||
void initAfterRead() override;
|
||||
|
||||
RiaLineArcWellPathCalculator lineArcWellPathCalculator() const;
|
||||
|
||||
void onTargetMoved( const caf::SignalEmitter* moved, bool fullUpdate );
|
||||
|
||||
private:
|
||||
caf::PdmField<double> m_connectionMdOnParentWellPath;
|
||||
caf::PdmChildArrayField<RimWellPathTarget*> m_wellTargets;
|
||||
caf::PdmField<bool> m_pickPointsEnabled;
|
||||
|
||||
std::shared_ptr<RicCreateWellTargetsPickEventHandler> m_pickTargetsEventHandler;
|
||||
|
||||
cvf::cref<RigWellPath> m_parentGeometry;
|
||||
};
|
@@ -20,7 +20,11 @@
|
||||
|
||||
#include "RiaOffshoreSphericalCoords.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimModeledWellPathLateral.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
|
||||
#include "cafPdmUiCheckBoxEditor.h"
|
||||
@@ -37,6 +41,7 @@ void caf::AppEnum<RimWellPathTarget::TargetTypeEnum>::setUp()
|
||||
{
|
||||
addItem( RimWellPathTarget::POINT_AND_TANGENT, "POINT_AND_TANGENT", "Point and Tangent" );
|
||||
addItem( RimWellPathTarget::POINT, "POINT", "Point" );
|
||||
addItem( RimWellPathTarget::LATERAL_ANCHOR_POINT_MD, "LATERAL_ANCHOR_POINT_MD", "Lateral Anchor Point MD" );
|
||||
setDefault( RimWellPathTarget::POINT_AND_TANGENT );
|
||||
}
|
||||
} // namespace caf
|
||||
@@ -44,7 +49,8 @@ void caf::AppEnum<RimWellPathTarget::TargetTypeEnum>::setUp()
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellPathTarget::RimWellPathTarget()
|
||||
: m_targetType( POINT_AND_TANGENT )
|
||||
: moved( this )
|
||||
, m_targetType( POINT_AND_TANGENT )
|
||||
, m_targetPoint( cvf::Vec3d::ZERO )
|
||||
, m_azimuth( 0.0 )
|
||||
, m_inclination( 0.0 )
|
||||
@@ -61,6 +67,9 @@ RimWellPathTarget::RimWellPathTarget()
|
||||
m_hasTangentConstraintUiField.xmlCapability()->disableIO();
|
||||
CAF_PDM_InitField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", "" );
|
||||
CAF_PDM_InitField( &m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_lateralMDConnection, "LateralMD", 0.0, "Lateral Anchor Point MD", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_parentWellPath, "ParentWellPath", "Parent Well Path", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -97,6 +106,15 @@ void RimWellPathTarget::setAsPointTargetXYD( const cvf::Vec3d& point )
|
||||
m_inclination = 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTarget::setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, const cvf::Vec3d& tangent )
|
||||
{
|
||||
RiaOffshoreSphericalCoords sphericalCoords( tangent );
|
||||
setAsPointXYZAndTangentTarget( point, sphericalCoords.azi(), sphericalCoords.inc() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -108,6 +126,16 @@ void RimWellPathTarget::setAsPointXYZAndTangentTarget( const cvf::Vec3d& point,
|
||||
m_inclination = cvf::Math::toDegrees( inclination );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTarget::setAsLateralMDConnection( RimWellPath* wellPath, double md )
|
||||
{
|
||||
m_targetType = LATERAL_ANCHOR_POINT_MD;
|
||||
m_parentWellPath.setValue( wellPath );
|
||||
m_lateralMDConnection = md;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -150,9 +178,16 @@ RimWellPathTarget::TargetTypeEnum RimWellPathTarget::targetType() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RimWellPathTarget::targetPointXYZ() const
|
||||
{
|
||||
cvf::Vec3d xyzPoint( m_targetPoint() );
|
||||
xyzPoint.z() = -xyzPoint.z();
|
||||
return xyzPoint;
|
||||
if ( m_targetType != LATERAL_ANCHOR_POINT_MD )
|
||||
{
|
||||
cvf::Vec3d xyzPoint( m_targetPoint() );
|
||||
xyzPoint.z() = -xyzPoint.z();
|
||||
return xyzPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_parentWellPath->wellPathGeometry()->interpolatedPointAlongWellPath( m_lateralMDConnection );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -164,6 +199,12 @@ double RimWellPathTarget::azimuth() const
|
||||
{
|
||||
return cvf::Math::toRadians( m_azimuth );
|
||||
}
|
||||
else if ( m_targetType() == LATERAL_ANCHOR_POINT_MD )
|
||||
{
|
||||
auto tangent = m_parentWellPath->wellPathGeometry()->tangentAlongWellPath( m_lateralMDConnection );
|
||||
RiaOffshoreSphericalCoords sphericalCoords( tangent );
|
||||
return cvf::Math::toRadians( sphericalCoords.azi() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
@@ -179,6 +220,12 @@ double RimWellPathTarget::inclination() const
|
||||
{
|
||||
return cvf::Math::toRadians( m_inclination );
|
||||
}
|
||||
else if ( m_targetType() == LATERAL_ANCHOR_POINT_MD )
|
||||
{
|
||||
auto tangent = m_parentWellPath->wellPathGeometry()->tangentAlongWellPath( m_lateralMDConnection );
|
||||
RiaOffshoreSphericalCoords sphericalCoords( tangent );
|
||||
return cvf::Math::toRadians( sphericalCoords.inc() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
@@ -190,6 +237,11 @@ double RimWellPathTarget::inclination() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RimWellPathTarget::tangent() const
|
||||
{
|
||||
if ( m_targetType() == LATERAL_ANCHOR_POINT_MD )
|
||||
{
|
||||
return m_parentWellPath->wellPathGeometry()->tangentAlongWellPath( m_lateralMDConnection );
|
||||
}
|
||||
|
||||
double aziRad = cvf::Math::toRadians( m_azimuth );
|
||||
double incRad = cvf::Math::toRadians( m_inclination );
|
||||
|
||||
@@ -290,6 +342,14 @@ void RimWellPathTarget::flagRadius2AsIncorrect( bool isEditable, bool isIncorrec
|
||||
m_dogleg2.uiCapability()->setUiReadOnly( !isEditable );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellPathTarget::onMoved()
|
||||
{
|
||||
moved.send( m_isFullUpdateEnabled );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -353,13 +413,7 @@ void RimWellPathTarget::fieldChangedByUi( const caf::PdmFieldHandle* changedFiel
|
||||
m_targetType = POINT;
|
||||
}
|
||||
|
||||
RimModeledWellPath* wellPath;
|
||||
firstAncestorOrThisOfTypeAsserted( wellPath );
|
||||
wellPath->updateWellPathVisualization();
|
||||
if ( m_isFullUpdateEnabled )
|
||||
{
|
||||
wellPath->scheduleUpdateOfDependentVisualization();
|
||||
}
|
||||
moved.send( m_isFullUpdateEnabled );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -385,9 +439,6 @@ void RimWellPathTarget::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderi
|
||||
m_azimuth.uiCapability()->setUiReadOnly( false );
|
||||
m_inclination.uiCapability()->setUiReadOnly( false );
|
||||
}
|
||||
|
||||
RimWellPathGeometryDef* geomDef = nullptr;
|
||||
firstAncestorOrThisOfTypeAsserted( geomDef );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -23,12 +23,18 @@
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmCoreVec3d.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
class RimWellPath;
|
||||
|
||||
class RimWellPathTarget : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<bool> moved;
|
||||
|
||||
public:
|
||||
RimWellPathTarget();
|
||||
~RimWellPathTarget() override;
|
||||
@@ -37,7 +43,9 @@ public:
|
||||
bool isEnabled() const;
|
||||
|
||||
void setAsPointTargetXYD( const cvf::Vec3d& point );
|
||||
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, const cvf::Vec3d& tangent );
|
||||
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuth, double inclination );
|
||||
void setAsLateralMDConnection( RimWellPath* wellPath, double md );
|
||||
void setDerivedTangent( double azimuth, double inclination );
|
||||
|
||||
RiaLineArcWellPathCalculator::WellTarget wellTargetData();
|
||||
@@ -45,7 +53,8 @@ public:
|
||||
enum TargetTypeEnum
|
||||
{
|
||||
POINT_AND_TANGENT,
|
||||
POINT
|
||||
POINT,
|
||||
LATERAL_ANCHOR_POINT_MD
|
||||
};
|
||||
TargetTypeEnum targetType() const;
|
||||
cvf::Vec3d targetPointXYZ() const;
|
||||
@@ -57,6 +66,8 @@ public:
|
||||
void flagRadius1AsIncorrect( bool isEditable, bool isIncorrect, double actualRadius );
|
||||
void flagRadius2AsIncorrect( bool isEditable, bool isIncorrect, double actualRadius );
|
||||
|
||||
void onMoved();
|
||||
|
||||
private:
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
@@ -78,4 +89,7 @@ private:
|
||||
caf::PdmField<double> m_dogleg1;
|
||||
caf::PdmField<double> m_dogleg2;
|
||||
caf::PdmField<bool> m_hasTangentConstraintUiField;
|
||||
|
||||
caf::PdmField<double> m_lateralMDConnection;
|
||||
caf::PdmPtrField<RimWellPath*> m_parentWellPath;
|
||||
};
|
||||
|
@@ -539,7 +539,7 @@ void RimStimPlanModel::updateThicknessDirection()
|
||||
}
|
||||
|
||||
wellGeomDef->updateConnectedEditors();
|
||||
wellGeomDef->updateWellPathVisualization();
|
||||
wellGeomDef->updateWellPathVisualization( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -261,6 +261,40 @@ cvf::Vec3d
|
||||
return interpolatedVectorValuesAlongWellPath( m_wellPathPoints, measuredDepth, horizontalLengthAlongWellToStartClipPoint );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RigWellPath::tangentAlongWellPath( double measuredDepth ) const
|
||||
{
|
||||
if ( m_measuredDepths.size() < 2u ) return cvf::Vec3d::UNDEFINED;
|
||||
|
||||
if ( measuredDepth <= m_measuredDepths.front() )
|
||||
{
|
||||
return ( m_wellPathPoints[1] - m_wellPathPoints[0] ).getNormalized();
|
||||
}
|
||||
else if ( measuredDepth >= m_measuredDepths.back() )
|
||||
{
|
||||
auto N = m_measuredDepths.size();
|
||||
return ( m_wellPathPoints[N - 1] - m_wellPathPoints[N - 2] ).getNormalized();
|
||||
}
|
||||
|
||||
for ( size_t i = 1; i < m_measuredDepths.size(); i++ )
|
||||
{
|
||||
cvf::Vec3d point1 = m_wellPathPoints[i - 1];
|
||||
cvf::Vec3d point2 = m_wellPathPoints[i - 0];
|
||||
|
||||
double md1 = m_measuredDepths[i - 1];
|
||||
double md2 = m_measuredDepths[i];
|
||||
|
||||
if ( measuredDepth >= md1 && measuredDepth < md2 )
|
||||
{
|
||||
return ( point2 - point1 ).getNormalized();
|
||||
}
|
||||
}
|
||||
|
||||
return cvf::Vec3d::UNDEFINED;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -430,6 +464,14 @@ void RigWellPath::setUniqueStartIndex( size_t uniqueStartIndex )
|
||||
m_startIndex = uniqueStartIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigWellPath::uniqueStartIndex() const
|
||||
{
|
||||
return m_startIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -438,6 +480,14 @@ std::vector<cvf::Vec3d> RigWellPath::uniqueWellPathPoints() const
|
||||
return std::vector<cvf::Vec3d>( m_wellPathPoints.begin() + m_startIndex, m_wellPathPoints.end() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RigWellPath::uniqueMeasuredDepths() const
|
||||
{
|
||||
return std::vector<double>( m_measuredDepths.begin() + m_startIndex, m_measuredDepths.end() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -454,7 +504,7 @@ std::pair<std::vector<cvf::Vec3d>, std::vector<double>>
|
||||
for ( size_t i = 0; i < m_measuredDepths.size(); ++i )
|
||||
{
|
||||
double measuredDepth = m_measuredDepths[i];
|
||||
if ( measuredDepth > startMD && measuredDepth < endMD )
|
||||
if ( measuredDepth > startMD && measuredDepth <= endMD )
|
||||
{
|
||||
pointsAndMDs.first.push_back( m_wellPathPoints[i] );
|
||||
pointsAndMDs.second.push_back( measuredDepth );
|
||||
|
@@ -66,13 +66,17 @@ public:
|
||||
cvf::Vec3d interpolatedPointAlongWellPath( double measuredDepth,
|
||||
double* horizontalLengthAlongWellToStartClipPoint = nullptr ) const;
|
||||
|
||||
cvf::Vec3d tangentAlongWellPath( double measuredDepth ) const;
|
||||
|
||||
double wellPathAzimuthAngle( const cvf::Vec3d& position ) const;
|
||||
void twoClosestPoints( const cvf::Vec3d& position, cvf::Vec3d* p1, cvf::Vec3d* p2 ) const;
|
||||
double identicalTubeLength( const RigWellPath& otherWellPathGeometry ) const;
|
||||
|
||||
static cvf::ref<RigWellPath> commonGeometry( const std::vector<const RigWellPath*>& allGeometries );
|
||||
void setUniqueStartIndex( size_t uniqueStartIndex );
|
||||
size_t uniqueStartIndex() const;
|
||||
std::vector<cvf::Vec3d> uniqueWellPathPoints() const;
|
||||
std::vector<double> uniqueMeasuredDepths() const;
|
||||
|
||||
std::pair<std::vector<cvf::Vec3d>, std::vector<double>>
|
||||
clippedPointSubset( double startMD, double endMD, double* horizontalLengthAlongWellToStartClipPoint = nullptr ) const;
|
||||
|
@@ -534,7 +534,7 @@ void RiuViewerCommands::displayContextMenu( QMouseEvent* event )
|
||||
menuBuilder.subMenuEnd();
|
||||
|
||||
menuBuilder.addSeparator();
|
||||
|
||||
menuBuilder << "RicNewWellPathLateralAtDepthFeature";
|
||||
menuBuilder << "RicNewWellPathIntersectionFeature";
|
||||
}
|
||||
|
||||
|
@@ -67,7 +67,7 @@ void PdmFieldScriptingCapabilityIOHandler<QString>::writeToField( QString&
|
||||
while ( !inputStream.atEnd() )
|
||||
{
|
||||
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
|
||||
if ( currentChar != QChar( '\\' ) )
|
||||
if ( currentChar > 1 && currentChar != QChar( '\\' ) )
|
||||
{
|
||||
if ( currentChar == QChar( '"' ) ) // End Quote
|
||||
{
|
||||
|
@@ -27,7 +27,8 @@ DataType* PdmChildArrayField<DataType*>::operator[]( size_t index ) const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Assign a regular raw pointer. This method should be considered private.
|
||||
/// External use should be considered deprecated.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
void PdmChildArrayField<DataType*>::push_back( DataType* pointer )
|
||||
@@ -39,7 +40,8 @@ void PdmChildArrayField<DataType*>::push_back( DataType* pointer )
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Assign a unique pointer and take ownership.
|
||||
/// This should be preferred over the method taking a raw pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
void PdmChildArrayField<DataType*>::push_back( DataTypeUniquePtr pointer )
|
||||
|
@@ -80,7 +80,8 @@ caf::PdmChildField<DataType*>::~PdmChildField()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Assign a regular raw pointer. This method should be considered private.
|
||||
/// External use should be considered deprecated.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
caf::PdmChildField<DataType*>& PdmChildField<DataType*>::operator=( const DataTypePtr& fieldValue )
|
||||
@@ -94,7 +95,8 @@ caf::PdmChildField<DataType*>& PdmChildField<DataType*>::operator=( const DataTy
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Assign a unique pointer and take ownership.
|
||||
/// This should be preferred over the method taking a raw pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
caf::PdmChildField<DataType*>& PdmChildField<DataType*>::operator=( DataTypeUniquePtr fieldValue )
|
||||
@@ -103,7 +105,8 @@ caf::PdmChildField<DataType*>& PdmChildField<DataType*>::operator=( DataTypeUniq
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Assign a regular raw pointer. This method should be considered private.
|
||||
/// External use should be considered deprecated.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
void caf::PdmChildField<DataType*>::setValue( const DataTypePtr& fieldValue )
|
||||
@@ -114,7 +117,8 @@ void caf::PdmChildField<DataType*>::setValue( const DataTypePtr& fieldValue )
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Assign a unique pointer and take ownership.
|
||||
/// This should be preferred over the method taking a raw pointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
void caf::PdmChildField<DataType*>::setValue( DataTypeUniquePtr fieldValue )
|
||||
|
Reference in New Issue
Block a user