Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Locate.h: Use Face_location / Barycentric_coordinates everywhere #7638

Merged
merged 1 commit into from
Aug 14, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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