Go to the documentation of this file.00001 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00002
00003
00004
00005
00006 #define ON_NGON_BOZO_VACCINE
00007
00008
00009
00010
00011
00012
00013
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));
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 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
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
00174 ON_BOOL32 GetDescription( ON_wString& );
00175 ON_BOOL32 Archive() const;
00176
00177 public:
00178 ON_MeshNgonList* m_ngon_list;
00179
00180
00181
00182
00183
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
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
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
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
00429
00430
00431
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
00444
00445
00446
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