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/Arrangement_2/Arr_on_surface_with_history_2_impl.h $ 00015 // $Id: Arr_on_surface_with_history_2_impl.h 50366 2009-07-05 12:56:48Z efif $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 // Efi Fogel <efif@post.tau.ac.il> 00020 // Baruch Zukerman <baruchzu@post.tau.ac.il> 00021 00022 #ifndef CGAL_ARR_ON_SURFACE_WITH_HISTORY_2_FUNCTIONS_H 00023 #define CGAL_ARR_ON_SURFACE_WITH_HISTORY_2_FUNCTIONS_H 00024 00030 CGAL_BEGIN_NAMESPACE 00031 00032 //----------------------------------------------------------------------------- 00033 // Default constructor. 00034 // 00035 template<class GeomTr, class TopTr> 00036 Arrangement_on_surface_with_history_2<GeomTr, TopTr>:: 00037 Arrangement_on_surface_with_history_2 () : 00038 Base_arr_2 () 00039 { 00040 m_observer.attach (*this); 00041 } 00042 00043 //----------------------------------------------------------------------------- 00044 // Copy constructor. 00045 // 00046 template<class GeomTr, class TopTr> 00047 Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00048 Arrangement_on_surface_with_history_2 (const Self& arr) : 00049 Base_arr_2 () 00050 { 00051 assign (arr); 00052 m_observer.attach (*this); 00053 } 00054 00055 //----------------------------------------------------------------------------- 00056 // Constructor given a traits object. 00057 // 00058 template<class GeomTr, class TopTr> 00059 Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00060 Arrangement_on_surface_with_history_2 (const Geometry_traits_2 * tr) : 00061 Base_arr_2 (static_cast<Data_traits_2*> (tr)) 00062 { 00063 m_observer.attach (*this); 00064 } 00065 00066 //----------------------------------------------------------------------------- 00067 // Assignment operator. 00068 // 00069 template<class GeomTr, class TopTr> 00070 Arrangement_on_surface_with_history_2<GeomTr,TopTr>& 00071 Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00072 operator=(const Self& arr) 00073 { 00074 // Check for self-assignment. 00075 if (this == &arr) 00076 return (*this); 00077 00078 assign (arr); 00079 return (*this); 00080 } 00081 00082 //----------------------------------------------------------------------------- 00083 // Assign an arrangement with history. 00084 // 00085 template<class GeomTr, class TopTr> 00086 void Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00087 assign(const Self& arr) 00088 { 00089 // Clear the current contents of the arrangement. 00090 clear(); 00091 00092 // Assign the base arrangement. 00093 Base_arr_2::assign (arr); 00094 00095 // Create duplicates of the stored curves and map the curves of the 00096 // original arrangement to their corresponding duplicates. 00097 typedef std::map<const Curve_halfedges*, Curve_halfedges*> Curve_map; 00098 typedef typename Curve_map::value_type Curve_map_entry; 00099 00100 Curve_map cv_map; 00101 Curve_const_iterator ocit; 00102 const Curve_2 *p_cv; 00103 Curve_halfedges *dup_c; 00104 00105 for (ocit = arr.curves_begin(); ocit != arr.curves_end(); ++ocit) 00106 { 00107 // Create a duplicate of the current curve. 00108 dup_c = m_curves_alloc.allocate (1); 00109 00110 p_cv = &(*ocit); 00111 m_curves_alloc.construct (dup_c, *p_cv); 00112 m_curves.push_back (*dup_c); 00113 00114 // Assign a map entry. 00115 cv_map.insert (Curve_map_entry (&(*ocit), dup_c)); 00116 } 00117 00118 // Go over the list of halfedges in our arrangement. The curves associated 00119 // with these edges sotre pointers to the curves in the original 00120 // arrangement, so we now have to modify these pointers, according to the 00121 // mapping we have just created. While doing so, we also construct the set 00122 // of edges associated with each (duplicated) curve in our arrangement. 00123 Data_iterator dit; 00124 std::list<Curve_2*> dup_curves; 00125 typename std::list<Curve_2*>::iterator iter; 00126 Edge_iterator eit; 00127 Halfedge_handle e; 00128 const Curve_halfedges *org_c; 00129 00130 for (eit = this->edges_begin(); eit != this->edges_end(); ++eit) 00131 { 00132 e = eit; 00133 dup_curves.clear(); 00134 for (dit = e->curve().data().begin(); 00135 dit != e->curve().data().end(); ++dit) 00136 { 00137 org_c = static_cast<Curve_halfedges*>(*dit); 00138 dup_c = (cv_map.find (org_c))->second; 00139 00140 dup_curves.push_back (dup_c); 00141 dup_c->_insert (e); 00142 } 00143 00144 // Replace the curve pointers associated with the edge. 00145 e->curve().data().clear(); 00146 for (iter = dup_curves.begin(); iter != dup_curves.end(); ++iter) 00147 e->curve().data().insert (*iter); 00148 } 00149 00150 return; 00151 } 00152 00153 //----------------------------------------------------------------------------- 00154 // Destructor. 00155 // 00156 template<class GeomTr, class TopTr> 00157 Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00158 ~Arrangement_on_surface_with_history_2 () 00159 { 00160 clear(); 00161 } 00162 00163 //----------------------------------------------------------------------------- 00164 // Clear the arrangement. 00165 // 00166 template<class GeomTr, class TopTr> 00167 void Arrangement_on_surface_with_history_2<GeomTr,TopTr>::clear () 00168 { 00169 // Free all stored curves. 00170 Curve_iterator cit = m_curves.begin(); 00171 Curve_halfedges *p_cv; 00172 00173 while (cit != m_curves.end()) 00174 { 00175 p_cv = &(*cit); 00176 ++cit; 00177 00178 m_curves.erase (p_cv); 00179 m_curves_alloc.destroy (p_cv); 00180 m_curves_alloc.deallocate (p_cv, 1); 00181 } 00182 m_curves.destroy(); 00183 00184 // Clear the base arrangement. 00185 Base_arr_2::clear(); 00186 00187 return; 00188 } 00189 00190 //----------------------------------------------------------------------------- 00191 // Split a given edge into two at the given split point. 00192 // 00193 template<class GeomTr, class TopTr> 00194 typename Arrangement_on_surface_with_history_2<GeomTr,TopTr>::Halfedge_handle 00195 Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00196 split_edge(Halfedge_handle e, const Point_2& p) 00197 { 00198 // Split the curve associated with the halfedge e at the given point p. 00199 Data_x_curve_2 cv1, cv2; 00200 00201 this->m_geom_traits->split_2_object() (e->curve(), p, 00202 cv1, cv2); 00203 00204 // cv1 always lies to the left of cv2. If e is directed from left to right, 00205 // we should split and return the halfedge associated with cv1, and 00206 // otherwise we should return the halfedge associated with cv2 after the 00207 // split. 00208 if (e->direction() == ARR_LEFT_TO_RIGHT) 00209 { 00210 return (Base_arr_2::split_edge (e, cv1, cv2)); 00211 } 00212 else 00213 { 00214 return (Base_arr_2::split_edge (e, cv2, cv1)); 00215 } 00216 } 00217 00218 //----------------------------------------------------------------------------- 00219 // Merge two edges to form a single edge. 00220 // 00221 template<class GeomTr, class TopTr> 00222 typename Arrangement_on_surface_with_history_2<GeomTr,TopTr>::Halfedge_handle 00223 Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00224 merge_edge(Halfedge_handle e1, Halfedge_handle e2) 00225 { 00226 CGAL_precondition_msg (are_mergeable(e1, e2), 00227 "Edges are not mergeable."); 00228 00229 // Merge the two curves. 00230 Data_x_curve_2 cv; 00231 00232 this->m_geom_traits->merge_2_object()(e1->curve(), e2->curve(), cv); 00233 00234 return (Base_arr_2::merge_edge (e1, e2, cv)); 00235 } 00236 00237 //----------------------------------------------------------------------------- 00238 // Check if two edges can be merged to a single edge. 00239 // 00240 template<class GeomTr, class TopTr> 00241 bool Arrangement_on_surface_with_history_2<GeomTr,TopTr>::are_mergeable 00242 (Halfedge_const_handle e1, 00243 Halfedge_const_handle e2) const 00244 { 00245 // Both halfedges must be non-fictitious. 00246 if (e1->is_fictitious() || e2->is_fictitious()) 00247 return (false); 00248 00249 // In order to be mergeable, the two halfedges must share a common 00250 // end-vertex. We assign vh to be this vertex. 00251 Vertex_const_handle vh; 00252 00253 if (e1->target() == e2->source() || e1->target() == e2->target()) 00254 { 00255 vh = e1->target(); 00256 } 00257 else 00258 { 00259 if (e1->source() == e2->source() || e1->source() == e2->target()) 00260 { 00261 vh = e1->source(); 00262 } 00263 else 00264 { 00265 // No common end-vertex: the edges are not mergeable. 00266 return (false); 00267 } 00268 } 00269 00270 // If there are other edges incident to vh, it is impossible to remove it 00271 // and merge the two edges. 00272 if (vh->degree() != 2) 00273 return (false); 00274 00275 // Check whether the curves associated with the two edges are mergeable. 00276 return (this->m_geom_traits->are_mergeable_2_object()(e1->curve(), 00277 e2->curve())); 00278 } 00279 00280 //----------------------------------------------------------------------------- 00281 // Register a new observer (so it starts receiving notifications). 00282 // 00283 template<class GeomTr, class TopTr> 00284 void Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00285 _register_observer(Arr_observer<Self> *p_obs) 00286 { 00287 Base_arr_2::_register_observer 00288 (reinterpret_cast<Arr_observer<Base_arr_2>*>(p_obs)); 00289 return; 00290 } 00291 00292 //----------------------------------------------------------------------------- 00293 // Unregister an observer (so it stops receiving notifications). 00294 // 00295 template<class GeomTr, class TopTr> 00296 bool Arrangement_on_surface_with_history_2<GeomTr,TopTr>:: 00297 _unregister_observer(Arr_observer<Self> *p_obs) 00298 { 00299 return (Base_arr_2::_unregister_observer 00300 (reinterpret_cast<Arr_observer<Base_arr_2>*>(p_obs))); 00301 } 00302 00303 CGAL_END_NAMESPACE 00304 00305 #endif