Merge pull request #4579 from sloriot/BGL-copy_face_graph_nm_vertices

Handle non-manifold vertices in copy_face_graph
This commit is contained in:
Sebastien Loriot 2020-04-16 16:23:02 +02:00 committed by GitHub
commit fb7d41a008
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 316 additions and 185 deletions

View File

@ -35,16 +35,17 @@ int main(int argc, char* argv[])
std::ifstream in((argc>1)?argv[1]:"cube.off");
in >> S;
assert( CGAL::is_valid_polygon_mesh(S) );
// Note that the vertex_point property of the Source and Target1
// come from different kernels.
typedef CGAL::Surface_mesh<Point> Target1;
Target1 T1;
{
CGAL::copy_face_graph(S, T1);
std::ofstream out("sm.off");
out << T1;
}
CGAL::copy_face_graph(S, T1);
assert( CGAL::is_valid_polygon_mesh(T1) );
assert( vertices(S).size()==vertices(T1).size() );
assert( halfedges(S).size()==halfedges(T1).size() );
assert( faces(S).size()==faces(T1).size() );
#if defined(CGAL_USE_OPENMESH)
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Target2;
@ -62,7 +63,13 @@ int main(int argc, char* argv[])
CGAL::copy_face_graph(S, T2, CGAL::parameters::vertex_to_vertex_output_iterator(std::inserter(v2v, v2v.end()))
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
.face_to_face_output_iterator(std::inserter(f2f, f2f.end())));
OpenMesh::IO::write_mesh(T2, "om.off");
assert( CGAL::is_valid_polygon_mesh(T2) );
assert( v2v.size()==vertices(T2).size() );
assert( h2h.size()==halfedges(T2).size() );
assert( f2f.size()==faces(T2).size() );
assert( vertices(S).size()==vertices(T2).size() );
assert( halfedges(S).size()==halfedges(T2).size() );
assert( faces(S).size()==faces(T2).size() );
}
#endif
S.clear();
@ -79,12 +86,14 @@ int main(int argc, char* argv[])
boost::unordered_map<source_vertex_descriptor, tm_vertex_descriptor> v2v;
boost::unordered_map<source_halfedge_descriptor, tm_halfedge_descriptor> h2h;
boost::unordered_map<source_face_descriptor, tm_face_descriptor> f2f;
CGAL::copy_face_graph(T1, S, std::inserter(v2v, v2v.end()), std::inserter(h2h, h2h.end()));
std::ofstream out("reverse.off");
out << S;
CGAL::copy_face_graph(T1, S, CGAL::parameters::vertex_to_vertex_map(boost::make_assoc_property_map(v2v))
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
.face_to_face_map(boost::make_assoc_property_map(f2f)));
assert( CGAL::is_valid_polygon_mesh(S) );
assert( vertices(S).size()==vertices(T1).size() );
assert( halfedges(S).size()==halfedges(T1).size() );
assert( faces(S).size()==faces(T1).size() );
}
return 0;
}

View File

