make the edge_descriptor of Polyhedron hashable

This commit is contained in:
Sébastien Loriot 2014-07-23 08:20:16 +02:00
parent 5c6b54257a
commit cdec3d6414
8 changed files with 64 additions and 41 deletions

View File

@ -10,3 +10,4 @@ Polyhedron
Triangulation_2
Surface_mesh_simplification
Property_map
Miscellany

View File

@ -27,14 +27,14 @@ The traits class `boost::graph_traits< CGAL::Polyhedron_3<T> >` provides the fol
| Member | Value | Description |
| :----------------------- | :----: | :---------- |
| `vertex_descriptor` | `Polyhedron_3::Vertex_handle` | The vertex descriptor |
| `edge_descriptor` | `Polyhedron_3::Halfedge_handle` | The edge descriptor |
| `edge_descriptor` | `unspecified_type` | The edge descriptor |
| `halfedge_descriptor` | `Polyhedron_3::Halfedge_handle` | The halfedge descriptor |
| `face_descriptor` | `Polyhedron_3::Face_handle` | The face descriptor |
| `adjacency_iterator` | `CGAL::Vertex_around_target_iterator<Polyhedron_3<T> >` | Iterates through adjacent vertices|
| `out_edge_iterator` | `CGAL::Out_edge_iterator<Polyhedron_3<T> >` | Iterate through the out-edges of a vertex. |
| `in_edge_iterator` | `CGAL::Out_edge_iterator<Polyhedron_3<T> >` | Iterate through the in-edges of a vertex. |
| `vertex_iterator` | `unspecified_type` | Iterate through the vertices of a polyhedron.|
| `edge_iterator` | `Polyhedron_3::Halfedge_iterator` | Iterate through the edges of a polyhedron.|
| `edge_iterator` | `unspecified_type` | Iterate through the edges of a polyhedron.|
| `halfedge_iterator` | `Polyhedron_3::Halfedge_iterator` | Iterate through the halfedges of a polyhedron.|
| `face_iterator` | `Polyhedron_3::Face_iterator` | Iterate through the faces of a polyhedron.|
| `directed_category` | Inherits from `boost::bidirectional_graph_tag`, `boost::vertex_list_graph_tag` and `boost::edge_list_graph_tag` | |
@ -44,6 +44,8 @@ The traits class `boost::graph_traits< CGAL::Polyhedron_3<T> >` provides the fol
| `edges_size_type` | `Polyhedron_3::size_type` | The size type of the edge list |
| `degree_size_type` | `Polyhedron_3::size_type` | The size type of the adjacency list |
For convenience, the type `edge_descriptor` is hashable using the functor `CGAL::Handle_hash_function`
that is the default hash functor of `CGAL::Unique_hash_map`.
\section BGLT2GT Specializations for the 2D Triangulation Classes

View File

@ -31,6 +31,8 @@
#include <CGAL/basic.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/Handle_hash_function.h>
#ifndef CGAL_NO_DEPRECATED_CODE
#include <CGAL/boost/graph/halfedge_graph_traits.h>
#endif
@ -134,6 +136,22 @@ private:
Halfedge_handle halfedge_;
};
// make edge_descriptor hashable by default in Unique_hash_map
namespace handle{
template<typename Halfedge_handle>
struct Hash_functor< HDS_edge<Halfedge_handle> >
{
std::size_t
operator()(const HDS_edge<Halfedge_handle>& edge)
{
Halfedge_handle he = edge.halfedge();
if ( he < he->opposite() )
return Hash_functor<Halfedge_handle>()(he);
return Hash_functor<Halfedge_handle>()(he->opposite());
}
};
} //end of namespace handle
template<typename Halfedge_handle>
struct Construct_edge {
typedef HDS_edge<Halfedge_handle> result_type;

View File

@ -50,7 +50,7 @@ private:
CGAL::Unique_hash_map<key_type,std::size_t> map_;
};
// Special case for edges. Hashes each half_edge.
// Special case for edges.
template<class Polyhedron>
class Polyhedron_edge_index_map_external
: public boost::put_get_helper<std::size_t, Polyhedron_edge_index_map_external<Polyhedron> >
@ -62,21 +62,17 @@ public:
typedef typename boost::graph_traits<Polyhedron>::edge_descriptor key_type;
Polyhedron_edge_index_map_external(Polyhedron& p)
: map_(std::size_t(-1), num_halfedges(p)), p(p)
: map_(std::size_t(-1), num_halfedges(p))
{
unsigned int data = 0;
typename boost::graph_traits<Polyhedron>::edge_iterator it, end;
for(boost::tie(it, end) = edges(p); it != end; ++it, ++data) {
map_[halfedge(*it, p)] = data;
map_[opposite(halfedge(*it, p), p)] = data;
}
for(boost::tie(it, end) = edges(p); it != end; ++it, ++data)
map_[*it] = data;
}
reference operator[](const key_type& k) const { return map_[halfedge(k,p)]; }
reference operator[](const key_type& k) const { return map_[k]; }
private:
CGAL::Unique_hash_map<typename boost::graph_traits<Polyhedron>::halfedge_descriptor,
std::size_t> map_;
Polyhedron& p;
CGAL::Unique_hash_map<key_type,std::size_t> map_;
};
template<typename Handle>

