BWAPI
|
00001 // Copyright (c) 2005 Tel-Aviv University (Israel). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Arr_face_map.h $ 00015 // $Id: Arr_face_map.h 53436 2009-12-15 23:14:31Z lrineau $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 #ifndef CGAL_ARR_FACE_MAP_H 00020 #define CGAL_ARR_FACE_MAP_H 00021 00026 #include <CGAL/Unique_hash_map.h> 00027 #if BOOST_VERSION >= 104000 00028 #include <boost/property_map/property_map.hpp> 00029 #else 00030 #include <boost/property_map.hpp> 00031 #endif 00032 #include <boost/graph/properties.hpp> 00033 00034 CGAL_BEGIN_NAMESPACE 00035 00041 template <class Arrangement_> 00042 class Arr_face_index_map : public Arr_observer<Arrangement_> 00043 { 00044 public: 00045 00046 typedef Arrangement_ Arrangement_2; 00047 typedef typename Arrangement_2::Face_handle Face_handle; 00048 00049 // Boost property type definitions: 00050 typedef boost::readable_property_map_tag category; 00051 typedef unsigned int value_type; 00052 typedef value_type reference; 00053 typedef Face_handle key_type; 00054 00055 private: 00056 00057 typedef Arr_face_index_map<Arrangement_2> Self; 00058 typedef Arr_observer<Arrangement_2> Base; 00059 00060 typedef Unique_hash_map<Face_handle, unsigned int> Index_map; 00061 00062 // Data members: 00063 unsigned int n_faces; // The current number of faces. 00064 Index_map index_map; // Mapping faces to indices. 00065 std::vector<Face_handle> rev_map; // Mapping indices to faces. 00066 00067 enum {MIN_REV_MAP_SIZE = 32}; 00068 00069 public: 00070 00072 Arr_face_index_map () : 00073 Base (), 00074 n_faces (0), 00075 rev_map (MIN_REV_MAP_SIZE) 00076 {} 00077 00079 Arr_face_index_map (const Arrangement_2& arr) : 00080 Base (const_cast<Arrangement_2&> (arr)) 00081 { 00082 _init(); 00083 } 00084 00086 Arr_face_index_map (const Self& other) : 00087 Base (const_cast<Arrangement_2&> (*(other.arrangement()))) 00088 { 00089 _init(); 00090 } 00091 00093 Self& operator= (const Self& other) 00094 { 00095 if (this == &other) 00096 return (*this); 00097 00098 this->detach(); 00099 this->attach (const_cast<Arrangement_2&> (*(other.arrangement()))); 00100 00101 return (*this); 00102 } 00103 00109 unsigned int operator[] (Face_handle f) const 00110 { 00111 return (index_map[f]); 00112 } 00113 00119 Face_handle face (const int i) const 00120 { 00121 CGAL_precondition((unsigned int) i < n_faces); 00122 00123 return (rev_map[i]); 00124 } 00125 00127 00128 00133 virtual void after_assign () 00134 { 00135 _init(); 00136 } 00137 00141 virtual void after_clear () 00142 { 00143 _init(); 00144 } 00145 00149 virtual void after_attach () 00150 { 00151 _init(); 00152 } 00153 00157 virtual void after_detach () 00158 { 00159 n_faces = 0; 00160 index_map.clear(); 00161 } 00162 00169 virtual void after_split_face (Face_handle /* f */, 00170 Face_handle new_f, 00171 bool /* is_hole */) 00172 { 00173 // Update the number of vertices. 00174 n_faces++; 00175 00176 // If necessary, allocate memory for the reverse mapping. 00177 if (rev_map.size() < n_faces) 00178 rev_map.resize(2 * n_faces); 00179 00180 // Update the mapping of the newly created face. 00181 index_map[new_f] = n_faces - 1; 00182 rev_map[n_faces - 1] = new_f; 00183 00184 return; 00185 } 00186 00192 virtual void before_merge_face (Face_handle /* f1 */, 00193 Face_handle f2, 00194 typename 00195 Arrangement_2::Halfedge_handle /* e */) 00196 { 00197 // Update the number of faces. 00198 n_faces--; 00199 00200 // Reduce memory consumption in case the number of faces has 00201 // drastically decreased. 00202 if (2*n_faces+1 < rev_map.size() && 00203 rev_map.size() / 2 >= MIN_REV_MAP_SIZE) 00204 { 00205 rev_map.resize (rev_map.size() / 2); 00206 } 00207 00208 // Get the current face index, and assign this index to the face 00209 // currently indexed (n - 1). 00210 unsigned int index = index_map[f2]; 00211 00212 if (index == n_faces) 00213 return; 00214 00215 Face_handle last_f = rev_map[n_faces]; 00216 index_map[last_f] = index; 00217 rev_map[index] = last_f; 00218 00219 // Clear the reverse mapping for the last face. 00220 rev_map[n_faces] = Face_handle(); 00221 00222 return; 00223 } 00225 00226 private: 00227 00229 void _init () 00230 { 00231 // Get the number of faces and allocate the reverse map accordingly. 00232 n_faces = this->arrangement()->number_of_faces(); 00233 00234 if (n_faces < MIN_REV_MAP_SIZE) 00235 rev_map.resize (MIN_REV_MAP_SIZE); 00236 else 00237 rev_map.resize (n_faces); 00238 00239 // Clear the current mapping. 00240 index_map.clear(); 00241 00242 // Create the initial mapping. 00243 typename Arrangement_2::Face_iterator fit; 00244 Face_handle fh; 00245 unsigned int index = 0; 00246 00247 for (fit = this->arrangement()->faces_begin(); 00248 fit != this->arrangement()->faces_end(); ++fit, ++index) 00249 { 00250 // Map the current face to the current index. 00251 fh = fit; 00252 index_map[fh] = index; 00253 rev_map[index] = fh; 00254 } 00255 00256 return; 00257 } 00258 00259 }; 00260 00268 template<class Arrangement> 00269 unsigned int get (const CGAL::Arr_face_index_map<Arrangement>& index_map, 00270 typename Arrangement::Face_handle f) 00271 { 00272 return (index_map[f]); 00273 } 00274 00279 template <class Arrangement_, class Type_> 00280 class Arr_face_property_map 00281 { 00282 public: 00283 00284 typedef Arrangement_ Arrangement_2; 00285 typedef typename Arrangement_2::Face_handle Face_handle; 00286 typedef Arr_face_index_map<Arrangement_2> Index_map; 00287 00288 // Boost property type definitions: 00289 typedef boost::read_write_property_map_tag category; 00290 typedef Type_ value_type; 00291 typedef value_type& reference; 00292 typedef Face_handle key_type; 00293 00294 private: 00295 00296 typedef Arr_face_property_map<Arrangement_2, value_type> Self; 00297 00298 // Data members: 00299 const Index_map *ind_map; // The index map. 00300 value_type *props; // The properties vector. 00301 bool owner; // Should the vector be freed. 00302 00304 Self& operator= (const Self& ); 00305 00306 public: 00307 00309 Arr_face_property_map (const Index_map& index_map) : 00310 ind_map (&index_map), 00311 owner (true) 00312 { 00313 props = new value_type [index_map.arrangement()->number_of_faces()]; 00314 } 00315 00317 Arr_face_property_map (const Self& map) : 00318 ind_map (map.ind_map), 00319 props (map.props), 00320 owner (false) 00321 {} 00322 00324 ~Arr_face_property_map () 00325 { 00326 if (owner) 00327 delete[] props; 00328 } 00329 00331 const value_type& operator[] (Face_handle f) const 00332 { 00333 return (props [(*ind_map)[f]]); 00334 } 00335 00337 value_type& operator[] (Face_handle f) 00338 { 00339 return (props [(*ind_map)[f]]); 00340 } 00341 00342 }; 00343 00351 template<class Arrangement, class Type> 00352 const typename CGAL::Arr_face_property_map<Arrangement, Type>::value_type& 00353 get (const CGAL::Arr_face_property_map<Arrangement, Type>& prop_map, 00354 typename Arrangement::Face_handle f) 00355 { 00356 return (prop_map[f]); 00357 } 00358 00366 template<class Arrangement, class Type> 00367 void put (CGAL::Arr_face_property_map<Arrangement, Type>& prop_map, 00368 typename Arrangement::Face_handle f, 00369 typename CGAL::Arr_face_property_map<Arrangement, Type>:: 00370 value_type t) 00371 { 00372 prop_map[f] = t; 00373 return; 00374 } 00375 00376 CGAL_END_NAMESPACE 00377 00378 #endif