#4012 Always place well target points in real cell geometry

This commit is contained in:
Gaute Lindkvist 2019-01-31 15:49:12 +01:00
parent bd6bbe9da9
commit 107a4b9b60
7 changed files with 121 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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