Clean code to use Face_location / Barycentric_coordinates everywhere

This commit is contained in:
Mael Rouxel-Labbé 2023-08-04 13:30:26 +02:00
parent 1d3456d6b0
commit 361f6e2f63
1 changed files with 50 additions and 94 deletions

View File

@ -52,6 +52,36 @@
namespace CGAL { namespace CGAL {
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {
/// \ingroup PMP_locate_grp
///
/// A variant used in the function `get_descriptor_from_location()`.
template <typename TriangleMesh>
using descriptor_variant = boost::variant<typename boost::graph_traits<TriangleMesh>::vertex_descriptor,
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor,
typename boost::graph_traits<TriangleMesh>::face_descriptor>;
/// \ingroup PMP_locate_grp
///
/// A triplet of coordinates describing the barycentric coordinates of a point
/// with respect to the vertices of a triangular face.
///
/// \sa `Face_location`
template <typename FT>
using Barycentric_coordinates = std::array<FT, 3>;
/// \ingroup PMP_locate_grp
///
/// If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`)
/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondence
/// between the coordinates in `bc` and the vertices of the face `f` is the following:
/// - `w0` corresponds to `source(halfedge(f, tm), tm)`
/// - `w1` corresponds to `target(halfedge(f, tm), tm)`
/// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)`
template <typename TriangleMesh, typename FT>
using Face_location = std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
Barycentric_coordinates<FT> >;
namespace internal { namespace internal {
// The Ray must have the same ambient dimension as the property map's value type (aka, the point type) // The Ray must have the same ambient dimension as the property map's value type (aka, the point type)
@ -85,51 +115,20 @@ struct Location_traits
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor; typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef std::array<FT, 3> Barycentric_coordinates; typedef CGAL::Polygon_mesh_processing::Barycentric_coordinates<FT> Barycentric_coordinates;
typedef std::pair<face_descriptor, Barycentric_coordinates> Face_location; typedef CGAL::Polygon_mesh_processing::Face_location<TriangleMesh, FT> Face_location;
}; };
} // end namespace internal } // end namespace internal
/// \ingroup PMP_locate_grp
///
/// A variant used in the function `get_descriptor_from_location()`.
template <typename TriangleMesh>
using descriptor_variant = boost::variant<typename boost::graph_traits<TriangleMesh>::vertex_descriptor,
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor,
typename boost::graph_traits<TriangleMesh>::face_descriptor>;
/// \ingroup PMP_locate_grp
///
/// A triplet of coordinates describing the barycentric coordinates of a point
/// with respect to the vertices of a triangular face.
///
/// \sa `Face_location`
template <typename FT>
using Barycentric_coordinates = std::array<FT, 3>;
/// \ingroup PMP_locate_grp
///
/// If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`)
/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondence
/// between the coordinates in `bc` and the vertices of the face `f` is the following:
/// - `w0` corresponds to `source(halfedge(f, tm), tm)`
/// - `w1` corresponds to `target(halfedge(f, tm), tm)`
/// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)`
template <typename TriangleMesh, typename FT>
using Face_location = std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
Barycentric_coordinates<FT> >;
// forward declarations // forward declarations
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool is_in_face(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, bool is_in_face(const Face_location<TriangleMesh, FT>& loc,
std::array<FT, 3> >& loc,
const TriangleMesh& tm); const TriangleMesh& tm);
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
descriptor_variant<TriangleMesh> descriptor_variant<TriangleMesh>
get_descriptor_from_location(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc,
std::array<FT, 3> >& loc,
const TriangleMesh& tm); const TriangleMesh& tm);
// end of forward declarations // end of forward declarations
@ -138,8 +137,7 @@ namespace internal {
template <typename FT, typename TriangleMesh, typename OutputIterator> template <typename FT, typename TriangleMesh, typename OutputIterator>
OutputIterator OutputIterator
incident_faces(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, incident_faces(const Face_location<TriangleMesh, FT>& loc,
std::array<FT, 3> >& location,
const TriangleMesh& tm, const TriangleMesh& tm,
OutputIterator out) OutputIterator out)
{ {
@ -147,7 +145,7 @@ incident_faces(const std::pair<typename boost::graph_traits<TriangleMesh>::face_
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor; typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
const descriptor_variant<TriangleMesh> dv = get_descriptor_from_location(location, tm); const descriptor_variant<TriangleMesh> dv = get_descriptor_from_location(loc, tm);
if(const vertex_descriptor* vd_ptr = boost::get<vertex_descriptor>(&dv)) if(const vertex_descriptor* vd_ptr = boost::get<vertex_descriptor>(&dv))
{ {
@ -173,7 +171,7 @@ incident_faces(const std::pair<typename boost::graph_traits<TriangleMesh>::face_
// Snapping coordinates for robustness // Snapping coordinates for robustness
template <typename FT> template <typename FT>
bool bool
snap_coordinates_to_border(std::array<FT, 3>& coords, snap_coordinates_to_border(Barycentric_coordinates<FT>& coords,
const FT tolerance = std::numeric_limits<FT>::epsilon()) const FT tolerance = std::numeric_limits<FT>::epsilon())
{ {
#ifdef CGAL_PMP_LOCATE_DEBUG #ifdef CGAL_PMP_LOCATE_DEBUG
@ -224,8 +222,7 @@ snap_coordinates_to_border(std::array<FT, 3>& coords,
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
snap_location_to_border(std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, snap_location_to_border(Face_location<TriangleMesh, FT>& loc,
std::array<FT, 3> >& loc,
const TriangleMesh /*tm*/, const TriangleMesh /*tm*/,
const FT tolerance = std::numeric_limits<FT>::epsilon()) const FT tolerance = std::numeric_limits<FT>::epsilon())
{ {
@ -235,7 +232,7 @@ snap_location_to_border(std::pair<typename boost::graph_traits<TriangleMesh>::fa
template <typename K, typename P, int = P::Ambient_dimension::value> template <typename K, typename P, int = P::Ambient_dimension::value>
struct Barycentric_coordinate_calculator // 2D version struct Barycentric_coordinate_calculator // 2D version
{ {
std::array<typename K::FT, 3> Barycentric_coordinates<typename K::FT>
operator()(const P& ip, const P& iq, const P& ir, const P& iquery, const K& k) const operator()(const P& ip, const P& iq, const P& ir, const P& iquery, const K& k) const
{ {
typedef typename K::FT FT; typedef typename K::FT FT;
@ -273,7 +270,7 @@ struct Barycentric_coordinate_calculator // 2D version
template <typename K, typename P> template <typename K, typename P>
struct Barycentric_coordinate_calculator<K, P, 3 /*3D specialization*/> struct Barycentric_coordinate_calculator<K, P, 3 /*3D specialization*/>
{ {
std::array<typename K::FT, 3> Barycentric_coordinates<typename K::FT>
operator()(const P& ip, const P& iq, const P& ir, const P& iquery, const K& k) const operator()(const P& ip, const P& iq, const P& ir, const P& iquery, const K& k) const
{ {
typedef typename K::FT FT; typedef typename K::FT FT;
@ -364,7 +361,7 @@ struct Barycentric_point_constructor<K, P, 3> // 3D version
/// \pre `query` lies on the plane defined by `p`, `q`, and `r`. /// \pre `query` lies on the plane defined by `p`, `q`, and `r`.
/// ///
template <typename GeomTraits, typename Point> template <typename GeomTraits, typename Point>
std::array<typename GeomTraits::FT, 3> Barycentric_coordinates<typename GeomTraits::FT>
barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query, barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query,
const GeomTraits& gt) const GeomTraits& gt)
{ {
@ -373,7 +370,7 @@ barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Po
} }
template <typename Point> template <typename Point>
std::array<typename CGAL::Kernel_traits<Point>::type::FT, 3> Barycentric_coordinates<typename CGAL::Kernel_traits<Point>::type::FT>
barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query) barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query)
{ {
typedef typename CGAL::Kernel_traits<Point>::type Kernel; typedef typename CGAL::Kernel_traits<Point>::type Kernel;
@ -411,7 +408,7 @@ random_location_on_halfedge(typename boost::graph_traits<TriangleMesh>::halfedge
const int h_id = halfedge_index_in_face(hd, tm); const int h_id = halfedge_index_in_face(hd, tm);
const FT t(rnd.uniform_real(0., 1.)); const FT t(rnd.uniform_real(0., 1.));
std::array<FT, 3> coordinates; Barycentric_coordinates<FT> coordinates;
coordinates[h_id] = t; coordinates[h_id] = t;
coordinates[(h_id+1)%3] = FT(1)-t; coordinates[(h_id+1)%3] = FT(1)-t;
coordinates[(h_id+2)%3] = FT(0); coordinates[(h_id+2)%3] = FT(0);
@ -510,8 +507,7 @@ descriptor_variant<TriangleMesh>
#ifdef DOXYGEN_RUNNING // just for convenience because template alias do not allow template deduction #ifdef DOXYGEN_RUNNING // just for convenience because template alias do not allow template deduction
get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc, get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc,
#else #else
get_descriptor_from_location(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc,
std::array<FT, 3> >& loc,
#endif #endif
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
@ -589,12 +585,10 @@ get_descriptor_from_location(const std::pair<typename boost::graph_traits<Triang
template <typename FT, typename TriangleMesh, typename NamedParameters = parameters::Default_named_parameters> template <typename FT, typename TriangleMesh, typename NamedParameters = parameters::Default_named_parameters>
#ifdef DOXYGEN_RUNNING #ifdef DOXYGEN_RUNNING
Point Point
construct_point(const Face_location<TriangleMesh, FT>& loc,
#else #else
typename internal::Location_traits<TriangleMesh, NamedParameters>::Point typename internal::Location_traits<TriangleMesh, NamedParameters>::Point
construct_point(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif #endif
construct_point(const Face_location<TriangleMesh, FT>& loc,
const TriangleMesh& tm, const TriangleMesh& tm,
const NamedParameters& np = parameters::default_values()) const NamedParameters& np = parameters::default_values())
{ {
@ -648,12 +642,7 @@ construct_point(const std::pair<typename boost::graph_traits<TriangleMesh>::face
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
#ifdef DOXYGEN_RUNNING
is_on_vertex(const Face_location<TriangleMesh, FT>& loc, is_on_vertex(const Face_location<TriangleMesh, FT>& loc,
#else
is_on_vertex(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif
const typename boost::graph_traits<TriangleMesh>::vertex_descriptor vd, const typename boost::graph_traits<TriangleMesh>::vertex_descriptor vd,
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
@ -692,12 +681,7 @@ is_on_vertex(const std::pair<typename boost::graph_traits<TriangleMesh>::face_de
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
#ifdef DOXYGEN_RUNNING
is_on_halfedge(const Face_location<TriangleMesh, FT>& loc, is_on_halfedge(const Face_location<TriangleMesh, FT>& loc,
#else
is_on_halfedge(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif
const typename boost::graph_traits<TriangleMesh>::halfedge_descriptor hd, const typename boost::graph_traits<TriangleMesh>::halfedge_descriptor hd,
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
@ -738,11 +722,7 @@ is_on_halfedge(const std::pair<typename boost::graph_traits<TriangleMesh>::face_
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
#ifdef DOXYGEN_RUNNING
is_in_face(const Barycentric_coordinates<FT>& bar, is_in_face(const Barycentric_coordinates<FT>& bar,
#else
is_in_face(const std::array<FT, 3>& bar,
#endif
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
CGAL_USE(tm); CGAL_USE(tm);
@ -780,12 +760,7 @@ is_in_face(const std::array<FT, 3>& bar,
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
#ifdef DOXYGEN_RUNNING
is_in_face(const Face_location<TriangleMesh, FT>& loc, is_in_face(const Face_location<TriangleMesh, FT>& loc,
#else
is_in_face(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
return is_in_face(loc.second, tm); return is_in_face(loc.second, tm);
@ -812,12 +787,7 @@ is_in_face(const std::pair<typename boost::graph_traits<TriangleMesh>::face_desc
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
#ifdef DOXYGEN_RUNNING
is_on_face_border(const Face_location<TriangleMesh, FT>& loc, is_on_face_border(const Face_location<TriangleMesh, FT>& loc,
#else
is_on_face_border(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
if(!is_in_face(loc, tm)) if(!is_in_face(loc, tm))
@ -853,12 +823,7 @@ is_on_face_border(const std::pair<typename boost::graph_traits<TriangleMesh>::fa
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
#ifdef DOXYGEN_RUNNING
is_on_mesh_border(const Face_location<TriangleMesh, FT>& loc, is_on_mesh_border(const Face_location<TriangleMesh, FT>& loc,
#else
is_on_mesh_border(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
@ -1136,7 +1101,7 @@ locate_in_face(const typename internal::Location_traits<TriangleMesh, NamedParam
const Point_reference p1 = get(vpm, vd1); const Point_reference p1 = get(vpm, vd1);
const Point_reference p2 = get(vpm, vd2); const Point_reference p2 = get(vpm, vd2);
std::array<FT, 3> coords = barycentric_coordinates<Geom_traits, Point>(p0, p1, p2, query, gt); Barycentric_coordinates<FT> coords = barycentric_coordinates<Geom_traits, Point>(p0, p1, p2, query, gt);
if(snap_tolerance != FT(0) && !is_in_face(coords, tm)) if(snap_tolerance != FT(0) && !is_in_face(coords, tm))
{ {
@ -1174,12 +1139,7 @@ locate_in_face(const typename internal::Location_traits<TriangleMesh, NamedParam
/// ///
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
Face_location<TriangleMesh, FT> Face_location<TriangleMesh, FT>
#ifdef DOXYGEN_RUNNING
locate_in_adjacent_face(const Face_location<TriangleMesh, FT>& loc, locate_in_adjacent_face(const Face_location<TriangleMesh, FT>& loc,
#else
locate_in_adjacent_face(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
#endif
const typename boost::graph_traits<TriangleMesh>::face_descriptor fd, const typename boost::graph_traits<TriangleMesh>::face_descriptor fd,
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
@ -1247,11 +1207,9 @@ locate_in_adjacent_face(const std::pair<typename boost::graph_traits<TriangleMes
// note: not returning the query location to emphasis that the known location can change too. // note: not returning the query location to emphasis that the known location can change too.
template <typename FT, typename TriangleMesh, typename NamedParameters> template <typename FT, typename TriangleMesh, typename NamedParameters>
bool bool
locate_in_common_face(std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, locate_in_common_face(Face_location<TriangleMesh, FT>& known_location,
std::array<FT, 3> >& known_location,
const typename internal::Location_traits<TriangleMesh, NamedParameters>::Point& query, const typename internal::Location_traits<TriangleMesh, NamedParameters>::Point& query,
std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, Face_location<TriangleMesh, FT>& query_location,
std::array<FT, 3> >& query_location,
const TriangleMesh& tm, const TriangleMesh& tm,
const NamedParameters& np, const NamedParameters& np,
const FT tolerance = std::numeric_limits<FT>::epsilon()) const FT tolerance = std::numeric_limits<FT>::epsilon())
@ -1323,10 +1281,8 @@ locate_in_common_face(std::pair<typename boost::graph_traits<TriangleMesh>::face
// - both locations must be known but can change // - both locations must be known but can change
template <typename FT, typename TriangleMesh> template <typename FT, typename TriangleMesh>
bool bool
locate_in_common_face(std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor, locate_in_common_face(Face_location<TriangleMesh, FT>& first_location,
std::array<FT, 3> >& first_location, Face_location<TriangleMesh, FT>& second_location,
std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& second_location,
const TriangleMesh& tm) const TriangleMesh& tm)
{ {
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor; typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;