opennurbs_linecurve.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 
00019 ON_OBJECT_IMPLEMENT(ON_LineCurve,ON_Curve,"4ED7D4DB-E947-11d3-BFE5-0010830122F0");
00020 
00021 ON_LineCurve::ON_LineCurve()
00022 {
00023   m_line.from.Zero();
00024   m_line.to.Zero();
00025   m_t.m_t[0] = 0.0;
00026   m_t.m_t[1] = 1.0;
00027   m_dim = 3;
00028 }
00029 
00030 ON_LineCurve::ON_LineCurve(const ON_2dPoint& a,const ON_2dPoint& b) : m_line(a,b), m_dim(2)
00031 {
00032   double len = m_line.Length();
00033   if ( len <= ON_ZERO_TOLERANCE )
00034     len = 1.0;
00035   m_t.Set(0.0,len);
00036 }
00037 
00038 ON_LineCurve::ON_LineCurve(const ON_3dPoint& a,const ON_3dPoint& b) : m_line(a,b), m_dim(3)
00039 {
00040   double len = m_line.Length();
00041   if ( len <= ON_ZERO_TOLERANCE )
00042     len = 1.0;
00043   m_t.Set(0.0,len);
00044 }
00045 
00046 
00047 ON_LineCurve::ON_LineCurve( const ON_Line& L ) : m_line(L), m_dim(3)
00048 {
00049   double len = m_line.Length();
00050   if ( len <= ON_ZERO_TOLERANCE )
00051     len = 1.0;
00052   m_t.Set(0.0,len);
00053 }
00054 
00055 ON_LineCurve::ON_LineCurve( const ON_Line& L, double t0, double t1 ) : m_line(L), m_t(t0,t1), m_dim(3)
00056 {
00057 }
00058 
00059 ON_LineCurve::ON_LineCurve( const ON_LineCurve& src )
00060 {
00061   *this = src;
00062 }
00063 
00064 ON_LineCurve::~ON_LineCurve()
00065 {
00066 }
00067 
00068 unsigned int ON_LineCurve::SizeOf() const
00069 {
00070   unsigned int sz = ON_Curve::SizeOf();
00071   sz += (sizeof(*this) - sizeof(ON_Curve));
00072   return sz;
00073 }
00074 
00075 ON__UINT32 ON_LineCurve::DataCRC(ON__UINT32 current_remainder) const
00076 {
00077   current_remainder = ON_CRC32(current_remainder,sizeof(m_line),&m_line);
00078   current_remainder = ON_CRC32(current_remainder,sizeof(m_t),&m_t);
00079   current_remainder = ON_CRC32(current_remainder,sizeof(m_dim),&m_dim);
00080 
00081   return current_remainder;
00082 }
00083 
00084 ON_LineCurve& ON_LineCurve::operator=( const ON_LineCurve& src )
00085 {
00086   if ( this != &src ) {
00087     ON_Curve::operator=(src);
00088     m_line = src.m_line;
00089     m_t = src.m_t;
00090     m_dim  = src.m_dim;
00091   }
00092   return *this;
00093 }
00094 
00095 ON_LineCurve& ON_LineCurve::operator=( const ON_Line& L )
00096 {
00097   m_line = L;
00098   m_t.m_t[0] = 0.0;
00099   m_t.m_t[1] = L.Length();
00100   if ( m_t.m_t[1] == 0.0 )
00101     m_t.m_t[1] = 1.0;
00102   m_dim = 3;
00103   return *this;
00104 }
00105 
00106 int ON_LineCurve::Dimension() const
00107 {
00108   return m_dim;
00109 }
00110 
00111 ON_BOOL32 
00112 ON_LineCurve::GetBBox( // returns true if successful
00113          double* boxmin,    // minimum
00114          double* boxmax,    // maximum
00115          ON_BOOL32 bGrowBox
00116          ) const
00117 {
00118   return ON_GetPointListBoundingBox( m_dim, false, 2, 3, m_line.from, 
00119                       boxmin, boxmax, bGrowBox?true:false
00120                       );
00121 }
00122 
00123 ON_BOOL32
00124 ON_LineCurve::Transform( const ON_Xform& xform )
00125 {
00126   TransformUserData(xform);
00127         DestroyCurveTree();
00128   return m_line.Transform( xform );
00129 }
00130 
00131 bool ON_LineCurve::IsDeformable() const
00132 {
00133   return true;
00134 }
00135 
00136 bool ON_LineCurve::MakeDeformable()
00137 {
00138   return true;
00139 }
00140 
00141 
00142 ON_BOOL32
00143 ON_LineCurve::SwapCoordinates( int i, int j )
00144 {
00145   ON_BOOL32 rc = false;
00146   if ( i >= 0 && i < 3 && j >= 0 && j < 3 && i != j ) {
00147     double t = m_line.from[i];
00148     m_line.from[i] = m_line.from[j];
00149     m_line.from[j] = t;
00150     t = m_line.to[i];
00151     m_line.to[i] = m_line.to[j];
00152     m_line.to[j] = t;
00153     rc = true;
00154   }
00155   return rc;
00156 }
00157 
00158 ON_BOOL32 ON_LineCurve::IsValid( ON_TextLog* text_log ) const
00159 {
00160   return ( m_t[0] < m_t[1] && m_line.Length() > 0.0 ) ? true : false;
00161 }
00162 
00163 void ON_LineCurve::Dump( ON_TextLog& dump ) const
00164 {
00165   dump.Print( "ON_LineCurve:  domain = [%g,%g]\n",m_t[0],m_t[1]);
00166   dump.PushIndent();
00167   dump.Print( "start = ");
00168   dump.Print( m_line.from );
00169   dump.Print( "\nend = ");
00170   dump.Print( m_line.to );
00171   dump.Print( "\n");
00172   dump.Print( "length = %g\n",m_line.Length());
00173   dump.PopIndent();
00174 }
00175 
00176 ON_BOOL32 ON_LineCurve::Write(
00177        ON_BinaryArchive& file // open binary file
00178      ) const
00179 {
00180   ON_BOOL32 rc = file.Write3dmChunkVersion(1,0);
00181   if (rc) {
00182     rc = file.WriteLine( m_line );
00183     if (rc) rc = file.WriteInterval( m_t );
00184     if (rc) rc = file.WriteInt(m_dim);
00185   }
00186   return rc;
00187 }
00188 
00189 ON_BOOL32 ON_LineCurve::Read(
00190        ON_BinaryArchive& file // open binary file
00191      )
00192 {
00193   int major_version = 0;
00194   int minor_version = 0;
00195   ON_BOOL32 rc = file.Read3dmChunkVersion(&major_version,&minor_version);
00196   if (rc && major_version==1) {
00197     // common to all 1.x versions
00198     rc = file.ReadLine( m_line );
00199     if (rc) rc = file.ReadInterval( m_t );
00200     if (rc) rc = file.ReadInt(&m_dim);
00201   }
00202   return rc;
00203 }
00204 
00205 ON_Interval ON_LineCurve::Domain() const
00206 {
00207   return m_t;
00208 }
00209 
00210 ON_BOOL32 ON_LineCurve::SetDomain( double t0, double t1)
00211 {
00212   if (t0 < t1)
00213   {
00214     m_t.Set(t0, t1);
00215                 DestroyCurveTree();
00216     return true;
00217   }
00218   return false;
00219 }
00220 
00221 bool ON_LineCurve::ChangeDimension( int desired_dimension )
00222 {
00223   bool rc = (desired_dimension>=2 && desired_dimension<=3);
00224 
00225   if (rc && m_dim != desired_dimension )
00226   {
00227     DestroyCurveTree();
00228     if ( desired_dimension == 2 )
00229     {
00230       // 7 April 2003 Dale Lear - zero z coords if x coord are set
00231       if( ON_UNSET_VALUE != m_line.from.x )
00232         m_line.from.z = 0.0;
00233       if( ON_UNSET_VALUE != m_line.to.x )
00234         m_line.to.z = 0.0;
00235       m_dim = 2;
00236     }
00237     else
00238     {
00239       if ( 2 == m_dim  )
00240       {
00241         // 7 April 2003 Dale Lear
00242         // zero z coords if x coords are set and z coords are not set
00243         if( ON_UNSET_VALUE != m_line.from.x && ON_UNSET_VALUE == m_line.from.z )
00244           m_line.from.z = 0.0;
00245         if( ON_UNSET_VALUE != m_line.from.x && ON_UNSET_VALUE == m_line.to.z )
00246           m_line.from.z = 0.0;
00247       }
00248       m_dim = 3;
00249     }
00250   }
00251 
00252   return rc;
00253 }
00254 
00255 
00256 int ON_LineCurve::SpanCount() const
00257 {
00258   return 1;
00259 }
00260 
00261 ON_BOOL32 ON_LineCurve::GetSpanVector( // span "knots" 
00262        double* s
00263        ) const
00264 {
00265   s[0] = m_t[0];
00266   s[1] = m_t[1];
00267   return m_t.IsIncreasing();
00268 }
00269 
00270 int ON_LineCurve::Degree() const
00271 {
00272   return 1;
00273 }
00274 
00275 
00276 ON_BOOL32
00277 ON_LineCurve::IsLinear(  // true if curve locus is a line segment
00278       double tolerance   // tolerance to use when checking linearity
00279       ) const
00280 {
00281   return IsValid();
00282 }
00283 
00284 int ON_LineCurve::IsPolyline(
00285       ON_SimpleArray<ON_3dPoint>* pline_points,
00286       ON_SimpleArray<double>* pline_t
00287       ) const
00288 {
00289   int rc = 0;
00290   if ( pline_points )
00291     pline_points->SetCount(0);
00292   if ( pline_t )
00293     pline_t->SetCount(0);
00294   if ( IsValid() )
00295   {
00296     rc = 2;
00297     if ( pline_points )
00298     {
00299       pline_points->Reserve(2);
00300       pline_points->Append( m_line.from );
00301       pline_points->Append( m_line.to );
00302     }
00303     if ( pline_t )
00304     {
00305       pline_t->Reserve(2);
00306       pline_t->Append( m_t[0] );
00307       pline_t->Append( m_t[1] );
00308     }
00309   }
00310   return rc;
00311 }
00312 
00313 
00314 ON_BOOL32
00315 ON_LineCurve::IsArc( // true if curve locus in an arc or circle
00316       const ON_Plane* plane, // if not NULL, test is performed in this plane
00317       ON_Arc* arc,         // if not NULL and true is returned, then arc
00318                               // arc parameters are filled in
00319       double tolerance // tolerance to use when checking linearity
00320       ) const
00321 {
00322   return false;
00323 }
00324 
00325 ON_BOOL32
00326 ON_LineCurve::IsPlanar(
00327       ON_Plane* plane, // if not NULL and true is returned, then plane parameters
00328                          // are filled in
00329       double tolerance // tolerance to use when checking linearity
00330       ) const
00331 {
00332   ON_BOOL32 rc = IsValid();
00333   if ( plane != NULL && rc ) 
00334   {
00335     if ( m_dim == 2 )
00336       rc = ON_Curve::IsPlanar(plane,tolerance);
00337     else if ( !m_line.InPlane(*plane,tolerance) )
00338       m_line.InPlane(*plane,0.0);
00339   }
00340   return rc;
00341 }
00342 
00343 ON_BOOL32
00344 ON_LineCurve::IsInPlane(
00345       const ON_Plane& plane, // plane to test
00346       double tolerance // tolerance to use when checking linearity
00347       ) const
00348 {
00349   ON_BOOL32 rc = false;
00350   double d = fabs( plane.DistanceTo( PointAtStart() ));
00351   if ( d <= tolerance ) {
00352     d = fabs( plane.DistanceTo( PointAtEnd() ));
00353     if ( d <= tolerance )
00354       rc = true;
00355   }
00356   return rc;
00357 }
00358 
00359 ON_BOOL32 
00360 ON_LineCurve::IsClosed() const
00361 {
00362   return false;
00363 }
00364 
00365 ON_BOOL32 
00366 ON_LineCurve::IsPeriodic() const
00367 {
00368   return false;
00369 }
00370 
00371 ON_BOOL32
00372 ON_LineCurve::Reverse()
00373 {
00374   const ON_3dPoint p = m_line.from;
00375   m_line.from = m_line.to;
00376   m_line.to = p;
00377   m_t.Reverse();
00378         DestroyCurveTree();
00379   return true;
00380 }
00381 
00382 ON_BOOL32 ON_LineCurve::Evaluate( // returns false if unable to evaluate
00383        double t,       // evaluation parameter
00384        int der_count,  // number of derivatives (>=0)
00385        int v_stride,   // v[] array stride (>=Dimension())
00386        double* v,      // v[] array of length stride*(ndir+1)
00387        int side,       // optional - determines which side to evaluate from
00388                        //         0 = default
00389                        //      <  0 to evaluate from below, 
00390                        //      >  0 to evaluate from above
00391        int* hint       // optional - evaluation hint (int) used to speed
00392                        //            repeated evaluations
00393        ) const
00394 {
00395   ON_BOOL32 rc = false;
00396   if ( m_t[0] < m_t[1] ) {
00397     double s = (t == m_t[1]) ? 1.0 : (t-m_t[0])/(m_t[1]-m_t[0]);
00398     const ON_3dPoint p = m_line.PointAt(s);
00399     v[0] = p.x;
00400     v[1] = p.y;
00401     if ( m_dim == 3 )
00402       v[2] = p.z;
00403     if ( der_count >= 1 ) 
00404     {
00405       v += v_stride;
00406       ON_3dVector d = m_line.to - m_line.from;
00407       double dt = m_t[1] - m_t[0];
00408       v[0] = d.x/dt;
00409       v[1] = d.y/dt;
00410       if ( m_dim == 3 )
00411         v[2] = d.z/dt;
00412       for ( int di = 2; di <= der_count; di++ ) {
00413         v += v_stride;
00414         v[0] = 0.0;
00415         v[1] = 0.0;
00416         if ( m_dim == 3 )
00417           v[2] = 0.0;
00418       }
00419     }
00420     rc = true;
00421   }
00422   return rc;
00423 }
00424 
00425 ON_BOOL32 ON_LineCurve::SetStartPoint(ON_3dPoint start_point)
00426 {
00427   m_line.from = start_point;
00428         DestroyCurveTree();
00429   return true;
00430 }
00431 
00432 ON_BOOL32 ON_LineCurve::SetEndPoint(ON_3dPoint end_point)
00433 {
00434   m_line.to = end_point;
00435         DestroyCurveTree();
00436   return true;
00437 }
00438 
00439 
00440 int ON_LineCurve::GetNurbForm(
00441       ON_NurbsCurve& c,
00442       double tolerance,
00443       const ON_Interval* subdomain
00444       ) const
00445 {
00446   int rc = 0;
00447   if ( c.Create( m_dim==2?2:3, false, 2, 2 ) ) 
00448   {
00449     rc = 1;
00450     double t0 = m_t[0];
00451     double t1 = m_t[1];
00452     if (subdomain )
00453     {
00454       if ( t0 < t1 )
00455       {
00456         const ON_Interval& sd = *subdomain;
00457         double s0 = sd[0];
00458         double s1 = sd[1];
00459         if (s0 < t0) s0 = t0;
00460         if (s1 > t1) s1 = t1;
00461         if (s0 < s1)
00462         {
00463           t0 = s0;
00464           t1 = s1;
00465         }
00466         else
00467           rc = 0;
00468       }
00469       else
00470       {
00471         rc = 0;
00472       }
00473     }  
00474     if ( t0 < t1 )
00475     {
00476       c.m_knot[0] = t0;
00477       c.m_knot[1] = t1;
00478       c.SetCV( 0, PointAt(t0));
00479       c.SetCV( 1, PointAt(t1));
00480     }
00481     else if ( t0 > t1 )
00482     {
00483       rc = 0;
00484       c.m_knot[0] = t1;
00485       c.m_knot[1] = t0;
00486       c.SetCV( 0, PointAt(t1));
00487       c.SetCV( 1, PointAt(t0));
00488     }
00489     else
00490     {
00491       rc = 0;
00492       c.m_knot[0] = 0.0;
00493       c.m_knot[1] = 1.0;
00494       c.SetCV( 0, m_line.from );
00495       c.SetCV( 1, m_line.to );
00496     }
00497   }
00498   return rc;
00499 }
00500 
00501 int ON_LineCurve::HasNurbForm() const
00502 
00503 {
00504   if (!IsValid())
00505     return 0;
00506   return 1;
00507 }
00508 
00509 
00510 
00511 ON_BOOL32 ON_LineCurve::Trim( const ON_Interval& domain )
00512 {
00513   ON_BOOL32 rc = false;
00514   if ( domain.IsIncreasing() )
00515   {
00516     DestroyCurveTree();
00517     ON_3dPoint p = PointAt( domain[0] );
00518     ON_3dPoint q = PointAt( domain[1] );
00519                 if( p.DistanceTo(q)>0){                                                         // 2 April 2003 Greg Arden A successfull trim 
00520                                                                                                                                                                         // should return an IsValid ON_LineCurve .
00521                         m_line.from = p;
00522                         m_line.to = q;
00523                         m_t = domain;
00524                         rc = true;
00525                 }
00526   }
00527         DestroyCurveTree();
00528   return rc;
00529 }
00530 
00531 
00532 bool ON_LineCurve::Extend(
00533   const ON_Interval& domain
00534   )
00535 
00536 {
00537   double len = Domain().Length();
00538   ON_3dVector V = m_line.Direction();
00539   ON_3dPoint Q0 = m_line.from;
00540   ON_3dPoint Q1 = m_line.to;
00541   double t0 = Domain()[0];
00542   double t1 = Domain()[1];
00543   bool do_it = false;
00544   if (domain[1] > Domain()[1]) {
00545     Q1 += (domain[1]-Domain()[1])/len*V;
00546     t1 = domain[1];
00547     do_it = true;
00548   }
00549   if (domain[0] < Domain()[0]) {
00550     Q0 += (domain[0]-Domain()[0])/len*V;
00551     t0 = domain[0];
00552     do_it = true;
00553   }
00554 
00555   if (do_it){
00556     m_line = ON_Line(Q0, Q1);
00557     SetDomain(t0, t1);
00558     DestroyCurveTree();
00559   }
00560   return do_it;
00561 }
00562 
00563 ON_BOOL32 ON_LineCurve::Split( 
00564       double t,
00565       ON_Curve*& left_side,
00566       ON_Curve*& right_side
00567     ) const
00568 
00569 {
00570   ON_BOOL32 rc = false;
00571   if ( m_t.Includes(t,true) )
00572   {
00573     const int dim = m_dim;
00574     double t0 = m_t[0];
00575     double t1 = m_t[1];
00576     ON_Line left, right;
00577     left.from = m_line.from;
00578     left.to = m_line.PointAt(m_t.NormalizedParameterAt(t));
00579     right.from = left.to;
00580     right.to = m_line.to;
00581 
00582                 // 27 March 2003, Greg Arden.  Result must pass IsValid()
00583                 if( left.Length()==0 || right.Length()==0)
00584                         return false;
00585 
00586     ON_LineCurve* left_line = ON_LineCurve::Cast(left_side);
00587     ON_LineCurve* right_line = ON_LineCurve::Cast(right_side);
00588     if ( left_side && !left_line )
00589     {
00590       ON_ERROR("ON_LineCurve::Split - input left_side not an ON_LineCurve*");
00591       return false;
00592     }
00593     if ( right_side && !right_line )
00594     {
00595       ON_ERROR("ON_LineCurve::Split - input right_side not an ON_LineCurve*");
00596       return false;
00597     }
00598     if ( !left_line )
00599     {
00600       left_line = new ON_LineCurve();
00601       left_side = left_line;
00602     }
00603     if ( !right_line )
00604     {
00605       right_line = new ON_LineCurve();
00606       right_side = right_line;
00607     }
00608 
00609     left_line->DestroyCurveTree();
00610     left_line->m_line = left;
00611     left_line->m_t.Set( t0, t );
00612     left_line->m_dim = dim;
00613 
00614     right_line->DestroyCurveTree();
00615     right_line->m_line = right;
00616     right_line->m_t.Set( t, t1 );
00617     right_line->m_dim = dim;
00618 
00619     rc = true;
00620   }
00621   return rc;
00622 }
00623 
00624 ON_BOOL32 ON_LineCurve::GetCurveParameterFromNurbFormParameter(
00625       double nurbs_t,
00626       double* curve_t
00627       ) const
00628 {
00629   *curve_t = nurbs_t;
00630   return true;
00631 }
00632 
00633 ON_BOOL32 ON_LineCurve::GetNurbFormParameterFromCurveParameter(
00634       double curve_t,
00635       double* nurbs_t
00636       ) const
00637 {
00638   *nurbs_t = curve_t;
00639   return true;
00640 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:01