Exemplo n.º 1
0
ON_BOOL32 ON_PlaneSurface::GetSpanVector( int dir, double* s ) const
{
  ON_Interval d = Domain(dir);
  s[0] = d.Min();
  s[1] = d.Max();
  return d.IsIncreasing();
}
Exemplo n.º 2
0
double ON_PolyEdgeSegment::EdgeParameter(double t) const
{
  double edge_t = ON_UNSET_VALUE;
  if ( m_edge )
  {
    if ( m_t == t && m_edge_t != ON_UNSET_VALUE )
      edge_t = m_edge_t;
    else
    {
      ON_PolyEdgeSegment* p = const_cast<ON_PolyEdgeSegment*>(this);
      if ( t != m_t )
      {
        p->m_t = t;
        p->m_trim_t = ON_UNSET_VALUE;
        p->m_srf_uv[0] = ON_UNSET_VALUE;
        p->m_srf_uv[1] = ON_UNSET_VALUE;
      }
      ON_Interval d = Domain();
      bool bReversedEdgeDir = ReversedEdgeDir();
      if ( bReversedEdgeDir || m_edge_domain != d )
      {
        double s = d.NormalizedParameterAt(t);
        if ( bReversedEdgeDir )
          s = 1.0 - s;
        edge_t = m_edge_domain.ParameterAt(s);
      }
      else
        edge_t = t;
      p->m_edge_t = edge_t;
    }
  }
  return edge_t;
}
Exemplo n.º 3
0
ON_BOOL32 ON_Surface::GetDomain( int dir, double* t0, double* t1 ) const
{
  ON_Interval d = Domain(dir);
  if ( t0 ) *t0 = d[0];
  if ( t1 ) *t1 = d[1];
  return d.IsIncreasing();
}
Exemplo n.º 4
0
bool ON_Arc::SetAngleIntervalRadians( ON_Interval angle_in_radians )
{
  bool rc = angle_in_radians.IsIncreasing() 
            && angle_in_radians.Length() < (1.0+ON_SQRT_EPSILON)*2.0*ON_PI;
  if (rc)
  {
    m_angle = angle_in_radians;
  }
  return rc;
}
Exemplo n.º 5
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);
}
ON_Color CZAnalysisVAM::FalseColor(double z) const
{
  // Simple example of one way to change a number 
  // into a color.
  double s = m_z_range.NormalizedParameterAt(z);
  if ( s < 0.0 ) s = 0.0; else if (s > 1.0) s = 1.0;
  double hue = m_hue_range.ParameterAt(s);
  ON_Color c;
  c.SetHSV( hue, 1.0, 1.0 );
  return c;
}
Exemplo n.º 7
0
ON_BOOL32 
ON_Surface::IsClosed(int dir) const
{
  ON_Interval d = Domain(dir);
  if ( d.IsIncreasing() && Dimension() <= 3 ) {
    const int span_count = SpanCount(dir?0:1);
    const int span_degree = Degree(dir?0:1);
    if ( span_count > 0 && span_degree > 0 )
    {
      ON_SimpleArray<double> s(span_count+1);
      s.SetCount(span_count+1);
      int n = 2*span_degree+1;
      double delta = 1.0/n;
      ON_3dPoint P, Q;
      P.Zero();
      Q.Zero();
      int hintP[2] = {0,0};
      int hintQ[2] = {0,0};
      double *u0, *u1, *v0, *v1;
      double t;
      ON_Interval sp;
      if ( dir ) {
        v0 = &d.m_t[0];
        v1 = &d.m_t[1];
        u0 = &t;
        u1 = &t;
      }
      else {
        u0 = &d.m_t[0];
        u1 = &d.m_t[1];
        v0 = &t;
        v1 = &t;
      }
      if ( GetSpanVector( dir?0:1, s.Array() ) )
      {
        int span_index, i;
        for ( span_index = 0; span_index < span_count; span_index++ ) {
          sp.Set(s[span_index],s[span_index+1]);
          for ( i = 0; i < n; i++ ) {
            t = sp.ParameterAt(i*delta);
            if ( !Evaluate( *u0, *v0, 1, 3, P, 0, hintP ) )
              return false;
            if ( !Evaluate( *u1, *v1, 2, 3, Q, 0, hintQ ) )
              return false;
            if ( false == ON_PointsAreCoincident( 3, 0, &P.x, &Q.x ) )
              return false;
          }
        }
        return true;
      }
    }
  }
  return false;
}
Exemplo n.º 8
0
ON_BOOL32 ON_LineCurve::GetNormalizedArcLengthPoint(
        double s,
        double* t,
        double fractional_tolerance,
        const ON_Interval* sub_domain
        ) const
{
  ON_Interval domain = (sub_domain) ? *sub_domain : Domain();
  if ( t )
    *t = domain.ParameterAt(s);
  return true;
}
Exemplo n.º 9
0
ON_BOOL32 ON_Surface::GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus
       int dir,
       double t,       // t = parameter in domain
       double* tminus, // tminus
       double* tplus   // tplus
       ) const
{
  ON_BOOL32 rc = false;
  ON_Interval d = Domain( dir );
  if ( d.IsIncreasing() )
    rc = ON_GetParameterTolerance( d.Min(), d.Max(), t, tminus, tplus );
  return rc;
}
CRhinoCommand::result CCommandSampleSubCrvLength::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select curve to measure" );
  go.SetGeometryFilter( CRhinoGetObject::curve_object );
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();

  const CRhinoObjRef& ref = go.Object(0);
  const ON_Curve* crv = ref.Curve();
  if( !crv )
    return CRhinoCommand::failure;

  CRhinoGetPoint gp;
  gp.SetCommandPrompt( L"First point on curve" );
  gp.Constrain( *crv );
  gp.GetPoint();
  if( gp.CommandResult() != CRhinoCommand::success )
    return gp.CommandResult();

  double t0;
  if( !crv->GetClosestPoint(gp.Point(), &t0) )
    return CRhinoCommand::nothing;

  gp.SetCommandPrompt( L"Second point on curve" );
  gp.GetPoint();
  if( gp.CommandResult() != CRhinoCommand::success )
    return gp.CommandResult();

  double t1;
  if( !crv->GetClosestPoint(gp.Point(), &t1) )
    return CRhinoCommand::nothing;

  ON_Interval dom;
  if( t0 < t1 )
    dom.Set( t0, t1 );
  else
    dom.Set( t1, t0 );

  double len;
  if( crv->GetLength(&len, 0.0, &dom) )
    RhinoApp().Print( L"Subcurve length = %f.\n", len );
  else
    RhinoApp().Print( L"Unable to calculate length of subcurve.\n" );

	return CRhinoCommand::success;
}
Exemplo n.º 11
0
bool ON_Surface::SetDomain( int dir, ON_Interval domain )
{
  return ( dir >= 0 
           && dir <= 1 
           && domain.IsIncreasing() 
           && SetDomain( dir, domain[0], domain[1] )) ? true : false;
}
Exemplo n.º 12
0
double ON_PolyEdgeCurve::TrimParameter(double t) const
{
  double trim_t = ON_UNSET_VALUE;
  int segment_index = SegmentIndex(t);
  ON_PolyEdgeSegment* seg = SegmentCurve( segment_index );
  if ( seg )
  {
    ON_Interval pdom = SegmentDomain(segment_index);
    ON_Interval sdom = seg->Domain();
    if ( sdom != pdom )
    {
      double s = pdom.NormalizedParameterAt(t);
      t = sdom.ParameterAt(s);
    }
    trim_t = seg->TrimParameter(t);
  }
  return trim_t;
}
Exemplo n.º 13
0
ON_2dPoint ON_PolyEdgeCurve::SurfaceParameter(double t) const
{
  ON_2dPoint srf_uv(ON_UNSET_VALUE,ON_UNSET_VALUE);
  int segment_index = SegmentIndex(t);
  ON_PolyEdgeSegment* seg = SegmentCurve( segment_index );
  if ( seg )
  {
    ON_Interval pdom = SegmentDomain(segment_index);
    ON_Interval sdom = seg->Domain();
    if ( sdom != pdom )
    {
      double s = pdom.NormalizedParameterAt(t);
      t = sdom.ParameterAt(s);
    }
    srf_uv = seg->SurfaceParameter(t);
  }
  return srf_uv;
}
Exemplo n.º 14
0
bool ON_CurveProxy::SetProxyCurveDomain( ON_Interval proxy_curve_subdomain )
{
  bool rc = proxy_curve_subdomain.IsIncreasing();
  if ( rc )
  {
    if ( m_real_curve )
    {
      ON_Interval cdom = m_real_curve->Domain();
      cdom.Intersection( proxy_curve_subdomain );
      rc = cdom.IsIncreasing();
      if (rc )
        m_real_curve_domain = cdom;
    }
    else
    {
      m_real_curve_domain = proxy_curve_subdomain;
    }
  }
  return rc;
}
Exemplo n.º 15
0
static
ON_NurbsSurface* ON_BrepExtrudeHelper_MakeConeSrf( const ON_3dPoint& apex_point,
                                                 const ON_BrepEdge& edge, ON_BOOL32 bRev )
{
  // The "s" parameter runs along the edge.
  // The "t" parameter is the ruling parameter;
  // t=0 is at the base_edge and t=max is at the apex.
  //   surface side    location
  //     south           base_edge
  //     east            line from bRev?START:END of edge to apex
  //     north           singular side at apex
  //     west            line from bRev?END:START of edge to apex.
  ON_NurbsSurface* cone_srf = new ON_NurbsSurface();
  if ( cone_srf->CreateConeSurface( apex_point, edge ) )
  {
    if ( bRev )
      cone_srf->Reverse(0);
    // get a decent interval for the ruling parameter
    double d = 0.0;
    ON_Interval edom = edge.Domain();
    ON_3dPoint pt;
    int i, hint=0;
    for ( i = 0; i <= 16; i++ )
    {
      if ( !edge.EvPoint( edom.ParameterAt(i/16.0), pt, 0, &hint ) )
        continue;
      if ( pt.DistanceTo(apex_point) > d )
        d = pt.DistanceTo(apex_point);
    }
    if ( d > ON_SQRT_EPSILON )
      cone_srf->SetDomain(1,0.0,d);
  }
  else
  {
    delete cone_srf;
    cone_srf = 0;
  }
  return cone_srf;
}
Exemplo n.º 16
0
bool ON_PlaneSurface::SetExtents( 
       int dir,
       ON_Interval extents,
       bool bSyncDomain
       )
{
  if ( dir < 0 || dir > 1 || !extents.IsIncreasing() )
    return false;
  m_extents[dir] = extents;
  if ( bSyncDomain )
    m_domain[dir] = m_extents[dir];
  return true;
}
Exemplo n.º 17
0
ON_BOOL32 ON_ArcCurve::Trim( const ON_Interval& in )
{
  ON_BOOL32 rc = in.IsIncreasing();
  if (rc) 
  {
    double t0 = m_t.NormalizedParameterAt(in.m_t[0]);
    double t1 = m_t.NormalizedParameterAt(in.m_t[1]);
    const ON_Interval arc_angle0 = m_arc.DomainRadians();
    double a0 = arc_angle0.ParameterAt(t0);
    double a1 = arc_angle0.ParameterAt(t1);
		// Resulting ON_Arc must pass IsValid()
    if ( a1 - a0 > ON_ZERO_TOLERANCE && m_arc.SetAngleIntervalRadians(ON_Interval(a0,a1)) ) 
    {
      m_t = in;
    }
    else
    {
      rc = false;
    }
  }
  return rc;
}
Exemplo n.º 18
0
ON_BOOL32 ON_PolyEdgeCurve::Prepend( ON_PolyEdgeSegment* new_segment )
{
  DestroyRuntimeCache();
  ON_BOOL32 rc = false;
  if ( new_segment )
  {
    if ( Count() > 0 )
    {
      // keep segment domains in synch with polycurve domain
      // so that parameter bookkeeping is easy.
      ON_Interval cdom = Domain();
      ON_Interval sdom = new_segment->Domain();
      if ( sdom[1] != cdom[0] )
      {
        sdom[0] = cdom[0] - sdom.Length();
        sdom[1] = cdom[0];
        new_segment->SetDomain(sdom[0],sdom[1]);
      }
    }
    rc = ON_PolyCurve::Prepend(new_segment);
  }
  return rc;
}
Exemplo n.º 19
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.º 20
0
ON_BOOL32 ON_LineCurve::Trim( const ON_Interval& domain )
{
  ON_BOOL32 rc = false;
  if ( domain.IsIncreasing() )
  {
    ON_3dPoint p = PointAt( domain[0] );
    ON_3dPoint q = PointAt( domain[1] );
		if( p.DistanceTo(q)>0){								// 2 April 2003 Greg Arden A successfull trim 
																					// should return an IsValid ON_LineCurve .
			m_line.from = p;
			m_line.to = q;
			m_t = domain;
			rc = true;
		}
  }
  return rc;
}
Exemplo n.º 21
0
bool ON_PolyEdgeCurve::EvSrfDerivatives(
        double t,
        ON_3dPoint& srfpoint,
        ON_3dVector& du,
        ON_3dVector& dv,
        ON_3dVector& duu,
        ON_3dVector& duv,
        ON_3dVector& dvv
        ) const
{
  bool rc = false;
  int segment_index = SegmentIndex(t);
  ON_PolyEdgeSegment* seg = SegmentCurve( segment_index );
  if ( seg )
  {
    ON_Interval pdom = SegmentDomain(segment_index);
    ON_Interval sdom = seg->Domain();
    double s = t;
    if ( sdom != pdom )
    {
      double x = pdom.NormalizedParameterAt(t);
      s = sdom.ParameterAt(x);
    }
    // s is the segment parameter at the polyedge parameter t
    // Get the corresponding surfaces parameters
    ON_2dPoint srf_uv = seg->SurfaceParameter(s);
    if ( ON_IsValid(srf_uv.x) )
    {
      if ( srf_uv.x == seg->m_evsrf_uv[0] && srf_uv.y == seg->m_evsrf_uv[1] )
      {
        rc = true;
        srfpoint = seg->m_evsrf_pt;
        du = seg->m_evsrf_du;
        dv = seg->m_evsrf_dv;
        duu = seg->m_evsrf_duu;
        duv = seg->m_evsrf_duv;
        dvv = seg->m_evsrf_dvv;
      }
      else if ( seg->m_surface )
      {
        rc = seg->m_surface->Ev2Der( 
                  srf_uv.x, srf_uv.y, 
                  srfpoint, 
                  du, dv, 
                  duu, duv, dvv, 
                  0, seg->m_evsrf_hint 
                  ) ? true : false;
        if ( rc )
        {
          CookDerivativesHelper( du, dv, duu, duv, dvv);
          seg->m_evsrf_uv[0] = srf_uv.x;
          seg->m_evsrf_uv[1] = srf_uv.y;
          seg->m_evsrf_pt = srfpoint;
          seg->m_evsrf_du = du;
          seg->m_evsrf_dv = dv;
          seg->m_evsrf_duu = duu;
          seg->m_evsrf_duv = duv;
          seg->m_evsrf_dvv = dvv;
        }
      }
    }
  }
  return rc;
}
Exemplo n.º 22
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.º 23
0
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;
}
Exemplo n.º 24
0
ON_Surface::ISO
ON_Surface::IsIsoparametric( const ON_Curve& curve, const ON_Interval* subdomain ) const
{
  ISO iso = not_iso;

  if ( subdomain )
  {
    ON_Interval cdom = curve.Domain();
    double t0 = cdom.NormalizedParameterAt(subdomain->Min());
    double t1 = cdom.NormalizedParameterAt(subdomain->Max());
    if ( t0 < t1-ON_SQRT_EPSILON )
    {
      if ( (t0 > ON_SQRT_EPSILON && t0 < 1.0-ON_SQRT_EPSILON) || (t1 > ON_SQRT_EPSILON && t1 < 1.0-ON_SQRT_EPSILON) )
      {
        cdom.Intersection(*subdomain);
        if ( cdom.IsIncreasing() )
        {
          ON_NurbsCurve nurbs_curve;
          if ( curve.GetNurbForm( nurbs_curve, 0.0,&cdom) )
          {
            return IsIsoparametric( nurbs_curve, 0 );
          }
        }
      }
    }
  }


  ON_BoundingBox bbox;
  double tolerance = 0.0;
  const int dim = curve.Dimension();
  if ( (dim == 2 || dim==3) && curve.GetBoundingBox(bbox) ) 
  {
    iso = IsIsoparametric( bbox );
    switch (iso) {
    case x_iso:
    case W_iso:
    case E_iso:
      // make sure curve is a (nearly) vertical line
      // and weed out vertical scribbles
      tolerance = bbox.m_max.x - bbox.m_min.x;
      if ( tolerance < ON_ZERO_TOLERANCE && ON_ZERO_TOLERANCE*1024.0 <= (bbox.m_max.y-bbox.m_min.y) )
      {
        // 26 March 2007 Dale Lear
        //    If tolerance is tiny, then use ON_ZERO_TOLERANCE
        //    This fixes cases where iso curves where not getting
        //    the correct flag because tol=1e-16 and the closest
        //    point to line had calculation errors of 1e-15.
        tolerance = ON_ZERO_TOLERANCE;
      }
      if ( !curve.IsLinear( tolerance ) )
        iso = not_iso;
      break;
    case y_iso:
    case S_iso:
    case N_iso:
      // make sure curve is a (nearly) horizontal line
      // and weed out horizontal scribbles
      tolerance = bbox.m_max.y - bbox.m_min.y;
      if ( tolerance < ON_ZERO_TOLERANCE && ON_ZERO_TOLERANCE*1024.0 <= (bbox.m_max.x-bbox.m_min.x) )
      {
        // 26 March 2007 Dale Lear
        //    If tolerance is tiny, then use ON_ZERO_TOLERANCE
        //    This fixes cases where iso curves where not getting
        //    the correct flag because tol=1e-16 and the closest
        //    point to line had calculation errors of 1e-15.
        tolerance = ON_ZERO_TOLERANCE;
      }
      if ( !curve.IsLinear( tolerance ) )
        iso = not_iso;
      break;
    default:
      // nothing here
      break;
    }
  }
  return iso;
}
Exemplo n.º 25
0
int 
ON_CurveProxy::GetNurbForm( // returns 0: unable to create NURBS representation
                 //            with desired accuracy.
                 //         1: success - returned NURBS parameterization
                 //            matches the curve's to wthe desired accuracy
                 //         2: success - returned NURBS point locus matches
                 //            the curve's to the desired accuracy but, on
                 //            the interior of the curve's domain, the 
                 //            curve's parameterization and the NURBS
                 //            parameterization may not match to the 
                 //            desired accuracy.
      ON_NurbsCurve& nurbs,
      double tolerance,  // (>=0)
      const ON_Interval* sub_domain  // OPTIONAL subdomain of ON::ProxyCurve::Domain()
      ) const
{
  ON_BOOL32 rc = false;
  if ( m_real_curve ) 
  {
    ON_Interval scratch_domain = RealCurveInterval( sub_domain );
    rc = m_real_curve->GetNurbForm(nurbs,tolerance,&scratch_domain);
    if ( rc )
    {
      if ( m_bReversed )
        nurbs.Reverse();
      ON_Interval d = m_this_domain;
      if ( sub_domain )
        d.Intersection( *sub_domain );
      nurbs.SetDomain( d[0], d[1] );

      if ( nurbs.m_dim <= 3 && nurbs.m_dim >= 1 )
      {
        double t0 = Domain()[0];
        double t1 = Domain()[1];
        if ( 0 != sub_domain )
        {
          if ( t0 < sub_domain->Min() )
            t0 = sub_domain->Min();
          if ( sub_domain->Max() < t1 )
            t1 = sub_domain->Max();
        }
        // set ends of NURBS curve to be exactly on ends of proxy curve
        ON_3dPoint P0 = PointAt(t0);
        ON_3dPoint P1 = PointAt(t1);
        ON_3dPoint N0 = nurbs.PointAtStart();
        ON_3dPoint N1 = nurbs.PointAtEnd();
				
				// 22 September 2003, GBA.  The end tuning code below should only  be applied
				//					to clamped nurbs curves.  In particular it should not be used on
				//					periodic nurbs curves.  Fixes TRR#11502.
				ON_BOOL32 clamped = nurbs.IsClamped(2);
        if ( clamped && (P0 != N0 || P1 != N1) )
        {
          if ( 0==nurbs.m_is_rat )
          {
            nurbs.SetCV(0,P0);
            nurbs.SetCV(nurbs.m_cv_count-1,P1);
          }
          else
          {
            ON_4dPoint H0, H1;
            H0 = P0;
            H0.w = nurbs.Weight(0);
            H0.x *= H0.w;
            H0.y *= H0.w;
            H0.z *= H0.w;
            nurbs.SetCV(0,H0);

            H1 = P1;
            H1.w = nurbs.Weight(nurbs.m_cv_count-1);
            H1.x *= H1.w;
            H1.y *= H1.w;
            H1.z *= H1.w;
            nurbs.SetCV(nurbs.m_cv_count-1,H1);
          }
        }
      }
    }
  }
  return rc;
}
CRhinoCommand::result CCommandSampleCageEdit::RunCommand( const CRhinoCommandContext& context )
{
  ON_Workspace ws;
  CRhinoCommand::result rc = CRhinoCommand::success;
 
  // Get the captive object
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select captive surface or polysurface" );
  go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object );
  go.GetObjects( 1, 1 );
  rc = go.CommandResult();
  if( CRhinoCommand::success != rc )
    return rc;
 
  const CRhinoObject* captive = go.Object(0).Object();
  if( 0 == captive )
    return CRhinoCommand::failure;
 
  // Define the control line
  ON_Line line;
  CArgsRhinoGetLine args;
  rc = RhinoGetLine( args, line );
  if( CRhinoCommand::success != rc )
    return rc;
 
  // Get the curve parameters
  int degree = 3;
  int cv_count = 4;
  for(;;)
  {
    CRhinoGetOption gl;
    gl.SetCommandPrompt( L"NURBS Parameters" );
    gl.AcceptNothing();
    int d_opt = gl.AddCommandOptionInteger( RHCMDOPTNAME(L"Degree"), &degree, L"Curve degree", 1.0, 100.0 );
    int p_opt = gl.AddCommandOptionInteger( RHCMDOPTNAME(L"PointCount"), &cv_count, L"Number of control points", 2.0, 100.0 );
    gl.GetOption();
    rc = gl.CommandResult();
    if( CRhinoCommand::success != rc )
      return rc;
 
    if( CRhinoGet::nothing == gl.Result() )
      break;
 
    if( cv_count <= degree )
    {
      if( CRhinoGet::option != gl.Result() )
        continue;
      const CRhinoCommandOption* opt = go.Option();
      if( 0 == opt )
        continue;
      if( d_opt == opt->m_option_index )
        cv_count = degree + 1;
      else 
        degree = cv_count - 1;
    }
  }
 
  // Set up morph control
  ON_MorphControl* control = new ON_MorphControl();
  control->m_varient = 1; // 1= curve
 
  // Specify the source line curve
  control->m_nurbs_curve0.Create( 3, false, 2, 2 );
  control->m_nurbs_curve0.MakeClampedUniformKnotVector();
  control->m_nurbs_curve0.SetCV( 0, line.from );
  control->m_nurbs_curve0.SetCV( 1, line.to );
 
  // Specify the destination NURBS curve
  control->m_nurbs_curve.Create( 3, false, degree + 1, cv_count );
  control->m_nurbs_curve.MakeClampedUniformKnotVector();
  double* g = ws.GetDoubleMemory( control->m_nurbs_curve.m_cv_count );
  control->m_nurbs_curve.GetGrevilleAbcissae( g );
  ON_Interval d = control->m_nurbs_curve.Domain();
  double s = 0.0;
  int i;
  for( i = 0; i < control->m_nurbs_curve.m_cv_count; i++ )
  {
    s = d.NormalizedParameterAt( g[i] );
    control->m_nurbs_curve.SetCV( i, line.PointAt(s) );
  }
 
  // Make sure domains match
  s = line.Length();
  if( s > ON_SQRT_EPSILON )
    control->m_nurbs_curve0.SetDomain( 0.0, s );
  d = control->m_nurbs_curve0.Domain();
  control->m_nurbs_curve.SetDomain( d[0], d[1] );
 
  // Create the morph control object
  CRhinoMorphControl* control_object = new CRhinoMorphControl();
  control_object->SetControl( control );
  context.m_doc.AddObject( control_object );
 
  // Set up the capture
  RhinoCaptureObject( control_object, const_cast<CRhinoObject*>(captive) );
 
  // Clean up display
  context.m_doc.UnselectAll();
 
  // Turn on the control grips
  control_object->EnableGrips( true );
  context.m_doc.Redraw( CRhinoView::mark_display_hint );
 
  return rc;
}
Exemplo n.º 27
0
ON_BOOL32
ON_Surface::EvNormal( // returns false if unable to evaluate
         double s, double t, // evaluation parameters (s,t)
         ON_3dPoint& point,  // returns value of surface
         ON_3dVector& ds, // first partial derivatives (Ds)
         ON_3dVector& dt, // (Dt)
         ON_3dVector& normal, // unit normal
         int side,       // optional - determines which side to evaluate from
                         //         0 = default
                         //         1 from NE quadrant
                         //         2 from NW quadrant
                         //         3 from SW quadrant
                         //         4 from SE quadrant
         int* hint       // optional - evaluation hint (int[2]) used to speed
                         //            repeated evaluations
         ) const
{
  // simple cross product normal - override to support singular surfaces
  ON_BOOL32 rc = Ev1Der( s, t, point, ds, dt, side, hint );
  if ( rc ) {
    const double len_ds = ds.Length();
    const double len_dt = dt.Length();

    // do not reduce the tolerance used here - there is a retry in the code
    // below.
    if ( len_ds >  ON_SQRT_EPSILON*len_dt && len_dt >  ON_SQRT_EPSILON*len_ds ) 
    {
      ON_3dVector a = ds/len_ds;
      ON_3dVector b = dt/len_dt;
      normal = ON_CrossProduct( a, b );
      rc = normal.Unitize();
    }
    else 
    {
      // see if we have a singular point 
      double v[6][3];
      int normal_side = side;
      ON_BOOL32 bOnSide = false;
      ON_Interval sdom = Domain(0);
      ON_Interval tdom = Domain(1);
		  if (s == sdom.Min()) {
			  normal_side = (normal_side >= 3) ? 4 : 1;
        bOnSide = true;
		  }
		  else if (s == sdom.Max()) {
			  normal_side = (normal_side >= 3) ? 3 : 2;
        bOnSide = true;
		  }
		  if (t == tdom.Min()) {
			  normal_side = (normal_side == 2 || normal_side == 3) ? 2 : 1;
        bOnSide = true;
		  }
		  else if (t == tdom.Max()) {
			  normal_side = (normal_side == 2 || normal_side == 3) ? 3 : 4;
        bOnSide = true;
		  }
      if ( !bOnSide )
      {
        // 2004 November 11 Dale Lear 
        //  Added a retry again with a more generous tolerance
        if ( len_ds >  ON_EPSILON*len_dt && len_dt >  ON_EPSILON*len_ds ) 
        {
          ON_3dVector a = ds/len_ds;
          ON_3dVector b = dt/len_dt;
          normal = ON_CrossProduct( a, b );
          rc = normal.Unitize();
        }
        else
        {
          rc = false;
        }
      }
      else {
        rc = Evaluate( s, t, 2, 3, &v[0][0], normal_side, hint );
        if ( rc ) {
	        rc = ON_EvNormal( normal_side, v[1], v[2], v[3], v[4], v[5], normal);
        }
      }
    }
  }
  if ( !rc ) {
    normal.Zero();
  }
  return rc;
}
Exemplo n.º 28
0
ON_BOOL32 ON_PolyEdgeCurve::ChangeClosedCurveSeam( double t )
{
  //int saved_is_closed_helper = m_is_closed_helper;

  if ( SegmentCount() == 1 )
  {
    // A ON_PolyEdgeSegment cannot have its start/end
    // changed. Split it into two segments and let 
    // ON_PolyCurve::ChangeClosedCurveSeam() do the work.
    if ( !IsClosed() )
      return false;

    ON_Interval crvd = Domain();
    double s = crvd.NormalizedParameterAt(t);

    if ( s <= ON_SQRT_EPSILON || s >= (1.0 - ON_SQRT_EPSILON) )
    {
      s = fmod(s,1.0);
      if ( s < 0.0 )
        s += 1.0;
      if ( fabs(s) <= ON_SQRT_EPSILON || fabs(1.0-s) <= ON_SQRT_EPSILON )
      {
        // split parameter is at start/end of this segemnt
        if ( t != crvd[0] )
        {
          DestroyRuntimeCache();
          SetDomain(t,t+crvd.Length() );
          //m_is_closed_helper = saved_is_closed_helper;
        }
        return true;
      }
      return false;
    }

    ON_PolyEdgeSegment* left_seg = SegmentCurve(0);
    if ( 0 == left_seg )
      return false;

    DestroyRuntimeCache();

    ON_Curve* left = left_seg;
    ON_Curve* right = 0;
    double segt = SegmentCurveParameter(t);
    if ( !left_seg->Split(segt,left,right) )
      return false;
    SetDomain(crvd[0],t);
    
    ON_PolyEdgeSegment* right_seg = ON_PolyEdgeSegment::Cast(right);
    if ( 0 == right_seg )
      return false;
    Append(right_seg);

    double st[3];
    st[0] = crvd[0];
    st[1] = t;
    st[2] = crvd[1];
    SetParameterization( st );
  }

  // ON_PolyCurve::ChangeClosedCurveSeam works fine on
  // two or more segments.
  ON_BOOL32 rc = ON_PolyCurve::ChangeClosedCurveSeam(t);
  //if ( saved_is_closed_helper )
  //  m_is_closed_helper = saved_is_closed_helper;

  return rc;
}
Exemplo n.º 29
0
bool ON_Arc::GetNurbFormParameterFromRadian(double RadianParameter, double* NurbParameter ) const
{
	if(!IsValid() || NurbParameter==NULL) 
		return false;

  ON_Interval ADomain = DomainRadians();

  double endtol = 10.0*ON_EPSILON*(fabs(ADomain[0]) + fabs(ADomain[1]));

  double del = RadianParameter - ADomain[0];
	if(del <= endtol && del >= -ON_SQRT_EPSILON)
  {
		*NurbParameter=ADomain[0];
		return true;
	} 
  else {
    del = ADomain[1] - RadianParameter;
    if(del <= endtol && del >= -ON_SQRT_EPSILON){
		  *NurbParameter=ADomain[1];
		  return true;
    }
	}

	if( !ADomain.Includes(RadianParameter ) )
		return false;


	ON_NurbsCurve crv;

	if( !GetNurbForm(crv))
		return false;

	//Isolate a bezier that contains the solution
	int cnt = crv.SpanCount();	
	int si =0;	//get span index
	int ki=0;		//knot index
	double ang = ADomain[0];
	ON_3dPoint cp;
	cp = crv.PointAt( crv.Knot(0) ) - Center();
	double x = ON_DotProduct(Plane().Xaxis(),cp);
	double y = ON_DotProduct(Plane().Yaxis(),cp);
	double at = atan2( y, x);	//todo make sure we dont go to far

	for( si=0, ki=0; si<cnt; si++, ki+=crv.KnotMultiplicity(ki) ){
		cp = crv.PointAt( crv.Knot(ki+2)) - Center();
		x = ON_DotProduct(Plane().Xaxis(),cp);
		y = ON_DotProduct(Plane().Yaxis(),cp);
		double at2 = atan2(y,x);
		if(at2>at)
			ang+=(at2-at);
		else
			ang += (2*ON_PI + at2 - at);
		at = at2;
		if( ang>RadianParameter)
			break;
	} 

	// Crash Protection trr#55679
	if( ki+2>= crv.KnotCount())
	{
		 *NurbParameter=ADomain[1];
		 return true;		
	}
	ON_Interval BezDomain(crv.Knot(ki), crv.Knot(ki+2));

	ON_BezierCurve bez;
	if(!crv.ConvertSpanToBezier(ki,bez))
		return false;

 	ON_Xform COC;
	COC.ChangeBasis( ON_Plane(),Plane());   

	
	bez.Transform(COC);	// change coordinates to circles local frame
	double a[3];							// Bez coefficients of a quadratic to solve
	for(int i=0; i<3; i++)
		a[i] = tan(RadianParameter)* bez.CV(i)[0] - bez.CV(i)[1];

	//Solve the Quadratic
	double descrim = (a[1]*a[1]) - a[0]*a[2];
	double squared = a[0]-2*a[1]+a[2];
	double tbez;
	if(fabs(squared)> ON_ZERO_TOLERANCE){
		ON_ASSERT(descrim>=0);
		descrim = sqrt(descrim);
		tbez = (a[0]-a[1] + descrim)/(a[0]-2*a[1]+a[2]);
		if( tbez<0 || tbez>1){
			double tbez2 = (a[0]-a[1]-descrim)/(a[0] - 2*a[1] + a[2]);
			if( fabs(tbez2 - .5)<fabs(tbez-.5) )
				tbez = tbez2;
		}

		ON_ASSERT(tbez>=-ON_ZERO_TOLERANCE && tbez<=1+ON_ZERO_TOLERANCE);
	}
	else{
		// Quadratic degenerates to linear
		tbez = 1.0;
		if(a[0]-a[2])
			tbez = a[0]/(a[0]-a[2]);
	}	
	if(tbez<0)
		tbez=0.0;
	else if(tbez>1.0)
		tbez=1.0;


		//Debug ONLY Code  - check the result
//		double aa = a[0]*(1-tbez)*(1-tbez)  + 2*a[1]*tbez*(1-tbez) + a[2]*tbez*tbez;
//		double tantheta= tan(RadianParameter);
//		ON_3dPoint bezp;
//		bez.Evaluate(tbez, 0, 3, bezp);
//		double yx = bezp.y/bezp.x;


	*NurbParameter = BezDomain.ParameterAt(tbez);
	return true;

}
Exemplo n.º 30
0
ON_Surface::ISO 
ON_Surface::IsIsoparametric( const ON_BoundingBox& bbox ) const
{
  ISO iso = not_iso;
  if ( bbox.m_min.z == bbox.m_max.z ) {
    const double ds = bbox.m_max.x - bbox.m_min.x;
    const double dt = bbox.m_max.y - bbox.m_min.y;
    double a, b, s0, s1, t0, t1;
    ON_Interval d = Domain(0);
    s0 = d.Min();
    s1 = d.Max();
    d = Domain(1);
    t0 = d.Min();
    t1 = d.Max();
    double stol = (s1-s0)/32.0;
    double ttol = (t1-t0)/32.0;
    if ( s0 < s1 && t0 < t1 && ( ds <= stol || dt <= ttol) ) 
    {
      if ( ds*(t1-t0) <= dt*(s1-s0) ) 
      {
        // check for s = constant iso
        if ( bbox.m_max.x <= s0+stol ) 
        {
          // check for west side iso
          GetParameterTolerance( 0, s0, &a, &b);
          if ( a <= bbox.m_min.x && bbox.m_max.x <= b  ) 
            iso = W_iso;
        }
        else if ( bbox.m_min.x >= s1-stol ) 
        {
          // check for east side iso
          GetParameterTolerance( 0, s1, &a, &b);
          if ( a <= bbox.m_min.x && bbox.m_max.x <= b  )
            iso = E_iso;
        }

        if ( iso == not_iso && (s0 < bbox.m_max.x || bbox.m_min.x < s1) )
        {
          // check for interior "u = constant" iso
          GetParameterTolerance( 0, 0.5*(bbox.m_min.x+bbox.m_max.x), &a, &b);
          if ( a <= bbox.m_min.x && bbox.m_max.x <= b  )
            iso = x_iso;
        }
      }
      else
      {
        // check for t = constant iso
        if ( bbox.m_max.y <= t0+ttol ) 
        {
          // check for south side iso
          GetParameterTolerance( 1, t0, &a, &b);
          if ( a < bbox.m_min.y && bbox.m_max.y <= b  )
            iso = S_iso;
        }
        else if ( bbox.m_min.y >= t1-ttol ) 
        {
          // check for north side iso
          GetParameterTolerance( 1, t1, &a, &b);
          if ( a < bbox.m_min.y && bbox.m_max.y <= b  )
            iso = N_iso;
        }

        if ( iso == not_iso && (t0 < bbox.m_max.x || bbox.m_min.x < t1) )
        {
          // check for interior "t = constant" iso
          GetParameterTolerance( 1, 0.5*(bbox.m_min.y+bbox.m_max.y), &a, &b);
          if ( a < bbox.m_min.y && bbox.m_max.y <= b  )
            iso = y_iso;
        }
      }
    }
  }
  return iso;
}