CGAL 5.1 - CGAL and the Boost Graph Library
BGL_polyhedron_3/normals.cpp
#include <fstream>
#include <boost/graph/graph_traits.hpp>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/property_map.h>
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
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
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 argc, char** argv)
{
typedef boost::property_map<
Polyhedron,
>::const_type Face_index_map;
std::ifstream in((argc>1)?argv[1]:"cube.off");
Polyhedron P;
in >> P ;
// initialize facet indices
std::size_t i = 0;
for(Polyhedron::Facet_iterator it = P.facets_begin(); it != P.facets_end(); ++it, ++i)
{
it->id() = i;
}
// 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, P));
calculate_face_normals(
P // Graph
, get(CGAL::vertex_point, P) // map from vertex_descriptor to point
, normals // map from face_descriptor to Vector_3
);
std::cout << "Normals" << std::endl;
for(Polyhedron::Facet_iterator it = P.facets_begin(); it != P.facets_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;
}
CGAL::sqrt
NT sqrt(const NT &x)
Kernel::Point_3
FaceListGraph::faces
std::pair< boost::graph_traits< FaceListGraph >::face_iterator, boost::graph_traits< FaceListGraph >::face_iterator > faces(const FaceListGraph &g)
CGAL::NULL_VECTOR
const CGAL::Null_vector NULL_VECTOR
Kernel
CGAL::face_index_t
face_index_t
The constant face_index is a property tag which identifies the index property of a face of a FaceGrap...
Definition: properties.h:27
FaceGraph::halfedge
boost::graph_traits< FaceGraph >::halfedge_descriptor halfedge(boost::graph_traits< FaceGraph >::face_descriptor f, const FaceGraph &g)
HalfedgeGraph
The concept HalfedgeGraph is a refinement of the Bgl concept IncidenceGraph and adds the notion of a ...
Definition: HalfedgeGraph.h:46
Kernel::Vector_3
CGAL::Polyhedron_3
CGAL::unit_normal
CGAL::Vector_3< Kernel > unit_normal(const CGAL::Point_3< Kernel > &p, const CGAL::Point_3< Kernel > &q, const CGAL::Point_3< Kernel > &r)
normal
CGAL::Vector_3< Kernel > normal(const CGAL::Point_3< Kernel > &p, const CGAL::Point_3< Kernel > &q, const CGAL::Point_3< Kernel > &r)
EdgeListGraph::target
boost::graph_traits< EdgeListGraph >::vertex_descriptor target(boost::graph_traits< EdgeListGraph >::edge_descriptor e, const EdgeListGraph &g)
HalfedgeGraph::next
boost::graph_traits< HalfedgeGraph >::halfedge_descriptor next(boost::graph_traits< HalfedgeGraph >::halfedge_descriptor h, const HalfedgeGraph &g)
CGAL::Simple_cartesian