diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt
index 22326e51da2..b147cf1f81f 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt
@@ -695,14 +695,17 @@ as follows:
- You can obtain a pair of iterators of type \link
- ArrangementDcelFace::Hole_iterator `Hole_iterator`\endlink that
+ Arrangement_2::Face::Hole_iterator `Hole_iterator`\endlink that
define the range of holes inside a face \f$f\f$ by calling \link
Arrangement_2::Face::holes_begin() `f->holes_begin()`\endlink and
\link Arrangement_2::Face::holes_end() `f->holes_end()`\endlink. The
value type of this iterator type is \link
Arrangement_2::Ccb_halfedge_circulator
`Ccb_halfedge_circulator`\endlink, defining the CCB that winds in a
- clockwise order around a hole.
+ clockwise order around a hole. The call \link
+ Arrangement_2::Face::number_of_holes()
+ `f->number_of_holes()`\endlink return the number of holes in
+ \f$f\f$.
- The calls \link Arrangement_2::Face::isolated_vertices_begin()
`f->isolated_vertices_begin()`\endlink and \link
@@ -2434,27 +2437,26 @@ and \f$f\f$ be handles to a vertex of type
provides the Boolean predicate \link
Arrangement_2::Halfedge::is_fictitious `is_fictitious()`\endlink. If
the call \link Arrangement_2::Halfedge::is_fictitious
- `e->is_fictitious()`\endlink predicate evaluates to `false`, you can
- access the \f$x\f$-monotone curve associated with
- \f$e\f$. Otherwise, \f$e\f$ is not associated with an \link
- Arrangement_2::X_monotone_curve_2 `X_monotone_curve_2`\endlink object.
+ `e->is_fictitious()`\endlink evaluates to `false`, you can access
+ the \f$x\f$-monotone curve associated with \f$e\f$. Otherwise,
+ \f$e\f$ is not associated with an \link
+ Arrangement_2::X_monotone_curve_2 `X_monotone_curve_2`\endlink
+ object.
- The nested \link Arrangement_2::Face `Face`\endlink type provides
the Boolean predicate \link Arrangement_2::Face::is_fictitious()
`is_fictitious()`\endlink. The call \link
Arrangement_2::Face::is_fictitious() `f->is_fictitious()`\endlink
- predicate evaluates to `true` only when \f$f\f$ lies outside the
- bounding rectangle. The method \link
- Arrangement_2::Face::outer_ccb() `outer_ccb()`\endlink (see Section
- \ref arr_sssectr_face must not be invoked for the fictitious
- face. \cgalFootnote{Typically, the code is guarded against such
- malicious calls with adequate preconditions. However, these
- preconditions are suppressed when the code is compiled with maximum
- optimization.}
- Note that a valid unbounded face (of an arrangement
- that supports unbounded curves) has a valid outer CCB, although the
- CCB comprises only fictitious halfedges if the arrangement is
- induced only by bounded curves.
+ evaluates to `true` only when \f$f\f$ lies outside the bounding
+ rectangle. The method \link Arrangement_2::Face::outer_ccb()
+ `outer_ccb()`\endlink (see Section \ref arr_sssectr_face must not be
+ invoked for the fictitious face. \cgalFootnote{Typically, the code
+ is guarded against such malicious calls with adequate
+ preconditions. However, these preconditions are suppressed when the
+ code is compiled with maximum optimization.} Note that a valid
+ unbounded face (of an arrangement that supports unbounded curves)
+ has a valid outer CCB, although the CCB comprises only fictitious
+ halfedges if the arrangement is induced only by bounded curves.
@@ -2876,27 +2878,29 @@ can be used to represent a 2D arrangement embedded in a 3D
surface. The template is parameterized by template parameters
geometry traits and topology traits. The
topology-traits type deals with the topology of the parametric
-surface. As explained in the previous section, a parametric surface
-\f$S \f$ is given by a continuous function \f$\phi_S: \Phi \rightarrow
-\mathbb{R}^3\f$, where the domain \f$\Phi = X \times Y\f$ is a
-rectangular two-dimensional parameter space; \f$S =
-\phi_S(\Phi)\f$. \f$X\f$ and \f$Y\f$ are open, half-open, or closed
-intervals with endpoints in \f$\overline{\mathbb{R}}\f$.
+surface; see Section \ref aos_sec-topol_traits. As explained in the
+previous section, a parametric surface \f$S \f$ is given by a
+continuous function \f$\phi_S: \Phi \rightarrow \mathbb{R}^3\f$, where
+the domain \f$\Phi = X \times Y\f$ is a rectangular two-dimensional
+parameter space; \f$S = \phi_S(\Phi)\f$. \f$X\f$ and \f$Y\f$ are open,
+half-open, or closed intervals with endpoints in
+\f$\overline{\mathbb{R}}\f$.
The geometry-traits type introduces the type names of the basic
geometric objects (i.e., point, curve, and \f$u \f$-monotone curve)
and the set of operations on objects of these types required to
construct and maintain the arrangement and to operate on it. The
traits-concept hierarchy described in Section \ref aos_sec-geom_traits
-accurately defines the requirements imposed on a model of a
-geometry traits class. Recall that requirements apply to the parameter
-space \f$\Phi = X \times Y\f$; thus, they are defined in terms of
-\f$x\f$ and \f$y\f$ coordinates. Most requirements apply to all type
-of arrangements regardless of the embedding surface. However, several
+accurately defines the requirements imposed on a model of a geometry
+traits class. Recall that requirements apply to the parameter space
+\f$\Phi = X \times Y\f$; thus, they are defined in terms of \f$x\f$
+and \f$y\f$ coordinates. Most requirements apply to all type of
+arrangements regardless of the embedding surface. However, several
refined concepts apply only to arrangements on surfaces that are not
-the plane, that is, modeled with \f$\phi_S\f$ not being the identity
-mapping. They differ according to the type of the side boundaries of
-the parameter space being open, closed, contracted, or identified.
+in the plane, that is, modeled with \f$\phi_S\f$ not being the
+identity mapping. They differ according to the type of the side
+boundaries of the parameter space being open, closed, contracted, or
+identified.
At this point only one type of arrangements on non planar surfaces is
supported, namely, arrangements embedded in the sphere and induced by
@@ -2931,6 +2935,127 @@ Sites are drawn in red and Voronoi edges are drawn in blue.
(d) A degenerate power diagram of 14 sites on the sphere.
\cgalFigureCaptionEnd
+
+\subsection aos_ssec-curved_surfaces-basic Basic Manipulation and Traversal Methods
+
+
+The types \link Arrangement_on_surface_2::Vertex `Vertex`\endlink,
+\link Arrangement_on_surface_2::Halfedge `Halfedge`\endlink, and \link
+Arrangement_on_surface_2::Face `Face`\endlink nested in the
+`Arrangement_on_surface_2` class template support the methods listed
+in Section \ref arr_ssectraverse and in Section \ref
+arr_sssecunb_basic. Let \f$v\f$, \f$e\f$, and \f$f\f$ be handles to a
+vertex of type \link Arrangement_on_surface_2::Vertex
+`Vertex`\endlink, a halfedge of type \link
+Arrangement_on_surface_2::Halfedge `Halfedge`\endlink, and a face of
+type \link Arrangement_on_surface_2::Face `Face`\endlink,
+respectively.
+
+
+
+- The calls \link
+ Arrangement_on_surface_2::Vertex::parameter_space_in_x()
+ `v->parameter_space_in_x()`\endlink and \link
+ Arrangement_on_surface_2::Vertex::parameter_space_in_y()
+ `v->parameter_space_in_y()`\endlink determine the location of the
+ geometric embedding of the vertex \f$v\f$. The call \link
+ Arrangement_on_surface_2::Vertex::parameter_space_in_x()
+ `v->parameter_space_in_x()`\endlink returns `CGAL::ARR_INTERIOR` if
+ the geometric embedding of \f$v\f$ is a point \f$p\f$ that does not
+ lie on the left nor on the right sides of the boundary of the
+ parameter space. If the left and right sides are not identified,
+ then `CGAL::ARR_LEFT_BOUNDARY` or `CGAL::ARR_RIGHT_BOUNDARY` are
+ returned if \f$p\f$ lies on the left or the right side,
+ respectively. If the left and right sides are identified, the
+ return value is non-deterministic. Similarly, the call \link
+ Arrangement_2::Vertex::parameter_space_in_y()
+ `v->parameter_space_in_y()`\endlink returns `CGAL::ARR_INTERIOR` if
+ the geometric embedding of \f$v\f$ is a point \f$q\f$ that does not
+ lie on the bottom nor on the top sides of the boundary of the
+ parameter space. If the bottom and top sides are not identified,
+ then `CGAL::ARR_BOTTOM_BOUNDARY` or `CGAL::ARR_TOP_BOUNDARY` are
+ returned if \f$q\f$ lies on the bottom or the top side,
+ respectively. If the bottom and top sides are identified, the
+ return value is non-deterministic.
+
+ If you want to determine whether a point \f$p\f$ lies on identified
+ sides, you need to exploit one of the two traits functors \link
+ ArrangementIdentifiedVerticalTraits_2::Is_on_y_identification_2
+ `Is_on_y_identification_2`\endlink or \link
+ ArrangementIdentifiedVerticalTraits_2::Is_on_y_identification_2
+ `Is_on_y_identification_2`\endlink; see Section \ref
+ aos_ssec-traits-curved. If \f$p\f$ is incident to an
+ \f$x\f$-monotone curve \f$c\f$ and \f$c\f$ is not vertical (thus,
+ does not lie on the identified side as well), you can determine the
+ boundary side of the end of \f$c\f$ associated with \f$p\f$
+ exploiting either the \link
+ ArrangementVerticalSideTraits_2::Parameter_space_in_x_2
+ `Parameter_space_in_x_2`\endlink functor or the \link
+ ArrangementHorizontalSideTraits_2::Parameter_space_in_y_2
+ `Parameter_space_in_x_2`\endlink functor; see Section \ref
+ aos_ssec-traits-curved.
+
+
- A face in a planar arrangement has at most one outer CCB. However,
+ a face in an arrangement embedded on a surface, such as a torus, may
+ have two outer CCBs; to this end, the methods \link
+ Arrangement_on_surface_2::Face::outer_ccbs_begin()
+ `outer_ccbs_begin()`\endlink and \link
+ Arrangement_on_surface_2::Face::outer_ccbs_end()
+ `outer_ccbs_end()`\endlink return a pair of iterators of type \link
+ Arrangement_on_surface_2::Face::Outer_ccb_iterator
+ `Outer_ccb_iterator`\endlink that define a range of outer CCBs
+ inside the face \f$f\f$. Similarly, the methods \link
+ Arrangement_on_surface_2::Face::inner_ccbs_begin()
+ `inner_ccbs_begin()`\endlink and \link
+ Arrangement_on_surface_2::Face::inner_ccbs_end()
+ `inner_ccbs_end()`\endlink return a pair of iterators of type \link
+ Arrangement_on_surface_2::Face::Inner_ccb_iterator
+ `Inner_ccb_iterator`\endlink that define a range of inner CCBs
+ inside the face \f$f\f$. (The latter pair of member functions and
+ the iterator type are equivalent to the methods \link
+ Arrangement_on_surface_2::Face::holes_begin()
+ `holes_begin()`\endlink, \link
+ Arrangement_on_surface_2::Face::holes_end() `holes()`\endlink, and
+ \link Arrangement_on_surface_2::Face::Hole_iterator
+ `Hole_iterator`\endlink; see Section arr_sssectr_face.) The calls
+ \link Arrangement_on_surface_2::Face::number_of_outer_ccbs()
+ `f->number_of_outer_ccbs()`\endlink and \link
+ Arrangement_on_surface_2::Face::number_of_inner_ccbs()
+ `f->number_of_inner_ccbs()`\endlink return the number of outer CCBs
+ and the number of inner CCBs in \f$f\f$, respectively.
+
+
+
+The template function `is_in_x_range()` listed below, and defined in the
+file `is_in_x_range.h`, checks whether a given point \f$p\f$ is in the
+$x$-range of the curve associated with a given halfedge \f$e\f$. The
+function template also exemplifies how some of the above functions can
+be used.
+
+\code
+bool is_in_x_range(const X_monotone_curve_2& xcv, const Point_2& point) const {
+ typedef Arr_geodesic_arc_on_sphere_traits_2 Traits;
+
+ Direction_2 p = project_xy(point);
+ if (xcv.is_vertical()) {
+ const Direction_3& normal = xcv.normal();
+ Direction_2 q = (xcv.is_directed_right()) ?
+ Direction_2(-(normal.dy()), normal.dx()) :
+ Direction_2(normal.dy(), -(normal.dx()));
+ const Kernel& kernel = *this;
+ return kernel.equal_2_object()(p, q);
+ }
+
+ // The curve is not vertical:
+ Direction_2 r = project_xy(xcv.right());
+ const Kernel& kernel = *this;
+ if (kernel.equal_2_object()(p, r)) return true;
+ Direction_2 l = Traits::project_xy(xcv.left());
+ if (kernel.equal_2_object()(p, l)) return true;
+ return kernel.counterclockwise_in_between_2_object()(p, l, r);
+}
+\endcode
+
\section aos_sec-geom_traits The Geometry Traits
@@ -5250,9 +5375,17 @@ instantiate the curve-data traits:
\section aos_sec-topol_traits The Topology Traits
-
-At this point we do not expose the topology traits concept. The
-package contains one topology traits, namely,
+A topology traits class encapsulates the definitions of the
+topological entities and the implementation of the functions that
+handle these topological entities, used by the
+`Arrangement_on_surface_2` class
+template and by the peripheral modules. Every topology traits class
+must model the basic concept `ArrangementBasicTopologyTraits`. A model
+of this basic concept holds the (\sc{Dcel}) data structure used to
+represent the arrangement cells (i.e., vertices, edges, and facets)
+and the incident * relations between them. At this point we do not
+expose the concepts that refine the basic concept. The package
+contains one topology traits, namely,
`Arr_spherical_topology_traits_2`. It can serve as a topology traits
for an arrangement embedded on a sphere. More precisely, for an
arrangement embedded on a sphere defined over a parameter space the
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_segment_traits_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_segment_traits_2.h
index dc104a10619..244fdb67252 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_segment_traits_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_segment_traits_2.h
@@ -60,11 +60,11 @@ supports the merging of curves of opposite directions.
\cgalModels `ArrangementDirectionalXMonotoneTraits_2`
*/
-template< typename Kernel >
-class Arr_segment_traits_2 {
+template
+class Arr_segment_traits_2 : public Kernel {
public:
-Class Trim_2{
+Class Trim_2 {
public:
/// \name Creation
/// @{
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_spherical_topology_traits_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_spherical_topology_traits_2.h
index eeed2041379..3969c0a92cc 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_spherical_topology_traits_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_spherical_topology_traits_2.h
@@ -21,6 +21,8 @@ namespace CGAL {
* `Arr_default_dcel`.
*
*
+ * \cgalModels `ArrangementBasicTopologyTraits`
+ *
* \sa `Arr_default_dcel`
* \sa `CGAL::Arr_geodesic_arc_on_sphere_traits_2`
*/
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h
index 68b15923796..0bb487d18bd 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h
@@ -76,20 +76,20 @@ public:
typedef typename Topology_traits::Dcel Dcel;
/*! the point type, as defined by the traits class. */
- typedef typename Geometry__traits_2::Point_2 Point_2;
+ typedef typename Geometry_traits_2::Point_2 Point_2;
/*! the \f$ x\f$-monotone curve type, as defined by the traits class. */
typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2;
/*! the size type (equivalent to `size_t`). */
- typedef typename Dcel::Size Size;
+ typedef typename Dcel::Size Size;
/*! \ingroup PkgArrangementOnSurface2DCEL
* An object \f$ v\f$ of the class `Vertex` represents an arrangement vertex,
* that is a \f$ 0\f$-dimensional cell, associated with a point on the
* ambient surface.
*/
- class Vertex : public Dcel::Vertex {
+ class Vertex : public typename Dcel::Vertex {
public:
/// \name Creation
/// @{
@@ -162,7 +162,7 @@ public:
* Halfedges are stored in doubly-connected lists and form chains. These
* chains define the inner and outer boundaries of connected components.
*/
- class Halfedge : public Dcel::Halfedge {
+ class Halfedge : public typename Dcel::Halfedge {
public:
/// \name Creation
/// @{
@@ -226,8 +226,8 @@ public:
/*! \ingroup PkgArrangementOnSurface2DCEL
*
- * An object of the class `Face` represents an arrangement face, namely, a \f$
- * 2\f$-dimensional arrangement cell. An arrangement that supports only
+ * An object of the class `Face` represents an arrangement face, namely, a
+ * \f$2\f$-dimensional arrangement cell. An arrangement that supports only
* bounded curves contains exactly one unbounded face, and a number of
* bounded faces. An arrangement that supports also unbounded curves has one
* or more unbounded faces. Such an arrangement has also exactly one
@@ -241,8 +241,37 @@ public:
* do not correspond to real curves. A face may also contain holes, which are
* defined by clockwise-oriented halfedge chains, and isolated vertices.
*/
- class Face : public Dcel::Face {
+ class Face : public typename Dcel::Face {
+ private:
+ typedef Dcel::Face Base;
+
public:
+
+ /// \name Types inherited from the base Dcel::Face
+ /// @{
+
+ /*! a bidirectional iterator over the inner CCBs of the face.
+ * Its value type is `Ccb_halfedge_circulator`.
+ */
+ typedef typename Base::Inner_ccb_iterator Inner_ccb_iterator;
+
+ /*! a bidirectional iterator over the outer CCBs of the face.
+ * Its value type is `Ccb_halfedge_circulator`.
+ */
+ typedef typename Base::Outer_ccb_iterator Outer_ccb_iterator;
+
+ /*! a bidirectional iterator over the holes (i.e., inner CCBs) contained
+ * inside the face. Its value type is `Ccb_halfedge_circulator`.
+ */
+ typedef typename Base::Hole_iterator Hole_iterator;
+
+ /*! a bidirectional iterator over the isolated vertices contained inside
+ * the face. Its value type is `Vertex`.
+ */
+ typedef typename Base::Isolated_vertex_iterator Isolated_vertex_iterator;
+
+ /// @}
+
/// \name Creation
/// @{
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTopologyTraits.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTopologyTraits.h
new file mode 100644
index 00000000000..750182554c3
--- /dev/null
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTopologyTraits.h
@@ -0,0 +1,51 @@
+/*! \ingroup PkgArrangementOnSurface2ConceptsTopologyTraits
+ * \cgalConcept
+ *
+ * The concept `ArrangementBasicTopologyTraits` defines the minimal
+ * functionality needed for a model of a topology traits, which can substitutes
+ * the `TopolTraits` template parameters when the class template
+ * `Arrangement_on_surface_2` is instantiated. In
+ * particular. a model of this concept holds the Dcel data structure used to
+ * represent the arrangement cells (i.e., vertices, edges, and facets) and the
+ * incident relations between them.
+ *
+ * \cgalHasModel `CGAL::Arr_spherical_topology_traits_2`
+ */
+
+class ArrangementBasicTopologyTraits {
+public:
+ /// \name Types
+ /// @{
+
+ //! models the concept `ArrTraits::Point_2`.
+ typedef unspecified_type Point_2;
+
+ //! models the concept `ArrTraits::XMonotoneCurve_2`.
+ typedef unspecified_type X_monotone_curve_2;
+
+ //! models the concept `ArrangementDcel`.
+ typedef unspecified_type Dcel;
+
+ /// @}
+
+ /// \name Creation
+ /// @{
+
+ /// @}
+
+ /// \name Access Functions
+ /// @{
+
+ /*! Obtain the DCEL (const version). */
+ const Dcel& dcel() const;
+
+ /*! Obtain the DCEL (non-const version). */
+ Dcel& dcel();
+
+ /// @}
+
+ /// \name Modifiers
+ /// @{
+ /// @}
+
+};
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTraits_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTraits_2.h
index 7680e9f6601..90399a98211 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTraits_2.h
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Concepts/ArrangementBasicTraits_2.h
@@ -103,7 +103,7 @@ public:
/*! models the concept `ArrTraits::ConstructMaxVertex_2`.
*/
-typedef unspecified_type Construct_max_vertex_2;
+ typedef unspecified_type Construct_max_vertex_2;
/*! models the concept `ArrTraits::IsVertical_2`.
*/
diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt
index d82ada01e9d..3d2336b6ee4 100644
--- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt
+++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt
@@ -114,6 +114,7 @@ implemented as peripheral classes or as free (global) functions.
- `ArrangementDcelOuterCcb`
- `ArrangementDcelInnerCcb`
- `ArrangementDcelIsolatedVertex`
+- `ArrangementBasicTopologyTraits`
- `ArrangementBasicTraits_2`
- `ArrangementConstructXMonotoneCurveTraits_2`
- `ArrangementLandmarkTraits_2`
diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unbounded_non_intersecting.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unbounded_non_intersecting.cpp
index 729f720a404..b0293f6051d 100644
--- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unbounded_non_intersecting.cpp
+++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unbounded_non_intersecting.cpp
@@ -31,10 +31,10 @@ int main() {
for (auto it = arr.unbounded_faces_begin(); it != arr.unbounded_faces_end();
++it)
{
- std::cout << "Face no. " << k++ << "(" << it->number_of_outer_ccbs()
- << "," << it->number_of_inner_ccbs() << ")" << ": ";
- Arrangement::Ccb_halfedge_const_circulator first, curr;
- curr = first = it->outer_ccb();
+ std::cout << "Face no. " << k++ << "(" << it->is_unbounded() << ","
+ << it->number_of_holes() << ")" << ": ";
+ Arrangement::Ccb_halfedge_const_circulator first = it->outer_ccb();
+ auto curr = first;
if (! curr->source()->is_at_open_boundary())
std::cout << "(" << curr->source()->point() << ")";