Improve well path target configuration (#8570)

Improve the scripting possibilities for well targets
Added tests and examples
This commit is contained in:
Magne Sjaastad
2022-02-19 13:18:49 +01:00
committed by GitHub
parent 0b5bc2ba68
commit 5c72d31cc9
10 changed files with 326 additions and 263 deletions

View File

@@ -43,8 +43,7 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
{
m_lineArcEndpoints.push_back( activeWellPathTargets[0].targetPointXYZ + referencePointXyz );
m_targetStatuses.resize( activeWellPathTargets.size(),
{ !activeWellPathTargets[0].isTangentConstrained,
0.0,
{ 0.0,
0.0,
false,
true,
@@ -58,8 +57,7 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
}
m_targetStatuses.resize( activeWellPathTargets.size(),
{ false,
0.0,
{ 0.0,
0.0,
false,
false,
@@ -76,20 +74,22 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
{
for ( size_t tIdx = 0; tIdx < activeWellPathTargets.size() - 2; ++tIdx )
{
if ( !activeWellPathTargets[tIdx + 1].isTangentConstrained )
{
cvf::Vec3d tangent = smootheningTargetTangent( activeWellPathTargets[tIdx].targetPointXYZ,
activeWellPathTargets[tIdx + 1].targetPointXYZ,
activeWellPathTargets[tIdx + 2].targetPointXYZ );
RiaOffshoreSphericalCoords tangentSphCS( tangent );
adjustedWellPathTargets[tIdx + 1].azimuth = tangentSphCS.azi();
adjustedWellPathTargets[tIdx + 1].inclination = tangentSphCS.inc();
adjustedWellPathTargets[tIdx + 1].isTangentConstrained = true;
cvf::Vec3d tangent = smootheningTargetTangent( activeWellPathTargets[tIdx].targetPointXYZ,
activeWellPathTargets[tIdx + 1].targetPointXYZ,
activeWellPathTargets[tIdx + 2].targetPointXYZ );
m_targetStatuses[tIdx + 1].hasDerivedTangent = true;
m_targetStatuses[tIdx + 1].resultAzimuth = tangentSphCS.azi();
m_targetStatuses[tIdx + 1].resultInclination = tangentSphCS.inc();
}
RiaOffshoreSphericalCoords tangentSphCS( tangent );
if ( !adjustedWellPathTargets[tIdx + 1].isAzimuthConstrained )
adjustedWellPathTargets[tIdx + 1].azimuthRadians = tangentSphCS.azi();
if ( !adjustedWellPathTargets[tIdx + 1].isInclinationConstrained )
adjustedWellPathTargets[tIdx + 1].inclinationRadians = tangentSphCS.inc();
adjustedWellPathTargets[tIdx + 1].isAzimuthConstrained = true;
adjustedWellPathTargets[tIdx + 1].isInclinationConstrained = true;
m_targetStatuses[tIdx + 1].resultAzimuthRadians = adjustedWellPathTargets[tIdx + 1].azimuthRadians;
m_targetStatuses[tIdx + 1].resultInclinationRadians = adjustedWellPathTargets[tIdx + 1].inclinationRadians;
}
}
@@ -100,7 +100,7 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
size_t startSSegmentIdx = 0;
size_t endSSegementIdx = activeWellPathTargets.size() - 1;
if ( !adjustedWellPathTargets[0].isTangentConstrained )
if ( !adjustedWellPathTargets[0].isAnyDirectionFixed() )
{
startSSegmentIdx = 1;
@@ -109,13 +109,13 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
WellTargetStatus& target1Status = m_targetStatuses[0];
WellTargetStatus& target2Status = m_targetStatuses[1];
if ( adjustedWellPathTargets[1].isTangentConstrained )
if ( adjustedWellPathTargets[1].isAnyDirectionFixed() )
{
// Create an upside down J curve from target 2 back to 1
RiaJCurveCalculator jCurve( target2.targetPointXYZ,
target2.azimuth + M_PI,
M_PI - target2.inclination,
target2.azimuthRadians + M_PI,
M_PI - target2.inclinationRadians,
target2.radius1,
target1.targetPointXYZ );
@@ -126,14 +126,13 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE )
{
target2Status.hasOverriddenRadius1 = true;
target2Status.resultRadius1 = jCurve.radius();
}
target2Status.resultRadius1 = jCurve.radius();
m_lineArcEndpoints.push_back( target2.targetPointXYZ + referencePointXyz );
target1Status.hasDerivedTangent = true;
target1Status.resultAzimuth = jCurve.endAzimuth() + M_PI;
target1Status.resultInclination = M_PI - jCurve.endInclination();
target1Status.resultAzimuthRadians = jCurve.endAzimuth() + M_PI;
target1Status.resultInclinationRadians = M_PI - jCurve.endInclination();
target2Status.isRadius1Editable = true;
}
@@ -143,25 +142,23 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
cvf::Vec3d t12 = target2.targetPointXYZ - target1.targetPointXYZ;
RiaOffshoreSphericalCoords t12Sph( t12 );
target1Status.hasDerivedTangent = true;
target1Status.resultAzimuth = t12Sph.azi();
target1Status.resultInclination = t12Sph.inc();
target1Status.resultAzimuthRadians = t12Sph.azi();
target1Status.resultInclinationRadians = t12Sph.inc();
target2Status.hasDerivedTangent = true;
target2Status.resultAzimuth = t12Sph.azi();
target2Status.resultInclination = t12Sph.inc();
target2Status.resultAzimuthRadians = t12Sph.azi();
target2Status.resultInclinationRadians = t12Sph.inc();
}
m_startTangent = RiaOffshoreSphericalCoords::unitVectorFromAziInc( target1Status.resultAzimuth,
target1Status.resultInclination );
m_startTangent = RiaOffshoreSphericalCoords::unitVectorFromAziInc( target1Status.resultAzimuthRadians,
target1Status.resultInclinationRadians );
}
else
{
m_startTangent = RiaOffshoreSphericalCoords::unitVectorFromAziInc( activeWellPathTargets[0].azimuth,
activeWellPathTargets[0].inclination );
m_startTangent = RiaOffshoreSphericalCoords::unitVectorFromAziInc( activeWellPathTargets[0].azimuthRadians,
activeWellPathTargets[0].inclinationRadians );
}
if ( !adjustedWellPathTargets.back().isTangentConstrained )
if ( !adjustedWellPathTargets.back().isAnyDirectionFixed() )
{
endSSegementIdx -= 1;
}
@@ -180,45 +177,44 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
// Ignore targets in the same place
if ( ( target1.targetPointXYZ - target2.targetPointXYZ ).length() < 1e-6 ) continue;
if ( target1.isTangentConstrained && target2.isTangentConstrained )
if ( target1.isAnyDirectionFixed() && target2.isAnyDirectionFixed() )
{
RiaSCurveCalculator sCurveCalc( target1.targetPointXYZ,
target1.azimuth,
target1.inclination,
target1.azimuthRadians,
target1.inclinationRadians,
target1.radius2,
target2.targetPointXYZ,
target2.azimuth,
target2.inclination,
target2.azimuthRadians,
target2.inclinationRadians,
target2.radius1 );
if ( sCurveCalc.solveStatus() != RiaSCurveCalculator::CONVERGED )
{
double p1p2Length = ( target2.targetPointXYZ - target1.targetPointXYZ ).length();
sCurveCalc = RiaSCurveCalculator::fromTangentsAndLength( target1.targetPointXYZ,
target1.azimuth,
target1.inclination,
target1.azimuthRadians,
target1.inclinationRadians,
0.2 * p1p2Length,
target2.targetPointXYZ,
target2.azimuth,
target2.inclination,
target2.azimuthRadians,
target2.inclinationRadians,
0.2 * p1p2Length );
// RiaLogging::warning("Using fall-back calculation of well path geometry between active target
// number: " + QString::number(tIdx+1) + " and " + QString::number(tIdx+2));
target1Status.hasOverriddenRadius2 = true;
target1Status.resultRadius2 = sCurveCalc.firstRadius();
target2Status.hasOverriddenRadius1 = true;
target2Status.resultRadius1 = sCurveCalc.secondRadius();
}
target2Status.resultRadius1 = sCurveCalc.secondRadius();
target1Status.resultRadius2 = sCurveCalc.firstRadius();
target2Status.isRadius1Editable = true;
target1Status.isRadius2Editable = true;
m_lineArcEndpoints.push_back( sCurveCalc.firstArcEndpoint() + referencePointXyz );
m_lineArcEndpoints.push_back( sCurveCalc.secondArcStartpoint() + referencePointXyz );
m_lineArcEndpoints.push_back( target2.targetPointXYZ + referencePointXyz );
target1Status.isRadius2Editable = true;
target2Status.isRadius1Editable = true;
}
}
}
@@ -236,8 +232,8 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
// Create an ordinary J curve
RiaJCurveCalculator jCurve( target1.targetPointXYZ,
target1.azimuth,
target1.inclination,
target1.azimuthRadians,
target1.inclinationRadians,
target1.radius2,
target2.targetPointXYZ );
@@ -248,16 +244,15 @@ RiaLineArcWellPathCalculator::RiaLineArcWellPathCalculator( const cvf::Vec3d&
else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE )
{
target1Status.hasOverriddenRadius2 = true;
target1Status.resultRadius2 = jCurve.radius();
}
target1Status.resultRadius2 = jCurve.radius();
target1Status.isRadius2Editable = true;
m_lineArcEndpoints.push_back( target2.targetPointXYZ + referencePointXyz );
target1Status.isRadius2Editable = true;
target2Status.hasDerivedTangent = true;
target2Status.resultAzimuth = jCurve.endAzimuth();
target2Status.resultInclination = jCurve.endInclination();
target2Status.resultAzimuthRadians = jCurve.endAzimuth();
target2Status.resultInclinationRadians = jCurve.endInclination();
}
}

View File

@@ -27,10 +27,13 @@ class RiaLineArcWellPathCalculator
public:
struct WellTarget
{
bool isAnyDirectionFixed() const { return isAzimuthConstrained || isInclinationConstrained; }
cvf::Vec3d targetPointXYZ;
bool isTangentConstrained;
double azimuth;
double inclination;
bool isAzimuthConstrained;
bool isInclinationConstrained;
double azimuthRadians;
double inclinationRadians;
double radius1;
double radius2;
@@ -41,9 +44,8 @@ public:
struct WellTargetStatus
{
bool hasDerivedTangent;
double resultAzimuth;
double resultInclination;
double resultAzimuthRadians;
double resultInclinationRadians;
bool isRadius1Editable;
bool hasOverriddenRadius1;

View File

@@ -624,28 +624,16 @@ RiaLineArcWellPathCalculator RimWellPathGeometryDef::lineArcWellPathCalculator()
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 );
activeTargets[tIdx]->setDerivedTangent( targetStatuses[tIdx].resultAzimuthRadians,
targetStatuses[tIdx].resultInclinationRadians );
if ( targetStatuses[tIdx].hasDerivedTangent )
{
activeTargets[tIdx]->setDerivedTangent( targetStatuses[tIdx].resultAzimuth,
targetStatuses[tIdx].resultInclination );
}
activeTargets[tIdx]->setRadius1Data( targetStatuses[tIdx].isRadius1Editable,
targetStatuses[tIdx].hasOverriddenRadius1,
targetStatuses[tIdx].resultRadius1 );
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 );
}
activeTargets[tIdx]->setRadius2Data( targetStatuses[tIdx].isRadius2Editable,
targetStatuses[tIdx].hasOverriddenRadius2,
targetStatuses[tIdx].resultRadius2 );
}
return wellPathCalculator;

