opennurbs_planesurface.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 #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  // open binary file
00096      ) const
00097 {
00098   ON_BOOL32 rc = file.Write3dmChunkVersion(1,1);
00099 
00100   // version 1.0 chunks
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   // added to version 1.1 chunks
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 // open binary 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     // common to all 1.x formats
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( // returns true if successful
00153          double* boxmin,    // minimum
00154          double* boxmax,    // maximum
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   // evaluation domain - do not confuse with m_extents
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,  // t = parameter in domain
00236          double* tminus, // tminus
00237          double* tplus   // 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, // default = NULL,
00305     double point_tolerance, // default=ON_ZERO_TOLERANCE
00306     double d1_tolerance, // default==ON_ZERO_TOLERANCE
00307     double d2_tolerance, // default==ON_ZERO_TOLERANCE
00308     double cos_angle_tolerance, // default==ON_DEFAULT_ANGLE_TOLERANCE_COSINE
00309     double curvature_tolerance  // default==ON_SQRT_EPSILON
00310     ) const
00311 {
00312   return true;
00313 }
00314 
00315 ON_BOOL32
00316 ON_PlaneSurface::Transpose()
00317 {
00318   // swaps x and y axes and reverses zaxis
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( // returns false if unable to evaluate
00334        double s, double t, // evaluation parameters
00335        int der_count,  // number of derivatives (>=0)
00336        int v_stride,   // v[] array stride (>=Dimension())
00337        double* v,      // v[] array of length stride*(ndir+1)
00338        int side,       // optional - determines which side to evaluate from
00339                        //         0 = default
00340                        //      <  0 to evaluate from below, 
00341                        //      >  0 to evaluate from above
00342        int* hint       // optional - evaluation hint (int) used to speed
00343                        //            repeated evaluations
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       // zero higher partials
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,  // parameters of local closest point returned here
00526         double maximum_distance,
00527         const ON_Interval* sdomain, // first parameter sub_domain
00528         const ON_Interval* tdomain  // second parameter sub_domain
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     // convert m_plane coordinates to ON_Surface coordinates
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 // Find parameters of the point on a surface that is locally closest to 
00579 // the test_point.  The search for a local close point starts at 
00580 // seed parameters. If a sub_domain parameter is not NULL, then
00581 // the search is restricted to the specified portion of the surface.
00582 //
00583 // true if returned if the search is successful.  false is returned if
00584 // the search fails.
00585 ON_BOOL32 ON_PlaneSurface::GetLocalClosestPoint( const ON_3dPoint& test_point, // test_point
00586         double s0, double t0,     // seed_parameters
00587         double* s,double* t,   // parameters of local closest point returned here
00588         const ON_Interval* sdomain, // first parameter sub_domain
00589         const ON_Interval* tdomain  // second parameter sub_domain
00590         ) const
00591 {
00592   // for planes, global serach is fast and returns same answer as local search
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( // returns 0: unable to create NURBS representation
00619                    //            with desired accuracy.
00620                    //         1: success - returned NURBS parameterization
00621                    //            matches the surface's to wthe desired accuracy
00622                    //         2: success - returned NURBS point locus matches
00623                    //            the surfaces's to the desired accuracy but, on
00624                    //            the interior of the surface's domain, the 
00625                    //            surface's parameterization and the NURBS
00626                    //            parameterization may not match to the 
00627                    //            desired accuracy.
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( // returns 0: unable to create NURBS representation
00678                    //            with desired accuracy.
00679                    //         1: success - returned NURBS parameterization
00680                    //            matches the surface's to wthe desired accuracy
00681                    //         2: success - returned NURBS point locus matches
00682                    //            the surfaces's to the desired accuracy but, on
00683                    //            the interior of the surface's domain, the 
00684                    //            surface's parameterization and the NURBS
00685                    //            parameterization may not match to the 
00686                    //            desired accuracy.
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   // rectangle extents - do not confuse with m_domain
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     //version 1.1 - write list of viewport uuids instead of single uuid
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     //version 1.1 - write list of viewport uuids instead of single uuid
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 


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