|
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_sweep.h $ 00015 // $Id: Gps_agg_op_sweep.h 41153 2007-12-10 23:21:34Z efif $ $Date: 2007-12-11 00:21:34 +0100 (Tue, 11 Dec 2007) $ 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_SWEEP_H 00022 #define CGAL_GSP_AGG_OP_SWEEP_H 00023 00024 #include <CGAL/Sweep_line_2.h> 00025 #include <CGAL/Unique_hash_map.h> 00026 00027 CGAL_BEGIN_NAMESPACE 00028 00029 template <class Arrangement_, 00030 class MetaTraits_, 00031 class SweepVisitor, 00032 class CurveWrap, 00033 class SweepEvent, 00034 typename Allocator = CGAL_ALLOCATOR(int) > 00035 class Gps_agg_op_sweep_line_2 : 00036 public Sweep_line_2<MetaTraits_, 00037 SweepVisitor, 00038 CurveWrap, 00039 SweepEvent, 00040 Allocator> 00041 { 00042 public: 00043 00044 typedef Arrangement_ Arrangement_2; 00045 typedef MetaTraits_ Traits_2; 00046 typedef typename Traits_2::Point_2 Point_2; 00047 typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; 00048 00049 typedef typename Arrangement_2::Vertex_handle Vertex_handle; 00050 typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; 00051 00052 typedef std::pair<Arrangement_2 *, 00053 std::vector<Vertex_handle> *> Arr_entry; 00054 00055 typedef Sweep_line_2<Traits_2, 00056 SweepVisitor, 00057 CurveWrap, 00058 SweepEvent, 00059 Allocator> Base; 00060 00061 typedef SweepEvent Event; 00062 00063 00064 typedef typename Base::Event_queue_iterator EventQueueIter; 00065 typedef typename Event::Subcurve_iterator EventCurveIter; 00066 00067 typedef typename Base::Base_event Base_event; 00068 typedef typename Base_event::Attribute Attribute; 00069 00070 typedef typename Base::Base_subcurve Base_subcurve; 00071 00072 typedef CurveWrap Subcurve; 00073 00074 typedef std::list<Subcurve*> SubCurveList; 00075 typedef typename SubCurveList::iterator SubCurveListIter; 00076 00077 00078 typedef typename Base::Status_line_iterator StatusLineIter; 00079 00080 public: 00081 00086 Gps_agg_op_sweep_line_2 (SweepVisitor* visitor) : 00087 Base (visitor) 00088 {} 00089 00095 Gps_agg_op_sweep_line_2 (Traits_2 *traits, SweepVisitor* visitor) : 00096 Base(traits, visitor) 00097 {} 00098 00100 template<class CurveInputIterator> 00101 void sweep (CurveInputIterator curves_begin, 00102 CurveInputIterator curves_end, 00103 unsigned int lower, 00104 unsigned int upper, 00105 unsigned int jump, 00106 std::vector<Arr_entry>& arr_vec) 00107 { 00108 CGAL_assertion (this->m_queue->empty() && 00109 this->m_statusLine.size() == 0); 00110 00111 typedef Unique_hash_map<Vertex_handle, Event *> Vertices_map; 00112 typedef typename Traits_2::Compare_xy_2 Compare_xy_2; 00113 00114 this->m_visitor->before_sweep(); 00115 // Allocate all of the Subcurve objects as one block. 00116 this->m_num_of_subCurves = std::distance (curves_begin, curves_end); 00117 this->m_subCurves = 00118 this->m_subCurveAlloc.allocate (this->m_num_of_subCurves); 00119 00120 this->m_curves_pair_set.resize (2 * this->m_num_of_subCurves); 00121 00122 // Initialize the event queue using the vertices vectors. Note that these 00123 // vertices are already sorted, we simply have to merge them 00124 Vertices_map vert_map; 00125 Vertex_handle vh; 00126 Vertex_handle invalid_v; 00127 unsigned int i = lower; 00128 unsigned int n = (arr_vec[i].second)->size(); 00129 unsigned int j; 00130 EventQueueIter q_iter; 00131 bool first = true; 00132 Attribute event_type; 00133 Event *event; 00134 00135 for (j = 0; 00136 j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v; 00137 j++) 00138 { 00139 // Insert the vertices of the first vector one after the other. 00140 event_type = _type_of_vertex (vh); 00141 if (event_type == Base_event::DEFAULT) 00142 continue; 00143 00144 event = this->_allocate_event (vh->point(), event_type, 00145 ARR_INTERIOR, ARR_INTERIOR); 00146 // \todo When the boolean set operations are exteneded to support 00147 // unbounded curves, we will need here a special treatment. 00148 00149 #ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_H 00150 event->set_finite(); 00151 #endif 00152 00153 if (! first) 00154 { 00155 q_iter = this->m_queue->insert_after (q_iter, event); 00156 } 00157 else 00158 { 00159 q_iter = this->m_queue->insert (event); 00160 first = false; 00161 } 00162 00163 vert_map[vh] = event; 00164 } 00165 00166 Comparison_result res = LARGER; 00167 Compare_xy_2 comp_xy = this->m_traits->compare_xy_2_object(); 00168 EventQueueIter q_end = this->m_queue->end(); 00169 00170 for (i += jump; i <= upper; i += jump) 00171 { 00172 // Merge the vertices of the other vectors into the existing queue. 00173 q_iter = this->m_queue->begin(); 00174 n = (arr_vec[i].second)->size(); 00175 00176 for (j = 0; 00177 j < n && (vh = (*(arr_vec[i].second))[j]) != invalid_v; 00178 j++) 00179 { 00180 event_type = _type_of_vertex (vh); 00181 if (event_type == Base_event::DEFAULT) 00182 continue; 00183 00184 while (q_iter != q_end && 00185 (res = comp_xy (vh->point(), (*q_iter)->point())) == LARGER) 00186 { 00187 ++q_iter; 00188 } 00189 00190 if (res == SMALLER || q_iter == q_end) 00191 { 00192 event = this->_allocate_event (vh->point(), event_type, 00193 ARR_INTERIOR, ARR_INTERIOR); 00194 // \todo When the boolean set operations are exteneded to support 00195 // unbounded curves, we will need here a special treatment. 00196 00197 #ifndef CGAL_ARRANGEMENT_ON_SURFACE_2_H 00198 event->set_finite(); 00199 #endif 00200 00201 this->m_queue->insert_before (q_iter, event); 00202 vert_map[vh] = event; 00203 } 00204 else if (res == EQUAL) 00205 { 00206 // In this case q_iter points to an event already associated with 00207 // the vertex, so we just update the map: 00208 vert_map[vh] = *q_iter; 00209 } 00210 } 00211 } 00212 00213 // Go over all curves (which are associated with halfedges) and associate 00214 // them with the events we have just created. 00215 unsigned int index = 0; 00216 CurveInputIterator iter; 00217 Halfedge_handle he; 00218 Event *e_left; 00219 Event *e_right; 00220 00221 for (iter = curves_begin; iter != curves_end; ++iter, index++) 00222 { 00223 // Get the events associated with the end-vertices of the current 00224 // halfedge. 00225 he = iter->data().halfedge(); 00226 00227 CGAL_assertion (vert_map.is_defined (he->source())); 00228 CGAL_assertion (vert_map.is_defined (he->target())); 00229 00230 if ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) 00231 { 00232 e_left = vert_map[he->source()]; 00233 e_right = vert_map[he->target()]; 00234 } 00235 else 00236 { 00237 e_left = vert_map[he->target()]; 00238 e_right = vert_map[he->source()]; 00239 } 00240 00241 // Create the subcurve object. 00242 this->m_subCurveAlloc.construct (this->m_subCurves + index, 00243 this->m_masterSubcurve); 00244 00245 (this->m_subCurves + index)->init (*iter); 00246 (this->m_subCurves + index)->set_left_event(e_left); 00247 (this->m_subCurves + index)->set_right_event(e_right); 00248 00249 e_right->add_curve_to_left (this->m_subCurves + index); 00250 this->_add_curve_to_right (e_left, this->m_subCurves + index); 00251 } 00252 00253 // Perform the sweep: 00254 this->_sweep(); 00255 this->_complete_sweep(); 00256 this->m_visitor->after_sweep(); 00257 00258 return; 00259 } 00260 00261 private: 00262 00267 Attribute _type_of_vertex (Vertex_handle v) 00268 { 00269 typename Arrangement_2::Halfedge_around_vertex_circulator first, circ; 00270 00271 circ = first = v->incident_halfedges(); 00272 do 00273 { 00274 // Check if the current edge separates two faces with unequal 00275 // containment flags (otherwise we will simply not keep it). 00276 if (circ->face()->contained() != circ->twin()->face()->contained()) 00277 { 00278 if ((Arr_halfedge_direction)circ->direction() == ARR_LEFT_TO_RIGHT) 00279 return (Base_event::RIGHT_END); 00280 else 00281 return (Base_event::LEFT_END); 00282 } 00283 ++circ; 00284 00285 } while (circ != first); 00286 00287 // If we reached here, we should not keep this vertex. 00288 return (Base_event::DEFAULT); 00289 } 00290 }; 00291 00292 00293 CGAL_END_NAMESPACE 00294 00295 #endif
1.7.6.1