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/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_agg_op_visitor.h $ 00015 // $Id: Gps_agg_op_visitor.h 49836 2009-06-07 19:21:39Z eric $ 00016 // 00017 // 00018 // Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il> 00019 // Ron Wein <wein@post.tau.ac.il> 00020 00021 #ifndef CGAL_GSP_AGG_OP_VISITOR_H 00022 #define CGAL_GSP_AGG_OP_VISITOR_H 00023 00024 #include <CGAL/Unique_hash_map.h> 00025 #include <CGAL/Sweep_line_2/Arr_construction_sl_visitor.h> 00026 #include <boost/mpl/if.hpp> 00027 #include <boost/type_traits.hpp> 00028 #include <CGAL/Arr_tags.h> 00029 #include <CGAL/Arr_topology_traits/Arr_bounded_planar_construction_helper.h> 00030 #include <CGAL/Arr_topology_traits/Arr_unb_planar_construction_helper.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00034 template<class Traits, class Arrangement_, class Event,class Subcurve> 00035 class Gps_agg_op_base_visitor : 00036 public 00037 Arr_construction_sl_visitor< 00038 // TODO derive (helper) from topology traits class 00039 typename boost::mpl::if_< 00040 boost::is_same< typename Arr_are_all_sides_oblivious_tag< 00041 typename Traits::Arr_left_side_tag, 00042 typename Traits::Arr_bottom_side_tag, 00043 typename Traits::Arr_top_side_tag, 00044 typename Traits::Arr_right_side_tag 00045 >::result, Arr_all_sides_oblivious_tag >, 00046 Arr_bounded_planar_construction_helper<Traits, 00047 Arrangement_, 00048 Event, 00049 Subcurve>, 00050 Arr_unb_planar_construction_helper<Traits, 00051 Arrangement_, 00052 Event, 00053 Subcurve> 00054 >::type 00055 > 00056 { 00057 protected: 00058 typedef Arrangement_ Arrangement; 00059 00060 00061 00062 typedef typename boost::mpl::if_< 00063 boost::is_same< typename Arr_are_all_sides_oblivious_tag< 00064 typename Traits::Arr_left_side_tag, 00065 typename Traits::Arr_bottom_side_tag, 00066 typename Traits::Arr_top_side_tag, 00067 typename Traits::Arr_right_side_tag 00068 >::result, Arr_all_sides_oblivious_tag >, 00069 Arr_bounded_planar_construction_helper<Traits, 00070 Arrangement, 00071 Event, 00072 Subcurve>, 00073 Arr_unb_planar_construction_helper<Traits, 00074 Arrangement, 00075 Event, 00076 Subcurve> 00077 >::type Construction_helper; 00078 typedef Arr_construction_sl_visitor<Construction_helper> Base; 00079 00080 typedef typename Base::Status_line_iterator SL_iterator; 00081 typedef typename Base::Halfedge_handle Halfedge_handle; 00082 typedef typename Base::Vertex_handle Vertex_handle; 00083 typedef typename Base::Event_subcurve_iterator SubCurveIter; 00084 typedef typename Base::Event_subcurve_reverse_iterator SubCurveRevIter; 00085 typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; 00086 typedef typename Traits::Point_2 Point_2; 00087 00088 typedef Unique_hash_map<Halfedge_handle, unsigned int> Edges_hash; 00089 00090 protected: 00091 00092 Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter) 00093 00094 00095 public: 00096 00097 Gps_agg_op_base_visitor(Arrangement *arr, 00098 Edges_hash* hash): Base(arr), 00099 m_edges_hash(hash) 00100 {} 00101 00102 // TODO (IMPORTANT): unbounded helper might be not fully supported 00103 // TODO add mpl-warning 00104 00105 virtual Halfedge_handle insert_in_face_interior(const X_monotone_curve_2& cv, 00106 Subcurve* sc) 00107 { 00108 Halfedge_handle he = 00109 Base::insert_in_face_interior(cv, sc); 00110 insert_edge_to_hash(he, cv); 00111 return (he); 00112 } 00113 00114 virtual Halfedge_handle insert_at_vertices(const X_monotone_curve_2& cv, 00115 Halfedge_handle hhandle, 00116 Halfedge_handle prev, 00117 Subcurve* sc, 00118 bool &new_face_created) 00119 { 00120 Halfedge_handle res_he = 00121 Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created); 00122 insert_edge_to_hash(res_he, cv); 00123 return (res_he); 00124 } 00125 00126 virtual Halfedge_handle insert_from_right_vertex 00127 (const X_monotone_curve_2& cv, 00128 Halfedge_handle he, 00129 Subcurve* sc) 00130 { 00131 Halfedge_handle res_he = 00132 Base::insert_from_right_vertex(cv, he, sc); 00133 insert_edge_to_hash(res_he, cv); 00134 return (res_he); 00135 } 00136 00137 virtual Halfedge_handle insert_from_left_vertex 00138 (const X_monotone_curve_2& cv, 00139 Halfedge_handle he, 00140 Subcurve* sc) 00141 { 00142 Halfedge_handle res_he = 00143 Base::insert_from_left_vertex(cv, he, sc); 00144 insert_edge_to_hash(res_he, cv); 00145 return (res_he); 00146 } 00147 00148 00149 00150 private: 00151 00152 void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv) 00153 { 00154 const Comparison_result he_dir = 00155 ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ? SMALLER : LARGER; 00156 00157 const Comparison_result cv_dir = 00158 this->m_arr_access.arrangement().geometry_traits()-> 00159 compare_endpoints_xy_2_object()(cv); 00160 00161 if (he_dir == cv_dir) 00162 { 00163 (*m_edges_hash)[he] = cv.data().bc(); 00164 (*m_edges_hash)[he->twin()] = cv.data().twin_bc(); 00165 } 00166 else 00167 { 00168 (*m_edges_hash)[he] = cv.data().twin_bc(); 00169 (*m_edges_hash)[he->twin()] = cv.data().bc(); 00170 } 00171 } 00172 00173 00174 }; 00175 00176 template <class BaseEvent_> 00177 class Indexed_event : public BaseEvent_ 00178 { 00179 private: 00180 00181 unsigned int m_index; 00182 00183 public: 00184 00185 Indexed_event () : 00186 BaseEvent_(), 00187 m_index (0) 00188 {} 00189 00190 unsigned int index () const 00191 { 00192 return (m_index); 00193 } 00194 00195 void set_index (unsigned int index) 00196 { 00197 m_index = index; 00198 return; 00199 } 00200 }; 00201 00202 template<class Traits, class Arrangement_, class Event, class Subcurve> 00203 class Gps_agg_op_visitor : 00204 public Gps_agg_op_base_visitor<Traits, Arrangement_, Event, Subcurve> 00205 { 00206 protected: 00207 00208 typedef Arrangement_ Arrangement; 00209 00210 typedef Gps_agg_op_base_visitor<Traits, 00211 Arrangement, 00212 Event, 00213 Subcurve> Base; 00214 00215 typedef typename Base::SL_iterator SL_iterator; 00216 typedef typename Base::Halfedge_handle Halfedge_handle; 00217 typedef typename Base::Vertex_handle Vertex_handle; 00218 typedef typename Base::SubCurveIter SubCurveIter; 00219 typedef typename Base::SubCurveRevIter SubCurveRevIter; 00220 typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; 00221 typedef typename Traits::Point_2 Point_2; 00222 00223 protected: 00224 00225 unsigned int m_event_count; // The number of events so far. 00226 std::vector<Vertex_handle> *m_vertices_vec; // The vertices, sorted in 00227 // ascending order. 00228 00229 public: 00230 00231 Gps_agg_op_visitor (Arrangement *arr, 00232 typename Base::Edges_hash* hash, 00233 std::vector<Vertex_handle>* vertices_vec) : 00234 Base (arr, hash), 00235 m_event_count (0), 00236 m_vertices_vec (vertices_vec) 00237 {} 00238 00239 void before_handle_event (Event* event) 00240 { 00241 event->set_index (m_event_count); 00242 m_event_count++; 00243 00244 return; 00245 } 00246 00247 virtual Halfedge_handle 00248 insert_in_face_interior (const X_monotone_curve_2& cv, 00249 Subcurve* sc) 00250 { 00251 Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc); 00252 00253 // We now have a halfedge whose source vertex is associated with the 00254 // last event and whose target vertex is associated with the current event: 00255 Event *curr_event = reinterpret_cast<Event*>(this->current_event()); 00256 Event *last_event = reinterpret_cast<Event*>((sc)->last_event()); 00257 00258 CGAL_assertion ((Arr_halfedge_direction)res_he->direction() == ARR_LEFT_TO_RIGHT); 00259 _insert_vertex (curr_event, res_he->target()); 00260 _insert_vertex (last_event, res_he->source()); 00261 00262 return (res_he); 00263 } 00264 00265 virtual Halfedge_handle 00266 insert_from_right_vertex (const X_monotone_curve_2& cv, 00267 Halfedge_handle he, 00268 Subcurve* sc) 00269 { 00270 Halfedge_handle res_he = Base::insert_from_right_vertex (cv, he, sc); 00271 00272 // We now have a halfedge whose target vertex is associated with the 00273 // last event (we have already dealt with its source vertex). 00274 Event *last_event = reinterpret_cast<Event*>((sc)->last_event()); 00275 CGAL_assertion ((Arr_halfedge_direction)res_he->direction() == ARR_RIGHT_TO_LEFT); 00276 _insert_vertex (last_event, res_he->target()); 00277 00278 return (res_he); 00279 } 00280 00281 virtual Halfedge_handle 00282 insert_from_left_vertex (const X_monotone_curve_2& cv, 00283 Halfedge_handle he, 00284 Subcurve* sc) 00285 { 00286 Halfedge_handle res_he = Base::insert_from_left_vertex (cv, he, sc); 00287 00288 // We now have a halfedge whose target vertex is associated with the 00289 // current event (we have already dealt with its source vertex). 00290 Event *curr_event = reinterpret_cast<Event*>(this->current_event()); 00291 00292 CGAL_assertion ((Arr_halfedge_direction)res_he->direction() == ARR_LEFT_TO_RIGHT); 00293 _insert_vertex (curr_event, res_he->target()); 00294 00295 return (res_he); 00296 } 00297 00298 private: 00299 00300 void _insert_vertex (const Event* event, 00301 Vertex_handle v) 00302 { 00303 const unsigned int index = event->index(); 00304 00305 if (index >= m_vertices_vec->size()) 00306 m_vertices_vec->resize (2 * (index + 1)); 00307 00308 (*m_vertices_vec)[index] = v; 00309 return; 00310 } 00311 00312 }; 00313 00314 CGAL_END_NAMESPACE 00315 00316 #endif