Merge remote-tracking branch 'cgal/releases/CGAL-5.0-branch'

This commit is contained in:
Sébastien Loriot 2020-04-16 16:29:55 +02:00
commit a8f9858099
18 changed files with 323 additions and 208 deletions

View File

@ -35,17 +35,17 @@ int main(int argc, char* argv[])
std::ifstream in((argc>1)?argv[1]:"cube.off"); std::ifstream in((argc>1)?argv[1]:"cube.off");
in >> S; in >> S;
assert( CGAL::is_valid_polygon_mesh(S) );
// Note that the vertex_point property of the Source and Target1 // Note that the vertex_point property of the Source and Target1
// come from different kernels. // come from different kernels.
typedef CGAL::Surface_mesh<Point> Target1; typedef CGAL::Surface_mesh<Point> Target1;
Target1 T1; Target1 T1;
{
CGAL::copy_face_graph(S, T1); CGAL::copy_face_graph(S, T1);
std::ofstream out("sm.off"); assert( CGAL::is_valid_polygon_mesh(T1) );
out.precision(17); assert( vertices(S).size()==vertices(T1).size() );
out << T1; assert( halfedges(S).size()==halfedges(T1).size() );
} assert( faces(S).size()==faces(T1).size() );
#if defined(CGAL_USE_OPENMESH) #if defined(CGAL_USE_OPENMESH)
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Target2; typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Target2;
@ -63,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())) 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())) .halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
.face_to_face_output_iterator(std::inserter(f2f, f2f.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 #endif
S.clear(); S.clear();
@ -80,13 +86,14 @@ int main(int argc, char* argv[])
boost::unordered_map<source_vertex_descriptor, tm_vertex_descriptor> v2v; boost::unordered_map<source_vertex_descriptor, tm_vertex_descriptor> v2v;
boost::unordered_map<source_halfedge_descriptor, tm_halfedge_descriptor> h2h; boost::unordered_map<source_halfedge_descriptor, tm_halfedge_descriptor> h2h;
boost::unordered_map<source_face_descriptor, tm_face_descriptor> f2f; 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.precision(17);
out << S;
CGAL::copy_face_graph(T1, S, CGAL::parameters::vertex_to_vertex_map(boost::make_assoc_property_map(v2v)) 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())) .halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
.face_to_face_map(boost::make_assoc_property_map(f2f))); .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; 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 } //end of namespace internal
template <typename P, typename Property> template <typename P>
struct property_map<CGAL::Dual<P>, Property> struct property_map<CGAL::Dual<P>, halfedge_index_t>
: internal::Dual_property_maps<P, Property> {}; : 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> template <typename P>
struct property_map<CGAL::Dual<P>, boost::vertex_index_t> 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 { namespace CGAL {
template <typename P, typename Property> #define CGAL_GET_OVERLOADS(Property) \
typename boost::property_map<P, Property>::type \
get(Property p, Dual<P>& dual) template <typename P> \
{ typename boost::property_map<P, Property>::type \
return get(p, dual.primal()); 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> CGAL_GET_OVERLOADS(boost::edge_index_t)
typename boost::property_map<P, Property>::const_type CGAL_GET_OVERLOADS(boost::halfedge_index_t)
get(Property p, const Dual<P>& dual) CGAL_GET_OVERLOADS(boost::vertex_point_t)
{
return get(p, dual.primal());
}
template <typename P, typename Property, typename Key > #undef CGAL_GET_OVERLOADS
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;
};
template <typename P, typename Key> 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) 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); return get(typename boost::internal::Dual_vertex_index_pmap<P>(dual.primal()), k);
} }
template <typename P, typename Key> 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) 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); 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> template <typename P>
typename boost::internal::Dual_vertex_index_pmap<P> typename boost::internal::Dual_vertex_index_pmap<P>
get(boost::vertex_index_t, const Dual<P>& dual) get(boost::vertex_index_t, const Dual<P>& dual)

View File

@ -1048,6 +1048,36 @@ get(PropertyTag ptag, Face_filtered_graph<Graph, FIMap, VIMap, HIMap>& w)
return get(ptag, w.graph()); 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 //specializations for indices
template <class Graph, template <class Graph,
typename FIMap, typename FIMap,

View File

