From 9a83a5f8649c9b93a484f97eb7de83ef30059a3d Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Wed, 10 Jan 2007 17:30:22 +0000 Subject: [PATCH] added dcel template --- .../CGAL/Boolean_set_operations_2/Gps_utils.h | 206 +-- .../include/CGAL/General_polygon_set_2.h | 1544 ++++++++--------- .../include/CGAL/Polygon_set_2.h | 52 +- 3 files changed, 870 insertions(+), 932 deletions(-) diff --git a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_utils.h b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_utils.h index 9c0b37b3808..1ee5e6efc34 100644 --- a/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_utils.h +++ b/Boolean_set_operations_2/include/CGAL/Boolean_set_operations_2/Gps_utils.h @@ -25,16 +25,14 @@ #include #include #include +#include #include #include - - -template - void General_polygon_set_2:: - construct_polygon(Ccb_halfedge_const_circulator ccb, - Polygon_2& pgn, - Traits_* tr) +template +void General_polygon_set_2:: +construct_polygon(Ccb_halfedge_const_circulator ccb, Polygon_2 & pgn, + Traits_ * tr) { typedef CGAL::Ccb_curve_iterator Ccb_curve_iterator; Ccb_curve_iterator begin(ccb, false); @@ -48,15 +46,15 @@ template class Arr_bfs_scanner { public: - - typedef typename Arrangement::Traits_2 Gps_traits; - typedef typename Gps_traits::Polygon_2 Polygon_2; - typedef typename Gps_traits::Polygon_with_holes_2 Polygon_with_holes_2; + typedef typename Arrangement::Traits_2 Gps_traits; + typedef typename Arrangement::Dcel My_gps_dcel; + typedef typename Gps_traits::Polygon_2 Polygon_2; + typedef typename Gps_traits::Polygon_with_holes_2 Polygon_with_holes_2; typedef typename Arrangement::Ccb_halfedge_const_circulator - Ccb_halfedge_const_circulator; - typedef typename Arrangement::Face_const_iterator Face_const_iterator; - typedef typename Arrangement::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Arrangement::Hole_const_iterator Hole_const_iterator; + Ccb_halfedge_const_circulator; + typedef typename Arrangement::Face_const_iterator Face_const_iterator; + typedef typename Arrangement::Halfedge_const_iterator Halfedge_const_iterator; + typedef typename Arrangement::Hole_const_iterator Hole_const_iterator; protected: @@ -79,7 +77,7 @@ public: Hole_const_iterator holes_it; Face_const_iterator fit; - if(!ubf->contained()) + if (!ubf->contained()) { ubf->set_visited(true); for (holes_it = ubf->holes_begin(); @@ -123,13 +121,14 @@ public: void scan_ccb(Ccb_halfedge_const_circulator ccb) { Polygon_2 pgn_boundary; - General_polygon_set_2::construct_polygon(ccb, pgn_boundary, m_traits); + General_polygon_set_2:: + construct_polygon(ccb, pgn_boundary, m_traits); Ccb_halfedge_const_circulator ccb_end = ccb; do { Halfedge_const_iterator he = ccb; - if(!he->twin()->face()->visited()) + if (!he->twin()->face()->visited()) all_incident_faces(he->twin()->face()); ++ccb; } @@ -161,12 +160,13 @@ public: { CGAL_assertion(!f->visited()); f->set_visited(true); - if(!f->is_unbounded()) + if (!f->is_unbounded()) { - if(!f->contained()) + if (!f->contained()) { m_pgn_holes.push_back(Polygon_2()); - General_polygon_set_2::construct_polygon(f->outer_ccb(), m_pgn_holes.back(), m_traits); + General_polygon_set_2:: + construct_polygon(f->outer_ccb(), m_pgn_holes.back(), m_traits); m_holes_q.push(f); } @@ -178,7 +178,7 @@ public: //get the current halfedge on the face boundary Halfedge_const_iterator he = ccb_circ; Face_const_iterator new_f = he->twin()->face(); - if(!new_f->visited()) + if (!new_f->visited()) { all_incident_faces(new_f); } @@ -187,20 +187,21 @@ public: while(ccb_circ != ccb_end); } - if(f->contained()) + if (f->contained()) { Hole_const_iterator hit; for(hit = f->holes_begin(); hit != f->holes_end(); ++hit) { Ccb_halfedge_const_circulator ccb_of_hole = *hit; Halfedge_const_iterator he = ccb_of_hole; - if(is_single_face(ccb_of_hole)) + if (is_single_face(ccb_of_hole)) { CGAL_assertion(!he->twin()->face()->contained()); m_pgn_holes.push_back(Polygon_2()); - General_polygon_set_2::construct_polygon - (he->twin()->face()->outer_ccb(), m_pgn_holes.back(), m_traits); + General_polygon_set_2:: + construct_polygon(he->twin()->face()->outer_ccb(), + m_pgn_holes.back(), m_traits); m_holes_q.push(he->twin()->face()); } @@ -210,7 +211,7 @@ public: do { Halfedge_const_iterator he = ccb_of_hole; - if(!he->twin()->face()->visited()) + if (!he->twin()->face()->visited()) all_incident_faces(he->twin()->face()); ++ccb_of_hole; } @@ -230,9 +231,9 @@ public: { //get the current halfedge on the face boundary Halfedge_const_iterator he = ccb_circ; - if(he->twin()->face() != curr_f) + if (he->twin()->face() != curr_f) return false; - if(he->twin()->target()->degree() != 2) + if (he->twin()->target()->degree() != 2) return false; ++ccb_circ; } @@ -242,7 +243,7 @@ public: }; -template +template class Init_faces_visitor { typedef typename Arrangement::Face_iterator Face_iterator; @@ -256,28 +257,27 @@ public: } }; -template < class Traits_> -void General_polygon_set_2::_insert(const Polygon_2& pgn, Arrangement_2& arr) +template +void General_polygon_set_2:: +_insert(const Polygon_2& pgn, Arrangement_2 & arr) { CGAL_precondition(m_traits->is_valid_2_object()(pgn)); typedef Arr_accessor Arr_accessor; Arr_accessor accessor(arr); - Compare_endpoints_xy_2 cmp_ends = - m_traits->compare_endpoints_xy_2_object(); + Compare_endpoints_xy_2 cmp_ends = m_traits->compare_endpoints_xy_2_object(); - std::pair itr_pair = + std::pair itr_pair = m_traits->construct_curves_2_object()(pgn); - if(itr_pair.first == itr_pair.second) + if (itr_pair.first == itr_pair.second) return; Curve_const_iterator curr = itr_pair.first; Curve_const_iterator end = itr_pair.second; Face_iterator f; - if(arr.is_empty()) + if (arr.is_empty()) { f = arr.unbounded_face(); } @@ -298,7 +298,7 @@ void General_polygon_set_2::_insert(const Polygon_2& pgn, Arrangement_2 //first_he is directed from left to right (see insert_in_face_interior) Halfedge_handle curr_he; - if(cmp_ends(*curr) == CGAL::SMALLER) + if (cmp_ends(*curr) == CGAL::SMALLER) { // curr curve and first_he have the same direction curr_he = first_he; @@ -313,7 +313,7 @@ void General_polygon_set_2::_insert(const Polygon_2& pgn, Arrangement_2 Curve_const_iterator temp = curr; ++temp; - if(temp == end) // a polygon with circular arcs may have only + if (temp == end) // a polygon with circular arcs may have only // two edges (full circle for example) { /*Halfedge_handle he = @@ -338,7 +338,7 @@ void General_polygon_set_2::_insert(const Polygon_2& pgn, Arrangement_2 for(++curr ; curr != last; ++curr) { const X_monotone_curve_2& curr_cv = *curr; - if(cmp_ends(curr_cv) == CGAL::SMALLER) + if (cmp_ends(curr_cv) == CGAL::SMALLER) curr_he = arr.insert_from_left_vertex(curr_cv, curr_he); else { @@ -365,21 +365,20 @@ void General_polygon_set_2::_insert(const Polygon_2& pgn, Arrangement_2 } -template < class Traits_ > - template< class PolygonIter > -void General_polygon_set_2::insert(PolygonIter p_begin, - PolygonIter p_end) +template +template +void General_polygon_set_2:: +insert(PolygonIter p_begin, PolygonIter p_end) { typename std::iterator_traits::value_type pgn; _insert(p_begin, p_end, pgn); } -template < class Traits_ > - template< class PolygonIter, class PolygonWithHolesIter> -void General_polygon_set_2::insert(PolygonIter p_begin, - PolygonIter p_end, - PolygonWithHolesIter pwh_begin, - PolygonWithHolesIter pwh_end) +template +template +void General_polygon_set_2:: +insert(PolygonIter p_begin, PolygonIter p_end, + PolygonWithHolesIter pwh_begin, PolygonWithHolesIter pwh_end) { typedef std::list XCurveList; typedef Init_faces_visitor My_visitor; @@ -402,7 +401,7 @@ void General_polygon_set_2::insert(PolygonIter p_begin, } insert_non_intersecting_curves(*m_arr, xcurve_list.begin(), xcurve_list.end()); - if(is_unbounded) + if (is_unbounded) m_arr->unbounded_face()->set_contained(true); My_visitor v; @@ -412,11 +411,10 @@ void General_polygon_set_2::insert(PolygonIter p_begin, } //insert a range of simple polygons to the arrangement -template < class Traits_ > - template< class PolygonIter > -void General_polygon_set_2::_insert(PolygonIter p_begin, - PolygonIter p_end, - Polygon_2& /*pgn*/) +template +template +void General_polygon_set_2:: +_insert(PolygonIter p_begin, PolygonIter p_end, Polygon_2 & /*pgn*/) { for(PolygonIter pitr = p_begin; pitr != p_end; ++pitr) { @@ -425,11 +423,10 @@ void General_polygon_set_2::_insert(PolygonIter p_begin, } } -template < class Traits_ > - template< class PolygonIter > -void General_polygon_set_2::_insert(PolygonIter p_begin, - PolygonIter p_end, - Polygon_with_holes_2& /*pgn*/) +template +template +void General_polygon_set_2:: +_insert(PolygonIter p_begin, PolygonIter p_end, Polygon_with_holes_2 & /*pgn*/) { typedef std::list XCurveList; typedef Init_faces_visitor My_visitor; @@ -446,7 +443,7 @@ void General_polygon_set_2::_insert(PolygonIter p_begin, } insert_non_intersecting_curves(*m_arr, xcurve_list.begin(), xcurve_list.end()); - if(is_unbounded) + if (is_unbounded) m_arr->unbounded_face()->set_contained(true); My_visitor v; @@ -460,8 +457,9 @@ void General_polygon_set_2::_insert(PolygonIter p_begin, //insert non-sipmle poloygons with holes (non incident edges may have // common vertex, but they dont intersect at their interior -template -void General_polygon_set_2::_insert (const Polygon_with_holes_2& pgn, Arrangement_2& arr) +template +void General_polygon_set_2:: +_insert(const Polygon_with_holes_2 & pgn, Arrangement_2 & arr) { CGAL_precondition(m_traits->is_valid_2_object()(pgn)); typedef std::list XCurveList; @@ -472,7 +470,7 @@ void General_polygon_set_2::_insert (const Polygon_with_holes_2& pgn, A _construct_curves(pgn, std::back_inserter(xcurve_list)); insert_non_intersecting_curves(arr, xcurve_list.begin(), xcurve_list.end()); - if(pgn.is_unbounded()) + if (pgn.is_unbounded()) arr.unbounded_face()->set_contained(true); My_visitor v; @@ -481,11 +479,11 @@ void General_polygon_set_2::_insert (const Polygon_with_holes_2& pgn, A _reset_faces(&arr); } -template - template +template +template void - General_polygon_set_2::_construct_curves(const Polygon_2& pgn, - OutputIterator oi) +General_polygon_set_2:: +_construct_curves(const Polygon_2 & pgn, OutputIterator oi) { std::pair itr_pair = @@ -493,13 +491,13 @@ void std::copy (itr_pair.first, itr_pair.second, oi); } -template - template +template +template void -General_polygon_set_2::_construct_curves(const Polygon_with_holes_2& pgn, - OutputIterator oi) +General_polygon_set_2:: +_construct_curves(const Polygon_with_holes_2 & pgn, OutputIterator oi) { - if(!pgn.is_unbounded()) + if (!pgn.is_unbounded()) { const Polygon_2& pgn_boundary = pgn.outer_boundary(); std::pair::_construct_curves(const Polygon_with_holes_2& pg } } -template - template< class OutputIterator > - OutputIterator - General_polygon_set_2::polygons_with_holes(OutputIterator out) const +template +template +OutputIterator +General_polygon_set_2:: +polygons_with_holes(OutputIterator out) const { typedef Arr_bfs_scanner Arr_bfs_scanner; Arr_bfs_scanner scanner(this->m_traits, out); @@ -531,35 +530,38 @@ template } -template < class Traits_ > -typename General_polygon_set_2::Size -General_polygon_set_2::number_of_polygons_with_holes() const +template +typename General_polygon_set_2::Size +General_polygon_set_2:: +number_of_polygons_with_holes() const { - typedef Arr_bfs_scanner Arr_bfs_scanner; + typedef Arr_bfs_scanner + Arr_bfs_scanner; Counting_output_iterator coi; Arr_bfs_scanner scanner(this->m_traits, coi); scanner.scan(*(this->m_arr)); return (scanner.output_iterator().current_counter()); } -template < class Traits_ > -bool General_polygon_set_2::locate(const Point_2& q, Polygon_with_holes_2& pgn) const +template +bool General_polygon_set_2:: +locate(const Point_2& q, Polygon_with_holes_2& pgn) const { Walk_pl pl(*m_arr); Object obj = pl.locate(q); Face_const_iterator f; - if(CGAL::assign(f, obj)) + if (CGAL::assign(f, obj)) { - if(!f->contained()) + if (!f->contained()) return false; } else { Halfedge_const_handle he; - if(CGAL::assign(he, obj)) + if (CGAL::assign(he, obj)) { - if(he->face()->contained()) + if (he->face()->contained()) f = he->face(); else { @@ -574,7 +576,7 @@ bool General_polygon_set_2::locate(const Point_2& q, Polygon_with_holes CGAL::assign(v, obj); Halfedge_around_vertex_const_circulator hav = v->incident_halfedges(); Halfedge_const_handle he = hav; - if(he->face()->contained()) + if (he->face()->contained()) f = he->face(); else { @@ -593,7 +595,7 @@ bool General_polygon_set_2::locate(const Point_2& q, Polygon_with_holes Ccb_halfedge_const_circulator ccb_of_pgn = get_boundary_of_polygon(f); this->_reset_faces(); - if(ccb_of_pgn == Ccb_halfedge_const_circulator()) // the polygon has no boundary + if (ccb_of_pgn == Ccb_halfedge_const_circulator()) // the polygon has no boundary { // f is unbounded scanner.scan_contained_ubf(m_arr->unbounded_face()); @@ -610,14 +612,15 @@ bool General_polygon_set_2::locate(const Point_2& q, Polygon_with_holes return true; } -template < class Traits_ > -typename General_polygon_set_2::Ccb_halfedge_const_circulator - General_polygon_set_2::get_boundary_of_polygon(Face_const_iterator f) const +template +typename General_polygon_set_2::Ccb_halfedge_const_circulator +General_polygon_set_2:: +get_boundary_of_polygon(Face_const_iterator f) const { CGAL_assertion(!f->visited()); f->set_visited(true); - if(f->is_unbounded()) + if (f->is_unbounded()) { return Ccb_halfedge_const_circulator(); } @@ -628,9 +631,9 @@ typename General_polygon_set_2::Ccb_halfedge_const_circulator //get the current halfedge on the face boundary Halfedge_const_iterator he = ccb_circ; Face_const_iterator new_f = he->twin()->face(); - if(!new_f->visited()) + if (!new_f->visited()) { - if(is_hole_of_face(new_f, he) && !new_f->contained()) + if (is_hole_of_face(new_f, he) && !new_f->contained()) return (he->twin()); return (get_boundary_of_polygon(new_f)); } @@ -642,10 +645,9 @@ typename General_polygon_set_2::Ccb_halfedge_const_circulator } -template < class Traits_ > -bool General_polygon_set_2:: - is_hole_of_face(Face_const_handle f, - Halfedge_const_handle he) const +template +bool General_polygon_set_2:: +is_hole_of_face(Face_const_handle f, Halfedge_const_handle he) const { Hole_const_iterator holes_it; for (holes_it = f->holes_begin(); holes_it != f->holes_end(); ++holes_it) @@ -656,7 +658,7 @@ bool General_polygon_set_2:: { Halfedge_const_handle he_inside_hole = ccb; he_inside_hole = he_inside_hole->twin(); - if(he == he_inside_hole) + if (he == he_inside_hole) return true; ++ccb; diff --git a/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h b/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h index 4fa07ce3f16..835f5a18024 100644 --- a/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h +++ b/Boolean_set_operations_2/include/CGAL/General_polygon_set_2.h @@ -16,10 +16,20 @@ // // // Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_GENERAL_POLYGON_SET_2_H #define CGAL_GENERAL_POLYGON_SET_2_H +#include +#include +#include +#include +#include +#include +#include + +#include #include #include #include @@ -27,32 +37,21 @@ #include #include #include - #include - - -#include - -#include -#include -#include -#include -#include -#include #include CGAL_BEGIN_NAMESPACE // General_polygon_set_2 -template < class Traits_ > +template > class General_polygon_set_2 { public: - typedef Traits_ Traits_2; + typedef Dcel_ Dcel; typedef typename Traits_2::Polygon_2 Polygon_2; typedef typename Traits_2::Polygon_with_holes_2 Polygon_with_holes_2; - typedef Arrangement_2 > Arrangement_2; + typedef Arrangement_2 Arrangement_2; typedef std::size_t Size; private: @@ -61,35 +60,37 @@ private: typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; typedef typename Polygon_with_holes_2::Hole_const_iterator - GP_Holes_const_iterator; + GP_Holes_const_iterator; typedef typename Traits_2::Curve_const_iterator Curve_const_iterator; - typedef typename Traits_2::Compare_endpoints_xy_2 Compare_endpoints_xy_2; + typedef typename Traits_2::Compare_endpoints_xy_2 + Compare_endpoints_xy_2; typedef typename Traits_2::Construct_opposite_2 Construct_opposite_2; - typedef typename Arrangement_2::Face_const_iterator Face_const_iterator; - typedef typename Arrangement_2::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator; - typedef typename Arrangement_2::Edge_const_iterator Edge_const_iterator; - typedef typename Arrangement_2::Hole_const_iterator Hole_const_iterator; + typedef typename Arrangement_2::Face_const_iterator Face_const_iterator; + typedef typename Arrangement_2::Halfedge_const_iterator + Halfedge_const_iterator; + typedef typename Arrangement_2::Vertex_const_iterator Vertex_const_iterator; + typedef typename Arrangement_2::Edge_const_iterator Edge_const_iterator; + typedef typename Arrangement_2::Hole_const_iterator Hole_const_iterator; typedef typename Arrangement_2::Ccb_halfedge_const_circulator - Ccb_halfedge_const_circulator; - typedef typename Arrangement_2::Face_iterator Face_iterator; - typedef typename Arrangement_2::Halfedge_iterator Halfedge_iterator; - typedef typename Arrangement_2::Vertex_iterator Vertex_iterator; - typedef typename Arrangement_2::Edge_iterator Edge_iterator; - typedef typename Arrangement_2::Hole_iterator Hole_iterator; + Ccb_halfedge_const_circulator; + typedef typename Arrangement_2::Face_iterator Face_iterator; + typedef typename Arrangement_2::Halfedge_iterator Halfedge_iterator; + typedef typename Arrangement_2::Vertex_iterator Vertex_iterator; + typedef typename Arrangement_2::Edge_iterator Edge_iterator; + typedef typename Arrangement_2::Hole_iterator Hole_iterator; typedef typename Arrangement_2::Ccb_halfedge_circulator - Ccb_halfedge_circulator; - typedef typename Arrangement_2::Face_handle Face_handle; - typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; - typedef typename Arrangement_2::Vertex_handle Vertex_handle; + Ccb_halfedge_circulator; + typedef typename Arrangement_2::Face_handle Face_handle; + typedef typename Arrangement_2::Halfedge_handle Halfedge_handle; + typedef typename Arrangement_2::Vertex_handle Vertex_handle; - typedef typename Arrangement_2::Face_const_handle Face_const_handle; - typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; - typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; + typedef typename Arrangement_2::Face_const_handle Face_const_handle; + typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle; + typedef typename Arrangement_2::Vertex_const_handle Vertex_const_handle; typedef typename Arrangement_2::Halfedge_around_vertex_const_circulator - Halfedge_around_vertex_const_circulator; + Halfedge_around_vertex_const_circulator; typedef std::pair *> Arr_entry; @@ -120,18 +121,19 @@ public: {} - General_polygon_set_2(const Self& ps): m_traits(new Traits_2(*(ps.m_traits))), - m_traits_owner(true), - m_arr(new Arrangement_2(*(ps.m_arr))) + General_polygon_set_2(const Self& ps) : + m_traits(new Traits_2(*(ps.m_traits))), + m_traits_owner(true), + m_arr(new Arrangement_2(*(ps.m_arr))) {} General_polygon_set_2& operator=(const Self& ps) { - if(this == &ps) + if (this == &ps) return (*this); - if(m_traits_owner) + if (m_traits_owner) delete m_traits; delete m_arr; m_traits = new Traits_2(*(ps.m_traits)); @@ -165,16 +167,13 @@ private: m_arr(arr) {} - public: - - - +public: //destructor virtual ~General_polygon_set_2() { delete m_arr; - if(m_traits_owner) + if (m_traits_owner) delete m_traits; } @@ -222,14 +221,11 @@ private: // precondition: the first range is disjoint simple polygons // the second range is disjoint polygons with holes template - void insert(PolygonIterator pgn_begin, - PolygonIterator pgn_end, - PolygonWithHolesIterator pgn_with_holes_begin, - PolygonWithHolesIterator pgn_with_holes_end); + void insert(PolygonIterator pgn_begin, PolygonIterator pgn_end, + PolygonWithHolesIterator pgn_with_holes_begin, + PolygonWithHolesIterator pgn_with_holes_end); - - - // test for intersection with a simple polygon + // test for intersection with a simple polygon bool do_intersect(const Polygon_2 &pgn) const { CGAL_precondition(m_traits->is_valid_2_object()(pgn)); @@ -248,10 +244,10 @@ private: //test for intersection with another General_polygon_set_2 object bool do_intersect(const Self& other) const { - if(this->is_empty() || other.is_empty()) + if (this->is_empty() || other.is_empty()) return false; - if(this->is_plane() || other.is_plane()) + if (this->is_plane() || other.is_plane()) return true; Arrangement_2 res_arr; @@ -401,7 +397,7 @@ private: // TODO: move to private (or prot. area) void _complement(Arrangement_2* arr) { - for(Face_iterator fit = arr->faces_begin(); + for (Face_iterator fit = arr->faces_begin(); fit != arr->faces_end(); ++fit) { @@ -409,7 +405,7 @@ private: } Construct_opposite_2 ctr_opp = m_traits->construct_opposite_2_object(); - for(Edge_iterator eit = arr->edges_begin(); + for (Edge_iterator eit = arr->edges_begin(); eit != arr->edges_end(); ++eit) { @@ -427,7 +423,7 @@ private: m_traits->compare_endpoints_xy_2_object(); Construct_opposite_2 ctr_opp = m_traits->construct_opposite_2_object(); - for(Edge_iterator eit = arr.edges_begin(); + for (Edge_iterator eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) { @@ -435,7 +431,7 @@ private: X_monotone_curve_2& cv = he->curve(); bool is_cont = he->face()->contained(); bool has_same_dir = (cmp_endpoints(cv) == he->direction()); - if((is_cont && !has_same_dir) || + if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir)) arr.modify_edge(he, ctr_opp(cv)); } @@ -480,9 +476,9 @@ private: Object obj = pl.locate(q); Face_const_iterator f; - if(CGAL::assign(f, obj)) + if (CGAL::assign(f, obj)) { - if(f->contained()) + if (f->contained()) return ON_POSITIVE_SIDE; return ON_NEGATIVE_SIDE ; @@ -506,10 +502,10 @@ private: Oriented_side oriented_side(const Self& other) const { - if(this->is_empty() || other.is_empty()) + if (this->is_empty() || other.is_empty()) return ON_NEGATIVE_SIDE; - if(this->is_plane() || other.is_plane()) + if (this->is_plane() || other.is_plane()) return ON_POSITIVE_SIDE; Arrangement_2 res_arr; @@ -519,7 +515,7 @@ private: if (func.found_reg_intersection()) return ON_POSITIVE_SIDE; - if(func.found_boundary_intersection()) + if (func.found_boundary_intersection()) return ON_ORIENTED_BOUNDARY; return ON_NEGATIVE_SIDE; @@ -537,30 +533,30 @@ private: bool is_valid() const { - if(!CGAL::is_valid(*m_arr)) + if (!CGAL::is_valid(*m_arr)) return false; Compare_endpoints_xy_2 cmp_endpoints = m_traits->compare_endpoints_xy_2_object(); Construct_opposite_2 ctr_opp = m_traits->construct_opposite_2_object(); - for(Edge_const_iterator eci = m_arr->edges_begin(); + for (Edge_const_iterator eci = m_arr->edges_begin(); eci != m_arr->edges_end(); ++eci) { Halfedge_const_handle he = eci; - if(he->face() == he->twin()->face()) + if (he->face() == he->twin()->face()) { return false; } - if(he->face()->contained() == he->twin()->face()->contained()) + if (he->face()->contained() == he->twin()->face()->contained()) { return false; } const X_monotone_curve_2& cv = he->curve(); bool is_cont = he->face()->contained(); bool has_same_dir = (cmp_endpoints(cv) == he->direction()); - if((is_cont && !has_same_dir) || + if ((is_cont && !has_same_dir) || (!is_cont && has_same_dir)) return false; } @@ -572,783 +568,729 @@ private: template OutputIterator polygons_with_holes(OutputIterator out) const; - // join a range of polygons - template - void join(InputIterator begin, InputIterator end, unsigned int k = 5) -{ - typename std::iterator_traits::value_type pgn; - this->join(begin, end, pgn, k); - this->remove_redundant_edges(); - this->_reset_faces(); -} + // join a range of polygons + template + void join(InputIterator begin, InputIterator end, unsigned int k = 5) + { + typename std::iterator_traits::value_type pgn; + this->join(begin, end, pgn, k); + this->remove_redundant_edges(); + this->_reset_faces(); + } -// join range of simple polygons -template -inline void join(InputIterator begin, - InputIterator end, - Polygon_2& pgn, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin, end) + 1); + // join range of simple polygons + template + inline void join(InputIterator begin, + InputIterator end, + Polygon_2& pgn, + unsigned int k=5) + { + std::vector arr_vec (std::distance(begin, end) + 1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - for(InputIterator itr = begin; itr!=end; ++itr, ++i) - { - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr, *(arr_vec[i].first)); - } - - Join_merge join_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; -} - - -//join range of polygons with holes -template -inline void join(InputIterator begin, - InputIterator end, - Polygon_with_holes_2& pgn, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin, end) + 1); - arr_vec[0].first = this->m_arr; - - unsigned int i = 1; - for(InputIterator itr = begin; itr!=end; ++itr, ++i) - { - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr, *(arr_vec[i].first)); - } - - Join_merge join_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; -} - -template -inline void join(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin1, end1)+ - std::distance(begin2, end2)+1); - - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) - { - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr1, *(arr_vec[i].first)); - } - - for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) - { - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr2, *(arr_vec[i].first)); - } - - Join_merge join_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; - this->remove_redundant_edges(); - this->_reset_faces(); -} - - -// intersect range of polygins -template -inline void intersection(InputIterator begin, InputIterator end, unsigned int k=5) -{ - typename std::iterator_traits::value_type pgn; - this->intersection(begin, end, pgn, k); - this->remove_redundant_edges(); - this->_reset_faces(); -} - - -// intersect range of simple polygons -template -inline void intersection(InputIterator begin, - InputIterator end, - Polygon_2& pgn, - unsigned int k) -{ - std::vector arr_vec (std::distance(begin, end) + 1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator itr = begin; itr!=end; ++itr, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr, *(arr_vec[i].first)); - } - - Intersection_merge intersection_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; -} - -//intersect range of polygons with holes -template -inline void intersection(InputIterator begin, - InputIterator end, - Polygon_with_holes_2& pgn, - unsigned int k) -{ - std::vector arr_vec (std::distance(begin, end) + 1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator itr = begin; itr!=end; ++itr, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr, *(arr_vec[i].first)); - } - - Intersection_merge intersection_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; -} - - -template -inline void intersection(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin1, end1)+ - std::distance(begin2, end2)+1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr1)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr1, *(arr_vec[i].first)); - } - - for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr2)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr2, *(arr_vec[i].first)); - } - - Intersection_merge intersection_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; - this->remove_redundant_edges(); - this->_reset_faces(); -} - - - -// symmetric_difference of a range of polygons (similar to xor) -template -inline void symmetric_difference(InputIterator begin, InputIterator end, - unsigned int k=5) -{ - typename std::iterator_traits::value_type pgn; - this->symmetric_difference(begin, end, pgn, k); - this->remove_redundant_edges(); - this->_reset_faces(); -} - - -// intersect range of simple polygons -template -inline void symmetric_difference(InputIterator begin, - InputIterator end, - Polygon_2& pgn, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin, end) + 1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator itr = begin; itr!=end; ++itr, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr, *(arr_vec[i].first)); - } - - Xor_merge xor_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; -} - -//intersect range of polygons with holes -template -inline void symmetric_difference(InputIterator begin, - InputIterator end, - Polygon_with_holes_2& pgn, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin, end) + 1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator itr = begin; itr!=end; ++itr, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr, *(arr_vec[i].first)); - } - - Xor_merge xor_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; -} - - -template -inline void symmetric_difference(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2, - unsigned int k=5) -{ - std::vector arr_vec (std::distance(begin1, end1)+ - std::distance(begin2, end2)+1); - arr_vec[0].first = this->m_arr; - unsigned int i = 1; - - for(InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr1)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr1, *(arr_vec[i].first)); - } - - for(InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) - { - CGAL_precondition(m_traits->is_valid_2_object()(*itr2)); - arr_vec[i].first = new Arrangement_2(m_traits); - _insert(*itr2, *(arr_vec[i].first)); - } - - Xor_merge xor_merge; - _build_sorted_vertices_vectors (arr_vec); - _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge); - - //the result arrangement is at index 0 - this->m_arr = arr_vec[0].first; - delete arr_vec[0].second; - this->remove_redundant_edges(); - this->_reset_faces(); -} - - -static void construct_polygon(Ccb_halfedge_const_circulator ccb, - Polygon_2& pgn, - Traits_2* tr); - - -bool is_hole_of_face(Face_const_handle f, - Halfedge_const_handle he) const; - -Ccb_halfedge_const_circulator get_boundary_of_polygon(Face_const_iterator f) const; - - -void remove_redundant_edges() -{ - this->_remove_redundant_edges(m_arr); -} - -void _remove_redundant_edges(Arrangement_2* arr) -{ - for(Edge_iterator itr = arr->edges_begin(); - itr != arr->edges_end(); ) - { - Halfedge_handle he = itr; - if(he->face()->contained() == he->twin()->face()->contained()) + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + for (InputIterator itr = begin; itr!=end; ++itr, ++i) { - Edge_iterator next = itr; - ++next; - arr->remove_edge(he); - itr = next; - } - else - ++itr; - } -} - -class Less_vertex_handle -{ - typename Traits_2::Compare_xy_2 comp_xy; - -public: - - Less_vertex_handle (const typename Traits_2::Compare_xy_2& cmp) : - comp_xy (cmp) - {} - - bool operator() (Vertex_handle v1, Vertex_handle v2) const - { - return (comp_xy (v1->point(), v2->point()) == SMALLER); - } -}; - -void _build_sorted_vertices_vectors (std::vector& arr_vec) -{ - Less_vertex_handle comp (m_traits->compare_xy_2_object()); - Arrangement_2 *p_arr; - Vertex_iterator vit; - const unsigned int n = arr_vec.size(); - unsigned int i, j; - - for (i = 0; i < n; i++) - { - // Allocate a vector of handles to all vertices in the current - // arrangement. - p_arr = arr_vec[i].first; - arr_vec[i].second = new std::vector; - arr_vec[i].second->resize (p_arr->number_of_vertices()); - - for (j = 0, vit = p_arr->vertices_begin(); - vit != p_arr->vertices_end(); - j++, ++vit) - { - (*(arr_vec[i].second))[j] = vit; + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr, *(arr_vec[i].first)); } - // Sort the vector. - std::sort (arr_vec[i].second->begin(), arr_vec[i].second->end(), - comp); - } - - return; -} - -template -void _divide_and_conquer (unsigned int lower, - unsigned int upper, - std::vector& arr_vec, - unsigned int k, - Merge merge_func) -{ - if((upper - lower) < k) - { - merge_func(lower, upper, 1, arr_vec); - return; - } - - unsigned int sub_size = ((upper - lower + 1) / k); + Join_merge join_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge); - unsigned int i=0; - unsigned int curr_lower = lower; - - for(; im_arr = arr_vec[0].first; + delete arr_vec[0].second; } - _divide_and_conquer (curr_lower, upper,arr_vec, k, merge_func); - merge_func (lower, curr_lower, sub_size ,arr_vec); - return; -} - -// mark all faces as non-visited -void _reset_faces() const -{ - _reset_faces(m_arr); -} - -void _reset_faces(Arrangement_2* arr) const -{ - Face_const_iterator fit = arr->faces_begin(); - for( ; fit != arr->faces_end(); ++fit) + //join range of polygons with holes + template + inline void join(InputIterator begin, InputIterator end, + Polygon_with_holes_2& pgn, unsigned int k=5) { - fit->set_visited(false); + std::vector arr_vec (std::distance(begin, end) + 1); + arr_vec[0].first = this->m_arr; + + unsigned int i = 1; + for (InputIterator itr = begin; itr!=end; ++itr, ++i) + { + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr, *(arr_vec[i].first)); + } + + Join_merge join_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; } -} - -void _insert(const Polygon_2& pgn, Arrangement_2& arr); - -void _insert(const Polygon_with_holes_2& pgn, Arrangement_2& arr); - -template< class PolygonIter > -void _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_2& pgn); - -template< class PolygonIter > -void _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_with_holes_2& pgn); - -template -void _construct_curves(const Polygon_2& pgn, OutputIterator oi); - -template -void _construct_curves(const Polygon_with_holes_2& pgn, OutputIterator oi); - - -bool _is_empty(const Polygon_2& pgn) const -{ - const std::pair& itr_pair = - m_traits->construct_curves_2_object()(pgn); - return (itr_pair.first == itr_pair.second); -} - -bool _is_empty(const Polygon_with_holes_2& pgn) const -{ - return (false); -} - -bool _is_plane(const Polygon_2& pgn) const -{ - return (false); -} - -bool _is_plane(const Polygon_with_holes_2& pgn) const -{ - return (pgn.is_unbounded() && (pgn.holes_begin() == pgn.holes_end())); -} - -void _intersection(const Arrangement_2& arr) -{ - Arrangement_2* res_arr = new Arrangement_2(m_traits); - Gps_intersection_functor func; - overlay(*m_arr, arr, *res_arr, func); - delete m_arr; // delete the previous arrangement + template + inline void join(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + unsigned int k=5) + { + std::vector arr_vec (std::distance(begin1, end1)+ + std::distance(begin2, end2)+1); + + arr_vec[0].first = this->m_arr; + unsigned int i = 1; - m_arr = res_arr; - remove_redundant_edges(); -} + for (InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) + { + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr1, *(arr_vec[i].first)); + } + + for (InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) + { + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr2, *(arr_vec[i].first)); + } -void _intersection(const Arrangement_2& arr1, - const Arrangement_2& arr2, - Arrangement_2& res) -{ - Gps_intersection_functor func; - overlay(arr1, arr2, res, func); - _remove_redundant_edges(&res); + Join_merge join_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, join_merge); -} - -template -void _intersection(const Polygon_& pgn) -{ - if(_is_empty(pgn)) - this->clear(); - if(_is_plane(pgn)) - return; - if(this->is_empty()) - return; - - if(this->is_plane()) - { - Arrangement_2* arr = new Arrangement_2(m_traits); - _insert(pgn, *arr); - delete (this->m_arr); - this->m_arr = arr; - return; + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + this->remove_redundant_edges(); + this->_reset_faces(); } - Arrangement_2 second_arr; - _insert(pgn, second_arr); - _intersection(second_arr); -} - void _intersection(const Self& other) + // intersect range of polygins + template + inline void intersection(InputIterator begin, InputIterator end, + unsigned int k=5) { - if(other.is_empty()) + typename std::iterator_traits::value_type pgn; + this->intersection(begin, end, pgn, k); + this->remove_redundant_edges(); + this->_reset_faces(); + } + + + // intersect range of simple polygons + template + inline void intersection(InputIterator begin, InputIterator end, + Polygon_2& pgn, unsigned int k) + { + std::vector arr_vec (std::distance(begin, end) + 1); + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + + for (InputIterator itr = begin; itr!=end; ++itr, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr, *(arr_vec[i].first)); + } + + Intersection_merge intersection_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + } + + //intersect range of polygons with holes + template + inline void intersection(InputIterator begin, InputIterator end, + Polygon_with_holes_2& pgn, unsigned int k) + { + std::vector arr_vec (std::distance(begin, end) + 1); + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + + for (InputIterator itr = begin; itr!=end; ++itr, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr, *(arr_vec[i].first)); + } + + Intersection_merge intersection_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + } + + + template + inline void intersection(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + unsigned int k=5) + { + std::vector arr_vec (std::distance(begin1, end1)+ + std::distance(begin2, end2)+1); + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + + for (InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr1)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr1, *(arr_vec[i].first)); + } + + for (InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr2)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr2, *(arr_vec[i].first)); + } + + Intersection_merge intersection_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, intersection_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + this->remove_redundant_edges(); + this->_reset_faces(); + } + + + + // symmetric_difference of a range of polygons (similar to xor) + template + inline void symmetric_difference(InputIterator begin, InputIterator end, + unsigned int k=5) + { + typename std::iterator_traits::value_type pgn; + this->symmetric_difference(begin, end, pgn, k); + this->remove_redundant_edges(); + this->_reset_faces(); + } + + + // intersect range of simple polygons + template + inline void symmetric_difference(InputIterator begin, InputIterator end, + Polygon_2& pgn, unsigned int k=5) + { + std::vector arr_vec (std::distance(begin, end) + 1); + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + + for (InputIterator itr = begin; itr!=end; ++itr, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr, *(arr_vec[i].first)); + } + + Xor_merge xor_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + } + + //intersect range of polygons with holes + template + inline void symmetric_difference(InputIterator begin, InputIterator end, + Polygon_with_holes_2& pgn, unsigned int k=5) + { + std::vector arr_vec (std::distance(begin, end) + 1); + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + + for (InputIterator itr = begin; itr!=end; ++itr, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr, *(arr_vec[i].first)); + } + + Xor_merge xor_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + } + + + template + inline void symmetric_difference(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2, + unsigned int k=5) + { + std::vector arr_vec (std::distance(begin1, end1)+ + std::distance(begin2, end2)+1); + arr_vec[0].first = this->m_arr; + unsigned int i = 1; + + for (InputIterator1 itr1 = begin1; itr1!=end1; ++itr1, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr1)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr1, *(arr_vec[i].first)); + } + + for (InputIterator2 itr2 = begin2; itr2!=end2; ++itr2, ++i) + { + CGAL_precondition(m_traits->is_valid_2_object()(*itr2)); + arr_vec[i].first = new Arrangement_2(m_traits); + _insert(*itr2, *(arr_vec[i].first)); + } + + Xor_merge xor_merge; + _build_sorted_vertices_vectors (arr_vec); + _divide_and_conquer(0, arr_vec.size()-1, arr_vec, k, xor_merge); + + //the result arrangement is at index 0 + this->m_arr = arr_vec[0].first; + delete arr_vec[0].second; + this->remove_redundant_edges(); + this->_reset_faces(); + } + + static void construct_polygon(Ccb_halfedge_const_circulator ccb, + Polygon_2 & pgn, Traits_2 * tr); + + bool is_hole_of_face(Face_const_handle f, Halfedge_const_handle he) const; + + Ccb_halfedge_const_circulator + get_boundary_of_polygon(Face_const_iterator f) const; + + void remove_redundant_edges() + { + this->_remove_redundant_edges(m_arr); + } + + void _remove_redundant_edges(Arrangement_2* arr) + { + for (Edge_iterator itr = arr->edges_begin(); itr != arr->edges_end(); ) + { + Halfedge_handle he = itr; + if (he->face()->contained() == he->twin()->face()->contained()) + { + Edge_iterator next = itr; + ++next; + arr->remove_edge(he); + itr = next; + } + else + ++itr; + } + } + + class Less_vertex_handle + { + typename Traits_2::Compare_xy_2 comp_xy; + + public: + + Less_vertex_handle (const typename Traits_2::Compare_xy_2& cmp) : + comp_xy (cmp) + {} + + bool operator() (Vertex_handle v1, Vertex_handle v2) const + { + return (comp_xy (v1->point(), v2->point()) == SMALLER); + } + }; + + void _build_sorted_vertices_vectors (std::vector& arr_vec) + { + Less_vertex_handle comp (m_traits->compare_xy_2_object()); + Arrangement_2 *p_arr; + Vertex_iterator vit; + const unsigned int n = arr_vec.size(); + unsigned int i, j; + + for (i = 0; i < n; i++) + { + // Allocate a vector of handles to all vertices in the current + // arrangement. + p_arr = arr_vec[i].first; + arr_vec[i].second = new std::vector; + arr_vec[i].second->resize (p_arr->number_of_vertices()); + + for (j = 0, vit = p_arr->vertices_begin(); + vit != p_arr->vertices_end(); + j++, ++vit) + { + (*(arr_vec[i].second))[j] = vit; + } + + // Sort the vector. + std::sort (arr_vec[i].second->begin(), arr_vec[i].second->end(), comp); + } + + return; + } + + template + void _divide_and_conquer (unsigned int lower, unsigned int upper, + std::vector& arr_vec, + unsigned int k, Merge merge_func) + { + if ((upper - lower) < k) + { + merge_func(lower, upper, 1, arr_vec); + return; + } + + unsigned int sub_size = ((upper - lower + 1) / k); + unsigned int i = 0; + unsigned int curr_lower = lower; + + for (; ifaces_begin(); + for ( ; fit != arr->faces_end(); ++fit) + { + fit->set_visited(false); + } + } + + void _insert(const Polygon_2& pgn, Arrangement_2& arr); + + void _insert(const Polygon_with_holes_2& pgn, Arrangement_2& arr); + + template + void _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_2& pgn); + + template + void _insert(PolygonIter p_begin, PolygonIter p_end, + Polygon_with_holes_2& pgn); + + template + void _construct_curves(const Polygon_2& pgn, OutputIterator oi); + + template + void _construct_curves(const Polygon_with_holes_2& pgn, OutputIterator oi); + + + bool _is_empty(const Polygon_2& pgn) const + { + const std::pair& itr_pair = + m_traits->construct_curves_2_object()(pgn); + return (itr_pair.first == itr_pair.second); + } + + bool _is_empty(const Polygon_with_holes_2& pgn) const + { + return (false); + } + + bool _is_plane(const Polygon_2& pgn) const + { + return (false); + } + + bool _is_plane(const Polygon_with_holes_2& pgn) const + { + return (pgn.is_unbounded() && (pgn.holes_begin() == pgn.holes_end())); + } + + void _intersection(const Arrangement_2& arr) + { + Arrangement_2* res_arr = new Arrangement_2(m_traits); + Gps_intersection_functor func; + overlay(*m_arr, arr, *res_arr, func); + delete m_arr; // delete the previous arrangement + + m_arr = res_arr; + remove_redundant_edges(); + } + + void _intersection(const Arrangement_2& arr1, + const Arrangement_2& arr2, + Arrangement_2& res) + { + Gps_intersection_functor func; + overlay(arr1, arr2, res, func); + _remove_redundant_edges(&res); + + } + + template + void _intersection(const Polygon_& pgn) + { + if (_is_empty(pgn)) + this->clear(); + if (_is_plane(pgn)) return; + if (this->is_empty()) return; + if (this->is_plane()) + { + Arrangement_2* arr = new Arrangement_2(m_traits); + _insert(pgn, *arr); + delete (this->m_arr); + this->m_arr = arr; + return; + } + + Arrangement_2 second_arr; + _insert(pgn, second_arr); + _intersection(second_arr); + } + + void _intersection(const Self& other) + { + if (other.is_empty()) { m_arr->clear(); return; } - - if(other.is_plane()) - return; - - if(this->is_empty()) - return; - - if(this->is_plane()) + if (other.is_plane()) return; + if (this->is_empty()) return; + if (this->is_plane()) { *(this->m_arr) = *(other.m_arr); return; } - + _intersection(*(other.m_arr)); } - - void _join(const Arrangement_2& arr) -{ - Arrangement_2* res_arr = new Arrangement_2(m_traits); - Gps_join_functor func; - overlay(*m_arr, arr, *res_arr, func); - delete m_arr; // delete the previous arrangement + + void _join(const Arrangement_2& arr) + { + Arrangement_2* res_arr = new Arrangement_2(m_traits); + Gps_join_functor func; + overlay(*m_arr, arr, *res_arr, func); + delete m_arr; // delete the previous arrangement - m_arr = res_arr; - remove_redundant_edges(); -} - -void _join(const Arrangement_2& arr1, - const Arrangement_2& arr2, - Arrangement_2& res) -{ - Gps_join_functor func; - overlay(arr1, arr2, res, func); - _remove_redundant_edges(&res); - -} - -template -void _join(const Polygon_& pgn) -{ - if(_is_empty(pgn)) - return; - if(_is_plane(pgn)) - { - this->clear(); - this->m_arr->unbounded_face()->set_contained(true); - return; - } - if(this->is_empty()) - { - Arrangement_2* arr = new Arrangement_2(m_traits); - _insert(pgn, *arr); - delete (this->m_arr); - this->m_arr = arr; - return; + m_arr = res_arr; + remove_redundant_edges(); } - if(this->is_plane()) - return; - - Arrangement_2 second_arr; - _insert(pgn, second_arr); - _join(second_arr); -} - - -void _join(const Self& other) -{ - if(other.is_empty()) - return; - if(other.is_plane()) + void _join(const Arrangement_2& arr1, const Arrangement_2& arr2, + Arrangement_2& res) { - this->clear(); - this->m_arr->unbounded_face()->set_contained(true); - return; - } - if(this->is_empty()) - { - *(this->m_arr) = *(other.m_arr); - return; - } - if(this->is_plane()) - return; - - _join(*(other.m_arr)); -} - -void _difference(const Arrangement_2& arr) -{ - Arrangement_2* res_arr = new Arrangement_2(m_traits); - Gps_difference_functor func; - overlay(*m_arr, arr, *res_arr, func); - delete m_arr; // delete the previous arrangement + Gps_join_functor func; + overlay(arr1, arr2, res, func); + _remove_redundant_edges(&res); - m_arr = res_arr; - remove_redundant_edges(); - fix_curves_direction(); -} - -void _difference(const Arrangement_2& arr1, - const Arrangement_2& arr2, - Arrangement_2& res) -{ - Gps_difference_functor func; - overlay(arr1, arr2, res, func); - _remove_redundant_edges(&res); - _fix_curves_direction(res); - -} - -template -void _difference(const Polygon_& pgn) -{ - if(_is_empty(pgn)) - return; - - if(_is_plane(pgn)) - { - this->clear(); - return; } - if(this->is_empty()) - return; - if(this->is_plane()) + template + void _join(const Polygon_& pgn) { - Arrangement_2* arr = new Arrangement_2(m_traits); - _insert(pgn, *arr); - delete (this->m_arr); - this->m_arr = arr; - this->complement(); - return; - } - - Arrangement_2 second_arr; - _insert(pgn, second_arr); - _difference(second_arr); -} - - -void _difference(const Self& other) -{ - if(other.is_empty()) - return; - if(other.is_plane()) - { - this->clear(); - return; - } - if(this->is_empty()) - { - return; - } - if(this->is_plane()) - { - *(this->m_arr) = *(other.m_arr); - this->complement(); - return; - } - - _difference(*(other.m_arr)); -} - -void _symmetric_difference(const Arrangement_2& arr) -{ - Arrangement_2* res_arr = new Arrangement_2(m_traits); - Gps_sym_diff_functor func; - overlay(*m_arr, arr, *res_arr, func); - delete m_arr; // delete the previous arrangement + if (_is_empty(pgn)) return; + if (_is_plane(pgn)) + { + this->clear(); + this->m_arr->unbounded_face()->set_contained(true); + return; + } + if (this->is_empty()) + { + Arrangement_2* arr = new Arrangement_2(m_traits); + _insert(pgn, *arr); + delete (this->m_arr); + this->m_arr = arr; + return; + } + if (this->is_plane()) return; - m_arr = res_arr; - remove_redundant_edges(); - fix_curves_direction(); -} - -void _symmetric_difference(const Arrangement_2& arr1, - const Arrangement_2& arr2, - Arrangement_2& res) -{ - Gps_sym_diff_functor func; - overlay(arr1, arr2, res, func); - _remove_redundant_edges(&res); - _fix_curves_direction(res); -} - -template -void _symmetric_difference(const Polygon_& pgn) -{ - if(_is_empty(pgn)) - return; - - if(_is_plane(pgn)) - { - this->complement(); - return; - } - if(this->is_empty()) - { - Arrangement_2* arr = new Arrangement_2(m_traits); - _insert(pgn, *arr); - delete (this->m_arr); - this->m_arr = arr; - return; + Arrangement_2 second_arr; + _insert(pgn, second_arr); + _join(second_arr); } - if(this->is_plane()) + + void _join(const Self& other) { - Arrangement_2* arr = new Arrangement_2(m_traits); - _insert(pgn, *arr); - delete (this->m_arr); - this->m_arr = arr; - this->complement(); - return; - } - - Arrangement_2 second_arr; - _insert(pgn, second_arr); - _symmetric_difference(second_arr); -} - - -void _symmetric_difference(const Self& other) -{ - if(other.is_empty()) - return; - - if(other.is_plane()) - { - this->complement(); - return; - } - if(this->is_empty()) - { - *(this->m_arr) = *(other.m_arr); - return; + if (other.is_empty()) return; + if (other.is_plane()) + { + this->clear(); + this->m_arr->unbounded_face()->set_contained(true); + return; + } + if (this->is_empty()) + { + *(this->m_arr) = *(other.m_arr); + return; + } + if (this->is_plane()) return; + _join(*(other.m_arr)); } - if(this->is_plane()) + void _difference(const Arrangement_2& arr) { - *(this->m_arr) = *(other.m_arr); - this->complement(); - return; + Arrangement_2* res_arr = new Arrangement_2(m_traits); + Gps_difference_functor func; + overlay(*m_arr, arr, *res_arr, func); + delete m_arr; // delete the previous arrangement + + m_arr = res_arr; + remove_redundant_edges(); + fix_curves_direction(); } - - _symmetric_difference(*(other.m_arr)); -} - + + void _difference(const Arrangement_2& arr1, const Arrangement_2& arr2, + Arrangement_2& res) + { + Gps_difference_functor func; + overlay(arr1, arr2, res, func); + _remove_redundant_edges(&res); + _fix_curves_direction(res); + + } + + template + void _difference(const Polygon_& pgn) + { + if (_is_empty(pgn)) return; + if (_is_plane(pgn)) + { + this->clear(); + return; + } + if (this->is_empty()) return; + if (this->is_plane()) + { + Arrangement_2* arr = new Arrangement_2(m_traits); + _insert(pgn, *arr); + delete (this->m_arr); + this->m_arr = arr; + this->complement(); + return; + } + + Arrangement_2 second_arr; + _insert(pgn, second_arr); + _difference(second_arr); + } + + + void _difference(const Self& other) + { + if (other.is_empty()) return; + if (other.is_plane()) + { + this->clear(); + return; + } + if (this->is_empty()) return; + if (this->is_plane()) + { + *(this->m_arr) = *(other.m_arr); + this->complement(); + return; + } + + _difference(*(other.m_arr)); + } + + void _symmetric_difference(const Arrangement_2& arr) + { + Arrangement_2* res_arr = new Arrangement_2(m_traits); + Gps_sym_diff_functor func; + overlay(*m_arr, arr, *res_arr, func); + delete m_arr; // delete the previous arrangement + + m_arr = res_arr; + remove_redundant_edges(); + fix_curves_direction(); + } + + void _symmetric_difference(const Arrangement_2& arr1, + const Arrangement_2& arr2, + Arrangement_2& res) + { + Gps_sym_diff_functor func; + overlay(arr1, arr2, res, func); + _remove_redundant_edges(&res); + _fix_curves_direction(res); + } + + template + void _symmetric_difference(const Polygon_& pgn) + { + if (_is_empty(pgn)) return; + + if (_is_plane(pgn)) + { + this->complement(); + return; + } + if (this->is_empty()) + { + Arrangement_2* arr = new Arrangement_2(m_traits); + _insert(pgn, *arr); + delete (this->m_arr); + this->m_arr = arr; + return; + } + + if (this->is_plane()) + { + Arrangement_2* arr = new Arrangement_2(m_traits); + _insert(pgn, *arr); + delete (this->m_arr); + this->m_arr = arr; + this->complement(); + return; + } + + Arrangement_2 second_arr; + _insert(pgn, second_arr); + _symmetric_difference(second_arr); + } + + + void _symmetric_difference(const Self& other) + { + if (other.is_empty()) return; + + if (other.is_plane()) + { + this->complement(); + return; + } + if (this->is_empty()) + { + *(this->m_arr) = *(other.m_arr); + return; + } + + if (this->is_plane()) + { + *(this->m_arr) = *(other.m_arr); + this->complement(); + return; + } + + _symmetric_difference(*(other.m_arr)); + } + }; #include diff --git a/Boolean_set_operations_2/include/CGAL/Polygon_set_2.h b/Boolean_set_operations_2/include/CGAL/Polygon_set_2.h index d593f685b12..8ac0a3d530c 100644 --- a/Boolean_set_operations_2/include/CGAL/Polygon_set_2.h +++ b/Boolean_set_operations_2/include/CGAL/Polygon_set_2.h @@ -16,6 +16,7 @@ // // // Author(s) : Baruch Zukerman +// Efi Fogel #ifndef CGAL_POLYGON_SET_2_H #define CGAL_POLYGON_SET_2_H @@ -23,19 +24,22 @@ #include #include #include +#include + #include CGAL_BEGIN_NAMESPACE template > + typename Containter = std::vector, + class Dcel_ = Gps_dcel > > class Polygon_set_2 : - public General_polygon_set_2 > + public General_polygon_set_2, Dcel_> { private: - typedef General_polygon_set_2 > + typedef General_polygon_set_2, Dcel_> Base; - typedef Polygon_set_2 Self; + typedef Polygon_set_2 Self; public: typedef typename Base::Traits_2 Traits_2; @@ -97,10 +101,8 @@ public: } template - inline void intersection(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2) + inline void intersection(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2) { Base::intersection(begin1, end1, begin2, end2); } @@ -132,10 +134,8 @@ public: } template - inline void join(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2) + inline void join(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2) { Base::join(begin1, end1, begin2, end2); } @@ -167,10 +167,8 @@ public: } template - inline void difference(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2) + inline void difference(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2) { Base::difference(begin1, end1, begin2, end2); } @@ -202,10 +200,8 @@ public: } template - inline void symmetric_difference(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2) + inline void symmetric_difference(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2) { Base::symmetric_difference(begin1, end1, begin2, end2); } @@ -232,20 +228,18 @@ public: } template - inline bool do_intersect(InputIterator1 begin1, - InputIterator1 end1, - InputIterator2 begin2, - InputIterator2 end2) + inline bool do_intersect(InputIterator1 begin1, InputIterator1 end1, + InputIterator2 begin2, InputIterator2 end2) { return (Base::do_intersect(begin1, end1, begin2, end2)); } - private: +private: - inline const Base& base(const Self& other) const - { - return (static_cast(other)); - } + inline const Base& base(const Self& other) const + { + return (static_cast(other)); + } };