#1161 and #1188 Fixed problems with last MSW segments. Two errors: missing last segment ID, and missing drawing the last pipe segment.

This commit is contained in:
Jacob Støren 2017-02-07 10:52:58 +01:00
parent 94a90c8796
commit 76bc449d1f
3 changed files with 54 additions and 39 deletions

View File

@ -470,21 +470,14 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords()
double squareDistanceTolerance = 1e-4*1e-4; double squareDistanceTolerance = 1e-4*1e-4;
size_t firstSegmentWithLength = 0; const size_t lastOriginalCoordIdx = m_originalPipeCenterCoords->size() - 1;
size_t i; const size_t originalSegmentCount = m_originalPipeCenterCoords->size() - 1;
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;
}
}
// Only zero-length segments size_t firstSegmentWithLength = findFirstSegmentWithLenght(squareDistanceTolerance);
if (i == m_originalPipeCenterCoords->size() - 1) return;
// Return if we have only zero-length segments
if (firstSegmentWithLength == cvf::UNDEFINED_SIZE_T) return;
m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(firstSegmentWithLength)); m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(firstSegmentWithLength));
m_filteredPipeSegmentToResult.push_back(firstSegmentWithLength); m_filteredPipeSegmentToResult.push_back(firstSegmentWithLength);
@ -492,30 +485,37 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords()
cvf::Vec3d lastValidDirectionAB; cvf::Vec3d lastValidDirectionAB;
size_t lastValidSegment = 0; 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 coordA = m_originalPipeCenterCoords->get(coordBIdx - 1);
cvf::Vec3d coordB = m_originalPipeCenterCoords->get(i + 0); cvf::Vec3d coordB = m_originalPipeCenterCoords->get(coordBIdx + 0);
cvf::Vec3d coordC = m_originalPipeCenterCoords->get(i + 1); cvf::Vec3d coordC = m_originalPipeCenterCoords->get(coordBIdx + 1);
cvf::Vec3d directionAB = coordB - coordA; cvf::Vec3d directionAB = coordB - coordA;
// Skip segment lengths below tolerance
if (directionAB.lengthSquared() > squareDistanceTolerance) if (directionAB.lengthSquared() > squareDistanceTolerance)
{ {
lastValidDirectionAB = directionAB.getNormalized(); 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; cvf::Vec3d directionBC = coordC - coordB;
if (directionBC.lengthSquared() < squareDistanceTolerance) if (directionBC.lengthSquared() < squareDistanceTolerance)
{ {
continue; 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 cosMinBendAngle = cvf::Math::cos(cvf::Math::toRadians(m_minimumBendAngle));
double dotProduct = lastValidDirectionAB * (-directionBC).getNormalized(); double dotProduct = lastValidDirectionAB * (-directionBC).getNormalized();
if (dotProduct > cosMinBendAngle) if (dotProduct > cosMinBendAngle)
{ {
bool success = false; bool success = false;
@ -533,42 +533,50 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords()
double bendRadius = m_bendScalingFactor * m_radius + 1.0e-30; double bendRadius = m_bendScalingFactor * m_radius + 1.0e-30;
cvf::Vec3d firstIntermediate = coordB - pipeIntermediateDirection * bendRadius; cvf::Vec3d firstIntermediate = coordB - pipeIntermediateDirection * bendRadius;
cvf::Vec3d secondIntermediate = coordB + pipeIntermediateDirection * bendRadius;
m_filteredPipeCenterCoords.push_back(firstIntermediate); m_filteredPipeCenterCoords.push_back(firstIntermediate);
m_filteredPipeSegmentToResult.push_back(lastValidSegment); m_filteredPipeSegmentToResult.push_back(lastValidSegment);
m_filteredPipeCenterCoords.push_back(coordB); 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_filteredPipeCenterCoords.push_back(secondIntermediate);
m_filteredPipeSegmentToResult.push_back(i); m_filteredPipeSegmentToResult.push_back(coordBIdx);
} }
else else
{ {
m_filteredPipeCenterCoords.push_back(coordB); m_filteredPipeCenterCoords.push_back(coordB);
m_filteredPipeSegmentToResult.push_back(i); m_filteredPipeSegmentToResult.push_back(coordBIdx);
} }
} }
// Add last cross section if not duplicate coordinate // 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.
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();
}
m_filteredPipeCenterCoords.push_back(m_originalPipeCenterCoords->get(lastOriginalCoordIdx));
CVF_ASSERT(m_filteredPipeCenterCoords.size() - 1 == m_filteredPipeSegmentToResult.size()); 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;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -63,6 +63,8 @@ private:
void clearComputedData(); void clearComputedData();
void updateFilteredPipeCenterCoords(); 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<cvf::Vec3d>* nodes); static void computeCircle(double radius, size_t tesselationCount, const cvf::Vec3d& center, const cvf::Vec3d& orient1, const cvf::Vec3d& orient2, std::vector<cvf::Vec3d>* nodes);
static cvf::ref<cvf::DrawableGeo> generateLine(const cvf::Vec3dArray* coords); static cvf::ref<cvf::DrawableGeo> generateLine(const cvf::Vec3dArray* coords);

View File

@ -380,6 +380,11 @@ void RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellF
cvf::Vec3d centerLastCell = prevCell.center(); cvf::Vec3d centerLastCell = prevCell.center();
finishPipeCenterLine(pipeBranchesCLCoords, centerLastCell); 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 else
{ {
// Remove the ID that is superfluous since we will not add an ending point // Remove the ID that is superfluous since we will not add an ending point