2018-07-03 08:42:31 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
2019-01-09 15:21:38 +01:00
// Copyright (C) 2018- Equinor ASA
2018-07-03 08:42:31 +02:00
//
// 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 "RimWellPathGeometryDef.h"
2018-11-05 14:28:07 +01:00
#include "WellPathCommands/RicCreateWellTargetsPickEventHandler.h"
2018-07-03 08:42:31 +02:00
2018-11-05 14:28:07 +01:00
#include "RiaFieldHandleTools.h"
#include "RiaJCurveCalculator.h"
#include "RiaLogging.h"
2018-09-11 08:36:14 +02:00
#include "RiaOffshoreSphericalCoords.h"
2018-11-05 14:28:07 +01:00
#include "RiaPolyArcLineSampler.h"
#include "RiaSCurveCalculator.h"
#include "RigWellPath.h"
2018-09-11 08:36:14 +02:00
2018-07-03 08:42:31 +02:00
#include "RimModeledWellPath.h"
2018-11-05 14:28:07 +01:00
#include "RimWellPathTarget.h"
2018-08-29 16:03:31 +02:00
#include "RiuViewerCommands.h"
2018-11-05 14:28:07 +01:00
#include "cafCmdFeatureMenuBuilder.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTableViewEditor.h"
#include "cafPdmUiTreeOrdering.h"
2018-09-11 08:36:14 +02:00
#include "cvfGeometryTools.h"
2018-11-27 11:25:25 +01:00
#include "WellPathCommands/PointTangentManipulator/RicWellPathGeometry3dEditor.h"
2018-07-03 08:42:31 +02:00
2018-11-05 14:28:07 +01:00
2018-07-03 08:42:31 +02:00
namespace caf
{
template <>
void caf :: AppEnum < RimWellPathGeometryDef :: WellStartType >:: setUp ()
{
addItem ( RimWellPathGeometryDef :: START_AT_FIRST_TARGET , "START_AT_FIRST_TARGET" , "Start at First Target" );
addItem ( RimWellPathGeometryDef :: START_AT_SURFACE , "START_AT_SURFACE" , "Start at Surface" );
addItem ( RimWellPathGeometryDef :: START_FROM_OTHER_WELL , "START_FROM_OTHER_WELL" , "Branch" );
addItem ( RimWellPathGeometryDef :: START_AT_AUTO_SURFACE , "START_AT_AUTO_SURFACE" , "Auto Surface" );
setDefault ( RimWellPathGeometryDef :: START_AT_FIRST_TARGET );
}
}
CAF_PDM_SOURCE_INIT ( RimWellPathGeometryDef , "WellPathGeometryDef" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathGeometryDef :: RimWellPathGeometryDef ()
2018-08-29 16:03:31 +02:00
: m_pickTargetsEventHandler ( new RicCreateWellTargetsPickEventHandler ( this ))
2018-07-03 08:42:31 +02:00
{
2018-10-02 15:55:28 +02:00
CAF_PDM_InitObject ( "Well Targets" , ":/WellTargets.png" , "" , "" );
2018-07-03 08:42:31 +02:00
2018-11-26 21:50:46 +01:00
this -> setUi3dEditorTypeName ( RicWellPathGeometry3dEditor :: uiEditorTypeName ());
2018-09-11 09:31:50 +02:00
CAF_PDM_InitField ( & m_referencePointUtmXyd , "ReferencePosUtmXyd" , cvf :: Vec3d ( 0 , 0 , 0 ), "UTM Reference Point" , "" , "" , "" );
2018-07-03 08:42:31 +02:00
2018-10-31 14:55:27 +01:00
CAF_PDM_InitField ( & m_mdrkbAtFirstTarget , "MdrkbAtFirstTarget" , 0.0 , "MDRKB at First Target" , "" , "" , "" );
2018-07-03 08:42:31 +02:00
CAF_PDM_InitFieldNoDefault ( & m_wellTargets , "WellPathTargets" , "Well Targets" , "" , "" , "" );
m_wellTargets . uiCapability () -> setUiEditorTypeName ( caf :: PdmUiTableViewEditor :: uiEditorTypeName ());
//m_wellTargets.uiCapability()->setUiTreeHidden(true);
m_wellTargets . uiCapability () -> setUiTreeChildrenHidden ( true );
m_wellTargets . uiCapability () -> setUiLabelPosition ( caf :: PdmUiItemInfo :: TOP );
m_wellTargets . uiCapability () -> setCustomContextMenuEnabled ( true );
2018-08-29 16:03:31 +02:00
CAF_PDM_InitField ( & m_pickPointsEnabled , "m_pickPointsEnabled" , false , "" , "" , "" , "" );
caf :: PdmUiPushButtonEditor :: configureEditorForField ( & m_pickPointsEnabled );
2018-09-11 09:31:50 +02:00
// Temp conversion field.
CAF_PDM_InitField ( & m_referencePointXyz_OBSOLETE , "ReferencePos" , cvf :: Vec3d ( 0 , 0 , 0 ), "UTM Reference Point" , "" , "" , "" );
2018-11-05 14:28:07 +01:00
RiaFieldhandleTools :: disableWriteAndSetFieldHidden ( & m_referencePointXyz_OBSOLETE );
2018-09-11 09:31:50 +02:00
/// To be removed ?
CAF_PDM_InitFieldNoDefault ( & m_wellStartType , "WellStartType" , "Start Type" , "" , "" , "" );
m_wellStartType . xmlCapability () -> disableIO ();
CAF_PDM_InitFieldNoDefault ( & m_parentWell , "ParentWell" , "Parent Well" , "" , "" , "" );
m_parentWell . xmlCapability () -> disableIO ();
CAF_PDM_InitField ( & m_kickoffDepthOrMD , "KickoffDepthOrMD" , 100.0 , "Kickoff Depth" , "" , "" , "" );
m_kickoffDepthOrMD . xmlCapability () -> disableIO ();
2018-07-03 08:42:31 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPathGeometryDef ::~ RimWellPathGeometryDef ()
{
}
2018-09-11 09:31:50 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf :: Vec3d RimWellPathGeometryDef :: referencePointXyz () const
{
cvf :: Vec3d xyz ( m_referencePointUtmXyd ());
xyz . z () = - xyz . z ();
return xyz ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: setReferencePointXyz ( const cvf :: Vec3d & refPointXyz )
{
cvf :: Vec3d xyd ( refPointXyz );
xyd . z () = - xyd . z ();
m_referencePointUtmXyd = xyd ;
}
2018-10-31 14:55:27 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathGeometryDef :: mdrkbAtFirstTarget () const
{
return m_mdrkbAtFirstTarget ;
}
2018-11-16 11:35:13 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: setMdrkbAtFirstTarget ( double mdrkb )
{
m_mdrkbAtFirstTarget = mdrkb ;
}
2018-07-03 08:42:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf :: ref < RigWellPath > RimWellPathGeometryDef :: createWellPathGeometry ()
{
cvf :: ref < RigWellPath > wellPathGeometry = new RigWellPath ;
2018-09-28 14:06:56 +02:00
RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator ();
if ( wellPathCalculator . lineArcEndpoints (). size () < 2 ) return wellPathGeometry ;
RiaPolyArcLineSampler arcLineSampler ( wellPathCalculator . startTangent (), wellPathCalculator . lineArcEndpoints ());
2018-07-03 08:42:31 +02:00
arcLineSampler . sampledPointsAndMDs ( 30 ,
false ,
& ( wellPathGeometry -> m_wellPathPoints ),
& ( wellPathGeometry -> m_measuredDepths ));
return wellPathGeometry ;
}
2018-09-26 12:38:53 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < RiaWellPlanCalculator :: WellPlanSegment > RimWellPathGeometryDef :: wellPlan () const
{
2018-09-28 14:06:56 +02:00
RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator ();
RiaWellPlanCalculator wpCalc ( wellPathCalculator . startTangent (), wellPathCalculator . lineArcEndpoints ());
2018-09-26 12:38:53 +02:00
return wpCalc . wellPlan ();
}
2018-07-03 08:42:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: updateWellPathVisualization ()
{
RimModeledWellPath * modWellPath ;
this -> firstAncestorOrThisOfTypeAsserted ( modWellPath );
modWellPath -> updateWellPathVisualization ();
}
2018-10-02 15:55:28 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: pair < RimWellPathTarget * , RimWellPathTarget *>
RimWellPathGeometryDef :: 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 };
}
2018-07-03 08:42:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-08-29 16:03:31 +02:00
void RimWellPathGeometryDef :: insertTarget ( const RimWellPathTarget * targetToInsertBefore , RimWellPathTarget * targetToInsert )
2018-07-03 08:42:31 +02:00
{
size_t index = m_wellTargets . index ( targetToInsertBefore );
if ( index < m_wellTargets . size ()) m_wellTargets . insert ( index , targetToInsert );
else m_wellTargets . push_back ( targetToInsert );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: deleteTarget ( RimWellPathTarget * targetTodelete )
{
m_wellTargets . removeChildObject ( targetTodelete );
delete targetTodelete ;
}
2018-07-31 11:44:15 +02:00
//--------------------------------------------------------------------------------------------------
2018-08-06 07:52:02 +02:00
///
2018-07-31 11:44:15 +02:00
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: 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 );
}
}
2018-08-14 14:23:55 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimWellPathTarget * RimWellPathGeometryDef :: firstActiveTarget () const
{
for ( const RimWellPathTarget * target : m_wellTargets )
{
if ( target -> isEnabled ())
{
return target ;
}
}
return nullptr ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RimWellPathTarget * RimWellPathGeometryDef :: 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 ;
}
2018-08-29 16:03:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: enableTargetPointPicking ( bool isEnabling )
{
2019-02-11 13:46:48 +01:00
m_pickPointsEnabled = isEnabling ;
this -> updateConnectedEditors ();
2018-08-29 16:03:31 +02:00
}
2018-07-04 16:49:04 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf :: PdmOptionItemInfo > RimWellPathGeometryDef :: calculateValueOptions ( const caf :: PdmFieldHandle * fieldNeedingOptions ,
bool * useOptionsOnly )
{
QList < caf :: PdmOptionItemInfo > options ;
if ( fieldNeedingOptions == & m_wellStartType )
{
options . push_back ( caf :: PdmOptionItemInfo ( "Start at First Target" , RimWellPathGeometryDef :: START_AT_FIRST_TARGET ));
}
return options ;
}
2018-07-03 08:42:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: fieldChangedByUi ( const caf :: PdmFieldHandle * changedField ,
const QVariant & oldValue ,
const QVariant & newValue )
{
2018-09-11 09:31:50 +02:00
if ( & m_referencePointUtmXyd == changedField )
2018-07-03 08:42:31 +02:00
{
std :: cout << "fieldChanged" << std :: endl ;
}
2018-08-29 16:03:31 +02:00
else if ( changedField == & m_pickPointsEnabled )
{
2019-02-11 13:46:48 +01:00
this -> updateConnectedEditors ();
2018-08-29 16:03:31 +02:00
}
2018-07-03 08:42:31 +02:00
updateWellPathVisualization ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: defineUiOrdering ( QString uiConfigName , caf :: PdmUiOrdering & uiOrdering )
{
uiOrdering . add ( & m_wellStartType );
if ( m_wellStartType == START_FROM_OTHER_WELL )
{
uiOrdering . add ( & m_parentWell );
m_kickoffDepthOrMD . uiCapability () -> setUiName ( "Measured Depth" );
uiOrdering . add ( & m_kickoffDepthOrMD );
}
if ( m_wellStartType == START_AT_SURFACE )
{
m_kickoffDepthOrMD . uiCapability () -> setUiName ( "Kick-Off Depth" );
uiOrdering . add ( & m_kickoffDepthOrMD );
}
2018-09-11 09:31:50 +02:00
uiOrdering . add ( & m_referencePointUtmXyd );
2018-10-31 14:55:27 +01:00
uiOrdering . add ( & m_mdrkbAtFirstTarget );
2018-07-03 08:42:31 +02:00
uiOrdering . add ( & m_wellTargets );
2018-08-29 16:03:31 +02:00
uiOrdering . add ( & m_pickPointsEnabled );
2018-07-03 08:42:31 +02:00
uiOrdering . skipRemainingFields ( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: defineUiTreeOrdering ( caf :: PdmUiTreeOrdering & uiTreeOrdering , QString uiConfigName )
{
uiTreeOrdering . skipRemainingChildren ( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-07-31 08:44:37 +02:00
std :: vector < RimWellPathTarget *> RimWellPathGeometryDef :: activeWellTargets () const
2018-07-03 08:42:31 +02:00
{
2018-07-31 08:44:37 +02:00
std :: vector < RimWellPathTarget *> active ;
for ( const auto & wt : m_wellTargets )
{
if ( wt -> isEnabled ())
{
active . push_back ( wt );
}
}
2018-07-04 16:49:04 +02:00
2018-07-31 08:44:37 +02:00
return active ;
}
2018-07-04 16:49:04 +02:00
2018-09-28 14:06:56 +02:00
#if 0 // Kept for reference a bit longer
2018-07-31 08:44:37 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RimWellPathGeometryDef::lineArcEndpoints() const
{
2018-08-14 11:25:08 +02:00
double prevSegmentEndAzi = 0;
double prevSegmentEndInc = 0;
2018-07-31 08:44:37 +02:00
std::vector<RimWellPathTarget*> activeWellPathTargets = activeWellTargets();
CVF_ASSERT(activeWellPathTargets.size() > 1);
2018-07-04 16:49:04 +02:00
2018-07-31 08:44:37 +02:00
std::vector<cvf::Vec3d> endPoints;
2018-09-11 09:31:50 +02:00
endPoints.push_back( activeWellPathTargets[0]->targetPointXYZ() + referencePointXyz() );
2018-07-04 16:49:04 +02:00
2018-07-31 08:44:37 +02:00
for ( size_t tIdx = 0; tIdx < activeWellPathTargets.size() - 1; ++tIdx)
{
RimWellPathTarget* target1 = activeWellPathTargets[tIdx];
RimWellPathTarget* target2 = activeWellPathTargets[tIdx+1];
2018-07-04 16:49:04 +02:00
2018-09-27 14:19:10 +02:00
// Ignore targets in the same place
if ((target1->targetPointXYZ() - target2->targetPointXYZ()).length() < 1e-6) continue;
2018-09-24 15:31:58 +02:00
target1->flagRadius2AsIncorrect(false, 0);
target2->flagRadius1AsIncorrect(false, 0);
2018-08-14 11:25:08 +02:00
if ( target1->targetType() == RimWellPathTarget::POINT_AND_TANGENT
2018-07-04 16:49:04 +02:00
&& target2->targetType() == RimWellPathTarget::POINT_AND_TANGENT)
{
RiaSCurveCalculator sCurveCalc(target1->targetPointXYZ(),
target1->azimuth(),
target1->inclination(),
2018-08-14 11:25:08 +02:00
target1->radius2(),
2018-07-04 16:49:04 +02:00
target2->targetPointXYZ(),
target2->azimuth(),
target2->inclination(),
2018-08-14 11:25:08 +02:00
target2->radius1());
2018-07-04 16:49:04 +02:00
2018-09-24 15:31:58 +02:00
if ( sCurveCalc.solveStatus() != RiaSCurveCalculator::CONVERGED )
2018-08-07 13:15:41 +02:00
{
2018-08-10 12:10:39 +02:00
double p1p2Length = (target2->targetPointXYZ() - target1->targetPointXYZ()).length();
2018-08-07 13:15:41 +02:00
sCurveCalc = RiaSCurveCalculator::fromTangentsAndLength(target1->targetPointXYZ(),
target1->azimuth(),
target1->inclination(),
2018-08-10 12:10:39 +02:00
0.2*p1p2Length,
2018-08-07 13:15:41 +02:00
target2->targetPointXYZ(),
target2->azimuth(),
target2->inclination(),
2018-08-10 12:10:39 +02:00
0.2*p1p2Length);
2018-08-10 15:22:43 +02:00
RiaLogging::warning("Using fall-back calculation of well path geometry between active target number: " + QString::number(tIdx+1) + " and " + QString::number(tIdx+2));
2018-09-24 15:31:58 +02:00
target1->flagRadius2AsIncorrect(true, sCurveCalc.firstRadius());
target2->flagRadius1AsIncorrect(true, sCurveCalc.secondRadius());
2018-08-07 13:15:41 +02:00
}
2018-08-14 11:25:08 +02:00
2018-09-11 09:31:50 +02:00
endPoints.push_back( sCurveCalc.firstArcEndpoint() + referencePointXyz() );
endPoints.push_back( sCurveCalc.secondArcStartpoint() + referencePointXyz() );
endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() );
2018-08-14 11:25:08 +02:00
}
else if ( target1->targetType() == RimWellPathTarget::POINT
&& target2->targetType() == RimWellPathTarget::POINT_AND_TANGENT)
{
RiaSCurveCalculator sCurveCalc(target1->targetPointXYZ(),
prevSegmentEndAzi,
prevSegmentEndInc,
target1->radius2(),
target2->targetPointXYZ(),
target2->azimuth(),
target2->inclination(),
target2->radius1());
2018-09-24 15:31:58 +02:00
if ( sCurveCalc.solveStatus() != RiaSCurveCalculator::CONVERGED )
2018-08-14 11:25:08 +02:00
{
double p1p2Length = (target2->targetPointXYZ() - target1->targetPointXYZ()).length();
sCurveCalc = RiaSCurveCalculator::fromTangentsAndLength(target1->targetPointXYZ(),
prevSegmentEndAzi,
prevSegmentEndInc,
0.2*p1p2Length,
target2->targetPointXYZ(),
target2->azimuth(),
target2->inclination(),
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));
2018-09-24 15:31:58 +02:00
target1->flagRadius2AsIncorrect(true, sCurveCalc.firstRadius());
target2->flagRadius1AsIncorrect(true, sCurveCalc.secondRadius());
2018-08-14 11:25:08 +02:00
}
2018-09-11 09:31:50 +02:00
endPoints.push_back( sCurveCalc.firstArcEndpoint() + referencePointXyz() );
endPoints.push_back( sCurveCalc.secondArcStartpoint() + referencePointXyz() );
endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() );
2018-08-14 11:25:08 +02:00
}
else if ( target1->targetType() == RimWellPathTarget::POINT_AND_TANGENT
&& target2->targetType() == RimWellPathTarget::POINT)
{
RiaJCurveCalculator jCurve(target1->targetPointXYZ(),
target1->azimuth(),
target1->inclination(),
target1->radius2(),
target2->targetPointXYZ());
2018-09-24 15:31:58 +02:00
if ( jCurve.curveStatus() == RiaJCurveCalculator::OK )
2018-08-14 11:25:08 +02:00
{
2018-09-11 09:31:50 +02:00
endPoints.push_back(jCurve.firstArcEndpoint() + referencePointXyz());
2018-08-14 11:25:08 +02:00
}
2018-09-24 15:31:58 +02:00
else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE )
{
target1->flagRadius2AsIncorrect(true, jCurve.radius());
}
2018-09-11 09:31:50 +02:00
endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() );
2018-08-14 11:25:08 +02:00
prevSegmentEndAzi = jCurve.endAzimuth();
prevSegmentEndInc = jCurve.endInclination();
2018-09-10 16:32:24 +02:00
target2->setDerivedTangent(prevSegmentEndAzi, prevSegmentEndInc);
2018-07-04 16:49:04 +02:00
}
2018-08-14 11:25:08 +02:00
else if ( target1->targetType() == RimWellPathTarget::POINT
&& target2->targetType() == RimWellPathTarget::POINT)
{
RiaJCurveCalculator jCurve(target1->targetPointXYZ(),
prevSegmentEndAzi,
prevSegmentEndInc,
target1->radius2(),
target2->targetPointXYZ());
2018-09-24 15:31:58 +02:00
if ( jCurve.curveStatus() == RiaJCurveCalculator::OK )
2018-08-14 11:25:08 +02:00
{
2018-09-11 09:31:50 +02:00
endPoints.push_back(jCurve.firstArcEndpoint() + referencePointXyz());
2018-08-14 11:25:08 +02:00
}
2018-09-24 15:31:58 +02:00
else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE )
{
target1->flagRadius2AsIncorrect(true, jCurve.radius());
}
2018-09-11 09:31:50 +02:00
endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() );
2018-08-14 11:25:08 +02:00
prevSegmentEndAzi = jCurve.endAzimuth();
prevSegmentEndInc = jCurve.endInclination();
2018-09-10 16:32:24 +02:00
target2->setDerivedTangent(prevSegmentEndAzi, prevSegmentEndInc);
2018-08-14 11:25:08 +02:00
}
else
{
CVF_ASSERT(false);
}
2018-07-03 08:42:31 +02:00
}
return endPoints;
}
2018-09-28 14:06:56 +02:00
#endif
2018-07-04 16:49:04 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2018-09-28 14:06:56 +02:00
RiaLineArcWellPathCalculator RimWellPathGeometryDef :: lineArcWellPathCalculator () const
2018-07-04 16:49:04 +02:00
{
2018-09-28 14:06:56 +02:00
std :: vector < RimWellPathTarget *> wellTargets = activeWellTargets ();
2018-07-31 08:44:37 +02:00
2018-09-28 14:06:56 +02:00
std :: vector < RiaLineArcWellPathCalculator :: WellTarget > targetDatas ;
for ( auto wellTarget : wellTargets )
2018-07-04 16:49:04 +02:00
{
2018-09-28 14:06:56 +02:00
targetDatas . push_back ( wellTarget -> wellTargetData ());
2018-07-04 16:49:04 +02:00
}
2018-09-28 14:06:56 +02:00
RiaLineArcWellPathCalculator wellPathCalculator ( referencePointXyz (), targetDatas );
const std :: vector < RiaLineArcWellPathCalculator :: WellTargetStatus >& targetStatuses = wellPathCalculator . targetStatuses ();
for ( size_t tIdx = 0 ; tIdx < wellTargets . size (); ++ tIdx )
2018-07-04 16:49:04 +02:00
{
2018-09-28 14:06:56 +02:00
wellTargets [ tIdx ] -> flagRadius1AsIncorrect ( false , 0 );
wellTargets [ tIdx ] -> flagRadius2AsIncorrect ( false , 0 );
if ( targetStatuses [ tIdx ]. hasDerivedTangent )
{
wellTargets [ tIdx ] -> setDerivedTangent ( targetStatuses [ tIdx ]. resultAzimuth , targetStatuses [ tIdx ]. resultInclination );
}
if ( targetStatuses [ tIdx ]. hasOverriddenRadius1 )
{
wellTargets [ tIdx ] -> flagRadius1AsIncorrect ( true , targetStatuses [ tIdx ]. resultRadius1 );
}
if ( targetStatuses [ tIdx ]. hasOverriddenRadius2 )
{
wellTargets [ tIdx ] -> flagRadius2AsIncorrect ( true , targetStatuses [ tIdx ]. resultRadius2 );
}
2018-07-04 16:49:04 +02:00
}
2018-09-28 14:06:56 +02:00
return wellPathCalculator ;
2018-07-04 16:49:04 +02:00
}
2018-07-03 08:42:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: defineCustomContextMenu ( const caf :: PdmFieldHandle * fieldNeedingMenu ,
QMenu * menu ,
QWidget * fieldEditorWidget )
{
caf :: CmdFeatureMenuBuilder menuBuilder ;
menuBuilder << "RicNewWellPathListTargetFeature" ;
menuBuilder << "Separator" ;
menuBuilder << "RicDeleteWellPathTargetFeature" ;
menuBuilder . appendToMenu ( menu );
}
2018-08-29 16:03:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: 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" ;
}
}
}
if ( field == & m_wellTargets )
{
auto tvAttribute = dynamic_cast < caf :: PdmUiTableViewEditorAttribute *> ( attribute );
2018-10-31 09:31:53 +01:00
if ( tvAttribute )
2018-08-29 16:03:31 +02:00
{
2018-10-31 09:31:53 +01:00
tvAttribute -> resizePolicy = caf :: PdmUiTableViewEditorAttribute :: RESIZE_TO_FIT_CONTENT ;
if ( m_pickPointsEnabled )
{
tvAttribute -> baseColor . setRgb ( 255 , 220 , 255 );
tvAttribute -> alwaysEnforceResizePolicy = true ;
}
2018-08-29 16:03:31 +02:00
}
}
}
2018-09-11 09:31:50 +02:00
2019-02-11 13:46:48 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: defineObjectEditorAttribute ( QString uiConfigName , caf :: PdmUiEditorAttribute * attribute )
{
RicWellPathGeometry3dEditorAttribute * attrib = dynamic_cast < RicWellPathGeometry3dEditorAttribute *> ( attribute );
if ( attrib )
{
attrib -> pickEventHandler = m_pickTargetsEventHandler ;
attrib -> enablePicking = m_pickPointsEnabled ;
}
}
2018-09-11 09:31:50 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathGeometryDef :: initAfterRead ()
{
// To be removed before release 2018.11
if ( m_referencePointXyz_OBSOLETE != cvf :: Vec3d :: ZERO && m_referencePointUtmXyd == cvf :: Vec3d :: ZERO )
{
m_referencePointUtmXyd = cvf :: Vec3d ( m_referencePointXyz_OBSOLETE (). x (), m_referencePointXyz_OBSOLETE (). y (), - m_referencePointXyz_OBSOLETE (). z ());
}
}