diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bgl_dual_adapter.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bgl_dual_adapter.cpp index aac2d9bf263..25edcebecc1 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bgl_dual_adapter.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bgl_dual_adapter.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/graph_traits_dual.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/graph_traits_dual.h new file mode 100644 index 00000000000..6be8db37bfe --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/graph_traits_dual.h @@ -0,0 +1,539 @@ +// Copyright (c) 2005,2007,2009,2010,2011 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Ron Wein +// Ophir Setter +// Sebastien Loriot +// Efi Fogel + +// This file contains the follwoing three parts: +// 1. The common base class template of the specialized +// Dual class template. +// +// 2. The common base class template of the specialized +// boost::graph_traits > class template. +// +// 3. Macro definitions of free Function templates required by +// the various Boost Graph concepts. There is one macro per required function +// template. Each macro accepts the name of a template class, an instance of +// which represents an arrangement data structure, e.g., Arrangement_2. The +// definitios of the free functions templates for a given arrangement data +// strcture must be present when a dual of this data structure is defined. + +#include + +#ifndef CGAL_GRAPH_TRAITS_DUAL_H +#define CGAL_GRAPH_TRAITS_DUAL_H + +namespace CGAL { + +// Forward declaration. +template class Dual; + +/*! \class + * Generic implementation of the common base class template of the specialized + * Dual class template. + */ +template +class Dual_arrangement_on_surface { +public: + typedef Arrangement_ Arrangement; + typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; + typedef typename Arrangement::Topology_traits Topology_traits; + + typedef typename Arrangement::Size Size; + typedef typename Arrangement::Face_handle Vertex_handle; + typedef typename Arrangement::Halfedge_handle Edge_handle; + + typedef typename Arrangement::Face_iterator Vertex_iterator; + typedef typename Arrangement::Halfedge_iterator Edge_iterator; + +protected: + typedef typename Arrangement::Face_handle Face_handle; + typedef typename Arrangement::Ccb_halfedge_circulator Ccb_halfedge_circulator; + typedef typename Arrangement::Outer_ccb_iterator Outer_ccb_iterator; + typedef typename Arrangement::Inner_ccb_iterator Inner_ccb_iterator; + + /*! \class + * Iterator over the neighbors of a dual vertex (a face in the primal + * arrangement). + * These neighbors are the adjacent faces along the outer boundaries of the + * face and its inner boundaries. + */ + class Face_neighbor_iterator { + typedef Face_neighbor_iterator Self; + + public: + typedef std::forward_iterator_tag iterator_category; + typedef Edge_handle value_type; + typedef value_type reference; + typedef value_type* pointer; + typedef int difference_type; + + private: + Outer_ccb_iterator _outer_ccb_iter; + Inner_ccb_iterator _inner_ccb_iter; + Ccb_halfedge_circulator _ccb_curr; + Ccb_halfedge_circulator _ccb_first; + Face_handle _face; + bool _out; + Edge_handle _hh; + bool _end; + + public: + /*! Default constructor. */ + Face_neighbor_iterator() : _end (true) {} + + /*! Constructor. + * \param face The face (dual vertex). + * \param out_edges Do we need the outgoing or the ingoing halfedges. + * \param start Should we start traversing the edges. + * If false, we construct a past-the-end iterator. + */ + Face_neighbor_iterator(Face_handle face, bool out_edges, bool start) : + _face(face), + _out(out_edges), + _end(! start) + { + CGAL_precondition(! face->is_fictitious()); + + if (start) { + _outer_ccb_iter = _face->outer_ccbs_begin(); + _inner_ccb_iter = _face->inner_ccbs_begin(); + + if (_outer_ccb_iter != _face->outer_ccbs_end()) { + // Start from the first outer CCB, if one exists. + _ccb_curr = _ccb_first = *_outer_ccb_iter; + } + else if (_inner_ccb_iter != face->inner_ccbs_end()) { + // Otherwise, start from the first inner CCB. + _ccb_curr = _ccb_first = *_inner_ccb_iter; + } + else { + // In this case there are no CCBs to traverse: + _end = true; + return; + } + + _hh = this->_dereference(); + + // In case the incident face of the twin halfedge is fictitious, + // skip it and proceed to the next edge. + if (_hh->is_fictitious()) ++(*this); + } + else { // end iterator. + _outer_ccb_iter = _face->outer_ccbs_end(); + _inner_ccb_iter = _face->inner_ccbs_end(); + } + } + + /*! Equality operators. */ + bool operator==(const Self& it) const { return (this->_equal(it)); } + + bool operator!= (const Self& it) const { return (! this->_equal(it)); } + + /*! Dereference operators. */ + reference operator*() const { return (_hh); } + + pointer operator->() const { return (&_hh); } + + /* Increment operators. */ + Self& operator++() + { + do { + this->_increment(); + if (_end) return (*this); + _hh = this->_dereference(); + } while (_hh->is_fictitious()); + return (*this); + } + + Self operator++(int ) + { + Self tmp = *this; + do { + this->_increment(); + if (_end) return (tmp); + _hh = this->_dereference(); + } while (_hh->is_fictitious()); + return (tmp); + } + + private: + /*! Check two iterators for equality. */ + bool _equal(const Self& it) const + { + return (_out == it._out && _face == it._face && ((_end && it._end) || + (_outer_ccb_iter == it._outer_ccb_iter && + _inner_ccb_iter == it._inner_ccb_iter && + _ccb_curr == it._ccb_curr))); + } + + /*! Derefernce the current circulator. */ + Edge_handle _dereference() const + { + if (_out) return (_ccb_curr); + else return (_ccb_curr->twin()); + } + + // Increments of the iterator. + void _increment() + { + CGAL_assertion(! _end); + + // If we have not traversed the entire CCB in full, move to the next + // halfedge along the current CCB. + ++_ccb_curr; + + if (_ccb_curr != _ccb_first) return; + + // In this case we have completed the current CCB and we have to move + // to the next one. + if (_outer_ccb_iter != _face->outer_ccbs_end()) { + // Try to move to the next outer CCB. + ++_outer_ccb_iter; + if (_outer_ccb_iter != _face->outer_ccbs_end()) { + _ccb_curr = _ccb_first = *_outer_ccb_iter; + return; + } + + // In this case we start traversing the inner CCBs. + if (_inner_ccb_iter != _face->inner_ccbs_end()) { + CGAL_assertion (_inner_ccb_iter == _face->inner_ccbs_begin()); + + // Otherwise, start from the first inner CCB. + _ccb_curr = _ccb_first = *_inner_ccb_iter; + return; + } + } + else if (_inner_ccb_iter != _face->inner_ccbs_end()) { + + // In this case we have already traversed all outer CCBs (and at least + // one inner CCB), so we try to move to the next inner CCB. + ++_inner_ccb_iter; + if (_inner_ccb_iter != _face->inner_ccbs_end()) { + // Otherwise, start from the first inner CCB. + _ccb_curr = _ccb_first = *_inner_ccb_iter; + return; + } + } + + // In this case we finished traversing all outer and inner CCBs: + _end = true; + return; + } + }; + + // Data members: + mutable Arrangement* p_arr; // The primal arrangement. + +public: + typedef Face_neighbor_iterator Incident_edge_iterator; + + /*! Default constructor. */ + Dual_arrangement_on_surface() : p_arr(NULL) {} + + /*! Constructor from an arrangement. */ + Dual_arrangement_on_surface(const Arrangement& arr) : + p_arr(const_cast(&arr)) + {} + + /*! Obtain the primal arrangement (const version). */ + const Arrangement* arrangement() const { return (p_arr); } + + /*! Obtain the primal arrangement (non-const version). */ + Arrangement* arrangement() { return (p_arr); } + + /*! Obtain the number of vertices (face of the primal arrangement). */ + Size number_of_vertices() const { return (p_arr->number_of_faces()); } + + /*! Obtain the begin iterator of the vertices of the dual arrangement + * (faces of the primal arrangement). + */ + Vertex_iterator vertices_begin() const { return (p_arr->faces_begin()); } + + /*! Obtain the pass-the-end iterator of the vertices of the dual arrangement + * (faces of the primal arrangement). + */ + Vertex_iterator vertices_end() const { return (p_arr->faces_end()); } + + /*! Obtain the number of edges. */ + Size number_of_edges () const { return (p_arr->number_of_halfedges()); } + + /*! Obtain the begin iterator of the edges of the dual arrangement. */ + Edge_iterator edges_begin() const { return (p_arr->halfedges_begin()); } + + /*! Obtain the pass-the-end iterator of the edges of the dual arrangement. */ + Edge_iterator edges_end() const { return (p_arr->halfedges_end()); } + + /*! Obtain the dual vertex-degree (number of edges forming the face boundary). + */ + Size degree(Vertex_handle v) const + { + Incident_edge_iterator begin = Incident_edge_iterator(v, true, true); + Incident_edge_iterator end = Incident_edge_iterator(v, false, true); + Size deg = 0; + + while (begin != end) { + deg++; + ++begin; + } + + return (deg); + } + + /*! Traverse the outgoing edges of a given vertex. */ + Incident_edge_iterator out_edges_begin(Vertex_handle v) const + { return (Incident_edge_iterator (v, true, true)); } + + Incident_edge_iterator out_edges_end(Vertex_handle v) const + { return (Incident_edge_iterator (v, true, false)); } + + /*! Traverse the ingoing edges of a given vertex. */ + Incident_edge_iterator in_edges_begin(Vertex_handle v) const + { return (Incident_edge_iterator (v, false, true)); } + + Incident_edge_iterator in_edges_end(Vertex_handle v) const + { return (Incident_edge_iterator (v, false, false)); } +}; + +} //namespace CGAL + +#include +#include + +namespace CGAL { + +/*! \class + * The common base class template of the specialized + * boost::graph_traits > class template. + * The latter serves as a dual adapter for the specialied arrangment, where the + * valid arrangement faces correspond to graph verices, and two graph vertices + * are connected if the two corrsponding faces are adjacent. + * We consider the graph as directed. We also allow parallel edges, as two + * faces may have more than one common edges. + */ +template +class Graph_traits_dual_arr_on_surface_impl { +public: + typedef Arrangement_ Arrangement; + typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; + typedef typename Arrangement::Topology_traits Topology_traits; + typedef Dual_arrangement_on_surface Dual_arr_2; + +private: + typedef typename Dual_arr_2::Vertex_iterator Vertex_iterator; + typedef typename Dual_arr_2::Edge_iterator Edge_iterator; + typedef typename Dual_arr_2::Incident_edge_iterator Incident_edge_iterator; + + /*! \struct + * Define the arrangement traversal category, which indicates the arrangement + * models the BidirectionalGraph concept and the VertexListGraph and + * EdgeListGraph concepts. + */ + struct Dual_arr_traversal_category : + public virtual boost::bidirectional_graph_tag, // This tag refines the + // incidence_graph_tag. + public virtual boost::vertex_list_graph_tag, // Can iterate over vertices. + public virtual boost::edge_list_graph_tag // Can iterate over edges. + {}; + +public: + // Types required of the Graph concept: + typedef typename Dual_arr_2::Vertex_handle vertex_descriptor; + typedef boost::directed_tag directed_category; + typedef boost::allow_parallel_edge_tag edge_parallel_category; + + typedef Dual_arr_traversal_category traversal_category; + + // Types required by the IncidenceGraph concept: + typedef typename Dual_arr_2::Edge_handle edge_descriptor; + typedef Incident_edge_iterator out_edge_iterator; + typedef typename Dual_arr_2::Size degree_size_type; + + // Types required by the BidirectionalGraph concept: + typedef Incident_edge_iterator in_edge_iterator; + + // Types required by the VertexListGraph concept: + typedef boost::counting_iterator vertex_iterator; + typedef typename Dual_arr_2::Size vertices_size_type; + + // Types required by the EdgeListGraph concept: + typedef boost::counting_iterator edge_iterator; + typedef typename Dual_arr_2::Size edges_size_type; + + // Types not required by any of these concepts: + typedef void adjacency_iterator; +}; + +} + +// Macro definitions of free Function templates required by the various Boost +// Graph concepts. Each macro provides the required free function template with +// the specific interface and its implementation. +// We use macros (and not base functions similar to +// Graph_traits_dual_arr_on_surface_impl) for simplicity. The implementation +// is typically a one-liner. However, the interface is typically several lines +// of code. The alternative implementation (with base common functions) while +// being more safe (provided tight type checking) would consume many repeated +// lines of code. + +// Functions required by the IncidenceGraph concept: +// ------------------------------------------------- + +/*! Obtain the out-degree of a vertex in a given dual arrangement. + * \param v The vertex. + * \param darr The dual arrangement. + * \param Number of halfedges around the boundary of the primal face. + */ +#define CGAL_DUAL_ARRANGEMENT_2_OUT_DEGREE(T) \ +template \ +typename boost::graph_traits > >::degree_size_type \ +out_degree(typename boost::graph_traits > >::vertex_descriptor v,\ + const Dual >& darr) \ +{ return darr.degree(v); } + +/*! Return a range of the out-edges of a vertex given by its descriptor and the + * dual arrangement it belongs to. + * \param v The vertex. + * \param darr The dual arrangement. + * \return A pair of out-edges iterators. + */ +#define CGAL_DUAL_ARRANGEMENT_2_OUT_EDGES(T) \ +template \ +std::pair > >::out_edge_iterator, \ + typename boost::graph_traits > >::out_edge_iterator> \ +out_edges(typename boost::graph_traits > >::vertex_descriptor v,\ + const Dual >& darr) \ +{ return std::make_pair(darr.out_edges_begin(v), darr.out_edges_end(v)); } \ + +/*! Obtain the source vertex of a dual arrangement edge. + * \param e The edge. + * \param darr The dual arrangement. + * \return The incident face of e in the primal arrangement. + */ +#define CGAL_DUAL_ARRANGEMENT_2_SOURCE(T) \ +template \ +typename boost::graph_traits > >::vertex_descriptor \ +source(typename boost::graph_traits > >::edge_descriptor e, \ + const Dual >& /* darr */) \ +{ return e->face(); } + +/*! Obtain the target vertex of a dual arrangement edge. + * \param e The edge. + * \param darr The dual arrangement. + * \return The incident face of the twin of e in the primal arrangement. + */ +#define CGAL_DUAL_ARRANGEMENT_2_TARGET(T) \ +template \ +typename boost::graph_traits > >::vertex_descriptor \ +target(typename boost::graph_traits > >::edge_descriptor e, \ + const Dual >& /* darr */) \ +{ return e->twin()->face(); } + +// Functions required by the BidirectionalGraph concept: +// ----------------------------------------------------- + +/*! Obtain the in-degree of a vertex in a given dual arrangement. + * \param v The vertex. + * \param darr The dual arrangement. + * \param Number of halfedges around the boundary of the primal face. + */ +#define CGAL_DUAL_ARRANGEMENT_2_IN_DEGREE(T) \ +template \ +typename boost::graph_traits > >::degree_size_type \ +in_degree(typename boost::graph_traits > >::vertex_descriptor v,\ + const Dual >& darr) \ +{ return darr.degree(v); } + +/*! Return a range of the in-edges of a vertex given by its descriptor and the + * dual arrangement it belongs to. + * \param v The vertex. + * \param darr The dual arrangement. + * \return A pair of in-edges iterators. + */ +#define CGAL_DUAL_ARRANGEMENT_2_IN_EDGES(T) \ +template \ +std::pair > >::in_edge_iterator, \ + typename boost::graph_traits > >::in_edge_iterator> \ +in_edges(typename boost::graph_traits > >::vertex_descriptor v,\ + const Dual >& darr) \ +{ return std::make_pair(darr.in_edges_begin(v), darr.in_edges_end(v)); } + +/*! Obtain the degree of a vertex in a given dual arrangement. + * \param v The vertex. + * \param darr The dual arrangement. + * \param Number of ingoing and outgoing halfedges incident to v. + */ +#define CGAL_DUAL_ARRANGEMENT_2_DEGREE(T) \ +template \ +typename boost::graph_traits > >::degree_size_type \ +degree(typename boost::graph_traits > >::vertex_descriptor v, \ + const Dual >& darr) \ +{ return (2 * darr.degree(v)); } + +// Functions required by the VertexListGraph concept: +// -------------------------------------------------- + +/*! Obtain the number of vertices in the given dual arrangement. + * \param darr The dual arrangement. + * \return Number of faces in the primal arrangement. + */ +#define CGAL_DUAL_ARRANGEMENT_2_NUM_VERTICES(T) \ +template \ +typename boost::graph_traits > >::vertices_size_type \ +num_vertices(const Dual >& darr) \ +{ return darr.number_of_vertices(); } + +/*! Obtain the range of vertices of the given dual arrangement. + * \param darr The dual arrangement. + * \return A pair of vertex iterators. + */ +#define CGAL_DUAL_ARRANGEMENT_2_VERTICES(T) \ +template \ +std::pair > >::vertex_iterator, \ + typename boost::graph_traits > >::vertex_iterator> \ +vertices(const Dual >& darr) \ +{ return std::make_pair(darr.vertices_begin(), darr.vertices_end()); } + +// Functions required by the EdgeListGraph concept: +// ------------------------------------------------ + +/*! Obtain the number of edges in the given dual arrangement. + * \param darr The dual arrangement. + * \return Number of halfedges in the primal arrangement. + */ +#define CGAL_DUAL_ARRANGEMENT_2_NUM_EDGES(T) \ +template \ +typename boost::graph_traits > >::edges_size_type \ +num_edges(const Dual >& darr) \ +{ return darr.number_of_edges(); } + +/*! Obtain the range of edges of the given dual arrangement. + * \param darr The dual arrangement. + * \return A pair of edge iterators. + */ +#define CGAL_DUAL_ARRANGEMENT_2_EDGES(T) \ +template \ +std::pair > >::edge_iterator, \ + typename boost::graph_traits > >::edge_iterator> \ +edges(const Dual >& darr) \ +{ return std::make_pair(darr.edges_begin(), darr.edges_end()); } + +#endif diff --git a/Arrangement_on_surface_2/include/CGAL/boost/graph/graph_traits_Dual_Arrangement_2.h b/Arrangement_on_surface_2/include/CGAL/boost/graph/graph_traits_Dual_Arrangement_2.h index be5fafe3060..0a23c73122e 100644 --- a/Arrangement_on_surface_2/include/CGAL/boost/graph/graph_traits_Dual_Arrangement_2.h +++ b/Arrangement_on_surface_2/include/CGAL/boost/graph/graph_traits_Dual_Arrangement_2.h @@ -23,6 +23,6 @@ #ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H #define CGAL_BOOST_GRAPH_GRAPH_TRAITS_ARRANGEMENT_2_H -#include +#include #endif //CGAL_BOOST_GRAPH_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H diff --git a/Arrangement_on_surface_2/include/CGAL/graph_traits_Dual_Arrangement_2.h b/Arrangement_on_surface_2/include/CGAL/graph_traits_Dual_Arrangement_2.h deleted file mode 100644 index dd8a4f14226..00000000000 --- a/Arrangement_on_surface_2/include/CGAL/graph_traits_Dual_Arrangement_2.h +++ /dev/null @@ -1,755 +0,0 @@ -// Copyright (c) 2005,2007,2009,2010,2011 Tel-Aviv University (Israel). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Ron Wein -// Ophir Setter - -#ifndef CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H -#define CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H - -#include - -#include - -/*! \file - * Definition of the specialized Dual class, - * and the specialized boost::graph_traits >class. - */ - -// include this to avoid a VC15 warning -#include - -#include -#include - -namespace CGAL { - -// Forward declaration. -template class Dual; - -/*! \class - * Specilaization of the Dual<> template for Arrangement_on_surface_2. - */ -template -class Dual > -{ -public: - - typedef GeomTraits_ Geometry_traits_2; - typedef TopTraits_ Topology_traits; - typedef CGAL::Arrangement_on_surface_2 - Arrangement_on_surface_2; - - typedef typename Arrangement_on_surface_2::Size Size; - typedef typename Arrangement_on_surface_2::Face_handle Vertex_handle; - typedef typename Arrangement_on_surface_2::Halfedge_handle Edge_handle; - - typedef typename Arrangement_on_surface_2::Face_iterator Vertex_iterator; - typedef typename Arrangement_on_surface_2::Halfedge_iterator Edge_iterator; - -protected: - - typedef typename Arrangement_on_surface_2::Face_handle Face_handle; - typedef typename Arrangement_on_surface_2::Ccb_halfedge_circulator - Ccb_halfedge_circulator; - typedef typename Arrangement_on_surface_2::Outer_ccb_iterator - Outer_ccb_iterator; - typedef typename Arrangement_on_surface_2::Inner_ccb_iterator - Inner_ccb_iterator; - - /*! \class - * Iterator over the neighbors of a dual vertex (a face in the primal - * arrangement). - * These neighbors are the adjacent faces along the outer boundaries of the - * face and its inner boundaries. - */ - class Face_neighbor_iterator - { - typedef Face_neighbor_iterator Self; - - public: - - typedef std::forward_iterator_tag iterator_category; - typedef Edge_handle value_type; - typedef value_type reference; - typedef value_type* pointer; - typedef int difference_type; - - private: - - Outer_ccb_iterator _outer_ccb_iter; - Inner_ccb_iterator _inner_ccb_iter; - Ccb_halfedge_circulator _ccb_curr; - Ccb_halfedge_circulator _ccb_first; - Face_handle _face; - bool _out; - Edge_handle _hh; - bool _end; - - public: - - /*! Default constructor. */ - Face_neighbor_iterator () : - _end (true) - {} - - /*! - * Constructor. - * \param face The face (dual vertex). - * \param out_edges Do we need the outgoing or the ingoing halfedges. - * \param start Should we start traversing the edges. - * If false, we construct a past-the-end iterator. - */ - Face_neighbor_iterator (Face_handle face, - bool out_edges, - bool start) : - _face (face), - _out (out_edges), - _end (! start) - { - CGAL_precondition (! face->is_fictitious()); - - if (start) - { - _outer_ccb_iter = _face->outer_ccbs_begin(); - _inner_ccb_iter = _face->inner_ccbs_begin(); - - if (_outer_ccb_iter != _face->outer_ccbs_end()) - { - // Start from the first outer CCB, if one exists. - _ccb_curr = _ccb_first = *_outer_ccb_iter; - } - else if (_inner_ccb_iter != face->inner_ccbs_end()) - { - // Otherwise, start from the first inner CCB. - _ccb_curr = _ccb_first = *_inner_ccb_iter; - } - else - { - // In this case there are no CCBs to traverse: - _end = true; - return; - } - - _hh = this->_dereference(); - - // In case the incident face of the twin halfedge is fictitious, - // skip it and proceed to the next edge. - if (_hh->is_fictitious()) - ++(*this); - } - else // end iterator. - { - _outer_ccb_iter = _face->outer_ccbs_end(); - _inner_ccb_iter = _face->inner_ccbs_end(); - } - } - - /*! Equality operators. */ - bool operator== (const Self& it) const - { - return (this->_equal(it)); - } - - bool operator!= (const Self& it) const - { - return (! this->_equal(it)); - } - - /*! Dereference operators. */ - reference operator* () const - { - return (_hh); - } - - pointer operator-> () const - { - return (&_hh); - } - - /* Increment operators. */ - Self& operator++ () - { - do - { - this->_increment(); - if (_end) - return (*this); - - _hh = this->_dereference(); - - } while (_hh->is_fictitious()); - - return (*this); - } - - Self operator++ (int ) - { - Self tmp = *this; - - do - { - this->_increment(); - if (_end) - return (tmp); - - _hh = this->_dereference(); - - } while (_hh->is_fictitious()); - - return (tmp); - } - - private: - - /*! Check two iterators for equality. */ - bool _equal (const Self& it) const - { - return (_out == it._out && _face == it._face && - ((_end && it._end) || - (_outer_ccb_iter == it._outer_ccb_iter && - _inner_ccb_iter == it._inner_ccb_iter && - _ccb_curr == it._ccb_curr))); - } - - /*! Derefernce the current circulator. */ - Edge_handle _dereference () const - { - if (_out) - return (_ccb_curr); - else - return (_ccb_curr->twin()); - } - - // Increments of the iterator. - void _increment () - { - CGAL_assertion (! _end); - - // If we have not traversed the entire CCB in full, move to the next - // halfedge along the current CCB. - ++_ccb_curr; - - if (_ccb_curr != _ccb_first) - return; - - // In this case we have completed the current CCB and we have to move - // to the next one. - if (_outer_ccb_iter != _face->outer_ccbs_end()) - { - // Try to move to the next outer CCB. - ++_outer_ccb_iter; - if (_outer_ccb_iter != _face->outer_ccbs_end()) - { - _ccb_curr = _ccb_first = *_outer_ccb_iter; - return; - } - - // In this case we start traversing the inner CCBs. - if (_inner_ccb_iter != _face->inner_ccbs_end()) - { - CGAL_assertion (_inner_ccb_iter == _face->inner_ccbs_begin()); - - // Otherwise, start from the first inner CCB. - _ccb_curr = _ccb_first = *_inner_ccb_iter; - return; - } - } - else if (_inner_ccb_iter != _face->inner_ccbs_end()) - { - - // In this case we have already traversed all outer CCBs (and at least - // one inner CCB), so we try to move to the next inner CCB. - ++_inner_ccb_iter; - if (_inner_ccb_iter != _face->inner_ccbs_end()) - { - // Otherwise, start from the first inner CCB. - _ccb_curr = _ccb_first = *_inner_ccb_iter; - return; - } - } - - // In this case we finished traversing all outer and inner CCBs: - _end = true; - return; - } - - }; - - // Data members: - mutable Arrangement_on_surface_2 *p_arr; // The primal arrangement. - -public: - - typedef Face_neighbor_iterator Incident_edge_iterator; - - /*! Default constructor. */ - Dual () : - p_arr (NULL) - {} - - /*! Constructor from an arrangement. */ - Dual (const Arrangement_on_surface_2& arr) : - p_arr (const_cast (&arr)) - {} - - /*! Get the primal arrangement (const version). */ - const Arrangement_on_surface_2* arrangement () const - { - return (p_arr); - } - - /*! Get the primal arrangement (non-const version). */ - Arrangement_on_surface_2* arrangement () - { - return (p_arr); - } - - /*! Get the number of vertices (face of the primal arrangement). */ - Size number_of_vertices () const - { - return (p_arr->number_of_faces()); - } - - /*! Traverse the vertices (faces of the primal arrangement). */ - Vertex_iterator vertices_begin () const - { - return (p_arr->faces_begin()); - } - - Vertex_iterator vertices_end () const - { - return (p_arr->faces_end()); - } - - /*! Get the number of edges. */ - Size number_of_edges () const - { - return (p_arr->number_of_halfedges()); - } - - /*! Traverse the edges. */ - Edge_iterator edges_begin () const - { - return (p_arr->halfedges_begin()); - } - - Edge_iterator edges_end () const - { - return (p_arr->halfedges_end()); - } - - /*! - * Get the dual vertex-degree (number of edges forming the face boundary). - */ - Size degree (Vertex_handle v) const - { - Incident_edge_iterator begin = Incident_edge_iterator (v, true, true); - Incident_edge_iterator end = Incident_edge_iterator (v, false, true); - Size deg = 0; - - while (begin != end) - { - deg++; - ++begin; - } - - return (deg); - } - - /*! Traverse the outgoing edges of a given vertex. */ - Incident_edge_iterator out_edges_begin (Vertex_handle v) const - { - return (Incident_edge_iterator (v, true, true)); - } - - Incident_edge_iterator out_edges_end (Vertex_handle v) const - { - return (Incident_edge_iterator (v, true, false)); - } - - /*! Traverse the ingoing edges of a given vertex. */ - Incident_edge_iterator in_edges_begin (Vertex_handle v) const - { - return (Incident_edge_iterator (v, false, true)); - } - - Incident_edge_iterator in_edges_end (Vertex_handle v) const - { - return (Incident_edge_iterator (v, false, false)); - } -}; - -/*! \class - * Specilaization of the Dual<> template for Arrangement_2. - */ -template -class Dual > : - public Dual::Geometry_traits_2, - typename CGAL::Arrangement_2::Topology_traits> > -{ - typedef Traits_ Traits_2; - typedef Dcel_ Dcel; - typedef Dual::Geometry_traits_2, - typename CGAL::Arrangement_2::Topology_traits> > Base; - -public: - - /*! Default constructor. */ - Dual () : - Base() - {} - - /*! Constructor from an arrangement. */ - Dual (const CGAL::Arrangement_2& arr) : - Base (arr) - {} -}; - -} //namespace CGAL - -#include -#include - -namespace boost { - -/*! \class - * Specialization of the BGL graph-traits template, which serve as a dual - * adapter for Arrangment_on_surface_2, where the valid arrangement faces - * correspond to graph verices, and two graph vertices are connected if the - * two corrsponding faces are adjacent. - * We consider the graph as directed. We also allow parallel edges, as two - * faces may have more than one common edges. - */ -template -class graph_traits > > -{ -public: - - typedef GeomTraits_ Geometry_traits_2; - typedef TopTraits_ Topology_traits; - typedef CGAL::Arrangement_on_surface_2 - Arrangement_on_surface_2; - typedef CGAL::Dual Dual_arr_2; - -private: - - typedef typename Dual_arr_2::Vertex_iterator Vertex_iterator; - typedef typename Dual_arr_2::Edge_iterator Edge_iterator; - typedef typename Dual_arr_2::Incident_edge_iterator Incident_edge_iterator; - - /*! \struct - * Define the arrangement traversal category, which indicates the arrangement - * models the BidirectionalGraph concept and the VertexListGraph and - * EdgeListGraph concepts. - */ - struct Dual_arr_traversal_category : - public virtual boost::bidirectional_graph_tag, // This tag refines the - // incidence_graph_tag. - public virtual boost::vertex_list_graph_tag, // Can iterate over vertices. - public virtual boost::edge_list_graph_tag // Can iterate over edges. - {}; - -public: - - // Types required of the Graph concept: - typedef typename Dual_arr_2::Vertex_handle vertex_descriptor; - typedef boost::directed_tag directed_category; - typedef boost::allow_parallel_edge_tag edge_parallel_category; - - typedef Dual_arr_traversal_category traversal_category; - - // Types required by the IncidenceGraph concept: - typedef typename Dual_arr_2::Edge_handle edge_descriptor; - typedef Incident_edge_iterator out_edge_iterator; - typedef typename Dual_arr_2::Size degree_size_type; - - // Types required by the BidirectionalGraph concept: - typedef Incident_edge_iterator in_edge_iterator; - - // Types required by the VertexListGraph concept: - typedef boost::counting_iterator vertex_iterator; - typedef typename Dual_arr_2::Size vertices_size_type; - - // Types required by the EdgeListGraph concept: - typedef boost::counting_iterator edge_iterator; - typedef typename Dual_arr_2::Size edges_size_type; - - // Types not required by any of these concepts: - typedef void adjacency_iterator; - -}; - -/*! \class - * Specialization of the BGL graph-traits template, which serve as a dual - * adapter for Arrangment_2. - */ -template -class graph_traits > > : - public graph_traits::Geometry_traits_2, - typename CGAL::Arrangement_2::Topology_traits> > > -{}; - -} // namespace boost - -namespace CGAL { - -// Functions required by the IncidenceGraph concept: -// ------------------------------------------------- - -/*! - * Get the out-degree of a vertex in a given dual arrangement. - * \param v The vertex. - * \param darr The dual arrangement. - * \param Number of halfedges around the boundary of the primal face. - */ -template -typename -boost::graph_traits > >::degree_size_type -out_degree(typename - boost::graph_traits > >:: - vertex_descriptor v, - const CGAL::Dual >& darr) -{ - return darr.degree (v); -} - -/*! - * Return a range of the out-edges of a vertex given by its descriptor and the - * dual arrangement it belongs to. - * \param v The vertex. - * \param darr The dual arrangement. - * \return A pair of out-edges iterators. - */ -template -std::pair > >:: - out_edge_iterator, - typename - boost::graph_traits > >:: - out_edge_iterator> -out_edges(typename - boost::graph_traits > >:: - vertex_descriptor v, - const CGAL::Dual >& darr) -{ - return std::make_pair (darr.out_edges_begin (v), darr.out_edges_end (v)); -} - -/*! - * Get the source vertex of a dual arrangement edge. - * \param e The edge. - * \param darr The dual arrangement. - * \return The incident face of e in the primal arrangement. - */ -template -typename -boost::graph_traits > >::vertex_descriptor -source(typename - boost::graph_traits > >:: - edge_descriptor e, - const CGAL::Dual >& /* darr */) -{ - return e->face(); -} - -/*! - * Get the target vertex of a dual arrangement edge. - * \param e The edge. - * \param darr The dual arrangement. - * \return The incident face of e's twin in the primal arrangement. - */ -template -typename -boost::graph_traits > >::vertex_descriptor -target(typename - boost::graph_traits > >:: - edge_descriptor e, - const CGAL::Dual >& /* darr */) -{ - return e->twin()->face(); -} - -// Functions required by the BidirectionalGraph concept: -// ----------------------------------------------------- - -/*! - * Get the in-degree of a vertex in a given dual arrangement. - * \param v The vertex. - * \param darr The dual arrangement. - * \param Number of halfedges around the boundary of the primal face. - */ -template -typename -boost::graph_traits > >::degree_size_type -in_degree(typename - boost::graph_traits > >:: - vertex_descriptor v, - const CGAL::Dual >& darr) -{ - return darr.degree (v); -} - -/*! - * Return a range of the in-edges of a vertex given by its descriptor and the - * dual arrangement it belongs to. - * \param v The vertex. - * \param darr The dual arrangement. - * \return A pair of in-edges iterators. - */ -template -std::pair > >:: - in_edge_iterator, - typename - boost::graph_traits > >:: - in_edge_iterator> -in_edges(typename - boost::graph_traits > >:: - vertex_descriptor v, - const CGAL::Dual >& darr) -{ - return std::make_pair (darr.in_edges_begin (v), darr.in_edges_end (v)); -} - -/*! - * Get the degree of a vertex in a given dual arrangement. - * \param v The vertex. - * \param darr The dual arrangement. - * \param Number of ingoing and outgoing halfedges incident to v. - */ -template -typename -boost::graph_traits > >::degree_size_type -degree(typename - boost::graph_traits > >:: - vertex_descriptor v, - const CGAL::Dual >& darr) -{ - return (2 * darr.degree (v)); -} - -// Functions required by the VertexListGraph concept: -// -------------------------------------------------- - -/*! - * Get the number of vertices in the given dual arrangement. - * \param darr The dual arrangement. - * \return Number of faces in the primal arrangement. - */ -template -typename -boost::graph_traits > >::vertices_size_type -num_vertices(const CGAL::Dual >& darr) -{ - return darr.number_of_vertices(); -} - -/*! - * Get the range of vertices of the given dual arrangement. - * \param darr The dual arrangement. - * \return A pair of vertex iterators. - */ -template -std::pair > >:: - vertex_iterator, - typename - boost::graph_traits > >:: - vertex_iterator> -vertices (const CGAL::Dual >& darr) -{ - return std::make_pair (darr.vertices_begin(), darr.vertices_end()); -} - -// Functions required by the EdgeListGraph concept: -// ------------------------------------------------ - -/*! - * Get the number of edges in the given dual arrangement. - * \param darr The dual arrangement. - * \return Number of halfedges in the primal arrangement. - */ -template -typename -boost::graph_traits > >::edges_size_type -num_edges(const CGAL::Dual >& darr) -{ - return darr.number_of_edges(); -} - -/*! - * Get the range of edges of the given dual arrangement. - * \param darr The dual arrangement. - * \return A pair of edge iterators. - */ -template -std::pair > >:: - edge_iterator, - typename - boost::graph_traits > >:: - edge_iterator> -edges (const CGAL::Dual >& darr) -{ - return std::make_pair (darr.edges_begin(), darr.edges_end()); -} - -} //namespace CGAL - -#include - -#endif diff --git a/Arrangement_on_surface_2/include/CGAL/graph_traits_dual_arrangement_2.h b/Arrangement_on_surface_2/include/CGAL/graph_traits_dual_arrangement_2.h new file mode 100644 index 00000000000..060db488191 --- /dev/null +++ b/Arrangement_on_surface_2/include/CGAL/graph_traits_dual_arrangement_2.h @@ -0,0 +1,97 @@ +// Copyright (c) 2019 Tel-Aviv University (Israel). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Ron Wein +// Ophir Setter +// Sebastien Loriot +// Efi Fogel + +#ifndef CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H +#define CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H + +#include + +/*! \file + * Definition of: + * 1. the specialized Dual class, + * 2. the specialized boost::graph_traits >class, + * 3. The free functions required by the various graph concepts. + */ + +// include this to avoid a VC15 warning +#include + +#include +#include +#include + +namespace CGAL { + +// The specialized Dual +class Dual > : + public Dual_arrangement_on_surface > +{ +public: + typedef Arrangement_2 Arrangement; + typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; + typedef typename Arrangement::Topology_traits Topology_traits; + +private: + typedef Dual_arrangement_on_surface Base; + +public: + /*! Default constructor. */ + Dual() : Base() {} + + /*! Constructor from an arrangement. */ + Dual(const Arrangement& arr) : Base(arr) {} +}; + +} + +namespace boost { + +// The specialized graph_traits +class graph_traits > > : + public CGAL::Graph_traits_dual_arr_on_surface_impl > +{}; + +} + +namespace CGAL { + +// Templates of free functions that handle +// graph_traits +// Ophir Setter +// Sebastien Loriot +// Efi Fogel + +#ifndef CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_ON_SURFACE_2_H +#define CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_ON_SURFACE_2_H + +#include + +/*! \file + * Definition of: + * 1. the specialized Dual class, + * 2. the specialized boost::graph_traits > class, + * 3. The free functions required by the various graph concepts. + */ + +// include this to avoid a VC15 warning +#include + +#include +#include +#include + +namespace CGAL { + +// The specialized Dual +class Dual > : + public Dual_arrangement_on_surface > +{ +public: + typedef Arrangement_on_surface_2 Arrangement; + typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; + typedef typename Arrangement::Topology_traits Topology_traits; + +private: + typedef Dual_arrangement_on_surface Base; + +public: + /*! Default constructor. */ + Dual() : Base() {} + + /*! Constructor from an arrangement. */ + Dual(const Arrangement& arr) : Base(arr) {} +}; + +} + +namespace boost { + +// The specialized graph_traits +class graph_traits > > : + public CGAL::Graph_traits_dual_arr_on_surface_impl + > +{}; + +} + +namespace CGAL { + +// Templates of free functions that handle +// graph_traits +// Ophir Setter +// Sebastien Loriot +// Efi Fogel + +#ifndef CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_ON_SURFACE_WITH_HISTORY_2_H +#define CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_ON_SURFACE_WITH_HISTORY_2_H + +#include + +/*! \file + * Definition of: + * 1. the specialized Dual class, + * 2. the specialized + * boost::graph_traits >class, + * 3. The free functions required by the various graph concepts. + */ + +// include this to avoid a VC15 warning +#include + +#include +#include +#include + +namespace CGAL { + +// The specialized Dual +class Dual > : + public Dual_arrangement_on_surface > +{ +public: + typedef Arrangement_on_surface_with_history_2 Arrangement; + typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; + typedef typename Arrangement::Topology_traits Topology_traits; + +private: + typedef Dual_arrangement_on_surface Base; + +public: + /*! Default constructor. */ + Dual() : Base() {} + + /*! Constructor from an arrangement. */ + Dual(const Arrangement& arr) : Base(arr) {} +}; + +} + +namespace boost { + +// The specialized +// graph_traits +class graph_traits > > : + public CGAL::Graph_traits_dual_arr_on_surface_impl + > +{}; + +} + +namespace CGAL { + +// Templates of free functions that handle +// graph_traits +// Ophir Setter +// Sebastien Loriot +// Efi Fogel + +#ifndef CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_WITH_HISTORY_2_H +#define CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_WITH_HISTORY_2_H + +#include + +/*! \file + * Definition of: + * 1. the specialized Dual class, + * 2. the specialized + * boost::graph_traits >class, + * 3. The free functions required by the various graph concepts. + */ + +// include this to avoid a VC15 warning +#include + +#include +#include +#include + +namespace CGAL { + +// The specialized Dual +class Dual > : + public Dual_arrangement_on_surface > +{ +public: + typedef Arrangement_with_history_2 Arrangement; + typedef typename Arrangement::Geometry_traits_2 Geometry_traits_2; + typedef typename Arrangement::Topology_traits Topology_traits; + +private: + typedef Dual_arrangement_on_surface Base; + +public: + /*! Default constructor. */ + Dual() : Base() {} + + /*! Constructor from an arrangement. */ + Dual(const Arrangement& arr) : Base(arr) {} +}; + +} + +namespace boost { + +// The specialized graph_traits +class graph_traits > > : + public CGAL::Graph_traits_dual_arr_on_surface_impl + > +{}; + +} + +namespace CGAL { + +// Templates of free functions that handle +// graph_traits -#include +#include // leda_rational, or Gmpq, or Quotient typedef CGAL::Exact_rational Number_type; diff --git a/BGL/examples/BGL_arrangement_2/arrangement_dual.cpp b/BGL/examples/BGL_arrangement_2/arrangement_dual.cpp index 7166c92d054..3ca5598ea27 100644 --- a/BGL/examples/BGL_arrangement_2/arrangement_dual.cpp +++ b/BGL/examples/BGL_arrangement_2/arrangement_dual.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/Classification/include/CGAL/Classification/Planimetric_grid.h b/Classification/include/CGAL/Classification/Planimetric_grid.h index 8339864ba53..33e0d141928 100644 --- a/Classification/include/CGAL/Classification/Planimetric_grid.h +++ b/Classification/include/CGAL/Classification/Planimetric_grid.h @@ -28,6 +28,8 @@ #include +#include + #include #include diff --git a/Envelope_3/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h b/Envelope_3/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h index a06d8a56c57..0bc094544f1 100644 --- a/Envelope_3/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h +++ b/Envelope_3/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h @@ -46,7 +46,7 @@ #ifdef CGAL_ENVELOPE_USE_BFS_FACE_ORDER #include -#include +#include #include #endif @@ -92,7 +92,8 @@ namespace CGAL { // the envelope between 2 surfaces over a feature // of the arrangement // 4. Overlay_2 - overlay of 2 MinimizationDiagram_2 -template , @@ -138,9 +139,9 @@ protected: Ccb_halfedge_circulator; typedef typename Minimization_diagram_2::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Minimization_diagram_2::Outer_ccb_iterator + typedef typename Minimization_diagram_2::Outer_ccb_iterator Outer_ccb_iterator; - typedef typename Minimization_diagram_2::Inner_ccb_iterator + typedef typename Minimization_diagram_2::Inner_ccb_iterator Inner_ccb_iterator; typedef Arr_observer Md_observer; @@ -155,7 +156,7 @@ protected: public: // c'tor Envelope_divide_and_conquer_3(Envelope_type type = ENVELOPE_LOWER) - { + { // Allocate the traits. m_geom_traits = new Traits; m_own_traits = true; @@ -178,7 +179,7 @@ public: m_is_lower = ((type == ENVELOPE_LOWER) ? true : false); } - + // virtual destructor. virtual ~Envelope_divide_and_conquer_3() { @@ -199,11 +200,11 @@ public: Envelope_3::Arbitrary_dividor dividor; construct_lu_envelope(begin, end, result, dividor); } - + // compute the envelope of surfaces in 3D using the given set dividor template - void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end, + void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end, Minimization_diagram_2& result, SetDividor& dividor) { @@ -211,7 +212,7 @@ public: { return; // result is empty } - + // make the general surfaces xy-monotone std::list xy_monotones; for (; begin != end; ++begin) @@ -220,10 +221,10 @@ public: std::back_inserter(xy_monotones)); // recursively construct the envelope of the xy-monotone parts - construct_lu_envelope_xy_monotones(xy_monotones.begin(), + construct_lu_envelope_xy_monotones(xy_monotones.begin(), xy_monotones.end(), result, dividor); - CGAL_assertion(is_envelope_valid(result)); + CGAL_assertion(is_envelope_valid(result)); } // compute the envelope of xy-monotone surfaces in 3D, @@ -266,7 +267,7 @@ public: protected: - // compute the envelope of xy-monotone surfaces in 3D + // compute the envelope of xy-monotone surfaces in 3D template void construct_lu_envelope_xy_monotones(SurfaceIterator begin, SurfaceIterator end, @@ -284,25 +285,25 @@ protected: { // only one surface is in the collection. insert it the result Xy_monotone_surface_3& surf = *first; - + deal_with_one_surface(surf, result); - return; + return; } - + // divide the surfaces into 2 groups (insert surface to each group // alternately) // Efi: this copy is redundant. It is sufficient to determine the range std::list group1, group2; dividor(first, end, std::back_inserter(group1), std::back_inserter(group2)); - + // recursively calculate the LU_envelope of the 2 groups Minimization_diagram_2 result1(m_geom_traits), result2(m_geom_traits); construct_lu_envelope_xy_monotones(group1.begin(), group1.end(), result1, dividor); construct_lu_envelope_xy_monotones(group2.begin(), group2.end(), result2, dividor); - + // merge the results: merge_envelopes(result1, result2, result); @@ -323,7 +324,7 @@ protected: m_geom_traits-> construct_projected_boundary_2_object()(surf, std::back_inserter(boundary)); - + if (boundary.empty()) { //one infinite surface @@ -344,13 +345,13 @@ protected: Oriented_side side = boundary_cv.second; Halfedge_handle he = insert_non_intersecting_curve(result, boundary_cv.first); - + if (side == ON_ORIENTED_BOUNDARY) { // vertical xy-surface he->face()->set_no_data(); he->twin()->face()->set_no_data(); - + continue; } @@ -374,41 +375,41 @@ protected: he->twin()->face()->set_no_data(); } - // init auxiliary data for f and its boundarys. + // init auxiliary data for f and its boundarys. for(Outer_ccb_iterator ocit = f->outer_ccbs_begin(); ocit != f->outer_ccbs_end(); ocit++){ Ccb_halfedge_circulator face_hec = *ocit; Ccb_halfedge_circulator face_hec_begin = face_hec; - do + do { face_hec->set_is_equal_data_in_face(true); face_hec->set_has_equal_data_in_face(true); face_hec->set_has_equal_data_in_target_and_face(true); - + face_hec->twin()->set_is_equal_data_in_face(false); face_hec->twin()->set_has_equal_data_in_face(false); face_hec->twin()->set_has_equal_data_in_target_and_face(false); - + ++face_hec; - } + } while(face_hec != face_hec_begin); } for(Outer_ccb_iterator icit = f->inner_ccbs_begin(); icit != f->inner_ccbs_end(); icit++){ Ccb_halfedge_circulator face_hec = *icit; Ccb_halfedge_circulator face_hec_begin = face_hec; - do + do { face_hec->set_is_equal_data_in_face(true); face_hec->set_has_equal_data_in_face(true); face_hec->set_has_equal_data_in_target_and_face(true); - + face_hec->twin()->set_is_equal_data_in_face(false); face_hec->twin()->set_has_equal_data_in_face(false); face_hec->twin()->set_has_equal_data_in_target_and_face(false); - + ++face_hec; - } + } while(face_hec != face_hec_begin); } } @@ -449,7 +450,7 @@ protected: } } } - + public: void merge_envelopes(Minimization_diagram_2& result1, @@ -457,20 +458,20 @@ public: Minimization_diagram_2& result) { // overlay the 2 arrangements - + Overlay_2 overlay; overlay(result1, result2, result); - + CGAL_expensive_assertion_msg(is_valid(result), "after overlay result is not valid"); - + // make sure the aux flags are correctly set by the overlay //CGAL_assertion(verify_aux_flags(result)); // for each face, edge and vertex in the result, should calculate // which surfaces are on the envelope // a face can be cut, or faces can be merged. - + // now the minimization diagram might change - we need to keep data in the // edges, when they're split Keep_edge_data_observer edge_observer(result, this); @@ -523,13 +524,13 @@ public: for (li = edges_to_resolve.begin(); li != edges_to_resolve.end(); ++li) { resolver->resolve(*li, result); - + } edges_to_resolve.clear(); - + // decompose the result, to have faces without holes /* decompose(result); - CGAL_expensive_assertion_msg(result.is_valid(), + CGAL_expensive_assertion_msg(result.is_valid(), "after decomposition result is not valid");*/ // compute the surface on the envelope for each face, @@ -559,7 +560,7 @@ public: visitor(bfs_visitor)); index_map.detach(); #else - // traverse the faces in arbitrary order + // traverse the faces in arbitrary order Face_iterator fi = result.faces_begin(); for (; fi != result.faces_end(); ++fi) { @@ -600,7 +601,7 @@ public: // resolver->resolve(hi, result); // } // #endif - + // detach the edge_observer from result, since no need for it anymore edge_observer.detach(); @@ -627,7 +628,7 @@ public: continue; } resolver->resolve(vh); - + } CGAL_expensive_assertion_msg(result.is_valid(), @@ -636,21 +637,21 @@ public: // make sure that aux_source and decision are set at all features // after all resolvings CGAL_assertion(check_resolve_was_ok(result)); - + // make sure the aux flags are correctly after all resolvings //CGAL_assertion(verify_aux_flags(result)); // finally, remove unneccessary edges, between faces with the same surface // (and which are not degenerate) - + remove_unneccessary_edges(result); - CGAL_expensive_assertion_msg(result.is_valid(), + CGAL_expensive_assertion_msg(result.is_valid(), "after remove edges result is not valid"); // also remove unneccessary vertices (that were created in the process of // vertical decomposition but the vertical edge was removed) remove_unneccessary_vertices(result); - CGAL_expensive_assertion_msg(result.is_valid(), + CGAL_expensive_assertion_msg(result.is_valid(), "after remove vertices result is not valid"); // update is_equal_data and has_equal_data of halfedge->face and @@ -661,7 +662,7 @@ public: // update the envelope surfaces according to the decision and the aux // surfaces in aux source update_envelope_surfaces_by_decision(result); - + // make sure that all the flags are correctly set on the envelope result //CGAL_assertion(verify_flags(result)); CGAL_expensive_assertion_msg(is_valid(result), @@ -670,7 +671,7 @@ public: protected: - + void deal_with_faces_to_split(std::list& faces_to_split, Minimization_diagram_2& result) { @@ -741,7 +742,7 @@ protected: if (can_remove_edge(hh)) edges.push_back(hh); } - + for (typename std::list::iterator ci = edges.begin(); ci != edges.end(); ++ci) { @@ -847,7 +848,7 @@ protected: end = v->end_data(); } } - + // check if we can remove the edge from the envelope // this can be done if the envelope surfaces on the edge are the same as // the envelope surfaces on both sides of the edge @@ -855,7 +856,7 @@ protected: bool can_remove_edge(Halfedge_handle hh) { Face_handle f1 = hh->face(), f2 = hh->twin()->face(); - + // we check if the decision done on the edge is equal to the decision // done on the faces. if not, then the envelope surfaces must differ CGAL_assertion(hh->is_decision_set() && f1->is_decision_set() && @@ -875,10 +876,10 @@ protected: if (decision == DAC_DECISION_FIRST) return equal_first; - + if (decision == DAC_DECISION_SECOND) return equal_second; - + return (equal_first && equal_second); } @@ -895,7 +896,7 @@ protected: When I tried to use the following code I got a Segmentation Fault when trying to compute power diagram: - + if ((v->parameter_space_in_x() != ARR_INTERIOR) || (v->parameter_space_in_y() != ARR_INTERIOR)) return false; @@ -908,7 +909,7 @@ protected: /*if (v->get_is_fake() && !v->is_decision_set()) return true; - + if (h->get_is_fake() && !h->is_decision_set()) { @@ -931,13 +932,13 @@ protected: if (decision == DAC_DECISION_FIRST) return equal_first; - + if (decision == DAC_DECISION_SECOND) return equal_second; - + return (equal_first && equal_second); } - + // check if we can remove an isolated vertex from the envelope // this can be done if the envelope surfaces on the vertex are the same as // the envelope surfaces on its incident face @@ -958,10 +959,10 @@ protected: if (decision == DAC_DECISION_FIRST) return equal_first; - + if (decision == DAC_DECISION_SECOND) return equal_second; - + return (equal_first && equal_second); } @@ -977,13 +978,13 @@ protected: Halfedge_handle he1 = hec1, he2 = hec2; CGAL_assertion(he1 != he2); CGAL_assertion(he1->is_decision_set() && he2->is_decision_set()); - + /* if (vh->get_is_fake()) { * CGAL_assertion(he1->get_decision() == he2->get_decision()); * return true; * } */ - + CGAL_assertion(vh->is_decision_set()); // if the decision done on the vertex and its incident halfedges are // different, the envelope differs too. @@ -1001,14 +1002,14 @@ protected: if (decision == DAC_DECISION_FIRST) return equal_first; - + if (decision == DAC_DECISION_SECOND) return equal_second; return (equal_first && equal_second); } - - // Remove unneccessary vertices, which have degree 2, and the 2 curves + + // Remove unneccessary vertices, which have degree 2, and the 2 curves // can be merged // (and which are not degenerate) void remove_unneccessary_vertices(Minimization_diagram_2& result) @@ -1016,14 +1017,14 @@ protected: // we have 2 types of unneccessary vertices: those with degree 2 (that // satisfy all the conditions below), and isolated vertices that have the // same envelope information as the face they're contained in. - + // all the vertices that don't have their data set, are those vertices // on vertical edges, created in the decomposition process, // and are not neccessary - // also those vertices with degree 2, that can merge their 2 edges and + // also those vertices with degree 2, that can merge their 2 edges and // with same data as both these edges, can be removed - + // collect all vertices candidate to remove in this list, // and remove the correct ones at the end // (thus, not destroying the iterator) @@ -1041,28 +1042,28 @@ protected: } typename Traits::Merge_2 curves_merge = m_geom_traits->merge_2_object(); - typename Traits::Are_mergeable_2 curves_can_merge = + typename Traits::Are_mergeable_2 curves_can_merge = m_geom_traits->are_mergeable_2_object(); // check the candidates and remove if necessary typename std::list::iterator ci; - for (ci = candidates_to_remove.begin(); + for (ci = candidates_to_remove.begin(); ci != candidates_to_remove.end(); ++ci) { Vertex_handle vh = *ci; CGAL_assertion(vh->degree() == 2); - - // we can remove this vertex only if the data on its halfedges is the + + // we can remove this vertex only if the data on its halfedges is the // same if (!combinatorically_can_remove_vertex(vh)) continue; - + // merge the edges, if geometrically possible (if data on vertex is not // set, then it must be geometrically possible) Halfedge_around_vertex_circulator hec1 = vh->incident_halfedges(); Halfedge_around_vertex_circulator hec2 = hec1++; Halfedge_handle he1 = hec1, he2 = hec2; - + const X_monotone_curve_2& a = he1->curve(), b = he2->curve(); CGAL_assertion(vh->is_decision_set() || curves_can_merge(a,b)); @@ -1072,7 +1073,7 @@ protected: X_monotone_curve_2 c; curves_merge(a,b,c); - // the decisions on he1 and he2 were the same, so the decision on + // the decisions on he1 and he2 were the same, so the decision on // the edge that will be left after the merge will be ok // but we need to take care of the bool flags of the target relation // of the edge that will be left @@ -1115,7 +1116,7 @@ protected: result.merge_edge(he1, he2 ,c); CGAL_assertion(new_edge->is_decision_set()); - CGAL_expensive_assertion_msg(result.is_valid(), + CGAL_expensive_assertion_msg(result.is_valid(), "after remove vertex result is not valid"); } @@ -1157,7 +1158,7 @@ protected: fh->set_data(begin, end); else fh->add_data(begin, end); - } + } } // foreach feature of result, update the envelope surfaces, according @@ -1168,12 +1169,12 @@ protected: Vertex_iterator vi = result.vertices_begin(); for (; vi != result.vertices_end(); ++vi) update_envelope_surfaces_by_decision(vi); - + // edges Halfedge_iterator hi = result.halfedges_begin(); for (; hi != result.halfedges_end(); ++hi) update_envelope_surfaces_by_decision(hi); - + // faces Face_iterator fi = result.faces_begin(); for (; fi != result.faces_end(); ++fi) @@ -1218,7 +1219,7 @@ protected: has_equal &= has_equal_first; else if (decision == DAC_DECISION_SECOND) has_equal &= has_equal_second; - else + else has_equal &= (has_equal_first & has_equal_second); } @@ -1264,7 +1265,7 @@ protected: else if (decision == DAC_DECISION_SECOND) has_equal &= has_equal_second; - else + else has_equal &= (has_equal_first & has_equal_second); } h->set_is_equal_data_in_target(is_equal); @@ -1297,7 +1298,7 @@ protected: else if (decision == DAC_DECISION_SECOND) has_equal &= has_equal_second; - else + else has_equal &= (has_equal_first & has_equal_second); } h->set_has_equal_data_in_target_and_face(has_equal); @@ -1340,7 +1341,7 @@ protected: has_equal &= has_equal_first; else if (decision == DAC_DECISION_SECOND) has_equal &= has_equal_second; - else + else has_equal &= (has_equal_first & has_equal_second); } v->set_is_equal_data_in_face(is_equal); @@ -1348,7 +1349,7 @@ protected: } void update_flags(Minimization_diagram_2& result) - { + { // edges Halfedge_iterator hi = result.halfedges_begin(); for (; hi != result.halfedges_end(); ++hi) @@ -1371,7 +1372,7 @@ protected: { return fh->get_aux_is_set(id); } - + template bool aux_has_no_data(FeatureHandle fh, unsigned int id) { @@ -1379,7 +1380,7 @@ protected: Halfedge_handle h; Vertex_handle v; Face_handle f; - + // aux source of a face must be a face! // aux source of a halfedge can be face or halfedge // aux source of a vertex can be face, halfedge or vertex @@ -1497,9 +1498,9 @@ protected: } } } - - // confirm that aux source and decision are set over all minimization + + // confirm that aux source and decision are set over all minimization // diagram features bool check_resolve_was_ok(Minimization_diagram_2& result) { @@ -1559,12 +1560,12 @@ protected: for (; vi != result.vertices_end(); ++vi) { Vertex_handle vh = vi; - + all_ok &= (vh->get_is_set()); CGAL_assertion_msg(all_ok, "data not set over vertex"); all_ok &= (!vh->has_no_data()); - CGAL_assertion_msg(all_ok, "data empty over vertex"); + CGAL_assertion_msg(all_ok, "data empty over vertex"); /* all_ok &= (!vh->get_is_fake());*/ CGAL_assertion_msg(all_ok, "fake vertex in envelope"); } @@ -1572,7 +1573,7 @@ protected: for (; hi != result.halfedges_end(); ++hi) { Halfedge_handle hh = hi; - + all_ok &= (hh->get_is_set()); if (!all_ok) std::cerr << "edge: " << hh->curve() << std::endl; @@ -1594,14 +1595,14 @@ protected: } return all_ok; } - + // observer for the minimization diagram // keeps the relevant data in the new faces class Keep_face_data_observer : public Md_observer { public: typedef typename Minimization_diagram_2::Face_handle Face_handle; - + Keep_face_data_observer(Minimization_diagram_2& arr) : Md_observer(arr) {} @@ -1619,7 +1620,7 @@ protected: new_f->set_decision(org_f->get_decision()); } }; - + // observer for the minimization diagram // keeps the relevant data in the new edges & vertices @@ -1628,12 +1629,12 @@ protected: public: typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle; typedef typename Minimization_diagram_2::Vertex_handle Vertex_handle; - typedef typename Minimization_diagram_2::X_monotone_curve_2 + typedef typename Minimization_diagram_2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Envelope_divide_and_conquer_3::Self Self; Keep_edge_data_observer(Minimization_diagram_2& arr, Self* b) : @@ -1651,7 +1652,7 @@ protected: virtual void after_split_edge(Halfedge_handle he1, Halfedge_handle he2) { - // update data of the new vertex, which is the common vertex of he1 and + // update data of the new vertex, which is the common vertex of he1 and // he2, and of the new edge according to the data in the original edge CGAL_assertion(he2->source() == he1->target()); @@ -1669,19 +1670,19 @@ protected: // find the halfedge with the additional information, to be copied into // the second halfedge Halfedge_handle org_he = he1, new_he = he2; - + if (org_he->is_decision_set()) { new_he->set_decision(org_he->get_decision()); new_he->twin()->set_decision(org_he->get_decision()); new_vertex->set_decision(org_he->get_decision()); - } + } if (org_he->get_aux_is_set(0)) { new_vertex->set_aux_source(0, org_he->get_aux_source(0)); new_he->set_aux_source(0, org_he->get_aux_source(0)); new_he->twin()->set_aux_source(0, org_he->twin()->get_aux_source(0)); - } + } if (org_he->get_aux_is_set(1)) { new_vertex->set_aux_source(1, org_he->get_aux_source(1)); @@ -1812,11 +1813,11 @@ protected: } }; #endif - + protected: Envelope_resolver* resolver; const Traits* m_geom_traits; - bool m_own_traits; + bool m_own_traits; bool m_is_lower; }; diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 0a910866d15..daf9d606172 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -178,7 +178,7 @@ g `CGAL::wlop_simplify_and_regularize_point_set()`. -### Classification +### Classification - Added data structures to handle classification of Surface Meshes and of Clusters. @@ -233,7 +233,7 @@ g - The function `copy_face_graph()` now uses named parameters, some allowing it to use property maps instead of output iterators. -- Addition of the following named parameters : +- Addition of the following named parameters : - vertex_to_vertex_output_iterator - halfedge_to_halfedge_output_iterator - face_to_face_output_iterator @@ -252,6 +252,23 @@ g - Added a read-write property map to convert on-the-fly geometric objects from Cartesian kernels. +### 2D Arrangements + +- Refracted and fixed the `graph_traits` for the dual of an arrangement of the + following types: + `Arrangement_on_surface_2`, + `Arrangement_2`, + `Arrangement_on_surface_with_history_2`, and + `Arrangement_with_history_2`. + +- **Breaking change**: The old `` + header file has been replaced by the four header files below; each defines + the `graph_traits` for dual of the corresponding arrangement type. + ``, + ``, + ``, and + `