From b1e2d4bb81e105bc29e2e103c8a1f0f58622ecd2 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Wed, 19 Apr 2017 15:17:50 -0400 Subject: [PATCH] Add examples for BGL LCC --- BGL/examples/BGL_LCC/CMakeLists.txt | 56 +++++++++++ BGL/examples/BGL_LCC/copy_lcc.cpp | 86 +++++++++++++++++ BGL/examples/BGL_LCC/cube.off | 19 ++++ BGL/examples/BGL_LCC/distance.cmd | 1 + BGL/examples/BGL_LCC/distance_lcc.cpp | 52 ++++++++++ BGL/examples/BGL_LCC/incident_vertices.cmd | 1 + .../BGL_LCC/incident_vertices_lcc.cpp | 60 ++++++++++++ BGL/examples/BGL_LCC/kruskal_lcc.cpp | 75 +++++++++++++++ BGL/examples/BGL_LCC/normals.cmd | 1 + BGL/examples/BGL_LCC/normals_lcc.cpp | 96 +++++++++++++++++++ BGL/examples/BGL_LCC/range.cmd | 1 + BGL/examples/BGL_LCC/range_lcc.cpp | 64 +++++++++++++ BGL/examples/BGL_LCC/transform_iterator.cmd | 1 + .../BGL_LCC/transform_iterator_lcc.cpp | 58 +++++++++++ 14 files changed, 571 insertions(+) create mode 100644 BGL/examples/BGL_LCC/CMakeLists.txt create mode 100644 BGL/examples/BGL_LCC/copy_lcc.cpp create mode 100644 BGL/examples/BGL_LCC/cube.off create mode 100644 BGL/examples/BGL_LCC/distance.cmd create mode 100644 BGL/examples/BGL_LCC/distance_lcc.cpp create mode 100644 BGL/examples/BGL_LCC/incident_vertices.cmd create mode 100644 BGL/examples/BGL_LCC/incident_vertices_lcc.cpp create mode 100644 BGL/examples/BGL_LCC/kruskal_lcc.cpp create mode 100644 BGL/examples/BGL_LCC/normals.cmd create mode 100644 BGL/examples/BGL_LCC/normals_lcc.cpp create mode 100644 BGL/examples/BGL_LCC/range.cmd create mode 100644 BGL/examples/BGL_LCC/range_lcc.cpp create mode 100644 BGL/examples/BGL_LCC/transform_iterator.cmd create mode 100644 BGL/examples/BGL_LCC/transform_iterator_lcc.cpp diff --git a/BGL/examples/BGL_LCC/CMakeLists.txt b/BGL/examples/BGL_LCC/CMakeLists.txt new file mode 100644 index 00000000000..2b6ca948fce --- /dev/null +++ b/BGL/examples/BGL_LCC/CMakeLists.txt @@ -0,0 +1,56 @@ +# Created by the script cgal_create_CMakeLists +# This is the CMake script for compiling a set of CGAL applications. + +project( BGL_LCC_Examples ) + + +cmake_minimum_required(VERSION 2.8.11) + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS ) + +if ( NOT CGAL_FOUND ) + + message(STATUS "This project requires the CGAL library, and will not be compiled.") + return() + +endif() + +# include helper file +include( ${CGAL_USE_FILE} ) + + +# Boost and its components +find_package( Boost REQUIRED ) + +if ( NOT Boost_FOUND ) + + message(STATUS "This project requires the Boost library, and will not be compiled.") + + return() + +endif() + +# include for local directory +include_directories( BEFORE ../../include ) + + +# Creating entries for all C++ files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + +create_single_source_cgal_program( "distance_lcc.cpp" ) + +create_single_source_cgal_program( "incident_vertices_lcc.cpp" ) + +create_single_source_cgal_program( "kruskal_lcc.cpp" ) + +create_single_source_cgal_program( "normals_lcc.cpp" ) + +create_single_source_cgal_program( "range_lcc.cpp" ) + +create_single_source_cgal_program( "transform_iterator_lcc.cpp" ) + +create_single_source_cgal_program( "copy_lcc.cpp" ) + diff --git a/BGL/examples/BGL_LCC/copy_lcc.cpp b/BGL/examples/BGL_LCC/copy_lcc.cpp new file mode 100644 index 00000000000..ec36c663545 --- /dev/null +++ b/BGL/examples/BGL_LCC/copy_lcc.cpp @@ -0,0 +1,86 @@ +#include +#include + +#include +#include +#include + +#include +#include + +#if defined(CGAL_USE_OPENMESH) +#include +#include +#include +#endif + +#include + +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef CGAL::Polyhedron_3 Source; +typedef boost::graph_traits::vertex_descriptor sm_vertex_descriptor; +typedef boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; +typedef boost::graph_traits::face_descriptor sm_face_descriptor; + +typedef CGAL::Exact_predicates_exact_constructions_kernel Other_kernel; +typedef Other_kernel::Point_3 Point; + +int main(int argc, char* argv[]) +{ + Source S; + + std::ifstream in((argc>1)?argv[1]:"cube.off"); + in >> S; + + // Note that the vertex_point property of the Source and Target1 + // come from different kernels. + typedef CGAL::Surface_mesh Target1; + Target1 T1; + { + CGAL::copy_face_graph(S, T1); + std::ofstream out("sm.off"); + out << T1; + } + +#if defined(CGAL_USE_OPENMESH) + typedef OpenMesh::PolyMesh_ArrayKernelT Target2; + Target2 T2; + { + typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + typedef boost::graph_traits::face_descriptor tm_face_descriptor; + + // Use an unordered_map to keep track of elements. + boost::unordered_map v2v; + boost::unordered_map h2h; + boost::unordered_map f2f; + + CGAL::copy_face_graph(S, T2, std::inserter(v2v, v2v.end()), + std::inserter(h2h, h2h.end()), + std::inserter(f2f, f2f.end())); + OpenMesh::IO::write_mesh(T2, "om.off"); + } +#endif + S.clear(); + { + typedef boost::graph_traits::vertex_descriptor source_vertex_descriptor; + typedef boost::graph_traits::halfedge_descriptor source_halfedge_descriptor; + + typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + + boost::unordered_map v2v; + boost::unordered_map h2h; + + CGAL::copy_face_graph(T1, S, std::inserter(v2v, v2v.end()), std::inserter(h2h, h2h.end())); + std::ofstream out("reverse.off"); + out << T1; + } + return 0; +} diff --git a/BGL/examples/BGL_LCC/cube.off b/BGL/examples/BGL_LCC/cube.off new file mode 100644 index 00000000000..7476f26cc46 --- /dev/null +++ b/BGL/examples/BGL_LCC/cube.off @@ -0,0 +1,19 @@ +OFF +8 7 0 +# vertices + -1 -1 1 + -1 1 1 + 1 1 1 + 1 -1 1 + -1 -1 -1 + -1 1 -1 + 1 1 -1 + 1 -1 -1 +# facets + 3 3 2 1 + 3 3 1 0 + 4 0 1 5 4 + 4 6 5 1 2 + 4 3 7 6 2 + 4 4 7 3 0 + 4 4 5 6 7 diff --git a/BGL/examples/BGL_LCC/distance.cmd b/BGL/examples/BGL_LCC/distance.cmd new file mode 100644 index 00000000000..5cea844d830 --- /dev/null +++ b/BGL/examples/BGL_LCC/distance.cmd @@ -0,0 +1 @@ +cube.off diff --git a/BGL/examples/BGL_LCC/distance_lcc.cpp b/BGL/examples/BGL_LCC/distance_lcc.cpp new file mode 100644 index 00000000000..7d86b17f94e --- /dev/null +++ b/BGL/examples/BGL_LCC/distance_lcc.cpp @@ -0,0 +1,52 @@ +#include +#include + +#include + +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Linear_cell_complex_traits<3, Kernel> LCC_traits; + +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map<2, 3, LCC_traits> LCC; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; + +int main(int, char** argv) +{ + LCC lcc; + CGAL::load_off_for_bgl(lcc, argv[1]); + + // This is the vector where the distance gets written to + std::vector distance(lcc.vertex_attributes().size()); + + // Here we start at an arbitrary vertex + // Any other vertex could be the starting point + vertex_iterator vb, ve; + boost::tie(vb,ve)=vertices(lcc); + vertex_descriptor vd = *vb; + + std::cout << "We compute distances to " << vd->point() << std::endl; + + // bfs = breadth first search explores the graph + // Just as the distance_recorder there is a way to record the predecessor of a vertex + boost::breadth_first_search(lcc, + vd, + visitor(boost::make_bfs_visitor + (boost::record_distances + (make_iterator_property_map + (distance.begin(), + get(boost::vertex_index, lcc)), + boost::on_tree_edge())))); + + // Traverse all vertices and show at what distance they are + for(boost::tie(vb,ve)=vertices(lcc); vb!=ve; ++vb) + { + vd = *vb; + std::cout<point()<<" is "<id()]<<" hops away."< +#include +#include +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Linear_cell_complex_traits<3, Kernel> LCC_traits; + +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map<2, 3, LCC_traits> LCC; + +typedef boost::graph_traits GraphTraits; +typedef GraphTraits::vertex_descriptor vertex_descriptor; +typedef CGAL::Halfedge_around_target_iterator halfedge_around_target_iterator; + +template +OutputIterator +adjacent_vertices_V1(const LCC& g, + vertex_descriptor vd, + OutputIterator out) +{ + typename GraphTraits::halfedge_descriptor hb = halfedge(vd,g), done(hb); + do + { + *out++ = source(hb,g); + hb = opposite(next(hb,g),g); + } + while(hb!= done); + return out; +} + + +template +OutputIterator adjacent_vertices_V2(const LCC& g, + vertex_descriptor vd, + OutputIterator out) +{ + halfedge_around_target_iterator hi, he; + for(boost::tie(hi, he) = halfedges_around_target(halfedge(vd,g),g); hi != he; ++hi) + { + *out++ = source(*hi,g); + } + return out; +} + + +int main(int, char** argv) +{ + LCC lcc; + CGAL::load_off_for_bgl(lcc, argv[1]); + + GraphTraits::vertex_iterator vi = vertices(lcc).first; + std::list V; + adjacent_vertices_V1(lcc, *vi, std::back_inserter(V)); + ++vi; + adjacent_vertices_V2(lcc, *vi, std::back_inserter(V)); + std::cerr << "done\n"; + return 0; +} diff --git a/BGL/examples/BGL_LCC/kruskal_lcc.cpp b/BGL/examples/BGL_LCC/kruskal_lcc.cpp new file mode 100644 index 00000000000..fc6db66f054 --- /dev/null +++ b/BGL/examples/BGL_LCC/kruskal_lcc.cpp @@ -0,0 +1,75 @@ +#include +#include + +#include +#include + +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Linear_cell_complex_traits<3, Kernel> LCC_traits; + +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map<2, 3, LCC_traits> LCC; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + + + +void kruskal(const LCC& lcc) +{ + // We use the default edge weight which is the length of the edge + // This property map is defined in graph_traits_Linear_cell_complex.h + + // This function call requires a vertex_index_map named parameter which + // when ommitted defaults to "get(vertex_index,graph)". + // That default works here because the vertex type has an "id()" method + // field which is used by the vertex_index internal property. + std::list mst; + boost::kruskal_minimum_spanning_tree(lcc,std::back_inserter(mst)); + + std::cout << "#VRML V2.0 utf8\n" + "Shape {\n" + "appearance Appearance {\n" + "material Material { emissiveColor 1 0 0}}\n" + "geometry\n" + "IndexedLineSet {\n" + "coord Coordinate {\n" + "point [ \n"; + + vertex_iterator vb, ve; + for(boost::tie(vb,ve) = vertices(lcc); vb!=ve; ++vb){ + std::cout << (*vb)->point() << "\n"; + } + + std::cout << "]\n" + "}\n" + "coordIndex [\n"; + + for(std::list::iterator it = mst.begin(); it != mst.end(); ++it){ + std::cout << source(*it,lcc)->id() + << ", " << target(*it,lcc)->id() << ", -1\n"; + } + + std::cout << "]\n" + "}#IndexedLineSet\n" + "}# Shape\n"; +} + + +int main() +{ + LCC lcc; + + Point a(1,0,0); + Point b(0,1,0); + Point c(0,0,1); + Point d(0,0,0); + + lcc.make_tetrahedron(a,b,c,d); + kruskal(lcc); + + return 0; +} diff --git a/BGL/examples/BGL_LCC/normals.cmd b/BGL/examples/BGL_LCC/normals.cmd new file mode 100644 index 00000000000..5cea844d830 --- /dev/null +++ b/BGL/examples/BGL_LCC/normals.cmd @@ -0,0 +1 @@ +cube.off diff --git a/BGL/examples/BGL_LCC/normals_lcc.cpp b/BGL/examples/BGL_LCC/normals_lcc.cpp new file mode 100644 index 00000000000..76ba0a55c70 --- /dev/null +++ b/BGL/examples/BGL_LCC/normals_lcc.cpp @@ -0,0 +1,96 @@ +#include + +#include +#include + +#include +#include +#include +#include + +typedef CGAL::Cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef Kernel::Vector_3 Vector; + +typedef CGAL::Linear_cell_complex_traits<3, Kernel> LCC_traits; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map<2, 3, LCC_traits> LCC; + +template +void calculate_face_normals(const HalfedgeGraph& g, + PointMap pm, + NormalMap nm) +{ + typedef boost::graph_traits GraphTraits; + typedef typename GraphTraits::face_iterator face_iterator; + typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::property_traits::value_type point; + typedef typename boost::property_traits::value_type normal; + + face_iterator fb, fe; + for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) + { + halfedge_descriptor edg = halfedge(*fb, g); + halfedge_descriptor edgb = edg; + + point p0 = pm[target(edg, g)]; + edg = next(edg, g); + point p1 = pm[target(edg, g)]; + edg = next(edg, g); + point p2 = pm[target(edg, g)]; + edg = next(edg, g); + + if(edg == edgb) { + // triangle + nm[*fb] = CGAL::unit_normal(p1, p2, p0); + } else { + // not a triangle + normal n(CGAL::NULL_VECTOR); + + do { + n = n + CGAL::normal(p1, p2, p0); + p0 = p1; + p1 = p2; + + edg = next(edg, g); + p2 = pm[target(edg, g)]; + } while(edg != edgb); + + nm[*fb] = n / CGAL::sqrt(n.squared_length()); + } + } +} + +int main(int, char** argv) +{ + typedef boost::property_map::const_type + Face_index_map; + + LCC lcc; + CGAL::load_off_for_bgl(lcc, argv[1]); + + // Ad hoc property_map to store normals. Face_index_map is used to + // map face_descriptors to a contiguous range of indices. See + // http://www.boost.org/libs/property_map/doc/vector_property_map.html + // for details. + boost::vector_property_map + normals(get(CGAL::face_index, lcc)); + + calculate_face_normals( + lcc // Graph + , get(CGAL::vertex_point, lcc) // map from vertex_descriptor to point + , normals // map from face_descriptor to Vector_3 + ); + + std::cout << "Normals" << std::endl; + for(LCC::Attribute_range<2>::type::iterator it=lcc.attributes<2>().begin(); + it!=lcc.attributes<2>().end(); ++it) + { + // Facet_iterator is a face_descriptor, so we can use it as the + // key here + std::cout << normals[it] << std::endl; + } + + return 0; +} diff --git a/BGL/examples/BGL_LCC/range.cmd b/BGL/examples/BGL_LCC/range.cmd new file mode 100644 index 00000000000..5cea844d830 --- /dev/null +++ b/BGL/examples/BGL_LCC/range.cmd @@ -0,0 +1 @@ +cube.off diff --git a/BGL/examples/BGL_LCC/range_lcc.cpp b/BGL/examples/BGL_LCC/range_lcc.cpp new file mode 100644 index 00000000000..170e725269e --- /dev/null +++ b/BGL/examples/BGL_LCC/range_lcc.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Linear_cell_complex_traits<3, Kernel> LCC_traits; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map<2, 3, LCC_traits> LCC; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; + +typedef CGAL::Iterator_range vertex_range; + +vertex_range vertices_range(const LCC& lcc) +{ + return vertex_range(vertices(lcc)); +} + +struct Fct +{ + void operator()(const vertex_descriptor& vd) const + { + std::cout << vd->point() << std::endl; + } +}; + +void fct(const LCC& lcc) +{ + vertex_range vr(vertices(lcc)); + +#ifndef CGAL_CFG_NO_CPP0X_RANGE_BASED_FOR + std::cout << "new for loop" << std::endl; + for(vertex_descriptor vd : vr){ + std::cout << vd->point() << std::endl; + } +#endif + + std::cout << "BOOST_FOREACH" << std::endl; + BOOST_FOREACH(vertex_descriptor vd, vr){ + std::cout << vd->point() << std::endl; + } + + std::cout << "boost::tie + std::for_each" << std::endl; + vertex_iterator vb, ve; + + boost::tie(vb,ve) = vertices_range(lcc); + std::for_each(vb,ve, Fct()); +} + +int main(int, char** argv) +{ + LCC lcc; + CGAL::load_off_for_bgl(lcc, argv[1]); + + fct(lcc); + return 0; +} diff --git a/BGL/examples/BGL_LCC/transform_iterator.cmd b/BGL/examples/BGL_LCC/transform_iterator.cmd new file mode 100644 index 00000000000..5cea844d830 --- /dev/null +++ b/BGL/examples/BGL_LCC/transform_iterator.cmd @@ -0,0 +1 @@ +cube.off diff --git a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp new file mode 100644 index 00000000000..0a75de825d4 --- /dev/null +++ b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Linear_cell_complex_traits<3, Kernel> LCC_traits; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map<2, 3, LCC_traits> LCC; + +typedef boost::graph_traits GraphTraits; +typedef GraphTraits::vertex_descriptor vertex_descriptor; +typedef GraphTraits::halfedge_descriptor halfedge_descriptor; +typedef CGAL::Halfedge_around_target_iterator halfedge_around_target_iterator; + + +template +struct Source { + const G* g; + + Source() + : g(NULL) + {} + + Source(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::vertex_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return source(h, *g); + } +}; + +int main(int, char** argv) +{ + LCC lcc; + CGAL::load_off_for_bgl(lcc, argv[1]); + GraphTraits::vertex_descriptor vd = *(vertices(lcc).first); + + typedef boost::transform_iterator,halfedge_around_target_iterator> adjacent_vertex_iterator; + + halfedge_around_target_iterator hb,he; + boost::tie(hb,he) = halfedges_around_target(halfedge(vd,lcc),lcc); + adjacent_vertex_iterator avib, avie; + avib = boost::make_transform_iterator(hb, Source(lcc)); + avie = boost::make_transform_iterator(he, Source(lcc)); + + std::list V; + std::copy(avib,avie, std::back_inserter(V)); + return 0; +}