Skip to content

Commit

Permalink
Locate.h: Use Face_location / Barycentric_coordinates everywhere (#7638)
Browse files Browse the repository at this point in the history
## Release Management

* Affected package(s): `PMP`
* Issue(s) solved (if any): -
* Feature/Small Feature (if any): -
* License and copyright ownership: no change
  • Loading branch information
sloriot authored Aug 14, 2023
2 parents ed71cfd + 361f6e2 commit b534d12
Showing 1 changed file with 50 additions and 94 deletions.
144 changes: 50 additions & 94 deletions Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,36 @@

namespace CGAL {
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 {

// The Ray must have the same ambient dimension as the property map's value type (aka, the point type)
Expand Down Expand Up @@ -85,51 +115,20 @@ struct Location_traits

typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;

typedef std::array<FT, 3> Barycentric_coordinates;
typedef std::pair<face_descriptor, Barycentric_coordinates> Face_location;
typedef CGAL::Polygon_mesh_processing::Barycentric_coordinates<FT> Barycentric_coordinates;
typedef CGAL::Polygon_mesh_processing::Face_location<TriangleMesh, FT> Face_location;
};

} // 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
template <typename FT, typename TriangleMesh>
bool is_in_face(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
bool is_in_face(const Face_location<TriangleMesh, FT>& loc,
const TriangleMesh& tm);

template <typename FT, typename TriangleMesh>
descriptor_variant<TriangleMesh>
get_descriptor_from_location(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc,
const TriangleMesh& tm);

// end of forward declarations
Expand All @@ -138,16 +137,15 @@ namespace internal {

template <typename FT, typename TriangleMesh, typename OutputIterator>
OutputIterator
incident_faces(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& location,
incident_faces(const Face_location<TriangleMesh, FT>& loc,
const TriangleMesh& tm,
OutputIterator out)
{
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_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))
{
Expand All @@ -173,7 +171,7 @@ incident_faces(const std::pair<typename boost::graph_traits<TriangleMesh>::face_
// Snapping coordinates for robustness
template <typename FT>
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())
{
#ifdef CGAL_PMP_LOCATE_DEBUG
Expand Down Expand Up @@ -224,8 +222,7 @@ snap_coordinates_to_border(std::array<FT, 3>& coords,

template <typename FT, typename TriangleMesh>
bool
snap_location_to_border(std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
snap_location_to_border(Face_location<TriangleMesh, FT>& loc,
const TriangleMesh /*tm*/,
const FT tolerance = std::numeric_limits<FT>::epsilon())
{
Expand All @@ -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>
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
{
typedef typename K::FT FT;
Expand Down Expand Up @@ -273,7 +270,7 @@ struct Barycentric_coordinate_calculator // 2D version
template <typename K, typename P>
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
{
typedef typename K::FT FT;
Expand Down Expand Up @@ -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`.
///
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,
const GeomTraits& gt)
{
Expand All @@ -373,7 +370,7 @@ barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Po
}

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)
{
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
Expand Down Expand Up @@ -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 FT t(rnd.uniform_real(0., 1.));

std::array<FT, 3> coordinates;
Barycentric_coordinates<FT> coordinates;
coordinates[h_id] = t;
coordinates[(h_id+1)%3] = FT(1)-t;
coordinates[(h_id+2)%3] = FT(0);
Expand Down Expand Up @@ -510,8 +507,7 @@ descriptor_variant<TriangleMesh>
#ifdef DOXYGEN_RUNNING // just for convenience because template alias do not allow template deduction
get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc,
#else
get_descriptor_from_location(const std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& loc,
get_descriptor_from_location(const Face_location<TriangleMesh, FT>& loc,
#endif
const TriangleMesh& tm)
{
Expand Down Expand Up @@ -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>
#ifdef DOXYGEN_RUNNING
Point
construct_point(const Face_location<TriangleMesh, FT>& loc,
#else
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
construct_point(const Face_location<TriangleMesh, FT>& loc,
const TriangleMesh& tm,
const NamedParameters& np = parameters::default_values())
{
Expand Down Expand Up @@ -648,12 +642,7 @@ construct_point(const std::pair<typename boost::graph_traits<TriangleMesh>::face
///
template <typename FT, typename TriangleMesh>
bool
#ifdef DOXYGEN_RUNNING
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 TriangleMesh& tm)
{
Expand Down Expand Up @@ -692,12 +681,7 @@ is_on_vertex(const std::pair<typename boost::graph_traits<TriangleMesh>::face_de
///
template <typename FT, typename TriangleMesh>
bool
#ifdef DOXYGEN_RUNNING
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 TriangleMesh& tm)
{
Expand Down Expand Up @@ -738,11 +722,7 @@ is_on_halfedge(const std::pair<typename boost::graph_traits<TriangleMesh>::face_
///
template <typename FT, typename TriangleMesh>
bool
#ifdef DOXYGEN_RUNNING
is_in_face(const Barycentric_coordinates<FT>& bar,
#else
is_in_face(const std::array<FT, 3>& bar,
#endif
const TriangleMesh& tm)
{
CGAL_USE(tm);
Expand Down Expand Up @@ -780,12 +760,7 @@ is_in_face(const std::array<FT, 3>& bar,
///
template <typename FT, typename TriangleMesh>
bool
#ifdef DOXYGEN_RUNNING
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)
{
return is_in_face(loc.second, tm);
Expand All @@ -812,12 +787,7 @@ is_in_face(const std::pair<typename boost::graph_traits<TriangleMesh>::face_desc
///
template <typename FT, typename TriangleMesh>
bool
#ifdef DOXYGEN_RUNNING
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)
{
if(!is_in_face(loc, tm))
Expand Down Expand Up @@ -853,12 +823,7 @@ is_on_face_border(const std::pair<typename boost::graph_traits<TriangleMesh>::fa
///
template <typename FT, typename TriangleMesh>
bool
#ifdef DOXYGEN_RUNNING
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)
{
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
Expand Down Expand Up @@ -1136,7 +1101,7 @@ locate_in_face(const typename internal::Location_traits<TriangleMesh, NamedParam
const Point_reference p1 = get(vpm, vd1);
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))
{
Expand Down Expand Up @@ -1174,12 +1139,7 @@ locate_in_face(const typename internal::Location_traits<TriangleMesh, NamedParam
///
template <typename FT, typename TriangleMesh>
Face_location<TriangleMesh, FT>
#ifdef DOXYGEN_RUNNING
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 TriangleMesh& tm)
{
Expand Down Expand Up @@ -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.
template <typename FT, typename TriangleMesh, typename NamedParameters>
bool
locate_in_common_face(std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& known_location,
locate_in_common_face(Face_location<TriangleMesh, FT>& known_location,
const typename internal::Location_traits<TriangleMesh, NamedParameters>::Point& query,
std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& query_location,
Face_location<TriangleMesh, FT>& query_location,
const TriangleMesh& tm,
const NamedParameters& np,
const FT tolerance = std::numeric_limits<FT>::epsilon())
Expand Down Expand Up @@ -1323,10 +1281,8 @@ locate_in_common_face(std::pair<typename boost::graph_traits<TriangleMesh>::face
// - both locations must be known but can change
template <typename FT, typename TriangleMesh>
bool
locate_in_common_face(std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& first_location,
std::pair<typename boost::graph_traits<TriangleMesh>::face_descriptor,
std::array<FT, 3> >& second_location,
locate_in_common_face(Face_location<TriangleMesh, FT>& first_location,
Face_location<TriangleMesh, FT>& second_location,
const TriangleMesh& tm)
{
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
Expand Down

0 comments on commit b534d12

Please sign in to comment.