@ -158,19 +158,15 @@ struct Dual_face_index_pmap{
}
};
template<typename P, typename Property,
bool is_edge = boost::is_same<boost::edge_property_tag,
typename boost::property_kind<Property>::type>::value>
struct Dual_property_maps : boost::property_map<P, Property> {};
template< typename P, typename Property>
struct Dual_property_maps<P, Property, false> {};
} //end of namespace internal
template <typename P, typename Property>
struct property_map<CGAL::Dual<P>, Property>
: internal::Dual_property_maps<P, Property> {};
template <typename P>
struct property_map<CGAL::Dual<P>, halfedge_index_t>
: boost::property_map<P, halfedge_index_t> {};
template <typename P>
struct property_map<CGAL::Dual<P>, edge_index_t>
: boost::property_map<P, edge_index_t> {};
template <typename P>
struct property_map<CGAL::Dual<P>, boost::vertex_index_t>
@ -190,53 +186,49 @@ struct property_map<CGAL::Dual<P>, boost::face_index_t>
namespace CGAL {
template <typename P, typename Property>
typename boost::property_map<P, Property>::type
get(Property p, Dual<P>& dual)
{
return get(p, dual.primal());
#define CGAL_GET_OVERLOADS(Property) \
\
template <typename P> \
typename boost::property_map<P, Property>::type \
get(Property p, Dual<P>& dual) \
{ \
return get(p, dual.primal()); \
} \
\
template <typename P> \
typename boost::property_map<P, Property>::const_type \
get(Property p, const Dual<P>& dual) \
{ \
return get(p, dual.primal()); \
} \
\
template <typename P, typename Key > \
typename boost::property_map_value<P, Property>::type \
get(Property p, const Dual<P>& dual, const Key& k) \
{ \
return get(p, dual.primal(), k); \
}
template <typename P, typename Property>
typename boost::property_map<P, Property>::const_type
get(Property p, const Dual<P>& dual)
{
return get(p, dual.primal());
}
CGAL_GET_OVERLOADS(boost::edge_index_t)
CGAL_GET_OVERLOADS(boost::halfedge_index_t)
CGAL_GET_OVERLOADS(boost::vertex_point_t)
template <typename P, typename Property, typename Key >
typename boost::property_map_value<P, Property>::type
get(Property p, const Dual<P>& dual, const Key& k)
{
return get(p, dual.primal(), k);
}
template<typename G, typename P, typename>
struct Property_map_value_dummy {
typedef typename boost::property_map_value<G, P>::type type;
};
#undef CGAL_GET_OVERLOADS
template <typename P, typename Key>
typename Property_map_value_dummy<Dual<P>, boost::vertex_index_t, Key>::type
typename boost::property_map_value<Dual<P>, boost::vertex_index_t>::type
get(boost::vertex_index_t, const Dual<P>& dual, const Key& k)
{
return get(typename boost::internal::Dual_vertex_index_pmap<P>(dual.primal()), k);
}
template <typename P, typename Key>
typename Property_map_value_dummy<Dual<P>, boost::face_index_t, Key>::type
typename boost::property_map_value<Dual<P>, boost::face_index_t>::type
get(boost::face_index_t, const Dual<P>& dual, const Key& k)
{
return get(typename boost::internal::Dual_face_index_pmap<P>(dual.primal()), k);
}
template <typename P, typename Property, typename Key, typename Value>
void
put(Property p, const Dual<P>& dual, const Key& k, const Value& val)
{
put(p, dual.primal(), k, val);
}
template <typename P>
typename boost::internal::Dual_vertex_index_pmap<P>
get(boost::vertex_index_t, const Dual<P>& dual)

View File

@ -1043,6 +1043,36 @@ get(PropertyTag ptag, Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
return get(ptag, w.graph());
}
#define CGAL_FFG_DYNAMIC_PMAP_SPEC(TAG) \
template <class Graph, \
typename FIMap, \
typename VIMap, \
typename HIMap, \
class T> \
typename boost::property_map<Graph, TAG<T> >::const_type \
get(TAG<T> ptag, const Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w) \
{ \
return get(ptag, w.graph()); \
} \
\
template <class Graph, \
typename FIMap, \
typename VIMap, \
typename HIMap, \
class T> \
typename boost::property_map<Graph, TAG<T> >::type \
get(TAG<T> ptag, Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w) \
{ \
return get(ptag, w.graph()); \
}
CGAL_FFG_DYNAMIC_PMAP_SPEC(dynamic_vertex_property_t)
CGAL_FFG_DYNAMIC_PMAP_SPEC(dynamic_halfedge_property_t)
CGAL_FFG_DYNAMIC_PMAP_SPEC(dynamic_edge_property_t)
CGAL_FFG_DYNAMIC_PMAP_SPEC(dynamic_face_property_t)
#undef CGAL_FFG_DYNAMIC_PMAP_SPEC
//specializations for indices
template <class Graph,
typename FIMap,

View File

@ -32,17 +32,15 @@ namespace CGAL {
namespace internal {
template <typename SourceMesh, typename TargetMesh,
typename Hmap,
typename V2V, typename H2H, typename F2F,
typename Src_vpm, typename Tgt_vpm>
void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
Hmap hmap,
V2V v2v, H2H h2h, F2F f2f,
Src_vpm sm_vpm, Tgt_vpm tm_vpm )
{
typedef typename boost::graph_traits<SourceMesh>::vertex_descriptor sm_vertex_descriptor;
typedef typename boost::graph_traits<TargetMesh>::vertex_descriptor tm_vertex_descriptor;
typedef typename boost::graph_traits<TargetMesh>::vertex_iterator tm_vertex_iterator;
typedef typename boost::graph_traits<TargetMesh>::halfedge_iterator tm_halfedge_iterator;
typedef typename boost::graph_traits<SourceMesh>::face_descriptor sm_face_descriptor;
typedef typename boost::graph_traits<TargetMesh>::face_descriptor tm_face_descriptor;
@ -57,10 +55,14 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
typename Kernel_traits<typename boost::property_traits<Tgt_vpm>::value_type>::type >
conv;
typedef CGAL::dynamic_halfedge_property_t<tm_halfedge_descriptor> Dyn_h_tag;
typename boost::property_map<SourceMesh, Dyn_h_tag >::const_type hs_to_ht = get(Dyn_h_tag(), sm);
std::vector<tm_halfedge_descriptor> tm_border_halfedges;
std::vector<sm_halfedge_descriptor> sm_border_halfedges;
tm_face_descriptor tm_null_face = boost::graph_traits<TargetMesh>::null_face();
const tm_face_descriptor tm_null_face = boost::graph_traits<TargetMesh>::null_face();
const tm_vertex_descriptor tm_null_vertex = boost::graph_traits<TargetMesh>::null_vertex();
reserve(tm, static_cast<typename boost::graph_traits<TargetMesh>::vertices_size_type>(vertices(sm).size()),
static_cast<typename boost::graph_traits<TargetMesh>::edges_size_type>(edges(sm).size()),
@ -77,8 +79,8 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
set_next( tm_h, tm_h, tm );
set_next( tm_h_opp, tm_h_opp, tm );
put(hmap, sm_h, tm_h);
put(hmap, sm_h_opp, tm_h_opp);
put(hs_to_ht, sm_h, tm_h);
put(hs_to_ht, sm_h_opp, tm_h_opp);
*h2h++=std::make_pair(sm_h, tm_h);
*h2h++=std::make_pair(sm_h_opp, tm_h_opp);
@ -106,6 +108,8 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
set_target(tm_h, tm_h_tgt, tm);
put(tm_vpm, tm_h_tgt, conv(get(sm_vpm, sm_h_tgt)));
}
else
set_target(tm_h, tm_null_vertex, tm);
if ( halfedge(sm_h_src,sm)==sm_h_opp )
{
tm_vertex_descriptor tm_h_src = add_vertex(tm);
@ -114,6 +118,8 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
set_target(tm_h_opp, tm_h_src, tm);
put(tm_vpm, tm_h_src, conv(get(sm_vpm, sm_h_src)));
}
else
set_target(tm_h_opp, tm_null_vertex, tm);
}
//create faces and connect halfedges
for(sm_face_descriptor sm_f : faces(sm))
@ -122,13 +128,13 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
*f2f++=std::make_pair(sm_f, tm_f);
sm_halfedge_descriptor sm_h_i=halfedge(sm_f, sm);
tm_halfedge_descriptor tm_h_prev = get(hmap, prev(sm_h_i, sm));
tm_halfedge_descriptor tm_h_prev = get(hs_to_ht, prev(sm_h_i, sm));
set_halfedge(tm_f, tm_h_prev, tm);
CGAL_precondition(*halfedges_around_face(sm_h_i, sm).first == sm_h_i);
for(sm_halfedge_descriptor sm_h : halfedges_around_face(sm_h_i, sm))
{
tm_halfedge_descriptor tm_h = get(hmap, sm_h);
tm_halfedge_descriptor tm_h = get(hs_to_ht, sm_h);
set_next(tm_h_prev, tm_h, tm);
set_face(tm_h, tm_f, tm);
tm_h_prev=tm_h;
@ -150,16 +156,14 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
halfedges_around_face(next(sm_border_halfedges[i], sm), sm))
{
CGAL_assertion(next(tm_h_prev, tm) == tm_h_prev);
tm_h = get(hmap, sm_h);
tm_h = get(hs_to_ht, sm_h);
set_next(tm_h_prev, tm_h, tm);
tm_h_prev=tm_h;
}
}
// update halfedge vertex of all but the vertex halfedge
for(tm_vertex_iterator vit = vertices(tm).first;
vit != vertices(tm).second; ++vit)
for(tm_vertex_descriptor v : vertices(tm))
{
tm_vertex_descriptor v = *vit;
tm_halfedge_descriptor h = halfedge(v, tm);
tm_halfedge_descriptor next_around_vertex=h;
do{
@ -167,52 +171,36 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
set_target(next_around_vertex, v, tm);
}while(h != next_around_vertex);
}
// detect if there are some non-manifold umbrellas and fix missing halfedge target pointers
for (tm_halfedge_iterator it=halfedges(tm).first; it!=halfedges(tm).second; ++it)
{
if (target(*it, tm) == tm_null_vertex)
{
// create and fill a map from target halfedge to source halfedge
typedef CGAL::dynamic_halfedge_property_t<sm_halfedge_descriptor> Dyn_th_tag;
typename boost::property_map<TargetMesh, Dyn_th_tag >::type ht_to_hs = get(Dyn_th_tag(), tm);
for (sm_halfedge_descriptor hs : halfedges(sm))
put(ht_to_hs, get(hs_to_ht, hs), hs);
for(; it!=halfedges(tm).second; ++it)
{
if (target(*it, tm) == tm_null_vertex)
{
// we recover tm_v using the halfedge associated to the target vertex of
// the halfedge in sm corresponding to *it. This is working because we
// set the vertex halfedge pointer to the "same" halfedges.
tm_vertex_descriptor tm_v =
target( get(hs_to_ht, halfedge(target(get(ht_to_hs, *it), sm), sm)), tm);
for(tm_halfedge_descriptor ht : halfedges_around_target(*it, tm))
set_target(ht, tm_v, tm);
}
}
break;
}
}
}
template <typename SourceMesh, typename TargetMesh,
typename V2V, typename H2H, typename F2F,
typename Src_vpm, typename Tgt_vpm>
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
Tag_false,
V2V v2v, H2H h2h, F2F f2f,
Src_vpm sm_vpm, Tgt_vpm tm_vpm )
{
typedef typename boost::graph_traits<SourceMesh>::halfedge_descriptor sm_halfedge_descriptor;
typedef typename boost::graph_traits<TargetMesh>::halfedge_descriptor tm_halfedge_descriptor;
boost::unordered_map<sm_halfedge_descriptor,
tm_halfedge_descriptor> hash_map(num_halfedges(sm));
copy_face_graph_impl(sm, tm,
boost::make_assoc_property_map(hash_map),
v2v, h2h, f2f,
sm_vpm, tm_vpm);
}
template <typename SourceMesh, typename TargetMesh,
typename V2V, typename H2H, typename F2F,
typename Src_vpm, typename Tgt_vpm>
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
Tag_true,
V2V v2v, H2H h2h, F2F f2f,
Src_vpm sm_vpm, Tgt_vpm tm_vpm )
{
typedef typename boost::graph_traits<TargetMesh>::halfedge_descriptor tm_halfedge_descriptor;
std::vector<tm_halfedge_descriptor> hedges(num_halfedges(sm));
// init halfedge index map
/// \TODO shall we keep that?
helpers::init_halfedge_indices(const_cast<SourceMesh&>(sm),
get(boost::halfedge_index, sm));
copy_face_graph_impl(sm, tm,
bind_property_maps(get(boost::halfedge_index, sm),
make_property_map(hedges)),
v2v, h2h, f2f,
sm_vpm, tm_vpm);
}
} // end of namespace internal
namespace impl
{
@ -333,18 +321,20 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
{
using parameters::choose_parameter;
using parameters::get_parameter;
internal::copy_face_graph(sm, tm,
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
choose_parameter(get_parameter(np1, internal_np::vertex_to_vertex_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::vertex_to_vertex_map))),
choose_parameter(get_parameter(np1, internal_np::halfedge_to_halfedge_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::halfedge_to_halfedge_map))),
choose_parameter(get_parameter(np1, internal_np::face_to_face_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::face_to_face_map))),
choose_parameter(get_parameter(np1, internal_np::vertex_point),
get(vertex_point, sm)),
choose_parameter(get_parameter(np2, internal_np::vertex_point),
get(vertex_point, tm)));
internal::copy_face_graph_impl(
sm,
tm,
choose_parameter(get_parameter(np1, internal_np::vertex_to_vertex_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::vertex_to_vertex_map))),
choose_parameter(get_parameter(np1, internal_np::halfedge_to_halfedge_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::halfedge_to_halfedge_map))),
choose_parameter(get_parameter(np1, internal_np::face_to_face_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::face_to_face_map))),
choose_parameter(get_parameter(np1, internal_np::vertex_point),
get(vertex_point, sm)),
choose_parameter(get_parameter(np2, internal_np::vertex_point),
get(vertex_point, tm)));
}
template <typename SourceMesh, typename TargetMesh>
@ -361,7 +351,7 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
copy_face_graph(sm, tm, np, parameters::all_default());
}
#if !defined(DOXYGEN_RUNNING)
#if !defined(DOXYGEN_RUNNING) && !defined(CGAL_NO_DEPRECATED_CODE)
template <typename SourceMesh, typename TargetMesh,
typename V2V, typename H2H, typename F2F,
typename Src_vpm, typename Tgt_vpm>
@ -369,10 +359,9 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
V2V v2v, H2H h2h, F2F f2f,
Src_vpm sm_vpm, Tgt_vpm tm_vpm )
{
internal::copy_face_graph(sm, tm,
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
v2v, h2h, f2f,
sm_vpm, tm_vpm);
internal::copy_face_graph_impl(sm, tm,
v2v, h2h, f2f,
sm_vpm, tm_vpm);
}

