opennurbs_cylinder.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_Cylinder::ON_Cylinder() 
00020 {
00021   height[0] = 0.0;
00022   height[1] = 0.0;
00023 }
00024 
00025 ON_Cylinder::ON_Cylinder(
00026     const ON_Circle& c
00027     )
00028 {
00029   Create(c);
00030 }
00031 
00032 ON_Cylinder::ON_Cylinder(
00033     const ON_Circle& c,
00034     double h
00035     )
00036 {
00037   Create(c,h);
00038 }
00039 
00040 ON_Cylinder::~ON_Cylinder()
00041 {}
00042 
00043 bool ON_Cylinder::Create(
00044     const ON_Circle& c
00045     )
00046 {
00047   return Create( c, 0.0 );
00048 }
00049 
00050 bool ON_Cylinder::Create(
00051     const ON_Circle& c,
00052     double h
00053     )
00054 {
00055   circle = c;
00056   if ( h > 0.0 ) {
00057     height[0] = 0.0;
00058     height[1] = h;
00059   }
00060   else {
00061     height[0] = h;
00062     height[1] = 0.0;
00063   }
00064   return IsValid();
00065 }
00066 
00067 bool ON_Cylinder::IsValid() const
00068 {
00069   return circle.IsValid();
00070 }
00071 
00072 bool ON_Cylinder::IsFinite() const
00073 {
00074   return height[0] != height[1];
00075 }
00076 
00077 const ON_3dVector& ON_Cylinder::Axis() const
00078 {
00079   return circle.plane.zaxis;
00080 }
00081 
00082 const ON_3dPoint& ON_Cylinder::Center() const
00083 {
00084   return circle.plane.origin;
00085 }
00086 
00087 double ON_Cylinder::Height() const
00088 {
00089   return height[1] - height[0];
00090 }
00091 
00092 ON_Circle ON_Cylinder::CircleAt( 
00093       double t // linear parameter
00094       ) const
00095 {
00096   ON_Circle c = circle;
00097   if ( t != 0.0 )
00098     c.Translate(t*circle.plane.zaxis);
00099   return c;
00100 }
00101 
00102 ON_Line ON_Cylinder::LineAt( 
00103       double s // angular parameter
00104       ) const
00105 {
00106   ON_3dPoint p = circle.PointAt(s);
00107   ON_Line line;
00108   line.from = p + height[0]*circle.plane.zaxis;
00109   line.to   = p + height[1]*circle.plane.zaxis;
00110   return line;
00111 }
00112 
00113 
00114 ON_3dPoint ON_Cylinder::PointAt( double s, double t ) const
00115 {
00116   return ( circle.PointAt(s) + t*circle.plane.zaxis );
00117 }
00118 
00119 ON_3dPoint ON_Cylinder::NormalAt( double s, double t ) const
00120 {
00121   ON_3dVector N = ON_CrossProduct( circle.TangentAt(s), circle.plane.zaxis );
00122   N.Unitize();
00123   return N;
00124 }
00125 
00126 // returns parameters of point on cylinder that is closest to given point
00127 bool ON_Cylinder::ClosestPointTo( 
00128        ON_3dPoint point, 
00129        double* s, // angular parameter
00130        double* t  // linear parameter
00131        ) const
00132 {
00133   bool rc = true;
00134   //const ON_3dVector v = point - circle.plane.origin;
00135   double h = (point - circle.plane.origin)*circle.plane.zaxis;
00136   if ( s )
00137     rc = circle.ClosestPointTo( point - h*circle.plane.zaxis, s );
00138   if ( t ) {
00139     if ( height[0] < height[1] ) {
00140       if ( h < height[0] ) h = height[0]; else if ( h > height[1] ) h = height[1];
00141     }
00142     else if ( height[0] > height[1] ) {
00143       if ( h > height[0] ) h = height[0]; else if ( h < height[1] ) h = height[1];
00144     }
00145     *t = h;
00146   }
00147   return rc;
00148 }
00149 
00150 // returns point on cylinder that is closest to given point
00151 ON_3dPoint ON_Cylinder::ClosestPointTo( 
00152        ON_3dPoint point
00153        ) const
00154 {
00155   double s, t;
00156   ClosestPointTo( point, &s, &t );
00157   return PointAt( s, t );
00158 }
00159 
00160 // rotate plane about its origin
00161 bool ON_Cylinder::Rotate(
00162       double sin_angle,
00163       double cos_angle,
00164       const ON_3dVector& axis // axis of rotation
00165       )
00166 {
00167   return Rotate( sin_angle, cos_angle, axis, circle.plane.origin );
00168 }
00169 
00170 bool ON_Cylinder::Rotate(
00171       double angle,               // angle in radians
00172       const ON_3dVector& axis // axis of rotation
00173       )
00174 {
00175   return Rotate( sin(angle), cos(angle), axis, circle.plane.origin );
00176 }
00177 
00178 // rotate plane about a point and axis
00179 bool ON_Cylinder::Rotate(
00180       double sin_angle,               // sin(angle)
00181       double cos_angle,               // cos(angle)
00182       const ON_3dVector& axis, // axis of rotation
00183       const ON_3dPoint& point  // center of rotation
00184       )
00185 {
00186   return circle.Rotate( sin_angle, cos_angle, axis, point );
00187 }
00188 
00189 bool ON_Cylinder::Rotate(
00190       double angle,              // angle in radians
00191       const ON_3dVector& axis, // axis of rotation
00192       const ON_3dPoint&  point  // center of rotation
00193       )
00194 {
00195   return Rotate( sin(angle), cos(angle), axis, point );
00196 }
00197 
00198 bool ON_Cylinder::Translate(
00199       const ON_3dVector& delta
00200       )
00201 {
00202   return circle.Translate( delta );
00203 }
00204 
00205 int ON_Cylinder::GetNurbForm( ON_NurbsSurface& s ) const
00206 {
00207   int rc = 0;
00208   if ( IsValid() && height[0] != height[1] ) {
00209     ON_NurbsCurve n0, n1;
00210     int i;
00211     ON_Circle c0 = CircleAt(height[0]);
00212     ON_Circle c1 = CircleAt(height[1]);
00213 
00214 
00215     if ( height[0] <= height[1] ) {
00216       c0.GetNurbForm(n0);
00217       c1.GetNurbForm(n1);
00218     }
00219     else {
00220       c0.GetNurbForm(n1);
00221       c1.GetNurbForm(n0);
00222     }
00223 
00224     if (    n0.m_dim != n1.m_dim 
00225          || n0.m_is_rat != n1.m_is_rat
00226          || n0.m_order != n1.m_order 
00227          || n0.m_cv_count != n1.m_cv_count )
00228       return 0;
00229 
00230     s.Create(3,true, n0.m_order, 2, n0.m_cv_count, 2 );
00231     if ( height[0] <= height[1] ) {
00232       s.m_knot[1][0] = height[0];
00233       s.m_knot[1][1] = height[1]; 
00234     }
00235     else {
00236       s.m_knot[1][0] = height[1];
00237       s.m_knot[1][1] = height[0]; 
00238     }
00239 
00240     for ( i = 0; i < n0.KnotCount(); i++ )
00241       s.m_knot[0][i] = n0.m_knot[i];
00242 
00243     for ( i = 0; i < n0.m_cv_count; i++ ) {
00244       s.SetCV(i,0,ON::homogeneous_rational,n0.CV(i));
00245       s.SetCV(i,1,ON::homogeneous_rational,n1.CV(i));
00246     }
00247     rc = 2;
00248   }
00249   return rc;
00250 }
00251 
00252 ON_RevSurface* ON_Cylinder::RevSurfaceForm( ON_RevSurface* srf ) const
00253 {
00254   if ( srf )
00255     srf->Destroy();
00256   ON_RevSurface* pRevSurface = NULL;
00257   if ( IsFinite() && IsValid() )
00258   {
00259     ON_Line line;
00260     line.from = PointAt(0.0,height[0]);
00261     line.to = PointAt(0.0,height[1]);
00262     ON_Interval h(height[0],height[1]); // h = evaluation domain for line (must be increasing)
00263     if ( h.IsDecreasing() )
00264       h.Swap();
00265     ON_LineCurve* line_curve = new ON_LineCurve( line, h[0], h[1] );
00266     if ( srf )
00267       pRevSurface = srf;
00268     else
00269       pRevSurface = new ON_RevSurface();
00270     pRevSurface->m_angle.Set(0.0,2.0*ON_PI);
00271     pRevSurface->m_t = pRevSurface->m_angle;
00272     pRevSurface->m_curve = line_curve;
00273     pRevSurface->m_axis.from = circle.plane.origin;
00274     pRevSurface->m_axis.to = circle.plane.origin + circle.plane.zaxis;
00275     pRevSurface->m_bTransposed = false;
00276     ON_Circle c0(circle);
00277     c0.Translate(height[0]*circle.plane.zaxis);
00278     ON_Circle c1(circle);
00279     c1.Translate(height[1]*circle.plane.zaxis);
00280     pRevSurface->m_bbox = c0.BoundingBox();
00281     pRevSurface->m_bbox.Union(c1.BoundingBox());
00282   }
00283   return pRevSurface;
00284 }
00285 
00286 /*
00287 // obsolete use ON_BrepCylinder 
00288 ON_Brep* ON_Cylinder::BrepForm( ON_Brep* brep ) const
00289 {
00290   if ( brep )
00291     brep->Destroy();
00292   ON_Brep* pBrep = 0;
00293   ON_RevSurface* pRevSurface = RevSurfaceForm();
00294   if ( pRevSurface )
00295   {
00296     if ( brep )
00297       pBrep = brep;
00298     else
00299       pBrep = new ON_Brep();
00300     if ( !pBrep->Create(pRevSurface) ) 
00301     {
00302       if ( !brep )
00303         delete pBrep;
00304       pBrep = 0;
00305       if (pRevSurface)
00306       {
00307         delete pRevSurface;
00308         pRevSurface = 0;
00309       }
00310     }
00311     else 
00312     {
00313       // add caps
00314       for ( int capcount = 0; capcount < 2; capcount++ )
00315       {
00316         // capcount = 0 for bottom cap and 1 for top cap
00317         ON_Circle circle = CircleAt(height[capcount]);
00318         if ( capcount == 0 )
00319           circle.Reverse();
00320         double radius = circle.radius;
00321         ON_NurbsSurface* pCapSurface = ON_NurbsSurfaceQuadrilateral( 
00322           circle.plane.PointAt(-radius,-radius),
00323           circle.plane.PointAt(+radius,-radius),
00324           circle.plane.PointAt(+radius,+radius),
00325           circle.plane.PointAt(-radius,+radius)
00326           );
00327         pCapSurface->m_knot[0][0] = -fabs(radius);
00328         pCapSurface->m_knot[0][1] =  fabs(radius);
00329         pCapSurface->m_knot[1][0] = pCapSurface->m_knot[0][0];
00330         pCapSurface->m_knot[1][1] = pCapSurface->m_knot[0][1];
00331         circle.Create( ON_xy_plane, ON_origin, radius );
00332         ON_NurbsCurve* c2 = new ON_NurbsCurve();
00333         circle.GetNurbForm(*c2);
00334         c2->ChangeDimension(2);
00335 
00336         pBrep->m_S.Append(pCapSurface);
00337         pBrep->m_C2.Append(c2);
00338         ON_BrepFace& cap = pBrep->NewFace( pBrep->m_S.Count()-1 );
00339         ON_BrepLoop& loop = pBrep->NewLoop( ON_BrepLoop::outer, cap );
00340         ON_BrepEdge& edge = pBrep->m_E[capcount?0:2];
00341         ON_BrepTrim& trim = pBrep->NewTrim( edge, true, loop, pBrep->m_C2.Count()-1 );
00342         for ( int eti = 0; eti < edge.m_ti.Count(); eti++ )
00343           pBrep->m_T[ edge.m_ti[eti] ].m_type = ON_BrepTrim::mated;
00344         trim.m_tolerance[0] = 0.0;
00345         trim.m_tolerance[1] = 0.0;
00346         trim.m_pbox.m_min.x = -radius;
00347         trim.m_pbox.m_min.y = -radius;
00348         trim.m_pbox.m_min.z = 0.0;
00349         trim.m_pbox.m_max.x = radius;
00350         trim.m_pbox.m_max.y = radius;
00351         trim.m_pbox.m_max.z = 0.0;
00352         loop.m_pbox = trim.m_pbox;
00353         pBrep->SetTrimTypeFlags(trim);
00354         pBrep->SetTrimIsoFlags(trim);
00355       }
00356       if ( !pBrep->IsValid() )
00357       {
00358         if (brep)
00359           brep->Destroy();
00360         else
00361           delete pBrep;
00362         pBrep = 0;
00363       }
00364     }
00365   }
00366   return pBrep;
00367 }
00368 */
00369 


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