00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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(
00113 double* boxmin,
00114 double* boxmax,
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
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
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
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
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
00242
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(
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(
00278 double tolerance
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(
00316 const ON_Plane* plane,
00317 ON_Arc* arc,
00318
00319 double tolerance
00320 ) const
00321 {
00322 return false;
00323 }
00324
00325 ON_BOOL32
00326 ON_LineCurve::IsPlanar(
00327 ON_Plane* plane,
00328
00329 double tolerance
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,
00346 double tolerance
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(
00383 double t,
00384 int der_count,
00385 int v_stride,
00386 double* v,
00387 int side,
00388
00389
00390
00391 int* hint
00392
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){
00520
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
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 }