diff --git a/ApplicationCode/Commands/RicViewerEventInterface.h b/ApplicationCode/Commands/RicViewerEventInterface.h index 2e33707a7d..3e5fba9b07 100644 --- a/ApplicationCode/Commands/RicViewerEventInterface.h +++ b/ApplicationCode/Commands/RicViewerEventInterface.h @@ -25,29 +25,28 @@ #include "cvfObject.h" #include "cvfVector3.h" -namespace cvf { - class Part; -} +namespace cvf { + class Part; +} + + +class RicViewerEventObject +{ +public: + RicViewerEventObject(cvf::Vec3d globalIntersectionPoint, const std::vector>& partAndTriangleIndexPairs) + : m_globalIntersectionPoint(globalIntersectionPoint), + m_partAndTriangleIndexPairs(partAndTriangleIndexPairs) + { + } + + cvf::Vec3d m_globalIntersectionPoint; + std::vector> m_partAndTriangleIndexPairs; +}; + class RicViewerEventInterface { public: - virtual bool handleEvent(cvf::Object* eventObject) = 0; -}; - - -class RicViewerEventObject : public cvf::Object -{ -public: - RicViewerEventObject(cvf::Vec3d globalIntersectionPoint, cvf::Part* firstHitPart, cvf::uint firstPartTriangleIndex) - : globalIntersectionPoint(globalIntersectionPoint), - firstHitPart(firstHitPart), - firstPartTriangleIndex(firstPartTriangleIndex) - { - } - - cvf::Vec3d globalIntersectionPoint; - cvf::Part* firstHitPart; - cvf::uint firstPartTriangleIndex; + virtual bool handleEvent(const RicViewerEventObject& eventObject) = 0; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp b/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp index a83dc266f2..4c75202084 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp @@ -37,15 +37,13 @@ RicIntersectionViewerEventHandler* RicIntersectionViewerEventHandler::instance() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicIntersectionViewerEventHandler::handleEvent(cvf::Object* eventObject) +bool RicIntersectionViewerEventHandler::handleEvent(const RicViewerEventObject& eventObject) { std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); if (selection.size() == 1) { - RicViewerEventObject* polylineUiEvent = dynamic_cast(eventObject); - if (polylineUiEvent) { RimIntersection* intersection = selection[0]; @@ -54,7 +52,7 @@ bool RicIntersectionViewerEventHandler::handleEvent(cvf::Object* eventObject) CVF_ASSERT(rimView); cvf::ref transForm = rimView->displayCoordTransform(); - cvf::Vec3d domainCoord = transForm->transformToDomainCoord(polylineUiEvent->globalIntersectionPoint); + cvf::Vec3d domainCoord = transForm->transformToDomainCoord(eventObject.m_globalIntersectionPoint); if (intersection->inputPolyLineFromViewerEnabled()) { diff --git a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h b/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h index 6d7d3d0880..721d61b169 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h +++ b/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h @@ -29,6 +29,6 @@ public: static RicIntersectionViewerEventHandler* instance(); protected: - virtual bool handleEvent(cvf::Object* eventObject) override; + virtual bool handleEvent(const RicViewerEventObject& eventObject) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp index 6f95204113..f8b5e54f77 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp @@ -26,6 +26,7 @@ #include "RiuMainWindow.h" +#include "RivObjectSourceInfo.h" #include "RivWellPathSourceInfo.h" #include "cafDisplayCoordTransform.h" @@ -46,43 +47,67 @@ RicWellPathViewerEventHandler* RicWellPathViewerEventHandler::instance() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicWellPathViewerEventHandler::handleEvent(cvf::Object* eventObject) +bool RicWellPathViewerEventHandler::handleEvent(const RicViewerEventObject& eventObject) { - RicViewerEventObject* uiEvent = dynamic_cast(eventObject); - if (!uiEvent) return false; + if (eventObject.m_partAndTriangleIndexPairs.empty()) return false; - if (uiEvent->firstHitPart && uiEvent->firstHitPart->sourceInfo()) + const caf::PdmObject* objectToSelect = nullptr; + + cvf::uint wellPathTriangleIndex = cvf::UNDEFINED_UINT; + const RivWellPathSourceInfo* wellPathSourceInfo = nullptr; + for (const auto & partAndTriangleIndexPair : eventObject.m_partAndTriangleIndexPairs) { - const RivWellPathSourceInfo* wellPathSourceInfo = dynamic_cast(uiEvent->firstHitPart->sourceInfo()); - if (wellPathSourceInfo) + const cvf::Part* part = partAndTriangleIndexPair.first; + + const RivObjectSourceInfo* sourceInfo = dynamic_cast(part->sourceInfo()); + if (!objectToSelect && sourceInfo) { - Rim3dView* rimView = RiaApplication::instance()->activeReservoirView(); - if (!rimView) return false; - - cvf::ref transForm = rimView->displayCoordTransform(); - cvf::Vec3d domainCoord = transForm->transformToDomainCoord(uiEvent->globalIntersectionPoint); - - double measuredDepth = wellPathSourceInfo->measuredDepth(uiEvent->firstPartTriangleIndex, domainCoord); - - // NOTE: This computation was used to find the location for a fracture when clicking on a well path - // It turned out that the computation was a bit inaccurate - // Consider to use code in RigSimulationWellCoordsAndMD instead - cvf::Vec3d trueVerticalDepth = wellPathSourceInfo->trueVerticalDepth(uiEvent->firstPartTriangleIndex, domainCoord); - - QString wellPathText; - wellPathText += QString("Well path name : %1\n").arg(wellPathSourceInfo->wellPath()->name()); - wellPathText += QString("Measured depth : %1\n").arg(measuredDepth); - - QString formattedText; - formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", trueVerticalDepth.x(), trueVerticalDepth.y(), -trueVerticalDepth.z()); - wellPathText += formattedText; - - RiuMainWindow::instance()->setResultInfo(wellPathText); - - RiuMainWindow::instance()->selectAsCurrentItem(wellPathSourceInfo->wellPath()); - - return true; + objectToSelect = sourceInfo->object(); } + + if (part && part->sourceInfo() && dynamic_cast(part->sourceInfo())) + { + wellPathSourceInfo = dynamic_cast(part->sourceInfo()); + wellPathTriangleIndex = partAndTriangleIndexPair.second; + break; + } + } + + if (wellPathSourceInfo) + { + Rim3dView* rimView = RiaApplication::instance()->activeReservoirView(); + if (!rimView) return false; + + cvf::ref transForm = rimView->displayCoordTransform(); + cvf::Vec3d domainCoord = transForm->transformToDomainCoord(eventObject.m_globalIntersectionPoint); + + double measuredDepth = wellPathSourceInfo->measuredDepth(wellPathTriangleIndex, domainCoord); + + // NOTE: This computation was used to find the location for a fracture when clicking on a well path + // It turned out that the computation was a bit inaccurate + // Consider to use code in RigSimulationWellCoordsAndMD instead + cvf::Vec3d trueVerticalDepth = wellPathSourceInfo->trueVerticalDepth(wellPathTriangleIndex, domainCoord); + + QString wellPathText; + wellPathText += QString("Well path name : %1\n").arg(wellPathSourceInfo->wellPath()->name()); + wellPathText += QString("Measured depth : %1\n").arg(measuredDepth); + + QString formattedText; + formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", trueVerticalDepth.x(), trueVerticalDepth.y(), -trueVerticalDepth.z()); + wellPathText += formattedText; + + RiuMainWindow::instance()->setResultInfo(wellPathText); + + if (objectToSelect) + { + RiuMainWindow::instance()->selectAsCurrentItem(objectToSelect); + } + else + { + RiuMainWindow::instance()->selectAsCurrentItem(wellPathSourceInfo->wellPath()); + } + + return true; } return false; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h index 305e856ab8..16dde93d89 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h @@ -30,6 +30,6 @@ class RicWellPathViewerEventHandler : public RicViewerEventInterface public: static RicWellPathViewerEventHandler* instance(); - virtual bool handleEvent(cvf::Object* eventObject); + virtual bool handleEvent(const RicViewerEventObject& eventObject); }; diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.cpp b/ApplicationCode/UserInterface/RiuViewerCommands.cpp index cf7af25498..2d54258375 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.cpp +++ b/ApplicationCode/UserInterface/RiuViewerCommands.cpp @@ -148,15 +148,15 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) cvf::Vec3d localIntersectionPoint(cvf::Vec3d::ZERO); cvf::Vec3d globalIntersectionPoint(cvf::Vec3d::ZERO); - cvf::Part* firstHitPart = nullptr; - cvf::Part* nncFirstHitPart = nullptr; + const cvf::Part* firstHitPart = nullptr; + const cvf::Part* nncFirstHitPart = nullptr; m_currentPickPositionInDomainCoords = cvf::Vec3d::UNDEFINED; cvf::HitItemCollection hitItems; if (m_viewer->rayPick(winPosX, winPosY, &hitItems)) { - extractIntersectionData(hitItems, &localIntersectionPoint, &globalIntersectionPoint, &firstHitPart, &firstPartTriangleIndex, &nncFirstHitPart, NULL); + extractIntersectionData(hitItems, &localIntersectionPoint, &globalIntersectionPoint, &firstHitPart, &firstPartTriangleIndex, &nncFirstHitPart, nullptr); cvf::Vec3d displayModelOffset = cvf::Vec3d::ZERO; @@ -426,24 +426,31 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM // Extract all the above information from the pick { - cvf::Part* firstHitPart = nullptr; + const cvf::Part* firstHitPart = nullptr; uint firstPartTriangleIndex = cvf::UNDEFINED_UINT; - cvf::Part* firstNncHitPart = nullptr; + const cvf::Part* firstNncHitPart = nullptr; uint nncPartTriangleIndex = cvf::UNDEFINED_UINT; cvf::HitItemCollection hitItems; if (m_viewer->rayPick(winPosX, winPosY, &hitItems)) { - extractIntersectionData(hitItems, &localIntersectionPoint, &globalIntersectionPoint, &firstHitPart, &firstPartTriangleIndex, &firstNncHitPart, &nncPartTriangleIndex); + std::vector> partAndTriangleIndexPairs; + extractIntersectionData(hitItems, &localIntersectionPoint, &globalIntersectionPoint, &partAndTriangleIndexPairs, &firstNncHitPart, &nncPartTriangleIndex); - cvf::ref eventObj = new RicViewerEventObject(globalIntersectionPoint, firstHitPart, firstPartTriangleIndex); - for (size_t i = 0; i < m_viewerEventHandlers.size(); i++) + if (!partAndTriangleIndexPairs.empty()) { - if (m_viewerEventHandlers[i]->handleEvent(eventObj.p())) + RicViewerEventObject viewerEventObject(globalIntersectionPoint, partAndTriangleIndexPairs); + for (size_t i = 0; i < m_viewerEventHandlers.size(); i++) { - return; + if (m_viewerEventHandlers[i]->handleEvent(viewerEventObject)) + { + return; + } } + + firstHitPart = partAndTriangleIndexPairs.front().first; + firstPartTriangleIndex = partAndTriangleIndexPairs.front().second; } } @@ -632,8 +639,35 @@ void RiuViewerCommands::findCellAndGridIndex(const RivIntersectionBoxSourceInfo* void RiuViewerCommands::extractIntersectionData(const cvf::HitItemCollection& hitItems, cvf::Vec3d* localIntersectionPoint, cvf::Vec3d* globalIntersectionPoint, - cvf::Part** firstPart, uint* firstPartFaceHit, - cvf::Part** nncPart, uint* nncPartFaceHit) + const cvf::Part** firstPart, uint* firstPartFaceHit, + const cvf::Part** nncPart, uint* nncPartFaceHit) +{ + std::vector> partAndTriangleIndexPairs; + extractIntersectionData(hitItems, localIntersectionPoint, globalIntersectionPoint, + &partAndTriangleIndexPairs, nncPart, nncPartFaceHit); + + if (!partAndTriangleIndexPairs.empty()) + { + if (firstPart) + { + *firstPart = partAndTriangleIndexPairs.front().first; + } + + if (firstPartFaceHit) + { + *firstPartFaceHit = partAndTriangleIndexPairs.front().second; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewerCommands::extractIntersectionData(const cvf::HitItemCollection& hitItems, + cvf::Vec3d* localIntersectionPoint, + cvf::Vec3d*globalIntersectionPoint, + std::vector>* partAndTriangleIndexPairs, + const cvf::Part** nncPart, uint* nncPartFaceHit) { CVF_ASSERT(hitItems.count() > 0); @@ -649,7 +683,7 @@ void RiuViewerCommands::extractIntersectionData(const cvf::HitItemCollection& hi } } - const cvf::HitItem* firstNonNncHitItem = nullptr; + size_t firstNonNncPartIndex = cvf::UNDEFINED_SIZE_T; cvf::Vec3d firstItemIntersectionPoint = hitItems.item(0)->intersectionPoint(); // Check if we have a close hit item with NNC data @@ -684,58 +718,66 @@ void RiuViewerCommands::extractIntersectionData(const cvf::HitItemCollection& hi } } - if (!isNncpart && !firstNonNncHitItem) + if (!isNncpart && firstNonNncPartIndex == cvf::UNDEFINED_SIZE_T) { - firstNonNncHitItem = hitItemCandidate; - firstItemIntersectionPoint = firstNonNncHitItem->intersectionPoint(); + firstItemIntersectionPoint = hitItemCandidate->intersectionPoint(); + firstNonNncPartIndex = i; } - if (firstNonNncHitItem && *nncPart) + if (firstNonNncPartIndex != cvf::UNDEFINED_SIZE_T && *nncPart) { break; } } - if (firstNonNncHitItem) + if (firstNonNncPartIndex != cvf::UNDEFINED_SIZE_T) { - const cvf::Part* pickedPart = firstNonNncHitItem->part(); - CVF_ASSERT(pickedPart); - *firstPart = const_cast(pickedPart); - - const cvf::Transform* xf = pickedPart->transform(); - cvf::Vec3d globalPickedPoint = firstNonNncHitItem->intersectionPoint(); - - if (globalIntersectionPoint) { - *globalIntersectionPoint = globalPickedPoint; - } + const cvf::HitItem* firstNonNncHitItem = hitItems.item(firstNonNncPartIndex); + const cvf::Part* pickedPart = firstNonNncHitItem->part(); + CVF_ASSERT(pickedPart); - if (localIntersectionPoint) - { - if (xf) + const cvf::Transform* xf = pickedPart->transform(); + const cvf::Vec3d& globalPickedPoint = firstNonNncHitItem->intersectionPoint(); + + if (globalIntersectionPoint) { - *localIntersectionPoint = globalPickedPoint.getTransformedPoint(xf->worldTransform().getInverted()); + *globalIntersectionPoint = globalPickedPoint; } - else + + if (localIntersectionPoint) { - *localIntersectionPoint = globalPickedPoint; + if (xf) + { + *localIntersectionPoint = globalPickedPoint.getTransformedPoint(xf->worldTransform().getInverted()); + } + else + { + *localIntersectionPoint = globalPickedPoint; + } } } - if (firstPartFaceHit) + for (size_t i = firstNonNncPartIndex; i < hitItems.count(); i++) { - const cvf::HitDetailDrawableGeo* detail = dynamic_cast(firstNonNncHitItem->detail()); + const cvf::HitItem* hitItem = hitItems.item(i); + const cvf::Part* pickedPart = hitItem->part(); + + cvf::uint faceIndex = cvf::UNDEFINED_UINT; + const cvf::HitDetailDrawableGeo* detail = dynamic_cast(hitItem->detail()); if (detail) { - *firstPartFaceHit = detail->faceIndex(); + faceIndex = detail->faceIndex(); } + + partAndTriangleIndexPairs->push_back(std::make_pair(pickedPart, faceIndex)); } } else { if (localIntersectionPoint && nncPart && *nncPart) { - cvf::Vec3d globalPickedPoint = firstItemIntersectionPoint; + const cvf::Vec3d& globalPickedPoint = firstItemIntersectionPoint; if (globalIntersectionPoint) { diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.h b/ApplicationCode/UserInterface/RiuViewerCommands.h index da3cb16a1c..fe2aae48bc 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.h +++ b/ApplicationCode/UserInterface/RiuViewerCommands.h @@ -64,7 +64,8 @@ private: void findCellAndGridIndex(const RivIntersectionBoxSourceInfo* intersectionBoxSourceInfo, cvf::uint firstPartTriangleIndex, size_t* cellIndex, size_t* gridIndex); void ijkFromCellIndex(size_t gridIdx, size_t cellIndex, size_t* i, size_t* j, size_t* k); - void extractIntersectionData(const cvf::HitItemCollection& hitItems, cvf::Vec3d* localIntersectionPoint, cvf::Vec3d* globalIntersectionPoint, cvf::Part** firstPart, uint* firstPartFaceHit, cvf::Part** nncPart, uint* nncPartFaceHit); + void extractIntersectionData(const cvf::HitItemCollection& hitItems, cvf::Vec3d* localIntersectionPoint, cvf::Vec3d* globalIntersectionPoint, const cvf::Part** firstPart, uint* firstPartFaceHit, const cvf::Part** nncPart, uint* nncPartFaceHit); + void extractIntersectionData(const cvf::HitItemCollection& hitItems, cvf::Vec3d* localIntersectionPoint, cvf::Vec3d* globalIntersectionPoint, std::vector>* partAndTriangleIndexPairs, const cvf::Part** nncPart, uint* nncPartFaceHit); bool handleOverlayItemPicking(int winPosX, int winPosY);