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:
Gaute Lindkvist
2021-01-04 11:09:01 +01:00
committed by GitHub
parent 73925e6e20
commit 72614b0c00
48 changed files with 1925 additions and 209 deletions

1
.gitignore vendored
View File

@@ -25,6 +25,7 @@ CMakeCache.txt
cmake_install.cmake
CPack*.cmake
CTest*.cmake
cmakebuild/
#Unit test binaries
*_UnitTests

View File

@@ -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*";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View 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;
};

View File

@@ -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

View File

@@ -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 )
{

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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 )
{

View File

@@ -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;
};

View File

@@ -60,7 +60,7 @@ void RicDeleteWellPathTargetFeature::onActionTriggered( bool isChecked )
}
wellGeomDef->updateConnectedEditors();
wellGeomDef->updateWellPathVisualization();
wellGeomDef->updateWellPathVisualization( false );
}
}

View File

@@ -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;
}

View File

@@ -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();
};

View File

@@ -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 );
}
}

View File

@@ -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" ) );
}
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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 );
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}

View File

@@ -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;
};

View 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() );
}

View 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;
};

View File

@@ -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();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -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 );

View File

@@ -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();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -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 )

View File

@@ -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();

View File

@@ -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 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -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;

View File

@@ -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" );

View File

@@ -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;
};

View File

@@ -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();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -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;
};

View File

@@ -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;
}
}

View 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;
};

View File

@@ -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
{

View File

@@ -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;
};

View File

@@ -539,7 +539,7 @@ void RimStimPlanModel::updateThicknessDirection()
}
wellGeomDef->updateConnectedEditors();
wellGeomDef->updateWellPathVisualization();
wellGeomDef->updateWellPathVisualization( false );
}
}

View File

@@ -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 );

View File

@@ -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;

View File

@@ -534,7 +534,7 @@ void RiuViewerCommands::displayContextMenu( QMouseEvent* event )
menuBuilder.subMenuEnd();
menuBuilder.addSeparator();
menuBuilder << "RicNewWellPathLateralAtDepthFeature";
menuBuilder << "RicNewWellPathIntersectionFeature";
}

View File

@@ -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
{

View File

@@ -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 )

View File

@@ -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 )