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