View File

@@ -23,6 +23,7 @@
#include "RigWellPath.h"
#include "RimModeledWellPath.h"
#include "RimProject.h"
#include "RimWellPath.h"
#include "RimWellPathGeometryDef.h"
@@ -51,10 +52,6 @@ void caf::AppEnum<RimWellPathTarget::TargetTypeEnum>::setUp()
//--------------------------------------------------------------------------------------------------
RimWellPathTarget::RimWellPathTarget()
: moved( this )
, m_targetType( TargetTypeEnum::POINT )
, m_targetPointXYD( cvf::Vec3d::ZERO )
, m_azimuth( 0.0 )
, m_inclination( 0.0 )
, m_isFullUpdateEnabled( true )
{
CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Target",
@@ -65,8 +62,6 @@ RimWellPathTarget::RimWellPathTarget()
"Class containing the Well Target definition" );
CAF_PDM_InitField( &m_isEnabled, "IsEnabled", true, "" );
CAF_PDM_InitField( &m_isLocked, "IsLocked", false, "" );
m_isLocked.uiCapability()->setUiHidden( true );
CAF_PDM_InitScriptableFieldNoDefault( &m_targetPointXYD, "TargetPoint", "Relative Coord" );
CAF_PDM_InitFieldNoDefault( &m_targetPointForDisplay, "TargetPointForDisplay", "UTM Coord" );
@@ -79,13 +74,28 @@ RimWellPathTarget::RimWellPathTarget()
CAF_PDM_InitScriptableField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" );
CAF_PDM_InitScriptableField( &m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", "" );
CAF_PDM_InitFieldNoDefault( &m_targetType, "TargetType", "Type" );
m_targetType.uiCapability()->setUiHidden( true );
CAF_PDM_InitScriptableField( &m_useFixedAzimuth, "UseFixedAzimuth", false, "Azi" );
CAF_PDM_InitScriptableField( &m_azimuthDeg, "Azimuth", 0.0, "Azi(deg)" );
CAF_PDM_InitField( &m_hasTangentConstraintUiField, "HasTangentConstraint", false, "Dir" );
m_hasTangentConstraintUiField.xmlCapability()->disableIO();
CAF_PDM_InitScriptableField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)" );
CAF_PDM_InitScriptableField( &m_inclination, "Inclination", 0.0, "Inc(deg)" );
CAF_PDM_InitScriptableField( &m_useFixedInclination, "UseFixedInclination", false, "Inc" );
CAF_PDM_InitScriptableField( &m_inclinationDeg, "Inclination", 0.0, "Inc(deg)" );
CAF_PDM_InitScriptableField( &m_estimatedDogleg1, "EstimatedDogleg1", 0.0, "Est DL in", "", "[deg/30m]", "" );
m_estimatedDogleg1.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitScriptableField( &m_estimatedDogleg2, "EstimatedDogleg2", 0.0, "Est DL out", "", "[deg/30m]", "" );
m_estimatedDogleg2.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitScriptableField( &m_estimatedAzimuthDeg, "EstimatedAzimuth", 0.0, "Est Azi(deg)" );
m_estimatedAzimuthDeg.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitScriptableField( &m_estimatedInclinationDeg, "EstimatedInclination", 0.0, "Est Inc(deg)" );
m_estimatedInclinationDeg.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitFieldNoDefault( &m_targetType_OBSOLETE, "TargetType", "Type" );
m_targetType_OBSOLETE.uiCapability()->setUiHidden( true );
m_targetType_OBSOLETE.xmlCapability()->setIOWritable( false );
CAF_PDM_InitField( &m_hasTangentConstraintUiField_OBSOLETE, "HasTangentConstraint", false, "Dir" );
m_hasTangentConstraintUiField_OBSOLETE.xmlCapability()->setIOWritable( false );
m_hasTangentConstraintUiField_OBSOLETE.uiCapability()->setUiHidden( true );
}
//--------------------------------------------------------------------------------------------------
@@ -124,10 +134,12 @@ void RimWellPathTarget::setPointXYZ( const cvf::Vec3d& point )
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setAsPointTargetXYD( const cvf::Vec3d& point )
{
m_targetType = TargetTypeEnum::POINT;
m_targetPointXYD = point;
m_azimuth = 0.0;
m_inclination = 0.0;
m_useFixedAzimuth = false;
m_useFixedInclination = false;
m_azimuthDeg = 0.0;
m_inclinationDeg = 0.0;
}
//--------------------------------------------------------------------------------------------------
@@ -135,10 +147,12 @@ void RimWellPathTarget::setAsPointTargetXYD( const cvf::Vec3d& point )
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setAsPointTargetXYZ( const cvf::Vec3d& point )
{
m_targetType = TargetTypeEnum::POINT;
m_targetPointXYD = cvf::Vec3d( point.x(), point.y(), -point.z() );
m_azimuth = 0.0;
m_inclination = 0.0;
m_useFixedAzimuth = false;
m_useFixedInclination = false;
m_azimuthDeg = 0.0;
m_inclinationDeg = 0.0;
}
//--------------------------------------------------------------------------------------------------
@@ -153,24 +167,46 @@ void RimWellPathTarget::setAsPointXYZAndTangentTarget( const cvf::Vec3d& point,
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuth, double inclination )
void RimWellPathTarget::setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuthRadians, double inclinationRadians )
{
m_targetType = TargetTypeEnum::POINT_AND_TANGENT;
m_targetType_OBSOLETE = TargetTypeEnum::POINT_AND_TANGENT;
m_targetPointXYD = cvf::Vec3d( point.x(), point.y(), -point.z() );
m_azimuth = cvf::Math::toDegrees( azimuth );
m_inclination = cvf::Math::toDegrees( inclination );
m_useFixedAzimuth = true;
m_useFixedInclination = true;
m_azimuthDeg = cvf::Math::toDegrees( azimuthRadians );
m_inclinationDeg = cvf::Math::toDegrees( inclinationRadians );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setDerivedTangent( double azimuth, double inclination )
void RimWellPathTarget::setFixedAzimuth( double fixedAzimuthDeg )
{
if ( m_targetType == TargetTypeEnum::POINT )
{
m_azimuth = cvf::Math::toDegrees( azimuth );
m_inclination = cvf::Math::toDegrees( inclination );
}
m_useFixedAzimuth = true;
m_azimuthDeg = fixedAzimuthDeg;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setFixedInclination( double fixedInclinationDeg )
{
m_useFixedInclination = true;
m_inclinationDeg = fixedInclinationDeg;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::setDerivedTangent( double azimuthRadians, double inclinationRadians )
{
m_estimatedAzimuthDeg = cvf::Math::toDegrees( azimuthRadians );
m_estimatedInclinationDeg = cvf::Math::toDegrees( inclinationRadians );
if ( !m_useFixedAzimuth ) m_azimuthDeg = cvf::Math::toDegrees( azimuthRadians );
if ( !m_useFixedInclination ) m_inclinationDeg = cvf::Math::toDegrees( inclinationRadians );
}
//--------------------------------------------------------------------------------------------------
@@ -190,24 +226,17 @@ RiaLineArcWellPathCalculator::WellTarget RimWellPathTarget::wellTargetData()
{
RiaLineArcWellPathCalculator::WellTarget targetData;
targetData.targetPointXYZ = targetPointXYZ();
targetData.isTangentConstrained = ( targetType() == TargetTypeEnum::POINT_AND_TANGENT );
targetData.azimuth = azimuth();
targetData.inclination = inclination();
targetData.radius1 = radius1();
targetData.radius2 = radius2();
targetData.targetPointXYZ = targetPointXYZ();
targetData.isAzimuthConstrained = m_useFixedAzimuth();
targetData.isInclinationConstrained = m_useFixedInclination();
targetData.azimuthRadians = azimuthRadians();
targetData.inclinationRadians = inclinationRadians();
targetData.radius1 = radius1();
targetData.radius2 = radius2();
return targetData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathTarget::TargetTypeEnum RimWellPathTarget::targetType() const
{
return m_targetType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -221,11 +250,11 @@ cvf::Vec3d RimWellPathTarget::targetPointXYZ() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathTarget::azimuth() const
double RimWellPathTarget::azimuthRadians() const
{
if ( m_targetType() == TargetTypeEnum::POINT_AND_TANGENT )
if ( m_useFixedAzimuth() )
{
return cvf::Math::toRadians( m_azimuth );
return cvf::Math::toRadians( m_azimuthDeg );
}
return std::numeric_limits<double>::infinity();
@@ -234,11 +263,11 @@ double RimWellPathTarget::azimuth() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathTarget::inclination() const
double RimWellPathTarget::inclinationRadians() const
{
if ( m_targetType() == TargetTypeEnum::POINT_AND_TANGENT )
if ( m_useFixedInclination() )
{
return cvf::Math::toRadians( m_inclination );
return cvf::Math::toRadians( m_inclinationDeg );
}
return std::numeric_limits<double>::infinity();
@@ -249,8 +278,8 @@ double RimWellPathTarget::inclination() const
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RimWellPathTarget::tangent() const
{
double aziRad = cvf::Math::toRadians( m_azimuth );
double incRad = cvf::Math::toRadians( m_inclination );
double aziRad = cvf::Math::toRadians( m_azimuthDeg );
double incRad = cvf::Math::toRadians( m_inclinationDeg );
return RiaOffshoreSphericalCoords::unitVectorFromAziInc( aziRad, incRad );
}
@@ -294,21 +323,23 @@ double doglegFromRadius( double radius )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::flagRadius1AsIncorrect( bool isEditable, bool isIncorrect, double actualRadius )
void RimWellPathTarget::setRadius1Data( bool isEditable, bool isIncorrect, double actualRadius )
{
double estimatedDogLeg = doglegFromRadius( actualRadius );
m_estimatedDogleg1 = estimatedDogLeg;
if ( isIncorrect )
{
if ( actualRadius < radius1() )
{
m_dogleg1.uiCapability()->setUiContentTextColor( Qt::red );
m_dogleg1.uiCapability()->setUiToolTip( "Actual Dogleg: " + QString::number( doglegFromRadius( actualRadius ) ) +
m_dogleg1.uiCapability()->setUiToolTip( "Actual Dogleg: " + QString::number( estimatedDogLeg ) +
"\nThe dogleg constraint is not satisfied!" );
}
else
{
m_dogleg1.uiCapability()->setUiContentTextColor( Qt::darkGreen );
m_dogleg1.uiCapability()->setUiToolTip( "Actual Dogleg: " +
QString::number( doglegFromRadius( actualRadius ) ) );
m_dogleg1.uiCapability()->setUiToolTip( "Actual Dogleg: " + QString::number( estimatedDogLeg ) );
}
}
else
@@ -323,21 +354,23 @@ void RimWellPathTarget::flagRadius1AsIncorrect( bool isEditable, bool isIncorrec
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::flagRadius2AsIncorrect( bool isEditable, bool isIncorrect, double actualRadius )
void RimWellPathTarget::setRadius2Data( bool isEditable, bool isIncorrect, double actualRadius )
{
double estimatedDogLeg = doglegFromRadius( actualRadius );
m_estimatedDogleg2 = estimatedDogLeg;
if ( isIncorrect )
{
if ( actualRadius < radius2() )
{
m_dogleg2.uiCapability()->setUiContentTextColor( Qt::red );
m_dogleg2.uiCapability()->setUiToolTip( "Actual Dogleg: " + QString::number( doglegFromRadius( actualRadius ) ) +
m_dogleg2.uiCapability()->setUiToolTip( "Actual Dogleg: " + QString::number( estimatedDogLeg ) +
"\nThe dogleg constraint is not satisfied!" );
}
else
{
m_dogleg2.uiCapability()->setUiContentTextColor( Qt::darkGreen );
m_dogleg2.uiCapability()->setUiToolTip( "Actual Dogleg: " +
QString::number( doglegFromRadius( actualRadius ) ) );
m_dogleg2.uiCapability()->setUiToolTip( "Actual Dogleg: " + QString::number( estimatedDogLeg ) );
}
}
else
@@ -354,7 +387,7 @@ void RimWellPathTarget::flagRadius2AsIncorrect( bool isEditable, bool isIncorrec
//--------------------------------------------------------------------------------------------------
std::vector<caf::PdmFieldHandle*> RimWellPathTarget::fieldsFor3dManipulator()
{
return { &m_targetType, &m_targetPointXYD, &m_azimuth, &m_inclination };
return { &m_targetPointXYD, &m_azimuthDeg, &m_inclinationDeg };
}
//--------------------------------------------------------------------------------------------------
@@ -373,6 +406,21 @@ void RimWellPathTarget::enableFullUpdate( bool enable )
m_isFullUpdateEnabled = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::initAfterRead()
{
if ( RimProject::current()->isProjectFileVersionEqualOrOlderThan( "2021.10.2" ) )
{
if ( m_targetType_OBSOLETE() == RimWellPathTarget::TargetTypeEnum::POINT_AND_TANGENT )
{
m_useFixedAzimuth = true;
m_useFixedInclination = true;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -473,27 +521,6 @@ RimWellPathGeometryDef* RimWellPathTarget::geometryDefinition() const
return geoDef;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimWellPathTarget::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_targetType )
{
options.push_back(
caf::PdmOptionItemInfo( "o->",
RimWellPathTarget::TargetTypeEnum::POINT_AND_TANGENT ) ); //, false,
// QIcon(":/WellTargetPointTangent16x16.png")
//));
options.push_back(
caf::PdmOptionItemInfo( "o", RimWellPathTarget::TargetTypeEnum::POINT ) ); //, false,
// QIcon(":/WellTargetPoint16x16.png")));
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -501,14 +528,6 @@ void RimWellPathTarget::fieldChangedByUi( const caf::PdmFieldHandle* changedFiel
const QVariant& oldValue,
const QVariant& newValue )
{
if ( changedField == &m_hasTangentConstraintUiField )
{
if ( m_hasTangentConstraintUiField )
m_targetType = TargetTypeEnum::POINT_AND_TANGENT;
else
m_targetType = TargetTypeEnum::POINT;
}
moved.send( m_isFullUpdateEnabled );
}
@@ -517,39 +536,20 @@ void RimWellPathTarget::fieldChangedByUi( const caf::PdmFieldHandle* changedFiel
//--------------------------------------------------------------------------------------------------
void RimWellPathTarget::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
m_hasTangentConstraintUiField = ( m_targetType == TargetTypeEnum::POINT_AND_TANGENT );
if ( m_isEnabled() && !m_isLocked() )
if ( m_isEnabled() )
{
m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly( false );
m_targetType.uiCapability()->setUiReadOnly( false );
m_targetPointXYD.uiCapability()->setUiReadOnly( false );
if ( m_targetType == TargetTypeEnum::POINT )
{
m_azimuth.uiCapability()->setUiReadOnly( true );
m_inclination.uiCapability()->setUiReadOnly( true );
}
else
{
m_azimuth.uiCapability()->setUiReadOnly( false );
m_inclination.uiCapability()->setUiReadOnly( false );
}
m_azimuthDeg.uiCapability()->setUiReadOnly( !m_useFixedAzimuth() );
m_inclinationDeg.uiCapability()->setUiReadOnly( !m_useFixedInclination() );
}
else
{
m_dogleg1.uiCapability()->setUiReadOnly( true );
m_targetType.uiCapability()->setUiReadOnly( true );
m_targetPointXYD.uiCapability()->setUiReadOnly( true );
m_azimuth.uiCapability()->setUiReadOnly( true );
m_inclination.uiCapability()->setUiReadOnly( true );
m_azimuthDeg.uiCapability()->setUiReadOnly( true );
m_inclinationDeg.uiCapability()->setUiReadOnly( true );
m_dogleg2.uiCapability()->setUiReadOnly( true );
m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly( true );
}
if ( m_isLocked )
{
m_isEnabled.uiCapability()->setUiReadOnly( true );
}
{

View File

@@ -48,8 +48,10 @@ public:
void setAsPointTargetXYD( const cvf::Vec3d& point );
void setAsPointTargetXYZ( 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 setDerivedTangent( double azimuth, double inclination );
void setAsPointXYZAndTangentTarget( const cvf::Vec3d& point, double azimuthRadians, double inclinationRadians );
void setFixedAzimuth( double fixedAzimuthDeg );
void setFixedInclination( double fixedInclinationDeg );
void setDerivedTangent( double azimuthRadians, double inclinationRadians );
void updateFrom3DManipulator( const cvf::Vec3d& pointXYD );
RiaLineArcWellPathCalculator::WellTarget wellTargetData();
@@ -60,48 +62,53 @@ public:
POINT
};
TargetTypeEnum targetType() const;
cvf::Vec3d targetPointXYZ() const;
double azimuth() const;
double inclination() const;
cvf::Vec3d tangent() const;
double radius1() const;
double radius2() const;
void flagRadius1AsIncorrect( bool isEditable, bool isIncorrect, double actualRadius );
void flagRadius2AsIncorrect( bool isEditable, bool isIncorrect, double actualRadius );
cvf::Vec3d targetPointXYZ() const;
double azimuthRadians() const;
double inclinationRadians() const;
cvf::Vec3d tangent() const;
double radius1() const;
double radius2() const;
void setRadius1Data( bool isEditable, bool isIncorrect, double actualRadius );
void setRadius2Data( bool isEditable, bool isIncorrect, double actualRadius );
std::vector<caf::PdmFieldHandle*> fieldsFor3dManipulator();
void onMoved();
private:
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void initAfterRead() override;
cvf::Vec3d targetPointForDisplayXYD() const;
void setTargetPointFromDisplayCoord( const cvf::Vec3d& coordInXYZ );
double measuredDepth() const;
RimWellPathGeometryDef* geometryDefinition() const;
void enableFullUpdate( bool enable );
private:
void enableFullUpdate( bool enable );
bool m_isFullUpdateEnabled;
caf::PdmField<bool> m_isEnabled;
caf::PdmField<bool> m_isLocked;
caf::PdmField<caf::AppEnum<TargetTypeEnum>> m_targetType;
caf::PdmField<cvf::Vec3d> m_targetPointXYD;
caf::PdmProxyValueField<cvf::Vec3d> m_targetPointForDisplay;
caf::PdmProxyValueField<double> m_targetMeasuredDepth;
caf::PdmField<bool> m_isEnabled;
caf::PdmField<cvf::Vec3d> m_targetPointXYD;
caf::PdmProxyValueField<cvf::Vec3d> m_targetPointForDisplay;
caf::PdmProxyValueField<double> m_targetMeasuredDepth;
caf::PdmField<double> m_azimuth;
caf::PdmField<double> m_inclination;
caf::PdmField<double> m_azimuthDeg;
caf::PdmField<double> m_inclinationDeg;
caf::PdmField<double> m_dogleg1;
caf::PdmField<double> m_dogleg2;
caf::PdmField<bool> m_hasTangentConstraintUiField;
caf::PdmField<bool> m_useFixedAzimuth;
caf::PdmField<bool> m_useFixedInclination;
caf::PdmField<double> m_estimatedDogleg1;
caf::PdmField<double> m_estimatedDogleg2;
caf::PdmField<double> m_estimatedAzimuthDeg;
caf::PdmField<double> m_estimatedInclinationDeg;
bool m_isFullUpdateEnabled;
caf::PdmField<bool> m_hasTangentConstraintUiField_OBSOLETE;
caf::PdmField<caf::AppEnum<TargetTypeEnum>> m_targetType_OBSOLETE;
};

View File

@@ -40,6 +40,11 @@ RimcRimWellPathGeometryDef_appendNewWellTarget::RimcRimWellPathGeometryDef_appen
CAF_PDM_InitObject( "Create and Add New Well Target", "", "", "Create and Add New Well Target" );
CAF_PDM_InitScriptableFieldNoDefault( &m_coordinate, "Coordinate", "", "", "", "Coordinate" );
CAF_PDM_InitScriptableField( &m_isAbsolute, "Absolute", false, "", "", "", "Relative or Absolute Coordinate" );
CAF_PDM_InitScriptableField( &m_useFixedAzimuth, "UseFixedAzimuth", false, "" );
CAF_PDM_InitScriptableField( &m_useFixedInclination, "UseFixedInclination", false, "" );
CAF_PDM_InitScriptableField( &m_fixedAzimuthValue, "FixedAzimuthValue", 0.0, "", "", "", "[Degrees]" );
CAF_PDM_InitScriptableField( &m_fixedInclinationValue, "FixedInclinationValue", 0.0, "", "", "", "[Degrees]" );
}
//--------------------------------------------------------------------------------------------------
@@ -60,6 +65,17 @@ caf::PdmObjectHandle* RimcRimWellPathGeometryDef_appendNewWellTarget::execute()
auto newTarget = new RimWellPathTarget;
newTarget->setAsPointTargetXYD(
cvf::Vec3d( relativeTargetPoint.x(), relativeTargetPoint.y(), -relativeTargetPoint.z() ) );
if ( m_useFixedAzimuth )
{
newTarget->setFixedAzimuth( m_fixedAzimuthValue );
}
if ( m_useFixedInclination )
{
newTarget->setFixedInclination( m_fixedInclinationValue );
}
geoDef->insertTarget( nullptr, newTarget );
geoDef->updateConnectedEditors();

View File

@@ -43,4 +43,9 @@ public:
private:
caf::PdmField<cvf::Vec3d> m_coordinate;
caf::PdmField<bool> m_isAbsolute;
caf::PdmField<bool> m_useFixedAzimuth;
caf::PdmField<double> m_fixedAzimuthValue;
caf::PdmField<bool> m_useFixedInclination;
caf::PdmField<double> m_fixedInclinationValue;
};

View File

@@ -41,14 +41,33 @@ geometry.update() # Commit updates back to ResInsight
coord = [0, 0, 0]
geometry.append_well_target(coord)
# Append new well targets relative the the reference point
# Append well target with fixed azimuth
coord = [2229.10, -833.74, -74.70]
target = geometry.append_well_target(coord)
target = geometry.append_well_target(
coord, use_fixed_azimuth=True, fixed_azimuth_value=45.1
)
# Append well target with fixed inclination
coord = [3403.15, -1938.61, -80.93]
target = geometry.append_well_target(
coord, use_fixed_inclination=True, fixed_inclination_value=115.2
)
coord = [4577.21, -3043.47, -87.15]
target = geometry.append_well_target(coord)
geometry.update()
# Read out estimated dogleg and azimuth/inclination for well targets
for w in geometry.well_path_targets():
print(
"DL1:{} DL2:{} Azi: {} Incl: {}".format(
w.estimated_dogleg1,
w.estimated_dogleg2,
w.estimated_azimuth,
w.estimated_inclination,
)
)
# Add a curve intersection based on the modeled well path
well_path_intersection = intersection_coll.add_new_object(rips.CurveIntersection)
well_path_intersection.type = "CS_WELL_PATH"

View File

@@ -1,35 +0,0 @@
from rips.generated.generated_classes import (
ModeledWellPath,
StimPlanModel,
WellPathGeometry,
WellPathTarget,
)
import sys
import os
sys.path.insert(1, os.path.join(sys.path[0], "../../"))
import rips
def test_well_path_target(rips_instance, initialize_test):
well_path_coll = rips_instance.project.descendants(rips.WellPathCollection)[0]
my_well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
my_well_path.name = "test"
my_well_path.update()
geometry = my_well_path.well_path_geometry()
geometry.add_new_object(rips.WellPathTarget)
geometry.add_new_object(rips.WellPathTarget)
geometry.add_new_object(rips.WellPathTarget)
assert len(geometry.well_path_targets()) == 3
assert len(well_path_coll.well_paths()) == 1
my_well_path_duplicate = well_path_coll.well_paths()[0]
assert my_well_path_duplicate.name == "test"
geometry_duplicate = my_well_path_duplicate.well_path_geometry()
assert len(geometry_duplicate.well_path_targets()) == 3
# Not allowed to add object of unrelated type
invalid_object = geometry.add_new_object(rips.WellPath)
assert invalid_object is None

View File

@@ -0,0 +1,66 @@
from rips.generated.generated_classes import (
ModeledWellPath,
StimPlanModel,
WellPathGeometry,
WellPathTarget,
)
import sys
import os
sys.path.insert(1, os.path.join(sys.path[0], "../../"))
import rips
def test_add_new_object_for_well_paths(rips_instance, initialize_test):
well_path_coll = rips_instance.project.descendants(rips.WellPathCollection)[0]
my_well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
my_well_path.name = "test"
my_well_path.update()
geometry = my_well_path.well_path_geometry()
geometry.add_new_object(rips.WellPathTarget)
geometry.add_new_object(rips.WellPathTarget)
geometry.add_new_object(rips.WellPathTarget)
assert len(geometry.well_path_targets()) == 3
assert len(well_path_coll.well_paths()) == 1
my_well_path_duplicate = well_path_coll.well_paths()[0]
assert my_well_path_duplicate.name == "test"
geometry_duplicate = my_well_path_duplicate.well_path_geometry()
assert len(geometry_duplicate.well_path_targets()) == 3
# Not allowed to add object of unrelated type
invalid_object = geometry.add_new_object(rips.WellPath)
assert invalid_object is None
def test_add_well_path_targets(rips_instance, initialize_test):
well_path_coll = rips_instance.project.descendants(rips.WellPathCollection)[0]
my_well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
my_well_path.name = "test"
my_well_path.update()
geometry = my_well_path.well_path_geometry()
# Append well target with fixed azimuth
coord = [2229.10, -833.74, -74.70]
target = geometry.append_well_target(
coord, use_fixed_azimuth=True, fixed_azimuth_value=110.1
)
assert target.use_fixed_inclination == False
assert target.use_fixed_azimuth == True
assert target.azimuth == 110.1
assert target.inclination == 0.0
# Append well target with fixed inclination
coord = [4577.21, -3043.47, -87.15]
target = geometry.append_well_target(
coord, use_fixed_inclination=True, fixed_inclination_value=25.6
)
assert target.use_fixed_inclination == True
assert target.use_fixed_azimuth == False
assert target.azimuth == 0.0
assert target.inclination == 25.6