Add examples for BGL LCC

This commit is contained in:
Guillaume Damiand 2017-04-19 15:17:50 -04:00
parent 977876ca48
commit b1e2d4bb81
14 changed files with 571 additions and 0 deletions

View File

@ -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" )

View File

@ -0,0 +1,86 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#if defined(CGAL_USE_OPENMESH)
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
#endif
#include <CGAL/boost/graph/copy_face_graph.h>
#include <iostream>
#include <fstream>
#include <iterator>
#include <boost/unordered_map.hpp>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Source;
typedef boost::graph_traits<Source>::vertex_descriptor sm_vertex_descriptor;
typedef boost::graph_traits<Source>::halfedge_descriptor sm_halfedge_descriptor;
typedef boost::graph_traits<Source>::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<Point> 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</* MyTraits*/> Target2;
Target2 T2;
{
typedef boost::graph_traits<Target2>::vertex_descriptor tm_vertex_descriptor;
typedef boost::graph_traits<Target2>::halfedge_descriptor tm_halfedge_descriptor;
typedef boost::graph_traits<Target2>::face_descriptor tm_face_descriptor;
// Use an unordered_map to keep track of elements.
boost::unordered_map<sm_vertex_descriptor, tm_vertex_descriptor> v2v;
boost::unordered_map<sm_halfedge_descriptor, tm_halfedge_descriptor> h2h;
boost::unordered_map<sm_face_descriptor, tm_face_descriptor> 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<Target1>::vertex_descriptor source_vertex_descriptor;
typedef boost::graph_traits<Target1>::halfedge_descriptor source_halfedge_descriptor;
typedef boost::graph_traits<Source>::vertex_descriptor tm_vertex_descriptor;
typedef boost::graph_traits<Source>::halfedge_descriptor tm_halfedge_descriptor;
boost::unordered_map<source_vertex_descriptor, tm_vertex_descriptor> v2v;
boost::unordered_map<source_halfedge_descriptor, tm_halfedge_descriptor> 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;
}

View File

@ -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

View File

@ -0,0 +1 @@
cube.off

View File

@ -0,0 +1,52 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex.h>
#include <boost/graph/breadth_first_search.hpp>
#include <fstream>
typedef CGAL::Simple_cartesian<double> 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<LCC>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<LCC>::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<int> 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<<vd->point()<<" is "<<distance[vd->id()]<<" hops away."<<std::endl;
}
return 0;
}

View File

@ -0,0 +1 @@
cube.off

View File

@ -0,0 +1,60 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex.h>
#include <CGAL/boost/graph/iterator.h>
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double> 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<LCC> GraphTraits;
typedef GraphTraits::vertex_descriptor vertex_descriptor;
typedef CGAL::Halfedge_around_target_iterator<LCC> halfedge_around_target_iterator;
template <typename OutputIterator>
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 <typename OutputIterator>
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<vertex_descriptor> 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;
}

View File

@ -0,0 +1,75 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex.h>
#include <iostream>
#include <list>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
typedef CGAL::Simple_cartesian<double> 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<LCC>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<LCC>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<LCC>::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<edge_descriptor> 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<edge_descriptor>::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;
}

View File

@ -0,0 +1 @@
cube.off

View File

@ -0,0 +1,96 @@
#include <fstream>
#include <boost/graph/graph_traits.hpp>
#include <CGAL/property_map.h>
#include <CGAL/basic.h>
#include <CGAL/Kernel/global_functions.h>
#include <CGAL/Cartesian.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex.h>
typedef CGAL::Cartesian<double> 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<typename HalfedgeGraph,
typename PointMap,
typename NormalMap>
void calculate_face_normals(const HalfedgeGraph& g,
PointMap pm,
NormalMap nm)
{
typedef boost::graph_traits<HalfedgeGraph> GraphTraits;
typedef typename GraphTraits::face_iterator face_iterator;
typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
typedef typename boost::property_traits<PointMap>::value_type point;
typedef typename boost::property_traits<NormalMap>::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<LCC, CGAL::face_index_t>::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<Vector, Face_index_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;
}

View File

@ -0,0 +1 @@
cube.off

View File

@ -0,0 +1,64 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex.h>
#include <boost/foreach.hpp>
#include <iostream>
#include <fstream>
#include <list>
#include <algorithm>
typedef CGAL::Simple_cartesian<double> 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<LCC>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<LCC>::vertex_iterator vertex_iterator;
typedef CGAL::Iterator_range<vertex_iterator> 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;
}

View File

@ -0,0 +1 @@
cube.off

View File

@ -0,0 +1,58 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex.h>
#include <CGAL/boost/graph/iterator.h>
#include <fstream>
#include <boost/iterator/transform_iterator.hpp>
#include <algorithm>
typedef CGAL::Simple_cartesian<double> 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<LCC> GraphTraits;
typedef GraphTraits::vertex_descriptor vertex_descriptor;
typedef GraphTraits::halfedge_descriptor halfedge_descriptor;
typedef CGAL::Halfedge_around_target_iterator<LCC> halfedge_around_target_iterator;
template <typename G>
struct Source {
const G* g;
Source()
: g(NULL)
{}
Source(const G& g)
: g(&g)
{}
typedef typename boost::graph_traits<G>::vertex_descriptor result_type;
typedef typename boost::graph_traits<G>::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<Source<LCC>,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>(lcc));
avie = boost::make_transform_iterator(he, Source<LCC>(lcc));
std::list<vertex_descriptor> V;
std::copy(avib,avie, std::back_inserter(V));
return 0;
}