View File

@ -37,8 +37,8 @@ void concept_check_dual() {
Graph, face_descriptor, boost::face_index_t> >();
// edge properties should be forwarded
boost::function_requires< boost::concepts::ReadablePropertyGraph<
Graph, edge_descriptor, boost::edge_weight_t> >();
//boost::function_requires< boost::concepts::ReadablePropertyGraph<
// Graph, edge_descriptor, boost::edge_weight_t> >();
// boost::function_requires< boost::concepts::PropertyGraph<
// Graph, halfedge_descriptor, CGAL::halfedge_index_t> >();

View File

@ -2,6 +2,35 @@
#include "test_Prefix.h"
#include <boost/range/distance.hpp>
#include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/boost/graph/copy_face_graph.h>
template <typename T>
void
test_copy_face_graph_nm_umbrella()
{
CGAL_GRAPH_TRAITS_MEMBERS(T);
T g;
Kernel::Point_3 p;
CGAL::make_tetrahedron(p, p, p, p, g);
CGAL::make_tetrahedron(p, p, p, p, g);
std::vector<vertex_descriptor> verts(vertices(g).begin(), vertices(g).end());
//merge verts[0] and verts[4]
for (halfedge_descriptor h : CGAL::halfedges_around_target(verts[4], g))
set_target(h, verts[0], g);
remove_vertex(verts[4], g);
T g_copy;
CGAL::copy_face_graph(g, g_copy);
for (halfedge_descriptor h : halfedges(g_copy))
{
assert( target(h, g_copy) != Traits::null_vertex() );
}
}
template <typename T>
void
@ -444,6 +473,7 @@ template <typename Graph>
void
test_Euler_operations()
{
test_copy_face_graph_nm_umbrella<Graph>();
join_face_test<Graph>();
add_vertex_and_face_to_border_test<Graph>();
add_face_to_border_test<Graph>();

View File

@ -475,25 +475,19 @@ void reserve(HalfedgeDS_default<T,I,A>& p,
}// namespace CGAL
namespace boost {
// property_map dispatcher into Polyhedron
template<class T, class I, class A, class Tag>
struct property_map<CGAL::HalfedgeDS_default<T,I,A>, Tag>
{
typedef typename CGAL::HDS_property_map<Tag>::
template bind_<T,I,A> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
#define CGAL_PM_SPECIALIZATION(TAG) \
template<class T, class I, class A> \
struct property_map<CGAL::HalfedgeDS_default<T,I,A>, TAG> \
{\
typedef typename CGAL::HDS_property_map<TAG>:: \
template bind_<T,I,A> map_gen; \
typedef typename map_gen::type type; \
typedef typename map_gen::const_type const_type; \
};
// property_map dispatcher into const Polyhedron
template<class T, class I, class A, class Tag>
struct property_map<const CGAL::HalfedgeDS_default<T,I,A>, Tag>
{
typedef typename CGAL::HDS_property_map<Tag>::
template bind_<T,I,A> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
CGAL_PM_SPECIALIZATION(vertex_point_t)
#undef CGAL_PM_SPECIALIZATION
} // namespace boost

View File

@ -3333,8 +3333,7 @@ namespace CommonKernelFunctors {
CGAL_kernel_assertion_msg(bool(optional) == true,
"the segment does not intersect the supporting"
" plane");
using boost::get;
const Point_3* p = get<Point_3>(&*optional);
const Point_3* p = boost::get<Point_3>(&*optional);
CGAL_kernel_assertion_msg(p != 0,
"the segment intersection with the plane is "
"not a point");

View File

@ -17,6 +17,7 @@
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Dynamic_property_map.h>
#define CGAL_LCC_ARGS unsigned int d_, unsigned int ambient_dim, \
@ -402,6 +403,76 @@ struct property_map<const CGAL_LCC_TYPE, Tag>
} // namespace boost
// dynamic property map ambiguity resolution
#define CGAL_LCC_DYNAMIC_PMAP_SPEC(TAG, DESC) \
namespace boost { \
template<unsigned int d_, unsigned int ambient_dim, \
class Traits_, \
class Items_, \
class Alloc_, \
template<unsigned int,class,class,class,class> \
class CMap, \
class Storage_,\
class T>\
struct property_map< \
CGAL::Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_>,\
TAG<T> > \
{\
typedef CGAL::Linear_cell_complex_for_combinatorial_map\
<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_> LCC;\
typedef typename boost::graph_traits<LCC>::DESC DESC;\
typedef CGAL::internal::Dynamic_property_map<DESC,T> type;\
typedef type const_type;\
};\
} \
\
namespace CGAL { \
template <unsigned int d_, unsigned int ambient_dim, \
class Traits_, \
class Items_, \
class Alloc_, \
template<unsigned int,class,class,class,class> \
class CMap, \
class Storage_,\
class T> \
typename boost::property_map< \
Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_>, \
TAG<T> >::const_type \
get(TAG<T>, const Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_>&) \
{ \
typedef Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_> LCC;\
typedef typename boost::graph_traits<LCC>::DESC DESC; \
return internal::Dynamic_property_map<DESC,T>();\
} \
\
template <unsigned int d_, unsigned int ambient_dim, \
class Traits_, \
class Items_, \
class Alloc_, \
template<unsigned int,class,class,class,class> \
class CMap, \
class Storage_,\
class T> \
typename boost::property_map< \
Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_>, \
TAG<T> >::type \
get(TAG<T>, Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_>&) \
{ \
typedef Linear_cell_complex_for_combinatorial_map<d_, ambient_dim, Traits_, Items_, Alloc_, CMap , Storage_> LCC;\
typedef typename boost::graph_traits<LCC>::DESC DESC; \
return internal::Dynamic_property_map<DESC,T>();\
} \
}
CGAL_LCC_DYNAMIC_PMAP_SPEC(CGAL::dynamic_vertex_property_t, vertex_descriptor)
CGAL_LCC_DYNAMIC_PMAP_SPEC(CGAL::dynamic_halfedge_property_t, halfedge_descriptor)
CGAL_LCC_DYNAMIC_PMAP_SPEC(CGAL::dynamic_edge_property_t, edge_descriptor)
CGAL_LCC_DYNAMIC_PMAP_SPEC(CGAL::dynamic_face_property_t, face_descriptor)
#undef CGAL_LCC_DYNAMIC_PMAP_SPEC
#undef CGAL_NAME_LCC_ARGS
#undef CGAL_LCC_ARGS
#undef CGAL_LCC_TYPE

View File

@ -184,9 +184,10 @@ void extrude_mesh(const InputMesh& input,
std::vector<std::pair<input_vertex_descriptor, output_vertex_descriptor> > bottom_v2v;
std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > bottom_h2h;
copy_face_graph(input, output, std::back_inserter(bottom_v2v),
std::back_inserter(bottom_h2h), Emptyset_iterator(),
input_vpm, output_vpm);
copy_face_graph(input, output, parameters::vertex_point_map(input_vpm)
.vertex_to_vertex_output_iterator(std::back_inserter(bottom_v2v))
.halfedge_to_halfedge_output_iterator(std::back_inserter(bottom_h2h)),
parameters::vertex_point_map(output_vpm));
// create the offset for the other side
for(std::size_t i = 0; i< bottom_v2v.size(); ++i)
@ -198,9 +199,11 @@ void extrude_mesh(const InputMesh& input,
// collect border halfedges for the creation of the triangle strip
std::vector<std::pair<input_vertex_descriptor, output_vertex_descriptor> > top_v2v;
std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > top_h2h;
copy_face_graph(input, output, std::inserter(top_v2v, top_v2v.end()),
std::inserter(top_h2h, top_h2h.end()), Emptyset_iterator(),
input_vpm, output_vpm);
copy_face_graph(input, output, parameters::vertex_point_map(input_vpm)
.vertex_to_vertex_output_iterator(std::inserter(top_v2v, top_v2v.end()))
.halfedge_to_halfedge_output_iterator(std::inserter(top_h2h, top_h2h.end())),
parameters::vertex_point_map(output_vpm));
for(std::size_t i = 0; i< top_v2v.size(); ++i)
{
top(top_v2v[i].first, top_v2v[i].second);

View File

@ -230,10 +230,8 @@ test_dual_with_various_faces()
// copy dual to a sm
Surface_mesh sm_dual;
CGAL::copy_face_graph(dual, sm_dual,
CGAL::Emptyset_iterator(),
CGAL::Emptyset_iterator(),
CGAL::Emptyset_iterator(),
Dual_vpm<Surface_mesh, Point, Pmap>(mesh, vpmap));
CGAL::parameters::vertex_point_map(
Dual_vpm<Surface_mesh, Point, Pmap>(mesh, vpmap)));
for(typename boost::graph_traits<Surface_mesh>::face_descriptor fit : faces(sm_dual))
{

View File

@ -239,23 +239,31 @@ struct T2_property_map<Tr, boost::face_index_t>
// overloads and specializations in the boost namespace
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
struct property_map<CGAL_2D_TRIANGULATION, Tag>
{
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
#define CGAL_PM_SPECIALIZATION(TAG) \
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS> \
struct property_map<CGAL_2D_TRIANGULATION, TAG> \
{ \
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, TAG> map_gen; \
typedef typename map_gen::type type; \
typedef typename map_gen::const_type const_type; \
}; \
\
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS> \
struct property_map<const CGAL_2D_TRIANGULATION, TAG> \
{ \
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, TAG> map_gen; \
typedef typename map_gen::type type; \
typedef typename map_gen::const_type const_type; \
};
// see struct property_map in Polyehdron for an explanation
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
struct property_map<const CGAL_2D_TRIANGULATION, Tag>
{
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
CGAL_PM_SPECIALIZATION(vertex_point_t)
CGAL_PM_SPECIALIZATION(edge_weight_t)
CGAL_PM_SPECIALIZATION(vertex_index_t)
CGAL_PM_SPECIALIZATION(halfedge_index_t)
CGAL_PM_SPECIALIZATION(edge_index_t)
CGAL_PM_SPECIALIZATION(face_index_t)
#undef CGAL_PM_SPECIALIZATION
} // end namespace boost

View File

@ -284,23 +284,31 @@ get(boost::face_index_t, const Triangulation_data_structure_2<VB,FB>&)
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class VB, class FB, class Tag>
struct property_map<CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
{
typedef typename CGAL::internal::TDS2_property_map<VB, FB, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
#define CGAL_PM_SPECIALIZATION(TAG) \
template <class VB, class FB> \
struct property_map<CGAL::Triangulation_data_structure_2<VB,FB>, TAG> \
{ \
typedef typename CGAL::internal::TDS2_property_map<VB, FB, TAG> map_gen; \
typedef typename map_gen::type type; \
typedef typename map_gen::const_type const_type; \
}; \
\
template <class VB, class FB> \
struct property_map<const CGAL::Triangulation_data_structure_2<VB,FB>, TAG> \
{ \
typedef typename CGAL::internal::TDS2_property_map<VB, FB, TAG> map_gen; \
typedef typename map_gen::type type; \
typedef typename map_gen::const_type const_type; \
};
// see struct property_map in Polyehdron for an explanation
template <class VB, class FB, class Tag>
struct property_map<const CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
{
typedef typename CGAL::internal::TDS2_property_map<VB, FB, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
CGAL_PM_SPECIALIZATION(vertex_point_t)
CGAL_PM_SPECIALIZATION(edge_weight_t)
CGAL_PM_SPECIALIZATION(vertex_index_t)
CGAL_PM_SPECIALIZATION(halfedge_index_t)
CGAL_PM_SPECIALIZATION(edge_index_t)
CGAL_PM_SPECIALIZATION(face_index_t)
#undef CGAL_PM_SPECIALIZATION
} // namespace boost