Integrate remarks from the review by Michael and Guillaume.

Switch from pair of iterators to a range class
This commit is contained in:
Andreas Fabri 2014-09-26 16:53:37 +02:00
parent d8d9eb605b
commit 08a033ffb4
10 changed files with 271 additions and 114 deletions

View File

@ -46,18 +46,18 @@ private:
public: public:
// Graph // Graph
typedef typename SM::Vertex_descriptor vertex_descriptor; typedef typename SM::Vertex_index vertex_descriptor;
typedef typename SM::Point vertex_property_type; typedef typename SM::Point vertex_property_type;
typedef typename SM::Edge_descriptor edge_descriptor; typedef typename SM::Edge_index edge_descriptor;
typedef boost::undirected_tag directed_category; typedef boost::undirected_tag directed_category;
typedef boost::disallow_parallel_edge_tag edge_parallel_category; typedef boost::disallow_parallel_edge_tag edge_parallel_category;
typedef SM_graph_traversal_category traversal_category; typedef SM_graph_traversal_category traversal_category;
// HalfedgeGraph // HalfedgeGraph
typedef typename SM::halfedge_descriptor halfedge_descriptor; typedef typename SM::halfedge_index halfedge_descriptor;
// FaceGraph // FaceGraph
typedef typename SM::face_descriptor face_descriptor; typedef typename SM::face_index face_descriptor;
// VertexListGraph // VertexListGraph
typedef typename SM::Vertex_iterator vertex_iterator; typedef typename SM::Vertex_iterator vertex_iterator;

View File