@ -32,17 +32,15 @@ namespace CGAL {
namespace internal { namespace internal {
template <typename SourceMesh, typename TargetMesh, template <typename SourceMesh, typename TargetMesh,
typename Hmap,
typename V2V, typename H2H, typename F2F, typename V2V, typename H2H, typename F2F,
typename Src_vpm, typename Tgt_vpm> typename Src_vpm, typename Tgt_vpm>
void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm, void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
Hmap hmap,
V2V v2v, H2H h2h, F2F f2f, V2V v2v, H2H h2h, F2F f2f,
Src_vpm sm_vpm, Tgt_vpm tm_vpm ) Src_vpm sm_vpm, Tgt_vpm tm_vpm )
{ {
typedef typename boost::graph_traits<SourceMesh>::vertex_descriptor sm_vertex_descriptor; 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_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<SourceMesh>::face_descriptor sm_face_descriptor;
typedef typename boost::graph_traits<TargetMesh>::face_descriptor tm_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 > typename Kernel_traits<typename boost::property_traits<Tgt_vpm>::value_type>::type >
conv; 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<tm_halfedge_descriptor> tm_border_halfedges;
std::vector<sm_halfedge_descriptor> sm_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()), 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()), 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, tm_h, tm );
set_next( tm_h_opp, tm_h_opp, tm ); set_next( tm_h_opp, tm_h_opp, tm );
put(hmap, sm_h, tm_h); put(hs_to_ht, sm_h, tm_h);
put(hmap, sm_h_opp, tm_h_opp); put(hs_to_ht, sm_h_opp, tm_h_opp);
*h2h++=std::make_pair(sm_h, tm_h); *h2h++=std::make_pair(sm_h, tm_h);
*h2h++=std::make_pair(sm_h_opp, tm_h_opp); *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); set_target(tm_h, tm_h_tgt, tm);
put(tm_vpm, tm_h_tgt, conv(get(sm_vpm, sm_h_tgt))); 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 ) if ( halfedge(sm_h_src,sm)==sm_h_opp )
{ {
tm_vertex_descriptor tm_h_src = add_vertex(tm); 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); set_target(tm_h_opp, tm_h_src, tm);
put(tm_vpm, tm_h_src, conv(get(sm_vpm, sm_h_src))); 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 //create faces and connect halfedges
for(sm_face_descriptor sm_f : faces(sm)) 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); *f2f++=std::make_pair(sm_f, tm_f);
sm_halfedge_descriptor sm_h_i=halfedge(sm_f, sm); 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); set_halfedge(tm_f, tm_h_prev, tm);
CGAL_precondition(*halfedges_around_face(sm_h_i, sm).first == sm_h_i); 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)) 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_next(tm_h_prev, tm_h, tm);
set_face(tm_h, tm_f, tm); set_face(tm_h, tm_f, tm);
tm_h_prev=tm_h; 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)) halfedges_around_face(next(sm_border_halfedges[i], sm), sm))
{ {
CGAL_assertion(next(tm_h_prev, tm) == tm_h_prev); 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); set_next(tm_h_prev, tm_h, tm);
tm_h_prev=tm_h; tm_h_prev=tm_h;
} }
} }
// update halfedge vertex of all but the vertex halfedge // update halfedge vertex of all but the vertex halfedge
for(tm_vertex_iterator vit = vertices(tm).first; for(tm_vertex_descriptor v : vertices(tm))
vit != vertices(tm).second; ++vit)
{ {
tm_vertex_descriptor v = *vit;
tm_halfedge_descriptor h = halfedge(v, tm); tm_halfedge_descriptor h = halfedge(v, tm);
tm_halfedge_descriptor next_around_vertex=h; tm_halfedge_descriptor next_around_vertex=h;
do{ do{
@ -167,47 +171,36 @@ void copy_face_graph_impl(const SourceMesh& sm, TargetMesh& tm,
set_target(next_around_vertex, v, tm); set_target(next_around_vertex, v, tm);
}while(h != next_around_vertex); }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));
copy_face_graph_impl(sm, tm,
bind_property_maps(get_initialized_halfedge_index_map(sm),
make_property_map(hedges)),
v2v, h2h, f2f,
sm_vpm, tm_vpm);
}
} // end of namespace internal } // end of namespace internal
namespace impl namespace impl
{ {
@ -329,8 +322,7 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
using parameters::choose_parameter; using parameters::choose_parameter;
using parameters::get_parameter; using parameters::get_parameter;
internal::copy_face_graph(sm, tm, internal::copy_face_graph_impl(sm, tm,
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
choose_parameter(get_parameter(np1, internal_np::vertex_to_vertex_output_iterator), choose_parameter(get_parameter(np1, internal_np::vertex_to_vertex_output_iterator),
impl::make_functor(get_parameter(np1, internal_np::vertex_to_vertex_map))), impl::make_functor(get_parameter(np1, internal_np::vertex_to_vertex_map))),
choose_parameter(get_parameter(np1, internal_np::halfedge_to_halfedge_output_iterator), choose_parameter(get_parameter(np1, internal_np::halfedge_to_halfedge_output_iterator),
@ -357,7 +349,7 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
copy_face_graph(sm, tm, np, parameters::all_default()); 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, template <typename SourceMesh, typename TargetMesh,
typename V2V, typename H2H, typename F2F, typename V2V, typename H2H, typename F2F,
typename Src_vpm, typename Tgt_vpm> typename Src_vpm, typename Tgt_vpm>
@ -365,8 +357,7 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
V2V v2v, H2H h2h, F2F f2f, V2V v2v, H2H h2h, F2F f2f,
Src_vpm sm_vpm, Tgt_vpm tm_vpm ) Src_vpm sm_vpm, Tgt_vpm tm_vpm )
{ {
internal::copy_face_graph(sm, tm, internal::copy_face_graph_impl(sm, tm,
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
v2v, h2h, f2f, v2v, h2h, f2f,
sm_vpm, tm_vpm); sm_vpm, tm_vpm);
} }

View File

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

View File

@ -2,8 +2,38 @@
#include "test_Prefix.h" #include "test_Prefix.h"
#include <boost/range/distance.hpp> #include <boost/range/distance.hpp>
#include <CGAL/boost/graph/Euler_operations.h> #include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/IO/OFF_reader.h> #include <CGAL/IO/OFF_reader.h>
#include <CGAL/Polygon_mesh_processing/border.h> #include <CGAL/Polygon_mesh_processing/border.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> template <typename T>
void void
@ -588,6 +618,7 @@ template <typename Graph>
void void
test_Euler_operations() test_Euler_operations()
{ {
test_copy_face_graph_nm_umbrella<Graph>();
join_face_test<Graph>(); join_face_test<Graph>();
add_vertex_and_face_to_border_test<Graph>(); add_vertex_and_face_to_border_test<Graph>();
add_face_to_border_test<Graph>(); add_face_to_border_test<Graph>();

View File

@ -14,34 +14,34 @@ to do whatever they want with the software. Using the software means to accept
the license, which has the status of a contract between the user and the owner the license, which has the status of a contract between the user and the owner
of the \cgal software. of the \cgal software.
\section licensesGPL GPL \section licensesGPL GNU GPL
The \sc{Gpl} is an Open Source license that, if you distribute your software The GNU GPL is an Open Source license that, if you distribute your software
based on \sc{Gpl}ed \cgal data structures, obliges you to distribute the based on GPLed \cgal data structures, obliges you to distribute the
source code of your software under the \sc{Gpl}. source code of your software under the GPL.
The exact license terms can be found at the Free Software Foundation The exact license terms can be found at the Free Software Foundation
web site: http://www.gnu.org/copyleft/gpl.html. web site: http://www.gnu.org/copyleft/gpl.html.
\section licensesLGPL LGPL \section licensesLGPL GNU LGPL
The \sc{Lgpl} is an Open Source license that obliges you to distribute The GNU LGPL is an Open Source license that obliges you to distribute
modifications you make on \cgal software accessible to the users. modifications you make on \cgal software accessible to the users.
In contrast to the \sc{Gpl}, there is no obligation to make the source In contrast to the GPL, there is no obligation to make the source
code of software you build on top of \sc{Lgpl}ed \cgal data structures. code of software you build on top of LGPLed \cgal data structures.
The exact license terms can be found at the Free Software Foundation web site: The exact license terms can be found at the Free Software Foundation web site:
http://www.gnu.org/copyleft/lesser.html. http://www.gnu.org/copyleft/lesser.html.
\section licensesRationale Rationale of the License Choice \section licensesRationale Rationale of the License Choice
We have chosen the \sc{Gpl} and the \sc{Lgpl} as they are well-known We have chosen the GPL and the LGPL as they are well-known
and well-understood open source licenses. The former restricts and well-understood open source licenses. The former restricts
commercial use, and the latter allows to promote software as de facto standard commercial use, and the latter allows to promote software as de facto standard
so that people can build new higher level data structures on top. so that people can build new higher level data structures on top.
Therefore, the packages forming a foundation layer are distributed under Therefore, the packages forming a foundation layer are distributed under
the \sc{Lgpl}, and the higher level packages under the \sc{Gpl}. the LGPL, and the higher level packages under the GPL.
The package overview states for each package under which license it is distributed. The package overview states for each package under which license it is distributed.
\section licensesCommercial Commercial Licenses \section licensesCommercial Commercial Licenses
@ -57,7 +57,7 @@ as well as in evolutive maintenance.
Users who have a commercial license for specific packages can check that Users who have a commercial license for specific packages can check that
they do not accidentally use packages for which they do not have a commercial they do not accidentally use packages for which they do not have a commercial
license. The same holds for users who want to be sure that they only license. The same holds for users who want to be sure that they only
use packages of \cgal released under the \sc{Lgpl}. use packages of \cgal released under the LGPL.
To enable checking, users have to define one of the following macros: To enable checking, users have to define one of the following macros:

View File

@ -355,7 +355,7 @@ removes some unneeded files, and performs minor repair on some glitches.''')
class_and_struct_files=list(package_glob('./*/class*.html')) class_and_struct_files=list(package_glob('./*/class*.html'))
class_and_struct_files.extend(package_glob('./*/struct*.html')) class_and_struct_files.extend(package_glob('./*/struct*.html'))
for fn in class_and_struct_files: for fn in class_and_struct_files:
re_replace_first_in_file(r'<p>Inherits\s*(.*)</p>', r'<a name="details" id="details"></a><h2 class="groupheader">Inherits from</h2><p>\1</p>', fn) re_replace_first_in_file(r'<p>Inherits\s*(.*)</p>', r'<h2 class="groupheader">Inherits from</h2><p>\1</p>', fn)
# remove class name in Definition section if there is no default template # remove class name in Definition section if there is no default template
# parameter documented # parameter documented

View File

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

View File

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

View File

@ -17,6 +17,7 @@
#include <CGAL/boost/graph/properties.h> #include <CGAL/boost/graph/properties.h>
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h> #include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/Unique_hash_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, \ #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 } // 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_ARGS
#undef CGAL_LCC_TYPE #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_vertex_descriptor, output_vertex_descriptor> > bottom_v2v;
std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > bottom_h2h; std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > bottom_h2h;
copy_face_graph(input, output, std::back_inserter(bottom_v2v), copy_face_graph(input, output, parameters::vertex_point_map(input_vpm)
std::back_inserter(bottom_h2h), Emptyset_iterator(), .vertex_to_vertex_output_iterator(std::back_inserter(bottom_v2v))
input_vpm, output_vpm); .halfedge_to_halfedge_output_iterator(std::back_inserter(bottom_h2h)),
parameters::vertex_point_map(output_vpm));
// create the offset for the other side // create the offset for the other side
for(std::size_t i = 0; i< bottom_v2v.size(); ++i) 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 // 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_vertex_descriptor, output_vertex_descriptor> > top_v2v;
std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > top_h2h; std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > top_h2h;
copy_face_graph(input, output, std::inserter(top_v2v, top_v2v.end()), copy_face_graph(input, output, parameters::vertex_point_map(input_vpm)
std::inserter(top_h2h, top_h2h.end()), Emptyset_iterator(), .vertex_to_vertex_output_iterator(std::inserter(top_v2v, top_v2v.end()))
input_vpm, output_vpm); .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) for(std::size_t i = 0; i< top_v2v.size(); ++i)
{ {
top(top_v2v[i].first, top_v2v[i].second); 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 // copy dual to a sm
Surface_mesh sm_dual; Surface_mesh sm_dual;
CGAL::copy_face_graph(dual, sm_dual, CGAL::copy_face_graph(dual, sm_dual,
CGAL::Emptyset_iterator(), CGAL::parameters::vertex_point_map(
CGAL::Emptyset_iterator(), Dual_vpm<Surface_mesh, Point, Pmap>(mesh, vpmap)));
CGAL::Emptyset_iterator(),
Dual_vpm<Surface_mesh, Point, Pmap>(mesh, vpmap));
for(typename boost::graph_traits<Surface_mesh>::face_descriptor fit : faces(sm_dual)) for(typename boost::graph_traits<Surface_mesh>::face_descriptor fit : faces(sm_dual))
{ {

View File

@ -1574,7 +1574,7 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
} }
else if(action->text() == QString("Line Width")) else if(action->text() == QString("Line Width"))
{ {
menu_actions["line width"] = action->menu()->actions().last(); menu_actions["Line width"] = action->menu()->actions().last();
} }
} }
@ -1719,7 +1719,7 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
slider->setValue( slider->setValue(
qobject_cast<QSlider*>( qobject_cast<QSlider*>(
qobject_cast<QWidgetAction*> qobject_cast<QWidgetAction*>
(menu_actions["line width"])->defaultWidget() (menu_actions["Line width"])->defaultWidget()
)->value()); )->value());
slider->setOrientation(Qt::Horizontal); slider->setOrientation(Qt::Horizontal);
sliderAction->setDefaultWidget(slider); sliderAction->setDefaultWidget(slider);

View File

@ -27,12 +27,7 @@
#include <CGAL/Segment_Delaunay_graph_2/Filtered_traits_concept_check_tags.h> #include <CGAL/Segment_Delaunay_graph_2/Filtered_traits_concept_check_tags.h>
// includes for the default parameters of the filtered traits // includes for the default parameters of the filtered traits
#ifdef CGAL_USE_GMP #include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/Gmpq.h>
#else
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#endif
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include <CGAL/Interval_arithmetic.h> #include <CGAL/Interval_arithmetic.h>
@ -56,11 +51,7 @@ namespace CGAL {
// this traits class does support intersecting segments // this traits class does support intersecting segments
template<class CK, template<class CK,
class CK_MTag = Field_with_sqrt_tag, class CK_MTag = Field_with_sqrt_tag,
#ifdef CGAL_USE_GMP class EK = Simple_cartesian< internal::Exact_field_selector<double>::Type >,
class EK = Simple_cartesian< Gmpq >,
#else
class EK = Simple_cartesian< Quotient<MP_Float> >,
#endif
class EK_MTag = Field_tag, class EK_MTag = Field_tag,
class FK = Simple_cartesian< Interval_nt<false> >, class FK = Simple_cartesian< Interval_nt<false> >,
class FK_MTag = Field_with_sqrt_tag, class FK_MTag = Field_with_sqrt_tag,

View File

@ -24,12 +24,8 @@
#include <CGAL/Segment_Delaunay_graph_2/Filtered_traits_concept_check_tags.h> #include <CGAL/Segment_Delaunay_graph_2/Filtered_traits_concept_check_tags.h>
// includes for the default parameters of the filtered traits // includes for the default parameters of the filtered traits
#ifdef CGAL_USE_GMP #include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/Gmpq.h>
#else
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#endif
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include <CGAL/Interval_arithmetic.h> #include <CGAL/Interval_arithmetic.h>
@ -53,11 +49,7 @@ namespace CGAL {
// this traits class does support intersecting segments // this traits class does support intersecting segments
template<class CK, template<class CK,
class CK_MTag = Field_with_sqrt_tag, class CK_MTag = Field_with_sqrt_tag,
#ifdef CGAL_USE_GMP class EK = Simple_cartesian< internal::Exact_field_selector<double>::Type >,
class EK = Simple_cartesian< Gmpq >,
#else
class EK = Simple_cartesian< Quotient<MP_Float> >,
#endif
class EK_MTag = Field_tag, class EK_MTag = Field_tag,
class FK = Simple_cartesian< Interval_nt<false> >, class FK = Simple_cartesian< Interval_nt<false> >,
class FK_MTag = Field_with_sqrt_tag, class FK_MTag = Field_with_sqrt_tag,

View File

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

View File

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