diff --git a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake index dd55b9252d..2d98f85c33 100644 --- a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake @@ -27,6 +27,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogFileCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogRftCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveDeleteFeature.h +${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveViewerEventHandler.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -57,6 +58,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogFileCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogRftCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveDeleteFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveViewerEventHandler.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.cpp b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.cpp new file mode 100644 index 0000000000..ea5337d7e8 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.cpp @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "Ric3dWellLogCurveViewerEventHandler.h" + +#include "Rim3dWellLogCurve.h" +#include "Rim3dWellLogCurveCollection.h" +#include "RiuMainWindow.h" +#include "RivObjectSourceInfo.h" + +#include "cvfPart.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Ric3dWellLogCurveViewerEventHandler* Ric3dWellLogCurveViewerEventHandler::instance() +{ + static Ric3dWellLogCurveViewerEventHandler* singleton = new Ric3dWellLogCurveViewerEventHandler; + return singleton; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Ric3dWellLogCurveViewerEventHandler::handleEvent(const RicViewerEventObject& eventObject) +{ + if (eventObject.m_partAndTriangleIndexPairs.empty()) return false; + + cvf::uint triangleIndex = cvf::UNDEFINED_UINT; + + const auto& partAndTriangleIndexPair = eventObject.m_partAndTriangleIndexPairs.front(); + const cvf::Part* part = partAndTriangleIndexPair.first; + + const RivObjectSourceInfo* sourceInfo = dynamic_cast(part->sourceInfo()); + if (sourceInfo) + { + Rim3dWellLogCurveCollection* curveCollection = dynamic_cast(sourceInfo->object()); + if (curveCollection) + { + cvf::Vec3d closestPoint; + double measuredDepthAtPoint; + double valueAtPoint; + Rim3dWellLogCurve* curve = curveCollection->checkForCurveIntersection( + eventObject.m_globalIntersectionPoint, &closestPoint, &measuredDepthAtPoint, &valueAtPoint); + if (curve) + { + RiuMainWindow::instance()->selectAsCurrentItem(curve); + } + else + { + RiuMainWindow::instance()->selectAsCurrentItem(curveCollection); + } + return true; + } + } + return false; +} diff --git a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h new file mode 100644 index 0000000000..8299a191d7 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicViewerEventInterface.h" + +//================================================================================================== +/// +//================================================================================================== +class Ric3dWellLogCurveViewerEventHandler : public RicViewerEventInterface +{ +public: + static Ric3dWellLogCurveViewerEventHandler* instance(); + + bool handleEvent(const RicViewerEventObject& eventObject) override; +}; diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp index 9d920eebd1..9088d2f5db 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp @@ -29,6 +29,7 @@ #include "cvfPrimitiveSetIndexedUInt.h" #include "cvfBoundingBox.h" +#include "cvfMath.h" #include @@ -37,72 +38,25 @@ //-------------------------------------------------------------------------------------------------- Riv3dWellLogCurveGeometryGenerator::Riv3dWellLogCurveGeometryGenerator(RimWellPath* wellPath) : m_wellPath(wellPath) + , m_planeWidth(0.0) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref - Riv3dWellLogCurveGeometryGenerator::createCurveLine(const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox, - const std::vector& resultValues, - const std::vector& resultMds, - double minResultValue, - double maxResultValue, - double planeAngle, - double planeOffsetFromWellPathCenter, - double planeWidth) const +void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::DisplayCoordTransform* displayCoordTransform, + const cvf::BoundingBox& wellPathClipBoundingBox, + const std::vector& resultValues, + const std::vector& resultMds, + double minResultValue, + double maxResultValue, + double planeAngle, + double planeOffsetFromWellPathCenter, + double planeWidth) { - std::vector vertices; - std::vector indices; + m_planeWidth = planeWidth; - createCurveVerticesAndIndices(resultValues, - resultMds, - minResultValue, - maxResultValue, - planeAngle, - planeOffsetFromWellPathCenter, - planeWidth, - displayCoordTransform, - wellPathClipBoundingBox, - &vertices, - &indices); - - if (vertices.empty() || indices.empty()) - { - return nullptr; - } - - cvf::ref indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES); - cvf::ref indexArray = new cvf::UIntArray(indices); - - cvf::ref drawable = new cvf::DrawableGeo(); - - indexedUInt->setIndices(indexArray.p()); - drawable->addPrimitiveSet(indexedUInt.p()); - - cvf::ref vertexArray = new cvf::Vec3fArray(vertices); - drawable->setVertexArray(vertexArray.p()); - - return drawable; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std::vector& resultValues, - const std::vector& resultMds, - double minResultValue, - double maxResultValue, - double planeAngle, - double planeOffsetFromWellPathCenter, - double planeWidth, - const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox, - std::vector* vertices, - std::vector* indices) const -{ if (!wellPathGeometry()) return; if (wellPathGeometry()->m_wellPathPoints.empty()) return; if (!wellPathClipBoundingBox.isValid()) return; @@ -153,13 +107,15 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std std::reverse(interpolatedCurveNormals.begin(), interpolatedCurveNormals.end()); // The result values for the part of the well which is not clipped off, matching interpolatedWellPathPoints size - std::vector resultValuesForInterpolatedPoints(resultValues.end() - interpolatedWellPathPoints.size(), - resultValues.end()); + m_curveValues = std::vector(resultValues.end() - interpolatedWellPathPoints.size(), + resultValues.end()); + m_curveMeasuredDepths = std::vector(resultMds.end() - interpolatedWellPathPoints.size(), + resultMds.end()); double maxClampedResult = -HUGE_VAL; double minClampedResult = HUGE_VAL; - for (double& result : resultValuesForInterpolatedPoints) + for (double& result : m_curveValues) { if (!RigCurveDataTools::isValidValue(result, false)) continue; @@ -174,34 +130,54 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std return; } - vertices->resize(interpolatedWellPathPoints.size()); + m_curveVertices = std::vector(); + m_curveVertices.reserve(interpolatedWellPathPoints.size()); double plotRangeToResultRangeFactor = planeWidth / (maxClampedResult - minClampedResult); - for (size_t i = 0; i < interpolatedCurveNormals.size(); i++) + for (size_t i = 0; i < interpolatedWellPathPoints.size(); i++) { double scaledResult = 0; - if (RigCurveDataTools::isValidValue(resultValuesForInterpolatedPoints[i], false)) + if (RigCurveDataTools::isValidValue(m_curveValues[i], false)) { scaledResult = - planeOffsetFromWellPathCenter + (resultValuesForInterpolatedPoints[i] - minClampedResult) * plotRangeToResultRangeFactor; + planeOffsetFromWellPathCenter + (m_curveValues[i] - minClampedResult) * plotRangeToResultRangeFactor; } - - (*vertices)[i] = cvf::Vec3f(interpolatedWellPathPoints[i] + scaledResult * interpolatedCurveNormals[i]); + cvf::Vec3d curvePoint(interpolatedWellPathPoints[i] + scaledResult * interpolatedCurveNormals[i]); + m_curveVertices.push_back(cvf::Vec3f(curvePoint)); } - std::vector> valuesIntervals = - RigCurveDataTools::calculateIntervalsOfValidValues(resultValuesForInterpolatedPoints, false); - - for (const std::pair& interval : valuesIntervals) + std::vector indices; + indices.reserve(interpolatedWellPathPoints.size()); + for (size_t i = 0; i < m_curveValues.size() - 1; ++i) { - for (size_t i = interval.first; i < interval.second; i++) + if (RigCurveDataTools::isValidValue(m_curveValues[i], false) && + RigCurveDataTools::isValidValue(m_curveValues[i + 1], false)) { - indices->push_back(cvf::uint(i)); - indices->push_back(cvf::uint(i + 1)); + indices.push_back(cvf::uint(i)); + indices.push_back(cvf::uint(i + 1)); } } + + cvf::ref indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES); + cvf::ref indexArray = new cvf::UIntArray(indices); + + m_curveDrawable = new cvf::DrawableGeo(); + + indexedUInt->setIndices(indexArray.p()); + m_curveDrawable->addPrimitiveSet(indexedUInt.p()); + + cvf::ref vertexArray = new cvf::Vec3fArray(m_curveVertices); + m_curveDrawable->setVertexArray(vertexArray.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref Riv3dWellLogCurveGeometryGenerator::curveDrawable() +{ + return m_curveDrawable; } //-------------------------------------------------------------------------------------------------- @@ -211,3 +187,49 @@ const RigWellPath* Riv3dWellLogCurveGeometryGenerator::wellPathGeometry() const { return m_wellPath->wellPathGeometry(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Riv3dWellLogCurveGeometryGenerator::findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtClosestPoint) const +{ + cvf::Vec3f globalIntersectionFloat(globalIntersection); + float closestDistance = m_planeWidth * 0.1; + *closestPoint = cvf::Vec3d::UNDEFINED; + *measuredDepthAtPoint = cvf::UNDEFINED_DOUBLE; + *valueAtClosestPoint = cvf::UNDEFINED_DOUBLE; + if (m_curveVertices.size() < 2u) false; + CVF_ASSERT(m_curveVertices.size() == m_curveValues.size()); + for (size_t i = 1; i < m_curveVertices.size(); ++i) + { + bool validCurveSegment = RigCurveDataTools::isValidValue(m_curveValues[i], false) && + RigCurveDataTools::isValidValue(m_curveValues[i - 1], false); + if (validCurveSegment) + { + cvf::Vec3f a = m_curveVertices[i - 1]; + cvf::Vec3f b = m_curveVertices[i]; + cvf::Vec3f ap = globalIntersectionFloat - a; + cvf::Vec3f ab = b - a; + // Projected point is clamped to one of the end points of the segment. + float distanceToProjectedPointAlongAB = ap * ab / (ab * ab); + float clampedDistance = cvf::Math::clamp(distanceToProjectedPointAlongAB, 0.0f, 1.0f); + cvf::Vec3f projectionOfGlobalIntersection = a + clampedDistance * ab; + float distance = (projectionOfGlobalIntersection - globalIntersectionFloat).length(); + if (distance < closestDistance) + { + *closestPoint = cvf::Vec3d(projectionOfGlobalIntersection); + closestDistance = distance; + *measuredDepthAtPoint = m_curveMeasuredDepths[i - 1] * (1.0f - clampedDistance) + m_curveMeasuredDepths[i] * clampedDistance; + *valueAtClosestPoint = m_curveValues[i - 1] * (1.0f - clampedDistance) + m_curveValues[i] * clampedDistance; + } + } + } + + if (closestPoint->isUndefined()) + return false; + + return true; +} diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.h b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.h index eaa2df0404..0f09fca27a 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.h +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.h @@ -43,32 +43,33 @@ class RimWellPath; class Riv3dWellLogCurveGeometryGenerator : public cvf::Object { public: + typedef std::pair PointValuePair; Riv3dWellLogCurveGeometryGenerator(RimWellPath* wellPath); - cvf::ref createCurveLine(const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox, - const std::vector& resultValues, - const std::vector& resultMds, - double planeAngle, - double planeOffsetFromWellPathCenter, - double planeWidth, - double minResultValue, - double maxResultValue) const; -private: - void createCurveVerticesAndIndices(const std::vector& resultValues, - const std::vector& resultMds, - double minResultValue, - double maxResultValue, - double planeAngle, - double planeOffsetFromWellPathCenter, - double planeWidth, - const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox, - std::vector* vertices, - std::vector* indices) const; + void createCurveDrawables(const caf::DisplayCoordTransform* displayCoordTransform, + const cvf::BoundingBox& wellPathClipBoundingBox, + const std::vector& resultValues, + const std::vector& resultMds, + double planeAngle, + double planeOffsetFromWellPathCenter, + double planeWidth, + double minResultValue, + double maxResultValue); const RigWellPath* wellPathGeometry() const; + cvf::ref curveDrawable(); + + bool findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtClosestPoint) const; + private: caf::PdmPointer m_wellPath; + cvf::ref m_curveDrawable; + std::vector m_curveVertices; + std::vector m_curveMeasuredDepths; + std::vector m_curveValues; + double m_planeWidth; }; diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp index 33f541ebc9..bf7d916190 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp @@ -29,6 +29,7 @@ #include "Riv3dWellLogCurveGeomertyGenerator.h" #include "Riv3dWellLogGridGeomertyGenerator.h" +#include "RivObjectSourceInfo.h" #include "cafDisplayCoordTransform.h" #include "cafEffectGenerator.h" @@ -51,7 +52,6 @@ Riv3dWellLogPlanePartMgr::Riv3dWellLogPlanePartMgr(RimWellPath* wellPath, RimGri , m_gridView(gridView) { CVF_ASSERT(m_wellPath.notNull()); - m_3dWellLogCurveGeometryGenerator = new Riv3dWellLogCurveGeometryGenerator(m_wellPath.p()); m_3dWellLogGridGeometryGenerator = new Riv3dWellLogGridGeometryGenerator(m_wellPath.p()); } @@ -89,29 +89,34 @@ void Riv3dWellLogPlanePartMgr::append3dWellLogCurvesToModel(cvf::ModelBasicList* if (!m_wellPath->rim3dWellLogCurveCollection()) return; if (m_wellPath->rim3dWellLogCurveCollection()->vectorOf3dWellLogCurves().empty()) return; - const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); - - size_t colorIndex = 0; + Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); for (Rim3dWellLogCurve* rim3dWellLogCurve : m_wellPath->rim3dWellLogCurveCollection()->vectorOf3dWellLogCurves()) { - colorIndex++; + cvf::ref generator = rim3dWellLogCurve->geometryGenerator(); + if (generator.isNull()) + { + generator = new Riv3dWellLogCurveGeometryGenerator(m_wellPath.p()); + rim3dWellLogCurve->setGeometryGenerator(generator.p()); + } + if (!rim3dWellLogCurve->isShowingCurve()) continue; std::vector resultValues; std::vector resultMds; rim3dWellLogCurve->curveValuesAndMds(&resultValues, &resultMds); - cvf::ref curveDrawable = - m_3dWellLogCurveGeometryGenerator->createCurveLine(displayCoordTransform, - wellPathClipBoundingBox, - resultValues, - resultMds, - rim3dWellLogCurve->minCurveValue(), - rim3dWellLogCurve->maxCurveValue(), - planeAngle(curveCollection, rim3dWellLogCurve), - wellPathCenterToPlotStartOffset(curveCollection, rim3dWellLogCurve), - planeWidth()); + generator->createCurveDrawables(displayCoordTransform, + wellPathClipBoundingBox, + resultValues, + resultMds, + rim3dWellLogCurve->minCurveValue(), + rim3dWellLogCurve->maxCurveValue(), + planeAngle(curveCollection, rim3dWellLogCurve), + wellPathCenterToPlotStartOffset(curveCollection, rim3dWellLogCurve), + planeWidth()); + + cvf::ref curveDrawable = generator->curveDrawable(); if (curveDrawable.isNull() || !curveDrawable->boundingBox().isValid()) { @@ -226,9 +231,9 @@ void Riv3dWellLogPlanePartMgr::appendGridToModel(cvf::ModelBasicList* const Rim3dWellLogCurve* rim3dWellLogCurve, double gridIntervalSize) { - const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); - bool showGrid = curveCollection->isShowingGrid(); - bool showBackground = curveCollection->isShowingBackground(); + Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); + bool showGrid = curveCollection->isShowingGrid(); + bool showBackground = curveCollection->isShowingBackground(); cvf::Color3f gridColor(0.4f, 0.4f, 0.4f); caf::SurfaceEffectGenerator backgroundEffectGen(cvf::Color4f(1.0, 1.0, 1.0, 1.0), caf::PO_2); @@ -249,12 +254,14 @@ void Riv3dWellLogPlanePartMgr::appendGridToModel(cvf::ModelBasicList* cvf::ref curveNormalsEffect = curveNormalsEffectGen.generateCachedEffect(); cvf::ref background = m_3dWellLogGridGeometryGenerator->background(); + cvf::ref sourceInfo = new RivObjectSourceInfo(curveCollection); if (showBackground && background.notNull()) { cvf::ref part = createPart(background.p(), backgroundEffect.p()); if (part.notNull()) { model->addPart(part.p()); + part->setSourceInfo(sourceInfo.p()); } } @@ -282,6 +289,7 @@ void Riv3dWellLogPlanePartMgr::appendGridToModel(cvf::ModelBasicList* if (part.notNull()) { model->addPart(part.p()); + part->setSourceInfo(sourceInfo.p()); } } } diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h index 860ddb9c9e..fa6b639612 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h @@ -20,13 +20,13 @@ #include "cvfBase.h" #include "cvfObject.h" +#include "cvfVector3.h" #include "Rim3dWellLogCurve.h" #include "Rim3dWellLogCurveCollection.h" #include "cafPdmPointer.h" -#include namespace cvf { @@ -45,7 +45,6 @@ class DisplayCoordTransform; class RimGridView; class RimWellPath; -class Riv3dWellLogCurveGeometryGenerator; class Riv3dWellLogGridGeometryGenerator; class Riv3dWellLogPlanePartMgr : public cvf::Object @@ -74,9 +73,8 @@ private: double planeWidth() const; private: - cvf::ref m_3dWellLogCurveGeometryGenerator; - cvf::ref m_3dWellLogGridGeometryGenerator; - - caf::PdmPointer m_wellPath; - caf::PdmPointer m_gridView; + cvf::ref m_3dWellLogGridGeometryGenerator; + + caf::PdmPointer m_wellPath; + caf::PdmPointer m_gridView; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp index bbe0e64ba3..fbf49270d9 100644 --- a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp @@ -24,6 +24,7 @@ #include "RimProject.h" #include "cafPdmUiDoubleSliderEditor.h" +#include "cvfMath.h" CAF_PDM_SOURCE_INIT(Rim3dWellLogCurveCollection, "Rim3dWellLogCurveCollection"); @@ -176,6 +177,36 @@ void Rim3dWellLogCurveCollection::redrawAffectedViewsAndEditors() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Rim3dWellLogCurve* Rim3dWellLogCurveCollection::checkForCurveIntersection(const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint) +{ + double smallestDistance = std::numeric_limits::max(); + Rim3dWellLogCurve* closestCurve = nullptr; + for (auto& wellLogCurve : m_3dWellLogCurves) + { + cvf::Vec3d closestPointOnCurve; + double measuredDepthAtPointOnCurve; + double valueAtPointOnCurve; + if (wellLogCurve->findClosestPointOnCurve(globalIntersection, &closestPointOnCurve, &measuredDepthAtPointOnCurve, &valueAtPointOnCurve)) + { + double distance = globalIntersection.pointDistance(closestPointOnCurve); + if (distance < smallestDistance) + { + closestCurve = wellLogCurve.p(); + *closestPoint = closestPointOnCurve; + *measuredDepthAtPoint = measuredDepthAtPointOnCurve; + *valueAtPoint = valueAtPointOnCurve; + } + } + } + return closestCurve; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h index 1a633d0478..f495e9ab0e 100644 --- a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h @@ -23,6 +23,9 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cvfBase.h" +#include "cvfVector3.h" + class Rim3dWellLogCurve; //================================================================================================== @@ -58,6 +61,10 @@ public: std::vector vectorOf3dWellLogCurves() const; void redrawAffectedViewsAndEditors(); + Rim3dWellLogCurve* checkForCurveIntersection(const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint); private: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp index 75b3f2a0a5..05218ebe85 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp @@ -19,12 +19,15 @@ #include "Rim3dWellLogCurve.h" #include "RigCurveDataTools.h" +#include "Riv3dWellLogCurveGeomertyGenerator.h" #include "Rim3dWellLogCurveCollection.h" #include "RimProject.h" #include "cafPdmUiDoubleSliderEditor.h" +#include "cvfVector3.h" + #include #include // Needed for HUGE_VAL on Linux @@ -244,6 +247,28 @@ void Rim3dWellLogCurve::resetMinMaxValuesAndUpdateUI() this->updateConnectedEditors(); } +void Rim3dWellLogCurve::setGeometryGenerator(Riv3dWellLogCurveGeometryGenerator* generator) +{ + m_geometryGenerator = generator; +} + +bool Rim3dWellLogCurve::findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint) const +{ + if (m_geometryGenerator.notNull()) + { + return m_geometryGenerator->findClosestPointOnCurve(globalIntersection, closestPoint, measuredDepthAtPoint, valueAtPoint); + } + return false; +} + +cvf::ref Rim3dWellLogCurve::geometryGenerator() +{ + return m_geometryGenerator; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h index 2702a3289a..979608b736 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h @@ -24,6 +24,11 @@ #include "cafPdmFieldCvfColor.h" +#include "cvfObject.h" +#include "cvfVector3.h" + +class Riv3dWellLogCurveGeometryGenerator; + //================================================================================================== /// /// @@ -47,17 +52,26 @@ public: void updateCurveIn3dView(); - DrawPlane drawPlane() const; - cvf::Color3f color() const; - bool isShowingCurve() const; + DrawPlane drawPlane() const; + cvf::Color3f color() const; + bool isShowingCurve() const; - virtual void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const = 0; + virtual void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const = 0; - void setColor(const cvf::Color3f& color); + void setColor(const cvf::Color3f& color); - double minCurveValue() const; - double maxCurveValue() const; - void resetMinMaxValuesAndUpdateUI(); + double minCurveValue() const; + double maxCurveValue() const; + void resetMinMaxValuesAndUpdateUI(); + bool findClosestPointOnCurve(const cvf::Vec3d& globalIntersection, + cvf::Vec3d* closestPoint, + double* measuredDepthAtPoint, + double* valueAtPoint) const; + + void setGeometryGenerator(Riv3dWellLogCurveGeometryGenerator* generator); + cvf::ref geometryGenerator(); + + protected: virtual caf::PdmFieldHandle* objectToggleField() override; virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; @@ -75,7 +89,7 @@ protected: caf::PdmField m_maxCurveValue; double m_minCurveDataValue; double m_maxCurveDataValue; - + cvf::ref m_geometryGenerator; private: caf::PdmField m_showCurve; diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.cpp b/ApplicationCode/UserInterface/RiuViewerCommands.cpp index 714ebf12f5..3d93e42fa1 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.cpp +++ b/ApplicationCode/UserInterface/RiuViewerCommands.cpp @@ -26,6 +26,7 @@ #include "RicEclipsePropertyFilterNewExec.h" #include "RicGeoMechPropertyFilterNewExec.h" #include "RicViewerEventInterface.h" +#include "WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h" #include "WellPathCommands/RicIntersectionViewerEventHandler.h" #include "WellPathCommands/RicWellPathViewerEventHandler.h" @@ -121,6 +122,10 @@ RiuViewerCommands::RiuViewerCommands(RiuViewer* ownerViewer) m_viewerEventHandlers.push_back(dynamic_cast(RicIntersectionViewerEventHandler::instance())); } + { + m_viewerEventHandlers.push_back(dynamic_cast(Ric3dWellLogCurveViewerEventHandler::instance())); + } + { m_viewerEventHandlers.push_back(dynamic_cast(RicWellPathViewerEventHandler::instance())); }