@ -25,6 +25,7 @@
#include <boost/graph/graph_traits.hpp> #include <boost/graph/graph_traits.hpp>
#include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/transform_iterator.hpp>
#include <CGAL/Range.h>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
#include <CGAL/circulator_bases.h> #include <CGAL/circulator_bases.h>
#include <CGAL/boost/graph/internal/helpers.h> #include <CGAL/boost/graph/internal/helpers.h>
@ -781,11 +782,11 @@ private:
* returns an iterator range over all halfedges with vertex `source(h,g)` as source. * returns an iterator range over all halfedges with vertex `source(h,g)` as source.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Halfedge_around_source_iterator<Graph>,Halfedge_around_source_iterator<Graph> > Range<Halfedge_around_source_iterator<Graph> >
halfedges_around_source(typename boost::graph_traits<Graph>::halfedge_descriptor h, Graph& g) halfedges_around_source(typename boost::graph_traits<Graph>::halfedge_descriptor h, Graph& g)
{ {
typedef Halfedge_around_source_iterator<Graph> I; typedef Halfedge_around_source_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
/** /**
@ -793,7 +794,7 @@ halfedges_around_source(typename boost::graph_traits<Graph>::halfedge_descriptor
* returns an iterator range over all halfedges with vertex `v` as source. * returns an iterator range over all halfedges with vertex `v` as source.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Halfedge_around_source_iterator<Graph>,Halfedge_around_source_iterator<Graph> > Range<Halfedge_around_source_iterator<Graph> >
halfedges_around_source(typename boost::graph_traits<Graph>::vertex_descriptor v, Graph& g) halfedges_around_source(typename boost::graph_traits<Graph>::vertex_descriptor v, Graph& g)
{ {
return halfedges_around_source(opposite(halfedge(v,g),g),g); return halfedges_around_source(opposite(halfedge(v,g),g),g);
@ -804,11 +805,11 @@ halfedges_around_source(typename boost::graph_traits<Graph>::vertex_descriptor v
* returns an iterator range over all halfedges with vertex `target(h,g)` as target. * returns an iterator range over all halfedges with vertex `target(h,g)` as target.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Halfedge_around_target_iterator<Graph>,Halfedge_around_target_iterator<Graph> > Range<Halfedge_around_target_iterator<Graph> >
halfedges_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) halfedges_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Halfedge_around_target_iterator<Graph> I; typedef Halfedge_around_target_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
/** /**
@ -816,7 +817,7 @@ halfedges_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor
* returns an iterator range over all halfedges with vertex `v` as target. * returns an iterator range over all halfedges with vertex `v` as target.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Halfedge_around_target_iterator<Graph>,Halfedge_around_target_iterator<Graph> > Range<Halfedge_around_target_iterator<Graph> >
halfedges_around_target(typename boost::graph_traits<Graph>::vertex_descriptor v, Graph& g) halfedges_around_target(typename boost::graph_traits<Graph>::vertex_descriptor v, Graph& g)
{ {
return halfedges_around_target(halfedge(v,g),g); return halfedges_around_target(halfedge(v,g),g);
@ -827,11 +828,11 @@ halfedges_around_target(typename boost::graph_traits<Graph>::vertex_descriptor v
* returns an iterator range over all halfedges incident to the same face as `h`. * returns an iterator range over all halfedges incident to the same face as `h`.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Halfedge_around_face_iterator<Graph>,Halfedge_around_face_iterator<Graph> > Range<Halfedge_around_face_iterator<Graph> >
halfedges_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) halfedges_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Halfedge_around_face_iterator<Graph> I; typedef Halfedge_around_face_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
@ -901,11 +902,11 @@ public:
* returns an iterator range over all faces around vertex `target(h,g)`. * returns an iterator range over all faces around vertex `target(h,g)`.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Face_around_target_iterator<Graph>,Face_around_target_iterator<Graph> > Range<Face_around_target_iterator<Graph> >
faces_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) faces_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Face_around_target_iterator<Graph> I; typedef Face_around_target_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
/** /**
@ -913,11 +914,11 @@ faces_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h,
* returns an iterator range over all faces adjacent to the same face `face(h,g)`. * returns an iterator range over all faces adjacent to the same face `face(h,g)`.
*/ */
template<typename Graph> template<typename Graph>
std::pair<Face_around_face_iterator<Graph>,Face_around_face_iterator<Graph> > Range<Face_around_face_iterator<Graph> >
faces_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) faces_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Face_around_face_iterator<Graph> I; typedef Face_around_face_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
template <typename Graph> template <typename Graph>
@ -1089,20 +1090,20 @@ public:
template <typename Graph> template <typename Graph>
std::pair<Vertex_around_target_iterator<Graph>, Vertex_around_target_iterator<Graph> > Range<Vertex_around_target_iterator<Graph> >
adjacent_vertices(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) adjacent_vertices(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Vertex_around_face_iterator<Graph> I; typedef Vertex_around_face_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
template <typename Graph> template <typename Graph>
std::pair<Vertex_around_target_iterator<Graph>, Vertex_around_target_iterator<Graph> > Range<Vertex_around_target_iterator<Graph> >
adjacent_vertices(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph& g) adjacent_vertices(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph& g)
{ {
typedef Vertex_around_face_iterator<Graph> I; typedef Vertex_around_face_iterator<Graph> I;
return std::make_pair(I(halfedge(v,g),g), I(halfedge(v,g),g,1)); return make_range(I(halfedge(v,g),g), I(halfedge(v,g),g,1));
} }
/** /**
@ -1110,30 +1111,30 @@ adjacent_vertices(typename boost::graph_traits<Graph>::vertex_descriptor v, cons
* returns an iterator range over all vertices adjacent to the vertex `target(h,g)`. * returns an iterator range over all vertices adjacent to the vertex `target(h,g)`.
*/ */
template <typename Graph> template <typename Graph>
std::pair<Vertex_around_target_iterator<Graph>, Vertex_around_target_iterator<Graph> > Range<Vertex_around_target_iterator<Graph> >
vertices_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) vertices_around_target(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Vertex_around_target_iterator<Graph> I; typedef Vertex_around_target_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
template <typename Graph> template <typename Graph>
std::pair<Vertex_around_target_iterator<Graph>, Vertex_around_target_iterator<Graph> > Range<Vertex_around_target_iterator<Graph> >
vertices_around_target(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph& g) vertices_around_target(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph& g)
{ {
typedef Vertex_around_target_iterator<Graph> I; typedef Vertex_around_target_iterator<Graph> I;
return std::make_pair(I(halfedge(v,g),g), I(halfedge(v,g),g,1)); return make_range(I(halfedge(v,g),g), I(halfedge(v,g),g,1));
} }
/** /**
* \ingroup PkgBGLIterators * \ingroup PkgBGLIterators
* returns an iterator range over all vertices adjacent to the face `face(h,g)`. * returns an iterator range over all vertices adjacent to the face `face(h,g)`.
*/ */
template <typename Graph> template <typename Graph>
std::pair<Vertex_around_face_iterator<Graph>, Vertex_around_face_iterator<Graph> > Range<Vertex_around_face_iterator<Graph> >
vertices_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g) vertices_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, const Graph& g)
{ {
typedef Vertex_around_face_iterator<Graph> I; typedef Vertex_around_face_iterator<Graph> I;
return std::make_pair(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
template <typename Graph> template <typename Graph>

View File

@ -40,11 +40,11 @@ public:
typedef boost::readable_property_map_tag category; typedef boost::readable_property_map_tag category;
typedef typename CGAL::Kernel_traits<Point>::type::FT value_type; typedef typename CGAL::Kernel_traits<Point>::type::FT value_type;
typedef value_type reference; typedef value_type reference;
typedef typename SM::Edge_descriptor key_type; typedef typename SM::Edge_index key_type;
SM_edge_weight_pmap(const CGAL::Surface_mesh<Point>& sm) SM_edge_weight_pmap(const CGAL::Surface_mesh<Point>& sm)
: pm_(sm. template get_property_map< : pm_(sm. template get_property_map<
typename SM::Vertex_descriptor, typename SM::Vertex_index,
typename SM::Point >("v:point")), typename SM::Point >("v:point")),
sm_(sm) sm_(sm)
{} {}
@ -56,7 +56,7 @@ public:
} }
private: private:
typename CGAL::Property_map< typename SM::Vertex_descriptor, typename CGAL::Property_map< typename SM::Vertex_index,
typename SM::Point > pm_; typename SM::Point > pm_;
const SM& sm_; const SM& sm_;
}; };
@ -86,22 +86,22 @@ template <typename Point, typename T>
struct property_map<CGAL::Surface_mesh<Point>, boost::vertex_property_t<T> > struct property_map<CGAL::Surface_mesh<Point>, boost::vertex_property_t<T> >
{ {
typedef CGAL::Surface_mesh<Point> SM; typedef CGAL::Surface_mesh<Point> SM;
typedef typename CGAL::Property_map<typename SM::vertex_descriptor,T> type; typedef typename CGAL::Property_map<typename SM::vertex_index,T> type;
typedef typename CGAL::Property_map<typename SM::vertex_descriptor,T> const_type; typedef typename CGAL::Property_map<typename SM::vertex_index,T> const_type;
}; };
template <typename Point, typename T> template <typename Point, typename T>
typename property_map<CGAL::Surface_mesh<Point>, boost::vertex_property_t<T> >::const_type typename property_map<CGAL::Surface_mesh<Point>, boost::vertex_property_t<T> >::const_type
get(boost::vertex_property_t<T> vprop, const CGAL::Surface_mesh<Point>& sm) get(boost::vertex_property_t<T> vprop, const CGAL::Surface_mesh<Point>& sm)
{ {
return sm.template get_property_map<typename CGAL::Surface_mesh<Point>::Vertex_descriptor, T>(vprop.s); return sm.template get_property_map<typename CGAL::Surface_mesh<Point>::Vertex_index, T>(vprop.s);
} }
template <typename Point, typename T> template <typename Point, typename T>
typename property_map<CGAL::Surface_mesh<Point>, boost::vertex_property_t<T> >::const_type typename property_map<CGAL::Surface_mesh<Point>, boost::vertex_property_t<T> >::const_type
add(boost::vertex_property_t<T> vprop, CGAL::Surface_mesh<Point>& sm) add(boost::vertex_property_t<T> vprop, CGAL::Surface_mesh<Point>& sm)
{ {
return sm.template add_property_map<typename CGAL::Surface_mesh<Point>::Vertex_descriptor, T>(vprop.s, vprop.t); return sm.template add_property_map<typename CGAL::Surface_mesh<Point>::Vertex_index, T>(vprop.s, vprop.t);
} }
template <typename K, typename V, typename P> template <typename K, typename V, typename P>
@ -220,7 +220,7 @@ struct property_map<CGAL::Surface_mesh<K>, CGAL::vertex_point_t >
{ {
typedef CGAL::Surface_mesh<K> SM; typedef CGAL::Surface_mesh<K> SM;
typedef typedef
typename CGAL::Property_map< typename SM::Vertex_descriptor, typename CGAL::Property_map< typename SM::Vertex_index,
K K
> type; > type;
typedef type const_type; typedef type const_type;

View File

@ -0,0 +1,127 @@
// Copyright (c) 2014 GeometryFactory (France). 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 Lesser 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$
//
// Author(s) : Andreas Fabri
#ifndef CGAL_RANGE_H
#define CGAL_RANGE_H
#include <utility>
namespace CGAL {
// Range is a ...
template <typename T>
struct Range : public std::pair<T,T>
{
typedef std::pair<T,T> Base;
Range(const T&b, const T& e)
: Base(b,e)
{}
const T& begin() const
{
return first;
}
const T& end() const
{
return second;
}
};
template <typename T>
Range<T>
make_range(const T& b, const T&e)
{
return Range<T>(b,e);
}
template<typename T>
inline T range_begin( Range<T> & x )
{
return x.first;
}
template<typename T>
inline T range_end( Range<T> & x )
{
return x.second;
}
template<typename T>
inline T range_begin(const Range<T>& x )
{
return x.first;
}
template<typename T>
inline T range_end(const Range<T>& x )
{
return x.second;
}
}
namespace boost {
template <typename X>
struct range_iterator;
template <typename X>
struct range_mutable_iterator;
template <typename X>
struct range_const_iterator;
template <typename T>
struct range_iterator<CGAL::Range<T> >
{
typedef T type;
};
template<typename T>
struct range_mutable_iterator< CGAL::Range<T> >
{
typedef T type;
};
template<typename T>
struct range_const_iterator< CGAL::Range<T> >
{
typedef T type;
};
/*
template <typename T>
T
begin(const CGAL::Range<T>& r)
{
return r.first;
}
template <typename T>
T
end(const CGAL::Range<T>& r)
{
return r.second;
}
*/
}
#endif // CGAL_RANGE_H

View File

@ -32,10 +32,10 @@ It provides the following features:
The main class `Surface_mesh` provides four nested classes that The main class `Surface_mesh` provides four nested classes that
represent the basic elements of the halfedge data structure: represent the basic elements of the halfedge data structure:
- `Surface_mesh::Vertex_descriptor` - `Surface_mesh::Vertex_index`
- `Surface_mesh::Halfedge_descriptor` - `Surface_mesh::Halfedge_index`
- `Surface_mesh::Face_descriptor` - `Surface_mesh::Face_index`
- `Surface_mesh::Edge_descriptor` - `Surface_mesh::Edge_index`
Descriptors are just a typed wrapper for an index Descriptors are just a typed wrapper for an index
and should be passed by value. They are and should be passed by value. They are
@ -49,14 +49,14 @@ operation is not topologically valid.
\code \code
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
Mesh m; Mesh m;
Mesh::Vertex_descriptor u = m.add_vertex(K::Point_3(0,1,0)); Mesh::Vertex_index u = m.add_vertex(K::Point_3(0,1,0));
Mesh::Vertex_descriptor v = m.add_vertex(K::Point_3(0,0,0)); Mesh::Vertex_index v = m.add_vertex(K::Point_3(0,0,0));
Mesh::Vertex_descriptor w = m.add_vertex(K::Point_3(1,0,0)); Mesh::Vertex_index w = m.add_vertex(K::Point_3(1,0,0));
m.add_face(u, v, w); m.add_face(u, v, w);
\endcode \endcode
As `Surface_mesh` is index-based `Vertex_descriptor`, `Face_descriptor`, As `Surface_mesh` is index-based `Vertex_index`, `Face_index`,
`Halfedge_descriptor` and `Edge_descriptor` `Halfedge_index` and `Edge_descriptor`
don't have member functions to access connectivity or properties. don't have member functions to access connectivity or properties.
The functions of the `Surface_mesh` instance they were The functions of the `Surface_mesh` instance they were
created from needs to be used to obtain that information. created from needs to be used to obtain that information.
@ -170,9 +170,9 @@ operation, this function only checks if the halfedge associated to `v`
is a border halfedge. The user is in charge to correctly set the halfedge is a border halfedge. The user is in charge to correctly set the halfedge
associated to a vertex after having applied an operation that might invalidate associated to a vertex after having applied an operation that might invalidate
this property. this property.
The functions `Surface_mesh::fix_border(Vertex_descriptor v)`, The functions `Surface_mesh::fix_constant_border_property(Vertex_descriptor v)`,
`Surface_mesh::fix_border(Halfedge_descriptor h)`, and `Surface_mesh::fix_constant_border_property(Halfedge_descriptor h)`, and
`Surface_mesh::fix_border()` allow to restore this property `Surface_mesh::fix_constant_border_property()` allow to restore this property
for a single vertex `v`, for all vertices on the boundary of the for a single vertex `v`, for all vertices on the boundary of the
face of `h`, and for all vertices of the surface mesh, respectively. face of `h`, and for all vertices of the surface mesh, respectively.
@ -187,15 +187,15 @@ as
[Kruskal minimum spanning tree](http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/kruskal_min_spanning_tree.html) [Kruskal minimum spanning tree](http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/kruskal_min_spanning_tree.html)
directly on a surface mesh. directly on a surface mesh.
The types and free functions of the BGL API have each an equivalent type or member function, The types and free functions of the BGL API have each a similar type or member function,
for example for example
| BGL | Surface mesh | | BGL | %Surface_mesh | Remark |
| :---- | :---- | | :---- | :---- | :--- |
| `boost::graph_traits<G>::vertex_descriptor` | `Surface_mesh::Vertex_descriptor` | | `boost::graph_traits<G>::vertex_descriptor` | `Surface_mesh::Vertex_index` | |
| `edges(const G& g)` | `sm.edges()` | | `edges(const G& g)` | `sm.edges()` | |
| `vd = source(ed,g)` | `vd = sm.source(ed)` | | `vd = source(ed,g)` | `vd = sm.source(ed)` | |
| `n = num_vertices(g)` | `n = sm.num_vertices()` | | `n = num_vertices(g)` | `n = sm.number_of_vertices()` | the latter only counts non-deleted vertices |
| etc. | | | etc. | | |
@ -203,9 +203,9 @@ The class `Surface_mesh` is also a model of the concept `MutableFaceGraph` defin
in the package \ref PkgBGLSummary. This and similar concepts like `HalfedgeGraph` in the package \ref PkgBGLSummary. This and similar concepts like `HalfedgeGraph`
refine the graph concepts of the BGL by introducing the notion of halfedges and faces, refine the graph concepts of the BGL by introducing the notion of halfedges and faces,
as well as cycles of halfedges around faces and around vertices. as well as cycles of halfedges around faces and around vertices.
Again, there are equivalent types and functions: Again, there are similar types and functions:
| BGL | Surface mesh | | BGL | %Surface_mesh |
| :---- | :---- | | :---- | :---- |
| `boost::graph_traits<G>::halfedge_descriptor` | `Surface_mesh::Halfedge_descriptor` | | `boost::graph_traits<G>::halfedge_descriptor` | `Surface_mesh::Halfedge_descriptor` |
| `hd = next(hd, g)` | `hd = sm.next(hd)` | | `hd = next(hd, g)` | `hd = sm.next(hd)` |
@ -230,8 +230,7 @@ The BGL way of retrieving the index property map of a graph `g` is
`vipm = get(boost::vertex_index, g)`, and `get(vipm, vd)` in order then `vipm = get(boost::vertex_index, g)`, and `get(vipm, vd)` in order then
to retrieve the index for a vertex descriptor `vd`, and it is to retrieve the index for a vertex descriptor `vd`, and it is
`get(vertex_index, g, vd)` to obtain the vertex index directly. `get(vertex_index, g, vd)` to obtain the vertex index directly.
For the `Surface_mesh` class, all an index property map has to do
is to call `Vertex_descriptor::idx()`.
\subsection SubsectionSurfaceMeshBglExample Example \subsection SubsectionSurfaceMeshBglExample Example
@ -263,16 +262,16 @@ the surface mesh, they are taken from the free list in case it is
not empty. not empty.
For all elements we offer a function to obtain the number of For all elements we offer a function to obtain the number of
added and removed elements, as well as the number of removed elements. elements, as well as the number of removed elements.
For vertices the functions are `Surface_mesh::num_vertices()` For vertices the functions are `Surface_mesh::numbr_of_vertices()`
and `Surface_mesh::num_removed_vertices()`, respectively. The first function and `Surface_mesh::number_of_removed_vertices()`, respectively.
matches the free function `num_vertices(const G&)` of the \sc{Bgl} The first function is slightly different from the free function
package. As \sc{Bgl} style algorithms use the indices of elements `num_vertices(const G&)` of the \sc{Bgl} package.
As \sc{Bgl} style algorithms use the indices of elements
to access data in temporary vectors of size `num_vertices()` to access data in temporary vectors of size `num_vertices()`
this function must return a number larger than the largest index of this function must return a number larger than the largest index of
the elements. the elements.
Iterators like the `Surface_mesh::Vertex_iterator` only enumerate Iterators like the `Surface_mesh::Vertex_iterator` only enumerate
elements that are not marked as deleted. elements that are not marked as deleted.

View File

@ -5,7 +5,7 @@
#include <boost/utility/addressof.hpp> #include <boost/utility/addressof.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/functional/value_factory.hpp> #include <boost/functional/value_factory.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h> #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h> #include <CGAL/Surface_mesh.h>
#include <CGAL/box_intersection_d.h> #include <CGAL/box_intersection_d.h>
@ -76,19 +76,20 @@ struct Callback {
unsigned int intersect(const SM& P, const SM& Q) { unsigned int intersect(const SM& P, const SM& Q) {
std::vector<Box> P_boxes, Q_boxes; std::vector<Box> P_boxes, Q_boxes;
std::vector<const Box*> P_box_ptr, Q_box_ptr; std::vector<const Box*> P_box_ptr, Q_box_ptr;
P_boxes.reserve(P.num_faces()); P_boxes.reserve(P.number_of_faces());
P_box_ptr.reserve(P.num_faces()); P_box_ptr.reserve(P.number_of_faces());
Q_boxes.reserve(Q.num_faces()); Q_boxes.reserve(Q.number_of_faces());
Q_box_ptr.reserve(Q.num_faces()); Q_box_ptr.reserve(Q.number_of_faces());
// build boxes and pointers to boxes // build boxes and pointers to boxes
std::transform(P.faces_begin(), P.faces_end(), boost::transform(P.faces(),
std::back_inserter(P_boxes), std::back_inserter(P_boxes),
boost::bind(boost::value_factory<Box>(), _1, boost::cref(P))); boost::bind(boost::value_factory<Box>(), _1, boost::cref(P)));
std::transform(P_boxes.begin(), P_boxes.end(), std::back_inserter(P_box_ptr), std::transform(P_boxes.begin(), P_boxes.end(), std::back_inserter(P_box_ptr),
&boost::addressof<Box>); &boost::addressof<Box>);
std::transform(Q.faces_begin(), Q.faces_end(), boost::transform(Q.faces(),
std::back_inserter(Q_boxes), std::back_inserter(Q_boxes),
boost::bind(boost::value_factory<Box>(), _1, boost::cref(Q))); boost::bind(boost::value_factory<Box>(), _1, boost::cref(Q)));
std::transform(Q_boxes.begin(), Q_boxes.end(), std::back_inserter(Q_box_ptr), std::transform(Q_boxes.begin(), Q_boxes.end(), std::back_inserter(Q_box_ptr),

View File

@ -7,6 +7,7 @@
typedef CGAL::Simple_cartesian<double> K; typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<typename K::Point_3> Mesh; typedef CGAL::Surface_mesh<typename K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
int main() int main()
{ {
@ -21,14 +22,13 @@ int main()
std::cout << "After insertion of 5 vertices and removal of the 3. vertex\n" std::cout << "After insertion of 5 vertices and removal of the 3. vertex\n"
<< "# used vertices / total vertices = " << "# used vertices / total vertices = "
<< m.num_vertices() - m.num_removed_vertices() << m.number_of_vertices()
<< " / " << m.num_vertices() << std::endl; << " / " << m.num_vertices() << std::endl;
std::cout << "Iterate over used vertices\n"; std::cout << "Iterate over used vertices\n";
{ {
Mesh::Vertex_iterator vbegin, vend; BOOST_FOREACH(vertex_descriptor vd, m.vertices()){
for(boost::tie(vbegin, vend) = m.vertices(); vbegin != vend; ++vbegin) { std::cout << m.point(vd) << std::endl;
std::cout << m.point(*vbegin) << std::endl;
} }
} }
@ -42,9 +42,9 @@ int main()
<< m.num_vertices() - m.num_removed_vertices() << m.num_vertices() - m.num_removed_vertices()
<< " / " << m.num_vertices() << std::endl; << " / " << m.num_vertices() << std::endl;
{ {
unsigned int i = 0, end = m.vertices().second->idx(); unsigned int i = 0, end = m.num_vertices();
for( ; i < end; ++i) { for( ; i < end; ++i) {
Mesh::Vertex_index vh(i); vertex_descriptor vh(i);
assert(m.is_removed(vh) == removed[vh]); assert(m.is_removed(vh) == removed[vh]);
std::cout << m.point(vh) << ((m.is_removed(vh)) ? " R\n" : "\n"); std::cout << m.point(vh) << ((m.is_removed(vh)) ? " R\n" : "\n");
} }
@ -54,13 +54,13 @@ int main()
std::cout << "\nAfter garbage collection\n" std::cout << "\nAfter garbage collection\n"
<< "# used vertices / total vertices = " << "# used vertices / total vertices = "
<< m.num_vertices() - m.num_removed_vertices() << m.number_of_vertices()
<< " / " << m.num_vertices() << std::endl; << " / " << m.num_vertices() << std::endl;
{ {
unsigned int i = 0, end = m.vertices().second->idx(); unsigned int i = 0, end = m.num_vertices();
for( ; i < end; ++i) { for( ; i < end; ++i) {
Mesh::Vertex_index vh(i); vertex_descriptor vh(i);
std::cout << m.point(vh) << ((m.is_removed(vh)) ? " R\n" : "\n"); std::cout << m.point(vh) << ((m.is_removed(vh)) ? " R\n" : "\n");
} }
} }

View File

@ -3,6 +3,8 @@
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h> #include <CGAL/Surface_mesh.h>
#include <boost/foreach.hpp>
typedef CGAL::Simple_cartesian<double> K; typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<typename K::Point_3> Mesh; typedef CGAL::Surface_mesh<typename K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor; typedef Mesh::Vertex_index vertex_descriptor;
@ -22,20 +24,20 @@ int main()
m.add_face(v2, v3, v4); m.add_face(v2, v3, v4);
// add a Boolean property to all faces and initialize it to false // add a Boolean property to all faces and initialize it to false
m.add_property_map<Face_descriptor,bool>("f:my_property", false); m.add_property_map<face_descriptor,bool>("f:my_property", false);
// give each vertex a name, the default is empty // give each vertex a name, the default is empty
CGAL::Property_map<Vertex_descriptor,std::string> name CGAL::Property_map<vertex_descriptor,std::string> name
= m.add_property_map<Vertex_descriptor,std::string>("v:name", "noname"); = m.add_property_map<vertex_descriptor,std::string>("v:name", "noname");
// add some names to the vertices // add some names to the vertices
name[v0] = "hello"; name[v0] = "hello";
name[v2] = "world"; name[v2] = "world";
// retrieve the point property // retrieve the point property
CGAL::Property_map<Vertex_descriptor, K::Point_3> location = m.points(); CGAL::Property_map<vertex_descriptor, K::Point_3> location = m.points();
for(Mesh::Vertex_iterator it = m.vertices_begin(); it != m.vertices_end(); ++it) { BOOST_FOREACH( vertex_descriptor vd, m.vertices()) {
std::cout << name[*it] << " @ " << location[*it] << std::endl; std::cout << name[vd] << " @ " << location[vd] << std::endl;
} }
// delete the string property again // delete the string property again

View File

@ -34,6 +34,7 @@
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <CGAL/Range.h>
#include <CGAL/circulator.h> #include <CGAL/circulator.h>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
#include <CGAL/Surface_mesh/Surface_mesh_fwd.h> #include <CGAL/Surface_mesh/Surface_mesh_fwd.h>
@ -367,7 +368,7 @@ public:
/// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>. /// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>.
/// \sa `vertices()` /// \sa `vertices()`
/// \sa `Halfedge_range`, `Edge_range`, `Face_range` /// \sa `Halfedge_range`, `Edge_range`, `Face_range`
typedef std::pair<Vertex_iterator, Vertex_iterator> Vertex_range; typedef Range<Vertex_iterator> Vertex_range;
/// \brief This class iterates linearly over all halfedges. /// \brief This class iterates linearly over all halfedges.
/// ///
@ -385,7 +386,7 @@ public:
/// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>. /// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>.
/// \sa `halfedges()` /// \sa `halfedges()`
/// \sa `Vertex_range`, `Edge_range`, `Face_range` /// \sa `Vertex_range`, `Edge_range`, `Face_range`
typedef std::pair<Halfedge_iterator, Halfedge_iterator> Halfedge_range; typedef Range<Halfedge_iterator> Halfedge_range;
/// \brief This class iterates linearly over all edges. /// \brief This class iterates linearly over all edges.
/// ///
@ -403,7 +404,7 @@ public:
/// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>. /// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>.
/// \sa `edges()` /// \sa `edges()`
/// \sa `Halfedge_range`, `Vertex_range`, `Face_range` /// \sa `Halfedge_range`, `Vertex_range`, `Face_range`
typedef std::pair<Edge_iterator, Edge_iterator> Edge_range; typedef Range<Edge_iterator> Edge_range;
/// \brief This class iterates linearly over all faces. /// \brief This class iterates linearly over all faces.
/// ///
@ -421,26 +422,26 @@ public:
/// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>. /// A model of <a href="http://www.boost.org/libs/range/doc/html/range/concepts/bidirectional_range.html">BidirectionalRange</a>.
/// \sa `faces()` /// \sa `faces()`
/// \sa `Vertex_range`, `Halfedge_range`, `Edge_range` /// \sa `Vertex_range`, `Halfedge_range`, `Edge_range`
typedef std::pair<Face_iterator, Face_iterator> Face_range; typedef Range<Face_iterator> Face_range;
typedef CGAL::Vertex_around_target_iterator<Surface_mesh> Vertex_around_target_iterator; typedef CGAL::Vertex_around_target_iterator<Surface_mesh> Vertex_around_target_iterator;
typedef std::pair<Vertex_around_target_iterator,Vertex_around_target_iterator> Vertex_around_target_range; typedef Range<Vertex_around_target_iterator> Vertex_around_target_range;
typedef CGAL::Halfedge_around_target_iterator<Surface_mesh> Halfedge_around_target_iterator; typedef CGAL::Halfedge_around_target_iterator<Surface_mesh> Halfedge_around_target_iterator;
typedef std::pair<Halfedge_around_target_iterator,Halfedge_around_target_iterator> Halfedge_around_target_range; typedef Range<Halfedge_around_target_iterator> Halfedge_around_target_range;
typedef CGAL::Face_around_target_iterator<Surface_mesh> Face_around_target_iterator; typedef CGAL::Face_around_target_iterator<Surface_mesh> Face_around_target_iterator;
typedef std::pair<Face_around_target_iterator,Face_around_target_iterator> Face_around_target_range; typedef Range<Face_around_target_iterator> Face_around_target_range;
typedef CGAL::Vertex_around_face_iterator<Surface_mesh> Vertex_around_face_iterator; typedef CGAL::Vertex_around_face_iterator<Surface_mesh> Vertex_around_face_iterator;
typedef std::pair<Vertex_around_face_iterator,Vertex_around_face_iterator> Vertex_around_face_range; typedef Range<Vertex_around_face_iterator> Vertex_around_face_range;
typedef CGAL::Halfedge_around_face_iterator<Surface_mesh> Halfedge_around_face_iterator; typedef CGAL::Halfedge_around_face_iterator<Surface_mesh> Halfedge_around_face_iterator;
typedef std::pair<Halfedge_around_face_iterator,Halfedge_around_face_iterator> Halfedge_around_face_range; typedef Range<Halfedge_around_face_iterator> Halfedge_around_face_range;
typedef CGAL::Face_around_face_iterator<Surface_mesh> Face_around_face_iterator; typedef CGAL::Face_around_face_iterator<Surface_mesh> Face_around_face_iterator;
typedef std::pair<Face_around_face_iterator,Face_around_face_iterator> Face_around_face_range; typedef Range<Face_around_face_iterator> Face_around_face_range;
/// @cond CGAL_BEGIN_END /// @cond CGAL_BEGIN_END
@ -457,11 +458,13 @@ public:
} }
/// @endcond /// @endcond
/// returns the iterator range of the vertices of the mesh. /// returns the iterator range of the vertices of the mesh.
Vertex_range vertices() const { Vertex_range vertices() const {
return std::make_pair(vertices_begin(), vertices_end()); return make_range(vertices_begin(), vertices_end());
} }
/// @cond CGAL_BEGIN_END /// @cond CGAL_BEGIN_END
/// Start iterator for halfedges. /// Start iterator for halfedges.
Halfedge_iterator halfedges_begin() const Halfedge_iterator halfedges_begin() const
@ -476,9 +479,10 @@ public:
} }
/// @endcond /// @endcond
/// returns the iterator range of the halfedges of the mesh. /// returns the iterator range of the halfedges of the mesh.
Halfedge_range halfedges() const { Halfedge_range halfedges() const {
return std::make_pair(halfedges_begin(), halfedges_end()); return make_range(halfedges_begin(), halfedges_end());
} }
@ -496,10 +500,11 @@ public:
} }
/// @endcond /// @endcond
/// returns the iterator range of the edges of the mesh. /// returns the iterator range of the edges of the mesh.
Edge_range edges() const Edge_range edges() const
{ {
return std::make_pair(edges_begin(), edges_end()); return make_range(edges_begin(), edges_end());
} }
@ -519,7 +524,7 @@ public:
/// returns the iterator range of the faces of the mesh. /// returns the iterator range of the faces of the mesh.
Face_range faces() const { Face_range faces() const {
return std::make_pair(faces_begin(), faces_end()); return make_range(faces_begin(), faces_end());
} }
/// returns the iterator range for vertices around vertex `target(h)`, starting at `source(h)`. /// returns the iterator range for vertices around vertex `target(h)`, starting at `source(h)`.
@ -826,7 +831,27 @@ public:
/// garbage collection. /// garbage collection.
///@{ ///@{
size_type number_of_vertices() const
{
return num_vertices() + num_removed_vertices();
}
size_type number_of_halfedges() const
{
return num_halfedges() + num_removed_halfedges();
}
size_type number_of_edges() const
{
return num_edges() + num_removed_edges();
}
size_type number_of_faces() const
{
return num_faces() + num_removed_faces();
}
#ifndef DOXYGEN_RUNNING
/// returns the number of used and removed vertices in the mesh. /// returns the number of used and removed vertices in the mesh.
size_type num_vertices() const { return (size_type) vprops_.size(); } size_type num_vertices() const { return (size_type) vprops_.size(); }
@ -851,10 +876,10 @@ public:
/// returns the number of removed faces in the mesh. /// returns the number of removed faces in the mesh.
size_type num_removed_faces() const { return removed_faces_; } size_type num_removed_faces() const { return removed_faces_; }
#endif
/// returns `true` iff the mesh is empty, i.e., has no used vertices. /// returns `true` iff the mesh is empty, i.e., has no used vertices.
bool empty() const { return num_vertices() == num_removed_vertices(); } bool is_empty() const { return num_vertices() == num_removed_vertices(); }
/// removes all vertices, edges and faces. Collects garbage and clears all properties. /// removes all vertices, edges and faces. Collects garbage and clears all properties.
void clear(); void clear();
@ -872,7 +897,7 @@ public:
} }
/// @endcond /// @endcond
/// reserves space for vertices, faces, edges and their currently /// reserves space for vertices, halfedges, edges, faces, and their currently
/// associated properties. /// associated properties.
void reserve(size_type nvertices, void reserve(size_type nvertices,
size_type nedges, size_type nedges,
@ -1292,7 +1317,7 @@ public:
} }
/// restores the constant time border property for vertex `v`. /// restores the constant time border property for vertex `v`.
void fix_border(Vertex_index v) void fix_constant_border_property(Vertex_index v)
{ {
if(halfedge(v) == null_halfedge()) if(halfedge(v) == null_halfedge())
return; return;
@ -1307,7 +1332,7 @@ public:
/// restores the constant time border property for all vertices /// restores the constant time border property for all vertices
/// around the face associated to `h`. /// around the face associated to `h`.
void fix_border(Halfedge_index h) void fix_constant_border_property(Halfedge_index h)
{ {
if(is_border(h)){ if(is_border(h)){
Halfedge_around_face_circulator hafc(h,*this),done(hafc); Halfedge_around_face_circulator hafc(h,*this),done(hafc);
@ -1317,17 +1342,17 @@ public:
} else { } else {
Vertex_around_face_circulator vafc(h,*this),done(vafc); Vertex_around_face_circulator vafc(h,*this),done(vafc);
do { do {
fix_border(*vafc); fix_constant_border_property(*vafc);
}while(++vafc != done); }while(++vafc != done);
} }
} }
/// restores the constant time border property for all vertices /// restores the constant time border property for all vertices
/// of the surface mesh. /// of the surface mesh.
void fix_border() void fix_constant_border_property()
{ {
BOOST_FOREACH(Vertex_index vd, vertices()){ BOOST_FOREACH(Vertex_index vd, vertices()){
fix_border(vd); fix_constant_border_property(vd);
} }
} }
@ -1509,6 +1534,7 @@ private: //------------------------------------------------------- private data
/// \relates Surface_mesh /// \relates Surface_mesh
/// Inserts the surface mesh in an output stream in Ascii OFF format. /// Inserts the surface mesh in an output stream in Ascii OFF format.
/// If the vertices have a normal property it is also inserted in the stream.
template <typename P> template <typename P>
std::ostream& operator<<(std::ostream& os, const Surface_mesh<P>& sm) std::ostream& operator<<(std::ostream& os, const Surface_mesh<P>& sm)
{ {
@ -1516,6 +1542,7 @@ private: //------------------------------------------------------- private data
} }
/// \relates Surface_mesh /// \relates Surface_mesh
/// Extracts the surface mesh from an input stream in Ascii OFF format. /// Extracts the surface mesh from an input stream in Ascii OFF format.
/// If the vertices have a normal property it is also extracted from the stream.
template <typename P> template <typename P>
std::istream& operator>>(std::istream& is, Surface_mesh<P>& sm) std::istream& operator>>(std::istream& is, Surface_mesh<P>& sm)
{ {

View File

@ -39,9 +39,9 @@ class Surface_mesh_incremental_builder {
public: public:
typedef HalfedgeDS_ HDS; // internal typedef HalfedgeDS_ HDS; // internal
typedef HalfedgeDS_ HalfedgeDS; typedef HalfedgeDS_ HalfedgeDS;
typedef typename HDS::Vertex_descriptor Vertex_descriptor; typedef typename boost::graph_traits<HDS>::vertex_descriptor Vertex_descriptor;
typedef typename HDS::Halfedge_descriptor Halfedge_descriptor; typedef typename boost::graph_traits<HDS>::halfedge_descriptor Halfedge_descriptor;
typedef typename HDS::Face_descriptor Face_descriptor; typedef typename boost::graph_traits<HDS>::face_descriptor Face_descriptor;
typedef typename HDS::Point Point_3; typedef typename HDS::Point Point_3;
typedef typename HDS::size_type size_type; typedef typename HDS::size_type size_type;