opennurbs_morph.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 
00020 ON_Localizer::ON_Localizer()
00021 {
00022   m_nurbs_curve = 0;
00023   m_nurbs_surface = 0;
00024   Destroy();
00025 }
00026 
00027 ON_Localizer::~ON_Localizer()
00028 {
00029   Destroy();
00030 }
00031 
00032 ON_Localizer::ON_Localizer(const ON_Localizer& src)
00033 {
00034   m_nurbs_curve = 0;
00035   m_nurbs_surface = 0;
00036   Destroy();
00037   *this = src;
00038 }
00039 
00040 ON_Localizer& ON_Localizer::operator=(const ON_Localizer& src)
00041 {
00042   if ( this != &src )
00043   {
00044     Destroy();
00045     m_type = src.m_type;
00046     m_d = src.m_d;
00047     m_P = src.m_P;
00048     m_V = src.m_V;
00049     if ( src.m_nurbs_curve )
00050       m_nurbs_curve = src.m_nurbs_curve->Duplicate();
00051     if ( src.m_nurbs_surface )
00052       m_nurbs_surface = src.m_nurbs_surface->Duplicate();
00053   }
00054   return *this;
00055 }
00056 
00057 
00058 void ON_Localizer::Destroy()
00059 {
00060   m_type = no_type;
00061   m_P.Set(0.0,0.0,0.0);
00062   m_V.Set(0.0,0.0,0.0);
00063   m_d.Set(0.0,0.0);
00064   if (m_nurbs_curve)
00065   {
00066     delete m_nurbs_curve;
00067     m_nurbs_curve = 0;
00068   }
00069   if (m_nurbs_surface)
00070   {
00071     delete m_nurbs_surface;
00072     m_nurbs_surface = 0;
00073   }
00074 }
00075 
00076 bool ON_Localizer::Write(ON_BinaryArchive& archive) const
00077 {
00078   bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00079   if (!rc)
00080     return false;
00081 
00082   for(;;)
00083   {
00084     rc = archive.WriteInt(m_type);
00085     if ( !rc ) break;
00086     rc = archive.WritePoint(m_P);
00087     if ( !rc ) break;
00088     rc = archive.WriteVector(m_V);
00089     if ( !rc ) break;
00090     rc = archive.WriteInterval(m_d);
00091     if ( !rc ) break;
00092 
00093     rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00094     if (!rc) break;
00095     rc = archive.WriteBool( m_nurbs_curve ? true : false );
00096     if ( rc && m_nurbs_curve )
00097       rc = m_nurbs_curve->Write(archive)?true:false;
00098     if ( !archive.EndWrite3dmChunk() )
00099       rc = false;
00100     if (!rc) break;
00101 
00102     rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00103     if (!rc) break;
00104     rc = archive.WriteBool( m_nurbs_surface ? true : false );
00105     if ( rc && m_nurbs_surface )
00106       rc = m_nurbs_surface->Write(archive)?true:false;
00107     if ( !archive.EndWrite3dmChunk() )
00108       rc = false;
00109     if (!rc) break;
00110 
00111     break;
00112   }
00113   
00114   if ( !archive.EndWrite3dmChunk() )
00115     rc = false;
00116 
00117   return rc;
00118 }
00119 
00120 bool ON_Localizer::Read(ON_BinaryArchive& archive)
00121 {
00122   Destroy();
00123 
00124   int major_version = 0;
00125   int minor_version = 0;
00126   bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00127   if (!rc)
00128     return false;
00129 
00130   for(;;)
00131   {
00132     rc = (1 == major_version);
00133     if ( !rc ) break;
00134 
00135     int i = no_type;
00136     rc = archive.ReadInt(&i);
00137     if ( !rc ) break;
00138 
00139     switch(i)
00140     {
00141     case sphere_type:   m_type = sphere_type;   break;
00142     case plane_type:    m_type = plane_type;    break;
00143     case cylinder_type: m_type = cylinder_type; break;
00144     case curve_type:    m_type = curve_type;    break;
00145     case surface_type:  m_type = surface_type;  break;
00146     case distance_type: m_type = distance_type; break;
00147     }
00148 
00149     rc = archive.ReadPoint(m_P);
00150     if ( !rc ) break;
00151     rc = archive.ReadVector(m_V);
00152     if ( !rc ) break;
00153     rc = archive.ReadInterval(m_d);
00154     if ( !rc ) break;
00155 
00156     int mjv = 0, mnv = 0;
00157     rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&mjv,&mnv);
00158     if (!rc) break;
00159     rc = (1 == mjv);
00160     bool bReadCurve = false;
00161     if (rc)
00162       rc = archive.ReadBool( &bReadCurve );
00163     if ( rc && bReadCurve)
00164     {
00165       m_nurbs_curve = new ON_NurbsCurve();
00166       rc = m_nurbs_curve->Read(archive)?true:false;
00167     }
00168     if ( !archive.EndRead3dmChunk() )
00169       rc = false;
00170     if (!rc) break;
00171 
00172     rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&mjv,&mnv);
00173     if (!rc) break;
00174     rc = (1 == mjv);
00175     bool bReadSurface = false;
00176     rc = archive.ReadBool( &bReadSurface );
00177     if ( rc && bReadSurface )
00178     {
00179       m_nurbs_surface = new ON_NurbsSurface();
00180       rc = m_nurbs_surface->Read(archive)?true:false;
00181     }
00182     if ( !archive.EndRead3dmChunk() )
00183       rc = false;
00184     if (!rc) break;
00185 
00186     break;
00187   }
00188   
00189   if ( !archive.EndRead3dmChunk() )
00190     rc = false;
00191 
00192   return rc;
00193 }
00194 
00195 
00196 bool ON_Localizer::CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector V, double r0, double r1 )
00197 {
00198   Destroy();
00199   if (    P.IsValid() 
00200        && V.IsValid() 
00201        && V.Length() > 0.0 
00202        && ON_IsValid(r0) 
00203        && ON_IsValid(r1) 
00204        && r0 > 0.0
00205        && r1 > 0.0
00206        && r0 != r1 )
00207   {
00208     m_P = P;
00209     m_V = V;
00210     m_V.Unitize();
00211     m_d.Set(r0,r1);
00212     m_type = cylinder_type;
00213   }
00214   return (cylinder_type == m_type);
00215 }
00216 
00217 bool ON_Localizer::CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 )
00218 {
00219   Destroy();
00220   if ( P.IsValid()
00221        && N.IsValid()
00222        && N.Length() > 0.0
00223        && ON_IsValid(h0)
00224        && ON_IsValid(h1)
00225        && h0 != h1 )
00226   {
00227     m_V = N;
00228     m_V.Unitize();
00229     m_P.Set( -(m_V.x*P.x + m_V.y*P.y + m_V.z*P.z), 0.0, 0.0 );
00230     m_d.Set(h0,h1);
00231     m_type = plane_type;
00232   }
00233   return (plane_type == m_type);
00234 }
00235 
00236 bool ON_Localizer::CreateSphereLocalizer( ON_3dPoint P, double r0, double r1 )
00237 {
00238   Destroy();
00239   if ( P.IsValid()
00240        && ON_IsValid(r0)
00241        && ON_IsValid(r1)
00242        && r0 > 0.0
00243        && r1 > 0.0
00244        && r0 != r1 )
00245   {
00246     m_P = P;
00247     m_V.Zero();
00248     m_d.Set(r0,r1);
00249     m_type = sphere_type;
00250   }
00251   return (sphere_type == m_type);
00252 }
00253 
00254 double ON_Localizer::Value(double t) const
00255 {
00256   double s = m_d.NormalizedParameterAt(t);
00257   if ( s <= 0.0 )
00258     s = 0.0;
00259   else if ( s >= 1.0 )
00260     s = 1.0;
00261   else
00262     s = s*s*(3.0 - 2.0*s);
00263 
00264   return s;
00265 }
00266 
00267 double ON_Localizer::Value(ON_3dPoint P) const
00268 {
00269   double t = m_d.m_t[1];
00270 
00271   switch ( m_type )
00272   {
00273   case cylinder_type:
00274     // t = distance from P to axis
00275     t = ON_CrossProduct( P-m_P, m_V ).Length();
00276     break;
00277 
00278   case plane_type:
00279     // t = distance above plane
00280     t = m_V.x*P.x + m_V.y*P.y + m_V.z*P.z + m_P.x;
00281     break;
00282 
00283   case sphere_type:
00284     // t = distance to P
00285     t = (P-m_P).Length();
00286     break;
00287 
00288   case curve_type:
00289     break;
00290 
00291   case surface_type:
00292     break;
00293 
00294   case distance_type:
00295     // confused user should be calling Value(double)
00296     return 1.0; // default must be one
00297     break;
00298 
00299   default:
00300     return 1.0; // default must be one
00301   }
00302 
00303   return Value(t);
00304 }
00305 
00306 
00307 bool ON_Localizer::IsZero( const ON_BoundingBox& bbox ) const
00308 {
00309   bool rc = false;
00310 
00311   ON_BoundingBox loc_bbox;
00312   bool bTestLocBox = false;
00313   double d;
00314 
00315   switch ( m_type )
00316   {
00317   case cylinder_type:
00318     {
00319       ON_3dPointArray corners;
00320       bbox.GetCorners(corners);
00321       int i;
00322       double t0, t1;
00323       t0 = t1 = (corners[0]-m_P)*m_V;
00324       for ( i = 1; i < 8; i++ )
00325       {
00326         d = (corners[i]-m_P)*m_V;
00327         if ( d < t0 )
00328           t0 = d;
00329         else if (d > t1 )
00330           t1 = d;
00331       }
00332       ON_Line L(m_P+t0*m_V,m_P+t1*m_V);
00333       if ( m_d[0] > m_d[1] )
00334       {
00335         // function is supported along the line
00336         d = bbox.MinimumDistanceTo(L);
00337         if ( d >= m_d[0] )
00338           rc = true;
00339       }
00340       else
00341       {
00342         // function is supported outside cylinder
00343         d = bbox.MaximumDistanceTo(L);
00344         if ( d <= m_d[0] )
00345           rc = true;
00346       }
00347     }
00348     break;
00349 
00350   case plane_type:
00351     {
00352       ON_PlaneEquation e;
00353       e.x = m_V.x; e.y = m_V.y; e.z = m_V.z; e.d = m_P.x;
00354       e.d -= m_d[0];
00355       if ( m_d[0] > m_d[1] )
00356       {
00357         e.x = -e.x; e.y = -e.y; e.z = -e.z; e.d = -e.d;
00358       }
00359       if ( e.MaximumValueAt(bbox) <= 0.0 )
00360         rc = true;
00361     }
00362     break;
00363 
00364   case sphere_type:
00365     loc_bbox.m_min = m_P;
00366     loc_bbox.m_max = m_P;
00367     bTestLocBox = true;
00368     break;
00369 
00370   case curve_type:
00371     if ( m_nurbs_curve)
00372     {
00373       loc_bbox = m_nurbs_curve->BoundingBox();
00374       bTestLocBox = true;
00375     }
00376     break;
00377 
00378   case surface_type:
00379     if ( m_nurbs_surface)
00380     {
00381       loc_bbox = m_nurbs_surface->BoundingBox();
00382       bTestLocBox = true;
00383     }
00384     break;
00385 
00386   case distance_type:
00387     rc = false;
00388     break;
00389 
00390   default:
00391     rc = true;
00392   }
00393 
00394   if ( bTestLocBox )
00395   {
00396     if ( m_d[1] < m_d[0] && m_d[0] > 0.0 )
00397     {
00398       // function is zero outside loc_bbox + m_d[0]
00399       double d = loc_bbox.MinimumDistanceTo(bbox);
00400       if ( d > m_d[0] )
00401         rc = true;
00402     }
00403     else if ( m_d[0] > 0.0 )
00404     {
00405       // function is zero inside loc_bbox-m_d[0]
00406       loc_bbox.m_min.x += m_d[0];
00407       loc_bbox.m_min.y += m_d[0];
00408       loc_bbox.m_min.z += m_d[0];
00409       loc_bbox.m_max.x -= m_d[0];
00410       loc_bbox.m_max.y -= m_d[0];
00411       loc_bbox.m_max.z -= m_d[0];
00412       if ( loc_bbox.IsValid() && loc_bbox.Includes(bbox) )
00413         rc = true;
00414     }
00415   }
00416   return rc;
00417 }
00418 
00419 ON_SpaceMorph::ON_SpaceMorph()
00420 {
00421   m_tolerance = 0.0;
00422   m_bQuickPreview = false;
00423   m_bPreserveStructure = false;
00424 }
00425 
00426 ON_SpaceMorph::~ON_SpaceMorph()
00427 {
00428 }
00429 
00430 double ON_SpaceMorph::Tolerance() const
00431 {
00432   return m_tolerance;
00433 }
00434 
00435 void ON_SpaceMorph::SetTolerance(double tolerance)
00436 {
00437   m_tolerance = (ON_IsValid(tolerance) && tolerance > 0.0 ) 
00438               ? tolerance
00439               : 0.0;
00440 }
00441 
00442 bool ON_SpaceMorph::QuickPreview() const
00443 {
00444   return m_bQuickPreview;
00445 }
00446 
00447 void ON_SpaceMorph::SetQuickPreview( bool bQuickPreview )
00448 {
00449   m_bQuickPreview = bQuickPreview ? true : false;
00450 }
00451 
00452 bool ON_SpaceMorph::IsIdentity( const ON_BoundingBox& bbox ) const
00453 {
00454   return false;
00455 }
00456 
00457 bool ON_SpaceMorph::PreserveStructure() const
00458 {
00459   return m_bPreserveStructure;
00460 }
00461 
00462 void ON_SpaceMorph::SetPreserveStructure( bool bPreserveStructure )
00463 {
00464   m_bPreserveStructure = bPreserveStructure ? true : false;
00465 }
00466 
00467 bool ON_Mesh::EvaluatePoint( const class ON_ObjRef& objref, ON_3dPoint& P ) const
00468 {
00469   // virtual function default
00470   P = ON_UNSET_POINT;
00471   ON_COMPONENT_INDEX ci = objref.m_component_index;
00472 
00473   switch ( ci.m_type )
00474   {
00475   case ON_COMPONENT_INDEX::mesh_vertex:
00476     if ( ci.m_index >= 0 && ci.m_index < m_V.Count() )
00477       P = m_V[ci.m_index];
00478     break;
00479 
00480   case ON_COMPONENT_INDEX::meshtop_vertex:
00481     if ( ci.m_index >= 0 && ci.m_index < m_top.m_topv.Count() )
00482     {
00483       const ON_MeshTopologyVertex& topv = m_top.m_topv[ci.m_index];
00484       if ( topv.m_v_count > 0 && topv.m_vi )
00485       {
00486         int vi = topv.m_vi[0];
00487         if ( vi >= 0 && vi < m_V.Count() )
00488           P = m_V[vi];
00489       }
00490     }
00491     break;
00492 
00493   case ON_COMPONENT_INDEX::meshtop_edge:
00494     if ( 5 == objref.m_evp.m_t_type 
00495          && fabs(objref.m_evp.m_t[0] + objref.m_evp.m_t[1] - 1.0) <= ON_SQRT_EPSILON )
00496     {
00497       ON_Line L = m_top.TopEdgeLine(ci.m_index);
00498       if ( L.IsValid() )
00499       {
00500         P = L.PointAt(objref.m_evp.m_t[0]);
00501       }
00502     }
00503     break;
00504 
00505   case ON_COMPONENT_INDEX::mesh_face:
00506     if ( 4 == objref.m_evp.m_t_type 
00507          && fabs(objref.m_evp.m_t[0] + objref.m_evp.m_t[1] + objref.m_evp.m_t[2] + objref.m_evp.m_t[3] - 1.0) <= ON_SQRT_EPSILON )
00508     {
00509       if ( ci.m_index >= 0 && ci.m_index < m_F.Count() )
00510       {
00511         const int* fvi = m_F[ci.m_index].vi;
00512         if ( fvi[0] < 0 || fvi[0] >= m_V.Count() )
00513           break;
00514         if ( fvi[1] < 0 || fvi[1] >= m_V.Count() )
00515           break;
00516         if ( fvi[2] < 0 || fvi[2] >= m_V.Count() )
00517           break;
00518         if ( fvi[3] < 0 || fvi[3] >= m_V.Count() )
00519           break;
00520         ON_3dPoint V[4];
00521         V[0] = m_V[fvi[0]];
00522         V[1] = m_V[fvi[1]];
00523         V[2] = m_V[fvi[2]];
00524         V[3] = m_V[fvi[3]];
00525         P = objref.m_evp.m_t[0]*V[0] + objref.m_evp.m_t[1]*V[1] + objref.m_evp.m_t[2]*V[2] + objref.m_evp.m_t[3]*V[3];
00526       }
00527     }
00528     break;
00529 
00530   default:
00531     // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
00532     break;
00533   }
00534 
00535   return P.IsValid();
00536 }
00537 


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