mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Improve well path modeling
* Improve handling of MD at first target * When sea level well target is disabled, update MD of first target * Show well target spheres by default, allow toggling of spheres * Activate well target modifiers when clicking on well targets * Remove selection update causing an unstable 3D view * Improve display and handling of multiple locations * Add special 3D target for tie in well target * Add slider to tie in MD input field * Show MD in well path target table * Delete all well path laterals when deleting a well path * Python : Add lateral to parent well * Python : Add perforation interval
This commit is contained in:
parent
40bd4c285a
commit
8dbb1d5ccd
@ -114,12 +114,6 @@ void RiaCompletionTypeCalculationScheduler::slotRecalculateCompletionType()
|
|||||||
|
|
||||||
Rim3dView* activeView = RiaApplication::instance()->activeReservoirView();
|
Rim3dView* activeView = RiaApplication::instance()->activeReservoirView();
|
||||||
|
|
||||||
QModelIndex mi;
|
|
||||||
if ( RiuMainWindow::instance() )
|
|
||||||
{
|
|
||||||
mi = RiuMainWindow::instance()->projectTreeView()->treeView()->currentIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( RimEclipseCase* eclipseCase : uniqueCases )
|
for ( RimEclipseCase* eclipseCase : uniqueCases )
|
||||||
{
|
{
|
||||||
if ( eclipseCase )
|
if ( eclipseCase )
|
||||||
@ -148,11 +142,6 @@ void RiaCompletionTypeCalculationScheduler::slotRecalculateCompletionType()
|
|||||||
RiuMainWindow::instance()->setActiveViewer( activeView->viewer()->layoutWidget() );
|
RiuMainWindow::instance()->setActiveViewer( activeView->viewer()->layoutWidget() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mi.isValid() && RiuMainWindow::instance() )
|
|
||||||
{
|
|
||||||
RiuMainWindow::instance()->projectTreeView()->treeView()->setCurrentIndex( mi );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -7,6 +7,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathListTargetFeature.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathAttributeFeature.h
|
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathAttributeFeature.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathTargetFeature.h
|
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathTargetFeature.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathAttributeFeature.h
|
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathAttributeFeature.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathFeature.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsImpl.h
|
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsImpl.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.h
|
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathPickEventHandler.h
|
${CMAKE_CURRENT_LIST_DIR}/RicWellPathPickEventHandler.h
|
||||||
@ -40,6 +41,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathListTargetFeature.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathAttributeFeature.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathAttributeFeature.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathTargetFeature.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathTargetFeature.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathAttributeFeature.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathAttributeFeature.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathFeature.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsImpl.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsImpl.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RicWellPathPickEventHandler.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RicWellPathPickEventHandler.cpp
|
||||||
|
@ -79,6 +79,14 @@ void RicPointTangentManipulator::setHandleSize( double handleSize )
|
|||||||
m_partManager->setHandleSize( handleSize );
|
m_partManager->setHandleSize( handleSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicPointTangentManipulator::setPolyline( const std::vector<cvf::Vec3d>& polyline )
|
||||||
|
{
|
||||||
|
m_partManager->setPolyline( polyline );
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -94,7 +102,7 @@ bool RicPointTangentManipulator::eventFilter( QObject* obj, QEvent* inputEvent )
|
|||||||
{
|
{
|
||||||
if ( inputEvent->type() == QEvent::MouseButtonPress )
|
if ( inputEvent->type() == QEvent::MouseButtonPress )
|
||||||
{
|
{
|
||||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( inputEvent );
|
auto* mouseEvent = static_cast<QMouseEvent*>( inputEvent );
|
||||||
|
|
||||||
if ( mouseEvent->button() == Qt::LeftButton )
|
if ( mouseEvent->button() == Qt::LeftButton )
|
||||||
{
|
{
|
||||||
@ -119,7 +127,7 @@ bool RicPointTangentManipulator::eventFilter( QObject* obj, QEvent* inputEvent )
|
|||||||
{
|
{
|
||||||
if ( m_partManager->isManipulatorActive() )
|
if ( m_partManager->isManipulatorActive() )
|
||||||
{
|
{
|
||||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( inputEvent );
|
auto* mouseEvent = static_cast<QMouseEvent*>( inputEvent );
|
||||||
|
|
||||||
cvf::ref<cvf::RayIntersectSpec> rayIs =
|
cvf::ref<cvf::RayIntersectSpec> rayIs =
|
||||||
m_viewer->rayIntersectSpecFromWindowCoordinates( mouseEvent->pos().x(),
|
m_viewer->rayIntersectSpecFromWindowCoordinates( mouseEvent->pos().x(),
|
||||||
|
@ -55,6 +55,7 @@ public:
|
|||||||
void setOrigin( const cvf::Vec3d& origin );
|
void setOrigin( const cvf::Vec3d& origin );
|
||||||
void setTangent( const cvf::Vec3d& tangent );
|
void setTangent( const cvf::Vec3d& tangent );
|
||||||
void setHandleSize( double handleSize );
|
void setHandleSize( double handleSize );
|
||||||
|
void setPolyline( const std::vector<cvf::Vec3d>& polyline );
|
||||||
|
|
||||||
void appendPartsToModel( cvf::ModelBasicList* model );
|
void appendPartsToModel( cvf::ModelBasicList* model );
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
// for more details.
|
// for more details.
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "RicPointTangentManipulatorPartMgr.h"
|
#include "RicPointTangentManipulatorPartMgr.h"
|
||||||
|
|
||||||
#include "RivPartPriority.h"
|
#include "RivPartPriority.h"
|
||||||
@ -36,17 +37,16 @@
|
|||||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||||
#include "cvfRay.h"
|
#include "cvfRay.h"
|
||||||
|
|
||||||
|
#include "cvfGeometryTools.h"
|
||||||
#include "cvfMath.h"
|
#include "cvfMath.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RicPointTangentManipulatorPartMgr::RicPointTangentManipulatorPartMgr()
|
RicPointTangentManipulatorPartMgr::RicPointTangentManipulatorPartMgr()
|
||||||
: m_tangentOnStartManipulation( cvf::Vec3d::UNDEFINED )
|
: m_tangentOnStartManipulation( cvf::Vec3d::UNDEFINED )
|
||||||
, m_originOnStartManipulation( cvf::Vec3d::UNDEFINED )
|
, m_originOnStartManipulation( cvf::Vec3d::UNDEFINED )
|
||||||
, m_activeHandle( NONE )
|
, m_activeHandle( HandleType::NONE )
|
||||||
, m_handleSize( 1.0 )
|
, m_handleSize( 1.0 )
|
||||||
, m_isGeometryUpdateNeeded( true )
|
, m_isGeometryUpdateNeeded( true )
|
||||||
{
|
{
|
||||||
@ -104,12 +104,20 @@ void RicPointTangentManipulatorPartMgr::originAndTangent( cvf::Vec3d* origin, cv
|
|||||||
*tangent = m_tangent;
|
*tangent = m_tangent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicPointTangentManipulatorPartMgr::setPolyline( const std::vector<cvf::Vec3d>& polyline )
|
||||||
|
{
|
||||||
|
m_polyline = polyline;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RicPointTangentManipulatorPartMgr::isManipulatorActive() const
|
bool RicPointTangentManipulatorPartMgr::isManipulatorActive() const
|
||||||
{
|
{
|
||||||
return m_activeHandle != NONE;
|
return m_activeHandle != HandleType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -172,7 +180,37 @@ void RicPointTangentManipulatorPartMgr::updateManipulatorFromRay( const cvf::Ray
|
|||||||
{
|
{
|
||||||
if ( !isManipulatorActive() ) return;
|
if ( !isManipulatorActive() ) return;
|
||||||
|
|
||||||
if ( m_activeHandle == HORIZONTAL_PLANE )
|
if ( m_activeHandle == HandleType::PRESCRIBED_POLYLINE )
|
||||||
|
{
|
||||||
|
cvf::Plane plane;
|
||||||
|
plane.setFromPointAndNormal( m_origin, newMouseRay->direction() );
|
||||||
|
cvf::Vec3d newIntersection;
|
||||||
|
newMouseRay->planeIntersect( plane, &newIntersection );
|
||||||
|
|
||||||
|
const cvf::Vec3d newOrigin = m_originOnStartManipulation + ( newIntersection - m_initialPickPoint );
|
||||||
|
|
||||||
|
double closestDistance = std::numeric_limits<double>::max();
|
||||||
|
cvf::Vec3d closestPoint;
|
||||||
|
|
||||||
|
for ( size_t i = 1; i < m_polyline.size(); i++ )
|
||||||
|
{
|
||||||
|
const auto& p1 = m_polyline[i];
|
||||||
|
const auto& p2 = m_polyline[i - 1];
|
||||||
|
|
||||||
|
double normalizedIntersection;
|
||||||
|
const auto pointOnLine = cvf::GeometryTools::projectPointOnLine( p1, p2, newOrigin, &normalizedIntersection );
|
||||||
|
|
||||||
|
const double candidateDistance = pointOnLine.pointDistanceSquared( newOrigin );
|
||||||
|
if ( candidateDistance < closestDistance )
|
||||||
|
{
|
||||||
|
closestDistance = candidateDistance;
|
||||||
|
closestPoint = pointOnLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_origin = closestPoint;
|
||||||
|
}
|
||||||
|
else if ( m_activeHandle == HandleType::HORIZONTAL_PLANE )
|
||||||
{
|
{
|
||||||
cvf::Plane plane;
|
cvf::Plane plane;
|
||||||
plane.setFromPointAndNormal( m_origin, cvf::Vec3d::Z_AXIS );
|
plane.setFromPointAndNormal( m_origin, cvf::Vec3d::Z_AXIS );
|
||||||
@ -183,7 +221,7 @@ void RicPointTangentManipulatorPartMgr::updateManipulatorFromRay( const cvf::Ray
|
|||||||
|
|
||||||
m_origin = newOrigin;
|
m_origin = newOrigin;
|
||||||
}
|
}
|
||||||
else if ( m_activeHandle == VERTICAL_AXIS )
|
else if ( m_activeHandle == HandleType::VERTICAL_AXIS )
|
||||||
{
|
{
|
||||||
cvf::Plane plane;
|
cvf::Plane plane;
|
||||||
cvf::Vec3d planeNormal = ( newMouseRay->direction() ^ cvf::Vec3d::Z_AXIS ) ^ cvf::Vec3d::Z_AXIS;
|
cvf::Vec3d planeNormal = ( newMouseRay->direction() ^ cvf::Vec3d::Z_AXIS ) ^ cvf::Vec3d::Z_AXIS;
|
||||||
@ -201,7 +239,6 @@ void RicPointTangentManipulatorPartMgr::updateManipulatorFromRay( const cvf::Ray
|
|||||||
|
|
||||||
m_origin = newOrigin;
|
m_origin = newOrigin;
|
||||||
}
|
}
|
||||||
// m_tangent = newTangent;
|
|
||||||
|
|
||||||
m_isGeometryUpdateNeeded = true;
|
m_isGeometryUpdateNeeded = true;
|
||||||
}
|
}
|
||||||
@ -211,7 +248,7 @@ void RicPointTangentManipulatorPartMgr::updateManipulatorFromRay( const cvf::Ray
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicPointTangentManipulatorPartMgr::endManipulator()
|
void RicPointTangentManipulatorPartMgr::endManipulator()
|
||||||
{
|
{
|
||||||
m_activeHandle = NONE;
|
m_activeHandle = HandleType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -219,8 +256,15 @@ void RicPointTangentManipulatorPartMgr::endManipulator()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicPointTangentManipulatorPartMgr::recreateAllGeometryAndParts()
|
void RicPointTangentManipulatorPartMgr::recreateAllGeometryAndParts()
|
||||||
{
|
{
|
||||||
createHorizontalPlaneHandle();
|
if ( m_polyline.empty() )
|
||||||
createVerticalAxisHandle();
|
{
|
||||||
|
createHorizontalPlaneHandle();
|
||||||
|
createVerticalAxisHandle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
createPolylineHandle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -228,8 +272,15 @@ void RicPointTangentManipulatorPartMgr::recreateAllGeometryAndParts()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicPointTangentManipulatorPartMgr::createGeometryOnly()
|
void RicPointTangentManipulatorPartMgr::createGeometryOnly()
|
||||||
{
|
{
|
||||||
m_handleParts[HORIZONTAL_PLANE]->setDrawable( createHorizontalPlaneGeo().p() );
|
if ( m_polyline.empty() )
|
||||||
m_handleParts[VERTICAL_AXIS]->setDrawable( createVerticalAxisGeo().p() );
|
{
|
||||||
|
m_handleParts[HandleType::HORIZONTAL_PLANE]->setDrawable( createHorizontalPlaneGeo().p() );
|
||||||
|
m_handleParts[HandleType::VERTICAL_AXIS]->setDrawable( createVerticalAxisGeo().p() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_handleParts[HandleType::PRESCRIBED_POLYLINE]->setDrawable( createPolylineGeo().p() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -241,7 +292,7 @@ void RicPointTangentManipulatorPartMgr::createHorizontalPlaneHandle()
|
|||||||
|
|
||||||
ref<cvf::DrawableGeo> geo = createHorizontalPlaneGeo();
|
ref<cvf::DrawableGeo> geo = createHorizontalPlaneGeo();
|
||||||
|
|
||||||
HandleType handleId = HORIZONTAL_PLANE;
|
HandleType handleId = HandleType::HORIZONTAL_PLANE;
|
||||||
cvf::Color4f color = cvf::Color4f( 1.0f, 0.0f, 1.0f, 0.7f );
|
cvf::Color4f color = cvf::Color4f( 1.0f, 0.0f, 1.0f, 0.7f );
|
||||||
cvf::String partName( "PointTangentManipulator Horizontal Plane Handle" );
|
cvf::String partName( "PointTangentManipulator Horizontal Plane Handle" );
|
||||||
|
|
||||||
@ -318,7 +369,7 @@ void RicPointTangentManipulatorPartMgr::createVerticalAxisHandle()
|
|||||||
using namespace cvf;
|
using namespace cvf;
|
||||||
cvf::ref<cvf::DrawableGeo> geo = createVerticalAxisGeo();
|
cvf::ref<cvf::DrawableGeo> geo = createVerticalAxisGeo();
|
||||||
|
|
||||||
HandleType handleId = VERTICAL_AXIS;
|
HandleType handleId = HandleType::VERTICAL_AXIS;
|
||||||
cvf::Color4f color = cvf::Color4f( 0.0f, 0.7f, 0.8f, 0.7f );
|
cvf::Color4f color = cvf::Color4f( 0.0f, 0.7f, 0.8f, 0.7f );
|
||||||
cvf::String partName( "PointTangentManipulator Vertical Axis Handle" );
|
cvf::String partName( "PointTangentManipulator Vertical Axis Handle" );
|
||||||
|
|
||||||
@ -362,6 +413,42 @@ cvf::ref<cvf::DrawableGeo> RicPointTangentManipulatorPartMgr::createVerticalAxis
|
|||||||
return createIndexedTriangelDrawableGeo( vertexArray.p(), indexArray.p() );
|
return createIndexedTriangelDrawableGeo( vertexArray.p(), indexArray.p() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicPointTangentManipulatorPartMgr::createPolylineHandle()
|
||||||
|
{
|
||||||
|
cvf::ref<cvf::DrawableGeo> geo = createPolylineGeo();
|
||||||
|
|
||||||
|
HandleType handleId = HandleType::PRESCRIBED_POLYLINE;
|
||||||
|
cvf::Color4f color = cvf::Color4f( 0.8f, 0.7f, 0.8f, 0.7f );
|
||||||
|
cvf::String partName( "PointTangentManipulator Polyline Handle" );
|
||||||
|
|
||||||
|
addHandlePart( geo.p(), color, handleId, partName );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
cvf::ref<cvf::DrawableGeo> RicPointTangentManipulatorPartMgr::createPolylineGeo()
|
||||||
|
{
|
||||||
|
using namespace cvf;
|
||||||
|
|
||||||
|
cvf::ref<cvf::GeometryBuilderTriangles> geomBuilder = new cvf::GeometryBuilderTriangles;
|
||||||
|
|
||||||
|
double radius = m_handleSize * 0.3;
|
||||||
|
cvf::GeometryUtils::createSphere( radius, 10, 10, geomBuilder.p() );
|
||||||
|
|
||||||
|
Vec3f origin( m_origin );
|
||||||
|
|
||||||
|
geomBuilder->transformVertexRange( 0, geomBuilder->vertexCount() - 1, cvf::Mat4f::fromTranslation( origin ) );
|
||||||
|
|
||||||
|
cvf::ref<cvf::Vec3fArray> vertexArray = geomBuilder->vertices();
|
||||||
|
cvf::ref<cvf::UIntArray> indexArray = geomBuilder->triangles();
|
||||||
|
|
||||||
|
return createIndexedTriangelDrawableGeo( vertexArray.p(), indexArray.p() );
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
@ -38,18 +38,19 @@ class String;
|
|||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
class Array;
|
class Array;
|
||||||
typedef Array<Vec3f> Vec3fArray;
|
using Vec3fArray = Array<Vec3f>;
|
||||||
typedef Array<uint> UIntArray;
|
using UIntArray = Array<uint>;
|
||||||
|
|
||||||
} // namespace cvf
|
} // namespace cvf
|
||||||
|
|
||||||
class RicPointTangentManipulatorPartMgr : public cvf::Object
|
class RicPointTangentManipulatorPartMgr : public cvf::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum HandleType
|
enum class HandleType
|
||||||
{
|
{
|
||||||
HORIZONTAL_PLANE,
|
HORIZONTAL_PLANE,
|
||||||
VERTICAL_AXIS,
|
VERTICAL_AXIS,
|
||||||
|
PRESCRIBED_POLYLINE,
|
||||||
AZIMUTH,
|
AZIMUTH,
|
||||||
INCLINATION,
|
INCLINATION,
|
||||||
NONE
|
NONE
|
||||||
@ -63,6 +64,7 @@ public:
|
|||||||
void setTangent( const cvf::Vec3d& tangent );
|
void setTangent( const cvf::Vec3d& tangent );
|
||||||
void setHandleSize( double handleSize );
|
void setHandleSize( double handleSize );
|
||||||
void originAndTangent( cvf::Vec3d* origin, cvf::Vec3d* tangent );
|
void originAndTangent( cvf::Vec3d* origin, cvf::Vec3d* tangent );
|
||||||
|
void setPolyline( const std::vector<cvf::Vec3d>& polyline );
|
||||||
|
|
||||||
bool isManipulatorActive() const;
|
bool isManipulatorActive() const;
|
||||||
void tryToActivateManipulator( const cvf::HitItem* hitItem );
|
void tryToActivateManipulator( const cvf::HitItem* hitItem );
|
||||||
@ -81,6 +83,9 @@ private:
|
|||||||
void createVerticalAxisHandle();
|
void createVerticalAxisHandle();
|
||||||
cvf::ref<cvf::DrawableGeo> createVerticalAxisGeo();
|
cvf::ref<cvf::DrawableGeo> createVerticalAxisGeo();
|
||||||
|
|
||||||
|
void createPolylineHandle();
|
||||||
|
cvf::ref<cvf::DrawableGeo> createPolylineGeo();
|
||||||
|
|
||||||
void addHandlePart( cvf::DrawableGeo* geo, const cvf::Color4f& color, HandleType handleId, const cvf::String& partName );
|
void addHandlePart( cvf::DrawableGeo* geo, const cvf::Color4f& color, HandleType handleId, const cvf::String& partName );
|
||||||
|
|
||||||
void addActiveModePart( cvf::DrawableGeo* geo, const cvf::Color4f& color, HandleType handleId, const cvf::String& partName );
|
void addActiveModePart( cvf::DrawableGeo* geo, const cvf::Color4f& color, HandleType handleId, const cvf::String& partName );
|
||||||
@ -99,6 +104,8 @@ private:
|
|||||||
double m_handleSize;
|
double m_handleSize;
|
||||||
bool m_isGeometryUpdateNeeded;
|
bool m_isGeometryUpdateNeeded;
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> m_polyline;
|
||||||
|
|
||||||
HandleType m_activeHandle;
|
HandleType m_activeHandle;
|
||||||
cvf::Vec3d m_initialPickPoint;
|
cvf::Vec3d m_initialPickPoint;
|
||||||
cvf::Vec3d m_tangentOnStartManipulation;
|
cvf::Vec3d m_tangentOnStartManipulation;
|
||||||
|
@ -20,12 +20,15 @@
|
|||||||
|
|
||||||
#include "RicPointTangentManipulator.h"
|
#include "RicPointTangentManipulator.h"
|
||||||
|
|
||||||
|
#include "RigWellPath.h"
|
||||||
|
|
||||||
#include "Rim3dView.h"
|
#include "Rim3dView.h"
|
||||||
#include "RimCase.h"
|
#include "RimCase.h"
|
||||||
#include "RimModeledWellPath.h"
|
#include "RimModeledWellPath.h"
|
||||||
#include "RimWellPathGeometryDef.h"
|
#include "RimWellPathGeometryDef.h"
|
||||||
#include "RimWellPathGeometryDefTools.h"
|
#include "RimWellPathGeometryDefTools.h"
|
||||||
#include "RimWellPathTarget.h"
|
#include "RimWellPathTarget.h"
|
||||||
|
#include "RimWellPathTieIn.h"
|
||||||
|
|
||||||
#include "RiuViewer.h"
|
#include "RiuViewer.h"
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ RicWellTarget3dEditor::RicWellTarget3dEditor()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RicWellTarget3dEditor::~RicWellTarget3dEditor()
|
RicWellTarget3dEditor::~RicWellTarget3dEditor()
|
||||||
{
|
{
|
||||||
RiuViewer* ownerRiuViewer = dynamic_cast<RiuViewer*>( ownerViewer() );
|
auto* ownerRiuViewer = dynamic_cast<RiuViewer*>( ownerViewer() );
|
||||||
|
|
||||||
if ( m_cvfModel.notNull() && ownerRiuViewer )
|
if ( m_cvfModel.notNull() && ownerRiuViewer )
|
||||||
{
|
{
|
||||||
@ -68,9 +71,9 @@ RicWellTarget3dEditor::~RicWellTarget3dEditor()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicWellTarget3dEditor::configureAndUpdateUi( const QString& uiConfigName )
|
void RicWellTarget3dEditor::configureAndUpdateUi( const QString& uiConfigName )
|
||||||
{
|
{
|
||||||
RimWellPathTarget* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
auto* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
||||||
RiuViewer* ownerRiuViewer = dynamic_cast<RiuViewer*>( ownerViewer() );
|
auto* ownerRiuViewer = dynamic_cast<RiuViewer*>( ownerViewer() );
|
||||||
Rim3dView* view = mainOrComparisonView();
|
Rim3dView* view = mainOrComparisonView();
|
||||||
|
|
||||||
if ( !target || !target->isEnabled() || !view )
|
if ( !target || !target->isEnabled() || !view )
|
||||||
{
|
{
|
||||||
@ -110,6 +113,29 @@ void RicWellTarget3dEditor::configureAndUpdateUi( const QString& uiConfigName )
|
|||||||
m_manipulator->setTangent( target->tangent() );
|
m_manipulator->setTangent( target->tangent() );
|
||||||
m_manipulator->setHandleSize( handleSize );
|
m_manipulator->setHandleSize( handleSize );
|
||||||
|
|
||||||
|
{
|
||||||
|
RimWellPath* wellPath = nullptr;
|
||||||
|
target->firstAncestorOrThisOfType( wellPath );
|
||||||
|
|
||||||
|
if ( wellPath && !wellPath->isTopLevelWellPath() && geomDef->firstActiveTarget() == target )
|
||||||
|
{
|
||||||
|
if ( auto parentWellPath = wellPath->wellPathTieIn()->parentWell() )
|
||||||
|
{
|
||||||
|
auto geo = parentWellPath->wellPathGeometry();
|
||||||
|
auto points = geo->wellPathPoints();
|
||||||
|
|
||||||
|
for ( auto& p : points )
|
||||||
|
{
|
||||||
|
p = dispXf->transformToDisplayCoord( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the first target of a lateral, use the coordinates from the parent well as snap-to locations for
|
||||||
|
// the 3D manipulator sphere
|
||||||
|
m_manipulator->setPolyline( points );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_cvfModel->removeAllParts();
|
m_cvfModel->removeAllParts();
|
||||||
m_manipulator->appendPartsToModel( m_cvfModel.p() );
|
m_manipulator->appendPartsToModel( m_cvfModel.p() );
|
||||||
|
|
||||||
@ -129,64 +155,167 @@ void RicWellTarget3dEditor::cleanupBeforeSettingPdmObject()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicWellTarget3dEditor::slotUpdated( const cvf::Vec3d& origin, const cvf::Vec3d& tangent )
|
void RicWellTarget3dEditor::slotUpdated( const cvf::Vec3d& origin, const cvf::Vec3d& tangent )
|
||||||
{
|
{
|
||||||
RimWellPathTarget* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
auto* manipulatedTarget = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
||||||
Rim3dView* view = mainOrComparisonView();
|
Rim3dView* view = mainOrComparisonView();
|
||||||
|
|
||||||
if ( !target || !view )
|
if ( !manipulatedTarget || !view )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RimWellPathGeometryDef* geomDef;
|
RimWellPathGeometryDef* geomDef;
|
||||||
target->firstAncestorOrThisOfTypeAsserted( geomDef );
|
manipulatedTarget->firstAncestorOrThisOfTypeAsserted( geomDef );
|
||||||
if ( !geomDef ) return;
|
if ( !geomDef ) return;
|
||||||
|
|
||||||
if ( geomDef->useReferencePointFromTopLevelWell() )
|
RimModeledWellPath* modeledWellPath = nullptr;
|
||||||
|
geomDef->firstAncestorOfType( modeledWellPath );
|
||||||
|
|
||||||
|
cvf::Vec3d domainCoordXYZ; // domain coordinate of the new location
|
||||||
|
cvf::Vec3d deltaManipulatorMovement; // delta change relative current location of target
|
||||||
|
cvf::Vec3d relativePositionXYZ; // position of well target relative to anchor point
|
||||||
{
|
{
|
||||||
RimModeledWellPath* modeledWellPath = nullptr;
|
cvf::ref<caf::DisplayCoordTransform> dispXf = view->displayCoordTransform();
|
||||||
geomDef->firstAncestorOfType( modeledWellPath );
|
domainCoordXYZ = dispXf->transformToDomainCoord( origin );
|
||||||
if ( modeledWellPath )
|
|
||||||
|
relativePositionXYZ = domainCoordXYZ - geomDef->anchorPointXyz();
|
||||||
|
deltaManipulatorMovement = manipulatedTarget->targetPointXYZ() - relativePositionXYZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( geomDef->activeWellTargets().front() == manipulatedTarget )
|
||||||
|
{
|
||||||
|
// The first well target of a lateral is the tie-in well target
|
||||||
|
|
||||||
|
if ( modeledWellPath && modeledWellPath->wellPathTieIn() && modeledWellPath->wellPathTieIn()->parentWell() )
|
||||||
{
|
{
|
||||||
auto topLevelWellPath = dynamic_cast<RimModeledWellPath*>( modeledWellPath->topLevelWellPath() );
|
auto parentWell = modeledWellPath->wellPathTieIn()->parentWell();
|
||||||
if ( topLevelWellPath )
|
auto wellPathGeo = parentWell->wellPathGeometry();
|
||||||
|
auto closestMD = wellPathGeo->closestMeasuredDepth( domainCoordXYZ );
|
||||||
|
|
||||||
|
modeledWellPath->wellPathTieIn()->setTieInMeasuredDepth( closestMD );
|
||||||
|
modeledWellPath->wellPathTieIn()->updateChildWellGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool modifyAllTargetsOnAllWells = ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) &&
|
||||||
|
( QApplication::keyboardModifiers() & Qt::SHIFT ) );
|
||||||
|
|
||||||
|
if ( modifyAllTargetsOnAllWells )
|
||||||
|
{
|
||||||
|
for ( auto wellLateral : modeledWellPath->wellPathLaterals() )
|
||||||
{
|
{
|
||||||
// Manipulate the reference point of top level well path
|
if ( auto modeledLateral = dynamic_cast<RimModeledWellPath*>( wellLateral ) )
|
||||||
geomDef = topLevelWellPath->geometryDefinition();
|
{
|
||||||
|
auto activeTargets = modeledLateral->geometryDefinition()->activeWellTargets();
|
||||||
|
for ( auto t : activeTargets )
|
||||||
|
{
|
||||||
|
if ( t == activeTargets.front() ) continue;
|
||||||
|
if ( t == manipulatedTarget ) continue;
|
||||||
|
|
||||||
|
// Does not work very well
|
||||||
|
// Must update the tie-in MD also
|
||||||
|
updateTargetWithDeltaChange( t, deltaManipulatorMovement );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( QApplication::keyboardModifiers() & Qt::ControlModifier )
|
||||||
|
{
|
||||||
|
for ( auto target : geomDef->activeWellTargets() )
|
||||||
|
{
|
||||||
|
if ( target == geomDef->activeWellTargets().front() ) continue;
|
||||||
|
|
||||||
|
updateTargetWithDeltaChange( target, deltaManipulatorMovement );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cvf::Vec3d relativePositionXYD = relativePositionXYZ;
|
||||||
|
relativePositionXYD.z() = -relativePositionXYD.z();
|
||||||
|
|
||||||
|
manipulatedTarget->updateFrom3DManipulator( relativePositionXYD );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( modeledWellPath && modeledWellPath->isTopLevelWellPath() )
|
||||||
|
{
|
||||||
|
// Modification of top level well path
|
||||||
|
|
||||||
|
bool modifyReferencePoint = ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) &&
|
||||||
|
( QApplication::keyboardModifiers() & Qt::SHIFT ) );
|
||||||
|
if ( modifyReferencePoint )
|
||||||
|
{
|
||||||
|
// Find all linked wells and update reference point with delta change
|
||||||
|
std::vector<RimWellPathGeometryDef*> linkedWellPathGeoDefs;
|
||||||
|
if ( geomDef->isReferencePointUpdatesLinked() )
|
||||||
|
{
|
||||||
|
linkedWellPathGeoDefs = RimWellPathGeometryDefTools::linkedDefinitions();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
linkedWellPathGeoDefs.push_back( geomDef );
|
||||||
|
}
|
||||||
|
|
||||||
|
RimWellPathGeometryDefTools::updateLinkedGeometryDefinitions( linkedWellPathGeoDefs, deltaManipulatorMovement );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool modifyAllTargetOnWell = ( QApplication::keyboardModifiers() & Qt::ControlModifier );
|
||||||
|
if ( modifyAllTargetOnWell )
|
||||||
|
{
|
||||||
|
for ( auto t : geomDef->activeWellTargets() )
|
||||||
|
{
|
||||||
|
if ( t == manipulatedTarget ) continue;
|
||||||
|
|
||||||
|
updateTargetWithDeltaChange( t, deltaManipulatorMovement );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( modeledWellPath && !modeledWellPath->isTopLevelWellPath() )
|
||||||
|
{
|
||||||
|
bool modifyAllTargetsOnAllWells = ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) &&
|
||||||
|
( QApplication::keyboardModifiers() & Qt::SHIFT ) );
|
||||||
|
if ( modifyAllTargetsOnAllWells )
|
||||||
|
{
|
||||||
|
// Update all well targets on all connected laterals
|
||||||
|
|
||||||
|
for ( auto wellLateral : modeledWellPath->wellPathLaterals() )
|
||||||
|
{
|
||||||
|
if ( auto modeledLateral = dynamic_cast<RimModeledWellPath*>( wellLateral ) )
|
||||||
|
{
|
||||||
|
auto activeTargets = modeledLateral->geometryDefinition()->activeWellTargets();
|
||||||
|
for ( auto t : activeTargets )
|
||||||
|
{
|
||||||
|
if ( t == activeTargets.front() ) continue;
|
||||||
|
if ( t == manipulatedTarget ) continue;
|
||||||
|
|
||||||
|
updateTargetWithDeltaChange( t, deltaManipulatorMovement );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool modifyAllTargets = ( QApplication::keyboardModifiers() & Qt::ControlModifier );
|
||||||
|
if ( modifyAllTargets )
|
||||||
|
{
|
||||||
|
// Update all well targets on current well path
|
||||||
|
|
||||||
|
for ( auto t : geomDef->activeWellTargets() )
|
||||||
|
{
|
||||||
|
if ( t == geomDef->activeWellTargets().front() ) continue;
|
||||||
|
if ( t == manipulatedTarget ) continue;
|
||||||
|
|
||||||
|
updateTargetWithDeltaChange( t, deltaManipulatorMovement );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cvf::ref<caf::DisplayCoordTransform> dispXf = view->displayCoordTransform();
|
// Modify a single well target
|
||||||
|
|
||||||
auto domainCoordXYZ = dispXf->transformToDomainCoord( origin );
|
|
||||||
|
|
||||||
// If CTRL is pressed, modify the reference point instead of the well path target
|
|
||||||
bool modifyReferencePoint = ( QApplication::keyboardModifiers() & Qt::ControlModifier );
|
|
||||||
if ( modifyReferencePoint )
|
|
||||||
{
|
{
|
||||||
auto relativePositionXYZ = domainCoordXYZ - geomDef->anchorPointXyz();
|
cvf::Vec3d relativePositionXYD = relativePositionXYZ;
|
||||||
auto delta = target->targetPointXYZ() - relativePositionXYZ;
|
|
||||||
|
|
||||||
// Find all linked wells and update with delta change
|
|
||||||
|
|
||||||
std::vector<RimWellPathGeometryDef*> linkedWellPathGeoDefs;
|
|
||||||
if ( geomDef->isReferencePointUpdatesLinked() )
|
|
||||||
{
|
|
||||||
linkedWellPathGeoDefs = RimWellPathGeometryDefTools::linkedDefinitions();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
linkedWellPathGeoDefs.push_back( geomDef );
|
|
||||||
}
|
|
||||||
|
|
||||||
RimWellPathGeometryDefTools::updateLinkedGeometryDefinitions( linkedWellPathGeoDefs, delta );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cvf::Vec3d relativePositionXYD = domainCoordXYZ - geomDef->anchorPointXyz();
|
|
||||||
relativePositionXYD.z() = -relativePositionXYD.z();
|
relativePositionXYD.z() = -relativePositionXYD.z();
|
||||||
|
|
||||||
target->updateFrom3DManipulator( relativePositionXYD );
|
manipulatedTarget->updateFrom3DManipulator( relativePositionXYD );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +324,7 @@ void RicWellTarget3dEditor::slotUpdated( const cvf::Vec3d& origin, const cvf::Ve
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicWellTarget3dEditor::slotSelectedIn3D()
|
void RicWellTarget3dEditor::slotSelectedIn3D()
|
||||||
{
|
{
|
||||||
RimWellPathTarget* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
auto* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
||||||
if ( !target )
|
if ( !target )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -209,7 +338,7 @@ void RicWellTarget3dEditor::slotSelectedIn3D()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicWellTarget3dEditor::slotDragFinished()
|
void RicWellTarget3dEditor::slotDragFinished()
|
||||||
{
|
{
|
||||||
RimWellPathTarget* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
auto* target = dynamic_cast<RimWellPathTarget*>( this->pdmObject() );
|
||||||
if ( !target )
|
if ( !target )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -223,7 +352,7 @@ void RicWellTarget3dEditor::slotDragFinished()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicWellTarget3dEditor::removeAllFieldEditors()
|
void RicWellTarget3dEditor::removeAllFieldEditors()
|
||||||
{
|
{
|
||||||
if ( RimWellPathTarget* oldTarget = dynamic_cast<RimWellPathTarget*>( this->pdmObject() ) )
|
if ( auto* oldTarget = dynamic_cast<RimWellPathTarget*>( this->pdmObject() ) )
|
||||||
{
|
{
|
||||||
for ( auto field : oldTarget->fieldsFor3dManipulator() )
|
for ( auto field : oldTarget->fieldsFor3dManipulator() )
|
||||||
{
|
{
|
||||||
@ -231,3 +360,13 @@ void RicWellTarget3dEditor::removeAllFieldEditors()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicWellTarget3dEditor::updateTargetWithDeltaChange( RimWellPathTarget* target, const cvf::Vec3d& delta )
|
||||||
|
{
|
||||||
|
auto coordXYZ = target->targetPointXYZ() - delta;
|
||||||
|
target->setPointXYZ( coordXYZ );
|
||||||
|
target->updateConnectedEditors();
|
||||||
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
class RicPointTangentManipulator;
|
class RicPointTangentManipulator;
|
||||||
|
class RimWellPathTarget;
|
||||||
|
|
||||||
namespace cvf
|
namespace cvf
|
||||||
{
|
{
|
||||||
@ -54,6 +55,8 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void removeAllFieldEditors();
|
void removeAllFieldEditors();
|
||||||
|
|
||||||
|
static void updateTargetWithDeltaChange( RimWellPathTarget* target, const cvf::Vec3d& delta );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPointer<RicPointTangentManipulator> m_manipulator;
|
QPointer<RicPointTangentManipulator> m_manipulator;
|
||||||
cvf::ref<cvf::ModelBasicList> m_cvfModel;
|
cvf::ref<cvf::ModelBasicList> m_cvfModel;
|
||||||
|
@ -66,21 +66,27 @@ void RicCreateMultipleWellPathLaterals::onActionTriggered( bool isChecked )
|
|||||||
|
|
||||||
if ( selected )
|
if ( selected )
|
||||||
{
|
{
|
||||||
m_ui->setSourceLateral( selected );
|
m_ui->setTopLevelWellPath( selected->topLevelWellPath() );
|
||||||
|
|
||||||
double startMD = 0.0;
|
double startMD = 0.0;
|
||||||
double endMD = 0.0;
|
double endMD = 0.0;
|
||||||
if ( auto tieIn = selected->wellPathTieIn() )
|
|
||||||
|
auto sourceLateral = m_ui->sourceLateral();
|
||||||
|
if ( sourceLateral )
|
||||||
{
|
{
|
||||||
startMD = selected->wellPathTieIn()->tieInMeasuredDepth() + 50.0;
|
if ( auto tieIn = sourceLateral->wellPathTieIn() )
|
||||||
endMD = startMD + 50.0;
|
|
||||||
|
|
||||||
if ( auto parentWell = selected->wellPathTieIn()->parentWell() )
|
|
||||||
{
|
{
|
||||||
if ( !parentWell->wellPathGeometry()->measuredDepths().empty() )
|
startMD = sourceLateral->wellPathTieIn()->tieInMeasuredDepth() + 50.0;
|
||||||
{
|
endMD = startMD + 50.0;
|
||||||
double candidate = parentWell->wellPathGeometry()->measuredDepths().back() - 50.0;
|
|
||||||
|
|
||||||
if ( candidate > startMD ) endMD = candidate;
|
if ( auto parentWell = sourceLateral->wellPathTieIn()->parentWell() )
|
||||||
|
{
|
||||||
|
if ( !parentWell->wellPathGeometry()->measuredDepths().empty() )
|
||||||
|
{
|
||||||
|
double candidate = parentWell->wellPathGeometry()->measuredDepths().back() - 50.0;
|
||||||
|
|
||||||
|
if ( candidate > startMD ) endMD = candidate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,9 @@ RicCreateMultipleWellPathLateralsUi::RicCreateMultipleWellPathLateralsUi()
|
|||||||
{
|
{
|
||||||
CAF_PDM_InitFieldNoDefault( &m_sourceLateral, "SourceLaterals", "Source Well Path Lateral", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_sourceLateral, "SourceLaterals", "Source Well Path Lateral", "", "", "" );
|
||||||
|
|
||||||
|
CAF_PDM_InitFieldNoDefault( &m_topLevelWellPath, "TopLevelWellPath", "Top Level Well Path", "", "", "" );
|
||||||
|
m_topLevelWellPath.uiCapability()->setUiHidden( true );
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault( &m_locations, "Locations", "Locations", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_locations, "Locations", "Locations", "", "", "" );
|
||||||
m_locations = new RimMultipleLocations;
|
m_locations = new RimMultipleLocations;
|
||||||
}
|
}
|
||||||
@ -54,9 +57,13 @@ RicCreateMultipleWellPathLateralsUi::RicCreateMultipleWellPathLateralsUi()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicCreateMultipleWellPathLateralsUi::setSourceLateral( RimModeledWellPath* lateral )
|
void RicCreateMultipleWellPathLateralsUi::setTopLevelWellPath( RimWellPath* wellPath )
|
||||||
{
|
{
|
||||||
m_sourceLateral = lateral;
|
m_topLevelWellPath = wellPath;
|
||||||
|
|
||||||
|
auto laterals = RimTools::wellPathCollection()->connectedWellPathLaterals( m_topLevelWellPath );
|
||||||
|
|
||||||
|
if ( !laterals.empty() ) m_sourceLateral = dynamic_cast<RimModeledWellPath*>( laterals.front() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -108,14 +115,15 @@ QList<caf::PdmOptionItemInfo>
|
|||||||
|
|
||||||
if ( fieldNeedingOptions == &m_sourceLateral )
|
if ( fieldNeedingOptions == &m_sourceLateral )
|
||||||
{
|
{
|
||||||
if ( sourceLateral()->wellPathTieIn() && sourceLateral()->wellPathTieIn()->parentWell() )
|
if ( m_topLevelWellPath )
|
||||||
{
|
{
|
||||||
auto parentWell = sourceLateral()->wellPathTieIn()->parentWell();
|
auto laterals = RimTools::wellPathCollection()->connectedWellPathLaterals( m_topLevelWellPath );
|
||||||
auto laterals = RimTools::wellPathCollection()->connectedWellPathLaterals( parentWell );
|
|
||||||
|
|
||||||
for ( auto lateral : laterals )
|
for ( auto lateral : laterals )
|
||||||
{
|
{
|
||||||
options.push_back( caf::PdmOptionItemInfo( lateral->name(), lateral ) );
|
caf::IconProvider iconProvider = lateral->uiIconProvider();
|
||||||
|
|
||||||
|
options.push_back( caf::PdmOptionItemInfo( lateral->name(), lateral, false, iconProvider ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
class RimModeledWellPath;
|
class RimModeledWellPath;
|
||||||
|
class RimWellPath;
|
||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
@ -46,7 +47,7 @@ class RicCreateMultipleWellPathLateralsUi : public caf::PdmObject
|
|||||||
public:
|
public:
|
||||||
RicCreateMultipleWellPathLateralsUi();
|
RicCreateMultipleWellPathLateralsUi();
|
||||||
|
|
||||||
void setSourceLateral( RimModeledWellPath* lateral );
|
void setTopLevelWellPath( RimWellPath* wellPath );
|
||||||
void setDefaultValues( double start, double end );
|
void setDefaultValues( double start, double end );
|
||||||
|
|
||||||
RimModeledWellPath* sourceLateral() const;
|
RimModeledWellPath* sourceLateral() const;
|
||||||
@ -60,6 +61,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
caf::PdmPtrField<RimModeledWellPath*> m_sourceLateral;
|
caf::PdmPtrField<RimModeledWellPath*> m_sourceLateral;
|
||||||
|
caf::PdmPtrField<RimWellPath*> m_topLevelWellPath;
|
||||||
|
|
||||||
caf::PdmChildField<RimMultipleLocations*> m_locations;
|
caf::PdmChildField<RimMultipleLocations*> m_locations;
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "RigHexIntersectionTools.h"
|
#include "RigHexIntersectionTools.h"
|
||||||
#include "RigMainGrid.h"
|
#include "RigMainGrid.h"
|
||||||
#include "RigWellPath.h"
|
#include "RigWellPath.h"
|
||||||
|
#include "RigWellPathGeometryTools.h"
|
||||||
|
|
||||||
#include "Rim3dView.h"
|
#include "Rim3dView.h"
|
||||||
#include "RimEclipseView.h"
|
#include "RimEclipseView.h"
|
||||||
@ -111,8 +112,15 @@ bool RicCreateWellTargetsPickEventHandler::handle3dPickEvent( const Ric3dPickEve
|
|||||||
targetPointInDomain =
|
targetPointInDomain =
|
||||||
wellPathSourceInfo->closestPointOnCenterLine( firstPickItem.faceIdx(), intersectionPointInDomain );
|
wellPathSourceInfo->closestPointOnCenterLine( firstPickItem.faceIdx(), intersectionPointInDomain );
|
||||||
double md = wellPathSourceInfo->measuredDepth( firstPickItem.faceIdx(), intersectionPointInDomain );
|
double md = wellPathSourceInfo->measuredDepth( firstPickItem.faceIdx(), intersectionPointInDomain );
|
||||||
doSetAzimuthAndInclination = calculateAzimuthAndInclinationAtMd( md, wellPathGeometry, &azimuth, &inclination );
|
|
||||||
double rkbDiff = wellPathGeometry->rkbDiff();
|
{
|
||||||
|
const auto [az, inc] = RigWellPathGeometryTools::calculateAzimuthAndInclinationAtMd( md, wellPathGeometry );
|
||||||
|
azimuth = az;
|
||||||
|
inclination = inc;
|
||||||
|
doSetAzimuthAndInclination = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double rkbDiff = wellPathGeometry->rkbDiff();
|
||||||
if ( m_geometryToAddTargetsTo->airGap() == 0.0 && rkbDiff != std::numeric_limits<double>::infinity() )
|
if ( m_geometryToAddTargetsTo->airGap() == 0.0 && rkbDiff != std::numeric_limits<double>::infinity() )
|
||||||
{
|
{
|
||||||
m_geometryToAddTargetsTo->setAirGap( rkbDiff );
|
m_geometryToAddTargetsTo->setAirGap( rkbDiff );
|
||||||
@ -190,59 +198,6 @@ bool RicCreateWellTargetsPickEventHandler::handle3dPickEvent( const Ric3dPickEve
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
bool RicCreateWellTargetsPickEventHandler::calculateAzimuthAndInclinationAtMd( double measuredDepth,
|
|
||||||
gsl::not_null<const RigWellPath*> wellPathGeometry,
|
|
||||||
double* azimuth,
|
|
||||||
double* inclination ) const
|
|
||||||
{
|
|
||||||
int mdIndex = -1;
|
|
||||||
auto mdList = wellPathGeometry->measuredDepths();
|
|
||||||
|
|
||||||
for ( int i = 0; i < (int)mdList.size(); i++ )
|
|
||||||
{
|
|
||||||
if ( mdList[i] > measuredDepth )
|
|
||||||
{
|
|
||||||
mdIndex = i - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ptList = wellPathGeometry->wellPathPoints();
|
|
||||||
if ( mdIndex > 0 && mdIndex < (int)ptList.size() - 2 )
|
|
||||||
{
|
|
||||||
auto v1 = cvf::Vec3d( ptList[mdIndex - 1] );
|
|
||||||
auto v2 = cvf::Vec3d( ptList[mdIndex] );
|
|
||||||
auto v3 = cvf::Vec3d( ptList[mdIndex + 1] );
|
|
||||||
auto v4 = cvf::Vec3d( ptList[mdIndex + 2] );
|
|
||||||
|
|
||||||
auto v21 = v2 - v1;
|
|
||||||
auto v32 = v3 - v2;
|
|
||||||
auto v43 = v4 - v3;
|
|
||||||
|
|
||||||
v21.normalize();
|
|
||||||
v32.normalize();
|
|
||||||
v43.normalize();
|
|
||||||
|
|
||||||
auto v13mean = ( v21 + v32 ) / 2;
|
|
||||||
auto v24mean = ( v32 + v43 ) / 2;
|
|
||||||
|
|
||||||
double weight = ( measuredDepth - mdList[mdIndex] ) / ( mdList[mdIndex + 1] - mdList[mdIndex] );
|
|
||||||
auto vTan = v13mean * weight + v24mean * ( 1 - weight );
|
|
||||||
|
|
||||||
RiaOffshoreSphericalCoords coords( vTan );
|
|
||||||
*azimuth = coords.azi();
|
|
||||||
*inclination = coords.inc();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*azimuth = 0.0;
|
|
||||||
*inclination = 0.0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -43,11 +43,6 @@ protected:
|
|||||||
void notifyUnregistered() override;
|
void notifyUnregistered() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool calculateAzimuthAndInclinationAtMd( double measuredDepth,
|
|
||||||
gsl::not_null<const RigWellPath*> wellPathGeometry,
|
|
||||||
double* azimuth,
|
|
||||||
double* inclination ) const;
|
|
||||||
|
|
||||||
static bool isGridSourceObject( const cvf::Object* object );
|
static bool isGridSourceObject( const cvf::Object* object );
|
||||||
static cvf::Vec3d findHexElementIntersection( gsl::not_null<Rim3dView*> view,
|
static cvf::Vec3d findHexElementIntersection( gsl::not_null<Rim3dView*> view,
|
||||||
const RiuPickItemInfo& pickItem,
|
const RiuPickItemInfo& pickItem,
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021- 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 "RicDeleteWellPathFeature.h"
|
||||||
|
|
||||||
|
#include "RimTools.h"
|
||||||
|
#include "RimWellPath.h"
|
||||||
|
#include "RimWellPathCollection.h"
|
||||||
|
|
||||||
|
#include "cafSelectionManager.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
CAF_CMD_SOURCE_INIT( RicDeleteWellPathFeature, "RicDeleteWellPathFeature" );
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RicDeleteWellPathFeature::isCommandEnabled()
|
||||||
|
{
|
||||||
|
std::vector<RimWellPath*> objects;
|
||||||
|
caf::SelectionManager::instance()->objectsByType( &objects );
|
||||||
|
|
||||||
|
return !objects.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicDeleteWellPathFeature::onActionTriggered( bool isChecked )
|
||||||
|
{
|
||||||
|
std::vector<RimWellPath*> wellPaths;
|
||||||
|
caf::SelectionManager::instance()->objectsByType( &wellPaths );
|
||||||
|
|
||||||
|
if ( !wellPaths.empty() )
|
||||||
|
{
|
||||||
|
auto wpc = RimTools::wellPathCollection();
|
||||||
|
|
||||||
|
for ( auto w : wellPaths )
|
||||||
|
{
|
||||||
|
for ( auto wl : w->allWellPathLaterals() )
|
||||||
|
{
|
||||||
|
wpc->deleteWell( wl );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wpc->rebuildWellPathNodes();
|
||||||
|
wpc->scheduleRedrawAffectedViews();
|
||||||
|
wpc->updateAllRequiredEditors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RicDeleteWellPathFeature::setupActionLook( QAction* actionToSetup )
|
||||||
|
{
|
||||||
|
actionToSetup->setText( "Delete Well Path" );
|
||||||
|
actionToSetup->setIcon( QIcon( ":/Erase.svg" ) );
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021- 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 RicDeleteWellPathFeature : public caf::CmdFeature
|
||||||
|
{
|
||||||
|
CAF_CMD_HEADER_INIT;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isCommandEnabled() override;
|
||||||
|
void onActionTriggered( bool isChecked ) override;
|
||||||
|
void setupActionLook( QAction* actionToSetup ) override;
|
||||||
|
};
|
@ -24,6 +24,7 @@
|
|||||||
#include "Riu3dSelectionManager.h"
|
#include "Riu3dSelectionManager.h"
|
||||||
|
|
||||||
#include "cafSelectionManager.h"
|
#include "cafSelectionManager.h"
|
||||||
|
#include "cafSelectionManagerTools.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ CAF_CMD_SOURCE_INIT( RicLinkWellPathFeature, "RicLinkWellPathFeature" );
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RicLinkWellPathFeature::isCommandEnabled()
|
bool RicLinkWellPathFeature::isCommandEnabled()
|
||||||
{
|
{
|
||||||
return ( wellPathGeometryDef() != nullptr );
|
return ( !wellPaths().empty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -42,10 +43,14 @@ bool RicLinkWellPathFeature::isCommandEnabled()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RicLinkWellPathFeature::onActionTriggered( bool isChecked )
|
void RicLinkWellPathFeature::onActionTriggered( bool isChecked )
|
||||||
{
|
{
|
||||||
if ( auto geoDef = wellPathGeometryDef() )
|
for ( auto w : wellPaths() )
|
||||||
{
|
{
|
||||||
geoDef->enableLinkOfReferencePointUpdates( isChecked );
|
if ( auto modeledWell = dynamic_cast<RimModeledWellPath*>( w ) )
|
||||||
geoDef->updateConnectedEditors();
|
{
|
||||||
|
auto geoDef = modeledWell->geometryDefinition();
|
||||||
|
geoDef->enableLinkOfReferencePointUpdates( isChecked );
|
||||||
|
geoDef->updateConnectedEditors();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +63,8 @@ void RicLinkWellPathFeature::setupActionLook( QAction* actionToSetup )
|
|||||||
actionToSetup->setText( text );
|
actionToSetup->setText( text );
|
||||||
actionToSetup->setCheckable( true );
|
actionToSetup->setCheckable( true );
|
||||||
actionToSetup->setChecked( isCommandChecked() );
|
actionToSetup->setChecked( isCommandChecked() );
|
||||||
|
|
||||||
|
actionToSetup->setIcon( QIcon( ":/chain.png" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -65,27 +72,39 @@ void RicLinkWellPathFeature::setupActionLook( QAction* actionToSetup )
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RicLinkWellPathFeature::isCommandChecked()
|
bool RicLinkWellPathFeature::isCommandChecked()
|
||||||
{
|
{
|
||||||
if ( auto geoDef = wellPathGeometryDef() )
|
if ( !wellPaths().empty() )
|
||||||
{
|
{
|
||||||
return geoDef->isReferencePointUpdatesLinked();
|
auto firstWell = dynamic_cast<RimModeledWellPath*>( wellPaths().front() );
|
||||||
|
if ( auto geoDef = firstWell->geometryDefinition() )
|
||||||
|
{
|
||||||
|
return geoDef->isReferencePointUpdatesLinked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RimWellPathGeometryDef* RicLinkWellPathFeature::wellPathGeometryDef()
|
std::vector<RimWellPath*> RicLinkWellPathFeature::wellPaths()
|
||||||
{
|
{
|
||||||
|
std::vector<RimWellPath*> wellPaths;
|
||||||
|
|
||||||
auto wellPathSelectionItem = RiuWellPathSelectionItem::wellPathSelectionItem();
|
auto wellPathSelectionItem = RiuWellPathSelectionItem::wellPathSelectionItem();
|
||||||
if ( wellPathSelectionItem && wellPathSelectionItem->m_wellpath )
|
if ( wellPathSelectionItem && wellPathSelectionItem->m_wellpath )
|
||||||
{
|
{
|
||||||
if ( auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( wellPathSelectionItem->m_wellpath ) )
|
if ( auto modeledWellPath =
|
||||||
|
dynamic_cast<RimModeledWellPath*>( wellPathSelectionItem->m_wellpath->topLevelWellPath() ) )
|
||||||
{
|
{
|
||||||
return modeledWellPath->geometryDefinition();
|
wellPaths.push_back( modeledWellPath );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
auto selectedWells = caf::selectedObjectsByTypeStrict<RimWellPath*>();
|
||||||
|
for ( auto w : selectedWells )
|
||||||
|
{
|
||||||
|
wellPaths.push_back( w->topLevelWellPath() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return wellPaths;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "cafCmdFeature.h"
|
#include "cafCmdFeature.h"
|
||||||
|
|
||||||
class RimWellPathGeometryDef;
|
class RimWellPath;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
///
|
///
|
||||||
@ -36,5 +36,5 @@ public:
|
|||||||
bool isCommandChecked() override;
|
bool isCommandChecked() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static RimWellPathGeometryDef* wellPathGeometryDef();
|
static std::vector<RimWellPath*> wellPaths();
|
||||||
};
|
};
|
||||||
|
@ -84,8 +84,8 @@ void RicNewWellPathLateralAtDepthFeature::setupActionLook( QAction* actionToSetu
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RimWellPath* RicNewWellPathLateralAtDepthFeature::createLateralAtMeasuredDepth( RimWellPath* parentWellPath,
|
RimModeledWellPath* RicNewWellPathLateralAtDepthFeature::createLateralAtMeasuredDepth( RimWellPath* parentWellPath,
|
||||||
double parentWellMD )
|
double parentWellMD )
|
||||||
{
|
{
|
||||||
RimProject* project = RimProject::current();
|
RimProject* project = RimProject::current();
|
||||||
RimWellPathCollection* wellPathColl = RimTools::wellPathCollection();
|
RimWellPathCollection* wellPathColl = RimTools::wellPathCollection();
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "cafCmdFeature.h"
|
#include "cafCmdFeature.h"
|
||||||
|
|
||||||
|
class RimModeledWellPath;
|
||||||
class RimWellPath;
|
class RimWellPath;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
@ -34,6 +35,6 @@ public:
|
|||||||
void onActionTriggered( bool isChecked ) override;
|
void onActionTriggered( bool isChecked ) override;
|
||||||
void setupActionLook( QAction* actionToSetup ) override;
|
void setupActionLook( QAction* actionToSetup ) override;
|
||||||
|
|
||||||
static RimWellPath* createLateralAtMeasuredDepth( RimWellPath* parentWellPath, double parentWellMD );
|
static RimModeledWellPath* createLateralAtMeasuredDepth( RimWellPath* parentWellPath, double parentWellMD );
|
||||||
static QString updateNameOfParentAndFindNameOfSideStep( RimWellPath* parentWellPath );
|
static QString updateNameOfParentAndFindNameOfSideStep( RimWellPath* parentWellPath );
|
||||||
};
|
};
|
||||||
|
@ -31,14 +31,15 @@
|
|||||||
#include "RimWellPath.h"
|
#include "RimWellPath.h"
|
||||||
#include "RimWellPathAttribute.h"
|
#include "RimWellPathAttribute.h"
|
||||||
#include "RimWellPathAttributeCollection.h"
|
#include "RimWellPathAttributeCollection.h"
|
||||||
|
#include "RimWellPathGeometryDef.h"
|
||||||
#include "RimWellPathValve.h"
|
#include "RimWellPathValve.h"
|
||||||
|
|
||||||
#include "RiuMainWindow.h"
|
#include "RiuMainWindow.h"
|
||||||
|
|
||||||
|
#include "RivExtrudedCurveIntersectionPartMgr.h"
|
||||||
#include "RivObjectSourceInfo.h"
|
#include "RivObjectSourceInfo.h"
|
||||||
#include "RivWellPathSourceInfo.h"
|
#include "RivWellPathSourceInfo.h"
|
||||||
|
|
||||||
#include "RivExtrudedCurveIntersectionPartMgr.h"
|
|
||||||
#include "cafDisplayCoordTransform.h"
|
#include "cafDisplayCoordTransform.h"
|
||||||
#include "cafSelectionManager.h"
|
#include "cafSelectionManager.h"
|
||||||
#include "cvfPart.h"
|
#include "cvfPart.h"
|
||||||
@ -179,6 +180,10 @@ bool RicWellPathPickEventHandler::handle3dPickEvent( const Ric3dPickEvent& event
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( auto geoDef = dynamic_cast<RimWellPathGeometryDef*>( sourceInfo->object() ) )
|
||||||
|
{
|
||||||
|
RiuMainWindow::instance()->selectAsCurrentItem( geoDef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dynamic_cast<const RivWellPathSourceInfo*>( firstPickedPart->sourceInfo() ) )
|
if ( dynamic_cast<const RivWellPathSourceInfo*>( firstPickedPart->sourceInfo() ) )
|
||||||
|
@ -59,6 +59,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RivWellDiskPartMgr.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RivElementVectorResultPartMgr.h
|
${CMAKE_CURRENT_LIST_DIR}/RivElementVectorResultPartMgr.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivPolylinePartMgr.h
|
${CMAKE_CURRENT_LIST_DIR}/RivPolylinePartMgr.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.h
|
${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivDrawableSpheres.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set (SOURCE_GROUP_SOURCE_FILES
|
set (SOURCE_GROUP_SOURCE_FILES
|
||||||
@ -116,6 +117,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RivWellDiskPartMgr.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RivElementVectorResultPartMgr.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivElementVectorResultPartMgr.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivPolylinePartMgr.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivPolylinePartMgr.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RivDrawableSpheres.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND CODE_HEADER_FILES
|
list(APPEND CODE_HEADER_FILES
|
||||||
|
84
ApplicationLibCode/ModelVisualization/RivDrawableSpheres.cpp
Normal file
84
ApplicationLibCode/ModelVisualization/RivDrawableSpheres.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 - 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 "RivDrawableSpheres.h"
|
||||||
|
|
||||||
|
#include "cvfRay.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RivDrawableSpheres::RivDrawableSpheres()
|
||||||
|
: cvf::DrawableVectors()
|
||||||
|
, m_radius( 1.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RivDrawableSpheres::RivDrawableSpheres( cvf::String vectorMatrixUniformName, cvf::String colorUniformName )
|
||||||
|
: cvf::DrawableVectors( vectorMatrixUniformName, colorUniformName )
|
||||||
|
, m_radius( 1.0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
/// Estimate the intersection of a sphere by the sphere inscribed in a bounding box
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RivDrawableSpheres::rayIntersectCreateDetail( const cvf::Ray& ray,
|
||||||
|
cvf::Vec3d* intersectionPoint,
|
||||||
|
cvf::ref<cvf::HitDetail>* hitDetail ) const
|
||||||
|
{
|
||||||
|
if ( m_centerCoordArray.isNull() ) return false;
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < m_centerCoordArray->size(); i++ )
|
||||||
|
{
|
||||||
|
cvf::BoundingBox bb;
|
||||||
|
|
||||||
|
cvf::Vec3f center = m_centerCoordArray->get( i );
|
||||||
|
cvf::Vec3f corner1 = cvf::Vec3f( center.x() + m_radius, center.y() + m_radius, center.z() + m_radius );
|
||||||
|
cvf::Vec3f corner2 = cvf::Vec3f( center.x() - m_radius, center.y() - m_radius, center.z() - m_radius );
|
||||||
|
|
||||||
|
bb.add( corner1 );
|
||||||
|
bb.add( corner2 );
|
||||||
|
|
||||||
|
if ( ray.boxIntersect( bb, intersectionPoint ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivDrawableSpheres::setRadius( float radius )
|
||||||
|
{
|
||||||
|
m_radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RivDrawableSpheres::setCenterCoords( cvf::Vec3fArray* vertexArray )
|
||||||
|
{
|
||||||
|
m_centerCoordArray = vertexArray;
|
||||||
|
}
|
39
ApplicationLibCode/ModelVisualization/RivDrawableSpheres.h
Normal file
39
ApplicationLibCode/ModelVisualization/RivDrawableSpheres.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 - 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 "cvfDrawableVectors.h"
|
||||||
|
|
||||||
|
class RivDrawableSpheres : public cvf::DrawableVectors
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RivDrawableSpheres();
|
||||||
|
RivDrawableSpheres( cvf::String vectorMatrixUniformName, cvf::String colorUniformName );
|
||||||
|
|
||||||
|
bool rayIntersectCreateDetail( const cvf::Ray& ray,
|
||||||
|
cvf::Vec3d* intersectionPoint,
|
||||||
|
cvf::ref<cvf::HitDetail>* hitDetail ) const override;
|
||||||
|
|
||||||
|
void setRadius( float radius );
|
||||||
|
void setCenterCoords( cvf::Vec3fArray* vertexArray );
|
||||||
|
|
||||||
|
private:
|
||||||
|
cvf::ref<cvf::Vec3fArray> m_centerCoordArray; // Coordinates for sphere center
|
||||||
|
float m_radius; // Sphere radius
|
||||||
|
};
|
@ -53,6 +53,7 @@
|
|||||||
#include "RimWellPathValve.h"
|
#include "RimWellPathValve.h"
|
||||||
|
|
||||||
#include "Riv3dWellLogPlanePartMgr.h"
|
#include "Riv3dWellLogPlanePartMgr.h"
|
||||||
|
#include "RivDrawableSpheres.h"
|
||||||
#include "RivFishbonesSubsPartMgr.h"
|
#include "RivFishbonesSubsPartMgr.h"
|
||||||
#include "RivObjectSourceInfo.h"
|
#include "RivObjectSourceInfo.h"
|
||||||
#include "RivPartPriority.h"
|
#include "RivPartPriority.h"
|
||||||
@ -789,14 +790,14 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
|
|||||||
colors->add( sphereColor );
|
colors->add( sphereColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
cvf::ref<cvf::DrawableVectors> vectorDrawable;
|
cvf::ref<RivDrawableSpheres> vectorDrawable;
|
||||||
if ( RiaGuiApplication::instance()->useShaders() )
|
if ( RiaGuiApplication::instance()->useShaders() )
|
||||||
{
|
{
|
||||||
vectorDrawable = new cvf::DrawableVectors( "u_transformationMatrix", "u_color" );
|
vectorDrawable = new RivDrawableSpheres( "u_transformationMatrix", "u_color" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vectorDrawable = new cvf::DrawableVectors();
|
vectorDrawable = new RivDrawableSpheres();
|
||||||
}
|
}
|
||||||
|
|
||||||
vectorDrawable->setVectors( vertices.p(), vecRes.p() );
|
vectorDrawable->setVectors( vertices.p(), vecRes.p() );
|
||||||
@ -814,12 +815,20 @@ void RivWellPathPartMgr::buildWellPathParts( const caf::DisplayCoordTransform* d
|
|||||||
cvf::GeometryUtils::createSphere( cellRadius, 15, 15, &builder );
|
cvf::GeometryUtils::createSphere( cellRadius, 15, 15, &builder );
|
||||||
vectorDrawable->setGlyph( builder.trianglesUShort().p(), builder.vertices().p() );
|
vectorDrawable->setGlyph( builder.trianglesUShort().p(), builder.vertices().p() );
|
||||||
|
|
||||||
|
{
|
||||||
|
vectorDrawable->setRadius( cellRadius );
|
||||||
|
vectorDrawable->setCenterCoords( vertices.p() );
|
||||||
|
}
|
||||||
|
|
||||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||||
part->setName( "RivWellPathPartMgr_WellTargetSpheres" );
|
part->setName( "RivWellPathPartMgr_WellTargetSpheres" );
|
||||||
part->setDrawable( vectorDrawable.p() );
|
part->setDrawable( vectorDrawable.p() );
|
||||||
|
|
||||||
part->setEffect( new cvf::Effect() );
|
part->setEffect( new cvf::Effect() );
|
||||||
|
|
||||||
|
auto sourceInfo = new RivObjectSourceInfo( geoDef );
|
||||||
|
part->setSourceInfo( sourceInfo );
|
||||||
|
|
||||||
m_spherePart = part;
|
m_spherePart = part;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,6 +372,9 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
|||||||
{
|
{
|
||||||
menuBuilder << "RicNewEditableWellPathFeature";
|
menuBuilder << "RicNewEditableWellPathFeature";
|
||||||
menuBuilder << "RicNewWellPathLateralFeature";
|
menuBuilder << "RicNewWellPathLateralFeature";
|
||||||
|
menuBuilder << "RicLinkWellPathFeature";
|
||||||
|
|
||||||
|
menuBuilder.addSeparator();
|
||||||
menuBuilder << "RicNewWellPathIntersectionFeature";
|
menuBuilder << "RicNewWellPathIntersectionFeature";
|
||||||
|
|
||||||
appendCreateCompletions( menuBuilder );
|
appendCreateCompletions( menuBuilder );
|
||||||
@ -399,12 +402,18 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
|||||||
menuBuilder.subMenuEnd();
|
menuBuilder.subMenuEnd();
|
||||||
menuBuilder.addSeparator();
|
menuBuilder.addSeparator();
|
||||||
|
|
||||||
|
menuBuilder << "RicDeleteWellPathFeature";
|
||||||
|
|
||||||
menuBuilder.addSeparator();
|
menuBuilder.addSeparator();
|
||||||
|
|
||||||
if ( dynamic_cast<RimModeledWellPath*>( firstUiItem ) )
|
if ( auto modeledWellPath = dynamic_cast<RimModeledWellPath*>( firstUiItem ) )
|
||||||
{
|
{
|
||||||
menuBuilder << "RicShowWellPlanFeature";
|
menuBuilder << "RicShowWellPlanFeature";
|
||||||
menuBuilder << "RicCreateMultipleWellPathLaterals";
|
|
||||||
|
if ( modeledWellPath->isTopLevelWellPath() )
|
||||||
|
{
|
||||||
|
menuBuilder << "RicCreateMultipleWellPathLaterals";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( dynamic_cast<RimWellPathCompletions*>( firstUiItem ) )
|
else if ( dynamic_cast<RimWellPathCompletions*>( firstUiItem ) )
|
||||||
@ -1068,6 +1077,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
|
|||||||
menuBuilder << "RicCutReferencesToClipboardFeature";
|
menuBuilder << "RicCutReferencesToClipboardFeature";
|
||||||
|
|
||||||
menuBuilder << "Separator";
|
menuBuilder << "Separator";
|
||||||
|
|
||||||
|
menuBuilder << "RicDeleteWellPathFeature";
|
||||||
|
menuBuilder << "RicLinkWellPathFeature";
|
||||||
|
|
||||||
if ( dynamic_cast<RimSummaryCase*>( firstUiItem ) || dynamic_cast<RimSummaryCaseCollection*>( firstUiItem ) )
|
if ( dynamic_cast<RimSummaryCase*>( firstUiItem ) || dynamic_cast<RimSummaryCaseCollection*>( firstUiItem ) )
|
||||||
{
|
{
|
||||||
menuBuilder << "RicCreatePlotFromSelectionFeature";
|
menuBuilder << "RicCreatePlotFromSelectionFeature";
|
||||||
|
@ -60,12 +60,6 @@ RimMultipleLocations::RimMultipleLocations()
|
|||||||
CAF_PDM_InitFieldNoDefault( &m_rangeSpacing, "Spacing", "Spacing", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_rangeSpacing, "Spacing", "Spacing", "", "", "" );
|
||||||
m_rangeSpacing.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
m_rangeSpacing.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault( &m_minimumMD, "MinimumMD", "Minimum MD", "", "", "" );
|
|
||||||
m_minimumMD.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault( &m_maximumMD, "MaximumMD", "Maximum MD", "", "", "" );
|
|
||||||
m_maximumMD.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
|
||||||
|
|
||||||
CAF_PDM_InitField( &m_rangeCount, "RangeValveCount", 10, "Number of Items", "", "", "" );
|
CAF_PDM_InitField( &m_rangeCount, "RangeValveCount", 10, "Number of Items", "", "", "" );
|
||||||
|
|
||||||
CAF_PDM_InitFieldNoDefault( &m_locations, "Locations", "Measured Depths", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_locations, "Locations", "Measured Depths", "", "", "" );
|
||||||
@ -77,9 +71,6 @@ RimMultipleLocations::RimMultipleLocations()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RimMultipleLocations::setRange( double minimumMD, double maximumMD )
|
void RimMultipleLocations::setRange( double minimumMD, double maximumMD )
|
||||||
{
|
{
|
||||||
m_minimumMD = minimumMD;
|
|
||||||
m_maximumMD = maximumMD;
|
|
||||||
|
|
||||||
m_rangeStart = minimumMD;
|
m_rangeStart = minimumMD;
|
||||||
m_rangeEnd = maximumMD;
|
m_rangeEnd = maximumMD;
|
||||||
}
|
}
|
||||||
@ -91,8 +82,6 @@ void RimMultipleLocations::updateRangesAndLocations()
|
|||||||
{
|
{
|
||||||
double existingRangeStart = m_rangeStart();
|
double existingRangeStart = m_rangeStart();
|
||||||
double existingRangeEnd = m_rangeEnd();
|
double existingRangeEnd = m_rangeEnd();
|
||||||
m_rangeStart = std::clamp( m_rangeStart(), minimumMD(), maximumMD() );
|
|
||||||
m_rangeEnd = std::clamp( m_rangeEnd(), minimumMD(), maximumMD() );
|
|
||||||
if ( existingRangeStart != m_rangeStart() || existingRangeEnd != m_rangeEnd() )
|
if ( existingRangeStart != m_rangeStart() || existingRangeEnd != m_rangeEnd() )
|
||||||
{
|
{
|
||||||
computeRangesAndLocations();
|
computeRangesAndLocations();
|
||||||
@ -295,8 +284,6 @@ void RimMultipleLocations::fieldChangedByUi( const caf::PdmFieldHandle* changedF
|
|||||||
changedField == &m_rangeSpacing )
|
changedField == &m_rangeSpacing )
|
||||||
{
|
{
|
||||||
recomputeLocations = true;
|
recomputeLocations = true;
|
||||||
m_rangeStart = std::clamp( m_rangeStart(), minimumMD(), maximumMD() );
|
|
||||||
m_rangeEnd = std::clamp( m_rangeEnd(), minimumMD(), maximumMD() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( changedField == &m_rangeSpacing )
|
if ( changedField == &m_rangeSpacing )
|
||||||
@ -337,22 +324,6 @@ double RimMultipleLocations::minimumSpacingMeters() const
|
|||||||
return 10.0;
|
return 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
double RimMultipleLocations::minimumMD() const
|
|
||||||
{
|
|
||||||
return m_rangeStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
double RimMultipleLocations::maximumMD() const
|
|
||||||
{
|
|
||||||
return m_rangeEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -64,8 +64,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
int rangeCountFromSpacing() const;
|
int rangeCountFromSpacing() const;
|
||||||
double minimumSpacingMeters() const;
|
double minimumSpacingMeters() const;
|
||||||
double minimumMD() const;
|
|
||||||
double maximumMD() const;
|
|
||||||
static std::vector<double> locationsFromStartSpacingAndCount( double start, double spacing, size_t count );
|
static std::vector<double> locationsFromStartSpacingAndCount( double start, double spacing, size_t count );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -75,8 +73,5 @@ private:
|
|||||||
caf::PdmField<double> m_rangeSpacing;
|
caf::PdmField<double> m_rangeSpacing;
|
||||||
caf::PdmField<int> m_rangeCount;
|
caf::PdmField<int> m_rangeCount;
|
||||||
|
|
||||||
caf::PdmField<double> m_minimumMD;
|
|
||||||
caf::PdmField<double> m_maximumMD;
|
|
||||||
|
|
||||||
caf::PdmField<std::vector<double>> m_locations; // Given in measured depth
|
caf::PdmField<std::vector<double>> m_locations; // Given in measured depth
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "RimWellPathTarget.h"
|
#include "RimWellPathTarget.h"
|
||||||
#include "RimWellPathTieIn.h"
|
#include "RimWellPathTieIn.h"
|
||||||
|
|
||||||
|
#include "RigWellPathGeometryTools.h"
|
||||||
#include "cafPdmFieldScriptingCapability.h"
|
#include "cafPdmFieldScriptingCapability.h"
|
||||||
#include "cafPdmUiDoubleValueEditor.h"
|
#include "cafPdmUiDoubleValueEditor.h"
|
||||||
#include "cafPdmUiTreeOrdering.h"
|
#include "cafPdmUiTreeOrdering.h"
|
||||||
@ -87,7 +88,7 @@ void RimModeledWellPath::createWellPathGeometry()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RimModeledWellPath::updateWellPathVisualization()
|
void RimModeledWellPath::updateWellPathVisualization()
|
||||||
{
|
{
|
||||||
this->setWellPathGeometry( m_geometryDefinition->createWellPathGeometry().p() );
|
createWellPathGeometry();
|
||||||
|
|
||||||
std::vector<RimPlotCurve*> refferingCurves;
|
std::vector<RimPlotCurve*> refferingCurves;
|
||||||
this->objectsWithReferringPtrFieldsOfType( refferingCurves );
|
this->objectsWithReferringPtrFieldsOfType( refferingCurves );
|
||||||
@ -288,7 +289,10 @@ void RimModeledWellPath::updateTieInLocationFromParentWell()
|
|||||||
cvf::Vec3d relativePointXYZ = lastPointXYZ - referencePointXYZ;
|
cvf::Vec3d relativePointXYZ = lastPointXYZ - referencePointXYZ;
|
||||||
|
|
||||||
auto firstTarget = targets.front();
|
auto firstTarget = targets.front();
|
||||||
firstTarget->setPointXYZ( relativePointXYZ );
|
const auto [azimuth, inclination] =
|
||||||
|
RigWellPathGeometryTools::calculateAzimuthAndInclinationAtMd( tieIn->tieInMeasuredDepth(),
|
||||||
|
parentWellPath->wellPathGeometry() );
|
||||||
|
firstTarget->setAsPointXYZAndTangentTarget( relativePointXYZ, azimuth, inclination );
|
||||||
|
|
||||||
updateGeometry( true );
|
updateGeometry( true );
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,6 @@ RimWellPath::RimWellPath()
|
|||||||
CAF_PDM_InitFieldNoDefault( &m_wellPathTieIn, "WellPathTieIn", "well Path Tie-In", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_wellPathTieIn, "WellPathTieIn", "well Path Tie-In", "", "", "" );
|
||||||
m_wellPathTieIn = new RimWellPathTieIn;
|
m_wellPathTieIn = new RimWellPathTieIn;
|
||||||
m_wellPathTieIn->connectWellPaths( nullptr, this, 0.0 );
|
m_wellPathTieIn->connectWellPaths( nullptr, this, 0.0 );
|
||||||
|
|
||||||
this->setDeletable( true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -1170,6 +1168,31 @@ std::vector<RimWellPath*> RimWellPath::allWellPathLaterals() const
|
|||||||
return laterals;
|
return laterals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<RimWellPath*> RimWellPath::wellPathLaterals() const
|
||||||
|
{
|
||||||
|
std::vector<RimWellPath*> laterals;
|
||||||
|
|
||||||
|
std::vector<caf::PdmObjectHandle*> referringObjects;
|
||||||
|
this->objectsWithReferringPtrFields( referringObjects );
|
||||||
|
for ( auto obj : referringObjects )
|
||||||
|
{
|
||||||
|
if ( auto tieIn = dynamic_cast<RimWellPathTieIn*>( obj ) )
|
||||||
|
{
|
||||||
|
auto tieInWellPath = tieIn->childWell();
|
||||||
|
if ( tieInWellPath == this ) continue;
|
||||||
|
if ( tieInWellPath )
|
||||||
|
{
|
||||||
|
laterals.push_back( tieInWellPath );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return laterals;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -163,6 +163,7 @@ public:
|
|||||||
RimWellPath* topLevelWellPath();
|
RimWellPath* topLevelWellPath();
|
||||||
const RimWellPath* topLevelWellPath() const;
|
const RimWellPath* topLevelWellPath() const;
|
||||||
std::vector<RimWellPath*> allWellPathLaterals() const;
|
std::vector<RimWellPath*> allWellPathLaterals() const;
|
||||||
|
std::vector<RimWellPath*> wellPathLaterals() const;
|
||||||
|
|
||||||
RimWellPathTieIn* wellPathTieIn() const;
|
RimWellPathTieIn* wellPathTieIn() const;
|
||||||
void connectWellPaths( RimWellPath* childWell, double tieInMeasuredDepth );
|
void connectWellPaths( RimWellPath* childWell, double tieInMeasuredDepth );
|
||||||
|
@ -583,6 +583,15 @@ void RimWellPathCollection::deleteAllWellPaths()
|
|||||||
updateAllRequiredEditors();
|
updateAllRequiredEditors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimWellPathCollection::deleteWell( RimWellPath* wellPath )
|
||||||
|
{
|
||||||
|
m_wellPaths.removeChildObject( wellPath );
|
||||||
|
delete wellPath;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -98,6 +98,7 @@ public:
|
|||||||
void removeWellPath( gsl::not_null<RimWellPath*> wellPath );
|
void removeWellPath( gsl::not_null<RimWellPath*> wellPath );
|
||||||
|
|
||||||
void deleteAllWellPaths();
|
void deleteAllWellPaths();
|
||||||
|
void deleteWell( RimWellPath* wellPath );
|
||||||
|
|
||||||
void groupWellPaths( const std::vector<RimWellPath*>& wellPaths );
|
void groupWellPaths( const std::vector<RimWellPath*>& wellPaths );
|
||||||
void rebuildWellPathNodes();
|
void rebuildWellPathNodes();
|
||||||
|
@ -105,7 +105,7 @@ RimWellPathGeometryDef::RimWellPathGeometryDef()
|
|||||||
CAF_PDM_InitScriptableField( &m_linkReferencePointUpdates,
|
CAF_PDM_InitScriptableField( &m_linkReferencePointUpdates,
|
||||||
"LinkReferencePointUpdates",
|
"LinkReferencePointUpdates",
|
||||||
false,
|
false,
|
||||||
"Link Reference Point Updates",
|
"Link Reference Point",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"" );
|
"" );
|
||||||
@ -121,7 +121,7 @@ RimWellPathGeometryDef::RimWellPathGeometryDef()
|
|||||||
CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" );
|
CAF_PDM_InitField( &m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", "" );
|
||||||
caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled );
|
caf::PdmUiPushButtonEditor::configureEditorForField( &m_pickPointsEnabled );
|
||||||
|
|
||||||
CAF_PDM_InitScriptableField( &m_showSpheres, "ShowSpheres", false, "Spheres", "", "", "" );
|
CAF_PDM_InitScriptableField( &m_showSpheres, "ShowSpheres", true, "Spheres", "", "", "" );
|
||||||
CAF_PDM_InitField( &m_sphereColor, "SphereColor", cvf::Color3f( cvf::Color3f::CEETRON ), "Sphere Color", "", "", "" );
|
CAF_PDM_InitField( &m_sphereColor, "SphereColor", cvf::Color3f( cvf::Color3f::CEETRON ), "Sphere Color", "", "", "" );
|
||||||
CAF_PDM_InitField( &m_sphereRadiusFactor, "SphereRadiusFactor", 0.15, "Sphere Radius Factor", "", "", "" );
|
CAF_PDM_InitField( &m_sphereRadiusFactor, "SphereRadiusFactor", 0.15, "Sphere Radius Factor", "", "", "" );
|
||||||
}
|
}
|
||||||
@ -289,7 +289,17 @@ cvf::ref<RigWellPath> RimWellPathGeometryDef::createWellPathGeometry()
|
|||||||
RiaPolyArcLineSampler arcLineSampler( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() );
|
RiaPolyArcLineSampler arcLineSampler( wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints() );
|
||||||
auto [sampledWellPathPoints, sampledMeasuredDepths] = arcLineSampler.sampledPointsAndMDs( 30, false );
|
auto [sampledWellPathPoints, sampledMeasuredDepths] = arcLineSampler.sampledPointsAndMDs( 30, false );
|
||||||
wellPathPoints.insert( wellPathPoints.end(), sampledWellPathPoints.begin(), sampledWellPathPoints.end() );
|
wellPathPoints.insert( wellPathPoints.end(), sampledWellPathPoints.begin(), sampledWellPathPoints.end() );
|
||||||
double startMD = measuredDepths.empty() ? 0.0 : measuredDepths.back();
|
|
||||||
|
double startMD = 0.0;
|
||||||
|
if ( !measuredDepths.empty() )
|
||||||
|
{
|
||||||
|
startMD = measuredDepths.back();
|
||||||
|
}
|
||||||
|
else if ( !m_useAutoGeneratedTargetAtSeaLevel )
|
||||||
|
{
|
||||||
|
startMD = m_mdAtFirstTarget;
|
||||||
|
}
|
||||||
|
|
||||||
for ( auto md : sampledMeasuredDepths )
|
for ( auto md : sampledMeasuredDepths )
|
||||||
{
|
{
|
||||||
measuredDepths.push_back( md + startMD );
|
measuredDepths.push_back( md + startMD );
|
||||||
@ -523,6 +533,23 @@ void RimWellPathGeometryDef::fieldChangedByUi( const caf::PdmFieldHandle* change
|
|||||||
RimWellPathGeometryDefTools::updateLinkedGeometryDefinitions( linkedDefs, delta );
|
RimWellPathGeometryDefTools::updateLinkedGeometryDefinitions( linkedDefs, delta );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( changedField == &m_useAutoGeneratedTargetAtSeaLevel && !m_useAutoGeneratedTargetAtSeaLevel )
|
||||||
|
{
|
||||||
|
auto firstTarget = firstActiveTarget();
|
||||||
|
if ( firstTarget != nullptr )
|
||||||
|
{
|
||||||
|
auto firstLocationXYZ = firstTarget->targetPointXYZ() + anchorPointXyz();
|
||||||
|
|
||||||
|
// Temporarily enable target at sea level to be able to create a complete geometry to find MD of first
|
||||||
|
// target of the complete geometry
|
||||||
|
m_useAutoGeneratedTargetAtSeaLevel = true;
|
||||||
|
auto wellPathGeo = createWellPathGeometry();
|
||||||
|
m_useAutoGeneratedTargetAtSeaLevel = false;
|
||||||
|
|
||||||
|
double mdAtFirstTarget = wellPathGeo->closestMeasuredDepth( firstLocationXYZ );
|
||||||
|
m_mdAtFirstTarget = mdAtFirstTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
changed.send( false );
|
changed.send( false );
|
||||||
}
|
}
|
||||||
@ -759,6 +786,14 @@ void RimWellPathGeometryDef::defineObjectEditorAttribute( QString uiConfigName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
caf::PdmFieldHandle* RimWellPathGeometryDef::objectToggleField()
|
||||||
|
{
|
||||||
|
return &m_showSpheres;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -102,6 +102,7 @@ protected:
|
|||||||
caf::PdmUiEditorAttribute* attribute ) override;
|
caf::PdmUiEditorAttribute* attribute ) override;
|
||||||
|
|
||||||
void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
void defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||||
|
caf::PdmFieldHandle* objectToggleField() override;
|
||||||
|
|
||||||
void onTargetMoved( const caf::SignalEmitter* emitter, bool fullUpdate );
|
void onTargetMoved( const caf::SignalEmitter* emitter, bool fullUpdate );
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ void caf::AppEnum<RimWellPathTarget::TargetTypeEnum>::setUp()
|
|||||||
{
|
{
|
||||||
addItem( RimWellPathTarget::TargetTypeEnum::POINT_AND_TANGENT, "POINT_AND_TANGENT", "Point and Tangent" );
|
addItem( RimWellPathTarget::TargetTypeEnum::POINT_AND_TANGENT, "POINT_AND_TANGENT", "Point and Tangent" );
|
||||||
addItem( RimWellPathTarget::TargetTypeEnum::POINT, "POINT", "Point" );
|
addItem( RimWellPathTarget::TargetTypeEnum::POINT, "POINT", "Point" );
|
||||||
setDefault( RimWellPathTarget::TargetTypeEnum::POINT_AND_TANGENT );
|
setDefault( RimWellPathTarget::TargetTypeEnum::POINT );
|
||||||
}
|
}
|
||||||
} // namespace caf
|
} // namespace caf
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -51,7 +51,7 @@ void caf::AppEnum<RimWellPathTarget::TargetTypeEnum>::setUp()
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RimWellPathTarget::RimWellPathTarget()
|
RimWellPathTarget::RimWellPathTarget()
|
||||||
: moved( this )
|
: moved( this )
|
||||||
, m_targetType( TargetTypeEnum::POINT_AND_TANGENT )
|
, m_targetType( TargetTypeEnum::POINT )
|
||||||
, m_targetPointXYD( cvf::Vec3d::ZERO )
|
, m_targetPointXYD( cvf::Vec3d::ZERO )
|
||||||
, m_azimuth( 0.0 )
|
, m_azimuth( 0.0 )
|
||||||
, m_inclination( 0.0 )
|
, m_inclination( 0.0 )
|
||||||
@ -69,10 +69,13 @@ RimWellPathTarget::RimWellPathTarget()
|
|||||||
m_isLocked.uiCapability()->setUiHidden( true );
|
m_isLocked.uiCapability()->setUiHidden( true );
|
||||||
|
|
||||||
CAF_PDM_InitScriptableFieldNoDefault( &m_targetPointXYD, "TargetPoint", "Relative Coord", "", "", "" );
|
CAF_PDM_InitScriptableFieldNoDefault( &m_targetPointXYD, "TargetPoint", "Relative Coord", "", "", "" );
|
||||||
CAF_PDM_InitScriptableFieldNoDefault( &m_targetPointForDisplay, "TargetPointForDisplay", "UTM Coord", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_targetPointForDisplay, "TargetPointForDisplay", "UTM Coord", "", "", "" );
|
||||||
m_targetPointForDisplay.registerGetMethod( this, &RimWellPathTarget::targetPointForDisplayXYD );
|
m_targetPointForDisplay.registerGetMethod( this, &RimWellPathTarget::targetPointForDisplayXYD );
|
||||||
m_targetPointForDisplay.registerSetMethod( this, &RimWellPathTarget::setTargetPointFromDisplayCoord );
|
m_targetPointForDisplay.registerSetMethod( this, &RimWellPathTarget::setTargetPointFromDisplayCoord );
|
||||||
|
|
||||||
|
CAF_PDM_InitScriptableFieldNoDefault( &m_targetMeasuredDepth, "TargetMeasuredDepth", "MD", "", "", "" );
|
||||||
|
m_targetMeasuredDepth.registerGetMethod( this, &RimWellPathTarget::measuredDepth );
|
||||||
|
|
||||||
CAF_PDM_InitScriptableField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" );
|
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_InitScriptableField( &m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", "" );
|
||||||
|
|
||||||
@ -224,10 +227,8 @@ double RimWellPathTarget::azimuth() const
|
|||||||
{
|
{
|
||||||
return cvf::Math::toRadians( m_azimuth );
|
return cvf::Math::toRadians( m_azimuth );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return std::numeric_limits<double>::infinity();
|
||||||
return std::numeric_limits<double>::infinity();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -239,10 +240,8 @@ double RimWellPathTarget::inclination() const
|
|||||||
{
|
{
|
||||||
return cvf::Math::toRadians( m_inclination );
|
return cvf::Math::toRadians( m_inclination );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return std::numeric_limits<double>::infinity();
|
||||||
return std::numeric_limits<double>::infinity();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -441,6 +440,28 @@ void RimWellPathTarget::setTargetPointFromDisplayCoord( const cvf::Vec3d& coordI
|
|||||||
m_targetPointXYD = newCoordInXYD;
|
m_targetPointXYD = newCoordInXYD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RimWellPathTarget::measuredDepth() const
|
||||||
|
{
|
||||||
|
RimWellPath* wellPath = nullptr;
|
||||||
|
this->firstAncestorOfType( wellPath );
|
||||||
|
|
||||||
|
auto geoDef = geometryDefinition();
|
||||||
|
|
||||||
|
if ( geoDef && wellPath && wellPath->wellPathGeometry() )
|
||||||
|
{
|
||||||
|
auto offsetXYZ = geoDef->anchorPointXyz();
|
||||||
|
auto coordXYZ = targetPointXYZ() + offsetXYZ;
|
||||||
|
|
||||||
|
auto wellPathGeo = wellPath->wellPathGeometry();
|
||||||
|
return wellPathGeo->closestMeasuredDepth( coordXYZ );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -85,6 +85,7 @@ private:
|
|||||||
|
|
||||||
cvf::Vec3d targetPointForDisplayXYD() const;
|
cvf::Vec3d targetPointForDisplayXYD() const;
|
||||||
void setTargetPointFromDisplayCoord( const cvf::Vec3d& coordInXYZ );
|
void setTargetPointFromDisplayCoord( const cvf::Vec3d& coordInXYZ );
|
||||||
|
double measuredDepth() const;
|
||||||
|
|
||||||
RimWellPathGeometryDef* geometryDefinition() const;
|
RimWellPathGeometryDef* geometryDefinition() const;
|
||||||
|
|
||||||
@ -96,9 +97,11 @@ private:
|
|||||||
caf::PdmField<caf::AppEnum<TargetTypeEnum>> m_targetType;
|
caf::PdmField<caf::AppEnum<TargetTypeEnum>> m_targetType;
|
||||||
caf::PdmField<cvf::Vec3d> m_targetPointXYD;
|
caf::PdmField<cvf::Vec3d> m_targetPointXYD;
|
||||||
caf::PdmProxyValueField<cvf::Vec3d> m_targetPointForDisplay;
|
caf::PdmProxyValueField<cvf::Vec3d> m_targetPointForDisplay;
|
||||||
caf::PdmField<double> m_azimuth;
|
caf::PdmProxyValueField<double> m_targetMeasuredDepth;
|
||||||
caf::PdmField<double> m_inclination;
|
|
||||||
caf::PdmField<double> m_dogleg1;
|
caf::PdmField<double> m_azimuth;
|
||||||
caf::PdmField<double> m_dogleg2;
|
caf::PdmField<double> m_inclination;
|
||||||
caf::PdmField<bool> m_hasTangentConstraintUiField;
|
caf::PdmField<double> m_dogleg1;
|
||||||
|
caf::PdmField<double> m_dogleg2;
|
||||||
|
caf::PdmField<bool> m_hasTangentConstraintUiField;
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
|
|
||||||
#include "RiuMainWindow.h"
|
#include "RiuMainWindow.h"
|
||||||
|
|
||||||
#include "cafPdmUiDoubleValueEditor.h"
|
#include "RigWellPathGeometryTools.h"
|
||||||
|
#include "cafPdmUiDoubleSliderEditor.h"
|
||||||
|
|
||||||
CAF_PDM_SOURCE_INIT( RimWellPathTieIn, "RimWellPathTieIn" );
|
CAF_PDM_SOURCE_INIT( RimWellPathTieIn, "RimWellPathTieIn" );
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ RimWellPathTieIn::RimWellPathTieIn()
|
|||||||
CAF_PDM_InitFieldNoDefault( &m_parentWell, "ParentWellPath", "Parent Well Path", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_parentWell, "ParentWellPath", "Parent Well Path", "", "", "" );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_childWell, "ChildWellPath", "ChildWellPath", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_childWell, "ChildWellPath", "ChildWellPath", "", "", "" );
|
||||||
CAF_PDM_InitFieldNoDefault( &m_tieInMeasuredDepth, "TieInMeasuredDepth", "Tie In Measured Depth", "", "", "" );
|
CAF_PDM_InitFieldNoDefault( &m_tieInMeasuredDepth, "TieInMeasuredDepth", "Tie In Measured Depth", "", "", "" );
|
||||||
m_tieInMeasuredDepth.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
|
m_tieInMeasuredDepth.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
|
||||||
|
|
||||||
CAF_PDM_InitField( &m_addValveAtConnection, "AddValveAtConnection", false, "Add Outlet Valve for Branches", "", "", "" );
|
CAF_PDM_InitField( &m_addValveAtConnection, "AddValveAtConnection", false, "Add Outlet Valve for Branches", "", "", "" );
|
||||||
|
|
||||||
@ -227,3 +228,32 @@ QList<caf::PdmOptionItemInfo> RimWellPathTieIn::calculateValueOptions( const caf
|
|||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RimWellPathTieIn::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||||
|
QString uiConfigName,
|
||||||
|
caf::PdmUiEditorAttribute* attribute )
|
||||||
|
{
|
||||||
|
if ( field == &m_tieInMeasuredDepth )
|
||||||
|
{
|
||||||
|
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
|
||||||
|
|
||||||
|
if ( myAttr && parentWell() )
|
||||||
|
{
|
||||||
|
double minimumValue = 0.0, maximumValue = 0.0;
|
||||||
|
|
||||||
|
auto wellPathGeo = parentWell()->wellPathGeometry();
|
||||||
|
|
||||||
|
if ( wellPathGeo )
|
||||||
|
{
|
||||||
|
minimumValue = wellPathGeo->measuredDepths().front();
|
||||||
|
maximumValue = wellPathGeo->measuredDepths().back();
|
||||||
|
|
||||||
|
myAttr->m_minimum = minimumValue;
|
||||||
|
myAttr->m_maximum = maximumValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -53,6 +53,10 @@ private:
|
|||||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||||
bool* useOptionsOnly ) override;
|
bool* useOptionsOnly ) override;
|
||||||
|
|
||||||
|
void defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||||
|
QString uiConfigName,
|
||||||
|
caf::PdmUiEditorAttribute* attribute ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
caf::PdmPtrField<RimWellPath*> m_parentWell;
|
caf::PdmPtrField<RimWellPath*> m_parentWell;
|
||||||
caf::PdmPtrField<RimWellPath*> m_childWell;
|
caf::PdmPtrField<RimWellPath*> m_childWell;
|
||||||
|
@ -14,8 +14,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RimcDataContainerDouble.h
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RimcDataContainerString.h
|
${CMAKE_CURRENT_LIST_DIR}/RimcDataContainerString.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimcDataContainerTime.h
|
${CMAKE_CURRENT_LIST_DIR}/RimcDataContainerTime.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlotCollection.h
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlotCollection.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlot.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlot.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogTrack.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogTrack.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellPathGeometryDef.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimcModeledWellPath.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set (SOURCE_GROUP_SOURCE_FILES
|
set (SOURCE_GROUP_SOURCE_FILES
|
||||||
@ -35,6 +37,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RimcDataContainerTime.cpp
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlotCollection.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlotCollection.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlot.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogPlot.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogTrack.cpp
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellLogTrack.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimcWellPathGeometryDef.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/RimcModeledWellPath.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND CODE_HEADER_FILES
|
list(APPEND CODE_HEADER_FILES
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021- 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 "RimcModeledWellPath.h"
|
||||||
|
|
||||||
|
#include "RimModeledWellPath.h"
|
||||||
|
#include "RimPerforationCollection.h"
|
||||||
|
#include "RimPerforationInterval.h"
|
||||||
|
#include "RimTools.h"
|
||||||
|
#include "RimWellPathCollection.h"
|
||||||
|
#include "RimWellPathGeometryDef.h"
|
||||||
|
#include "RimWellPathTarget.h"
|
||||||
|
|
||||||
|
#include "WellPathCommands/RicNewWellPathLateralAtDepthFeature.h"
|
||||||
|
|
||||||
|
#include "cafPdmAbstractFieldScriptingCapability.h"
|
||||||
|
#include "cafPdmFieldScriptingCapability.h"
|
||||||
|
|
||||||
|
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimModeledWellPath, RimcModeledWellPath_appendLateral, "AppendLateral" );
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimcModeledWellPath_appendLateral::RimcModeledWellPath_appendLateral( caf::PdmObjectHandle* self )
|
||||||
|
: caf::PdmObjectMethod( self )
|
||||||
|
{
|
||||||
|
CAF_PDM_InitObject( "Append Well Path Lateral", "", "", "Append Well Path Lateral" );
|
||||||
|
CAF_PDM_InitScriptableField( &m_tieInDepth, "TieInDepth", 0.0, "", "", "", "Measured Depth on the Parent Well Path" );
|
||||||
|
CAF_PDM_InitScriptableFieldNoDefault( &m_lateralName, "LateralName", "", "", "", "Lateral Name" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
caf::PdmObjectHandle* RimcModeledWellPath_appendLateral::execute()
|
||||||
|
{
|
||||||
|
auto parentWellPath = self<RimModeledWellPath>();
|
||||||
|
|
||||||
|
auto lateral = RicNewWellPathLateralAtDepthFeature::createLateralAtMeasuredDepth( parentWellPath, m_tieInDepth );
|
||||||
|
if ( !m_lateralName().isEmpty() )
|
||||||
|
{
|
||||||
|
lateral->setName( m_lateralName );
|
||||||
|
}
|
||||||
|
lateral->geometryDefinition()->enableTargetPointPicking( false );
|
||||||
|
|
||||||
|
return lateral;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimcModeledWellPath_appendLateral::resultIsPersistent() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::unique_ptr<caf::PdmObjectHandle> RimcModeledWellPath_appendLateral::defaultResult() const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<caf::PdmObjectHandle>( new RimModeledWellPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimModeledWellPath,
|
||||||
|
RimcModeledWellPath_appendPerforationInterval,
|
||||||
|
"AppendPerforationInterval" );
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimcModeledWellPath_appendPerforationInterval::RimcModeledWellPath_appendPerforationInterval( caf::PdmObjectHandle* self )
|
||||||
|
: caf::PdmObjectMethod( self )
|
||||||
|
{
|
||||||
|
CAF_PDM_InitObject( "Append Perforation Interval", "", "", "Append Perforation Interval" );
|
||||||
|
CAF_PDM_InitScriptableField( &m_startMD, "StartMd", 0.0, "", "", "", "Start Measured Depth" );
|
||||||
|
CAF_PDM_InitScriptableField( &m_endMD, "EndMd", 0.0, "", "", "", "End Measured Depth" );
|
||||||
|
CAF_PDM_InitScriptableField( &m_diameter, "Diameter", 0.0, "", "", "", "Diameter" );
|
||||||
|
CAF_PDM_InitScriptableField( &m_skinFactor, "SkinFactor", 0.0, "", "", "", "Skin Factor" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
caf::PdmObjectHandle* RimcModeledWellPath_appendPerforationInterval::execute()
|
||||||
|
{
|
||||||
|
auto wellPath = self<RimModeledWellPath>();
|
||||||
|
|
||||||
|
auto perforationInterval = new RimPerforationInterval;
|
||||||
|
perforationInterval->setStartAndEndMD( m_startMD, m_endMD );
|
||||||
|
perforationInterval->setSkinFactor( m_skinFactor );
|
||||||
|
perforationInterval->setDiameter( m_diameter );
|
||||||
|
|
||||||
|
wellPath->perforationIntervalCollection()->appendPerforation( perforationInterval );
|
||||||
|
|
||||||
|
auto* wellPathCollection = RimTools::wellPathCollection();
|
||||||
|
|
||||||
|
wellPathCollection->uiCapability()->updateConnectedEditors();
|
||||||
|
wellPathCollection->scheduleRedrawAffectedViews();
|
||||||
|
|
||||||
|
return perforationInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimcModeledWellPath_appendPerforationInterval::resultIsPersistent() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::unique_ptr<caf::PdmObjectHandle> RimcModeledWellPath_appendPerforationInterval::defaultResult() const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<caf::PdmObjectHandle>( new RimPerforationInterval );
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021- 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 "cafPdmField.h"
|
||||||
|
#include "cafPdmObjectHandle.h"
|
||||||
|
#include "cafPdmObjectMethod.h"
|
||||||
|
|
||||||
|
#include "cvfVector3.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RimcModeledWellPath_appendLateral : public caf::PdmObjectMethod
|
||||||
|
{
|
||||||
|
CAF_PDM_HEADER_INIT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RimcModeledWellPath_appendLateral( caf::PdmObjectHandle* self );
|
||||||
|
|
||||||
|
caf::PdmObjectHandle* execute() override;
|
||||||
|
bool resultIsPersistent() const override;
|
||||||
|
std::unique_ptr<PdmObjectHandle> defaultResult() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
caf::PdmField<double> m_tieInDepth;
|
||||||
|
caf::PdmField<QString> m_lateralName;
|
||||||
|
};
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RimcModeledWellPath_appendPerforationInterval : public caf::PdmObjectMethod
|
||||||
|
{
|
||||||
|
CAF_PDM_HEADER_INIT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RimcModeledWellPath_appendPerforationInterval( caf::PdmObjectHandle* self );
|
||||||
|
|
||||||
|
caf::PdmObjectHandle* execute() override;
|
||||||
|
bool resultIsPersistent() const override;
|
||||||
|
std::unique_ptr<PdmObjectHandle> defaultResult() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
caf::PdmField<double> m_startMD;
|
||||||
|
caf::PdmField<double> m_endMD;
|
||||||
|
caf::PdmField<double> m_diameter;
|
||||||
|
caf::PdmField<double> m_skinFactor;
|
||||||
|
};
|
@ -0,0 +1,85 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021- 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 "RimcWellPathGeometryDef.h"
|
||||||
|
|
||||||
|
#include "RimModeledWellPath.h"
|
||||||
|
#include "RimWellPathCollection.h"
|
||||||
|
#include "RimWellPathGeometryDef.h"
|
||||||
|
#include "RimWellPathTarget.h"
|
||||||
|
|
||||||
|
#include "cafPdmAbstractFieldScriptingCapability.h"
|
||||||
|
#include "cafPdmFieldScriptingCapability.h"
|
||||||
|
#include "cafPdmFieldScriptingCapabilityCvfVec3d.h"
|
||||||
|
|
||||||
|
CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimWellPathGeometryDef,
|
||||||
|
RimcRimWellPathGeometryDef_appendNewWellTarget,
|
||||||
|
"AppendWellTarget" );
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RimcRimWellPathGeometryDef_appendNewWellTarget::RimcRimWellPathGeometryDef_appendNewWellTarget( caf::PdmObjectHandle* self )
|
||||||
|
: caf::PdmObjectMethod( self )
|
||||||
|
{
|
||||||
|
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::PdmObjectHandle* RimcRimWellPathGeometryDef_appendNewWellTarget::execute()
|
||||||
|
{
|
||||||
|
auto geoDef = self<RimWellPathGeometryDef>();
|
||||||
|
|
||||||
|
cvf::Vec3d relativeTargetPoint = m_coordinate();
|
||||||
|
relativeTargetPoint.z() = -relativeTargetPoint.z();
|
||||||
|
if ( m_isAbsolute )
|
||||||
|
{
|
||||||
|
cvf::Vec3d referencePoint = geoDef->anchorPointXyz();
|
||||||
|
relativeTargetPoint -= referencePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto newTarget = new RimWellPathTarget;
|
||||||
|
newTarget->setAsPointTargetXYD(
|
||||||
|
cvf::Vec3d( relativeTargetPoint.x(), relativeTargetPoint.y(), -relativeTargetPoint.z() ) );
|
||||||
|
geoDef->insertTarget( nullptr, newTarget );
|
||||||
|
|
||||||
|
geoDef->updateConnectedEditors();
|
||||||
|
geoDef->updateWellPathVisualization( false );
|
||||||
|
|
||||||
|
return newTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimcRimWellPathGeometryDef_appendNewWellTarget::resultIsPersistent() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::unique_ptr<caf::PdmObjectHandle> RimcRimWellPathGeometryDef_appendNewWellTarget::defaultResult() const
|
||||||
|
{
|
||||||
|
return std::unique_ptr<caf::PdmObjectHandle>( new RimWellPathTarget );
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021- 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 "cafPdmField.h"
|
||||||
|
#include "cafPdmObjectHandle.h"
|
||||||
|
#include "cafPdmObjectMethod.h"
|
||||||
|
|
||||||
|
#include "cvfVector3.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RimcRimWellPathGeometryDef_appendNewWellTarget : public caf::PdmObjectMethod
|
||||||
|
{
|
||||||
|
CAF_PDM_HEADER_INIT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RimcRimWellPathGeometryDef_appendNewWellTarget( caf::PdmObjectHandle* self );
|
||||||
|
|
||||||
|
caf::PdmObjectHandle* execute() override;
|
||||||
|
bool resultIsPersistent() const override;
|
||||||
|
std::unique_ptr<PdmObjectHandle> defaultResult() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
caf::PdmField<cvf::Vec3d> m_coordinate;
|
||||||
|
caf::PdmField<bool> m_isAbsolute;
|
||||||
|
};
|
@ -315,41 +315,15 @@ cvf::Vec3d RigWellPath::tangentAlongWellPath( double measuredDepth ) const
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
double RigWellPath::wellPathAzimuthAngle( const cvf::Vec3d& position ) const
|
double RigWellPath::wellPathAzimuthAngle( const cvf::Vec3d& position ) const
|
||||||
{
|
{
|
||||||
size_t closestIndex = cvf::UNDEFINED_SIZE_T;
|
|
||||||
double closestDistance = cvf::UNDEFINED_DOUBLE;
|
|
||||||
|
|
||||||
for ( size_t i = 1; i < m_wellPathPoints.size(); i++ )
|
|
||||||
{
|
|
||||||
cvf::Vec3d p1 = m_wellPathPoints[i - 1];
|
|
||||||
cvf::Vec3d p2 = m_wellPathPoints[i - 0];
|
|
||||||
|
|
||||||
double candidateDistance = cvf::GeometryTools::linePointSquareDist( p1, p2, position );
|
|
||||||
if ( candidateDistance < closestDistance )
|
|
||||||
{
|
|
||||||
closestDistance = candidateDistance;
|
|
||||||
closestIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For vertical well (x-component of direction = 0) returned angle will be 90.
|
// For vertical well (x-component of direction = 0) returned angle will be 90.
|
||||||
double azimuthAngleDegrees = 90.0;
|
double azimuthAngleDegrees = 90.0;
|
||||||
|
|
||||||
if ( closestIndex != cvf::UNDEFINED_DOUBLE )
|
cvf::Vec3d p1 = cvf::Vec3d::UNDEFINED;
|
||||||
|
cvf::Vec3d p2 = cvf::Vec3d::UNDEFINED;
|
||||||
|
twoClosestPoints( position, &p1, &p2 );
|
||||||
|
|
||||||
|
if ( !p1.isUndefined() )
|
||||||
{
|
{
|
||||||
cvf::Vec3d p1;
|
|
||||||
cvf::Vec3d p2;
|
|
||||||
|
|
||||||
if ( closestIndex > 0 )
|
|
||||||
{
|
|
||||||
p1 = m_wellPathPoints[closestIndex - 1];
|
|
||||||
p2 = m_wellPathPoints[closestIndex - 0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p1 = m_wellPathPoints[closestIndex + 1];
|
|
||||||
p2 = m_wellPathPoints[closestIndex + 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
cvf::Vec3d direction = p2 - p1;
|
cvf::Vec3d direction = p2 - p1;
|
||||||
|
|
||||||
if ( fabs( direction.y() ) > 1e-5 )
|
if ( fabs( direction.y() ) > 1e-5 )
|
||||||
@ -370,34 +344,11 @@ void RigWellPath::twoClosestPoints( const cvf::Vec3d& position, cvf::Vec3d* p1,
|
|||||||
{
|
{
|
||||||
CVF_ASSERT( p1 && p2 );
|
CVF_ASSERT( p1 && p2 );
|
||||||
|
|
||||||
size_t closestIndex = cvf::UNDEFINED_SIZE_T;
|
auto closeIndices = closestIndices( position );
|
||||||
double closestDistance = cvf::UNDEFINED_DOUBLE;
|
if ( closeIndices.first != cvf::UNDEFINED_SIZE_T )
|
||||||
|
|
||||||
for ( size_t i = 1; i < m_wellPathPoints.size(); i++ )
|
|
||||||
{
|
{
|
||||||
cvf::Vec3d point1 = m_wellPathPoints[i - 1];
|
*p1 = m_wellPathPoints[closeIndices.first];
|
||||||
cvf::Vec3d point2 = m_wellPathPoints[i - 0];
|
*p2 = m_wellPathPoints[closeIndices.second];
|
||||||
|
|
||||||
double candidateDistance = cvf::GeometryTools::linePointSquareDist( point1, point2, position );
|
|
||||||
if ( candidateDistance < closestDistance )
|
|
||||||
{
|
|
||||||
closestDistance = candidateDistance;
|
|
||||||
closestIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( closestIndex != cvf::UNDEFINED_SIZE_T )
|
|
||||||
{
|
|
||||||
if ( closestIndex > 0 )
|
|
||||||
{
|
|
||||||
*p1 = m_wellPathPoints[closestIndex - 1];
|
|
||||||
*p2 = m_wellPathPoints[closestIndex - 0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*p1 = m_wellPathPoints[closestIndex + 1];
|
|
||||||
*p2 = m_wellPathPoints[closestIndex + 0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,6 +380,32 @@ double RigWellPath::identicalTubeLength( const RigWellPath& other ) const
|
|||||||
return identicalLength;
|
return identicalLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigWellPath::closestMeasuredDepth( const cvf::Vec3d& position ) const
|
||||||
|
{
|
||||||
|
auto [firstIndex, secondIndex] = closestIndices( position );
|
||||||
|
if ( firstIndex != cvf::UNDEFINED_SIZE_T )
|
||||||
|
{
|
||||||
|
cvf::Vec3d p1 = m_wellPathPoints[firstIndex];
|
||||||
|
cvf::Vec3d p2 = m_wellPathPoints[secondIndex];
|
||||||
|
|
||||||
|
double diffP1 = ( p1 - position ).lengthSquared();
|
||||||
|
double diffP2 = ( p2 - position ).lengthSquared();
|
||||||
|
|
||||||
|
double weigth1 = diffP2 / ( diffP1 + diffP2 );
|
||||||
|
|
||||||
|
double measureDepth1 = m_measuredDepths[firstIndex];
|
||||||
|
double measureDepth2 = m_measuredDepths[secondIndex];
|
||||||
|
|
||||||
|
double interpolatedValue = measureDepth1 * weigth1 + measureDepth2 * ( 1.0 - weigth1 );
|
||||||
|
return interpolatedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -681,3 +658,40 @@ std::vector<cvf::Vec3d> RigWellPath::clipPolylineStartAboveZ( const std::vector<
|
|||||||
|
|
||||||
return clippedPolyLine;
|
return clippedPolyLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
// Returns the closes indices with smallest index first
|
||||||
|
// If not found, cvf::UNDEFINED_SIZE_T is returned for both
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::pair<size_t, size_t> RigWellPath::closestIndices( const cvf::Vec3d& position ) const
|
||||||
|
{
|
||||||
|
size_t closestIndex = cvf::UNDEFINED_SIZE_T;
|
||||||
|
double closestDistance = cvf::UNDEFINED_DOUBLE;
|
||||||
|
|
||||||
|
for ( size_t i = 1; i < m_wellPathPoints.size(); i++ )
|
||||||
|
{
|
||||||
|
cvf::Vec3d point1 = m_wellPathPoints[i - 1];
|
||||||
|
cvf::Vec3d point2 = m_wellPathPoints[i - 0];
|
||||||
|
|
||||||
|
double candidateDistance = cvf::GeometryTools::linePointSquareDist( point1, point2, position );
|
||||||
|
if ( candidateDistance < closestDistance )
|
||||||
|
{
|
||||||
|
closestDistance = candidateDistance;
|
||||||
|
closestIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( closestIndex != cvf::UNDEFINED_SIZE_T )
|
||||||
|
{
|
||||||
|
if ( closestIndex > 0 )
|
||||||
|
{
|
||||||
|
return { closestIndex - 1, closestIndex };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { closestIndex, closestIndex + 1 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T };
|
||||||
|
}
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
double wellPathAzimuthAngle( const cvf::Vec3d& position ) const;
|
double wellPathAzimuthAngle( const cvf::Vec3d& position ) const;
|
||||||
void twoClosestPoints( const cvf::Vec3d& position, cvf::Vec3d* p1, cvf::Vec3d* p2 ) const;
|
void twoClosestPoints( const cvf::Vec3d& position, cvf::Vec3d* p1, cvf::Vec3d* p2 ) const;
|
||||||
double identicalTubeLength( const RigWellPath& otherWellPathGeometry ) const;
|
double identicalTubeLength( const RigWellPath& otherWellPathGeometry ) const;
|
||||||
|
double closestMeasuredDepth( const cvf::Vec3d& position ) const;
|
||||||
|
|
||||||
static cvf::ref<RigWellPath> commonGeometry( const std::vector<const RigWellPath*>& allGeometries );
|
static cvf::ref<RigWellPath> commonGeometry( const std::vector<const RigWellPath*>& allGeometries );
|
||||||
void setUniqueStartAndEndIndex( size_t uniqueStartIndex, size_t uniqueEndIndex );
|
void setUniqueStartAndEndIndex( size_t uniqueStartIndex, size_t uniqueEndIndex );
|
||||||
@ -90,6 +91,9 @@ public:
|
|||||||
double* horizontalLengthAlongWellToClipPoint,
|
double* horizontalLengthAlongWellToClipPoint,
|
||||||
size_t* indexToFirstVisibleSegment );
|
size_t* indexToFirstVisibleSegment );
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::pair<size_t, size_t> closestIndices( const cvf::Vec3d& position ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<cvf::Vec3d> m_wellPathPoints;
|
std::vector<cvf::Vec3d> m_wellPathPoints;
|
||||||
std::vector<double> m_measuredDepths;
|
std::vector<double> m_measuredDepths;
|
||||||
|
@ -53,10 +53,6 @@ void RigWellPathGeometryExporter::exportWellPathGeometry( gsl::not_null<const Ri
|
|||||||
{
|
{
|
||||||
rkbOffset = modeledWellPath->geometryDefinition()->airGap();
|
rkbOffset = modeledWellPath->geometryDefinition()->airGap();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
rkbOffset = modeledWellPath->geometryDefinition()->mdAtFirstTarget();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exportWellPathGeometry( *wellPathGeom, mdStepSize, rkbOffset, xValues, yValues, tvdValues, mdValues );
|
exportWellPathGeometry( *wellPathGeom, mdStepSize, rkbOffset, xValues, yValues, tvdValues, mdValues );
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "cvfMath.h"
|
#include "cvfMath.h"
|
||||||
#include "cvfMatrix3.h"
|
#include "cvfMatrix3.h"
|
||||||
|
|
||||||
|
#include "RiaOffshoreSphericalCoords.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@ -133,6 +134,61 @@ std::vector<double> RigWellPathGeometryTools::interpolateMdFromTvd( const std::v
|
|||||||
return interpolatedMdValues;
|
return interpolatedMdValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::pair<double, double>
|
||||||
|
RigWellPathGeometryTools::calculateAzimuthAndInclinationAtMd( double measuredDepth,
|
||||||
|
gsl::not_null<const RigWellPath*> wellPathGeometry )
|
||||||
|
{
|
||||||
|
int mdIndex = -1;
|
||||||
|
auto mdList = wellPathGeometry->measuredDepths();
|
||||||
|
|
||||||
|
for ( int i = 0; i < (int)mdList.size(); i++ )
|
||||||
|
{
|
||||||
|
if ( mdList[i] > measuredDepth )
|
||||||
|
{
|
||||||
|
mdIndex = i - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ptList = wellPathGeometry->wellPathPoints();
|
||||||
|
if ( mdIndex >= 0 && mdIndex < (int)ptList.size() - 1 )
|
||||||
|
{
|
||||||
|
const auto& v2 = cvf::Vec3d( ptList[mdIndex] );
|
||||||
|
const auto& v3 = cvf::Vec3d( ptList[mdIndex + 1] );
|
||||||
|
|
||||||
|
auto v32 = ( v3 - v2 ).getNormalized();
|
||||||
|
|
||||||
|
auto v13mean = v32;
|
||||||
|
|
||||||
|
if ( mdIndex > 0 )
|
||||||
|
{
|
||||||
|
const auto& v1 = cvf::Vec3d( ptList[mdIndex - 1] );
|
||||||
|
auto v21 = ( v2 - v1 ).getNormalized();
|
||||||
|
v13mean = ( v21 + v32 ) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto v24mean = v32;
|
||||||
|
if ( mdIndex < (int)ptList.size() - 2 )
|
||||||
|
{
|
||||||
|
const auto& v4 = cvf::Vec3d( ptList[mdIndex + 2] );
|
||||||
|
auto v43 = ( v4 - v3 ).getNormalized();
|
||||||
|
v24mean = ( v32 + v43 ) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
double weight = ( measuredDepth - mdList[mdIndex] ) / ( mdList[mdIndex + 1] - mdList[mdIndex] );
|
||||||
|
auto vTan = v13mean * ( 1.0 - weight ) + v24mean * ( weight );
|
||||||
|
|
||||||
|
RiaOffshoreSphericalCoords coords( vTan );
|
||||||
|
|
||||||
|
return { coords.azi(), coords.inc() };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { 0.0, 0.0 };
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <gsl/gsl>
|
||||||
|
|
||||||
class RigWellPath;
|
class RigWellPath;
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
@ -45,6 +47,9 @@ public:
|
|||||||
const std::vector<double>& originalTvdValues,
|
const std::vector<double>& originalTvdValues,
|
||||||
const std::vector<double>& tvdValuesToInterpolateFrom );
|
const std::vector<double>& tvdValuesToInterpolateFrom );
|
||||||
|
|
||||||
|
static std::pair<double, double>
|
||||||
|
calculateAzimuthAndInclinationAtMd( double measuredDepth, gsl::not_null<const RigWellPath*> wellPathGeometry );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::vector<cvf::Vec3d> interpolateUndefinedNormals( const cvf::Vec3d& planeNormal,
|
static std::vector<cvf::Vec3d> interpolateUndefinedNormals( const cvf::Vec3d& planeNormal,
|
||||||
const std::vector<cvf::Vec3d>& normals,
|
const std::vector<cvf::Vec3d>& normals,
|
||||||
|
@ -3,15 +3,32 @@ import rips
|
|||||||
|
|
||||||
# Connect to ResInsight instance
|
# Connect to ResInsight instance
|
||||||
resinsight = rips.Instance.find()
|
resinsight = rips.Instance.find()
|
||||||
# Example code
|
|
||||||
print("ResInsight version: " + resinsight.version_string())
|
|
||||||
|
|
||||||
modeled_well_paths = resinsight.project.descendants(rips.ModeledWellPath)
|
# Create a modeled well path and add well path targets
|
||||||
|
# The coordinates are based on the Norne case
|
||||||
|
|
||||||
for wellpath in modeled_well_paths:
|
well_path_coll = resinsight.project.descendants(rips.WellPathCollection)[0]
|
||||||
geometry = wellpath.well_path_geometry()
|
well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
|
||||||
geometry.print_object_info()
|
well_path.name = "Test Well-1"
|
||||||
reference_point = geometry.reference_point
|
well_path.update()
|
||||||
reference_point[0] += 100
|
|
||||||
geometry.update()
|
geometry = well_path.well_path_geometry()
|
||||||
geometry.print_object_info()
|
|
||||||
|
reference_point = geometry.reference_point
|
||||||
|
reference_point[0] = 457196
|
||||||
|
reference_point[1] = 7322270
|
||||||
|
reference_point[2] = 2742
|
||||||
|
geometry.update() # Commit updates back to ResInsight
|
||||||
|
|
||||||
|
# Create the first well target at the reference point
|
||||||
|
coord = [0, 0, 0]
|
||||||
|
geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
# Append new well targets relative the the reference point
|
||||||
|
coord = [454.28, 250, -10]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
coord = [1054.28, 250, -50]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
well_path.append_perforation_interval(3300, 3350, 0.2, 0.76)
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
# Load ResInsight Processing Server Client Library
|
||||||
|
import rips
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Connect to ResInsight instance
|
||||||
|
resinsight = rips.Instance.find()
|
||||||
|
|
||||||
|
# Create a modeled well path and add well path targets
|
||||||
|
# The coordinates are based on the Norne case
|
||||||
|
# Add a lateral to the main well path
|
||||||
|
|
||||||
|
well_path_coll = resinsight.project.descendants(rips.WellPathCollection)[0]
|
||||||
|
well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
|
||||||
|
well_path.name = "Test Well-1"
|
||||||
|
well_path.update()
|
||||||
|
|
||||||
|
geometry = well_path.well_path_geometry()
|
||||||
|
|
||||||
|
reference_point = geometry.reference_point
|
||||||
|
reference_point[0] = 457196
|
||||||
|
reference_point[1] = 7322270
|
||||||
|
reference_point[2] = 2742
|
||||||
|
geometry.update() # Commit updates back to ResInsight
|
||||||
|
|
||||||
|
# Create the first well target at the reference point
|
||||||
|
coord = [0, 0, 0]
|
||||||
|
geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
# Append new well targets relative the the reference point
|
||||||
|
coord = [454.28, 250, -10]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
coord = [1054.28, 250, -50]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
# Create a lateral at specified location on parent well
|
||||||
|
measured_depth = 3600
|
||||||
|
lateral = well_path.append_lateral(measured_depth)
|
||||||
|
geometry = lateral.well_path_geometry()
|
||||||
|
|
||||||
|
coord = [770, 280, 50]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
coord = [1054.28, -100, 50]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
coord = [2054.28, -100, 45]
|
||||||
|
target = geometry.append_well_target(coord)
|
||||||
|
|
||||||
|
|
||||||
|
# Wait 2 second
|
||||||
|
print("Wait 2 seconds ...")
|
||||||
|
time.sleep(2)
|
||||||
|
print("Move reference point of parent well")
|
||||||
|
|
||||||
|
geometry = well_path.well_path_geometry()
|
||||||
|
reference_point = geometry.reference_point
|
||||||
|
reference_point[2] += 50
|
||||||
|
geometry.update() # Commit updates back to ResInsight
|
Loading…
Reference in New Issue
Block a user