BWAPI
|
00001 // Copyright (c) 1997 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/HalfedgeDS/include/CGAL/HalfedgeDS_const_decorator.h $ 00019 // $Id: HalfedgeDS_const_decorator.h 35787 2007-01-24 17:16:05Z spion $ 00020 // 00021 // 00022 // Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de> 00023 00024 #ifndef CGAL_HALFEDGEDS_CONST_DECORATOR_H 00025 #define CGAL_HALFEDGEDS_CONST_DECORATOR_H 1 00026 00027 #include <CGAL/HalfedgeDS_items_decorator.h> 00028 #include <vector> 00029 #include <CGAL/IO/Verbose_ostream.h> 00030 00031 CGAL_BEGIN_NAMESPACE 00032 00033 template < class p_HDS > 00034 class HalfedgeDS_const_decorator 00035 : public HalfedgeDS_items_decorator<p_HDS> { 00036 00037 // TYPES (inherited from Items_decorator, but have to be repeated) 00038 // --------------------------------------------------------------- 00039 public: 00040 typedef p_HDS HDS; 00041 typedef p_HDS HalfedgeDS; 00042 typedef typename HDS::Traits Traits; 00043 typedef typename HDS::Vertex Vertex; 00044 typedef typename HDS::Halfedge Halfedge; 00045 typedef typename HDS::Face Face; 00046 00047 typedef typename HDS::Vertex_handle Vertex_handle; 00048 typedef typename HDS::Vertex_const_handle Vertex_const_handle; 00049 typedef typename HDS::Vertex_iterator Vertex_iterator; 00050 typedef typename HDS::Vertex_const_iterator Vertex_const_iterator; 00051 00052 typedef typename HDS::Halfedge_handle Halfedge_handle; 00053 typedef typename HDS::Halfedge_const_handle Halfedge_const_handle; 00054 typedef typename HDS::Halfedge_iterator Halfedge_iterator; 00055 typedef typename HDS::Halfedge_const_iterator Halfedge_const_iterator; 00056 00057 typedef typename HDS::Face_handle Face_handle; 00058 typedef typename HDS::Face_const_handle Face_const_handle; 00059 typedef typename HDS::Face_iterator Face_iterator; 00060 typedef typename HDS::Face_const_iterator Face_const_iterator; 00061 00062 typedef typename HDS::size_type size_type; 00063 typedef typename HDS::difference_type difference_type; 00064 typedef typename HDS::iterator_category iterator_category; 00065 00066 // The following types are equal to either `Tag_true' or `Tag_false', 00067 // dependent whether the named feature is supported or not. 00068 00069 typedef typename HDS::Supports_vertex_halfedge 00070 Supports_vertex_halfedge; 00071 typedef typename HDS::Supports_halfedge_prev Supports_halfedge_prev; 00072 typedef typename HDS::Supports_halfedge_vertex 00073 Supports_halfedge_vertex; 00074 typedef typename HDS::Supports_halfedge_face Supports_halfedge_face; 00075 typedef typename HDS::Supports_face_halfedge Supports_face_halfedge; 00076 00077 typedef typename HDS::Supports_removal Supports_removal; 00078 00079 protected: 00080 typedef typename Vertex::Base VBase; 00081 typedef typename Halfedge::Base HBase; 00082 typedef typename Halfedge::Base_base HBase_base; 00083 typedef typename Face::Base FBase; 00084 00085 00086 // PRIVATE MEMBER VARIABLES 00087 // ---------------------------------- 00088 private: 00089 const p_HDS* hds; 00090 00091 // CREATION 00092 // ---------------------------------- 00093 public: 00094 // No default constructor, keeps always a reference to a HDS! 00095 00096 HalfedgeDS_const_decorator( const p_HDS& h) : hds(&h) {} 00097 // keeps internally a const reference to `hds'. 00098 00099 bool is_valid( bool verb = false, int level = 0) const; 00100 // returns `true' if the halfedge data structure `hds' is valid 00101 // with respect to the `level' value as defined in the reference 00102 // manual. If `verbose' is `true', statistics are written to 00103 // `cerr'. 00104 00105 bool normalized_border_is_valid( bool verb = false) const; 00106 // returns `true' if the border halfedges are in normalized 00107 // representation, which is when enumerating all halfedges with 00108 // the halfedge iterator the following holds: The non-border edges 00109 // precede the border edges. For border edges, the second halfedge 00110 // is a border halfedge. (The first halfedge may or may not be a 00111 // border halfedge.) The halfedge iterator `border_halfedges_begin 00112 // ()' denotes the first border edge. If `verbose' is `true', 00113 // statistics are written to `cerr'. 00114 }; 00115 00116 template < class p_HDS > 00117 bool 00118 HalfedgeDS_const_decorator<p_HDS>:: 00119 normalized_border_is_valid( bool verb) const { 00120 bool valid = true; 00121 Verbose_ostream verr(verb); 00122 verr << "begin CGAL::HalfedgeDS_const_decorator<HDS>::" 00123 "normalized_border_is_valid( verb=true):" << std::endl; 00124 00125 Halfedge_const_iterator e = hds->halfedges_begin(); 00126 size_type count = 0; 00127 while( e != hds->halfedges_end() && ! e->is_border() && ! 00128 e->opposite()->is_border()) { 00129 ++e; 00130 ++e; 00131 ++count; 00132 } 00133 verr << " non-border edges: " << count << std::endl; 00134 if ( e != hds->border_halfedges_begin()) { 00135 verr << " first border edge does not start at " 00136 "border_halfedges_begin()" << std::endl; 00137 valid = false; 00138 } else { 00139 count = 0; 00140 while( valid && e != hds->halfedges_end() && 00141 e->opposite()->is_border()) { 00142 ++e; 00143 ++e; 00144 ++count; 00145 } 00146 verr << " border edges: " << count << std::endl; 00147 verr << " total edges: " << hds->size_of_halfedges()/2 00148 << std::endl; 00149 if ( e != hds->halfedges_end()) { 00150 if ( e->is_border()) { 00151 verr << " border edge " << count 00152 << ": wrong orientation." << std::endl; 00153 } 00154 verr << " the sum of full + border equals not total edges." 00155 << std::endl; 00156 valid = false; 00157 } 00158 } 00159 verr << "end of CGAL::HalfedgeDS_const_decorator<HDS>::normalized_" 00160 "border_is_valid(): structure is " 00161 << ( valid ? "valid." : "NOT VALID.") << std::endl; 00162 return valid; 00163 } 00164 00165 template < class p_HDS > 00166 bool 00167 HalfedgeDS_const_decorator<p_HDS>:: 00168 is_valid( bool verb, int level) const { 00169 Verbose_ostream verr(verb); 00170 verr << "begin CGAL::HalfedgeDS_const_decorator<HDS>::is_valid(" 00171 " verb=true, level = " << level << "):" << std::endl; 00172 00173 bool valid = ( 1 != (hds->size_of_halfedges() & 1)); 00174 if ( ! valid) 00175 verr << "number of halfedges is odd." << std::endl; 00176 00177 // All halfedges. 00178 Halfedge_const_iterator begin = hds->halfedges_begin(); 00179 Halfedge_const_iterator end = hds->halfedges_end(); 00180 size_type n = 0; 00181 size_type nb = 0; 00182 for( ; valid && (begin != end); begin++) { 00183 verr << "halfedge " << n << std::endl; 00184 if ( begin->is_border()) 00185 verr << " is border halfedge" << std::endl; 00186 // Pointer integrity. 00187 valid = valid && ( begin->next() != Halfedge_const_handle()); 00188 valid = valid && ( begin->opposite() != Halfedge_const_handle()); 00189 if ( ! valid) { 00190 verr << " pointer integrity corrupted (ptr==0)." 00191 << std::endl; 00192 break; 00193 } 00194 // opposite integrity. 00195 valid = valid && ( begin->opposite() != begin); 00196 valid = valid && ( begin->opposite()->opposite() == begin); 00197 if ( ! valid) { 00198 verr << " opposite pointer integrity corrupted." 00199 << std::endl; 00200 break; 00201 } 00202 // previous integrity. 00203 valid = valid && ( ! check_tag( Supports_halfedge_prev()) || 00204 get_prev(begin->next()) == begin); 00205 if ( ! valid) { 00206 verr << " previous pointer integrity corrupted." 00207 << std::endl; 00208 break; 00209 } 00210 if ( level > 0) { 00211 // vertex integrity. 00212 valid = valid && ( ! check_tag( Supports_halfedge_vertex()) 00213 || get_vertex( begin) != Vertex_const_handle()); 00214 if ( ! valid) { 00215 verr << " vertex pointer integrity corrupted." 00216 << std::endl; 00217 break; 00218 } 00219 valid = valid && ( get_vertex( begin) == 00220 get_vertex( begin->next()->opposite())); 00221 if ( ! valid) { 00222 verr << " vertex pointer integrity2 corrupted." 00223 << std::endl; 00224 break; 00225 } 00226 // face integrity. 00227 valid = valid && ( ! check_tag( Supports_halfedge_face()) 00228 || begin->is_border() 00229 || get_face(begin) != Face_const_handle()); 00230 if ( ! valid) { 00231 verr << " face pointer integrity corrupted." 00232 << std::endl; 00233 break; 00234 } 00235 valid = valid && ( get_face(begin) == get_face(begin->next())); 00236 if ( ! valid) { 00237 verr << " face pointer integrity2 corrupted." 00238 << std::endl; 00239 break; 00240 } 00241 } 00242 ++n; 00243 if ( begin->is_border()) 00244 ++nb; 00245 } 00246 verr << "summe border halfedges (2*nb) = " << 2 * nb << std::endl; 00247 if ( valid && n != hds->size_of_halfedges()) 00248 verr << "counting halfedges failed." << std::endl; 00249 if ( valid && level >= 4 && (nb != hds->size_of_border_halfedges())) 00250 verr << "counting border halfedges failed." << std::endl; 00251 valid = valid && ( n == hds->size_of_halfedges()); 00252 valid = valid && ( level < 4 || 00253 (nb == hds->size_of_border_halfedges())); 00254 00255 // All vertices. 00256 Vertex_const_iterator vbegin = hds->vertices_begin(); 00257 Vertex_const_iterator vend = hds->vertices_end(); 00258 size_type v = 0; 00259 n = 0; 00260 for( ; valid && (vbegin != vend); ++vbegin) { 00261 verr << "vertex " << v << std::endl; 00262 // Pointer integrity. 00263 if ( get_vertex_halfedge( vbegin) != Halfedge_const_handle()) 00264 valid = valid && ( ! check_tag( 00265 Supports_halfedge_vertex()) || 00266 get_vertex( get_vertex_halfedge( vbegin)) == vbegin); 00267 else 00268 valid = valid && (! check_tag( 00269 Supports_vertex_halfedge())); 00270 if ( ! valid) { 00271 verr << " halfedge pointer in vertex corrupted." 00272 << std::endl; 00273 break; 00274 } 00275 // cycle-around-vertex test. 00276 Halfedge_const_handle h = get_vertex_halfedge( vbegin); 00277 if ( level >= 2 && h != Halfedge_const_handle()) { 00278 Halfedge_const_handle g = h; 00279 do { 00280 verr << " halfedge " << n << std::endl; 00281 ++n; 00282 h = h->next()->opposite(); 00283 valid = valid && ( n <= hds->size_of_halfedges() && n!=0); 00284 if ( ! valid) 00285 verr << " too many halfedges around vertices." 00286 << std::endl; 00287 } while ( valid && (h != g)); 00288 } 00289 ++v; 00290 } 00291 if ( valid && v != hds->size_of_vertices()) 00292 verr << "counting vertices failed." << std::endl; 00293 if ( valid && level >= 2 && ( check_tag( Supports_vertex_halfedge()) 00294 && n != hds->size_of_halfedges())) 00295 verr << "counting halfedges via vertices failed." << std::endl; 00296 valid = valid && ( v == hds->size_of_vertices()); 00297 valid = valid && ( level < 2 || 00298 ! check_tag( Supports_vertex_halfedge()) || 00299 n == hds->size_of_halfedges()); 00300 00301 // All faces. 00302 Face_const_iterator fbegin = hds->faces_begin(); 00303 Face_const_iterator fend = hds->faces_end(); 00304 size_type f = 0; 00305 n = 0; 00306 for( ; valid && (fbegin != fend); ++fbegin) { 00307 verr << "face " << f << std::endl; 00308 // Pointer integrity. 00309 if ( get_face_halfedge( fbegin) != Halfedge_const_handle()) 00310 valid = valid && ( ! check_tag( 00311 Supports_halfedge_face()) || 00312 get_face( get_face_halfedge( fbegin)) == fbegin); 00313 else 00314 valid = valid && (! check_tag( 00315 Supports_face_halfedge()) || begin->is_border()); 00316 if ( ! valid) { 00317 verr << " halfedge pointer in face corrupted." << std::endl; 00318 break; 00319 } 00320 // cycle-around-face test. 00321 Halfedge_const_handle h = get_face_halfedge( fbegin); 00322 if ( level >= 3 && h != Halfedge_const_handle()) { 00323 Halfedge_const_handle g = h; 00324 do { 00325 verr << " halfedge " << n << std::endl; 00326 ++n; 00327 h = h->next(); 00328 valid = valid && ( n <= hds->size_of_halfedges() && n!=0); 00329 if ( ! valid) 00330 verr << " too many halfedges around faces." 00331 << std::endl; 00332 } while ( valid && (h != g)); 00333 } 00334 ++f; 00335 } 00336 if ( valid && f != hds->size_of_faces()) 00337 verr << "counting faces failed." << std::endl; 00338 if ( valid && level >= 3 && check_tag( Supports_face_halfedge()) && 00339 n + nb != hds->size_of_halfedges()) 00340 verr << "counting halfedges via faces failed." << std::endl; 00341 valid = valid && ( f == hds->size_of_faces()); 00342 valid = valid && ( level < 3 || 00343 ! check_tag( Supports_face_halfedge()) || 00344 n + nb == hds->size_of_halfedges()); 00345 00346 if ( level >= 4) { 00347 verr << "level 4: normalized_border_is_valid( verbose = true)" 00348 << std::endl; 00349 valid = valid && ( normalized_border_is_valid( verb)); 00350 } 00351 verr << "end of CGAL::HalfedgeDS_const_decorator<HDS>::" 00352 "is_valid(): structure is " << ( valid ? "valid." : 00353 "NOT VALID.") << std::endl; 00354 return valid; 00355 } 00356 00357 CGAL_END_NAMESPACE 00358 00359 #endif // CGAL_HALFEDGEDS_CONST_DECORATOR_H // 00360 // EOF //