00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00017
00018 ON_OBJECT_IMPLEMENT(ON_PlaneSurface,ON_Surface,"4ED7D4DF-E947-11d3-BFE5-0010830122F0");
00019 ON_OBJECT_IMPLEMENT(ON_ClippingPlaneSurface,ON_PlaneSurface,"DBC5A584-CE3F-4170-98A8-497069CA5C36");
00020
00021
00022 ON_PlaneSurface::ON_PlaneSurface()
00023 {}
00024
00025 ON_PlaneSurface::ON_PlaneSurface( const ON_PlaneSurface& src )
00026 {
00027 *this = src;
00028 }
00029
00030 ON_PlaneSurface& ON_PlaneSurface::operator=( const ON_PlaneSurface& src )
00031 {
00032 if ( this != &src ) {
00033 ON_Surface::operator=(src);
00034 m_plane = src.m_plane;
00035 m_domain[0] = src.m_domain[0];
00036 m_domain[1] = src.m_domain[1];
00037 m_extents[0] = src.m_extents[0];
00038 m_extents[1] = src.m_extents[1];
00039 }
00040 return *this;
00041 }
00042
00043 ON_PlaneSurface::ON_PlaneSurface( const ON_Plane& src )
00044 {
00045 *this = src;
00046 }
00047
00048
00049 unsigned int ON_PlaneSurface::SizeOf() const
00050 {
00051 unsigned int sz = ON_Surface::SizeOf();
00052 sz += (sizeof(*this) - sizeof(ON_Surface));
00053 return sz;
00054 }
00055
00056 ON__UINT32 ON_PlaneSurface::DataCRC(ON__UINT32 current_remainder) const
00057 {
00058 current_remainder = ON_CRC32(current_remainder,sizeof(m_plane),&m_plane);
00059 current_remainder = ON_CRC32(current_remainder,2*sizeof(m_domain[0]),&m_domain[0]);
00060 current_remainder = ON_CRC32(current_remainder,2*sizeof(m_extents[0]),&m_extents[0]);
00061 return current_remainder;
00062 }
00063
00064
00065 ON_PlaneSurface& ON_PlaneSurface::operator=( const ON_Plane& src )
00066 {
00067 m_plane = src;
00068 m_domain[0].Set(0.0,1.0);
00069 m_domain[1].Set(0.0,1.0);
00070 m_extents[0] = m_domain[0];
00071 m_extents[1] = m_domain[1];
00072 return *this;
00073 }
00074
00075 ON_PlaneSurface::~ON_PlaneSurface()
00076 {}
00077
00078 ON_BOOL32
00079 ON_PlaneSurface::IsValid( ON_TextLog* text_log ) const
00080 {
00081 return ( m_plane.IsValid()
00082 && m_domain[0].IsIncreasing() && m_domain[1].IsIncreasing()
00083 && m_extents[0].IsIncreasing() && m_extents[1].IsIncreasing()
00084 ) ? true : false;
00085 }
00086
00087 void
00088 ON_PlaneSurface::Dump( ON_TextLog& dump ) const
00089 {
00090 dump.Print("ON_PlaneSurface\n");
00091 }
00092
00093 ON_BOOL32
00094 ON_PlaneSurface::Write(
00095 ON_BinaryArchive& file
00096 ) const
00097 {
00098 ON_BOOL32 rc = file.Write3dmChunkVersion(1,1);
00099
00100
00101 if (rc)
00102 rc = file.WritePlane( m_plane );
00103 if (rc)
00104 rc = file.WriteInterval( m_domain[0] );
00105 if (rc)
00106 rc = file.WriteInterval( m_domain[1] );
00107
00108
00109 if (rc)
00110 rc = file.WriteInterval( m_extents[0] );
00111 if (rc)
00112 rc = file.WriteInterval( m_extents[1] );
00113 return rc;
00114 }
00115
00116 ON_BOOL32
00117 ON_PlaneSurface::Read(
00118 ON_BinaryArchive& file
00119 )
00120 {
00121 int major_version = 0;
00122 int minor_version = 0;
00123 ON_BOOL32 rc = file.Read3dmChunkVersion(&major_version,&minor_version);
00124 if (rc && major_version == 1) {
00125
00126 if (rc)
00127 rc = file.ReadPlane( m_plane );
00128 if (rc)
00129 rc = file.ReadInterval( m_domain[0] );
00130 if (rc)
00131 rc = file.ReadInterval( m_domain[1] );
00132 m_extents[0] = m_domain[0];
00133 m_extents[1] = m_domain[1];
00134 if ( minor_version >= 1 )
00135 {
00136 if (rc)
00137 rc = file.ReadInterval( m_extents[0] );
00138 if (rc)
00139 rc = file.ReadInterval( m_extents[1] );
00140 }
00141 }
00142 return rc;
00143 }
00144
00145 int
00146 ON_PlaneSurface::Dimension() const
00147 {
00148 return 3;
00149 }
00150
00151 ON_BOOL32
00152 ON_PlaneSurface::GetBBox(
00153 double* boxmin,
00154 double* boxmax,
00155 ON_BOOL32 bGrowBox
00156 ) const
00157 {
00158 int i,j,k=0;
00159 ON_3dPoint corner[4];
00160 for ( i = 0; i < 2; i++ ) for ( j = 0; j < 2; j++ ) {
00161 corner[k++] = PointAt( m_domain[0].m_t[i], m_domain[1].m_t[j] );
00162 }
00163 return ON_GetPointListBoundingBox( 3, 0, 4, 3,
00164 &corner[0].x,
00165 boxmin,
00166 boxmax, bGrowBox?true:false );
00167 }
00168
00169 ON_BOOL32
00170 ON_PlaneSurface::Transform( const ON_Xform& xform )
00171 {
00172 TransformUserData(xform);
00173 ON_3dPoint p = m_plane.origin + m_extents[0][0]*m_plane.xaxis + m_extents[1][0]*m_plane.yaxis;
00174 ON_3dPoint q = m_plane.origin + m_extents[0][1]*m_plane.xaxis + m_extents[1][1]*m_plane.yaxis;
00175 bool rc = m_plane.Transform( xform )?true:false;
00176 if (rc && fabs(fabs(xform.Determinant())-1.0) > ON_SQRT_EPSILON )
00177 {
00178 p = xform*p;
00179 q = xform*q;
00180 double x0, x1, y0, y1;
00181 rc = false;
00182 if ( m_plane.ClosestPointTo(p,&x0,&y0) && m_plane.ClosestPointTo(q,&x1,&y1) )
00183 {
00184 if ( x0 < x1 && y0 < y1 )
00185 {
00186 m_extents[0].Set(x0,x1);
00187 m_extents[1].Set(y0,y1);
00188 rc = true;
00189 }
00190 }
00191 }
00192 return rc;
00193 }
00194
00195 ON_Interval ON_PlaneSurface::Domain( int dir ) const
00196 {
00197
00198 return dir ? m_domain[1] : m_domain[0];
00199 }
00200
00201 int ON_PlaneSurface::SpanCount( int dir ) const
00202 {
00203 return 1;
00204 }
00205
00206 ON_BOOL32 ON_PlaneSurface::GetSurfaceSize(
00207 double* width,
00208 double* height
00209 ) const
00210 {
00211 if ( width )
00212 *width = Extents(0).Length();
00213 if ( height )
00214 *height = Extents(1).Length();
00215 return true;
00216 }
00217
00218
00219 ON_BOOL32 ON_PlaneSurface::GetSpanVector( int dir, double* s ) const
00220 {
00221 ON_Interval d = Domain(dir);
00222 s[0] = d.Min();
00223 s[1] = d.Max();
00224 return d.IsIncreasing();
00225 }
00226
00227 int ON_PlaneSurface::Degree( int dir ) const
00228 {
00229 return 1;
00230 }
00231
00232 ON_BOOL32
00233 ON_PlaneSurface::GetParameterTolerance(
00234 int dir,
00235 double t,
00236 double* tminus,
00237 double* tplus
00238 ) const
00239 {
00240 dir = (dir)?1:0;
00241 return ON_GetParameterTolerance( m_domain[dir][0], m_domain[dir][1], t, tminus, tplus );
00242 }
00243
00244 ON_BOOL32 ON_PlaneSurface::IsPlanar( ON_Plane* plane, double tolerance ) const
00245 {
00246 if ( plane )
00247 *plane = this->m_plane;
00248 return true;
00249 }
00250
00251 ON_BOOL32
00252 ON_PlaneSurface::IsClosed( int dir ) const
00253 {
00254 return false;
00255 }
00256
00257 ON_BOOL32
00258 ON_PlaneSurface::IsPeriodic( int dir ) const
00259 {
00260 return false;
00261 }
00262
00263 ON_BOOL32
00264 ON_PlaneSurface::IsSingular( int side ) const
00265 {
00266 return false;
00267 }
00268
00269 bool ON_PlaneSurface::GetNextDiscontinuity(
00270 int dir,
00271 ON::continuity c,
00272 double t0,
00273 double t1,
00274 double* t,
00275 int* hint,
00276 int* dtype,
00277 double cos_angle_tolerance,
00278 double curvature_tolerance
00279 ) const
00280 {
00281 return ON_Surface::GetNextDiscontinuity(dir,c,t0,t1,t,hint,dtype,cos_angle_tolerance,curvature_tolerance);
00282 }
00283
00284 ON_BOOL32
00285 ON_PlaneSurface::Reverse( int dir )
00286 {
00287 if ( dir < 0 || dir > 1 )
00288 return false;
00289 m_extents[dir].Reverse();
00290 m_domain[dir].Reverse();
00291 if ( dir )
00292 m_plane.yaxis.Reverse();
00293 else
00294 m_plane.xaxis.Reverse();
00295 m_plane.zaxis.Reverse();
00296 m_plane.UpdateEquation();
00297 return true;
00298 }
00299
00300 bool ON_PlaneSurface::IsContinuous(
00301 ON::continuity desired_continuity,
00302 double s,
00303 double t,
00304 int* hint,
00305 double point_tolerance,
00306 double d1_tolerance,
00307 double d2_tolerance,
00308 double cos_angle_tolerance,
00309 double curvature_tolerance
00310 ) const
00311 {
00312 return true;
00313 }
00314
00315 ON_BOOL32
00316 ON_PlaneSurface::Transpose()
00317 {
00318
00319 m_plane.Flip();
00320
00321 ON_Interval i = m_domain[0];
00322 m_domain[0] = m_domain[1];
00323 m_domain[1] = i;
00324
00325 i = m_extents[0];
00326 m_extents[0] = m_extents[1];
00327 m_extents[1] = i;
00328
00329 return true;
00330 }
00331
00332 ON_BOOL32
00333 ON_PlaneSurface::Evaluate(
00334 double s, double t,
00335 int der_count,
00336 int v_stride,
00337 double* v,
00338 int side,
00339
00340
00341
00342 int* hint
00343
00344 ) const
00345 {
00346 double ds = 1.0;
00347 double dt = 1.0;
00348 if ( m_extents[0] != m_domain[0] )
00349 {
00350 s = m_extents[0].ParameterAt( m_domain[0].NormalizedParameterAt(s) );
00351 ds = m_extents[0].Length()/m_domain[0].Length();
00352 }
00353 if ( m_extents[1] != m_domain[1] )
00354 {
00355 t = m_extents[1].ParameterAt( m_domain[1].NormalizedParameterAt(t) );
00356 dt = m_extents[1].Length()/m_domain[1].Length();
00357 }
00358 ON_3dPoint P = m_plane.PointAt( s, t );
00359 v[0] = P.x;
00360 v[1] = P.y;
00361 v[2] = P.z;
00362 v += v_stride;
00363 if ( der_count >= 1 )
00364 {
00365 v[0] = ds*m_plane.xaxis.x;
00366 v[1] = ds*m_plane.xaxis.y;
00367 v[2] = ds*m_plane.xaxis.z;
00368 v += v_stride;
00369
00370 v[0] = dt*m_plane.yaxis.x;
00371 v[1] = dt*m_plane.yaxis.y;
00372 v[2] = dt*m_plane.yaxis.z;
00373 v += v_stride;
00374
00375 if ( der_count > 1 )
00376 {
00377
00378 memset( v, 0, (((der_count+1)*(der_count+2)/2-4)*v_stride+3)*sizeof(*v) );
00379 }
00380 }
00381 return true;
00382 }
00383
00384 ON_Curve* ON_PlaneSurface::IsoCurve( int dir, double c ) const
00385 {
00386 ON_LineCurve* line_curve = 0;
00387 if ( (dir == 0 || dir == 1) && IsValid() )
00388 {
00389 ON_Line line;
00390 ON_Interval domain = Domain(dir);
00391 if ( dir == 1 )
00392 {
00393 line.from = PointAt( c, domain[0] );
00394 line.to = PointAt( c, domain[1] );
00395 }
00396 else
00397 {
00398 line.from = PointAt( domain[0], c );
00399 line.to = PointAt( domain[1], c );
00400 }
00401 line_curve = new ON_LineCurve(line);
00402 line_curve->m_dim = 3;
00403 line_curve->m_t = domain;
00404 }
00405 return line_curve;
00406 }
00407
00408 ON_BOOL32 ON_PlaneSurface::Trim(
00409 int dir,
00410 const ON_Interval& domain
00411 )
00412 {
00413 if ( dir < 0 || dir > 1 )
00414 return false;
00415 ON_Interval current_domain = Domain(dir);
00416 if ( current_domain[0] == ON_UNSET_VALUE && current_domain[1] == ON_UNSET_VALUE )
00417 current_domain = domain;
00418 ON_Interval trim_domain, trim_extents = m_extents[dir];
00419 trim_domain.Intersection(domain, Domain(dir) );
00420 if ( !trim_domain.IsIncreasing() )
00421 return false;
00422 if ( m_domain[dir] == m_extents[dir] )
00423 trim_extents = trim_domain;
00424 else
00425 {
00426 double x0 = m_extents[dir].ParameterAt( m_domain[dir].NormalizedParameterAt( trim_domain[0] ) );
00427 double x1 = m_extents[dir].ParameterAt( m_domain[dir].NormalizedParameterAt( trim_domain[1] ) );
00428 trim_extents.Set(x0,x1);
00429 }
00430 if ( !trim_extents.IsIncreasing() )
00431 return false;
00432 m_extents[dir] = trim_extents;
00433 m_domain[dir] = trim_domain;
00434 return true;
00435 }
00436
00437 bool ON_PlaneSurface::Extend(
00438 int dir,
00439 const ON_Interval& domain
00440 )
00441 {
00442 if ( dir < 0 || dir > 1 ) return false;
00443 bool changed = false;
00444 ON_Interval tdom = Domain(dir);
00445 ON_Interval xdom = m_extents[dir];
00446
00447 if (domain[0] < Domain(dir)[0]){
00448 changed = true;
00449 tdom[0] = domain[0];
00450 xdom[0] = m_extents[dir].ParameterAt( m_domain[dir].NormalizedParameterAt(domain[0]));
00451 }
00452 if (domain[1] > Domain(dir)[1]){
00453 changed = true;
00454 tdom[1] = domain[1];
00455 xdom[1] = m_extents[dir].ParameterAt( m_domain[dir].NormalizedParameterAt(domain[1]));
00456 }
00457 if (!changed) return false;
00458 DestroySurfaceTree();
00459
00460 m_domain[dir] = tdom;
00461 m_extents[dir] = xdom;
00462 return true;
00463 }
00464
00465 ON_BOOL32 ON_PlaneSurface::Split(
00466 int dir,
00467 double c,
00468 ON_Surface*& west_or_south_side,
00469 ON_Surface*& east_or_north_side
00470 ) const
00471 {
00472 ON_PlaneSurface* ws_side = 0;
00473 ON_PlaneSurface* en_side = 0;
00474
00475 if ( dir < 0 || dir > 1 )
00476 return false;
00477 if ( !Domain(dir).Includes(c,true) )
00478 return false;
00479
00480 double t;
00481 if ( Domain(dir) == Extents(dir) )
00482 t = c;
00483 else
00484 {
00485 t = Extents(dir).ParameterAt( Domain(dir).NormalizedParameterAt(c) );
00486 if ( !Extents(dir).Includes(t,true) )
00487 return false;
00488 }
00489
00490 if ( west_or_south_side )
00491 {
00492 if ( west_or_south_side == east_or_north_side )
00493 return false;
00494 ws_side = ON_PlaneSurface::Cast(west_or_south_side);
00495 if ( !ws_side )
00496 return false;
00497 }
00498
00499 if ( east_or_north_side )
00500 {
00501 en_side = ON_PlaneSurface::Cast(east_or_north_side);
00502 if ( !en_side )
00503 return false;
00504 }
00505
00506 if ( !ws_side )
00507 ws_side = new ON_PlaneSurface();
00508 if ( !en_side )
00509 en_side = new ON_PlaneSurface();
00510
00511 *ws_side = *this;
00512 *en_side = *this;
00513 ws_side->m_domain[dir].m_t[1] = c;
00514 en_side->m_domain[dir].m_t[0] = c;
00515 ws_side->m_extents[dir].m_t[1] = t;
00516 en_side->m_extents[dir].m_t[0] = t;
00517
00518 west_or_south_side = ws_side;
00519 east_or_north_side = en_side;
00520
00521 return true;
00522 }
00523
00524 bool ON_PlaneSurface::GetClosestPoint( const ON_3dPoint& test_point,
00525 double* s,double* t,
00526 double maximum_distance,
00527 const ON_Interval* sdomain,
00528 const ON_Interval* tdomain
00529 ) const
00530 {
00531 double u = 0.0, v=0.0;
00532
00533 ON_Interval sdom = Domain(0);
00534 ON_Interval tdom = Domain(1);
00535 if(sdomain==NULL)
00536 sdomain = &sdom;
00537 if(tdomain==NULL)
00538 tdomain = &tdom;
00539
00540 bool rc = m_plane.ClosestPointTo( test_point, &u, &v );
00541 if ( rc )
00542 {
00543
00544 if ( m_domain[0] != m_extents[0] )
00545 {
00546 u = m_domain[0].ParameterAt( m_extents[0].NormalizedParameterAt(u) );
00547 }
00548 if ( m_domain[1] != m_extents[1] )
00549 {
00550 v = m_domain[1].ParameterAt( m_extents[1].NormalizedParameterAt(v) );
00551 }
00552
00553 if ( u < sdomain->Min() )
00554 u = sdomain->Min();
00555 else if ( u > sdomain->Max() )
00556 u = sdomain->Max();
00557
00558 if ( v < tdomain->Min() )
00559 v = tdomain->Min();
00560 else if ( v > tdomain->Max() )
00561 v = tdomain->Max();
00562
00563 if ( s )
00564 *s = u;
00565 if ( t )
00566 *t = v;
00567 if (maximum_distance > 0.0)
00568 {
00569 ON_3dPoint pt = PointAt(u,v);
00570 if ( test_point.DistanceTo(pt) > maximum_distance )
00571 rc = false;
00572 }
00573 }
00574 return rc;
00575 }
00576
00578
00579
00580
00581
00582
00583
00584
00585 ON_BOOL32 ON_PlaneSurface::GetLocalClosestPoint( const ON_3dPoint& test_point,
00586 double s0, double t0,
00587 double* s,double* t,
00588 const ON_Interval* sdomain,
00589 const ON_Interval* tdomain
00590 ) const
00591 {
00592
00593 return GetClosestPoint(test_point,s,t,0.0,sdomain,tdomain);
00594 }
00595
00596
00597 ON_Surface* ON_PlaneSurface::Offset(
00598 double offset_distance,
00599 double tolerance,
00600 double* max_deviation
00601 ) const
00602 {
00603 if ( max_deviation )
00604 *max_deviation = 0.0;
00605 ON_PlaneSurface* offset_srf = new ON_PlaneSurface(*this);
00606 ON_3dVector delta = offset_srf->m_plane.zaxis;
00607 double d = delta.Length();
00608 if ( fabs(1.0-d) <= ON_SQRT_EPSILON )
00609 d = 1.0;
00610 d = offset_distance/d;
00611 offset_srf->m_plane.origin = offset_srf->m_plane.origin + (d*delta);
00612 offset_srf->m_plane.UpdateEquation();
00613 return offset_srf;
00614 }
00615
00616
00617 int
00618 ON_PlaneSurface::GetNurbForm(
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 ON_NurbsSurface& nurbs,
00629 double tolerance
00630 ) const
00631 {
00632 ON_BOOL32 rc = IsValid();
00633
00634 if( !rc )
00635 {
00636 if ( m_plane.origin.x != ON_UNSET_VALUE
00637 && m_plane.xaxis.x != ON_UNSET_VALUE
00638 && m_plane.yaxis.x != ON_UNSET_VALUE
00639 && m_domain[0].IsIncreasing() && m_domain[1].IsIncreasing()
00640 && m_extents[0].Length() > 0.0 && m_extents[1].Length() > 0.0
00641 )
00642 {
00643 ON_3dVector N = ON_CrossProduct(m_plane.xaxis,m_plane.yaxis);
00644 if ( N.Length() <= 1.0e-4 )
00645 {
00646 ON_WARNING("ON_PlaneSurface::GetNurbForm - using invalid surface.");
00647 rc = true;
00648 }
00649 }
00650 }
00651
00652 if ( rc )
00653 {
00654 nurbs.m_dim = 3;
00655 nurbs.m_is_rat = 0;
00656 nurbs.m_order[0] = nurbs.m_order[1] = 2;
00657 nurbs.m_cv_count[0] = nurbs.m_cv_count[1] = 2;
00658 nurbs.m_cv_stride[1] = nurbs.m_dim;
00659 nurbs.m_cv_stride[0] = nurbs.m_cv_stride[1]*nurbs.m_cv_count[1];
00660 nurbs.ReserveCVCapacity(12);
00661 nurbs.ReserveKnotCapacity(0,2);
00662 nurbs.ReserveKnotCapacity(1,2);
00663 nurbs.m_knot[0][0] = m_domain[0][0];
00664 nurbs.m_knot[0][1] = m_domain[0][1];
00665 nurbs.m_knot[1][0] = m_domain[1][0];
00666 nurbs.m_knot[1][1] = m_domain[1][1];
00667 nurbs.SetCV( 0, 0, PointAt( m_domain[0][0], m_domain[1][0] ));
00668 nurbs.SetCV( 0, 1, PointAt( m_domain[0][0], m_domain[1][1] ));
00669 nurbs.SetCV( 1, 0, PointAt( m_domain[0][1], m_domain[1][0] ));
00670 nurbs.SetCV( 1, 1, PointAt( m_domain[0][1], m_domain[1][1] ));
00671 }
00672
00673 return rc;
00674 }
00675
00676 int
00677 ON_PlaneSurface::HasNurbForm(
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 ) const
00688
00689 {
00690 if (!IsValid())
00691 return 0;
00692 return 1;
00693 }
00694
00695 bool ON_PlaneSurface::SetExtents(
00696 int dir,
00697 ON_Interval extents,
00698 bool bSyncDomain
00699 )
00700 {
00701 if ( dir < 0 || dir > 1 || !extents.IsIncreasing() )
00702 return false;
00703 m_extents[dir] = extents;
00704 if ( bSyncDomain )
00705 m_domain[dir] = m_extents[dir];
00706 return true;
00707 }
00708
00709 ON_Interval ON_PlaneSurface::Extents(
00710 int dir
00711 ) const
00712 {
00713
00714 return dir ? m_extents[1] : m_extents[0];
00715 }
00716
00717 bool ON_PlaneSurface::CreatePseudoInfinitePlane(
00718 ON_PlaneEquation plane_equation,
00719 const ON_BoundingBox& bbox,
00720 double padding
00721 )
00722 {
00723 ON_Plane plane(&plane_equation.x);
00724 return CreatePseudoInfinitePlane(plane,bbox,padding);
00725 }
00726
00727 bool ON_PlaneSurface::CreatePseudoInfinitePlane(
00728 const ON_Plane& plane,
00729 const ON_BoundingBox& bbox,
00730 double padding
00731 )
00732 {
00733 ON_3dPoint bbox_corners[8];
00734 if ( !bbox.GetCorners(bbox_corners) )
00735 return false;
00736 return CreatePseudoInfinitePlane(plane,8,bbox_corners,padding);
00737 }
00738
00739 bool ON_PlaneSurface::CreatePseudoInfinitePlane(
00740 const ON_Plane& plane,
00741 int point_count,
00742 const ON_3dPoint* point_list,
00743 double padding
00744 )
00745 {
00746 if ( !plane.IsValid() )
00747 return false;
00748 if ( point_count < 1 )
00749 return false;
00750 if ( 0 == point_list )
00751 return false;
00752 if ( !ON_IsValid(padding) || padding < 0.0 )
00753 return false;
00754
00755 ON_Interval plane_domain[2];
00756 double s, t;
00757 s = ON_UNSET_VALUE;
00758 t = ON_UNSET_VALUE;
00759 if ( !plane.ClosestPointTo( point_list[0], &s, &t ) || !ON_IsValid(s) || !ON_IsValid(t) )
00760 return 0;
00761 plane_domain[0].m_t[1] = plane_domain[0].m_t[0] = s;
00762 plane_domain[1].m_t[1] = plane_domain[1].m_t[0] = t;
00763
00764 for ( int i = 1; i < point_count; i++ )
00765 {
00766 s = ON_UNSET_VALUE;
00767 t = ON_UNSET_VALUE;
00768 if ( !plane.ClosestPointTo( point_list[i], &s, &t ) || !ON_IsValid(s) || !ON_IsValid(t) )
00769 return 0;
00770 if ( s < plane_domain[0].m_t[0] ) plane_domain[0].m_t[0] = s; else if ( s > plane_domain[0].m_t[1] ) plane_domain[0].m_t[1] = s;
00771 if ( t < plane_domain[1].m_t[0] ) plane_domain[1].m_t[0] = t; else if ( t > plane_domain[1].m_t[1] ) plane_domain[1].m_t[1] = t;
00772 }
00773
00774 s = padding*plane_domain[0].Length() + padding;
00775 if ( !(s > 0.0) && !plane_domain[0].IsIncreasing() )
00776 s = 1.0;
00777 plane_domain[0].m_t[0] -= s;
00778 plane_domain[0].m_t[1] += s;
00779
00780 t = padding*plane_domain[1].Length() + padding;
00781 if ( !(t > 0.0) && !plane_domain[1].IsIncreasing() )
00782 t = 1.0;
00783 plane_domain[1].m_t[0] -= t;
00784 plane_domain[1].m_t[1] += t;
00785
00786 m_plane = plane;
00787 m_domain[0] = plane_domain[0];
00788 m_domain[1] = plane_domain[1];
00789 m_extents[0] = plane_domain[0];
00790 m_extents[1] = plane_domain[1];
00791
00792 return IsValid()?true:false;
00793 }
00794
00795
00796
00797 ON_BOOL32 ON_PlaneSurface::SetDomain(
00798 int dir,
00799 double t0,
00800 double t1
00801 )
00802 {
00803 bool rc = false;
00804 if ( dir >= 0 && dir <= 1 && t0 < t1 )
00805 {
00806 rc = true;
00807 m_domain[dir].Set(t0,t1);
00808 DestroySurfaceTree();
00809 }
00810 return rc;
00811 }
00812
00813 void ON_ClippingPlaneInfo::Default()
00814 {
00815 memset(this,0,sizeof(*this));
00816 }
00817
00818 bool ON_ClippingPlaneInfo::Write( ON_BinaryArchive& file ) const
00819 {
00820 bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00821 if (!rc)
00822 return false;
00823
00824 for(;;)
00825 {
00826 rc = file.WritePlaneEquation(m_plane_equation);
00827 if (!rc) break;
00828
00829 rc = file.WriteUuid(m_plane_id);
00830 if (!rc) break;
00831
00832 rc = file.WriteBool(m_bEnabled);
00833 if (!rc) break;
00834
00835 break;
00836 }
00837
00838 if ( !file.EndWrite3dmChunk() )
00839 rc = false;
00840
00841 return rc;
00842 }
00843
00844 bool ON_ClippingPlaneInfo::Read( ON_BinaryArchive& file )
00845 {
00846 Default();
00847
00848 int major_version = 0;
00849 int minor_version = 0;
00850 bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00851 if (!rc)
00852 return false;
00853
00854 for(;;)
00855 {
00856 rc = (1 == major_version);
00857 if (!rc) break;
00858
00859 rc = file.ReadPlaneEquation(m_plane_equation);
00860 if (!rc) break;
00861
00862 rc = file.ReadUuid(m_plane_id);
00863 if (!rc) break;
00864
00865 rc = file.ReadBool(&m_bEnabled);
00866 if (!rc) break;
00867
00868 break;
00869 }
00870
00871 if ( !file.EndRead3dmChunk() )
00872 rc = false;
00873
00874 return rc;
00875 }
00876
00877
00878 void ON_ClippingPlane::Default()
00879 {
00880 m_plane = ON_xy_plane;
00881 m_viewport_ids.Empty();
00882 m_plane_id = ON_nil_uuid;
00883 m_bEnabled = true;
00884 }
00885
00886 ON_ClippingPlane::ON_ClippingPlane()
00887 {
00888 Default();
00889 }
00890
00891 ON_ClippingPlane::~ON_ClippingPlane()
00892 {
00893 }
00894
00895 ON_ClippingPlaneInfo ON_ClippingPlane::ClippingPlaneInfo() const
00896 {
00897 ON_ClippingPlaneInfo info;
00898 info.m_plane_equation = m_plane.plane_equation;
00899 info.m_plane_id = m_plane_id;
00900 info.m_bEnabled = m_bEnabled;
00901 return info;
00902 }
00903
00904 bool ON_ClippingPlane::Read( ON_BinaryArchive& file )
00905 {
00906 Default();
00907
00908 int major_version = 0;
00909 int minor_version = 0;
00910
00911 bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00912 if (!rc)
00913 return false;
00914
00915 for(;;)
00916 {
00917 rc = (1 == major_version);
00918 if (!rc) break;
00919
00920 ON_UUID viewport_id;
00921 rc = file.ReadUuid(viewport_id);
00922 if(!rc) break;
00923
00924 if( 0 == minor_version )
00925 m_viewport_ids.AddUuid( viewport_id );
00926
00927 rc = file.ReadUuid(m_plane_id);
00928 if (!rc) break;
00929
00930 rc = file.ReadPlane(m_plane);
00931 if (!rc) break;
00932
00933 rc = file.ReadBool(&m_bEnabled);
00934 if (!rc) break;
00935
00936 if( minor_version > 0 )
00937 {
00938 rc = m_viewport_ids.Read(file);
00939 if (!rc) break;
00940 }
00941
00942 break;
00943 }
00944
00945 if ( !file.EndRead3dmChunk() )
00946 rc = false;
00947
00948 return rc;
00949 }
00950
00951 bool ON_ClippingPlane::Write( ON_BinaryArchive& file ) const
00952 {
00953 bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,1);
00954 if (!rc)
00955 return false;
00956
00957 for(;;)
00958 {
00959
00960 ON_UUID viewport_id = ::ON_nil_uuid;
00961 if( m_viewport_ids.Count() > 0 )
00962 viewport_id = *(m_viewport_ids.Array());
00963 rc = file.WriteUuid(viewport_id);
00964 if (!rc) break;
00965
00966 rc = file.WriteUuid(m_plane_id);
00967 if (!rc) break;
00968
00969 rc = file.WritePlane(m_plane);
00970 if (!rc) break;
00971
00972 rc = file.WriteBool(m_bEnabled);
00973 if (!rc) break;
00974
00975
00976 rc = m_viewport_ids.Write(file);
00977 if (!rc) break;
00978
00979 break;
00980 }
00981
00982 if ( !file.EndWrite3dmChunk() )
00983 rc = false;
00984
00985 return rc;
00986 }
00987
00988
00989 void ON_ClippingPlaneSurface::Default()
00990 {
00991 m_clipping_plane.Default();
00992 m_plane = m_clipping_plane.m_plane;
00993 m_domain[0].Set(0.0,1.0);
00994 m_domain[1].Set(0.0,1.0);
00995 m_extents[0].Set(-1.0,1.0);
00996 m_extents[1].Set(-1.0,1.0);
00997 }
00998
00999
01000 ON::object_type ON_ClippingPlaneSurface::ObjectType() const
01001 {
01002 return ON::clipplane_object;
01003 }
01004
01005 ON_ClippingPlaneSurface::ON_ClippingPlaneSurface()
01006 {
01007 Default();
01008 }
01009
01010 ON_ClippingPlaneSurface::~ON_ClippingPlaneSurface()
01011 {
01012 }
01013
01014 ON_ClippingPlaneSurface::ON_ClippingPlaneSurface(const ON_PlaneSurface& src)
01015 : ON_PlaneSurface(src)
01016 {
01017 m_clipping_plane.m_plane = m_plane;
01018 }
01019
01020 ON_ClippingPlaneSurface::ON_ClippingPlaneSurface(const ON_Plane& src)
01021 : ON_PlaneSurface(src)
01022 {
01023 m_clipping_plane.m_plane = m_plane;
01024 }
01025
01026 ON_ClippingPlaneSurface& ON_ClippingPlaneSurface::operator=(const ON_Plane& src)
01027 {
01028 m_plane = src;
01029 m_clipping_plane.m_plane = m_plane;
01030 return *this;
01031 }
01032
01033 ON_ClippingPlaneSurface& ON_ClippingPlaneSurface::operator=(const ON_PlaneSurface& src)
01034 {
01035 if ( this != &src )
01036 {
01037 ON_PlaneSurface::operator=(src);
01038 m_clipping_plane.m_plane = m_plane;
01039 }
01040 return *this;
01041 }
01042
01043 unsigned int ON_ClippingPlaneSurface::SizeOf() const
01044 {
01045 return ON_PlaneSurface::SizeOf() + sizeof(m_clipping_plane);
01046 }
01047
01048 ON__UINT32 ON_ClippingPlaneSurface::DataCRC(ON__UINT32 current_remainder) const
01049 {
01050 ON__UINT32 crc = ON_PlaneSurface::DataCRC(current_remainder);
01051 crc = ON_CRC32(crc,sizeof(m_clipping_plane),&m_clipping_plane);
01052 return crc;
01053 }
01054
01055 void ON_ClippingPlaneSurface::Dump( ON_TextLog& text_log ) const
01056 {
01057 text_log.Print("Clipping plane surface\n");
01058 text_log.PushIndent();
01059 text_log.Print("Enabled = %d",m_clipping_plane.m_bEnabled);
01060 text_log.Print("View IDs =\n");
01061 {
01062 text_log.PushIndent();
01063 ON_SimpleArray<ON_UUID> uuid_list;
01064 m_clipping_plane.m_viewport_ids.GetUuids(uuid_list);
01065 for( int i=0; i<uuid_list.Count(); i++ )
01066 {
01067 text_log.Print( uuid_list[i] );
01068 text_log.Print("\n");
01069 }
01070 text_log.PopIndent();
01071 }
01072 text_log.Print("Plane ID = ");
01073 text_log.Print(m_clipping_plane.m_plane_id);
01074 text_log.Print("\n");
01075
01076 text_log.Print("Plane surface\n");
01077 text_log.PushIndent();
01078 ON_PlaneSurface::Dump(text_log);
01079 text_log.PopIndent();
01080 text_log.PopIndent();
01081 }
01082
01083 ON_BOOL32 ON_ClippingPlaneSurface::Write( ON_BinaryArchive& file ) const
01084 {
01085 bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
01086 if (!rc)
01087 return false;
01088
01089 for(;;)
01090 {
01091 rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,0);
01092 if (rc)
01093 {
01094 rc = ON_PlaneSurface::Write(file)?true:false;
01095 if (!file.EndWrite3dmChunk())
01096 rc = false;
01097 }
01098 if (!rc) break;
01099
01100 rc = m_clipping_plane.Write(file);
01101 if (rc) break;
01102
01103 break;
01104 }
01105
01106 if (!file.EndWrite3dmChunk() )
01107 rc = false;
01108
01109 return rc;
01110 }
01111
01112 ON_BOOL32 ON_ClippingPlaneSurface::Read( ON_BinaryArchive& file )
01113 {
01114 Default();
01115
01116 int major_version = 0;
01117 int minor_version = 0;
01118
01119 bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
01120 if (!rc)
01121 return false;
01122
01123 for(;;)
01124 {
01125 rc = ( 1 == major_version );
01126 if (!rc) break;
01127
01128 ON__UINT32 tcode = 0;
01129 ON__INT64 big_value = 0;
01130
01131 rc = file.BeginRead3dmBigChunk(&tcode,&big_value)?true:false;
01132 if (rc)
01133 {
01134 rc = (TCODE_ANONYMOUS_CHUNK == tcode);
01135 if (rc)
01136 rc = (ON_PlaneSurface::Read(file)?true:false);
01137 if (!file.EndRead3dmChunk())
01138 rc = false;
01139 }
01140 if (!rc) break;
01141
01142 rc = m_clipping_plane.Read(file);
01143 if (rc) break;
01144
01145 break;
01146 }
01147
01148 if (!file.EndRead3dmChunk() )
01149 rc = false;
01150
01151 return rc;
01152 }
01153
01154