mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4012 Always place well target points in real cell geometry
This commit is contained in:
parent
bd6bbe9da9
commit
107a4b9b60
@ -20,9 +20,16 @@
|
||||
|
||||
#include "RiaOffshoreSphericalCoords.h"
|
||||
|
||||
#include "RigFemPart.h"
|
||||
#include "RigFemPartCollection.h"
|
||||
#include "RigFemPartGrid.h"
|
||||
#include "RigHexIntersectionTools.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "Rim3dView.h"
|
||||
#include "RimGeoMechView.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathGeometryDef.h"
|
||||
@ -30,11 +37,18 @@
|
||||
|
||||
#include "RiuViewerCommands.h"
|
||||
|
||||
#include "RivFemPartGeometryGenerator.h"
|
||||
#include "RivFemPickSourceInfo.h"
|
||||
#include "RivSourceInfo.h"
|
||||
#include "RivWellPathSourceInfo.h"
|
||||
|
||||
#include "cafDisplayCoordTransform.h"
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -98,6 +112,17 @@ bool RicCreateWellTargetsPickEventHandler::handlePickEvent(const Ric3DPickEvent&
|
||||
{
|
||||
targetPointInDomain = intersectionPointInDomain;
|
||||
doSetAzimuthAndInclination = false;
|
||||
|
||||
cvf::Vec3d domainRayOrigin =
|
||||
rimView->displayCoordTransform()->transformToDomainCoord(firstPickItem.globalRayOrigin());
|
||||
cvf::Vec3d domainRayEnd = targetPointInDomain + (targetPointInDomain - domainRayOrigin);
|
||||
|
||||
cvf::Vec3d hexElementIntersection = findHexElementIntersection(rimView, firstPickItem, domainRayOrigin, domainRayEnd);
|
||||
CVF_ASSERT(!hexElementIntersection.isUndefined());
|
||||
if (!hexElementIntersection.isUndefined())
|
||||
{
|
||||
targetPointInDomain = hexElementIntersection;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_geometryToAddTargetsTo->firstActiveTarget())
|
||||
@ -196,3 +221,75 @@ bool RicCreateWellTargetsPickEventHandler::calculateAzimuthAndInclinationAtMd(do
|
||||
*inclination = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Vec3d RicCreateWellTargetsPickEventHandler::findHexElementIntersection(Rim3dView* view, const RiuPickItemInfo& pickItem, const cvf::Vec3d& domainRayOrigin, const cvf::Vec3d& domainRayEnd)
|
||||
{
|
||||
auto sourceInfo = dynamic_cast<const RivSourceInfo*>(pickItem.sourceInfo());
|
||||
auto femSourceInfo = dynamic_cast<const RivFemPickSourceInfo*>(pickItem.sourceInfo());
|
||||
|
||||
size_t cellIndex = cvf::UNDEFINED_SIZE_T;
|
||||
std::array<cvf::Vec3d, 8> cornerVertices;
|
||||
double characteristicLength = 0.0;
|
||||
if (sourceInfo)
|
||||
{
|
||||
size_t gridIndex = sourceInfo->gridIndex();
|
||||
if (sourceInfo->hasCellFaceMapping())
|
||||
{
|
||||
cellIndex = sourceInfo->m_cellFaceFromTriangleMapper->cellIndex(pickItem.faceIdx());
|
||||
|
||||
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>(view);
|
||||
if (eclipseView && eclipseView->mainGrid())
|
||||
{
|
||||
RigGridBase* hitGrid = eclipseView->mainGrid()->gridByIndex(gridIndex);
|
||||
hitGrid->cellCornerVertices(cellIndex, cornerVertices.data());
|
||||
double dx, dy, dz;
|
||||
hitGrid->characteristicCellSizes(&dx, &dy, &dz);
|
||||
characteristicLength = dz;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (femSourceInfo)
|
||||
{
|
||||
size_t femPartIndex = femSourceInfo->femPartIndex();
|
||||
if (femSourceInfo->triangleToElmMapper())
|
||||
{
|
||||
size_t elementIndex = femSourceInfo->triangleToElmMapper()->elementIndex(pickItem.faceIdx());
|
||||
|
||||
RimGeoMechView* geoMechView = dynamic_cast<RimGeoMechView*>(view);
|
||||
if (geoMechView && geoMechView->femParts())
|
||||
{
|
||||
RigFemPart* femPart = geoMechView->femParts()->part(femPartIndex);
|
||||
if (femPart->elementType(cellIndex) == HEX8 || femPart->elementType(cellIndex) == HEX8P)
|
||||
{
|
||||
cellIndex = elementIndex;
|
||||
femPart->getOrCreateStructGrid()->cellCornerVertices(cellIndex, cornerVertices.data());
|
||||
characteristicLength = femPart->characteristicElementSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<HexIntersectionInfo> intersectionInfo;
|
||||
RigHexIntersectionTools::lineHexCellIntersection(domainRayOrigin, domainRayEnd, cornerVertices.data(), cellIndex, &intersectionInfo);
|
||||
if (!intersectionInfo.empty())
|
||||
{
|
||||
// Sort intersection on distance to ray origin
|
||||
CVF_ASSERT(intersectionInfo.size() > 1);
|
||||
std::sort(intersectionInfo.begin(), intersectionInfo.end(),
|
||||
[&domainRayOrigin](const HexIntersectionInfo& lhs, const HexIntersectionInfo& rhs)
|
||||
{
|
||||
return (lhs.m_intersectionPoint - domainRayOrigin).lengthSquared() < (rhs.m_intersectionPoint - domainRayOrigin).lengthSquared();
|
||||
}
|
||||
);
|
||||
const double eps = 1.0e-3;
|
||||
cvf::Vec3d intersectionRay = intersectionInfo.back().m_intersectionPoint - intersectionInfo.front().m_intersectionPoint;
|
||||
cvf::Vec3d newPoint = intersectionInfo.front().m_intersectionPoint + intersectionRay * eps;
|
||||
CVF_ASSERT(RigHexIntersectionTools::isPointInCell(newPoint, cornerVertices.data()));
|
||||
return newPoint;
|
||||
}
|
||||
|
||||
return cvf::Vec3d::UNDEFINED;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ private:
|
||||
double* azimuth,
|
||||
double* inclination) const;
|
||||
|
||||
static cvf::Vec3d findHexElementIntersection(Rim3dView* view, const RiuPickItemInfo& pickItem, const cvf::Vec3d& domainRayOrigin, const cvf::Vec3d& domainRayEnd);
|
||||
private:
|
||||
caf::PdmPointer<RimWellPathGeometryDef> m_geometryToAddTargetsTo;
|
||||
};
|
||||
|
@ -52,13 +52,13 @@ RiuPickItemInfo RiuPickItemInfo::extractPickItemInfo(const cvf::HitItem* hitItem
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiuPickItemInfo> RiuPickItemInfo::convertToPickItemInfos( const cvf::HitItemCollection &hitItems)
|
||||
std::vector<RiuPickItemInfo> RiuPickItemInfo::convertToPickItemInfos( const cvf::HitItemCollection &hitItems, const cvf::Vec3d& globalRayOrigin)
|
||||
{
|
||||
std::vector<RiuPickItemInfo> pickItemInfos;
|
||||
pickItemInfos.reserve(hitItems.count());
|
||||
for ( size_t i = 0; i < hitItems.count(); i++ )
|
||||
{
|
||||
pickItemInfos.emplace_back(RiuPickItemInfo(hitItems.item(i)));
|
||||
pickItemInfos.emplace_back(RiuPickItemInfo(hitItems.item(i), globalRayOrigin));
|
||||
}
|
||||
return pickItemInfos;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ namespace cvf
|
||||
class Object;
|
||||
class HitItem;
|
||||
class HitItemCollection;
|
||||
class Ray;
|
||||
}
|
||||
|
||||
|
||||
@ -39,18 +40,21 @@ public:
|
||||
, m_pickedPart(nullptr)
|
||||
, m_globalPickedPoint (cvf::Vec3d::UNDEFINED)
|
||||
, m_localPickedPoint (cvf::Vec3d::UNDEFINED)
|
||||
, m_globalRayOrigin(cvf::Vec3d::UNDEFINED)
|
||||
, m_sourceInfo (nullptr)
|
||||
, m_faceIdx (-1)
|
||||
{}
|
||||
|
||||
explicit RiuPickItemInfo(const cvf::HitItem* hitItem)
|
||||
explicit RiuPickItemInfo(const cvf::HitItem* hitItem, const cvf::Vec3d& globalRayOrigin)
|
||||
: m_pickedPart(nullptr)
|
||||
, m_globalPickedPoint (cvf::Vec3d::UNDEFINED)
|
||||
, m_localPickedPoint (cvf::Vec3d::UNDEFINED)
|
||||
, m_globalRayOrigin(cvf::Vec3d::UNDEFINED)
|
||||
, m_sourceInfo (nullptr)
|
||||
, m_faceIdx (-1)
|
||||
{
|
||||
*this = extractPickItemInfo(hitItem);
|
||||
m_globalRayOrigin = globalRayOrigin;
|
||||
}
|
||||
|
||||
const cvf::Part* pickedPart() const { return m_pickedPart;}
|
||||
@ -59,18 +63,19 @@ public:
|
||||
const cvf::Object* sourceInfo() const { return m_sourceInfo;}
|
||||
cvf::uint faceIdx() const { return m_faceIdx;}
|
||||
double distanceAlongRay() const { return m_distanceAlongRay;}
|
||||
cvf::Vec3d globalRayOrigin() const { return m_globalRayOrigin;}
|
||||
|
||||
static RiuPickItemInfo extractPickItemInfo(const cvf::HitItem* hitItem);
|
||||
static std::vector<RiuPickItemInfo> convertToPickItemInfos(const cvf::HitItemCollection &hitItems);
|
||||
static std::vector<RiuPickItemInfo> convertToPickItemInfos(const cvf::HitItemCollection &hitItems, const cvf::Vec3d& globalRayOrigin);
|
||||
|
||||
private:
|
||||
double m_distanceAlongRay;
|
||||
const cvf::Part* m_pickedPart;
|
||||
cvf::Vec3d m_globalPickedPoint;
|
||||
cvf::Vec3d m_localPickedPoint;
|
||||
cvf::Vec3d m_globalRayOrigin;
|
||||
const cvf::Object* m_sourceInfo;
|
||||
cvf::uint m_faceIdx;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -158,9 +158,10 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event)
|
||||
std::vector<RiuPickItemInfo> pickItemInfos;
|
||||
{
|
||||
cvf::HitItemCollection hitItems;
|
||||
if (m_viewer->rayPick(event->x(), event->y(), &hitItems))
|
||||
cvf::Vec3d globalRayOrigin;
|
||||
if (m_viewer->rayPick(event->x(), event->y(), &hitItems, &globalRayOrigin))
|
||||
{
|
||||
pickItemInfos = RiuPickItemInfo::convertToPickItemInfos(hitItems);
|
||||
pickItemInfos = RiuPickItemInfo::convertToPickItemInfos(hitItems, globalRayOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,15 +525,16 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM
|
||||
|
||||
std::vector<RiuPickItemInfo> pickItemInfos;
|
||||
{
|
||||
cvf::Vec3d globalRayOrigin;
|
||||
cvf::HitItemCollection hitItems;
|
||||
m_viewer->rayPick(winPosX, winPosY, &hitItems);
|
||||
m_viewer->rayPick(winPosX, winPosY, &hitItems, &globalRayOrigin);
|
||||
|
||||
// Do specialized text pick, since vizfwk does not hit text
|
||||
handleTextPicking(winPosX, winPosY, &hitItems);
|
||||
|
||||
if (hitItems.count())
|
||||
{
|
||||
pickItemInfos = RiuPickItemInfo::convertToPickItemInfos(hitItems);
|
||||
pickItemInfos = RiuPickItemInfo::convertToPickItemInfos(hitItems, globalRayOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ const caf::NavigationPolicy* caf::Viewer::getNavigationPolicy() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool caf::Viewer::rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints)
|
||||
bool caf::Viewer::rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints, cvf::Vec3d* globalRayOrigin/*=nullptr*/)
|
||||
{
|
||||
CVF_ASSERT(m_mainRendering.notNull());
|
||||
|
||||
@ -485,7 +485,11 @@ bool caf::Viewer::rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pick
|
||||
if (ris.notNull())
|
||||
{
|
||||
bool retVal = m_mainRendering->rayIntersect(*ris, pickedPoints);
|
||||
|
||||
if (retVal && globalRayOrigin)
|
||||
{
|
||||
CVF_ASSERT(ris->ray() != nullptr);
|
||||
*globalRayOrigin = ris->ray()->origin();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
else
|
||||
|
@ -135,7 +135,7 @@ public:
|
||||
// Test whether it is any point in doing navigation etc.
|
||||
bool canRender() const;
|
||||
|
||||
bool rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints) ;
|
||||
bool rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints, cvf::Vec3d* rayGlobalOrigin = nullptr) ;
|
||||
cvf::OverlayItem* overlayItem(int winPosX, int winPosY);
|
||||
|
||||
// QPainter based drawing on top of the OpenGL graphics
|
||||
|
Loading…
Reference in New Issue
Block a user