BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_S2/SM_constrained_triang_traits.h
Go to the documentation of this file.
00001 // Copyright (c) 1997-2000  Max-Planck-Institute Saarbruecken (Germany).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Nef_S2/include/CGAL/Nef_S2/SM_constrained_triang_traits.h $
00015 // $Id: SM_constrained_triang_traits.h 40851 2007-11-09 15:27:44Z ameyer $
00016 // 
00017 //
00018 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
00019 #ifndef CGAL_SM_CONSTRAINED_TRIANG_TRAITS_H
00020 #define CGAL_SM_CONSTRAINED_TRIANG_TRAITS_H
00021 
00022 #include <CGAL/basic.h>
00023 #include <CGAL/Unique_hash_map.h>
00024 #include <CGAL/generic_sweep.h>
00025 //#include <CGAL/Nef_S2/SM_checker.h>
00026 #include <string>
00027 #include <map>
00028 #include <set>
00029 #undef CGAL_NEF_DEBUG
00030 #define CGAL_NEF_DEBUG 139
00031 #include <CGAL/Nef_2/debug.h>
00032 
00033 CGAL_BEGIN_NAMESPACE
00034 
00035 /* For a detailed documentation see the MPI research report 2001-1-003 
00036    which documents the planar flavor of this baby; only minor deviations
00037    are included in this code */
00038 
00039 template <typename Decorator_, typename Kernel_>
00040 class SM_constrained_triang_traits : public Decorator_ {
00041 public:
00042   typedef SM_constrained_triang_traits<Decorator_,Kernel_> Self;
00043   typedef Decorator_                                       Base;
00044 
00045 
00046   typedef typename Kernel_::Point_2     Point;
00047   typedef typename Kernel_::Segment_2   Segment;
00048 
00049   typedef typename Base::SHalfedge_handle   SHalfedge_handle;
00050   typedef typename Base::SVertex_handle     SVertex_handle;
00051   typedef typename Base::SFace_handle       SFace_handle;
00052   typedef typename Base::SHalfedge_iterator SHalfedge_iterator;
00053   typedef typename Base::SVertex_iterator   SVertex_iterator;
00054   typedef typename Base::SFace_iterator     SFace_iterator;
00055   typedef typename Base::SHalfedge_around_svertex_circulator
00056           SHalfedge_around_svertex_circulator;
00057 
00058   // the types interfacing the sweep:
00059   typedef std::pair<SVertex_iterator,SVertex_iterator> INPUT;
00060   typedef Decorator_                                 OUTPUT;
00061   typedef Kernel_                                    GEOMETRY;
00062 
00063 
00064   class lt_edges_in_sweepline : public Decorator_
00065   {  const Point& p;
00066      const SHalfedge_handle& e_bottom;
00067      const SHalfedge_handle& e_top;
00068      const Kernel_& K;
00069   public:
00070   lt_edges_in_sweepline(const Point& pi, 
00071      const SHalfedge_handle& e1, const SHalfedge_handle& e2, 
00072      const Decorator_& D, const Kernel_& k) : 
00073        Decorator_(D), p(pi), e_bottom(e1), e_top(e2), K(k) {}
00074 
00075   lt_edges_in_sweepline(const lt_edges_in_sweepline& lt) : 
00076      Decorator_(lt), p(lt.p), 
00077      e_bottom(lt.e_bottom), e_top(lt.e_top), K(lt.K) {}
00078 
00079   Segment seg(const SHalfedge_handle& e) const
00080   { return K.construct_segment(point(source(e)),point(target(e))); }
00081 
00082   int orientation(SHalfedge_handle e, const Point& p) const
00083   { return K.orientation(e->source()->point(),e->twin()->source()->point(),p); }
00084 
00085   bool operator()(const SHalfedge_handle& e1, const SHalfedge_handle& e2) const
00086   { // Precondition:
00087     // [[p]] is identical to the source of either [[e1]] or [[e2]]. 
00088     if (e1 == e_bottom || e2 == e_top) return true;
00089     if (e2 == e_bottom || e1 == e_top) return false;
00090     if ( e1 == e2 ) return 0;
00091     int s = 0;
00092     if ( p == e1->source()->point() )
00093       s =   orientation(e2,p);
00094     else if ( p == e2->source()->point() ) 
00095       s = - orientation(e1,p);
00096     else CGAL_error_msg("compare error in sweep.");
00097     if ( s || e1->source() == e1->twin()->source() || 
00098          e2->source() == e2->twin()->source()) 
00099       return ( s < 0 );
00100     s = orientation(e2,e1->twin()->source()->point());
00101     if (s==0) CGAL_error_msg("parallel edges not allowed.");
00102     return ( s < 0 );
00103   }
00104 
00105 
00106   }; // lt_edges_in_sweepline
00107 
00108   class lt_pnts_xy : public Decorator_
00109   { const Kernel_& K;
00110   public:
00111    lt_pnts_xy(const Decorator_& D, const Kernel_& k) : Decorator_(D), K(k) {}
00112    lt_pnts_xy(const lt_pnts_xy& lt) : Decorator_(lt), K(lt.K) {}
00113    int operator()(const SVertex_handle& v1, const SVertex_handle& v2) const
00114    { return K.compare_xy(v1->point(),v2->point()) < 0; }
00115   }; // lt_pnts_xy
00116 
00117 
00118   typedef std::map<SHalfedge_handle, SHalfedge_handle, lt_edges_in_sweepline> 
00119           Sweep_status_structure; 
00120   typedef typename Sweep_status_structure::iterator   ss_iterator;
00121   typedef typename Sweep_status_structure::value_type ss_pair;
00122   typedef std::set<SVertex_iterator,lt_pnts_xy> Event_Q;
00123   typedef typename Event_Q::const_iterator event_iterator;
00124 
00125   const GEOMETRY&         K;
00126   Event_Q                 event_Q;
00127   event_iterator          event_it;         
00128   SVertex_handle           event;
00129   Point                   p_sweep;
00130   Sweep_status_structure  SL;
00131   CGAL::Unique_hash_map<SHalfedge_handle,ss_iterator> SLItem;
00132   SHalfedge_handle         e_low,e_high; // framing edges !
00133   SHalfedge_handle         e_search;
00134   SVertex_iterator         v_first, v_beyond;
00135 
00136   SM_constrained_triang_traits(const INPUT& in, OUTPUT& out, 
00137                                const GEOMETRY& k) 
00138       : Base(out), K(k), event_Q(lt_pnts_xy(*this,K)), 
00139         SL(lt_edges_in_sweepline(p_sweep,e_low,e_high,*this,K)),
00140         SLItem(SL.end()), v_first(in.first), v_beyond(in.second)
00141     { CGAL_NEF_TRACEN("Constrained Triangulation Sweep"); }
00142 
00143   /* |treat_new_sedge| is used to forward information that exists
00144      at input edges of the triangulation as such it spreads input
00145      information to the newly created edges of the triangulation;
00146      the used operation incident_mark refers to the base class of
00147      |*this| */
00148   void treat_new_edge(SHalfedge_handle e)
00149   { assoc_info(e);
00150     e->mark() = incident_mark(e) = incident_mark(e->twin()) = 
00151       incident_mark(e->snext());
00152     CGAL_NEF_TRACEN(" treat_new_edge "<<PH(e));
00153   }
00154 
00155   SHalfedge_handle new_bi_edge(SVertex_handle v1, SVertex_handle v2)
00156   { // appended at v1 and v2 adj list
00157     SHalfedge_handle e = Base::new_shalfedge_pair(v1,v2);
00158     treat_new_edge(e);
00159     return e;
00160   }
00161 
00162   SHalfedge_handle new_bi_edge(SHalfedge_handle e_bf, SHalfedge_handle e_af)
00163   { // ccw before e_bf and after e_af 
00164     SHalfedge_handle e = 
00165       Base::new_shalfedge_pair(e_bf,e_af,Base::BEFORE, Base::AFTER);
00166     treat_new_edge(e);
00167     return e;
00168   }
00169 
00170   SHalfedge_handle new_bi_edge(SVertex_handle v, SHalfedge_handle e_bf)
00171   { // appended at v's adj list and before e_bf
00172     SHalfedge_handle e = Base::new_shalfedge_pair(v,e_bf,Base::BEFORE);
00173     treat_new_edge(e);
00174     return e;
00175   }
00176 
00177   Segment segment(SHalfedge_handle e) const
00178   { return K.construct_segment(e->source()->point(),e->twin()->source()->point()); }
00179 
00180   bool is_forward(SHalfedge_handle e) const
00181   { return K.compare_xy(point(source(e)),point(target(e))) < 0; }
00182 
00183   bool edge_is_visible_from(SVertex_handle v, SHalfedge_handle e)
00184   {
00185     Point p =  v->point();
00186     Point p1 = e->source()->point();
00187     Point p2 = e->twin()->source()->point();
00188     return ( K.orientation(p1,p2,p) > 0 ); // left_turn
00189   }
00190 
00191   void triangulate_up(SHalfedge_handle& e_apex)
00192   {
00193     CGAL_NEF_TRACEN("triangulate_up "<<segment(e_apex));
00194     SVertex_handle v_apex = e_apex->source();
00195     while (true) {
00196       SHalfedge_handle e_vis = e_apex->twin()->sprev();
00197       bool in_sweep_line = (SLItem[e_vis] != SL.end()); 
00198       bool not_visible = !edge_is_visible_from(v_apex,e_vis);
00199         CGAL_NEF_TRACEN(" checking "<<in_sweep_line<<not_visible<<" "<<segment(e_vis));
00200       if ( in_sweep_line || not_visible) {
00201         CGAL_NEF_TRACEN("  STOP"); return;
00202       }
00203       SHalfedge_handle e_back = new_bi_edge(e_apex,e_vis);
00204       e_apex = e_back;
00205       CGAL_NEF_TRACEN(" produced " << segment(e_apex));
00206     }
00207   }
00208 
00209   void triangulate_down(SHalfedge_handle& e_apex)
00210   {
00211     CGAL_NEF_TRACEN("triangulate_down "<<segment(e_apex));
00212     SVertex_handle v_apex = e_apex->source();
00213     while (true) {
00214       SHalfedge_handle e_vis = e_apex->snext();
00215       bool in_sweep_line = (SLItem[e_vis] != SL.end());
00216       bool not_visible = !edge_is_visible_from(v_apex,e_vis);
00217         CGAL_NEF_TRACEN(" checking "<<in_sweep_line<<not_visible<<" "<<segment(e_vis));
00218       if ( in_sweep_line || not_visible) {
00219           CGAL_NEF_TRACEN("  STOP"); return;
00220       }
00221       SHalfedge_handle e_vis_rev = e_vis->twin();
00222       SHalfedge_handle e_forw = new_bi_edge(e_vis_rev,e_apex);
00223       e_apex = e_forw->twin();
00224       CGAL_NEF_TRACEN(" produced " << segment(e_apex));
00225     }
00226   }
00227 
00228   void triangulate_between(SHalfedge_handle e_upper, SHalfedge_handle e_lower)
00229   {
00230     // we triangulate the interior of the whole chain between
00231     // target(e_upper) and target(e_lower)
00232     CGAL_assertion(e_upper->source()==e_lower->source());
00233     CGAL_NEF_TRACE("triangulate_between\n   "<<segment(e_upper));
00234     CGAL_NEF_TRACEN("\n   "<<segment(e_lower));
00235     SHalfedge_handle e_end = e_lower->twin();
00236     while (true) {
00237       SHalfedge_handle e_vis =  e_upper->snext();
00238       SHalfedge_handle en_vis = e_vis->snext();
00239       CGAL_NEF_TRACEN(" working on base e_vis " << segment(e_vis));
00240       CGAL_NEF_TRACEN(" next is " << segment(en_vis));
00241       if (en_vis == e_end) return;
00242       e_upper = new_bi_edge(e_vis->twin(),e_upper)->twin();
00243       CGAL_NEF_TRACEN(" produced " << segment(e_upper));
00244     } 
00245   }
00246 
00247   void process_event() 
00248   {
00249       CGAL_NEF_TRACEN("\nPROCESS_EVENT " << p_sweep);
00250     SHalfedge_handle e, ep, eb_low, eb_high, e_end;
00251     if ( !is_isolated(event) ) {
00252       e = last_out_edge(event);
00253       ep = first_out_edge(event);
00254     }
00255     ss_iterator sit_pred, sit;
00256     /* PRECONDITION:
00257        only ingoing => e is lowest in ingoing bundle
00258        only outgoing => e is highest in outgoing bundle
00259        ingoing and outgoing => e is lowest in ingoing bundle */
00260     eb_high = e_end = ep;
00261     eb_low = e;
00262     CGAL_NEF_TRACEN("determining handle in SL");
00263     if ( e != SHalfedge_handle() ) {
00264       e_search->twin()->source()->point() = p_sweep; // degenerate loop edge
00265       sit_pred = SLItem[e];
00266       if ( sit_pred != SL.end())  sit = --sit_pred;
00267       else  sit = sit_pred = --SL.upper_bound(e_search);
00268     } else { // event is isolated vertex
00269       e_search->twin()->source()->point() = p_sweep; // degenerate loop edge
00270       sit_pred = --SL.upper_bound(e_search);
00271     }
00272 
00273     bool ending_edges(0), starting_edges(0);
00274     while ( e != SHalfedge_handle() ) { // walk adjacency list clockwise
00275       if ( SLItem[e] != SL.end() ) 
00276       {
00277         CGAL_NEF_TRACEN("ending " << segment(e));
00278         if (ending_edges) triangulate_between(e,cyclic_adj_succ(e));
00279         ending_edges = true;
00280         SL.erase(SLItem[e]);
00281         link_bi_edge_to(e,SL.end());
00282         // not in SL anymore
00283       }
00284       else
00285       {
00286         CGAL_NEF_TRACEN("starting "<<segment(e));
00287         sit = SL.insert(sit,ss_pair(e,e));
00288         link_bi_edge_to(e,sit);
00289         if ( !starting_edges ) eb_high = cyclic_adj_succ(e);
00290         starting_edges = true;
00291       }
00292 
00293       if (e == e_end) break;
00294       e = cyclic_adj_pred(e);
00295     }
00296     if (!ending_edges) 
00297     {
00298       SHalfedge_handle e_vis = sit_pred->second;
00299       SHalfedge_handle e_vis_n = cyclic_adj_succ(e_vis);
00300       eb_low = eb_high = new_bi_edge(event,e_vis_n); 
00301       CGAL_NEF_TRACEN(" producing link "<<segment(eb_low)<<
00302              "\n    before "<<segment(e_vis_n));
00303     }
00304 
00305     triangulate_up(eb_high);
00306     triangulate_down(eb_low);
00307     sit_pred->second = eb_low;
00308   }
00309 
00310   bool event_exists() 
00311   { if ( event_it != event_Q.end() ) {
00312       // event is set at end of loop and in init
00313       event = *event_it;
00314       p_sweep = event->point();
00315       return true;
00316     }
00317     return false; 
00318   }
00319 
00320   void procede_to_next_event() 
00321   { ++event_it; }
00322 
00323   void link_bi_edge_to(SHalfedge_handle e, ss_iterator sit) {
00324     SLItem[e] = SLItem[e->twin()] = sit; 
00325   }
00326 
00327   void initialize_structures()
00328   {
00329       CGAL_NEF_TRACEN("initialize_structures ");
00330     
00331     for ( event = v_first; event != v_beyond; ++event )
00332       event_Q.insert(event); // sorted order of vertices
00333 
00334     event_it = event_Q.begin();
00335     if ( event_Q.empty() ) return;
00336     event = *event_it;
00337     p_sweep = event->point(); 
00338     if ( !is_isolated(event) ) {
00339       SHalfedge_around_svertex_circulator 
00340         e(first_out_edge(event)), eend(e);
00341       CGAL_For_all(e,eend) {
00342         CGAL_NEF_TRACEN("init with "<<PH(e));
00343         ss_iterator sit = SL.insert(ss_pair(e,e)).first;
00344         link_bi_edge_to(e,sit);
00345       }
00346     }
00347 
00348 
00349     SVertex_handle v_tmp = new_svertex(Point());
00350     e_high = Base::new_shalfedge_pair(event,v_tmp);
00351     e_low  = Base::new_shalfedge_pair(event,v_tmp);
00352     // this are two symbolic edges just accessed as sentinels
00353     // they carry no geometric information
00354     e_search = Base::new_shalfedge_pair(v_tmp,v_tmp);
00355     // this is just a loop used for searches in SL
00356 
00357     ss_iterator sit_high = SL.insert(ss_pair(e_high,e_high)).first;
00358     ss_iterator sit_low  = SL.insert(ss_pair(e_low,e_low)).first;
00359     // inserting sentinels into SL
00360     link_bi_edge_to(e_high, sit_high);
00361     link_bi_edge_to(e_low , sit_low);
00362     // we mark them being in the sweepline, which they will never leave 
00363 
00364 
00365     // we move to the second vertex:
00366     procede_to_next_event();
00367     event_exists(); // sets p_sweep for check invariants
00368     CGAL_NEF_TRACEN("EOF initialization");
00369   }
00370 
00371   void complete_structures() 
00372   {
00373     if (e_low != SHalfedge_handle()) {
00374       delete_vertex(e_search->twin()->source());
00375     } // removing sentinels and e_search
00376   }
00377 
00378 
00379   void check_ccw_local_embedding() const
00380   { 
00381 #ifdef CGAL_CHECK_EXPENSIVEXXX
00382     PM_checker<Decorator_,Kernel_> C(*this,K); 
00383     C.check_order_preserving_embedding(event);
00384 #endif
00385   }
00386 
00387   void check_invariants()
00388   {
00389 #ifdef CGAL_CHECK_EXPENSIVEXXX
00390     if ( event_it == event_Q.end() ) return;
00391     check_ccw_local_embedding();
00392 #endif
00393   }
00394 
00395   void check_final()
00396   {
00397 #ifdef CGAL_CHECK_EXPENSIVEXXX
00398     PM_checker<Decorator_,Kernel_> C(*this,K); C.check_is_triangulation();
00399 #endif
00400   }
00401 
00402 }; // SM_constrained_triang_traits<Decorator_,Kernel_,New_edge_>
00403 
00404 
00405 CGAL_END_NAMESPACE
00406 #endif // CGAL_SM_CONSTRAINED_TRIANG_TRAITS_H
00407 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines