opennurbs_mesh_ngon.cpp
Go to the documentation of this file.
00001 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00002 
00003 
00004 
00005 // DO NOT COPY THIS DEFINE
00006 #define ON_NGON_BOZO_VACCINE
00007 
00008 
00009 
00010 
00011 
00012 // Do not copy or move the definition of
00013 // the ON_NGON_MEMBLK structure.
00014 struct ON_NGON_MEMBLK
00015 {
00016 #if !defined(ON_NGON_BOZO_VACCINE)
00017 #error You are a bozo!  Read the comments.
00018 #endif
00019   struct ON_NGON_MEMBLK* next;
00020 };
00021 
00022 ON_MeshNgonList::ON_MeshNgonList()
00023 {
00024   m_ngons_count = 0;
00025   m_ngons_capacity = 0;
00026   m_ngons = 0;
00027   m_memblk_list = 0; 
00028 }
00029 
00030 ON_MeshNgonList::~ON_MeshNgonList()
00031 {
00032   Destroy();
00033 }
00034 
00035 void ON_MeshNgonList::Destroy()
00036 {
00037   m_ngons_count = 0;
00038   m_ngons_capacity = 0;
00039   if ( 0 != m_ngons )
00040   {
00041     onfree(m_ngons);
00042     m_ngons = 0;
00043   }
00044   struct ON_NGON_MEMBLK* p = m_memblk_list;
00045   m_memblk_list = 0;
00046   while(p)
00047   {
00048     struct ON_NGON_MEMBLK* next = p->next;
00049     onfree(p);
00050     p = next;
00051   }
00052 }
00053 
00054 
00055 ON_MeshNgonList::ON_MeshNgonList(const ON_MeshNgonList& src)
00056 {
00057   m_ngons_count = 0;
00058   m_ngons_capacity = 0;
00059   m_ngons = 0;
00060   m_memblk_list = 0; 
00061   if ( src.m_ngons_count > 0 && 0 != src.m_ngons )
00062   {
00063     *this = src;
00064   }
00065 }
00066 
00067 
00068 ON_MeshNgonList& ON_MeshNgonList::operator=(const ON_MeshNgonList& src)
00069 {
00070   if ( this != &src )
00071   {
00072     Destroy();
00073     ReserveNgonCapacity(src.m_ngons_count);
00074     for ( int i = 0; i < src.m_ngons_count; i++ )
00075     {
00076       const ON_MeshNgon& ngon = src.m_ngons[i];
00077       AddNgon(ngon.N,ngon.vi,ngon.fi);
00078     }
00079   }
00080   return *this;
00081 }
00082 
00083 
00084 bool ON_MeshNgonList::ReserveNgonCapacity(int capacity)
00085 {
00086   bool rc = true;
00087   if ( capacity > m_ngons_capacity )
00088   {
00089     m_ngons = (ON_MeshNgon*)onrealloc(m_ngons,capacity*sizeof(m_ngons[0]));
00090     if ( 0 == m_ngons )
00091     {
00092       m_ngons_capacity = 0;
00093       m_ngons_count = 0;
00094       rc = false;
00095     }
00096     else
00097     {
00098       m_ngons_capacity = capacity;
00099     }
00100   }
00101   return rc;
00102 }
00103 
00104 struct ON_MeshNgon* ON_MeshNgonList::AddNgon(int N)
00105 {
00106   if ( N < 3 || N > 100000 )
00107     return 0;
00108 
00109   if ( m_ngons_count >= m_ngons_capacity )
00110   {
00111     int capacity = 2*m_ngons_count;
00112     if (capacity < m_ngons_count+16)
00113       capacity = m_ngons_count+16;
00114     if ( !ReserveNgonCapacity(capacity) )
00115       return 0;
00116   }
00117   ON_MeshNgon& ngon = m_ngons[m_ngons_count++];
00118 
00119   ngon.N = N;
00120   struct ON_NGON_MEMBLK* blk = (struct ON_NGON_MEMBLK*)onmalloc(sizeof(*blk) + (2*N)*sizeof(int));
00121   if ( 0 == blk )
00122     return 0;
00123   ngon.vi = (int*)(blk + 1);
00124   ngon.fi = ngon.vi + N;
00125   memset(ngon.vi,0xFF,(2*N)*sizeof(int)); // set all indicies to -1
00126   blk->next = m_memblk_list;
00127   m_memblk_list = blk;
00128   return &ngon;
00129 }
00130 
00131 bool ON_MeshNgonList::AddNgon(int N, const int* vi, const int* fi)
00132 {
00133   if ( 0 == vi || 0 == fi )
00134     return false;
00135   struct ON_MeshNgon* ngon = AddNgon(N);
00136   if ( 0 == ngon )
00137     return false;
00138   memcpy(ngon->vi,vi,N*sizeof(ngon->vi[0]));
00139   memcpy(ngon->fi,fi,(N-2)*sizeof(ngon->fi[0]));
00140   return true;
00141 }
00142 
00143 int ON_MeshNgonList::NgonCount() const
00144 {
00145   return m_ngons_count;
00146 }
00147 
00148 ON_MeshNgon* ON_MeshNgonList::Ngon(int Ngon_index) const
00149 {
00150   return (Ngon_index < 0 || Ngon_index >= m_ngons_count) ? 0 : m_ngons+Ngon_index;
00151 }
00152 
00153 
00154 class /* DO NOT EXPORT THIS CLASS */ ON_MeshNgonUserData : public ON_UserData
00155 {
00156 #if !defined(ON_NGON_BOZO_VACCINE)
00157 #error You are a bozo!  Read the comments.
00158 #endif
00159   ON_OBJECT_DECLARE(ON_MeshNgonUserData);
00160 
00161 public:
00162   ON_MeshNgonUserData();
00163   ~ON_MeshNgonUserData();
00164   ON_MeshNgonUserData(const ON_MeshNgonUserData&);
00165   ON_MeshNgonUserData& operator=(const ON_MeshNgonUserData&);
00166 
00167   // vitual ON_UserData override
00168   ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
00169   unsigned int SizeOf() const;
00170   ON_BOOL32 Write(ON_BinaryArchive&) const;
00171   ON_BOOL32 Read(ON_BinaryArchive&);
00172 
00173   // vitual ON_UserData override
00174   ON_BOOL32 GetDescription( ON_wString& );
00175   ON_BOOL32 Archive() const; 
00176 
00177 public:
00178   ON_MeshNgonList* m_ngon_list;
00179 
00180   // used to validate ngon list.
00181   // If the information here does not match the
00182   // information in the mesh, then the ngon list
00183   // is known to be invalid.
00184   int m_mesh_F_count;
00185   int m_mesh_V_count;
00186 };
00187 
00188 ON_OBJECT_IMPLEMENT(ON_MeshNgonUserData,ON_UserData,"31F55AA3-71FB-49f5-A975-757584D937FF");
00189 
00190 ON_MeshNgonUserData::ON_MeshNgonUserData()
00191 {
00192   m_userdata_uuid = ON_MeshNgonUserData::m_ON_MeshNgonUserData_class_id.Uuid();
00193   m_application_uuid = ON_opennurbs4_id;
00194   m_userdata_copycount = 1;
00195   m_ngon_list = 0;
00196   m_mesh_F_count = 0;
00197   m_mesh_V_count = 0;
00198 }
00199 
00200 ON_MeshNgonUserData::~ON_MeshNgonUserData()
00201 {
00202   if ( 0 != m_ngon_list )
00203   {
00204     delete m_ngon_list;
00205     m_ngon_list = 0;
00206   }
00207 }
00208 
00209 ON_MeshNgonUserData::ON_MeshNgonUserData(const ON_MeshNgonUserData& src) 
00210 : ON_UserData(src)
00211 , m_mesh_F_count(src.m_mesh_F_count)
00212 , m_mesh_V_count(src.m_mesh_V_count)
00213 {
00214   m_ngon_list = (0 != src.m_ngon_list) 
00215               ? new ON_MeshNgonList(*src.m_ngon_list)
00216               : 0;
00217 }
00218 
00219 ON_MeshNgonUserData& ON_MeshNgonUserData::operator=(const ON_MeshNgonUserData& src)
00220 {
00221   if ( this != &src )
00222   {
00223     if (0 != m_ngon_list )
00224     {
00225       delete m_ngon_list;
00226       m_ngon_list = 0;
00227     }
00228     ON_UserData::operator=(src);
00229     if (0 != src.m_ngon_list) 
00230     {
00231        m_ngon_list = new ON_MeshNgonList(*src.m_ngon_list);
00232     }
00233     m_mesh_F_count = src.m_mesh_F_count;
00234     m_mesh_V_count = src.m_mesh_V_count;
00235   }
00236   return *this;
00237 }
00238 
00239 ON_BOOL32 ON_MeshNgonUserData::IsValid( ON_TextLog* text_log ) const
00240 {
00241   return true;
00242 }
00243 
00244 unsigned int ON_MeshNgonList::SizeOf() const
00245 {
00246   unsigned int sz = sizeof(*this);
00247   int icount = 0;
00248   for ( int i = 0; i < m_ngons_count; i++ )
00249   {
00250     icount += 2*m_ngons[i].N;
00251   }
00252   sz += m_ngons_capacity*sizeof(m_ngons[0]);
00253   sz += icount*sizeof(int);
00254   return sz;
00255 }
00256 
00257 unsigned int ON_MeshNgonUserData::SizeOf() const
00258 {
00259   unsigned int sz = ON_UserData::SizeOf();
00260   if ( 0 != m_ngon_list )
00261     sz += m_ngon_list->SizeOf();
00262   return sz;
00263 }
00264 
00265 
00266 ON_BOOL32 ON_MeshNgonUserData::Write(ON_BinaryArchive& archive) const
00267 {
00268   bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,1);
00269   if (!rc)
00270     return false;
00271   for (;;)
00272   {
00273     int count = ( 0 == m_ngon_list ) ? 0 : m_ngon_list->NgonCount();
00274     const ON_MeshNgon* ngon_array = (count > 0) ? m_ngon_list->Ngon(0) : 0;
00275     if ( 0 == ngon_array )
00276       count = 0;
00277     rc = archive.WriteInt(count);
00278     if (count <= 0 || !rc)
00279       break;
00280     for ( int i = 0; i < count; i++ )
00281     {
00282       const struct ON_MeshNgon& ngon = ngon_array[i];
00283       rc = archive.WriteInt(ngon.N);
00284       if (!rc)
00285         break;
00286       rc = archive.WriteInt(ngon.N,ngon.vi);
00287       if (!rc)
00288         break;
00289       rc = archive.WriteInt(ngon.N,ngon.fi);
00290       if (!rc)
00291         break;
00292     }
00293     if (!rc)
00294       break;
00295 
00296     // chunk version 1.1 added face and vertex validation counts.
00297     rc = archive.WriteInt(m_mesh_F_count);
00298     if (!rc)
00299       break;
00300     rc = archive.WriteInt(m_mesh_V_count);
00301     if (!rc)
00302       break;
00303 
00304     break;
00305   }
00306   if ( !archive.EndWrite3dmChunk() )
00307     rc = false;
00308   return rc;
00309 }
00310 
00311 ON_BOOL32 ON_MeshNgonUserData::Read(ON_BinaryArchive& archive)
00312 {
00313   if ( 0 != m_ngon_list )
00314   {
00315     delete m_ngon_list;
00316     m_ngon_list = 0;
00317   }
00318   int major_version = 0;
00319   int minor_version = 0;
00320   bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00321   if (!rc)
00322     return false;
00323   for (;;)
00324   {
00325     rc = (1 == major_version);
00326     if (!rc)
00327       break;
00328     int count = 0;
00329     rc = archive.ReadInt(&count);
00330     if (count <= 0 || !rc)
00331       break;
00332 
00333     m_ngon_list = new ON_MeshNgonList();
00334     if ( 0 == m_ngon_list )
00335       break;
00336 
00337     m_ngon_list->ReserveNgonCapacity(count);
00338 
00339     for ( int i = 0; i < count; i++ )
00340     {
00341       int N = 0;
00342       rc = archive.ReadInt(&N);
00343       if (!rc)
00344         break;
00345       if ( N <= 0 )
00346         continue;
00347       struct ON_MeshNgon* ngon = m_ngon_list->AddNgon(N);
00348       if ( 0 == ngon )
00349         break;
00350 
00351       rc = archive.ReadInt(N,ngon->vi);
00352       if (!rc)
00353         break;
00354       rc = archive.ReadInt(N,ngon->fi);
00355       if (!rc)
00356         break;
00357       ngon->N = N;
00358     }
00359     if (!rc)
00360       break;
00361 
00362     if ( minor_version >= 1 )
00363     {
00364       // chunk version 1.1 added face and vertex validation counts.
00365       rc = archive.ReadInt(&m_mesh_F_count);
00366       if (!rc)
00367         break;
00368       rc = archive.ReadInt(&m_mesh_V_count);
00369       if (!rc)
00370         break;
00371     }
00372 
00373     break;
00374   }
00375   if ( !archive.EndRead3dmChunk() )
00376     rc = false;
00377   return rc;
00378 }
00379 
00380 // vitual ON_UserData override
00381 ON_BOOL32 ON_MeshNgonUserData::GetDescription( ON_wString& description )
00382 {
00383   description = L"Mesh N-gon list";
00384   return true;
00385 }
00386 
00387 ON_BOOL32 ON_MeshNgonUserData::Archive() const
00388 {
00389   return ( 0 != m_ngon_list && m_ngon_list->NgonCount() > 0 );
00390 }
00391 
00392 static
00393 bool ON_ValidateNgon(
00394   const ON_MeshNgon* ngon,
00395   int mesh_V_count,
00396   int mesh_F_count
00397   )
00398 {
00399   unsigned int j;
00400   if ( 0 == ngon || ngon->N < 0 )
00401     return false;
00402   const unsigned int N = ngon->N;
00403   for ( j = 0; j < N; j++ )
00404   {
00405     if ( ngon->vi[j] < 0 || ngon->vi[j] >= mesh_V_count )
00406       return false;
00407     if ( ngon->fi[j] < -1 || ngon->fi[j] >= mesh_F_count )
00408       return false;
00409   }
00410   return true;
00411 }
00412 
00413 static 
00414 bool ON_ValidateMeshNgonUserData(
00415   ON_MeshNgonUserData* ngud,
00416   const ON_Mesh& mesh
00417   )
00418 {
00419   int i;
00420   if ( 0 == ngud || 0 == ngud->m_ngon_list )
00421     return false;
00422 
00423   const int mesh_V_count = mesh.m_V.Count();
00424   const int mesh_F_count = mesh.m_F.Count();
00425 
00426   if ( 0 == ngud->m_mesh_V_count && 0 == ngud->m_mesh_F_count )
00427   {
00428     // This is old user data that did not have validation counts
00429     // saved in the file.
00430 
00431     // Set validation counts to -1 so we never do this slow validation again.
00432     ngud->m_mesh_V_count = -1;
00433     ngud->m_mesh_F_count = -1;
00434 
00435     const int ngon_count = ngud->m_ngon_list->NgonCount();
00436 
00437     for ( i = 0; i < ngon_count; i++ )
00438     {
00439       if ( !ON_ValidateNgon(ngud->m_ngon_list->Ngon(i),mesh_V_count,mesh_F_count) )
00440         return false;
00441     }
00442 
00443     // Set validation counts to proper values because we will 
00444     // assume this old ngon information is valid since the indices
00445     // are in range.  This assumption may not be valid, but
00446     // at least the ngon won't cause a crash.
00447     ngud->m_mesh_V_count = mesh_V_count;
00448     ngud->m_mesh_F_count = mesh_F_count;
00449   }
00450 
00451   return ( ngud->m_mesh_F_count == mesh_F_count && ngud->m_mesh_V_count == mesh_V_count );
00452 }
00453                          
00454 
00455 const class ON_MeshNgonList* ON_Mesh::NgonList() const
00456 {
00457   ON_UserData* ud = GetUserData(ON_MeshNgonUserData::m_ON_MeshNgonUserData_class_id.Uuid());
00458   ON_MeshNgonUserData* ngud = ON_MeshNgonUserData::Cast(ud);
00459   
00460   if ( 0 != ngud && !ON_ValidateMeshNgonUserData(ngud,*this) )
00461   {
00462     delete ngud;
00463     ngud = 0;
00464   }
00465 
00466   return (0 == ngud) ? 0 : ngud->m_ngon_list;
00467 }
00468 
00469 
00470 class ON_MeshNgonList* ON_Mesh::ModifyNgonList()
00471 {
00472   ON_UserData* ud = GetUserData(ON_MeshNgonUserData::m_ON_MeshNgonUserData_class_id.Uuid());
00473   ON_MeshNgonUserData* ngud = ON_MeshNgonUserData::Cast(ud);
00474   if ( 0 == ngud )
00475   {
00476     if ( ud )
00477     {
00478       delete ud;
00479       ud = 0;
00480     }
00481     ngud = new ON_MeshNgonUserData();
00482     ngud->m_mesh_F_count = m_F.Count();
00483     ngud->m_mesh_V_count = m_V.Count();
00484     AttachUserData(ngud);
00485   }
00486   else if ( 0 != ngud->m_ngon_list && !ON_ValidateMeshNgonUserData(ngud,*this) )
00487   {
00488     delete ngud->m_ngon_list;
00489     ngud->m_ngon_list = 0;
00490   }
00491 
00492   if ( 0 == ngud->m_ngon_list )
00493   {
00494     ngud->m_ngon_list = new ON_MeshNgonList();
00495     ngud->m_mesh_F_count = m_F.Count();
00496     ngud->m_mesh_V_count = m_V.Count();
00497   }
00498 
00499   return ngud->m_ngon_list;
00500 }
00501 
00502 
00503 void ON_Mesh::DestroyNgonList()
00504 {
00505   ON_UserData* ud = GetUserData(ON_MeshNgonUserData::m_ON_MeshNgonUserData_class_id.Uuid());
00506   if ( 0 != ud )
00507   {
00508     delete ud;
00509     ud = 0;
00510   }
00511 }
00512 


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