Exemplo n.º 1
0
ON_Interval ON_CurveProxy::RealCurveInterval( const ON_Interval* sub_domain ) const
{
  if ( !sub_domain )
    return m_real_curve_domain;
  ON_Interval d = m_this_domain;
  d.Intersection(*sub_domain);
  double t0 = RealCurveParameter( d[m_bReversed?1:0] );
  double t1 = RealCurveParameter( d[m_bReversed?0:1] );
  return ON_Interval(t0,t1);
}
Exemplo n.º 2
0
void ON_CurveProxy::SetProxyCurve( const ON_Curve* real_curve, 
                                   ON_Interval real_curve_subdomain)
{
  if ( real_curve != this )
  {
    // setting m_real_curve=0 prevents crashes if user has deleted
    // the "real" curve before calling SetProxyCurve().
    m_real_curve = 0;
    DestroyCurveTree();
    m_real_curve_domain.Destroy();
    m_this_domain.Destroy();
    m_bReversed = false;
  }
  else
  {
    // If you are debugging and end up here, there is a 99% chance
    // that you passed the wrong pointer to SetProxyCurve().
    // However, I will assume you really meant to use a fancy self
    // reference to adjust domains.
    if ( IsValid() && m_this_domain.Includes(real_curve_subdomain) )
    {
      real_curve = m_real_curve;
      // because input real_curve_subdomain was with respect to "this".
      double r0 = RealCurveParameter(real_curve_subdomain[0]);
      double r1 = RealCurveParameter(real_curve_subdomain[1]);
      real_curve_subdomain.Set(r0,r1);
    }
    else
    {
      real_curve = 0;
    }

    // setting m_real_curve=0 prevents crashes if user has deleted
    // the "real" curve before calling SetProxyCurve().
    m_real_curve = 0;
    DestroyCurveTree();
  }

  m_real_curve = real_curve;
  if ( m_real_curve )
  {
    SetProxyCurveDomain( real_curve_subdomain );
  }
  else
  {
    m_real_curve_domain = real_curve_subdomain;
  }
  m_this_domain = m_real_curve_domain;
}
Exemplo n.º 3
0
bool ON_CurveProxy::IsContinuous(
    ON::continuity desired_continuity,
    double t, 
    int* hint, // default = NULL,
    double point_tolerance, // default=ON_ZERO_TOLERANCE
    double d1_tolerance, // default==ON_ZERO_TOLERANCE
    double d2_tolerance, // default==ON_ZERO_TOLERANCE
    double cos_angle_tolerance, // default==ON_DEFAULT_ANGLE_TOLERANCE_COSINE
    double curvature_tolerance  // default==ON_SQRT_EPSILON
    ) const
{
  bool rc = true;
  if ( m_real_curve )
  {
    if ( m_real_curve_domain != m_real_curve->Domain() )
    {
      // 20 March 2003 Dale Lear
      //      Added this code to correctly handle the new locus
      //      flavors of ON::continuity.
      switch(desired_continuity)
      {
      case ON::unknown_continuity:
      case ON::C0_continuous:
      case ON::C1_continuous:
      case ON::C2_continuous:
      case ON::G1_continuous:
      case ON::G2_continuous:
      case ON::Cinfinity_continuous:
      case ON::Gsmooth_continuous:
        break;

      case ON::C0_locus_continuous:
      case ON::C1_locus_continuous:
      case ON::C2_locus_continuous:
      case ON::G1_locus_continuous:
      case ON::G2_locus_continuous:
        if ( t >= Domain()[1] )
        {
          // Since the proxy curve is using a subset of the real curve,
          // the proxy can't be closed.  So if the query parameter
          // is >= domain max, the curve cannot be locus continuous.
          rc = false;
        }
        else
        {
          // otherwise we want the answer for a non-locus test
          desired_continuity = ON::ParametricContinuity(desired_continuity);
        }
        break;
      }
    }
    if (rc)
      rc = m_real_curve->IsContinuous( desired_continuity, 
                           RealCurveParameter(t), hint, 
                           point_tolerance, d1_tolerance, d2_tolerance, 
                           cos_angle_tolerance, curvature_tolerance );
  }
  return rc;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
// override of virtual ON_Curve::Split
ON_BOOL32 ON_CurveProxy::Split(
    double t,
    ON_Curve*& left_side,
    ON_Curve*& right_side
  ) const
{
  ON_BOOL32 rc = false;
  if ( m_this_domain.IsIncreasing() && m_real_curve_domain.IsIncreasing() && m_this_domain.Includes(t,true) )
  {
    double crv_t = RealCurveParameter(t);
    if ( m_real_curve_domain.Includes(crv_t,true) )
    {
      ON_CurveProxy* left_proxy = 0;
      ON_CurveProxy* right_proxy = 0;
      if ( left_side )
      {
        left_proxy = ON_CurveProxy::Cast(left_side);
        if ( !left_proxy )
          return false;
      }
      if ( right_side )
      {
        right_proxy = ON_CurveProxy::Cast(right_side);
        if ( !right_proxy )
          return false;
        if ( right_side == left_side )
          return false;
      }

      bool bRev = m_bReversed;

      ON_Interval left_real_dom, right_real_dom;
      if ( bRev )
      {
        left_real_dom.Set(crv_t,m_real_curve_domain[1]);
        right_real_dom.Set(m_real_curve_domain[0],crv_t);
      }
      else
      {
        left_real_dom.Set(m_real_curve_domain[0],crv_t);
        right_real_dom.Set(crv_t,m_real_curve_domain[1]);
      }

      ON_Interval left_this_dom(m_this_domain[0],t);
      ON_Interval right_this_dom(t,m_this_domain[1]);

      if (    left_real_dom.IsIncreasing() 
           && right_real_dom.IsIncreasing()
           && left_this_dom.IsIncreasing()
           && right_this_dom.IsIncreasing()
           )
      {
        // note well that left_proxy or right_proxy might also be this
        const ON_Curve* real_crv = m_real_curve;
        if ( real_crv )
        {
          ON_Interval d = real_crv->Domain();
          if ( !d.Includes(left_real_dom) )
            return false;
          if ( !d.Includes(right_real_dom) )
            return false;
        }

        if ( !left_proxy )
          left_proxy = new ON_CurveProxy();
        if ( !right_proxy )
          right_proxy = new ON_CurveProxy();

        left_proxy->SetProxyCurve( real_crv, left_real_dom );
        right_proxy->SetProxyCurve( real_crv, right_real_dom );

        if ( bRev )
        {
          left_proxy->Reverse();
          right_proxy->Reverse();
        }

        left_proxy->SetDomain(left_this_dom[0],left_this_dom[1]);
        right_proxy->SetDomain(right_this_dom[0],right_this_dom[1]);

        if (!left_side) left_side = left_proxy;
        if (!right_side) right_side = right_proxy;

        rc = true;
      }
    }
  }
  return rc;
}
Exemplo n.º 8
0
ON_BOOL32 
ON_CurveProxy::Evaluate( // returns false if unable to evaluate
       double t,       // evaluation parameter
       int der_count,  // number of derivatives (>=0)
       int v_stride,   // v[] array stride (>=Dimension())
       double* v,      // v[] array of length stride*(ndir+1)
       int side,       // optional - determines which side to evaluate from
                       //         0 = default
                       //      <  0 to evaluate from below, 
                       //      >  0 to evaluate from above
       int* hint       // optional - evaluation hint (int) used to speed
                       //            repeated evaluations
       ) const
{
  // When the proxy domain is a proper subdomain of the 
  // real curve and we are evaluating at the end, we
  // need to be certain we are getting the values
  // from the active part of the curve.
  double normt = m_this_domain.NormalizedParameterAt(t);
  if( fabs( normt )<ON_ZERO_TOLERANCE)
    side = (abs(side) <= 1) ? 1 : 2;
  else if( fabs(1.0 - normt)<ON_ZERO_TOLERANCE)
    side = (abs(side) <= 1) ? -1 : -2;
  
  if ( 0 != side )
  {
    if ( m_bReversed )
    {
      side = -side;
    }
    if (m_bReversed || m_real_curve_domain != m_this_domain )
    {
      // 9 November 2010 Dale Lear - ON_TuneupEvaluationParameter fix
      //  If we have to adjust the evaluation parameter for the 
      //  real curve and the evaluation side was specified, then
      //  set side to +2 or -2 to trigger the use of
      //  ON_TuneupEvaluationParameter() when it matters.
      if ( -1 == side )
        side = -2;
      else if ( 1 == side )
        side = 2;
    }
  }

  double r = RealCurveParameter(t);
  ON_BOOL32 rc = ( m_real_curve ) 
          ? m_real_curve->Evaluate( r,der_count,v_stride,v,side,hint) 
          : false;
  if ( rc && m_bReversed ) 
  {
    // negate odd derivatives
    const int dim = m_real_curve->Dimension();
    int di, i;
    for ( di = 1; di <= der_count; di+=2 ) 
    {
      v += v_stride;
      for ( i = 0; i < dim; i++ ) 
      {
        v[i] = -v[i];
      }
      v += v_stride;
    }
  }
  return rc;
}
Exemplo n.º 9
0
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;
}