mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 07:00:17 -05:00
Pipe geometry: Skip non-finite coords and degenerate cylinder segments
Robustness fixes in RivPipeGeometryGenerator: - updateFilteredPipeCenterCoords: drop NaN/Inf input coords. The main loop now skips iterations where any of the three sampled coords is undefined, and the trailing endpoint walks back to the last finite coord so the segment-to-result bookkeeping invariant holds. - computeExtrudedCoordsAndNormals: stop asserting on parallel plane/ray intersections (these can occur at very sharp bends due to numerical issues) and return early when the extruded node count does not match the expected cross-section node count.
This commit is contained in:
1 parent
bac0249e6a
commit
498c6be663
1 file changed
+19
-6
@@ -604,14 +604,16 @@ void RivPipeGeometryGenerator::computeExtrudedCoordsAndNormals( cvf::Vec3d
|
||||
{
|
||||
nextExtrudedNodes.push_back( intersection );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parallel plane and ray
|
||||
CVF_ASSERT( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( nextExtrudedNodes.size() != crossSectionNodeCount )
|
||||
{
|
||||
// This should not happen, but if it does, we just skip the segment. This can happen for very sharp bends where the intersection
|
||||
// plane is almost parallel to the ray direction, and numerical issues can cause us to miss the intersection.
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the normals for the cylinder segment
|
||||
|
||||
cvf::Plane cylinderPlane;
|
||||
@@ -662,6 +664,10 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords()
|
||||
cvf::Vec3d coordB = m_originalPipeCenterCoords->get( coordBIdx + 0 );
|
||||
cvf::Vec3d coordC = m_originalPipeCenterCoords->get( coordBIdx + 1 );
|
||||
|
||||
// Skip non-finite coords; treat as zero-length so they neither update
|
||||
// lastValidDirectionAB nor get pushed to the filtered list.
|
||||
if ( coordA.isUndefined() || coordB.isUndefined() || coordC.isUndefined() ) continue;
|
||||
|
||||
cvf::Vec3d directionAB = coordB - coordA;
|
||||
|
||||
if ( directionAB.lengthSquared() > squareDistanceTolerance )
|
||||
@@ -722,7 +728,14 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords()
|
||||
// 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 ) );
|
||||
// Walk backwards to the last finite coord. The loop pre-pushes a segment-to-result entry for the
|
||||
// upcoming endpoint, so we must push one finite coord here to keep the assert below in sync.
|
||||
size_t lastFiniteIdx = lastOriginalCoordIdx;
|
||||
while ( lastFiniteIdx > firstSegmentWithLength && m_originalPipeCenterCoords->get( lastFiniteIdx ).isUndefined() )
|
||||
{
|
||||
--lastFiniteIdx;
|
||||
}
|
||||
m_filteredPipeCenterCoords.push_back( m_originalPipeCenterCoords->get( lastFiniteIdx ) );
|
||||
|
||||
CVF_ASSERT( m_filteredPipeCenterCoords.size() - 1 == m_filteredPipeSegmentToResult.size() );
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user