mirror of https://github.com/CGAL/cgal
General_polygon_set_on_surface_2 - first verstion
This commit is contained in:
parent
c50131c8c9
commit
097c3793fd
|
|
@ -1173,6 +1173,7 @@ Boolean_set_operations_2/examples/Boolean_set_operations_2/char_g.dat -text
|
|||
Boolean_set_operations_2/examples/Boolean_set_operations_2/char_m.dat -text
|
||||
Boolean_set_operations_2/examples/Boolean_set_operations_2/pgn_holes.dat -text
|
||||
Boolean_set_operations_2/examples/Boolean_set_operations_2/test.dxf -text svneol=unset#application/octet-stream
|
||||
Boolean_set_operations_2/include/CGAL/General_polygon_set_on_surface_2.h -text
|
||||
Boolean_set_operations_2/test/Boolean_set_operations_2/data/pgn_holes1.dat -text
|
||||
Boolean_set_operations_2/test/Boolean_set_operations_2/data/pgn_holes2.dat -text
|
||||
Boolean_set_operations_2/test/Boolean_set_operations_2/data/pgn_holes3.dat -text
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ CGAL_BEGIN_NAMESPACE
|
|||
public:
|
||||
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Traits_2 Traits;
|
||||
typedef typename Arrangement::Geometry_traits_2 Traits;
|
||||
typedef Ccb_curve_iterator<Arrangement> Self;
|
||||
typedef typename Arrangement::Ccb_halfedge_const_circulator
|
||||
Ccb_halfedge_const_circulator;
|
||||
|
|
|
|||
|
|
@ -100,12 +100,12 @@ public:
|
|||
|
||||
template <class Arrangement_>
|
||||
class Gps_agg_meta_traits :
|
||||
public Gps_traits_decorator<typename Arrangement_::Traits_2,
|
||||
public Gps_traits_decorator<typename Arrangement_::Geometry_traits_2,
|
||||
Gps_agg_curve_data<Arrangement_>,
|
||||
Point_with_vertex<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Traits_2 Traits;
|
||||
typedef typename Arrangement::Geometry_traits_2 Traits;
|
||||
|
||||
typedef typename Traits::X_monotone_curve_2 Base_X_monotone_curve_2;
|
||||
typedef typename Traits::Point_2 Base_Point_2;
|
||||
|
|
|
|||
|
|
@ -16,10 +16,22 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_AGG_OP_H
|
||||
#define CGAL_GPS_AGG_OP_H
|
||||
|
||||
/*!
|
||||
\file Gps_agg_op.h
|
||||
\brief The class Gps_agg_op is responsible for aggregated Boolean set
|
||||
operations depending on a visitor template parameter.
|
||||
It uses the sweep-line algorithm from the arrangement packages
|
||||
to overlay all the polygon sets, and then it uses a BFS that
|
||||
determines which of the faces is contained in the result using
|
||||
the visitor.
|
||||
*/
|
||||
|
||||
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_meta_traits.h>
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_op_sweep.h>
|
||||
#include <CGAL/Sweep_line_2/Arr_construction_subcurve.h>
|
||||
|
|
@ -38,7 +50,7 @@ template <class Arrangement_, class Bfs_visitor_>
|
|||
class Gps_agg_op
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef typename Arrangement_2::Traits_2 Traits_2;
|
||||
typedef typename Arrangement_2::Geometry_traits_2 Traits_2;
|
||||
typedef typename Traits_2::Curve_const_iterator Curve_const_iterator;
|
||||
typedef Gps_agg_meta_traits<Arrangement_2> Meta_traits;
|
||||
typedef typename Meta_traits::Curve_data Curve_data;
|
||||
|
|
@ -120,8 +132,10 @@ public:
|
|||
|
||||
for (i = lower; i <= upper; i += jump, ++n_pgn)
|
||||
{
|
||||
// The BFS scan (after the loop) starts in the reference face,
|
||||
// so we count the number of polygons that contain the reference face.
|
||||
Arrangement_2* arr = (arr_vec[i]).first;
|
||||
if (arr->unbounded_face()->contained())
|
||||
if (arr->reference_face()->contained())
|
||||
++n_inf_pgn;
|
||||
|
||||
Edge_iterator itr = arr->edges_begin();
|
||||
|
|
@ -144,9 +158,9 @@ public:
|
|||
lower, upper, jump,
|
||||
arr_vec);
|
||||
|
||||
m_faces_hash[m_arr->unbounded_face()] = n_inf_pgn;
|
||||
m_faces_hash[m_arr->reference_face()] = n_inf_pgn;
|
||||
Bfs_visitor visitor(&m_edges_hash, &m_faces_hash, n_pgn);
|
||||
visitor.visit_ubf(m_arr->unbounded_face(), n_inf_pgn);
|
||||
visitor.visit_ubf(m_arr->faces_begin(), n_inf_pgn);
|
||||
Bfs_scanner scanner(visitor);
|
||||
scanner.scan(*m_arr);
|
||||
visitor.after_scan(*m_arr);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ private:
|
|||
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ? SMALLER : LARGER;
|
||||
|
||||
const Comparison_result cv_dir =
|
||||
this->m_arr_access.arrangement().traits()->
|
||||
this->m_arr_access.arrangement().geometry_traits()->
|
||||
compare_endpoints_xy_2_object()(cv);
|
||||
|
||||
if (he_dir == cv_dir)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BPS_BASE_VISITOR_H
|
||||
#define CGAL_GPS_BPS_BASE_VISITOR_H
|
||||
|
|
@ -24,7 +25,14 @@
|
|||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement_>
|
||||
//! Gps_bfs_base_visitor
|
||||
/*! This is a base class for all visitors that are responsible for merging
|
||||
polygon sets.
|
||||
We use DerivedVisitor for static polymorphism for using contained_criteria
|
||||
which determines if we should mark the face as contained given the inside
|
||||
count of the face.
|
||||
*/
|
||||
template <class Arrangement_, class DerivedVisitor>
|
||||
class Gps_bfs_base_visitor
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
|
|
@ -50,23 +58,38 @@ public:
|
|||
{}
|
||||
|
||||
|
||||
void flip_face(Face_iterator f1, Face_iterator f2, Halfedge_iterator he)
|
||||
//! discovered_face
|
||||
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face
|
||||
during a BFS scan. In the BFS traversal we are going from old_face to
|
||||
new_face throught the half-edge he.
|
||||
\param old_face The face that was already revealed
|
||||
\param new_face The face that we have just now revealed
|
||||
\param he The half-edge that is used to traverse between them.
|
||||
*/
|
||||
void discovered_face(Face_iterator old_face,
|
||||
Face_iterator new_face,
|
||||
Halfedge_iterator he)
|
||||
{
|
||||
CGAL_assertion(m_edges_hash->is_defined(he) &&
|
||||
m_edges_hash->is_defined(he->twin()) &&
|
||||
m_faces_hash->is_defined(f1) &&
|
||||
!m_faces_hash->is_defined(f2));
|
||||
unsigned int ic = compute_ic(old_face, new_face, he);
|
||||
|
||||
// IC of f2 (inside counter)
|
||||
unsigned int ic_f2 =
|
||||
(*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()];
|
||||
(*m_faces_hash)[f2] = ic_f2;
|
||||
if (static_cast<DerivedVisitor*>(this)->contained_criteria(ic))
|
||||
new_face->set_contained(true);
|
||||
}
|
||||
|
||||
// mark the unbounded_face (true iff contained)
|
||||
void visit_ubf(Face_iterator ubf, unsigned int ubf_ic)
|
||||
{
|
||||
CGAL_assertion(ubf->number_of_outer_ccbs() == 0);
|
||||
if(static_cast<DerivedVisitor*>(this)->contained_criteria(ubf_ic))
|
||||
ubf->set_contained(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// compute the inside count of a face
|
||||
unsigned int compute_ic(Face_iterator f1, Face_iterator f2, Halfedge_iterator he)
|
||||
unsigned int compute_ic(Face_iterator f1,
|
||||
Face_iterator f2,
|
||||
Halfedge_iterator he)
|
||||
{
|
||||
CGAL_assertion(m_edges_hash->is_defined(he) &&
|
||||
m_edges_hash->is_defined(he->twin()) &&
|
||||
|
|
@ -75,7 +98,7 @@ protected:
|
|||
unsigned int ic_f2 =
|
||||
(*m_faces_hash)[f1] - (*m_edges_hash)[he] + (*m_edges_hash)[he->twin()];
|
||||
(*m_faces_hash)[f2] = ic_f2;
|
||||
|
||||
|
||||
return (ic_f2);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
//
|
||||
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
|
||||
#ifndef CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
||||
#define CGAL_GPS_BFS_INTERSECTION_VISITOR_H
|
||||
|
||||
|
|
@ -25,12 +28,14 @@
|
|||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement_>
|
||||
class Gps_bfs_intersection_visitor : public Gps_bfs_base_visitor<Arrangement_>
|
||||
class Gps_bfs_intersection_visitor :
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_intersection_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Gps_bfs_base_visitor<Arrangement> Base;
|
||||
typedef Gps_bfs_intersection_visitor<Arrangement> Self;
|
||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
||||
typedef typename Base::Edges_hash Edges_hash;
|
||||
typedef typename Base::Faces_hash Faces_hash;
|
||||
|
||||
|
|
@ -44,33 +49,23 @@ public:
|
|||
{}
|
||||
|
||||
|
||||
void flip_face(Face_iterator f1, Face_iterator f2, Halfedge_iterator he)
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
inside count should be marked as contained.
|
||||
\param ic the inner count of the talked-about face.
|
||||
\return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(unsigned int ic)
|
||||
{
|
||||
unsigned int ic_f2;
|
||||
ic_f2 = this->compute_ic(f1, f2, he);
|
||||
(*(this->m_faces_hash))[f2] = ic_f2;
|
||||
|
||||
CGAL_assertion(ic_f2 <= this->m_num_of_polygons);
|
||||
|
||||
// only faces that have inside counter equal to the number of polygons
|
||||
// which are intersectd, will be marked true (containted)
|
||||
if(ic_f2 == this->m_num_of_polygons)
|
||||
f2->set_contained(true);
|
||||
}
|
||||
|
||||
// mark the unbounded_face (true iff contained)
|
||||
void visit_ubf(Face_iterator ubf, unsigned int ubf_ic)
|
||||
{
|
||||
CGAL_assertion(ubf->is_unbounded());
|
||||
if(ubf_ic == this->m_num_of_polygons)
|
||||
ubf->set_contained(true);
|
||||
// intersection means that all polygons contain the face.
|
||||
CGAL_assertion(ic <= this->m_num_of_polygons);
|
||||
return (ic == this->m_num_of_polygons);
|
||||
}
|
||||
|
||||
void after_scan(Arrangement&)
|
||||
{}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BFS_JOIN_VISITOR_H
|
||||
#define CGAL_GPS_BFS_JOIN_VISITOR_H
|
||||
|
|
@ -25,12 +26,14 @@
|
|||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement_>
|
||||
class Gps_bfs_join_visitor : public Gps_bfs_base_visitor<Arrangement_>
|
||||
class Gps_bfs_join_visitor :
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_join_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Gps_bfs_base_visitor<Arrangement> Base;
|
||||
typedef Gps_bfs_join_visitor<Arrangement> Self;
|
||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
||||
typedef typename Base::Edges_hash Edges_hash;
|
||||
typedef typename Base::Faces_hash Faces_hash;
|
||||
|
||||
|
|
@ -40,23 +43,16 @@ public:
|
|||
Base(edges_hash, faces_hash, n_pgn)
|
||||
{}
|
||||
|
||||
|
||||
void flip_face(Face_iterator f1, Face_iterator f2, Halfedge_iterator he)
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
inside count should be marked as contained.
|
||||
\param ic the inner count of the talked-about face.
|
||||
\return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(unsigned int ic)
|
||||
{
|
||||
unsigned int ic_f2;
|
||||
ic_f2 = this->compute_ic(f1, f2, he);
|
||||
(*(this->m_faces_hash))[f2] = ic_f2;
|
||||
|
||||
if(ic_f2 > 0)
|
||||
f2->set_contained(true);
|
||||
}
|
||||
|
||||
// mark the unbounded_face
|
||||
void visit_ubf(Face_iterator ubf, unsigned int ubf_ic)
|
||||
{
|
||||
CGAL_assertion(ubf->is_unbounded());
|
||||
if(ubf_ic > 0)
|
||||
ubf->set_contained(true);
|
||||
// at least one polygon contains the face.
|
||||
return (ic > 0);
|
||||
}
|
||||
|
||||
void after_scan(Arrangement&)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BFS_SCANNER_H
|
||||
#define CGAL_GPS_BFS_SCANNER_H
|
||||
|
|
@ -30,7 +31,7 @@ class Gps_bfs_scanner
|
|||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
|
||||
typedef typename Arrangement::Inner_ccb_iterator Hole_iterator;
|
||||
typedef typename Arrangement::Inner_ccb_iterator Inner_ccb_iterator;
|
||||
typedef typename Arrangement::Ccb_halfedge_circulator
|
||||
Ccb_halfedge_circulator;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
|
|
@ -40,7 +41,7 @@ class Gps_bfs_scanner
|
|||
|
||||
protected:
|
||||
Visitor* m_visitor;
|
||||
std::queue<Hole_iterator> m_holes;
|
||||
std::queue<Inner_ccb_iterator> m_holes;
|
||||
std::stack<Ccb_halfedge_circulator> m_ccb_stcak;
|
||||
|
||||
public:
|
||||
|
|
@ -50,15 +51,23 @@ public:
|
|||
|
||||
void scan(Arrangement& arr)
|
||||
{
|
||||
Face_iterator ubf = arr.unbounded_face();
|
||||
ubf->set_visited(true);
|
||||
push_to_queue_holes_of_face(ubf);
|
||||
|
||||
while(!m_holes.empty())
|
||||
Face_iterator ubf;
|
||||
for (ubf = arr.faces_begin(); ubf != arr.faces_end(); ++ubf)
|
||||
{
|
||||
Hole_iterator hole = m_holes.front();
|
||||
m_holes.pop();
|
||||
scan(*hole);
|
||||
if (ubf->number_of_outer_ccbs() != 0)
|
||||
continue;
|
||||
if (ubf->visited() == true)
|
||||
continue;
|
||||
|
||||
ubf->set_visited(true);
|
||||
push_to_queue_holes_of_face(ubf);
|
||||
|
||||
while(!m_holes.empty())
|
||||
{
|
||||
Inner_ccb_iterator hole = m_holes.front();
|
||||
m_holes.pop();
|
||||
scan(*hole);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +95,7 @@ public:
|
|||
{
|
||||
push_to_queue_holes_of_face(he->twin()->face());
|
||||
new_f->set_visited(true);
|
||||
m_visitor->flip_face(he->face(), new_f, he);
|
||||
m_visitor->discovered_face(he->face(), new_f, he);
|
||||
|
||||
//scan(he->twin());
|
||||
m_ccb_stcak.push(he->twin());
|
||||
|
|
@ -99,7 +108,8 @@ public:
|
|||
|
||||
void push_to_queue_holes_of_face(Face_iterator f)
|
||||
{
|
||||
for(Hole_iterator hit = f->holes_begin(); hit!= f->holes_end(); ++hit)
|
||||
for(Inner_ccb_iterator hit = f->inner_ccbs_begin();
|
||||
hit!= f->inner_ccbs_end(); ++hit)
|
||||
{
|
||||
m_holes.push(hit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_BFS_XOR_VISITOR_H
|
||||
#define CGAL_GPS_BFS_XOR_VISITOR_H
|
||||
|
|
@ -25,43 +26,45 @@
|
|||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement_>
|
||||
class Gps_bfs_xor_visitor : public Gps_bfs_base_visitor<Arrangement_>
|
||||
class Gps_bfs_xor_visitor :
|
||||
public Gps_bfs_base_visitor<Arrangement_, Gps_bfs_xor_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement;
|
||||
typedef typename Arrangement::Face_iterator Face_iterator;
|
||||
typedef typename Arrangement::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Gps_bfs_base_visitor<Arrangement> Base;
|
||||
typedef Gps_bfs_xor_visitor<Arrangement> Self;
|
||||
typedef Gps_bfs_base_visitor<Arrangement, Self> Base;
|
||||
typedef typename Base::Edges_hash Edges_hash;
|
||||
typedef typename Base::Faces_hash Faces_hash;
|
||||
|
||||
public:
|
||||
|
||||
Gps_bfs_xor_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash, unsigned int n_pgn):
|
||||
Gps_bfs_xor_visitor(Edges_hash* edges_hash, Faces_hash* faces_hash,
|
||||
unsigned int n_pgn) :
|
||||
Base(edges_hash, faces_hash, n_pgn)
|
||||
{}
|
||||
|
||||
|
||||
void flip_face(Face_iterator f1, Face_iterator f2, Halfedge_iterator he)
|
||||
//! contained_criteria
|
||||
/*! contained_criteria is used to the determine if the face which has
|
||||
inside count should be marked as contained.
|
||||
\param ic the inner count of the talked-about face.
|
||||
\return true if the face of ic, otherwise false.
|
||||
*/
|
||||
bool contained_criteria(unsigned int ic)
|
||||
{
|
||||
unsigned int ic_f2;
|
||||
ic_f2 = this->compute_ic(f1, f2, he);
|
||||
(*(this->m_faces_hash))[f2] = ic_f2;
|
||||
|
||||
if(ic_f2%2)
|
||||
f2->set_contained(true);
|
||||
}
|
||||
|
||||
// mark the unbounded_face (true iff contained)
|
||||
void visit_ubf(Face_iterator ubf, unsigned int ubf_ic)
|
||||
{
|
||||
CGAL_assertion(ubf->is_unbounded());
|
||||
if(ubf_ic%2)
|
||||
ubf->set_contained(true);
|
||||
// xor means odd number of polygons.
|
||||
return (ic % 2) == 1;
|
||||
}
|
||||
|
||||
//! after_scan post-processing after bfs scan.
|
||||
/*! The function fixes some of the curves, to be in the same direction as the
|
||||
half-edges.
|
||||
|
||||
\param arr The given arrangment.
|
||||
*/
|
||||
void after_scan(Arrangement& arr)
|
||||
{
|
||||
typedef typename Arrangement::Traits_2 Traits;
|
||||
typedef typename Arrangement::Geometry_traits_2 Traits;
|
||||
typedef typename Traits::Compare_endpoints_xy_2 Compare_endpoints_xy_2;
|
||||
typedef typename Traits::Construct_opposite_2 Construct_opposite_2;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
|
|
@ -79,7 +82,8 @@ public:
|
|||
Halfedge_iterator he = eit;
|
||||
const X_monotone_curve_2& cv = he->curve();
|
||||
const bool is_cont = he->face()->contained();
|
||||
const Comparison_result he_res = ((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
|
||||
const Comparison_result he_res =
|
||||
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
|
||||
SMALLER : LARGER;
|
||||
const bool has_same_dir = (cmp_endpoints(cv) == he_res);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,30 @@
|
|||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_join_visitor.h>
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_xor_visitor.h>
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_bfs_intersection_visitor.h>
|
||||
#include <CGAL/Boolean_set_operations_2/Gps_agg_op.h>
|
||||
#include <vector>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class Arrangement_>
|
||||
class Join_merge
|
||||
/*!
|
||||
\file Gps_merge.h
|
||||
\brief This file contains classes that are responsible for merging
|
||||
two sets of polygons in the divide-and-conquer algorithm.
|
||||
The file contains 3 mergers: Join_merge, Intersection_merge and
|
||||
Xor_merge. Join_merge is used when we want to merge the two sets,
|
||||
Intersection_merge is used for intersection, and Xor_merge is used
|
||||
for symmetric difference.
|
||||
*/
|
||||
|
||||
//! Base_merge
|
||||
/*! Base_merge is the base class for all merger classes.
|
||||
All merges used BFS algorithm with a different visitor when discovering
|
||||
a new face.
|
||||
*/
|
||||
template <class Arrangement_, class Visitor_>
|
||||
class Base_merge
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef Visitor_ Visitor;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
|
@ -46,12 +61,12 @@ public:
|
|||
if(i==j)
|
||||
return;
|
||||
|
||||
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->traits();
|
||||
typename Arrangement_2::Geometry_traits_2* tr =
|
||||
arr_vec[i].first->geometry_traits();
|
||||
Arrangement_2 *res = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Gps_bfs_join_visitor<Arrangement_2> >
|
||||
agg_op(*res, *verts, *tr);
|
||||
Gps_agg_op<Arrangement_2, Visitor> agg_op(*res, *verts, *tr);
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
|
|
@ -66,82 +81,33 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
//! Join_merge
|
||||
/*! Join_merge is used to join two sets of polygons together in the D&C
|
||||
algorithm. It is a base merge with a visitor that joins faces.
|
||||
*/
|
||||
template <class Arrangement_>
|
||||
class Intersection_merge
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
class Join_merge : public Base_merge<Arrangement_,
|
||||
Gps_bfs_join_visitor<Arrangement_> >
|
||||
{};
|
||||
|
||||
public:
|
||||
void operator()(unsigned int i,
|
||||
unsigned int j,
|
||||
unsigned int jump,
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
if(i==j)
|
||||
return;
|
||||
|
||||
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->traits();
|
||||
Arrangement_2 *res = new Arrangement_2 (tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Gps_bfs_intersection_visitor<Arrangement_2> >
|
||||
agg_op(*res, *verts, *tr);
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
{
|
||||
delete (arr_vec[count].first);
|
||||
delete (arr_vec[count].second);
|
||||
}
|
||||
|
||||
arr_vec[i].first = res;
|
||||
arr_vec[i].second = verts;
|
||||
}
|
||||
};
|
||||
|
||||
//! Intersection_merge
|
||||
/*! Intersection_merge is used to merge two sets of polygons creating their
|
||||
intersection.
|
||||
*/
|
||||
template <class Arrangement_>
|
||||
class Xor_merge
|
||||
class Intersection_merge : public Base_merge<Arrangement_,
|
||||
Gps_bfs_intersection_visitor<Arrangement_> >
|
||||
{};
|
||||
|
||||
//! Xor_merge
|
||||
/*! Xor_merge is used to merge two sets of polygons creating their
|
||||
symmetric difference.
|
||||
*/
|
||||
template <class Arrangement_>
|
||||
class Xor_merge : public Base_merge<Arrangement_,
|
||||
Gps_bfs_xor_visitor<Arrangement_> >
|
||||
{
|
||||
typedef Arrangement_ Arrangement_2;
|
||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
||||
typedef std::pair<Arrangement_2 *,
|
||||
std::vector<Vertex_handle> *> Arr_entry;
|
||||
|
||||
public:
|
||||
|
||||
// Temporarily defined to see if this avoids a warning on SunPro CC
|
||||
Xor_merge()
|
||||
{}
|
||||
|
||||
void operator()(unsigned int i,
|
||||
unsigned int j,
|
||||
unsigned int jump,
|
||||
std::vector<Arr_entry>& arr_vec)
|
||||
{
|
||||
if(i==j)
|
||||
return;
|
||||
|
||||
typename Arrangement_2::Traits_2* tr = arr_vec[i].first->traits();
|
||||
Arrangement_2 *res = new Arrangement_2(tr);
|
||||
std::vector<Vertex_handle> *verts = new std::vector<Vertex_handle>;
|
||||
|
||||
Gps_agg_op<Arrangement_2, Gps_bfs_xor_visitor<Arrangement_2> >
|
||||
agg_op(*res, *verts, *tr);
|
||||
agg_op.sweep_arrangements(i, j, jump, arr_vec);
|
||||
|
||||
for(unsigned int count=i; count<=j; count+=jump)
|
||||
{
|
||||
delete (arr_vec[count].first);
|
||||
delete (arr_vec[count].second);
|
||||
}
|
||||
|
||||
arr_vec[i].first = res;
|
||||
arr_vec[i].second = verts;
|
||||
}
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,6 +17,7 @@
|
|||
//
|
||||
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
|
||||
// Efi Fogel <efif@post.tau.ac.il>
|
||||
// Ophir Setter <ophir.setter@cs.tau.ac.il>
|
||||
|
||||
#ifndef CGAL_GPS_UTILS_H
|
||||
#define CGAL_GPS_UTILS_H
|
||||
|
|
@ -30,32 +31,47 @@
|
|||
|
||||
#include <queue>
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
template <class Traits_, class TopTraits_>
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
construct_polygon(Ccb_halfedge_const_circulator ccb, Polygon_2 & pgn,
|
||||
Traits_ * tr)
|
||||
{
|
||||
typedef CGAL::Ccb_curve_iterator<Arrangement_2> Ccb_curve_iterator;
|
||||
typedef CGAL::Ccb_curve_iterator<Arrangement_on_surface_2>
|
||||
Ccb_curve_iterator;
|
||||
Ccb_curve_iterator begin(ccb, false);
|
||||
Ccb_curve_iterator end(ccb, true);
|
||||
|
||||
tr->construct_polygon_2_object()(begin, end, pgn);
|
||||
}
|
||||
|
||||
|
||||
// The comments below was written after trying to understand what the visitors
|
||||
// do. There was no comment by the author of this class.
|
||||
// This class is used afterwards to extract polygons from the representing
|
||||
// arrangement.
|
||||
// This scanner is not the same as the Gps_bfs_scanner. In this file, the
|
||||
// Gps_bfs_scanner is used with Init_faces_visitor to init the faces of the
|
||||
// representing arrangement.
|
||||
// It seems that Gps_bfs_scanner is used for a regular bfs scan on the faces
|
||||
// of the arrangements, with comparison to Arr_bfs_scanner that cares about
|
||||
// inner ccbs and outer ccbs (it treats them differently).
|
||||
// If this is the case, we should unite Gps_bfs_scanner with the regular
|
||||
// adaptation of arrangement to boost graph.
|
||||
template <class Arrangement, class OutputIterator>
|
||||
class Arr_bfs_scanner
|
||||
{
|
||||
public:
|
||||
typedef typename Arrangement::Traits_2 Gps_traits;
|
||||
typedef typename Arrangement::Dcel Gps_dcel;
|
||||
typedef typename Arrangement::Geometry_traits_2 Gps_traits;
|
||||
typedef typename Arrangement::Topology_traits Gps_top_traits;
|
||||
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::Inner_ccb_const_iterator Hole_const_iterator;
|
||||
typedef typename Arrangement::Outer_ccb_const_iterator
|
||||
Outer_ccb_const_iterator;
|
||||
typedef typename Arrangement::Inner_ccb_const_iterator
|
||||
Inner_ccb_const_iterator;
|
||||
|
||||
|
||||
protected:
|
||||
|
|
@ -74,40 +90,47 @@ public:
|
|||
|
||||
void scan(Arrangement& arr)
|
||||
{
|
||||
Face_const_iterator ubf = arr.unbounded_face();
|
||||
Hole_const_iterator holes_it;
|
||||
Face_const_iterator ubf;
|
||||
for (ubf = arr.faces_begin(); ubf != arr.faces_end(); ++ubf)
|
||||
{
|
||||
if (ubf->number_of_outer_ccbs() != 0)
|
||||
continue;
|
||||
if (ubf->visited())
|
||||
continue;
|
||||
|
||||
Inner_ccb_const_iterator holes_it;
|
||||
if (!ubf->contained())
|
||||
{
|
||||
ubf->set_visited(true);
|
||||
for (holes_it = ubf->inner_ccbs_begin();
|
||||
holes_it != ubf->inner_ccbs_end(); ++holes_it)
|
||||
{
|
||||
scan_ccb (*holes_it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ubf is contained -> unbounded polygon !!
|
||||
scan_contained_ubf(ubf);
|
||||
|
||||
}
|
||||
|
||||
while(!m_holes_q.empty())
|
||||
{
|
||||
Face_const_iterator top_f = m_holes_q.front();
|
||||
m_holes_q.pop();
|
||||
top_f->set_visited(true);
|
||||
for (holes_it = top_f->inner_ccbs_begin();
|
||||
holes_it != top_f->inner_ccbs_end(); ++holes_it)
|
||||
{
|
||||
scan_ccb(*holes_it);
|
||||
}
|
||||
|
||||
//scan_uncontained_face(top_f->outer_ccb());
|
||||
}
|
||||
}
|
||||
|
||||
Face_const_iterator fit;
|
||||
|
||||
if (!ubf->contained())
|
||||
{
|
||||
ubf->set_visited(true);
|
||||
for (holes_it = ubf->holes_begin();
|
||||
holes_it != ubf->holes_end(); ++holes_it)
|
||||
{
|
||||
scan_ccb (*holes_it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ubf is contained -> unbounded polygon !!
|
||||
scan_contained_ubf(ubf);
|
||||
|
||||
}
|
||||
|
||||
while(!m_holes_q.empty())
|
||||
{
|
||||
Face_const_iterator top_f = m_holes_q.front();
|
||||
m_holes_q.pop();
|
||||
top_f->set_visited(true);
|
||||
for (holes_it = top_f->holes_begin();
|
||||
holes_it != top_f->holes_end(); ++holes_it)
|
||||
{
|
||||
scan_ccb(*holes_it);
|
||||
}
|
||||
|
||||
//scan_uncontained_face(top_f->outer_ccb());
|
||||
}
|
||||
|
||||
for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
|
||||
{
|
||||
fit->set_visited(false);
|
||||
|
|
@ -123,7 +146,7 @@ public:
|
|||
{
|
||||
|
||||
Polygon_2 pgn_boundary;
|
||||
General_polygon_set_2<Gps_traits, Gps_dcel>::
|
||||
General_polygon_set_on_surface_2<Gps_traits, Gps_top_traits>::
|
||||
construct_polygon(ccb, pgn_boundary, m_traits);
|
||||
|
||||
Ccb_halfedge_const_circulator ccb_end = ccb;
|
||||
|
|
@ -135,9 +158,10 @@ public:
|
|||
++ccb;
|
||||
}
|
||||
while(ccb != ccb_end);
|
||||
Polygon_with_holes_2 pgn = m_traits->construct_polygon_with_holes_2_object()(pgn_boundary,
|
||||
m_pgn_holes.begin(),
|
||||
m_pgn_holes.end());
|
||||
Polygon_with_holes_2 pgn =
|
||||
m_traits->construct_polygon_with_holes_2_object()(pgn_boundary,
|
||||
m_pgn_holes.begin(),
|
||||
m_pgn_holes.end());
|
||||
/*Polygon_with_holes_2 pgn(pgn_boundary,
|
||||
m_pgn_holes.begin(),
|
||||
m_pgn_holes.end());*/
|
||||
|
|
@ -148,13 +172,14 @@ public:
|
|||
|
||||
void scan_contained_ubf(Face_const_iterator ubf)
|
||||
{
|
||||
CGAL_assertion(ubf->is_unbounded() && ubf->contained());
|
||||
CGAL_assertion(ubf->number_of_outer_ccbs() == 0 && ubf->contained());
|
||||
// ubf is contained -> unbounded polygon !!
|
||||
all_incident_faces(ubf);
|
||||
Polygon_2 boundary;
|
||||
Polygon_with_holes_2 pgn = m_traits->construct_polygon_with_holes_2_object()(boundary,
|
||||
m_pgn_holes.begin(),
|
||||
m_pgn_holes.end());
|
||||
Polygon_with_holes_2 pgn =
|
||||
m_traits->construct_polygon_with_holes_2_object()(boundary,
|
||||
m_pgn_holes.begin(),
|
||||
m_pgn_holes.end());
|
||||
/*Polygon_with_holes_2 pgn(boundary,
|
||||
m_pgn_holes.begin(),
|
||||
m_pgn_holes.end());*/
|
||||
|
|
@ -168,37 +193,46 @@ public:
|
|||
{
|
||||
CGAL_assertion(!f->visited());
|
||||
f->set_visited(true);
|
||||
if (!f->is_unbounded())
|
||||
if (f->number_of_outer_ccbs() != 0)
|
||||
{
|
||||
if (!f->contained())
|
||||
{
|
||||
m_pgn_holes.push_back(Polygon_2());
|
||||
General_polygon_set_2<Gps_traits, Gps_dcel>::
|
||||
construct_polygon(f->outer_ccb(), m_pgn_holes.back(), m_traits);
|
||||
for (Outer_ccb_const_iterator oci = f->outer_ccbs_begin();
|
||||
oci != f->outer_ccbs_end(); ++oci)
|
||||
{
|
||||
m_pgn_holes.push_back(Polygon_2());
|
||||
General_polygon_set_on_surface_2<Gps_traits, Gps_top_traits>::
|
||||
construct_polygon(*oci, m_pgn_holes.back(), m_traits);
|
||||
}
|
||||
|
||||
m_holes_q.push(f);
|
||||
}
|
||||
|
||||
|
||||
Ccb_halfedge_const_circulator ccb_end = f->outer_ccb();
|
||||
Ccb_halfedge_const_circulator ccb_circ = ccb_end;
|
||||
do
|
||||
{
|
||||
//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())
|
||||
{
|
||||
all_incident_faces(new_f);
|
||||
for (Outer_ccb_const_iterator oci = f->outer_ccbs_begin();
|
||||
oci != f->outer_ccbs_end(); ++oci)
|
||||
{
|
||||
Ccb_halfedge_const_circulator ccb_end = *oci;
|
||||
Ccb_halfedge_const_circulator ccb_circ = ccb_end;
|
||||
do
|
||||
{
|
||||
//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())
|
||||
{
|
||||
all_incident_faces(new_f);
|
||||
}
|
||||
++ccb_circ;
|
||||
}
|
||||
++ccb_circ;
|
||||
while(ccb_circ != ccb_end);
|
||||
}
|
||||
while(ccb_circ != ccb_end);
|
||||
}
|
||||
|
||||
if (f->contained())
|
||||
{
|
||||
Hole_const_iterator hit;
|
||||
for(hit = f->holes_begin(); hit != f->holes_end(); ++hit)
|
||||
Inner_ccb_const_iterator hit;
|
||||
for(hit = f->inner_ccbs_begin(); hit != f->inner_ccbs_end(); ++hit)
|
||||
{
|
||||
Ccb_halfedge_const_circulator ccb_of_hole = *hit;
|
||||
Halfedge_const_iterator he = ccb_of_hole;
|
||||
|
|
@ -207,11 +241,10 @@ public:
|
|||
CGAL_assertion(!he->twin()->face()->contained());
|
||||
|
||||
m_pgn_holes.push_back(Polygon_2());
|
||||
General_polygon_set_2<Gps_traits, Gps_dcel>::
|
||||
General_polygon_set_on_surface_2<Gps_traits, Gps_top_traits>::
|
||||
construct_polygon(he->twin()->face()->outer_ccb(),
|
||||
m_pgn_holes.back(), m_traits);
|
||||
m_holes_q.push(he->twin()->face());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -259,17 +292,34 @@ class Init_faces_visitor
|
|||
|
||||
public:
|
||||
|
||||
void flip_face(Face_iterator f1, Face_iterator f2, Halfedge_iterator /*he*/)
|
||||
//! discovered_face
|
||||
/*! discovered_face is called by Gps_bfs_scanner when it reveals a new face
|
||||
during a BFS scan. It is important to say that I have a strong suspition
|
||||
that this place is the reason why discovered_face was once called
|
||||
"flip_face" (WTF?)
|
||||
\param old_f The face that was already revealed
|
||||
\param new_f The face that we have just now revealed
|
||||
*/
|
||||
void discovered_face(Face_iterator old_f,
|
||||
Face_iterator new_f,
|
||||
Halfedge_iterator /*he*/)
|
||||
{
|
||||
f2->set_contained(!f1->contained());
|
||||
new_f->set_contained(!old_f->contained());
|
||||
}
|
||||
};
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
_insert(const Polygon_2& pgn, Arrangement_2 & arr)
|
||||
|
||||
//! _insert
|
||||
/*! The function inserts a polygon into an arrangement, assuming that the
|
||||
polygon is contained in one face of the arrangement.
|
||||
\param pgn The polygon to be inserted to the arrangement. pgn must be
|
||||
completely disjoint from the arrangement
|
||||
\param arr The arrangement to insert the polygon to.
|
||||
*/
|
||||
template <class Traits_, class TopTraits_>
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
_insert(const Polygon_2& pgn, Arrangement_on_surface_2 & arr)
|
||||
{
|
||||
typedef Arr_accessor<Arrangement_2> Arr_accessor;
|
||||
typedef Arr_accessor<Arrangement_on_surface_2> Arr_accessor;
|
||||
|
||||
Arr_accessor accessor(arr);
|
||||
Compare_endpoints_xy_2 cmp_ends = m_traits->compare_endpoints_xy_2_object();
|
||||
|
|
@ -283,23 +333,29 @@ _insert(const Polygon_2& pgn, Arrangement_2 & arr)
|
|||
Curve_const_iterator curr = itr_pair.first;
|
||||
Curve_const_iterator end = itr_pair.second;
|
||||
|
||||
Face_iterator f;
|
||||
if (arr.is_empty())
|
||||
const Arr_parameter_space ps_x =
|
||||
m_traits_adaptor.parameter_space_in_x_2_object()(*curr, ARR_MIN_END);
|
||||
const Arr_parameter_space ps_y =
|
||||
m_traits_adaptor.parameter_space_in_y_2_object()(*curr, ARR_MIN_END);
|
||||
|
||||
Object obj_f;
|
||||
if ((ps_x == ARR_INTERIOR) && (ps_y == ARR_INTERIOR))
|
||||
{
|
||||
f = arr.unbounded_face();
|
||||
Point_location pl(arr);
|
||||
obj_f = pl.locate(m_traits->construct_min_vertex_2_object()(*curr));
|
||||
}
|
||||
else
|
||||
{
|
||||
Walk_pl pl(arr);
|
||||
|
||||
Object obj = pl.locate(m_traits->construct_min_vertex_2_object()(*curr));
|
||||
|
||||
Face_const_iterator const_f;
|
||||
// pgn must be completely disjoint from the arrangement
|
||||
CGAL_assertion(CGAL::assign(const_f, obj) && !const_f->contained());
|
||||
CGAL::assign(const_f, obj);
|
||||
f = arr.non_const_handle(const_f);
|
||||
obj_f = accessor.locate_curve_end(*curr, ARR_MIN_END, ps_x, ps_y);
|
||||
}
|
||||
|
||||
Face_const_handle const_f;
|
||||
// face should not be contained as the pgn is completly disjoint of the
|
||||
// arrangement.
|
||||
CGAL_assertion(CGAL::assign(const_f, obj_f) && !const_f->contained());
|
||||
CGAL::assign(const_f, obj_f);
|
||||
Face_iterator f = arr.non_const_handle(const_f);
|
||||
|
||||
Halfedge_handle first_he =
|
||||
arr.insert_in_face_interior(*curr, f);
|
||||
//first_he is directed from left to right (see insert_in_face_interior)
|
||||
|
|
@ -332,8 +388,7 @@ _insert(const Polygon_2& pgn, Arrangement_2 & arr)
|
|||
cmp_ends(*temp),
|
||||
new_face_created);
|
||||
CGAL_assertion(new_face_created);
|
||||
CGAL_assertion((he->face() != he->twin()->face()) &&
|
||||
(he->face() != arr.unbounded_face()));
|
||||
CGAL_assertion((he->face() != he->twin()->face()));
|
||||
|
||||
he->face()->set_contained(true);
|
||||
return;
|
||||
|
|
@ -365,36 +420,36 @@ _insert(const Polygon_2& pgn, Arrangement_2 & arr)
|
|||
cmp_ends(last_cv),
|
||||
new_face_created);
|
||||
CGAL_assertion(new_face_created);
|
||||
CGAL_assertion((last_he->face() != last_he->twin()->face()) &&
|
||||
(last_he->face() != arr.unbounded_face()));
|
||||
CGAL_assertion((last_he->face() != last_he->twin()->face()));
|
||||
|
||||
last_he->face()->set_contained(true);
|
||||
}
|
||||
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template<class PolygonIter >
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
insert(PolygonIter p_begin, PolygonIter p_end)
|
||||
{
|
||||
typename std::iterator_traits<PolygonIter>::value_type pgn;
|
||||
//check validity of all polygons
|
||||
for( ; p_begin != p_end; ++p_begin)
|
||||
//check validity of all polygons
|
||||
for( ; p_begin != p_end; ++p_begin)
|
||||
{
|
||||
CGAL_precondition(is_valid_unkown_polygon(*p_begin, *m_traits));
|
||||
CGAL_precondition(is_valid_unknown_polygon(*p_begin, *m_traits));
|
||||
}
|
||||
|
||||
_insert(p_begin, p_end, pgn);
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template<class PolygonIter, class PolygonWithHolesIter>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
insert(PolygonIter p_begin, PolygonIter p_end,
|
||||
PolygonWithHolesIter pwh_begin, PolygonWithHolesIter pwh_end)
|
||||
{
|
||||
typedef std::list<X_monotone_curve_2> XCurveList;
|
||||
typedef Init_faces_visitor<Arrangement_2> My_visitor;
|
||||
typedef Gps_bfs_scanner<Arrangement_2, My_visitor> Arr_bfs_scanner;
|
||||
typedef Init_faces_visitor<Arrangement_on_surface_2> My_visitor;
|
||||
typedef Gps_bfs_scanner<Arrangement_on_surface_2, My_visitor> Arr_bfs_scanner;
|
||||
|
||||
XCurveList xcurve_list;
|
||||
|
||||
|
|
@ -415,7 +470,14 @@ insert(PolygonIter p_begin, PolygonIter p_end,
|
|||
insert_non_intersecting_curves(*m_arr, xcurve_list.begin(), xcurve_list.end());
|
||||
|
||||
if (is_unbounded)
|
||||
m_arr->unbounded_face()->set_contained(true);
|
||||
{
|
||||
for (Face_iterator fit = m_arr->faces_begin();
|
||||
fit != m_arr->faces_end(); ++fit)
|
||||
{
|
||||
if (fit->number_of_outer_ccbs() == 0)
|
||||
fit->set_contained(true);
|
||||
}
|
||||
}
|
||||
|
||||
My_visitor v;
|
||||
Arr_bfs_scanner scanner(v);
|
||||
|
|
@ -424,9 +486,9 @@ insert(PolygonIter p_begin, PolygonIter p_end,
|
|||
}
|
||||
|
||||
//insert a range of simple polygons to the arrangement
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template<class PolygonIter>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
_insert(PolygonIter p_begin, PolygonIter p_end, Polygon_2 & /*pgn*/)
|
||||
{
|
||||
for(PolygonIter pitr = p_begin; pitr != p_end; ++pitr)
|
||||
|
|
@ -435,14 +497,14 @@ _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_2 & /*pgn*/)
|
|||
}
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template<class PolygonIter>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
_insert(PolygonIter p_begin, PolygonIter p_end, Polygon_with_holes_2 & /*pgn*/)
|
||||
{
|
||||
typedef std::list<X_monotone_curve_2> XCurveList;
|
||||
typedef Init_faces_visitor<Arrangement_2> My_visitor;
|
||||
typedef Gps_bfs_scanner<Arrangement_2, My_visitor> Arr_bfs_scanner;
|
||||
typedef Init_faces_visitor<Arrangement_on_surface_2> My_visitor;
|
||||
typedef Gps_bfs_scanner<Arrangement_on_surface_2, My_visitor> Arr_bfs_scanner;
|
||||
|
||||
XCurveList xcurve_list;
|
||||
bool is_unbounded = false;
|
||||
|
|
@ -456,7 +518,14 @@ _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_with_holes_2 & /*pgn*/)
|
|||
insert_non_intersecting_curves(*m_arr, xcurve_list.begin(), xcurve_list.end());
|
||||
|
||||
if (is_unbounded)
|
||||
m_arr->unbounded_face()->set_contained(true);
|
||||
{
|
||||
for (Face_iterator fit = m_arr->faces_begin();
|
||||
fit != m_arr->faces_end(); ++fit)
|
||||
{
|
||||
if (fit->number_of_outer_ccbs() == 0)
|
||||
fit->set_contained(true);
|
||||
}
|
||||
}
|
||||
|
||||
My_visitor v;
|
||||
Arr_bfs_scanner scanner(v);
|
||||
|
|
@ -464,18 +533,17 @@ _insert(PolygonIter p_begin, PolygonIter p_end, Polygon_with_holes_2 & /*pgn*/)
|
|||
_reset_faces(m_arr);
|
||||
}
|
||||
|
||||
|
||||
//insert non-sipmle poloygons with holes (non incident edges may have
|
||||
//insert non-sipmle poloygons with holes (non incident edges may have
|
||||
// common vertex, but they dont intersect at their interior
|
||||
template <class Traits_, class Dcel_>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
_insert(const Polygon_with_holes_2 & pgn, Arrangement_2 & arr)
|
||||
template <class Traits_, class TopTraits_>
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
_insert(const Polygon_with_holes_2 & pgn, Arrangement_on_surface_2 & arr)
|
||||
{
|
||||
//not needed gps.insert(PWH) has the precondition
|
||||
// CGAL_precondition(is_valid_polygon_with_holes(pgn, *m_traits));
|
||||
typedef std::list<X_monotone_curve_2> XCurveList;
|
||||
typedef Init_faces_visitor<Arrangement_2> My_visitor;
|
||||
typedef Gps_bfs_scanner<Arrangement_2, My_visitor> Arr_bfs_scanner;
|
||||
typedef Init_faces_visitor<Arrangement_on_surface_2> My_visitor;
|
||||
typedef Gps_bfs_scanner<Arrangement_on_surface_2, My_visitor> Arr_bfs_scanner;
|
||||
|
||||
XCurveList xcurve_list;
|
||||
_construct_curves(pgn, std::back_inserter(xcurve_list));
|
||||
|
|
@ -483,7 +551,14 @@ _insert(const Polygon_with_holes_2 & pgn, Arrangement_2 & arr)
|
|||
|
||||
//if (pgn.is_unbounded())
|
||||
if (m_traits->construct_is_unbounded_object()(pgn))
|
||||
arr.unbounded_face()->set_contained(true);
|
||||
{
|
||||
for (Face_iterator fit = arr.faces_begin();
|
||||
fit != arr.faces_end(); ++fit)
|
||||
{
|
||||
if (fit->number_of_outer_ccbs() == 0)
|
||||
fit->set_contained(true);
|
||||
}
|
||||
}
|
||||
|
||||
My_visitor v;
|
||||
Arr_bfs_scanner scanner(v);
|
||||
|
|
@ -491,10 +566,10 @@ _insert(const Polygon_with_holes_2 & pgn, Arrangement_2 & arr)
|
|||
_reset_faces(&arr);
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template <class OutputIterator>
|
||||
void
|
||||
General_polygon_set_2<Traits_, Dcel_>::
|
||||
General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
_construct_curves(const Polygon_2 & pgn, OutputIterator oi)
|
||||
{
|
||||
std::pair<Curve_const_iterator,
|
||||
|
|
@ -503,9 +578,9 @@ _construct_curves(const Polygon_2 & pgn, OutputIterator oi)
|
|||
std::copy (itr_pair.first, itr_pair.second, oi);
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template <class OutputIterator>
|
||||
void General_polygon_set_2<Traits_, Dcel_>::
|
||||
void General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
_construct_curves(const Polygon_with_holes_2 & pgn, OutputIterator oi)
|
||||
{
|
||||
//if (!pgn.is_unbounded())
|
||||
|
|
@ -517,7 +592,8 @@ _construct_curves(const Polygon_with_holes_2 & pgn, OutputIterator oi)
|
|||
m_traits->construct_curves_2_object()(pgn_boundary);
|
||||
std::copy (itr_pair.first, itr_pair.second, oi);
|
||||
}
|
||||
std::pair<GP_Holes_const_iterator, GP_Holes_const_iterator> hpair = m_traits->construct_holes_object()(pgn);
|
||||
std::pair<GP_Holes_const_iterator, GP_Holes_const_iterator> hpair =
|
||||
m_traits->construct_holes_object()(pgn);
|
||||
GP_Holes_const_iterator hit;
|
||||
for (hit = hpair.first; hit != hpair.second; ++hit)
|
||||
{
|
||||
|
|
@ -529,26 +605,26 @@ _construct_curves(const Polygon_with_holes_2 & pgn, OutputIterator oi)
|
|||
}
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
template <class Traits_, class TopTraits_>
|
||||
template <class OutputIterator>
|
||||
OutputIterator
|
||||
General_polygon_set_2<Traits_, Dcel_>::
|
||||
General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
polygons_with_holes(OutputIterator out) const
|
||||
{
|
||||
typedef Arr_bfs_scanner<Arrangement_2, OutputIterator> Arr_bfs_scanner;
|
||||
typedef Arr_bfs_scanner<Arrangement_on_surface_2, OutputIterator> Arr_bfs_scanner;
|
||||
Arr_bfs_scanner scanner(this->m_traits, out);
|
||||
scanner.scan(*(this->m_arr));
|
||||
return (scanner.output_iterator());
|
||||
}
|
||||
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
typename General_polygon_set_2<Traits_, Dcel_>::Size
|
||||
General_polygon_set_2<Traits_, Dcel_>::
|
||||
template <class Traits_, class TopTraits_>
|
||||
typename General_polygon_set_on_surface_2<Traits_, TopTraits_>::Size
|
||||
General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
number_of_polygons_with_holes() const
|
||||
{
|
||||
|
||||
typedef Arr_bfs_scanner<Arrangement_2, Counting_output_iterator>
|
||||
typedef Arr_bfs_scanner<Arrangement_on_surface_2, Counting_output_iterator>
|
||||
Arr_bfs_scanner;
|
||||
//counting_output_operator CTOR reqires a parameter
|
||||
std::size_t *cc = new size_t();
|
||||
|
|
@ -557,11 +633,12 @@ number_of_polygons_with_holes() const
|
|||
return (scanner.output_iterator().current_counter());
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
bool General_polygon_set_2<Traits_, Dcel_>::
|
||||
|
||||
template <class Traits_, class TopTraits_>
|
||||
bool General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
locate(const Point_2& q, Polygon_with_holes_2& pgn) const
|
||||
{
|
||||
Walk_pl pl(*m_arr);
|
||||
Point_location pl(*m_arr);
|
||||
|
||||
Object obj = pl.locate(q);
|
||||
Face_const_iterator f;
|
||||
|
|
@ -601,7 +678,7 @@ locate(const Point_2& q, Polygon_with_holes_2& pgn) const
|
|||
}
|
||||
|
||||
typedef Oneset_iterator<Polygon_with_holes_2> OutputItr;
|
||||
typedef Arr_bfs_scanner<Arrangement_2, OutputItr> Arr_bfs_scanner;
|
||||
typedef Arr_bfs_scanner<Arrangement_on_surface_2, OutputItr> Arr_bfs_scanner;
|
||||
|
||||
OutputItr oi (pgn);
|
||||
Arr_bfs_scanner scanner(this->m_traits, oi);
|
||||
|
|
@ -609,10 +686,17 @@ locate(const Point_2& q, Polygon_with_holes_2& pgn) const
|
|||
|
||||
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());
|
||||
for (Face_iterator fit = m_arr->faces_begin(); fit != m_arr->faces_end();
|
||||
++fit)
|
||||
{
|
||||
if (fit->number_of_outer_ccbs() == 0)
|
||||
scanner.scan_contained_ubf(fit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -626,19 +710,27 @@ locate(const Point_2& q, Polygon_with_holes_2& pgn) const
|
|||
return true;
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
typename General_polygon_set_2<Traits_, Dcel_>::Ccb_halfedge_const_circulator
|
||||
General_polygon_set_2<Traits_, Dcel_>::
|
||||
template <class Traits_, class TopTraits_>
|
||||
typename General_polygon_set_on_surface_2<Traits_, TopTraits_>::Ccb_halfedge_const_circulator
|
||||
General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
get_boundary_of_polygon(Face_const_iterator f) const
|
||||
{
|
||||
CGAL_assertion(!f->visited());
|
||||
f->set_visited(true);
|
||||
|
||||
if (f->is_unbounded())
|
||||
if (f->number_of_outer_ccbs() == 0) // (f->is_unbounded())
|
||||
{
|
||||
return Ccb_halfedge_const_circulator();
|
||||
}
|
||||
Ccb_halfedge_const_circulator ccb_end = f->outer_ccb();
|
||||
|
||||
// We assume that a polygon has only one outer_ccb. This code does not handle
|
||||
// the case where there are more than 1 outer ccbs. If this is the case, we
|
||||
// need to devise a method to convert the outer ccbs to inner ccbs so we
|
||||
// will have only one outer ccb.
|
||||
if (f->number_of_outer_ccbs() > 1)
|
||||
CGAL_error_msg("Not implemented yet.");
|
||||
|
||||
Ccb_halfedge_const_circulator ccb_end = *f->outer_ccbs_begin();
|
||||
Ccb_halfedge_const_circulator ccb_circ = ccb_end;
|
||||
do
|
||||
{
|
||||
|
|
@ -659,12 +751,13 @@ get_boundary_of_polygon(Face_const_iterator f) const
|
|||
|
||||
}
|
||||
|
||||
template <class Traits_, class Dcel_>
|
||||
bool General_polygon_set_2<Traits_, Dcel_>::
|
||||
template <class Traits_, class TopTraits_>
|
||||
bool General_polygon_set_on_surface_2<Traits_, TopTraits_>::
|
||||
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)
|
||||
Inner_ccb_const_iterator holes_it;
|
||||
for (holes_it = f->inner_ccbs_begin();
|
||||
holes_it != f->inner_ccbs_end(); ++holes_it)
|
||||
{
|
||||
Ccb_halfedge_const_circulator ccb = *holes_it;
|
||||
Ccb_halfedge_const_circulator ccb_end = ccb;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -40,6 +40,7 @@ class Polygon_set_2 :
|
|||
private:
|
||||
typedef General_polygon_set_2<Gps_segment_traits_2<Kernel, Containter>, Dcel_>
|
||||
Base;
|
||||
typedef typename Base::Base Base_of_base;
|
||||
typedef Polygon_set_2<Kernel, Containter, Dcel_> Self;
|
||||
|
||||
public:
|
||||
|
|
@ -237,9 +238,9 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
inline const Base& base(const Self& other) const
|
||||
inline const Base_of_base& base(const Self& other) const
|
||||
{
|
||||
return (static_cast<const Base&>(other));
|
||||
return (static_cast<const Base_of_base&>(other));
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ int main (int argc, char **argv) {
|
|||
|
||||
int result = 0;
|
||||
for (int i=1;i<10;i++) {
|
||||
std::stringstream strs;
|
||||
std::string si;
|
||||
strs << i;
|
||||
std::stringstream strs;
|
||||
std::string si;
|
||||
strs << i;
|
||||
strs >> si;
|
||||
std::string filename = testfilePrefix + si + testfileSuffix;
|
||||
const char *cfilename = filename.c_str();
|
||||
|
|
@ -126,8 +126,11 @@ int main (int argc, char **argv) {
|
|||
}
|
||||
if (result == 0)
|
||||
std::cout <<"ALL TESTS SUCCEEDED!" << std::endl;
|
||||
else
|
||||
else
|
||||
{
|
||||
std::cout <<"SOME TESTS FAILED" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue