BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Straight_skeleton_2.h
Go to the documentation of this file.
00001 // Copyright (c) 2005-2008 Fernando Luis Cacciola Carballal. All rights reserved.
00002 //
00003 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00004 // the terms of the Q Public License version 1.0.
00005 // See the file LICENSE.QPL distributed with CGAL.
00006 //
00007 // Licensees holding a valid commercial license may use this file in
00008 // accordance with the commercial license agreement provided with the software.
00009 //
00010 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00011 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00012 //
00013 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Straight_skeleton_2/include/CGAL/Straight_skeleton_2.h $
00014 // $Id: Straight_skeleton_2.h 43050 2008-04-28 17:03:23Z fcacciola $
00015 // 
00016 // Author(s)     : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
00017 
00018 #ifndef CGAL_STRAIGHT_SKELETON_2_H
00019 #define CGAL_STRAIGHT_SKELETON_2_H 1
00020 
00021 #include <CGAL/Straight_skeleton_2/Straight_skeleton_aux.h>
00022 #include <CGAL/Straight_skeleton_items_2.h>
00023 #include <CGAL/HalfedgeDS_default.h>
00024 
00025 CGAL_BEGIN_NAMESPACE
00026 
00027 template<  class Traits_
00028          , class Items_ = Straight_skeleton_items_2
00029          , class Alloc_ = CGAL_ALLOCATOR(int)
00030         >
00031 class Straight_skeleton_2 : public CGAL_HALFEDGEDS_DEFAULT <Traits_,Items_,Alloc_>
00032 {
00033 public :
00034 
00035   typedef Traits_ Traits ;
00036 
00037   typedef Straight_skeleton_2<Traits_,Items_,Alloc_> Self ;
00038   
00039   typedef CGAL_HALFEDGEDS_DEFAULT <Traits_,Items_,Alloc_> Base ;
00040   
00041   typedef typename Base::Vertex_base     Vertex ;
00042   typedef typename Base::Halfedge_base   Halfedge ;
00043   typedef typename Base::Face_base       Face ;
00044   
00045   typedef typename Base::Vertex_handle   Vertex_handle ;
00046   typedef typename Base::Halfedge_handle Halfedge_handle  ;
00047   typedef typename Base::Face_handle     Face_handle  ;
00048   
00049   typedef typename Base::Vertex_const_handle   Vertex_const_handle ;
00050   typedef typename Base::Halfedge_const_handle Halfedge_const_handle  ;
00051   typedef typename Base::Face_const_handle     Face_const_handle  ;
00052   
00053   typedef typename Base::Vertex_iterator   Vertex_iterator ;
00054   typedef typename Base::Halfedge_iterator Halfedge_iterator  ;
00055   typedef typename Base::Face_iterator     Face_iterator  ;
00056 
00057   typedef typename Base::Vertex_const_iterator   Vertex_const_iterator ;
00058   typedef typename Base::Halfedge_const_iterator Halfedge_const_iterator  ;
00059   typedef typename Base::Face_const_iterator     Face_const_iterator  ;
00060 
00061   typedef typename Base::size_type size_type ;
00062     
00063   Straight_skeleton_2() {}
00064   
00065 private :
00066 
00067     Vertex_handle   vertices_push_back( const Vertex& v)                   { return Base::vertices_push_back(v); }
00068     Halfedge_handle edges_push_back( const Halfedge& h, const Halfedge& g) { return Base::edges_push_back(h,g); }
00069     Halfedge_handle edges_push_back( const Halfedge& h)                    { return Base::edges_push_back(h); }
00070     Face_handle     faces_push_back( const Face& f)                        { return Base::faces_push_back(f); }
00071     
00072     void vertices_pop_front()                                          { Base::vertifces_pop_front(); }
00073     void vertices_pop_back()                                           { Base::vertifces_pop_back(); }
00074     void vertices_erase( Vertex_handle v)                              { Base::vertices_erase(v); }
00075     void vertices_erase( Vertex_iterator first, Vertex_iterator last)  { Base::vertices_erase(first,last); }
00076     void edges_erase( Halfedge_handle h)                               { Base::edges_erase(h) ; }
00077     void edges_pop_front()                                             { Base::edges_pop_front(); }
00078     void edges_pop_back()                                              { Base::edges_pop_back(); }
00079     void edges_erase( Halfedge_iterator first, Halfedge_iterator last) { Base::edges_erase(first,last); }
00080     void faces_pop_front()                                             { Base::faces_pop_front(); }
00081     void faces_pop_back()                                              { Base::faces_pop_back(); }
00082     void faces_erase( Face_handle f)                                   { Base::faces_erase(f); }
00083     void faces_erase( Face_iterator first, Face_iterator last)         { Base::faces_erase(first,last); }
00084     void vertices_clear()                                              { Base::vertices_clear(); }
00085     void edges_clear()                                                 { Base::edeges_clear(); }
00086     void faces_clear()                                                 { Base::faces_clear(); }
00087     void clear()                                                       { Base::clear();}
00088     
00089     void vertices_splice( Vertex_iterator target, Self &source, Vertex_iterator begin, Vertex_iterator end) 
00090       { Base::vertices_splice(target,source,begin,end); }
00091 
00092     void halfedges_splice( Halfedge_iterator target, Self &source, Halfedge_iterator begin, Halfedge_iterator end)
00093       { Base::halfedges_splice(target,source,begin,end); }
00094 
00095     void faces_splice( Face_iterator target, Self &source,  Face_iterator begin, Face_iterator end)
00096       { Base::faces_splice(target,source,begin,end); }
00097     
00098     void normalize_border() { Base::normalize_border(); }
00099     
00100 public :
00101 
00102     static int id ( Vertex_const_handle h )
00103     {
00104       Vertex_const_handle null ;
00105       return h != null ? h->id() : -1 ; 
00106     }
00107     static int id ( Halfedge_const_handle h )
00108     {
00109       Halfedge_const_handle null ;
00110       return h != null ? h->id() : -1 ; 
00111     }
00112     static int id ( Face_const_handle h )
00113     {
00114       Face_const_handle null ;
00115       return h != null ? 0 : -1 ; 
00116     }
00117 
00118     bool is_valid() const
00119     {
00120       //
00121       // This is a copy of the validity code in Halfedge_const_decorator with a different reporting mechanism
00122       //
00123       CGAL_STSKEL_VALIDITY_TRACE("begin Straight_skeleton::is_valid()" );
00124   
00125       bool valid = ( 1 != (this->size_of_halfedges() & 1));
00126       
00127       CGAL_STSKEL_VALIDITY_TRACE_IF(!valid,"number of halfedges: " << this->size_of_halfedges() << " is odd." ) ;
00128       
00129       // All halfedges.
00130       Halfedge_const_iterator begin = this->halfedges_begin();
00131       Halfedge_const_iterator end   = this->halfedges_end();
00132       size_type  n = 0;
00133       size_type nb = 0;
00134       for( ; valid && (begin != end); begin++)
00135       {
00136           CGAL_STSKEL_VALIDITY_TRACE("he["<< id(begin) << "]" << ( begin->is_border() ?  " [border]" : "" ) );
00137              
00138           // Pointer integrity.
00139           valid = valid && ( begin->next() != Halfedge_const_handle());
00140           if ( ! valid) 
00141           {
00142             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<<id(begin)<<"]->next() == NULL!");
00143             break;
00144           }
00145           valid = valid && ( begin->opposite() != Halfedge_const_handle());
00146           if ( ! valid) 
00147           {
00148             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<<id(begin)<<"]->opposite() == NULL!");
00149             break;
00150           }
00151           // opposite integrity.
00152           valid = valid && ( begin->opposite() != begin);
00153           if ( ! valid) 
00154           {
00155             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<<id(begin)<<"]->opposite() == he!");
00156             break;
00157           }
00158           valid = valid && ( begin->opposite()->opposite() == begin);
00159           if ( ! valid) 
00160           {
00161             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<<id(begin)<<"]->opposite()["<< id(begin->opposite())
00162                                        <<"]->opposite()["<< id(begin->opposite()->opposite()) <<"] != he!"
00163                                       );
00164             break;
00165           }
00166           // previous integrity.
00167           valid = valid && begin->next()->prev() == begin;
00168           if ( ! valid) 
00169           {
00170             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<< id(begin) <<"]->next()["<< id(begin->next())
00171                                       <<"]->prev()["<< id(begin->next()->prev()) <<"] != he."
00172                                       );
00173             break;
00174           }
00175           // vertex integrity.
00176           valid = valid && begin->vertex() != Vertex_const_handle();
00177           if ( ! valid) 
00178           {
00179               CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<<id(begin)<<"]->vertex() == NULL!");
00180               break;
00181           }
00182           if ( ! begin->vertex()->has_infinite_time() )
00183           {
00184             valid = valid && ( begin->vertex() == begin->next()->opposite()->vertex());
00185             if ( ! valid) 
00186             {
00187                 CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<< id(begin) <<"]->vertex()["<< id(begin->vertex())
00188                                           <<"] != he->next()["<< id(begin->next())
00189                                           <<"]->opposite()["<< id(begin->next()->opposite()) 
00190                                           <<"]->vertex()["<< id(begin->next()->opposite()->vertex())<<"]"
00191                                           );
00192                 break;
00193             }
00194           }
00195           // face integrity.
00196           valid = valid && ( begin->is_border() || begin->face() != Face_const_handle() );
00197           if ( ! valid) 
00198           {
00199             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<<id(begin)<<"]->face() == NULL.");
00200             break;
00201           }
00202           valid = valid && ( begin->face() == begin->next()->face());
00203           if ( ! valid) 
00204           {
00205             CGAL_STSKEL_VALIDITY_TRACE("ERROR: he["<< id(begin) <<"]->face()["<< id(begin->face())
00206                                       <<"] != he->next()["<< id(begin->next()) <<"]->face()["<< id(begin->next()->face())<<"]."
00207                                       );
00208             break;
00209           }
00210           ++n;
00211           if ( begin->is_border())
00212               ++nb;
00213       }
00214       CGAL_STSKEL_VALIDITY_TRACE("summe border halfedges (2*nb) = " << 2 * nb );
00215       
00216       bool nvalid = ( n == this->size_of_halfedges());
00217       
00218       CGAL_STSKEL_VALIDITY_TRACE_IF(valid && !nvalid
00219                                    ,"ERROR: counted number of halfedges:" << n 
00220                                    << " mismatch with this->size_of_halfedges():" << this->size_of_halfedges() 
00221                                    );
00222           
00223       valid = valid && nvalid ;
00224       
00225       // All vertices.
00226       Vertex_const_iterator vbegin = this->vertices_begin();
00227       Vertex_const_iterator vend   = this->vertices_end();
00228       
00229       size_type v = 0;
00230       n = 0;
00231       bool is_partial_skeleton = false ;
00232       
00233       for( ; valid && (vbegin != vend); ++vbegin) 
00234       {
00235           // Pointer integrity.
00236           valid = valid && vbegin->halfedge() != Halfedge_const_handle()  ;
00237           if ( ! valid) 
00238           {
00239             CGAL_STSKEL_VALIDITY_TRACE("ERROR: v["<< id(vbegin) <<"]->halfedge() == NULL.");
00240             break;
00241           }
00242           
00243           // cycle-around-vertex test.
00244           if ( !vbegin->has_infinite_time() )
00245           {
00246             valid = valid && vbegin->halfedge()->vertex() == vbegin;
00247             if ( ! valid) 
00248             {
00249               CGAL_STSKEL_VALIDITY_TRACE("ERROR: v["<< id(vbegin) <<"]->halfedge()["<< id(vbegin->halfedge()) 
00250                                         <<"]->vertex()["<< id(vbegin->halfedge()->vertex()) <<"] != v."
00251                                         );
00252               break;
00253             }
00254             
00255             CGAL_STSKEL_VALIDITY_TRACE("Circulating halfedges around v["<<id(vbegin)<<"]");
00256             
00257             Halfedge_const_handle h =  vbegin->halfedge();
00258             if ( h != Halfedge_const_handle()) 
00259             {
00260               Halfedge_const_handle g = h;
00261               do 
00262               {
00263                 CGAL_STSKEL_VALIDITY_TRACE("  v->halfedge(): " << id(h) << ", ->next(): " << id(h->next()) 
00264                                           << ", ->next()->opposite(): " << id(h->next()->opposite())
00265                                           );
00266                 ++n;
00267                 h = h->next()->opposite();
00268                 valid = valid && ( n <= this->size_of_halfedges() && n!=0);
00269                 CGAL_STSKEL_VALIDITY_TRACE_IF(!valid,"ERROR: more than " << this->size_of_halfedges() 
00270                                              << " halfedges around v["<< id(vbegin)<<"]"
00271                                              );
00272               } while ( valid && (h != g));
00273             }
00274           }
00275           else is_partial_skeleton = true ;
00276           
00277           ++v;
00278       }
00279       
00280       if ( ! is_partial_skeleton )
00281       {
00282         bool vvalid = (v == this->size_of_vertices());
00283         
00284         CGAL_STSKEL_VALIDITY_TRACE_IF(valid && !vvalid
00285                                      ,"ERROR: counted number of vertices:" << v 
00286                                      << " mismatch with this->size_of_vertices():" << this->size_of_vertices()
00287                                      ); 
00288             
00289         bool vnvalid = n == this->size_of_halfedges() ;
00290         CGAL_STSKEL_VALIDITY_TRACE_IF(valid && !vnvalid
00291                                      ,"ERROR: counted number of halfedges via vertices:" << n 
00292                                      << " mismatch with this->size_of_halfedges():" << this->size_of_halfedges() 
00293                                      );
00294         
00295         valid = valid && vvalid && vnvalid ;
00296       }
00297       
00298       // All faces.
00299       Face_const_iterator fbegin = this->faces_begin();
00300       Face_const_iterator fend   = this->faces_end();
00301       size_type f = 0;
00302       n = 0;
00303       for( ; valid && (fbegin != fend); ++fbegin) 
00304       {
00305       
00306           valid = valid && ( begin->is_border() || fbegin->halfedge() != Halfedge_const_handle()  );
00307           if ( ! valid)
00308           {
00309             CGAL_STSKEL_VALIDITY_TRACE("ERROR: f["<<id(fbegin)<<"]->halfedge() == NULL." );
00310             break;
00311           }
00312           
00313           valid = valid && fbegin->halfedge()->face() == fbegin ;
00314           if ( ! valid) 
00315           {
00316             CGAL_STSKEL_VALIDITY_TRACE("ERROR: f["<<id(fbegin)<<"]->halfedge()["<< id(fbegin->halfedge()) 
00317                                        <<"]->face()["<< id(fbegin->halfedge()->face()) <<"] != f."
00318                                       );
00319             break;
00320           }
00321           // cycle-around-face test.
00322           CGAL_STSKEL_VALIDITY_TRACE("Circulating halfedges around f["<<id(fbegin)<<"]" );
00323           Halfedge_const_handle h = fbegin->halfedge();
00324           if ( h != Halfedge_const_handle()) 
00325           {
00326             Halfedge_const_handle g = h;
00327             do 
00328             {
00329               CGAL_STSKEL_VALIDITY_TRACE("  f->halfedge():" << id(h) << ", ->next(): " << id(h->next()));
00330               ++n;
00331               h = h->next();
00332               valid = valid && ( n <= this->size_of_halfedges() && n!=0);
00333               CGAL_STSKEL_VALIDITY_TRACE_IF(!valid,"ERROR: more than " << this->size_of_halfedges() 
00334                                            << " halfedges around f["<< id(fbegin)<<"]"
00335                                            );
00336             } while ( valid && (h != g));
00337           }
00338           ++f;
00339       }
00340       
00341       bool fvalid = ( f == this->size_of_faces());
00342       
00343       CGAL_STSKEL_VALIDITY_TRACE_IF(valid && !fvalid
00344                                    ,"ERROR: counted number of faces:" << f 
00345                                    << " mismatch with this->size_of_faces():" << this->size_of_faces() 
00346                                    );
00347           
00348       bool fnvalid = ( n + nb  == this->size_of_halfedges() );
00349                      
00350       CGAL_STSKEL_VALIDITY_TRACE_IF(valid && !fnvalid
00351                                    ,"ERROR: counted number of halfedges via faces:" << n
00352                                    << " plus counted number of border halfedges: " << nb  
00353                                    << " mismatch with this->size_of_halfedges():" << this->size_of_halfedges() 
00354                                    );
00355       
00356       valid = valid && fvalid && fnvalid ;
00357       
00358       CGAL_STSKEL_VALIDITY_TRACE ("end of Straight_skeleton_2>::is_valid(): " << ( valid ? "valid." : "NOT VALID.") );
00359       
00360       return valid;
00361     }    
00362 };
00363 
00364 
00365 CGAL_END_NAMESPACE
00366 
00367 
00368 #endif // CGAL_STRAIGHT_SKELETON_2_H //
00369 // EOF //
00370 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines