00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018
00019
00020
00021 class ON_BrepRegionTopologyUserData : public ON_UserData
00022 {
00023 ON_OBJECT_DECLARE(ON_BrepRegionTopologyUserData);
00024 public:
00025 static ON_BrepRegionTopology* RegionTopology(const ON_Brep* brep,bool bValidateFaceCount);
00026
00027 ON_BrepRegionTopologyUserData();
00028 ~ON_BrepRegionTopologyUserData();
00029 ON_BrepRegionTopologyUserData(const ON_BrepRegionTopologyUserData&);
00030 ON_BrepRegionTopologyUserData& operator=(const ON_BrepRegionTopologyUserData&);
00031
00032 unsigned int SizeOf() const;
00033 ON_BOOL32 Archive() const;
00034 ON_BOOL32 Transform( const ON_Xform& );
00035 ON_BOOL32 Write(ON_BinaryArchive& binary_archive) const;
00036 ON_BOOL32 Read(ON_BinaryArchive& binary_archive);
00037
00038 ON_BOOL32 GetDescription( ON_wString& description );
00039
00040 ON_BrepRegionTopology m_region_topology;
00041 };
00042
00043 ON_OBJECT_IMPLEMENT(ON_BrepRegionTopologyUserData,ON_UserData,"7FE23D63-E536-43f1-98E2-C807A2625AFF");
00044
00045 ON_BrepRegionTopology* ON_BrepRegionTopologyUserData::RegionTopology(const ON_Brep* brep,bool bValidateFaceCount)
00046 {
00047 ON_BrepRegionTopology* rtop = 0;
00048 if ( brep )
00049 {
00050 ON_BrepRegionTopologyUserData* ud = ON_BrepRegionTopologyUserData::Cast(brep->GetUserData(ON_BrepRegionTopologyUserData::m_ON_BrepRegionTopologyUserData_class_id.Uuid()));
00051 if (ud)
00052 {
00053 rtop = &ud->m_region_topology;
00054 if (bValidateFaceCount && rtop->m_FS.Count() != 2*brep->m_F.Count())
00055 rtop = 0;
00056 }
00057 }
00058 return rtop;
00059 }
00060
00061 ON_BrepRegionTopologyUserData::ON_BrepRegionTopologyUserData()
00062 {
00063 m_userdata_copycount = 1;
00064 m_userdata_uuid = ON_BrepRegionTopologyUserData::m_ON_BrepRegionTopologyUserData_class_id.Uuid();
00065 m_application_uuid = ON_opennurbs4_id;
00066 }
00067
00068 ON_BrepRegionTopologyUserData::~ON_BrepRegionTopologyUserData()
00069 {
00070 }
00071
00072 ON_BrepRegionTopologyUserData::ON_BrepRegionTopologyUserData( const ON_BrepRegionTopologyUserData& src )
00073 : ON_UserData(src)
00074 , m_region_topology(src.m_region_topology)
00075 {
00076 m_userdata_uuid = ON_BrepRegionTopologyUserData::m_ON_BrepRegionTopologyUserData_class_id.Uuid();
00077 m_application_uuid = ON_opennurbs4_id;
00078 }
00079
00080 ON_BrepRegionTopologyUserData& ON_BrepRegionTopologyUserData::operator=(const ON_BrepRegionTopologyUserData& src)
00081 {
00082 if ( this != &src )
00083 {
00084 ON_UserData::operator=(src);
00085 m_region_topology = src.m_region_topology;
00086 }
00087 return *this;
00088 }
00089
00090 unsigned int ON_BrepRegionTopologyUserData::SizeOf() const
00091 {
00092 return ON_UserData::SizeOf() + m_region_topology.SizeOf();
00093 }
00094
00095 ON_BOOL32 ON_BrepRegionTopologyUserData::Archive() const
00096 {
00097 return true;
00098 }
00099
00100 ON_BOOL32 ON_BrepRegionTopologyUserData::Transform( const ON_Xform& xform)
00101 {
00102
00103
00104
00105 int i, j;
00106 const int region_count = m_region_topology.m_R.Count();
00107 const int faceside_count = m_region_topology.m_FS.Count();
00108 const ON_Brep* brep = ON_Brep::Cast(Owner());
00109 if ( brep )
00110 {
00111 const int face_count = brep->m_F.Count();
00112 for (i = 0; i < region_count; i++ )
00113 {
00114 ON_BrepRegion& r = m_region_topology.m_R[i];
00115 r.m_bbox.Destroy();
00116 for ( j = 0; j < r.m_fsi.Count(); j++ )
00117 {
00118 int fsi = r.m_fsi[j];
00119 if ( fsi >= 0 && fsi < faceside_count )
00120 {
00121 int fi = m_region_topology.m_FS[fsi].m_fi;
00122 if ( fi >= 0 && fi < face_count )
00123 {
00124 r.m_bbox.Union(brep->m_F[fi].BoundingBox());
00125 }
00126 }
00127 }
00128 }
00129 }
00130
00131 for ( i = 0; i < faceside_count; i++ )
00132 m_region_topology.m_FS[i].TransformUserData(xform);
00133 for ( i = 0; i < region_count; i++ )
00134 m_region_topology.m_R[i].TransformUserData(xform);
00135
00136 return true;
00137 }
00138
00139 ON_BOOL32 ON_BrepRegionTopologyUserData::Write(ON_BinaryArchive& binary_archive) const
00140 {
00141 return m_region_topology.Write(binary_archive);
00142 }
00143
00144 ON_BOOL32 ON_BrepRegionTopologyUserData::Read(ON_BinaryArchive& binary_archive)
00145 {
00146 m_region_topology.m_brep = ON_Brep::Cast(Owner());
00147 return m_region_topology.Read(binary_archive);
00148 }
00149
00150 ON_BOOL32 ON_BrepRegionTopologyUserData::GetDescription( ON_wString& description )
00151 {
00152 description=L"Brep Region Topology";
00153 return true;
00154 }
00155
00156 ON_OBJECT_IMPLEMENT(ON_BrepFaceSide,ON_Object,"30930370-0D5B-4ee4-8083-BD635C7398A4");
00157
00158 ON_BOOL32 ON_BrepFaceSide::IsValid( ON_TextLog* text_log ) const
00159 {
00160 return true;
00161 }
00162
00163 ON_BrepFaceSide::ON_BrepFaceSide()
00164 {
00165 m_faceside_index = -1;
00166 m_ri = -1;
00167 m_fi = -1;
00168 m_srf_dir = 0;
00169 m_rtop = 0;
00170 memset(&m_faceside_user,0,sizeof(m_faceside_user));
00171 }
00172
00173 ON_BrepFaceSide::~ON_BrepFaceSide()
00174 {
00175 }
00176
00177 ON_BrepFaceSide& ON_BrepFaceSide::operator=(const ON_BrepFaceSide& src)
00178 {
00179 if ( this != &src)
00180 {
00181
00182 m_faceside_user = src.m_faceside_user;
00183 m_faceside_index = src.m_faceside_index;
00184 m_ri = src.m_ri;
00185 m_fi = src.m_fi;
00186 m_srf_dir = src.m_srf_dir;
00187 ON_Object::operator=(src);
00188 }
00189 return *this;
00190 }
00191
00192 ON_BOOL32 ON_BrepFaceSide::Write(ON_BinaryArchive& file) const
00193 {
00194 bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00195 if ( !rc )
00196 return false;
00197 for(;;)
00198 {
00199 rc = file.WriteInt( m_faceside_index );
00200 if (!rc) break;
00201 rc = file.WriteInt( m_ri );
00202 if (!rc) break;
00203 rc = file.WriteInt( m_fi );
00204 if (!rc) break;
00205 rc = file.WriteInt( m_srf_dir );
00206 if (!rc) break;
00207
00208 break;
00209 }
00210 if (!file.EndWrite3dmChunk())
00211 rc = false;
00212 return rc;
00213 }
00214
00215 ON_BOOL32 ON_BrepFaceSide::Read(ON_BinaryArchive& file)
00216 {
00217 int major_version = 0;
00218 int minor_version = 0;
00219 bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00220 if ( !rc )
00221 return false;
00222 for(;;)
00223 {
00224 rc = (1==major_version);
00225 if (!rc) break;
00226 rc = file.ReadInt( &m_faceside_index );
00227 if (!rc) break;
00228 rc = file.ReadInt( &m_ri );
00229 if (!rc) break;
00230 rc = file.ReadInt( &m_fi );
00231 if (!rc) break;
00232 rc = file.ReadInt( &m_srf_dir );
00233 if (!rc) break;
00234
00235 break;
00236 }
00237 if (!file.EndRead3dmChunk())
00238 rc = false;
00239 return rc;
00240 }
00241
00242
00243 ON_Brep* ON_BrepFaceSide::Brep() const
00244 {
00245 return m_rtop ? m_rtop->Brep() : 0;
00246 }
00247
00248
00249 ON_BrepRegionTopology* ON_BrepFaceSide::RegionTopology() const
00250 {
00251 return m_rtop;
00252 }
00253
00254 ON_BrepRegion* ON_BrepFaceSide::Region() const
00255 {
00256 ON_BrepRegion* region = 0;
00257 if ( m_rtop && m_ri >= 0 && m_ri < m_rtop->m_R.Count() )
00258 {
00259 region = &m_rtop->m_R[m_ri];
00260
00261 }
00262 return region;
00263 }
00264
00265 class ON_BrepFace* ON_BrepFaceSide::Face() const
00266 {
00267 class ON_BrepFace* face = 0;
00268 if ( m_rtop && m_fi >= 0 )
00269 {
00270 ON_Brep* brep = m_rtop->Brep();
00271 if ( brep && m_fi < brep->m_F.Count() )
00272 {
00273 face = &brep->m_F[m_fi];
00274 }
00275 }
00276 return face;
00277 }
00278
00279 int ON_BrepFaceSide::SurfaceNormalDirection() const
00280 {
00281 return m_srf_dir;
00282 }
00283
00284 ON_OBJECT_IMPLEMENT(ON_BrepRegion,ON_Object,"CA7A0092-7EE6-4f99-B9D2-E1D6AA798AA1");
00285
00286 ON_BOOL32 ON_BrepRegion::IsValid( ON_TextLog* text_log ) const
00287 {
00288 return true;
00289 }
00290
00291
00292 ON_BrepRegion::ON_BrepRegion()
00293 {
00294 m_region_index = -1;
00295 m_type = -1;
00296 m_rtop = 0;
00297 memset(&m_region_user,0,sizeof(m_region_user));
00298 }
00299
00300 ON_BrepRegion::~ON_BrepRegion()
00301 {
00302 }
00303
00304 ON_BrepRegion& ON_BrepRegion::operator=(const ON_BrepRegion& src)
00305 {
00306 if ( this != &src )
00307 {
00308
00309 m_region_user = src.m_region_user;
00310 m_region_index = src.m_region_index;
00311 m_fsi = src.m_fsi;
00312 m_type = src.m_type;
00313 m_bbox = src.m_bbox;
00314 ON_Object::operator=(src);
00315 }
00316 return *this;
00317 }
00318
00319
00320 ON_BOOL32 ON_BrepRegion::Write(ON_BinaryArchive& file) const
00321 {
00322 bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00323 if ( !rc )
00324 return false;
00325 for(;;)
00326 {
00327 rc = file.WriteInt( m_region_index );
00328 if (!rc) break;
00329 rc = file.WriteInt( m_type );
00330 if (!rc) break;
00331 rc = file.WriteArray( m_fsi );
00332 if (!rc) break;
00333 rc = file.WriteBoundingBox( m_bbox );
00334 if (!rc) break;
00335
00336 break;
00337 }
00338 if (!file.EndWrite3dmChunk())
00339 rc = false;
00340 return rc;
00341 }
00342
00343 ON_BOOL32 ON_BrepRegion::Read(ON_BinaryArchive& file)
00344 {
00345 int major_version = 0;
00346 int minor_version = 0;
00347 bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00348 if ( !rc )
00349 return false;
00350 for(;;)
00351 {
00352 rc = (1==major_version);
00353 if (!rc) break;
00354 rc = file.ReadInt( &m_region_index );
00355 if (!rc) break;
00356 rc = file.ReadInt( &m_type );
00357 if (!rc) break;
00358 rc = file.ReadArray( m_fsi );
00359 if (!rc) break;
00360 rc = file.ReadBoundingBox( m_bbox );
00361 if (!rc) break;
00362
00363 break;
00364 }
00365 if (!file.EndRead3dmChunk())
00366 rc = false;
00367 return rc;
00368 }
00369
00370
00371 ON_Brep* ON_BrepRegion::Brep() const
00372 {
00373 return m_rtop ? m_rtop->Brep() : 0;
00374 }
00375
00376 ON_BrepRegionTopology* ON_BrepRegion::RegionTopology() const
00377 {
00378 return m_rtop;
00379 }
00380
00381
00382 ON_BrepFaceSide* ON_BrepRegion::FaceSide(int rfsi) const
00383 {
00384 ON_BrepFaceSide* faceside = 0;
00385 if ( m_rtop && rfsi >= 0 && rfsi < m_fsi.Count() )
00386 {
00387 int fsi = m_fsi[rfsi];
00388 if ( fsi >= 0 && fsi < m_rtop->m_FS.Count() )
00389 {
00390 faceside = &m_rtop->m_FS[fsi];
00391 }
00392 }
00393 return faceside;
00394 }
00395
00396
00397 bool ON_BrepRegion::IsFinite() const
00398 {
00399 return (1 == m_type);
00400 }
00401
00402 const ON_BoundingBox& ON_BrepRegion::BoundingBox() const
00403 {
00404 return m_bbox;
00405 }
00406
00407 ON_BrepFaceSideArray::ON_BrepFaceSideArray()
00408 {
00409 }
00410
00411 ON_BrepFaceSideArray::~ON_BrepFaceSideArray()
00412 {
00413 }
00414
00415 bool ON_BrepFaceSideArray::Read( ON_BinaryArchive& file )
00416 {
00417 Empty();
00418 int count = 0;
00419 int i;
00420 int major_version = 0;
00421 int minor_version = 0;
00422 bool rc = file.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK, &major_version, &minor_version );
00423 if (rc)
00424 {
00425 for(;;)
00426 {
00427 rc = (1 == major_version);
00428 if (!rc) break;
00429 if (rc) rc = file.ReadInt(&count);
00430 SetCapacity(count);
00431 for ( i = 0; i < count && rc; i++ )
00432 {
00433 ON_BrepFaceSide& faceside = AppendNew();
00434 rc = faceside.Read(file)?true:false;
00435 }
00436 break;
00437 }
00438 if ( !file.EndRead3dmChunk() )
00439 rc = false;
00440 }
00441 return rc;
00442 }
00443
00444 bool ON_BrepFaceSideArray::Write( ON_BinaryArchive& file ) const
00445 {
00446 int i;
00447 bool rc = file.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 0 );
00448 if (rc)
00449 {
00450 const int count = Count();
00451 if (rc) rc = file.WriteInt( count );
00452 for ( i = 0; rc && i < count; i++ )
00453 {
00454 rc = m_a[i].Write(file)?true:false;
00455 }
00456 if ( !file.EndWrite3dmChunk() )
00457 rc = false;
00458 }
00459 return rc;
00460 }
00461
00462 unsigned int ON_BrepFaceSideArray::SizeOf() const
00463 {
00464 unsigned int sz = SizeOfArray();
00465 for ( int i = 0; i < m_count; i++ )
00466 sz += (m_a[i].SizeOf() - ((unsigned int)sizeof(ON_BrepFaceSide)));
00467 return sz;
00468 }
00469
00470 ON_BrepRegionArray::ON_BrepRegionArray()
00471 {
00472 }
00473
00474 ON_BrepRegionArray::~ON_BrepRegionArray()
00475 {
00476 }
00477
00478 bool ON_BrepRegionArray::Read( ON_BinaryArchive& file )
00479 {
00480 Empty();
00481 int count = 0;
00482 int i;
00483 int major_version = 0;
00484 int minor_version = 0;
00485 bool rc = file.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK, &major_version, &minor_version );
00486 if (rc)
00487 {
00488 for(;;)
00489 {
00490 rc = (1 == major_version);
00491 if (!rc) break;
00492 if (rc) rc = file.ReadInt(&count);
00493 SetCapacity(count);
00494 for ( i = 0; i < count && rc ; i++ )
00495 {
00496 ON_BrepRegion& region = AppendNew();
00497 rc = region.Read(file)?true:false;
00498 }
00499 break;
00500 }
00501 if ( !file.EndRead3dmChunk() )
00502 rc = false;
00503 }
00504 return rc;
00505 }
00506
00507 bool ON_BrepRegionArray::Write( ON_BinaryArchive& file ) const
00508 {
00509 int i;
00510 bool rc = file.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 0 );
00511 if (rc)
00512 {
00513 const int count = Count();
00514 if (rc) rc = file.WriteInt( count );
00515 for ( i = 0; rc && i < count; i++ )
00516 {
00517 rc = m_a[i].Write(file)?true:false;
00518 }
00519 if ( !file.EndWrite3dmChunk() )
00520 rc = false;
00521 }
00522 return rc;
00523 }
00524
00525 unsigned int ON_BrepRegionArray::SizeOf() const
00526 {
00527 unsigned int sz = SizeOfArray();
00528 for ( int i = 0; i < m_count; i++ )
00529 sz += (m_a[i].SizeOf() - ((unsigned int)sizeof(ON_BrepRegion)));
00530 return sz;
00531 }
00532
00533 ON_BrepRegionTopology::ON_BrepRegionTopology()
00534 {
00535 }
00536
00537 ON_BrepRegionTopology::~ON_BrepRegionTopology()
00538 {
00539 }
00540
00541 ON_BrepRegionTopology::ON_BrepRegionTopology(const ON_BrepRegionTopology& src)
00542 {
00543 int i;
00544
00545 m_brep = 0;
00546 m_FS = src.m_FS;
00547 m_R = src.m_R;
00548 for (i = 0; i < m_FS.Count(); i++ )
00549 m_FS[i].m_rtop = this;
00550 for (i = 0; i < m_R.Count(); i++ )
00551 m_R[i].m_rtop = this;
00552 }
00553
00554 ON_BrepRegionTopology& ON_BrepRegionTopology::operator=(const ON_BrepRegionTopology& src)
00555 {
00556 if ( this != &src )
00557 {
00558
00559 m_FS = src.m_FS;
00560 m_R = src.m_R;
00561 int i;
00562 for (i = 0; i < m_FS.Count(); i++ )
00563 m_FS[i].m_rtop = this;
00564 for (i = 0; i < m_R.Count(); i++ )
00565 m_R[i].m_rtop = this;
00566 }
00567 return *this;
00568 }
00569
00570
00571 bool ON_BrepRegionTopology::IsValid( ON_TextLog* text_log) const
00572 {
00573 #define PRINT_MSG(s) if (text_log) text_log->Print(s)
00574 #define PRINT_MSG1(s,a1) if (text_log) text_log->Print(s,a1)
00575 #define PRINT_MSG2(s,a1,a2) if (text_log) text_log->Print(s,a1,a2)
00576 #define PRINT_MSG3(s,a1,a2,a3) if (text_log) text_log->Print(s,a1,a2,a3)
00577 int infinite_region_index = -1;
00578 int rfs_count = 0;
00579 int ri, fsi;
00580 if ( !m_brep )
00581 {
00582 PRINT_MSG("ON_BrepRegionTopology::m_brep is NULL\n");
00583 return false;
00584 }
00585 const int faceside_count = m_FS.Count();
00586 if ( faceside_count != 2*m_brep->m_F.Count() )
00587 {
00588 PRINT_MSG("ON_BrepRegionTopology::m_FS.Count() != 2*m_brep->m_F.Count()\n");
00589 return false;
00590 }
00591
00592 int void_regionside_count = 0;
00593 for ( fsi = 0; fsi < faceside_count; fsi++ )
00594 {
00595 const ON_BrepFaceSide& fs = m_FS[fsi];
00596 const int fi = fsi/2;
00597 const int srf_dir = (fsi%2) ? -1 : 1;
00598 if ( fs.m_rtop != this )
00599 {
00600 PRINT_MSG1("ON_BrepRegionTopology::m_FS[%d].m_rtop != this\n",fsi);
00601 return false;
00602 }
00603 if ( fi != fs.m_fi )
00604 {
00605 PRINT_MSG3("ON_BrepRegionTopology::m_FS[%d].m_fi = %d != %d\n",fsi,fs.m_fi,fi);
00606 return false;
00607 }
00608 if ( fs.m_srf_dir != srf_dir )
00609 {
00610 PRINT_MSG3("ON_BrepRegionTopology::m_FS[%d].m_srf_dir = %d != %d\n",fsi,fs.m_srf_dir,srf_dir);
00611 return false;
00612 }
00613 if ( -1 == fs.m_ri )
00614 {
00615 void_regionside_count++;
00616 }
00617 }
00618
00619 const int region_count = m_R.Count();
00620 if ( region_count <= 0 )
00621 {
00622 PRINT_MSG("ON_BrepRegionTopology::m_R.Count() <= 0\n");
00623 return false;
00624 }
00625 for ( ri = 0; ri < region_count; ri++ )
00626 {
00627 const ON_BrepRegion& region = m_R[ri];
00628 if ( region.m_rtop != this )
00629 {
00630 PRINT_MSG1("ON_BrepRegionTopology::m_R[%d].m_rtop != this\n",ri);
00631 return false;
00632 }
00633 if ( region.m_type < 0 )
00634 {
00635 PRINT_MSG("ON_BrepRegionTopology::m_R[%d].m_type < 0\n");
00636 return false;
00637 }
00638 if ( region.m_type > 1 )
00639 {
00640 PRINT_MSG("ON_BrepRegionTopology::m_R[%d].m_type > 1\n");
00641 return false;
00642 }
00643 if ( 0 == region.m_type )
00644 {
00645 if ( infinite_region_index >= 0 )
00646 {
00647 PRINT_MSG2("ON_BrepRegionTopology::m_R[%d and %d].m_type = 0\n",infinite_region_index,ri);
00648 return false;
00649 }
00650 infinite_region_index = ri;
00651 }
00652 if ( region.m_fsi.Count() <= 0 )
00653 {
00654 PRINT_MSG1("ON_BrepRegionTopology::m_R[%d].m_fsi.Count() <= 0\n",ri);
00655 return false;
00656 }
00657 for ( int rfsi = 0; rfsi < region.m_fsi.Count(); rfsi++ )
00658 {
00659 fsi = region.m_fsi[rfsi];
00660 if ( fsi < 0 || fsi >= faceside_count)
00661 {
00662 PRINT_MSG2("ON_BrepRegionTopology::m_R[%d].m_fsi[%d] is out of range\n",ri,rfsi);
00663 return false;
00664 }
00665 const ON_BrepFaceSide& faceside = m_FS[fsi];
00666 if ( faceside.m_ri != ri )
00667 {
00668 PRINT_MSG3("ON_BrepRegionTopology::m_FS[m_R[%d].m_fsi[%d]].m_ri != %d\n",ri,rfsi,ri);
00669 return false;
00670 }
00671 for ( int j = rfsi+1; j < region.m_fsi.Count(); j++ )
00672 {
00673 if ( fsi == region.m_fsi[j] )
00674 {
00675 PRINT_MSG3("ON_BrepRegionTopology::m_R[%d].m_fsi[%d and %d]] are duplicates\n",ri,rfsi,j);
00676 return false;
00677 }
00678 }
00679 rfs_count++;
00680 }
00681 }
00682
00683 if ( faceside_count != rfs_count+void_regionside_count )
00684 {
00685 PRINT_MSG2("Sum of ON_BrepRegionTopology::m_R[%d].m_fsi.Count() = %d != m_FS.Count()\n",ri,rfs_count);
00686 return false;
00687 }
00688
00689 if ( infinite_region_index < 0 )
00690 {
00691 PRINT_MSG("ON_BrepRegionTopology::m_R[] has no infinte region\n");
00692 return false;
00693 }
00694
00695 #undef PRINT_MSG
00696 #undef PRINT_MSG1
00697 #undef PRINT_MSG2
00698 #undef PRINT_MSG3
00699 return true;
00700 }
00701
00702 ON_Brep* ON_BrepRegionTopology::Brep() const
00703 {
00704 return m_brep;
00705 }
00706
00707
00708 bool ON_BrepRegionTopology::Read( ON_BinaryArchive& file )
00709 {
00710 int i;
00711 int major_version = 0;
00712 int minor_version = 0;
00713 bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00714 if ( !rc )
00715 return false;
00716 for(;;)
00717 {
00718 rc = (1 == major_version);
00719 if (!rc) break;
00720
00721 rc = m_FS.Read(file);
00722 for ( i = 0; i < m_FS.Count(); i++ )
00723 m_FS[i].m_rtop = this;
00724 if (!rc) break;
00725
00726 rc = m_R.Read(file);
00727 for ( i = 0; i < m_R.Count(); i++ )
00728 m_R[i].m_rtop = this;
00729 if (!rc) break;
00730
00731 break;
00732 }
00733 if ( !file.EndRead3dmChunk() )
00734 rc = false;
00735 return rc;
00736 }
00737
00738 bool ON_BrepRegionTopology::Write( ON_BinaryArchive& file) const
00739 {
00740 bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00741 if (!rc)
00742 return false;
00743 for(;;)
00744 {
00745 rc = m_FS.Write(file);
00746 if (!rc) break;
00747 rc = m_R.Write(file);
00748 if (!rc) break;
00749
00750 break;
00751 }
00752 if ( !file.EndWrite3dmChunk() )
00753 rc = false;
00754 return rc;
00755 }
00756
00757 unsigned int ON_BrepRegionTopology::SizeOf() const
00758 {
00759 return m_FS.SizeOf() + m_R.SizeOf();
00760 }
00761
00762 ON_BrepFaceSide* ON_BrepFace::FaceSide(int dir) const
00763 {
00764 ON_BrepFaceSide* faceside = 0;
00765 const ON_BrepRegionTopology* rtop = ON_BrepRegionTopologyUserData::RegionTopology(m_brep,true);
00766 if ( rtop )
00767 {
00768 if ( m_face_index >= 0 && m_face_index < m_brep->m_F.Count() )
00769 {
00770 int fsi = 2*m_face_index + ((dir<1)?1:0);
00771 faceside = const_cast<ON_BrepFaceSide*>(&rtop->m_FS[fsi]);
00772 if ( m_face_index != faceside->m_fi || dir != faceside->m_srf_dir )
00773 faceside = 0;
00774 }
00775 }
00776 return faceside;
00777 }
00778
00779 bool ON_Brep::HasRegionTopology() const
00780 {
00781 ON_UserData* ud = GetUserData(ON_BrepRegionTopologyUserData::m_ON_BrepRegionTopologyUserData_class_id.Uuid());
00782 return (0 != ud);
00783 }
00784
00785 const ON_BrepRegionTopology& ON_Brep::RegionTopology() const
00786 {
00787 ON_BrepRegionTopology* rtop = ON_BrepRegionTopologyUserData::RegionTopology(this,false);
00788 if ( 0 == rtop )
00789 {
00790 ON_BrepRegionTopologyUserData* ud = new ON_BrepRegionTopologyUserData();
00791 if ( const_cast<ON_Brep*>(this)->AttachUserData(ud) )
00792 {
00793 rtop = &ud->m_region_topology;
00794 }
00795 else
00796 {
00797 ON_ERROR("Unable to create brep region topology");
00798 delete ud;
00799 }
00800 }
00801
00802
00803
00804 return *rtop;
00805 }
00806
00807 void ON_Brep::DestroyRegionTopology()
00808 {
00809 ON_UserData* ud = GetUserData(ON_BrepRegionTopologyUserData::m_ON_BrepRegionTopologyUserData_class_id.Uuid());
00810 if ( ud )
00811 delete ud;
00812 }
00813
00814 void ON_Brep::MemoryRelocate()
00815 {
00816 int i, count;
00817
00818
00819
00820 ON_Geometry::MemoryRelocate();
00821
00822
00823
00824
00825 count = m_E.Count();
00826 for ( i = 0; i < count; i++ )
00827 {
00828 m_E[i].m_brep = this;
00829 }
00830
00831 count = m_T.Count();
00832 for ( i = 0; i < count; i++ )
00833 {
00834 m_T[i].m_brep = this;
00835 }
00836
00837 count = m_L.Count();
00838 for ( i = 0; i < count; i++ )
00839 {
00840 m_L[i].m_brep = this;
00841 }
00842
00843 count = m_F.Count();
00844 for ( i = 0; i < count; i++ )
00845 {
00846 m_F[i].m_brep = this;
00847 }
00848
00849 ON_BrepRegionTopology* rtop = ON_BrepRegionTopologyUserData::RegionTopology(this,false);
00850 if ( rtop )
00851 {
00852 rtop->m_brep = this;
00853 count = rtop->m_FS.Count();
00854 for ( i = 0; i < count; i++ )
00855 rtop->m_FS[i].m_rtop = rtop;
00856 count = rtop->m_R.Count();
00857 for ( i = 0; i < count; i++ )
00858 rtop->m_R[i].m_rtop = rtop;
00859 }
00860
00861 }
00862
00863 ON_Brep* ON_Brep::SubBrep(
00864 int subfi_count,
00865 const int* subfi,
00866 ON_Brep* sub_brep
00867 ) const
00868 {
00869 class LeakStopper : public ON_Workspace
00870 {
00871
00872
00873
00874 public:
00875 LeakStopper() {m_p=0;m_sub_brep=0;}
00876 ~LeakStopper() {if (m_p) delete m_p; else if (m_sub_brep) m_sub_brep->Destroy();}
00877 ON_Brep* m_p;
00878 ON_Brep* m_sub_brep;
00879 };
00880 LeakStopper leak_stopper;
00881
00882 if ( sub_brep )
00883 sub_brep->Destroy();
00884
00885 if ( subfi_count <= 0 || 0 == subfi )
00886 return 0;
00887
00888 if ( subfi_count > m_F.Count() )
00889 return 0;
00890
00891
00892
00893 int fi, fli, lti, i, j;
00894 int Lcount = 0;
00895 int Tcount = 0;
00896 int Ecount = 0;
00897 int Vcount = 0;
00898 int maxfi = -1;
00899 int minfi = m_F.Count();
00900 int* Emap = leak_stopper.GetIntMemory(m_E.Count());
00901 memset(Emap,0,m_E.Count()*sizeof(Emap[0]));
00902 int* Vmap = leak_stopper.GetIntMemory(m_V.Count());
00903 memset(Vmap,0,m_V.Count()*sizeof(Vmap[0]));
00904 for ( i = 0; i < subfi_count; i++ )
00905 {
00906 fi = subfi[i];
00907 if ( fi < 0 || fi >= m_F.Count() )
00908 {
00909 ON_ERROR("ON_Brep::SubBrep sub_fi[] has invalid indices");
00910 return 0;
00911 }
00912 if ( fi > maxfi )
00913 maxfi = fi;
00914 else if ( fi < minfi )
00915 minfi = fi;
00916 else
00917 {
00918 for ( j = 0; j < i; j++ )
00919 {
00920 if ( subfi[j] == fi )
00921 {
00922 ON_ERROR("ON_Brep::SubBrep sub_fi[] has duplicate indices");
00923 return 0;
00924 }
00925 }
00926 }
00927
00928 const ON_BrepFace& face = m_F[fi];
00929 for ( fli = 0; fli < face.m_li.Count(); fli++ )
00930 {
00931 const ON_BrepLoop* loop = face.Loop(fli);
00932 if ( !loop || this != loop->Brep() )
00933 return 0;
00934 Lcount++;
00935 for ( lti = 0; lti < loop->m_ti.Count(); lti++ )
00936 {
00937 const ON_BrepTrim* trim = loop->Trim(lti);
00938 if ( !trim || this != trim->Brep() )
00939 return 0;
00940 Tcount++;
00941 if ( trim->m_vi[0] < 0 || trim->m_vi[0] >= m_V.Count() )
00942 return 0;
00943 if ( trim->m_vi[1] < 0 || trim->m_vi[1] >= m_V.Count() )
00944 return 0;
00945 if ( 0 == Vmap[trim->m_vi[0]] )
00946 {
00947 Vmap[trim->m_vi[0]] = 1;
00948 Vcount++;
00949 }
00950 if ( 0 == Vmap[trim->m_vi[1]] )
00951 {
00952 Vmap[trim->m_vi[1]] = 1;
00953 Vcount++;
00954 }
00955 if ( ON_BrepTrim::singular == trim->m_type ||
00956 ON_BrepTrim::ptonsrf == trim->m_type)
00957 {
00958 if ( trim->m_ei >= 0 || trim->m_vi[0] != trim->m_vi[1] )
00959 return 0;
00960 }
00961 else if ( trim->m_ei >= 0 )
00962 {
00963 const ON_BrepEdge* edge = trim->Edge();
00964 if ( 0 == edge || this != edge->Brep() )
00965 return 0;
00966 if ( 0 == Emap[trim->m_ei] )
00967 {
00968 Emap[trim->m_ei] = 1;
00969 Ecount++;
00970
00971 if ( 0 == Vmap[edge->m_vi[0]] )
00972 return 0;
00973 if ( 0 == Vmap[edge->m_vi[1]] )
00974 return 0;
00975 }
00976 }
00977 else
00978 {
00979 return 0;
00980 }
00981 }
00982 }
00983 }
00984
00985 if ( !sub_brep )
00986 {
00987 sub_brep = ON_Brep::New();
00988 leak_stopper.m_p = sub_brep;
00989 }
00990 else
00991 {
00992 leak_stopper.m_sub_brep = sub_brep;
00993 }
00994
00995 sub_brep->m_F.Reserve(subfi_count);
00996 sub_brep->m_L.Reserve(Lcount);
00997 sub_brep->m_T.Reserve(Tcount);
00998 sub_brep->m_E.Reserve(Ecount);
00999 sub_brep->m_V.Reserve(Vcount);
01000 sub_brep->m_S.Reserve(subfi_count);
01001 sub_brep->m_C2.Reserve(Tcount);
01002 sub_brep->m_C3.Reserve(Ecount);
01003
01004
01005 for ( i = 0; i < m_V.Count(); i++ )
01006 {
01007 if ( Vmap[i] )
01008 {
01009 const ON_BrepVertex& vertex = m_V[i];
01010 ON_BrepVertex& sub_vertex = sub_brep->NewVertex(vertex.point,vertex.m_tolerance);
01011 Vmap[i] = sub_vertex.m_vertex_index;
01012 sub_vertex.CopyUserData(vertex);
01013
01014 memcpy(&sub_vertex.m_vertex_user, &vertex.m_vertex_user, sizeof(sub_vertex.m_vertex_user));
01015 }
01016 else
01017 Vmap[i] = -1;
01018 }
01019
01020
01021 for ( i = 0; i < m_E.Count(); i++ )
01022 {
01023 if ( Emap[i] )
01024 {
01025 const ON_BrepEdge& edge = m_E[i];
01026 if ( Vmap[edge.m_vi[0]] < 0 )
01027 return 0;
01028 if ( Vmap[edge.m_vi[1]] < 0 )
01029 return 0;
01030 ON_Curve* c3 = edge.DuplicateCurve();
01031 if ( 0 == c3 )
01032 return 0;
01033 sub_brep->m_C3.Append(c3);
01034 ON_BrepVertex& sub_v0 = sub_brep->m_V[Vmap[edge.m_vi[0]]];
01035 ON_BrepVertex& sub_v1 = sub_brep->m_V[Vmap[edge.m_vi[1]]];
01036 ON_BrepEdge& sub_edge = sub_brep->NewEdge(sub_v0,sub_v1,sub_brep->m_C3.Count()-1,0,edge.m_tolerance);
01037 Emap[i] = sub_edge.m_edge_index;
01038 sub_edge.CopyUserData(edge);
01039
01040 memcpy(&sub_edge.m_edge_user, &edge.m_edge_user, sizeof(sub_edge.m_edge_user));
01041 }
01042 else
01043 Emap[i] = -1;
01044 }
01045
01046 bool bHaveBBox = m_bbox.IsValid();
01047 ON_BoundingBox sub_bbox;
01048
01049 for ( i = 0; i < subfi_count; i++ )
01050 {
01051 const ON_BrepFace& face = m_F[subfi[i]];
01052 ON_Surface* srf = face.DuplicateSurface();
01053 if (!srf)
01054 return 0;
01055 sub_brep->m_S.Append(srf);
01056 ON_BrepFace& sub_face = sub_brep->NewFace(sub_brep->m_S.Count()-1);
01057 sub_face.CopyUserData(face);
01058 sub_face.m_bRev = face.m_bRev;
01059 sub_face.m_face_material_channel = face.m_face_material_channel;
01060 sub_face.m_face_uuid = face.m_face_uuid;
01061 sub_face.m_bbox = face.m_bbox;
01062 sub_face.m_domain[0] = face.m_domain[0];
01063 sub_face.m_domain[1] = face.m_domain[1];
01064
01065 memcpy(&sub_face.m_face_user, &face.m_face_user, sizeof(sub_face.m_face_user));
01066
01067 if ( bHaveBBox )
01068 {
01069 if ( sub_face.m_bbox.IsValid() )
01070 sub_bbox.Union(sub_face.m_bbox);
01071 else
01072 {
01073 bHaveBBox = false;
01074 sub_bbox.Destroy();
01075 }
01076 }
01077
01078
01079 for ( fli = 0; fli < face.m_li.Count(); fli++ )
01080 {
01081 const ON_BrepLoop& loop = m_L[face.m_li[fli]];
01082 ON_BrepLoop& sub_loop = sub_brep->NewLoop(loop.m_type,sub_face);
01083 sub_loop.CopyUserData(loop);
01084 sub_loop.m_pbox = loop.m_pbox;
01085
01086 memcpy(&sub_loop.m_loop_user, &loop.m_loop_user, sizeof(sub_loop.m_loop_user));
01087
01088 for ( lti = 0; lti < loop.m_ti.Count(); lti++ )
01089 {
01090 const ON_BrepTrim& trim = m_T[loop.m_ti[lti]];
01091 if ( Vmap[trim.m_vi[0]] < 0 || Vmap[trim.m_vi[1]] < 0 )
01092 return 0;
01093 if ( trim.m_ei >= 0 && Emap[trim.m_ei] < 0 )
01094 return 0;
01095 if(trim.m_c2i >= 0)
01096 {
01097 ON_Curve* c2 = trim.DuplicateCurve();
01098 if ( !c2 )
01099 return 0;
01100 sub_brep->m_C2.Append(c2);
01101 }
01102 else if(trim.m_type != ON_BrepTrim::ptonsrf)
01103 return 0;
01104 if ( trim.m_ei >= 0 )
01105 {
01106 ON_BrepEdge& sub_edge = sub_brep->m_E[Emap[trim.m_ei]];
01107 sub_brep->NewTrim(sub_edge,trim.m_bRev3d,sub_loop,sub_brep->m_C2.Count()-1);
01108 }
01109 else if ( ON_BrepTrim::singular == trim.m_type )
01110 {
01111 ON_BrepVertex& sub_vertex = sub_brep->m_V[Vmap[trim.m_vi[0]]];
01112 sub_brep->NewSingularTrim(sub_vertex,sub_loop,trim.m_iso,sub_brep->m_C2.Count()-1);
01113 }
01114
01115 else if ( ON_BrepTrim::ptonsrf == trim.m_type)
01116 {
01117 ON_BrepTrim& sub_trim = sub_brep->NewTrim(false, sub_loop, -1);
01118 sub_trim.m_type = ON_BrepTrim::ptonsrf;
01119 ON_BrepVertex& sub_vertex = sub_brep->m_V[Vmap[trim.m_vi[0]]];
01120 sub_trim.m_vi[0] = sub_trim.m_vi[1] = sub_vertex.m_vertex_index;
01121 }
01122 else
01123 {
01124 return 0;
01125 }
01126 ON_BrepTrim& sub_trim = sub_brep->m_T[sub_brep->m_T.Count()-1];
01127 sub_trim.CopyUserData(trim);
01128 sub_trim.m__legacy_2d_tol = trim.m__legacy_2d_tol;
01129 sub_trim.m__legacy_3d_tol = trim.m__legacy_3d_tol;
01130 sub_trim.m__legacy_flags = trim.m__legacy_flags;
01131 sub_trim.m_tolerance[0] = trim.m_tolerance[0];
01132 sub_trim.m_tolerance[1] = trim.m_tolerance[1];
01133 sub_trim.m_pbox = trim.m_pbox;
01134 sub_trim.m_iso = trim.m_iso;
01135
01136 memcpy(&sub_trim.m_trim_user, &trim.m_trim_user, sizeof(sub_trim.m_trim_user));
01137
01138
01139
01140
01141
01142 if ( ON_BrepTrim::mated != trim.m_type )
01143 sub_trim.m_type = trim.m_type;
01144 }
01145 }
01146 }
01147
01148 if ( !bHaveBBox || !sub_bbox.IsValid() )
01149 sub_brep->BoundingBox();
01150 else
01151 sub_brep->m_bbox = sub_bbox;
01152
01153
01154 leak_stopper.m_p = 0;
01155 leak_stopper.m_sub_brep = 0;
01156 return sub_brep;
01157 }
01158
01159 ON_Brep* ON_BrepRegion::RegionBoundaryBrep( ON_Brep* brep ) const
01160 {
01161 ON_Workspace ws;
01162 if ( 0 == m_rtop )
01163 return 0;
01164
01165 const ON_Brep* rtop_brep = m_rtop->Brep();
01166
01167 if ( rtop_brep == brep || 0 == rtop_brep || rtop_brep->m_F.Count() <= 0 || m_fsi.Count() <= 0 )
01168 return 0;
01169
01170 ON_SimpleArray<const ON_BrepFaceSide*> FS(m_fsi.Count());
01171 ON_SimpleArray<int> subfi(m_fsi.Count());
01172
01173 int rfsi, i;
01174 for ( rfsi = 0; rfsi < m_fsi.Count(); rfsi++ )
01175 {
01176 const ON_BrepFaceSide* fs = FaceSide(rfsi);
01177 if ( 0 == fs || fs->m_fi < 0 || fs->m_fi >= rtop_brep->m_F.Count() )
01178 return 0;
01179 for ( i = 0; i < FS.Count(); i++ )
01180 {
01181 if ( fs->m_fi == FS[i]->m_fi )
01182 break;
01183 }
01184 if ( i < FS.Count() )
01185 continue;
01186 FS.Append(fs);
01187 subfi.Append(fs->m_fi);
01188 }
01189
01190 brep = rtop_brep->SubBrep(subfi.Count(),subfi.Array(),brep);
01191 if ( !brep )
01192 return 0;
01193 if ( brep->m_F.Count() != FS.Count() )
01194 return 0;
01195 for ( i = 0; i < FS.Count(); i++ )
01196 {
01197 ON_BrepFace& face = brep->m_F[i];
01198 face.m_bRev = ( FS[i]->m_srf_dir < 0 );
01199 }
01200
01201 ON_BOOL32 bIsOriented = false;
01202 ON_BOOL32 bHasBoundary = true;
01203 if ( brep->IsManifold(&bIsOriented,&bHasBoundary) )
01204 {
01205 if ( bIsOriented && !bHasBoundary )
01206 {
01207 if ( 1 == m_type )
01208 brep->m_is_solid = 2;
01209 else if ( 0 == m_type )
01210 brep->m_is_solid = 1;
01211 }
01212 }
01213
01214 return brep;
01215 }
01216