From b48adbbaa947b0040e58f61a7ca642618d996634 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Fri, 13 Apr 2018 14:36:37 +0200 Subject: [PATCH] 3D Well log curves: Use the new generalized interpolation for normals * Don't have to perform the normal generation again for grid points. --- .../Riv3dWellLogCurveGeomertyGenerator.cpp | 16 +++-- .../Riv3dWellLogGridGeomertyGenerator.cpp | 58 ++++++++----------- .../RigWellPathGeometryTools.cpp | 50 +++------------- .../RigWellPathGeometryTools.h | 8 +-- 4 files changed, 41 insertions(+), 91 deletions(-) diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp index 31e59abfe0..b26f00f647 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeomertyGenerator.cpp @@ -113,15 +113,19 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance; } - std::vector interpolatedWellPathPoints; + std::vector wellPathNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle); + std::vector interpolatedWellPathPoints; + std::vector interpolatedNormals; // Iterate from bottom of well path and up to be able to stop at given Z max clipping height for (auto md = resultMds.rbegin(); md != resultMds.rend(); md++) { cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(*md); + cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathNormals, *md); if (point.z() > maxZClipHeight) break; interpolatedWellPathPoints.push_back(point); + interpolatedNormals.push_back(normal.getNormalized()); } if (interpolatedWellPathPoints.empty()) return; @@ -132,12 +136,6 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std std::vector resultValuesForInterpolatedPoints(resultValues.end() - interpolatedWellPathPoints.size(), resultValues.end()); - std::vector pairsOfWellPathPoints; - RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(wellPathGeometry(), interpolatedWellPathPoints, &pairsOfWellPathPoints); - - std::vector pointNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, pairsOfWellPathPoints, RigWellPathGeometryTools::LINE_SEGMENTS); - if (interpolatedWellPathPoints.size() != pointNormals.size()) return; - double maxResult = -HUGE_VAL; double minResult = HUGE_VAL; @@ -153,7 +151,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std double plotRangeToResultRangeFactor = planeWidth / (maxResult - minResult); - for (size_t i = 0; i < pointNormals.size(); i++) + for (size_t i = 0; i < interpolatedNormals.size(); i++) { double scaledResult = 0; @@ -164,7 +162,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std } (*vertices)[i] = cvf::Vec3f( - displayCoordTransform->transformToDisplayCoord(interpolatedWellPathPoints[i] + scaledResult * pointNormals[i])); + displayCoordTransform->transformToDisplayCoord(interpolatedWellPathPoints[i] + scaledResult * interpolatedNormals[i])); } std::vector> valuesIntervals = diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogGridGeomertyGenerator.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogGridGeomertyGenerator.cpp index dea144f13c..96bfee9e79 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogGridGeomertyGenerator.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogGridGeomertyGenerator.cpp @@ -92,42 +92,17 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform* std::map< DrawableId, cvf::ref > drawables; - std::vector gridPoints; - - size_t newStartIndex = originalWellPathSize - wellPathPoints.size(); - double firstMd = wellPathGeometry()->m_measuredDepths.at(newStartIndex); - double lastMd = wellPathGeometry()->m_measuredDepths.back(); - - double md = lastMd; - while (md >= firstMd) - { - cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(md); - gridPoints.push_back(point); - md -= gridIntervalSize; - } - - std::vector pointNormals; - - std::vector closestPoints; - RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(wellPathGeometry(), gridPoints, &closestPoints); - - pointNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, closestPoints, RigWellPathGeometryTools::LINE_SEGMENTS); - if (pointNormals.size() != gridPoints.size()) - { - return std::map< DrawableId, cvf::ref >(); - } - // calculateLineSegmentNormals returns normals for the whole well path. Erase the part which is clipped off std::vector wellPathSegmentNormals = - RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, wellPathGeometry()->m_wellPathPoints, RigWellPathGeometryTools::POLYLINE); + RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle); wellPathSegmentNormals.erase(wellPathSegmentNormals.begin(), wellPathSegmentNormals.end() - wellPathPoints.size()); { std::vector vertices; - vertices.reserve(gridPoints.size()); + vertices.reserve(wellPathPoints.size()); std::vector indices; - indices.reserve(gridPoints.size()); + indices.reserve(wellPathPoints.size()); cvf::uint indexCounter = 0; // Line along and close to well for (size_t i = 0; i < wellPathPoints.size(); i++) @@ -162,20 +137,37 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform* drawables[GridBorder] = gridBorderDrawable; } { + std::vector interpolatedGridPoints; + std::vector interpolatedGridNormals; + + size_t newStartIndex = originalWellPathSize - wellPathPoints.size(); + double firstMd = wellPathGeometry()->m_measuredDepths.at(newStartIndex); + double lastMd = wellPathGeometry()->m_measuredDepths.back(); + + double md = lastMd; + while (md >= firstMd) + { + cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(md); + cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathSegmentNormals, md); + interpolatedGridPoints.push_back(point); + interpolatedGridNormals.push_back(normal.getNormalized()); + md -= gridIntervalSize; + } + std::vector vertices; - vertices.reserve(gridPoints.size()); + vertices.reserve(interpolatedGridPoints.size()); std::vector indices; - indices.reserve(gridPoints.size()); + indices.reserve(interpolatedGridPoints.size()); cvf::uint indexCounter = 0; // Normal lines. Start from one to avoid drawing at surface edge. - for (size_t i = 1; i < pointNormals.size(); i++) + for (size_t i = 1; i < interpolatedGridNormals.size(); i++) { vertices.push_back(cvf::Vec3f( - displayCoordTransform->transformToDisplayCoord(gridPoints[i] + pointNormals[i] * planeOffsetFromWellPathCenter))); + displayCoordTransform->transformToDisplayCoord(interpolatedGridPoints[i] + interpolatedGridNormals[i] * planeOffsetFromWellPathCenter))); vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord( - gridPoints[i] + pointNormals[i] * (planeOffsetFromWellPathCenter + planeWidth)))); + interpolatedGridPoints[i] + interpolatedGridNormals[i] * (planeOffsetFromWellPathCenter + planeWidth)))); indices.push_back(indexCounter++); indices.push_back(indexCounter++); diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp b/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp index 95e0ca09fb..f375dc2bcb 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp @@ -30,37 +30,27 @@ /// //-------------------------------------------------------------------------------------------------- std::vector RigWellPathGeometryTools::calculateLineSegmentNormals(const RigWellPath* wellPathGeometry, - double planeAngle, - const std::vector& vertices, - VertexOrganization organization) + double planeAngle) { std::vector pointNormals; if (!wellPathGeometry) return pointNormals; + + const std::vector& vertices = wellPathGeometry->wellPathPoints(); + if (vertices.empty()) return pointNormals; + pointNormals.reserve(vertices.size()); + cvf::Vec3d up(0, 0, 1); - // Project onto normal plane cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(wellPathGeometry); const cvf::Vec3d projectionPlaneNormal = (up ^ dominantDirection).getNormalized(); CVF_ASSERT(projectionPlaneNormal * dominantDirection <= std::numeric_limits::epsilon()); - size_t intervalSize; - if (organization == LINE_SEGMENTS) - { - pointNormals.reserve(vertices.size() / 2); - intervalSize = 2; - } - else // organization == POLYLINE - { - pointNormals.reserve(vertices.size()); - intervalSize = 1; - } - cvf::Vec3d lastNormal; - for (size_t i = 0; i < vertices.size() - 1; i += intervalSize) + for (size_t i = 0; i < vertices.size() - 1; ++i) { cvf::Vec3d p1 = vertices[i]; cvf::Vec3d p2 = vertices[i + 1]; @@ -77,35 +67,11 @@ std::vector RigWellPathGeometryTools::calculateLineSegmentNormals(co lastNormal = normal; } - if (organization == POLYLINE) - { - pointNormals.push_back(lastNormal); - } + pointNormals.push_back(lastNormal); return interpolateUndefinedNormals(up, pointNormals, vertices); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(const RigWellPath* wellPathGeometry, - const std::vector& points, - std::vector* closestWellPathPoints) -{ - CVF_ASSERT(closestWellPathPoints != nullptr); - - for (const cvf::Vec3d point : points) - { - cvf::Vec3d p1 = cvf::Vec3d::UNDEFINED; - cvf::Vec3d p2 = cvf::Vec3d::UNDEFINED; - wellPathGeometry->twoClosestPoints(point, &p1, &p2); - if (p1.isUndefined() || p2.isUndefined()) continue; - - closestWellPathPoints->push_back(p1); - closestWellPathPoints->push_back(p2); - } -} - std::vector RigWellPathGeometryTools::interpolateUndefinedNormals(const cvf::Vec3d& planeNormal, const std::vector& normals, const std::vector& vertices) diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.h b/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.h index d1b26dd6ef..17cd410a79 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.h +++ b/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.h @@ -39,13 +39,7 @@ public: public: static std::vector calculateLineSegmentNormals(const RigWellPath* wellPathGeometry, - double angle, - const std::vector& vertices, - VertexOrganization organization); - - static void calculatePairsOfClosestSamplingPointsAlongWellPath(const RigWellPath* wellPathGeometry, - const std::vector& points, - std::vector* closestWellPathPoints); + double angle); private: static std::vector interpolateUndefinedNormals(const cvf::Vec3d& planeNormal, const std::vector& normals,