ON_BOOL32 ON_CurveProxy::GetParameterTolerance( double t, // t = parameter in domain double* tminus, // tminus double* tplus // tplus ) const { ON_BOOL32 rc = ( m_real_curve ) ? m_real_curve->GetParameterTolerance( RealCurveParameter(t),tminus,tplus) : false; if (rc) { if ( tminus ) *tminus = ThisCurveParameter(*tminus); if ( tplus ) *tplus = ThisCurveParameter(*tplus); } return rc; }
ON_BOOL32 ON_CurveProxy::GetNormalizedArcLengthPoints( int count, const double* s, double* t, double absolute_tolerance , double fractional_tolerance , const ON_Interval* sub_domain ) const { // 23 July 2004 Dale Lear: // Fixed a bug so this would work right when m_bReversed = true int i, j; if ( !m_real_curve ) return false; if( count<0) return false; ON_Interval scratch_domain = RealCurveInterval( sub_domain ); ON_SimpleArray<double> ss; if( m_bReversed) { ss.Reserve(count); ss.SetCount(count); for(i=0, j = count-1; i<count; i++, j--) { ss[i] = 1.0-s[j]; } s = ss.Array(); } ON_BOOL32 rc = m_real_curve->GetNormalizedArcLengthPoints(count, s, t , absolute_tolerance, fractional_tolerance, &scratch_domain); if( rc) { for(i=0;i<count; i++) { t[i] = ThisCurveParameter( t[i]); } if ( m_bReversed ) { double x; for (i = 0, j = count-1; i < j; i++, j-- ) { x = t[i]; t[i] = t[j]; t[j] = x; } } } return rc; }
bool ON_CurveProxy::GetClosestPoint( const ON_3dPoint& test_point, double* t, // parameter of global closest point returned here double maximum_distance, const ON_Interval* sub_domain ) const { bool rc = false; if ( m_real_curve ) { ON_Interval scratch_domain = RealCurveInterval( sub_domain ); rc = m_real_curve->GetClosestPoint( test_point, t, maximum_distance, &scratch_domain ); if ( rc ) *t = ThisCurveParameter(*t); } return rc; }
ON_BOOL32 ON_CurveProxy::GetLocalClosestPoint( const ON_3dPoint& test_point, double seed_parameter, double* t, const ON_Interval* sub_domain ) const { ON_BOOL32 rc = false; if ( m_real_curve ) { ON_Interval scratch_domain = RealCurveInterval( sub_domain ); double sp = RealCurveParameter(seed_parameter); rc = m_real_curve->GetLocalClosestPoint( test_point, sp, t, &scratch_domain ); if ( rc && t ) *t = ThisCurveParameter(*t); } return rc; }
ON_BOOL32 ON_CurveProxy::GetNurbFormParameterFromCurveParameter( double curve_t, double* nurbs_t ) const { ON_BOOL32 rc = false; if ( m_real_curve ) { // 18 June 2003 Dale Lear and Chuck // Fixing joining bug in STEP TEST 2 caused by error // in converting NURBS parameter to arc parameter. const ON_Curve* real_crv = m_real_curve; ON_Curve* tmp_real_crv = 0; if ( m_real_curve_domain != m_real_curve->Domain() ) { const ON_ArcCurve* arc_curve = ON_ArcCurve::Cast(m_real_curve); if ( 0 != arc_curve ) { tmp_real_crv = arc_curve->DuplicateCurve(); if ( 0 != tmp_real_crv ) { if ( tmp_real_crv->Trim(m_real_curve_domain) ) { real_crv = tmp_real_crv; } } } } rc = real_crv->GetNurbFormParameterFromCurveParameter( RealCurveParameter(curve_t),nurbs_t); if ( rc ) *nurbs_t = ThisCurveParameter(*nurbs_t); if ( 0 != tmp_real_crv ) delete tmp_real_crv; } return rc; }
ON_BOOL32 ON_CurveProxy::GetNormalizedArcLengthPoint( double s, double* t, double fractional_tolerance, const ON_Interval* sub_domain ) const { if ( !m_real_curve ) return false; if ( s<0.0 || s>1.0) return false; ON_Interval scratch_domain = RealCurveInterval( sub_domain ); if( m_bReversed) s = 1-s; ON_BOOL32 rc = m_real_curve->GetNormalizedArcLengthPoint(s, t , fractional_tolerance, &scratch_domain); if( rc){ *t = ThisCurveParameter( *t); } return rc; }
bool ON_CurveProxy::GetNextDiscontinuity( ON::continuity c, double t0, double t1, double* t, int* hint, int* dtype, double cos_angle_tolerance, double curvature_tolerance ) const { bool rc = false; if ( 0 != dtype ) *dtype = 0; if ( 0 != m_real_curve ) { double s; // convert to "real" curve parameters double s0 = RealCurveParameter( t0 ); double s1 = RealCurveParameter( t1 ); // 21 October 2005 Dale Lear: // // NOTE: If m_bReversed is true, then RealCurveParameter // will reverse the direction of the search. // The commented out code below just messed things up. // //if ( m_bReversed ) //{ // // NOTE: GetNextDiscontinuity search begins at // // "t0" and goes towards "t1" so it is ok if s0 > s1. // s = s0; s0 = s1; s1 = s; //} ON::continuity parametric_c = ON::ParametricContinuity(c); int realcrv_dtype = 0; bool realcrv_rc = m_real_curve->GetNextDiscontinuity(parametric_c,s0,s1,&s,hint,&realcrv_dtype,cos_angle_tolerance,curvature_tolerance); if ( realcrv_rc ) { double thiscrv_t = ThisCurveParameter(s); if ( !(t0 < thiscrv_t && thiscrv_t < t1) && !(t1 < thiscrv_t && thiscrv_t < t0) ) { realcrv_rc = false; realcrv_dtype = 0; // Sometimes proxy domain adjustments kill all the precision. // To avoid infinite loops, it is critical that *t != t0 double s2 = ON_SQRT_EPSILON*s1 + (1.0 - ON_SQRT_EPSILON)*s0; if ( (s0 < s2 && s2 < s1) || (s1 < s2 && s2 < s0) ) { realcrv_rc = m_real_curve->GetNextDiscontinuity(parametric_c,s2,s1,&s,hint,&realcrv_dtype,cos_angle_tolerance,curvature_tolerance); if ( realcrv_rc ) thiscrv_t = ThisCurveParameter(s); } } if ( realcrv_rc ) { if ( (t0 < thiscrv_t && thiscrv_t < t1) || (t1 < thiscrv_t && thiscrv_t < t0) ) { *t = thiscrv_t; if ( dtype ) *dtype = realcrv_dtype; rc = true; } } } if ( !rc && parametric_c != c ) { // 20 March 2003 Dale Lear: // Let base class test decide locus continuity questions at ends rc = ON_Curve::GetNextDiscontinuity( c, t0, t1, t, hint, dtype, cos_angle_tolerance, curvature_tolerance ); } } return rc; }
int ON_CurveProxy::IsPolyline( ON_SimpleArray<ON_3dPoint>* pline_points, ON_SimpleArray<double>* pline_t ) const { ON_SimpleArray<double> tmp_t; if ( pline_points ) pline_points->SetCount(0); if ( pline_t ) pline_t->SetCount(0); if ( !m_real_curve_domain.IsIncreasing() ) return 0; if ( !m_real_curve ) return 0; const ON_Interval cdom = m_real_curve->Domain(); if ( !cdom.Includes(m_real_curve_domain) ) return 0; // See if the "real" curve is a polyline int rc = 0; if ( m_real_curve_domain == cdom ) { // proxy uses entire curve rc = m_real_curve->IsPolyline(pline_points,pline_t); if ( rc < 2 ) rc = 0; if ( pline_points && pline_points->Count() != rc) { // The pline_points info is bogus, clear everything and // return 0. pline_points->SetCount(0); if ( pline_t ) pline_t->SetCount(0); rc = 0; } if ( pline_t && pline_t->Count() != rc) { // The pline_t info is bogus, clear everything and // return 0. pline_t->SetCount(0); if ( pline_points ) pline_points->SetCount(0); rc = 0; } if ( rc ) { if ( m_bReversed ) { if ( pline_points ) pline_points->Reverse(); if ( pline_t ) pline_t->Reverse(); } if ( pline_points && IsClosed() && pline_points->Count() > 3 ) { // 27 February 2003 Dale Lear // If proxy curve says it's closed, then // make sure end point of returned polyline // is exactly equal to start point. *pline_points->Last() = *pline_points->First(); } if ( pline_t && (m_bReversed || m_real_curve_domain != m_this_domain) ) { int i; for ( i = 0; i < rc; i++ ) { (*pline_t)[i] = ThisCurveParameter( (*pline_t)[i] ); } } } } else { // 12 December 2003 Dale Lear // We have to extract a sub curve for the test, because // the region in question may be a polyline and the unused // portion may not be a polyline. This tends to happen // when the "real" curve is a polycurve that contains // a polyline and the polycurve has been parametrically // trimmed during a brep operation (like a boolean). // // The ON_CurveProxy::DuplicateCurve() scope is critical // because there are situation where people derive a // class from ON_CurveProxy, and override the virtual // DuplicateCurve(). In this situation I rely on getting // the result returned by ON_CurveProxy::DuplicateCurve(). ON_Curve* temp_curve = ON_CurveProxy::DuplicateCurve(); if ( temp_curve ) { rc = temp_curve->IsPolyline(pline_points,pline_t); delete temp_curve; } } return rc; }