mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3695 Well path creation : Crash when creating a vertical well
Caused by two identical reference points next to each other
This commit is contained in:
@@ -17,16 +17,15 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "RiaPolyArcLineSampler.h"
|
#include "RiaPolyArcLineSampler.h"
|
||||||
#include "cvfGeometryTools.h"
|
|
||||||
#include "cvfMatrix4.h"
|
|
||||||
#include "RiaArcCurveCalculator.h"
|
#include "RiaArcCurveCalculator.h"
|
||||||
|
|
||||||
|
#include "cvfGeometryTools.h"
|
||||||
|
#include "cvfMatrix4.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
RiaPolyArcLineSampler::RiaPolyArcLineSampler(const cvf::Vec3d& startTangent,
|
RiaPolyArcLineSampler::RiaPolyArcLineSampler(const cvf::Vec3d& startTangent, const std::vector<cvf::Vec3d>& lineArcEndPoints)
|
||||||
const std::vector<cvf::Vec3d>& lineArcEndPoints)
|
|
||||||
: m_startTangent(startTangent)
|
: m_startTangent(startTangent)
|
||||||
, m_lineArcEndPoints(lineArcEndPoints)
|
, m_lineArcEndPoints(lineArcEndPoints)
|
||||||
, m_samplingsInterval(0.15)
|
, m_samplingsInterval(0.15)
|
||||||
@@ -35,7 +34,6 @@ RiaPolyArcLineSampler::RiaPolyArcLineSampler(const cvf::Vec3d& startTangent,
|
|||||||
, m_points(nullptr)
|
, m_points(nullptr)
|
||||||
, m_meshDs(nullptr)
|
, m_meshDs(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -56,26 +54,28 @@ void RiaPolyArcLineSampler::sampledPointsAndMDs(double sampleInterval,
|
|||||||
points->clear();
|
points->clear();
|
||||||
mds->clear();
|
mds->clear();
|
||||||
|
|
||||||
if (m_lineArcEndPoints.size() < 2) return ;
|
std::vector<cvf::Vec3d> pointsNoDuplicates = RiaPolyArcLineSampler::pointsWithoutDuplicates(m_lineArcEndPoints);
|
||||||
|
|
||||||
|
if (pointsNoDuplicates.size() < 2) return;
|
||||||
|
|
||||||
m_points = points;
|
m_points = points;
|
||||||
m_meshDs = mds;
|
m_meshDs = mds;
|
||||||
m_totalMD = startMD;
|
m_totalMD = startMD;
|
||||||
|
|
||||||
cvf::Vec3d p1 = m_lineArcEndPoints[0];
|
cvf::Vec3d p1 = pointsNoDuplicates[0];
|
||||||
cvf::Vec3d p2 = m_lineArcEndPoints[1];
|
cvf::Vec3d p2 = pointsNoDuplicates[1];
|
||||||
|
|
||||||
m_points->push_back(p1);
|
m_points->push_back(p1);
|
||||||
m_meshDs->push_back(m_totalMD);
|
m_meshDs->push_back(m_totalMD);
|
||||||
|
|
||||||
cvf::Vec3d t2 = m_startTangent;
|
cvf::Vec3d t2 = m_startTangent;
|
||||||
|
|
||||||
for (size_t pIdx = 0; pIdx < m_lineArcEndPoints.size() - 1 ; ++pIdx)
|
for (size_t pIdx = 0; pIdx < pointsNoDuplicates.size() - 1; ++pIdx)
|
||||||
{
|
{
|
||||||
sampleSegment(t2, m_lineArcEndPoints[pIdx], m_lineArcEndPoints[pIdx + 1] , &t2);
|
sampleSegment(t2, pointsNoDuplicates[pIdx], pointsNoDuplicates[pIdx + 1], &t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@@ -85,7 +85,7 @@ void RiaPolyArcLineSampler::sampleSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec
|
|||||||
{
|
{
|
||||||
cvf::Vec3d p1p2 = p2 - p1;
|
cvf::Vec3d p1p2 = p2 - p1;
|
||||||
|
|
||||||
CVF_ASSERT (p1p2.lengthSquared() > 1e-20);
|
CVF_ASSERT(p1p2.lengthSquared() > 1e-20);
|
||||||
|
|
||||||
if (cvf::GeometryTools::getAngle(t1, p1p2) < 1e-5)
|
if (cvf::GeometryTools::getAngle(t1, p1p2) < 1e-5)
|
||||||
{
|
{
|
||||||
@@ -100,16 +100,37 @@ void RiaPolyArcLineSampler::sampleSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RiaPolyArcLineSampler::sampleLine(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent )
|
std::vector<cvf::Vec3d> RiaPolyArcLineSampler::pointsWithoutDuplicates(const std::vector<cvf::Vec3d>& points)
|
||||||
|
{
|
||||||
|
std::vector<cvf::Vec3d> outputPoints;
|
||||||
|
|
||||||
|
cvf::Vec3d previousPoint = cvf::Vec3d::UNDEFINED;
|
||||||
|
const double threshold = 1e-6;
|
||||||
|
for (const auto& p : points)
|
||||||
|
{
|
||||||
|
if (previousPoint.isUndefined() || ((previousPoint - p).lengthSquared()) > threshold)
|
||||||
|
{
|
||||||
|
outputPoints.push_back(p);
|
||||||
|
previousPoint = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RiaPolyArcLineSampler::sampleLine(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent)
|
||||||
{
|
{
|
||||||
cvf::Vec3d p1p2 = p2 - p1;
|
cvf::Vec3d p1p2 = p2 - p1;
|
||||||
|
|
||||||
double p1p2Length = p1p2.length();
|
double p1p2Length = p1p2.length();
|
||||||
if ( p1p2Length > m_samplingsInterval && m_isResamplingLines )
|
if (p1p2Length > m_samplingsInterval && m_isResamplingLines)
|
||||||
{
|
{
|
||||||
cvf::Vec3d tp1p2 = p1p2 / p1p2Length;
|
cvf::Vec3d tp1p2 = p1p2 / p1p2Length;
|
||||||
double mdInc = m_samplingsInterval;
|
double mdInc = m_samplingsInterval;
|
||||||
while ( mdInc < p1p2Length )
|
while (mdInc < p1p2Length)
|
||||||
{
|
{
|
||||||
cvf::Vec3d ps = p1 + mdInc * tp1p2;
|
cvf::Vec3d ps = p1 + mdInc * tp1p2;
|
||||||
m_points->push_back(ps);
|
m_points->push_back(ps);
|
||||||
@@ -135,7 +156,7 @@ void RiaPolyArcLineSampler::sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p
|
|||||||
double radius = CS_rad.radius();
|
double radius = CS_rad.radius();
|
||||||
cvf::Mat4d arcCS = CS_rad.arcCS();
|
cvf::Mat4d arcCS = CS_rad.arcCS();
|
||||||
|
|
||||||
double angleInc = m_samplingsInterval/ radius;
|
double angleInc = m_samplingsInterval / radius;
|
||||||
|
|
||||||
cvf::Vec3d C = CS_rad.center();
|
cvf::Vec3d C = CS_rad.center();
|
||||||
cvf::Vec3d N = CS_rad.normal();
|
cvf::Vec3d N = CS_rad.normal();
|
||||||
@@ -144,12 +165,12 @@ void RiaPolyArcLineSampler::sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p
|
|||||||
// Rotate vector an increment, and transform to arc CS
|
// Rotate vector an increment, and transform to arc CS
|
||||||
|
|
||||||
double arcAngle = cvf::GeometryTools::getAngle(N, p1 - C, p2 - C);
|
double arcAngle = cvf::GeometryTools::getAngle(N, p1 - C, p2 - C);
|
||||||
if (arcAngle/angleInc > 5000)
|
if (arcAngle / angleInc > 5000)
|
||||||
{
|
{
|
||||||
angleInc = arcAngle/5000;
|
angleInc = arcAngle / 5000;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( double angle = angleInc; angle < arcAngle; angle += angleInc )
|
for (double angle = angleInc; angle < arcAngle; angle += angleInc)
|
||||||
{
|
{
|
||||||
cvf::Vec3d C_to_incP = cvf::Vec3d::X_AXIS;
|
cvf::Vec3d C_to_incP = cvf::Vec3d::X_AXIS;
|
||||||
C_to_incP *= radius;
|
C_to_incP *= radius;
|
||||||
@@ -159,9 +180,8 @@ void RiaPolyArcLineSampler::sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p
|
|||||||
|
|
||||||
m_points->push_back(C_to_incP);
|
m_points->push_back(C_to_incP);
|
||||||
m_meshDs->push_back(m_totalMD + angle * radius);
|
m_meshDs->push_back(m_totalMD + angle * radius);
|
||||||
|
|
||||||
}
|
}
|
||||||
m_totalMD += arcAngle*radius;
|
m_totalMD += arcAngle * radius;
|
||||||
m_points->push_back(p2);
|
m_points->push_back(p2);
|
||||||
m_meshDs->push_back(m_totalMD);
|
m_meshDs->push_back(m_totalMD);
|
||||||
|
|
||||||
|
|||||||
@@ -25,15 +25,15 @@
|
|||||||
class RiaPolyArcLineSampler
|
class RiaPolyArcLineSampler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RiaPolyArcLineSampler(const cvf::Vec3d& startTangent,
|
RiaPolyArcLineSampler(const cvf::Vec3d& startTangent, const std::vector<cvf::Vec3d>& lineArcEndPoints);
|
||||||
const std::vector<cvf::Vec3d>& lineArcEndPoints);
|
|
||||||
|
|
||||||
|
|
||||||
void sampledPointsAndMDs(double sampleInterval,
|
void sampledPointsAndMDs(double sampleInterval,
|
||||||
bool isResamplingLines,
|
bool isResamplingLines,
|
||||||
std::vector<cvf::Vec3d>* points,
|
std::vector<cvf::Vec3d>* points,
|
||||||
std::vector<double>* mds);
|
std::vector<double>* mds);
|
||||||
|
|
||||||
|
static std::vector<cvf::Vec3d> pointsWithoutDuplicates(const std::vector<cvf::Vec3d>& points);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sampleLine(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
|
void sampleLine(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
|
||||||
void sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
|
void sampleArc(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
|
||||||
@@ -49,4 +49,3 @@ private:
|
|||||||
cvf::Vec3d m_startTangent;
|
cvf::Vec3d m_startTangent;
|
||||||
std::vector<cvf::Vec3d> m_lineArcEndPoints;
|
std::vector<cvf::Vec3d> m_lineArcEndPoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,22 +6,22 @@
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
TEST(RiaPolyArcLineSampler, Basic)
|
TEST(RiaPolyArcLineSampler, Basic)
|
||||||
{
|
{
|
||||||
std::vector<cvf::Vec3d> points { {0,0,0}, {0,0,-10}, {0,10,-20},{0,20,-20}, {0,30, -30} };
|
std::vector<cvf::Vec3d> points{{0, 0, 0}, {0, 0, -10}, {0, 10, -20}, {0, 20, -20}, {0, 30, -30}};
|
||||||
|
|
||||||
RiaPolyArcLineSampler sampler({0,0,-1}, points);
|
RiaPolyArcLineSampler sampler({0, 0, -1}, points);
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> sampledPoints;
|
std::vector<cvf::Vec3d> sampledPoints;
|
||||||
std::vector<double> mds;
|
std::vector<double> mds;
|
||||||
|
|
||||||
sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds);
|
sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds);
|
||||||
#if 0
|
#if 0
|
||||||
for (size_t pIdx = 0; pIdx < sampledPoints.size(); ++pIdx)
|
for (size_t pIdx = 0; pIdx < sampledPoints.size(); ++pIdx)
|
||||||
{
|
{
|
||||||
std::cout << sampledPoints[pIdx].x() << " "
|
std::cout << sampledPoints[pIdx].x() << " "
|
||||||
<< sampledPoints[pIdx].y() << " "
|
<< sampledPoints[pIdx].y() << " "
|
||||||
<< sampledPoints[pIdx].z() << " md: " << mds[pIdx] << std::endl;
|
<< sampledPoints[pIdx].z() << " md: " << mds[pIdx] << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EXPECT_EQ(27, (int)sampledPoints.size());
|
EXPECT_EQ(27, (int)sampledPoints.size());
|
||||||
EXPECT_NEAR(51.4159, mds.back(), 1e-4);
|
EXPECT_NEAR(51.4159, mds.back(), 1e-4);
|
||||||
|
|
||||||
@@ -31,3 +31,47 @@ TEST(RiaPolyArcLineSampler, Basic)
|
|||||||
EXPECT_NEAR(points[4].y(), sampledPoints[25].y(), 2);
|
EXPECT_NEAR(points[4].y(), sampledPoints[25].y(), 2);
|
||||||
EXPECT_NEAR(points[4].z(), sampledPoints[25].z(), 2);
|
EXPECT_NEAR(points[4].z(), sampledPoints[25].z(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RiaPolyArcLineSampler, TestInvalidInput)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Two identical points after each other
|
||||||
|
std::vector<cvf::Vec3d> points{{0, 0, -20}, {0, 0, -20}};
|
||||||
|
|
||||||
|
RiaPolyArcLineSampler sampler({0, 0, -1}, points);
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> sampledPoints;
|
||||||
|
std::vector<double> mds;
|
||||||
|
|
||||||
|
sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, (int)sampledPoints.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::vector<cvf::Vec3d> points;
|
||||||
|
|
||||||
|
RiaPolyArcLineSampler sampler({0, 0, -1}, points);
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> sampledPoints;
|
||||||
|
std::vector<double> mds;
|
||||||
|
|
||||||
|
sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, (int)sampledPoints.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::vector<cvf::Vec3d> points{{0, 0, 0}};
|
||||||
|
|
||||||
|
RiaPolyArcLineSampler sampler({0, 0, -1}, points);
|
||||||
|
|
||||||
|
std::vector<cvf::Vec3d> sampledPoints;
|
||||||
|
std::vector<double> mds;
|
||||||
|
|
||||||
|
sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, (int)sampledPoints.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user