diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h index 9777d6bd223..2db39e5197b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h @@ -27,37 +27,199 @@ namespace CGAL{ namespace Polygon_mesh_processing{ -///\cond SKIP_IN_MANUAL - template -void -compute_normals(const PolygonMesh& pmesh, - VertexNormalMap vnm, - FaceNormalMap fnm) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - compute_normals(pmesh, vnm, fnm, get(vertex_point, pmesh), Kernel()); +/** +* \ingroup PkgPolygonMeshProcessing +* computes the outward unit vector normal to face `f`. +* @tparam Kernel Geometric traits class. It can be omitted and deduced automatically from the point type of `PolygonMesh`. +* @tparam PolygonMesh a model of `FaceGraph` +* +* @param f the face on which the normal is computed +* @param pmesh the polygon mesh to which `f` belongs +*/ +template ::type +#endif + , typename Kernel +#ifdef DOXYGEN_RUNNING + = typename Kernel_traits< + typename boost::property_traits::value_type>::Kernel +#endif + > +typename Kernel::Vector_3 +compute_face_normal(typename boost::graph_traits::face_descriptor f, + const PolygonMesh& pmesh + , VertexPointMap vpmap +#ifdef DOXYGEN_RUNNING + = get(vertex_point_t, pmesh) +#endif + , const Kernel& +#ifdef DOXYGEN_RUNNING + k = Kernel() +#endif + ) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + + Vector normal = CGAL::NULL_VECTOR; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + halfedge_descriptor he = halfedge(f, pmesh); + halfedge_descriptor end = he; + do + { + const Point& prv = vpmap[target(prev(he, pmesh), pmesh)]; + const Point& curr = vpmap[target(he, pmesh)]; + const Point& nxt = vpmap[target(next(he, pmesh), pmesh)]; + Vector n = CGAL::cross_product(nxt - curr, prv - curr); + normal = normal + n; + + he = next(he, pmesh); + } while (he != end); + + return normal / std::sqrt(normal * normal); } +/** +* \ingroup PkgPolygonMeshProcessing +* computes the outward unit vector normal for all faces of the polygon mesh. +* @tparam Kernel Geometric traits class. It can be omitted and deduced automatically from the point type of `PolygonMesh`. +* @tparam PolygonMesh a model of `FaceGraph` +* @tparam FaceNormalMap the property map in which the normals are written. +* @tparam VertexPointMap the property map with the points associated to the vertices. +* -template +* @param pmesh the polygon mesh +*/ +template ::type +#endif + , typename Kernel +#ifdef DOXYGEN_RUNNING + = typename Kernel_traits< + typename boost::property_traits::value_type>::Kernel +#endif + > void -compute_normals(const PolygonMesh& pmesh, - VertexNormalMap vnm, - FaceNormalMap fnm, - VertexPointMap vpmap) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - compute_normals(pmesh, vnm, fnm, vpmap, Kernel()); +compute_face_normals(const PolygonMesh& pmesh + , FaceNormalMap fnm + , VertexPointMap vpmap +#ifdef DOXYGEN_RUNNING + = get(vertex_point, pmesh) +#endif + ,const Kernel& k +#ifdef DOXYGEN_RUNNING + = Kernel() +#endif + ) +{ + typename boost::graph_traits::face_descriptor f; + BOOST_FOREACH(f, faces(pmesh)){ + typename Kernel::Vector_3 vec = compute_face_normal(f,pmesh, vpmap, k); + put(fnm, f, vec); + } +} + +/** +* \ingroup PkgPolygonMeshProcessing +* computes the unit normal at vertex `v` as the average of the normals of incident faces. +* @tparam Kernel a %CGAL `Kernel` with `FT` a model of `FieldWithSqrt` +* @tparam PolygonMesh a model of `FaceGraph` +* +* @param v the vertex around which the normal is computed +* @param pmesh the polygon mesh to which `v` belongs +*/ +template::type +#endif + , typename Kernel +#ifdef DOXYGEN_RUNNING + = typename Kernel_traits< + typename boost::property_traits::value_type>::Kernel +#endif + > +typename Kernel::Vector_3 +compute_vertex_normal(typename boost::graph_traits::vertex_descriptor v, + const PolygonMesh& pmesh, + VertexPointMap vpmap +#ifdef DOXYGEN_RUNNING + = get(vertex_point_t, pmesh) +#endif + , const Kernel& k +#ifdef DOXYGEN_RUNNING + = Kernel() +#endif + ) +{ + typedef typename Kernel::Vector_3 Vector; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + Vector normal = CGAL::NULL_VECTOR; + halfedge_descriptor he = halfedge(v, pmesh); + halfedge_descriptor end = he; + do + { + if (!is_border(he, pmesh)) + { + Vector n = compute_face_normal(face(he, pmesh), pmesh, vpmap, k); + normal = normal + (n / std::sqrt(n*n)); + } + he = opposite(next(he, pmesh), pmesh); + } while (he != end); + + return normal / std::sqrt(normal * normal); +} + +/** +* \ingroup PkgPolygonMeshProcessing +* computes the outward unit vector normal for all vertices of the polygon mesh. +* @tparam Kernel Geometric traits class. It can be omitted and deduced automatically from the point type of `PolygonMesh`. +* @tparam PolygonMesh a model of `FaceGraph` +* @tparam VertexNormalMap the property map in which the normals are written. +* @tparam VertexPointMap the property map with the points associated to the vertices. +* +* @param f the face on which the normal is computed +* @param pmesh the polygon mesh +*/ +template ::type +#endif + , typename Kernel +#ifdef DOXYGEN_RUNNING + = typename Kernel_traits< + typename boost::property_traits::value_type>::Kernel +#endif + > +void +compute_vertex_normals(const PolygonMesh& pmesh + , VertexNormalMap vnm + , VertexPointMap vpmap +#ifdef DOXYGEN_RUNNING + = get(vertex_point, pmesh) +#endif + ,const Kernel& k +#ifdef DOXYGEN_RUNNING + = Kernel() +#endif + ) +{ + typename boost::graph_traits::vertex_descriptor v; + BOOST_FOREACH(v, vertices(pmesh)){ + typename Kernel::Vector_3 vec = compute_vertex_normal(v,pmesh, vpmap, k); + put(vnm, v, vec); + } } -///\endcond /** * \ingroup PkgPolygonMeshProcessing * computes the outward unit vector normal for all vertices and faces of the polygon mesh. @@ -109,245 +271,9 @@ compute_normals(const PolygonMesh& pmesh } - ///\cond SKIP_IN_MANUAL -template -void -compute_vertex_normals(const PolygonMesh& pmesh, - VertexNormalMap vnm) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - compute_vertex_normals(pmesh, vnm, get(vertex_point, pmesh), Kernel()); -} - - -template -void -compute_vertex_normals(const PolygonMesh& pmesh, - VertexNormalMap vnm, - VertexPointMap vpmap) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - compute_vertex_normals(pmesh, vnm, vpmap, Kernel()); -} - -///\endcond -/** -* \ingroup PkgPolygonMeshProcessing -* computes the outward unit vector normal for all vertices of the polygon mesh. -* @tparam Kernel Geometric traits class. It can be omitted and deduced automatically from the point type of `PolygonMesh`. -* @tparam PolygonMesh a model of `FaceGraph` -* @tparam VertexNormalMap the property map in which the normals are written. -* @tparam VertexPointMap the property map with the points associated to the vertices. -* -* @param f the face on which the normal is computed -* @param pmesh the polygon mesh -*/ -template ::type -#endif - , typename Kernel -#ifdef DOXYGEN_RUNNING - = typename Kernel_traits< - typename boost::property_traits::value_type>::Kernel -#endif - > -void -compute_vertex_normals(const PolygonMesh& pmesh - , VertexNormalMap vnm - , VertexPointMap vpmap -#ifdef DOXYGEN_RUNNING - = get(vertex_point, pmesh) -#endif - ,const Kernel& k -#ifdef DOXYGEN_RUNNING - = Kernel() -#endif - ) -{ - typename boost::graph_traits::vertex_descriptor v; - BOOST_FOREACH(v, vertices(pmesh)){ - typename Kernel::Vector_3 vec = compute_vertex_normal(v,pmesh, vpmap, k); - put(vnm, v, vec); - } -} - -///\cond SKIP_IN_MANUAL - -template -void -compute_face_normals(const PolygonMesh& pmesh, - FaceNormalMap fnm) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - compute_face_normals(pmesh, fnm, get(vertex_point, pmesh), Kernel()); -} - - -template -void -compute_face_normals(const PolygonMesh& pmesh, - FaceNormalMap fnm, - VertexPointMap vpmap) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - compute_face_normals(pmesh, fnm, vpmap, Kernel()); -} - -///\endcond - -/** -* \ingroup PkgPolygonMeshProcessing -* computes the outward unit vector normal for all faces of the polygon mesh. -* @tparam Kernel Geometric traits class. It can be omitted and deduced automatically from the point type of `PolygonMesh`. -* @tparam PolygonMesh a model of `FaceGraph` -* @tparam FaceNormalMap the property map in which the normals are written. -* @tparam VertexPointMap the property map with the points associated to the vertices. -* - -* @param pmesh the polygon mesh -*/ -template ::type -#endif - , typename Kernel -#ifdef DOXYGEN_RUNNING - = typename Kernel_traits< - typename boost::property_traits::value_type>::Kernel -#endif - > -void -compute_face_normals(const PolygonMesh& pmesh - , FaceNormalMap fnm - , VertexPointMap vpmap -#ifdef DOXYGEN_RUNNING - = get(vertex_point, pmesh) -#endif - ,const Kernel& k -#ifdef DOXYGEN_RUNNING - = Kernel() -#endif - ) -{ - typename boost::graph_traits::face_descriptor f; - BOOST_FOREACH(f, faces(pmesh)){ - typename Kernel::Vector_3 vec = compute_face_normal(f,pmesh, vpmap, k); - put(fnm, f, vec); - } -} - - -///\cond SKIP_IN_MANUAL - -template -typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel::Vector_3 -compute_face_normal( - typename boost::graph_traits::face_descriptor f, - const PolygonMesh& pmesh) -{ - typedef typename Kernel_traits< - typename boost::property_traits< - typename boost::property_map< - PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; - return compute_face_normal(f, pmesh, get(vertex_point, pmesh), Kernel()); -} - - - -template -typename Kernel_traits< - typename boost::property_traits::value_type>::Kernel::Vector_3 -compute_face_normal( - typename boost::graph_traits::face_descriptor f, - const PolygonMesh& pmesh, - VertexPointMap vpmap) -{ - typedef typename Kernel_traits< - typename boost::property_traits::value_type>::Kernel Kernel; - return compute_face_normal(f, pmesh, vpmap, Kernel()); -} - -/// \endcond - - -/** -* \ingroup PkgPolygonMeshProcessing -* computes the outward unit vector normal to face `f`. -* @tparam Kernel Geometric traits class. It can be omitted and deduced automatically from the point type of `PolygonMesh`. -* @tparam PolygonMesh a model of `FaceGraph` -* -* @param f the face on which the normal is computed -* @param pmesh the polygon mesh to which `f` belongs -*/ -template ::type -#endif - , typename Kernel -#ifdef DOXYGEN_RUNNING - = typename Kernel_traits< - typename boost::property_traits::value_type>::Kernel -#endif - > -typename Kernel::Vector_3 -compute_face_normal(typename boost::graph_traits::face_descriptor f, - const PolygonMesh& pmesh - , VertexPointMap vpmap -#ifdef DOXYGEN_RUNNING - = get(vertex_point_t, pmesh) -#endif - , const Kernel& k -#ifdef DOXYGEN_RUNNING - = Kernel() -#endif - ) -{ - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - - Vector normal = CGAL::NULL_VECTOR; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - halfedge_descriptor he = halfedge(f, pmesh); - halfedge_descriptor end = he; - do - { - const Point& prv = vpmap[target(prev(he, pmesh), pmesh)]; - const Point& curr = vpmap[target(he, pmesh)]; - const Point& nxt = vpmap[target(next(he, pmesh), pmesh)]; - Vector n = CGAL::cross_product(nxt - curr, prv - curr); - normal = normal + n; - - he = next(he, pmesh); - } while (he != end); - - return normal / std::sqrt(normal * normal); -} - -///\cond SKIP_IN_MANUAL - +// compute_vertex_normal overloads template typename Kernel_traits< typename boost::property_traits< @@ -363,8 +289,32 @@ compute_vertex_normal( PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; return compute_vertex_normal(v, pmesh, get(vertex_point, pmesh), Kernel()); } - +// compute_vertex_normals overloads +template +void +compute_vertex_normals(const PolygonMesh& pmesh, + VertexNormalMap vnm) +{ + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + compute_vertex_normals(pmesh, vnm, get(vertex_point, pmesh), Kernel()); +} + +template +void +compute_vertex_normals(const PolygonMesh& pmesh, + VertexNormalMap vnm, + VertexPointMap vpmap) +{ + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + compute_vertex_normals(pmesh, vnm, vpmap, Kernel()); +} template typename Kernel_traits< @@ -377,66 +327,98 @@ compute_vertex_normal( VertexPointMap vpmap) { typedef typename Kernel_traits< typename boost::property_traits::value_type>::Kernel Kernel; - return compute_vertex_normal(v, pmesh, vpmap, Kernel); + return compute_vertex_normal(v, pmesh, vpmap, Kernel()); } - -/// \endcond - - -/** -* \ingroup PkgPolygonMeshProcessing -* computes the unit normal at vertex `v` as the average of the normals of incident faces. -* @tparam Kernel a %CGAL `Kernel` with `FT` a model of `FieldWithSqrt` -* @tparam PolygonMesh a model of `FaceGraph` -* -* @param v the vertex around which the normal is computed -* @param pmesh the polygon mesh to which `v` belongs -*/ -template::type -#endif - , typename Kernel -#ifdef DOXYGEN_RUNNING - = typename Kernel_traits< - typename boost::property_traits::value_type>::Kernel -#endif - > -typename Kernel::Vector_3 -compute_vertex_normal(typename boost::graph_traits::vertex_descriptor v, - const PolygonMesh& pmesh, - VertexPointMap vpmap -#ifdef DOXYGEN_RUNNING - = get(vertex_point_t, pmesh) -#endif - , const Kernel& k -#ifdef DOXYGEN_RUNNING - = Kernel() -#endif - ) +// compute_face_normal overloads +template +typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel::Vector_3 +compute_face_normal( + typename boost::graph_traits::face_descriptor f, + const PolygonMesh& pmesh) { - typedef typename Kernel::Vector_3 Vector; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - Vector normal = CGAL::NULL_VECTOR; - halfedge_descriptor he = halfedge(v, pmesh); - halfedge_descriptor end = he; - do - { - if (!is_border(he, pmesh)) - { - Vector n = compute_face_normal(face(he, pmesh), pmesh, vpmap, k); - normal = normal + (n / std::sqrt(n*n)); - } - he = opposite(next(he, pmesh), pmesh); - } while (he != end); - - return normal / std::sqrt(normal * normal); + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + return compute_face_normal(f, pmesh, get(vertex_point, pmesh), Kernel()); } -} +template +typename Kernel_traits< + typename boost::property_traits::value_type>::Kernel::Vector_3 +compute_face_normal( + typename boost::graph_traits::face_descriptor f, + const PolygonMesh& pmesh, + VertexPointMap vpmap) +{ + typedef typename Kernel_traits< + typename boost::property_traits::value_type>::Kernel Kernel; + return compute_face_normal(f, pmesh, vpmap, Kernel()); +} + +// compute_face_normals overloads +template +void +compute_face_normals(const PolygonMesh& pmesh, + FaceNormalMap fnm) +{ + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + compute_face_normals(pmesh, fnm, get(vertex_point, pmesh), Kernel()); +} + + +template +void +compute_face_normals(const PolygonMesh& pmesh, + FaceNormalMap fnm, + VertexPointMap vpmap) +{ + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + compute_face_normals(pmesh, fnm, vpmap, Kernel()); +} + +// compute_normals overloads +template +void +compute_normals(const PolygonMesh& pmesh, + VertexNormalMap vnm, + FaceNormalMap fnm) +{ + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + compute_normals(pmesh, vnm, fnm, get(vertex_point, pmesh), Kernel()); +} + + +template +void +compute_normals(const PolygonMesh& pmesh, + VertexNormalMap vnm, + FaceNormalMap fnm, + VertexPointMap vpmap) +{ + typedef typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< + PolygonMesh, CGAL::vertex_point_t>::type>::value_type>::Kernel Kernel; + compute_normals(pmesh, vnm, fnm, vpmap, Kernel()); +} + +/// \endcond + +} } // end of namespace CGAL::Polygon_mesh_processing