2018-07-02 07:47:56 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2019-01-09 08:15:34 -06:00
|
|
|
// Copyright (C) 2018- Equinor ASA
|
2018-11-16 01:43:19 -06:00
|
|
|
//
|
2018-07-02 07:47:56 -05:00
|
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
2018-11-16 01:43:19 -06:00
|
|
|
//
|
2018-07-02 07:47:56 -05:00
|
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
2018-11-16 01:43:19 -06:00
|
|
|
//
|
|
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
2018-07-02 07:47:56 -05:00
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "RiaPolyArcLineSampler.h"
|
2018-09-24 08:48:16 -05:00
|
|
|
#include "RiaArcCurveCalculator.h"
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
#include "cvfGeometryTools.h"
|
|
|
|
#include "cvfMatrix4.h"
|
2018-07-02 07:47:56 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-11-16 01:43:19 -06:00
|
|
|
///
|
2018-07-02 07:47:56 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
RiaPolyArcLineSampler::RiaPolyArcLineSampler( const cvf::Vec3d& startTangent,
|
|
|
|
const std::vector<cvf::Vec3d>& lineArcEndPoints )
|
|
|
|
: m_startTangent( startTangent )
|
|
|
|
, m_lineArcEndPoints( lineArcEndPoints )
|
2019-11-14 10:05:10 -06:00
|
|
|
, m_maxSamplingsInterval( 0.15 )
|
2019-09-06 03:40:57 -05:00
|
|
|
, m_isResamplingLines( true )
|
|
|
|
, m_totalMD( 0.0 )
|
|
|
|
, m_points( nullptr )
|
|
|
|
, m_meshDs( nullptr )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-11-16 01:43:19 -06:00
|
|
|
///
|
2018-07-02 07:47:56 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiaPolyArcLineSampler::sampledPointsAndMDs( double sampleInterval,
|
|
|
|
bool isResamplingLines,
|
|
|
|
std::vector<cvf::Vec3d>* points,
|
|
|
|
std::vector<double>* mds )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
CVF_ASSERT( sampleInterval > 0.0 );
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-11-14 10:05:10 -06:00
|
|
|
m_maxSamplingsInterval = sampleInterval;
|
2019-11-19 04:08:59 -06:00
|
|
|
m_isResamplingLines = isResamplingLines;
|
2018-07-02 07:47:56 -05:00
|
|
|
|
|
|
|
double startMD = 0.0;
|
|
|
|
points->clear();
|
|
|
|
mds->clear();
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
std::vector<cvf::Vec3d> pointsNoDuplicates = RiaPolyArcLineSampler::pointsWithoutDuplicates( m_lineArcEndPoints );
|
2018-11-16 01:43:19 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( pointsNoDuplicates.size() < 2 ) return;
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
m_points = points;
|
|
|
|
m_meshDs = mds;
|
2018-07-02 07:47:56 -05:00
|
|
|
m_totalMD = startMD;
|
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
cvf::Vec3d p1 = pointsNoDuplicates[0];
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
m_points->push_back( p1 );
|
|
|
|
m_meshDs->push_back( m_totalMD );
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
cvf::Vec3d t2 = m_startTangent;
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
for ( size_t pIdx = 0; pIdx < pointsNoDuplicates.size() - 1; ++pIdx )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
sampleSegment( t2, pointsNoDuplicates[pIdx], pointsNoDuplicates[pIdx + 1], &t2 );
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
return;
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-11-16 01:43:19 -06:00
|
|
|
///
|
2018-07-02 07:47:56 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiaPolyArcLineSampler::sampleSegment( cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
cvf::Vec3d p1p2 = p2 - p1;
|
2018-11-16 01:43:19 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
CVF_ASSERT( p1p2.lengthSquared() > 1e-20 );
|
2018-09-24 08:31:58 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( cvf::GeometryTools::getAngle( t1, p1p2 ) < 1e-5 )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
sampleLine( p1, p2, endTangent );
|
2018-11-16 01:43:19 -06:00
|
|
|
}
|
2018-07-02 07:47:56 -05:00
|
|
|
else // resample arc
|
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
sampleArc( t1, p1, p2, endTangent );
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-11-16 01:43:19 -06:00
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
std::vector<cvf::Vec3d> RiaPolyArcLineSampler::pointsWithoutDuplicates( const std::vector<cvf::Vec3d>& points )
|
2018-11-16 01:43:19 -06:00
|
|
|
{
|
|
|
|
std::vector<cvf::Vec3d> outputPoints;
|
|
|
|
|
|
|
|
cvf::Vec3d previousPoint = cvf::Vec3d::UNDEFINED;
|
|
|
|
const double threshold = 1e-6;
|
2019-09-06 03:40:57 -05:00
|
|
|
for ( const auto& p : points )
|
2018-11-16 01:43:19 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
if ( previousPoint.isUndefined() || ( ( previousPoint - p ).lengthSquared() ) > threshold )
|
2018-11-16 01:43:19 -06:00
|
|
|
{
|
2019-09-06 03:40:57 -05:00
|
|
|
outputPoints.push_back( p );
|
2018-11-16 01:43:19 -06:00
|
|
|
previousPoint = p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputPoints;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
2018-07-02 07:47:56 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiaPolyArcLineSampler::sampleLine( cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
cvf::Vec3d p1p2 = p2 - p1;
|
|
|
|
|
|
|
|
double p1p2Length = p1p2.length();
|
2019-11-14 10:05:10 -06:00
|
|
|
|
|
|
|
if ( m_isResamplingLines && p1p2Length > m_maxSamplingsInterval )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
cvf::Vec3d tp1p2 = p1p2 / p1p2Length;
|
2019-11-14 10:05:10 -06:00
|
|
|
double mdInc = m_maxSamplingsInterval;
|
2019-09-06 03:40:57 -05:00
|
|
|
while ( mdInc < p1p2Length )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
cvf::Vec3d ps = p1 + mdInc * tp1p2;
|
2019-09-06 03:40:57 -05:00
|
|
|
m_points->push_back( ps );
|
|
|
|
m_meshDs->push_back( m_totalMD + mdInc );
|
2019-11-14 10:05:10 -06:00
|
|
|
mdInc += m_maxSamplingsInterval;
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|
|
|
|
}
|
2019-11-14 10:05:10 -06:00
|
|
|
|
2018-07-02 07:47:56 -05:00
|
|
|
m_totalMD += p1p2Length;
|
2019-09-06 03:40:57 -05:00
|
|
|
m_points->push_back( p2 );
|
|
|
|
m_meshDs->push_back( m_totalMD );
|
2018-11-16 01:43:19 -06:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
( *endTangent ) = p1p2.getNormalized();
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-11-16 01:43:19 -06:00
|
|
|
///
|
2018-07-02 07:47:56 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2019-09-06 03:40:57 -05:00
|
|
|
void RiaPolyArcLineSampler::sampleArc( cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
// Find arc CS
|
2019-09-06 03:40:57 -05:00
|
|
|
RiaArcCurveCalculator CS_rad( p1, t1, p2 );
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
double radius = CS_rad.radius();
|
|
|
|
cvf::Mat4d arcCS = CS_rad.arcCS();
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-11-14 10:05:10 -06:00
|
|
|
double angleInc = m_maxSamplingsInterval / radius;
|
|
|
|
|
2019-11-19 04:08:59 -06:00
|
|
|
angleInc = angleInc < m_maxSamplingArcAngle ? angleInc : m_maxSamplingArcAngle; // Angle from 6 deg dogleg on 10 m
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2018-09-26 05:37:15 -05:00
|
|
|
cvf::Vec3d C = CS_rad.center();
|
|
|
|
cvf::Vec3d N = CS_rad.normal();
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
// Sample arc by
|
2018-07-02 07:47:56 -05:00
|
|
|
// Rotate vector an increment, and transform to arc CS
|
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
double arcAngle = cvf::GeometryTools::getAngle( N, p1 - C, p2 - C );
|
|
|
|
if ( arcAngle / angleInc > 5000 )
|
2018-07-04 09:49:04 -05:00
|
|
|
{
|
2018-11-16 01:43:19 -06:00
|
|
|
angleInc = arcAngle / 5000;
|
2018-07-04 09:49:04 -05:00
|
|
|
}
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
for ( double angle = angleInc; angle < arcAngle; angle += angleInc )
|
2018-07-02 07:47:56 -05:00
|
|
|
{
|
|
|
|
cvf::Vec3d C_to_incP = cvf::Vec3d::X_AXIS;
|
2018-09-24 08:48:16 -05:00
|
|
|
C_to_incP *= radius;
|
2019-09-06 03:40:57 -05:00
|
|
|
C_to_incP.transformVector( cvf::Mat3d::fromRotation( cvf::Vec3d::Z_AXIS, angle ) );
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
C_to_incP.transformPoint( arcCS );
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
m_points->push_back( C_to_incP );
|
|
|
|
m_meshDs->push_back( m_totalMD + angle * radius );
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|
2019-11-14 10:05:10 -06:00
|
|
|
|
2018-11-16 01:43:19 -06:00
|
|
|
m_totalMD += arcAngle * radius;
|
2019-09-06 03:40:57 -05:00
|
|
|
m_points->push_back( p2 );
|
|
|
|
m_meshDs->push_back( m_totalMD );
|
2018-07-02 07:47:56 -05:00
|
|
|
|
2019-09-06 03:40:57 -05:00
|
|
|
( *endTangent ) = CS_rad.endTangent();
|
2018-07-02 07:47:56 -05:00
|
|
|
}
|