From 76bc449d1f948f967039545e1a9dfd9e16097fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Tue, 7 Feb 2017 10:52:58 +0100 Subject: [PATCH] #1161 and #1188 Fixed problems with last MSW segments. Two errors: missing last segment ID, and missing drawing the last pipe segment. --- .../RivPipeGeometryGenerator.cpp | 86 ++++++++++--------- .../RivPipeGeometryGenerator.h | 2 + .../RigSimulationWellCenterLineCalculator.cpp | 5 ++ 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp index 9ee6760972..06afe5c970 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp @@ -470,21 +470,14 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords() double squareDistanceTolerance = 1e-4*1e-4; - size_t firstSegmentWithLength = 0; - size_t i; - for (i = 0; i < m_originalPipeCenterCoords->size() - 1; i++) - { - cvf::Vec3d candidateDir = (*m_originalPipeCenterCoords)[i] - (*m_originalPipeCenterCoords)[i+1]; - double dirLengthSq = candidateDir.lengthSquared(); - if (dirLengthSq > squareDistanceTolerance && candidateDir.normalize()) - { - firstSegmentWithLength = i; - break; - } - } + const size_t lastOriginalCoordIdx = m_originalPipeCenterCoords->size() - 1; + const size_t originalSegmentCount = m_originalPipeCenterCoords->size() - 1; - // Only zero-length segments - if (i == m_originalPipeCenterCoords->size() - 1) return; + size_t firstSegmentWithLength = findFirstSegmentWithLenght(squareDistanceTolerance); + + // Return if we have only zero-length segments + + if (firstSegmentWithLength == cvf::UNDEFINED_SIZE_T) return; m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(firstSegmentWithLength)); m_filteredPipeSegmentToResult.push_back(firstSegmentWithLength); @@ -492,30 +485,37 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords() cvf::Vec3d lastValidDirectionAB; size_t lastValidSegment = 0; - for (i = firstSegmentWithLength + 1; i < m_originalPipeCenterCoords->size() - 1; i++) + // Go along the line, inserting bends, and skipping zero segments. + // The zero segments are skipped by ignoring the _first_ coordinate(s) equal to the next ones + + for (size_t coordBIdx = firstSegmentWithLength + 1; coordBIdx < lastOriginalCoordIdx; coordBIdx++) { - cvf::Vec3d coordA = m_originalPipeCenterCoords->get(i - 1); - cvf::Vec3d coordB = m_originalPipeCenterCoords->get(i + 0); - cvf::Vec3d coordC = m_originalPipeCenterCoords->get(i + 1); + cvf::Vec3d coordA = m_originalPipeCenterCoords->get(coordBIdx - 1); + cvf::Vec3d coordB = m_originalPipeCenterCoords->get(coordBIdx + 0); + cvf::Vec3d coordC = m_originalPipeCenterCoords->get(coordBIdx + 1); cvf::Vec3d directionAB = coordB - coordA; - // Skip segment lengths below tolerance if (directionAB.lengthSquared() > squareDistanceTolerance) { lastValidDirectionAB = directionAB.getNormalized(); - lastValidSegment = i; + lastValidSegment = coordBIdx; } + // Wait to store a segment until we find an endpoint that is the start point of a valid segment + cvf::Vec3d directionBC = coordC - coordB; if (directionBC.lengthSquared() < squareDistanceTolerance) { continue; } + // Check if the angle between AB and BC is sharper than m_minimumBendAngle (Straight == 180 deg) + // Sharper angle detected, insert bending stuff + double cosMinBendAngle = cvf::Math::cos(cvf::Math::toRadians(m_minimumBendAngle)); double dotProduct = lastValidDirectionAB * (-directionBC).getNormalized(); - if (dotProduct > cosMinBendAngle) + if (dotProduct > cosMinBendAngle) { bool success = false; @@ -533,42 +533,50 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords() double bendRadius = m_bendScalingFactor * m_radius + 1.0e-30; cvf::Vec3d firstIntermediate = coordB - pipeIntermediateDirection * bendRadius; + cvf::Vec3d secondIntermediate = coordB + pipeIntermediateDirection * bendRadius; m_filteredPipeCenterCoords.push_back(firstIntermediate); m_filteredPipeSegmentToResult.push_back(lastValidSegment); m_filteredPipeCenterCoords.push_back(coordB); - m_filteredPipeSegmentToResult.push_back(i); + m_filteredPipeSegmentToResult.push_back(coordBIdx); - cvf::Vec3d secondIntermediate = coordB + pipeIntermediateDirection * bendRadius; m_filteredPipeCenterCoords.push_back(secondIntermediate); - m_filteredPipeSegmentToResult.push_back(i); + m_filteredPipeSegmentToResult.push_back(coordBIdx); } else { m_filteredPipeCenterCoords.push_back(coordB); - m_filteredPipeSegmentToResult.push_back(i); + m_filteredPipeSegmentToResult.push_back(coordBIdx); } } - // Add last cross section if not duplicate coordinate - cvf::Vec3d coordA = m_originalPipeCenterCoords->get(m_originalPipeCenterCoords->size() - 2); - cvf::Vec3d coordB = m_originalPipeCenterCoords->get(m_originalPipeCenterCoords->size() - 1); - - cvf::Vec3d directionAB = coordB - coordA; - if (directionAB.lengthSquared() > squareDistanceTolerance) - { - m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(m_originalPipeCenterCoords->size() - 1)); - } - else - { - // Remove last segment as the length is below tolerance - m_filteredPipeSegmentToResult.pop_back(); - } + // Add the last point, as the above loop will not end the last none-zero segment, but wait for the start of the next valid one. + m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(lastOriginalCoordIdx)); + CVF_ASSERT(m_filteredPipeCenterCoords.size() - 1 == m_filteredPipeSegmentToResult.size()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RivPipeGeometryGenerator::findFirstSegmentWithLenght(double squareDistanceTolerance) +{ + size_t segIdx; + for ( segIdx = 0; segIdx < m_originalPipeCenterCoords->size() - 1; segIdx++ ) + { + cvf::Vec3d candidateDir = (*m_originalPipeCenterCoords)[segIdx] - (*m_originalPipeCenterCoords)[segIdx+1]; + double dirLengthSq = candidateDir.lengthSquared(); + if ( dirLengthSq > squareDistanceTolerance && candidateDir.normalize() ) + { + return segIdx; + } + } + + return cvf::UNDEFINED_SIZE_T; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h index 6865787c7b..c0aa640f30 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h @@ -63,6 +63,8 @@ private: void clearComputedData(); void updateFilteredPipeCenterCoords(); + size_t findFirstSegmentWithLenght(double squareDistanceTolerance); + static void computeCircle(double radius, size_t tesselationCount, const cvf::Vec3d& center, const cvf::Vec3d& orient1, const cvf::Vec3d& orient2, std::vector* nodes); static cvf::ref generateLine(const cvf::Vec3dArray* coords); diff --git a/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp index e8b6d0d5d5..859b2e8806 100644 --- a/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp +++ b/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp @@ -380,6 +380,11 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellF cvf::Vec3d centerLastCell = prevCell.center(); finishPipeCenterLine(pipeBranchesCLCoords, centerLastCell); } + else if (prevWellResPoint && prevWellResPoint->isPointValid()) + { + // Continue the line with the same point, just to keep the last Cell ID + pipeBranchesCLCoords.back().push_back(prevWellResPoint->m_bottomPosition); + } else { // Remove the ID that is superfluous since we will not add an ending point