View File

@ -31,12 +31,27 @@
namespace CGAL {
//mechanism to abuse Handle_hash_function which is the default
//template parameter of Unique_hash_map
namespace internal{
namespace handle {
template <class H>
struct Hash_functor{
std::size_t
operator()(const H& h)
{
return std::size_t(&*h) /
sizeof( typename std::iterator_traits<H>::value_type);
}
};
}
}
struct Handle_hash_function {
typedef std::size_t result_type;
template <class H>
std::size_t operator() (const H& h) const {
return std::size_t(&*h) /
sizeof( typename std::iterator_traits<H>::value_type);
return ::CGAL::internal::handle::Hash_functor<H>()(h);
}
};

View File

@ -204,6 +204,12 @@ and <code>src/</code> directories).
</ul>
<h3>Triangulated Surface Mesh Simplification</h3>
<ul>
<li>
Breaking change: Due to the cleanup of the concepts of the package <em>CGAL and the Boost Graph Library</em>,
the named parameter <code>edge_is_border_map</code> has been removed, and the named parameter
<code>edge_is_constrained_map</code> now expects a property map with an edge descriptor as key type
(vs. halfedge descriptor before).
</li>
<li>Add some optimization in the code making the implementation faster
(depending on the cost and the placement chosen). However, for an edge which
collapse is not topologically valid, the vector of vertices of the link provided
@ -213,7 +219,7 @@ and <code>src/</code> directories).
but if it is a absolute requirement for user defined cost/placement, defining
the macro <code>CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK</code>
will restore the former behavior.
</li>
</li>
</ul>
<h3>Triangulated Surface Mesh Deformation (new package)</h3>

View File

@ -1,6 +1,8 @@
#include <iostream>
#include <fstream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
@ -25,24 +27,8 @@ typedef boost::graph_traits<Surface_mesh>::edge_iterator edge_iterator;
namespace SMS = CGAL::Surface_mesh_simplification ;
//
// BGL property map which indicates whether an edge is marked as non-removable
struct Hash
{
typedef std::size_t result_type;
result_type operator()(const edge_descriptor& ed) const
{
// although two edge_descriptors may be equal, they may store any of its two halfedges
CGAL::Handle_hash_function hhf;
std::size_t st1 = hhf(halfedge(ed,Surface_mesh()));
std::size_t st2 = hhf(opposite(halfedge(ed,Surface_mesh()),Surface_mesh()));
return (std::min)(st1,st2);
}
};
struct Constrained_edge_map : public boost::put_get_helper<bool,Constrained_edge_map>
{
typedef boost::readable_property_map_tag category;
@ -50,7 +36,7 @@ struct Constrained_edge_map : public boost::put_get_helper<bool,Constrained_edge
typedef bool reference;
typedef edge_descriptor key_type;
Constrained_edge_map(const CGAL::Unique_hash_map<key_type,bool,Hash>& aConstraints)
Constrained_edge_map(const CGAL::Unique_hash_map<key_type,bool>& aConstraints)
: mConstraints(aConstraints)
{}
@ -61,7 +47,7 @@ struct Constrained_edge_map : public boost::put_get_helper<bool,Constrained_edge
}
private:
const CGAL::Unique_hash_map<key_type,bool,Hash>& mConstraints;
const CGAL::Unique_hash_map<key_type,bool>& mConstraints;
};
bool is_border (edge_descriptor e, const Surface_mesh& sm)
@ -77,7 +63,7 @@ Point_3 point(vertex_descriptor vd, const Surface_mesh& sm)
int main( int argc, char** argv )
{
CGAL::Unique_hash_map<edge_descriptor,bool,Hash> constraint_hmap(false);
CGAL::Unique_hash_map<edge_descriptor,bool> constraint_hmap(false);
Surface_mesh surface_mesh;

View File

@ -29,7 +29,7 @@ namespace SMS = CGAL::Surface_mesh_simplification ;
// BGL property map which indicates whether an edge is marked as non-removable
//
struct Border_is_constrained_edge_map{
const Surface_mesh* sm;
const Surface_mesh* sm_ptr;
typedef boost::graph_traits<Surface_mesh>::edge_descriptor key_type;
typedef bool value_type;
typedef value_type reference;
@ -39,12 +39,11 @@ struct Border_is_constrained_edge_map{
{}
Border_is_constrained_edge_map(const Surface_mesh& sm)
: sm(&sm)
: sm_ptr(&sm)
{}
friend bool get(Border_is_constrained_edge_map m, key_type edge) {
return (face(halfedge(edge,*m.sm),*m.sm) == boost::graph_traits<Surface_mesh>::null_face())
|| (face(opposite(halfedge(edge,*m.sm),*m.sm),*m.sm) == boost::graph_traits<Surface_mesh>::null_face());
friend bool get(Border_is_constrained_edge_map m, const key_type& edge) {
return CGAL::is_border(edge, *m.sm_ptr);
}
};