General_polygon_set_on_surface_2 - first verstion

This commit is contained in:
Ophir Setter 2009-02-17 16:21:43 +00:00
parent c50131c8c9
commit 097c3793fd
17 changed files with 2335 additions and 2147 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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);
}
};

View File

@ -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

View File

@ -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&)

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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));
}
};

View File

@ -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);
}