BWAPI
|
00001 // Copyright (c) 2007 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/Sweep_line_2/Arr_vert_decomp_sl_visitor.h $ 00015 // $Id: Arr_vert_decomp_sl_visitor.h 49772 2009-06-03 21:25:53Z eric $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 00020 #ifndef CGAL_ARR_VERT_DECOMP_SL_VISITOR_H 00021 #define CGAL_ARR_VERT_DECOMP_SL_VISITOR_H 00022 00027 CGAL_BEGIN_NAMESPACE 00028 00029 #include <CGAL/Object.h> 00030 00035 template <class Helper_, class OutputIterator_> 00036 class Arr_vert_decomp_sl_visitor : 00037 public Helper_::Base_visitor 00038 { 00039 public: 00040 00041 typedef Helper_ Helper; 00042 typedef OutputIterator_ OutputIterator; 00043 00044 typedef typename Helper::Traits_2 Traits_2; 00045 typedef typename Helper::Arrangement_2 Arrangement_2; 00046 typedef typename Helper::Base_visitor Base; 00047 typedef typename Helper::Event Event; 00048 typedef typename Helper::Subcurve Subcurve; 00049 00050 typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; 00051 00052 typedef std::pair<CGAL::Object, CGAL::Object> Vert_pair; 00053 typedef std::pair<Vertex_const_handle, Vert_pair> Vert_entry; 00054 00055 protected: 00056 00057 typedef typename Base::Status_line_iterator Status_line_iterator; 00058 typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; 00059 //typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; 00060 typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator 00061 Halfedge_around_vertex_const_circulator; 00062 00063 // Data members: 00064 Helper m_helper; // The helper class. 00065 00066 const typename Arrangement_2::Geometry_traits_2 *m_traits; 00067 // The traits class. 00068 00069 const Vertex_const_handle invalid_vh; 00070 // An invalid vertex handle. 00071 00072 Vertex_const_handle m_prev_vh; // The previous vertex. 00073 CGAL::Object m_prev_obj_below; // The object this vertex sees below it. 00074 CGAL::Object m_prev_obj_above; // The object this vertex sees above it. 00075 00076 OutputIterator *m_out; // An output iterator for the result. 00077 00078 public: 00079 00085 Arr_vert_decomp_sl_visitor (const Arrangement_2 *arr, 00086 OutputIterator *oi) : 00087 m_helper (arr), 00088 m_traits (arr->geometry_traits()), 00089 invalid_vh(), 00090 m_out (oi) 00091 {} 00092 00093 /* A notification issued before the sweep process starts. */ 00094 void before_sweep (); 00095 00104 bool after_handle_event (Event* event, 00105 Status_line_iterator above, 00106 bool on_above); 00107 00111 void after_sweep (); 00112 }; 00113 00114 //----------------------------------------------------------------------------- 00115 // Memeber-function definitions: 00116 //----------------------------------------------------------------------------- 00117 00118 //----------------------------------------------------------------------------- 00119 // A notification issued before the sweep process starts. 00120 // 00121 template <class Hlpr, class OutIt> 00122 void Arr_vert_decomp_sl_visitor<Hlpr, OutIt>::before_sweep () 00123 { 00124 // Notify the helper that the sweep process now starts. 00125 m_helper.before_sweep(); 00126 00127 // Set an invalid previous vertex. 00128 m_prev_vh = Vertex_const_handle(); 00129 00130 return; 00131 } 00132 00133 //----------------------------------------------------------------------------- 00134 // A notification invoked after the sweep-line finishes handling the given 00135 // event. 00136 // 00137 template <class Hlpr, class OutIt> 00138 bool Arr_vert_decomp_sl_visitor<Hlpr, OutIt>::after_handle_event 00139 (Event* event, 00140 Status_line_iterator above, bool /* on_above */) 00141 { 00142 // Notify the helper on the event. 00143 m_helper.after_handle_event (event); 00144 00145 // We are only interested in events associated with valid points: 00146 if (! event->is_closed()) 00147 return (true); 00148 00149 // Get the vertex handle associated with the current event (stored with 00150 // the point). 00151 Vertex_const_handle vh = event->point().vertex_handle(); 00152 CGAL::Object obj_above, obj_below; 00153 00154 // Check the feature from above. 00155 if (above == this->status_line_end()) 00156 { 00157 // There is no concrete subcurve above the current event point, so we use 00158 // the helper class to obtain the object above. 00159 obj_above = m_helper.top_object(); 00160 } 00161 else 00162 { 00163 // We have a valid subcurve above the event: get its halfedge handle 00164 // and associate it with the vertex. 00165 obj_above = 00166 CGAL::make_object((*above)->last_curve().halfedge_handle()); 00167 } 00168 00169 // Check if the previous vertex we handled has the same x-coordinate 00170 // as the current one (it lies vertically below the current vertex). 00171 const bool prev_same_x = 00172 (m_prev_vh != invalid_vh && 00173 m_traits->compare_x_2_object() (vh->point(), 00174 m_prev_vh->point()) == EQUAL); 00175 00176 // Decrement the status-line iterator to reach the subcurve below the 00177 // event point. If the number of right subcurves associated with the 00178 // event is n_right, we decrement the iterator n_right times, then 00179 // check if it is possible to further decrement it. 00180 Status_line_iterator below = above; 00181 const int n_right = event->number_of_right_curves(); 00182 int k; 00183 00184 for (k = 0; k < n_right; k++) 00185 --below; 00186 00187 if (below == this->status_line_begin()) 00188 { 00189 if (prev_same_x) 00190 { 00191 // The previous vertex is vertically below the current vertex, 00192 // so we update their respective entries in the output map. 00193 // We first check if the two vertices are connected (by a vertical 00194 // segment) - if so, they "see" empty features. 00195 bool vert_connected = false; 00196 00197 if (! vh->is_isolated()) 00198 { 00199 Halfedge_around_vertex_const_circulator circ, first; 00200 00201 first = circ = vh->incident_halfedges(); 00202 do 00203 { 00204 if (circ->source() == m_prev_vh) 00205 vert_connected = true; 00206 ++circ; 00207 } while (! vert_connected && circ != first); 00208 } 00209 00210 if (! vert_connected) 00211 { 00212 obj_below = CGAL::make_object(m_prev_vh); 00213 m_prev_obj_above = CGAL::make_object(vh); 00214 } 00215 else 00216 { 00217 obj_below = CGAL::Object(); 00218 m_prev_obj_above = CGAL::Object(); 00219 } 00220 } 00221 else 00222 { 00223 // There is no concrete subcurve below the current event point, so we 00224 // use the helper class to obtain the object below. 00225 obj_below = m_helper.bottom_object(); 00226 } 00227 } 00228 else 00229 { 00230 // Decrement the iterator once more in order to reach the subcurve below 00231 // the current event. 00232 --below; 00233 00234 // If the previous event has the same x-coordinate as the current one, 00235 // we check whether it lies below or above the subcurve below. We do this 00236 // to distinguish between the following scenarios: 00237 // 00238 // 00239 // * * 00240 // 00241 // -------- x 00242 // 00243 // x --------- 00244 // 00245 if (prev_same_x && 00246 (m_traits->compare_y_at_x_2_object() 00247 (m_prev_vh->point(), 00248 (*below)->last_curve().base()) != SMALLER)) 00249 { 00250 // The previous vertex is vertically below the current vertex, 00251 // and above the subcurve that lies below vh. We therefore update 00252 // the respective entries in the output map accordingly. 00253 // We first check if the two vertices are connected (by a vertical 00254 // segment) - if so, they "see" empty features. 00255 bool vert_connected = false; 00256 00257 if (! vh->is_isolated()) 00258 { 00259 Halfedge_around_vertex_const_circulator circ, first; 00260 00261 first = circ = vh->incident_halfedges(); 00262 do 00263 { 00264 if (circ->source() == m_prev_vh) 00265 vert_connected = true; 00266 ++circ; 00267 } while (! vert_connected && circ != first); 00268 } 00269 00270 if (! vert_connected) 00271 { 00272 obj_below = CGAL::make_object(m_prev_vh); 00273 m_prev_obj_above = CGAL::make_object(vh); 00274 } 00275 else 00276 { 00277 obj_below = CGAL::Object(); 00278 m_prev_obj_above = CGAL::Object(); 00279 } 00280 } 00281 else 00282 { 00283 // Get the halfedge handle of the subcurve below the current event and 00284 // associate it with its vertex. 00285 obj_below = 00286 CGAL::make_object((*below)->last_curve().halfedge_handle()); 00287 } 00288 } 00289 00290 // We can now create the entry for the previous vertex, as we are not 00291 // going to change the identity of the features below or above it. 00292 if (m_prev_vh != Vertex_const_handle()) 00293 { 00294 *(*m_out) = Vert_entry (m_prev_vh, Vert_pair (m_prev_obj_below, 00295 m_prev_obj_above)); 00296 ++(*m_out); 00297 } 00298 00299 // We are done with the current vertex, but we cannot create the entry 00300 // yet - so we store it for the next event. 00301 m_prev_vh = vh; 00302 m_prev_obj_below = obj_below; 00303 m_prev_obj_above = obj_above; 00304 00305 // It is safe to deallocate the event. 00306 return (true); 00307 } 00308 00309 //----------------------------------------------------------------------------- 00310 // A notification issued when the sweep process is over. 00311 // 00312 template <class Hlpr, class OutIt> 00313 void Arr_vert_decomp_sl_visitor<Hlpr, OutIt>::after_sweep () 00314 { 00315 // Create an entry for the last vertex (the xy-largest one). 00316 if (m_prev_vh != invalid_vh) 00317 { 00318 *(*m_out) = Vert_entry (m_prev_vh, Vert_pair (m_prev_obj_below, 00319 m_prev_obj_above)); 00320 ++(*m_out); 00321 } 00322 00323 return; 00324 } 00325 00326 CGAL_END_NAMESPACE 00327 00328 #endif