opennurbs_brep_region.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 
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   // Transforming the bbox makes it grow too large under repeated
00103   // rotations.  So, we will destroy it here and reset it below.
00104   //m_bbox.Transform(xform);
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     // do not copy m_brep pointer
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     //region = const_cast<ON_BrepRegion*>(&m_rtop->m_R[m_ri]);
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     // do not copy m_brep pointer
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   // do not copy m_brep
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     // do not copy m_brep
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   // no region toplogy is available in public opennurbs.
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   // The call to the base class MemoryRelocate() takes care of 
00819   // updating user data back-pointers.
00820   ON_Geometry::MemoryRelocate();
00821 
00822   // When the memory location of an ON_Brep changes,
00823   // the m_brep backpointers on its pieces need to be updated.
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     // If an error occures during construction,
00872     // this class cleans up sub_brep in an
00873     // appropriate fashion.
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;        // ON_Brep::SubBrep allocated sub_brep
00878     ON_Brep* m_sub_brep; // user's sub_brep argument
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   // validate indices in extract_fi[] and
00892   // make sure there are no duplicates.
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)   // March 29, 2010 Lowell - Allow ptonsrf
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             // edge's vertices should already be mapped.
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   // build sub_brep vertices
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       // March 29, 2010 Lowell - Copy user fields
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   // build sub_brep edges
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       // March 29, 2010 Lowell - Copy user fields
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     // March 29, 2010 Lowell - Copy user fields
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       // April 19, 2010 Lowell - Copy user fields
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         // March 29, 2010 Lowell - copy ptonsrf type
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         // April 19, 2010 Lowell - Copy user fields
01136         memcpy(&sub_trim.m_trim_user, &trim.m_trim_user, sizeof(sub_trim.m_trim_user));
01137 
01138         // Since we are extracting a subset of the original brep,
01139         // some mated edges could turn into boundary edges. The
01140         // call to NewTrim() above will correctly handle setting
01141         // and updating sub_trims that came from mated trims.
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   // return subbrep after disabling the leak stopper
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 


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