BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h
Go to the documentation of this file.
00001 // Copyright (c) 2003,2004,2005,2006  INRIA Sophia-Antipolis (France) and
00002 // Notre Dame University (U.S.A.).  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/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h $
00015 // $Id: Segment_Delaunay_graph_2_impl.h 48908 2009-04-26 14:03:12Z spion $
00016 // 
00017 //
00018 // Author(s)     : Menelaos Karavelas <mkaravel@cse.nd.edu>
00019 
00020 
00021 // class implementation continued
00022 //=================================
00023 
00024 CGAL_BEGIN_NAMESPACE
00025 
00026 //====================================================================
00027 //====================================================================
00028 //                   CONSTRUCTORS
00029 //====================================================================
00030 //====================================================================
00031 
00032 // copy constructor
00033 template<class Gt, class ST, class D_S, class LTag>
00034 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00035 Segment_Delaunay_graph_2(const Segment_Delaunay_graph_2& other)
00036   : DG(other.geom_traits())
00037 {
00038   Segment_Delaunay_graph_2&
00039     non_const_other = const_cast<Segment_Delaunay_graph_2&>(other);
00040   copy(non_const_other);
00041   CGAL_postcondition( is_valid() );
00042 }
00043 
00044 // assignment operator
00045 template<class Gt, class ST, class D_S, class LTag>
00046 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Self&
00047 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00048 operator=(const Self& other)
00049 {
00050   if ( this != &other ) {
00051     Segment_Delaunay_graph_2&
00052       non_const_other = const_cast<Segment_Delaunay_graph_2&>(other);
00053     copy(non_const_other);
00054   }
00055   return (*this);
00056 }
00057 
00058 //====================================================================
00059 //====================================================================
00060 //                   METHODS FOR INSERTION
00061 //====================================================================
00062 //====================================================================
00063 
00064 //--------------------------------------------------------------------
00065 // insertion of first three sites
00066 //--------------------------------------------------------------------
00067 
00068 template<class Gt, class ST, class D_S, class LTag>
00069 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00070 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00071 insert_first(const Storage_site_2& ss, const Point_2& )
00072 {
00073   CGAL_precondition( number_of_vertices() == 0 );
00074 
00075   Vertex_handle v = this->_tds.insert_second();
00076   v->set_site(ss);
00077   return v;
00078 }
00079 
00080 template<class Gt, class ST, class D_S, class LTag>
00081 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00082 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00083 insert_second(const Storage_site_2& ss, const Point_2& p)
00084 {
00085   CGAL_precondition( number_of_vertices() == 1 );
00086   // p0 is actually a point
00087   Site_2 p0 = finite_vertices_begin()->site();
00088   // MK: change the equality test between points by the functor in
00089   // geometric traits
00090   Site_2 tp = Site_2::construct_site_2(p);
00091   if ( same_points(tp,p0) ) {
00092     // merge info of identical sites
00093     merge_info(finite_vertices_begin(), ss);
00094     return finite_vertices_begin();
00095   }
00096 
00097   return create_vertex_dim_up(ss);
00098 }
00099 
00100 template<class Gt, class ST, class D_S, class LTag>
00101 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00102 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00103 insert_third(const Storage_site_2& ss, const Point_2& p)
00104 {
00105   Site_2 t = Site_2::construct_site_2(p);
00106   return insert_third(t, ss);
00107 }
00108 
00109 template<class Gt, class ST, class D_S, class LTag>
00110 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00111 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00112 insert_third(const Site_2& t, const Storage_site_2& ss)
00113 {
00114   CGAL_precondition( number_of_vertices() == 2 );
00115 
00116   // p0 and p1 are actually points
00117   Vertex_handle v0 = finite_vertices_begin();
00118   Vertex_handle v1 = ++finite_vertices_begin();
00119   Site_2 t0 = v0->site();
00120   Site_2 t1 = v1->site();
00121 
00122   if ( same_points(t, t0) ) {
00123     // merge info of identical sites
00124     merge_info(v0, ss);
00125     return v0;
00126   }
00127   if ( same_points(t, t1) ) {
00128     // merge info of identical sites
00129     merge_info(v1, ss);
00130     return v1;
00131   }
00132 
00133   Vertex_handle v = create_vertex_dim_up(ss);
00134 
00135   Face_handle f(finite_faces_begin());
00136 
00137   Site_2 s1 = f->vertex(0)->site();
00138   Site_2 s2 = f->vertex(1)->site();
00139   Site_2 s3 = f->vertex(2)->site();
00140 
00141   Orientation o =
00142     geom_traits().orientation_2_object()(s1, s2, s3);
00143 
00144   if ( o != COLLINEAR ) {
00145     if ( o == RIGHT_TURN ) {
00146       f->reorient();
00147       for (int i = 0; i < 3; i++) {
00148         f->neighbor(i)->reorient();
00149       }
00150     }
00151   } else {
00152     typename Geom_traits::Compare_x_2 compare_x =
00153       geom_traits().compare_x_2_object();
00154 
00155     Comparison_result xcmp12 = compare_x(s1, s2);
00156     if ( xcmp12 == SMALLER ) {        // x1 < x2
00157       Comparison_result xcmp23 = compare_x(s2, s3);
00158       if ( xcmp23 == SMALLER ) {            // x2 < x3
00159         flip(f, f->index(v1));
00160       } else {
00161         Comparison_result xcmp31 = compare_x(s3, s1);
00162         if ( xcmp31 == SMALLER ) {          // x3 < x1
00163           flip(f, f->index(v0));
00164         } else {                            // x1 < x3 < x2
00165           flip(f, f->index(v)); 
00166         }
00167       }
00168     } else if ( xcmp12 == LARGER ) {  // x1 > x2
00169       Comparison_result xcmp32 = compare_x(s3, s2);
00170       if ( xcmp32 == SMALLER ) {            // x3 < x2
00171         flip(f, f->index(v1));
00172       } else {
00173         Comparison_result xcmp13 = compare_x(s1, s3);
00174         if ( xcmp13 == SMALLER ) {          // x1 < x3
00175           flip(f, f->index(v0));
00176         } else {                            // x2 < x3 < x1
00177           flip(f, f->index(v));
00178         }
00179       }
00180     } else {                          // x1 == x2
00181       typename Geom_traits::Compare_y_2 compare_y =
00182         geom_traits().compare_y_2_object();
00183 
00184       Comparison_result ycmp12 = compare_y(s1, s2);
00185       if ( ycmp12 == SMALLER ) {      // y1 < y2
00186         Comparison_result ycmp23 = compare_y(s2, s3);
00187         if ( ycmp23 == SMALLER ) {          // y2 < y3
00188           flip(f, f->index(v1));
00189         } else {
00190           Comparison_result ycmp31 = compare_y(s3, s1);
00191           if ( ycmp31 == SMALLER ) {        // y3 < y1
00192             flip(f, f->index(v0));
00193           } else {                          // y1 < y3 < y2
00194             flip(f, f->index(v));
00195           }
00196         }
00197       } else if ( ycmp12 == LARGER ) { // y1 > y2
00198         Comparison_result ycmp32 = compare_y(s3, s2);
00199         if ( ycmp32 == SMALLER ) {           // y3 < y2
00200           flip(f, f->index(v1));
00201         } else {
00202           Comparison_result ycmp13 = compare_y(s1, s3);
00203           if ( ycmp13 == SMALLER ) {         // y1 < y3
00204             flip(f, f->index(v0));
00205           } else {                           // y2 < y3 < y1
00206             flip(f, f->index(v));
00207           }
00208         }
00209       } else {
00210         // this line should never have been reached
00211         CGAL_error();
00212       }
00213     }
00214   }
00215 
00216   return v;
00217 }
00218 
00219 
00220 template<class Gt, class ST, class D_S, class LTag>
00221 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00222 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00223 insert_third(const Storage_site_2& ss, Vertex_handle , Vertex_handle )
00224 {
00225   CGAL_precondition( number_of_vertices() == 2 );
00226 
00227   //  this can only be the case if the first site is a segment
00228   CGAL_precondition( dimension() == 1 );
00229 
00230   Vertex_handle v = create_vertex_dim_up(ss);
00231 
00232   Face_circulator fc = incident_faces(v);
00233 
00234   while ( true ) {
00235     Face_handle f(fc);
00236     if ( !is_infinite(f) ) {
00237       flip(f, f->index(v));
00238       break;
00239     }
00240     ++fc;
00241   }
00242   
00243   return v;
00244 }
00245 
00246 //--------------------------------------------------------------------
00247 // insertion of a point
00248 //--------------------------------------------------------------------
00249 
00250 template<class Gt, class ST, class D_S, class LTag>
00251 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00252 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00253 insert_point(const Storage_site_2& ss, const Point_2& p, Vertex_handle vnear)
00254 {
00255   int n = number_of_vertices();
00256   if ( n == 0 ) {
00257     return insert_first(ss, p);
00258   } else if ( n == 1 ) {
00259     return insert_second(ss, p);
00260   } else if ( n == 2 ) {
00261     return insert_third(ss, p);
00262   }
00263 
00264   Site_2 t = Site_2::construct_site_2(p);
00265   return insert_point(ss, t, vnear);
00266 }
00267 
00268 
00269 template<class Gt, class ST, class D_S, class LTag>
00270 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00271 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00272 insert_point(const Storage_site_2& ss, const Site_2& t,
00273              Vertex_handle vnear)
00274 {
00275   CGAL_precondition( t.is_point() );
00276   CGAL_assertion( number_of_vertices() > 2 );
00277 
00278   //*********************************************************************
00279   //*********************************************************************
00280   //*********************************************************************
00281   //*********************************************************************
00282   //*********************************************************************
00283   //*********************************************************************
00284   //*********************************************************************
00285   //*********************************************************************
00286   //*********************************************************************
00287   //*********************************************************************
00288   //*********************************************************************
00289   // MK::ERROR: I need to write a insert_point_no_search method that
00290   // does not search for the nearest neighbor; this should be used by
00291   // insert_point. Below the first version of the code is correct. The
00292   // second is what the insert_point method should do before calling
00293   // insert_point_no_search.
00294 
00295   // first find the nearest neighbor
00296 #if 1
00297   Vertex_handle  vnearest = nearest_neighbor( t, vnear );
00298 #else
00299   Vertex_handle vnearest;
00300   if ( vnear == Vertex_handle() ) {
00301     vnearest = nearest_neighbor( t, vnear );
00302   } else {
00303     vnearest = vnear;
00304   }
00305 #endif
00306 
00307   //*********************************************************************
00308   //*********************************************************************
00309   //*********************************************************************
00310   //*********************************************************************
00311   //*********************************************************************
00312   //*********************************************************************
00313   //*********************************************************************
00314   //*********************************************************************
00315   //*********************************************************************
00316   //*********************************************************************
00317   //*********************************************************************
00318 
00319 
00320   // check is the point has already been inserted or lies on
00321   // a segment already inserted
00322   Arrangement_type at_res = arrangement_type(t, vnearest);
00323   if ( vnearest->is_point() ) {
00324     if ( at_res == AT2::IDENTICAL ) {
00325       // merge info of identical sites
00326       merge_info(vnearest, ss);
00327       return vnearest;
00328     }
00329   } else {
00330     CGAL_assertion( vnearest->is_segment() );
00331     CGAL_assertion( at_res != AT2::TOUCH_1 );
00332     CGAL_assertion( at_res != AT2::TOUCH_2 );
00333     CGAL_assertion( at_res == AT2::DISJOINT || at_res == AT2::INTERIOR );
00334     if ( at_res == AT2::INTERIOR ) {
00335       CGAL_assertion( t.is_input() );
00336 
00337       Vertex_triple vt = insert_exact_point_on_segment(ss, t, vnearest);
00338       return vt.first;
00339     } else {
00340       // the point to be inserted does not belong to the interior of a
00341       // segment
00342       CGAL_assertion( at_res == AT2::DISJOINT );
00343     }
00344   }
00345 
00346   return insert_point2(ss, t, vnearest);
00347 }
00348 
00349 template<class Gt, class ST, class D_S, class LTag>
00350 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00351 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00352 insert_point2(const Storage_site_2& ss, const Site_2& t,
00353               Vertex_handle vnearest)
00354 {
00355   CGAL_precondition( t.is_point() );
00356   CGAL_assertion( number_of_vertices() > 2 );
00357 
00358   CGAL_expensive_precondition
00359     ( nearest_neighbor(t, vnearest) == vnearest );
00360 
00361   // find the first conflict
00362 
00363 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG)
00364   // verify that there are no intersections...
00365   Vertex_circulator vc = incident_vertices(vnearest);
00366   Vertex_circulator vc_start = vc;
00367   do {
00368     Vertex_handle vv(vc);
00369     Arrangement_type at_res = arrangement_type(t, vv);
00370 
00371     CGAL_assertion( at_res == AT2::DISJOINT );
00372     ++vc;
00373   } while ( vc != vc_start );
00374 #endif
00375 
00376   // first look for conflict with vertex
00377   Face_circulator fc_start = incident_faces(vnearest);
00378   Face_circulator fc = fc_start;
00379   Face_handle start_f;
00380   Sign s;
00381 
00382   std::map<Face_handle,Sign> sign_map;
00383 
00384   do {
00385     Face_handle f(fc);
00386 
00387     s = incircle(f, t);
00388 
00389     sign_map[f] = s;
00390 
00391     if ( s == NEGATIVE ) {
00392       start_f = f;
00393       break;
00394     }
00395     ++fc;
00396   } while ( fc != fc_start );
00397 
00398   // we are not in conflict with a Voronoi vertex, so we have to
00399   // be in conflict with the interior of a Voronoi edge
00400   if ( s != NEGATIVE ) {
00401     Edge_circulator ec_start = incident_edges(vnearest);
00402     Edge_circulator ec = ec_start;
00403 
00404     bool interior_in_conflict(false);
00405     Edge e;
00406     do {
00407       e = *ec;
00408 
00409       Sign s1 = sign_map[e.first];
00410       Sign s2 = sign_map[e.first->neighbor(e.second)];
00411 
00412       if ( s1 == s2 ) {
00413         interior_in_conflict = edge_interior(e, t, s1);
00414       } else {
00415         // It seems that there was a problem here when one of the
00416         // signs was positive and the other zero. In this case we
00417         // still check pretending that both signs where positive
00418         interior_in_conflict = edge_interior(e, t, POSITIVE);
00419       }
00420 
00421       if ( interior_in_conflict ) { break; }
00422       ++ec;
00423     } while ( ec != ec_start );
00424 
00425     sign_map.clear();
00426 
00427     CGAL_assertion( interior_in_conflict );
00428 
00429     return insert_degree_2(e, ss);
00430   }
00431 
00432 
00433   // we are in conflict with a Voronoi vertex; start from that and 
00434   // find the entire conflict region and then repair the diagram
00435   List l;
00436   Face_map fm;
00437 
00438   Triple<bool, Vertex_handle, Arrangement_type>
00439     vcross(false, Vertex_handle(), AT2::DISJOINT);
00440 
00441   // MK:: NEED TO WRITE A FUNCTION CALLED find_conflict_region WHICH
00442   // IS GIVEN A STARTING FACE, A LIST, A FACE MAP, A VERTEX MAP AND A
00443   // LIST OF FLIPPED EDGES AND WHAT IS DOES IS INITIALIZE THE CONFLICT 
00444   // REGION AND EXPANDS THE CONFLICT REGION.
00445   initialize_conflict_region(start_f, l);
00446   expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross);
00447 
00448   CGAL_assertion( !vcross.first );
00449 
00450   Vertex_handle v = create_vertex(ss);
00451 
00452   retriangulate_conflict_region(v, l, fm);
00453 
00454   return v;
00455 }
00456 
00457 //--------------------------------------------------------------------
00458 // insertion of a point that lies on a segment
00459 //--------------------------------------------------------------------
00460 
00461 template<class Gt, class ST, class D_S, class LTag>
00462 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Face_pair
00463 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00464 find_faces_to_split(const Vertex_handle& v, const Site_2& t) const
00465 {
00466   CGAL_precondition( v->is_segment() );
00467 
00468 #ifndef CGAL_NO_ASSERTIONS
00469   {
00470     // count number of adjacent infinite faces
00471     Face_circulator fc = incident_faces(v);
00472     Face_circulator fc_start = fc;
00473     int n_inf = 0;
00474     do {
00475       if ( is_infinite(fc) ) { n_inf++; }
00476       fc++;
00477     } while ( fc != fc_start );
00478     CGAL_assertion( n_inf == 0 || n_inf == 2 || n_inf == 4 );
00479   }
00480 #endif
00481 
00482   Face_circulator fc1 = incident_faces(v);
00483   Face_circulator fc2 = fc1; ++fc2;
00484   Face_circulator fc_start = fc1;
00485   Face_handle f1, f2;
00486   bool found_f1 = false, found_f2 = false;
00487   Site_2 sitev_supp = v->site().supporting_site();
00488   do {
00489     Face_handle ff1(fc1), ff2(fc2);
00490 
00491     Oriented_side os1, os2;
00492 
00493     if ( is_infinite(ff1) ) {
00494       int id_v = ff1->index(v);
00495       int cw_v = this->cw( id_v );
00496       int ccw_v = this->ccw( id_v );
00497 
00498       Site_2 sv_ep;
00499       if ( is_infinite( ff1->vertex(cw_v) ) ) {
00500         CGAL_assertion(  !is_infinite( ff1->vertex(ccw_v) )  );
00501         CGAL_assertion( ff1->vertex(ccw_v)->site().is_point() );
00502         sv_ep = ff1->vertex(ccw_v)->site();
00503       } else {
00504         CGAL_assertion(  !is_infinite( ff1->vertex( cw_v) )  );
00505         CGAL_assertion( ff1->vertex( cw_v)->site().is_point() );
00506         sv_ep = ff1->vertex( cw_v)->site();
00507       }
00508 
00509       os1 = oriented_side(sv_ep, sitev_supp, t);
00510     } else {
00511       os1 = oriented_side(fc1->vertex(0)->site(),
00512                           fc1->vertex(1)->site(),
00513                           fc1->vertex(2)->site(),
00514                           sitev_supp, t);
00515     }
00516 
00517     if ( is_infinite(ff2) ) {
00518       int id_v = ff2->index(v);
00519       int cw_v = this->cw( id_v );
00520       int ccw_v = this->ccw( id_v );
00521 
00522       Site_2 sv_ep;
00523       if ( is_infinite( ff2->vertex(cw_v) ) ) {
00524         CGAL_assertion(  !is_infinite( ff2->vertex(ccw_v) )  );
00525         CGAL_assertion( ff2->vertex(ccw_v)->site().is_point() );
00526         sv_ep = ff2->vertex(ccw_v)->site();
00527       } else {
00528         CGAL_assertion(  !is_infinite( ff2->vertex( cw_v) )  );
00529         CGAL_assertion( ff2->vertex( cw_v)->site().is_point() );
00530         sv_ep = ff2->vertex( cw_v)->site();
00531       }
00532 
00533       os2 = oriented_side(sv_ep, sitev_supp, t);
00534     } else {
00535       os2 = oriented_side(fc2->vertex(0)->site(),
00536                           fc2->vertex(1)->site(),
00537                           fc2->vertex(2)->site(),
00538                           sitev_supp, t);
00539     }
00540 
00541     if ( !found_f1 &&
00542          os1 != ON_POSITIVE_SIDE && os2 == ON_POSITIVE_SIDE ) {
00543       f1 = ff2;
00544       found_f1 = true;
00545     }
00546 
00547     if ( !found_f2 &&
00548          os1 == ON_POSITIVE_SIDE && os2 != ON_POSITIVE_SIDE ) {
00549       f2 = ff2;
00550       found_f2 = true;
00551     }
00552 
00553     if ( found_f1 && found_f2 ) { break; }
00554 
00555     ++fc1, ++fc2;
00556   } while ( fc_start != fc1 ); 
00557 
00558 
00559   CGAL_assertion( found_f1 && found_f2 );
00560   CGAL_assertion( f1 != f2 );
00561 
00562   return Face_pair(f1, f2);
00563 }
00564 
00565 template<class Gt, class ST, class D_S, class LTag>
00566 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_triple
00567 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00568 insert_exact_point_on_segment(const Storage_site_2& ss, const Site_2& t,
00569                               Vertex_handle v)
00570 {
00571   // splits the segment site v->site() in two and inserts represented by t
00572   // on return the three vertices are, respectively, the vertex
00573   // corresponding to t and the two subsegments of v->site()
00574 
00575   CGAL_assertion( t.is_point() );
00576   CGAL_assertion( t.is_input() );
00577 
00578   Storage_site_2 ssitev = v->storage_site();  
00579 
00580   CGAL_assertion( ssitev.is_segment() );
00581 
00582   Face_pair fpair = find_faces_to_split(v, t);
00583 
00584   boost::tuples::tuple<Vertex_handle,Vertex_handle,Face_handle,Face_handle>
00585     qq = this->_tds.split_vertex(v, fpair.first, fpair.second);
00586 
00587   // now I need to update the sites for vertices v1 and v2
00588   Vertex_handle v1 = boost::tuples::get<0>(qq); //qq.first;
00589   Storage_site_2 ssv1 = split_storage_site(ssitev, ss, true);
00590   v1->set_site( ssv1 );
00591 
00592   Vertex_handle v2 = boost::tuples::get<1>(qq); //qq.second;
00593   Storage_site_2 ssv2 = split_storage_site(ssitev, ss, false);
00594   v2->set_site( ssv2 );
00595 
00596   Face_handle qqf = boost::tuples::get<2>(qq); //qq.third;
00597   Vertex_handle vsx =
00598     this->_tds.insert_in_edge(qqf, cw(qqf->index(v1)));
00599 
00600   vsx->set_site(ss);
00601   // merge info of point and segment; the point lies on the segment
00602   merge_info(vsx, ssitev);
00603 
00604   return Vertex_triple(vsx, v1, v2);
00605 }
00606 
00607 template<class Gt, class ST, class D_S, class LTag>
00608 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_triple
00609 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00610 insert_point_on_segment(const Storage_site_2& ss, const Site_2& ,
00611                         Vertex_handle v, const Tag_true&)
00612 {
00613   // splits the segment site v->site() in two and inserts the point of
00614   // intersection of t and v->site()
00615   // on return the three vertices are, respectively, the point of
00616   // intersection and the two subsegments of v->site()
00617 
00618   Storage_site_2 ssitev = v->storage_site();
00619   Storage_site_2 ssx = st_.construct_storage_site_2_object()(ss, ssitev);
00620 
00621   Site_2 sitev = ssitev.site();
00622 
00623   Face_pair fpair = find_faces_to_split(v, ssx.site());
00624 
00625   boost::tuples::tuple<Vertex_handle,Vertex_handle,Face_handle,Face_handle>
00626     qq = this->_tds.split_vertex(v, fpair.first, fpair.second);
00627 
00628   // now I need to update the sites for vertices v1 and v2
00629   Vertex_handle v1 = boost::tuples::get<0>(qq); //qq.first;
00630   Vertex_handle v2 = boost::tuples::get<1>(qq); //qq.second;
00631 
00632   Storage_site_2 ssv1 =
00633     st_.construct_storage_site_2_object()(ssitev, ss, true);
00634 
00635   Storage_site_2 ssv2 =
00636     st_.construct_storage_site_2_object()(ssitev, ss, false);
00637 
00638   Site_2 sv1 = ssv1.site();
00639   Site_2 sv2 = ssv2.site();
00640   v1->set_site( ssv1 );
00641   v2->set_site( ssv2 );
00642 
00643   Face_handle qqf = boost::tuples::get<2>(qq); //qq.third;
00644   Vertex_handle vsx =
00645     this->_tds.insert_in_edge(qqf, cw(qqf->index(v1)));
00646 
00647   vsx->set_site(ssx);
00648 
00649   return Vertex_triple(vsx, v1, v2);
00650 }
00651 
00652 //--------------------------------------------------------------------
00653 // insertion of a segment
00654 //--------------------------------------------------------------------
00655 template<class Gt, class ST, class D_S, class LTag>
00656 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00657 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00658 insert_segment(const Storage_site_2& ss, const Site_2& t, Vertex_handle vnear)
00659 {
00660   CGAL_precondition( t.is_segment() );
00661   CGAL_precondition( t.is_input() );
00662 
00663   if ( is_degenerate_segment(t) ) {
00664     Storage_site_2 ss_src = ss.source_site();
00665     convert_info(ss_src, ss, true);
00666     return insert_point(ss_src, t.source(), vnear);
00667   }
00668 
00669   Storage_site_2 ss_src = ss.source_site();
00670   convert_info(ss_src, ss, true);
00671   Storage_site_2 ss_trg = ss.target_site();
00672   convert_info(ss_trg, ss, false);
00673 
00674   Vertex_handle v0 = insert_point( ss_src, t.source(), vnear );
00675   CGAL_assertion( is_valid() );
00676   Vertex_handle v1 = insert_point( ss_trg, t.target(), v0 );
00677   CGAL_assertion( is_valid() );
00678 
00679   if ( number_of_vertices() == 2 ) {
00680     return insert_third(ss, v0, v1);
00681   }
00682 
00683   return insert_segment_interior(t, ss, v0);
00684 }
00685 
00686 
00687 template<class Gt, class ST, class D_S, class LTag>
00688 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00689 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00690 insert_segment_interior(const Site_2& t, const Storage_site_2& ss,
00691                         Vertex_handle vnearest)
00692 {
00693   CGAL_precondition( t.is_segment() );
00694   CGAL_precondition( number_of_vertices() > 2 );
00695 
00696   CGAL_assertion( vnearest != Vertex_handle() );
00697 
00698   // find the first conflict
00699 
00700   // first look if there are intersections...
00701   Vertex_circulator vc = incident_vertices(vnearest);
00702   Vertex_circulator vc_start = vc;
00703   do {
00704     Vertex_handle vv(vc);
00705     if ( is_infinite(vv) ) {
00706       vc++;
00707       continue;
00708     }
00709 
00710     Arrangement_type at_res = arrangement_type(t, vv);
00711 
00712     if ( vv->is_segment() ) {
00713       if ( at_res == AT2::DISJOINT || at_res == AT2::TOUCH_1 ||
00714            at_res == AT2::TOUCH_2 || at_res == AT2::TOUCH_11 ||
00715            at_res == AT2::TOUCH_12 || at_res == AT2::TOUCH_21 ||
00716            at_res == AT2::TOUCH_22 ) {
00717         // do nothing
00718       } else if ( at_res == AT2::IDENTICAL ) {
00719         // merge info of identical items
00720         merge_info(vv, ss);
00721         return vv;
00722       } else if ( at_res == AT2::CROSSING ) {
00723         Intersections_tag itag;
00724         return insert_intersecting_segment(ss, t, vv, itag);
00725       } else if ( at_res == AT2::TOUCH_11_INTERIOR_1 ) {
00726         Vertex_handle vp = second_endpoint_of_segment(vv);      
00727         Storage_site_2 ssvp = vp->storage_site();
00728         Storage_site_2 sss = split_storage_site(ss, ssvp, false);
00729 
00730         Storage_site_2 sss1 = split_storage_site(ss, ssvp, true);
00731         // merge the info of the first (common) subsegment
00732         merge_info(vv, sss1);
00733         // merge the info of the (common) splitting endpoint
00734         merge_info(vp, ss);
00735 
00736         return insert_segment_interior(sss.site(), sss, vp);
00737       } else if ( at_res == AT2::TOUCH_12_INTERIOR_1 ) {
00738         Vertex_handle vp = first_endpoint_of_segment(vv);       
00739         Storage_site_2 ssvp = vp->storage_site();
00740         Storage_site_2 sss = split_storage_site(ss, ssvp, true);
00741 
00742         Storage_site_2 sss1 = split_storage_site(ss, ssvp, false);
00743         // merge the info of the second (common) subsegment
00744         //      merge_info(vv, sss);
00745         // merge the info of the (common) splitting endpoint
00746         merge_info(vp, ss);
00747 
00748         return insert_segment_interior(sss.site(), sss, vp);
00749       } else {
00750         // this should never be reached; the only possible values for
00751         // at_res are DISJOINT, CROSSING, TOUCH_11_INTERIOR_1
00752         // and TOUCH_12_INTERIOR_1
00753         CGAL_error();
00754       }
00755     } else {
00756       CGAL_assertion( vv->is_point() );
00757       if ( at_res == AT2::INTERIOR ) {
00758         Storage_site_2 ssvv = vv->storage_site();
00759         if ( ssvv.is_input() ) {
00760           Storage_site_2 ss1 = split_storage_site(ss, ssvv, true);
00761           Storage_site_2 ss2 = split_storage_site(ss, ssvv, false);
00762           // merge the info of the splitting point and the segment
00763           merge_info(vv, ss);
00764           insert_segment_interior(ss1.site(), ss1, vv);
00765           return insert_segment_interior(ss2.site(), ss2, vv);
00766         } else {
00767           // this should never be reached; the only possible values for
00768           // at_res are DISJOINT and INTERIOR
00769           CGAL_error();
00770         }
00771       }
00772     }
00773     ++vc;
00774   } while ( vc != vc_start );
00775 
00776   // first look for conflict with vertex
00777   Face_circulator fc_start = incident_faces(vnearest);
00778   Face_circulator fc = fc_start;
00779   Face_handle start_f;
00780   Sign s;
00781 
00782   std::map<Face_handle,Sign> sign_map;
00783 
00784   do {
00785     Face_handle f(fc);
00786 
00787     s = incircle(f, t);
00788 
00789     sign_map[f] = s;
00790 
00791     if ( s == NEGATIVE ) {
00792       start_f = f;
00793       break;
00794     }
00795     ++fc;
00796   } while ( fc != fc_start );
00797 
00798   // segments must have a conflict with at least one vertex
00799   CGAL_assertion( s == NEGATIVE );
00800 
00801   // we are in conflict with a Voronoi vertex; start from that and 
00802   // find the entire conflict region and then repair the diagram
00803   List l;
00804   Face_map fm;
00805 
00806   Triple<bool, Vertex_handle, Arrangement_type>
00807     vcross(false, Vertex_handle(), AT2::DISJOINT);
00808 
00809   // MK:: NEED TO WRITE A FUNCTION CALLED find_conflict_region WHICH
00810   // IS GIVEN A STARTING FACE, A LIST, A FACE MAP, A VERTEX MAP AND A
00811   // LIST OF FLIPPED EDGES AND WHAT IS DOES IS INITIALIZE THE CONFLICT 
00812   // REGION AND EXPANDS THE CONFLICT REGION.
00813   initialize_conflict_region(start_f, l);
00814   expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross);
00815 
00816   CGAL_assertion( vcross.third == AT2::DISJOINT ||
00817                   vcross.third == AT2::CROSSING ||
00818                   vcross.third == AT2::INTERIOR );
00819 
00820   // the following condition becomes true only if intersecting
00821   // segments are found
00822   if ( vcross.first ) {
00823     if ( t.is_segment() ) {
00824       if ( vcross.third == AT2::CROSSING ) {
00825         Intersections_tag itag;
00826         return insert_intersecting_segment(ss, t, vcross.second, itag);
00827       } else if ( vcross.third == AT2::INTERIOR ) {
00828         Storage_site_2 ssvv = vcross.second->storage_site();
00829         Storage_site_2 ss1 = split_storage_site(ss, ssvv, true);
00830         Storage_site_2 ss2 = split_storage_site(ss, ssvv, false);
00831         // merge the info of the splitting point and the segment
00832         merge_info(vcross.second, ss);
00833         insert_segment_interior(ss1.site(), ss1, vcross.second);
00834         return insert_segment_interior(ss2.site(), ss2, vcross.second);
00835       } else {
00836         // this should never be reached; the only possible values for
00837         // vcross.third are CROSSING, INTERIOR and DISJOINT
00838         CGAL_error();
00839       }
00840     }
00841   }
00842 
00843   // no intersecting segment has been found; we insert the segment as
00844   // usual...
00845   Vertex_handle v = create_vertex(ss);
00846 
00847   retriangulate_conflict_region(v, l, fm);
00848 
00849   return v;
00850 }
00851 
00852 
00853 //--------------------------------------------------------------------
00854 // insertion of an intersecting segment
00855 //--------------------------------------------------------------------
00856 template<class Gt, class ST, class D_S, class LTag>
00857 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00858 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00859 insert_intersecting_segment_with_tag(const Storage_site_2& /* ss */,
00860                                      const Site_2& /* t */, Vertex_handle /* v */,
00861                                      Tag_false)
00862 {
00863 #if defined(__POWERPC__) && \
00864   defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ == 4)
00865   // hack to avoid nasty warning for G++ 3.4 on Darwin
00866   static int i;
00867 #else
00868   static int i = 0;
00869 #endif
00870   if ( i == 0 ) {
00871     i = 1;
00872     print_error_message();
00873   }
00874   return Vertex_handle();
00875 }
00876 
00877 template<class Gt, class ST, class D_S, class LTag>
00878 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
00879 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00880 insert_intersecting_segment_with_tag(const Storage_site_2& ss,
00881                                      const Site_2& t, Vertex_handle v,
00882                                      Tag_true tag)
00883 {
00884   CGAL_precondition( t.is_segment() && v->is_segment() );
00885 
00886   const Storage_site_2& ssitev = v->storage_site();
00887   Site_2 sitev = ssitev.site();
00888 
00889   if ( same_segments(t, sitev) ) {
00890     merge_info(v, ss);
00891     return v;
00892   }
00893 
00894   Vertex_triple vt = insert_point_on_segment(ss, t, v, tag);
00895 
00896   Vertex_handle vsx = vt.first;
00897   
00898   Storage_site_2 ss3 = st_.construct_storage_site_2_object()(ss, ssitev, true);
00899   Storage_site_2 ss4 = st_.construct_storage_site_2_object()(ss, ssitev, false);
00900   Site_2 s3 = ss3.site();
00901   Site_2 s4 = ss4.site();
00902 
00903   insert_segment_interior(s3, ss3, vsx);
00904   insert_segment_interior(s4, ss4, vsx);
00905   return vsx;
00906 }
00907 
00908 //--------------------------------------------------------------------
00909 //--------------------------------------------------------------------
00910 // helper methods for insertion (find conflict region)
00911 //--------------------------------------------------------------------
00912 //--------------------------------------------------------------------
00913 
00914 template<class Gt, class ST, class D_S, class LTag>
00915 void
00916 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00917 initialize_conflict_region(const Face_handle& f, List& l)
00918 {
00919 
00920 
00921   l.clear();
00922   for (int i = 0; i < 3; i++) {
00923     l.push_back(sym_edge(f, i));
00924   }
00925 }
00926 
00927 
00928 template<class Gt, class ST, class D_S, class LTag>
00929 void
00930 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
00931 expand_conflict_region(const Face_handle& f, const Site_2& t,
00932                        const Storage_site_2& ss,
00933                        List& l, Face_map& fm,
00934                        std::map<Face_handle,Sign>& sign_map,
00935                        Triple<bool,Vertex_handle,Arrangement_type>& vcross)
00936 {
00937   if ( fm.find(f) != fm.end() ) { return; }
00938 
00939   // this is done to stop the recursion when intersecting segments
00940   // are found
00941   if ( vcross.first ) { return; }
00942 
00943   // setting fm[f] to true means that the face has been reached and
00944   // that the face is available for recycling. If we do not want the
00945   // face to be available for recycling we must set this flag to
00946   // false.
00947   fm[f] = true;
00948 
00949   //  CGAL_assertion( fm.find(f) != fm.end() );
00950 
00951   for (int i = 0; i < 3; i++) {
00952     Face_handle n = f->neighbor(i);
00953 
00954     bool face_registered = (fm.find(n) != fm.end());
00955 
00956     if ( !face_registered ) {
00957       for (int j = 0; j < 3; j++) {
00958         Vertex_handle vf = n->vertex(j);
00959 
00960         if ( is_infinite(vf) ) { continue; }
00961 
00962         Arrangement_type at_res = arrangement_type(t, vf);
00963 
00964         CGAL_assertion( vcross.third == AT2::DISJOINT ||
00965                         vcross.third == AT2::CROSSING ||
00966                         vcross.third == AT2::INTERIOR );
00967 
00968         if ( vf->is_segment() ) {
00969           CGAL_assertion( at_res != AT2::IDENTICAL );
00970           CGAL_assertion( at_res != AT2::TOUCH_11_INTERIOR_1 );
00971           CGAL_assertion( at_res != AT2::TOUCH_12_INTERIOR_1 );
00972 
00973           if ( at_res == AT2::CROSSING ) {
00974             vcross.first = true;
00975             vcross.second = vf;
00976             vcross.third = AT2::CROSSING;
00977             l.clear();
00978             fm.clear();
00979             return;
00980           } else {
00981             CGAL_assertion ( at_res == AT2::DISJOINT ||
00982                              at_res == AT2::TOUCH_1 ||
00983                              at_res == AT2::TOUCH_2 ||
00984                              at_res == AT2::TOUCH_11 ||
00985                              at_res == AT2::TOUCH_12 ||
00986                              at_res == AT2::TOUCH_21 ||
00987                              at_res == AT2::TOUCH_22 );
00988             // we do nothing in these cases
00989           }
00990         } else {
00991           CGAL_assertion( vf->is_point() );
00992           if ( at_res == AT2::INTERIOR ) {
00993             vcross.first = true;
00994             vcross.second = vf;
00995             vcross.third = AT2::INTERIOR;
00996             l.clear();
00997             fm.clear();
00998             return;
00999           }
01000         }
01001       }
01002     }
01003 
01004     Sign s = incircle(n, t);
01005 
01006     sign_map[n] = s;
01007 
01008     Sign s_f = sign_map[f];
01009 
01010     if ( s == POSITIVE ) { continue; }
01011     if ( s != s_f ) { continue; }
01012 
01013     bool interior_in_conflict = edge_interior(f, i, t, s);
01014 
01015     if ( !interior_in_conflict ) { continue; }
01016 
01017     if ( face_registered ) { continue; }
01018 
01019     Edge e = sym_edge(f, i);
01020 
01021     CGAL_assertion( l.is_in_list(e) );
01022     int j = this->_tds.mirror_index(f, i);
01023     Edge e_before = sym_edge(n, ccw(j));
01024     Edge e_after = sym_edge(n, cw(j));
01025     if ( !l.is_in_list(e_before) ) {
01026       l.insert_before(e, e_before);
01027     }
01028     if ( !l.is_in_list(e_after) ) {
01029       l.insert_after(e, e_after);
01030     }
01031     l.remove(e);
01032 
01033     expand_conflict_region(n, t, ss, l, fm, sign_map, vcross);
01034 
01035     // this is done to stop the recursion when intersecting segments
01036     // are found
01037     //    if ( fm.size() == 0 && l.size() == 0 ) { return; }
01038     if ( vcross.first ) { return; }
01039   } // for-loop
01040 }
01041 
01042 
01043 //--------------------------------------------------------------------
01044 // retriangulate conflict region
01045 //--------------------------------------------------------------------
01046 
01047 template<class Gt, class ST, class D_S, class LTag>
01048 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
01049 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01050 add_bogus_vertex(Edge e, List& l)
01051 {
01052   Edge esym = sym_edge(e);
01053   Face_handle g1 = e.first;
01054   Face_handle g2 = esym.first;
01055 
01056   Vertex_handle v = insert_degree_2(e);
01057 
01058   Face_circulator fc(v);
01059   Face_handle f1(fc);
01060   Face_handle f2(++fc);
01061   int i1 = f1->index(v);
01062   int i2 = f2->index(v);
01063 
01064   CGAL_assertion( ((f1->neighbor(i1) == g1) && (f2->neighbor(i2) == g2)) ||
01065                   ((f1->neighbor(i1) == g2) && (f2->neighbor(i2) == g1)) );
01066 
01067   Edge ee, eesym;
01068   if ( f1->neighbor(i1) == g1 ) {
01069     ee = Edge(f2, i2);
01070     eesym = Edge(f1, i1);
01071   } else {
01072     ee = Edge(f1, i1);
01073     eesym = Edge(f2, i2);
01074   }
01075 
01076   l.replace(e, ee);
01077   l.replace(esym, eesym);
01078 
01079   return v;
01080 }
01081 
01082 
01083 template<class Gt, class ST, class D_S, class LTag>
01084 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_list
01085 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01086 add_bogus_vertices(List& l)
01087 {
01088   Vertex_list vertex_list;
01089 
01090   std::set<Edge> edge_list;
01091 
01092   edge_list.clear();
01093 
01094   Edge e_start = l.front();
01095   Edge e = e_start;
01096 
01097   do {
01098     Edge esym = sym_edge(e);
01099     if ( l.is_in_list(esym) &&
01100          edge_list.find(esym) == edge_list.end() ) {
01101       edge_list.insert(e);
01102     }
01103     e = l.next(e);
01104   } while ( e != e_start );
01105 
01106   typename std::set<Edge>::iterator it;
01107 
01108   for (it = edge_list.begin();  it != edge_list.end(); ++it) {
01109     Vertex_handle v = add_bogus_vertex(*it, l);
01110     vertex_list.push_back(v);
01111   }
01112 
01113   return vertex_list;
01114 }
01115 
01116 template<class Gt, class ST, class D_S, class LTag>
01117 void
01118 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01119 remove_bogus_vertices(Vertex_list& vl)
01120 {
01121   while ( vl.size() > 0 ) {
01122     Vertex_handle v = vl.front();
01123     vl.pop_front();
01124     remove_degree_2(v);
01125   }
01126 }
01127 
01128 
01129 template<class Gt, class ST, class D_S, class LTag>
01130 void
01131 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01132 retriangulate_conflict_region(Vertex_handle v, List& l, 
01133                               Face_map& fm)
01134 {
01135   // 1. add the bogus vetrices
01136   Vertex_list dummy_vertices = add_bogus_vertices(l);
01137 
01138   // 2. repair the face pointers...
01139   Edge e_start = l.front();
01140   Edge eit = e_start;
01141   do {
01142     Edge esym = sym_edge(eit);
01143     Face_handle f = eit.first;
01144     int k = eit.second;
01145     CGAL_assertion( !l.is_in_list(esym) );
01146     CGAL_assertion( fm.find(f) == fm.end() );
01147     f->vertex(ccw(k))->set_face(f);
01148     f->vertex( cw(k))->set_face(f);
01149     eit = l.next(eit);
01150   } while ( eit != e_start );
01151 
01152   // 3. copy the edge list to a vector of edges and clear the edge list
01153   std::vector<Edge> ve;
01154 
01155   Edge efront = l.front();
01156   Edge e = efront;
01157   do {
01158     ve.push_back(e);
01159     e = l.next(e);
01160   } while ( e != efront );
01161 
01162   l.clear();
01163 
01164   // 4. retriangulate the hole
01165   this->_tds.star_hole(v, ve.begin(), ve.end());
01166 
01167   // 5. remove the bogus vertices
01168   remove_bogus_vertices(dummy_vertices);
01169 
01170   // 6. remove the unused faces
01171   typename Face_map::iterator it;
01172   for (it = fm.begin(); it != fm.end(); ++it) {
01173     Face_handle fh = (*it).first;
01174     this->_tds.delete_face(fh);
01175   }
01176 
01177   fm.clear();
01178 
01179   // 7. DONE!!!!
01180 }
01181 
01182 //====================================================================
01183 //====================================================================
01184 //                   METHODS FOR REMOVAL
01185 //====================================================================
01186 //====================================================================
01187 
01188 template<class Gt, class ST, class D_S, class LTag>
01189 bool
01190 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01191 is_star(const Vertex_handle& v) const
01192 {
01193   CGAL_precondition( v->storage_site().is_point() );
01194 
01195   Vertex_circulator vc_start = incident_vertices(v);
01196   Vertex_circulator vc = vc_start;
01197   Storage_site_2 p = v->storage_site();
01198 
01199   size_type count = 0;
01200   do {
01201     Storage_site_2 ss = vc->storage_site();
01202     if ( ss.is_segment() && is_endpoint_of_segment(p, ss) ) {
01203       ++count;
01204       //      if ( count == 3 ) { break; }
01205       if ( count == 3 ) { return true; }
01206     }
01207     ++vc;
01208   } while ( vc != vc_start );
01209 
01210   return false;
01211 }
01212 
01213 
01214 template<class Gt, class ST, class D_S, class LTag>
01215 bool
01216 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01217 is_linear_chain(const Vertex_handle& v0, const Vertex_handle& v1,
01218                 const Vertex_handle& v2) const
01219 {
01220   Site_2 tt[3] = { v0->site(), v1->site(), v2->site() };
01221 
01222   if ( tt[1].is_point() &&
01223        tt[0].is_segment() &&
01224        tt[2].is_segment() &&
01225        is_endpoint_of_segment(tt[1], tt[0]) &&
01226        is_endpoint_of_segment(tt[1], tt[2]) ) {
01227     typename Geom_traits::Equal_2 are_equal = geom_traits().equal_2_object();
01228     Site_2 s_end[2];
01229     if (  are_equal( tt[1], tt[0].source_site() )  ) {
01230       s_end[0] = tt[0].target_site();
01231     } else {
01232       s_end[0] = tt[0].source_site();
01233     }
01234 
01235     if (  are_equal( tt[1], tt[2].source_site() )  ) {
01236       s_end[1] = tt[2].target_site();
01237     } else {
01238       s_end[1] = tt[2].source_site();
01239     }
01240 
01241     typename Geom_traits::Orientation_2 orientation =
01242       geom_traits().orientation_2_object();
01243 
01244     return orientation(s_end[0], s_end[1], tt[1]) == COLLINEAR;
01245   }
01246   return false;
01247 }
01248 
01249 
01250 template<class Gt, class ST, class D_S, class LTag>
01251 bool
01252 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01253 is_flippable(const Face_handle& f, int i) const
01254 {
01255   CGAL_assertion( !is_infinite(f->vertex( cw(i) )) );
01256 
01257   Vertex_handle v_other = f->vertex( ccw(i) );
01258   Vertex_handle v0 = f->vertex( i );
01259   Vertex_handle v1 = this->_tds.mirror_vertex( f, i );
01260 
01261   if ( is_infinite(v_other) || is_infinite(v0) || is_infinite(v1) ) {
01262     return false;
01263   }
01264 
01265   Vertex_handle v = f->vertex( cw(i) );
01266 
01267   Storage_site_2 ss = v->storage_site();
01268   Storage_site_2 ss_other = v_other->storage_site();
01269   if ( ss_other.is_point() && ss.is_segment() &&
01270        is_endpoint_of_segment(ss_other, ss) && is_star(v_other) ) {
01271     return false;
01272   }
01273 
01274   if ( is_linear_chain(v0, v_other, v1) ) { return false; }
01275 
01276   return (v0 != v1) && is_degenerate_edge(f, i);
01277 }
01278 
01279 
01280 template<class Gt, class ST, class D_S, class LTag>
01281 void
01282 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01283 minimize_degree(const Vertex_handle& v)
01284 {
01285   CGAL_precondition ( degree(v) > 3 );
01286 
01287   Face_circulator fc_start = incident_faces(v);
01288   Face_circulator fc = incident_faces(v);
01289   bool found(false);
01290   do {
01291     Face_handle f = Face_handle(fc);
01292     int i = ccw( f->index(v) );
01293 
01294     CGAL_assertion( f->vertex( cw(i) ) == v );
01295 
01296     if ( is_flippable(f,i) ) {
01297       Edge e = flip(f, i);
01298       f = e.first;
01299 
01300       if ( !f->has_vertex(v) ) {
01301         f = e.first->neighbor(e.second);
01302         CGAL_assertion( f->has_vertex(v) );
01303       }
01304 
01305       fc = --( incident_faces(v,f) );
01306       fc_start = fc;
01307       found = true;
01308     } else {
01309       ++fc;
01310       found = false;
01311     }
01312   } while ( found || fc != fc_start );
01313 }
01314 
01315 template<class Gt, class ST, class D_S, class LTag>
01316 void
01317 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01318 equalize_degrees(const Vertex_handle& v, Self& small_d,
01319                  std::map<Vertex_handle,Vertex_handle>& vmap,
01320                  List& l) const
01321 {
01322   size_type deg = degree(v);
01323   CGAL_assertion( l.size() <= deg );
01324   if ( l.size() == deg ) { return; }
01325 #if 0
01326   std::cerr << "size of l  : " << l.size() << std::endl;
01327   std::cerr << "degree of v: " << deg << std::endl;
01328 #endif
01329 
01330   //  typedef std::map<Edge,Edge>  Edge_map;
01331   // maps edges on the boundary of the conflict region from the small
01332   // diagram to edges of the star of v in the small diagram
01333   //  Edge_map emap;
01334 
01335   Edge e_small_start = l.front();
01336   Edge e_small = e_small_start;
01337   bool found;
01338   Edge e_small_begin;
01339   Edge e_large_begin;
01340   do {
01341     found = false;
01342     Vertex_handle v_sml_src = e_small.first->vertex(cw(e_small.second));
01343     Vertex_handle v_sml_trg = e_small.first->vertex(ccw(e_small.second));
01344 
01345     // first we find a first edge in common
01346     Face_circulator fc_start = incident_faces(v);
01347     Face_circulator fc = fc_start;
01348 
01349     do {
01350       int id = fc->index(v);
01351       Vertex_handle v_lrg_src = fc->vertex(ccw(id));
01352       Vertex_handle v_lrg_trg = fc->vertex(cw(id));
01353       if ( vmap[v_sml_src] == v_lrg_src && vmap[v_sml_trg] == v_lrg_trg ) {
01354         found = true;
01355         e_large_begin = Edge(fc, id);
01356         e_small_begin = e_small;
01357         break;
01358       }
01359     } while ( ++fc != fc_start );
01360     if ( found ) { break; }
01361     e_small = l.next(e_small);
01362   } while ( e_small != e_small_start );
01363 
01364   CGAL_assertion( found );
01365 
01366   Face_circulator fc_start = incident_faces(v, e_large_begin.first);
01367   Face_circulator fc = fc_start;
01368   e_small = e_small_begin;
01369   do {
01370     int id = fc->index(v);
01371     Vertex_handle vsml_src = e_small.first->vertex(cw(e_small.second));
01372     Vertex_handle vsml_trg = e_small.first->vertex(ccw(e_small.second));
01373     Vertex_handle vlrg_src = fc->vertex(ccw(id));
01374     Vertex_handle vlrg_trg = fc->vertex(cw(id));
01375     if ( vmap[vsml_src] != vlrg_src || vmap[vsml_trg] != vlrg_trg ) {
01376       Edge e_small_prev = l.previous(e_small);
01377       std::cerr << "size of l: " << l.size() << std::endl;
01378       l.remove(e_small);
01379 
01380       std::cerr << "size of l: " << l.size() << std::endl;
01381 
01382       Edge e_small_new = small_d.flip(e_small);
01383       Edge e_small_new_sym = small_d.sym_edge(e_small_new);
01384       Face_handle f1 = e_small_new.first;
01385       Face_handle f2 = e_small_new_sym.first;
01386 
01387       if ( f2->vertex(e_small_new_sym.second) == vsml_src ) {
01388         std::swap(f1, f2);
01389         std::swap(e_small_new, e_small_new_sym);
01390         CGAL_assertion( f1->vertex(e_small_new.second) == vsml_src );
01391         CGAL_assertion( f2->vertex(e_small_new_sym.second) == vsml_trg );
01392       }
01393 
01394       Edge to_list1(f1, cw(e_small_new.second));
01395       Edge to_list2(f2, ccw(e_small_new_sym.second));
01396 
01397       e_small = small_d.sym_edge(to_list1);
01398 
01399       l.insert_after(e_small_prev, e_small);
01400       std::cerr << "size of l: " << l.size() << std::endl;
01401       l.insert_after(e_small, small_d.sym_edge(to_list2));
01402       std::cerr << "size of l: " << l.size() << std::endl;
01403     } else {
01404       e_small = l.next(e_small);
01405       ++fc;
01406     }
01407     CGAL_assertion( l.size() <= deg );
01408   } while ( fc != fc_start );
01409 
01410 #if 0
01411   std::cerr << "size of l  : " << l.size() << std::endl;
01412   std::cerr << "degree of v: " << deg << std::endl;
01413 #endif
01414 
01415 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG)  
01416   // we go around the boundary of the conflict region verify that all
01417   // edges are there
01418   CGAL_assertion( l.size() == degree(v) );
01419   e_small = e_small_begin;
01420   fc_start = incident_faces(v, e_large_begin.first);
01421   fc = fc_start;
01422   do {
01423     int id = fc->index(v);
01424     Vertex_handle vsml_src = e_small.first->vertex(cw(e_small.second));
01425     Vertex_handle vsml_trg = e_small.first->vertex(ccw(e_small.second));
01426     Vertex_handle vlrg_src = fc->vertex(ccw(id));
01427     Vertex_handle vlrg_trg = fc->vertex(cw(id));
01428     CGAL_assertion(vmap[vsml_src] == vlrg_src && vmap[vsml_trg] == vlrg_trg );
01429 
01430     // go to next edge
01431     e_small = l.next(e_small);
01432   } while ( ++fc != fc_start );
01433 #endif
01434 }
01435 
01436 template<class Gt, class ST, class D_S, class LTag>
01437 void
01438 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01439 expand_conflict_region_remove(const Face_handle& f, const Site_2& t,
01440                               const Storage_site_2& ss,
01441                               List& l, Face_map& fm, Sign_map& sign_map)
01442 {
01443   if ( fm.find(f) != fm.end() ) { return; }
01444 
01445   // setting fm[f] to true means that the face has been reached and
01446   // that the face is available for recycling. If we do not want the
01447   // face to be available for recycling we must set this flag to
01448   // false.
01449   fm[f] = true;
01450 
01451   //  CGAL_assertion( fm.find(f) != fm.end() );
01452 
01453   for (int i = 0; i < 3; i++) {
01454     Face_handle n = f->neighbor(i);
01455 
01456     bool face_registered = (fm.find(n) != fm.end());
01457 
01458     Sign s = incircle(n, t);
01459 
01460     sign_map[n] = s;
01461 
01462     Sign s_f = sign_map[f];
01463 
01464     if ( s == POSITIVE ) { continue; }
01465     if ( s != s_f ) { continue; }
01466 
01467     bool interior_in_conflict = edge_interior(f, i, t, s);
01468 
01469     if ( !interior_in_conflict ) { continue; }
01470 
01471     if ( face_registered ) { continue; }
01472 
01473     Edge e = sym_edge(f, i);
01474 
01475     CGAL_assertion( l.is_in_list(e) );
01476     int j = this->_tds.mirror_index(f, i);
01477     Edge e_before = sym_edge(n, ccw(j));
01478     Edge e_after = sym_edge(n, cw(j));
01479     if ( !l.is_in_list(e_before) ) {
01480       l.insert_before(e, e_before);
01481     }
01482     if ( !l.is_in_list(e_after) ) {
01483       l.insert_after(e, e_after);
01484     }
01485     l.remove(e);
01486 
01487     expand_conflict_region_remove(n, t, ss, l, fm, sign_map);
01488   } // for-loop
01489 }
01490 
01491 
01492 template<class Gt, class ST, class D_S, class LTag>
01493 void
01494 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01495 find_conflict_region_remove(const Vertex_handle& v,
01496                             const Vertex_handle& vnearest,
01497                             List& l, Face_map& fm, Sign_map&)
01498 {
01499   CGAL_precondition( vnearest != Vertex_handle() );
01500   Storage_site_2 ss = v->storage_site();
01501   Site_2 t = ss.site();
01502 
01503   // find the first conflict
01504 
01505   // first look for conflict with vertex
01506   Face_circulator fc_start = incident_faces(vnearest);
01507   Face_circulator fc = fc_start;
01508   Face_handle start_f;
01509   Sign s;
01510 
01511   Sign_map sign_map;
01512 
01513   do {
01514     Face_handle f(fc);
01515 
01516     s = incircle(f, t);
01517 
01518     sign_map[f] = s;
01519 
01520     if ( s == NEGATIVE ) {
01521       start_f = f;
01522       break;
01523     }
01524     ++fc;
01525   } while ( fc != fc_start );
01526 
01527   CGAL_assertion( s == NEGATIVE );
01528 
01529   // we are not in conflict with a Voronoi vertex, so we have to
01530   // be in conflict with the interior of a Voronoi edge
01531   if ( s != NEGATIVE ) {
01532     Edge_circulator ec_start = incident_edges(vnearest);
01533     Edge_circulator ec = ec_start;
01534 
01535     bool interior_in_conflict(false);
01536     Edge e;
01537     do {
01538       e = *ec;
01539 
01540       Sign s1 = sign_map[e.first];
01541       Sign s2 = sign_map[e.first->neighbor(e.second)];
01542 
01543       if ( s1 == s2 ) {
01544         interior_in_conflict = edge_interior(e, t, s1);
01545       } else {
01546         // It seems that there was a problem here when one of the
01547         // signs was positive and the other zero. In this case we
01548         // still check pretending that both signs where positive
01549         interior_in_conflict = edge_interior(e, t, POSITIVE);
01550       }
01551 
01552       if ( interior_in_conflict ) { break; }
01553       ++ec;
01554     } while ( ec != ec_start );
01555 
01556     sign_map.clear();
01557 
01558     CGAL_assertion( interior_in_conflict );
01559 
01560     l.push_back(e);
01561     l.push_back(sym_edge(e));
01562     return;
01563   }
01564 
01565   initialize_conflict_region(start_f, l);
01566   expand_conflict_region_remove(start_f, t, ss, l, fm, sign_map);
01567 }
01568 
01569 
01570 //--------------------------------------------------------------------
01571 //--------------------------------------------------------------------
01572 
01573 template<class Gt, class ST, class D_S, class LTag>
01574 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::size_type
01575 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01576 count_faces(const List& l) const
01577 {
01578   std::vector<Face_handle> flist;
01579   get_faces(l, std::back_inserter(flist));
01580   return flist.size();
01581 }
01582 
01583 //--------------------------------------------------------------------
01584 //--------------------------------------------------------------------
01585 
01586 template<class Gt, class ST, class D_S, class LTag>
01587 void
01588 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01589 fill_hole(const Self& small_d, const Vertex_handle& v, const List& l,
01590           std::map<Vertex_handle,Vertex_handle>& vmap)
01591 {
01592 #if 0
01593   std::cerr << "size of l  : " << l.size() << std::endl;
01594   std::cerr << "degree of v: " << degree(v) << std::endl;
01595 #endif
01596 
01597   typedef std::map<Edge,Edge>  Edge_map;
01598   // maps edges on the boundary of the conflict region from the small
01599   // diagram to edges of the star of v in the small diagram
01600   Edge_map emap;
01601 
01602   Edge e_sml_sym = sym_edge(l.front());
01603 
01604   Vertex_handle v_sml_src = e_sml_sym.first->vertex(ccw(e_sml_sym.second));
01605   Vertex_handle v_sml_trg = e_sml_sym.first->vertex(cw(e_sml_sym.second));
01606 
01607   // first we find a first edge in common
01608   Face_circulator fc_start = incident_faces(v);
01609   Face_circulator fc = fc_start;
01610   Face_circulator fc_begin;
01611   bool found = false;
01612   do {
01613     int id = fc->index(v);
01614     Vertex_handle v_lrg_src = fc->vertex(ccw(id));
01615     Vertex_handle v_lrg_trg = fc->vertex(cw(id));
01616     if ( vmap[v_sml_src] == v_lrg_src && vmap[v_sml_trg] == v_lrg_trg ) {
01617       found = true;
01618       fc_begin = fc;
01619       break;
01620     }
01621   } while ( ++fc != fc_start );
01622   CGAL_assertion( found );
01623 
01624   // container of faces to delete
01625   std::list<Face_handle> to_delete;
01626 
01627   // next we go around the boundary of the conflict region and map all edges
01628   Edge e_small = l.front();
01629   fc_start = incident_faces(v, fc_begin);
01630   fc = fc_start;
01631   do {
01632     int id = fc->index(v);
01633 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG)
01634     Vertex_handle vsml_src = e_small.first->vertex(cw(e_small.second));
01635     Vertex_handle vsml_trg = e_small.first->vertex(ccw(e_small.second));
01636     Vertex_handle vlrg_src = fc->vertex(ccw(id));
01637     Vertex_handle vlrg_trg = fc->vertex(cw(id));
01638     CGAL_assertion(vmap[vsml_src] == vlrg_src && vmap[vsml_trg] == vlrg_trg );
01639 #endif
01640     // set mapping
01641     emap[e_small] = sym_edge(fc, id);
01642     // keep face for deletion
01643     to_delete.push_back(fc);
01644     // go to next edge
01645     e_small = l.next(e_small);
01646   } while ( ++fc != fc_start );
01647 
01648 
01649   // map the faces of the small diagram with the new faces of the
01650   // large diagram
01651   std::map<Face_handle,Face_handle> fmap;
01652   std::vector<Face_handle> f_small, f_large;
01653 
01654   small_d.get_faces(l, std::back_inserter(f_small));
01655   for (unsigned int i = 0; i < f_small.size(); i++) {
01656     Face_handle f = this->_tds.create_face();
01657     fmap[ f_small[i] ] = f;
01658     f_large.push_back(f);
01659   }
01660 
01661   CGAL_assertion( l.size() == degree(v) );
01662   CGAL_assertion( f_small.size() == f_large.size() );
01663   CGAL_assertion( f_small.size() == l.size() - 2 );
01664   CGAL_assertion( f_small.size() == count_faces(l) );
01665 
01666   // set the vertices for the new faces; also set the face for each
01667   // vertex
01668   for (typename std::vector<Face_handle>::iterator fit = f_small.begin();
01669        fit != f_small.end(); ++fit) {
01670     Face_handle ff_small = *fit;
01671     Face_handle f = fmap[ff_small];
01672 
01673     for (int i = 0; i < 3; ++i) {
01674       CGAL_assertion( vmap.find(ff_small->vertex(i)) != vmap.end() );
01675       f->set_vertex(i, vmap[ff_small->vertex(i)]);
01676       // we are setting the face for each vertex a lot of times; we
01677       // could possibly do it faster if we use the edges on the
01678       // boundary of the conflict region
01679       // in fact we may not even need it since the make_hole method
01680       // updates the faces of the vertices of the boundary of the
01681       // hole, and we do not introduce any new vertices
01682       f->vertex(i)->set_face(f);
01683     }
01684   }
01685 
01686   // set the neighbors for each face
01687   for (typename std::vector<Face_handle>::iterator fit = f_small.begin();
01688        fit != f_small.end(); ++fit) {
01689     Face_handle ff_small = *fit;
01690 
01691     for (int i = 0; i < 3; i++) {
01692       Face_handle f = fmap[ff_small];
01693       Face_handle n_small = ff_small->neighbor(i);
01694       if ( fmap.find(n_small) != fmap.end() ) {
01695         // this is one of the new faces
01696         f->set_neighbor(i, fmap[n_small]);
01697       } else {
01698         // otherwise it is one of the old faces outside the conflict
01699         // region; we have to use the edge map in this case
01700         Edge e_small_sym = small_d.sym_edge(ff_small, i);
01701         CGAL_assertion(emap.find(e_small_sym) != emap.end());
01702 
01703         Edge e_large = emap[e_small_sym];
01704         f->set_neighbor(i, e_large.first);
01705         e_large.first->set_neighbor(e_large.second, f);
01706       }
01707     }
01708   }
01709 
01710   // delete the unused faces and the vertex
01711   while ( !to_delete.empty() ) {
01712     delete_face(to_delete.front());
01713     to_delete.pop_front();
01714   }
01715   delete_vertex(v);
01716 }
01717 
01718 //--------------------------------------------------------------------
01719 //--------------------------------------------------------------------
01720 
01721 template<class Gt, class ST, class D_S, class LTag>
01722 bool
01723 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01724 remove_first(const Vertex_handle& v)
01725 {
01726   Delaunay_graph::remove_first(v);
01727   return true;
01728 }
01729 
01730 template<class Gt, class ST, class D_S, class LTag>
01731 bool
01732 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01733 remove_second(const Vertex_handle& v)
01734 {
01735   Delaunay_graph::remove_second(v);
01736   return true;
01737 }
01738 
01739 template<class Gt, class ST, class D_S, class LTag>
01740 bool
01741 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01742 remove_third(const Vertex_handle& v)
01743 {
01744   if ( is_degree_2(v) ) {
01745     CGAL_assertion( v->storage_site().is_point() );
01746     Face_handle fh( incident_faces(v) );
01747     int i = fh->index(v);
01748     flip(fh, i);
01749   } else if ( degree(v) == 4 ) {
01750     Edge_circulator ec = incident_edges(v);
01751     for (int i = 0; i < 4; i++) {
01752       Edge e = *ec;
01753       Edge sym = sym_edge(e);
01754       if ( e.first->vertex(e.second) != sym.first->vertex(sym.second) ) {
01755         flip(e);
01756         break;
01757       }
01758       ++ec;
01759     }
01760   }
01761 
01762   this->_tds.remove_dim_down( v );
01763   return true;
01764 }
01765 
01766 //--------------------------------------------------------------------
01767 //--------------------------------------------------------------------
01768 
01769 template<class Gt, class ST, class D_S, class LTag>
01770 void
01771 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01772 compute_small_diagram(const Vertex_handle& v, Self& small_d) const
01773 {
01774   Vertex_circulator vc_start = incident_vertices(v);
01775   Vertex_circulator vc = vc_start;
01776 
01777   // insert all neighboring sites
01778   do {
01779     if ( !is_infinite(vc) ) {
01780       Site_2 t = vc->site();
01781       if ( t.is_input() ) {
01782         small_d.insert(t);
01783       } else if ( t.is_point() ) {
01784         small_d.insert(t.supporting_site(0));
01785         /*Vertex_handle vnear =*/ small_d.insert(t.supporting_site(1));
01786         //      vh_small = sdg_small.nearest_neighbor(t, vnear);
01787       } else {
01788         CGAL_assertion( t.is_segment() );
01789         /*Vertex_handle vnear =*/ small_d.insert(t.supporting_site());
01790         //      vh_small = sdg_small.nearest_neighbor(t, vnear);
01791       }
01792       //      CGAL_assertion( vh_small != Vertex_handle() );
01793       //      vmap[vh_small] = vh_large;
01794     }
01795     ++vc;
01796   } while ( vc != vc_start );
01797 }
01798 
01799 //--------------------------------------------------------------------
01800 //--------------------------------------------------------------------
01801 
01802 template<class Gt, class ST, class D_S, class LTag>
01803 void
01804 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01805 compute_vertex_map(const Vertex_handle& v, const Self& small_d,
01806                    std::map<Vertex_handle,Vertex_handle>& vmap) const
01807 {
01808   Vertex_circulator vc_start = incident_vertices(v);
01809   Vertex_circulator vc = vc_start;
01810   Vertex_handle vh_large, vh_small;
01811 
01812   do {
01813     vh_large = Vertex_handle(vc);
01814     if ( is_infinite(vh_large) ) {
01815       vh_small = small_d.infinite_vertex();
01816       vmap[vh_small] = vh_large;
01817     } else { 
01818 #if !defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG)
01819       vh_small = Vertex_handle();
01820 #endif
01821       Site_2 t = vc->site();
01822       if ( t.is_input() ) {
01823         if ( t.is_segment() ) {
01824           Vertex_handle vv = small_d.nearest_neighbor( t.source() );
01825           Vertex_circulator vvc_start = small_d.incident_vertices(vv);
01826           Vertex_circulator vvc = vvc_start;
01827           do {
01828             if ( small_d.same_segments(t, vvc) ) {
01829               vh_small = vvc;
01830               break;
01831             }
01832           } while ( ++vvc != vvc_start );
01833           CGAL_assertion( small_d.same_segments(t, vh_small) );
01834         } else {
01835           CGAL_assertion( t.is_point() );
01836           vh_small = small_d.nearest_neighbor( t.point() );
01837           CGAL_assertion( small_d.same_points(t, vh_small->site()) );
01838         }
01839       } else if ( t.is_segment() ) {
01840         Vertex_handle vv =
01841           small_d.nearest_neighbor( t.source_site(), Vertex_handle() );
01842         Vertex_circulator vvc_start = small_d.incident_vertices(vv);
01843         Vertex_circulator vvc = vvc_start;
01844         do {
01845           if ( small_d.same_segments(t, vvc) ) {
01846             vh_small = vvc;
01847             break;
01848           }
01849         } while ( ++vvc != vvc_start );
01850         CGAL_assertion( small_d.same_segments(t, vh_small) );
01851       } else {
01852         CGAL_assertion( t.is_point() );
01853         vh_small = small_d.nearest_neighbor( t, Vertex_handle() );
01854         CGAL_assertion( small_d.same_points(t, vh_small->site()) );
01855       }
01856       CGAL_assertion( vh_small != Vertex_handle() );
01857       vmap[vh_small] = vh_large;
01858     }
01859     ++vc;
01860   } while ( vc != vc_start );
01861 }
01862 
01863 
01864 //--------------------------------------------------------------------
01865 //--------------------------------------------------------------------
01866 
01867 template<class Gt, class ST, class D_S, class LTag>
01868 void
01869 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01870 remove_degree_d_vertex(const Vertex_handle& v)
01871 {
01872 #if 0
01873   Self sdg_small;
01874   compute_small_diagram(v, sdg_small);
01875   std::map<Vertex_handle,Vertex_handle> vmap;
01876   compute_vertex_map(v, sdg_small, vmap);
01877 
01878   // find nearest neighbor of v in small diagram
01879   Site_2 t = v->site();
01880   Vertex_handle vn;
01881 
01882   CGAL_assertion( t.is_input() );
01883 
01884   if ( t.is_point() ) {
01885     vn = sdg_small.nearest_neighbor( t.point() );
01886   } else {
01887     vn = sdg_small.nearest_neighbor( t.source() );
01888   }
01889   CGAL_assertion( vn != Vertex_handle() );
01890 
01891   List l;
01892   Face_map fm;
01893   Sign_map sign_map;
01894 
01895   sdg_small.find_conflict_region_remove(v, vn, l, fm, sign_map);
01896 
01897   fm.clear();
01898   sign_map.clear();
01899 
01900   equalize_degrees(v, sdg_small, vmap, l);
01901 
01902   fill_hole(sdg_small, v, l, vmap);
01903 
01904   l.clear();
01905   return;
01906 
01907 #else
01908   minimize_degree(v);
01909   int deg = degree(v);
01910   if ( deg == 3 ) {
01911     remove_degree_3(v);
01912     return;
01913   }
01914   if ( deg == 2 ) {
01915     remove_degree_2(v);
01916     return;
01917   }
01918   
01919   Self sdg_small;
01920   compute_small_diagram(v, sdg_small);
01921 
01922   if ( sdg_small.number_of_vertices() <= 2 ) {
01923     CGAL_assertion( sdg_small.number_of_vertices() == 2 );
01924     CGAL_assertion( deg == 4 );
01925     Edge_circulator ec_start = incident_edges(v);
01926     Edge_circulator ec = ec_start;
01927     do {
01928       if ( is_infinite(*ec) ) { break; }
01929       ++ec;
01930     } while ( ec != ec_start );
01931     CGAL_assertion( is_infinite(ec) );
01932     flip(*ec);
01933     remove_degree_3(v);
01934     return;
01935   }
01936 
01937   std::map<Vertex_handle,Vertex_handle> vmap;
01938   compute_vertex_map(v, sdg_small, vmap);
01939 
01940   // find nearest neighbor of v in small diagram
01941   Site_2 t = v->site();
01942   Vertex_handle vn;
01943 
01944   CGAL_assertion( t.is_input() );
01945 
01946   // here we find a site in the small diagram that serves as a
01947   // starting point for finding all conflicts.
01948   // To do that we find the nearest neighbor of t if t is a point;
01949   // t is guarranteed to have a conflict with its nearest neighbor
01950   // If t is a segment, then one endpoint of t is enough; t is
01951   // guarranteed to have a conflict with the Voronoi edges around
01952   // this endpoint
01953   if ( t.is_point() ) {
01954     vn = sdg_small.nearest_neighbor( t.point() );
01955   } else {
01956     vn = sdg_small.nearest_neighbor( t.source() );
01957   }
01958   CGAL_assertion( vn != Vertex_handle() );
01959 
01960   List l;
01961   Face_map fm;
01962   Sign_map sign_map;
01963 
01964   sdg_small.find_conflict_region_remove(v, vn, l, fm, sign_map);
01965 
01966   fill_hole(sdg_small, v, l, vmap);
01967 
01968   l.clear();
01969   fm.clear();
01970   sign_map.clear();
01971 #endif
01972 }
01973 
01974 //--------------------------------------------------------------------
01975 //--------------------------------------------------------------------
01976 
01977 template<class Gt, class ST, class D_S, class LTag>
01978 bool
01979 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
01980 remove_base(const Vertex_handle& v)
01981 {
01982   Storage_site_2 ssv = v->storage_site();
01983   CGAL_precondition( ssv.is_input() );
01984 
01985   // first consider the case where we have up to 2 points
01986   size_type n = number_of_vertices();
01987 
01988   if ( n == 1 ) {
01989     return remove_first(v);
01990   } else if ( n == 2 ) {
01991     return remove_second(v);
01992   } 
01993 
01994   // secondly check if the point to be deleted is adjacent to a segment
01995   if ( ssv.is_point() ) {
01996     Vertex_circulator vc_start = incident_vertices(v);
01997     Vertex_circulator vc = vc_start;
01998 
01999     do {
02000       Storage_site_2 ss = vc->storage_site();
02001       if ( ss.is_segment() && is_endpoint_of_segment(ssv, ss) ) {
02002         return false;
02003       }
02004       ++vc;
02005     } while ( vc != vc_start );
02006   }
02007 
02008   // now do the deletion
02009   if ( n == 3 ) {
02010     return remove_third(v);
02011   }
02012 
02013   int deg = degree(v);
02014   if ( deg == 2 ) {
02015     remove_degree_2(v);
02016   } else if ( deg == 3 ) {
02017     remove_degree_3(v);
02018   } else {
02019     remove_degree_d_vertex(v);
02020   }
02021 
02022   return true;
02023 }
02024 
02025 //--------------------------------------------------------------------
02026 //--------------------------------------------------------------------
02027 
02028 template<class Gt, class ST, class D_S, class LTag>
02029 bool
02030 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02031 remove(const Vertex_handle& v)
02032 {
02033   CGAL_precondition( !is_infinite(v) );
02034   const Storage_site_2& ss = v->storage_site();
02035 
02036   if ( !ss.is_input() ) { return false; }
02037 
02038   Point_handle h1, h2;
02039   bool is_point = ss.is_point();
02040   if ( is_point ) {
02041     h1 = ss.point();
02042   } else {
02043     CGAL_assertion( ss.is_segment() );   
02044     h1 = ss.source_of_supporting_site();
02045     h2 = ss.target_of_supporting_site();
02046   }
02047 
02048   bool success = remove_base(v);
02049 
02050   if ( success ) {
02051     // unregister the input site
02052     if ( is_point ) {
02053       unregister_input_site( h1 );
02054     } else {
02055       unregister_input_site( h1, h2 );
02056     }
02057   }
02058   return success;
02059 }
02060 
02061 //--------------------------------------------------------------------
02062 //--------------------------------------------------------------------
02063 // combinatorial operations
02064 //--------------------------------------------------------------------
02065 //--------------------------------------------------------------------
02066 
02067 //--------------------------------------------------------------------
02068 //--------------------------------------------------------------------
02069 // point location
02070 //--------------------------------------------------------------------
02071 //--------------------------------------------------------------------
02072 template<class Gt, class ST, class D_S, class LTag>
02073 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
02074 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02075 nearest_neighbor(const Site_2& p,
02076                  Vertex_handle start_vertex) const
02077 {
02078   CGAL_precondition( p.is_point() );
02079 
02080   if ( number_of_vertices() == 0 ) {
02081     return Vertex_handle();
02082   }
02083 
02084   if ( start_vertex == Vertex_handle() ) {
02085     start_vertex = finite_vertex();
02086   }
02087 
02088   //  if ( start_vertex == NULL ) { return start_vertex; }
02089 
02090   Vertex_handle vclosest;
02091   Vertex_handle v = start_vertex;
02092 
02093   if ( number_of_vertices() < 3 ) {
02094     vclosest = v;
02095     Finite_vertices_iterator vit = finite_vertices_begin();
02096     for (; vit != finite_vertices_end(); ++vit) {
02097       Vertex_handle v1(vit);
02098       if ( v1 != vclosest /*&& !is_infinite(v1)*/ ) {
02099         Site_2 t0 = vclosest->site();
02100         Site_2 t1 = v1->site();
02101         if ( side_of_bisector(t0, t1, p) == ON_NEGATIVE_SIDE ) {
02102           vclosest = v1;
02103         }
02104       }
02105     }
02106     return vclosest;
02107   }
02108 
02109   do {
02110     vclosest = v;
02111     Site_2 t0 = v->site();
02112     //    if ( t0.is_point() && same_points(p, t0) ) {
02113     //      return vclosest;
02114     //    }
02115     Vertex_circulator vc_start = incident_vertices(v);
02116     Vertex_circulator vc = vc_start;
02117     do {
02118       if ( !is_infinite(vc) ) {
02119         Vertex_handle v1(vc);
02120         Site_2 t1 = v1->site();
02121         Oriented_side os = side_of_bisector(t0, t1, p);
02122 
02123         if ( os == ON_NEGATIVE_SIDE ) {
02124           v = v1;
02125           break;
02126         }
02127       }
02128       ++vc;
02129     } while ( vc != vc_start );
02130   } while ( vclosest != v );
02131 
02132   return vclosest;
02133 }
02134 
02135 //----------------------------------------------------------------------
02136 //----------------------------------------------------------------------
02137 // methods for the predicates
02138 //----------------------------------------------------------------------
02139 //----------------------------------------------------------------------
02140 
02141 template<class Gt, class ST, class D_S, class LTag>
02142 Sign
02143 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02144 incircle(const Face_handle& f, const Site_2& q) const
02145 {
02146   if ( !is_infinite(f) ) {
02147     return incircle(f->vertex(0)->site(),
02148                     f->vertex(1)->site(),
02149                     f->vertex(2)->site(), q);
02150   }
02151 
02152   int inf_i(-1); // to avoid compiler warning
02153   for (int i = 0; i < 3; i++) {
02154     if ( is_infinite(f->vertex(i)) ) {
02155       inf_i = i;
02156       break;
02157     }
02158   }
02159   return incircle( f->vertex( ccw(inf_i) )->site(),
02160                    f->vertex(  cw(inf_i) )->site(), q );
02161 }
02162 
02163 
02164 template<class Gt, class ST, class D_S, class LTag>
02165 Sign
02166 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02167 incircle(const Vertex_handle& v0, const Vertex_handle& v1,
02168               const Vertex_handle& v2, const Vertex_handle& v) const
02169 {
02170   CGAL_precondition( !is_infinite(v) );
02171 
02172   if ( !is_infinite(v0) && !is_infinite(v1) &&
02173        !is_infinite(v2) ) {
02174     return incircle(v0->site(), v1->site(),
02175                     v2->site(), v->site());
02176   }
02177 
02178   if ( is_infinite(v0) ) {
02179     CGAL_precondition( !is_infinite(v1) && !is_infinite(v2) );
02180     return incircle( v1->site(), v2->site(), v->site());
02181   }
02182   if ( is_infinite(v1) ) {
02183     CGAL_precondition( !is_infinite(v0) && !is_infinite(v2) );
02184     return incircle( v2->site(), v0->site(), v->site());
02185   }
02186 
02187   CGAL_assertion( is_infinite(v2) );
02188   CGAL_precondition( !is_infinite(v0) && !is_infinite(v1) );
02189   return incircle( v0->site(), v1->site(), v->site());
02190 }
02191 
02192 
02193 // this the finite edge interior predicate for a degenerate edge
02194 template<class Gt, class ST, class D_S, class LTag>
02195 bool
02196 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02197 finite_edge_interior(const Face_handle& f, int i, const Site_2& q,
02198                      Sign sgn, int) const
02199 {
02200   if ( !is_infinite( this->_tds.mirror_vertex(f, i) ) ) {
02201     CGAL_precondition( is_infinite(f->vertex(i)) );
02202 
02203     Face_handle g = f->neighbor(i);
02204     int j = this->_tds.mirror_index(f, i);
02205 
02206     return finite_edge_interior(g, j, q, sgn, 0 /* degenerate */);
02207   }
02208 
02209   CGAL_precondition( is_infinite( this->_tds.mirror_vertex(f, i) ) );
02210 
02211   Site_2 t1 = f->vertex( ccw(i) )->site();
02212   Site_2 t2 = f->vertex(  cw(i) )->site();
02213 
02214   if ( is_infinite(f->vertex(i)) ) {
02215     return finite_edge_interior(t1, t2, q, sgn);
02216   }
02217 
02218   Site_2 t3 = f->vertex(i)->site();
02219   return finite_edge_interior(t1, t2, t3, q, sgn);
02220 }
02221 
02222 template<class Gt, class ST, class D_S, class LTag>
02223 bool
02224 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02225 finite_edge_interior(const Vertex_handle& v1, const Vertex_handle& v2,
02226                      const Vertex_handle& v3, const Vertex_handle& v4,
02227                      const Vertex_handle& v, Sign sgn, int) const
02228 {
02229   CGAL_precondition( !is_infinite(v1) && !is_infinite(v2) && 
02230                      !is_infinite(v) );
02231   if ( !is_infinite( v4 ) ) {
02232     CGAL_precondition( is_infinite(v3) );
02233 
02234     return
02235       finite_edge_interior(v2, v1, v4, v3, v, sgn, 0 /* degenerate */);
02236   }
02237 
02238   CGAL_precondition( is_infinite( v4 ) );
02239 
02240   Site_2 t1 = v1->site();
02241   Site_2 t2 = v2->site();
02242   Site_2 q = v->site();
02243 
02244   if ( is_infinite(v3) ) {
02245     return finite_edge_interior(t1, t2, q, sgn);
02246   }
02247 
02248   Site_2 t3 = v3->site();
02249   return finite_edge_interior(t1, t2, t3, q, sgn);
02250 }
02251 
02252 template<class Gt, class ST, class D_S, class LTag>
02253 bool
02254 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02255 infinite_edge_interior(const Face_handle& f, int i,
02256                        const Site_2& q, Sign sgn) const
02257 {
02258   if ( !is_infinite( f->vertex(ccw(i)) ) ) {
02259     CGAL_precondition( is_infinite( f->vertex(cw(i)) ) );
02260     Face_handle g = f->neighbor(i);
02261     int j = this->_tds.mirror_index(f, i);
02262 
02263     return infinite_edge_interior(g, j, q, sgn);
02264   }
02265 
02266   CGAL_precondition( is_infinite( f->vertex(ccw(i)) ) );
02267 
02268   Site_2 t2 = f->vertex(  cw(i) )->site();
02269   Site_2 t3 = f->vertex(     i  )->site();
02270   Site_2 t4 = this->_tds.mirror_vertex(f, i)->site();
02271 
02272   return infinite_edge_interior(t2, t3, t4, q, sgn);
02273 }
02274 
02275 
02276 template<class Gt, class ST, class D_S, class LTag>
02277 bool
02278 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02279 infinite_edge_interior(const Vertex_handle& v1,
02280                        const Vertex_handle& v2,
02281                        const Vertex_handle& v3,
02282                        const Vertex_handle& v4,
02283                        const Vertex_handle& v, Sign sgn) const
02284 {
02285   CGAL_precondition( !is_infinite(v3) && !is_infinite(v4) && 
02286                      !is_infinite(v) );
02287 
02288   if ( !is_infinite( v1 ) ) {
02289     CGAL_precondition( is_infinite( v2 ) );
02290 
02291     return infinite_edge_interior(v2, v1, v4, v3, v, sgn);
02292   }
02293 
02294   CGAL_precondition( is_infinite( v1 ) );
02295 
02296   Site_2 t2 = v2->site();
02297   Site_2 t3 = v3->site();
02298   Site_2 t4 = v4->site();
02299   Site_2 q = v->site();
02300 
02301   return infinite_edge_interior(t2, t3, t4, q, sgn);
02302 }
02303 
02304 
02305 
02306 
02307 template<class Gt, class ST, class D_S, class LTag>
02308 bool
02309 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02310 edge_interior(const Vertex_handle& v1,
02311               const Vertex_handle& v2,
02312               const Vertex_handle& v3,
02313               const Vertex_handle& v4,
02314               const Vertex_handle& v, Sign sgn) const
02315 {
02316   CGAL_precondition( !is_infinite(v) );
02317 
02318   bool is_inf_v1 = is_infinite(v1);
02319   bool is_inf_v2 = is_infinite(v2);
02320   bool is_inf_v3 = is_infinite(v3);
02321   bool is_inf_v4 = is_infinite(v4);
02322 
02323   bool result;
02324 
02325   if ( !is_inf_v1 && !is_inf_v2 && !is_inf_v3 && !is_inf_v4 ) {
02326     result = finite_edge_interior(v1, v2, v3, v4, v, sgn);
02327   } else if ( is_inf_v3 || is_inf_v4 ) {
02328     result = finite_edge_interior(v1, v2, v3, v4, v, sgn, 0/* degenerate */);
02329   } else {
02330     result = infinite_edge_interior(v1, v2, v3, v4, v, sgn);
02331   }
02332 
02333   return result;
02334 }
02335 
02336 
02337 template<class Gt, class ST, class D_S, class LTag>
02338 bool
02339 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02340 edge_interior(const Face_handle& f, int i,
02341               const Site_2& q, Sign sgn) const
02342 {
02343   Face_handle g = f->neighbor(i);
02344 
02345   bool is_inf_f = is_infinite(f);
02346   bool is_inf_g = is_infinite(g);
02347 
02348   bool result;
02349 
02350   if ( !is_inf_f && !is_inf_g ) {
02351     result = finite_edge_interior(f, i, q, sgn);
02352   } else if ( !is_inf_f || !is_inf_g ) {
02353     result = finite_edge_interior(f, i, q, sgn, 0 /* denegerate */);
02354   } else {
02355     if ( !is_infinite(f, i) ) {
02356       result = finite_edge_interior(f, i, q, sgn, 0 /* degenerate */);
02357     } else {
02358       result = infinite_edge_interior(f, i, q, sgn);
02359     }
02360   }
02361 
02362   return result;
02363 }
02364 
02365 
02366 template<class Gt, class ST, class D_S, class LTag>
02367 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Arrangement_type
02368 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02369 arrangement_type(const Site_2& p, const Site_2& q) const
02370 {
02371   typedef typename Geom_traits::Arrangement_type_2  AT2;
02372   typedef typename AT2::result_type                 Arrangement_type;
02373 
02374   Arrangement_type res = geom_traits().arrangement_type_2_object()(p, q);
02375 
02376   // The valeus that have to be treated are the following:
02377   // DISJOINT, TOUCH_1, TOUCH_2, CROSSING, IDENTICAL, INTERIOR,
02378   // TOUCH_11_INTERIOR_1, TOUCH_12_INTERIOR_1, TOUCH_21_INTERIOR_1 and
02379   // TOUCH_22_INTERIOR_1.
02380   //
02381   // The remaining values will either never appear because of one of
02382   // the following reasons:
02383   // 1. we insert the endpoints of the segments first and then the
02384   //    interior (OVERLAPPING_*, INTERIOR_*, TOUCH_*_INTERIOR_2).
02385   // 2. the values have no meaning since we consider the segments to
02386   //    be open (TOUCH_INTERIOR_*). In this case, the conflict will
02387   //    appear when we test with the endpoint.
02388   // 3. a conflict will first happen with an endpoint before testing
02389   //    for the segment (TOUCH_2*_INTERIOR_1). In this case the
02390   //    segment to be inserted will first find an endpoint in its
02391   //    interior before actually finding that there is another segment
02392   //    it overlaps with.
02393 
02394   CGAL_assertion( res != AT2::INTERIOR_1 );
02395   CGAL_assertion( res != AT2::INTERIOR_2 );
02396 
02397   CGAL_assertion( res != AT2::OVERLAPPING_11 );
02398   CGAL_assertion( res != AT2::OVERLAPPING_12 );
02399   CGAL_assertion( res != AT2::OVERLAPPING_21 );
02400   CGAL_assertion( res != AT2::OVERLAPPING_22 );
02401 
02402   CGAL_assertion( res != AT2::TOUCH_11_INTERIOR_2 );
02403   CGAL_assertion( res != AT2::TOUCH_21_INTERIOR_2 );
02404   CGAL_assertion( res != AT2::TOUCH_12_INTERIOR_2 );
02405   CGAL_assertion( res != AT2::TOUCH_22_INTERIOR_2 );
02406 
02407   CGAL_assertion( res != AT2::TOUCH_21_INTERIOR_1 );
02408   CGAL_assertion( res != AT2::TOUCH_22_INTERIOR_1 );
02409 
02410   if ( res == AT2::TOUCH_INTERIOR_12 || res == AT2::TOUCH_INTERIOR_21 ||
02411        res == AT2::TOUCH_INTERIOR_11 || res == AT2::TOUCH_INTERIOR_22 ) {
02412     return AT2::DISJOINT;
02413   }
02414   if ( res == AT2::TOUCH_11 || res == AT2::TOUCH_12 ||
02415        res == AT2::TOUCH_21 || res == AT2::TOUCH_22 ) {
02416     return AT2::DISJOINT;
02417   }
02418 
02419   return res;
02420 }
02421 
02422 //--------------------------------------------------------------------
02423 //--------------------------------------------------------------------
02424 // embedding and visualization methods and constructions for primal
02425 // and dual
02426 //--------------------------------------------------------------------
02427 //--------------------------------------------------------------------
02428 
02429 // primal
02430 template<class Gt, class ST, class D_S, class LTag>
02431 Object
02432 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02433 primal(const Edge e) const
02434 {
02435   typedef typename Gt::Line_2   Line_2;
02436   typedef typename Gt::Ray_2    Ray_2;
02437 
02438   CGAL_precondition( !is_infinite(e) );
02439 
02440   if ( this->dimension() == 1 ) {
02441     Site_2 p = (e.first)->vertex(cw(e.second))->site();
02442     Site_2 q = (e.first)->vertex(ccw(e.second))->site();
02443 
02444     Line_2 l = construct_sdg_bisector_2_object()(p,q);
02445     return make_object(l);
02446   }
02447 
02448   // dimension == 2
02449   // none of the two adjacent faces is infinite
02450   if( (!is_infinite(e.first)) &&
02451       (!is_infinite(e.first->neighbor(e.second))) ) {
02452     Site_2 p = (e.first)->vertex( ccw(e.second) )->site();
02453     Site_2 q = (e.first)->vertex(  cw(e.second) )->site();
02454     Site_2 r = (e.first)->vertex(     e.second  )->site();
02455     Site_2 s = this->_tds.mirror_vertex(e.first, e.second)->site();
02456     return construct_sdg_bisector_segment_2_object()(p,q,r,s);
02457   }
02458 
02459   // both of the adjacent faces are infinite
02460   if ( is_infinite(e.first) &&
02461        is_infinite(e.first->neighbor(e.second)) )  {
02462     Site_2 p = (e.first)->vertex(cw(e.second))->site();
02463     Site_2 q = (e.first)->vertex(ccw(e.second))->site();
02464     Line_2 l = construct_sdg_bisector_2_object()(p,q);
02465     return make_object(l);
02466   }
02467 
02468   // only one of the adjacent faces is infinite
02469   CGAL_assertion( is_infinite( e.first ) ||
02470                   is_infinite( e.first->neighbor(e.second) )
02471                   );
02472 
02473   CGAL_assertion( !(is_infinite( e.first ) &&
02474                     is_infinite( e.first->neighbor(e.second) )
02475                     )
02476                   );
02477 
02478   CGAL_assertion( is_infinite(e.first->vertex(e.second)) ||
02479                   is_infinite(this->_tds.mirror_vertex(e.first, e.second)) );
02480 
02481   Edge ee = e;
02482   if ( is_infinite( e.first->vertex(e.second) )  ) {
02483     ee = sym_edge(e);
02484   }
02485   Site_2 p = ee.first->vertex( ccw(ee.second) )->site();
02486   Site_2 q = ee.first->vertex(  cw(ee.second) )->site();
02487   Site_2 r = ee.first->vertex(     ee.second  )->site();
02488 
02489   Ray_2 ray = construct_sdg_bisector_ray_2_object()(p,q,r);
02490   return make_object(ray);
02491 }
02492 
02493 //--------------------------------------------------------------------
02494 //--------------------------------------------------------------------
02495 // validity test method
02496 //--------------------------------------------------------------------
02497 //--------------------------------------------------------------------
02498 template<class Gt, class ST, class D_S, class LTag>
02499 bool Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02500 is_valid(bool verbose, int level) const
02501 {
02502   if (level < 0) { return true; }
02503 
02504   if (number_of_vertices() <= 1) {
02505     if ( verbose && number_of_vertices() == 1 ) {
02506       std::cerr << "SDGDS is ok... " << std::flush;
02507     }
02508     return true;
02509   }
02510 
02511   // level 0 test: check the TDS
02512   bool result = data_structure().is_valid(verbose, level);
02513 
02514   if ( result && verbose ) {
02515     std::cerr << "SDGDS is ok... " << std::flush;
02516   }
02517 
02518   if (level == 0) { return result; }
02519 
02520   // level 1 test: do the incircle tests
02521   if (number_of_vertices() < 3)  { return true; }
02522 
02523   for (All_edges_iterator eit = all_edges_begin();
02524        eit != all_edges_end(); ++eit) {
02525     Edge e = *eit;
02526     Face_handle f = e.first;
02527 
02528     Vertex_handle v = this->_tds.mirror_vertex(f, e.second);
02529 
02530     if ( f->vertex(e.second) == v ) { continue; }
02531     if ( !is_infinite(v) ) {
02532       result = result &&
02533         ( incircle(f, v->site()) != NEGATIVE );
02534     }
02535     Edge sym_e = sym_edge(e);
02536     f = sym_e.first;
02537     v = this->_tds.mirror_vertex(f, sym_e.second);
02538 
02539     if ( !is_infinite(v) ) {
02540       result = result &&
02541         ( incircle(f, v->site()) != NEGATIVE );
02542     }
02543   }
02544 
02545   if ( result && verbose ) {
02546     std::cerr << "Segment Delaunay graph is ok..." << std::flush;
02547   }
02548   if ( !result && verbose ) {
02549     std::cerr << "Segment Delaunay graph is NOT valid..." << std::flush;
02550   }
02551 
02552   return result;
02553 }
02554 
02555 
02556 //--------------------------------------------------------------------
02557 //--------------------------------------------------------------------
02558 // misc
02559 //--------------------------------------------------------------------
02560 //--------------------------------------------------------------------
02561 
02562 
02563 template<class Gt, class ST, class D_S, class LTag>
02564 void
02565 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02566 print_error_message() const
02567 {
02568   std::cerr << std::endl;
02569   std::cerr << "WARNING:" << std::endl;
02570   std::cerr << "A segment-segment intersection was found."
02571             << std::endl;
02572   std::cerr << "The Segment_Delaunay_graph_2 class is not configured"
02573             << " to handle this situation." << std::endl;
02574   std::cerr << "Please look at the documentation on how to handle"
02575             << " this behavior." << std::endl;
02576   std::cerr << std::endl;
02577 }
02578 
02579 //--------------------------------------------------------------------
02580 //--------------------------------------------------------------------
02581 // the copy method
02582 //--------------------------------------------------------------------
02583 //--------------------------------------------------------------------
02584 
02585 template<class Gt, class ST, class D_S, class LTag>
02586 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Storage_site_2
02587 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02588 copy_storage_site(const Storage_site_2& ss_other, Handle_map& hm,
02589                   const Tag_false&)
02590 {
02591   if ( ss_other.is_segment() ) {
02592     Point_handle p0 = hm[ ss_other.source_of_supporting_site() ];
02593     Point_handle p1 = hm[ ss_other.target_of_supporting_site() ];
02594     return st_.construct_storage_site_2_object()(p0, p1);
02595   } else {
02596     Point_handle p0 = hm[ ss_other.point() ];
02597     return st_.construct_storage_site_2_object()(p0);
02598   }
02599 }
02600 
02601 template<class Gt, class ST, class D_S, class LTag>
02602 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Storage_site_2
02603 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02604 copy_storage_site(const Storage_site_2& ss_other, Handle_map& hm,
02605                   const Tag_true&)
02606 {
02607   if ( ss_other.is_segment() ) {
02608     if ( ss_other.is_input() ) {
02609       Point_handle p0 = hm[ ss_other.source_of_supporting_site() ];
02610       Point_handle p1 = hm[ ss_other.target_of_supporting_site() ];
02611       return st_.construct_storage_site_2_object()(p0, p1);
02612     } else if ( ss_other.is_input(0) ) {
02613       Point_handle p0 = hm[ ss_other.source_of_supporting_site() ];
02614       Point_handle p1 = hm[ ss_other.target_of_supporting_site() ];
02615       Point_handle p4 = hm[ ss_other.source_of_crossing_site(1) ];
02616       Point_handle p5 = hm[ ss_other.target_of_crossing_site(1) ];
02617       return st_.construct_storage_site_2_object()(p0, p1, p4, p5, true);
02618     } else if ( ss_other.is_input(1) ) {
02619       Point_handle p0 = hm[ ss_other.source_of_supporting_site() ];
02620       Point_handle p1 = hm[ ss_other.target_of_supporting_site() ];
02621       Point_handle p2 = hm[ ss_other.source_of_crossing_site(0) ];
02622       Point_handle p3 = hm[ ss_other.target_of_crossing_site(0) ];
02623       return st_.construct_storage_site_2_object()(p0, p1, p2, p3, false);
02624     } else {
02625       Point_handle p0 = hm[ ss_other.source_of_supporting_site() ];
02626       Point_handle p1 = hm[ ss_other.target_of_supporting_site() ];
02627       Point_handle p2 = hm[ ss_other.source_of_crossing_site(0) ];
02628       Point_handle p3 = hm[ ss_other.target_of_crossing_site(0) ];
02629       Point_handle p4 = hm[ ss_other.source_of_crossing_site(1) ];
02630       Point_handle p5 = hm[ ss_other.target_of_crossing_site(1) ];
02631       return st_.construct_storage_site_2_object()(p0, p1, p2, p3, p4, p5);
02632     }
02633   } else {
02634     if ( ss_other.is_input() ) {
02635       Point_handle p0 = hm[ ss_other.point() ];
02636       return st_.construct_storage_site_2_object()(p0);
02637     } else {
02638       Point_handle p2 = hm[ ss_other.source_of_supporting_site(0) ];
02639       Point_handle p3 = hm[ ss_other.target_of_supporting_site(0) ];
02640       Point_handle p4 = hm[ ss_other.source_of_supporting_site(1) ];
02641       Point_handle p5 = hm[ ss_other.target_of_supporting_site(1) ];
02642       return st_.construct_storage_site_2_object()(p2, p3, p4, p5);
02643     }
02644   }
02645 }
02646 
02647 template<class Gt, class ST, class D_S, class LTag>
02648 void
02649 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02650 copy(Segment_Delaunay_graph_2& other)
02651 {
02652   // first copy the point container
02653   pc_ = other.pc_;
02654 
02655   // copy storage traits
02656   st_ = other.st_;
02657 
02658   // first create a map between the old point handles and the new ones
02659   Handle_map hm;
02660 
02661   Point_handle it_other = other.pc_.begin();
02662   Point_handle it_this = pc_.begin();
02663   for (; it_other != other.pc_.end(); ++it_other, ++it_this) {
02664     hm.insert( Point_handle_pair(it_other, it_this) );
02665   }
02666 
02667   copy(other, hm);
02668 }
02669 
02670 template<class Gt, class ST, class D_S, class LTag>
02671 void
02672 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02673 copy(Segment_Delaunay_graph_2& other, Handle_map& hm)
02674 {
02675   // second, copy the site representation info for the input sites
02676   // using the correct handles (i.e., the handles from the new point
02677   // container
02678   isc_.clear();
02679   typename Input_sites_container::iterator iit_other = other.isc_.begin();
02680   for (; iit_other != other.isc_.end(); ++iit_other) {
02681     Site_rep_2 old_srep = *iit_other;
02682     Site_rep_2 new_srep( hm[boost::tuples::get<0>(old_srep)],
02683                          hm[boost::tuples::get<1>(old_srep)],
02684                          boost::tuples::get<2>(old_srep) );
02685     isc_.insert( new_srep );
02686   }
02687   
02688   CGAL_assertion( pc_.size() == other.pc_.size() );
02689   CGAL_assertion( isc_.size() == other.isc_.size() );
02690 
02691 #ifndef CGAL_NO_ASSERTIONS
02692   {
02693     Point_handle it_other = other.pc_.begin();
02694     Point_handle it_this = pc_.begin();
02695     for (; it_other != other.pc_.end(); ++it_other, ++it_this) {
02696       CGAL_assertion( *it_other == *it_this );
02697     }
02698   }
02699 #endif
02700 
02701   // then copy the diagram
02702   DG::operator=(other);
02703 
02704   // now we have to update the sotrage sites in each vertex of the
02705   // diagram and also update the 
02706 
02707   // then update the storage sites for each vertex
02708   Intersections_tag itag;
02709 
02710   Finite_vertices_iterator vit_other = other.finite_vertices_begin();
02711   Finite_vertices_iterator vit_this = finite_vertices_begin();
02712   for (; vit_other != other.finite_vertices_end(); vit_other++,
02713          vit_this++) {
02714     Storage_site_2 ss_other = vit_other->storage_site();
02715 
02716 #ifndef CGAL_NO_ASSERTIONS
02717     Storage_site_2 ss_this = vit_this->storage_site();
02718     if ( ss_other.is_segment() ) {
02719       CGAL_assertion( ss_this.is_segment() );
02720       CGAL_assertion( same_segments(ss_this.site(), ss_other.site()) );
02721     } else {
02722       CGAL_assertion( ss_this.is_point() );
02723       CGAL_assertion( same_points(ss_this.site(), ss_other.site()) );
02724     }
02725 #endif
02726 
02727     Storage_site_2 new_ss_this = copy_storage_site(ss_other, hm, itag);
02728     vit_this->set_site( new_ss_this );
02729   }
02730 }
02731 
02732 //--------------------------------------------------------------------
02733 //--------------------------------------------------------------------
02734 // getting endpoints of segments
02735 //--------------------------------------------------------------------
02736 //--------------------------------------------------------------------
02737 
02738 template<class Gt, class ST, class D_S, class LTag>
02739 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
02740 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02741 first_endpoint_of_segment(const Vertex_handle& v) const
02742 {
02743   CGAL_assertion( v->is_segment() );
02744   Site_2 fe = v->site().source_site();
02745   Vertex_circulator vc_start = incident_vertices(v);
02746   Vertex_circulator vc = vc_start;
02747   do {
02748     // Vertex_handle vv(vc);
02749     if ( !is_infinite(vc) && vc->is_point() ) {
02750       if ( same_points(fe, vc->site()) ) {
02751         return Vertex_handle(vc);
02752       }
02753     }
02754     vc++;
02755   } while ( vc != vc_start );
02756 
02757   // we should never reach this point
02758   CGAL_error();
02759   return Vertex_handle();
02760 }
02761 
02762 template<class Gt, class ST, class D_S, class LTag>
02763 typename Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::Vertex_handle
02764 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02765 second_endpoint_of_segment(const Vertex_handle& v) const
02766 {
02767   CGAL_assertion( v->is_segment() );
02768   Site_2 fe = v->site().target_site();
02769   Vertex_circulator vc_start = incident_vertices(v);
02770   Vertex_circulator vc = vc_start;
02771   do {
02772     //      Vertex_handle vv(vc);
02773     if ( !is_infinite(vc) && vc->is_point() ) {
02774       if ( same_points(fe, vc->site()) ) {
02775         return Vertex_handle(vc);
02776       }
02777     }
02778     vc++;
02779   } while ( vc != vc_start );
02780 
02781   // we should never reach this point
02782   CGAL_error();
02783   return Vertex_handle();
02784 }
02785 
02786 //--------------------------------------------------------------------
02787 //--------------------------------------------------------------------
02788 // file I/O
02789 //--------------------------------------------------------------------
02790 //--------------------------------------------------------------------
02791 
02792 template<class Gt, class ST, class D_S, class LTag>
02793 void
02794 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02795 file_output(std::ostream& os, const Storage_site_2& t,
02796             Point_handle_mapper& P) const
02797 {
02798   CGAL_precondition( t.is_defined() );
02799 
02800   if ( t.is_point() ) {
02801     // 0 for point
02802     os << 0;
02803     if ( is_ascii(os) ) { os << ' '; }
02804     if ( t.is_input() ) {
02805       // 0 for input
02806       os << 0;
02807       if ( is_ascii(os) ) { os << ' '; }
02808       os << P[t.point()];
02809     } else {
02810       // 1 for non-input
02811       os << 1;
02812       if ( is_ascii(os) ) { os << ' '; }
02813       os << P[t.source_of_supporting_site(0)];
02814       if ( is_ascii(os) ) { os << ' '; }
02815       os << P[t.target_of_supporting_site(0)];
02816       if ( is_ascii(os) ) { os << ' '; }
02817       os << P[t.source_of_supporting_site(1)];
02818       if ( is_ascii(os) ) { os << ' '; }
02819       os << P[t.target_of_supporting_site(1)];
02820     }
02821   } else { // t is a segment
02822     // 1 for segment
02823     os << 1;
02824     if ( is_ascii(os) ) { os << ' '; }
02825     if ( t.is_input() ) {
02826       // 0 for input
02827       os << 0;
02828       if ( is_ascii(os) ) { os << ' '; }
02829       os << P[t.source_of_supporting_site()];
02830       if ( is_ascii(os) ) { os << ' '; }
02831       os << P[t.target_of_supporting_site()];
02832     } else if ( t.is_input(0) ) {
02833       // 1 for input source
02834       os << 1;
02835       if ( is_ascii(os) ) { os << ' '; }
02836       os << P[t.source_of_supporting_site()];
02837       if ( is_ascii(os) ) { os << ' '; }
02838       os << P[t.target_of_supporting_site()];
02839       if ( is_ascii(os) ) { os << ' '; }
02840       os << P[t.source_of_crossing_site(1)];
02841       if ( is_ascii(os) ) { os << ' '; }
02842       os << P[t.target_of_crossing_site(1)];
02843     } else if ( t.is_input(1) ) {
02844       // 2 for input target
02845       os << 2;
02846       if ( is_ascii(os) ) { os << ' '; }
02847       os << P[t.source_of_supporting_site()];
02848       if ( is_ascii(os) ) { os << ' '; }
02849       os << P[t.target_of_supporting_site()];
02850       if ( is_ascii(os) ) { os << ' '; }
02851       os << P[t.source_of_crossing_site(0)];
02852       if ( is_ascii(os) ) { os << ' '; }
02853       os << P[t.target_of_crossing_site(0)];
02854     } else {
02855       // 3 for non-input src & trg
02856       os << 3;
02857       if ( is_ascii(os) ) { os << ' '; }
02858       os << P[t.source_of_supporting_site()];
02859       if ( is_ascii(os) ) { os << ' '; }
02860       os << P[t.target_of_supporting_site()];
02861       if ( is_ascii(os) ) { os << ' '; }
02862       os << P[t.source_of_crossing_site(0)];
02863       if ( is_ascii(os) ) { os << ' '; }
02864       os << P[t.target_of_crossing_site(0)];
02865       if ( is_ascii(os) ) { os << ' '; }
02866       os << P[t.source_of_crossing_site(1)];
02867       if ( is_ascii(os) ) { os << ' '; }
02868       os << P[t.target_of_crossing_site(1)];
02869     }
02870   }
02871 }
02872 
02873 template<class Gt, class ST, class D_S, class LTag>
02874 void
02875 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02876 file_input(std::istream& is, Storage_site_2& t,
02877            const Point_handle_vector& P, const Tag_false&) const
02878 {
02879   int type, input;
02880   is >> type >> input;
02881   CGAL_assertion( type == 0 || type == 1 );
02882   CGAL_assertion( input == 0 );
02883   if ( type == 0 ) {
02884     // we have an input point
02885     size_type p;
02886     is >> p;
02887     t = st_.construct_storage_site_2_object()(P[p]);
02888   } else {
02889     CGAL_assertion( type == 1 );
02890     // we have an input segment
02891     size_type p1, p2;
02892     is >> p1 >> p2;
02893     t = st_.construct_storage_site_2_object()(P[p1], P[p2]);
02894   }
02895 }
02896 
02897 template<class Gt, class ST, class D_S, class LTag>
02898 void
02899 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02900 file_input(std::istream& is, Storage_site_2& t,
02901            const Point_handle_vector& P, const Tag_true&) const
02902 {
02903   int type, input;
02904   is >> type >> input;
02905   CGAL_assertion( type == 0 || type == 1 );
02906   CGAL_assertion( input >= 0 && input <= 3 );
02907   if ( type == 0 ) {
02908     // we have a point
02909     if ( input == 0 ) {
02910       // we have an input point
02911       size_type p;
02912       is >> p;
02913       t = st_.construct_storage_site_2_object()(P[p]);
02914     } else {
02915       // we have a point that is the intersection of two segments
02916       CGAL_assertion( input == 1 );
02917       size_type p1, p2, q1, q2;
02918       is >> p1 >> p2 >> q1 >> q2;
02919       t = st_.construct_storage_site_2_object()(P[p1], P[p2], P[q1], P[q2]);
02920     }
02921   } else {
02922     // we have a segment
02923     CGAL_assertion( type == 1 );
02924     if ( input == 0 ) {
02925       // we have an input segment
02926       size_type p1, p2;
02927       is >> p1 >> p2;
02928       t = st_.construct_storage_site_2_object()(P[p1], P[p2]);
02929     } else if ( input < 3 ) {
02930       // we have a segment whose source or target is input but not both
02931       size_type p1, p2, q1, q2;
02932       is >> p1 >> p2 >> q1 >> q2;
02933       t = st_.construct_storage_site_2_object()(P[p1], P[p2],
02934                                                 P[q1], P[q2], input == 1);
02935     } else {
02936       // we have a segment whose neither its source nor its target is input
02937       CGAL_assertion( input == 3 );
02938       size_type p1, p2, q1, q2, r1, r2;
02939       is >> p1 >> p2 >> q1 >> q2 >> r1 >> r2;
02940       t = st_.construct_storage_site_2_object()(P[p1], P[p2],
02941                                                 P[q1], P[q2],
02942                                                 P[r1], P[r2]);      
02943     }
02944   }
02945 }
02946 
02947 //--------------------------------------------------------------------
02948 
02949 template<class Gt, class ST, class D_S, class LTag>
02950 void
02951 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
02952 file_output(std::ostream& os, Point_handle_mapper& P,
02953             bool print_point_container) const
02954 {
02955   // ouput to a file
02956   size_type n = this->_tds.number_of_vertices();
02957   size_type m = this->_tds.number_of_full_dim_faces();
02958 
02959   CGAL_assertion( n >= 1 );
02960 
02961   if( is_ascii(os) ) {
02962     os << n << ' ' << m << ' ' << dimension() << std::endl;
02963   } else {
02964     os << n << m << dimension();
02965   }
02966 
02967   // points in point container and input sites container
02968   if ( print_point_container ) {
02969     if ( is_ascii(os) ) { os << std::endl; }
02970     os << pc_.size();
02971     if ( is_ascii(os) ) { os << std::endl; }
02972     for (const_Point_handle ph = pc_.begin(); ph != pc_.end(); ++ph) {
02973       os << *ph;
02974       if ( is_ascii(os) ) { os << std::endl; }
02975     }
02976 
02977     // print the input sites container
02978     if ( is_ascii(os) ) { os << std::endl; }
02979     os << isc_.size();
02980     if ( is_ascii(os) ) { os << std::endl; }
02981     for (typename Input_sites_container::const_iterator it = isc_.begin();
02982          it != isc_.end(); ++it) {
02983       os << P[boost::tuples::get<0>(*it)];
02984       if ( is_ascii(os) ) { os << " "; }
02985       os << P[boost::tuples::get<1>(*it)];
02986       if ( is_ascii(os) ) { os << std::endl; }
02987     }
02988   }
02989 
02990   std::map<Vertex_handle,int> V;
02991   std::map<Face_handle,int> F;
02992 
02993   // first vertex (infinite vertex) 
02994   size_type inum = 0;
02995   V[infinite_vertex()] = inum++;
02996   
02997   // finite vertices
02998   if (is_ascii(os)) os << std::endl;
02999   for (Finite_vertices_iterator vit = finite_vertices_begin();
03000        vit != finite_vertices_end(); ++vit) {
03001     V[vit] = inum++;
03002     //    os << vit->site();
03003     file_output(os, vit->storage_site(), P);
03004     // write non-combinatorial info of the vertex
03005     //    os << *vit ;
03006     if ( is_ascii(os) ) { os << std::endl; }
03007   }
03008   if ( is_ascii(os) ) { os << std::endl; }
03009 
03010   // vertices of the faces
03011   inum = 0;
03012   int dim = (dimension() == -1 ? 1 :  dimension() + 1);
03013   for(All_faces_iterator fit = all_faces_begin();
03014       fit != all_faces_end(); ++fit) {
03015     F[fit] = inum++;
03016     for(int j = 0; j < dim ; ++j) {
03017       os << V[ fit->vertex(j) ];
03018       if( is_ascii(os) ) { os << ' '; }
03019     }
03020     // write non-combinatorial info of the face
03021     //    os << *fit ;
03022     if( is_ascii(os) ) { os << std::endl; }
03023   }
03024   if( is_ascii(os) ) { os << std::endl; }
03025     
03026   // neighbor pointers of the  faces
03027   for( All_faces_iterator it = all_faces_begin();
03028        it != all_faces_end(); ++it) {
03029     for(int j = 0; j < dimension()+1; ++j){
03030       os << F[ it->neighbor(j) ];
03031       if( is_ascii(os) ) { os << ' '; }
03032     }
03033     if( is_ascii(os) ) { os << std::endl; }
03034   }
03035 
03036   if ( is_ascii(os) ) { os << std::endl; }
03037 }
03038 
03039 
03040 
03041 template<class Gt, class ST, class D_S, class LTag>
03042 void
03043 Segment_Delaunay_graph_2<Gt,ST,D_S,LTag>::
03044 file_input(std::istream& is, bool read_handle_vector,
03045            Point_handle_vector& P)
03046 {
03047   //input from file
03048   size_type n, m;
03049   int d;
03050   is >> n >> m >> d;
03051 
03052   CGAL_assertion( n >= 1 );
03053 
03054   size_type i = 0;
03055   Storage_site_2 ss;
03056 
03057   if ( read_handle_vector ) {
03058     pc_.clear();
03059     size_type np;
03060     is >> np;
03061     for (; i < np; i++) {
03062       Point_2 p;
03063       is >> p;
03064       std::pair<Point_handle,bool> res = pc_.insert(p);
03065       P.push_back(res.first);
03066       CGAL_assertion( P[i] == res.first );
03067     }
03068 
03069     // now read the input sites container
03070     isc_.clear();
03071     size_type nisc;
03072     is >> nisc;
03073     int id1, id2;
03074     for (i = 0; i < nisc; i++) {
03075       is >> id1 >> id2;
03076       isc_.insert( Site_rep_2(P[id1], P[id2], id1 == id2) );
03077     }
03078   }
03079 
03080   if ( n == 1 ) {
03081     CGAL_assertion( d == -1 );
03082     if ( number_of_vertices() > 0 ) { clear(); }
03083     return;
03084   }
03085   if ( n == 2 ) {
03086     CGAL_assertion( d == 0 );
03087     if ( number_of_vertices() > 0 ) { clear(); }
03088     file_input(is, ss, P, Intersections_tag());
03089     insert_first(ss, *ss.point());
03090     return;
03091   }
03092   if ( n == 3 ) {
03093     CGAL_assertion( d == 1 );
03094     if ( number_of_vertices() > 0 ) { clear(); }
03095     file_input(is, ss, P, Intersections_tag());
03096     insert_first(ss, *ss.point());  
03097     file_input(is, ss, P, Intersections_tag());
03098     insert_second(ss, *ss.point());  
03099     return;
03100   }
03101 
03102   if (this->_tds.number_of_vertices() != 0) { this->_tds.clear(); }
03103 
03104   this->_tds.set_dimension(d);
03105 
03106   std::vector<Vertex_handle> V(n);
03107   std::vector<Face_handle> F(m);
03108 
03109   // first vertex (infinite vertex)
03110   V[0] = this->_tds.create_vertex();
03111   this->set_infinite_vertex(V[0]);
03112   i = 1;
03113 
03114   // read vertices
03115   for (; i < n; ++i) {
03116     V[i] = this->_tds.create_vertex();
03117     file_input(is, ss, P, Intersections_tag());
03118     V[i]->set_site(ss);
03119     // read non-combinatorial info of the vertex
03120     //    is >> *(V[i]);
03121   }
03122   
03123   // Creation of the faces
03124   int index;
03125   int dim = (dimension() == -1 ? 1 : dimension() + 1);
03126 
03127   for (i = 0; i < m; ++i) {
03128     F[i] = this->_tds.create_face();
03129     for (int j = 0; j < dim ; ++j){
03130       is >> index;
03131       F[i]->set_vertex(j, V[index]);
03132       // The face pointer of vertices is set too often,
03133       // but otherwise we had to use a further map
03134       V[index]->set_face(F[i]);
03135     }
03136     // read in non-combinatorial info of the face
03137     //      is >> *(F[i]) ;
03138   }
03139 
03140   // Setting the neighbor pointers 
03141   for (i = 0; i < m; ++i) {
03142     for (int j = 0; j < dimension()+1; ++j){
03143       is >> index;
03144       F[i]->set_neighbor(j, F[index]);
03145     }
03146   }
03147 }
03148 
03149 
03150 CGAL_END_NAMESPACE
03151 
03152 // EOF
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines