From 68595b210ed36009bf3d10e47c1c262fab7c2b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Apr 2019 08:38:32 +0200 Subject: [PATCH 01/68] Add a += operator for SM's edge iterator --- Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 00472da2823..44eea9342e9 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -256,6 +256,7 @@ namespace CGAL { // increment. SM_Edge_index operator++(int) { SM_Edge_index tmp(*this); halfedge_ = SM_Halfedge_index((size_type)halfedge_ + 2); return tmp; } + SM_Edge_index operator+=(std::ptrdiff_t n) { halfedge_ = SM_Halfedge_index(std::ptrdiff_t(halfedge_) + 2*n); return *this; } // prints the index and a short identification string to an ostream. friend std::ostream& operator<<(std::ostream& os, SM_Edge_index const& e) From 52915956e387e8436fbdcdee0a832fcf4e4a6006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Apr 2019 08:39:02 +0200 Subject: [PATCH 02/68] Add PMP/locate.h --- .../license/Polygon_mesh_processing/locate.h | 63 + .../CGAL/Polygon_mesh_processing/locate.h | 1765 +++++++++++++++++ 2 files changed, 1828 insertions(+) create mode 100644 Installation/include/CGAL/license/Polygon_mesh_processing/locate.h create mode 100644 Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h diff --git a/Installation/include/CGAL/license/Polygon_mesh_processing/locate.h b/Installation/include/CGAL/license/Polygon_mesh_processing/locate.h new file mode 100644 index 00000000000..ada8db271c7 --- /dev/null +++ b/Installation/include/CGAL/license/Polygon_mesh_processing/locate.h @@ -0,0 +1,63 @@ +// Copyright (c) 2019 GeometryFactory SARL (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Andreas Fabri +// +// Warning: this file is generated, see include/CGAL/licence/README.md + +#ifndef CGAL_LICENSE_POLYGON_MESH_PROCESSING_LOCATE_H +#define CGAL_LICENSE_POLYGON_MESH_PROCESSING_LOCATE_H + +#include +#include + +#ifdef CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE + +# if CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +# if defined(CGAL_LICENSE_WARNING) + + CGAL_pragma_warning("Your commercial license for CGAL does not cover " + "this release of the Polygon Mesh Processing - Locate package.") +# endif + +# ifdef CGAL_LICENSE_ERROR +# error "Your commercial license for CGAL does not cover this release \ + of the Polygon Mesh Processing - Locate package. \ + You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +# endif // CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +#else // no CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE + +# if defined(CGAL_LICENSE_WARNING) + CGAL_pragma_warning("\nThe macro CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE is not defined." + "\nYou use the CGAL Polygon Mesh Processing - Locate package under " + "the terms of the GPLv3+.") +# endif // CGAL_LICENSE_WARNING + +# ifdef CGAL_LICENSE_ERROR +# error "The macro CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE is not defined.\ + You use the CGAL Polygon Mesh Processing - Locate package under the terms of \ + the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +#endif // no CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE + +#endif // CGAL_LICENSE_CHECK_POLYGON_MESH_PROCESSING_LOCATE_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h new file mode 100644 index 00000000000..158195af63f --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -0,0 +1,1765 @@ +// Copyright (c) 2014, 2017, 2018 INRIA (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé, +// Stephen Kiazyk +// +#ifndef CGAL_POLYGON_MESH_PROCESSING_LOCATE_H +#define CGAL_POLYGON_MESH_PROCESSING_LOCATE_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +// Everywhere in this file: +// If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` + +namespace CGAL { + +namespace Polygon_mesh_processing { + +namespace internal { + +// to not carry 5-lines-long types everywhere +template +struct Locate_types +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef boost::variant descriptor_variant; + + typedef typename boost::mpl::if_< + boost::is_same< + NamedParameters, Default>, + typename boost::property_map::const_type, + typename GetVertexPointMap::const_type + >::type VertexPointMap; + typedef typename boost::property_traits::value_type Point; + + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + + typedef CGAL::cpp11::array Barycentric_coordinates; + typedef std::pair Face_location; +}; + +} // end namespace internal + +// forward declarations +template +bool is_in_face(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm); + +template +typename internal::Locate_types::descriptor_variant +get_descriptor_from_location(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm); + +template +typename internal::Locate_types::Face_location +locate_in_face(typename boost::graph_traits::halfedge_descriptor he, + typename internal::Locate_types::FT t, + const TriangleMesh& tm); +// end of forward declarations + +namespace internal { + +template +OutputIterator +incident_faces(const typename internal::Locate_types::Face_location& location, + const TriangleMesh& tm, + OutputIterator out) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef boost::variant descriptor_variant; + + descriptor_variant dv = get_descriptor_from_location(location, tm); + + if(const vertex_descriptor* vd_ptr = boost::get(&dv)) + { + const vertex_descriptor vd = *vd_ptr; + for(face_descriptor fd : faces_around_target(halfedge(vd, tm), tm)) + *out++ = fd; + } + else if(const halfedge_descriptor* hd_ptr = boost::get(&dv)) + { + const halfedge_descriptor hd = *hd_ptr; + *out++ = face(hd, tm); + *out++ = face(opposite(hd, tm), tm); + } + else + { + const face_descriptor fd = boost::get(dv); + *out++ = fd; + } + + return out; +} + +// Snapping coordinates for robustness +template +bool +snap_coordinates_to_border(typename Locate_types::Barycentric_coordinates& coords, + const typename Locate_types::FT tolerance = + std::numeric_limits::FT>::epsilon()) +{ + typedef typename internal::Locate_types::FT FT; + + // @tmp clean that or protect it with a macro/variable +// std::cout << "Pre-snapping: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; +// std::cout << "Sum: " << coords[0] + coords[1] + coords[2] << std::endl; +// std::cout << "tolerance: " << tolerance << std::endl; + + // To still keep a sum roughly equals to 1, keep in memory the small changes + FT residue = 0.; + bool snapped = false; + + for(int i=0; i<3; ++i) + { + if(CGAL::abs(coords[i]) <= tolerance) + { + snapped = true; + residue += coords[i]; + coords[i] = 0.; + } + else if(CGAL::abs(1 - coords[i]) <= tolerance) + { + snapped = true; + residue -= 1. - coords[i]; + coords[i] = 1.; + } + } + + // Dump the residue into one of the barycentric values that is neither 0 nor 1 + for(int i=0; i<3; ++i) + { + if(coords[i] != 0. && coords[i] != 1.) + { + coords[i] += residue; + break; + } + } + + // @tmp clean that or protect it with a macro/variable +// std::cout << "Post-snapping: " << coords[0] << " " +// << coords[1] << " " +// << coords[2] << std::endl; +// std::cout << "Sum: " << coords[0] + coords[1] + coords[2] << std::endl; + + return snapped; +} + +template +bool +snap_location_to_border(typename Locate_types::Face_location& loc, + const typename Locate_types::FT tolerance = + std::numeric_limits::FT>::epsilon()) +{ + return snap_coordinates_to_border(loc.second, tolerance); +} + +template +typename std::iterator_traits::value_type +random_entity_in_range(InputIterator first, InputIterator beyond, + CGAL::Random& rnd = get_default_random()) +{ + typedef typename std::iterator_traits::difference_type size_type; + + size_type zero = 0, ne = std::distance(first, beyond); + std::advance(first, rnd.uniform_int(zero, ne - 1)); + + return *first; +} + +template +typename std::iterator_traits::value_type +random_entity_in_range(const CGAL::Iterator_range& range, + CGAL::Random& rnd = get_default_random()) +{ + return random_entity_in_range(range.begin(), range.end(), rnd); +} + +} // namespace internal + +/// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `pm`. +/// +/// \tparam PolygonMesh A model of `HalfedgeGraph` +/// +template +typename boost::graph_traits::vertex_descriptor +random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, + const PolygonMesh& pm, + CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(vertices_around_face(halfedge(fd, pm), pm), rnd); +} + +/// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `pm`. +/// +/// \tparam PolygonMesh A model of `HalfedgeGraph` +/// +template +typename boost::graph_traits::halfedge_descriptor +random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, + const PolygonMesh& pm, + CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, pm), pm), rnd); +} + +/// \brief returns a random non-null vertex of the polygon mesh `pm`. +/// +/// \tparam PolygonMesh A model of `VertexListGraph` +/// +template +typename boost::graph_traits::vertex_descriptor +random_vertex_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(vertices(pm), rnd); +} + +/// \brief returns a random non-null halfedge of the polygon mesh `pm`. +/// +/// \tparam PolygonMesh A model of `HalfedgeListGraph` +/// +template +typename boost::graph_traits::halfedge_descriptor +random_halfedge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(halfedges(pm), rnd); +} + +/// \brief returns a random non-null edge of the polygon mesh `pm`. +/// +/// \tparam PolygonMesh A model of `EdgeListGraph` +/// +template +typename boost::graph_traits::edge_descriptor +random_edge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(edges(pm), rnd); +} + +/// \brief returns a random non-null face of the polygon mesh `pm`. +/// +/// \tparam PolygonMesh A model of `FaceListGraph` +/// +template +typename boost::graph_traits::face_descriptor +random_face_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(faces(pm), rnd); +} + +/// \brief returns the number of `next` one has to apply to the halfedge `hd` +/// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. +/// +/// \tparam PolygonMesh A model of `FaceGraph` +/// +/// \param vd a vertex of `pm` whose index we seek +/// \param fd a face of `pm` in which we seek the index of `vd` +/// \param pm a mesh of type `PolygonMesh` +/// +/// \pre `vd` is a vertex of `fd`. +template +int vertex_index_in_face(const typename boost::graph_traits::vertex_descriptor vd, + const typename boost::graph_traits::face_descriptor fd, + const PolygonMesh& pm) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor start = halfedge(fd, pm); + halfedge_descriptor current = start; + int counter = 0; + + do + { + if(source(current, pm) == vd) + break; + + ++counter; + current = next(current, pm); + } + while(current != start); + + CGAL_postcondition(counter == 0 || current != start); + + return counter; +} + +/// \brief returns the number of `next` one has to apply to `hd` for `hd == he` +/// to be true, starting from `hd = halfedge(face(hd, tm), tm)`. +/// +/// \tparam PolygonMesh A model of `FaceGraph`. +/// +/// \param he a halfedge of `pm` whose index in `face(he, tm)` we seek +/// \param pm an object of type `PolygonMesh` +/// +template +int halfedge_index_in_face(typename boost::graph_traits::halfedge_descriptor he, + const PolygonMesh& pm) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + CGAL_precondition(he != boost::graph_traits::null_halfedge()); + CGAL_precondition(!is_border(he, pm)); + + face_descriptor f = face(he, pm); + halfedge_descriptor start = halfedge(f, pm); + halfedge_descriptor current = start; + int count = 0; + + while(current != he) + { + current = next(current, pm); + ++count; + } + + return count; +} + +template +struct Barycentric_coordinate_calculator // 2D version +{ + CGAL::array + 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::Vector_2 Vector_2; + + typename K::Construct_point_2 cp2 = k.construct_point_2_object(); + typename K::Construct_vector_2 cv2 = k.construct_vector_2_object(); + typename K::Compute_scalar_product_2 csp2 = k.compute_scalar_product_2_object(); + + const typename K::Point_2& p = cp2(ip); + const typename K::Point_2& q = cp2(iq); + const typename K::Point_2& r = cp2(ir); + const typename K::Point_2& query = cp2(iquery); + + Vector_2 v0 = cv2(p, q); + Vector_2 v1 = cv2(p, r); + Vector_2 v2 = cv2(p, query); + + FT d00 = csp2(v0, v0); + FT d01 = csp2(v0, v1); + FT d11 = csp2(v1, v1); + FT d20 = csp2(v2, v0); + FT d21 = csp2(v2, v1); + + FT denom = d00 * d11 - d01 * d01; + + FT v = (d11 * d20 - d01 * d21) / denom; + FT w = (d00 * d21 - d01 * d20) / denom; + + return CGAL::make_array(FT(1) - v - w, v, w); + } +}; + +template +struct Barycentric_coordinate_calculator +{ + CGAL::array + 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::Vector_3 Vector_3; + + typename K::Construct_point_3 cp3 = k.construct_point_3_object(); + typename K::Construct_vector_3 cv3 = k.construct_vector_3_object(); + typename K::Compute_scalar_product_3 csp3 = k.compute_scalar_product_3_object(); + + const typename K::Point_3& p = cp3(ip); + const typename K::Point_3& q = cp3(iq); + const typename K::Point_3& r = cp3(ir); + const typename K::Point_3& query = cp3(iquery); + + Vector_3 v0 = cv3(p, q); + Vector_3 v1 = cv3(p, r); + Vector_3 v2 = cv3(p, query); + + FT d00 = csp3(v0, v0); + FT d01 = csp3(v0, v1); + FT d11 = csp3(v1, v1); + FT d20 = csp3(v2, v0); + FT d21 = csp3(v2, v1); + + CGAL_assertion((d00 * d11 - d01 * d01) != FT(0)); // denom != 0. + FT denom_inv = 1. / (d00 * d11 - d01 * d01); + + FT v = (d11 * d20 - d01 * d21) * denom_inv; + FT w = (d00 * d21 - d01 * d20) * denom_inv; + + return CGAL::make_array(FT(1) - v - w, v, w); + } +}; + +/// \brief Given a set of three points and a query point, computes the barycentric +/// coordinates of the query point with respect to the first three points. +/// +/// \pre `p`, `q`, and `r` are not collinear. +/// \pre It must be possible to extract a kernel type model of `Kernel`, using `CGAL::Kernel_traits

` +/// (this is the case for all standard %CGAL point types). +/// \pre `query` lies on the plane defined by `p`, `q`, and `r`. +/// +template +CGAL::array::type::FT, 3> +barycentric_coordinates(const P& p, const P& q, const P& r, const P& query) +{ + typedef typename CGAL::Kernel_traits

::type Kernel; + + Barycentric_coordinate_calculator calculator; + + return calculator(p, q, r, query, Kernel()); +} + +// Random locations + +/// \brief Returns a random point over the halfedge `hd`, as a `Face_location`. +/// +/// \details The point is on the halfedge, meaning that all its barycentric coordinates +/// are positive. +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param hd a halfedge of `tm` +/// \param tm a triangulated surface mesh +/// \param rnd optional random number generator +/// +template +typename internal::Locate_types::Face_location +random_location_on_halfedge(typename boost::graph_traits::halfedge_descriptor hd, + const TriangleMesh& tm, + CGAL::Random& rnd = get_default_random()) +{ + typedef typename internal::Locate_types::FT FT; + + CGAL_precondition(CGAL::is_triangle_mesh(tm)); + + FT t = rnd.uniform_real(FT(0), FT(1)); + return locate_in_face(hd, t, tm); +} + +/// \brief Returns a random point over the face `fd`, as a `Face_location`. +/// +/// \details The point is on the face, meaning that all its barycentric coordinates +/// are positive. +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param fd a face of `tm` +/// \param tm a triangulated surface mesh +/// \param rnd optional random number generator +/// +template +typename internal::Locate_types::Face_location +random_location_on_face(typename boost::graph_traits::face_descriptor fd, + const TriangleMesh& CGAL_precondition_code(tm), + CGAL::Random& rnd = get_default_random()) +{ + typedef typename internal::Locate_types::FT FT; + + CGAL_precondition(CGAL::is_triangle_mesh(tm)); + CGAL_precondition(fd != boost::graph_traits::null_face()); + + FT u = rnd.uniform_real(FT(0), FT(1)); + FT v = rnd.uniform_real(FT(0), FT(FT(1) - u)); + return std::make_pair(fd, CGAL::make_array(u, v, FT(FT(1) - u - v))); +} + +/// \brief Returns a random point over the mesh `tm`. +/// +/// \details The returned location corresponds to a random point on a random face +/// of the mesh. The barycentric coordinates of the point in the face +/// are thus all positive. +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param tm a triangulated surface mesh +/// \param rnd optional random number generator +/// +template +typename internal::Locate_types::Face_location +random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + CGAL_precondition(CGAL::is_triangle_mesh(tm)); + + face_descriptor fd = random_face_in_mesh(tm, rnd); + return random_location_on_face(fd, tm, rnd); +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns a descriptor to the simplex +/// of smallest dimension on which the point corresponding to the location lies. +/// +/// \details In other words: +/// - if the point lies on a vertex, this function returns a `vertex_descriptor` `v`; +/// - if the point lies on a halfedge, this function returns a `halfedge_descriptor` `hd` +/// (note that in that case, `loc.first == face(hd, tm)` holds). +/// - otherwise, this function returns a `face_descriptor` `fd` (equal to `loc.first`). +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre the location corresponds to a point that is within a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +typename internal::Locate_types::descriptor_variant +get_descriptor_from_location(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename internal::Locate_types::Barycentric_coordinates Barycentric_coordinates; + + const face_descriptor fd = loc.first; + const Barycentric_coordinates& bar = loc.second; + + CGAL_precondition(CGAL::is_triangle_mesh(tm)); + CGAL_precondition(fd != boost::graph_traits::null_face()); + CGAL_precondition(is_in_face(loc, tm)); + + // the first barycentric coordinate corresponds to source(halfedge(fd, tm), tm) + halfedge_descriptor hd = prev(halfedge(fd, tm), tm); + + // check if the point is a vertex + for(int i=0; i<3; ++i) + { + if(bar[i] == 1) // coordinate at target(hd, tm) + return target(hd, tm); + hd = next(hd, tm); + } + CGAL_assertion(hd == prev(halfedge(fd, tm), tm)); + + // check if the point is on an edge + for(int i=0; i<3; ++i) + { + if(bar[i] == 0) // coordinate at target(hd, tm) + return prev(hd, tm); + hd = next(hd, tm); + } + + return fd; +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns the geometric position described +/// by these coordinates, as a point. +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param loc the location to transform into a point +/// \param tm a triangulated surface mesh +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +/// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +typename internal::Locate_types::Point +location_to_point(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm, + const NamedParameters& np) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename GetVertexPointMap::const_type VertexPointMap; + typedef typename boost::property_traits::value_type Point; + + using boost::choose_param; + using boost::get_param; + + CGAL_precondition(CGAL::is_triangle_mesh(tm)); + + VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + + halfedge_descriptor hd = halfedge(loc.first, tm); + const Point p0 = get(vpm, source(hd, tm)); + const Point p1 = get(vpm, target(hd, tm)); + const Point p2 = get(vpm, target(next(hd, tm), tm)); + + return CGAL::barycenter(p0, loc.second[0], p1, loc.second[1], p2, loc.second[2]); +} + +template +typename property_map_value::type +location_to_point(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm) +{ + return location_to_point(loc, tm, parameters::all_default()); +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns whether the location is +/// on the vertex `vd` or not. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +bool +is_on_vertex(const typename internal::Locate_types::Face_location& loc, + const typename boost::graph_traits::vertex_descriptor v, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename internal::Locate_types::descriptor_variant descriptor_variant; + + if(!is_in_face(loc, tm)) + return false; + + descriptor_variant dv = get_descriptor_from_location(loc, tm); + + if(const vertex_descriptor* vd_ptr = boost::get(&dv)) + return (v == *vd_ptr); + + return false; +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns whether the location is +/// on the halfedge `hd` or not. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +bool +is_on_halfedge(const typename internal::Locate_types::Face_location& loc, + const typename boost::graph_traits::halfedge_descriptor h, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename internal::Locate_types::descriptor_variant descriptor_variant; + + if(!is_in_face(loc, tm)) + return false; + + descriptor_variant dv = get_descriptor_from_location(loc, tm); + + if(const vertex_descriptor* vd_ptr = boost::get(&dv)) + return (*vd_ptr == source(h, tm) || *vd_ptr == target(h, tm)); + else if(const halfedge_descriptor* hd_ptr = boost::get(&dv)) + return (*hd_ptr == h); + + return false; +} + +/// \brief Given a set of barycentric coordinates, returns whether those barycentric +/// coordinates correspond to a point within the face (boundary included), +/// that is, if all the barycentric coordinates are positive. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre `tm` is a triangulated surface mesh. +/// +template +bool +is_in_face(const typename internal::Locate_types::Barycentric_coordinates& bar, + const TriangleMesh& CGAL_precondition_code(tm)) +{ + CGAL_precondition(CGAL::is_triangle_mesh(tm)); + + for(int i=0; i<3; ++i) + { + // "|| bar[i] > 1." is not needed because if everything is positive and the sum is '1', + // then each coefficient is below '1'. + if(bar[i] < 0.) + return false; + } + + return true; +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns whether the location is +/// in the face (boundary included) or not. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +bool +is_in_face(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm) +{ + return is_in_face(loc.second, tm); +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns whether the location is on the boundary +/// of the face or not. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +bool +is_on_face_border(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm) +{ + typedef typename internal::Locate_types::Face_location Face_location; + typedef typename Face_location::second_type Barycentric_coordinates; + + if(!is_in_face(loc, tm)) + return false; + + const Barycentric_coordinates& bar = loc.second; + + for(int i=0; i<3; ++i) + if(bar[i] == 0.) + return true; + + return false; +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, returns whether the location is +/// on the border of the mesh or not. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. +/// \pre `tm` is a triangulated surface mesh. +/// +template +bool +is_on_mesh_border(const typename internal::Locate_types::Face_location& loc, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename internal::Locate_types::Face_location Face_location; + typedef typename Face_location::second_type Barycentric_coordinates; + + const face_descriptor fd = loc.first; + const Barycentric_coordinates& bar = loc.second; + + if(!is_in_face(bar, tm)) + return false; + + // the first barycentric coordinate corresponds to source(halfedge(fd, tm), tm) + halfedge_descriptor hd = prev(halfedge(fd, tm), tm); + + // check if the point is a vertex + for(int i=0; i<3; ++i) + { + if(bar[i] == 1.) // coordinate at target(hd, tm) + return bool(CGAL::is_border(target(hd, tm), tm)); + hd = next(hd, tm); + } + CGAL_assertion(hd == prev(halfedge(fd, tm), tm)); + + // check if the point is on an edge + for(int i=0; i<3; ++i) + { + if(bar[i] == 0.) // coordinate at target(hd, tm) + return CGAL::is_border(edge(prev(hd, tm), tm), tm); + hd = next(hd, tm); + } + + // point is strictly within the face, so it's not on the border + return false; +} + +/// \name Constructions +/// @{ + +/// \brief Given two faces `fd1` and `fd2` of a polygonal mesh `pm`, returns +/// (if it exists) a common edge. The returned halfedge is incident to `fd1`. +/// +/// \tparam TriangleMesh A model of `HalfedgeGraph` +/// +template +boost::optional::halfedge_descriptor> +common_halfedge(const typename boost::graph_traits::face_descriptor fd1, + const typename boost::graph_traits::face_descriptor fd2, + const PolygonMesh& pm) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + if(fd1 == fd2) + return halfedge(fd1, pm); + + halfedge_descriptor hd = halfedge(fd1, pm), done = hd; + do + { + if(face(opposite(hd, pm), pm) == fd2) + return hd; + + hd = next(hd, pm); + } + while(hd != done); + + return boost::none; +} + +/// \name Constructions +/// @{ + +/// \brief Returns the location of the given vertex `vd` as a `Face_location`, +/// that is an ordered pair specifying a face containing the location +/// and the barycentric coordinates of the vertex `vd` in that face. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param vd a vertex of `tm` +/// \param tm a triangulated surface mesh +/// +template +typename internal::Locate_types::Face_location +locate_in_face(typename boost::graph_traits::vertex_descriptor vd, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename internal::Locate_types::FT FT; + + halfedge_descriptor he = halfedge(vd, tm); + + // Find a real face in case 'he' is a border halfedge + for(halfedge_descriptor hd : halfedges_around_target(he, tm)) + { + if(!is_border(hd, tm)) + { + he = hd; + break; + } + } + + CGAL_postcondition(!CGAL::is_border(he, tm)); // must find a 'real' face incident to 'vd' + + face_descriptor fd = face(he, tm); + + CGAL_assertion(target(he, tm) == vd); + CGAL_assertion(fd != boost::graph_traits::null_face()); + + FT coords[3] = { FT(0), FT(0), FT(0) }; + he = next(he, tm); // so that source(he, tm) == vd and it's simpler to handle 'index_in_face' + std::size_t halfedge_local_index = halfedge_index_in_face(he, tm); + coords[halfedge_local_index] = FT(1); + + return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); +} + +/// \brief Returns the location of the given vertex as a `Face_location` in `fd`, +/// that is an ordered pair composed of `fd` and of the barycentric coordinates +/// of the vertex in `fd`. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param vd a vertex of `tm` and a vertex of the face `fd` +/// \param fd a face of `tm` +/// \param tm a triangulated surface mesh +/// +template +typename internal::Locate_types::Face_location +locate_in_face(const typename boost::graph_traits::vertex_descriptor vd, + const typename boost::graph_traits::face_descriptor fd, + const TriangleMesh& tm) +{ + typedef typename internal::Locate_types::FT FT; + + FT coords[3] = { FT(0), FT(0), FT(0) }; + std::size_t vertex_local_index = vertex_index_in_face(vd, fd, tm); + coords[vertex_local_index] = FT(1); + + return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); +} + +/// \brief Given a point described by a halfedge `he` and a scalar `t` +/// as `p = (1 - t) * source(he, tm) + t * target(he, tm)`, +/// returns this location along the given edge as a `Face_location`, that is +/// an ordered pair specifying a face containing the location and the +/// barycentric coordinates of that location in that face. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param he a halfedge of `tm` +/// \param t the parametric distance of the desired point along `he` +/// \param tm a triangulation surface mesh +/// +/// \pre `tm` is a triangulated surface mesh. +/// +template +typename internal::Locate_types::Face_location +locate_in_face(const typename boost::graph_traits::halfedge_descriptor he, + const typename internal::Locate_types::FT t, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename internal::Locate_types::FT FT; + + face_descriptor fd = face(he, tm); + std::size_t edge_local_index = halfedge_index_in_face(he, tm); + + const FT one_minus_t(FT(1) - t); + FT coords[3] = { FT(0), FT(0), FT(0) }; + coords[edge_local_index] = one_minus_t; + coords[(edge_local_index + 1) % 3] = t; + + return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); +} + +/// \brief Given a point `query` and a face `fd` of a triangulation surface mesh, +/// returns this location as a `Face_location`, that is +/// an ordered pair composed of `fd` and of the barycentric coordinates of +/// `query` with respect to the vertices of `fd`. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param query a point +/// \param fd a face of `tm` +/// \param tm a triangulated surface mesh +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +template +typename internal::Locate_types::Face_location +locate_in_face(const typename internal::Locate_types::Point& query, + const typename boost::graph_traits::face_descriptor fd, + const TriangleMesh& tm, + const NamedParameters& np) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + typedef typename internal::Locate_types::Kernel K; + typedef typename K::FT FT; + + // VertexPointMap + typedef typename GetVertexPointMap::const_type VertexPointMap; + typedef typename boost::property_traits::value_type Point; + + using boost::choose_param; + using boost::get_param; + + VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + + vertex_descriptor vd0 = source(halfedge(fd, tm), tm); + vertex_descriptor vd1 = target(halfedge(fd, tm), tm); + vertex_descriptor vd2 = target(next(halfedge(fd, tm), tm), tm); + + const Point& p0 = get(vpm, vd0); + const Point& p1 = get(vpm, vd1); + const Point& p2 = get(vpm, vd2); + + CGAL::cpp11::array coords = barycentric_coordinates(p0, p1, p2, query); + + if(!is_in_face(coords, tm)) + { + std::cerr << "Warning: point " << query << " is not in the input face" << std::endl; + std::cerr << "Coordinates: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; + + // Try to to snap the coordinates, hoping the problem is just a -1e-17ish epsilon + // pushing the coordinates over the edge + internal::snap_coordinates_to_border(coords); // @tmp keep or not ? + } + + return std::make_pair(fd, coords); +} + +template +typename internal::Locate_types::Face_location +locate_in_face(const typename property_map_value::type& query, + const typename boost::graph_traits::face_descriptor f, + const TriangleMesh& tm) +{ + return locate_in_face(query, f, tm, parameters::all_default()); +} + +/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// `boost::graph_traits::face_descriptor` and an array +/// of barycentric coordinates, and a second face adjacent to the first, +/// return the `Face_location` of the point in the second face. +/// +/// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) +/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` +/// +/// \tparam TriangleMesh A model of `FaceGraph` +/// +/// \param loc the first location, with `loc.first` being a face of `tm` +/// \param fd the second face, adjacent to `loc.first` +/// \param tm the triangle mesh to which `he` belongs +/// +/// \pre `loc` corresponds to a point that lies on a face incident to both `loc.first` and `fd`. +/// +template +typename internal::Locate_types::Face_location +locate_in_adjacent_face(const typename internal::Locate_types::Face_location& loc, + const typename boost::graph_traits::face_descriptor fd, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef boost::variant descriptor_variant; + + typedef typename internal::Locate_types::Face_location Face_location; + typedef typename internal::Locate_types::FT FT; + + if(loc.first == fd) + return loc; + + Face_location loc_in_fd = std::make_pair(fd, CGAL::make_array(FT(0), FT(0), FT(0))); + descriptor_variant dv = get_descriptor_from_location(loc, tm); + + if(const vertex_descriptor* vd_ptr = boost::get(&dv)) + { + int index_of_vd = vertex_index_in_face(*vd_ptr, fd, tm); + loc_in_fd.second[index_of_vd] = 1.; + // Note that the barycentric coordinates were initialized to 0, + // so the second and third coordinates are already set up properly. + } + else if(const halfedge_descriptor* hd_ptr = boost::get(&dv)) + { + // Note that, here, we know that we are _not_ on a vertex + const halfedge_descriptor hd = *hd_ptr; + const halfedge_descriptor opp_hd = opposite(hd, tm); + CGAL_assertion(face(hd, tm) == loc.first); + CGAL_assertion(face(opp_hd, tm) == fd); + CGAL_assertion(loc.first != boost::graph_traits::null_face()); + CGAL_assertion(fd != boost::graph_traits::null_face()); + + const int index_of_hd = halfedge_index_in_face(hd, tm); + const int index_of_opp_hd = halfedge_index_in_face(opp_hd, tm); + + // - Coordinates will be non-null at indices `index_of_hd` + // and `index_of_hd + 1` in loc.first. + // - Coordinates will be non-null at indices `index_of_opp_hd` + // and `index_of_opp_hd + 1` in f. + // - The halfedges `hd` and `opp_hd` have opposite directions. + loc_in_fd.second[index_of_opp_hd] = loc.second[(index_of_hd + 1)%3]; + loc_in_fd.second[(index_of_opp_hd + 1)%3] = loc.second[index_of_hd]; + // note that the barycentric coordinates were initialized at 0, + // so the third coordinate is already set up properly + } + else + { + const face_descriptor fd2 = boost::get(dv); + CGAL_assertion(fd2 != boost::graph_traits::null_face()); + CGAL_assertion(fd2 != fd); + + // Calling this function for a location that is (strictly) in a face but + // asking for the location in a nearby face is meaningless + CGAL_assertion(false); + } + + CGAL_postcondition(loc_in_fd.first == fd); + return loc_in_fd; +} + +// Finding a common face to a location and a point +// - the first location must be known +// - the second must be a point in a face incident to get_descriptor_from_location(known_location) +// note: not returning the query location to emphasis that the known location can change too. +template +bool +locate_in_common_face(typename internal::Locate_types::Face_location& known_location, + const typename internal::Locate_types::Point& query, + typename internal::Locate_types::Face_location& query_location, + const TriangleMesh& tm, + const typename internal::Locate_types::FT tolerance = + std::numeric_limits::FT>::epsilon()) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef boost::variant descriptor_variant; + descriptor_variant dv = get_descriptor_from_location(known_location, tm); + + bool is_query_location_in_face = false; + + if(const vertex_descriptor* vd_ptr = boost::get(&dv)) + { + const vertex_descriptor vd = *vd_ptr; + halfedge_descriptor hd = halfedge(vd, tm); + + for(face_descriptor fd : faces_around_target(hd, tm)) + { + if(fd == boost::graph_traits::null_face()) + continue; + + // check if query can be found in that face + query_location = locate_in_face(query, fd, tm); + internal::snap_location_to_border(query_location, tolerance); // @tmp keep or not ? + + is_query_location_in_face = is_in_face(query_location, tm); + + if(is_query_location_in_face) + break; + } + } + else if(const halfedge_descriptor* hd_ptr = boost::get(&dv)) + { + const halfedge_descriptor hd = *hd_ptr; + face_descriptor fd = face(hd, tm); + + if(fd != boost::graph_traits::null_face()) + { + query_location = locate_in_face(query, fd, tm); + internal::snap_location_to_border(query_location, tolerance); // @tmp keep or not ? + is_query_location_in_face = is_in_face(query_location, tm); + } + + if(!is_query_location_in_face) + { + fd = face(opposite(hd, tm), tm); + query_location = locate_in_face(query, fd, tm); + is_query_location_in_face = is_in_face(query_location, tm); + } + } + else + { + const face_descriptor fd = boost::get(dv); + + CGAL_precondition(fd != boost::graph_traits::null_face()); + + query_location = locate_in_face(query, fd, tm); + internal::snap_location_to_border(query_location, tolerance); // @tmp keep or not ? + is_query_location_in_face = is_in_face(query_location, tm); + } + + // if this is not the same face as for 'known_query', change 'known_location' + if(is_query_location_in_face && query_location.first != known_location.first) + known_location = locate_in_adjacent_face(known_location, query_location.first, tm); + + return is_query_location_in_face; +} + +// Finding a common face to two locations +// - both locations must be known but can change +template +bool +locate_in_common_face(typename internal::Locate_types::Face_location& first_location, + typename internal::Locate_types::Face_location& second_location, + const TriangleMesh& tm) +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + // Check that we actually have something to do + if(first_location.first == second_location.first) + return true; + + bool is_first_location_on_border = is_on_face_border(first_location, tm); + bool is_second_location_on_border = is_on_face_border(second_location, tm); + + // We have already checked that they have different faces, if neither are on + // a border, then it's hopeless + if(!is_first_location_on_border && !is_second_location_on_border) + return false; + + // Find a common face in the sets of incident faces of each location + std::set first_incident_faces; + std::set second_incident_faces; + + internal::incident_faces(first_location, tm, std::inserter(first_incident_faces, first_incident_faces.begin())); + internal::incident_faces(second_location, tm, std::inserter(second_incident_faces, second_incident_faces.begin())); + + typename std::set::const_iterator fit = first_incident_faces.begin(); + typename std::set::const_iterator fend = first_incident_faces.end(); + typename std::set::const_iterator sit = second_incident_faces.begin(); + typename std::set::const_iterator send = second_incident_faces.end(); + + while(fit!=fend && sit!=send) + { + if(*fit == boost::graph_traits::null_face()) + ++fit; + if(*sit == boost::graph_traits::null_face()) + ++sit; + + if(*fit == *sit) + break; + else if(*fit < *sit) + ++fit; + else + ++sit; + } + + if(fit == fend || sit == send) // no common face... + return false; + + CGAL_assertion(*fit == *sit); + face_descriptor common_fd = *fit; + CGAL_assertion(common_fd != boost::graph_traits::null_face()); + + if(first_location.first != common_fd) + first_location = locate_in_adjacent_face(first_location, common_fd, tm); + + if(second_location.first != common_fd) + second_location = locate_in_adjacent_face(second_location, common_fd, tm); + + CGAL_postcondition(first_location.first == second_location.first); + return true; +} + +/// @} + +namespace internal { + +template::value> +struct Point_to_Point_3 +{ + typedef typename CGAL::Kernel_traits< + typename property_map_value::type>::Kernel K; + typedef typename K::Point_3 Point_3; + + Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), 0.); } +}; + +template +struct Point_to_Point_3 +{ + typedef typename CGAL::Kernel_traits< + typename property_map_value::type>::Kernel K; + typedef typename K::Point_3 Point_3; + + const Point_3& operator()(const Point_3& p) const { return p; } + Point_3 operator()(const Point& p) { return Point_3(p.x(), p.y(), p.z()); } +}; + +/// Readable property map that converts the output of a given vertex point map to a 3D point +template::const_type> +struct Point_to_Point_3_VPM +{ +private: + typedef VertexPointMap VPM; + typedef Point_to_Point_3_VPM Self; + +public: + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::property_traits::value_type Point; + typedef Point_to_Point_3 P_to_P3; + + typedef typename CGAL::Kernel_traits::Kernel K; + typedef typename K::Point_3 Point_3; + + // required typedefs + typedef vertex_descriptor key_type; + typedef Point_3 value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + + CGAL_static_assertion((boost::is_same::key_type, + vertex_descriptor>::value)); + + // Constructors + Point_to_Point_3_VPM() : conv_(), vpm_() { } // required for compilation by AABBtraits + Point_to_Point_3_VPM(const VertexPointMap vpm) : conv_(), vpm_(vpm) { } + Point_to_Point_3_VPM(const PolygonMesh& mesh) + : conv_(), vpm_(get_const_property_map(boost::vertex_point, mesh)) + { } + + // Access + const P_to_P3& converter() const { return conv_; } + const VertexPointMap& vpm() const { return vpm_; } + + // get function for property map + inline friend reference get(const Self& pmap, key_type v) { + return pmap.converter()(get(pmap.vpm(), v)); + } + +private: + // Can't be const nor references due to AABB_traits, so make sure to use property maps! + P_to_P3 conv_; + VertexPointMap vpm_; +}; + +} // namespace internal + +/// \name Nearest Face Location Queries +/// @{ + +/// \brief Creates an `AABB_tree` suitable for use with `locate_with_AABB_tree()`. +/// +/// \details This function should be called to create and cache an AABB tree +/// to avoid the AABB tree being rebuilt at every call of `locate_with_AABB_tree()`. +/// +/// \tparam TriangleMesh A model of `FaceListGraph` +/// \tparam AABBTraits A model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param tm a triangulated surface mesh +/// \param outTree output parameter that stores the computed `AABB_tree` +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +template +void build_AABB_tree(const TriangleMesh& tm, + AABB_tree& outTree, + const NamedParameters& np) +{ + typedef typename GetVertexPointMap::const_type VertexPointMap; + + using boost::choose_param; + using boost::get_param; + + VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + + typename boost::graph_traits::face_iterator facesStart, facesEnd; + boost::tie(facesStart, facesEnd) = faces(tm); + outTree.rebuild(facesStart, facesEnd, tm, vpm); + outTree.build(); +} + +template +void build_AABB_tree(const TriangleMesh& tm, + AABB_tree& outTree) +{ + return build_AABB_tree(tm, outTree, parameters::all_default()); +} + +/// \brief Returns the face location nearest to the given point, as a `Face_location`. +/// +/// \tparam TriangleMesh A model of `FaceListGraph` +/// \tparam AABBTraits A model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param p the point to locate on the input triangulated surface mesh +/// \param tree An `AABB_tree` containing the triangular faces of the input surface mesh to perform the point location with +/// \param tm a triangulated surface mesh +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +template +typename internal::Locate_types::Face_location +locate_with_AABB_tree(const typename AABBTraits::Point_3& p, + const AABB_tree& tree, + const TriangleMesh& tm, + const NamedParameters& np) +{ + typename AABB_tree::Point_and_primitive_id result = tree.closest_point_and_primitive(p); + + return locate_in_face(result.first, result.second, tm, np); +} + +template +typename internal::Locate_types::Face_location +locate_with_AABB_tree(const typename AABBTraits::Point_3& p, + const AABB_tree& tree, + const TriangleMesh& tm) +{ + return locate_with_AABB_tree(p, tree, tm, parameters::all_default()); +} + +/// \brief Returns the nearest face location to the given point. +/// +/// \details Note that this function will build an `AABB_tree` on each call. If you need +/// to call this function more than once, use `build_AABB_tree()` to cache a +/// copy of the `AABB_tree`, and use the overloads of this function +/// that accept a reference to an `AABB_tree` as input. +/// +/// \tparam TriangleMesh must be a model of `FaceListGraph`. +/// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param p the point to locate on the input triangulated surface mesh +/// \param tm a triangulated surface mesh +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +template +typename internal::Locate_types::Face_location +locate(const typename internal::Locate_types::Point& p, + const TriangleMesh& tm, + const NamedParameters& np) +{ + typedef typename GetVertexPointMap::const_type VertexPointMap; + + // Wrap the input VPM with a one converting to 3D (costs nothing if the input VPM + // already has value type Kernel::Point_3) + typedef internal::Point_to_Point_3_VPM VPM; + + typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; + typedef CGAL::AABB_traits::Kernel, + AABB_face_graph_primitive> AABB_face_graph_traits; + + using boost::get_param; + using boost::choose_param; + + const VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + const VPM wrapped_vpm(vpm); + + AABB_tree tree; + build_AABB_tree(tm, tree, parameters::vertex_point_map(wrapped_vpm)); + + return locate_with_AABB_tree(p, tree, tm, parameters::vertex_point_map(wrapped_vpm)); +} + +template +typename internal::Locate_types::Face_location +locate(const typename property_map_value::type& p, + const TriangleMesh& tm) +{ + return locate(p, tm, parameters::all_default()); +} + +namespace internal { + +// The Ray must have the same ambient dimension as the property map's value type (point type) + +template ::value> +struct Ray_type_selector +{ + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::Ray_2 type; +}; + +template +struct Ray_type_selector +{ + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::Ray_3 type; +}; + +} // end namespace internal + +/// \brief Returns the face location along `ray` nearest to its source point. +/// +/// \tparam TriangleMesh must be a model of `FaceListGraph`. +/// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param ray Ray to intersect with the input triangulated surface mesh +/// \param tree A `AABB_tree` containing the triangular faces of the input surface mesh to perform the point location with +/// \param tm a triangulated surface mesh +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +template +typename internal::Locate_types::Face_location +locate_with_AABB_tree(const typename CGAL::Kernel_traits::type::Ray_3& ray, + const AABB_tree& tree, + const TriangleMesh& tm, + const NamedParameters& np) +{ + typedef typename CGAL::Kernel_traits::type Kernel; + + typedef typename Kernel::FT FT; + typedef typename Kernel::Point_3 Point_3; + typedef typename Kernel::Ray_3 Ray_3; + + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef AABB_tree AABB_face_graph_tree; + + typedef typename AABB_face_graph_tree::template Intersection_and_primitive_id::Type Intersection_type; + typedef boost::optional Ray_intersection; + + std::vector intersections; + tree.all_intersections(ray, std::back_inserter(intersections)); + + bool found = false; + FT nearest_distance = 0; + Point_3 nearest_point = CGAL::ORIGIN; + face_descriptor nearest_face; + + for(std::size_t i = 0; i < intersections.size(); ++i) + { + if(intersections[i]) + { + Point_3* intersection_point = boost::get(&(intersections[i]->first)); + + if(intersection_point) + { + FT distance = CGAL::squared_distance(*intersection_point, ray.source()); + + if(!found || distance < nearest_distance) + { + found = true; + nearest_point = *intersection_point; + nearest_distance = distance; + nearest_face = intersections[i]->second; + } + } + } + } + + if(found) + return locate_in_face(nearest_point, nearest_face, tm, np); + else + return std::make_pair(boost::graph_traits::null_face(), + CGAL::make_array(FT(0), FT(0), FT(0))); +} + +template +typename internal::Locate_types::Face_location +locate_with_AABB_tree(const typename CGAL::Kernel_traits::type::Ray_3& ray, + const AABB_tree& tree, + const TriangleMesh& tm) +{ + return locate_with_AABB_tree(ray, tree, tm, parameters::all_default()); +} + +/// +/// \brief Returns the face location along `ray` nearest to its source point. +/// +/// \details Note that this function will build an `AABB_tree` on each call. If you need +/// to call this function more than once, use `build_AABB_tree()` to cache a +/// copy of the `AABB_tree`, and use the overloads of this function +/// that accept a reference to an `AABB_tree` as input. +/// +/// \tparam TriangleMesh must be a model of `FaceListGraph`. +/// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +/// \param ray Ray to intersect with the input triangulated surface mesh +/// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: +/// +/// \cgalNamedParamsBegin +/// \cgalParamBegin{vertex_point_map} +/// the property map with the points associated to the vertices of `tm`. +/// If this parameter is omitted, an internal property map for +/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// \cgalParamEnd +/// \cgalNamedParamsEnd +/// +template +typename internal::Locate_types::Face_location +locate(const typename internal::Ray_type_selector< + typename internal::Locate_types::Point>::type& ray, + const TriangleMesh& tm, + const NamedParameters& np) +{ + typedef typename GetVertexPointMap::const_type VertexPointMap; + + // Wrap the input VPM with a one converting to 3D (costs nothing if the input VPM + // already has value type Kernel::Point_3) + typedef internal::Point_to_Point_3_VPM VPM; + + typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; + typedef CGAL::AABB_traits::Kernel, + AABB_face_graph_primitive> AABB_face_graph_traits; + + using boost::get_param; + using boost::choose_param; + + const VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + const VPM wrapped_vpm(vpm); + + AABB_tree tree; + build_AABB_tree(tm, tree, parameters::vertex_point_map(wrapped_vpm)); + + return locate_with_AABB_tree(ray, tree, tm, np); +} + +template +typename internal::Locate_types::Face_location +locate(const typename internal::Ray_type_selector< + typename internal::Locate_types::Point>::type& ray, + const TriangleMesh& tm) +{ + return locate(ray, tm, parameters::all_default()); +} + +/// @} + +} // namespace Polygon_mesh_processing +} // namespace CGAL + +#endif // CGAL_POLYGON_MESH_PROCESSING_LOCATE_H From b0158ddd810a1eae10e0c9412d9b406fb4791ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Apr 2019 08:39:30 +0200 Subject: [PATCH 03/68] Add a test for PMP locate.h --- .../Polygon_mesh_processing/CMakeLists.txt | 2 + .../test_pmp_locate.cpp | 666 ++++++++++++++++++ 2 files changed, 668 insertions(+) create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index db345a3217e..3c4c032e542 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -98,6 +98,8 @@ endif() create_single_source_cgal_program("test_repair_polygon_soup.cpp") create_single_source_cgal_program("test_shape_predicates.cpp") create_single_source_cgal_program("test_pmp_collision_detection.cpp") + create_single_source_cgal_program("test_pmp_locate.cpp") + if( TBB_FOUND ) CGAL_target_use_TBB(test_pmp_distance) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp new file mode 100644 index 00000000000..5fe6454d8e2 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -0,0 +1,666 @@ +#include +#include + +// Graphs +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace PMP = CGAL::Polygon_mesh_processing; + +template +typename CGAL::Kernel_traits::type::Ray_3 +random_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd) +{ + typedef typename AABB_tree::AABB_traits::Point_3 Point_3; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + typedef typename Kernel::Ray_3 Ray_3; + + const CGAL::Bbox_3& bbox = aabb_tree.bbox(); + + FT px = rnd.get_double(bbox.xmin(), bbox.xmax()); + FT py = rnd.get_double(bbox.ymin(), bbox.ymax()); + FT pz = rnd.get_double(bbox.zmin(), bbox.zmax()); + + FT qx = rnd.get_double(bbox.xmin(), bbox.xmax()); + FT qy = rnd.get_double(bbox.ymin(), bbox.ymax()); + FT qz = rnd.get_double(bbox.zmin(), bbox.zmax()); + + return Ray_3(Point_3(px, py, pz), Point_3(qx, qy, qz)); +} + +template +bool is_equal(const FT& a, const FT& b) +{ + if(boost::is_floating_point::value) + return (CGAL::abs(a - b) <= 1e-12); // numeric_limits' epsilon is too restrictive... + else + return (a == b); +} + +template +void test_snappers(const G& g) +{ + std::cout << " test snappers..." << std::endl; + + typedef typename PMP::internal::Locate_types::FT FT; + + typename PMP::internal::Locate_types::Barycentric_coordinates coords = CGAL::make_array(FT(1e-11), FT(0.99999999999999999), FT(1e-12)); + typename PMP::internal::Locate_types::Face_location loc = std::make_pair(*(faces(g).first), coords); + + // --------------------------------------------------------------------------- + PMP::internal::snap_coordinates_to_border(coords); // uses numeric_limits' epsilon() + assert(coords[0] == 1e-11 && coords[1] == 1. && coords[2] == 1e-12); + + PMP::internal::snap_coordinates_to_border(coords, 1e-10); + assert(coords[0] == 0. && coords[1] == 1. && coords[2] == 0.); + + // --------------------------------------------------------------------------- + PMP::internal::snap_location_to_border(loc); // uses numeric_limits' epsilon() + assert(!PMP::is_on_face_border(loc, g)); + + PMP::internal::snap_location_to_border(loc, 1e-10); + assert(PMP::is_on_face_border(loc, g)); +} + +template +void test_constructions(const G& g, CGAL::Random& rnd) +{ + std::cout << " test constructions..." << std::endl; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename PMP::internal::Locate_types::descriptor_variant descriptor_variant; + + typedef typename boost::property_map_value::type Point; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + + typedef typename PMP::internal::Locate_types::Barycentric_coordinates Barycentric_coordinates; + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + typedef typename boost::property_map::const_type VPM; + VPM vpm = CGAL::get_const_property_map(boost::vertex_point, g); + + face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + halfedge_descriptor h = halfedge(f, g); + vertex_descriptor v = source(h, g); + + Point p = get(vpm, v); + Point q = get(vpm, target(h, g)); + Point r = get(vpm, target(next(h, g), g)); + + Barycentric_coordinates bar; + Face_location loc; + loc.first = f; + + // --------------------------------------------------------------------------- + bar = PMP::barycentric_coordinates(p, q, r, p, Kernel()); + assert(is_equal(bar[0], FT(1)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(0))); + bar = PMP::barycentric_coordinates(p, q, r, q, Kernel()); + assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(1)) && is_equal(bar[2], FT(0))); + bar = PMP::barycentric_coordinates(p, q, r, r, Kernel()); + assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(1))); + + bar = PMP::barycentric_coordinates(p, q, r, CGAL::midpoint(p, q), Kernel()); + assert(is_equal(bar[0], FT(0.5)) && is_equal(bar[1], FT(0.5)) && is_equal(bar[2], FT(0))); + + int n = 1e2; + while(n --> 0) // :) + { + const FT a = rnd.get_double(-1., 1.); + const FT b = rnd.get_double(-1., 1.); + const FT c = 1. - a - b; + + Point bp = CGAL::barycenter(p, a, q, b, r, c); + bar = PMP::barycentric_coordinates(p, q, r, bp); + assert(is_equal(bar[0], a) && is_equal(bar[1], b) && is_equal(bar[2], c)); + + loc.second = bar; + assert(CGAL::squared_distance(bp, PMP::location_to_point(loc, g)) < std::numeric_limits::epsilon()); + } + + // --------------------------------------------------------------------------- + loc = std::make_pair(f, CGAL::make_array(FT(0.3), FT(0.4), FT(0.3))); + descriptor_variant dv = PMP::get_descriptor_from_location(loc, g); + const face_descriptor* fd = boost::get(&dv); + assert(fd); + + loc = std::make_pair(f, CGAL::make_array(FT(0.5), FT(0.5), FT(0))); + dv = PMP::get_descriptor_from_location(loc, g); + const halfedge_descriptor* hd = boost::get(&dv); + assert(hd); + + loc = std::make_pair(f, CGAL::make_array(FT(1), FT(0), FT(0))); + dv = PMP::get_descriptor_from_location(loc, g); + assert(bool(boost::get(&dv))); + // --------------------------------------------------------------------------- + + Point s = PMP::location_to_point(loc, g, CGAL::parameters::all_default()); + s = PMP::location_to_point(loc, g); + assert(s == get(vpm, source(halfedge(f, g), g))); +} + +template +void test_random_entities(const G& g, CGAL::Random& rnd) +{ + std::cout << " test random entities..." << std::endl; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + vertex_descriptor v; + halfedge_descriptor h; + edge_descriptor e; + face_descriptor f; + + // --------------------------------------------------------------------------- + v = PMP::random_vertex_in_mesh(g, rnd); + assert(v != boost::graph_traits::null_vertex()); + + h = PMP::random_halfedge_in_mesh(g, rnd); + assert(h != boost::graph_traits::null_halfedge()); + + e = PMP::random_edge_in_mesh(g, rnd); + // assert(e != boost::graph_traits::null_edge()); + + f = PMP::random_face_in_mesh(g, rnd); + assert(f != boost::graph_traits::null_face()); + + // --------------------------------------------------------------------------- + h = PMP::random_halfedge_in_face(f, g, rnd); + assert(h != boost::graph_traits::null_halfedge()); + assert(face(h, g) == f); + + v = PMP::random_vertex_in_face(f, g, rnd); + assert(v != boost::graph_traits::null_vertex()); + + // could use vertices_around_face, but it's the point is not to + bool has_vertex = false; + halfedge_descriptor done = h; + do + { + if(target(h, g) == v) + { + has_vertex = true; + break; + } + + h = next(h, g); + } + while(h != done); + assert(has_vertex); + + // --------------------------------------------------------------------------- + Face_location loc; + loc.first = f; + + int nn = 1e2; + while(nn --> 0) + { + loc = PMP::random_location_on_mesh(g, rnd); + assert(loc.first != boost::graph_traits::null_face()); + assert(loc.second[0] >= 0.0 && loc.second[0] <= 1.0 && + loc.second[1] >= 0.0 && loc.second[1] <= 1.0 && + loc.second[2] >= 0.0 && loc.second[2] <= 1.0); + + loc = PMP::random_location_on_face(f, g, rnd); + assert(loc.first == f); + assert(loc.second[0] >= 0.0 && loc.second[0] <= 1.0 && + loc.second[1] >= 0.0 && loc.second[1] <= 1.0 && + loc.second[2] >= 0.0 && loc.second[2] <= 1.0); + + loc = PMP::random_location_on_halfedge(h, g, rnd); + assert(loc.first == face(h, g)); + assert(loc.second[0] >= 0.0 && loc.second[0] <= 1.0 && + loc.second[1] >= 0.0 && loc.second[1] <= 1.0 && + loc.second[2] >= 0.0 && loc.second[2] <= 1.0); + int h_id = PMP::halfedge_index_in_face(h, g); + assert(loc.second[(h_id+2)%3] == 0.0); + } +} + +template +void test_helpers(const G& g, CGAL::Random& rnd) +{ + std::cout << " test helpers..." << std::endl; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + halfedge_descriptor h = halfedge(f, g); + vertex_descriptor v = source(h, g); + + // --------------------------------------------------------------------------- + // Local index + int pos = PMP::vertex_index_in_face(v, f, g); + assert(pos == 0); + pos = PMP::vertex_index_in_face(target(h, g), f, g); + assert(pos == 1); + pos = PMP::vertex_index_in_face(target(next(h, g), g), f, g); + assert(pos == 2); + + pos = PMP::halfedge_index_in_face(h, g); + assert(pos == 0); + pos = PMP::halfedge_index_in_face(next(h, g), g); + assert(pos == 1); + pos = PMP::halfedge_index_in_face(prev(h, g), g); + assert(pos == 2); + + // --------------------------------------------------------------------------- + // Incident faces + Face_location loc = PMP::random_location_on_face(f, g, rnd); + std::set s; + PMP::internal::incident_faces(loc, g, std::inserter(s, s.begin())); + assert(PMP::is_on_face_border(loc, g) || s.size() == 1); + + loc = PMP::random_location_on_halfedge(h, g, rnd); + std::vector vec; + PMP::internal::incident_faces(loc, g, std::back_inserter(vec)); + assert(PMP::is_on_vertex(loc, source(h, g), g) || PMP::is_on_vertex(loc, target(h, g), g) || vec.size() == 2); + + // --------------------------------------------------------------------------- + // Common halfedge + assert(halfedge(f, g) == PMP::common_halfedge(f, f, g)); + + for(int i=0; i<100; ++i) + { + face_descriptor f2 = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + + if(f == f2) + continue; + + assert(is_triangle(halfedge(f, g), g) && is_triangle(halfedge(f2, g), g)); + std::set vertices; + + BOOST_FOREACH(vertex_descriptor vd, CGAL::vertices_around_face(halfedge(f, g), g)) { + vertices.insert(vd); + } + + BOOST_FOREACH(vertex_descriptor vd, CGAL::vertices_around_face(halfedge(f2, g), g)) { + vertices.insert(vd); + } + + boost::optional ohd = PMP::common_halfedge(f, f2, g); + if(ohd != boost::none) + { + // common edge means two common vertices and since faces are different, there are 4 vertices + assert(vertices.size() == 4); + } + } +} + +template +void test_predicates(const G& g, CGAL::Random& rnd) +{ + std::cout << " test predicates..." << std::endl; + + typedef typename boost::property_map_value::type Point; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + halfedge_descriptor h = halfedge(f, g); + vertex_descriptor v = source(h, g); + + // --------------------------------------------------------------------------- + Face_location loc(f, CGAL::make_array(FT(1), FT(0), FT(0))); + assert(PMP::is_on_vertex(loc, v, g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(1), FT(0))); + assert(PMP::is_on_vertex(loc, target(h, g), g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1))); + assert(PMP::is_on_vertex(loc, target(next(h, g), g), g)); + loc = Face_location(f, CGAL::make_array(FT(-1.), FT(1), FT(1))); + assert(!PMP::is_on_vertex(loc, target(next(h, g), g), g)); + + // --------------------------------------------------------------------------- + loc = Face_location(f, CGAL::make_array(FT(0.5), FT(0.5), FT(0))); + assert(PMP::is_on_halfedge(loc, h, g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(0.5), FT(0.5))); + assert(PMP::is_on_halfedge(loc, next(h, g), g)); + loc = Face_location(f, CGAL::make_array(FT(-0.5), FT(1.5), FT(0))); + assert(!PMP::is_on_halfedge(loc, h, g)); + loc = Face_location(f, CGAL::make_array(FT(0.1), FT(-0.6), FT(1.5))); + assert(!PMP::is_on_halfedge(loc, h, g)); + + // --------------------------------------------------------------------------- + loc = Face_location(f, CGAL::make_array(FT(0.3), FT(0.3), FT(0.4))); + assert(PMP::is_in_face(loc, g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1))); + assert(PMP::is_in_face(loc, g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(2), FT(-1.))); + assert(!PMP::is_in_face(loc, g)); + + // --------------------------------------------------------------------------- + loc = Face_location(f, CGAL::make_array(FT(0.3), FT(0.3), FT(0.4))); + assert(!PMP::is_on_face_border(loc, g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(0.6), FT(0.4))); + assert(PMP::is_on_face_border(loc, g)); + loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1))); + assert(PMP::is_on_face_border(loc, g)); + loc = Face_location(f, CGAL::make_array(FT(-0.2), FT(0), FT(1.2))); + assert(!PMP::is_on_face_border(loc, g)); + + // --------------------------------------------------------------------------- + int max = 1e3, counter = 0; + typename boost::graph_traits::halfedge_iterator hit, hend; + boost::tie(hit, hend) = halfedges(g); + for(; hit!=hend; ++hit) + { + const halfedge_descriptor h = *hit; + if(face(h, g) == boost::graph_traits::null_face()) + continue; + + const int id_of_h = PMP::halfedge_index_in_face(h, g); + const face_descriptor f = face(h, g); + loc.first = f; + + loc.second[id_of_h] = 1.; + loc.second[(id_of_h+1)%3] = 0.; + loc.second[(id_of_h+2)%3] = 0.; + boost::optional opt_hd = CGAL::is_border(source(h, g), g); + assert(PMP::is_on_mesh_border(loc, g) == (opt_hd != boost::none)); + + loc.second[id_of_h] = 0.5; + loc.second[(id_of_h+1)%3] = 0.5; + assert(PMP::is_on_mesh_border(loc, g) == CGAL::is_border(edge(h, g), g)); + + // Even if the point does lie on the border of the mesh, 'false' is returned because + // another face descriptor should be used. + loc.second[id_of_h] = -0.5; + loc.second[(id_of_h+1)%3] = 1.5; + assert(!PMP::is_on_mesh_border(loc, g)); + + if(++counter > max) + break; + } +} + +template +void test_locate_in_face(const G& g, CGAL::Random& rnd) +{ + std::cout << " test locate_in_face()..." << std::endl; + + typedef typename boost::property_map_value::type Point; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + typedef typename boost::property_map::const_type VertexPointMap; + VertexPointMap vpm = CGAL::get_const_property_map(boost::vertex_point, g); + + const face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + const halfedge_descriptor h = halfedge(f, g); + const vertex_descriptor v = target(h, g); + + Face_location loc; + typename PMP::internal::Locate_types::FT a = 0.1; + Point p = get(vpm, v); + + loc = PMP::locate_in_face(v, g); + assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + + loc = PMP::locate_in_face(v, f, g); + assert(loc.first == f); + assert(is_equal(loc.second[0], FT(0)) && is_equal(loc.second[1], FT(1)) && is_equal(loc.second[2], FT(0))); + + loc = PMP::locate_in_face(h, a, g); + const int h_id = PMP::halfedge_index_in_face(h, g); + assert(loc.first == f && is_equal(loc.second[(h_id+2)%3], FT(0))); + + loc = PMP::locate_in_face(p, f, g, CGAL::parameters::all_default()); + int v_id = PMP::vertex_index_in_face(v, f, g); + assert(loc.first == f && is_equal(loc.second[v_id], FT(1))); + + loc = PMP::locate_in_face(p, f, g); + v_id = PMP::vertex_index_in_face(v, f, g); + assert(loc.first == f && is_equal(loc.second[v_id], FT(1))); + + // --------------------------------------------------------------------------- + loc.second[0] = 0.2; + loc.second[1] = 0.8; + loc.second[2] = 0.; + + halfedge_descriptor neigh_hd = opposite(halfedge(f, g), g); + face_descriptor neigh_f = face(neigh_hd, g); + int neigh_hd_id = PMP::halfedge_index_in_face(neigh_hd, g); + Face_location neigh_loc; + neigh_loc.first = neigh_f; + neigh_loc.second[neigh_hd_id] = 0.3; + neigh_loc.second[(neigh_hd_id+1)%3] = 0.7; + neigh_loc.second[(neigh_hd_id+2)%3] = 0.; + + if(neigh_f != boost::graph_traits::null_face()) + { + PMP::locate_in_adjacent_face(loc, neigh_f, g); + + assert(PMP::locate_in_common_face(loc, neigh_loc, g)); + + assert(PMP::locate_in_common_face(loc, p, neigh_loc, g)); + assert(PMP::locate_in_common_face(loc, p, neigh_loc, g, 1e-10)); + } +} + +template +void test_locate_with_AABB_tree(const G& g, CGAL::Random& rnd) +{ + std::cout << " test locate_with_AABB_tree()..." << std::endl; + + typedef typename boost::property_map_value::type Point; + + typedef typename boost::property_map::const_type VertexPointMap; + + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + typedef typename Kernel::Ray_3 Ray_3; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + halfedge_descriptor h = halfedge(f, g); + vertex_descriptor v = target(h, g); + + // --------------------------------------------------------------------------- + typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; + typedef CGAL::AABB_traits AABB_face_graph_traits; + + CGAL::AABB_tree tree_a; + VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g); + typename AABB_face_graph_traits::Point_3 p3_a = get(vpm_a, v); + // --------------------------------------------------------------------------- + typedef typename Kernel::Point_2 Point_2; + typedef PMP::internal::Point_to_Point_3 Point_to_Point_3; + typedef PMP::internal::Point_to_Point_3_VPM VPM; + typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive_with_VPM; + typedef CGAL::AABB_traits AABB_face_graph_traits_with_VPM; + + CGAL::AABB_tree tree_b; + typename AABB_face_graph_traits::Point_3 p3_b = Point_to_Point_3()(Point_2(0., 0.)); + VPM vpm_b(g); + // --------------------------------------------------------------------------- + + PMP::build_AABB_tree(g, tree_a); + assert(tree_a.size() == num_faces(g)); + + PMP::build_AABB_tree(g, tree_b, CGAL::parameters::vertex_point_map(vpm_b)); + assert(tree_b.size() == num_faces(g)); + + Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g); + assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + + loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); + assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + + // --------------------------------------------------------------------------- + loc = PMP::locate(p3_a, g); + assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + assert(PMP::is_in_face(loc, g)); + + loc = PMP::locate_with_AABB_tree(p3_b, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); + assert(PMP::is_in_face(loc, g)); + + loc = PMP::locate(p3_b, g, CGAL::parameters::vertex_point_map(vpm_b)); + assert(PMP::is_in_face(loc, g)); + + // --------------------------------------------------------------------------- + Ray_3 r3 = random_ray >(tree_a, rnd); + loc = PMP::locate_with_AABB_tree(r3, tree_a, g); + if(loc.first != boost::graph_traits::null_face()) + assert(PMP::is_in_face(loc, g)); + + loc = PMP::locate_with_AABB_tree(r3, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); +} + +template +void test_locate(const G & g, CGAL::Random& rnd) +{ + assert(num_vertices(g) != 0 && num_faces(g) != 0); + + test_snappers(g); + test_constructions(g, rnd); + test_random_entities(g, rnd); + test_helpers(g, rnd); + test_predicates(g, rnd); + test_locate_in_face(g, rnd); + test_locate_with_AABB_tree(g, rnd); +} + +template +void test_2D_mesh(const char* fname, CGAL::Random& rnd) +{ + typedef CGAL::Regular_triangulation_2 RT; + RT tr; + + std::cout << "Testing Regular_triangulation_2 " << fname << "..." << std::endl; + + // @fixme +// std::ifstream input(fname); +// CGAL::read_off(input, tr); + + test_locate(tr, rnd); + + // @todo some additionnal tests of locate(), comparing it with tr.locate(); (?) +} + +template +void test_surface_mesh(const char* fname, CGAL::Random& rnd) +{ + typedef typename K::Point_3 Point; + typedef CGAL::Surface_mesh Mesh; + + std::cout << "Testing Surface_mesh " << fname << "..." << std::endl; + std::cout << "Kernel: " << typeid(K()).name() << std::endl; + + std::ifstream input(fname); + Mesh tm; + if(!input || !(input >> tm)) + { + std::cerr << "Error: cannot read file."; + return; + } + + test_locate(tm, rnd); +} + +template +void test_polyhedron(const char* fname, CGAL::Random& rnd) +{ + typedef CGAL::Polyhedron_3 Polyhedron; + + std::cout << "Testing Polyhedron_3 " << fname << "..." << std::endl; + std::ifstream input(fname); + Polyhedron poly; + if(!input || !(input >> poly)) + { + std::cerr << "Error: cannot read file."; + return; + } + + test_locate(poly, rnd); +} + +int main() +{ + std::cout.precision(17); + std::cout << std::fixed; + + typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; + + typedef typename CGAL::Kernel_traits >::type EPICKQUESTIONMARK; + CGAL_static_assertion((std::is_same::value)); + +#if 0 + typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; + +// CGAL::Random rnd(1527774218); // if needed to debug with a fixed seed + CGAL::Random rnd(CGAL::get_default_random()); + + std::cout << "seed: " << rnd.get_seed() << std::endl; + + test_2D_mesh("data/two_tris_collinear.off", rnd); +// test_2D_mesh("data/two_tris_collinear.off", rnd); + +// test_surface_mesh("data/mech-holes-shark.off", rnd); +// test_surface_mesh("data/mech-holes-shark.off", rnd); + +// test_polyhedron("data-coref/elephant_split_1.off", rnd); +// test_polyhedron("data-coref/elephant_split_2.off", rnd); +#endif + + return 0; +} From 28a210837e0c1fdb62e763adcd661a26c10f6574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Apr 2019 08:39:52 +0200 Subject: [PATCH 04/68] Fixed missing vertex point pmap (+ property) in RT2 graph traits --- .../boost/graph/graph_traits_Regular_triangulation_2.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h index 6c5fc6c41c6..f6616fb855f 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h @@ -280,6 +280,16 @@ namespace CGAL { }; }; + template + struct graph_has_property, CGAL::vertex_point_t> + : CGAL::Tag_true {}; + + template + inline RT2_vertex_point_map + get(boost::vertex_point_t, const Regular_triangulation_2&) { + RT2_vertex_point_map m; + return m; + } } // namespace CGAL From 09df9b5622b576d35b58dacab3cc9e6c5c8b46f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Apr 2019 17:14:52 +0200 Subject: [PATCH 05/68] Added some common graph traits for all 2D triangulations --- .../graph/graph_traits_2D_triangulation.h | 679 ++++++++++++++++++ 1 file changed, 679 insertions(+) create mode 100644 Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h new file mode 100644 index 00000000000..1fadb1adf86 --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h @@ -0,0 +1,679 @@ +// Copyright (c) 2007, 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Andreas Fabri, Fernando Cacciola + +#ifndef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS + #error CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS is not defined +#endif + +#ifndef CGAL_2D_TRIANGULATION + #error CGAL_2D_TRIANGULATION is not defined +#endif + +#ifndef CGAL_2D_TRIANGULATION_TEMPLATES + #error CGAL_2D_TRIANGULATION_TEMPLATES is not defined +#endif + +#include + +// include this to avoid a VC15 warning +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// Small include guard is required for that class +#ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION +#define CGAL_GRAPH_TRAITS_2D_TRIANGULATION + +namespace CGAL { + +namespace detail { + +template +struct T2_halfedge_descriptor +{ + typedef typename Tr::Face_handle face_descriptor; + face_descriptor first; + int second; + operator std::pair() { return std::make_pair(first, second); } + + T2_halfedge_descriptor() : first(), second(0) { } + T2_halfedge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } + T2_halfedge_descriptor(face_descriptor fd, int i) : first(fd), second(i) { } + + friend std::size_t hash_value(const T2_halfedge_descriptor& h) + { + return hash_value(h.first); + } + + bool operator==(const T2_halfedge_descriptor& other) const + { + return (first == other.first) && (second == other.second); + } + + bool operator!=(const T2_halfedge_descriptor& other) const + { + return (first != other.first) || (second != other.second); + } + + bool operator<(const T2_halfedge_descriptor& other) const + { + if(first < other.first) return true; + if(first > other.first) return false; + return second < other.second; + } +}; + +template +class T2_vertex_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename Tr::Vertex_handle key_type; + + T2_vertex_id_map() { } + + long operator[](key_type vh) const { return vh->id(); } +}; + +template +class T2_vertex_point_map +{ +public: + typedef boost::lvalue_property_map_tag category; + typedef typename Tr::Point value_type; + typedef value_type& reference; + typedef typename Tr::Vertex_handle key_type; + + friend reference get(T2_vertex_point_map, key_type vh) + { + return vh->point(); + } + friend void put(T2_vertex_point_map, key_type vh, reference v) + { + vh->point() = v; + } + reference operator[](key_type vh) const { return vh->point(); } +}; + +template +class T2_edge_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename Tr::Edge key_type; + + T2_edge_id_map() { } + + long operator[](key_type e) const { return (3 * e.first.id()) + e.second; } +}; + +template +class T2_edge_weight_map + : public boost::put_get_helper > +{ +private: + const Tr& tr; + +public: + typedef boost::readable_property_map_tag category; + typedef typename Tr::Geom_traits::FT value_type; + typedef value_type reference; + typedef typename Tr::Edge key_type; + + T2_edge_weight_map(const Tr& tr_) : tr(tr_) { } + + value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); } +}; + +template +struct T2_property_map { }; + +template +struct T2_property_map +{ + typedef detail::T2_vertex_id_map type; + typedef detail::T2_vertex_id_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_vertex_point_map type; + typedef detail::T2_vertex_point_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_edge_id_map type; + typedef detail::T2_edge_id_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_edge_weight_map type; + typedef detail::T2_edge_weight_map const_type; +}; + +} // namespace detail +} // namespace CGAL + +namespace std { + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4099) // For VC10 it is class hash +#endif + +#ifndef CGAL_CFG_NO_STD_HASH + +template < class Tr> +struct hash > +{ + std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor& e) const + { + return hash_value(e); + } +}; + +#endif // CGAL_CFG_NO_STD_HASH + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +} // namespace std + +#endif // CGAL_GRAPH_TRAITS_2D_TRIANGULATION + +namespace boost { + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +struct graph_traits< CGAL_2D_TRIANGULATION > +{ + typedef CGAL_2D_TRIANGULATION Triangulation; + + struct T2_graph_traversal_category : + public virtual bidirectional_graph_tag, + public virtual adjacency_graph_tag, + public virtual edge_list_graph_tag, + public virtual vertex_list_graph_tag { }; + + typedef typename Triangulation::Vertex_handle vertex_descriptor; + typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::detail::Edge edge_descriptor; + typedef typename Triangulation::Face_handle face_descriptor; + + typedef CGAL::Prevent_deref vertex_iterator; + typedef typename Triangulation::All_halfedges_iterator halfedge_iterator; + typedef typename Triangulation::All_edges_iterator edge_iterator; + typedef CGAL::Prevent_deref face_iterator; + + typedef CGAL::Counting_iterator< + CGAL::detail::Out_edge_circulator< + typename Triangulation::Edge_circulator, + edge_descriptor>, + edge_descriptor> out_edge_iterator; + typedef CGAL::Counting_iterator< + CGAL::detail::In_edge_circulator< + typename Triangulation::Edge_circulator, + edge_descriptor>, + edge_descriptor> in_edge_iterator; + + typedef CGAL::Counting_iterator Incident_vertices_iterator; + typedef Incident_vertices_iterator adjacency_iterator; + + typedef undirected_tag directed_category; + typedef disallow_parallel_edge_tag edge_parallel_category; + typedef T2_graph_traversal_category traversal_category; + + typedef typename Triangulation::size_type size_type; + typedef size_type vertices_size_type; + typedef size_type halfedges_size_type; + typedef size_type edges_size_type; + typedef size_type faces_size_type; + typedef size_type degree_size_type; + + // nulls + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } +}; + +} // namespace boost + +namespace CGAL { + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +next(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(e.first, g.ccw(e.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +prev(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(e.first, g.cw(e.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +opposite(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + return g.mirror_edge(e); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor +source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + return e.first->vertex(g.ccw(e.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor +target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + return e.first->vertex(g.cw(e.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor +source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + return e.first->vertex(g.ccw(e.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor +target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION& g) +{ + return e.first->vertex(g.cw(e.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor +face(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION&) +{ + return e.first; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor f, + const CGAL_2D_TRIANGULATION&) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(f,0); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; + face_descriptor fd = v->face(); + int i = fd->index(v); + return halfedge_descriptor(fd, g.ccw(i)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, + const CGAL_2D_TRIANGULATION&) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(e.first, e.second); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor +edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, + const CGAL_2D_TRIANGULATION&) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + return edge_descriptor(e.first, e.second); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +std::pair::edge_descriptor, +bool> +edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + if(c != 0) { + do { + // find the index of the other vertex of *c + int indv = 3 - c->first->index(u) - c->second; + if(c->first->vertex(indv) == v) + return std::make_pair(edge_descriptor(c->first, c->second), true); + } while (++c != done); + } + + return std::make_pair(edge_descriptor(), false); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +std::pair::halfedge_descriptor, +bool> +halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; + + std::pair eb = edge(u, v, g); + + if(!eb.second) + return std::make_pair(halfedge_descriptor(), false); + + const edge_descriptor& e = eb.first; + + if(e.first->vertex(g.ccw(e.first->index(u))) == v) + { + return std::make_pair(halfedge_descriptor(e.first, e.second), true); + } + else + { + face_descriptor nf = e.first->neighbor(e.second); + int idx = nf->index(e.first); + return std::make_pair(halfedge_descriptor(nf, idx), true); + } +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::vertex_iterator> +vertices(const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_iterator + Iter; + return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::edge_iterator> +edges(const CGAL_2D_TRIANGULATION& g) +{ + return make_range(g.all_edges_begin(), g.all_edges_end()); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::halfedge_iterator > +halfedges(const CGAL_2D_TRIANGULATION& g) +{ + return make_range(g.all_halfedges_begin(), g.all_halfedges_end()); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::face_iterator > +faces(const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_iterator + Iter; + return make_range( Iter(g.all_faces_begin()), Iter(g.all_faces_end()) ); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +out_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + if(c != 0) + { + do { + ++deg; + } while (++c != done); + } + return deg; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::out_edge_iterator > +out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION > + ::out_edge_iterator Iter; + + return make_range(Iter(ec), Iter(ec, out_deg)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::in_edge_iterator > +in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION > + ::in_edge_iterator Iter; + return make_range(Iter(ec), Iter(ec,out_deg)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::adjacency_iterator> +adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename CGAL_2D_TRIANGULATION::Vertex_circulator vc = out_edge_iterator(u, u.face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter; + return make_range( Iter(vc), Iter(vc,out_deg) ); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertices_size_type +num_vertices(const CGAL_2D_TRIANGULATION& g) +{ + return g.tds().number_of_vertices(); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edges_size_type +num_edges(const CGAL_2D_TRIANGULATION& g) +{ + return g.tds().number_of_vertices() + g.tds().number_of_faces() - 2; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedges_size_type +num_halfedges(const CGAL_2D_TRIANGULATION& g) +{ + return num_edges(g) * 2; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::faces_size_type +num_faces(const CGAL_2D_TRIANGULATION& g) +{ + return g.tds().number_of_faces(); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +in_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + if(c != 0) + { + do { + ++deg; + } while (++c != done); + } + return deg; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + if(c != 0) + { + do { + ++deg; + } while (++c != done); + } + return deg; +} + +// property maps +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > +get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > +get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > +get(boost::edge_index_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > +get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g) +{ + detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); + return m; +} + +} // namespace CGAL + +namespace boost { + +// g++ 'enumeral_type' in template unification not implemented workaround +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag> +struct property_map +{ + typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +// see struct property_map in Polyehdron for an explanation +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag> +struct property_map +{ + typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +} // namespace boost + +namespace CGAL { + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key> +inline +typename boost::property_traits< +typename boost::property_map< CGAL_2D_TRIANGULATION, PropertyTag>::const_type>::value_type +get(PropertyTag p, const CGAL_2D_TRIANGULATION& g, const Key& key) +{ + return get(get(p, g), key); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key, class Value> +inline void +put(PropertyTag p, CGAL_2D_TRIANGULATION& g, + const Key& key, const Value& value) +{ + typedef typename boost::property_map::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} + +} // namespace CGAL + +namespace boost { + +// What are those needed for ??? +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +struct edge_property_type +{ + typedef void type; +}; + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +struct vertex_property_type +{ + typedef void type; +}; + +} // namespace boost + +#undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS +#undef CGAL_2D_TRIANGULATION +#undef CGAL_2D_TRIANGULATION_TEMPLATES From 811810c02c78e4120eb219a67ec35bdaa3e601f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 19 Apr 2019 17:17:09 +0200 Subject: [PATCH 06/68] Switch the three main triangulations' graph traits to a common version --- .../graph_traits_Delaunay_triangulation_2.h | 152 +--- .../graph_traits_Regular_triangulation_2.h | 304 +------- .../graph/graph_traits_Triangulation_2.h | 668 +----------------- 3 files changed, 15 insertions(+), 1109 deletions(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h index 4ce347b7e6f..e582f0526d4 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h @@ -14,163 +14,23 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ -// +// // // Author(s) : Andreas Fabri, Fernando Cacciola #ifndef CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H #define CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H -// include this to avoid a VC15 warning -#include - -#include -#include -#include -#include -#include #include // The functions and classes in this file allows the user to // treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Delaunay_triangulation_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS +#define CGAL_2D_TRIANGULATION CGAL::Delaunay_triangulation_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS +#include -namespace boost { - - template - struct graph_traits< CGAL::Delaunay_triangulation_2 > { - - struct DT2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef CGAL::Delaunay_triangulation_2 Delaunay_triangulation; - - typedef typename CGAL::Delaunay_triangulation_2::Vertex_handle vertex_descriptor; - typedef typename CGAL::Triangulation_2::Face_handle face_descriptor; - typedef CGAL::detail::Edge, typename CGAL::Delaunay_triangulation_2::Edge> edge_descriptor; - typedef typename CGAL::Delaunay_triangulation_2::All_edges_iterator edge_iterator; - - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - - typedef typename Delaunay_triangulation::All_halfedges_iterator halfedge_iterator; - - typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef DT2_graph_traversal_category traversal_category; - typedef typename Delaunay_triangulation::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type halfedges_size_type; - typedef size_type edges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - -namespace CGAL { - - - - template - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::vertex_descriptor - source(typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::edge_descriptor e, - const CGAL::Delaunay_triangulation_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::vertex_descriptor - target(typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::edge_descriptor e, - const CGAL::Delaunay_triangulation_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - - template - inline std::pair< - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::out_edge_iterator, - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::out_edge_iterator > - out_edges( - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::vertex_descriptor u, - const CGAL::Delaunay_triangulation_2& g) - { - typename CGAL::Delaunay_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Delaunay_triangulation_2 > - ::out_edge_iterator Iter; - - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline std::pair< - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::in_edge_iterator, - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::in_edge_iterator > - in_edges( - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::vertex_descriptor u, - const CGAL::Delaunay_triangulation_2& g) - { - typename CGAL::Delaunay_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Delaunay_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Delaunay_triangulation_2 > - ::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - -} // namespace CGAL - -namespace boost { - - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::T2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyhedron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::T2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - - -#endif // CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H +#endif // CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h index f6616fb855f..591f6dc71c5 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h @@ -14,317 +14,23 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ -// +// // // Author(s) : Andreas Fabri, Fernando Cacciola #ifndef CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H #define CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H -// include this to avoid a VC15 warning -#include - -#include -#include -#include -#include -#include #include // The functions and classes in this file allows the user to // treat a CGAL Regular_triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Regular_triangulation_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS +#define CGAL_2D_TRIANGULATION CGAL::Regular_triangulation_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS - -namespace boost { - - template - struct graph_traits< CGAL::Regular_triangulation_2 > { - - struct DT2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef CGAL::Regular_triangulation_2 Regular_triangulation; - - typedef typename CGAL::Regular_triangulation_2::Vertex_handle vertex_descriptor; - typedef typename CGAL::Triangulation_2::Face_handle face_descriptor; - typedef CGAL::detail::Edge, typename CGAL::Regular_triangulation_2::Edge> edge_descriptor; - typedef typename CGAL::Regular_triangulation_2::All_edges_iterator edge_iterator; - - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - - typedef typename Regular_triangulation::All_halfedges_iterator halfedge_iterator; - - typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef DT2_graph_traversal_category traversal_category; - typedef typename Regular_triangulation::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - -namespace CGAL { - - template - inline Iterator_range >::vertex_iterator> - vertices(const Regular_triangulation_2& g) - { - typedef typename boost::graph_traits< Regular_triangulation_2 >::vertex_iterator - Iter; - return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); - } - - - template - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::vertex_descriptor - source(typename boost::graph_traits< CGAL::Regular_triangulation_2 >::edge_descriptor e, - const CGAL::Regular_triangulation_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::vertex_descriptor - target(typename boost::graph_traits< CGAL::Regular_triangulation_2 >::edge_descriptor e, - const CGAL::Regular_triangulation_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - - template - inline std::pair< - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::out_edge_iterator, - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::out_edge_iterator > - out_edges( - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::vertex_descriptor u, - const CGAL::Regular_triangulation_2& g) - { - typename CGAL::Regular_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Regular_triangulation_2 > - ::out_edge_iterator Iter; - - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline std::pair< - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::in_edge_iterator, - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::in_edge_iterator > - in_edges( - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::vertex_descriptor u, - const CGAL::Regular_triangulation_2& g) - { - typename CGAL::Regular_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Regular_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Regular_triangulation_2 > - ::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - - - - // property maps - template - class RT2_vertex_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Regular_triangulation_2::Vertex_handle key_type; - - RT2_vertex_id_map() - {} - - long operator[](key_type vh) const { - return vh->id(); - } - }; - - template - class RT2_vertex_point_map - { - public: - typedef boost::lvalue_property_map_tag category; - typedef typename Tds::Vertex::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Regular_triangulation_2::Vertex_handle key_type; - - friend reference get(RT2_vertex_point_map, key_type vh) - { - return vh->point(); - } - friend void put(RT2_vertex_point_map, key_type vh, reference v) - { - vh->point()=v; - } - reference operator[](key_type vh) const { - return vh->point(); - } - }; - - - template - class RT2_edge_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Regular_triangulation_2::Edge key_type; - - RT2_edge_id_map() - {} - - long operator[](key_type e) const { - return (3 * e.first.id()) + e.second; - } - }; - - - template - class RT2_edge_weight_map - : public boost::put_get_helper > - { - private: - const CGAL::Regular_triangulation_2& tr; - public: - typedef boost::readable_property_map_tag category; - typedef typename Gt::FT value_type; - typedef value_type reference; - typedef typename CGAL::Regular_triangulation_2::Edge key_type; - - RT2_edge_weight_map(const CGAL::Regular_triangulation_2& tr_) - : tr(tr_) - { } - - value_type operator[](key_type e) const { - return approximate_sqrt(tr.segment(e).squared_length()); - } - }; - - template - inline RT2_edge_weight_map - get(boost::edge_weight_t, const CGAL::Regular_triangulation_2& g) { - RT2_edge_weight_map m(g); - return m; - } - - template - struct RT2_property_map { }; - - template <> - struct RT2_property_map { - template - struct bind_ { - typedef RT2_vertex_id_map type; - typedef RT2_vertex_id_map const_type; - }; - }; - - - - template <> - struct RT2_property_map { - template - struct bind_ { - typedef RT2_vertex_point_map type; - typedef RT2_vertex_point_map const_type; - }; - }; - - - template <> - struct RT2_property_map { - template - struct bind_ { - typedef RT2_edge_id_map type; - typedef RT2_edge_id_map const_type; - }; - }; - - - template <> - struct RT2_property_map { - template - struct bind_ { - typedef RT2_edge_weight_map type; - typedef RT2_edge_weight_map const_type; - }; - }; - - template - struct graph_has_property, CGAL::vertex_point_t> - : CGAL::Tag_true {}; - - template - inline RT2_vertex_point_map - get(boost::vertex_point_t, const Regular_triangulation_2&) { - RT2_vertex_point_map m; - return m; - } - -} // namespace CGAL - -namespace boost { - - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::RT2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyhedron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::RT2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - +#include #endif // CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h index 0a901850a6d..38c6c89da19 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h @@ -21,676 +21,16 @@ #ifndef CGAL_GRAPH_TRAITS_TRIANGULATION_2_H #define CGAL_GRAPH_TRAITS_TRIANGULATION_2_H -#include - -// include this to avoid a VC15 warning -#include -#include -#include -#include -#include -#include - -#include #include -#include -#include // The functions and classes in this file allows the user to // treat a CGAL Triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Triangulation_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS +#define CGAL_2D_TRIANGULATION CGAL::Triangulation_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS -namespace CGAL { - - namespace detail { - - template - struct T2_halfedge_descriptor - { - typedef typename Tr::Face_handle face_descriptor; - face_descriptor first; - int second; - operator std::pair() { return std::make_pair(first,second); } - - T2_halfedge_descriptor() - : first(), second(0) - {} - - T2_halfedge_descriptor(const typename Tr::Edge& e) - : first(e.first), second(e.second) - {} - - T2_halfedge_descriptor(face_descriptor fd, int i) - : first(fd), second(i) - {} - - friend std::size_t hash_value(const T2_halfedge_descriptor& h) - { - return hash_value(h.first); - } - - bool operator==(const T2_halfedge_descriptor& other) const - { - return (first == other.first) && (second == other.second); - } - - bool operator!=(const T2_halfedge_descriptor& other) const - { - return (first != other.first) || (second != other.second); - } - - bool operator<(const T2_halfedge_descriptor& other) const - { - if(first < other.first) return true; - if(first > other.first) return false; - return second < other.second; - } - }; - - - } // namespace detail -} // namespace CGAL - -namespace boost { - - template - struct graph_traits< CGAL::Triangulation_2 > { - - struct T2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef CGAL::Triangulation_2 Triangulation; - - typedef typename CGAL::Triangulation_2::Vertex_handle vertex_descriptor; - typedef typename CGAL::Triangulation_2::Face_handle face_descriptor; - typedef CGAL::detail::Edge, typename CGAL::Triangulation_2::Edge> edge_descriptor; - typedef typename CGAL::Triangulation_2::All_edges_iterator edge_iterator; - - - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - - typedef typename Triangulation::All_halfedges_iterator halfedge_iterator; - - typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef T2_graph_traversal_category traversal_category; - typedef typename Triangulation::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - - -namespace CGAL { - - template - typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor - next(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first, g.ccw(e.second)); - } - - - template - typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor - prev(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first, g.cw(e.second)); - } - - - - template - typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor - opposite(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2& g) - { - - return g.mirror_edge(e); - } - - template - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor - source(typename boost::graph_traits< Triangulation_2 >::edge_descriptor e, - const Triangulation_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor - target(typename boost::graph_traits< Triangulation_2 >::edge_descriptor e, - const Triangulation_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - template - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor - source(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor - target(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - template - typename boost::graph_traits< Triangulation_2 >::face_descriptor - face(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2&) - { - return e.first; - } - - template - typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor - halfedge(typename boost::graph_traits< Triangulation_2 >::face_descriptor f, - const Triangulation_2&) - { - typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(f,0); - } - - template - typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor - halfedge(typename boost::graph_traits< Triangulation_2 >::vertex_descriptor v, - const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits< Triangulation_2 >::face_descriptor face_descriptor; - face_descriptor fd = v->face(); - int i = fd->index(v); - return halfedge_descriptor(fd,g.ccw(i)); - } - - template - typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor - halfedge(typename boost::graph_traits< Triangulation_2 >::edge_descriptor e, - const Triangulation_2&) - { - typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first,e.second); - } - - template - typename boost::graph_traits< Triangulation_2 >::edge_descriptor - edge(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, - const Triangulation_2&) - { - typedef typename boost::graph_traits< Triangulation_2 >::edge_descriptor edge_descriptor; - return edge_descriptor(e.first,e.second); - } - - template - std::pair >::edge_descriptor, - bool> - edge(typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor v, - const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::edge_descriptor edge_descriptor; - - typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); - if (c != 0) { - do { - // find the index of the other vertex of *c - int indv = 3 - c->first->index(u) - c->second; - if(c->first->vertex(indv) == v) - return std::make_pair(edge_descriptor(c->first, c->second), true); - } while (++c != done); - } - - return std::make_pair(edge_descriptor(), false); - } - - template - std::pair >::halfedge_descriptor, - bool> - halfedge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits< Triangulation_2 >::edge_descriptor edge_descriptor; - typedef typename boost::graph_traits< Triangulation_2 >::face_descriptor face_descriptor; - - std::pair eb = edge(u, v, g); - - if(!eb.second) - return std::make_pair(halfedge_descriptor(), false); - - const edge_descriptor& e = eb.first; - - if(e.first->vertex(g.ccw(e.first->index(u))) == v) - { - return std::make_pair(halfedge_descriptor(e.first, e.second), true); - } - else - { - face_descriptor nf = e.first->neighbor(e.second); - int idx = nf->index(e.first); - return std::make_pair(halfedge_descriptor(nf, idx), true); - } - } - - template - inline Iterator_range >::vertex_iterator> - vertices(const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::vertex_iterator - Iter; - return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); - } - - - template - inline Iterator_range >::edge_iterator> - edges(const Triangulation_2& g) - { - return make_range(g.all_edges_begin(), g.all_edges_end()); - } - - template - inline Iterator_range >::halfedge_iterator > - halfedges(const Triangulation_2& g) - { - return make_range(g.all_halfedges_begin(), g.all_halfedges_end()); - } - - template - inline Iterator_range >::face_iterator > - faces(const Triangulation_2& g) - { - typedef typename boost::graph_traits< Triangulation_2 >::face_iterator - Iter; - return make_range( Iter(g.all_faces_begin()), Iter(g.all_faces_end()) ); - } - - template - typename boost::graph_traits< Triangulation_2 >::degree_size_type - out_degree( - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - const Triangulation_2& g) - { - typename boost::graph_traits< Triangulation_2 >::degree_size_type deg = 0; - typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); - if ( c != 0) { - do { - ++deg; - } while (++c != done); - } - return deg; - } - - template - inline Iterator_range >::out_edge_iterator > - out_edges( - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - const Triangulation_2& g) - { - typename Triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< Triangulation_2 > - ::out_edge_iterator Iter; - - return make_range( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline Iterator_range >::in_edge_iterator > - in_edges( - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - const Triangulation_2& g) - { - typename Triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< Triangulation_2 > - ::in_edge_iterator Iter; - return make_range( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline Iterator_range >::adjacency_iterator> - adjacent_vertices( - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - const Triangulation_2& g) - { - typename Triangulation_2::Vertex_circulator vc = out_edge_iterator(u,u.face()); - typename boost::graph_traits< Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< Triangulation_2 > - ::adjacency_iterator Iter; - return make_range( Iter(vc), Iter(vc,out_deg) ); - } - - template - typename boost::graph_traits< Triangulation_2 >::vertices_size_type - num_vertices(const Triangulation_2& g) - { - return g.tds().number_of_vertices(); - } - - template - typename boost::graph_traits< Triangulation_2 >::edges_size_type - num_edges(const Triangulation_2& g) - { - - return g.tds().number_of_vertices() + g.tds().number_of_faces() - 2; - } - - template - typename boost::graph_traits< Triangulation_2 >::halfedges_size_type - num_halfedges(const Triangulation_2& g) - { - return num_edges(g) * 2; - } - - template - typename boost::graph_traits< Triangulation_2 >::faces_size_type - num_faces(const Triangulation_2& g) - { - return g.tds().number_of_faces(); - } - - template - typename boost::graph_traits< Triangulation_2 >::degree_size_type - in_degree( - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - const Triangulation_2& g) - { - typename boost::graph_traits< Triangulation_2 >::degree_size_type deg = 0; - typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); - if ( c != 0) { - do { - ++deg; - } while (++c != done); - } - return deg; - } - - template - typename boost::graph_traits< Triangulation_2 >::degree_size_type - degree( - typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, - const Triangulation_2& g) - { - typename boost::graph_traits< Triangulation_2 >::degree_size_type deg = 0; - typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); - if ( c != 0) { - do { - ++deg; - } while (++c != done); - } - return deg; - } - - - // property maps - template - class T2_vertex_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_2::Vertex_handle key_type; - - T2_vertex_id_map() - {} - - long operator[](key_type vh) const { - return vh->id(); - } - }; - - template - class T2_vertex_point_map - { - public: - typedef boost::lvalue_property_map_tag category; - typedef typename Tds::Vertex::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Triangulation_2::Vertex_handle key_type; - - friend reference get(T2_vertex_point_map, key_type vh) - { - return vh->point(); - } - friend void put(T2_vertex_point_map, key_type vh, reference v) - { - vh->point() = v; - } - reference operator[](key_type vh) const { - return vh->point(); - } - }; - - - template - class T2_edge_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_2::Edge key_type; - - T2_edge_id_map() - {} - - long operator[](key_type e) const { - return (3 * e.first.id()) + e.second; - } - }; - - template - class T2_edge_weight_map - : public boost::put_get_helper > - { - private: - const CGAL::Triangulation_2& tr; - public: - typedef boost::readable_property_map_tag category; - typedef typename Gt::FT value_type; - typedef value_type reference; - typedef typename CGAL::Triangulation_2::Edge key_type; - - T2_edge_weight_map(const CGAL::Triangulation_2& tr_) - : tr(tr_) - { } - - value_type operator[](key_type e) const { - return approximate_sqrt(tr.segment(e).squared_length()); - } - }; - - - template - inline T2_vertex_id_map - get(boost::vertex_index_t, const Triangulation_2&) { - T2_vertex_id_map m; - return m; - } - - template - inline T2_vertex_point_map - get(boost::vertex_point_t, const Triangulation_2&) { - T2_vertex_point_map m; - return m; - } - - template - inline T2_edge_id_map - get(boost::edge_index_t, const Triangulation_2&) { - T2_edge_id_map m; - return m; - } - - template - inline T2_edge_weight_map - get(boost::edge_weight_t, const Triangulation_2& g) { - T2_edge_weight_map m(g); - return m; - } - - template - struct T2_property_map { }; - - template <> - struct T2_property_map { - template - struct bind_ { - typedef T2_vertex_id_map type; - typedef T2_vertex_id_map const_type; - }; - }; - - template <> - struct T2_property_map { - template - struct bind_ { - typedef T2_vertex_point_map type; - typedef T2_vertex_point_map const_type; - }; - }; - - template <> - struct T2_property_map { - template - struct bind_ { - typedef T2_edge_id_map type; - typedef T2_edge_id_map const_type; - }; - }; - - template <> - struct T2_property_map { - template - struct bind_ { - typedef T2_edge_weight_map type; - typedef T2_edge_weight_map const_type; - }; - }; - -} // namespace CGAL - -namespace boost { - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::T2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyehdron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::T2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - -} // namespace boost - - -namespace CGAL { - - template - inline - typename boost::property_traits< - typename boost::property_map,PropertyTag>::const_type>::value_type - get(PropertyTag p, const Triangulation_2& g, const Key& key) { - return get(get(p, g), key); - } - - template - inline void - put(PropertyTag p, Triangulation_2& g, - const Key& key, const Value& value) - { - typedef typename boost::property_map, PropertyTag>::type Map; - Map pmap = get(p, g); - put(pmap, key, value); - } - -} // namespace CGAL - -namespace boost { - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - - -namespace std { - - -#if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4099) // For VC10 it is class hash -#endif - -#ifndef CGAL_CFG_NO_STD_HASH - - template < class Tr> - struct hash > { - std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor& e) const - { - return hash_value(e); - } - }; - -#endif // CGAL_CFG_NO_STD_HASH - -#if defined(BOOST_MSVC) -# pragma warning(pop) -#endif - -} // namespace std - +#include #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_2_H From 62cb1b7283c52c3b1a7f10a205f305cc47bbd677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 23 Apr 2019 10:32:59 +0200 Subject: [PATCH 07/68] Added class Triangulation_face_base_with_id_2 --- BGL/doc/BGL/BGL.txt | 2 +- .../CGAL/Triangulation_face_base_with_id_2.h | 45 +++++++++++++ BGL/doc/BGL/PackageDescription.txt | 1 + .../CGAL/Triangulation_face_base_with_id_2.h | 64 +++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h create mode 100644 Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index 6a319650062..70a4f1dad54 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -291,7 +291,7 @@ use the property map returned by the call `get(boost::vertex_index,ft)`. This property map assumes that the vertex has a member function `id()` that returns a reference to an int. Therefore \cgal offers a class `Triangulation_vertex_base_with_id_2`. -It is in the users responsibility to set the indices properly. +It is in the user's responsibility to set the indices properly. The example further illustrates that the graph traits also works for the Delaunay triangulation. diff --git a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h new file mode 100644 index 00000000000..83e14e58af7 --- /dev/null +++ b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h @@ -0,0 +1,45 @@ +namespace CGAL { + +/*! +\ingroup PkgBGLHelper + +The class `Triangulation_face_base_with_id_2` is a model of the +concept `TriangulationFaceBase_2`, the base face of a +2D-triangulation. It provides an integer field that can be used to +index faces for \sc{Bgl} algorithms. + +Note that the user is in charge of setting indices correctly before +running a graph algorithm. + +\tparam TriangulationTraits_2 is the geometric traits class +and must be a model of `TriangulationTraits_2`. + +\tparam TriangulationFaceBase_2 must be a face base class from which +`Triangulation_face_base_with_id_2` derives. It has the default +value `Triangulation_face_base_2`. + +\cgalModels `TriangulationFaceBase_2` + +\sa `CGAL::Triangulation_face_base_2` +*/ +template< typename TriangulationTraits_2, typename TriangulationFaceBase_2 > +class Triangulation_face_base_with_id_2 : public TriangulationFaceBase_2 { +public: + +/// \name Access Functions +/// @{ + +/*! +Returns the index. +*/ +int id() const; + +/*! +Returns a reference to the index stored in the face. +*/ +int& id(); + +/// @} + +}; /* end Triangulation_face_base_with_id_2 */ +} /* end namespace CGAL */ diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index ae7ea66baa1..7e0cccf4ad0 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -593,6 +593,7 @@ user might encounter. \cgalCRPSection{Helper Classes} - `CGAL::Triangulation_vertex_base_with_id_2` +- `CGAL::Triangulation_face_base_with_id_2` - `CGAL::Arr_vertex_index_map` - `CGAL::Arr_face_index_map` - `CGAL::HalfedgeDS_vertex_max_base_with_id` diff --git a/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h b/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h new file mode 100644 index 00000000000..f11bf4b81e4 --- /dev/null +++ b/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h @@ -0,0 +1,64 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_TRIANGULATION_FACE_BASE_WITH_ID_2_H +#define CGAL_TRIANGULATION_FACE_BASE_WITH_ID_2_H + +#include + +namespace CGAL { + +template < typename GT, + typename Fb = Triangulation_face_base_2 > +class Triangulation_face_base_with_id_2 + : public Fb +{ +public: + typedef typename Fb::Vertex_handle Vertex_handle; + typedef typename Fb::Face_handle Face_handle; + typedef typename Fb::Point Point; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Fb::template Rebind_TDS::Other Fb2; + typedef Triangulation_face_base_with_id_2 Other; + }; + + Triangulation_face_base_with_id_2() : Fb() { } + + Triangulation_face_base_with_id_2(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2) + : Fb(v0, v1, v2) + { } + + Triangulation_face_base_with_id_2(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, + Face_handle n0, Face_handle n1, Face_handle n2) + : Fb(v0, v1, v2, n0, n1, n2) + { } + + int& id() { return _id; } + int id() const { return _id; } + +private: + int _id; +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_FACE_BASE_WITH_ID_2_H From 092286a8b81b18d7084f5fb28cd18390d6f9d956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 23 Apr 2019 11:44:19 +0200 Subject: [PATCH 08/68] Fixed grabbing non-existent 'Point' typedef from a face base class --- Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h b/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h index f11bf4b81e4..39d96c49113 100644 --- a/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_face_base_with_id_2.h @@ -33,7 +33,6 @@ class Triangulation_face_base_with_id_2 public: typedef typename Fb::Vertex_handle Vertex_handle; typedef typename Fb::Face_handle Face_handle; - typedef typename Fb::Point Point; template < typename TDS2 > struct Rebind_TDS { From da59fabb72b9a9e75de7f3067f1c027658b3ea4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 24 Apr 2019 13:10:32 +0200 Subject: [PATCH 09/68] Fixed TH_2 not informing the user that you can't just use any vertex --- .../doc/Triangulation_2/CGAL/Triangulation_hierarchy_2.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_hierarchy_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_hierarchy_2.h index 74deac2f6ee..ff141b114e0 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_hierarchy_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_hierarchy_2.h @@ -32,7 +32,8 @@ when it is built for Delaunay triangulations. However it can be used as well for other triangulations. -\tparam Tr may be any of the \cgal triangulation classes. +\tparam Tr may be any of the \cgal triangulation classes. The vertex of the triangulation must + be a model of the concept `TriangulationHierarchyVertexBase_2`. \cgalHeading{Types} From d9a0baa44262340ae70ca7a7acf4f98e60b6e0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 24 Apr 2019 13:12:48 +0200 Subject: [PATCH 10/68] Multiple fixes for T2 graph traits factorization (need independent iterator classes, make it work for RT2 despite RT2 having a different vertex iterator, etc.) --- .../graph/graph_traits_2D_triangulation.h | 551 ++++++++---------- ...its_Constrained_Delaunay_triangulation_2.h | 181 +----- ...graph_traits_Constrained_triangulation_2.h | 303 +--------- ..._traits_Constrained_triangulation_plus_2.h | 298 +--------- .../graph_traits_Delaunay_triangulation_2.h | 2 +- ...ph_traits_Triangulation_data_structure_2.h | 109 ---- .../graph_traits_Triangulation_hierarchy_2.h | 302 +--------- 7 files changed, 279 insertions(+), 1467 deletions(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h index 1fadb1adf86..423b76adb6e 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h @@ -15,8 +15,9 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // -// -// Author(s) : Andreas Fabri, Fernando Cacciola +// Author(s) : Mael Rouxel-Labbé, +// Andreas Fabri, +// Fernando Cacciola #ifndef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS #error CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS is not defined @@ -30,40 +31,33 @@ #error CGAL_2D_TRIANGULATION_TEMPLATES is not defined #endif -#include - -// include this to avoid a VC15 warning -#include -#include -#include -#include -#include -#include - -#include #include #include -// Small include guard is required for that class +#include +#include +#include + +#include + +// Small include guard for helper classes #ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION #define CGAL_GRAPH_TRAITS_2D_TRIANGULATION namespace CGAL { - namespace detail { template struct T2_halfedge_descriptor { - typedef typename Tr::Face_handle face_descriptor; - face_descriptor first; - int second; - operator std::pair() { return std::make_pair(first, second); } + typedef typename Tr::Face_handle face_descriptor; T2_halfedge_descriptor() : first(), second(0) { } - T2_halfedge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } + explicit T2_halfedge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } T2_halfedge_descriptor(face_descriptor fd, int i) : first(fd), second(i) { } + operator std::pair() { return std::make_pair(first, second); } + friend std::size_t hash_value(const T2_halfedge_descriptor& h) { return hash_value(h.first); @@ -85,106 +79,151 @@ struct T2_halfedge_descriptor if(first > other.first) return false; return second < other.second; } + + face_descriptor first; + int second; }; -template -class T2_vertex_id_map - : public boost::put_get_helper > +template +struct T2_edge_descriptor + : public Tr::Edge { -public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename Tr::Vertex_handle key_type; + typedef typename Tr::Edge Base; + typedef typename Tr::Face_handle Face_handle; - T2_vertex_id_map() { } + T2_edge_descriptor() {} + T2_edge_descriptor(Face_handle fh, int i) : Base(fh, i) { } + explicit T2_edge_descriptor(const Base& e) : Base(e) { } + T2_edge_descriptor(const T2_edge_descriptor& e) : Base(e) { } - long operator[](key_type vh) const { return vh->id(); } -}; - -template -class T2_vertex_point_map -{ -public: - typedef boost::lvalue_property_map_tag category; - typedef typename Tr::Point value_type; - typedef value_type& reference; - typedef typename Tr::Vertex_handle key_type; - - friend reference get(T2_vertex_point_map, key_type vh) + T2_edge_descriptor& operator=(const T2_edge_descriptor& e) { - return vh->point(); + this->first = e.first; + this->second = e.second; + return *this; } - friend void put(T2_vertex_point_map, key_type vh, reference v) + + friend std::size_t hash_value(const T2_edge_descriptor& e) { - vh->point() = v; + if (e.first==Face_handle()) return 0; + return hash_value(e.firstneighbor(e.second)? + e.first:e.first->neighbor(e.second)); + } + + bool operator==(const T2_edge_descriptor& other) const + { + if((this->first == other.first)&&(this->second == other.second)) return true; + Face_handle fh = this->first->neighbor(this->second); + if(other.first != fh) return false; + int i = fh->index(this->first); + return (other.second == i); + } + + bool operator!=(T2_edge_descriptor& other) const + { + return ! (*this == other); } - reference operator[](key_type vh) const { return vh->point(); } }; -template -class T2_edge_id_map - : public boost::put_get_helper > -{ -public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename Tr::Edge key_type; - - T2_edge_id_map() { } - - long operator[](key_type e) const { return (3 * e.first.id()) + e.second; } -}; - -template -class T2_edge_weight_map - : public boost::put_get_helper > +template +struct T2_iterator { private: - const Tr& tr; + typedef T2_iterator Self; + typedef typename Tr::Triangulation_data_structure Tds; public: - typedef boost::readable_property_map_tag category; - typedef typename Tr::Geom_traits::FT value_type; - typedef value_type reference; - typedef typename Tr::Edge key_type; + typedef Descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; - T2_edge_weight_map(const Tr& tr_) : tr(tr_) { } + T2_iterator() { } + T2_iterator(const Triangulation_iterator& it) : it(it) { } - value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); } + bool operator==(const Self& other) const { return it == other.it; } + bool operator!=(const Self& other) const { return !(*this == other);} + Self& operator++() { ++it; return *this; } + Self& operator--() { --it; return *this; } + Self operator++(int) { Self tmp = *this; operator++(); return tmp; } + Self operator--(int) { Self tmp = *this; operator--(); return tmp; } + value_type operator*() const { return value_type(*it); } + + Triangulation_iterator it; }; -template -struct T2_property_map { }; - -template -struct T2_property_map +template +struct Out_edge_circulator + : public Circ { - typedef detail::T2_vertex_id_map type; - typedef detail::T2_vertex_id_map const_type; +private: + mutable E e; + +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + + Out_edge_circulator() : Circ() { } + Out_edge_circulator(Circ c) : Circ(c) { } + + const E& operator*() const + { + E ed(static_cast(this)->operator*()); + e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); + return e; + } +}; + +template +struct In_edge_circulator + : public Circ +{ +private: + mutable E e; + +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + + In_edge_circulator() : Circ() { } + In_edge_circulator(Circ c) : Circ(c) { } + + const E& operator*() const + { + e = E(static_cast(this)->operator*()); + return e; + } }; template -struct T2_property_map +struct Dereference_to_vertex_handle_enforcer + : public boost::iterator_adaptor< + Dereference_to_vertex_handle_enforcer, + typename Tr::All_vertices_iterator /*base*/, + typename Tr::Vertex_handle /*value*/, + boost::use_default, + typename Tr::Vertex_handle /*reference*/ + > { - typedef detail::T2_vertex_point_map type; - typedef detail::T2_vertex_point_map const_type; -}; +public: + typedef typename Tr::Vertex_handle value_type; -template -struct T2_property_map -{ - typedef detail::T2_edge_id_map type; - typedef detail::T2_edge_id_map const_type; -}; +private: + typedef Dereference_to_vertex_handle_enforcer Self; + typedef typename Tr::All_vertices_iterator I; + typedef boost::iterator_adaptor Base; -template -struct T2_property_map -{ - typedef detail::T2_edge_weight_map type; - typedef detail::T2_edge_weight_map const_type; +public: + Dereference_to_vertex_handle_enforcer() { } + explicit Dereference_to_vertex_handle_enforcer(const I& i) : Base(i) { } + +private: + friend class boost::iterator_core_access; + value_type dereference() const { return value_type(this->base()); } }; } // namespace detail @@ -229,28 +268,39 @@ struct graph_traits< CGAL_2D_TRIANGULATION > public virtual bidirectional_graph_tag, public virtual adjacency_graph_tag, public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; + public virtual vertex_list_graph_tag + { }; typedef typename Triangulation::Vertex_handle vertex_descriptor; typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - typedef CGAL::detail::Edge edge_descriptor; + typedef CGAL::detail::T2_edge_descriptor edge_descriptor; typedef typename Triangulation::Face_handle face_descriptor; - typedef CGAL::Prevent_deref vertex_iterator; - typedef typename Triangulation::All_halfedges_iterator halfedge_iterator; - typedef typename Triangulation::All_edges_iterator edge_iterator; + // Regular_triangulation_2 unfortunately overrides the type 'All_vertices_iterator' due to hidden + // points, so we can't simply use 'CGAL::Prevent_deref' since 'typeid(*vertex_iterator)' would + // not be the vertex_descripor type, which creates all types (!) of problems. + typedef CGAL::detail::Dereference_to_vertex_handle_enforcer vertex_iterator; + + // Since 'All_halfedges_...' and 'All_edges_...' have the same value type, we have to wrap them + // around to enforce the value_type being the correct descriptor + typedef CGAL::detail::T2_iterator halfedge_iterator; + typedef CGAL::detail::T2_iterator edge_iterator; typedef CGAL::Prevent_deref face_iterator; typedef CGAL::Counting_iterator< - CGAL::detail::Out_edge_circulator< - typename Triangulation::Edge_circulator, - edge_descriptor>, - edge_descriptor> out_edge_iterator; + CGAL::detail::In_edge_circulator< + typename Triangulation::Edge_circulator, + edge_descriptor>, + edge_descriptor> in_edge_iterator; typedef CGAL::Counting_iterator< - CGAL::detail::In_edge_circulator< - typename Triangulation::Edge_circulator, - edge_descriptor>, - edge_descriptor> in_edge_iterator; + CGAL::detail::Out_edge_circulator< + typename Triangulation::Edge_circulator, + edge_descriptor>, + edge_descriptor> out_edge_iterator; typedef CGAL::Counting_iterator Incident_vertices_iterator; typedef Incident_vertices_iterator adjacency_iterator; @@ -272,36 +322,15 @@ struct graph_traits< CGAL_2D_TRIANGULATION > static face_descriptor null_face() { return face_descriptor(); } }; +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +struct graph_traits + : public graph_traits< CGAL_2D_TRIANGULATION > +{ }; + } // namespace boost namespace CGAL { -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor -next(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, - const CGAL_2D_TRIANGULATION& g) -{ - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first, g.ccw(e.second)); -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor -prev(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, - const CGAL_2D_TRIANGULATION& g) -{ - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first, g.cw(e.second)); -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor -opposite(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, - const CGAL_2D_TRIANGULATION& g) -{ - return g.mirror_edge(e); -} - template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, @@ -310,6 +339,14 @@ source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, return e.first->vertex(g.ccw(e.second)); } +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor +source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, + const CGAL_2D_TRIANGULATION& g) +{ + return h.first->vertex(g.ccw(h.second)); +} + template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, @@ -320,26 +357,47 @@ target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor -source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, +target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, const CGAL_2D_TRIANGULATION& g) { - return e.first->vertex(g.ccw(e.second)); + return h.first->vertex(g.cw(h.second)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor -target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, - const CGAL_2D_TRIANGULATION& g) +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +next(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, + const CGAL_2D_TRIANGULATION& g) { - return e.first->vertex(g.cw(e.second)); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(h.first, g.ccw(h.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +prev(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(h.first, g.cw(h.second)); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor +opposite(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, + const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + + return halfedge_descriptor(g.mirror_edge(edge_descriptor(h.first, h.second))); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor -face(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, +face(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, const CGAL_2D_TRIANGULATION&) { - return e.first; + return h.first; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -374,16 +432,16 @@ halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor -edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor e, +edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, const CGAL_2D_TRIANGULATION&) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; - return edge_descriptor(e.first, e.second); + return edge_descriptor(h.first, h.second); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > std::pair::edge_descriptor, -bool> + bool> edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) @@ -405,7 +463,7 @@ edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > std::pair::halfedge_descriptor, -bool> + bool> halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) @@ -437,32 +495,59 @@ template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline Iterator_range::vertex_iterator> vertices(const CGAL_2D_TRIANGULATION& g) { - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_iterator - Iter; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_iterator Iter; return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); } -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline Iterator_range::edge_iterator> -edges(const CGAL_2D_TRIANGULATION& g) -{ - return make_range(g.all_edges_begin(), g.all_edges_end()); -} - template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline Iterator_range::halfedge_iterator > halfedges(const CGAL_2D_TRIANGULATION& g) { - return make_range(g.all_halfedges_begin(), g.all_halfedges_end()); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_iterator Iter; + return make_range(Iter(g.all_halfedges_begin()), Iter(g.all_halfedges_end())); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::edge_iterator> +edges(const CGAL_2D_TRIANGULATION& g) +{ + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_iterator Iter; + return make_range(Iter(g.all_edges_begin()), Iter(g.all_edges_end())); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline Iterator_range::face_iterator > faces(const CGAL_2D_TRIANGULATION& g) { - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_iterator - Iter; - return make_range( Iter(g.all_faces_begin()), Iter(g.all_faces_end()) ); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_iterator Iter; + return make_range(Iter(g.all_faces_begin()), Iter(g.all_faces_end())); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +in_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + if(c != 0) + { + do { + ++deg; + } while (++c != done); + } + return deg; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline Iterator_range::in_edge_iterator > +in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) +{ + typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator Iter; + return make_range(Iter(ec), Iter(ec,out_deg)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -488,22 +573,25 @@ out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descript { typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION > - ::out_edge_iterator Iter; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter; return make_range(Iter(ec), Iter(ec, out_deg)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline Iterator_range::in_edge_iterator > -in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, - const CGAL_2D_TRIANGULATION& g) +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, + const CGAL_2D_TRIANGULATION& g) { - typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION > - ::in_edge_iterator Iter; - return make_range(Iter(ec), Iter(ec,out_deg)); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + if(c != 0) + { + do { + ++deg; + } while (++c != done); + } + return deg; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -545,135 +633,8 @@ num_faces(const CGAL_2D_TRIANGULATION& g) return g.tds().number_of_faces(); } -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type -in_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, - const CGAL_2D_TRIANGULATION& g) -{ - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; - typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); - if(c != 0) - { - do { - ++deg; - } while (++c != done); - } - return deg; -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type -degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, - const CGAL_2D_TRIANGULATION& g) -{ - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; - typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); - if(c != 0) - { - do { - ++deg; - } while (++c != done); - } - return deg; -} - -// property maps -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > -get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION&) -{ - detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m; - return m; -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > -get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&) -{ - detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; - return m; -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > -get(boost::edge_index_t, const CGAL_2D_TRIANGULATION&) -{ - detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m; - return m; -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > -get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g) -{ - detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); - return m; -} - } // namespace CGAL -namespace boost { - -// g++ 'enumeral_type' in template unification not implemented workaround -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag> -struct property_map -{ - typedef typename CGAL::detail::T2_property_map map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; -}; - -// see struct property_map in Polyehdron for an explanation -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag> -struct property_map -{ - typedef typename CGAL::detail::T2_property_map map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; -}; - -} // namespace boost - -namespace CGAL { - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key> -inline -typename boost::property_traits< -typename boost::property_map< CGAL_2D_TRIANGULATION, PropertyTag>::const_type>::value_type -get(PropertyTag p, const CGAL_2D_TRIANGULATION& g, const Key& key) -{ - return get(get(p, g), key); -} - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key, class Value> -inline void -put(PropertyTag p, CGAL_2D_TRIANGULATION& g, - const Key& key, const Value& value) -{ - typedef typename boost::property_map::type Map; - Map pmap = get(p, g); - put(pmap, key, value); -} - -} // namespace CGAL - -namespace boost { - -// What are those needed for ??? -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -struct edge_property_type -{ - typedef void type; -}; - -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -struct vertex_property_type -{ - typedef void type; -}; - -} // namespace boost - #undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS #undef CGAL_2D_TRIANGULATION #undef CGAL_2D_TRIANGULATION_TEMPLATES diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h index 9c9180d3135..6a073bec25d 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h @@ -21,185 +21,16 @@ #ifndef CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H #define CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H -// include this to avoid a VC15 warning -#include - -#include -#include -#include -#include -#include #include // The functions and classes in this file allows the user to -// treat a CGAL Constrained_triangulation_2 object as a boost graph "as is". No -// wrapper is needed for the Constrained_triangulation_2 object. +// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No +// wrapper is needed for the Constrained_Delaunay_triangulation_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag +#define CGAL_2D_TRIANGULATION CGAL::Constrained_Delaunay_triangulation_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS, Itag - -namespace boost { - - template - struct graph_traits< CGAL::Constrained_Delaunay_triangulation_2 > { - - struct DT2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef CGAL::Constrained_Delaunay_triangulation_2 Constrained_Delaunay_triangulation; - - typedef typename CGAL::Constrained_Delaunay_triangulation_2::Vertex_handle vertex_descriptor; - typedef typename CGAL::Constrained_Delaunay_triangulation_2::Face_handle face_descriptor; - typedef CGAL::detail::Edge, typename CGAL::Constrained_Delaunay_triangulation_2::Edge> edge_descriptor; - typedef typename CGAL::Constrained_Delaunay_triangulation_2::All_edges_iterator edge_iterator; - - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - typedef typename Constrained_Delaunay_triangulation::All_halfedges_iterator halfedge_iterator; - typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef DT2_graph_traversal_category traversal_category; - typedef typename Constrained_Delaunay_triangulation::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - -namespace CGAL { - - - - template - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::vertex_descriptor - source(typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::edge_descriptor e, - const CGAL::Constrained_Delaunay_triangulation_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::vertex_descriptor - target(typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::edge_descriptor e, - const CGAL::Constrained_Delaunay_triangulation_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - - - template - inline std::pair< - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::out_edge_iterator, - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::out_edge_iterator > - out_edges( - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::vertex_descriptor u, - const CGAL::Constrained_Delaunay_triangulation_2& g) - { - typename CGAL::Constrained_Delaunay_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 > - ::out_edge_iterator Iter; - - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline std::pair< - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::in_edge_iterator, - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::in_edge_iterator > - in_edges( - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::vertex_descriptor u, - const CGAL::Constrained_Delaunay_triangulation_2& g) - { - typename CGAL::Constrained_Delaunay_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2 > - ::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - - - template - inline CT2_vertex_id_map - get(boost::vertex_index_t, const CGAL::Constrained_Delaunay_triangulation_2& ) { - CT2_vertex_id_map m; - return m; - } - - template - inline CT2_vertex_point_map - get(boost::vertex_point_t, const CGAL::Constrained_Delaunay_triangulation_2& ) { - CT2_vertex_point_map m; - return m; - } - template - inline CT2_edge_id_map - get(boost::edge_index_t, const CGAL::Constrained_Delaunay_triangulation_2& ) { - CT2_edge_id_map m; - return m; - } - - template - inline CT2_edge_weight_map - get(boost::edge_weight_t, const CGAL::Constrained_Delaunay_triangulation_2& g) { - CT2_edge_weight_map m(g); - return m; - } - -} // namespace CGAL - -namespace boost { - - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::CT2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyehdron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::CT2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - +#include #endif // CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h index f235ef1e975..f9d474ecdbc 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h @@ -21,309 +21,16 @@ #ifndef CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H #define CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H -// include this to avoid a VC15 warning -#include - -#include -#include -#include -#include -#include #include // The functions and classes in this file allows the user to -// treat a CGAL Constrained_triangulation_2 object as a boost graph "as is". No +// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Constrained_triangulation_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag +#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS, Itag - -namespace boost { - - template - struct graph_traits< CGAL::Constrained_triangulation_2 > { - - struct DT2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef CGAL::Constrained_triangulation_2 Constrained_triangulation; - - typedef typename CGAL::Constrained_triangulation_2::Vertex_handle vertex_descriptor; - typedef typename CGAL::Constrained_triangulation_2::Face_handle face_descriptor; - typedef CGAL::detail::Edge, typename CGAL::Constrained_triangulation_2::Edge> edge_descriptor; - typedef typename CGAL::Constrained_triangulation_2::All_edges_iterator edge_iterator; - - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - - typedef typename Constrained_triangulation::All_halfedges_iterator halfedge_iterator; - typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef DT2_graph_traversal_category traversal_category; - typedef typename Constrained_triangulation::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - -namespace CGAL { - - - - template - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::vertex_descriptor - source(typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::edge_descriptor e, - const CGAL::Constrained_triangulation_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::vertex_descriptor - target(typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::edge_descriptor e, - const CGAL::Constrained_triangulation_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - - - template - inline std::pair< - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::out_edge_iterator, - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::out_edge_iterator > - out_edges( - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::vertex_descriptor u, - const CGAL::Constrained_triangulation_2& g) - { - typename CGAL::Constrained_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Constrained_triangulation_2 > - ::out_edge_iterator Iter; - - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline std::pair< - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::in_edge_iterator, - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::in_edge_iterator > - in_edges( - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::vertex_descriptor u, - const CGAL::Constrained_triangulation_2& g) - { - typename CGAL::Constrained_triangulation_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Constrained_triangulation_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Constrained_triangulation_2 > - ::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - - - // property maps - template - class CT2_vertex_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Constrained_triangulation_2::Vertex_handle key_type; - - CT2_vertex_id_map() - {} - - long operator[](key_type vh) const { - return vh->id(); - } - }; - - template - class CT2_vertex_point_map - { - public: - typedef boost::lvalue_property_map_tag category; - typedef typename CGAL::Constrained_triangulation_2::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Constrained_triangulation_2::Vertex_handle key_type; - - friend reference get(CT2_vertex_point_map, key_type vh) - { - return vh->point(); - } - friend void put(CT2_vertex_point_map, key_type vh, reference v) - { - vh->point()=v; - } - reference operator[](key_type vh) const { - return vh->point(); - } - }; - - template - class CT2_edge_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Constrained_triangulation_2::Edge key_type; - - CT2_edge_id_map() - {} - - long operator[](key_type e) const { - return (3 * e.first.id()) + e.second; - } - }; - - template - class CT2_edge_weight_map - : public boost::put_get_helper > - { - private: - const CGAL::Constrained_triangulation_2& tr; - public: - typedef boost::readable_property_map_tag category; - typedef typename Gt::FT value_type; - typedef value_type reference; - typedef typename CGAL::Constrained_triangulation_2::Edge key_type; - - CT2_edge_weight_map(const CGAL::Constrained_triangulation_2& tr_) - : tr(tr_) - { } - - typename Gt::FT operator[](key_type e) const { - return approximate_sqrt(tr.segment(e).squared_length()); - } - }; - - - template - inline CT2_vertex_id_map - get(boost::vertex_index_t, const CGAL::Constrained_triangulation_2& ) { - CT2_vertex_id_map m; - return m; - } - - template - inline CT2_vertex_point_map - get(boost::vertex_point_t, const CGAL::Constrained_triangulation_2& ) { - CT2_vertex_point_map m; - return m; - } - - template - inline CT2_edge_id_map - get(boost::edge_index_t, const CGAL::Constrained_triangulation_2& ) { - CT2_edge_id_map m; - return m; - } - - template - inline CT2_edge_weight_map - get(boost::edge_weight_t, const CGAL::Constrained_triangulation_2& g) { - CT2_edge_weight_map m(g); - return m; - } - - template - struct CT2_property_map { }; - - template <> - struct CT2_property_map { - template - struct bind_ { - typedef CT2_vertex_id_map type; - typedef CT2_vertex_id_map const_type; - }; - }; - - template <> - struct CT2_property_map { - template - struct bind_ { - typedef CT2_vertex_point_map type; - typedef CT2_vertex_point_map const_type; - }; - }; - - - - template <> - struct CT2_property_map { - template - struct bind_ { - typedef CT2_edge_id_map type; - typedef CT2_edge_id_map const_type; - }; - }; - - - template <> - struct CT2_property_map { - template - struct bind_ { - typedef CT2_edge_weight_map type; - typedef CT2_edge_weight_map const_type; - }; - }; - -} // namespace CGAL - -namespace boost { - - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::CT2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyehdron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::CT2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - +#include #endif // CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h index 5d35c80e748..81bd2df4fe1 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h @@ -21,304 +21,16 @@ #ifndef CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H #define CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H -// include this to avoid a VC15 warning -#include - -#include -#include -#include -#include -#include #include // The functions and classes in this file allows the user to -// treat a CGAL Constrained_triangulation_plus_2 object as a boost graph "as is". No +// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Constrained_triangulation_plus_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr +#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_plus_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES Tr - -namespace boost { - - template - struct graph_traits< CGAL::Constrained_triangulation_plus_2 > { - - struct DT2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - typedef typename boost::graph_traits::edge_iterator edge_iterator; - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::face_iterator face_iterator; - typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; - typedef typename boost::graph_traits::Incident_vertices_iterator Incident_vertices_iterator; - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef DT2_graph_traversal_category traversal_category; - typedef typename boost::graph_traits::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - -namespace CGAL { - - - - template - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::vertex_descriptor - source(typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::edge_descriptor e, - const CGAL::Constrained_triangulation_plus_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::vertex_descriptor - target(typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::edge_descriptor e, - const CGAL::Constrained_triangulation_plus_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - - template - inline std::pair< - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::out_edge_iterator, - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::out_edge_iterator > - out_edges( - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::vertex_descriptor u, - const CGAL::Constrained_triangulation_plus_2& g) - { - typename CGAL::Constrained_triangulation_plus_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 > - ::out_edge_iterator Iter; - - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline std::pair< - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::in_edge_iterator, - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::in_edge_iterator > - in_edges( - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::vertex_descriptor u, - const CGAL::Constrained_triangulation_plus_2& g) - { - typename CGAL::Constrained_triangulation_plus_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2 > - ::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - - - // property maps - template - class CTP2_vertex_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Constrained_triangulation_plus_2::Vertex_handle key_type; - - CTP2_vertex_id_map() - {} - - long operator[](key_type vh) const { - return vh->id(); - } - }; - - template - class CTP2_vertex_point_map - { - public: - typedef boost::lvalue_property_map_tag category; - typedef typename CGAL::Constrained_triangulation_plus_2::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Constrained_triangulation_plus_2::Vertex_handle key_type; - - friend reference get(CTP2_vertex_point_map, key_type vh) - { - return vh->point(); - } - friend void put(CTP2_vertex_point_map, key_type vh, reference v) - { - vh->point()=v; - } - reference operator[](key_type vh) const { - return vh->point(); - } - }; - - template - class CTP2_edge_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Constrained_triangulation_plus_2::Edge key_type; - - CTP2_edge_id_map() - {} - - long operator[](key_type e) const { - return (3 * e.first.id()) + e.second; - } - }; - - template - class CTP2_edge_weight_map - : public boost::put_get_helper > - { - private: - const CGAL::Constrained_triangulation_plus_2& tr; - public: - typedef boost::readable_property_map_tag category; - typedef typename Tr::Geom_traits::FT value_type; - typedef value_type reference; - typedef typename CGAL::Constrained_triangulation_plus_2::Edge key_type; - - CTP2_edge_weight_map(const CGAL::Constrained_triangulation_plus_2& tr_) - : tr(tr_) - { } - - typename Tr::Geom_traits::FT operator[](key_type e) const { - return approximate_sqrt(tr.segment(e).squared_length()); - } - }; - - - template - inline CTP2_vertex_id_map - get(boost::vertex_index_t, const CGAL::Constrained_triangulation_plus_2& ) { - CTP2_vertex_id_map m; - return m; - } - - template - inline CTP2_vertex_point_map - get(boost::vertex_point_t, const CGAL::Constrained_triangulation_plus_2& ) { - CTP2_vertex_point_map m; - return m; - } - - template - inline CTP2_edge_id_map - get(boost::edge_index_t, const CGAL::Constrained_triangulation_plus_2& ) { - CTP2_edge_id_map m; - return m; - } - - template - inline CTP2_edge_weight_map - get(boost::edge_weight_t, const CGAL::Constrained_triangulation_plus_2& g) { - CTP2_edge_weight_map m(g); - return m; - } - - template - struct CTP2_property_map { }; - - template <> - struct CTP2_property_map { - template - struct bind_ { - typedef CTP2_vertex_id_map type; - typedef CTP2_vertex_id_map const_type; - }; - }; - - template <> - struct CTP2_property_map { - template - struct bind_ { - typedef CTP2_vertex_point_map type; - typedef CTP2_vertex_point_map const_type; - }; - }; - - - - template <> - struct CTP2_property_map { - template - struct bind_ { - typedef CTP2_edge_id_map type; - typedef CTP2_edge_id_map const_type; - }; - }; - - - template <> - struct CTP2_property_map { - template - struct bind_ { - typedef CTP2_edge_weight_map type; - typedef CTP2_edge_weight_map const_type; - }; - }; - -} // namespace CGAL - -namespace boost { - - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::CTP2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyhedron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::CTP2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - +#include #endif // CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h index e582f0526d4..cb79583b363 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h @@ -33,4 +33,4 @@ #include -#endif // CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H +#endif // CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h index 4a79b2f69ef..48d30084417 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -45,114 +44,6 @@ namespace CGAL { namespace detail { -template < class T, class EdgeBase > -class Edge : public EdgeBase { - -public: - typedef typename T::Face_handle Face_handle ; - - Edge() - {} - - Edge(Face_handle fh, int i) - : EdgeBase(fh,i) - {} - - Edge(const EdgeBase& e) - : EdgeBase(e) - {} - - Edge(const Edge& e) - : EdgeBase(e) - {} - - Edge& - operator=(const Edge& e) - { - this->first = e.first; - this->second = e.second; - return *this; - } - - friend std::size_t hash_value(const Edge& e) - { - if (e.first==Face_handle()) return 0; - return hash_value(e.firstneighbor(e.second)? - e.first:e.first->neighbor(e.second)); - } - - bool operator==(const Edge& other) const - { - if((this->first == other.first)&&(this->second == other.second)) return true; - Face_handle fh = this->first->neighbor(this->second); - if(other.first != fh) return false; - int i = fh->index(this->first); - return (other.second == i); - } - - bool operator!=(Edge& other) const - { - return ! (*this == other); - } -}; - -template -class Out_edge_circulator : public Circ -{ -private: - mutable E e; - -public: - - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - Out_edge_circulator() - : Circ() - {} - - Out_edge_circulator(Circ c) - : Circ(c) - {} - - const E& operator*() const - { - E ed = static_cast(this)->operator*(); - e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); - return e; - } -}; - -template -class In_edge_circulator : public Circ -{ -private: - mutable E e; - -public: - - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - In_edge_circulator() - : Circ() - {} - - In_edge_circulator(Circ c) - : Circ(c) - {} - - const E& operator*() const -{ - typename Circ::value_type ed = static_cast(this)->operator*(); - e = E(ed); - return e; - } -}; - - template struct TDS2_halfedge_descriptor { diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h index dd24d64a7ae..31932767c92 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h @@ -21,306 +21,16 @@ #ifndef CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H #define CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H -// include this to avoid a VC15 warning -#include - -#include -#include -#include -#include -#include #include // The functions and classes in this file allows the user to -// treat a CGAL Triangulation_hierarchy_2 object as a boost graph "as is". No -// wrapper is needed for the Triangulation_hierarchy_2 object. +// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No +// wrapper is needed for the Constrained_triangulation_2 object. +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr +#define CGAL_2D_TRIANGULATION CGAL::Triangulation_hierarchy_2 +#define CGAL_2D_TRIANGULATION_TEMPLATES Tr - -namespace boost { - - template - struct graph_traits< CGAL::Triangulation_hierarchy_2 > { - - struct DT2_graph_traversal_category : - public virtual bidirectional_graph_tag, - public virtual adjacency_graph_tag, - public virtual edge_list_graph_tag, - public virtual vertex_list_graph_tag { }; - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - typedef typename boost::graph_traits::edge_iterator edge_iterator; - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::face_iterator face_iterator; - typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; - typedef typename boost::graph_traits::Incident_vertices_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef DT2_graph_traversal_category traversal_category; - typedef typename boost::graph_traits::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; - - -} // namespace boost - -namespace CGAL { - - - - template - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::vertex_descriptor - source(typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::edge_descriptor e, - const CGAL::Triangulation_hierarchy_2& g) - { - return e.first->vertex(g.ccw(e.second)); - } - - template - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::vertex_descriptor - target(typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::edge_descriptor e, - const CGAL::Triangulation_hierarchy_2& g) - { - return e.first->vertex(g.cw(e.second)); - } - - - template - inline std::pair< - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::out_edge_iterator, - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::out_edge_iterator > - out_edges( - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::vertex_descriptor u, - const CGAL::Triangulation_hierarchy_2& g) - { - typename CGAL::Triangulation_hierarchy_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 > - ::out_edge_iterator Iter; - - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline std::pair< - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::in_edge_iterator, - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::in_edge_iterator > - in_edges( - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::vertex_descriptor u, - const CGAL::Triangulation_hierarchy_2& g) - { - typename CGAL::Triangulation_hierarchy_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< CGAL::Triangulation_hierarchy_2 > - ::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); - } - - - - // property maps - template - class TH2_vertex_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_hierarchy_2::Vertex_handle key_type; - - TH2_vertex_id_map() - {} - - long operator[](key_type vh) const { - return vh->id(); - } - }; - - template - class TH2_vertex_point_map - { - public: - typedef boost::lvalue_property_map_tag category; - typedef typename CGAL::Triangulation_hierarchy_2::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Triangulation_hierarchy_2::Vertex_handle key_type; - - friend reference get(TH2_vertex_point_map, key_type vh) - { - return vh->point(); - } - friend void put(TH2_vertex_point_map, key_type vh, reference v) - { - vh->point()=v; - } - reference operator[](key_type vh) const { - return vh->point(); - } - }; - - template - class TH2_edge_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_hierarchy_2::Edge key_type; - - TH2_edge_id_map() - {} - - long operator[](key_type e) const { - return (3 * e.first.id()) + e.second; - } - }; - - template - class TH2_edge_weight_map - : public boost::put_get_helper > - { - private: - const CGAL::Triangulation_hierarchy_2& tr; - public: - typedef boost::readable_property_map_tag category; - typedef typename Tr::Geom_traits::FT value_type; - typedef value_type reference; - typedef typename CGAL::Triangulation_hierarchy_2::Edge key_type; - - TH2_edge_weight_map(const CGAL::Triangulation_hierarchy_2& tr_) - : tr(tr_) - { } - - typename Tr::Geom_traits::FT operator[](key_type e) const { - return approximate_sqrt(tr.segment(e).squared_length()); - } - }; - - - template - inline TH2_vertex_id_map - get(boost::vertex_index_t, const CGAL::Triangulation_hierarchy_2& ) { - TH2_vertex_id_map m; - return m; - } - - template - inline TH2_vertex_point_map - get(boost::vertex_point_t, const CGAL::Triangulation_hierarchy_2& ) { - TH2_vertex_point_map m; - return m; - } - - template - inline TH2_edge_id_map - get(boost::edge_index_t, const CGAL::Triangulation_hierarchy_2& ) { - TH2_edge_id_map m; - return m; - } - - template - inline TH2_edge_weight_map - get(boost::edge_weight_t, const CGAL::Triangulation_hierarchy_2& g) { - TH2_edge_weight_map m(g); - return m; - } - - template - struct TH2_property_map { }; - - template <> - struct TH2_property_map { - template - struct bind_ { - typedef TH2_vertex_id_map type; - typedef TH2_vertex_id_map const_type; - }; - }; - - template <> - struct TH2_property_map { - template - struct bind_ { - typedef TH2_vertex_point_map type; - typedef TH2_vertex_point_map const_type; - }; - }; - - - - template <> - struct TH2_property_map { - template - struct bind_ { - typedef TH2_edge_id_map type; - typedef TH2_edge_id_map const_type; - }; - }; - - - template <> - struct TH2_property_map { - template - struct bind_ { - typedef TH2_edge_weight_map type; - typedef TH2_edge_weight_map const_type; - }; - }; - -} // namespace CGAL - -namespace boost { - - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::TH2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - // see struct property_map in Polyhedron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::TH2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; - - - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; - - template - struct vertex_property_type > { - typedef void type; - }; -} // namespace boost - +#include #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H From 9f57d48642100b4e227410904ef785817bcf1c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 24 Apr 2019 13:14:09 +0200 Subject: [PATCH 11/68] Factorize T2 graphs' properties via macros --- .../boost/graph/properties_2D_triangulation.h | 344 ++++++++++++++++++ ...ies_Constrained_Delaunay_triangulation_2.h | 30 ++ .../properties_Constrained_triangulation_2.h | 30 ++ ...perties_Constrained_triangulation_plus_2.h | 30 ++ .../properties_Delaunay_triangulation_2.h | 30 ++ .../properties_Regular_triangulation_2.h | 30 ++ .../boost/graph/properties_Triangulation_2.h | 30 ++ .../properties_Triangulation_hierarchy_2.h | 30 ++ 8 files changed, 554 insertions(+) create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h new file mode 100644 index 00000000000..e5f993f9440 --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h @@ -0,0 +1,344 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#include +#include +#include + +#ifndef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS + #error CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS is not defined +#endif + +#ifndef CGAL_2D_TRIANGULATION + #error CGAL_2D_TRIANGULATION is not defined +#endif + +// note only the properties below are protected by the macro, +// the rest of the file is the shared implementation of properties for all 2D triangulations +#ifndef CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H +#define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H + +namespace CGAL { +namespace detail { + +template +struct T2_halfedge_descriptor; + +template +struct T2_edge_descriptor; + +template +class T2_vertex_point_map +{ +public: + typedef boost::lvalue_property_map_tag category; + typedef typename Tr::Point value_type; + typedef value_type& reference; + typedef typename Tr::Vertex_handle key_type; + + T2_vertex_point_map() { } + + friend reference get(T2_vertex_point_map, key_type vh) + { + return vh->point(); + } + friend void put(T2_vertex_point_map, key_type vh, const value_type& v) + { + vh->point() = v; + } + + reference operator[](key_type vh) const { return vh->point(); } +}; + +template +class T2_edge_weight_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef typename Tr::Geom_traits::FT value_type; + typedef value_type reference; + typedef typename Tr::Edge key_type; + + T2_edge_weight_map(const Tr& tr_) : tr(tr_) { } + + value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); } + +private: + const Tr& tr; +}; + +template +class T2_vertex_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename Tr::Vertex_handle key_type; + + T2_vertex_id_map() { } + + value_type operator[](key_type vh) const { return vh->id(); } +}; + +template +class T2_halfedge_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef CGAL::detail::T2_halfedge_descriptor key_type; + + T2_halfedge_id_map() { } + + value_type operator[](key_type h) const { return (3 * h.first->id()) + h.second; } +}; + +template +class T2_edge_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef CGAL::detail::T2_edge_descriptor key_type; + typedef typename Tr::Face_handle face_descriptor; + + T2_edge_id_map() { } + + value_type operator[](key_type e) const + { + const face_descriptor f1 = e.first; + const face_descriptor f2 = f1->neighbor(e.second); + + if(f1->id() < f2->id()) + return 3 * f1->id() + e.second; + else + return 3 * f2->id() + f2->index(f1); + } +}; + +template +class T2_face_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename Tr::Face_handle key_type; + + T2_face_id_map() { } + + value_type operator[](key_type f) const { return f->id(); } +}; + +template +struct T2_property_map { }; + +template +struct T2_property_map +{ + typedef detail::T2_vertex_point_map type; + typedef detail::T2_vertex_point_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_edge_weight_map type; + typedef detail::T2_edge_weight_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_vertex_id_map type; + typedef detail::T2_vertex_id_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_halfedge_id_map type; + typedef detail::T2_halfedge_id_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_edge_id_map type; + typedef detail::T2_edge_id_map const_type; +}; + +template +struct T2_property_map +{ + typedef detail::T2_face_id_map type; + typedef detail::T2_face_id_map const_type; +}; + +} // end namespace detail + +} // CGAL + +#endif // CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H + +// overloads and specializations in the boost namespace +namespace boost { + +// g++ 'enumeral_type' in template unification not implemented workaround +template +struct property_map +{ + typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +// see struct property_map in Polyehdron for an explanation +template +struct property_map +{ + typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +} // end namespace boost + +namespace CGAL { + +template +struct graph_has_property + : CGAL::Tag_true{}; +template +struct graph_has_property + : CGAL::Tag_true{}; + +template +struct graph_has_property + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL_2D_TRIANGULATION::Vertex + >::value + > +{}; +template +struct graph_has_property + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL_2D_TRIANGULATION::Face + >::value + > +{}; +template +struct graph_has_property + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL_2D_TRIANGULATION::Face + >::value + > +{}; +template +struct graph_has_property + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL_2D_TRIANGULATION::Face + >::value + > +{}; + +// property maps +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > +get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > +get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g) +{ + detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > +get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > +get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > +get(boost::edge_index_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +inline detail::T2_face_id_map< CGAL_2D_TRIANGULATION > +get(boost::face_index_t, const CGAL_2D_TRIANGULATION&) +{ + detail::T2_face_id_map< CGAL_2D_TRIANGULATION > m; + return m; +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key> +inline +typename boost::property_traits< + typename boost::property_map< CGAL_2D_TRIANGULATION, PropertyTag>::const_type>::value_type +get(PropertyTag p, const CGAL_2D_TRIANGULATION& g, const Key& key) +{ + return get(get(p, g), key); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key, class Value> +inline void +put(PropertyTag p, CGAL_2D_TRIANGULATION& g, const Key& key, const Value& value) +{ + typedef typename boost::property_map::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} + +} // namespace CGAL + +#undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS +#undef CGAL_2D_TRIANGULATION diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h new file mode 100644 index 00000000000..fc9d538fb46 --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H +#define CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag +#define CGAL_2D_TRIANGULATION CGAL::Constrained_Delaunay_triangulation_2 + +#include + +#endif /* CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h new file mode 100644 index 00000000000..6238f25681d --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H +#define CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag +#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_2 + +#include + +#endif /* CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h new file mode 100644 index 00000000000..d5914040e52 --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H +#define CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr +#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_plus_2 + +#include + +#endif /* CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h new file mode 100644 index 00000000000..f9412771dda --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H +#define CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS +#define CGAL_2D_TRIANGULATION CGAL::Delaunay_triangulation_2 + +#include + +#endif /* CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h new file mode 100644 index 00000000000..ab6bf9b43d9 --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H +#define CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS +#define CGAL_2D_TRIANGULATION CGAL::Regular_triangulation_2 + +#include + +#endif /* CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h new file mode 100644 index 00000000000..d4e0104af0f --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_TRIANGULATION_2_H +#define CGAL_PROPERTIES_TRIANGULATION_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS +#define CGAL_2D_TRIANGULATION CGAL::Triangulation_2 + +#include + +#endif /* CGAL_PROPERTIES_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h new file mode 100644 index 00000000000..54ff046294a --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h @@ -0,0 +1,30 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H +#define CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H + +#include + +#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr +#define CGAL_2D_TRIANGULATION CGAL::Triangulation_hierarchy_2 + +#include + +#endif /* CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H */ From d244d4a0786d30960c2f524fd0352c87af1bea93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 24 Apr 2019 13:18:03 +0200 Subject: [PATCH 12/68] Properly test T2 graph traits / properties (+minor improvements to older tests) --- .../BGL/graph_concept_Triangulation_2.cpp | 1 + BGL/test/BGL/test_Has_member_id.cpp | 8 ++ BGL/test/BGL/test_Prefix.h | 101 ++++++++++++++---- BGL/test/BGL/test_Properties.cpp | 49 +++++---- BGL/test/BGL/test_graph_traits.cpp | 99 +++++++++++------ 5 files changed, 189 insertions(+), 69 deletions(-) diff --git a/BGL/test/BGL/graph_concept_Triangulation_2.cpp b/BGL/test/BGL/graph_concept_Triangulation_2.cpp index a62819f5c0c..09a54241928 100644 --- a/BGL/test/BGL/graph_concept_Triangulation_2.cpp +++ b/BGL/test/BGL/graph_concept_Triangulation_2.cpp @@ -1,4 +1,5 @@ #include + #include #include #include diff --git a/BGL/test/BGL/test_Has_member_id.cpp b/BGL/test/BGL/test_Has_member_id.cpp index e04d040c86d..6ff478d04c2 100644 --- a/BGL/test/BGL/test_Has_member_id.cpp +++ b/BGL/test/BGL/test_Has_member_id.cpp @@ -2,9 +2,13 @@ #include #include + #include #include +#include +#include + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::Polyhedron_3 Polyhedron_with_ids; @@ -32,5 +36,9 @@ int main() CGAL_static_assertion( (Has_member_id::Face>::value)); + CGAL_static_assertion(!Has_member_id >::value); + CGAL_static_assertion(Has_member_id >::value); + CGAL_static_assertion(Has_member_id >::value); + return 0; } diff --git a/BGL/test/BGL/test_Prefix.h b/BGL/test/BGL/test_Prefix.h index 8aacfd12f99..e5343a10659 100644 --- a/BGL/test/BGL/test_Prefix.h +++ b/BGL/test/BGL/test_Prefix.h @@ -1,8 +1,6 @@ #ifndef CGAL_TEST_PREFIX_H #define CGAL_TEST_PREFIX_H -#define CGAL_USE_SURFACE_MESH - #include #include @@ -12,14 +10,34 @@ #include #include + #include #include #include -#ifdef CGAL_USE_SURFACE_MESH #include #include -#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include @@ -37,10 +55,7 @@ typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits; typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper <2, 3, MyTraits>::type LCC; - -#ifdef CGAL_USE_SURFACE_MESH typedef CGAL::Surface_mesh SM; -#endif #if defined(CGAL_USE_OPENMESH) @@ -55,6 +70,31 @@ typedef CGAL::Surface_mesh SM; typedef OpenMesh::PolyMesh_ArrayKernelT OMesh; #endif +typedef CGAL::Triangulation_vertex_base_with_id_2 Vbb; +typedef CGAL::Triangulation_face_base_with_id_2 Fbb; + +typedef CGAL::Triangulation_2 > Triangulation_2; +typedef CGAL::Delaunay_triangulation_2 > Delaunay_triangulation_2; + +typedef CGAL::Regular_triangulation_vertex_base_2 RVb; +typedef CGAL::Regular_triangulation_face_base_2 RFb; +typedef CGAL::Regular_triangulation_2 > Regular_triangulation_2; + +typedef CGAL::Constrained_triangulation_face_base_2 CDFb; +typedef CGAL::Triangulation_hierarchy_vertex_base_2 CDVb; +typedef CGAL::Constrained_triangulation_2 > Constrained_triangulation_2; +typedef CGAL::Constrained_Delaunay_triangulation_2 > Constrained_Delaunay_triangulation_2; + +typedef CGAL::Constrained_triangulation_plus_2< + Constrained_Delaunay_triangulation_2> CDT_P2; + +typedef CGAL::Triangulation_hierarchy_2 Triangulation_hierarchy_2; + #include // helper to easily define all graph_traits members @@ -137,21 +177,46 @@ std::vector t_data() return vs; } -std::vector poly_data() -{ return t_data(); } - -#if defined(CGAL_USE_SURFACE_MESH) -std::vector sm_data() -{ return t_data(); } -#endif +std::vector poly_data() { return t_data(); } +std::vector sm_data() { return t_data(); } +std::vector lcc_data() { return t_data(); } #if defined(CGAL_USE_OPENMESH) -std::vector omesh_data() -{ return t_data(); } +std::vector omesh_data() { return t_data(); } #endif -std::vector lcc_data() -{ return t_data(); } +template +Tr build_dummy_triangulation() +{ + typedef typename Tr::Point Point; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + Tr t; + t.insert(Point(0.1,0)); + t.insert(Point(1,0)); + t.insert(Point(0.2,0.2)); + t.insert(Point(0,1)); + t.insert(Point(0,2)); + + int id = 0; + for(vertex_descriptor vd : vertices(t)) + vd->id() = id++; + + id = 0; + for(face_descriptor fd : faces(t)) + fd->id() = id++; + + return t; +} + +Triangulation_2 t2_data() { return build_dummy_triangulation(); } +Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation(); } +Regular_triangulation_2 rt2_data() { return build_dummy_triangulation(); } +Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation(); } +Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation(); } +CDT_P2 cdtp2_data() { return build_dummy_triangulation(); } +Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation(); } template struct Surface_fixture_1 { diff --git a/BGL/test/BGL/test_Properties.cpp b/BGL/test/BGL/test_Properties.cpp index 07975c24940..3ffd9d1720e 100644 --- a/BGL/test/BGL/test_Properties.cpp +++ b/BGL/test/BGL/test_Properties.cpp @@ -1,5 +1,5 @@ - #include "test_Prefix.h" + #include template< typename G, @@ -31,7 +31,6 @@ void index_uniqueness(const G&, void index_uniqueness_poly(const Polyhedron& g) { - std::cerr << "testing Polyhedron\n"; index_uniqueness(g, edges(g) , get(boost::edge_index, g)); index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); index_uniqueness(g, faces(g), get(boost::face_index, g)); @@ -45,28 +44,23 @@ void index_uniqueness_poly(const Polyhedron& g) void index_uniqueness_lcc(const LCC& g) { - std::cerr << "testing Linear_cell_complex\n"; index_uniqueness(g, edges(g) , get(boost::edge_index, g)); index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); index_uniqueness(g, faces(g), get(boost::face_index, g)); index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); } -#if defined(CGAL_USE_SURFACE_MESH) void index_uniqueness_sm(const SM& g) { - std::cerr << "testing Surface_mesh\n"; index_uniqueness(g, edges(g) , get(boost::edge_index, g)); index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); index_uniqueness(g, faces(g), get(boost::face_index, g)); index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); } -#endif #if defined(CGAL_USE_OPENMESH) void index_uniqueness_omesh(const OMesh& g) { - std::cerr << "testing OpenMesh\n"; index_uniqueness(g, edges(g) , get(boost::edge_index, g)); index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); index_uniqueness(g, faces(g), get(boost::face_index, g)); @@ -74,35 +68,48 @@ void index_uniqueness_omesh(const OMesh& g) } #endif -int -main() +template +void index_uniqueness_tr(const Triangulation& g) { + index_uniqueness(g, edges(g) , get(boost::edge_index, g)); + index_uniqueness(g, vertices(g), get(boost::vertex_index, g)); + index_uniqueness(g, faces(g), get(boost::face_index, g)); + index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g)); +} + +int main() +{ + std::cout << "testing Polyhedron\n"; std::vector polys = poly_data(); - - for(Polyhedron p : polys){ + for(Polyhedron p : polys) index_uniqueness_poly(p); - } + std::cout << "testing Linear_cell_complex\n"; std::vector lccs = lcc_data(); - for(LCC p : lccs){ + for(LCC p : lccs) index_uniqueness_lcc(p); - } -#if defined(CGAL_USE_SURFACE_MESH) + std::cout << "testing Surface_mesh\n"; std::vector sms = sm_data(); - - for(SM p : sms){ + for(SM p : sms) index_uniqueness_sm(p); - } -#endif #if defined(CGAL_USE_OPENMESH) + std::cout << "testing OpenMesh\n"; std::vector omeshs = omesh_data(); - for(OMesh p : omeshs){ + for(OMesh p : omeshs) index_uniqueness_omesh(p); - } #endif + std::cout << "testing Triangulations\n"; + index_uniqueness_tr(t2_data()); + index_uniqueness_tr(dt2_data()); + index_uniqueness_tr(rt2_data()); + index_uniqueness_tr(ct2_data()); + index_uniqueness_tr(cdt2_data()); + index_uniqueness_tr(cdtp2_data()); + index_uniqueness_tr(t2h_data()); + std::cerr << "done\n"; return 0; } diff --git a/BGL/test/BGL/test_graph_traits.cpp b/BGL/test/BGL/test_graph_traits.cpp index 102b04ff3ba..7e6e399aa05 100644 --- a/BGL/test/BGL/test_graph_traits.cpp +++ b/BGL/test/BGL/test_graph_traits.cpp @@ -1,11 +1,11 @@ - - #include "test_Prefix.h" -#include -#include + #include -typedef boost::unordered_set id_map; +#include +#include + +typedef boost::unordered_set id_map; template void test_isolated_vertex() @@ -58,6 +58,29 @@ void test_halfedge_around_face_iterator(const Graph& g) } } +template +void test_halfedge_iterators(const G& g) +{ + typedef boost::graph_traits< G > Traits; + typedef typename Traits::halfedge_iterator halfedge_iterator; + typedef typename Traits::halfedges_size_type halfedges_size_type; + + // do we iterate as many as that? + halfedge_iterator hb, he; + boost::tie(hb, he) = halfedges(g); + assert(boost::numeric_cast(std::distance(hb, he)) == num_halfedges(g)); + + id_map ids; + unsigned int count = 0; + for(boost::tie(hb, he) = halfedges(g); hb != he; ++hb) { + std::pair r = ids.insert(get(boost::halfedge_index, g, *hb)); + // unique? + assert(r.second); + ++count; + } + assert(count == num_halfedges(g)); +} + template void test_edge_iterators(const G& g) { @@ -86,7 +109,7 @@ void test_edge_iterators(const G& g) } template -void test_vertex_iterators(G& g) +void test_vertex_iterators(const G& g) { typedef boost::graph_traits< G > Traits; typedef typename Traits::vertex_iterator vertex_iterator; @@ -256,39 +279,55 @@ void test_read(const G& g) assert(CGAL::is_valid_polygon_mesh(g)); } - template -void -test(const std::vector& graphs) +void test_const_graph(const Graph& g) { - for(const Graph& p : graphs){ - test_edge_iterators(p); - test_read(p); - test_vertex_iterators(p); - test_out_edges(p); - test_in_edges(p); - test_in_out_edges(p); - test_edge_find(p); - test_faces(p); - test_halfedge_around_vertex_iterator(p); - test_halfedge_around_face_iterator(p); - } - test_isolated_vertex(); + test_vertex_iterators(g); + test_halfedge_iterators(g); + test_edge_iterators(g); + test_read(g); + test_out_edges(g); + test_in_edges(g); + test_in_out_edges(g); + test_edge_find(g); + test_faces(g); + test_halfedge_around_vertex_iterator(g); + test_halfedge_around_face_iterator(g); } -int -main() +template +void test_graph_range(const std::vector& graphs) { - test(poly_data()); + for(const Graph& g : graphs) + { + test_const_graph(g); + test_isolated_vertex(); + } +} - test(lcc_data()); +int main() +{ + std::cout << "Test polyhedron data..." << std::endl; + test_graph_range(poly_data()); -#if defined(CGAL_USE_SURFACE_MESH) - test(sm_data()); -#endif + std::cout << "Test LCC data..." << std::endl; + test_graph_range(lcc_data()); + + std::cout << "Test Surface_mesh data..." << std::endl; + test_graph_range(sm_data()); + + std::cout << "Test T2 data..." << std::endl; + test_const_graph(t2_data()); + test_const_graph(dt2_data()); + test_const_graph(rt2_data()); + test_const_graph(ct2_data()); + test_const_graph(cdt2_data()); + test_const_graph(cdtp2_data()); + test_const_graph(t2h_data()); #if defined(CGAL_USE_OPENMESH) - test(omesh_data()); + std::cout << "Test OpenMesh data..." << std::endl; + test_graph_range(omesh_data()); #endif std::cerr << "done" << std::endl; From 5cdfd8217c2c6d6ba4bfbb19b7193eb9d3877df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 25 Apr 2019 16:07:21 +0200 Subject: [PATCH 13/68] Fixes to PMP::locate() --- .../CGAL/Polygon_mesh_processing/locate.h | 511 +++++++++++------- 1 file changed, 320 insertions(+), 191 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 158195af63f..d69a6a32d88 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -38,13 +37,16 @@ #include #include -#include #include +#include #include #include #include +#include +#include #include +#include // Everywhere in this file: // If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) @@ -72,20 +74,20 @@ struct Locate_types halfedge_descriptor, face_descriptor> descriptor_variant; - typedef typename boost::mpl::if_< - boost::is_same< - NamedParameters, Default>, + typedef typename std::conditional< + std::is_same< + NamedParameters, Default>::value, typename boost::property_map::const_type, + boost::vertex_point_t>::const_type, typename GetVertexPointMap::const_type - >::type VertexPointMap; - typedef typename boost::property_traits::value_type Point; + >::type VPM; + typedef typename boost::property_traits::value_type Point; typedef typename CGAL::Kernel_traits::type Kernel; typedef typename Kernel::FT FT; - typedef CGAL::cpp11::array Barycentric_coordinates; + typedef std::array Barycentric_coordinates; typedef std::pair Face_location; }; @@ -156,10 +158,11 @@ snap_coordinates_to_border(typename Locate_types::Barycentric_coor { typedef typename internal::Locate_types::FT FT; - // @tmp clean that or protect it with a macro/variable -// std::cout << "Pre-snapping: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; -// std::cout << "Sum: " << coords[0] + coords[1] + coords[2] << std::endl; -// std::cout << "tolerance: " << tolerance << std::endl; +#ifdef CGAL_PMP_LOCATE_DEBUG + std::cout << "Pre-snapping: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; + std::cout << "Sum: " << coords[0] + coords[1] + coords[2] << std::endl; + std::cout << "tolerance: " << tolerance << std::endl; +#endif // To still keep a sum roughly equals to 1, keep in memory the small changes FT residue = 0.; @@ -191,11 +194,12 @@ snap_coordinates_to_border(typename Locate_types::Barycentric_coor } } - // @tmp clean that or protect it with a macro/variable -// std::cout << "Post-snapping: " << coords[0] << " " -// << coords[1] << " " -// << coords[2] << std::endl; -// std::cout << "Sum: " << coords[0] + coords[1] + coords[2] << std::endl; +#ifdef CGAL_PMP_LOCATE_DEBUG + std::cout << "Post-snapping: " << coords[0] << " " + << coords[1] << " " + << coords[2] << std::endl; + std::cout << "Sum: " << coords[0] + coords[1] + coords[2] << std::endl; +#endif return snapped; } @@ -230,6 +234,114 @@ random_entity_in_range(const CGAL::Iterator_range& range, return random_entity_in_range(range.begin(), range.end(), rnd); } +template +struct Barycentric_coordinate_calculator // 2D version +{ + CGAL::array + 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::Vector_2 Vector_2; + + typename K::Construct_point_2 cp2 = k.construct_point_2_object(); + typename K::Construct_vector_2 cv2 = k.construct_vector_2_object(); + typename K::Compute_scalar_product_2 csp2 = k.compute_scalar_product_2_object(); + + const typename K::Point_2& p = cp2(ip); + const typename K::Point_2& q = cp2(iq); + const typename K::Point_2& r = cp2(ir); + const typename K::Point_2& query = cp2(iquery); + + Vector_2 v0 = cv2(p, q); + Vector_2 v1 = cv2(p, r); + Vector_2 v2 = cv2(p, query); + + FT d00 = csp2(v0, v0); + FT d01 = csp2(v0, v1); + FT d11 = csp2(v1, v1); + FT d20 = csp2(v2, v0); + FT d21 = csp2(v2, v1); + + FT denom = d00 * d11 - d01 * d01; + + FT v = (d11 * d20 - d01 * d21) / denom; + FT w = (d00 * d21 - d01 * d20) / denom; + + return CGAL::make_array(FT(FT(1) - v - w), v, w); + } +}; + +template +struct Barycentric_coordinate_calculator +{ + CGAL::array + 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::Vector_3 Vector_3; + + typename K::Construct_point_3 cp3 = k.construct_point_3_object(); + typename K::Construct_vector_3 cv3 = k.construct_vector_3_object(); + typename K::Compute_scalar_product_3 csp3 = k.compute_scalar_product_3_object(); + + const typename K::Point_3& p = cp3(ip); + const typename K::Point_3& q = cp3(iq); + const typename K::Point_3& r = cp3(ir); + const typename K::Point_3& query = cp3(iquery); + + Vector_3 v0 = cv3(p, q); + Vector_3 v1 = cv3(p, r); + Vector_3 v2 = cv3(p, query); + + FT d00 = csp3(v0, v0); + FT d01 = csp3(v0, v1); + FT d11 = csp3(v1, v1); + FT d20 = csp3(v2, v0); + FT d21 = csp3(v2, v1); + + CGAL_assertion((d00 * d11 - d01 * d01) != FT(0)); // denom != 0. + FT denom_inv = 1. / (d00 * d11 - d01 * d01); + + FT v = (d11 * d20 - d01 * d21) * denom_inv; + FT w = (d00 * d21 - d01 * d20) * denom_inv; + + return CGAL::make_array(FT(FT(1) - v - w), v, w); + } +}; + +template +struct Barycentric_point_constructor // 2D version +{ + typedef typename K::FT FT; + + P operator()(const P& p, const FT wp, const P& q, const FT wq, const P& r, const FT wr) const + { + FT sum = wp + wq + wr; + CGAL_assertion(sum != 0); + FT x = (wp * p.x() + wq * q.x() + wr * r.x()) / sum; + FT y = (wp * p.y() + wq * q.y() + wr * r.y()) / sum; + + return P(x, y); + } +}; + +template +struct Barycentric_point_constructor // 3D version +{ + typedef typename K::FT FT; + + P operator()(const P& p, const FT wp, const P& q, const FT wq, const P& r, const FT wr) const + { + FT sum = wp + wq + wr; + CGAL_assertion(sum != 0); + FT x = (wp * p.x() + wq * q.x() + wr * r.x()) / sum; + FT y = (wp * p.y() + wq * q.y() + wr * r.y()) / sum; + FT z = (wp * p.z() + wq * q.z() + wr * r.z()) / sum; + + return P(x, y, z); + } +}; + } // namespace internal /// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `pm`. @@ -323,8 +435,11 @@ int vertex_index_in_face(const typename boost::graph_traits::vertex halfedge_descriptor current = start; int counter = 0; + std::cout << "vd to find: " << &*vd << " pt: " << vd->point() << std::endl; + do { + std::cout << "current source: " << &*source(current, pm) << " pt: " << source(current, pm)->point() << std::endl; if(source(current, pm) == vd) break; @@ -370,81 +485,6 @@ int halfedge_index_in_face(typename boost::graph_traits::halfedge_d return count; } -template -struct Barycentric_coordinate_calculator // 2D version -{ - CGAL::array - 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::Vector_2 Vector_2; - - typename K::Construct_point_2 cp2 = k.construct_point_2_object(); - typename K::Construct_vector_2 cv2 = k.construct_vector_2_object(); - typename K::Compute_scalar_product_2 csp2 = k.compute_scalar_product_2_object(); - - const typename K::Point_2& p = cp2(ip); - const typename K::Point_2& q = cp2(iq); - const typename K::Point_2& r = cp2(ir); - const typename K::Point_2& query = cp2(iquery); - - Vector_2 v0 = cv2(p, q); - Vector_2 v1 = cv2(p, r); - Vector_2 v2 = cv2(p, query); - - FT d00 = csp2(v0, v0); - FT d01 = csp2(v0, v1); - FT d11 = csp2(v1, v1); - FT d20 = csp2(v2, v0); - FT d21 = csp2(v2, v1); - - FT denom = d00 * d11 - d01 * d01; - - FT v = (d11 * d20 - d01 * d21) / denom; - FT w = (d00 * d21 - d01 * d20) / denom; - - return CGAL::make_array(FT(1) - v - w, v, w); - } -}; - -template -struct Barycentric_coordinate_calculator -{ - CGAL::array - 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::Vector_3 Vector_3; - - typename K::Construct_point_3 cp3 = k.construct_point_3_object(); - typename K::Construct_vector_3 cv3 = k.construct_vector_3_object(); - typename K::Compute_scalar_product_3 csp3 = k.compute_scalar_product_3_object(); - - const typename K::Point_3& p = cp3(ip); - const typename K::Point_3& q = cp3(iq); - const typename K::Point_3& r = cp3(ir); - const typename K::Point_3& query = cp3(iquery); - - Vector_3 v0 = cv3(p, q); - Vector_3 v1 = cv3(p, r); - Vector_3 v2 = cv3(p, query); - - FT d00 = csp3(v0, v0); - FT d01 = csp3(v0, v1); - FT d11 = csp3(v1, v1); - FT d20 = csp3(v2, v0); - FT d21 = csp3(v2, v1); - - CGAL_assertion((d00 * d11 - d01 * d01) != FT(0)); // denom != 0. - FT denom_inv = 1. / (d00 * d11 - d01 * d01); - - FT v = (d11 * d20 - d01 * d21) * denom_inv; - FT w = (d00 * d21 - d01 * d20) * denom_inv; - - return CGAL::make_array(FT(1) - v - w, v, w); - } -}; - /// \brief Given a set of three points and a query point, computes the barycentric /// coordinates of the query point with respect to the first three points. /// @@ -453,15 +493,21 @@ struct Barycentric_coordinate_calculator /// (this is the case for all standard %CGAL point types). /// \pre `query` lies on the plane defined by `p`, `q`, and `r`. /// +template +CGAL::array +barycentric_coordinates(const P& p, const P& q, const P& r, const P& query, const K& k) +{ + internal::Barycentric_coordinate_calculator calculator; + return calculator(p, q, r, query, k); +} + template CGAL::array::type::FT, 3> barycentric_coordinates(const P& p, const P& q, const P& r, const P& query) { typedef typename CGAL::Kernel_traits

::type Kernel; - Barycentric_coordinate_calculator calculator; - - return calculator(p, q, r, query, Kernel()); + return barycentric_coordinates(p, q, r, query, Kernel()); } // Random locations @@ -487,7 +533,7 @@ random_location_on_halfedge(typename boost::graph_traits::halfedge CGAL_precondition(CGAL::is_triangle_mesh(tm)); - FT t = rnd.uniform_real(FT(0), FT(1)); + FT t(rnd.uniform_real(0., 1.)); return locate_in_face(hd, t, tm); } @@ -513,8 +559,10 @@ random_location_on_face(typename boost::graph_traits::face_descrip CGAL_precondition(CGAL::is_triangle_mesh(tm)); CGAL_precondition(fd != boost::graph_traits::null_face()); - FT u = rnd.uniform_real(FT(0), FT(1)); - FT v = rnd.uniform_real(FT(0), FT(FT(1) - u)); + // calling 'rnd.uniform real' with double in case FT comes from an EPECK kernel (which doesn't seem to work too well) + FT u(rnd.uniform_real(0., 1.)); + FT v(rnd.uniform_real(0., double(FT(1) - u))); + return std::make_pair(fd, CGAL::make_array(u, v, FT(FT(1) - u - v))); } @@ -613,7 +661,7 @@ get_descriptor_from_location(const typename internal::Locate_types /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// @@ -630,24 +678,24 @@ location_to_point(const typename internal::Locate_types::Face_loca typedef typename GetVertexPointMap::const_type VertexPointMap; typedef typename boost::property_traits::value_type Point; - using boost::choose_param; - using boost::get_param; + typedef typename internal::Locate_types::Kernel Kernel; CGAL_precondition(CGAL::is_triangle_mesh(tm)); - VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); + VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); halfedge_descriptor hd = halfedge(loc.first, tm); - const Point p0 = get(vpm, source(hd, tm)); - const Point p1 = get(vpm, target(hd, tm)); - const Point p2 = get(vpm, target(next(hd, tm), tm)); + const Point& p0 = get(vpm, source(hd, tm)); + const Point& p1 = get(vpm, target(hd, tm)); + const Point& p2 = get(vpm, target(next(hd, tm), tm)); - return CGAL::barycenter(p0, loc.second[0], p1, loc.second[1], p2, loc.second[2]); + internal::Barycentric_point_constructor bp_constructor; + return bp_constructor(p0, loc.second[0], p1, loc.second[1], p2, loc.second[2]); } template -typename property_map_value::type +typename property_map_value::type location_to_point(const typename internal::Locate_types::Face_location& loc, const TriangleMesh& tm) { @@ -1069,12 +1117,12 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location +typename internal::Locate_types::Face_location locate_in_face(const typename internal::Locate_types::Point& query, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm, @@ -1089,11 +1137,8 @@ locate_in_face(const typename internal::Locate_types::const_type VertexPointMap; typedef typename boost::property_traits::value_type Point; - using boost::choose_param; - using boost::get_param; - - VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); + VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); vertex_descriptor vd0 = source(halfedge(fd, tm), tm); vertex_descriptor vd1 = target(halfedge(fd, tm), tm); @@ -1103,7 +1148,7 @@ locate_in_face(const typename internal::Locate_types coords = barycentric_coordinates(p0, p1, p2, query); + std::array coords = barycentric_coordinates(p0, p1, p2, query); if(!is_in_face(coords, tm)) { @@ -1120,7 +1165,7 @@ locate_in_face(const typename internal::Locate_types typename internal::Locate_types::Face_location -locate_in_face(const typename property_map_value::type& query, +locate_in_face(const typename property_map_value::type& query, const typename boost::graph_traits::face_descriptor f, const TriangleMesh& tm) { @@ -1247,7 +1292,7 @@ locate_in_common_face(typename internal::Locate_types::Face_locati if(fd == boost::graph_traits::null_face()) continue; - // check if query can be found in that face + // check if 'query' can be found in that face query_location = locate_in_face(query, fd, tm); internal::snap_location_to_border(query_location, tolerance); // @tmp keep or not ? @@ -1367,32 +1412,55 @@ namespace internal { template::value> -struct Point_to_Point_3 +struct Point_to_Point_3 // 2D case { - typedef typename CGAL::Kernel_traits< - typename property_map_value::type>::Kernel K; - typedef typename K::Point_3 Point_3; + typedef typename internal::Locate_types::Kernel K; + typedef typename K::Point_3 Point_3; - Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), 0.); } + Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), 0); } +}; + +template +struct Point_to_Point_3::Kernel::Point_3, + 3> // 3D case with nothing to do +{ + typedef typename internal::Locate_types::Kernel K; + typedef typename K::Point_3 Point_3; + + const Point_3& operator()(const Point_3& p) const { return p; } }; template -struct Point_to_Point_3 +struct Point_to_Point_3 // Generic 3D case { - typedef typename CGAL::Kernel_traits< - typename property_map_value::type>::Kernel K; - typedef typename K::Point_3 Point_3; + typedef typename internal::Locate_types::Kernel K; + typedef typename K::Point_3 Point_3; - const Point_3& operator()(const Point_3& p) const { return p; } - Point_3 operator()(const Point& p) { return Point_3(p.x(), p.y(), p.z()); } + Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), p.z()); } +}; + +template +struct Ray_to_Ray_3 // 2D case +{ + typedef typename internal::Locate_types::Kernel K; + typedef typename K::Ray_2 Ray_2; + typedef typename K::Ray_3 Ray_3; + typedef Point_to_Point_3 P2_to_P3; + + Ray_3 operator()(const Ray_2& r) const + { + P2_to_P3 to_p3; + return Ray_3(to_p3(r.source()), to_p3(r.second_point())); + } + + const Ray_3& operator()(const Ray_3& r) const { return r; } }; /// Readable property map that converts the output of a given vertex point map to a 3D point template::const_type> + boost::vertex_point_t>::const_type> struct Point_to_Point_3_VPM { private: @@ -1408,14 +1476,11 @@ public: typedef typename K::Point_3 Point_3; // required typedefs - typedef vertex_descriptor key_type; + typedef typename boost::property_traits::key_type key_type; typedef Point_3 value_type; typedef value_type reference; typedef boost::readable_property_map_tag category; - CGAL_static_assertion((boost::is_same::key_type, - vertex_descriptor>::value)); - // Constructors Point_to_Point_3_VPM() : conv_(), vpm_() { } // required for compilation by AABBtraits Point_to_Point_3_VPM(const VertexPointMap vpm) : conv_(), vpm_(vpm) { } @@ -1438,6 +1503,38 @@ private: VertexPointMap vpm_; }; +// Two different functions, because the AABB's traits' VPM must match the passed VPM (that is, +// the original VPM wrapped with P_to_P3_VPM if the VPM's value_type was not Point_3) +template +void build_AABB_tree(const TriangleMesh& tm, + AABB_tree& outTree, + const VPM& wrapped_vpm, + typename std::enable_if< + std::is_same< + typename AABBTraits::Point_3, typename boost::property_traits::value_type + >::value>::type* = 0) +{ + typename boost::graph_traits::face_iterator ffirst, fbeyond; + boost::tie(ffirst, fbeyond) = faces(tm); + outTree.rebuild(ffirst, fbeyond, tm, wrapped_vpm); + outTree.build(); +} + +template +void build_AABB_tree(const TriangleMesh& tm, + AABB_tree& outTree, + const VPM& vpm, + typename std::enable_if< + !std::is_same< + typename AABBTraits::Point_3, typename boost::property_traits::value_type + >::value>::type* = 0) +{ + typedef internal::Point_to_Point_3_VPM Wrapped_VPM; + const Wrapped_VPM wrapped_vpm(vpm); + + return internal::build_AABB_tree(tm, outTree, wrapped_vpm); +} + } // namespace internal /// \name Nearest Face Location Queries @@ -1460,7 +1557,7 @@ private: /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// @@ -1469,18 +1566,12 @@ void build_AABB_tree(const TriangleMesh& tm, AABB_tree& outTree, const NamedParameters& np) { - typedef typename GetVertexPointMap::const_type VertexPointMap; + typedef typename GetVertexPointMap::const_type VertexPointMap; - using boost::choose_param; - using boost::get_param; + const VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); - VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); - - typename boost::graph_traits::face_iterator facesStart, facesEnd; - boost::tie(facesStart, facesEnd) = faces(tm); - outTree.rebuild(facesStart, facesEnd, tm, vpm); - outTree.build(); + return internal::build_AABB_tree(tm, outTree, vpm); } template @@ -1505,25 +1596,46 @@ void build_AABB_tree(const TriangleMesh& tm, /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename AABBTraits::Point_3& p, +typename internal::Locate_types::Face_location +locate_with_AABB_tree(const typename internal::Locate_types::Point& p, const AABB_tree& tree, const TriangleMesh& tm, const NamedParameters& np) { - typename AABB_tree::Point_and_primitive_id result = tree.closest_point_and_primitive(p); + typedef typename internal::Locate_types::Point Point; + typedef internal::Point_to_Point_3 P_to_P3; + typedef typename AABBTraits::Point_3 Point_3; + CGAL_static_assertion((std::is_same::value)); - return locate_in_face(result.first, result.second, tm, np); + typedef typename GetVertexPointMap::const_type VertexPointMap; + typedef internal::Point_to_Point_3_VPM WrappedVPM; + + const Point_3& p3 = P_to_P3()(p); + typename AABB_tree::Point_and_primitive_id result = tree.closest_point_and_primitive(p3); + + // The VPM might return a point of any dimension, but the AABB tree necessarily returns + // a Point_3. So, wrap the VPM (again) to give a Point_3. Even if it's already wrapped, we're just + // forwarding a const& anyway. + const VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + const WrappedVPM wrapped_vpm(vpm); + + std::cout << "Result: " << result.first << std::endl; + std::cout << "in face: " << result.second->vertex(0)->point() << std::endl; + std::cout << "in face: " << result.second->vertex(1)->point() << std::endl; + std::cout << "in face: " << result.second->vertex(2)->point() << std::endl; + + return locate_in_face(result.first, result.second, tm, CGAL::parameters::vertex_point_map(wrapped_vpm)); } template typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename AABBTraits::Point_3& p, +locate_with_AABB_tree(const typename internal::Locate_types::Point& p, const AABB_tree& tree, const TriangleMesh& tm) { @@ -1549,42 +1661,47 @@ locate_with_AABB_tree(const typename AABBTraits::Point_3& p, /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate(const typename internal::Locate_types::Point& p, +typename internal::Locate_types::Face_location +locate(const typename internal::Locate_types::Point& p, const TriangleMesh& tm, const NamedParameters& np) { - typedef typename GetVertexPointMap::const_type VertexPointMap; - // Wrap the input VPM with a one converting to 3D (costs nothing if the input VPM // already has value type Kernel::Point_3) - typedef internal::Point_to_Point_3_VPM VPM; + typedef typename GetVertexPointMap::const_type VertexPointMap; + typedef internal::Point_to_Point_3_VPM WrappedVPM; + typedef typename internal::Locate_types::Point Intrinsic_point; - typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; - typedef CGAL::AABB_traits::Kernel, - AABB_face_graph_primitive> AABB_face_graph_traits; + typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; + typedef CGAL::AABB_traits< + typename internal::Locate_types::Kernel, + AABB_face_graph_primitive> AABB_face_graph_traits; - using boost::get_param; - using boost::choose_param; + typedef internal::Point_to_Point_3 P_to_P3; + typedef typename AABB_face_graph_traits::Point_3 Point_3; - const VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); - const VPM wrapped_vpm(vpm); + CGAL_static_assertion((std::is_same::value)); + + const VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + const WrappedVPM wrapped_vpm(vpm); AABB_tree tree; build_AABB_tree(tm, tree, parameters::vertex_point_map(wrapped_vpm)); - return locate_with_AABB_tree(p, tree, tm, parameters::vertex_point_map(wrapped_vpm)); + const Point_3& p3 = P_to_P3()(p); + + return locate_with_AABB_tree(p3, tree, tm, parameters::vertex_point_map(wrapped_vpm)); } template typename internal::Locate_types::Face_location -locate(const typename property_map_value::type& p, +locate(const typename property_map_value::type& p, const TriangleMesh& tm) { return locate(p, tm, parameters::all_default()); @@ -1592,7 +1709,7 @@ locate(const typename property_map_value::ty namespace internal { -// The Ray must have the same ambient dimension as the property map's value type (point type) +// The Ray must have the same ambient dimension as the property map's value type (aka, the point type) template ::value> @@ -1626,32 +1743,39 @@ struct Ray_type_selector /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// template typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename CGAL::Kernel_traits::type::Ray_3& ray, +locate_with_AABB_tree(const typename internal::Ray_type_selector< + typename internal::Locate_types::Point>::type& ray, const AABB_tree& tree, const TriangleMesh& tm, const NamedParameters& np) { - typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename internal::Locate_types::Kernel Kernel; - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_3 Point_3; - typedef typename Kernel::Ray_3 Ray_3; + typedef typename Kernel::FT FT; + typedef typename Kernel::Point_3 Point_3; + typedef typename Kernel::Ray_3 Ray_3; - typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef AABB_tree AABB_face_graph_tree; + typedef typename GetVertexPointMap::const_type VertexPointMap; + typedef internal::Point_to_Point_3_VPM WrappedVPM; + typedef internal::Ray_to_Ray_3 R_to_R3; + typedef AABB_tree AABB_face_graph_tree; typedef typename AABB_face_graph_tree::template Intersection_and_primitive_id::Type Intersection_type; - typedef boost::optional Ray_intersection; + typedef boost::optional Ray_intersection; + + // First, transform the ray into a 3D ray if needed + Ray_3 ray_3 = R_to_R3()(ray); std::vector intersections; - tree.all_intersections(ray, std::back_inserter(intersections)); + tree.all_intersections(ray_3, std::back_inserter(intersections)); bool found = false; FT nearest_distance = 0; @@ -1666,7 +1790,7 @@ locate_with_AABB_tree(const typename CGAL::Kernel_traits::null_face(), CGAL::make_array(FT(0), FT(0), FT(0))); @@ -1688,7 +1819,8 @@ locate_with_AABB_tree(const typename CGAL::Kernel_traits typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename CGAL::Kernel_traits::type::Ray_3& ray, +locate_with_AABB_tree(const typename internal::Ray_type_selector< + typename internal::Locate_types::Point>::type& ray, const AABB_tree& tree, const TriangleMesh& tm) { @@ -1714,12 +1846,12 @@ locate_with_AABB_tree(const typename CGAL::Kernel_traits -typename internal::Locate_types::Face_location +typename internal::Locate_types::Face_location locate(const typename internal::Ray_type_selector< typename internal::Locate_types::Point>::type& ray, const TriangleMesh& tm, @@ -1735,11 +1867,8 @@ locate(const typename internal::Ray_type_selector< typedef CGAL::AABB_traits::Kernel, AABB_face_graph_primitive> AABB_face_graph_traits; - using boost::get_param; - using boost::choose_param; - - const VertexPointMap vpm = choose_param(get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); + const VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); const VPM wrapped_vpm(vpm); AABB_tree tree; From e919ceff80dff7d9cc3d2a6321c883ba86654761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 25 Apr 2019 16:08:06 +0200 Subject: [PATCH 14/68] Improve PMP::locate() tests --- .../test_pmp_locate.cpp | 479 +++++++++++++----- 1 file changed, 351 insertions(+), 128 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 5fe6454d8e2..6c3c96a6dd2 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -1,24 +1,27 @@ -#include +#include #include +#include // Graphs #include #include #include #include -#include +#include #include #include #include #include +#include #include #include #include +#include #include #include -#include +#include #include #include @@ -33,9 +36,34 @@ namespace PMP = CGAL::Polygon_mesh_processing; +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; +typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; +typedef CGAL::Simple_cartesian::Type> Exact_kernel; + +template +typename CGAL::Kernel_traits::type::Ray_2 +random_2D_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd) +{ + typedef typename AABB_tree::AABB_traits::Point_3 Point_3; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Ray_2 Ray_2; + + const CGAL::Bbox_3& bbox = aabb_tree.bbox(); + + FT px = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax()); + FT py = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax()); + + FT qx = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax()); + FT qy = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax()); + + return Ray_2(Point_2(px, py), Point_2(qx, qy)); +} + template typename CGAL::Kernel_traits::type::Ray_3 -random_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd) +random_3D_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd) { typedef typename AABB_tree::AABB_traits::Point_3 Point_3; typedef typename CGAL::Kernel_traits::type Kernel; @@ -44,13 +72,13 @@ random_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd) const CGAL::Bbox_3& bbox = aabb_tree.bbox(); - FT px = rnd.get_double(bbox.xmin(), bbox.xmax()); - FT py = rnd.get_double(bbox.ymin(), bbox.ymax()); - FT pz = rnd.get_double(bbox.zmin(), bbox.zmax()); + FT px = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax()); + FT py = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax()); + FT pz = (bbox.zmin() == bbox.zmax()) ? bbox.zmin() : rnd.get_double(bbox.zmin(), bbox.zmax()); - FT qx = rnd.get_double(bbox.xmin(), bbox.xmax()); - FT qy = rnd.get_double(bbox.ymin(), bbox.ymax()); - FT qz = rnd.get_double(bbox.zmin(), bbox.zmax()); + FT qx = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax()); + FT qy = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax()); + FT qz = (bbox.zmin() == bbox.zmax()) ? bbox.zmin() : rnd.get_double(bbox.zmin(), bbox.zmax()); return Ray_3(Point_3(px, py, pz), Point_3(qx, qy, qz)); } @@ -76,10 +104,10 @@ void test_snappers(const G& g) // --------------------------------------------------------------------------- PMP::internal::snap_coordinates_to_border(coords); // uses numeric_limits' epsilon() - assert(coords[0] == 1e-11 && coords[1] == 1. && coords[2] == 1e-12); + assert(coords[0] == FT(1e-11) && coords[1] == FT(1) && coords[2] == FT(1e-12)); PMP::internal::snap_coordinates_to_border(coords, 1e-10); - assert(coords[0] == 0. && coords[1] == 1. && coords[2] == 0.); + assert(coords[0] == FT(0) && coords[1] == FT(1) && coords[2] == FT(0)); // --------------------------------------------------------------------------- PMP::internal::snap_location_to_border(loc); // uses numeric_limits' epsilon() @@ -89,6 +117,19 @@ void test_snappers(const G& g) assert(PMP::is_on_face_border(loc, g)); } + +template +struct Point_to_bare_point +{ + typedef typename K::Point_2 type; +}; + +template +struct Point_to_bare_point +{ + typedef typename K::Point_3 type; +}; + template void test_constructions(const G& g, CGAL::Random& rnd) { @@ -102,6 +143,7 @@ void test_constructions(const G& g, CGAL::Random& rnd) typedef typename boost::property_map_value::type Point; typedef typename CGAL::Kernel_traits::type Kernel; typedef typename Kernel::FT FT; + typedef typename Point_to_bare_point::type Bare_point; typedef typename PMP::internal::Locate_types::Barycentric_coordinates Barycentric_coordinates; typedef typename PMP::internal::Locate_types::Face_location Face_location; @@ -117,6 +159,10 @@ void test_constructions(const G& g, CGAL::Random& rnd) Point q = get(vpm, target(h, g)); Point r = get(vpm, target(next(h, g), g)); + Bare_point bp(p); + Bare_point bq(q); + Bare_point br(r); + Barycentric_coordinates bar; Face_location loc; loc.first = f; @@ -129,7 +175,8 @@ void test_constructions(const G& g, CGAL::Random& rnd) bar = PMP::barycentric_coordinates(p, q, r, r, Kernel()); assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(1))); - bar = PMP::barycentric_coordinates(p, q, r, CGAL::midpoint(p, q), Kernel()); + Point mp = Point(CGAL::midpoint(bp, bq)); + bar = PMP::barycentric_coordinates(p, q, r, mp); assert(is_equal(bar[0], FT(0.5)) && is_equal(bar[1], FT(0.5)) && is_equal(bar[2], FT(0))); int n = 1e2; @@ -139,12 +186,13 @@ void test_constructions(const G& g, CGAL::Random& rnd) const FT b = rnd.get_double(-1., 1.); const FT c = 1. - a - b; - Point bp = CGAL::barycenter(p, a, q, b, r, c); - bar = PMP::barycentric_coordinates(p, q, r, bp); + Bare_point barycentric_pt = CGAL::barycenter(bp, a, bq, b, br, c); + bar = PMP::barycentric_coordinates(p, q, r, Point(barycentric_pt)); assert(is_equal(bar[0], a) && is_equal(bar[1], b) && is_equal(bar[2], c)); loc.second = bar; - assert(CGAL::squared_distance(bp, PMP::location_to_point(loc, g)) < std::numeric_limits::epsilon()); + const FT sq_dist = CGAL::squared_distance(barycentric_pt, Bare_point(PMP::location_to_point(loc, g))); + assert(is_equal(sq_dist, FT(0))); } // --------------------------------------------------------------------------- @@ -180,6 +228,10 @@ void test_random_entities(const G& g, CGAL::Random& rnd) typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename boost::property_map_value::type Point; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + vertex_descriptor v; halfedge_descriptor h; edge_descriptor e; @@ -227,27 +279,27 @@ void test_random_entities(const G& g, CGAL::Random& rnd) loc.first = f; int nn = 1e2; - while(nn --> 0) + while(nn --> 0) // famous 'go to zero' operator { loc = PMP::random_location_on_mesh(g, rnd); assert(loc.first != boost::graph_traits::null_face()); - assert(loc.second[0] >= 0.0 && loc.second[0] <= 1.0 && - loc.second[1] >= 0.0 && loc.second[1] <= 1.0 && - loc.second[2] >= 0.0 && loc.second[2] <= 1.0); + assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) && + loc.second[1] >= FT(0) && loc.second[1] <= FT(1) && + loc.second[2] >= FT(0) && loc.second[2] <= FT(1)); loc = PMP::random_location_on_face(f, g, rnd); assert(loc.first == f); - assert(loc.second[0] >= 0.0 && loc.second[0] <= 1.0 && - loc.second[1] >= 0.0 && loc.second[1] <= 1.0 && - loc.second[2] >= 0.0 && loc.second[2] <= 1.0); + assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) && + loc.second[1] >= FT(0) && loc.second[1] <= FT(1) && + loc.second[2] >= FT(0) && loc.second[2] <= FT(1)); loc = PMP::random_location_on_halfedge(h, g, rnd); assert(loc.first == face(h, g)); - assert(loc.second[0] >= 0.0 && loc.second[0] <= 1.0 && - loc.second[1] >= 0.0 && loc.second[1] <= 1.0 && - loc.second[2] >= 0.0 && loc.second[2] <= 1.0); + assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) && + loc.second[1] >= FT(0) && loc.second[1] <= FT(1) && + loc.second[2] >= FT(0) && loc.second[2] <= FT(1)); int h_id = PMP::halfedge_index_in_face(h, g); - assert(loc.second[(h_id+2)%3] == 0.0); + assert(loc.second[(h_id+2)%3] == FT(0)); } } @@ -351,7 +403,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) assert(PMP::is_on_vertex(loc, target(h, g), g)); loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1))); assert(PMP::is_on_vertex(loc, target(next(h, g), g), g)); - loc = Face_location(f, CGAL::make_array(FT(-1.), FT(1), FT(1))); + loc = Face_location(f, CGAL::make_array(FT(-1), FT(1), FT(1))); assert(!PMP::is_on_vertex(loc, target(next(h, g), g), g)); // --------------------------------------------------------------------------- @@ -369,7 +421,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) assert(PMP::is_in_face(loc, g)); loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1))); assert(PMP::is_in_face(loc, g)); - loc = Face_location(f, CGAL::make_array(FT(0), FT(2), FT(-1.))); + loc = Face_location(f, CGAL::make_array(FT(0), FT(2), FT(-1))); assert(!PMP::is_in_face(loc, g)); // --------------------------------------------------------------------------- @@ -396,14 +448,14 @@ void test_predicates(const G& g, CGAL::Random& rnd) const face_descriptor f = face(h, g); loc.first = f; - loc.second[id_of_h] = 1.; - loc.second[(id_of_h+1)%3] = 0.; - loc.second[(id_of_h+2)%3] = 0.; + loc.second[id_of_h] = FT(1); + loc.second[(id_of_h+1)%3] = FT(0); + loc.second[(id_of_h+2)%3] = FT(0); boost::optional opt_hd = CGAL::is_border(source(h, g), g); assert(PMP::is_on_mesh_border(loc, g) == (opt_hd != boost::none)); - loc.second[id_of_h] = 0.5; - loc.second[(id_of_h+1)%3] = 0.5; + loc.second[id_of_h] = FT(0.5); + loc.second[(id_of_h+1)%3] = FT(0.5); assert(PMP::is_on_mesh_border(loc, g) == CGAL::is_border(edge(h, g), g)); // Even if the point does lie on the border of the mesh, 'false' is returned because @@ -465,18 +517,18 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) assert(loc.first == f && is_equal(loc.second[v_id], FT(1))); // --------------------------------------------------------------------------- - loc.second[0] = 0.2; - loc.second[1] = 0.8; - loc.second[2] = 0.; + loc.second[0] = FT(0.2); + loc.second[1] = FT(0.8); + loc.second[2] = FT(0); halfedge_descriptor neigh_hd = opposite(halfedge(f, g), g); face_descriptor neigh_f = face(neigh_hd, g); int neigh_hd_id = PMP::halfedge_index_in_face(neigh_hd, g); Face_location neigh_loc; neigh_loc.first = neigh_f; - neigh_loc.second[neigh_hd_id] = 0.3; - neigh_loc.second[(neigh_hd_id+1)%3] = 0.7; - neigh_loc.second[(neigh_hd_id+2)%3] = 0.; + neigh_loc.second[neigh_hd_id] = FT(0.3); + neigh_loc.second[(neigh_hd_id+1)%3] = FT(0.7); + neigh_loc.second[(neigh_hd_id+2)%3] = FT(0); if(neigh_f != boost::graph_traits::null_face()) { @@ -489,85 +541,211 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) } } -template -void test_locate_with_AABB_tree(const G& g, CGAL::Random& rnd) +template +struct Locate_with_AABB_tree_Tester // 2D case { - std::cout << " test locate_with_AABB_tree()..." << std::endl; + template + void operator()(const G& g, CGAL::Random& rnd) const + { + std::cout << " test locate_with_AABB_tree (2D)..." << std::endl; - typedef typename boost::property_map_value::type Point; + typedef typename boost::property_map_value::type Point; - typedef typename boost::property_map::const_type VertexPointMap; + typedef typename boost::property_map::const_type VertexPointMap; - typedef typename CGAL::Kernel_traits::type Kernel; - typedef typename Kernel::FT FT; - typedef typename Kernel::Ray_3 Ray_3; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + typedef typename Kernel::Ray_2 Ray_2; + typedef typename Kernel::Ray_3 Ray_3; + typedef typename Kernel::Point_3 Point_3; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::internal::Locate_types::Face_location Face_location; - face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); - halfedge_descriptor h = halfedge(f, g); - vertex_descriptor v = target(h, g); + face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + halfedge_descriptor h = halfedge(f, g); + vertex_descriptor v = target(h, g); - // --------------------------------------------------------------------------- - typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; - typedef CGAL::AABB_traits AABB_face_graph_traits; + // --------------------------------------------------------------------------- + typedef typename boost::property_traits::value_type Intrinsic_point; + typedef PMP::internal::Point_to_Point_3 Intrinsic_point_to_Point_3; + typedef PMP::internal::Point_to_Point_3_VPM WrappedVertexPointMap; + typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; + typedef CGAL::AABB_traits AABB_face_graph_traits; - CGAL::AABB_tree tree_a; - VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g); - typename AABB_face_graph_traits::Point_3 p3_a = get(vpm_a, v); - // --------------------------------------------------------------------------- - typedef typename Kernel::Point_2 Point_2; - typedef PMP::internal::Point_to_Point_3 Point_to_Point_3; - typedef PMP::internal::Point_to_Point_3_VPM VPM; - typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive_with_VPM; - typedef CGAL::AABB_traits AABB_face_graph_traits_with_VPM; + CGAL_static_assertion((std::is_same::value)); - CGAL::AABB_tree tree_b; - typename AABB_face_graph_traits::Point_3 p3_b = Point_to_Point_3()(Point_2(0., 0.)); - VPM vpm_b(g); - // --------------------------------------------------------------------------- + Intrinsic_point_to_Point_3 to_p3; - PMP::build_AABB_tree(g, tree_a); - assert(tree_a.size() == num_faces(g)); + CGAL::AABB_tree tree_a; + VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g); + typename boost::property_traits::value_type p_a = get(vpm_a, v); + const Point_3& p3_a = to_p3(p_a); + std::cout << v->point() << std::endl; + std::cout << "pa3: " << p_a << " ~~~~~~ " << p3_a << std::endl; + assert(p_a == v->point()); - PMP::build_AABB_tree(g, tree_b, CGAL::parameters::vertex_point_map(vpm_b)); - assert(tree_b.size() == num_faces(g)); + CGAL::AABB_tree tree_b; + WrappedVertexPointMap vpm_b(g); + // --------------------------------------------------------------------------- - Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g); - assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); - assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + PMP::build_AABB_tree(g, tree_a); + assert(tree_a.size() == num_faces(g)); - loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); - assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + PMP::build_AABB_tree(g, tree_b, CGAL::parameters::vertex_point_map(vpm_b)); + assert(tree_b.size() == num_faces(g)); - // --------------------------------------------------------------------------- - loc = PMP::locate(p3_a, g); - assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); - assert(PMP::is_in_face(loc, g)); + Face_location loc = PMP::locate_with_AABB_tree(p_a, tree_a, g); + std::cout << "LOC: " << loc.second[0] << " " << loc.second[1] << " " << loc.second[2] << std::endl; + assert(PMP::is_on_vertex(loc, v, g)); + assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + assert(is_equal(CGAL::squared_distance(to_p3(PMP::location_to_point(loc, g)), p3_a), FT(0))); - loc = PMP::locate_with_AABB_tree(p3_b, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); - assert(PMP::is_in_face(loc, g)); + loc = PMP::locate_with_AABB_tree(p_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); + assert(is_equal(CGAL::squared_distance(to_p3(PMP::location_to_point(loc, g)), p3_a), FT(0))); - loc = PMP::locate(p3_b, g, CGAL::parameters::vertex_point_map(vpm_b)); - assert(PMP::is_in_face(loc, g)); - - // --------------------------------------------------------------------------- - Ray_3 r3 = random_ray >(tree_a, rnd); - loc = PMP::locate_with_AABB_tree(r3, tree_a, g); - if(loc.first != boost::graph_traits::null_face()) + // --------------------------------------------------------------------------- + loc = PMP::locate(p_a, g); + assert(is_equal(CGAL::squared_distance(to_p3(PMP::location_to_point(loc, g)), p3_a), FT(0))); assert(PMP::is_in_face(loc, g)); - loc = PMP::locate_with_AABB_tree(r3, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); -} + loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); + assert(PMP::is_in_face(loc, g)); + + loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(vpm_b)); + assert(PMP::is_in_face(loc, g)); + + // --------------------------------------------------------------------------- + Ray_2 r2 = random_2D_ray >(tree_a, rnd); + loc = PMP::locate_with_AABB_tree(r2, tree_a, g); + if(loc.first != boost::graph_traits::null_face()) + assert(PMP::is_in_face(loc, g)); + + Ray_3 r3 = random_3D_ray >(tree_b, rnd); + loc = PMP::locate_with_AABB_tree(r3, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); + } +}; + +template +struct My_3D_Point +{ + typedef typename K::FT FT; + + typedef K R; + typedef CGAL::Dimension_tag<3> Ambient_dimension; + typedef CGAL::Dimension_tag<0> Feature_dimension; + + My_3D_Point() { } + My_3D_Point(const CGAL::Origin& /*o*/) : cx(0), cy(0), cz(0) { } + My_3D_Point(const FT x, const FT y, const FT z) : cx(x), cy(y), cz(z) { } + + FT x() const { return cx; } + FT y() const { return cy; } + FT z() const { return cz; } + +private: + FT cx, cy, cz; +}; + +template <> +struct Locate_with_AABB_tree_Tester<3> // 3D +{ + template + void operator()(const G& g, CGAL::Random& rnd) const + { + std::cout << " test locate_with_AABB_tree (3D)..." << std::endl; + + typedef typename boost::property_map_value::type Point; + + typedef typename boost::property_map::const_type VertexPointMap; + + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::FT FT; + typedef typename Kernel::Ray_3 Ray_3; + typedef typename Kernel::Point_3 Point_3; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + typedef typename PMP::internal::Locate_types::Face_location Face_location; + + face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + halfedge_descriptor h = halfedge(f, g); + vertex_descriptor v = target(h, g); + + // --------------------------------------------------------------------------- + typedef typename PMP::internal::Locate_types::VPM VertexPointMap; + typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; + typedef CGAL::AABB_traits AABB_face_graph_traits; + + CGAL_static_assertion((std::is_same::value)); + + CGAL::AABB_tree tree_a; + VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g); + typename boost::property_traits::value_type p3_a = get(vpm_a, v); + + // below tests the case where the value type of the VPM is not Kernel::Point_3 + typedef My_3D_Point Intrinsic_point; + typedef std::map Custom_map; + typedef boost::associative_property_map Custom_VPM; + typedef PMP::internal::Point_to_Point_3_VPM WrappedVertexPointMap; + typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive_with_WVPM; + typedef CGAL::AABB_traits AABB_face_graph_traits_with_WVPM; + + CGAL::AABB_tree tree_b; + Custom_map custom_map; + for(vertex_descriptor vd : vertices(g)) + { + const Point_3& p = get(vpm_a, vd); + custom_map[vd] = Intrinsic_point(p.x(), p.y(), p.z()); + } + + Custom_VPM custom_vpm(custom_map); + WrappedVertexPointMap vpm_b(custom_vpm); + // --------------------------------------------------------------------------- + + PMP::build_AABB_tree(g, tree_a); + assert(tree_a.size() == num_faces(g)); + + PMP::build_AABB_tree(g, tree_b, CGAL::parameters::vertex_point_map(vpm_b)); + assert(tree_b.size() == num_faces(g)); + + Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g); + assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + + loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); + assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + + // --------------------------------------------------------------------------- + loc = PMP::locate(p3_a, g); + assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + assert(PMP::is_in_face(loc, g)); + + loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); + assert(PMP::is_in_face(loc, g)); + + // doesn't necessarily have to wrap with a P_to_P3 here, it'll do it internally + loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(custom_vpm)); + assert(PMP::is_in_face(loc, g)); + + // --------------------------------------------------------------------------- + Ray_3 r3 = random_3D_ray >(tree_b, rnd); + loc = PMP::locate_with_AABB_tree(r3, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); + } +}; + template -void test_locate(const G & g, CGAL::Random& rnd) +void test_locate(const G& g, CGAL::Random& rnd) { assert(num_vertices(g) != 0 && num_faces(g) != 0); @@ -577,28 +755,77 @@ void test_locate(const G & g, CGAL::Random& rnd) test_helpers(g, rnd); test_predicates(g, rnd); test_locate_in_face(g, rnd); - test_locate_with_AABB_tree(g, rnd); + + // This test has slight syntax changes between 2D and 3D (e.g. testing ray_2 in 3D makes no sense) + Locate_with_AABB_tree_Tester< + CGAL::Ambient_dimension::Point>::value>()(g, rnd); } template -void test_2D_mesh(const char* fname, CGAL::Random& rnd) +void test_2D_triangulation(const char* fname, CGAL::Random& rnd) { typedef CGAL::Regular_triangulation_2 RT; + + std::cout << "Testing Regular_triangulation_2 " << fname; + + std::ifstream in(fname); + assert(in.good()); + RT tr; + double x, y; + while(in >> x >> y) + tr.insert(typename RT::Point(x, y)); - std::cout << "Testing Regular_triangulation_2 " << fname << "..." << std::endl; + std::ofstream out("triangulation.off"); + out << "OFF\n"; + out << tr.number_of_vertices() << " " << std::distance(tr.finite_faces_begin(), tr.finite_faces_end()) << " 0\n"; - // @fixme -// std::ifstream input(fname); -// CGAL::read_off(input, tr); + std::size_t counter = 0; + std::map ids; + for(const auto& v : CGAL::make_range(tr.finite_vertices_begin(), tr.finite_vertices_end())) + { + out << v.point().point() << " 0\n"; + if(ids.insert(std::make_pair(v.point().point(), counter)).second) + ++counter; + } + + for(const auto& fd : CGAL::make_range(tr.finite_faces_begin(), tr.finite_faces_end())) + { + out << "3 " << ids[fd.vertex(0)->point().point()] << " " << ids[fd.vertex(1)->point().point()] << " " << ids[fd.vertex(2)->point().point()] << "\n"; + } + + out.close(); + + std::cout << " (" << tr.number_of_vertices() << " vertices)..." << std::endl; + std::cout << "Kernel: " << typeid(K()).name() << std::endl; test_locate(tr, rnd); - - // @todo some additionnal tests of locate(), comparing it with tr.locate(); (?) } template -void test_surface_mesh(const char* fname, CGAL::Random& rnd) +void test_2D_surface_mesh(const char* fname, CGAL::Random& rnd) +{ + typedef typename K::Point_2 Point; + typedef CGAL::Surface_mesh Mesh; + + std::cout << "Testing Surface_mesh " << fname << "..." << std::endl; + std::cout << "Kernel: " << typeid(K()).name() << std::endl; + + std::ifstream input(fname); + assert(input.good()); + + Mesh tm; + if(!input || !(input >> tm)) + { + std::cerr << "Error: cannot read file."; + return; + } + + test_locate(tm, rnd); +} + +template +void test_3D_surface_mesh(const char* fname, CGAL::Random& rnd) { typedef typename K::Point_3 Point; typedef CGAL::Surface_mesh Mesh; @@ -623,6 +850,8 @@ void test_polyhedron(const char* fname, CGAL::Random& rnd) typedef CGAL::Polyhedron_3 Polyhedron; std::cout << "Testing Polyhedron_3 " << fname << "..." << std::endl; + std::cout << "Kernel: " << typeid(K()).name() << std::endl; + std::ifstream input(fname); Polyhedron poly; if(!input || !(input >> poly)) @@ -634,33 +863,27 @@ void test_polyhedron(const char* fname, CGAL::Random& rnd) test_locate(poly, rnd); } +template +void test(CGAL::Random& rnd) +{ + test_2D_triangulation("data/stair.xy", rnd); +// test_2D_surface_mesh("data/blobby_2D.off", rnd); +// test_3D_surface_mesh("data/mech-holes-shark.off", rnd); +// test_polyhedron("data-coref/elephant_split_2.off", rnd); +} + int main() { std::cout.precision(17); std::cout << std::fixed; - typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; + CGAL::Random rnd(1556198743); // if needed to debug with a fixed seed +// CGAL::Random rnd(CGAL::get_default_random()); - typedef typename CGAL::Kernel_traits >::type EPICKQUESTIONMARK; - CGAL_static_assertion((std::is_same::value)); + std::cout << "The seed is " << rnd.get_seed() << std::endl; -#if 0 - typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; + test(rnd); + test(rnd); -// CGAL::Random rnd(1527774218); // if needed to debug with a fixed seed - CGAL::Random rnd(CGAL::get_default_random()); - - std::cout << "seed: " << rnd.get_seed() << std::endl; - - test_2D_mesh("data/two_tris_collinear.off", rnd); -// test_2D_mesh("data/two_tris_collinear.off", rnd); - -// test_surface_mesh("data/mech-holes-shark.off", rnd); -// test_surface_mesh("data/mech-holes-shark.off", rnd); - -// test_polyhedron("data-coref/elephant_split_1.off", rnd); -// test_polyhedron("data-coref/elephant_split_2.off", rnd); -#endif - - return 0; + return EXIT_SUCCESS; } From aa4e1913d116d91d6fa723720edeaa0797cf7ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Apr 2019 16:33:10 +0200 Subject: [PATCH 15/68] Partial revert of 42a1c49066898beb34f0d5401d4eb7a3cb75941f Halfedges in TDS2 and T2 were being used to get halfedges in the T2 graph traits We now do it differently and without polluting the packages T2 and TDS2 --- .../CGAL/Triangulation_data_structure_2.h | 16 +--- .../CGAL/Triangulation_ds_iterators_2.h | 87 ++++++++----------- .../include/CGAL/Triangulation_2.h | 19 ---- 3 files changed, 40 insertions(+), 82 deletions(-) diff --git a/TDS_2/include/CGAL/Triangulation_data_structure_2.h b/TDS_2/include/CGAL/Triangulation_data_structure_2.h index ef05a3bb57e..ffacab72a17 100644 --- a/TDS_2/include/CGAL/Triangulation_data_structure_2.h +++ b/TDS_2/include/CGAL/Triangulation_data_structure_2.h @@ -61,8 +61,7 @@ class Triangulation_data_structure_2 typedef typename Vb::template Rebind_TDS::Other Vertex_base; typedef typename Fb::template Rebind_TDS::Other Face_base; - friend class Triangulation_ds_edge_iterator_2; - friend class Triangulation_ds_edge_iterator_2; + friend class Triangulation_ds_edge_iterator_2; friend class Triangulation_ds_face_circulator_2; friend class Triangulation_ds_edge_circulator_2; friend class Triangulation_ds_vertex_circulator_2; @@ -90,9 +89,7 @@ public: typedef typename Face_range::iterator Face_iterator; typedef typename Vertex_range::iterator Vertex_iterator; - typedef Triangulation_ds_edge_iterator_2 Edge_iterator; - typedef Triangulation_ds_edge_iterator_2 Halfedge_iterator; typedef Triangulation_ds_face_circulator_2 Face_circulator; typedef Triangulation_ds_vertex_circulator_2 Vertex_circulator; @@ -100,8 +97,7 @@ public: typedef Vertex_iterator Vertex_handle; typedef Face_iterator Face_handle; - - typedef std::pair Edge; + typedef std::pair Edge; typedef std::list List_edges; @@ -187,15 +183,7 @@ public: Edge_iterator edges_end() const { return Edge_iterator(this,1); } - - Halfedge_iterator halfedges_begin() const { - return Halfedge_iterator(this); - } - Halfedge_iterator halfedges_end() const { - return Halfedge_iterator(this,1); - } - Face_circulator incident_faces(Vertex_handle v, Face_handle f = Face_handle()) const{ return Face_circulator(v,f); diff --git a/TDS_2/include/CGAL/Triangulation_ds_iterators_2.h b/TDS_2/include/CGAL/Triangulation_ds_iterators_2.h index 610e72c254f..303f7d8afa8 100644 --- a/TDS_2/include/CGAL/Triangulation_ds_iterators_2.h +++ b/TDS_2/include/CGAL/Triangulation_ds_iterators_2.h @@ -31,8 +31,7 @@ namespace CGAL { - // with Once set to false, the Edge is reported twice, seen from the two adjacentfaces - template +template class Triangulation_ds_edge_iterator_2 { public: @@ -47,7 +46,7 @@ public: typedef std::ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; - typedef Triangulation_ds_edge_iterator_2 Edge_iterator; + typedef Triangulation_ds_edge_iterator_2 Edge_iterator; private: const Tds* _tds; @@ -71,15 +70,14 @@ public: private: void increment(); void decrement(); - bool associated_edge(CGAL::Tag_true); - bool associated_edge(CGAL::Tag_false); + bool associated_edge(); }; // Edge iterator implementation -template -Triangulation_ds_edge_iterator_2 :: +template +Triangulation_ds_edge_iterator_2:: Triangulation_ds_edge_iterator_2(const Tds * tds) : _tds(tds) { @@ -90,12 +88,12 @@ Triangulation_ds_edge_iterator_2(const Tds * tds) } pos = _tds->faces().begin(); if (_tds->dimension() == 1) edge.second = 2; - while ( pos != _tds->faces().end() - && !associated_edge(Boolean_tag()) ) increment(); + while ( pos != _tds->faces().end() && !associated_edge()) + increment(); } -template -Triangulation_ds_edge_iterator_2 :: +template +Triangulation_ds_edge_iterator_2:: Triangulation_ds_edge_iterator_2(const Tds * tds, int ) : _tds(tds) { @@ -105,19 +103,19 @@ Triangulation_ds_edge_iterator_2(const Tds * tds, int ) } -template +template inline bool -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2:: operator==(const Edge_iterator& fi) const { return _tds == fi._tds && pos == fi.pos && edge.second == fi.edge.second; } -template +template inline void -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2:: increment() { CGAL_triangulation_precondition(_tds->dimension() >= 1); @@ -127,10 +125,10 @@ increment() return; } -template +template inline void -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2:: decrement() { CGAL_triangulation_precondition(_tds->dimension() >= 1); @@ -140,57 +138,48 @@ decrement() return; } -template +template inline bool -Triangulation_ds_edge_iterator_2 :: -associated_edge(Tag_true) +Triangulation_ds_edge_iterator_2:: +associated_edge() { if (_tds->dimension() == 1) {return true;} return Face_handle(pos) < pos->neighbor(edge.second); } -template +template inline -bool -Triangulation_ds_edge_iterator_2 :: -associated_edge(Tag_false) -{ - return true; -} - -template -inline -Triangulation_ds_edge_iterator_2& -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2& +Triangulation_ds_edge_iterator_2:: operator++() { //CGAL_triangulation_precondition(pos != Iterator_base() && // pos != _tds->faces().end()); do increment(); - while( pos != _tds->faces().end() && !associated_edge(Boolean_tag())); + while( pos != _tds->faces().end() && !associated_edge()); return *this; } -template +template inline -Triangulation_ds_edge_iterator_2& -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2& +Triangulation_ds_edge_iterator_2:: operator--() { // CGAL_triangulation_precondition(pos != Iterator_base() // && *this != Edge_iterator(_tds)); do decrement(); - while ( !associated_edge(Boolean_tag()) && *this != Edge_iterator(_tds) ); + while ( !associated_edge() && *this != Edge_iterator(_tds) ); return *this; } -template +template inline -Triangulation_ds_edge_iterator_2 -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2 +Triangulation_ds_edge_iterator_2:: operator++(int) { Edge_iterator tmp(*this); @@ -198,10 +187,10 @@ operator++(int) return tmp; } -template +template inline -Triangulation_ds_edge_iterator_2 -Triangulation_ds_edge_iterator_2 :: +Triangulation_ds_edge_iterator_2 +Triangulation_ds_edge_iterator_2:: operator--(int) { Edge_iterator tmp(*this); @@ -209,20 +198,20 @@ operator--(int) return tmp; } -template +template inline -typename Triangulation_ds_edge_iterator_2::Edge* -Triangulation_ds_edge_iterator_2 :: +typename Triangulation_ds_edge_iterator_2::Edge* +Triangulation_ds_edge_iterator_2:: operator->() const { edge.first = pos; return &edge; } -template +template inline -typename Triangulation_ds_edge_iterator_2::Edge& -Triangulation_ds_edge_iterator_2 :: +typename Triangulation_ds_edge_iterator_2::Edge& +Triangulation_ds_edge_iterator_2:: operator*() const { edge.first = pos; diff --git a/Triangulation_2/include/CGAL/Triangulation_2.h b/Triangulation_2/include/CGAL/Triangulation_2.h index 16e355c20e4..55e445929fe 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2.h @@ -125,7 +125,6 @@ public: typedef typename Tds::Face_iterator All_faces_iterator; typedef typename Tds::Edge_iterator All_edges_iterator; - typedef typename Tds::Halfedge_iterator All_halfedges_iterator; typedef typename Tds::Vertex_iterator All_vertices_iterator; class Perturbation_order @@ -450,8 +449,6 @@ public: All_vertices_iterator all_vertices_end() const; All_edges_iterator all_edges_begin() const; All_edges_iterator all_edges_end() const; - All_halfedges_iterator all_halfedges_begin() const; - All_halfedges_iterator all_halfedges_end() const; //for compatibility with previous versions Face_iterator faces_begin() const {return finite_faces_begin();} @@ -3183,22 +3180,6 @@ all_edges_end() const return _tds.edges_end(); } -template -typename Triangulation_2::All_halfedges_iterator -Triangulation_2:: -all_halfedges_begin() const -{ - return _tds.halfedges_begin(); -} - -template -typename Triangulation_2::All_halfedges_iterator -Triangulation_2:: -all_halfedges_end() const -{ - return _tds.halfedges_end(); -} - template inline typename Triangulation_2::Face_circulator From 842ae3fbbdc5e0535de5b89bed769b596cc2cd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Apr 2019 16:34:39 +0200 Subject: [PATCH 16/68] Change T2 graph traits to only use finite elements This is way more logical because infinite faces have corrupt geometry, and do not present any particular use (if you want the convex hull, just walk the border) This is a breaking change, but the whole traits was so broken nobody could have been using it in the first place anyway. --- .../graph/graph_traits_2D_triangulation.h | 604 ++++++++++++------ .../boost/graph/properties_2D_triangulation.h | 72 ++- 2 files changed, 453 insertions(+), 223 deletions(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h index 423b76adb6e..a6065a2fa6f 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -47,90 +48,98 @@ namespace CGAL { namespace detail { -template -struct T2_halfedge_descriptor -{ - typedef typename Tr::Face_handle face_descriptor; - - T2_halfedge_descriptor() : first(), second(0) { } - explicit T2_halfedge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } - T2_halfedge_descriptor(face_descriptor fd, int i) : first(fd), second(i) { } - - operator std::pair() { return std::make_pair(first, second); } - - friend std::size_t hash_value(const T2_halfedge_descriptor& h) - { - return hash_value(h.first); - } - - bool operator==(const T2_halfedge_descriptor& other) const - { - return (first == other.first) && (second == other.second); - } - - bool operator!=(const T2_halfedge_descriptor& other) const - { - return (first != other.first) || (second != other.second); - } - - bool operator<(const T2_halfedge_descriptor& other) const - { - if(first < other.first) return true; - if(first > other.first) return false; - return second < other.second; - } - - face_descriptor first; - int second; -}; - +// A triangulation edge is a face handle + an int, and is thus actually a halfedge... template -struct T2_edge_descriptor +struct T2_halfedge_descriptor : public Tr::Edge { typedef typename Tr::Edge Base; typedef typename Tr::Face_handle Face_handle; - T2_edge_descriptor() {} - T2_edge_descriptor(Face_handle fh, int i) : Base(fh, i) { } - explicit T2_edge_descriptor(const Base& e) : Base(e) { } - T2_edge_descriptor(const T2_edge_descriptor& e) : Base(e) { } + T2_halfedge_descriptor() {} + T2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { } + explicit T2_halfedge_descriptor(const Base& e) : Base(e) { } + T2_halfedge_descriptor(const T2_halfedge_descriptor& h) : Base(h) { } - T2_edge_descriptor& operator=(const T2_edge_descriptor& e) + const Base& base() const { return static_cast(*this); } + + T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h) { - this->first = e.first; - this->second = e.second; + this->first = h.first; + this->second = h.second; return *this; } - friend std::size_t hash_value(const T2_edge_descriptor& e) + friend std::size_t hash_value(const T2_halfedge_descriptor& e) { + return hash_value(e.first); + } + + bool operator==(const T2_halfedge_descriptor& other) const { + return (this->first == other.first) && (this->second == other.second); + } + bool operator!=(const T2_halfedge_descriptor& other) const { + return (this->first != other.first) || (this->second != other.second); + } + + bool operator<(const T2_halfedge_descriptor& other) const { - if (e.first==Face_handle()) return 0; - return hash_value(e.firstneighbor(e.second)? - e.first:e.first->neighbor(e.second)); + if(this->first < other.first) return true; + if(this->first > other.first) return false; + return this->second < other.second; + } +}; + +// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge +template +struct T2_edge_descriptor +{ + typedef typename Tr::Face_handle Face_handle; + + T2_edge_descriptor() : first(), second(0) { } + explicit T2_edge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } + T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { } + + // so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle + operator std::pair() { return std::make_pair(first, second); } + + friend std::size_t hash_value(const T2_edge_descriptor& h) + { + if(h.first == Face_handle()) + return 0; + + return hash_value(h.first < h.first->neighbor(h.second) ? h.first + : h.first->neighbor(h.second)); } bool operator==(const T2_edge_descriptor& other) const { - if((this->first == other.first)&&(this->second == other.second)) return true; - Face_handle fh = this->first->neighbor(this->second); - if(other.first != fh) return false; - int i = fh->index(this->first); + if((first == other.first) && (second == other.second)) + return true; + + Face_handle fh = first->neighbor(second); + if(other.first != fh) + return false; + + int i = fh->index(first); return (other.second == i); } + bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); } - bool operator!=(T2_edge_descriptor& other) const - { - return ! (*this == other); - } + Face_handle first; + int second; }; -template -struct T2_iterator +// A halfedge iterator is just an edge iterator that duplicates everything twice, +// to see the edge from either side. +// Could probably be factorized with T2_edge_iterator, but it's clearer this way. +template +struct T2_halfedge_iterator { private: - typedef T2_iterator Self; - typedef typename Tr::Triangulation_data_structure Tds; + typedef T2_halfedge_iterator Self; + typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; + typedef T2_halfedge_descriptor Descriptor; + typedef typename Tr::Face_handle Face_handle; public: typedef Descriptor value_type; @@ -140,86 +149,222 @@ public: typedef std::ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; - T2_iterator() { } - T2_iterator(const Triangulation_iterator& it) : it(it) { } + T2_halfedge_iterator() { } + T2_halfedge_iterator(const Finite_edges_iterator& feit) : it(feit), on_adjacent_face(false) { } + + Self& operator++() + { + // If we are on the first face, move to the opposite face. If we are already on the opposite face, + // then it's time to move on the next edge + if(on_adjacent_face) { + ++it; + on_adjacent_face = false; + } else { + on_adjacent_face = true; + } + + return *this; + } + + Self& operator--() + { + // Note that while decreasing, we start from the opposite face + if(on_adjacent_face) { + on_adjacent_face = false; + } else { + --it; + on_adjacent_face = true; + } + + return *this; + } + + Self operator++(int) { Self tmp = *this; operator++(); return tmp; } + Self operator--(int) { Self tmp = *this; operator--(); return tmp; } bool operator==(const Self& other) const { return it == other.it; } - bool operator!=(const Self& other) const { return !(*this == other);} + bool operator!=(const Self& other) const { return !(*this == other); } + + value_type operator*() const + { + if(on_adjacent_face) { + Face_handle neigh_f = it->first->neighbor(it->second); + return value_type(neigh_f, neigh_f->index(it->first)); + } else { + return value_type(*it); + } + } + +private: + Finite_edges_iterator it; + bool on_adjacent_face; +}; + +template +struct T2_edge_iterator +{ +private: + typedef T2_edge_iterator Self; + typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; + typedef T2_edge_descriptor Descriptor; + +public: + typedef Descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + T2_edge_iterator() { } + T2_edge_iterator(const Finite_edges_iterator& feit) : it(feit) { } + + bool operator==(const Self& other) const { return it == other.it; } + bool operator!=(const Self& other) const { return !(*this == other); } Self& operator++() { ++it; return *this; } Self& operator--() { --it; return *this; } Self operator++(int) { Self tmp = *this; operator++(); return tmp; } Self operator--(int) { Self tmp = *this; operator--(); return tmp; } value_type operator*() const { return value_type(*it); } - Triangulation_iterator it; +private: + Finite_edges_iterator it; }; -template -struct Out_edge_circulator - : public Circ +template +struct T2_edge_circulator + : public Tr::Edge_circulator { private: - mutable E e; + typedef T2_edge_circulator Self; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Base; public: - typedef E value_type; - typedef E* pointer; - typedef E& reference; + typedef T2_edge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; - Out_edge_circulator() : Circ() { } - Out_edge_circulator(Circ c) : Circ(c) { } + T2_edge_circulator() : Base() { } + T2_edge_circulator(const Base& c, const Tr& tr) : Base(c), tr(&tr), e() { } - const E& operator*() const - { - E ed(static_cast(this)->operator*()); - e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); - return e; + // Note that the inf check is on the edge in the circulator, not on 'e', which isn't built yet + Self& operator++() { + do { this->Base::operator++(); } while(tr->is_infinite(this->Base::operator*())); + return *this; } + Self& operator--() { + do { this->Base::operator--(); } while(tr->is_infinite(this->Base::operator*())); + return *this; + } + Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } + Self operator--(int) { Self tmp(*this); --(*this); return tmp; } + +protected: + const Tr* tr; + mutable value_type e; }; -template +template struct In_edge_circulator - : public Circ + : public T2_edge_circulator { private: - mutable E e; + typedef T2_edge_circulator Base; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Edge_circulator; public: - typedef E value_type; - typedef E* pointer; - typedef E& reference; + typedef T2_edge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; - In_edge_circulator() : Circ() { } - In_edge_circulator(Circ c) : Circ(c) { } + In_edge_circulator() : Base() { } + In_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } - const E& operator*() const + const value_type& operator*() const { - e = E(static_cast(this)->operator*()); - return e; + this->e = value_type(this->Base::operator*()); + return this->e; } }; template -struct Dereference_to_vertex_handle_enforcer +struct Out_edge_circulator + : public T2_edge_circulator +{ +private: + typedef T2_edge_circulator Base; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Edge_circulator; + +public: + typedef T2_edge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + + Out_edge_circulator() : Base() { } + Out_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } + + const value_type& operator*() const + { + Edge ed(this->Base::operator*()); + this->e = value_type(ed.first->neighbor(ed.second), + ed.first->neighbor(ed.second)->index(ed.first)); + return this->e; + } +}; + +template +struct T2_vertex_circulator + : public In_edge_circulator +{ +private: + typedef In_edge_circulator Base; + typedef T2_edge_descriptor edge_descriptor; + typedef typename Tr::Edge_circulator Edge_circulator; + typedef typename Tr::Vertex_handle Vertex_handle; + +public: + typedef Vertex_handle value_type; + typedef value_type& reference; + + T2_vertex_circulator() : Base() { } + T2_vertex_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } + + const value_type& operator*() const + { + const edge_descriptor& edge = this->Base::operator*(); + v = edge.first->vertex(this->tr->ccw(edge.second)); + return v; + } + +private: + // Because we wrap the iterator with a Counting_iterator, which returns a ref in its operator*() + mutable Vertex_handle v; +}; + +template +struct Dereference_to_handle_enforcer : public boost::iterator_adaptor< - Dereference_to_vertex_handle_enforcer, - typename Tr::All_vertices_iterator /*base*/, - typename Tr::Vertex_handle /*value*/, + Dereference_to_handle_enforcer, + Iterator /*base*/, + Handle /*value*/, boost::use_default, - typename Tr::Vertex_handle /*reference*/ + Handle /*reference*/ > { public: - typedef typename Tr::Vertex_handle value_type; + typedef Handle value_type; private: - typedef Dereference_to_vertex_handle_enforcer Self; - typedef typename Tr::All_vertices_iterator I; + typedef Dereference_to_handle_enforcer Self; + typedef Iterator I; typedef boost::iterator_adaptor Base; public: - Dereference_to_vertex_handle_enforcer() { } - explicit Dereference_to_vertex_handle_enforcer(const I& i) : Base(i) { } + Dereference_to_handle_enforcer() { } + explicit Dereference_to_handle_enforcer(const I& i) : Base(i) { } private: friend class boost::iterator_core_access; @@ -276,34 +421,25 @@ struct graph_traits< CGAL_2D_TRIANGULATION > typedef CGAL::detail::T2_edge_descriptor edge_descriptor; typedef typename Triangulation::Face_handle face_descriptor; - // Regular_triangulation_2 unfortunately overrides the type 'All_vertices_iterator' due to hidden - // points, so we can't simply use 'CGAL::Prevent_deref' since 'typeid(*vertex_iterator)' would - // not be the vertex_descripor type, which creates all types (!) of problems. - typedef CGAL::detail::Dereference_to_vertex_handle_enforcer vertex_iterator; + // We need to go from 'Finite_vertex_iterator' to 'Vertex_handle' (and even more + // in the case of RT2, since it has also a hidden filter) + typedef CGAL::detail::Dereference_to_handle_enforcer< + Triangulation, + typename Triangulation::Finite_vertices_iterator, + vertex_descriptor> vertex_iterator; + typedef CGAL::detail::Dereference_to_handle_enforcer< + Triangulation, + typename Triangulation::Finite_faces_iterator, + face_descriptor> face_iterator; + typedef CGAL::detail::T2_halfedge_iterator halfedge_iterator; + typedef CGAL::detail::T2_edge_iterator edge_iterator; - // Since 'All_halfedges_...' and 'All_edges_...' have the same value type, we have to wrap them - // around to enforce the value_type being the correct descriptor - typedef CGAL::detail::T2_iterator halfedge_iterator; - typedef CGAL::detail::T2_iterator edge_iterator; - typedef CGAL::Prevent_deref face_iterator; - - typedef CGAL::Counting_iterator< - CGAL::detail::In_edge_circulator< - typename Triangulation::Edge_circulator, - edge_descriptor>, - edge_descriptor> in_edge_iterator; - typedef CGAL::Counting_iterator< - CGAL::detail::Out_edge_circulator< - typename Triangulation::Edge_circulator, - edge_descriptor>, - edge_descriptor> out_edge_iterator; - - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; + typedef CGAL::detail::T2_vertex_circulator Vertex_circulator; + typedef CGAL::Counting_iterator adjacency_iterator; + typedef CGAL::detail::In_edge_circulator In_edge_circ; + typedef CGAL::Counting_iterator in_edge_iterator; + typedef CGAL::detail::Out_edge_circulator Out_edge_circ; + typedef CGAL::Counting_iterator out_edge_iterator; typedef undirected_tag directed_category; typedef disallow_parallel_edge_tag edge_parallel_category; @@ -336,6 +472,7 @@ typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, const CGAL_2D_TRIANGULATION& g) { + CGAL_precondition(!g.is_infinite(e)); return e.first->vertex(g.ccw(e.second)); } @@ -344,6 +481,7 @@ typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, const CGAL_2D_TRIANGULATION& g) { + CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second))); return h.first->vertex(g.ccw(h.second)); } @@ -352,6 +490,7 @@ typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, const CGAL_2D_TRIANGULATION& g) { + CGAL_precondition(!g.is_infinite(e)); return e.first->vertex(g.cw(e.second)); } @@ -360,6 +499,7 @@ typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, const CGAL_2D_TRIANGULATION& g) { + CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second))); return h.first->vertex(g.cw(h.second)); } @@ -369,7 +509,18 @@ next(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(h.first, g.ccw(h.second)); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; + + CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second))); + + face_descriptor f = h.first; + int i = h.second; + if(!g.is_infinite(f)) + return halfedge_descriptor(f, g.ccw(i)); + + // Now, 'h' is border halfedge, move on to the adjacent infinite face + face_descriptor neigh_f = f->neighbor(g.ccw(i)); + return halfedge_descriptor(neigh_f, g.ccw(neigh_f->index(f))); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -378,7 +529,18 @@ prev(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(h.first, g.cw(h.second)); + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; + + CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second))); + + face_descriptor f = h.first; + int i = h.second; + if(!g.is_infinite(f)) + return halfedge_descriptor(f, g.cw(i)); + + // Now, 'h' is border halfedge, move on to the adjacent infinite face + face_descriptor neigh_f = f->neighbor(g.cw(i)); + return halfedge_descriptor(neigh_f, g.cw(neigh_f->index(f))); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -387,26 +549,32 @@ opposite(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descrip const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; - return halfedge_descriptor(g.mirror_edge(edge_descriptor(h.first, h.second))); + CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second))); + return halfedge_descriptor(g.mirror_edge(typename CGAL_2D_TRIANGULATION::Edge(h.first, h.second))); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, - const CGAL_2D_TRIANGULATION&) + const CGAL_2D_TRIANGULATION& g) { - return h.first; + if(g.is_infinite(h.first)) + return boost::graph_traits< CGAL_2D_TRIANGULATION >::null_face(); + else + return h.first; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor f, - const CGAL_2D_TRIANGULATION&) + const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(f,0); + + CGAL_USE(g); + CGAL_precondition(!g.is_infinite(f)); + return halfedge_descriptor(f, 0); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -416,26 +584,42 @@ halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descripto { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; - face_descriptor fd = v->face(); - int i = fd->index(v); - return halfedge_descriptor(fd, g.ccw(i)); + + CGAL_precondition(!g.is_infinite(v)); + + face_descriptor f = v->face(); + int i = f->index(v); + + while(g.is_infinite(f)) + { + f = f->neighbor(g.cw(i)); + i = f->index(v); + } + + return halfedge_descriptor(f, g.ccw(i)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e, - const CGAL_2D_TRIANGULATION&) + const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor; + + CGAL_USE(g); + CGAL_precondition(!g.is_infinite(e)); return halfedge_descriptor(e.first, e.second); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h, - const CGAL_2D_TRIANGULATION&) + const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + + CGAL_USE(g); + CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second))); return edge_descriptor(h.first, h.second); } @@ -448,13 +632,21 @@ edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; + CGAL_precondition(!g.is_infinite(u)); + CGAL_precondition(!g.is_infinite(v)); + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); - if(c != 0) { - do { - // find the index of the other vertex of *c - int indv = 3 - c->first->index(u) - c->second; - if(c->first->vertex(indv) == v) - return std::make_pair(edge_descriptor(c->first, c->second), true); + if(c != 0) + { + do + { + if(!g.is_infinite(*c)) + { + // find the index of the other vertex of *c + int indv = 3 - c->first->index(u) - c->second; + if(c->first->vertex(indv) == v) + return std::make_pair(edge_descriptor(c->first, c->second), true); + } } while (++c != done); } @@ -472,6 +664,9 @@ halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descripto typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor; typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor; + CGAL_precondition(!g.is_infinite(u)); + CGAL_precondition(!g.is_infinite(v)); + std::pair eb = edge(u, v, g); if(!eb.second) @@ -496,7 +691,7 @@ inline Iterator_range::ver vertices(const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_iterator Iter; - return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); + return make_range( Iter(g.finite_vertices_begin()), Iter(g.finite_vertices_end()) ); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -504,7 +699,7 @@ inline Iterator_range::hal halfedges(const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_iterator Iter; - return make_range(Iter(g.all_halfedges_begin()), Iter(g.all_halfedges_end())); + return make_range(Iter(g.finite_edges_begin()), Iter(g.finite_edges_end())); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -512,7 +707,7 @@ inline Iterator_range::edg edges(const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_iterator Iter; - return make_range(Iter(g.all_edges_begin()), Iter(g.all_edges_end())); + return make_range(Iter(g.finite_edges_begin()), Iter(g.finite_edges_end())); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -520,103 +715,105 @@ inline Iterator_range::fac faces(const CGAL_2D_TRIANGULATION& g) { typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_iterator Iter; - return make_range(Iter(g.all_faces_begin()), Iter(g.all_faces_end())); + return make_range(Iter(g.finite_faces_begin()), Iter(g.finite_faces_end())); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type -in_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, - const CGAL_2D_TRIANGULATION& g) +degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, + const CGAL_2D_TRIANGULATION& g) { typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; - typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); + typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(v), done(c); if(c != 0) { do { - ++deg; + if(!g.is_infinite(*c)) + ++deg; } while (++c != done); } + return deg; } +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +in_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, + const CGAL_2D_TRIANGULATION& g) +{ + return degree(v, g); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type +out_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, + const CGAL_2D_TRIANGULATION& g) +{ + return degree(v, g); +} + template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline Iterator_range::in_edge_iterator > -in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, +in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) { - typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); + typedef CGAL::detail::In_edge_circulator< CGAL_2D_TRIANGULATION > Circ; typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator Iter; - return make_range(Iter(ec), Iter(ec,out_deg)); -} -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type -out_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, - const CGAL_2D_TRIANGULATION& g) -{ - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; - typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); - if(c != 0) - { - do { - ++deg; - } while (++c != done); - } - return deg; + typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = degree(v, g); + + return make_range(Iter(Circ(ec, g)), Iter(Circ(ec, g), deg)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline Iterator_range::out_edge_iterator > -out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, +out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) { - typename CGAL_2D_TRIANGULATION::Edge_circulator ec(u, u->face()); - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter; + typedef CGAL::detail::Out_edge_circulator< CGAL_2D_TRIANGULATION > Circ; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter; - return make_range(Iter(ec), Iter(ec, out_deg)); -} + typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = degree(v, g); -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type -degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, - const CGAL_2D_TRIANGULATION& g) -{ - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0; - typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c); - if(c != 0) - { - do { - ++deg; - } while (++c != done); - } - return deg; + return make_range(Iter(Circ(ec, g)), Iter(Circ(ec, g), deg)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline Iterator_range::adjacency_iterator> -adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u, +adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) { - typename CGAL_2D_TRIANGULATION::Vertex_circulator vc = out_edge_iterator(u, u.face()); - typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type out_deg = out_degree(u, g); - typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter; - return make_range( Iter(vc), Iter(vc,out_deg) ); + typedef CGAL::detail::T2_vertex_circulator< CGAL_2D_TRIANGULATION > Circ; + typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter; + + typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); + typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = degree(v, g); + + return make_range(Iter(Circ(ec, g)), Iter(Circ(ec, g), deg)); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertices_size_type num_vertices(const CGAL_2D_TRIANGULATION& g) { - return g.tds().number_of_vertices(); + return g.number_of_vertices(); +} + +template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > +typename boost::graph_traits< CGAL_2D_TRIANGULATION >::faces_size_type +num_faces(const CGAL_2D_TRIANGULATION& g) +{ + return g.number_of_faces(); } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edges_size_type num_edges(const CGAL_2D_TRIANGULATION& g) { - return g.tds().number_of_vertices() + g.tds().number_of_faces() - 2; + // Euler characteristic for a triangulated topological disk is V-E+F=1 + return num_vertices(g) + num_faces(g) - 1; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -626,13 +823,6 @@ num_halfedges(const CGAL_2D_TRIANGULATION& g) return num_edges(g) * 2; } -template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -typename boost::graph_traits< CGAL_2D_TRIANGULATION >::faces_size_type -num_faces(const CGAL_2D_TRIANGULATION& g) -{ - return g.tds().number_of_faces(); -} - } // namespace CGAL #undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h index e5f993f9440..945d56f157d 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h @@ -95,9 +95,14 @@ public: typedef int reference; typedef typename Tr::Vertex_handle key_type; - T2_vertex_id_map() { } + T2_vertex_id_map(const Tr& tr) : tr(tr) { } - value_type operator[](key_type vh) const { return vh->id(); } + value_type operator[](key_type v) const { + CGAL_precondition(!tr.is_infinite(v)); + return v->id(); + } + + const Tr& tr; }; template @@ -110,9 +115,30 @@ public: typedef int reference; typedef CGAL::detail::T2_halfedge_descriptor key_type; - T2_halfedge_id_map() { } + typedef typename Tr::Face_handle face_descriptor; - value_type operator[](key_type h) const { return (3 * h.first->id()) + h.second; } + T2_halfedge_id_map(const Tr& tr) : tr(tr) { } + + // Halfedge id is twice the edge id, and +0/+1 depending whether + // h.first is such that h.first < opposite(h).first --> different ids + value_type operator[](key_type h) const + { + const face_descriptor f1 = h.first; + const face_descriptor f2 = f1->neighbor(h.second); + CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); + + if(tr.is_infinite(f1)) + return 2*(3 * f2->id() + f2->index(f1)); + else if(tr.is_infinite(f2)) + return 2*(3 * f1->id() + h.second) + 1; + else if(f1->id() < f2->id()) + return 2*(3 * f1->id() + h.second); + else + return 2*(3 * f2->id() + f2->index(f1)) + 1; + } + +private: + const Tr& tr; }; template @@ -126,18 +152,26 @@ public: typedef CGAL::detail::T2_edge_descriptor key_type; typedef typename Tr::Face_handle face_descriptor; - T2_edge_id_map() { } + T2_edge_id_map(const Tr& tr) : tr(tr) { } value_type operator[](key_type e) const { const face_descriptor f1 = e.first; const face_descriptor f2 = f1->neighbor(e.second); + CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); - if(f1->id() < f2->id()) + if(tr.is_infinite(f1)) + return 3 * f2->id() + f2->index(f1); + else if(tr.is_infinite(f2)) + return 3 * f1->id() + e.second; + else if(f1->id() < f2->id()) return 3 * f1->id() + e.second; else return 3 * f2->id() + f2->index(f1); } + +private: + const Tr& tr; }; template @@ -150,9 +184,15 @@ public: typedef int reference; typedef typename Tr::Face_handle key_type; - T2_face_id_map() { } + T2_face_id_map(const Tr& tr) : tr(tr) { } - value_type operator[](key_type f) const { return f->id(); } + value_type operator[](key_type f) const { + CGAL_precondition(!tr.is_infinite(f)); + return f->id(); + } + +private: + const Tr& tr; }; template @@ -290,33 +330,33 @@ get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g) template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > -get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION&) +get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m; + detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > -get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION&) +get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m; + detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > -get(boost::edge_index_t, const CGAL_2D_TRIANGULATION&) +get(boost::edge_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m; + detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > inline detail::T2_face_id_map< CGAL_2D_TRIANGULATION > -get(boost::face_index_t, const CGAL_2D_TRIANGULATION&) +get(boost::face_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_face_id_map< CGAL_2D_TRIANGULATION > m; + detail::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } From d5050e1404353e6fcdadbc2852b8edc002903f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Apr 2019 16:37:35 +0200 Subject: [PATCH 17/68] Improve BGL graph traits tests --- .../BGL/graph_concept_Triangulation_2.cpp | 4 ++- BGL/test/BGL/test_graph_traits.cpp | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/BGL/test/BGL/graph_concept_Triangulation_2.cpp b/BGL/test/BGL/graph_concept_Triangulation_2.cpp index 09a54241928..951e4beb2bc 100644 --- a/BGL/test/BGL/graph_concept_Triangulation_2.cpp +++ b/BGL/test/BGL/graph_concept_Triangulation_2.cpp @@ -41,6 +41,8 @@ void concept_check_triangulation() boost::function_requires< CGAL::HalfedgeListGraphConcept >(); boost::function_requires< CGAL::FaceGraphConcept >(); boost::function_requires< CGAL::FaceListGraphConcept >(); + + // Triangulations are not mutable graphs // boost::function_requires< CGAL::MutableHalfedgeGraphConcept >(); // boost::function_requires< CGAL::MutableFaceGraphConcept >(); @@ -60,6 +62,6 @@ int main() concept_check_triangulation(); concept_check_triangulation(); concept_check_triangulation(); - + return 0; } diff --git a/BGL/test/BGL/test_graph_traits.cpp b/BGL/test/BGL/test_graph_traits.cpp index 7e6e399aa05..58144b4e366 100644 --- a/BGL/test/BGL/test_graph_traits.cpp +++ b/BGL/test/BGL/test_graph_traits.cpp @@ -226,6 +226,41 @@ void test_in_out_edges(const G& g) } } +template +void test_adjacent_vertices(const G& g) +{ + typedef boost::graph_traits< G > Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::in_edge_iterator in_edge_iterator; + typedef typename Traits::out_edge_iterator out_edge_iterator; + typedef typename Traits::adjacency_iterator adjacency_iterator; + typedef std::pair ret; + + vertex_descriptor v = *(vertices(g).begin()); + + adjacency_iterator vb, ve; + boost::tie(vb, ve) = adjacent_vertices(v, g); + + in_edge_iterator ieb, iee; + boost::tie(ieb, iee) = in_edges(v, g); + + out_edge_iterator oeb, oee; + boost::tie(oeb, oee) = out_edges(v, g); + + assert(std::distance(vb, ve) == std::distance(ieb, iee)); + assert(std::distance(vb, ve) == std::distance(oeb, oee)); + + for(; vb != ve; ++vb) + { + vertex_descriptor s = *vb; + assert(s != v); + assert(s != Traits::null_vertex()); + ret found = edge(s, v, g); + assert(found.second); + } +} + // check that every edge can be found through edge(u, v, g) template void test_edge_find(const G& g) @@ -289,6 +324,7 @@ void test_const_graph(const Graph& g) test_out_edges(g); test_in_edges(g); test_in_out_edges(g); +// test_adjacent_vertices(g); test_edge_find(g); test_faces(g); test_halfedge_around_vertex_iterator(g); From a796a3633857af30b197e03ce5f8926f70cb8ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Apr 2019 16:38:45 +0200 Subject: [PATCH 18/68] Clean locate.h --- .../include/CGAL/Polygon_mesh_processing/locate.h | 8 -------- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 3 --- 2 files changed, 11 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index d69a6a32d88..8bcaf8c8981 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -435,11 +435,8 @@ int vertex_index_in_face(const typename boost::graph_traits::vertex halfedge_descriptor current = start; int counter = 0; - std::cout << "vd to find: " << &*vd << " pt: " << vd->point() << std::endl; - do { - std::cout << "current source: " << &*source(current, pm) << " pt: " << source(current, pm)->point() << std::endl; if(source(current, pm) == vd) break; @@ -1625,11 +1622,6 @@ locate_with_AABB_tree(const typename internal::Locate_typesvertex(0)->point() << std::endl; - std::cout << "in face: " << result.second->vertex(1)->point() << std::endl; - std::cout << "in face: " << result.second->vertex(2)->point() << std::endl; - return locate_in_face(result.first, result.second, tm, CGAL::parameters::vertex_point_map(wrapped_vpm)); } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 6c3c96a6dd2..62daa411c01 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -584,8 +584,6 @@ struct Locate_with_AABB_tree_Tester // 2D case VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g); typename boost::property_traits::value_type p_a = get(vpm_a, v); const Point_3& p3_a = to_p3(p_a); - std::cout << v->point() << std::endl; - std::cout << "pa3: " << p_a << " ~~~~~~ " << p3_a << std::endl; assert(p_a == v->point()); CGAL::AABB_tree tree_b; @@ -599,7 +597,6 @@ struct Locate_with_AABB_tree_Tester // 2D case assert(tree_b.size() == num_faces(g)); Face_location loc = PMP::locate_with_AABB_tree(p_a, tree_a, g); - std::cout << "LOC: " << loc.second[0] << " " << loc.second[1] << " " << loc.second[2] << std::endl; assert(PMP::is_on_vertex(loc, v, g)); assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); From 4bf0cba4cd05c72f77b31b3c0c0979bd42c3f56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 26 Apr 2019 16:38:55 +0200 Subject: [PATCH 19/68] Re-enable tests --- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 62daa411c01..784918c99dc 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -864,9 +864,9 @@ template void test(CGAL::Random& rnd) { test_2D_triangulation("data/stair.xy", rnd); -// test_2D_surface_mesh("data/blobby_2D.off", rnd); -// test_3D_surface_mesh("data/mech-holes-shark.off", rnd); -// test_polyhedron("data-coref/elephant_split_2.off", rnd); + test_2D_surface_mesh("data/blobby_2D.off", rnd); + test_3D_surface_mesh("data/mech-holes-shark.off", rnd); + test_polyhedron("data-coref/elephant_split_2.off", rnd); } int main() @@ -874,8 +874,8 @@ int main() std::cout.precision(17); std::cout << std::fixed; - CGAL::Random rnd(1556198743); // if needed to debug with a fixed seed -// CGAL::Random rnd(CGAL::get_default_random()); +// CGAL::Random rnd(1556198743); // if needed to debug with a fixed seed + CGAL::Random rnd(CGAL::get_default_random()); std::cout << "The seed is " << rnd.get_seed() << std::endl; From 44afd34dee7be139ce4ab78f91fa0de4e2a6ccee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 08:28:45 +0200 Subject: [PATCH 20/68] Fixed copyright --- .../include/CGAL/Polygon_mesh_processing/locate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 8bcaf8c8981..676bd9a6f15 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014, 2017, 2018 INRIA (France). +// Copyright (c) 2014, 2017, 2018 GeometryFactory (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). From 27bf65797293fe97f868d34a05f5cc110c59c530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 12:21:05 +0200 Subject: [PATCH 21/68] Removed bad assertion from PMP::locate.h test --- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 784918c99dc..2f080cd4676 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -584,7 +584,6 @@ struct Locate_with_AABB_tree_Tester // 2D case VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g); typename boost::property_traits::value_type p_a = get(vpm_a, v); const Point_3& p3_a = to_p3(p_a); - assert(p_a == v->point()); CGAL::AABB_tree tree_b; WrappedVertexPointMap vpm_b(g); From 9a03b19bfad6a90bb9dca6a048447a060417af40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 12:21:42 +0200 Subject: [PATCH 22/68] Fixed TDS2 graph traits to work without relying on halfedge hacks from TDS2.h --- ...ph_traits_Triangulation_data_structure_2.h | 1197 ++++++++++------- 1 file changed, 674 insertions(+), 523 deletions(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h index 48d30084417..efadd3231e7 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h @@ -39,64 +39,248 @@ // treat a CGAL Triangulation_data_structure_2 object as a boost graph "as is". No // wrapper is needed for the Triangulation_data_structure_2 object. - namespace CGAL { - namespace detail { +namespace detail { - template - struct TDS2_halfedge_descriptor - { - typedef typename Tr::Face_handle face_descriptor; - face_descriptor first; - int second; - operator std::pair() { return std::make_pair(first,second); } - - TDS2_halfedge_descriptor() - : first(), second(0) - {} - - TDS2_halfedge_descriptor(const typename Tr::Edge& e) - : first(e.first), second(e.second) - {} - - TDS2_halfedge_descriptor(face_descriptor fd, int i) - : first(fd), second(i) - {} - - friend std::size_t hash_value(const TDS2_halfedge_descriptor& h) - { - return hash_value(h.first); - } - - bool operator==(const TDS2_halfedge_descriptor& other) const - { - return (first == other.first) && (second == other.second); - } - - bool operator!=(const TDS2_halfedge_descriptor& other) const - { - return (first != other.first) || (second != other.second); - } +// A TDS edge is a face handle + an int, and is thus actually a halfedge... +template +struct TDS2_halfedge_descriptor + : public TDS::Edge +{ + typedef typename TDS::Edge Base; + typedef typename TDS::Face_handle Face_handle; - bool operator<(const TDS2_halfedge_descriptor& other) const - { - if(first < other.first) return true; - if(first > other.first) return false; - return second < other.second; - } - }; + TDS2_halfedge_descriptor() {} + TDS2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { } + explicit TDS2_halfedge_descriptor(const Base& e) : Base(e) { } + TDS2_halfedge_descriptor(const TDS2_halfedge_descriptor& h) : Base(h) { } + const Base& base() const { return static_cast(*this); } - } // namespace detail + TDS2_halfedge_descriptor& operator=(const TDS2_halfedge_descriptor& h) + { + this->first = h.first; + this->second = h.second; + return *this; + } + + friend std::size_t hash_value(const TDS2_halfedge_descriptor& e) { + return hash_value(e.first); + } + + bool operator==(const TDS2_halfedge_descriptor& other) const { + return (this->first == other.first) && (this->second == other.second); + } + bool operator!=(const TDS2_halfedge_descriptor& other) const { + return (this->first != other.first) || (this->second != other.second); + } + + bool operator<(const TDS2_halfedge_descriptor& other) const + { + if(this->first < other.first) return true; + if(this->first > other.first) return false; + return this->second < other.second; + } +}; + +// An edge is just a halfedge, but we give it a complete structure to distinguish it from TDS::Edge +template +struct TDS2_edge_descriptor +{ + typedef typename TDS::Face_handle Face_handle; + + TDS2_edge_descriptor() : first(), second(0) { } + explicit TDS2_edge_descriptor(const typename TDS::Edge& e) : first(e.first), second(e.second) { } + TDS2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { } + + // so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle + operator std::pair() { return std::make_pair(first, second); } + + friend std::size_t hash_value(const TDS2_edge_descriptor& h) + { + if(h.first == Face_handle()) + return 0; + + return hash_value(h.first < h.first->neighbor(h.second) ? h.first + : h.first->neighbor(h.second)); + } + + bool operator==(const TDS2_edge_descriptor& other) const + { + if((first == other.first) && (second == other.second)) + return true; + + Face_handle fh = first->neighbor(second); + if(other.first != fh) + return false; + + int i = fh->index(first); + return (other.second == i); + } + bool operator!=(TDS2_edge_descriptor& other) const { return ! (*this == other); } + + Face_handle first; + int second; +}; + +// A halfedge iterator is just an edge iterator that duplicates everything twice, +// to see the edge from either side. +// Could probably be factorized with T2_edge_iterator, but it's clearer this way. +template +struct TDS2_halfedge_iterator +{ +private: + typedef TDS2_halfedge_iterator Self; + typedef typename TDS::Edge_iterator Edge_iterator; + typedef TDS2_halfedge_descriptor Descriptor; + typedef typename TDS::Face_handle Face_handle; + +public: + typedef Descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + TDS2_halfedge_iterator() { } + TDS2_halfedge_iterator(const Edge_iterator& feit) : it(feit), on_adjacent_face(false) { } + + Self& operator++() + { + // If we are on the first face, move to the opposite face. If we are already on the opposite face, + // then it's time to move on the next edge + if(on_adjacent_face) { + ++it; + on_adjacent_face = false; + } else { + on_adjacent_face = true; + } + + return *this; + } + + Self& operator--() + { + // Note that while decreasing, we start from the opposite face + if(on_adjacent_face) { + on_adjacent_face = false; + } else { + --it; + on_adjacent_face = true; + } + + return *this; + } + + Self operator++(int) { Self tmp = *this; operator++(); return tmp; } + Self operator--(int) { Self tmp = *this; operator--(); return tmp; } + + bool operator==(const Self& other) const { return it == other.it; } + bool operator!=(const Self& other) const { return !(*this == other); } + + value_type operator*() const + { + if(on_adjacent_face) { + Face_handle neigh_f = it->first->neighbor(it->second); + return value_type(neigh_f, neigh_f->index(it->first)); + } else { + return value_type(*it); + } + } + +private: + Edge_iterator it; + bool on_adjacent_face; +}; + +template +struct TDS2_edge_iterator +{ +private: + typedef TDS2_edge_iterator Self; + typedef typename TDS::Edge_iterator Edge_iterator; + typedef TDS2_edge_descriptor Descriptor; + +public: + typedef Descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + TDS2_edge_iterator() { } + TDS2_edge_iterator(const Edge_iterator& feit) : it(feit) { } + + bool operator==(const Self& other) const { return it == other.it; } + bool operator!=(const Self& other) const { return !(*this == other); } + Self& operator++() { ++it; return *this; } + Self& operator--() { --it; return *this; } + Self operator++(int) { Self tmp = *this; operator++(); return tmp; } + Self operator--(int) { Self tmp = *this; operator--(); return tmp; } + value_type operator*() const { return value_type(*it); } + +private: + Edge_iterator it; +}; + +template +class TDS2_Out_edge_circulator + : public Circ +{ +private: + mutable E e; + +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + + TDS2_Out_edge_circulator() : Circ() {} + TDS2_Out_edge_circulator(Circ c) : Circ(c) {} + + const E& operator*() const + { + E ed = static_cast(this)->operator*(); + e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); + return e; + } +}; + +template +class TDS2_In_edge_circulator + : public Circ +{ +private: + mutable E e; + +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + + TDS2_In_edge_circulator() : Circ() {} + TDS2_In_edge_circulator(Circ c) : Circ(c) {} + + const E& operator*() const + { + typename Circ::value_type ed = static_cast(this)->operator*(); + e = E(ed); + return e; + } +}; + +} // namespace detail } // namespace CGAL namespace std{ // workaround a bug detected on at least g++ 4.4 where boost::next(Iterator) // is picked as a candidate for next(h,g) -template -struct iterator_traits< CGAL::detail::TDS2_halfedge_descriptor > +template +struct iterator_traits< CGAL::detail::TDS2_halfedge_descriptor > { typedef void* iterator_category; typedef void* difference_type; @@ -108,534 +292,506 @@ struct iterator_traits< CGAL::detail::TDS2_halfedge_descriptor > namespace boost { - template - struct graph_traits< CGAL::Triangulation_data_structure_2 > { - - struct TDS2_graph_traversal_category : +template +struct graph_traits > +{ + struct TDS2_graph_traversal_category : public virtual bidirectional_graph_tag, public virtual adjacency_graph_tag, public virtual edge_list_graph_tag, public virtual vertex_list_graph_tag { }; - typedef CGAL::Triangulation_data_structure_2 Triangulation_data_structure; + typedef CGAL::Triangulation_data_structure_2 Triangulation_data_structure; - typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle vertex_descriptor; - typedef typename CGAL::Triangulation_data_structure_2::Face_handle face_descriptor; - typedef CGAL::detail::Edge, typename CGAL::Triangulation_data_structure_2::Edge> edge_descriptor; - typedef typename CGAL::Triangulation_data_structure_2::Edge_iterator edge_iterator; + typedef typename Triangulation_data_structure::Vertex_handle vertex_descriptor; + typedef CGAL::detail::TDS2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::detail::TDS2_edge_descriptor edge_descriptor; + typedef typename Triangulation_data_structure::Face_handle face_descriptor; + typedef CGAL::Prevent_deref vertex_iterator; + typedef CGAL::detail::TDS2_halfedge_iterator halfedge_iterator; + typedef CGAL::detail::TDS2_edge_iterator edge_iterator; + typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::detail::TDS2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; + typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; + typedef CGAL::Counting_iterator Incident_vertices_iterator; + typedef Incident_vertices_iterator adjacency_iterator; - typedef typename CGAL::Triangulation_data_structure_2::Halfedge_iterator halfedge_iterator; + typedef undirected_tag directed_category; + typedef disallow_parallel_edge_tag edge_parallel_category; + typedef TDS2_graph_traversal_category traversal_category; - typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; - typedef CGAL::Counting_iterator Incident_vertices_iterator; - typedef Incident_vertices_iterator adjacency_iterator; - - typedef undirected_tag directed_category; - typedef disallow_parallel_edge_tag edge_parallel_category; - typedef TDS2_graph_traversal_category traversal_category; - typedef typename Triangulation_data_structure::size_type size_type; - typedef size_type vertices_size_type; - typedef size_type edges_size_type; - typedef size_type halfedges_size_type; - typedef size_type faces_size_type; - typedef size_type degree_size_type; - - // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } - }; + typedef typename Triangulation_data_structure::size_type size_type; + typedef size_type vertices_size_type; + typedef size_type edges_size_type; + typedef size_type halfedges_size_type; + typedef size_type faces_size_type; + typedef size_type degree_size_type; + // nulls + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } +}; } // namespace boost - namespace CGAL { - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor - next(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor +next(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2& ) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(e.first, Triangulation_data_structure_2::ccw(e.second)); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor +prev(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2& ) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(e.first, Triangulation_data_structure_2::cw(e.second)); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor +opposite(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2& g) +{ + typedef typename Triangulation_data_structure_2::Edge Edge; + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(g.mirror_edge(Edge(e.first, e.second))); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor +source(typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor e, const Triangulation_data_structure_2& ) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first, Triangulation_data_structure_2::ccw(e.second)); - } +{ + return e.first->vertex(Triangulation_data_structure_2::ccw(e.second)); +} - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor - prev(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, +template +typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor +target(typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor e, const Triangulation_data_structure_2& ) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first, Triangulation_data_structure_2::cw(e.second)); - } +{ + return e.first->vertex(Triangulation_data_structure_2::cw(e.second)); +} - +template +typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor +source(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2& ) +{ + return e.first->vertex(Triangulation_data_structure_2::ccw(e.second)); +} - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor - opposite(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, - const Triangulation_data_structure_2& g) - { - - return g.mirror_edge(e); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor - source(typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor e, - const Triangulation_data_structure_2& ) - { - return e.first->vertex(Triangulation_data_structure_2::ccw(e.second)); - } +template +typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor +target(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2& ) +{ + return e.first->vertex(Triangulation_data_structure_2::cw(e.second)); +} - template - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor - target(typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor e, - const Triangulation_data_structure_2& ) - { - return e.first->vertex(Triangulation_data_structure_2::cw(e.second)); - } +template +typename boost::graph_traits< Triangulation_data_structure_2 >::face_descriptor +face(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2&) +{ + return e.first; +} - template - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor - source(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, - const Triangulation_data_structure_2& ) - { - return e.first->vertex(Triangulation_data_structure_2::ccw(e.second)); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor - target(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, - const Triangulation_data_structure_2& ) - { - return e.first->vertex(Triangulation_data_structure_2::cw(e.second)); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::face_descriptor - face(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor +halfedge(typename boost::graph_traits< Triangulation_data_structure_2 >::face_descriptor f, const Triangulation_data_structure_2&) - { - return e.first; +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(f,0); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor +halfedge(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor v, + const Triangulation_data_structure_2& ) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::face_descriptor face_descriptor; + face_descriptor fd = v->face(); + int i = fd->index(v); + return halfedge_descriptor(fd,Triangulation_data_structure_2::ccw(i)); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor +halfedge(typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor e, + const Triangulation_data_structure_2&) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; + return halfedge_descriptor(e.first, e.second); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor +edge(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, + const Triangulation_data_structure_2&) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor edge_descriptor; + return edge_descriptor(e.first,e.second); +} + +template +inline Iterator_range >::vertex_iterator> +vertices(const Triangulation_data_structure_2& g) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_iterator Iter; + return make_range(Iter(g.vertices_begin()), Iter(g.vertices_end())); +} + +template +inline Iterator_range >::edge_iterator> +edges(const Triangulation_data_structure_2& g) +{ + typedef typename boost::graph_traits >::edge_iterator Iter; + return make_range(Iter(g.edges_begin()), Iter(g.edges_end())); +} + +template +inline Iterator_range >::halfedge_iterator > +halfedges(const Triangulation_data_structure_2& g) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_iterator Iter; + return make_range(Iter(g.edges_begin()), Iter(g.edges_end())); +} + +template +inline Iterator_range >::face_iterator > +faces(const Triangulation_data_structure_2& g) +{ + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::face_iterator Iter; + return make_range(Iter(g.faces_begin()), Iter(g.faces_end())); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type +out_degree(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, + const Triangulation_data_structure_2& g) +{ + typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type deg = 0; + typename Triangulation_data_structure_2::Edge_circulator c = g.incident_edges(u), done(c); + if ( c != 0) { + do { + ++deg; + } while (++c != done); } + return deg; +} - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor - halfedge(typename boost::graph_traits< Triangulation_data_structure_2 >::face_descriptor f, - const Triangulation_data_structure_2&) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(f,0); +template +inline Iterator_range >::out_edge_iterator > +out_edges(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, + const Triangulation_data_structure_2& g) +{ + typename Triangulation_data_structure_2::Edge_circulator ec(u,u->face()); + typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::out_edge_iterator Iter; + + return make_range( Iter(ec), Iter(ec,out_deg) ); +} + +template +inline Iterator_range >::in_edge_iterator > +in_edges(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, + const Triangulation_data_structure_2& g) +{ + typename Triangulation_data_structure_2::Edge_circulator ec(u,u->face()); + typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::in_edge_iterator Iter; + return make_range( Iter(ec), Iter(ec,out_deg) ); +} + +template +inline Iterator_range >::adjacency_iterator> +adjacent_vertices(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, + const Triangulation_data_structure_2& g) +{ + typename Triangulation_data_structure_2::Vertex_circulator vc = out_edge_iterator(u,u.face()); + typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); + typedef typename boost::graph_traits< Triangulation_data_structure_2 >::adjacency_iterator Iter; + return make_range( Iter(vc), Iter(vc,out_deg) ); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::vertices_size_type +num_vertices(const Triangulation_data_structure_2& g) +{ + return g.number_of_vertices(); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::edges_size_type +num_edges(const Triangulation_data_structure_2& g) +{ + return g.number_of_vertices() + g.number_of_faces() - 2; +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::halfedges_size_type +num_halfedges(const Triangulation_data_structure_2& g) +{ + return num_edges(g) * 2; +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::faces_size_type +num_faces(const Triangulation_data_structure_2& g) +{ + return g.number_of_faces(); +} + +template +typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type +in_degree(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, + const Triangulation_data_structure_2& g) +{ + typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type deg = 0; + typename Triangulation_data_structure_2::Edge_circulator c = g.incident_edges(u), done(c); + if ( c != 0) { + do { + ++deg; + } while (++c != done); } + return deg; +} - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor - halfedge(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor v, - const Triangulation_data_structure_2& ) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::face_descriptor face_descriptor; - face_descriptor fd = v->face(); - int i = fd->index(v); - return halfedge_descriptor(fd,Triangulation_data_structure_2::ccw(i)); +template +typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type +degree(typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, + const Triangulation_data_structure_2& g) +{ + typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type deg = 0; + typename Triangulation_data_structure_2::Edge_circulator c = g.incident_edges(u), done(c); + if ( c != 0) { + do { + ++deg; + } while (++c != done); } + return deg; +} - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor - halfedge(typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor e, - const Triangulation_data_structure_2&) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor halfedge_descriptor; - return halfedge_descriptor(e.first,e.second); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor - edge(typename boost::graph_traits< Triangulation_data_structure_2 >::halfedge_descriptor e, - const Triangulation_data_structure_2&) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::edge_descriptor edge_descriptor; - return edge_descriptor(e.first,e.second); - } - - - template - inline Iterator_range >::vertex_iterator> - vertices(const Triangulation_data_structure_2& g) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_iterator - Iter; - return make_range( Iter(g.vertices_begin()), Iter(g.vertices_end()) ); - } - - - template - inline Iterator_range >::edge_iterator> - edges(const Triangulation_data_structure_2& g) - { - return make_range(g.edges_begin(), g.edges_end()); - } - - template - inline Iterator_range >::halfedge_iterator > - halfedges(const Triangulation_data_structure_2& g) - { - return make_range(g.halfedges_begin(), g.halfedges_end()); - } - - template - inline Iterator_range >::face_iterator > - faces(const Triangulation_data_structure_2& g) - { - typedef typename boost::graph_traits< Triangulation_data_structure_2 >::face_iterator - Iter; - return make_range( Iter(g.faces_begin()), Iter(g.faces_end()) ); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type - out_degree( - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, - const Triangulation_data_structure_2& g) - { - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type deg = 0; - typename Triangulation_data_structure_2::Edge_circulator c = g.incident_edges(u), done(c); - if ( c != 0) { - do { - ++deg; - } while (++c != done); - } - return deg; - } - - template - inline Iterator_range >::out_edge_iterator > - out_edges( - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, - const Triangulation_data_structure_2& g) - { - typename Triangulation_data_structure_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< Triangulation_data_structure_2 > - ::out_edge_iterator Iter; - - return make_range( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline Iterator_range >::in_edge_iterator > - in_edges( - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, - const Triangulation_data_structure_2& g) - { - typename Triangulation_data_structure_2::Edge_circulator ec(u,u->face()); - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< Triangulation_data_structure_2 > - ::in_edge_iterator Iter; - return make_range( Iter(ec), Iter(ec,out_deg) ); - } - - template - inline Iterator_range >::adjacency_iterator> - adjacent_vertices( - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, - const Triangulation_data_structure_2& g) - { - typename Triangulation_data_structure_2::Vertex_circulator vc = out_edge_iterator(u,u.face()); - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); - typedef typename boost::graph_traits< Triangulation_data_structure_2 > - ::adjacency_iterator Iter; - return make_range( Iter(vc), Iter(vc,out_deg) ); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::vertices_size_type - num_vertices(const Triangulation_data_structure_2& g) - { - return g.number_of_vertices(); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::edges_size_type - num_edges(const Triangulation_data_structure_2& g) - { - - return g.number_of_vertices() + g.number_of_faces() - 2; - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::halfedges_size_type - num_halfedges(const Triangulation_data_structure_2& g) - { - return num_edges(g) * 2; - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::faces_size_type - num_faces(const Triangulation_data_structure_2& g) - { - return g.number_of_faces(); - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type - in_degree( - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, - const Triangulation_data_structure_2& g) - { - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type deg = 0; - typename Triangulation_data_structure_2::Edge_circulator c = g.incident_edges(u), done(c); - if ( c != 0) { - do { - ++deg; - } while (++c != done); - } - return deg; - } - - template - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type - degree( - typename boost::graph_traits< Triangulation_data_structure_2 >::vertex_descriptor u, - const Triangulation_data_structure_2& g) - { - typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type deg = 0; - typename Triangulation_data_structure_2::Edge_circulator c = g.incident_edges(u), done(c); - if ( c != 0) { - do { - ++deg; - } while (++c != done); - } - return deg; - } - - - // property maps - template - class TDS2_vertex_id_map +// property maps +template +class TDS2_vertex_id_map : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; - - TDS2_vertex_id_map() - {} - - long operator[](key_type vh) const { - return vh->id(); - } - }; +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; + TDS2_vertex_id_map() {} + + long operator[](key_type vh) const { return vh->id(); } +}; + +template +class TDS2_vertex_point_map +{ +public: + typedef boost::lvalue_property_map_tag category; + typedef typename VB::Point value_type; + typedef value_type& reference; + typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; + + friend reference get(TDS2_vertex_point_map, key_type vh) { return vh->point(); } + friend void put(TDS2_vertex_point_map, key_type vh, reference v) { vh->point() = v; } + reference operator[](key_type vh) const { return vh->point(); } +}; + +template +class TDS2_edge_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; + + TDS2_edge_id_map() {} + + long operator[](key_type e) const { return (3 * e.first.id()) + e.second; } +}; + +template +class TDS2_edge_weight_map + : public boost::put_get_helper > +{ +private: + const CGAL::Triangulation_data_structure_2& tr; + +public: + typedef boost::readable_property_map_tag category; + typedef typename VB::FT value_type; + typedef value_type reference; + typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; + + TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2& tr_) : tr(tr_) { } + + value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); } +}; + +template +inline TDS2_vertex_id_map +get(boost::vertex_index_t, const Triangulation_data_structure_2&) +{ + TDS2_vertex_id_map m; + return m; +} + +template +inline TDS2_vertex_point_map +get(boost::vertex_point_t, const Triangulation_data_structure_2&) +{ + TDS2_vertex_point_map m; + return m; +} + +template +inline TDS2_edge_id_map +get(boost::edge_index_t, const Triangulation_data_structure_2&) +{ + TDS2_edge_id_map m; + return m; +} + +template +inline TDS2_edge_weight_map +get(boost::edge_weight_t, const Triangulation_data_structure_2& g) +{ + TDS2_edge_weight_map m(g); + return m; +} + +template +struct TDS2_property_map { }; + +template <> +struct TDS2_property_map +{ template - class TDS2_vertex_point_map - { - public: - typedef boost::lvalue_property_map_tag category; - typedef typename VB::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; - - friend reference get(TDS2_vertex_point_map, key_type vh) - { - return vh->point(); - } - friend void put(TDS2_vertex_point_map, key_type vh, reference v) - { - vh->point()=v; - } - reference operator[](key_type vh) const { - return vh->point(); - } + struct bind_ { + typedef TDS2_vertex_id_map type; + typedef TDS2_vertex_id_map const_type; }; +}; + +template <> +struct TDS2_property_map +{ template - class TDS2_edge_id_map - : public boost::put_get_helper > - { - public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; - - TDS2_edge_id_map() - {} - - long operator[](key_type e) const { - return (3 * e.first.id()) + e.second; - } + struct bind_ { + typedef TDS2_vertex_point_map type; + typedef TDS2_vertex_point_map const_type; }; +}; + +template <> +struct TDS2_property_map +{ template - class TDS2_edge_weight_map - : public boost::put_get_helper > - { - private: - const CGAL::Triangulation_data_structure_2& tr; - public: - typedef boost::readable_property_map_tag category; - typedef typename VB::FT value_type; - typedef value_type reference; - typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; - - TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2& tr_) - : tr(tr_) - { } - - value_type operator[](key_type e) const { - return approximate_sqrt(tr.segment(e).squared_length()); - } + struct bind_ { + typedef TDS2_edge_id_map type; + typedef TDS2_edge_id_map const_type; }; +}; +template <> +struct TDS2_property_map +{ template - inline TDS2_vertex_id_map - get(boost::vertex_index_t, const Triangulation_data_structure_2&) { - TDS2_vertex_id_map m; - return m; - } - - template - inline TDS2_vertex_point_map - get(boost::vertex_point_t, const Triangulation_data_structure_2&) { - TDS2_vertex_point_map m; - return m; - } - - template - inline TDS2_edge_id_map - get(boost::edge_index_t, const Triangulation_data_structure_2&) { - TDS2_edge_id_map m; - return m; - } - - template - inline TDS2_edge_weight_map - get(boost::edge_weight_t, const Triangulation_data_structure_2& g) { - TDS2_edge_weight_map m(g); - return m; - } - - template - struct TDS2_property_map { }; - - template <> - struct TDS2_property_map { - template - struct bind_ { - typedef TDS2_vertex_id_map type; - typedef TDS2_vertex_id_map const_type; - }; - }; - - - - template <> - struct TDS2_property_map { - template - struct bind_ { - typedef TDS2_vertex_point_map type; - typedef TDS2_vertex_point_map const_type; - }; - }; - - - template <> - struct TDS2_property_map { - template - struct bind_ { - typedef TDS2_edge_id_map type; - typedef TDS2_edge_id_map const_type; - }; - }; - - - template <> - struct TDS2_property_map { - template - struct bind_ { - typedef TDS2_edge_weight_map type; - typedef TDS2_edge_weight_map const_type; - }; + struct bind_ { + typedef TDS2_edge_weight_map type; + typedef TDS2_edge_weight_map const_type; }; +}; } // namespace CGAL namespace boost { - // g++ 'enumeral_type' in template unification not implemented workaround - template - struct property_map, Tag> { - typedef typename - CGAL::TDS2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; +// g++ 'enumeral_type' in template unification not implemented workaround +template +struct property_map, Tag> +{ + typedef typename + CGAL::TDS2_property_map::template bind_ map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; - // see struct property_map in Polyehdron for an explanation - template - struct property_map, Tag> { - typedef typename - CGAL::TDS2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; - }; +// see struct property_map in Polyehdron for an explanation +template +struct property_map, Tag> +{ + typedef typename + CGAL::TDS2_property_map::template bind_ map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; } // namespace boost namespace CGAL { - template - inline - typename boost::property_traits< - typename boost::property_map,PropertyTag>::const_type>::value_type - get(PropertyTag p, const Triangulation_data_structure_2& g, const Key& key) { - return get(get(p, g), key); - } - - template - inline void - put(PropertyTag p, Triangulation_data_structure_2& g, - const Key& key, const Value& value) - { - typedef typename boost::property_map, PropertyTag>::type Map; - Map pmap = get(p, g); - put(pmap, key, value); - } +template +inline +typename boost::property_traits< +typename boost::property_map,PropertyTag>::const_type>::value_type +get(PropertyTag p, const Triangulation_data_structure_2& g, const Key& key) +{ + return get(get(p, g), key); +} + +template +inline void +put(PropertyTag p, Triangulation_data_structure_2& g, + const Key& key, const Value& value) +{ + typedef typename boost::property_map, PropertyTag>::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} } // namespace CGAL namespace boost { - // What are those needed for ??? - template - struct edge_property_type > { - typedef void type; - }; +// What are those needed for ??? +template +struct edge_property_type > { + typedef void type; +}; - template - struct vertex_property_type > { - typedef void type; - }; +template +struct vertex_property_type > { + typedef void type; +}; } // namespace boost - namespace std { - #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4099) // For VC10 it is class hash @@ -643,21 +799,17 @@ namespace std { #ifndef CGAL_CFG_NO_STD_HASH - template < class T, class EdgeBase> - struct hash > { - std::size_t operator()(const CGAL::detail::Edge& e) const - { - return hash_value(e); - } - }; +template +struct hash > +{ + std::size_t operator()(const CGAL::detail::TDS2_edge_descriptor& e) const { return hash_value(e); } +}; - template < class Tr> - struct hash > { - std::size_t operator()(const CGAL::detail::TDS2_halfedge_descriptor& e) const - { - return hash_value(e); - } - }; +template +struct hash > +{ + std::size_t operator()(const CGAL::detail::TDS2_halfedge_descriptor& e) const { return hash_value(e); } +}; #endif // CGAL_CFG_NO_STD_HASH @@ -667,5 +819,4 @@ namespace std { } // namespace std - #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_DATA_STRUCTURE_2_H From 64d7747f8b48c6e93c78d81b2ad794c364c7ab13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 13:21:46 +0200 Subject: [PATCH 23/68] Moved factorized 2D graph traits to /internal --- .../graph/graph_traits_Constrained_Delaunay_triangulation_2.h | 2 +- .../CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h | 2 +- .../boost/graph/graph_traits_Constrained_triangulation_plus_2.h | 2 +- .../CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h | 2 +- .../CGAL/boost/graph/graph_traits_Regular_triangulation_2.h | 2 +- .../include/CGAL/boost/graph/graph_traits_Triangulation_2.h | 2 +- .../CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h | 2 +- .../boost/graph/{ => internal}/graph_traits_2D_triangulation.h | 0 .../boost/graph/{ => internal}/properties_2D_triangulation.h | 0 .../graph/properties_Constrained_Delaunay_triangulation_2.h | 2 +- .../CGAL/boost/graph/properties_Constrained_triangulation_2.h | 2 +- .../boost/graph/properties_Constrained_triangulation_plus_2.h | 2 +- .../CGAL/boost/graph/properties_Delaunay_triangulation_2.h | 2 +- .../CGAL/boost/graph/properties_Regular_triangulation_2.h | 2 +- .../include/CGAL/boost/graph/properties_Triangulation_2.h | 2 +- .../CGAL/boost/graph/properties_Triangulation_hierarchy_2.h | 2 +- 16 files changed, 14 insertions(+), 14 deletions(-) rename Triangulation_2/include/CGAL/boost/graph/{ => internal}/graph_traits_2D_triangulation.h (100%) rename Triangulation_2/include/CGAL/boost/graph/{ => internal}/properties_2D_triangulation.h (100%) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h index 6a073bec25d..54a28e1e6d7 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Constrained_Delaunay_triangulation_2 #define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS, Itag -#include +#include #endif // CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h index f9d474ecdbc..466fd331d87 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_2 #define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS, Itag -#include +#include #endif // CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h index 81bd2df4fe1..d72f3d16053 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_plus_2 #define CGAL_2D_TRIANGULATION_TEMPLATES Tr -#include +#include #endif // CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h index cb79583b363..a35a19e7aac 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Delaunay_triangulation_2 #define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS -#include +#include #endif // CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h index 591f6dc71c5..d06bce18423 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Regular_triangulation_2 #define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS -#include +#include #endif // CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h index 38c6c89da19..63910c65184 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Triangulation_2 #define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS -#include +#include #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h index 31932767c92..189f007e58b 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h @@ -31,6 +31,6 @@ #define CGAL_2D_TRIANGULATION CGAL::Triangulation_hierarchy_2 #define CGAL_2D_TRIANGULATION_TEMPLATES Tr -#include +#include #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h similarity index 100% rename from Triangulation_2/include/CGAL/boost/graph/graph_traits_2D_triangulation.h rename to Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h similarity index 100% rename from Triangulation_2/include/CGAL/boost/graph/properties_2D_triangulation.h rename to Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h index fc9d538fb46..39bc63b86b7 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag #define CGAL_2D_TRIANGULATION CGAL::Constrained_Delaunay_triangulation_2 -#include +#include #endif /* CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h index 6238f25681d..cf240c2bd07 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag #define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_2 -#include +#include #endif /* CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h index d5914040e52..a110f485ba5 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr #define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_plus_2 -#include +#include #endif /* CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h index f9412771dda..f67b8e03ce6 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Delaunay_triangulation_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS #define CGAL_2D_TRIANGULATION CGAL::Delaunay_triangulation_2 -#include +#include #endif /* CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h index ab6bf9b43d9..1dd7da20f96 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Regular_triangulation_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS #define CGAL_2D_TRIANGULATION CGAL::Regular_triangulation_2 -#include +#include #endif /* CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h index d4e0104af0f..81f7a4c953d 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS #define CGAL_2D_TRIANGULATION CGAL::Triangulation_2 -#include +#include #endif /* CGAL_PROPERTIES_TRIANGULATION_2_H */ diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h index 54ff046294a..ff55fd46bf5 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_hierarchy_2.h @@ -25,6 +25,6 @@ #define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr #define CGAL_2D_TRIANGULATION CGAL::Triangulation_hierarchy_2 -#include +#include #endif /* CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H */ From 9cba48acfedbcc541720106f559fcedc9398fe8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 13:22:45 +0200 Subject: [PATCH 24/68] Fixed TDS graph traits implementation and factorized some parts with other T2 GT --- Convex_hull_3/include/CGAL/convex_hull_3.h | 1 + ...ph_traits_Triangulation_data_structure_2.h | 523 +----------------- .../internal/graph_traits_2D_triangulation.h | 389 +------------ .../graph_traits_2D_triangulation_helper.h | 445 +++++++++++++++ .../internal/properties_2D_triangulation.h | 73 ++- ...roperties_Triangulation_data_structure_2.h | 354 ++++++++++++ 6 files changed, 876 insertions(+), 909 deletions(-) create mode 100644 Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index 63dbb592b43..ac5999c37c7 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -54,6 +54,7 @@ #include #include #include +#include #include #include diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h index efadd3231e7..123d3502a6c 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h @@ -25,272 +25,22 @@ // include this to avoid a VC15 warning #include +#include + +#include +#include +#include #include #include #include #include -#include -#include -#include - // The functions and classes in this file allows the user to // treat a CGAL Triangulation_data_structure_2 object as a boost graph "as is". No // wrapper is needed for the Triangulation_data_structure_2 object. -namespace CGAL { - -namespace detail { - -// A TDS edge is a face handle + an int, and is thus actually a halfedge... -template -struct TDS2_halfedge_descriptor - : public TDS::Edge -{ - typedef typename TDS::Edge Base; - typedef typename TDS::Face_handle Face_handle; - - TDS2_halfedge_descriptor() {} - TDS2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { } - explicit TDS2_halfedge_descriptor(const Base& e) : Base(e) { } - TDS2_halfedge_descriptor(const TDS2_halfedge_descriptor& h) : Base(h) { } - - const Base& base() const { return static_cast(*this); } - - TDS2_halfedge_descriptor& operator=(const TDS2_halfedge_descriptor& h) - { - this->first = h.first; - this->second = h.second; - return *this; - } - - friend std::size_t hash_value(const TDS2_halfedge_descriptor& e) { - return hash_value(e.first); - } - - bool operator==(const TDS2_halfedge_descriptor& other) const { - return (this->first == other.first) && (this->second == other.second); - } - bool operator!=(const TDS2_halfedge_descriptor& other) const { - return (this->first != other.first) || (this->second != other.second); - } - - bool operator<(const TDS2_halfedge_descriptor& other) const - { - if(this->first < other.first) return true; - if(this->first > other.first) return false; - return this->second < other.second; - } -}; - -// An edge is just a halfedge, but we give it a complete structure to distinguish it from TDS::Edge -template -struct TDS2_edge_descriptor -{ - typedef typename TDS::Face_handle Face_handle; - - TDS2_edge_descriptor() : first(), second(0) { } - explicit TDS2_edge_descriptor(const typename TDS::Edge& e) : first(e.first), second(e.second) { } - TDS2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { } - - // so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle - operator std::pair() { return std::make_pair(first, second); } - - friend std::size_t hash_value(const TDS2_edge_descriptor& h) - { - if(h.first == Face_handle()) - return 0; - - return hash_value(h.first < h.first->neighbor(h.second) ? h.first - : h.first->neighbor(h.second)); - } - - bool operator==(const TDS2_edge_descriptor& other) const - { - if((first == other.first) && (second == other.second)) - return true; - - Face_handle fh = first->neighbor(second); - if(other.first != fh) - return false; - - int i = fh->index(first); - return (other.second == i); - } - bool operator!=(TDS2_edge_descriptor& other) const { return ! (*this == other); } - - Face_handle first; - int second; -}; - -// A halfedge iterator is just an edge iterator that duplicates everything twice, -// to see the edge from either side. -// Could probably be factorized with T2_edge_iterator, but it's clearer this way. -template -struct TDS2_halfedge_iterator -{ -private: - typedef TDS2_halfedge_iterator Self; - typedef typename TDS::Edge_iterator Edge_iterator; - typedef TDS2_halfedge_descriptor Descriptor; - typedef typename TDS::Face_handle Face_handle; - -public: - typedef Descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - TDS2_halfedge_iterator() { } - TDS2_halfedge_iterator(const Edge_iterator& feit) : it(feit), on_adjacent_face(false) { } - - Self& operator++() - { - // If we are on the first face, move to the opposite face. If we are already on the opposite face, - // then it's time to move on the next edge - if(on_adjacent_face) { - ++it; - on_adjacent_face = false; - } else { - on_adjacent_face = true; - } - - return *this; - } - - Self& operator--() - { - // Note that while decreasing, we start from the opposite face - if(on_adjacent_face) { - on_adjacent_face = false; - } else { - --it; - on_adjacent_face = true; - } - - return *this; - } - - Self operator++(int) { Self tmp = *this; operator++(); return tmp; } - Self operator--(int) { Self tmp = *this; operator--(); return tmp; } - - bool operator==(const Self& other) const { return it == other.it; } - bool operator!=(const Self& other) const { return !(*this == other); } - - value_type operator*() const - { - if(on_adjacent_face) { - Face_handle neigh_f = it->first->neighbor(it->second); - return value_type(neigh_f, neigh_f->index(it->first)); - } else { - return value_type(*it); - } - } - -private: - Edge_iterator it; - bool on_adjacent_face; -}; - -template -struct TDS2_edge_iterator -{ -private: - typedef TDS2_edge_iterator Self; - typedef typename TDS::Edge_iterator Edge_iterator; - typedef TDS2_edge_descriptor Descriptor; - -public: - typedef Descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - TDS2_edge_iterator() { } - TDS2_edge_iterator(const Edge_iterator& feit) : it(feit) { } - - bool operator==(const Self& other) const { return it == other.it; } - bool operator!=(const Self& other) const { return !(*this == other); } - Self& operator++() { ++it; return *this; } - Self& operator--() { --it; return *this; } - Self operator++(int) { Self tmp = *this; operator++(); return tmp; } - Self operator--(int) { Self tmp = *this; operator--(); return tmp; } - value_type operator*() const { return value_type(*it); } - -private: - Edge_iterator it; -}; - -template -class TDS2_Out_edge_circulator - : public Circ -{ -private: - mutable E e; - -public: - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - TDS2_Out_edge_circulator() : Circ() {} - TDS2_Out_edge_circulator(Circ c) : Circ(c) {} - - const E& operator*() const - { - E ed = static_cast(this)->operator*(); - e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); - return e; - } -}; - -template -class TDS2_In_edge_circulator - : public Circ -{ -private: - mutable E e; - -public: - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - TDS2_In_edge_circulator() : Circ() {} - TDS2_In_edge_circulator(Circ c) : Circ(c) {} - - const E& operator*() const - { - typename Circ::value_type ed = static_cast(this)->operator*(); - e = E(ed); - return e; - } -}; - -} // namespace detail -} // namespace CGAL - -namespace std{ - -// workaround a bug detected on at least g++ 4.4 where boost::next(Iterator) -// is picked as a candidate for next(h,g) -template -struct iterator_traits< CGAL::detail::TDS2_halfedge_descriptor > -{ - typedef void* iterator_category; - typedef void* difference_type; - typedef void* value_type; - typedef void* reference; -}; - -} // end of namespace std - -namespace boost { +namespace boost { template struct graph_traits > @@ -304,17 +54,19 @@ struct graph_traits > typedef CGAL::Triangulation_data_structure_2 Triangulation_data_structure; typedef typename Triangulation_data_structure::Vertex_handle vertex_descriptor; - typedef CGAL::detail::TDS2_halfedge_descriptor halfedge_descriptor; - typedef CGAL::detail::TDS2_edge_descriptor edge_descriptor; + typedef CGAL::internal::T2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::internal::T2_edge_descriptor edge_descriptor; typedef typename Triangulation_data_structure::Face_handle face_descriptor; typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::detail::TDS2_halfedge_iterator halfedge_iterator; - typedef CGAL::detail::TDS2_edge_iterator edge_iterator; + typedef CGAL::internal::T2_halfedge_iterator halfedge_iterator; + typedef CGAL::internal::T2_edge_iterator edge_iterator; typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; + typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; + typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; typedef CGAL::Counting_iterator Incident_vertices_iterator; typedef Incident_vertices_iterator adjacency_iterator; @@ -330,11 +82,16 @@ struct graph_traits > typedef size_type degree_size_type; // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } }; +template +struct graph_traits > + : public graph_traits< CGAL::Triangulation_data_structure_2 > +{ }; + } // namespace boost namespace CGAL { @@ -502,7 +259,7 @@ out_edges(typename boost::graph_traits< Triangulation_data_structure_2 >: typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_data_structure_2 >::out_edge_iterator Iter; - return make_range( Iter(ec), Iter(ec,out_deg) ); + return make_range(Iter(ec), Iter(ec,out_deg)); } template @@ -513,7 +270,7 @@ in_edges(typename boost::graph_traits< Triangulation_data_structure_2 >:: typename Triangulation_data_structure_2::Edge_circulator ec(u,u->face()); typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_data_structure_2 >::in_edge_iterator Iter; - return make_range( Iter(ec), Iter(ec,out_deg) ); + return make_range(Iter(ec), Iter(ec,out_deg)); } template @@ -585,238 +342,6 @@ degree(typename boost::graph_traits< Triangulation_data_structure_2 >::ve return deg; } -// property maps -template -class TDS2_vertex_id_map - : public boost::put_get_helper > -{ -public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; - - TDS2_vertex_id_map() {} - - long operator[](key_type vh) const { return vh->id(); } -}; - -template -class TDS2_vertex_point_map -{ -public: - typedef boost::lvalue_property_map_tag category; - typedef typename VB::Point value_type; - typedef value_type& reference; - typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; - - friend reference get(TDS2_vertex_point_map, key_type vh) { return vh->point(); } - friend void put(TDS2_vertex_point_map, key_type vh, reference v) { vh->point() = v; } - reference operator[](key_type vh) const { return vh->point(); } -}; - -template -class TDS2_edge_id_map - : public boost::put_get_helper > -{ -public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; - - TDS2_edge_id_map() {} - - long operator[](key_type e) const { return (3 * e.first.id()) + e.second; } -}; - -template -class TDS2_edge_weight_map - : public boost::put_get_helper > -{ -private: - const CGAL::Triangulation_data_structure_2& tr; - -public: - typedef boost::readable_property_map_tag category; - typedef typename VB::FT value_type; - typedef value_type reference; - typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; - - TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2& tr_) : tr(tr_) { } - - value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); } -}; - -template -inline TDS2_vertex_id_map -get(boost::vertex_index_t, const Triangulation_data_structure_2&) -{ - TDS2_vertex_id_map m; - return m; -} - -template -inline TDS2_vertex_point_map -get(boost::vertex_point_t, const Triangulation_data_structure_2&) -{ - TDS2_vertex_point_map m; - return m; -} - -template -inline TDS2_edge_id_map -get(boost::edge_index_t, const Triangulation_data_structure_2&) -{ - TDS2_edge_id_map m; - return m; -} - -template -inline TDS2_edge_weight_map -get(boost::edge_weight_t, const Triangulation_data_structure_2& g) -{ - TDS2_edge_weight_map m(g); - return m; -} - -template -struct TDS2_property_map { }; - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_vertex_id_map type; - typedef TDS2_vertex_id_map const_type; - }; -}; - - - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_vertex_point_map type; - typedef TDS2_vertex_point_map const_type; - }; -}; - - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_edge_id_map type; - typedef TDS2_edge_id_map const_type; - }; -}; - - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_edge_weight_map type; - typedef TDS2_edge_weight_map const_type; - }; -}; - } // namespace CGAL -namespace boost { -// g++ 'enumeral_type' in template unification not implemented workaround -template -struct property_map, Tag> -{ - typedef typename - CGAL::TDS2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; -}; - -// see struct property_map in Polyehdron for an explanation -template -struct property_map, Tag> -{ - typedef typename - CGAL::TDS2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; -}; - -} // namespace boost - - -namespace CGAL { - -template -inline -typename boost::property_traits< -typename boost::property_map,PropertyTag>::const_type>::value_type -get(PropertyTag p, const Triangulation_data_structure_2& g, const Key& key) -{ - return get(get(p, g), key); -} - -template -inline void -put(PropertyTag p, Triangulation_data_structure_2& g, - const Key& key, const Value& value) -{ - typedef typename boost::property_map, PropertyTag>::type Map; - Map pmap = get(p, g); - put(pmap, key, value); -} - -} // namespace CGAL - -namespace boost { - -// What are those needed for ??? -template -struct edge_property_type > { - typedef void type; -}; - -template -struct vertex_property_type > { - typedef void type; -}; -} // namespace boost - -namespace std { - -#if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4099) // For VC10 it is class hash -#endif - -#ifndef CGAL_CFG_NO_STD_HASH - -template -struct hash > -{ - std::size_t operator()(const CGAL::detail::TDS2_edge_descriptor& e) const { return hash_value(e); } -}; - -template -struct hash > -{ - std::size_t operator()(const CGAL::detail::TDS2_halfedge_descriptor& e) const { return hash_value(e); } -}; - -#endif // CGAL_CFG_NO_STD_HASH - -#if defined(BOOST_MSVC) -# pragma warning(pop) -#endif - -} // namespace std - #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_DATA_STRUCTURE_2_H diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h index a6065a2fa6f..1684327ec32 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h @@ -31,6 +31,8 @@ #error CGAL_2D_TRIANGULATION_TEMPLATES is not defined #endif +#include + #include #include #include @@ -41,367 +43,6 @@ #include -// Small include guard for helper classes -#ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION -#define CGAL_GRAPH_TRAITS_2D_TRIANGULATION - -namespace CGAL { -namespace detail { - -// A triangulation edge is a face handle + an int, and is thus actually a halfedge... -template -struct T2_halfedge_descriptor - : public Tr::Edge -{ - typedef typename Tr::Edge Base; - typedef typename Tr::Face_handle Face_handle; - - T2_halfedge_descriptor() {} - T2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { } - explicit T2_halfedge_descriptor(const Base& e) : Base(e) { } - T2_halfedge_descriptor(const T2_halfedge_descriptor& h) : Base(h) { } - - const Base& base() const { return static_cast(*this); } - - T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h) - { - this->first = h.first; - this->second = h.second; - return *this; - } - - friend std::size_t hash_value(const T2_halfedge_descriptor& e) { - return hash_value(e.first); - } - - bool operator==(const T2_halfedge_descriptor& other) const { - return (this->first == other.first) && (this->second == other.second); - } - bool operator!=(const T2_halfedge_descriptor& other) const { - return (this->first != other.first) || (this->second != other.second); - } - - bool operator<(const T2_halfedge_descriptor& other) const - { - if(this->first < other.first) return true; - if(this->first > other.first) return false; - return this->second < other.second; - } -}; - -// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge -template -struct T2_edge_descriptor -{ - typedef typename Tr::Face_handle Face_handle; - - T2_edge_descriptor() : first(), second(0) { } - explicit T2_edge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } - T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { } - - // so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle - operator std::pair() { return std::make_pair(first, second); } - - friend std::size_t hash_value(const T2_edge_descriptor& h) - { - if(h.first == Face_handle()) - return 0; - - return hash_value(h.first < h.first->neighbor(h.second) ? h.first - : h.first->neighbor(h.second)); - } - - bool operator==(const T2_edge_descriptor& other) const - { - if((first == other.first) && (second == other.second)) - return true; - - Face_handle fh = first->neighbor(second); - if(other.first != fh) - return false; - - int i = fh->index(first); - return (other.second == i); - } - bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); } - - Face_handle first; - int second; -}; - -// A halfedge iterator is just an edge iterator that duplicates everything twice, -// to see the edge from either side. -// Could probably be factorized with T2_edge_iterator, but it's clearer this way. -template -struct T2_halfedge_iterator -{ -private: - typedef T2_halfedge_iterator Self; - typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; - typedef T2_halfedge_descriptor Descriptor; - typedef typename Tr::Face_handle Face_handle; - -public: - typedef Descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - T2_halfedge_iterator() { } - T2_halfedge_iterator(const Finite_edges_iterator& feit) : it(feit), on_adjacent_face(false) { } - - Self& operator++() - { - // If we are on the first face, move to the opposite face. If we are already on the opposite face, - // then it's time to move on the next edge - if(on_adjacent_face) { - ++it; - on_adjacent_face = false; - } else { - on_adjacent_face = true; - } - - return *this; - } - - Self& operator--() - { - // Note that while decreasing, we start from the opposite face - if(on_adjacent_face) { - on_adjacent_face = false; - } else { - --it; - on_adjacent_face = true; - } - - return *this; - } - - Self operator++(int) { Self tmp = *this; operator++(); return tmp; } - Self operator--(int) { Self tmp = *this; operator--(); return tmp; } - - bool operator==(const Self& other) const { return it == other.it; } - bool operator!=(const Self& other) const { return !(*this == other); } - - value_type operator*() const - { - if(on_adjacent_face) { - Face_handle neigh_f = it->first->neighbor(it->second); - return value_type(neigh_f, neigh_f->index(it->first)); - } else { - return value_type(*it); - } - } - -private: - Finite_edges_iterator it; - bool on_adjacent_face; -}; - -template -struct T2_edge_iterator -{ -private: - typedef T2_edge_iterator Self; - typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; - typedef T2_edge_descriptor Descriptor; - -public: - typedef Descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - T2_edge_iterator() { } - T2_edge_iterator(const Finite_edges_iterator& feit) : it(feit) { } - - bool operator==(const Self& other) const { return it == other.it; } - bool operator!=(const Self& other) const { return !(*this == other); } - Self& operator++() { ++it; return *this; } - Self& operator--() { --it; return *this; } - Self operator++(int) { Self tmp = *this; operator++(); return tmp; } - Self operator--(int) { Self tmp = *this; operator--(); return tmp; } - value_type operator*() const { return value_type(*it); } - -private: - Finite_edges_iterator it; -}; - -template -struct T2_edge_circulator - : public Tr::Edge_circulator -{ -private: - typedef T2_edge_circulator Self; - typedef typename Tr::Edge Edge; - typedef typename Tr::Edge_circulator Base; - -public: - typedef T2_edge_descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - - T2_edge_circulator() : Base() { } - T2_edge_circulator(const Base& c, const Tr& tr) : Base(c), tr(&tr), e() { } - - // Note that the inf check is on the edge in the circulator, not on 'e', which isn't built yet - Self& operator++() { - do { this->Base::operator++(); } while(tr->is_infinite(this->Base::operator*())); - return *this; - } - Self& operator--() { - do { this->Base::operator--(); } while(tr->is_infinite(this->Base::operator*())); - return *this; - } - Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } - Self operator--(int) { Self tmp(*this); --(*this); return tmp; } - -protected: - const Tr* tr; - mutable value_type e; -}; - -template -struct In_edge_circulator - : public T2_edge_circulator -{ -private: - typedef T2_edge_circulator Base; - typedef typename Tr::Edge Edge; - typedef typename Tr::Edge_circulator Edge_circulator; - -public: - typedef T2_edge_descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - - In_edge_circulator() : Base() { } - In_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } - - const value_type& operator*() const - { - this->e = value_type(this->Base::operator*()); - return this->e; - } -}; - -template -struct Out_edge_circulator - : public T2_edge_circulator -{ -private: - typedef T2_edge_circulator Base; - typedef typename Tr::Edge Edge; - typedef typename Tr::Edge_circulator Edge_circulator; - -public: - typedef T2_edge_descriptor value_type; - typedef value_type* pointer; - typedef value_type& reference; - - Out_edge_circulator() : Base() { } - Out_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } - - const value_type& operator*() const - { - Edge ed(this->Base::operator*()); - this->e = value_type(ed.first->neighbor(ed.second), - ed.first->neighbor(ed.second)->index(ed.first)); - return this->e; - } -}; - -template -struct T2_vertex_circulator - : public In_edge_circulator -{ -private: - typedef In_edge_circulator Base; - typedef T2_edge_descriptor edge_descriptor; - typedef typename Tr::Edge_circulator Edge_circulator; - typedef typename Tr::Vertex_handle Vertex_handle; - -public: - typedef Vertex_handle value_type; - typedef value_type& reference; - - T2_vertex_circulator() : Base() { } - T2_vertex_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } - - const value_type& operator*() const - { - const edge_descriptor& edge = this->Base::operator*(); - v = edge.first->vertex(this->tr->ccw(edge.second)); - return v; - } - -private: - // Because we wrap the iterator with a Counting_iterator, which returns a ref in its operator*() - mutable Vertex_handle v; -}; - -template -struct Dereference_to_handle_enforcer - : public boost::iterator_adaptor< - Dereference_to_handle_enforcer, - Iterator /*base*/, - Handle /*value*/, - boost::use_default, - Handle /*reference*/ - > -{ -public: - typedef Handle value_type; - -private: - typedef Dereference_to_handle_enforcer Self; - typedef Iterator I; - typedef boost::iterator_adaptor Base; - -public: - Dereference_to_handle_enforcer() { } - explicit Dereference_to_handle_enforcer(const I& i) : Base(i) { } - -private: - friend class boost::iterator_core_access; - value_type dereference() const { return value_type(this->base()); } -}; - -} // namespace detail -} // namespace CGAL - -namespace std { - -#if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4099) // For VC10 it is class hash -#endif - -#ifndef CGAL_CFG_NO_STD_HASH - -template < class Tr> -struct hash > -{ - std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor& e) const - { - return hash_value(e); - } -}; - -#endif // CGAL_CFG_NO_STD_HASH - -#if defined(BOOST_MSVC) -# pragma warning(pop) -#endif - -} // namespace std - -#endif // CGAL_GRAPH_TRAITS_2D_TRIANGULATION - namespace boost { template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -417,28 +58,30 @@ struct graph_traits< CGAL_2D_TRIANGULATION > { }; typedef typename Triangulation::Vertex_handle vertex_descriptor; - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - typedef CGAL::detail::T2_edge_descriptor edge_descriptor; + typedef CGAL::internal::T2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::internal::T2_edge_descriptor edge_descriptor; typedef typename Triangulation::Face_handle face_descriptor; // We need to go from 'Finite_vertex_iterator' to 'Vertex_handle' (and even more // in the case of RT2, since it has also a hidden filter) - typedef CGAL::detail::Dereference_to_handle_enforcer< + typedef CGAL::internal::Dereference_to_handle_enforcer< Triangulation, typename Triangulation::Finite_vertices_iterator, vertex_descriptor> vertex_iterator; - typedef CGAL::detail::Dereference_to_handle_enforcer< + typedef CGAL::internal::Dereference_to_handle_enforcer< Triangulation, typename Triangulation::Finite_faces_iterator, face_descriptor> face_iterator; - typedef CGAL::detail::T2_halfedge_iterator halfedge_iterator; - typedef CGAL::detail::T2_edge_iterator edge_iterator; + typedef CGAL::internal::T2_halfedge_iterator halfedge_iterator; + typedef CGAL::internal::T2_edge_iterator edge_iterator; - typedef CGAL::detail::T2_vertex_circulator Vertex_circulator; + typedef CGAL::internal::T2_vertex_circulator Vertex_circulator; typedef CGAL::Counting_iterator adjacency_iterator; - typedef CGAL::detail::In_edge_circulator In_edge_circ; + typedef CGAL::internal::In_edge_circulator In_edge_circ; typedef CGAL::Counting_iterator in_edge_iterator; - typedef CGAL::detail::Out_edge_circulator Out_edge_circ; + typedef CGAL::internal::Out_edge_circulator Out_edge_circ; typedef CGAL::Counting_iterator out_edge_iterator; typedef undirected_tag directed_category; @@ -757,7 +400,7 @@ inline Iterator_range::in_ in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) { - typedef CGAL::detail::In_edge_circulator< CGAL_2D_TRIANGULATION > Circ; + typedef CGAL::internal::In_edge_circulator< CGAL_2D_TRIANGULATION > Circ; typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator Iter; typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); @@ -771,7 +414,7 @@ inline Iterator_range::out out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) { - typedef CGAL::detail::Out_edge_circulator< CGAL_2D_TRIANGULATION > Circ; + typedef CGAL::internal::Out_edge_circulator< CGAL_2D_TRIANGULATION > Circ; typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter; typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); @@ -785,7 +428,7 @@ inline Iterator_range::adj adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, const CGAL_2D_TRIANGULATION& g) { - typedef CGAL::detail::T2_vertex_circulator< CGAL_2D_TRIANGULATION > Circ; + typedef CGAL::internal::T2_vertex_circulator< CGAL_2D_TRIANGULATION > Circ; typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter; typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h new file mode 100644 index 00000000000..ec2c625735f --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h @@ -0,0 +1,445 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#include +#include +#include + +#include +#include +#include + +#include + +#ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS +#define CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS + +namespace CGAL { +namespace internal { + +// A triangulation edge is a face handle + an int, and is thus actually a halfedge... +template +struct T2_halfedge_descriptor + : public Tr::Edge +{ + typedef typename Tr::Edge Base; + typedef typename Tr::Face_handle Face_handle; + + T2_halfedge_descriptor() {} + T2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { } + explicit T2_halfedge_descriptor(const Base& e) : Base(e) { } + T2_halfedge_descriptor(const T2_halfedge_descriptor& h) : Base(h) { } + + const Base& base() const { return static_cast(*this); } + + T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h) + { + this->first = h.first; + this->second = h.second; + return *this; + } + + friend std::size_t hash_value(const T2_halfedge_descriptor& e) { + return hash_value(e.first); + } + + bool operator==(const T2_halfedge_descriptor& other) const { + return (this->first == other.first) && (this->second == other.second); + } + bool operator!=(const T2_halfedge_descriptor& other) const { + return (this->first != other.first) || (this->second != other.second); + } + + bool operator<(const T2_halfedge_descriptor& other) const + { + if(this->first < other.first) return true; + if(this->first > other.first) return false; + return this->second < other.second; + } +}; + +// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge +template +struct T2_edge_descriptor +{ + typedef typename Tr::Face_handle Face_handle; + + T2_edge_descriptor() : first(), second(0) { } + explicit T2_edge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { } + T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { } + + // so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle + operator std::pair() { return std::make_pair(first, second); } + + friend std::size_t hash_value(const T2_edge_descriptor& h) + { + if(h.first == Face_handle()) + return 0; + + return hash_value(h.first < h.first->neighbor(h.second) ? h.first + : h.first->neighbor(h.second)); + } + + bool operator==(const T2_edge_descriptor& other) const + { + if((first == other.first) && (second == other.second)) + return true; + + Face_handle fh = first->neighbor(second); + if(other.first != fh) + return false; + + int i = fh->index(first); + return (other.second == i); + } + bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); } + + Face_handle first; + int second; +}; + +// A halfedge iterator is just an edge iterator that duplicates everything twice, +// to see the edge from either side. +// Could probably be factorized with T2_edge_iterator, but it's clearer this way. +template +struct T2_halfedge_iterator +{ +private: + typedef T2_halfedge_iterator Self; + typedef EdgeIterator Edge_iterator; + typedef T2_halfedge_descriptor Descriptor; + typedef typename Tr::Face_handle Face_handle; + +public: + typedef Descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + T2_halfedge_iterator() { } + T2_halfedge_iterator(const Edge_iterator& feit) : it(feit), on_adjacent_face(false) { } + + Self& operator++() + { + // If we are on the first face, move to the opposite face. If we are already on the opposite face, + // then it's time to move on the next edge + if(on_adjacent_face) { + ++it; + on_adjacent_face = false; + } else { + on_adjacent_face = true; + } + + return *this; + } + + Self& operator--() + { + // Note that while decreasing, we start from the opposite face + if(on_adjacent_face) { + on_adjacent_face = false; + } else { + --it; + on_adjacent_face = true; + } + + return *this; + } + + Self operator++(int) { Self tmp = *this; operator++(); return tmp; } + Self operator--(int) { Self tmp = *this; operator--(); return tmp; } + + bool operator==(const Self& other) const { return it == other.it; } + bool operator!=(const Self& other) const { return !(*this == other); } + + value_type operator*() const + { + if(on_adjacent_face) { + Face_handle neigh_f = it->first->neighbor(it->second); + return value_type(neigh_f, neigh_f->index(it->first)); + } else { + return value_type(*it); + } + } + +private: + Edge_iterator it; + bool on_adjacent_face; +}; + +template +struct T2_edge_iterator +{ +private: + typedef T2_edge_iterator Self; + typedef EdgeIterator Edge_iterator; + typedef T2_edge_descriptor Descriptor; + +public: + typedef Descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + T2_edge_iterator() { } + T2_edge_iterator(const Edge_iterator& feit) : it(feit) { } + + bool operator==(const Self& other) const { return it == other.it; } + bool operator!=(const Self& other) const { return !(*this == other); } + Self& operator++() { ++it; return *this; } + Self& operator--() { --it; return *this; } + Self operator++(int) { Self tmp = *this; operator++(); return tmp; } + Self operator--(int) { Self tmp = *this; operator--(); return tmp; } + value_type operator*() const { return value_type(*it); } + +private: + Edge_iterator it; +}; + +// Must distinguish TDS and triangulations circulators (later are filtered) +template +class TDS2_Out_edge_circulator + : public Circ +{ +private: + mutable E e; + +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + + TDS2_Out_edge_circulator() : Circ() {} + TDS2_Out_edge_circulator(Circ c) : Circ(c) {} + + const E& operator*() const + { + E ed = static_cast(this)->operator*(); + e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); + return e; + } +}; + +template +class TDS2_In_edge_circulator + : public Circ +{ +private: + mutable E e; + +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + + TDS2_In_edge_circulator() : Circ() {} + TDS2_In_edge_circulator(Circ c) : Circ(c) {} + + const E& operator*() const + { + typename Circ::value_type ed = static_cast(this)->operator*(); + e = E(ed); + return e; + } +}; + +template +struct T2_edge_circulator + : public Tr::Edge_circulator +{ +private: + typedef T2_edge_circulator Self; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Base; + +public: + typedef T2_edge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + + T2_edge_circulator() : Base() { } + T2_edge_circulator(const Base& c, const Tr& tr) : Base(c), tr(&tr), e() { } + + // Note that the inf check is on the edge in the circulator, not on 'e', which isn't built yet + Self& operator++() { + do { this->Base::operator++(); } while(tr->is_infinite(this->Base::operator*())); + return *this; + } + Self& operator--() { + do { this->Base::operator--(); } while(tr->is_infinite(this->Base::operator*())); + return *this; + } + Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } + Self operator--(int) { Self tmp(*this); --(*this); return tmp; } + +protected: + const Tr* tr; + mutable value_type e; +}; + +template +struct In_edge_circulator + : public T2_edge_circulator +{ +private: + typedef T2_edge_circulator Base; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Edge_circulator; + +public: + typedef T2_edge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + + In_edge_circulator() : Base() { } + In_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } + + const value_type& operator*() const + { + this->e = value_type(this->Base::operator*()); + return this->e; + } +}; + +template +struct Out_edge_circulator + : public T2_edge_circulator +{ +private: + typedef T2_edge_circulator Base; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Edge_circulator; + +public: + typedef T2_edge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + + Out_edge_circulator() : Base() { } + Out_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } + + const value_type& operator*() const + { + Edge ed(this->Base::operator*()); + this->e = value_type(ed.first->neighbor(ed.second), + ed.first->neighbor(ed.second)->index(ed.first)); + return this->e; + } +}; + +template +struct T2_vertex_circulator + : public In_edge_circulator +{ +private: + typedef In_edge_circulator Base; + typedef T2_edge_descriptor edge_descriptor; + typedef typename Tr::Edge_circulator Edge_circulator; + typedef typename Tr::Vertex_handle Vertex_handle; + +public: + typedef Vertex_handle value_type; + typedef value_type& reference; + + T2_vertex_circulator() : Base() { } + T2_vertex_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { } + + const value_type& operator*() const + { + const edge_descriptor& edge = this->Base::operator*(); + v = edge.first->vertex(this->tr->ccw(edge.second)); + return v; + } + +private: + // Because we wrap the iterator with a Counting_iterator, which returns a ref in its operator*() + mutable Vertex_handle v; +}; + +template +struct Dereference_to_handle_enforcer + : public boost::iterator_adaptor< + Dereference_to_handle_enforcer, + Iterator /*base*/, + Handle /*value*/, + boost::use_default, + Handle /*reference*/ + > +{ +public: + typedef Handle value_type; + +private: + typedef Dereference_to_handle_enforcer Self; + typedef Iterator I; + typedef boost::iterator_adaptor Base; + +public: + Dereference_to_handle_enforcer() { } + explicit Dereference_to_handle_enforcer(const I& i) : Base(i) { } + +private: + friend class boost::iterator_core_access; + value_type dereference() const { return value_type(this->base()); } +}; + +} // namespace internal +} // namespace CGAL + +namespace std { + +// workaround a bug detected on at least g++ 4.4 where boost::next(Iterator) +// is picked as a candidate for next(h,g) +template +struct iterator_traits< CGAL::internal::T2_halfedge_descriptor > +{ + typedef void* iterator_category; + typedef void* difference_type; + typedef void* value_type; + typedef void* reference; +}; + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4099) // For VC10 it is class hash +#endif + +#ifndef CGAL_CFG_NO_STD_HASH + +template < class Tr> +struct hash > +{ + std::size_t operator()(const CGAL::internal::T2_halfedge_descriptor& e) const { + return hash_value(e); + } +}; + +#endif // CGAL_CFG_NO_STD_HASH + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +} // namespace std + +#endif // CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h index 945d56f157d..c81e606973f 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h @@ -35,7 +35,7 @@ #define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H namespace CGAL { -namespace detail { +namespace internal { template struct T2_halfedge_descriptor; @@ -113,9 +113,9 @@ public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; - typedef CGAL::detail::T2_halfedge_descriptor key_type; + typedef CGAL::internal::T2_halfedge_descriptor key_type; - typedef typename Tr::Face_handle face_descriptor; + typedef typename Tr::Face_handle Face_handle; T2_halfedge_id_map(const Tr& tr) : tr(tr) { } @@ -123,8 +123,8 @@ public: // h.first is such that h.first < opposite(h).first --> different ids value_type operator[](key_type h) const { - const face_descriptor f1 = h.first; - const face_descriptor f2 = f1->neighbor(h.second); + const Face_handle f1 = h.first; + const Face_handle f2 = f1->neighbor(h.second); CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); if(tr.is_infinite(f1)) @@ -149,15 +149,15 @@ public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; - typedef CGAL::detail::T2_edge_descriptor key_type; - typedef typename Tr::Face_handle face_descriptor; + typedef CGAL::internal::T2_edge_descriptor key_type; + typedef typename Tr::Face_handle Face_handle; T2_edge_id_map(const Tr& tr) : tr(tr) { } value_type operator[](key_type e) const { - const face_descriptor f1 = e.first; - const face_descriptor f2 = f1->neighbor(e.second); + const Face_handle f1 = e.first; + const Face_handle f2 = f1->neighbor(e.second); CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); if(tr.is_infinite(f1)) @@ -201,47 +201,46 @@ struct T2_property_map { }; template struct T2_property_map { - typedef detail::T2_vertex_point_map type; - typedef detail::T2_vertex_point_map const_type; + typedef internal::T2_vertex_point_map type; + typedef internal::T2_vertex_point_map const_type; }; template struct T2_property_map { - typedef detail::T2_edge_weight_map type; - typedef detail::T2_edge_weight_map const_type; + typedef internal::T2_edge_weight_map type; + typedef internal::T2_edge_weight_map const_type; }; template struct T2_property_map { - typedef detail::T2_vertex_id_map type; - typedef detail::T2_vertex_id_map const_type; + typedef internal::T2_vertex_id_map type; + typedef internal::T2_vertex_id_map const_type; }; template struct T2_property_map { - typedef detail::T2_halfedge_id_map type; - typedef detail::T2_halfedge_id_map const_type; + typedef internal::T2_halfedge_id_map type; + typedef internal::T2_halfedge_id_map const_type; }; template struct T2_property_map { - typedef detail::T2_edge_id_map type; - typedef detail::T2_edge_id_map const_type; + typedef internal::T2_edge_id_map type; + typedef internal::T2_edge_id_map const_type; }; template struct T2_property_map { - typedef detail::T2_face_id_map type; - typedef detail::T2_face_id_map const_type; + typedef internal::T2_face_id_map type; + typedef internal::T2_face_id_map const_type; }; -} // end namespace detail - +} // end namespace internal } // CGAL #endif // CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H @@ -253,7 +252,7 @@ namespace boost { template struct property_map { - typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename CGAL::internal::T2_property_map map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; @@ -262,7 +261,7 @@ struct property_map template struct property_map { - typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename CGAL::internal::T2_property_map map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; @@ -313,50 +312,50 @@ struct graph_has_property // property maps template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > +inline internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION > get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&) { - detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; + internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > +inline internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION > get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > +inline internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION > get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > +inline internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > +inline internal::T2_edge_id_map< CGAL_2D_TRIANGULATION > get(boost::edge_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > -inline detail::T2_face_id_map< CGAL_2D_TRIANGULATION > +inline internal::T2_face_id_map< CGAL_2D_TRIANGULATION > get(boost::face_index_t, const CGAL_2D_TRIANGULATION& g) { - detail::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h new file mode 100644 index 00000000000..a2cb3d1411c --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h @@ -0,0 +1,354 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H +#define CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H + +#include +#include +#include + +#include + +#include + +namespace CGAL { +namespace internal { + +// property maps +template +class TDS2_vertex_point_map +{ +public: + typedef boost::lvalue_property_map_tag category; + typedef typename VB::Point value_type; + typedef value_type& reference; + typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; + + friend reference get(TDS2_vertex_point_map, key_type vh) { return vh->point(); } + friend void put(TDS2_vertex_point_map, key_type vh, reference v) { vh->point() = v; } + reference operator[](key_type vh) const { return vh->point(); } +}; + +template +class TDS2_edge_weight_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef typename VB::FT value_type; + typedef value_type reference; + typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; + + TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2& tds_) : tds(tds_) { } + + value_type operator[](key_type e) const { return approximate_sqrt(tds.segment(e).squared_length()); } + +private: + const CGAL::Triangulation_data_structure_2& tds; +}; + +template +class TDS2_vertex_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; + + TDS2_vertex_id_map() {} + + long operator[](key_type vh) const { return vh->id(); } +}; + +template +class TDS2_halfedge_id_map + : public boost::put_get_helper > +{ + typedef typename CGAL::Triangulation_data_structure_2 TDS; + +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef CGAL::internal::T2_halfedge_descriptor key_type; + + typedef typename TDS::Face_handle face_descriptor; + + TDS2_halfedge_id_map() { } + + // Halfedge id is twice the edge id, and +0/+1 depending whether + // h.first is such that h.first < opposite(h).first --> different ids + value_type operator[](key_type h) const + { + const face_descriptor f1 = h.first; + const face_descriptor f2 = f1->neighbor(h.second); + + if(f1->id() < f2->id()) + return 2*(3 * f1->id() + h.second); + else + return 2*(3 * f2->id() + f2->index(f1)) + 1; + } +}; + +template +class TDS2_edge_id_map + : public boost::put_get_helper > +{ + typedef typename CGAL::Triangulation_data_structure_2 TDS; + +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef CGAL::internal::T2_edge_descriptor key_type; + + typedef typename TDS::Face_handle Face_handle; + + TDS2_edge_id_map() {} + + value_type operator[](key_type h) const + { + const Face_handle f1 = h.first; + const Face_handle f2 = f1->neighbor(h.second); + + if(f1->id() < f2->id()) + return 3 * f1->id() + h.second; + else + return 3 * f2->id() + f2->index(f1); + } +}; + +template +class TDS2_face_id_map + : public boost::put_get_helper > +{ + typedef typename CGAL::Triangulation_data_structure_2 TDS; + +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename TDS::Face_handle key_type; + + TDS2_face_id_map() { } + + value_type operator[](key_type f) const { return f->id(); } +}; + +template +struct TDS2_property_map { }; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_point_map type; + typedef internal::TDS2_vertex_point_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_edge_weight_map type; + typedef internal::TDS2_edge_weight_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_id_map type; + typedef internal::TDS2_vertex_id_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_id_map type; + typedef internal::TDS2_vertex_id_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_edge_id_map type; + typedef internal::TDS2_edge_id_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_id_map type; + typedef internal::TDS2_vertex_id_map const_type; +}; + +} // end namespace internal + +template +struct graph_has_property, boost::vertex_point_t> + : CGAL::Tag_true{}; +template +struct graph_has_property, boost::edge_weight_t> + : CGAL::Tag_true{}; + +template +struct graph_has_property, boost::vertex_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Vertex + >::value + > +{}; +template +struct graph_has_property, boost::halfedge_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Face + >::value + > +{}; +template +struct graph_has_property, boost::edge_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Face + >::value + > +{}; +template +struct graph_has_property, boost::face_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Face + >::value + > +{}; + +template +inline internal::TDS2_vertex_point_map +get(boost::vertex_point_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_vertex_point_map m; + return m; +} + +template +inline internal::TDS2_edge_weight_map +get(boost::edge_weight_t, const Triangulation_data_structure_2& g) +{ + internal::TDS2_edge_weight_map m(g); + return m; +} + +template +inline internal::TDS2_vertex_id_map +get(boost::vertex_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_vertex_id_map m; + return m; +} + +template +inline internal::TDS2_halfedge_id_map +get(boost::halfedge_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_halfedge_id_map m; + return m; +} + +template +inline internal::TDS2_edge_id_map +get(boost::edge_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_edge_id_map m; + return m; +} + +template +inline internal::TDS2_face_id_map +get(boost::face_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_face_id_map m; + return m; +} + +} // namespace CGAL + +namespace boost { + +// g++ 'enumeral_type' in template unification not implemented workaround +template +struct property_map, Tag> +{ + typedef typename CGAL::internal::TDS2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +// see struct property_map in Polyehdron for an explanation +template +struct property_map, Tag> +{ + typedef typename CGAL::internal::TDS2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +} // namespace boost + +namespace CGAL { + +template +inline +typename boost::property_traits< +typename boost::property_map,PropertyTag>::const_type>::value_type +get(PropertyTag p, const Triangulation_data_structure_2& g, const Key& key) +{ + return get(get(p, g), key); +} + +template +inline void +put(PropertyTag p, Triangulation_data_structure_2& g, + const Key& key, const Value& value) +{ + typedef typename boost::property_map, PropertyTag>::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} + +} // namespace CGAL + +namespace boost { + +// What are those needed for ??? +template +struct edge_property_type > { + typedef void type; +}; + +template +struct vertex_property_type > { + typedef void type; +}; + +} // namespace boost + +#endif /* CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H */ From 7bfb434d6f54b3941b82756c7cc8ad0b1dcfdfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 13:23:17 +0200 Subject: [PATCH 25/68] Misc minor fixes for PMP::locate --- .../CGAL/Polygon_mesh_processing/locate.h | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 676bd9a6f15..c7600bfd67b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -74,14 +74,8 @@ struct Locate_types halfedge_descriptor, face_descriptor> descriptor_variant; - typedef typename std::conditional< - std::is_same< - NamedParameters, Default>::value, - typename boost::property_map::const_type, - typename GetVertexPointMap::const_type - >::type VPM; + typedef typename GetVertexPointMap::const_type VPM; typedef typename boost::property_traits::value_type Point; typedef typename CGAL::Kernel_traits::type Kernel; @@ -263,6 +257,7 @@ struct Barycentric_coordinate_calculator // 2D version FT d21 = csp2(v2, v1); FT denom = d00 * d11 - d01 * d01; + CGAL_assertion((d00 * d11 - d01 * d01) != FT(0)); // denom != 0. FT v = (d11 * d20 - d01 * d21) / denom; FT w = (d00 * d21 - d01 * d20) / denom; @@ -445,7 +440,11 @@ int vertex_index_in_face(const typename boost::graph_traits::vertex } while(current != start); - CGAL_postcondition(counter == 0 || current != start); + if(counter != 0 && current == start) + { + CGAL_assertion_msg(false, "Could not find vertex in face"); + return -1; + } return counter; } @@ -1017,7 +1016,7 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); } -/// \brief Returns the location of the given vertex as a `Face_location` in `fd`, +/// \brief Returns the location of a given vertex as a `Face_location` in `fd`, /// that is an ordered pair composed of `fd` and of the barycentric coordinates /// of the vertex in `fd`. /// @@ -1537,7 +1536,7 @@ void build_AABB_tree(const TriangleMesh& tm, /// \name Nearest Face Location Queries /// @{ -/// \brief Creates an `AABB_tree` suitable for use with `locate_with_AABB_tree()`. +/// \brief creates an `AABB_tree` suitable for use with `locate_with_AABB_tree()`. /// /// \details This function should be called to create and cache an AABB tree /// to avoid the AABB tree being rebuilt at every call of `locate_with_AABB_tree()`. @@ -1578,7 +1577,7 @@ void build_AABB_tree(const TriangleMesh& tm, return build_AABB_tree(tm, outTree, parameters::all_default()); } -/// \brief Returns the face location nearest to the given point, as a `Face_location`. +/// \brief returns the face location nearest to the given point, as a `Face_location`. /// /// \tparam TriangleMesh A model of `FaceListGraph` /// \tparam AABBTraits A model of `AABBTraits` used to define a \cgal `AABB_tree`. @@ -1634,7 +1633,7 @@ locate_with_AABB_tree(const typename internal::Locate_types::Point return locate_with_AABB_tree(p, tree, tm, parameters::all_default()); } -/// \brief Returns the nearest face location to the given point. +/// \brief returns the nearest face location to the given point. /// /// \details Note that this function will build an `AABB_tree` on each call. If you need /// to call this function more than once, use `build_AABB_tree()` to cache a From 99df60329ff0b57488d8a14383c72cc036e408de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 15:12:18 +0200 Subject: [PATCH 26/68] Change BGL T2 graph traits doc to indicate that only finite simplices are used --- BGL/doc/BGL/BGL.txt | 12 +++--------- BGL/doc/BGL/PackageDescription.txt | 7 ++++++- BGL/doc/BGL/graph_traits.txt | 27 +++++++++++++-------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index 70a4f1dad54..23c63b9f37d 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -254,15 +254,9 @@ The main function illustrates the access to the `id()` field. \section BGLTriangulations Triangulations as Models of the Boost Graph Concept Triangulations have vertices and faces, allowing for a direct translation -as a graph. An edge is defined as a pair of a face handle and the -index of the edge. -Particular care has to be taken with the infinite vertex and its incident -edges. One can either use a -boost::filtered_graph -in order to make the infinite edges -invisible, or one can have a property map that returns an infinite length -for these edges. -A complete list can be found in the documentation of \link BGLT2GT boost::graph_traits \endlink. +as a graph. A halfedge is defined as a pair of a face handle and the +index of the edge. A complete list can be found in the documentation +of \link BGLT2GT boost::graph_traits \endlink. A classical example for an algorithm that is a combination of computational geometry and graph theory is the Euclidean Minimum diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 7e0cccf4ad0..287b2662399 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -546,7 +546,12 @@ Methods to read and write graphs. \cgalPkgPicture{emst-detail.png} \cgalPkgSummaryBegin \cgalPkgAuthors{Andreas Fabri, Fernando Cacciola, Philipp Moeller, and Ron Wein} -\cgalPkgDesc{This package provides a framework for interfacing \cgal data structures with the algorithms of the Boost Graph Library, or \sc{BGL} for short. It allows to run graph algorithms directly on \cgal data structures which are model of the \sc{BGL} graph concepts, for example the shortest path algorithm on a Delaunay triangulation in order to compute the Euclidean minimum spanning tree. Furthermore, it introduces several new graph concepts describing halfedge data structures.} +\cgalPkgDesc{This package provides a framework for interfacing \cgal data structures + with the algorithms of the Boost Graph Library, or \sc{BGL} for short. + It allows to run graph algorithms directly on \cgal data structures which are model + of the \sc{BGL} graph concepts, for example the shortest path algorithm + on a Delaunay triangulation in order to compute the Euclidean minimum spanning tree. + Furthermore, it introduces several new graph concepts describing halfedge data structures.} \cgalPkgManuals{Chapter_CGAL_and_the_Boost_Graph_Library,PkgBGLRef} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin diff --git a/BGL/doc/BGL/graph_traits.txt b/BGL/doc/BGL/graph_traits.txt index b16313ed534..437047ab040 100644 --- a/BGL/doc/BGL/graph_traits.txt +++ b/BGL/doc/BGL/graph_traits.txt @@ -150,30 +150,29 @@ and `CGAL::Triangulation_hierarchy_2` so that they are model of the graph concepts `BidirectionalGraph`, `VertexAndEdgeListGraph`, and `FaceListGraph`. -The mapping between vertices and edges of the triangulation and the +Only finite simplices exist when viewed through the scope of these graph traits classes. +The infinite vertex, halfedges, edges, and faces will thus not appear when looping around a border +vertex, or walking through the faces container. + +The mapping between vertices, edges, and faces of the triangulation and the graph is rather straightforward, but there are some subtleties. The value type of the \sc{Bgl} iterators is the vertex or edge descriptor, whereas in \cgal all iterators and circulators are also handles and hence have as value type Vertex or Edge. -The graph traits class for triangulations does not distinguish between -finite and infinite vertices and edges. As the edge weight computed -with the default property map of \sc{Bgl} algorithms (obtained with -`get(t, boost::edge_weight)`) is the length of the edge, -the edge weight is not well defined for infinite edges. For algorithms -that make use of the edge weight, the user must therefore -define a `boost::filtered_graph` or pass a property map to the -algorithm that returns "infinity" for infinite edges. - | Member | Value | Description | | :----------------------- | :----: | :---------- | -| `vertex_descriptor` | `Triangulation::Vertex_handle` | Identify vertices in the graph. | -| `edge_descriptor` | `unspecified_type` | Identify edges in the graph. It is constructible from and convertible to `Triangulation::Edge`. It is not a simple typedef, but a proper class, because in an undirected graph the edges `(u,v)` and `(v,u)` must be equal. This is not the case for the Edge type of the triangulation. | +| `vertex_descriptor` | `unspecified_type` | Identify vertices in the graph. | +| `halfedge_descriptor` | `unspecified_type` | Identify halfedges in the graph. It is constructible from and convertible to `Triangulation::Edge`. It is not a simple typedef, but a proper class, because there is no representation for halfedges in the 2D triangulation data structure. | +| `edge_descriptor` | `unspecified_type` | Identify edges in the graph. It is constructible from and convertible to `Triangulation::Edge`. It is not a simple typedef, but a proper class, because in an undirected graph the edges `(u,v)` and `(v,u)` must be equal. This is not the case for the Edge type of the triangulation. | +| `face_descriptor` | `unspecified_type` | Identify faces in the graph. | | `adjacency_iterator` | `unspecified_type` | An iterator to traverse through the vertices adjacent to a vertex. Its value type is `vertex_descriptor`. | | `out_edge_iterator` | `unspecified_type` | An iterator to traverse through the outgoing edges incident to a vertex. Its value type is `edge_descriptor`. | | `in_edge_iterator` | `unspecified_type` | An iterator to traverse through the incoming edges incident to a vertex. Its value type is `edge_descriptor`. | -| `vertex_iterator` | `unspecified_type` | An iterator to traverse through the vertices of the graph. Its value type is `vertex_descriptor`. | -| `edge_iterator` | `unspecified_type` | An iterator to traverse through the edges of the graph. Its value type is `edge_descriptor`. | +| `vertex_iterator` | `unspecified_type` | An iterator to traverse through the vertices of the graph. Its value type is `vertex_descriptor`. | +| `halfedge_iterator` | `unspecified_type` | An iterator to traverse through the halfedges of the graph. Its value type is `halfedge_descriptor`. | +| `edge_iterator` | `unspecified_type` | An iterator to traverse through the edges of the graph. Its value type is `edge_descriptor`. | +| `face_iterator` | `unspecified_type` | An iterator to traverse through the faces of the graph. Its value type is `face_descriptor`. | | `directed_category` | `boost::undirected_tag` | This graph is not directed. | | `edge_parallel_category` | `boost::disallow_parallel_edge_tag` | This graph does not support multiedges. | | `traversal_category` | Inherits from `boost::bidirectional_graph_tag`, `boost::adjacency_graph_tag`, `boost::vertex_list_graph_tag`, and `boost::edge_list_graph_tag` | The ways in which the vertices in the graph can be traversed.. | From a03701d2b7784bf1657a82a8b1b37d49cf9b119b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 15:44:51 +0200 Subject: [PATCH 27/68] Fix key type in generic 2D triangulation BGL properties --- .../CGAL/boost/graph/internal/properties_2D_triangulation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h index c81e606973f..1c912a22243 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h @@ -75,7 +75,7 @@ public: typedef boost::readable_property_map_tag category; typedef typename Tr::Geom_traits::FT value_type; typedef value_type reference; - typedef typename Tr::Edge key_type; + typedef CGAL::internal::T2_edge_descriptor key_type; T2_edge_weight_map(const Tr& tr_) : tr(tr_) { } From ab092afe57703c62794cfa92213792d5fa6fbd7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 15:45:22 +0200 Subject: [PATCH 28/68] Include 2D triangulation BGL properties from BGL graph traits header for convenience --- .../graph/graph_traits_Constrained_Delaunay_triangulation_2.h | 1 + .../CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h | 1 + .../boost/graph/graph_traits_Constrained_triangulation_plus_2.h | 1 + .../CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h | 1 + .../CGAL/boost/graph/graph_traits_Regular_triangulation_2.h | 1 + .../include/CGAL/boost/graph/graph_traits_Triangulation_2.h | 1 + .../boost/graph/graph_traits_Triangulation_data_structure_2.h | 1 + .../CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h | 1 + 8 files changed, 8 insertions(+) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h index 54a28e1e6d7..da2bd0c34f6 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h index 466fd331d87..9939ac33457 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h index d72f3d16053..1bed68fbf9c 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h index a35a19e7aac..2d8f16c6990 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h index d06bce18423..821a2af153f 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Regular_triangulation_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Regular_triangulation_2 object as a boost graph "as is". No diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h index 63910c65184..8889bbf55e0 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_TRIANGULATION_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Triangulation_2 object as a boost graph "as is". No diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h index 123d3502a6c..28de1f8cc58 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h @@ -26,6 +26,7 @@ // include this to avoid a VC15 warning #include #include +#include #include #include diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h index 189f007e58b..246a0ce5e58 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h @@ -22,6 +22,7 @@ #define CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H #include +#include // The functions and classes in this file allows the user to // treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No From e614fc43e13582843efc75fa554cb82722e28150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 15:47:43 +0200 Subject: [PATCH 29/68] Simplify/Clean all BGL T2 examples (can now get rid of Finite_filter stuff) --- BGL/examples/BGL_triangulation_2/dijkstra.cpp | 107 +++++--------- .../dijkstra_with_internal_properties.cpp | 86 ++++------- BGL/examples/BGL_triangulation_2/emst.cpp | 101 +++++-------- .../emst_cdt_plus_hierarchy.cpp | 116 ++++++--------- .../BGL_triangulation_2/emst_regular.cpp | 99 +++++-------- .../BGL_triangulation_2/face_graph.cpp | 138 +++++++----------- 6 files changed, 232 insertions(+), 415 deletions(-) diff --git a/BGL/examples/BGL_triangulation_2/dijkstra.cpp b/BGL/examples/BGL_triangulation_2/dijkstra.cpp index 82e0393bbf8..3a1b061eb9e 100644 --- a/BGL/examples/BGL_triangulation_2/dijkstra.cpp +++ b/BGL/examples/BGL_triangulation_2/dijkstra.cpp @@ -1,103 +1,70 @@ #include -#include -#include +#include #include -#include + #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_2 Point; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_2 Point; -typedef CGAL::Triangulation_2 Triangulation; +typedef CGAL::Triangulation_2 Triangulation; -// As we want to run Dijskra's shortest path algorithm we only -// consider finite vertices and edges. +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; -template -struct Is_finite { +typedef std::map VertexIndexMap; +typedef boost::associative_property_map VertexIdPropertyMap; - const T* t_; - - Is_finite() - : t_(NULL) - {} - - Is_finite(const T& t) - : t_(&t) - { } - - template - bool operator()(const VertexOrEdge& voe) const { - return ! t_->is_infinite(voe); - } -}; - -typedef Is_finite Filter; -typedef boost::filtered_graph Finite_triangulation; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; - -typedef std::map VertexIndexMap; -VertexIndexMap vertex_id_map; - -typedef boost::associative_property_map VertexIdPropertyMap; -VertexIdPropertyMap vertex_index_pmap(vertex_id_map); - -int -main(int argc,char* argv[]) +int main(int argc,char* argv[]) { const char* filename = (argc > 1) ? argv[1] : "data/points.xy"; std::ifstream input(filename); - Triangulation t; - Filter is_finite(t); - Finite_triangulation ft(t, is_finite, is_finite); + Triangulation tr; Point p ; - while(input >> p){ - t.insert(p); - } + while(input >> p) + tr.insert(p); vertex_iterator vit, ve; + // Associate indices to the vertices + VertexIndexMap vertex_id_map; + VertexIdPropertyMap vertex_index_pmap(vertex_id_map); int index = 0; - // boost::tie assigns the first and second element of the std::pair - // returned by boost::vertices to the variables vit and ve - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; - vertex_id_map[vd]= index++; - } + + for(vertex_descriptor vd : vertices(tr)) + vertex_id_map[vd] = index++; // Dijkstra's shortest path needs property maps for the predecessor and distance // We first declare a vector - std::vector predecessor(boost::num_vertices(ft)); - // and then turn it into a property map - boost::iterator_property_map::iterator, - VertexIdPropertyMap> - predecessor_pmap(predecessor.begin(), vertex_index_pmap); + std::vector predecessor(num_vertices(tr)); - std::vector distance(boost::num_vertices(ft)); - boost::iterator_property_map::iterator, - VertexIdPropertyMap> + // and then turn it into a property map + boost::iterator_property_map::iterator, VertexIdPropertyMap> + predecessor_pmap(predecessor.begin(), vertex_index_pmap); + + std::vector distance(num_vertices(tr)); + boost::iterator_property_map::iterator, VertexIdPropertyMap> distance_pmap(distance.begin(), vertex_index_pmap); // start at an arbitrary vertex - vertex_descriptor source = *boost::vertices(ft).first; + vertex_descriptor source = *vertices(tr).first; std::cout << "\nStart dijkstra_shortest_paths at " << source->point() <<"\n"; - boost::dijkstra_shortest_paths(ft, source, - distance_map(distance_pmap) - .predecessor_map(predecessor_pmap) - .vertex_index_map(vertex_index_pmap)); + boost::dijkstra_shortest_paths(tr, source, + distance_map(distance_pmap) + .predecessor_map(predecessor_pmap) + .vertex_index_map(vertex_index_pmap)); - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; + for(vertex_descriptor vd : vertices(tr)) + { std::cout << vd->point() << " [" << vertex_id_map[vd] << "] "; - std::cout << " has distance = " << boost::get(distance_pmap,vd) - << " and predecessor "; - vd = boost::get(predecessor_pmap,vd); + std::cout << " has distance = " << boost::get(distance_pmap,vd) + << " and predecessor "; + vd = boost::get(predecessor_pmap,vd); std::cout << vd->point() << " [" << vertex_id_map[vd] << "]\n "; } - return 0; + return EXIT_SUCCESS; } diff --git a/BGL/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp b/BGL/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp index 9b26686d725..b1bc089d216 100644 --- a/BGL/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp +++ b/BGL/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp @@ -1,94 +1,66 @@ #include + #include #include -#include +#include #include -#include + #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_2 Point; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_2 Point; -typedef CGAL::Triangulation_vertex_base_with_id_2 Tvb; -typedef CGAL::Triangulation_face_base_2 Tfb; -typedef CGAL::Triangulation_data_structure_2 Tds; -typedef CGAL::Delaunay_triangulation_2 Triangulation; +typedef CGAL::Triangulation_vertex_base_with_id_2 Tvb; +typedef CGAL::Triangulation_face_base_2 Tfb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Delaunay_triangulation_2 Triangulation; -// consider finite vertices and edges. +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; -template -struct Is_finite { +typedef boost::property_map::type VertexIdPropertyMap; - const T* t_; - - Is_finite() - : t_(NULL) - {} - - Is_finite(const T& t) - : t_(&t) - { } - - template - bool operator()(const VertexOrEdge& voe) const { - return ! t_->is_infinite(voe); - } -}; - -typedef Is_finite Filter; -typedef boost::filtered_graph Finite_triangulation; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; - - -int -main(int argc,char* argv[]) +int main(int argc,char* argv[]) { const char* filename = (argc > 1) ? argv[1] : "data/points.xy"; std::ifstream input(filename); - Triangulation t; - Filter is_finite(t); - Finite_triangulation ft(t, is_finite, is_finite); + Triangulation tr; - Point p ; - while(input >> p){ - t.insert(p); - } + Point p; + while(input >> p) + tr.insert(p); - vertex_iterator vit, ve; // associate indices to the vertices int index = 0; - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; + for(vertex_descriptor vd : vertices(tr)) vd->id()= index++; - } - typedef boost::property_map::type VertexIdPropertyMap; - VertexIdPropertyMap vertex_index_pmap = get(boost::vertex_index, ft); + VertexIdPropertyMap vertex_index_pmap = get(boost::vertex_index, tr); // Dijkstra's shortest path needs property maps for the predecessor and distance - std::vector predecessor(boost::num_vertices(ft)); + std::vector predecessor(num_vertices(tr)); boost::iterator_property_map::iterator, VertexIdPropertyMap> predecessor_pmap(predecessor.begin(), vertex_index_pmap); - std::vector distance(boost::num_vertices(ft)); + std::vector distance(num_vertices(tr)); boost::iterator_property_map::iterator, VertexIdPropertyMap> distance_pmap(distance.begin(), vertex_index_pmap); - vertex_descriptor source = *boost::vertices(ft).first; + vertex_descriptor source = *vertices(tr).first; std::cout << "\nStart dijkstra_shortest_paths at " << source->point() << std::endl; - boost::dijkstra_shortest_paths(ft, source , - distance_map(distance_pmap) - .predecessor_map(predecessor_pmap)); + boost::dijkstra_shortest_paths(tr, source, distance_map(distance_pmap) + .predecessor_map(predecessor_pmap)); - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; + for(vertex_descriptor vd : vertices(tr)) + { std::cout << vd->point() << " [" << vd->id() << "] "; std::cout << " has distance = " << get(distance_pmap,vd) << " and predecessor "; + vd = get(predecessor_pmap,vd); std::cout << vd->point() << " [" << vd->id() << "]\n"; } - return 0; + + return EXIT_SUCCESS; } diff --git a/BGL/examples/BGL_triangulation_2/emst.cpp b/BGL/examples/BGL_triangulation_2/emst.cpp index ca8282d3195..4de38c2adef 100644 --- a/BGL/examples/BGL_triangulation_2/emst.cpp +++ b/BGL/examples/BGL_triangulation_2/emst.cpp @@ -1,98 +1,65 @@ #include + #include #include #include -#include + #include +#include +#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_2 Point; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_2 Point; -typedef CGAL::Delaunay_triangulation_2 Triangulation; +typedef CGAL::Delaunay_triangulation_2 Triangulation; -// As we only consider finite vertices and edges -// we need the following filter - -template -struct Is_finite { - - const T* t_; - - Is_finite() - : t_(NULL) - {} - - Is_finite(const T& t) - : t_(&t) - { } - - template - bool operator()(const VertexOrEdge& voe) const { - return ! t_->is_infinite(voe); - } -}; - -typedef Is_finite Filter; -typedef boost::filtered_graph Finite_triangulation; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; -typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::edge_descriptor edge_descriptor; // The BGL makes use of indices associated to the vertices // We use a std::map to store the index -typedef std::map VertexIndexMap; -VertexIndexMap vertex_id_map; +typedef std::map VertexIndexMap; // A std::map is not a property map, because it is not lightweight -typedef boost::associative_property_map VertexIdPropertyMap; -VertexIdPropertyMap vertex_index_pmap(vertex_id_map); +typedef boost::associative_property_map VertexIdPropertyMap; -int -main(int argc,char* argv[]) +int main(int argc,char* argv[]) { const char* filename = (argc > 1) ? argv[1] : "data/points.xy"; std::ifstream input(filename); - Triangulation t; - Filter is_finite(t); - Finite_triangulation ft(t, is_finite, is_finite); + Triangulation tr; - Point p ; - while(input >> p){ - t.insert(p); - } + Point p; + while(input >> p) + tr.insert(p); - vertex_iterator vit, ve; // Associate indices to the vertices + VertexIndexMap vertex_id_map; + VertexIdPropertyMap vertex_index_pmap(vertex_id_map); int index = 0; - // boost::tie assigns the first and second element of the std::pair - // returned by boost::vertices to the variables vit and ve - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; - vertex_id_map[vd]= index++; - } + for(vertex_descriptor vd : vertices(tr)) + vertex_id_map[vd] = index++; // We use the default edge weight which is the squared length of the edge // This property map is defined in graph_traits_Triangulation_2.h // In the function call you can see a named parameter: vertex_index_map - std::list mst; - boost::kruskal_minimum_spanning_tree(ft, - std::back_inserter(mst), - vertex_index_map(vertex_index_pmap)); + std::list mst; + boost::kruskal_minimum_spanning_tree(tr, std::back_inserter(mst), + vertex_index_map(vertex_index_pmap)); + std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl; + for(edge_descriptor ed : mst) + { + vertex_descriptor svd = source(ed, tr); + vertex_descriptor tvd = target(ed, tr); + Triangulation::Vertex_handle sv = svd; + Triangulation::Vertex_handle tv = tvd; + std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl; + } - std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl; - - for(std::list::iterator it = mst.begin(); it != mst.end(); ++it){ - edge_descriptor ed = *it; - vertex_descriptor svd = source(ed,t); - vertex_descriptor tvd = target(ed,t); - Triangulation::Vertex_handle sv = svd; - Triangulation::Vertex_handle tv = tvd; - std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl; - } - - return 0; + return EXIT_SUCCESS; } diff --git a/BGL/examples/BGL_triangulation_2/emst_cdt_plus_hierarchy.cpp b/BGL/examples/BGL_triangulation_2/emst_cdt_plus_hierarchy.cpp index acac3a76a68..9db9e5ba347 100644 --- a/BGL/examples/BGL_triangulation_2/emst_cdt_plus_hierarchy.cpp +++ b/BGL/examples/BGL_triangulation_2/emst_cdt_plus_hierarchy.cpp @@ -1,4 +1,5 @@ #include + #include #include #include @@ -9,104 +10,71 @@ #include #include -#include + #include +#include +#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_2 Point; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_2 Point; -typedef CGAL::Triangulation_vertex_base_2 Vbb; -typedef CGAL::Triangulation_hierarchy_vertex_base_2 Vb; -typedef CGAL::Constrained_triangulation_face_base_2 Fb; -typedef CGAL::Triangulation_data_structure_2 TDS; -typedef CGAL::Exact_predicates_tag Itag; -typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; -typedef CGAL::Triangulation_hierarchy_2 CDTH; -typedef CGAL::Constrained_triangulation_plus_2 Triangulation; +typedef CGAL::Triangulation_vertex_base_2 Vbb; +typedef CGAL::Triangulation_hierarchy_vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::Exact_predicates_tag Itag; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Triangulation_hierarchy_2 CDTH; +typedef CGAL::Constrained_triangulation_plus_2 Triangulation; - -// As we only consider finite vertices and edges -// we need the following filter - -template -struct Is_finite { - - const T* t_; - - Is_finite() - : t_(NULL) - {} - - Is_finite(const T& t) - : t_(&t) - { } - - template - bool operator()(const VertexOrEdge& voe) const { - return ! t_->is_infinite(voe); - } -}; - -typedef Is_finite Filter; -typedef boost::filtered_graph Finite_triangulation; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; -typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::edge_descriptor edge_descriptor; // The BGL makes use of indices associated to the vertices // We use a std::map to store the index -typedef std::map VertexIndexMap; -VertexIndexMap vertex_id_map; +typedef std::map VertexIndexMap; // A std::map is not a property map, because it is not lightweight -typedef boost::associative_property_map VertexIdPropertyMap; -VertexIdPropertyMap vertex_index_pmap(vertex_id_map); +typedef boost::associative_property_map VertexIdPropertyMap; -int -main(int argc,char* argv[]) +int main(int argc,char* argv[]) { const char* filename = (argc > 1) ? argv[1] : "data/points.xy"; std::ifstream input(filename); - Triangulation t; - Filter is_finite(t); - Finite_triangulation ft(t, is_finite, is_finite); + Triangulation tr; - Point p ; - while(input >> p){ - t.insert(p); - } + Point p; + while(input >> p) + tr.insert(p); - vertex_iterator vit, ve; // Associate indices to the vertices + VertexIndexMap vertex_id_map; + VertexIdPropertyMap vertex_index_pmap(vertex_id_map); int index = 0; - // boost::tie assigns the first and second element of the std::pair - // returned by boost::vertices to the variables vit and ve - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; - vertex_id_map[vd]= index++; - } + for(vertex_descriptor vd : vertices(tr)) + vertex_id_map[vd] = index++; // We use the default edge weight which is the squared length of the edge // This property map is defined in graph_traits_Triangulation_2.h // In the function call you can see a named parameter: vertex_index_map - std::list mst; - boost::kruskal_minimum_spanning_tree(ft, - std::back_inserter(mst), - vertex_index_map(vertex_index_pmap)); + std::list mst; + boost::kruskal_minimum_spanning_tree(tr, + std::back_inserter(mst), + vertex_index_map(vertex_index_pmap)); - std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl; + std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl; + for(edge_descriptor ed : mst) + { + vertex_descriptor svd = source(ed, tr); + vertex_descriptor tvd = target(ed, tr); + Triangulation::Vertex_handle sv = svd; + Triangulation::Vertex_handle tv = tvd; + std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl; + } - for(std::list::iterator it = mst.begin(); it != mst.end(); ++it){ - edge_descriptor ed = *it; - vertex_descriptor svd = source(ed,t); - vertex_descriptor tvd = target(ed,t); - Triangulation::Vertex_handle sv = svd; - Triangulation::Vertex_handle tv = tvd; - std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl; - } - - return 0; + return EXIT_SUCCESS; } diff --git a/BGL/examples/BGL_triangulation_2/emst_regular.cpp b/BGL/examples/BGL_triangulation_2/emst_regular.cpp index 7b8983d6365..40f9af43377 100644 --- a/BGL/examples/BGL_triangulation_2/emst_regular.cpp +++ b/BGL/examples/BGL_triangulation_2/emst_regular.cpp @@ -1,38 +1,24 @@ #include -#include #include #include - #include #include -#include #include +#include +#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::FT FT; -typedef K::Weighted_point_2 Weighted_point; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::FT FT; +typedef K::Weighted_point_2 Weighted_point; -typedef CGAL::Regular_triangulation_2 Triangulation; +typedef CGAL::Regular_triangulation_2 Triangulation; -// As we only consider finite vertices and edges -// we need the following filter - -template -struct Is_finite { - - const T* t_; - - Is_finite() : t_(NULL) { } - Is_finite(const T& t) : t_(&t) { } - - template - bool operator()(const VertexOrEdge& voe) const { - return ! t_->is_infinite(voe); - } -}; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::edge_descriptor edge_descriptor; template struct Compute_edge_weight @@ -42,7 +28,7 @@ struct Compute_edge_weight Compute_edge_weight(const T& t) : t_(t) { } typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; FT operator()(const edge_descriptor ed) const { vertex_descriptor svd = source(ed, t_); @@ -53,69 +39,54 @@ struct Compute_edge_weight } }; -typedef Is_finite Filter; -typedef boost::filtered_graph Finite_triangulation; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; -typedef boost::graph_traits::edge_descriptor edge_descriptor; - // The BGL makes use of indices associated to the vertices // We use a std::map to store the index typedef std::map VertexIndexMap; -VertexIndexMap vertex_id_map; // A std::map is not a property map, because it is not lightweight typedef boost::associative_property_map VertexIdPropertyMap; -VertexIdPropertyMap vertex_index_pmap(vertex_id_map); -int -main(int argc,char* argv[]) +int main(int argc,char* argv[]) { const char* filename = (argc > 1) ? argv[1] : "data/weighted_points.xyw"; std::ifstream input(filename); - Triangulation t; - Filter is_finite(t); - Finite_triangulation ft(t, is_finite, is_finite); + Triangulation tr; - Weighted_point wp ; - while(input >> wp){ - t.insert(wp); - } + Weighted_point wp; + while(input >> wp) + tr.insert(wp); // Note that with the input "data/weighted_points.xyw", there is one hidden vertex - std::cout << "number of hidden vertices: " << t.number_of_hidden_vertices() << std::endl; + std::cout << "number of hidden vertices: " << tr.number_of_hidden_vertices() << std::endl; - vertex_iterator vit, ve; // Associate indices to the vertices + VertexIndexMap vertex_id_map; + VertexIdPropertyMap vertex_index_pmap(vertex_id_map); int index = 0; - // boost::tie assigns the first and second element of the std::pair - // returned by boost::vertices to the variables vit and ve - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; + + for(vertex_descriptor vd : vertices(tr)) vertex_id_map[vd]= index++; - } // We use a custom edge length property map that computes the power distance // between the extremities of an edge of the regular triangulation typedef Compute_edge_weight Edge_weight_functor; // In the function call you can see a named parameter: vertex_index_map - std::list mst; - boost::kruskal_minimum_spanning_tree( - ft, std::back_inserter(mst), - vertex_index_map(vertex_index_pmap). - weight_map(CGAL::internal::boost_::make_function_property_map< - edge_descriptor, FT, Edge_weight_functor>(Edge_weight_functor(t)))); + std::list mst; + boost::kruskal_minimum_spanning_tree(tr, std::back_inserter(mst), + vertex_index_map(vertex_index_pmap) + .weight_map(CGAL::internal::boost_::make_function_property_map< + edge_descriptor, FT, Edge_weight_functor>(Edge_weight_functor(tr)))); - std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl; - for(std::list::iterator it = mst.begin(); it != mst.end(); ++it){ - edge_descriptor ed = *it; - vertex_descriptor svd = source(ed,t); - vertex_descriptor tvd = target(ed,t); - Triangulation::Vertex_handle sv = svd; - Triangulation::Vertex_handle tv = tvd; - std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl; - } + std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl; + for(edge_descriptor ed : mst) + { + vertex_descriptor svd = source(ed, tr); + vertex_descriptor tvd = target(ed, tr); + Triangulation::Vertex_handle sv = svd; + Triangulation::Vertex_handle tv = tvd; + std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl; + } - return 0; + return EXIT_SUCCESS; } diff --git a/BGL/examples/BGL_triangulation_2/face_graph.cpp b/BGL/examples/BGL_triangulation_2/face_graph.cpp index efc5535a6a3..aa31b224721 100644 --- a/BGL/examples/BGL_triangulation_2/face_graph.cpp +++ b/BGL/examples/BGL_triangulation_2/face_graph.cpp @@ -1,4 +1,5 @@ #include + #include #include #include @@ -6,110 +7,81 @@ #include +typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic; +typedef CGAL::Projection_traits_xy_3 K; +typedef K::Point_2 Point; -typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic; -typedef CGAL::Projection_traits_xy_3 K; -typedef K::Point_2 Point; +typedef CGAL::Triangulation_2 Triangulation; -typedef CGAL::Triangulation_2 Triangulation; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::halfedge_iterator halfedge_iterator; +typedef boost::graph_traits::edge_iterator edge_iterator; +typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::face_iterator face_iterator; +typedef std::map VertexIndexMap; +typedef boost::associative_property_map VertexIdPropertyMap; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; -typedef boost::graph_traits::halfedge_iterator halfedge_iterator; -typedef boost::graph_traits::face_descriptor face_descriptor; -typedef boost::graph_traits::vertex_iterator vertex_iterator; -typedef boost::graph_traits::face_iterator face_iterator; -typedef boost::graph_traits::edge_iterator edge_iterator; -typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::property_map::type Ppmap; -typedef std::map VertexIndexMap; -VertexIndexMap vertex_id_map; - -typedef boost::associative_property_map VertexIdPropertyMap; -VertexIdPropertyMap vertex_index_pmap(vertex_id_map); - -typedef std::map HalfedgeIndexMap; -HalfedgeIndexMap halfedge_id_map; - -typedef boost::associative_property_map HalfedgeIdPropertyMap; -HalfedgeIdPropertyMap halfedge_index_pmap(halfedge_id_map); - -int -main(int,char*[]) +int main(int /*argc*/, char** /*argc*/) { - Triangulation t; + Triangulation tr; - t.insert(Point(0.1,0,1)); - t.insert(Point(1,0,1)); - t.insert(Point(0.2,0.2, 2)); - t.insert(Point(0,1,2)); - t.insert(Point(0,2,3)); + tr.insert(Point(0.1,0,1)); + tr.insert(Point(1,0,1)); + tr.insert(Point(0.2,0.2, 2)); + tr.insert(Point(0,1,2)); + tr.insert(Point(0,2,3)); - vertex_iterator vit, ve; // Associate indices to the vertices + VertexIndexMap vertex_id_map; + VertexIdPropertyMap vertex_index_pmap(vertex_id_map); int index = 0; - // boost::tie assigns the first and second element of the std::pair - // returned by boost::vertices to the variables vit and ve - for(boost::tie(vit,ve) = vertices(t); vit!=ve; ++vit ){ - vertex_descriptor vd = *vit; - if(! t.is_infinite(vd)){ - vertex_id_map[vd]= index++; - } - } + for(vertex_descriptor vd : vertices(tr)) + vertex_id_map[vd] = index++; std::cerr << index << " vertices" << std::endl; - index = 0; - face_iterator fit,fe; - for(boost::tie(fit,fe) = faces(t); fit!= fe; ++fit){ - face_descriptor fd = *fit; - halfedge_descriptor hd = halfedge(fd,t); - halfedge_descriptor n = next(hd,t); - - halfedge_descriptor nn = next(n,t); - if(next(nn,t) != hd){ - std::cerr << "the face is not a triangle" << std::endl; - } - - ++index; - } - - std::cerr << index << " faces" << std::endl; - index = 0; - edge_iterator eit,ee; - for(boost::tie(eit,ee) = edges(t); eit!= ee; ++eit){ - edge_descriptor ed = *eit; - vertex_descriptor vd = source(ed,t); - CGAL_USE(vd); - ++index; - } - - std::cerr << index << " edges" << std::endl; index = 0; - - halfedge_iterator hit,he; - for(boost::tie(hit,he) = halfedges(t); hit!= he; ++hit){ - halfedge_descriptor hd = *hit; - vertex_descriptor vd = source(hd,t); + for(halfedge_descriptor hd : halfedges(tr)) + { + vertex_descriptor vd = source(hd, tr); CGAL_USE(vd); ++index; } std::cerr << index << " halfedges" << std::endl; - std::cerr << num_vertices(t) << " " << num_edges(t) << " " << num_halfedges(t) << " " << num_faces(t) << std::endl; - - typedef boost::property_map::type Ppmap; - Ppmap ppmap = get(boost::vertex_point, t); - - - for(vertex_descriptor vd : vertices_around_target(*vertices(t).first, t)){ - std::cout << ppmap[vd] << std::endl; + index = 0; + for(edge_descriptor ed : edges(tr)) + { + vertex_descriptor vd = source(ed, tr); + CGAL_USE(vd); + ++index; } + std::cerr << index << " edges" << std::endl; + index = 0; + for(face_descriptor fd : faces(tr)) + { + halfedge_descriptor hd = halfedge(fd, tr); + CGAL_USE(hd); + ++index; + } + std::cerr << index << " faces" << std::endl; - ppmap[*(++vertices(t).first)] = Point(78,1,2); - std::cout << " changed point of vertex " << ppmap[*(++vertices(t).first)] << std::endl; + std::cerr << num_vertices(tr) << " " << num_halfedges(tr) << " " << num_edges(tr) << " " << num_faces(tr) << std::endl; - return 0; + std::cout << "vertices incident to the first vertex:" << std::endl; + Ppmap ppmap = get(boost::vertex_point, tr); + for(vertex_descriptor vd : vertices_around_target(*vertices(tr).first, tr)) + std::cout << ppmap[vd] << std::endl; + + ppmap[*(++vertices(tr).first)] = Point(78, 1, 2); + std::cout << "changed point of vertex " << ppmap[*(++vertices(tr).first)] << std::endl; + + return EXIT_SUCCESS; } From f921dd8a06f2dd58dc30a071d921fe67a6a42afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 16:02:28 +0200 Subject: [PATCH 30/68] Clarify some documentation in PMP::locate::random_location_on_XXX() --- .../CGAL/Polygon_mesh_processing/locate.h | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index c7600bfd67b..d8fccc33228 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -510,8 +510,10 @@ barycentric_coordinates(const P& p, const P& q, const P& r, const P& query) /// \brief Returns a random point over the halfedge `hd`, as a `Face_location`. /// -/// \details The point is on the halfedge, meaning that all its barycentric coordinates -/// are positive. +/// \details The random point is chosen on the halfedge, meaning that all +/// its barycentric coordinates are positive. It is constructed by uniformly generating +/// a value `t` between `0` and `1` and setting the barycentric coordinates to `t`, `1-t`, +/// and `0` for respetively the source and target of `hd`, and the third vertex. /// /// \tparam TriangleMesh A model of `FaceGraph` /// @@ -535,8 +537,10 @@ random_location_on_halfedge(typename boost::graph_traits::halfedge /// \brief Returns a random point over the face `fd`, as a `Face_location`. /// -/// \details The point is on the face, meaning that all its barycentric coordinates -/// are positive. +/// \details The random point is on the face, meaning that all its barycentric coordinates +/// are positive. It is constructed by uniformly picking a value `u` between `0` and `1`, +/// a value `v` between `1-u`, and setting the barycentric coordinates to `u`, `v`, and +/// `1-u-v` for respectively the source and target of `halfedge(fd, tm)`, and the third point. /// /// \tparam TriangleMesh A model of `FaceGraph` /// @@ -564,15 +568,17 @@ random_location_on_face(typename boost::graph_traits::face_descrip /// \brief Returns a random point over the mesh `tm`. /// -/// \details The returned location corresponds to a random point on a random face -/// of the mesh. The barycentric coordinates of the point in the face -/// are thus all positive. +/// \details The returned location is obtained by choosing a random face of the mesh and +/// a random point on that face. The barycentric coordinates of the point in the face +/// are thus all positive. Note that all faces have the same probability to be chosen. /// /// \tparam TriangleMesh A model of `FaceGraph` /// /// \param tm a triangulated surface mesh /// \param rnd optional random number generator /// +/// \sa `random_location_on_face()` +/// template typename internal::Locate_types::Face_location random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) From 9abef288409cbc58a44de3f05b6c08f033460fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 16:05:51 +0200 Subject: [PATCH 31/68] Add missing operator< for T2 edge descriptors and removed useless comparators --- .../graph_traits_2D_triangulation_helper.h | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h index ec2c625735f..81510aeb787 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h @@ -58,20 +58,6 @@ struct T2_halfedge_descriptor friend std::size_t hash_value(const T2_halfedge_descriptor& e) { return hash_value(e.first); } - - bool operator==(const T2_halfedge_descriptor& other) const { - return (this->first == other.first) && (this->second == other.second); - } - bool operator!=(const T2_halfedge_descriptor& other) const { - return (this->first != other.first) || (this->second != other.second); - } - - bool operator<(const T2_halfedge_descriptor& other) const - { - if(this->first < other.first) return true; - if(this->first > other.first) return false; - return this->second < other.second; - } }; // An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge @@ -110,6 +96,35 @@ struct T2_edge_descriptor } bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); } + void get_canonical_edge_representation(Face_handle& fh, int& i) const + { + Face_handle neigh_fh = fh->neighbor(i); + Face_handle canonical_fh = (fh < neigh_fh) ? fh : neigh_fh; + + int canonical_i = (fh < neigh_fh) ? i : neigh_fh->index(fh); + + fh = canonical_fh; + i = canonical_i; + } + + bool operator<(const T2_edge_descriptor& other) const + { + if(*this == other) + return false; + + Face_handle tfh = first; + int ti = second; + get_canonical_edge_representation(tfh, ti); + + Face_handle ofh = other.first; + int oi = other.second; + get_canonical_edge_representation(ofh, oi); + + if(tfh < ofh) return true; + if(tfh > ofh) return false; + return ti < oi; + } + Face_handle first; int second; }; From e183b52f6d6b604201c6068ea54d3e6f0a7bb8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 16:08:37 +0200 Subject: [PATCH 32/68] Convert to double using CGAL::to_double Since not every exact number type can just be casted to double like that --- .../include/CGAL/Polygon_mesh_processing/locate.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index d8fccc33228..ba0a4bd3726 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -561,7 +562,7 @@ random_location_on_face(typename boost::graph_traits::face_descrip // calling 'rnd.uniform real' with double in case FT comes from an EPECK kernel (which doesn't seem to work too well) FT u(rnd.uniform_real(0., 1.)); - FT v(rnd.uniform_real(0., double(FT(1) - u))); + FT v(rnd.uniform_real(0., CGAL::to_double(FT(1) - u))); return std::make_pair(fd, CGAL::make_array(u, v, FT(FT(1) - u - v))); } From 5ab413429a4e68ce1fe917458a3cd410a712434c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 30 Apr 2019 14:13:42 +0200 Subject: [PATCH 33/68] Complete PMP::locate's documentation --- .../PackageDescription.txt | 12 + .../Polygon_mesh_processing.txt | 19 + .../CGAL/Polygon_mesh_processing/locate.h | 453 ++++++++++++------ .../test_pmp_locate.cpp | 30 +- 4 files changed, 343 insertions(+), 171 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 032167d48e0..a35edeffdfb 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -54,6 +54,10 @@ /// Functions to detect sharp edges and surface patches of polygon meshes. /// \ingroup PkgPolygonMeshProcessingRef +/// \defgroup PMP_locate_grp Location Functions +/// Functions to locate points on a mesh, and manipulate such locations. +/// \ingroup PkgPolygonMeshProcessingRef + /// \defgroup PMP_predicates_grp Intersection Detection Functions /// Functions to detect intersections. /// Note that those functions will be exact as long as the underlying do-intersect predicates used are exact. @@ -121,6 +125,14 @@ and provides a list of the parameters that are used in this package. - `CGAL::Polygon_mesh_processing::is_needle_triangle_face()` - `CGAL::Polygon_mesh_processing::is_cap_triangle_face()` +\cgalCRPSection{Location Functions} +- \link PMP_locate_grp Point Location \endlink +- \link PMP_locate_grp Random Simplex Generation \endlink +- \link PMP_locate_grp Simplex Index \endlink +- \link PMP_locate_grp Location Predicates \endlink +- \link PMP_locate_grp Nearest Face Location Queries \endlink +- \link PMP_locate_grp Random Location Generation \endlink + \cgalCRPSection{Orientation Functions} - `CGAL::Polygon_mesh_processing::orient_polygon_soup()` - `CGAL::Polygon_mesh_processing::orient()` diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 004aad17948..05cff8fb35c 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -463,6 +463,25 @@ This package offers a toolkit of functions to detect such undesirable elements. - `CGAL::Polygon_mesh_processing::is_cap_triangle_face()` - `CGAL::Polygon_mesh_processing::is_needle_triangle_face()` +\subsection PMPLocationFunctions Surface Location Functions + +To ease the manipulation of points on a surface, \cgal offers a multitude of functions based upon +a different representation of a point on a polygon mesh: the point is represented as a pair of +a face of the polygon mesh and a triplet of barycentric coordinates. This definition enables +a robust handling of polylines between points living in the same face: for example, two 3D segments +created by four points within the same face that should intersect might not actually intersect due to +inexact computations. However, manipulating these same points through their barycentric coordinates +can instead be done, and intersections computed in the barycentric space will not suffer +from the same issues. Furthermore, this definition is only dependent on the intrinsic dimension +of the surface (i.e. 2) and not on the ambient dimension within which the surface is embedded. + +The functions of the group \ref PMP_locate_grp offer the following functionalities: +location computations (`CGAL::Polygon_mesh_processing::locate()`, and similar) given a point, +finding the nearest point on a mesh given a point or a ray +(`CGAL::Polygon_mesh_processing::locate_with_AABB_tree()`, and similar), location-based predicates +(for example, `CGAL::Polygon_mesh_processing::is_on_face_border()`), and random location generation +(for example, `CGAL::Polygon_mesh_processing::random_vertex_in_mesh()`). + **************************************** \section PMPOrientation Orientation diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index ba0a4bd3726..4f3dfe5aa87 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -32,9 +32,10 @@ #include #include #include +#include #include #include -#include +#include #include #include @@ -63,45 +64,93 @@ namespace Polygon_mesh_processing { namespace internal { -// to not carry 5-lines-long types everywhere -template -struct Locate_types +// The Ray must have the same ambient dimension as the property map's value type (aka, the point type) + +template ::value> +struct Ray_type_selector { - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef boost::variant descriptor_variant; + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::Ray_2 type; +}; - typedef typename GetVertexPointMap::const_type VPM; - typedef typename boost::property_traits::value_type Point; - - typedef typename CGAL::Kernel_traits::type Kernel; - typedef typename Kernel::FT FT; - - typedef std::array Barycentric_coordinates; - typedef std::pair Face_location; +template +struct Ray_type_selector +{ + typedef typename CGAL::Kernel_traits::type Kernel; + typedef typename Kernel::Ray_3 type; }; } // end namespace internal +/// \ingroup PMP_locate_grp +/// +/// \brief Helper class whose sole purpose is to make it easier to access some useful types. +/// +/// \tparam PolygonMesh A model of `FaceListGraph` +/// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" +/// +template +class Locate_types +{ +public: + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef boost::variant descriptor_variant; + +#ifdef DOXYGEN_RUNNING + /// This is the type of the vertex point property map, either the one passed through the named parameters + /// or the default, internal one of the mesh. + typedef unspecified_type VPM; + + /// The traits class, either passed as a named parameter or deduced from the Point type + /// of the vertex property map (the point type must then be compatible with `CGAL::Kernel_traits`) + typedef unspecified_type Geom_traits; +#else + typedef typename GetVertexPointMap::const_type VPM; + typedef typename GetGeomTraits::type Geom_traits; +#endif + + typedef typename boost::property_traits::value_type Point; + typedef typename Geom_traits::FT FT; + +#ifdef DOXYGEN_RUNNING + /// Either Geom_traits::Ray_2 or Geom_traits::Ray_3, depending on the ambient dimension of the mesh + typedef unspecified_type Ray; +#else + typedef typename internal::Ray_type_selector::type Ray; +#endif + + typedef std::array Barycentric_coordinates; + + /// If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) + /// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights 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)` + typedef std::pair Face_location; +}; + // forward declarations template -bool is_in_face(const typename internal::Locate_types::Face_location& loc, +bool is_in_face(const typename Locate_types::Face_location& loc, const TriangleMesh& tm); template -typename internal::Locate_types::descriptor_variant -get_descriptor_from_location(const typename internal::Locate_types::Face_location& loc, +typename Locate_types::descriptor_variant +get_descriptor_from_location(const typename Locate_types::Face_location& loc, const TriangleMesh& tm); template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate_in_face(typename boost::graph_traits::halfedge_descriptor he, - typename internal::Locate_types::FT t, + typename Locate_types::FT t, const TriangleMesh& tm); // end of forward declarations @@ -109,7 +158,7 @@ namespace internal { template OutputIterator -incident_faces(const typename internal::Locate_types::Face_location& location, +incident_faces(const typename Locate_types::Face_location& location, const TriangleMesh& tm, OutputIterator out) { @@ -151,7 +200,7 @@ snap_coordinates_to_border(typename Locate_types::Barycentric_coor const typename Locate_types::FT tolerance = std::numeric_limits::FT>::epsilon()) { - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::FT FT; #ifdef CGAL_PMP_LOCATE_DEBUG std::cout << "Pre-snapping: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; @@ -310,10 +359,13 @@ struct Barycentric_point_constructor // 2D version { typedef typename K::FT FT; - P operator()(const P& p, const FT wp, const P& q, const FT wq, const P& r, const FT wr) const + P operator()(const P& p, const FT wp, const P& q, const FT wq, const P& r, const FT wr, + const K& /*k*/) const { FT sum = wp + wq + wr; CGAL_assertion(sum != 0); + + // In theory, this should be compute_x_2(compute_point_2(...)) and construct_P() at the end... FT x = (wp * p.x() + wq * q.x() + wr * r.x()) / sum; FT y = (wp * p.y() + wq * q.y() + wr * r.y()) / sum; @@ -326,7 +378,8 @@ struct Barycentric_point_constructor // 3D version { typedef typename K::FT FT; - P operator()(const P& p, const FT wp, const P& q, const FT wq, const P& r, const FT wr) const + P operator()(const P& p, const FT wp, const P& q, const FT wq, const P& r, const FT wr, + const K& /*k*/) const { FT sum = wp + wq + wr; CGAL_assertion(sum != 0); @@ -340,10 +393,14 @@ struct Barycentric_point_constructor // 3D version } // namespace internal +/// \name Random Simplex Generation +/// @{ + +/// \ingroup PMP_locate_grp +/// /// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `pm`. /// /// \tparam PolygonMesh A model of `HalfedgeGraph` -/// template typename boost::graph_traits::vertex_descriptor random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, @@ -353,6 +410,8 @@ random_vertex_in_face(typename boost::graph_traits::face_descriptor return internal::random_entity_in_range(vertices_around_face(halfedge(fd, pm), pm), rnd); } +/// \ingroup PMP_locate_grp +/// /// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `pm`. /// /// \tparam PolygonMesh A model of `HalfedgeGraph` @@ -366,6 +425,8 @@ random_halfedge_in_face(typename boost::graph_traits::face_descript return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, pm), pm), rnd); } +/// \ingroup PMP_locate_grp +/// /// \brief returns a random non-null vertex of the polygon mesh `pm`. /// /// \tparam PolygonMesh A model of `VertexListGraph` @@ -377,6 +438,8 @@ random_vertex_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_ran return internal::random_entity_in_range(vertices(pm), rnd); } +/// \ingroup PMP_locate_grp +/// /// \brief returns a random non-null halfedge of the polygon mesh `pm`. /// /// \tparam PolygonMesh A model of `HalfedgeListGraph` @@ -388,6 +451,8 @@ random_halfedge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_r return internal::random_entity_in_range(halfedges(pm), rnd); } +/// \ingroup PMP_locate_grp +/// /// \brief returns a random non-null edge of the polygon mesh `pm`. /// /// \tparam PolygonMesh A model of `EdgeListGraph` @@ -399,6 +464,8 @@ random_edge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_rando return internal::random_entity_in_range(edges(pm), rnd); } +/// \ingroup PMP_locate_grp +/// /// \brief returns a random non-null face of the polygon mesh `pm`. /// /// \tparam PolygonMesh A model of `FaceListGraph` @@ -410,7 +477,14 @@ random_face_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_rando return internal::random_entity_in_range(faces(pm), rnd); } -/// \brief returns the number of `next` one has to apply to the halfedge `hd` +/// @} + +/// \name Simplex Index +/// @{ + +/// \ingroup PMP_locate_grp +/// +/// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd` /// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. /// /// \tparam PolygonMesh A model of `FaceGraph` @@ -450,6 +524,8 @@ int vertex_index_in_face(const typename boost::graph_traits::vertex return counter; } +/// \ingroup PMP_locate_grp +/// /// \brief returns the number of `next` one has to apply to `hd` for `hd == he` /// to be true, starting from `hd = halfedge(face(hd, tm), tm)`. /// @@ -482,9 +558,20 @@ int halfedge_index_in_face(typename boost::graph_traits::halfedge_d return count; } +/// @} + +/// \ingroup PMP_locate_grp +/// /// \brief Given a set of three points and a query point, computes the barycentric /// coordinates of the query point with respect to the first three points. /// +/// \tparam P the type of a geometric 2D or 3D point +/// \tparam K the type of a geometric traits. Must be a model of `Kernel`. +/// +/// \param p,q,r three points with respect to whom the barycentric coordinates of `query` will be computed +/// \param query the query point whose barycentric coordinates will be computed +/// \param k an instance of the geometric traits +/// /// \pre `p`, `q`, and `r` are not collinear. /// \pre It must be possible to extract a kernel type model of `Kernel`, using `CGAL::Kernel_traits

` /// (this is the case for all standard %CGAL point types). @@ -507,8 +594,11 @@ barycentric_coordinates(const P& p, const P& q, const P& r, const P& query) return barycentric_coordinates(p, q, r, query, Kernel()); } -// Random locations +/// \name Random Location Generation +/// @{ +/// \ingroup PMP_locate_grp +/// /// \brief Returns a random point over the halfedge `hd`, as a `Face_location`. /// /// \details The random point is chosen on the halfedge, meaning that all @@ -523,12 +613,12 @@ barycentric_coordinates(const P& p, const P& q, const P& r, const P& query) /// \param rnd optional random number generator /// template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location random_location_on_halfedge(typename boost::graph_traits::halfedge_descriptor hd, const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) { - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::FT FT; CGAL_precondition(CGAL::is_triangle_mesh(tm)); @@ -536,6 +626,8 @@ random_location_on_halfedge(typename boost::graph_traits::halfedge return locate_in_face(hd, t, tm); } +/// \ingroup PMP_locate_grp +/// /// \brief Returns a random point over the face `fd`, as a `Face_location`. /// /// \details The random point is on the face, meaning that all its barycentric coordinates @@ -550,13 +642,14 @@ random_location_on_halfedge(typename boost::graph_traits::halfedge /// \param rnd optional random number generator /// template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location random_location_on_face(typename boost::graph_traits::face_descriptor fd, - const TriangleMesh& CGAL_precondition_code(tm), + const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) { - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::FT FT; + CGAL_USE(tm); CGAL_precondition(CGAL::is_triangle_mesh(tm)); CGAL_precondition(fd != boost::graph_traits::null_face()); @@ -567,6 +660,8 @@ random_location_on_face(typename boost::graph_traits::face_descrip return std::make_pair(fd, CGAL::make_array(u, v, FT(FT(1) - u - v))); } +/// \ingroup PMP_locate_grp +/// /// \brief Returns a random point over the mesh `tm`. /// /// \details The returned location is obtained by choosing a random face of the mesh and @@ -581,7 +676,7 @@ random_location_on_face(typename boost::graph_traits::face_descrip /// \sa `random_location_on_face()` /// template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) { typedef typename boost::graph_traits::face_descriptor face_descriptor; @@ -592,8 +687,12 @@ random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_ return random_location_on_face(fd, tm, rnd); } +/// @} + +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns a descriptor to the simplex /// of smallest dimension on which the point corresponding to the location lies. /// @@ -601,7 +700,8 @@ random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_ /// - if the point lies on a vertex, this function returns a `vertex_descriptor` `v`; /// - if the point lies on a halfedge, this function returns a `halfedge_descriptor` `hd` /// (note that in that case, `loc.first == face(hd, tm)` holds). -/// - otherwise, this function returns a `face_descriptor` `fd` (equal to `loc.first`). +/// - otherwise, this function returns a `boost::graph_traitsface_descriptor` +/// `fd` (equal to `loc.first`). /// /// \tparam TriangleMesh A model of `FaceGraph` /// @@ -609,14 +709,14 @@ random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_ /// \pre `tm` is a triangulated surface mesh. /// template -typename internal::Locate_types::descriptor_variant -get_descriptor_from_location(const typename internal::Locate_types::Face_location& loc, +typename Locate_types::descriptor_variant +get_descriptor_from_location(const typename Locate_types::Face_location& loc, const TriangleMesh& tm) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename internal::Locate_types::Barycentric_coordinates Barycentric_coordinates; + typedef typename Locate_types::Barycentric_coordinates Barycentric_coordinates; const face_descriptor fd = loc.first; const Barycentric_coordinates& bar = loc.second; @@ -648,8 +748,10 @@ get_descriptor_from_location(const typename internal::Locate_types return fd; } +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns the geometric position described /// by these coordinates, as a point. /// @@ -666,14 +768,17 @@ get_descriptor_from_location(const typename internal::Locate_types /// If this parameter is omitted, an internal property map for /// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd +/// \cgalParamBegin{geom_traits} +/// a geometric traits class instance, model of `Kernel`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. /// \pre `tm` is a triangulated surface mesh. /// template -typename internal::Locate_types::Point -location_to_point(const typename internal::Locate_types::Face_location& loc, +typename Locate_types::Point +location_to_point(const typename Locate_types::Face_location& loc, const TriangleMesh& tm, const NamedParameters& np) { @@ -681,32 +786,38 @@ location_to_point(const typename internal::Locate_types::Face_loca typedef typename GetVertexPointMap::const_type VertexPointMap; typedef typename boost::property_traits::value_type Point; - typedef typename internal::Locate_types::Kernel Kernel; + typedef typename GetGeomTraits::type Geom_traits; CGAL_precondition(CGAL::is_triangle_mesh(tm)); VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, tm)); + Geom_traits gt = choose_param(get_param(np, internal_np::geom_traits), Geom_traits()); halfedge_descriptor hd = halfedge(loc.first, tm); const Point& p0 = get(vpm, source(hd, tm)); const Point& p1 = get(vpm, target(hd, tm)); const Point& p2 = get(vpm, target(next(hd, tm), tm)); - internal::Barycentric_point_constructor bp_constructor; - return bp_constructor(p0, loc.second[0], p1, loc.second[1], p2, loc.second[2]); + internal::Barycentric_point_constructor bp_constructor; + return bp_constructor(p0, loc.second[0], p1, loc.second[1], p2, loc.second[2], gt); } template typename property_map_value::type -location_to_point(const typename internal::Locate_types::Face_location& loc, +location_to_point(const typename Locate_types::Face_location& loc, const TriangleMesh& tm) { return location_to_point(loc, tm, parameters::all_default()); } +/// \name Location Predicates +/// @{ + +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// on the vertex `vd` or not. /// @@ -724,12 +835,12 @@ location_to_point(const typename internal::Locate_types::Face_loca /// template bool -is_on_vertex(const typename internal::Locate_types::Face_location& loc, +is_on_vertex(const typename Locate_types::Face_location& loc, const typename boost::graph_traits::vertex_descriptor v, const TriangleMesh& tm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename internal::Locate_types::descriptor_variant descriptor_variant; + typedef typename Locate_types::descriptor_variant descriptor_variant; if(!is_in_face(loc, tm)) return false; @@ -742,8 +853,10 @@ is_on_vertex(const typename internal::Locate_types::Face_location& return false; } +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// on the halfedge `hd` or not. /// @@ -761,13 +874,13 @@ is_on_vertex(const typename internal::Locate_types::Face_location& /// template bool -is_on_halfedge(const typename internal::Locate_types::Face_location& loc, +is_on_halfedge(const typename Locate_types::Face_location& loc, const typename boost::graph_traits::halfedge_descriptor h, const TriangleMesh& tm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename internal::Locate_types::descriptor_variant descriptor_variant; + typedef typename Locate_types::descriptor_variant descriptor_variant; if(!is_in_face(loc, tm)) return false; @@ -782,6 +895,8 @@ is_on_halfedge(const typename internal::Locate_types::Face_locatio return false; } +/// \ingroup PMP_locate_grp +/// /// \brief Given a set of barycentric coordinates, returns whether those barycentric /// coordinates correspond to a point within the face (boundary included), /// that is, if all the barycentric coordinates are positive. @@ -799,9 +914,10 @@ is_on_halfedge(const typename internal::Locate_types::Face_locatio /// template bool -is_in_face(const typename internal::Locate_types::Barycentric_coordinates& bar, - const TriangleMesh& CGAL_precondition_code(tm)) +is_in_face(const typename Locate_types::Barycentric_coordinates& bar, + const TriangleMesh& tm) { + CGAL_USE(tm); CGAL_precondition(CGAL::is_triangle_mesh(tm)); for(int i=0; i<3; ++i) @@ -815,8 +931,10 @@ is_in_face(const typename internal::Locate_types::Barycentric_coor return true; } +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// in the face (boundary included) or not. /// @@ -834,14 +952,16 @@ is_in_face(const typename internal::Locate_types::Barycentric_coor /// template bool -is_in_face(const typename internal::Locate_types::Face_location& loc, +is_in_face(const typename Locate_types::Face_location& loc, const TriangleMesh& tm) { return is_in_face(loc.second, tm); } +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is on the boundary /// of the face or not. /// @@ -859,11 +979,11 @@ is_in_face(const typename internal::Locate_types::Face_location& l /// template bool -is_on_face_border(const typename internal::Locate_types::Face_location& loc, +is_on_face_border(const typename Locate_types::Face_location& loc, const TriangleMesh& tm) { - typedef typename internal::Locate_types::Face_location Face_location; - typedef typename Face_location::second_type Barycentric_coordinates; + typedef typename Locate_types::Face_location Face_location; + typedef typename Face_location::second_type Barycentric_coordinates; if(!is_in_face(loc, tm)) return false; @@ -877,8 +997,10 @@ is_on_face_border(const typename internal::Locate_types::Face_loca return false; } +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// on the border of the mesh or not. /// @@ -896,13 +1018,13 @@ is_on_face_border(const typename internal::Locate_types::Face_loca /// template bool -is_on_mesh_border(const typename internal::Locate_types::Face_location& loc, +is_on_mesh_border(const typename Locate_types::Face_location& loc, const TriangleMesh& tm) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename internal::Locate_types::Face_location Face_location; + typedef typename Locate_types::Face_location Face_location; typedef typename Face_location::second_type Barycentric_coordinates; const face_descriptor fd = loc.first; @@ -935,9 +1057,10 @@ is_on_mesh_border(const typename internal::Locate_types::Face_loca return false; } -/// \name Constructions -/// @{ +/// @} +/// \ingroup PMP_locate_grp +/// /// \brief Given two faces `fd1` and `fd2` of a polygonal mesh `pm`, returns /// (if it exists) a common edge. The returned halfedge is incident to `fd1`. /// @@ -967,9 +1090,11 @@ common_halfedge(const typename boost::graph_traits::face_descriptor return boost::none; } -/// \name Constructions +/// \name Point Location /// @{ +/// \ingroup PMP_locate_grp +/// /// \brief Returns the location of the given vertex `vd` as a `Face_location`, /// that is an ordered pair specifying a face containing the location /// and the barycentric coordinates of the vertex `vd` in that face. @@ -987,14 +1112,14 @@ common_halfedge(const typename boost::graph_traits::face_descriptor /// \param tm a triangulated surface mesh /// template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate_in_face(typename boost::graph_traits::vertex_descriptor vd, const TriangleMesh& tm) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::FT FT; halfedge_descriptor he = halfedge(vd, tm); @@ -1023,6 +1148,8 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); } +/// \ingroup PMP_locate_grp +/// /// \brief Returns the location of a given vertex as a `Face_location` in `fd`, /// that is an ordered pair composed of `fd` and of the barycentric coordinates /// of the vertex in `fd`. @@ -1041,12 +1168,12 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, /// \param tm a triangulated surface mesh /// template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate_in_face(const typename boost::graph_traits::vertex_descriptor vd, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm) { - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::FT FT; FT coords[3] = { FT(0), FT(0), FT(0) }; std::size_t vertex_local_index = vertex_index_in_face(vd, fd, tm); @@ -1055,6 +1182,8 @@ locate_in_face(const typename boost::graph_traits::vertex_descript return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); } +/// \ingroup PMP_locate_grp +/// /// \brief Given a point described by a halfedge `he` and a scalar `t` /// as `p = (1 - t) * source(he, tm) + t * target(he, tm)`, /// returns this location along the given edge as a `Face_location`, that is @@ -1077,13 +1206,13 @@ locate_in_face(const typename boost::graph_traits::vertex_descript /// \pre `tm` is a triangulated surface mesh. /// template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate_in_face(const typename boost::graph_traits::halfedge_descriptor he, - const typename internal::Locate_types::FT t, + const typename Locate_types::FT t, const TriangleMesh& tm) { typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::FT FT; face_descriptor fd = face(he, tm); std::size_t edge_local_index = halfedge_index_in_face(he, tm); @@ -1096,6 +1225,8 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri return std::make_pair(fd, CGAL::make_array(coords[0], coords[1], coords[2])); } +/// \ingroup PMP_locate_grp +/// /// \brief Given a point `query` and a face `fd` of a triangulation surface mesh, /// returns this location as a `Face_location`, that is /// an ordered pair composed of `fd` and of the barycentric coordinates of @@ -1122,26 +1253,30 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// If this parameter is omitted, an internal property map for /// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd +/// \cgalParamBegin{geom_traits} +/// a geometric traits class instance, model of `Kernel`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate_in_face(const typename internal::Locate_types::Point& query, +typename Locate_types::Face_location +locate_in_face(const typename Locate_types::Point& query, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm, const NamedParameters& np) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename internal::Locate_types::Kernel K; - typedef typename K::FT FT; + typedef typename Locate_types::FT FT; // VertexPointMap + typedef typename GetGeomTraits::type Geom_traits; typedef typename GetVertexPointMap::const_type VertexPointMap; typedef typename boost::property_traits::value_type Point; VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, tm)); + Geom_traits gt = choose_param(get_param(np, internal_np::geom_traits), Geom_traits()); vertex_descriptor vd0 = source(halfedge(fd, tm), tm); vertex_descriptor vd1 = target(halfedge(fd, tm), tm); @@ -1151,7 +1286,7 @@ locate_in_face(const typename internal::Locate_types coords = barycentric_coordinates(p0, p1, p2, query); + std::array coords = barycentric_coordinates(p0, p1, p2, query, gt); if(!is_in_face(coords, tm)) { @@ -1166,17 +1301,21 @@ locate_in_face(const typename internal::Locate_types -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate_in_face(const typename property_map_value::type& query, const typename boost::graph_traits::face_descriptor f, const TriangleMesh& tm) { return locate_in_face(query, f, tm, parameters::all_default()); } +#endif +/// \ingroup PMP_locate_grp +/// /// \brief Given a `Face_location`, that is an ordered pair composed of a -/// `boost::graph_traits::face_descriptor` and an array +/// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, and a second face adjacent to the first, /// return the `Face_location` of the point in the second face. /// @@ -1196,8 +1335,8 @@ locate_in_face(const typename property_map_value -typename internal::Locate_types::Face_location -locate_in_adjacent_face(const typename internal::Locate_types::Face_location& loc, +typename Locate_types::Face_location +locate_in_adjacent_face(const typename Locate_types::Face_location& loc, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm) { @@ -1209,8 +1348,8 @@ locate_in_adjacent_face(const typename internal::Locate_types::Fac halfedge_descriptor, face_descriptor> descriptor_variant; - typedef typename internal::Locate_types::Face_location Face_location; - typedef typename internal::Locate_types::FT FT; + typedef typename Locate_types::Face_location Face_location; + typedef typename Locate_types::FT FT; if(loc.first == fd) return loc; @@ -1263,18 +1402,21 @@ locate_in_adjacent_face(const typename internal::Locate_types::Fac return loc_in_fd; } +// not documenting the next two functions as they are too technical +#ifndef DOXYGEN_RUNNING + // Finding a common face to a location and a point // - the first location must be known // - the second must be a point in a face incident to get_descriptor_from_location(known_location) // note: not returning the query location to emphasis that the known location can change too. template bool -locate_in_common_face(typename internal::Locate_types::Face_location& known_location, - const typename internal::Locate_types::Point& query, - typename internal::Locate_types::Face_location& query_location, +locate_in_common_face(typename Locate_types::Face_location& known_location, + const typename Locate_types::Point& query, + typename Locate_types::Face_location& query_location, const TriangleMesh& tm, - const typename internal::Locate_types::FT tolerance = - std::numeric_limits::FT>::epsilon()) + const typename Locate_types::FT tolerance = + std::numeric_limits::FT>::epsilon()) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -1346,8 +1488,8 @@ locate_in_common_face(typename internal::Locate_types::Face_locati // - both locations must be known but can change template bool -locate_in_common_face(typename internal::Locate_types::Face_location& first_location, - typename internal::Locate_types::Face_location& second_location, +locate_in_common_face(typename Locate_types::Face_location& first_location, + typename Locate_types::Face_location& second_location, const TriangleMesh& tm) { typedef typename boost::graph_traits::face_descriptor face_descriptor; @@ -1407,6 +1549,7 @@ locate_in_common_face(typename internal::Locate_types::Face_locati CGAL_postcondition(first_location.first == second_location.first); return true; } +#endif // DOXYGEN_RUNNING /// @} @@ -1417,19 +1560,17 @@ template::value> struct Point_to_Point_3 // 2D case { - typedef typename internal::Locate_types::Kernel K; - typedef typename K::Point_3 Point_3; + typedef typename Locate_types::Geom_traits::Point_3 Point_3; Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), 0); } }; template struct Point_to_Point_3::Kernel::Point_3, + typename Locate_types::Geom_traits::Point_3, 3> // 3D case with nothing to do { - typedef typename internal::Locate_types::Kernel K; - typedef typename K::Point_3 Point_3; + typedef typename Locate_types::Geom_traits::Point_3 Point_3; const Point_3& operator()(const Point_3& p) const { return p; } }; @@ -1437,8 +1578,7 @@ struct Point_to_Point_3 struct Point_to_Point_3 // Generic 3D case { - typedef typename internal::Locate_types::Kernel K; - typedef typename K::Point_3 Point_3; + typedef typename Locate_types::Geom_traits::Point_3 Point_3; Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), p.z()); } }; @@ -1446,10 +1586,10 @@ struct Point_to_Point_3 // Generic 3D case template struct Ray_to_Ray_3 // 2D case { - typedef typename internal::Locate_types::Kernel K; - typedef typename K::Ray_2 Ray_2; - typedef typename K::Ray_3 Ray_3; - typedef Point_to_Point_3 P2_to_P3; + typedef typename Locate_types::Geom_traits Geom_traits; + typedef typename Geom_traits::Ray_2 Ray_2; + typedef typename Geom_traits::Ray_3 Ray_3; + typedef Point_to_Point_3 P2_to_P3; Ray_3 operator()(const Ray_2& r) const { @@ -1460,7 +1600,7 @@ struct Ray_to_Ray_3 // 2D case const Ray_3& operator()(const Ray_3& r) const { return r; } }; -/// Readable property map that converts the output of a given vertex point map to a 3D point +// Readable property map that converts the output of a given vertex point map to a 3D point template::const_type> @@ -1543,6 +1683,8 @@ void build_AABB_tree(const TriangleMesh& tm, /// \name Nearest Face Location Queries /// @{ +/// \ingroup PMP_locate_grp +/// /// \brief creates an `AABB_tree` suitable for use with `locate_with_AABB_tree()`. /// /// \details This function should be called to create and cache an AABB tree @@ -1577,13 +1719,17 @@ void build_AABB_tree(const TriangleMesh& tm, return internal::build_AABB_tree(tm, outTree, vpm); } +#ifndef DOXYGEN_RUNNING template void build_AABB_tree(const TriangleMesh& tm, AABB_tree& outTree) { return build_AABB_tree(tm, outTree, parameters::all_default()); } +#endif +/// \ingroup PMP_locate_grp +/// /// \brief returns the face location nearest to the given point, as a `Face_location`. /// /// \tparam TriangleMesh A model of `FaceListGraph` @@ -1604,13 +1750,13 @@ void build_AABB_tree(const TriangleMesh& tm, /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename internal::Locate_types::Point& p, +typename Locate_types::Face_location +locate_with_AABB_tree(const typename Locate_types::Point& p, const AABB_tree& tree, const TriangleMesh& tm, const NamedParameters& np) { - typedef typename internal::Locate_types::Point Point; + typedef typename Locate_types::Point Point; typedef internal::Point_to_Point_3 P_to_P3; typedef typename AABBTraits::Point_3 Point_3; CGAL_static_assertion((std::is_same::value)); @@ -1631,15 +1777,19 @@ locate_with_AABB_tree(const typename internal::Locate_types -typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename internal::Locate_types::Point& p, +typename Locate_types::Face_location +locate_with_AABB_tree(const typename Locate_types::Point& p, const AABB_tree& tree, const TriangleMesh& tm) { return locate_with_AABB_tree(p, tree, tm, parameters::all_default()); } +#endif +/// \ingroup PMP_locate_grp +/// /// \brief returns the nearest face location to the given point. /// /// \details Note that this function will build an `AABB_tree` on each call. If you need @@ -1664,8 +1814,8 @@ locate_with_AABB_tree(const typename internal::Locate_types::Point /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate(const typename internal::Locate_types::Point& p, +typename Locate_types::Face_location +locate(const typename Locate_types::Point& p, const TriangleMesh& tm, const NamedParameters& np) { @@ -1673,11 +1823,11 @@ locate(const typename internal::Locate_types::Poi // already has value type Kernel::Point_3) typedef typename GetVertexPointMap::const_type VertexPointMap; typedef internal::Point_to_Point_3_VPM WrappedVPM; - typedef typename internal::Locate_types::Point Intrinsic_point; + typedef typename Locate_types::Point Intrinsic_point; typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; typedef CGAL::AABB_traits< - typename internal::Locate_types::Kernel, + typename Locate_types::Geom_traits, AABB_face_graph_primitive> AABB_face_graph_traits; typedef internal::Point_to_Point_3 P_to_P3; @@ -1693,39 +1843,21 @@ locate(const typename internal::Locate_types::Poi build_AABB_tree(tm, tree, parameters::vertex_point_map(wrapped_vpm)); const Point_3& p3 = P_to_P3()(p); - return locate_with_AABB_tree(p3, tree, tm, parameters::vertex_point_map(wrapped_vpm)); } +#ifndef DOXYGEN_RUNNING template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate(const typename property_map_value::type& p, const TriangleMesh& tm) { return locate(p, tm, parameters::all_default()); } +#endif -namespace internal { - -// The Ray must have the same ambient dimension as the property map's value type (aka, the point type) - -template ::value> -struct Ray_type_selector -{ - typedef typename CGAL::Kernel_traits::type Kernel; - typedef typename Kernel::Ray_2 type; -}; - -template -struct Ray_type_selector -{ - typedef typename CGAL::Kernel_traits::type Kernel; - typedef typename Kernel::Ray_3 type; -}; - -} // end namespace internal - +/// \ingroup PMP_locate_grp +/// /// \brief Returns the face location along `ray` nearest to its source point. /// /// \tparam TriangleMesh must be a model of `FaceListGraph`. @@ -1743,21 +1875,23 @@ struct Ray_type_selector /// If this parameter is omitted, an internal property map for /// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd +/// \cgalParamBegin{geom_traits} +/// a geometric traits class instance, model of `Kernel`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename internal::Ray_type_selector< - typename internal::Locate_types::Point>::type& ray, +typename Locate_types::Face_location +locate_with_AABB_tree(const typename Locate_types::Ray& ray, const AABB_tree& tree, const TriangleMesh& tm, const NamedParameters& np) { - typedef typename internal::Locate_types::Kernel Kernel; + typedef typename Locate_types::Geom_traits Geom_traits; - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_3 Point_3; - typedef typename Kernel::Ray_3 Ray_3; + typedef typename Geom_traits::FT FT; + typedef typename Geom_traits::Point_3 Point_3; + typedef typename Geom_traits::Ray_3 Ray_3; typedef typename boost::graph_traits::face_descriptor face_descriptor; @@ -1815,16 +1949,18 @@ locate_with_AABB_tree(const typename internal::Ray_type_selector< CGAL::make_array(FT(0), FT(0), FT(0))); } +#ifndef DOXYGEN_RUNNING template -typename internal::Locate_types::Face_location -locate_with_AABB_tree(const typename internal::Ray_type_selector< - typename internal::Locate_types::Point>::type& ray, +typename Locate_types::Face_location +locate_with_AABB_tree(const typename Locate_types::Ray& ray, const AABB_tree& tree, const TriangleMesh& tm) { return locate_with_AABB_tree(ray, tree, tm, parameters::all_default()); } +#endif +/// \ingroup PMP_locate_grp /// /// \brief Returns the face location along `ray` nearest to its source point. /// @@ -1838,6 +1974,7 @@ locate_with_AABB_tree(const typename internal::Ray_type_selector< /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param ray Ray to intersect with the input triangulated surface mesh +/// \param tm the input triangulated surface mesh /// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: /// /// \cgalNamedParamsBegin @@ -1846,23 +1983,25 @@ locate_with_AABB_tree(const typename internal::Ray_type_selector< /// If this parameter is omitted, an internal property map for /// `boost::vertex_point_t` should be available in `TriangleMesh`. /// \cgalParamEnd +/// \cgalParamBegin{geom_traits} +/// a geometric traits class instance, model of `Kernel`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template -typename internal::Locate_types::Face_location -locate(const typename internal::Ray_type_selector< - typename internal::Locate_types::Point>::type& ray, +typename Locate_types::Face_location +locate(const typename Locate_types::Ray& ray, const TriangleMesh& tm, const NamedParameters& np) { typedef typename GetVertexPointMap::const_type VertexPointMap; // Wrap the input VPM with a one converting to 3D (costs nothing if the input VPM - // already has value type Kernel::Point_3) + // already has value type Geom_traits::Point_3) typedef internal::Point_to_Point_3_VPM VPM; typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; - typedef CGAL::AABB_traits::Kernel, + typedef CGAL::AABB_traits::Geom_traits, AABB_face_graph_primitive> AABB_face_graph_traits; const VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), @@ -1875,14 +2014,16 @@ locate(const typename internal::Ray_type_selector< return locate_with_AABB_tree(ray, tree, tm, np); } +#ifndef DOXYGEN_RUNNING template -typename internal::Locate_types::Face_location +typename Locate_types::Face_location locate(const typename internal::Ray_type_selector< - typename internal::Locate_types::Point>::type& ray, + typename Locate_types::Point>::type& ray, const TriangleMesh& tm) { return locate(ray, tm, parameters::all_default()); } +#endif /// @} diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 2f080cd4676..ccfbdb45cd1 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -97,10 +97,10 @@ void test_snappers(const G& g) { std::cout << " test snappers..." << std::endl; - typedef typename PMP::internal::Locate_types::FT FT; + typedef typename PMP::Locate_types::FT FT; - typename PMP::internal::Locate_types::Barycentric_coordinates coords = CGAL::make_array(FT(1e-11), FT(0.99999999999999999), FT(1e-12)); - typename PMP::internal::Locate_types::Face_location loc = std::make_pair(*(faces(g).first), coords); + typename PMP::Locate_types::Barycentric_coordinates coords = CGAL::make_array(FT(1e-11), FT(0.99999999999999999), FT(1e-12)); + typename PMP::Locate_types::Face_location loc = std::make_pair(*(faces(g).first), coords); // --------------------------------------------------------------------------- PMP::internal::snap_coordinates_to_border(coords); // uses numeric_limits' epsilon() @@ -138,15 +138,15 @@ void test_constructions(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::descriptor_variant descriptor_variant; + typedef typename PMP::Locate_types::descriptor_variant descriptor_variant; typedef typename boost::property_map_value::type Point; typedef typename CGAL::Kernel_traits::type Kernel; typedef typename Kernel::FT FT; typedef typename Point_to_bare_point::type Bare_point; - typedef typename PMP::internal::Locate_types::Barycentric_coordinates Barycentric_coordinates; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Barycentric_coordinates Barycentric_coordinates; + typedef typename PMP::Locate_types::Face_location Face_location; typedef typename boost::property_map::const_type VPM; VPM vpm = CGAL::get_const_property_map(boost::vertex_point, g); @@ -226,7 +226,7 @@ void test_random_entities(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Face_location Face_location; typedef typename boost::property_map_value::type Point; typedef typename CGAL::Kernel_traits::type Kernel; @@ -312,7 +312,7 @@ void test_helpers(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Face_location Face_location; face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); @@ -390,7 +390,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Face_location Face_location; face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); @@ -482,7 +482,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Face_location Face_location; typedef typename boost::property_map::const_type VertexPointMap; VertexPointMap vpm = CGAL::get_const_property_map(boost::vertex_point, g); @@ -492,7 +492,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) const vertex_descriptor v = target(h, g); Face_location loc; - typename PMP::internal::Locate_types::FT a = 0.1; + typename PMP::Locate_types::FT a = 0.1; Point p = get(vpm, v); loc = PMP::locate_in_face(v, g); @@ -563,7 +563,7 @@ struct Locate_with_AABB_tree_Tester // 2D case typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Face_location Face_location; face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); @@ -669,14 +669,14 @@ struct Locate_with_AABB_tree_Tester<3> // 3D typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::internal::Locate_types::Face_location Face_location; + typedef typename PMP::Locate_types::Face_location Face_location; face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = target(h, g); // --------------------------------------------------------------------------- - typedef typename PMP::internal::Locate_types::VPM VertexPointMap; + typedef typename PMP::Locate_types::VPM VertexPointMap; typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; typedef CGAL::AABB_traits AABB_face_graph_traits; @@ -754,7 +754,7 @@ void test_locate(const G& g, CGAL::Random& rnd) // This test has slight syntax changes between 2D and 3D (e.g. testing ray_2 in 3D makes no sense) Locate_with_AABB_tree_Tester< - CGAL::Ambient_dimension::Point>::value>()(g, rnd); + CGAL::Ambient_dimension::Point>::value>()(g, rnd); } template From c1fb9534802ffea63c6007ff6d21c9e6600926eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 13:38:55 +0200 Subject: [PATCH 34/68] Rename 'Location_to_point()' to 'construct_point()' --- .../CGAL/Polygon_mesh_processing/locate.h | 12 ++++++------ .../test_pmp_locate.cpp | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 4f3dfe5aa87..7c5065f9057 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -778,9 +778,9 @@ get_descriptor_from_location(const typename Locate_types::Face_loc /// template typename Locate_types::Point -location_to_point(const typename Locate_types::Face_location& loc, - const TriangleMesh& tm, - const NamedParameters& np) +construct_point(const typename Locate_types::Face_location& loc, + const TriangleMesh& tm, + const NamedParameters& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename GetVertexPointMap::const_type VertexPointMap; @@ -805,10 +805,10 @@ location_to_point(const typename Locate_types::Face_location& loc, template typename property_map_value::type -location_to_point(const typename Locate_types::Face_location& loc, - const TriangleMesh& tm) +construct_point(const typename Locate_types::Face_location& loc, + const TriangleMesh& tm) { - return location_to_point(loc, tm, parameters::all_default()); + return construct_point(loc, tm, parameters::all_default()); } /// \name Location Predicates diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index ccfbdb45cd1..fc7ca8d41b5 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -191,7 +191,7 @@ void test_constructions(const G& g, CGAL::Random& rnd) assert(is_equal(bar[0], a) && is_equal(bar[1], b) && is_equal(bar[2], c)); loc.second = bar; - const FT sq_dist = CGAL::squared_distance(barycentric_pt, Bare_point(PMP::location_to_point(loc, g))); + const FT sq_dist = CGAL::squared_distance(barycentric_pt, Bare_point(PMP::construct_point(loc, g))); assert(is_equal(sq_dist, FT(0))); } @@ -211,8 +211,8 @@ void test_constructions(const G& g, CGAL::Random& rnd) assert(bool(boost::get(&dv))); // --------------------------------------------------------------------------- - Point s = PMP::location_to_point(loc, g, CGAL::parameters::all_default()); - s = PMP::location_to_point(loc, g); + Point s = PMP::construct_point(loc, g, CGAL::parameters::all_default()); + s = PMP::construct_point(loc, g); assert(s == get(vpm, source(halfedge(f, g), g))); } @@ -600,14 +600,14 @@ struct Locate_with_AABB_tree_Tester // 2D case assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); - assert(is_equal(CGAL::squared_distance(to_p3(PMP::location_to_point(loc, g)), p3_a), FT(0))); + assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0))); loc = PMP::locate_with_AABB_tree(p_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); - assert(is_equal(CGAL::squared_distance(to_p3(PMP::location_to_point(loc, g)), p3_a), FT(0))); + assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0))); // --------------------------------------------------------------------------- loc = PMP::locate(p_a, g); - assert(is_equal(CGAL::squared_distance(to_p3(PMP::location_to_point(loc, g)), p3_a), FT(0))); + assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0))); assert(PMP::is_in_face(loc, g)); loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); @@ -716,14 +716,14 @@ struct Locate_with_AABB_tree_Tester<3> // 3D assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); - assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); - assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); // --------------------------------------------------------------------------- loc = PMP::locate(p3_a, g); - assert(is_equal(CGAL::squared_distance(PMP::location_to_point(loc, g), p3_a), FT(0))); + assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); assert(PMP::is_in_face(loc, g)); loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); From 1e21492b9e9ab91539b1fdbe52a94a630ce089d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 14:37:03 +0200 Subject: [PATCH 35/68] Extract polyhedron genetion functions from helpers.h into a new header --- BGL/include/CGAL/boost/graph/helpers.h | 688 +-------------------- BGL/include/CGAL/boost/graph/polyhedra.h | 736 +++++++++++++++++++++++ 2 files changed, 738 insertions(+), 686 deletions(-) create mode 100644 BGL/include/CGAL/boost/graph/polyhedra.h diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 85a468bf33a..75b8f0d0ee4 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -21,29 +21,17 @@ #ifndef CGAL_BOOST_GRAPH_HELPERS_H #define CGAL_BOOST_GRAPH_HELPERS_H - -#include +#include #include #include #include #include -#include #include +#include namespace CGAL { - namespace Euler { - - template< typename Graph> - void fill_hole(typename boost::graph_traits::halfedge_descriptor h, - Graph& g); - - template - typename boost::graph_traits::face_descriptor add_face(const VertexRange& vr, - Graph& g); - }//Euler - /*! \ingroup PkgBGLHelperFct returns `true` if the halfedge `hd` is on a border. @@ -683,674 +671,6 @@ bool is_hexahedron( typename boost::graph_traits::halfedge_descriptor return true; } - - -/** - * \ingroup PkgBGLHelperFct - * \brief Creates an isolated triangle - * with its vertices initialized to `p0`, `p1` and `p2`, and adds it to the graph `g`. - * \returns the non-border halfedge that has the target vertex associated with `p0`. - **/ -template -typename boost::graph_traits::halfedge_descriptor -make_triangle(const P& p0, const P& p1, const P& p2, Graph& g) -{ - typedef typename boost::graph_traits Traits; - typedef typename Traits::halfedge_descriptor halfedge_descriptor; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename Traits::face_descriptor face_descriptor; - typedef typename boost::property_map::type Point_property_map; - Point_property_map ppmap = get(CGAL::vertex_point, g); - vertex_descriptor v0, v1, v2; - v0 = add_vertex(g); - v1 = add_vertex(g); - v2 = add_vertex(g); - - ppmap[v0] = p0; - ppmap[v1] = p1; - ppmap[v2] = p2; - halfedge_descriptor h0 = halfedge(add_edge(g),g); - halfedge_descriptor h1 = halfedge(add_edge(g),g); - halfedge_descriptor h2 = halfedge(add_edge(g),g); - set_next(h0, h1, g); - set_next(h1, h2, g); - set_next(h2, h0, g); - set_target(h0, v1, g); - set_target(h1, v2, g); - set_target(h2, v0, g); - set_halfedge(v1, h0, g); - set_halfedge(v2, h1, g); - set_halfedge(v0, h2, g); - face_descriptor f = add_face(g); - set_face(h0,f,g); - set_face(h1,f,g); - set_face(h2,f,g); - set_halfedge(f,h0,g); - h0 = opposite(h0,g); - h1 = opposite(h1,g); - h2 = opposite(h2,g); - set_next(h0, h2, g); - set_next(h2, h1, g); - set_next(h1, h0, g); - set_target(h0, v0, g); - set_target(h1, v1, g); - set_target(h2, v2, g); - set_face(h0, boost::graph_traits::null_face(),g); - set_face(h1, boost::graph_traits::null_face(),g); - set_face(h2, boost::graph_traits::null_face(),g); - return opposite(h2,g); -} - -namespace internal { - -template -typename boost::graph_traits::halfedge_descriptor -make_quad(typename boost::graph_traits::vertex_descriptor v0, - typename boost::graph_traits::vertex_descriptor v1, - typename boost::graph_traits::vertex_descriptor v2, - typename boost::graph_traits::vertex_descriptor v3, Graph& g) -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - halfedge_descriptor h0 = halfedge(add_edge(g),g); - halfedge_descriptor h1 = halfedge(add_edge(g),g); - halfedge_descriptor h2 = halfedge(add_edge(g),g); - halfedge_descriptor h3 = halfedge(add_edge(g),g); - set_next(h0, h1, g); - set_next(h1, h2, g); - set_next(h2, h3, g); - set_next(h3, h0, g); - set_target(h0, v1, g); - set_target(h1, v2, g); - set_target(h2, v3, g); - set_target(h3, v0, g); - set_halfedge(v1, h0, g); - set_halfedge(v2, h1, g); - set_halfedge(v3, h2, g); - set_halfedge(v0, h3, g); - face_descriptor f = add_face(g); - set_face(h0,f,g); - set_face(h1,f,g); - set_face(h2,f,g); - set_face(h3,f,g); - set_halfedge(f,h0,g); - h0 = opposite(h0,g); - h1 = opposite(h1,g); - h2 = opposite(h2,g); - h3 = opposite(h3,g); - set_next(h0, h3, g); - set_next(h3, h2, g); - set_next(h2, h1, g); - set_next(h1, h0, g); - set_target(h0, v0, g); - set_target(h1, v1, g); - set_target(h2, v2, g); - set_target(h3, v3, g); - set_face(h0, boost::graph_traits::null_face(),g); - set_face(h1, boost::graph_traits::null_face(),g); - set_face(h2, boost::graph_traits::null_face(),g); - set_face(h3, boost::graph_traits::null_face(),g); - return opposite(h3,g); -} - -//default Functor for make_grid -template -struct Default_grid_maker - : public CGAL::Creator_uniform_3 -{ - Point operator()(const Size_type& i, const Size_type& j)const - { - return CGAL::Creator_uniform_3::operator ()(i,j,0); - } -}; -} // namespace internal - -/** - * \ingroup PkgBGLHelperFct - * \brief Creates an isolated quad with - * its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`. - * \returns the non-border halfedge that has the target vertex associated with `p0`. - **/ -template -typename boost::graph_traits::halfedge_descriptor -make_quad(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g) -{ - typedef typename boost::graph_traits Traits; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename boost::property_map::type Point_property_map; - Point_property_map ppmap = get(CGAL::vertex_point, g); - vertex_descriptor v0, v1, v2, v3; - v0 = add_vertex(g); - v1 = add_vertex(g); - v2 = add_vertex(g); - v3 = add_vertex(g); - - ppmap[v0] = p0; - ppmap[v1] = p1; - ppmap[v2] = p2; - ppmap[v3] = p3; - return internal::make_quad(v0, v1, v2, v3, g); -} - -/** - * \ingroup PkgBGLHelperFct - * \brief Creates an isolated hexahedron - * with its vertices initialized to `p0`, `p1`, ...\ , and `p7`, and adds it to the graph `g`. - * \image html hexahedron.png - * \image latex hexahedron.png - * \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`. - **/ -template -typename boost::graph_traits::halfedge_descriptor -make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3, - const P& p4, const P& p5, const P& p6, const P& p7, Graph& g) -{ - typedef typename boost::graph_traits Traits; - typedef typename Traits::halfedge_descriptor halfedge_descriptor; - typedef typename Traits::vertex_descriptor vertex_descriptor; - - typedef typename boost::property_map::type Point_property_map; - Point_property_map ppmap = get(CGAL::vertex_point, g); - vertex_descriptor v0, v1, v2, v3, v4, v5, v6, v7; - v0 = add_vertex(g); - v1 = add_vertex(g); - v2 = add_vertex(g); - v3 = add_vertex(g); - v4 = add_vertex(g); - v5 = add_vertex(g); - v6 = add_vertex(g); - v7 = add_vertex(g); - ppmap[v0] = p0; - ppmap[v1] = p1; - ppmap[v2] = p2; - ppmap[v3] = p3; - ppmap[v4] = p4; - ppmap[v5] = p5; - ppmap[v6] = p6; - ppmap[v7] = p7; - - halfedge_descriptor ht = internal::make_quad(v4, v5, v6, v7, g); - halfedge_descriptor hb = prev(internal::make_quad(v0, v3, v2, v1, g),g); - for(int i=0; i <4; i++){ - halfedge_descriptor h = halfedge(add_edge(g),g); - set_target(h,target(hb,g),g); - set_next(h,opposite(hb,g),g); - set_next(opposite(prev(ht,g),g),h,g); - h = opposite(h,g); - set_target(h,source(prev(ht,g),g),g); - set_next(h,opposite(next(next(ht,g),g),g),g); - set_next(opposite(next(hb,g),g),h,g); - hb = next(hb,g); - ht = prev(ht,g); - } - for(int i=0; i <4; i++){ - Euler::fill_hole(opposite(hb,g),g); - hb = next(hb,g); - } - return next(next(hb,g),g); -} -/** - * \ingroup PkgBGLHelperFct - * \brief Creates an isolated tetrahedron - * with its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`. - * \image html tetrahedron.png - * \image latex tetrahedron.png - * \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, and `p2`. - **/ -template -typename boost::graph_traits::halfedge_descriptor -make_tetrahedron(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g) -{ - typedef typename boost::graph_traits Traits; - typedef typename Traits::halfedge_descriptor halfedge_descriptor; - typedef typename Traits::vertex_descriptor vertex_descriptor; - typedef typename Traits::face_descriptor face_descriptor; - typedef typename boost::property_map::type Point_property_map; - - Point_property_map ppmap = get(CGAL::vertex_point, g); - vertex_descriptor v0, v1, v2, v3; - v0 = add_vertex(g); - v2 = add_vertex(g); // this and the next line are switched to keep points in order - v1 = add_vertex(g); - v3 = add_vertex(g); - - ppmap[v0] = p0; - ppmap[v1] = p2;// this and the next line are switched to reorient the surface - ppmap[v2] = p1; - ppmap[v3] = p3; - halfedge_descriptor h0 = halfedge(add_edge(g),g); - halfedge_descriptor h1 = halfedge(add_edge(g),g); - halfedge_descriptor h2 = halfedge(add_edge(g),g); - set_next(h0, h1, g); - set_next(h1, h2, g); - set_next(h2, h0, g); - set_target(h0, v1, g); - set_target(h1, v2, g); - set_target(h2, v0, g); - set_halfedge(v1, h0, g); - set_halfedge(v2, h1, g); - set_halfedge(v0, h2, g); - face_descriptor f = add_face(g); - set_face(h0,f,g); - set_face(h1,f,g); - set_face(h2,f,g); - set_halfedge(f,h0,g); - h0 = opposite(h0,g); - h1 = opposite(h1,g); - h2 = opposite(h2,g); - set_next(h0, h2, g); - set_next(h2, h1, g); - set_next(h1, h0, g); - set_target(h0, v0, g); - set_target(h1, v1, g); - set_target(h2, v2, g); - halfedge_descriptor h3 = halfedge(add_edge(g),g); - halfedge_descriptor h4 = halfedge(add_edge(g),g); - halfedge_descriptor h5 = halfedge(add_edge(g),g); - set_target(h3, v3, g); - set_target(h4, v3, g); - set_target(h5, v3, g); - set_halfedge(v3, h3, g); - - set_next(h0, h3, g); - set_next(h1, h4, g); - set_next(h2, h5, g); - - set_next(h3, opposite(h4,g), g); - set_next(h4, opposite(h5,g), g); - set_next(h5, opposite(h3,g), g); - set_next(opposite(h4,g), h0, g); - set_next(opposite(h5,g), h1, g); - set_next(opposite(h3,g), h2, g); - - set_target(opposite(h3,g), v0, g); - set_target(opposite(h4,g), v1, g); - set_target(opposite(h5,g), v2, g); - - f = add_face(g); - set_halfedge(f,h0,g); - set_face(h0, f, g); - set_face(h3, f, g); - set_face(opposite(h4,g), f, g); - f = add_face(g); - set_halfedge(f,h1,g); - set_face(h1, f, g); - set_face(h4, f, g); - set_face(opposite(h5,g), f, g); - f = add_face(g); - set_halfedge(f,h2,g); - set_face(h2, f, g); - set_face(h5, f, g); - set_face(opposite(h3,g), f, g); - - return opposite(h2,g); -} - -/** - * \ingroup PkgBGLHelperFct - * \brief Creates a triangulated regular prism, outward oriented, - * having `nb_vertices` vertices in each of its bases and adds it to the graph `g`. - * If `center` is (0, 0, 0), then the first point of the prism is (`radius`, `height`, 0) - * \param nb_vertices the number of vertices per base. It must be greater than or equal to 3. - * \param g the graph in which the regular prism will be created. - * \param base_center the center of the circle in which the lower base is inscribed. - * \param height the distance between the two bases. - * \param radius the radius of the circles in which the bases are inscribed. - * \param is_closed determines if the bases must be created or not. If `is_closed` is `true`, `center` is a vertex. - * \returns the halfedge that has the target vertex associated with the first point in the first face. - */ -template -typename boost::graph_traits::halfedge_descriptor -make_regular_prism( - typename boost::graph_traits::vertices_size_type nb_vertices, - Graph& g, - const P& base_center = P(0,0,0), - typename CGAL::Kernel_traits

::Kernel::FT height = 1.0, - typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0, - bool is_closed = true) -{ - CGAL_assertion(nb_vertices >= 3); - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename CGAL::Kernel_traits

::Kernel::FT FT; - - const FT to_rad = CGAL_PI / 180.0; - const FT precision = 360.0/nb_vertices; - const FT diameter = 2*radius; - Point_property_map vpmap = get(CGAL::vertex_point, g); - std::vector vertices; - vertices.resize(nb_vertices*2); - for(typename boost::graph_traits::vertices_size_type i=0; i::vertices_size_type i=0; i < nb_vertices; ++i) - { - put(vpmap, - vertices[i], - P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(), - height+base_center.y(), - -0.5*diameter*sin(i*precision*to_rad) + base_center.z())); - - put(vpmap, - vertices[i+nb_vertices], - P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(), - base_center.y(), - -0.5*diameter*sin(i*precision*to_rad)+base_center.z())); - } - std::vector face; - face.resize(3); - //fill faces - for(typename boost::graph_traits::vertices_size_type i=0; i::vertices_size_type i=0; i -typename boost::graph_traits::halfedge_descriptor -make_pyramid( - typename boost::graph_traits::vertices_size_type nb_vertices, - Graph& g, - const P& base_center = P(0,0,0), - typename CGAL::Kernel_traits

::Kernel::FT height = 1.0, - typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0, - bool is_closed = true) -{ - CGAL_assertion(nb_vertices >= 3); - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename CGAL::Kernel_traits

::Kernel::FT FT; - const FT to_rad = CGAL_PI / 180.0; - const FT precision = 360.0/nb_vertices; - const FT diameter = 2*radius; - Point_property_map vpmap = get(CGAL::vertex_point, g); - std::vector vertices; - vertices.resize(nb_vertices); - for(typename boost::graph_traits::vertices_size_type i=0; - i::vertices_size_type i=0; - i < nb_vertices; ++i) - { - - put(vpmap, - vertices[i], - P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(), - base_center.y(), - -0.5*diameter*sin(i*precision*to_rad)+base_center.z())); - } - std::vector face; - face.resize(3); - //fill faces - for(typename boost::graph_traits::vertices_size_type i=0; - i::vertices_size_type i=0; - i -typename boost::graph_traits::halfedge_descriptor -make_icosahedron( - Graph& g, - const P& center = P(0,0,0), - typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0) -{ - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - Point_property_map vpmap = get(CGAL::vertex_point, g); - // create the initial icosahedron - std::vector v_vertices; - v_vertices.resize(12); - for(int i=0; i<12; ++i) - v_vertices[i] = add_vertex(g); - typename CGAL::Kernel_traits

::Kernel::FT t = - (radius + radius*CGAL::approximate_sqrt(5.0)) / 2.0; - - put(vpmap, v_vertices[0],P(-radius + center.x(), t + center.y(), 0.0 + center.z())); - put(vpmap, v_vertices[1],P( radius + center.x(), t + center.y(), 0.0 + center.z())); - put(vpmap, v_vertices[2],P(-radius + center.x(), -t + center.y(), 0.0 + center.z())); - put(vpmap, v_vertices[3],P( radius + center.x(), -t + center.y(), 0.0 + center.z())); - - put(vpmap, v_vertices[4],P( 0.0 + center.x(), -radius + center.y(), t + center.z())); - put(vpmap, v_vertices[5],P( 0.0 + center.x(), radius + center.y(), t + center.z())); - put(vpmap, v_vertices[6],P( 0.0 + center.x(), -radius + center.y(), -t + center.z())); - put(vpmap, v_vertices[7],P( 0.0 + center.x(), radius + center.y(), -t + center.z())); - - put(vpmap, v_vertices[8],P( t + center.x(), 0.0 + center.y(), -radius + center.z())); - put(vpmap, v_vertices[9],P( t + center.x(), 0.0 + center.y(), radius + center.z())); - put(vpmap, v_vertices[10],P(-t + center.x(), 0.0 + center.y(), -radius + center.z())); - put(vpmap, v_vertices[11],P(-t + center.x(), 0.0 + center.y(), radius + center.z())); - - std::vector face; - face.resize(3); - face[1] = v_vertices[0]; face[0] = v_vertices[5]; face[2] = v_vertices[11]; - Euler::add_face(face, g); - face[1] = v_vertices[0]; face[0] = v_vertices[1]; face[2] = v_vertices[5]; - Euler::add_face(face, g); - face[1] = v_vertices[0]; face[0] = v_vertices[7]; face[2] = v_vertices[1]; - Euler::add_face(face, g); - face[1] = v_vertices[0]; face[0] = v_vertices[10]; face[2] = v_vertices[7]; - Euler::add_face(face, g); - face[1] = v_vertices[0]; face[0] = v_vertices[11]; face[2] = v_vertices[10]; - Euler::add_face(face, g); - - face[1] = v_vertices[1] ; face[0] = v_vertices[9] ; face[2] = v_vertices[5]; - Euler::add_face(face, g); - face[1] = v_vertices[5] ; face[0] = v_vertices[4]; face[2] = v_vertices[11]; - Euler::add_face(face, g); - face[1] = v_vertices[11]; face[0] = v_vertices[2]; face[2] = v_vertices[10]; - Euler::add_face(face, g); - face[1] = v_vertices[10]; face[0] = v_vertices[6] ; face[2] = v_vertices[7]; - Euler::add_face(face, g); - face[1] = v_vertices[7] ; face[0] = v_vertices[8] ; face[2] = v_vertices[1]; - Euler::add_face(face, g); - - face[1] = v_vertices[3] ; face[0] = v_vertices[4] ; face[2] = v_vertices[9]; - Euler::add_face(face, g); - face[1] = v_vertices[3] ; face[0] = v_vertices[2] ; face[2] = v_vertices[4]; - Euler::add_face(face, g); - face[1] = v_vertices[3] ; face[0] = v_vertices[6] ; face[2] = v_vertices[2]; - Euler::add_face(face, g); - face[1] = v_vertices[3] ; face[0] = v_vertices[8] ; face[2] = v_vertices[6]; - Euler::add_face(face, g); - face[1] = v_vertices[3] ; face[0] = v_vertices[9] ; face[2] = v_vertices[8]; - Euler::add_face(face, g); - - face[1] = v_vertices[4] ; face[0] = v_vertices[5] ; face[2] = v_vertices[9] ; - Euler::add_face(face, g); - face[1] = v_vertices[2] ; face[0] = v_vertices[11] ; face[2] = v_vertices[4]; - Euler::add_face(face, g); - face[1] = v_vertices[6] ; face[0] = v_vertices[10] ; face[2] = v_vertices[2]; - Euler::add_face(face, g); - face[1] = v_vertices[8] ; face[0] = v_vertices[7] ; face[2] = v_vertices[6] ; - Euler::add_face(face, g); - face[1] = v_vertices[9] ; face[0] = v_vertices[1] ; face[2] = v_vertices[8] ; - Euler::add_face(face, g); - - return halfedge(v_vertices[1], v_vertices[0], g).first; -} - - -/*! - * \ingroup PkgBGLHelperFct - * - * \brief Creates a row major ordered grid with `i` cells along the width and `j` cells - * along the height and adds it to the graph `g`. - * An internal property map for `CGAL::vertex_point_t` must be available in `Graph`. - * - * \param i the number of cells along the width. - * \param j the number of cells along the height. - * \param g the graph in which the grid will be created. - * \param calculator the functor that will assign coordinates to the grid vertices. - * \param triangulated decides if a cell is composed of one quad or two triangles. - * If `triangulated` is `true`, the diagonal of each cell is oriented from (0,0) to (1,1) - * in the cell coordinates. - *\tparam CoordinateFunctor a function object providing `Point_3 operator()(size_type I, size_type J)` with `Point_3` being - * the value_type of the internal property_map for `CGAL::vertex_point_t`. - * and outputs a `boost::property_traits::%type>::%value_type`. - * It will be called with arguments (`w`, `h`), with `w` in [0..`i`] and `h` in [0..`j`]. - *

%Default: a point with positive integer coordinates (`w`, `h`, 0), with `w` in [0..`i`] and `h` in [0..`j`] - * \returns the non-border non-diagonal halfedge that has the target vertex associated with the first point of the grid (default is (0,0,0) ). - */ -template -typename boost::graph_traits::halfedge_descriptor -make_grid(typename boost::graph_traits::vertices_size_type i, - typename boost::graph_traits::vertices_size_type j, - Graph& g, - const CoordinateFunctor& calculator, - bool triangulated = false) -{ - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typename boost::graph_traits::vertices_size_type w(i+1), h(j+1); - Point_property_map vpmap = get(CGAL::vertex_point, g); - //create the vertices - std::vector v_vertices; - v_vertices.resize(static_cast(w*h)); - for(std::size_t k = 0; k < v_vertices.size(); ++k) - v_vertices[k] = add_vertex(g); - //assign the coordinates - for(typename boost::graph_traits::vertices_size_type a = 0; a::vertices_size_type b=0; b face; - if(triangulated) - face.resize(3); - else - face.resize(4); - for(typename boost::graph_traits::vertices_size_type a = 0; a::vertices_size_type b = 0; b -typename boost::graph_traits::halfedge_descriptor -make_grid(typename boost::graph_traits::vertices_size_type w, - typename boost::graph_traits::vertices_size_type h, - Graph& g, - bool triangulated = false) -{ - typedef typename boost::graph_traits::vertices_size_type Size_type; - typedef typename boost::property_traits::type>::value_type Point; - return make_grid(w, h, g, internal::Default_grid_maker(), triangulated); -} - namespace internal { template @@ -1511,8 +831,4 @@ bool is_empty(const FaceGraph& g) } // namespace CGAL -// Include "Euler_operations.h" at the end, because its implementation -// requires this header. -#include - #endif // CGAL_BOOST_GRAPH_HELPERS_H diff --git a/BGL/include/CGAL/boost/graph/polyhedra.h b/BGL/include/CGAL/boost/graph/polyhedra.h new file mode 100644 index 00000000000..7ed041fbc50 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/polyhedra.h @@ -0,0 +1,736 @@ +// Copyright (c) 2014, 2017 GeometryFactory (France). All rights reserved. +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Maxime Gimeno + +#ifndef CGAL_BOOST_GRAPH_POLYHEDRA_H +#define CGAL_BOOST_GRAPH_POLYHEDRA_H + +#include +#include +#include + +namespace CGAL { +namespace Euler { + +template< typename Graph> +void fill_hole(typename boost::graph_traits::halfedge_descriptor h, + Graph& g); + +template +typename boost::graph_traits::face_descriptor add_face(const VertexRange& vr, + Graph& g); + +} // namespace Euler + +/** + * \ingroup PkgBGLHelperFct + * + * \brief Creates an isolated triangle + * with its vertices initialized to `p0`, `p1` and `p2`, and adds it to the graph `g`. + * + * \returns the non-border halfedge that has the target vertex associated with `p0`. + **/ +template +typename boost::graph_traits::halfedge_descriptor +make_triangle(const P& p0, const P& p1, const P& p2, Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + + typedef typename Traits::face_descriptor face_descriptor; + typedef typename boost::property_map::type Point_property_map; + Point_property_map ppmap = get(CGAL::vertex_point, g); + vertex_descriptor v0, v1, v2; + v0 = add_vertex(g); + v1 = add_vertex(g); + v2 = add_vertex(g); + + ppmap[v0] = p0; + ppmap[v1] = p1; + ppmap[v2] = p2; + halfedge_descriptor h0 = halfedge(add_edge(g), g); + halfedge_descriptor h1 = halfedge(add_edge(g), g); + halfedge_descriptor h2 = halfedge(add_edge(g), g); + set_next(h0, h1, g); + set_next(h1, h2, g); + set_next(h2, h0, g); + set_target(h0, v1, g); + set_target(h1, v2, g); + set_target(h2, v0, g); + set_halfedge(v1, h0, g); + set_halfedge(v2, h1, g); + set_halfedge(v0, h2, g); + face_descriptor f = add_face(g); + set_face(h0, f, g); + set_face(h1, f, g); + set_face(h2, f, g); + set_halfedge(f, h0, g); + h0 = opposite(h0, g); + h1 = opposite(h1, g); + h2 = opposite(h2, g); + set_next(h0, h2, g); + set_next(h2, h1, g); + set_next(h1, h0, g); + set_target(h0, v0, g); + set_target(h1, v1, g); + set_target(h2, v2, g); + set_face(h0, boost::graph_traits::null_face(), g); + set_face(h1, boost::graph_traits::null_face(), g); + set_face(h2, boost::graph_traits::null_face(), g); + + return opposite(h2, g); +} + +namespace internal { + +template +typename boost::graph_traits::halfedge_descriptor +make_quad(typename boost::graph_traits::vertex_descriptor v0, + typename boost::graph_traits::vertex_descriptor v1, + typename boost::graph_traits::vertex_descriptor v2, + typename boost::graph_traits::vertex_descriptor v3, + Graph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + halfedge_descriptor h0 = halfedge(add_edge(g), g); + halfedge_descriptor h1 = halfedge(add_edge(g), g); + halfedge_descriptor h2 = halfedge(add_edge(g), g); + halfedge_descriptor h3 = halfedge(add_edge(g), g); + set_next(h0, h1, g); + set_next(h1, h2, g); + set_next(h2, h3, g); + set_next(h3, h0, g); + set_target(h0, v1, g); + set_target(h1, v2, g); + set_target(h2, v3, g); + set_target(h3, v0, g); + set_halfedge(v1, h0, g); + set_halfedge(v2, h1, g); + set_halfedge(v3, h2, g); + set_halfedge(v0, h3, g); + face_descriptor f = add_face(g); + set_face(h0, f, g); + set_face(h1, f, g); + set_face(h2, f, g); + set_face(h3, f, g); + set_halfedge(f, h0, g); + h0 = opposite(h0, g); + h1 = opposite(h1, g); + h2 = opposite(h2, g); + h3 = opposite(h3, g); + set_next(h0, h3, g); + set_next(h3, h2, g); + set_next(h2, h1, g); + set_next(h1, h0, g); + set_target(h0, v0, g); + set_target(h1, v1, g); + set_target(h2, v2, g); + set_target(h3, v3, g); + set_face(h0, boost::graph_traits::null_face(), g); + set_face(h1, boost::graph_traits::null_face(), g); + set_face(h2, boost::graph_traits::null_face(), g); + set_face(h3, boost::graph_traits::null_face(), g); + return opposite(h3, g); +} + +// default Functor for make_grid +template +struct Default_grid_maker + : public CGAL::Creator_uniform_3 +{ + Point operator()(const Size_type& i, const Size_type& j) const { + return CGAL::Creator_uniform_3::operator ()(i,j,0); + } +}; + +} // namespace internal + +/** + * \ingroup PkgBGLHelperFct + * + * \brief Creates an isolated quad with + * its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`. + * + * \returns the non-border halfedge that has the target vertex associated with `p0`. + **/ +template +typename boost::graph_traits::halfedge_descriptor +make_quad(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename boost::property_map::type Point_property_map; + + Point_property_map ppmap = get(CGAL::vertex_point, g); + + vertex_descriptor v0, v1, v2, v3; + v0 = add_vertex(g); + v1 = add_vertex(g); + v2 = add_vertex(g); + v3 = add_vertex(g); + ppmap[v0] = p0; + ppmap[v1] = p1; + ppmap[v2] = p2; + ppmap[v3] = p3; + + return internal::make_quad(v0, v1, v2, v3, g); +} + +/** + * \ingroup PkgBGLHelperFct + * \brief Creates an isolated hexahedron + * with its vertices initialized to `p0`, `p1`, ...\ , and `p7`, and adds it to the graph `g`. + * \image html hexahedron.png + * \image latex hexahedron.png + * \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`. + **/ +template +typename boost::graph_traits::halfedge_descriptor +make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3, + const P& p4, const P& p5, const P& p6, const P& p7, Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::vertex_descriptor vertex_descriptor; + + typedef typename boost::property_map::type Point_property_map; + Point_property_map ppmap = get(CGAL::vertex_point, g); + + vertex_descriptor v0, v1, v2, v3, v4, v5, v6, v7; + v0 = add_vertex(g); + v1 = add_vertex(g); + v2 = add_vertex(g); + v3 = add_vertex(g); + v4 = add_vertex(g); + v5 = add_vertex(g); + v6 = add_vertex(g); + v7 = add_vertex(g); + ppmap[v0] = p0; + ppmap[v1] = p1; + ppmap[v2] = p2; + ppmap[v3] = p3; + ppmap[v4] = p4; + ppmap[v5] = p5; + ppmap[v6] = p6; + ppmap[v7] = p7; + + halfedge_descriptor ht = internal::make_quad(v4, v5, v6, v7, g); + halfedge_descriptor hb = prev(internal::make_quad(v0, v3, v2, v1, g), g); + for(int i=0; i <4; ++i) + { + halfedge_descriptor h = halfedge(add_edge(g), g); + set_target(h,target(hb, g), g); + set_next(h, opposite(hb, g), g); + set_next(opposite(prev(ht, g), g), h, g); + h = opposite(h, g); + set_target(h, source(prev(ht, g), g), g); + set_next(h, opposite(next(next(ht, g), g), g), g); + set_next(opposite(next(hb, g), g), h, g); + hb = next(hb, g); + ht = prev(ht, g); + } + for(int i=0; i <4; ++i) + { + Euler::fill_hole(opposite(hb, g), g); + hb = next(hb, g); + } + + return next(next(hb, g), g); +} + +/** + * \ingroup PkgBGLHelperFct + * \brief Creates an isolated tetrahedron + * with its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`. + * \image html tetrahedron.png + * \image latex tetrahedron.png + * \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, and `p2`. + **/ +template +typename boost::graph_traits::halfedge_descriptor +make_tetrahedron(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + typedef typename boost::property_map::type Point_property_map; + Point_property_map ppmap = get(CGAL::vertex_point, g); + + vertex_descriptor v0, v1, v2, v3; + v0 = add_vertex(g); + v2 = add_vertex(g); // this and the next line are switched to keep points in order + v1 = add_vertex(g); + v3 = add_vertex(g); + + ppmap[v0] = p0; + ppmap[v1] = p2;// this and the next line are switched to reorient the surface + ppmap[v2] = p1; + ppmap[v3] = p3; + halfedge_descriptor h0 = halfedge(add_edge(g), g); + halfedge_descriptor h1 = halfedge(add_edge(g), g); + halfedge_descriptor h2 = halfedge(add_edge(g), g); + set_next(h0, h1, g); + set_next(h1, h2, g); + set_next(h2, h0, g); + set_target(h0, v1, g); + set_target(h1, v2, g); + set_target(h2, v0, g); + set_halfedge(v1, h0, g); + set_halfedge(v2, h1, g); + set_halfedge(v0, h2, g); + face_descriptor f = add_face(g); + set_face(h0, f, g); + set_face(h1, f, g); + set_face(h2, f, g); + set_halfedge(f, h0, g); + h0 = opposite(h0, g); + h1 = opposite(h1, g); + h2 = opposite(h2, g); + set_next(h0, h2, g); + set_next(h2, h1, g); + set_next(h1, h0, g); + set_target(h0, v0, g); + set_target(h1, v1, g); + set_target(h2, v2, g); + halfedge_descriptor h3 = halfedge(add_edge(g), g); + halfedge_descriptor h4 = halfedge(add_edge(g), g); + halfedge_descriptor h5 = halfedge(add_edge(g), g); + set_target(h3, v3, g); + set_target(h4, v3, g); + set_target(h5, v3, g); + set_halfedge(v3, h3, g); + + set_next(h0, h3, g); + set_next(h1, h4, g); + set_next(h2, h5, g); + + set_next(h3, opposite(h4, g), g); + set_next(h4, opposite(h5, g), g); + set_next(h5, opposite(h3, g), g); + set_next(opposite(h4, g), h0, g); + set_next(opposite(h5, g), h1, g); + set_next(opposite(h3, g), h2, g); + + set_target(opposite(h3, g), v0, g); + set_target(opposite(h4, g), v1, g); + set_target(opposite(h5, g), v2, g); + + f = add_face(g); + set_halfedge(f, h0, g); + set_face(h0, f, g); + set_face(h3, f, g); + set_face(opposite(h4, g), f, g); + f = add_face(g); + set_halfedge(f, h1, g); + set_face(h1, f, g); + set_face(h4, f, g); + set_face(opposite(h5, g), f, g); + f = add_face(g); + set_halfedge(f, h2, g); + set_face(h2, f, g); + set_face(h5, f, g); + set_face(opposite(h3, g), f, g); + + return opposite(h2, g); +} + +/** + * \ingroup PkgBGLHelperFct + * + * \brief Creates a triangulated regular prism, outward oriented, + * having `nb_vertices` vertices in each of its bases and adds it to the graph `g`. + * If `center` is (0, 0, 0), then the first point of the prism is (`radius`, `height`, 0) + * + * \param nb_vertices the number of vertices per base. It must be greater than or equal to 3. + * \param g the graph in which the regular prism will be created. + * \param base_center the center of the circle in which the lower base is inscribed. + * \param height the distance between the two bases. + * \param radius the radius of the circles in which the bases are inscribed. + * \param is_closed determines if the bases must be created or not. If `is_closed` is `true`, `center` is a vertex. + * + * \returns the halfedge that has the target vertex associated with the first point in the first face. + */ +template +typename boost::graph_traits::halfedge_descriptor +make_regular_prism(typename boost::graph_traits::vertices_size_type nb_vertices, + Graph& g, + const P& base_center = P(0,0,0), + typename CGAL::Kernel_traits

::Kernel::FT height = 1.0, + typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0, + bool is_closed = true) +{ + CGAL_assertion(nb_vertices >= 3); + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename CGAL::Kernel_traits

::Kernel::FT FT; + + typedef typename boost::property_map::type Point_property_map; + Point_property_map vpmap = get(CGAL::vertex_point, g); + + const FT to_rad = CGAL_PI / 180.0; + const FT precision = 360.0 / nb_vertices; + const FT diameter = 2 * radius; + + std::vector vertices; + vertices.resize(nb_vertices*2); + for(typename boost::graph_traits::vertices_size_type i=0; i::vertices_size_type i=0; i < nb_vertices; ++i) + { + put(vpmap, vertices[i], + P(0.5*diameter * cos(i*precision*to_rad) + base_center.x(), + height+base_center.y(), + -0.5*diameter * sin(i*precision*to_rad) + base_center.z())); + + put(vpmap, + vertices[i+nb_vertices], + P(0.5*diameter * cos(i*precision*to_rad) + base_center.x(), + base_center.y(), + -0.5*diameter * sin(i*precision*to_rad) + base_center.z())); + } + + //fill faces + std::vector face; + face.resize(3); + for(typename boost::graph_traits::vertices_size_type i=0; i::vertices_size_type i=0; i +typename boost::graph_traits::halfedge_descriptor +make_pyramid(typename boost::graph_traits::vertices_size_type nb_vertices, + Graph& g, + const P& base_center = P(0,0,0), + typename CGAL::Kernel_traits

::Kernel::FT height = 1.0, + typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0, + bool is_closed = true) +{ + CGAL_assertion(nb_vertices >= 3); + + typedef typename boost::property_map::type Point_property_map; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename CGAL::Kernel_traits

::Kernel::FT FT; + + const FT to_rad = CGAL_PI / 180.0; + const FT precision = 360.0/nb_vertices; + const FT diameter = 2*radius; + + Point_property_map vpmap = get(CGAL::vertex_point, g); + + std::vector vertices; + vertices.resize(nb_vertices); + for(typename boost::graph_traits::vertices_size_type i=0; i::vertices_size_type i=0; i face; + face.resize(3); + for(typename boost::graph_traits::vertices_size_type i=0; i::vertices_size_type i=0; i +typename boost::graph_traits::halfedge_descriptor +make_icosahedron(Graph& g, + const P& center = P(0,0,0), + typename CGAL::Kernel_traits

::Kernel::FT radius = 1.0) +{ + typedef typename boost::property_map::type Point_property_map; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + Point_property_map vpmap = get(CGAL::vertex_point, g); + + // create the initial icosahedron + std::vector v_vertices; + v_vertices.resize(12); + for(int i=0; i<12; ++i) + v_vertices[i] = add_vertex(g); + + typename CGAL::Kernel_traits

::Kernel::FT t = radius * (1.0 + CGAL::approximate_sqrt(5.0)) / 2.0; + + put(vpmap, v_vertices[0], P(-radius + center.x(), t + center.y(), 0.0 + center.z())); + put(vpmap, v_vertices[1], P( radius + center.x(), t + center.y(), 0.0 + center.z())); + put(vpmap, v_vertices[2], P(-radius + center.x(), -t + center.y(), 0.0 + center.z())); + put(vpmap, v_vertices[3], P( radius + center.x(), -t + center.y(), 0.0 + center.z())); + + put(vpmap, v_vertices[4], P( 0.0 + center.x(), -radius + center.y(), t + center.z())); + put(vpmap, v_vertices[5], P( 0.0 + center.x(), radius + center.y(), t + center.z())); + put(vpmap, v_vertices[6], P( 0.0 + center.x(), -radius + center.y(), -t + center.z())); + put(vpmap, v_vertices[7], P( 0.0 + center.x(), radius + center.y(), -t + center.z())); + + put(vpmap, v_vertices[8], P( t + center.x(), 0.0 + center.y(), -radius + center.z())); + put(vpmap, v_vertices[9], P( t + center.x(), 0.0 + center.y(), radius + center.z())); + put(vpmap, v_vertices[10], P(-t + center.x(), 0.0 + center.y(), -radius + center.z())); + put(vpmap, v_vertices[11], P(-t + center.x(), 0.0 + center.y(), radius + center.z())); + + std::vector face; + face.resize(3); + face[1] = v_vertices[0]; face[0] = v_vertices[5]; face[2] = v_vertices[11]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[1]; face[2] = v_vertices[5]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[7]; face[2] = v_vertices[1]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[10]; face[2] = v_vertices[7]; + Euler::add_face(face, g); + face[1] = v_vertices[0]; face[0] = v_vertices[11]; face[2] = v_vertices[10]; + Euler::add_face(face, g); + + face[1] = v_vertices[1]; face[0] = v_vertices[9]; face[2] = v_vertices[5]; + Euler::add_face(face, g); + face[1] = v_vertices[5]; face[0] = v_vertices[4]; face[2] = v_vertices[11]; + Euler::add_face(face, g); + face[1] = v_vertices[11]; face[0] = v_vertices[2]; face[2] = v_vertices[10]; + Euler::add_face(face, g); + face[1] = v_vertices[10]; face[0] = v_vertices[6]; face[2] = v_vertices[7]; + Euler::add_face(face, g); + face[1] = v_vertices[7]; face[0] = v_vertices[8]; face[2] = v_vertices[1]; + Euler::add_face(face, g); + + face[1] = v_vertices[3]; face[0] = v_vertices[4]; face[2] = v_vertices[9]; + Euler::add_face(face, g); + face[1] = v_vertices[3]; face[0] = v_vertices[2]; face[2] = v_vertices[4]; + Euler::add_face(face, g); + face[1] = v_vertices[3]; face[0] = v_vertices[6]; face[2] = v_vertices[2]; + Euler::add_face(face, g); + face[1] = v_vertices[3]; face[0] = v_vertices[8]; face[2] = v_vertices[6]; + Euler::add_face(face, g); + face[1] = v_vertices[3]; face[0] = v_vertices[9]; face[2] = v_vertices[8]; + Euler::add_face(face, g); + + face[1] = v_vertices[4]; face[0] = v_vertices[5]; face[2] = v_vertices[9]; + Euler::add_face(face, g); + face[1] = v_vertices[2]; face[0] = v_vertices[11]; face[2] = v_vertices[4]; + Euler::add_face(face, g); + face[1] = v_vertices[6]; face[0] = v_vertices[10]; face[2] = v_vertices[2]; + Euler::add_face(face, g); + face[1] = v_vertices[8]; face[0] = v_vertices[7]; face[2] = v_vertices[6]; + Euler::add_face(face, g); + face[1] = v_vertices[9]; face[0] = v_vertices[1]; face[2] = v_vertices[8]; + Euler::add_face(face, g); + + return halfedge(v_vertices[1], v_vertices[0], g).first; +} + +/*! + * \ingroup PkgBGLHelperFct + * + * \brief Creates a row major ordered grid with `i` cells along the width and `j` cells + * along the height and adds it to the graph `g`. + * An internal property map for `CGAL::vertex_point_t` must be available in `Graph`. + * + * \param i the number of cells along the width. + * \param j the number of cells along the height. + * \param g the graph in which the grid will be created. + * \param calculator the functor that will assign coordinates to the grid vertices. + * \param triangulated decides if a cell is composed of one quad or two triangles. + * If `triangulated` is `true`, the diagonal of each cell is oriented from (0,0) to (1,1) + * in the cell coordinates. + * + *\tparam CoordinateFunctor a function object providing `Point_3 operator()(size_type I, size_type J)` with `Point_3` being + * the value_type of the internal property_map for `CGAL::vertex_point_t`. + * and outputs a `boost::property_traits::%type>::%value_type`. + * It will be called with arguments (`w`, `h`), with `w` in [0..`i`] and `h` in [0..`j`]. + *

%Default: a point with positive integer coordinates (`w`, `h`, 0), with `w` in [0..`i`] and `h` in [0..`j`] + * + * \returns the non-border non-diagonal halfedge that has the target vertex associated with the first point of the grid (default is (0,0,0) ). + */ +template +typename boost::graph_traits::halfedge_descriptor +make_grid(typename boost::graph_traits::vertices_size_type i, + typename boost::graph_traits::vertices_size_type j, + Graph& g, + const CoordinateFunctor& calculator, + bool triangulated = false) +{ + typedef typename boost::property_map::type Point_property_map; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typename boost::graph_traits::vertices_size_type w(i+1), h(j+1); + Point_property_map vpmap = get(CGAL::vertex_point, g); + //create the vertices + std::vector v_vertices; + v_vertices.resize(static_cast(w*h)); + for(std::size_t k = 0; k < v_vertices.size(); ++k) + v_vertices[k] = add_vertex(g); + //assign the coordinates + for(typename boost::graph_traits::vertices_size_type a=0; a::vertices_size_type b=0; b face; + if(triangulated) + face.resize(3); + else + face.resize(4); + + for(typename boost::graph_traits::vertices_size_type a = 0; a::vertices_size_type b = 0; b +typename boost::graph_traits::halfedge_descriptor +make_grid(typename boost::graph_traits::vertices_size_type w, + typename boost::graph_traits::vertices_size_type h, + Graph& g, + bool triangulated = false) +{ + typedef typename boost::graph_traits::vertices_size_type Size_type; + typedef typename boost::property_traits::type>::value_type Point; + + return make_grid(w, h, g, internal::Default_grid_maker(), triangulated); +} + +} // namespace CGAL + +// Include "Euler_operations.h" at the end, because its implementation requires this header. +#include + +#endif // CGAL_BOOST_GRAPH_POLYHEDRA_H From 9e8524c29eb36f2b5677a58f8f5a654491d71d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 15:15:48 +0200 Subject: [PATCH 36/68] Rename BGL/polyhedra.h to BGL/generators.h --- BGL/include/CGAL/boost/graph/{polyhedra.h => generators.h} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename BGL/include/CGAL/boost/graph/{polyhedra.h => generators.h} (99%) diff --git a/BGL/include/CGAL/boost/graph/polyhedra.h b/BGL/include/CGAL/boost/graph/generators.h similarity index 99% rename from BGL/include/CGAL/boost/graph/polyhedra.h rename to BGL/include/CGAL/boost/graph/generators.h index 7ed041fbc50..051178b5ad1 100644 --- a/BGL/include/CGAL/boost/graph/polyhedra.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -18,8 +18,8 @@ // // Author(s) : Maxime Gimeno -#ifndef CGAL_BOOST_GRAPH_POLYHEDRA_H -#define CGAL_BOOST_GRAPH_POLYHEDRA_H +#ifndef CGAL_BOOST_GRAPH_GENERATORS_H +#define CGAL_BOOST_GRAPH_GENERATORS_H #include #include @@ -733,4 +733,4 @@ make_grid(typename boost::graph_traits::vertices_size_type w, // Include "Euler_operations.h" at the end, because its implementation requires this header. #include -#endif // CGAL_BOOST_GRAPH_POLYHEDRA_H +#endif // CGAL_BOOST_GRAPH_GENERATORS_H From f14f9ce4474c35ebf6b02ce8cedb36b6070a2ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 16:05:26 +0200 Subject: [PATCH 37/68] Move some functions from PMP to BGL --- BGL/include/CGAL/boost/graph/generators.h | 88 +++++++- BGL/include/CGAL/boost/graph/helpers.h | 78 +++++++- BGL/package_info/BGL/dependencies | 1 + .../CGAL/Polygon_mesh_processing/locate.h | 188 ------------------ 4 files changed, 165 insertions(+), 190 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/generators.h b/BGL/include/CGAL/boost/graph/generators.h index 051178b5ad1..4df1422d895 100644 --- a/BGL/include/CGAL/boost/graph/generators.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -16,13 +16,16 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // -// Author(s) : Maxime Gimeno +// Author(s) : Maxime Gimeno, +// Mael Rouxel-Labbé #ifndef CGAL_BOOST_GRAPH_GENERATORS_H #define CGAL_BOOST_GRAPH_GENERATORS_H #include #include + +#include #include namespace CGAL { @@ -38,6 +41,89 @@ typename boost::graph_traits::face_descriptor add_face(const VertexRange& } // namespace Euler +namespace internal { + +template +typename std::iterator_traits::value_type +random_entity_in_range(InputIterator first, InputIterator beyond, + CGAL::Random& rnd = get_default_random()) +{ + typedef typename std::iterator_traits::difference_type size_type; + + size_type zero = 0, ne = std::distance(first, beyond); + std::advance(first, rnd.uniform_int(zero, ne - 1)); + + return *first; +} + +template +typename std::iterator_traits::value_type +random_entity_in_range(const CGAL::Iterator_range& range, + CGAL::Random& rnd = get_default_random()) +{ + return random_entity_in_range(range.begin(), range.end(), rnd); +} + +// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `g`. +// \tparam Graph A model of `HalfedgeGraph` +template +typename boost::graph_traits::vertex_descriptor +random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, + const Graph& g, + CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(vertices_around_face(halfedge(fd, g), g), rnd); +} + +// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `g`. +// \tparam Graph A model of `HalfedgeGraph` +template +typename boost::graph_traits::halfedge_descriptor +random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, + const Graph& g, + CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, g), g), rnd); +} + +// \brief returns a random non-null vertex of the polygon mesh `g`. +// \tparam Graph A model of `VertexListGraph` +template +typename boost::graph_traits::vertex_descriptor +random_vertex_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(vertices(g), rnd); +} + +// \brief returns a random non-null halfedge of the polygon mesh `g`. +// \tparam Graph A model of `HalfedgeListGraph` +template +typename boost::graph_traits::halfedge_descriptor +random_halfedge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(halfedges(g), rnd); +} + +// \brief returns a random non-null edge of the polygon mesh `g`. +// \tparam Graph A model of `EdgeListGraph` +template +typename boost::graph_traits::edge_descriptor +random_edge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(edges(g), rnd); +} + +// \brief returns a random non-null face of the polygon mesh `g`. +// \tparam Graph A model of `FaceListGraph` +template +typename boost::graph_traits::face_descriptor +random_face_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(faces(g), rnd); +} + +} // namespace internal + /** * \ingroup PkgBGLHelperFct * diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 75b8f0d0ee4..f4836c7f1dc 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -21,7 +21,7 @@ #ifndef CGAL_BOOST_GRAPH_HELPERS_H #define CGAL_BOOST_GRAPH_HELPERS_H -#include +#include #include #include #include @@ -829,6 +829,82 @@ bool is_empty(const FaceGraph& g) return boost::empty(vertices(g)); } +/// \ingroup PkgBGLHelperFct +/// +/// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd` +/// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. +/// +/// \tparam Graph A model of `FaceGraph` +/// +/// \param vd a vertex of `g` whose index is sought +/// \param fd a face of `g` in which the index of `vd` is sought +/// \param g a mesh of type `Graph` +/// +/// \pre `vd` is a vertex of `fd`. +template +int vertex_index_in_face(const typename boost::graph_traits::vertex_descriptor vd, + const typename boost::graph_traits::face_descriptor fd, + const Graph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor start = halfedge(fd, g); + halfedge_descriptor current = start; + int counter = 0; + + do + { + if(source(current, g) == vd) + break; + + ++counter; + current = next(current, g); + } + while(current != start); + + if(counter != 0 && current == start) + { + CGAL_assertion_msg(false, "Could not find vertex in face"); + return -1; + } + + return counter; +} + +/// \ingroup PkgBGLHelperFct +/// +/// \brief returns the number of calls to `next(hd, tm)` one has to apply to `hd` for `hd == he` +/// to be true, starting from `hd = halfedge(face(he, tm), tm)`. +/// +/// \tparam Graph A model of `FaceGraph`. +/// +/// \param he a halfedge of `g` whose index in `face(he, tm)` is sought +/// \param g an object of type `Graph` +/// +template +int halfedge_index_in_face(typename boost::graph_traits::halfedge_descriptor he, + const Graph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + CGAL_precondition(he != boost::graph_traits::null_halfedge()); + CGAL_precondition(!is_border(he, g)); + + face_descriptor f = face(he, g); + halfedge_descriptor start = halfedge(f, g); + halfedge_descriptor current = start; + int count = 0; + + while(current != he) + { + current = next(current, g); + ++count; + } + + return count; +} + } // namespace CGAL #endif // CGAL_BOOST_GRAPH_HELPERS_H diff --git a/BGL/package_info/BGL/dependencies b/BGL/package_info/BGL/dependencies index 4a55ee6163f..ebc36eadd85 100644 --- a/BGL/package_info/BGL/dependencies +++ b/BGL/package_info/BGL/dependencies @@ -18,5 +18,6 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Stream_support diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 7c5065f9057..4adef39c82a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -257,27 +257,6 @@ snap_location_to_border(typename Locate_types::Face_location& loc, return snap_coordinates_to_border(loc.second, tolerance); } -template -typename std::iterator_traits::value_type -random_entity_in_range(InputIterator first, InputIterator beyond, - CGAL::Random& rnd = get_default_random()) -{ - typedef typename std::iterator_traits::difference_type size_type; - - size_type zero = 0, ne = std::distance(first, beyond); - std::advance(first, rnd.uniform_int(zero, ne - 1)); - - return *first; -} - -template -typename std::iterator_traits::value_type -random_entity_in_range(const CGAL::Iterator_range& range, - CGAL::Random& rnd = get_default_random()) -{ - return random_entity_in_range(range.begin(), range.end(), rnd); -} - template struct Barycentric_coordinate_calculator // 2D version { @@ -393,173 +372,6 @@ struct Barycentric_point_constructor // 3D version } // namespace internal -/// \name Random Simplex Generation -/// @{ - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `HalfedgeGraph` -template -typename boost::graph_traits::vertex_descriptor -random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, - const PolygonMesh& pm, - CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(vertices_around_face(halfedge(fd, pm), pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `HalfedgeGraph` -/// -template -typename boost::graph_traits::halfedge_descriptor -random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, - const PolygonMesh& pm, - CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, pm), pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null vertex of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `VertexListGraph` -/// -template -typename boost::graph_traits::vertex_descriptor -random_vertex_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(vertices(pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null halfedge of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `HalfedgeListGraph` -/// -template -typename boost::graph_traits::halfedge_descriptor -random_halfedge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(halfedges(pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null edge of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `EdgeListGraph` -/// -template -typename boost::graph_traits::edge_descriptor -random_edge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(edges(pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null face of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `FaceListGraph` -/// -template -typename boost::graph_traits::face_descriptor -random_face_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(faces(pm), rnd); -} - -/// @} - -/// \name Simplex Index -/// @{ - -/// \ingroup PMP_locate_grp -/// -/// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd` -/// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. -/// -/// \tparam PolygonMesh A model of `FaceGraph` -/// -/// \param vd a vertex of `pm` whose index we seek -/// \param fd a face of `pm` in which we seek the index of `vd` -/// \param pm a mesh of type `PolygonMesh` -/// -/// \pre `vd` is a vertex of `fd`. -template -int vertex_index_in_face(const typename boost::graph_traits::vertex_descriptor vd, - const typename boost::graph_traits::face_descriptor fd, - const PolygonMesh& pm) -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - halfedge_descriptor start = halfedge(fd, pm); - halfedge_descriptor current = start; - int counter = 0; - - do - { - if(source(current, pm) == vd) - break; - - ++counter; - current = next(current, pm); - } - while(current != start); - - if(counter != 0 && current == start) - { - CGAL_assertion_msg(false, "Could not find vertex in face"); - return -1; - } - - return counter; -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns the number of `next` one has to apply to `hd` for `hd == he` -/// to be true, starting from `hd = halfedge(face(hd, tm), tm)`. -/// -/// \tparam PolygonMesh A model of `FaceGraph`. -/// -/// \param he a halfedge of `pm` whose index in `face(he, tm)` we seek -/// \param pm an object of type `PolygonMesh` -/// -template -int halfedge_index_in_face(typename boost::graph_traits::halfedge_descriptor he, - const PolygonMesh& pm) -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - - CGAL_precondition(he != boost::graph_traits::null_halfedge()); - CGAL_precondition(!is_border(he, pm)); - - face_descriptor f = face(he, pm); - halfedge_descriptor start = halfedge(f, pm); - halfedge_descriptor current = start; - int count = 0; - - while(current != he) - { - current = next(current, pm); - ++count; - } - - return count; -} - -/// @} - /// \ingroup PMP_locate_grp /// /// \brief Given a set of three points and a query point, computes the barycentric From e382ed1f1ba79ecea00899a7bf30c86b6901996f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 16:05:57 +0200 Subject: [PATCH 38/68] Improve phrasing --- .../CGAL/Polygon_mesh_processing/locate.h | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 4adef39c82a..fc443963fef 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -52,8 +52,8 @@ // Everywhere in this file: // If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -// and the vertices of the face `f` is the following: +// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +// 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)` @@ -129,8 +129,8 @@ public: typedef std::array Barycentric_coordinates; /// If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) - /// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` - /// and the vertices of the face `f` is the following: + /// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance + /// 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)` @@ -578,7 +578,7 @@ get_descriptor_from_location(const typename Locate_types::Face_loc /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `boost::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. @@ -634,8 +634,8 @@ construct_point(const typename Locate_types::Face_location& loc, /// on the vertex `vd` or not. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -673,8 +673,8 @@ is_on_vertex(const typename Locate_types::Face_location& loc, /// on the halfedge `hd` or not. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -714,8 +714,8 @@ is_on_halfedge(const typename Locate_types::Face_location& loc, /// that is, if all the barycentric coordinates are positive. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -751,8 +751,8 @@ is_in_face(const typename Locate_types::Barycentric_coordinates& b /// in the face (boundary included) or not. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -778,8 +778,8 @@ is_in_face(const typename Locate_types::Face_location& loc, /// of the face or not. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -817,8 +817,8 @@ is_on_face_border(const typename Locate_types::Face_location& loc, /// on the border of the mesh or not. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -912,8 +912,8 @@ common_halfedge(const typename boost::graph_traits::face_descriptor /// and the barycentric coordinates of the vertex `vd` in that face. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -967,8 +967,8 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, /// of the vertex in `fd`. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -1003,8 +1003,8 @@ locate_in_face(const typename boost::graph_traits::vertex_descript /// barycentric coordinates of that location in that face. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -1045,8 +1045,8 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// `query` with respect to the vertices of `fd`. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) -/// such that `bc` is `(w0, w1, w2)`, the correspondance with the weights in `bc` -/// and the vertices of the face `f` is the following: +/// such that `bc` is the triplet of barycentric coordinates `(w0, w1, w2)`, the correspondance +/// 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)` @@ -1063,7 +1063,7 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `boost::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. @@ -1132,8 +1132,8 @@ locate_in_face(const typename property_map_value::Point& p, /// \brief returns the nearest face location to the given point. /// /// \details Note that this function will build an `AABB_tree` on each call. If you need -/// to call this function more than once, use `build_AABB_tree()` to cache a -/// copy of the `AABB_tree`, and use the overloads of this function -/// that accept a reference to an `AABB_tree` as input. +/// to call this function more than once, first use `build_AABB_tree()` to create a +/// an `AABB_tree` that you can store and use the function `locate_with_AABB_tree()`. /// /// \tparam TriangleMesh must be a model of `FaceListGraph`. /// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. @@ -1621,7 +1622,7 @@ locate_with_AABB_tree(const typename Locate_types::Point& p, /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `boost::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalNamedParamsEnd /// @@ -1685,7 +1686,7 @@ locate(const typename property_map_value::t /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `boost::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. @@ -1793,7 +1794,7 @@ locate_with_AABB_tree(const typename Locate_types::Ray& ray, /// \cgalParamBegin{vertex_point_map} /// the property map with the points associated to the vertices of `tm`. /// If this parameter is omitted, an internal property map for -/// `boost::vertex_point_t` should be available in `TriangleMesh`. +/// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. From 15357b83bdabba756c301a9729b2ce00cf598507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 16:06:22 +0200 Subject: [PATCH 39/68] Update locate/BGL tests --- BGL/test/BGL/test_helpers.cpp | 133 +++++++++++++---- .../CGAL/Polygon_mesh_processing/locate.h | 54 ++----- .../test_pmp_locate.cpp | 136 +++++------------- 3 files changed, 149 insertions(+), 174 deletions(-) diff --git a/BGL/test/BGL/test_helpers.cpp b/BGL/test/BGL/test_helpers.cpp index 3ba16eb4d6e..2464a60150a 100644 --- a/BGL/test/BGL/test_helpers.cpp +++ b/BGL/test/BGL/test_helpers.cpp @@ -1,40 +1,31 @@ -#include -#include +#include #include #include -#include + +#include #include #include -typedef CGAL::Simple_cartesian K; -typedef K::Point_3 Point_3; +#include +#include +typedef CGAL::Simple_cartesian K; +typedef K::Point_3 Point_3; template -void -test(const char *fname, bool triangle, bool quad, bool tetrahedron, bool hexahedron) +void test_validity() { - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - std::cerr << "test(" << fname << ")"<< std::endl; - Mesh m; - std::ifstream in(fname); - in >> m; - halfedge_descriptor hd = *halfedges(m).first; - assert(CGAL::is_isolated_triangle(hd, m) == triangle); - assert(CGAL::is_isolated_quad(hd, m) == quad); - assert(CGAL::is_tetrahedron(hd, m) == tetrahedron); - assert(CGAL::is_hexahedron(hd, m) == hexahedron); - } + std::cerr << "test validity" << std::endl; -template -void -test_validity(Mesh& mesh) -{ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::property_map::type VPMap; + + Mesh mesh; VPMap vpmap = get(CGAL::vertex_point, mesh); + vertex_descriptor vertices[4]; edge_descriptor edges[4]; vertices[0] = add_vertex(mesh); @@ -100,11 +91,32 @@ test_validity(Mesh& mesh) } -int main() +template +void test(const char *fname, bool triangle, bool quad, bool tetrahedron, bool hexahedron) { - typedef CGAL::Surface_mesh Mesh; - Mesh mesh; - test_validity(mesh); + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + std::cerr << "test(" << fname << ")"<< std::endl; + + Mesh m; + std::ifstream in(fname); + in >> m; + + halfedge_descriptor hd = *halfedges(m).first; + assert(CGAL::is_isolated_triangle(hd, m) == triangle); + assert(CGAL::is_isolated_quad(hd, m) == quad); + assert(CGAL::is_tetrahedron(hd, m) == tetrahedron); + assert(CGAL::is_hexahedron(hd, m) == hexahedron); +} + +template +void test_generators() +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + // triangle quad tetra hexa test("data/triangle.off", true, false, false, false ); test("data/quad.off", false, true, false, false ); @@ -112,20 +124,21 @@ int main() test("data/cube.off", false, false, false, false ); test("data/cube-quads.off", false, false, false, true ); - typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; - Point_3 a(0,0,0), b(1,0,0), c(1,1,0), d(0,1,0); Point_3 aa(0,0,1), bb(1,0,1), cc(1,1,1), dd(0,1,1); + Mesh m; halfedge_descriptor hd; hd = CGAL::make_triangle(a,b,c,m); assert(CGAL::is_isolated_triangle(hd,m)); assert(CGAL::is_valid_polygon_mesh(m)); + m.clear(); hd = CGAL::make_quad(a,b,c,d,m); assert(CGAL::is_isolated_quad(hd,m)); assert(CGAL::is_valid_polygon_mesh(m)); assert(CGAL::is_quad_mesh(m)); + m.clear(); hd = CGAL::make_tetrahedron(a,b,c,d,m); assert(CGAL::is_tetrahedron(hd,m)); @@ -136,26 +149,86 @@ int main() assert(CGAL::is_hexahedron(hd,m)); assert(CGAL::is_quad_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); + m.clear(); CGAL::make_icosahedron(m); assert(num_faces(m) == 20); assert(CGAL::is_triangle_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); + m.clear(); hd = CGAL::make_pyramid(3, m); assert(num_faces(m) == 6); assert(CGAL::is_triangle_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); + m.clear(); hd = CGAL::make_regular_prism(4, m); assert(num_faces(m) == 16); assert(CGAL::is_triangle_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); + m.clear(); CGAL::make_grid(3,3,m); assert(num_faces(m) == 9); assert(CGAL::is_quad_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); - std::cerr << "done" << std::endl; - return 0; + + // ----------------------------------------------------------------------------------------------- + + std::cerr << "test random element generators" << std::endl; + + vertex_descriptor v; + halfedge_descriptor h; + edge_descriptor e; + face_descriptor f; + + CGAL::Random rnd; + + // --------------------------------------------------------------------------- + v = CGAL::internal::random_vertex_in_mesh(m, rnd); + assert(v != boost::graph_traits::null_vertex()); + + h = CGAL::internal::random_halfedge_in_mesh(m, rnd); + assert(h != boost::graph_traits::null_halfedge()); + + e = CGAL::internal::random_edge_in_mesh(m, rnd); + + f = CGAL::internal::random_face_in_mesh(m, rnd); + assert(f != boost::graph_traits::null_face()); + + // --------------------------------------------------------------------------- + h = CGAL::internal::random_halfedge_in_face(f, m, rnd); + assert(h != boost::graph_traits::null_halfedge()); + assert(face(h, m) == f); + + v = CGAL::internal::random_vertex_in_face(f, m, rnd); + assert(v != boost::graph_traits::null_vertex()); + + // could use vertices_around_face, but it's the point is not to + bool has_vertex = false; + halfedge_descriptor done = h; + do + { + if(target(h, m) == v) + { + has_vertex = true; + break; + } + + h = next(h, m); + } + while(h != done); + assert(has_vertex); +} + +int main() +{ + typedef CGAL::Surface_mesh Mesh; + + test_validity(); + test_generators(); + + std::cerr << "done" << std::endl; + return EXIT_SUCCESS; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index fc443963fef..2e620e483d5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -377,7 +378,7 @@ struct Barycentric_point_constructor // 3D version /// \brief Given a set of three points and a query point, computes the barycentric /// coordinates of the query point with respect to the first three points. /// -/// \tparam P the type of a geometric 2D or 3D point +/// \tparam Point the type of a geometric 2D or 3D point /// \tparam K the type of a geometric traits. Must be a model of `Kernel`. /// /// \param p,q,r three points with respect to whom the barycentric coordinates of `query` will be computed @@ -389,21 +390,23 @@ struct Barycentric_point_constructor // 3D version /// (this is the case for all standard %CGAL point types). /// \pre `query` lies on the plane defined by `p`, `q`, and `r`. /// -template +template CGAL::array -barycentric_coordinates(const P& p, const P& q, const P& r, const P& query, const K& k) +barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query, + const K& k) { - internal::Barycentric_coordinate_calculator calculator; + internal::Barycentric_coordinate_calculator calculator; return calculator(p, q, r, query, k); } -template -CGAL::array::type::FT, 3> -barycentric_coordinates(const P& p, const P& q, const P& r, const P& query) +template +CGAL::array::type::FT, 3> +barycentric_coordinates(const Point& p, const Point& q, const Point& r, + const Point& query) { - typedef typename CGAL::Kernel_traits

::type Kernel; + typedef typename CGAL::Kernel_traits::type Kernel; - return barycentric_coordinates(p, q, r, query, Kernel()); + return barycentric_coordinates(p, q, r, query, Kernel()); } /// \name Random Location Generation @@ -495,7 +498,7 @@ random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_ CGAL_precondition(CGAL::is_triangle_mesh(tm)); - face_descriptor fd = random_face_in_mesh(tm, rnd); + face_descriptor fd = CGAL::internal::random_face_in_mesh(tm, rnd); return random_location_on_face(fd, tm, rnd); } @@ -871,37 +874,6 @@ is_on_mesh_border(const typename Locate_types::Face_location& loc, /// @} -/// \ingroup PMP_locate_grp -/// -/// \brief Given two faces `fd1` and `fd2` of a polygonal mesh `pm`, returns -/// (if it exists) a common edge. The returned halfedge is incident to `fd1`. -/// -/// \tparam TriangleMesh A model of `HalfedgeGraph` -/// -template -boost::optional::halfedge_descriptor> -common_halfedge(const typename boost::graph_traits::face_descriptor fd1, - const typename boost::graph_traits::face_descriptor fd2, - const PolygonMesh& pm) -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - if(fd1 == fd2) - return halfedge(fd1, pm); - - halfedge_descriptor hd = halfedge(fd1, pm), done = hd; - do - { - if(face(opposite(hd, pm), pm) == fd2) - return hd; - - hd = next(hd, pm); - } - while(hd != done); - - return boost::none; -} - /// \name Point Location /// @{ diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index fc7ca8d41b5..e7a838e3604 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -151,7 +153,7 @@ void test_constructions(const G& g, CGAL::Random& rnd) typedef typename boost::property_map::const_type VPM; VPM vpm = CGAL::get_const_property_map(boost::vertex_point, g); - face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = source(h, g); @@ -221,9 +223,7 @@ void test_random_entities(const G& g, CGAL::Random& rnd) { std::cout << " test random entities..." << std::endl; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename PMP::Locate_types::Face_location Face_location; @@ -232,54 +232,14 @@ void test_random_entities(const G& g, CGAL::Random& rnd) typedef typename CGAL::Kernel_traits::type Kernel; typedef typename Kernel::FT FT; - vertex_descriptor v; - halfedge_descriptor h; - edge_descriptor e; - face_descriptor f; - - // --------------------------------------------------------------------------- - v = PMP::random_vertex_in_mesh(g, rnd); - assert(v != boost::graph_traits::null_vertex()); - - h = PMP::random_halfedge_in_mesh(g, rnd); - assert(h != boost::graph_traits::null_halfedge()); - - e = PMP::random_edge_in_mesh(g, rnd); - // assert(e != boost::graph_traits::null_edge()); - - f = PMP::random_face_in_mesh(g, rnd); - assert(f != boost::graph_traits::null_face()); - - // --------------------------------------------------------------------------- - h = PMP::random_halfedge_in_face(f, g, rnd); - assert(h != boost::graph_traits::null_halfedge()); - assert(face(h, g) == f); - - v = PMP::random_vertex_in_face(f, g, rnd); - assert(v != boost::graph_traits::null_vertex()); - - // could use vertices_around_face, but it's the point is not to - bool has_vertex = false; - halfedge_descriptor done = h; - do - { - if(target(h, g) == v) - { - has_vertex = true; - break; - } - - h = next(h, g); - } - while(h != done); - assert(has_vertex); - // --------------------------------------------------------------------------- Face_location loc; - loc.first = f; + + halfedge_descriptor h = CGAL::internal::random_halfedge_in_mesh(g, rnd); + face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); int nn = 1e2; - while(nn --> 0) // famous 'go to zero' operator + while(nn --> 0) // the famous 'go to zero' operator { loc = PMP::random_location_on_mesh(g, rnd); assert(loc.first != boost::graph_traits::null_face()); @@ -298,7 +258,7 @@ void test_random_entities(const G& g, CGAL::Random& rnd) assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) && loc.second[1] >= FT(0) && loc.second[1] <= FT(1) && loc.second[2] >= FT(0) && loc.second[2] <= FT(1)); - int h_id = PMP::halfedge_index_in_face(h, g); + int h_id = CGAL::halfedge_index_in_face(h, g); assert(loc.second[(h_id+2)%3] == FT(0)); } } @@ -314,24 +274,24 @@ void test_helpers(const G& g, CGAL::Random& rnd) typedef typename PMP::Locate_types::Face_location Face_location; - face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = source(h, g); // --------------------------------------------------------------------------- // Local index - int pos = PMP::vertex_index_in_face(v, f, g); + int pos = CGAL::vertex_index_in_face(v, f, g); assert(pos == 0); - pos = PMP::vertex_index_in_face(target(h, g), f, g); + pos = CGAL::vertex_index_in_face(target(h, g), f, g); assert(pos == 1); - pos = PMP::vertex_index_in_face(target(next(h, g), g), f, g); + pos = CGAL::vertex_index_in_face(target(next(h, g), g), f, g); assert(pos == 2); - pos = PMP::halfedge_index_in_face(h, g); + pos = CGAL::halfedge_index_in_face(h, g); assert(pos == 0); - pos = PMP::halfedge_index_in_face(next(h, g), g); + pos = CGAL::halfedge_index_in_face(next(h, g), g); assert(pos == 1); - pos = PMP::halfedge_index_in_face(prev(h, g), g); + pos = CGAL::halfedge_index_in_face(prev(h, g), g); assert(pos == 2); // --------------------------------------------------------------------------- @@ -345,36 +305,6 @@ void test_helpers(const G& g, CGAL::Random& rnd) std::vector vec; PMP::internal::incident_faces(loc, g, std::back_inserter(vec)); assert(PMP::is_on_vertex(loc, source(h, g), g) || PMP::is_on_vertex(loc, target(h, g), g) || vec.size() == 2); - - // --------------------------------------------------------------------------- - // Common halfedge - assert(halfedge(f, g) == PMP::common_halfedge(f, f, g)); - - for(int i=0; i<100; ++i) - { - face_descriptor f2 = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); - - if(f == f2) - continue; - - assert(is_triangle(halfedge(f, g), g) && is_triangle(halfedge(f2, g), g)); - std::set vertices; - - BOOST_FOREACH(vertex_descriptor vd, CGAL::vertices_around_face(halfedge(f, g), g)) { - vertices.insert(vd); - } - - BOOST_FOREACH(vertex_descriptor vd, CGAL::vertices_around_face(halfedge(f2, g), g)) { - vertices.insert(vd); - } - - boost::optional ohd = PMP::common_halfedge(f, f2, g); - if(ohd != boost::none) - { - // common edge means two common vertices and since faces are different, there are 4 vertices - assert(vertices.size() == 4); - } - } } template @@ -392,7 +322,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) typedef typename PMP::Locate_types::Face_location Face_location; - face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = source(h, g); @@ -444,7 +374,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) if(face(h, g) == boost::graph_traits::null_face()) continue; - const int id_of_h = PMP::halfedge_index_in_face(h, g); + const int id_of_h = CGAL::halfedge_index_in_face(h, g); const face_descriptor f = face(h, g); loc.first = f; @@ -487,7 +417,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) typedef typename boost::property_map::const_type VertexPointMap; VertexPointMap vpm = CGAL::get_const_property_map(boost::vertex_point, g); - const face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + const face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); const halfedge_descriptor h = halfedge(f, g); const vertex_descriptor v = target(h, g); @@ -496,24 +426,24 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) Point p = get(vpm, v); loc = PMP::locate_in_face(v, g); - assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); loc = PMP::locate_in_face(v, f, g); assert(loc.first == f); assert(is_equal(loc.second[0], FT(0)) && is_equal(loc.second[1], FT(1)) && is_equal(loc.second[2], FT(0))); loc = PMP::locate_in_face(h, a, g); - const int h_id = PMP::halfedge_index_in_face(h, g); + const int h_id = CGAL::halfedge_index_in_face(h, g); assert(loc.first == f && is_equal(loc.second[(h_id+2)%3], FT(0))); loc = PMP::locate_in_face(p, f, g, CGAL::parameters::all_default()); - int v_id = PMP::vertex_index_in_face(v, f, g); + int v_id = CGAL::vertex_index_in_face(v, f, g); assert(loc.first == f && is_equal(loc.second[v_id], FT(1))); loc = PMP::locate_in_face(p, f, g); - v_id = PMP::vertex_index_in_face(v, f, g); + v_id = CGAL::vertex_index_in_face(v, f, g); assert(loc.first == f && is_equal(loc.second[v_id], FT(1))); // --------------------------------------------------------------------------- @@ -523,7 +453,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) halfedge_descriptor neigh_hd = opposite(halfedge(f, g), g); face_descriptor neigh_f = face(neigh_hd, g); - int neigh_hd_id = PMP::halfedge_index_in_face(neigh_hd, g); + int neigh_hd_id = CGAL::halfedge_index_in_face(neigh_hd, g); Face_location neigh_loc; neigh_loc.first = neigh_f; neigh_loc.second[neigh_hd_id] = FT(0.3); @@ -565,7 +495,7 @@ struct Locate_with_AABB_tree_Tester // 2D case typedef typename PMP::Locate_types::Face_location Face_location; - face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = target(h, g); @@ -597,9 +527,9 @@ struct Locate_with_AABB_tree_Tester // 2D case Face_location loc = PMP::locate_with_AABB_tree(p_a, tree_a, g); assert(PMP::is_on_vertex(loc, v, g)); - assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0))); loc = PMP::locate_with_AABB_tree(p_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); @@ -671,7 +601,7 @@ struct Locate_with_AABB_tree_Tester<3> // 3D typedef typename PMP::Locate_types::Face_location Face_location; - face_descriptor f = CGAL::Polygon_mesh_processing::random_face_in_mesh(g, rnd); + face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = target(h, g); @@ -713,9 +643,9 @@ struct Locate_with_AABB_tree_Tester<3> // 3D assert(tree_b.size() == num_faces(g)); Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g); - assert(is_equal(loc.second[PMP::vertex_index_in_face(v, loc.first, g)], FT(1))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); - assert(is_equal(loc.second[(PMP::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); + assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); + assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); + assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a)); From 4310b898a30217f9270eefb54fb3704807cf20ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 16:34:50 +0200 Subject: [PATCH 40/68] Locate_types > Location_traits (+ uniformize to 'TriangleMesh') --- .../CGAL/Polygon_mesh_processing/locate.h | 204 +++++++++--------- .../test_pmp_locate.cpp | 30 +-- 2 files changed, 117 insertions(+), 117 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 2e620e483d5..e9e5028b496 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -88,17 +88,17 @@ struct Ray_type_selector /// /// \brief Helper class whose sole purpose is to make it easier to access some useful types. /// -/// \tparam PolygonMesh A model of `FaceListGraph` +/// \tparam TriangleMesh A model of `FaceListGraph` /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// -template -class Locate_types +class Location_traits { public: - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef boost::variant descriptor_variant; @@ -112,9 +112,9 @@ public: /// of the vertex property map (the point type must then be compatible with `CGAL::Kernel_traits`) typedef unspecified_type Geom_traits; #else - typedef typename GetVertexPointMap::const_type VPM; - typedef typename GetGeomTraits::type Geom_traits; + typedef typename GetGeomTraits::type Geom_traits; #endif typedef typename boost::property_traits::value_type Point; @@ -140,18 +140,18 @@ public: // forward declarations template -bool is_in_face(const typename Locate_types::Face_location& loc, +bool is_in_face(const typename Location_traits::Face_location& loc, const TriangleMesh& tm); template -typename Locate_types::descriptor_variant -get_descriptor_from_location(const typename Locate_types::Face_location& loc, +typename Location_traits::descriptor_variant +get_descriptor_from_location(const typename Location_traits::Face_location& loc, const TriangleMesh& tm); template -typename Locate_types::Face_location +typename Location_traits::Face_location locate_in_face(typename boost::graph_traits::halfedge_descriptor he, - typename Locate_types::FT t, + typename Location_traits::FT t, const TriangleMesh& tm); // end of forward declarations @@ -159,7 +159,7 @@ namespace internal { template OutputIterator -incident_faces(const typename Locate_types::Face_location& location, +incident_faces(const typename Location_traits::Face_location& location, const TriangleMesh& tm, OutputIterator out) { @@ -197,11 +197,11 @@ incident_faces(const typename Locate_types::Face_location& locatio // Snapping coordinates for robustness template bool -snap_coordinates_to_border(typename Locate_types::Barycentric_coordinates& coords, - const typename Locate_types::FT tolerance = - std::numeric_limits::FT>::epsilon()) +snap_coordinates_to_border(typename Location_traits::Barycentric_coordinates& coords, + const typename Location_traits::FT tolerance = + std::numeric_limits::FT>::epsilon()) { - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; #ifdef CGAL_PMP_LOCATE_DEBUG std::cout << "Pre-snapping: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; @@ -251,9 +251,9 @@ snap_coordinates_to_border(typename Locate_types::Barycentric_coor template bool -snap_location_to_border(typename Locate_types::Face_location& loc, - const typename Locate_types::FT tolerance = - std::numeric_limits::FT>::epsilon()) +snap_location_to_border(typename Location_traits::Face_location& loc, + const typename Location_traits::FT tolerance = + std::numeric_limits::FT>::epsilon()) { return snap_coordinates_to_border(loc.second, tolerance); } @@ -428,12 +428,12 @@ barycentric_coordinates(const Point& p, const Point& q, const Point& r, /// \param rnd optional random number generator /// template -typename Locate_types::Face_location +typename Location_traits::Face_location random_location_on_halfedge(typename boost::graph_traits::halfedge_descriptor hd, const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) { - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; CGAL_precondition(CGAL::is_triangle_mesh(tm)); @@ -457,12 +457,12 @@ random_location_on_halfedge(typename boost::graph_traits::halfedge /// \param rnd optional random number generator /// template -typename Locate_types::Face_location +typename Location_traits::Face_location random_location_on_face(typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) { - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; CGAL_USE(tm); CGAL_precondition(CGAL::is_triangle_mesh(tm)); @@ -491,7 +491,7 @@ random_location_on_face(typename boost::graph_traits::face_descrip /// \sa `random_location_on_face()` /// template -typename Locate_types::Face_location +typename Location_traits::Face_location random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_random()) { typedef typename boost::graph_traits::face_descriptor face_descriptor; @@ -524,14 +524,14 @@ random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_ /// \pre `tm` is a triangulated surface mesh. /// template -typename Locate_types::descriptor_variant -get_descriptor_from_location(const typename Locate_types::Face_location& loc, +typename Location_traits::descriptor_variant +get_descriptor_from_location(const typename Location_traits::Face_location& loc, const TriangleMesh& tm) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename Locate_types::Barycentric_coordinates Barycentric_coordinates; + typedef typename Location_traits::Barycentric_coordinates Barycentric_coordinates; const face_descriptor fd = loc.first; const Barycentric_coordinates& bar = loc.second; @@ -592,8 +592,8 @@ get_descriptor_from_location(const typename Locate_types::Face_loc /// \pre `tm` is a triangulated surface mesh. /// template -typename Locate_types::Point -construct_point(const typename Locate_types::Face_location& loc, +typename Location_traits::Point +construct_point(const typename Location_traits::Face_location& loc, const TriangleMesh& tm, const NamedParameters& np) { @@ -620,7 +620,7 @@ construct_point(const typename Locate_types::Face_location& loc, template typename property_map_value::type -construct_point(const typename Locate_types::Face_location& loc, +construct_point(const typename Location_traits::Face_location& loc, const TriangleMesh& tm) { return construct_point(loc, tm, parameters::all_default()); @@ -650,12 +650,12 @@ construct_point(const typename Locate_types::Face_location& loc, /// template bool -is_on_vertex(const typename Locate_types::Face_location& loc, +is_on_vertex(const typename Location_traits::Face_location& loc, const typename boost::graph_traits::vertex_descriptor v, const TriangleMesh& tm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename Locate_types::descriptor_variant descriptor_variant; + typedef typename Location_traits::descriptor_variant descriptor_variant; if(!is_in_face(loc, tm)) return false; @@ -689,13 +689,13 @@ is_on_vertex(const typename Locate_types::Face_location& loc, /// template bool -is_on_halfedge(const typename Locate_types::Face_location& loc, +is_on_halfedge(const typename Location_traits::Face_location& loc, const typename boost::graph_traits::halfedge_descriptor h, const TriangleMesh& tm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename Locate_types::descriptor_variant descriptor_variant; + typedef typename Location_traits::descriptor_variant descriptor_variant; if(!is_in_face(loc, tm)) return false; @@ -729,7 +729,7 @@ is_on_halfedge(const typename Locate_types::Face_location& loc, /// template bool -is_in_face(const typename Locate_types::Barycentric_coordinates& bar, +is_in_face(const typename Location_traits::Barycentric_coordinates& bar, const TriangleMesh& tm) { CGAL_USE(tm); @@ -767,7 +767,7 @@ is_in_face(const typename Locate_types::Barycentric_coordinates& b /// template bool -is_in_face(const typename Locate_types::Face_location& loc, +is_in_face(const typename Location_traits::Face_location& loc, const TriangleMesh& tm) { return is_in_face(loc.second, tm); @@ -794,10 +794,10 @@ is_in_face(const typename Locate_types::Face_location& loc, /// template bool -is_on_face_border(const typename Locate_types::Face_location& loc, +is_on_face_border(const typename Location_traits::Face_location& loc, const TriangleMesh& tm) { - typedef typename Locate_types::Face_location Face_location; + typedef typename Location_traits::Face_location Face_location; typedef typename Face_location::second_type Barycentric_coordinates; if(!is_in_face(loc, tm)) @@ -833,13 +833,13 @@ is_on_face_border(const typename Locate_types::Face_location& loc, /// template bool -is_on_mesh_border(const typename Locate_types::Face_location& loc, +is_on_mesh_border(const typename Location_traits::Face_location& loc, const TriangleMesh& tm) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename Locate_types::Face_location Face_location; + typedef typename Location_traits::Face_location Face_location; typedef typename Face_location::second_type Barycentric_coordinates; const face_descriptor fd = loc.first; @@ -896,14 +896,14 @@ is_on_mesh_border(const typename Locate_types::Face_location& loc, /// \param tm a triangulated surface mesh /// template -typename Locate_types::Face_location +typename Location_traits::Face_location locate_in_face(typename boost::graph_traits::vertex_descriptor vd, const TriangleMesh& tm) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; halfedge_descriptor he = halfedge(vd, tm); @@ -952,12 +952,12 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, /// \param tm a triangulated surface mesh /// template -typename Locate_types::Face_location +typename Location_traits::Face_location locate_in_face(const typename boost::graph_traits::vertex_descriptor vd, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm) { - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; FT coords[3] = { FT(0), FT(0), FT(0) }; std::size_t vertex_local_index = vertex_index_in_face(vd, fd, tm); @@ -990,13 +990,13 @@ locate_in_face(const typename boost::graph_traits::vertex_descript /// \pre `tm` is a triangulated surface mesh. /// template -typename Locate_types::Face_location +typename Location_traits::Face_location locate_in_face(const typename boost::graph_traits::halfedge_descriptor he, - const typename Locate_types::FT t, + const typename Location_traits::FT t, const TriangleMesh& tm) { typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; face_descriptor fd = face(he, tm); std::size_t edge_local_index = halfedge_index_in_face(he, tm); @@ -1043,15 +1043,15 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// \cgalNamedParamsEnd /// template -typename Locate_types::Face_location -locate_in_face(const typename Locate_types::Point& query, +typename Location_traits::Face_location +locate_in_face(const typename Location_traits::Point& query, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm, const NamedParameters& np) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename Locate_types::FT FT; + typedef typename Location_traits::FT FT; // VertexPointMap typedef typename GetGeomTraits::type Geom_traits; @@ -1087,7 +1087,7 @@ locate_in_face(const typename Locate_types::Point #ifndef DOXYGEN_RUNNING // because this is in the middle of a @{ @} doxygen group template -typename Locate_types::Face_location +typename Location_traits::Face_location locate_in_face(const typename property_map_value::type& query, const typename boost::graph_traits::face_descriptor f, const TriangleMesh& tm) @@ -1119,8 +1119,8 @@ locate_in_face(const typename property_map_value -typename Locate_types::Face_location -locate_in_adjacent_face(const typename Locate_types::Face_location& loc, +typename Location_traits::Face_location +locate_in_adjacent_face(const typename Location_traits::Face_location& loc, const typename boost::graph_traits::face_descriptor fd, const TriangleMesh& tm) { @@ -1132,8 +1132,8 @@ locate_in_adjacent_face(const typename Locate_types::Face_location halfedge_descriptor, face_descriptor> descriptor_variant; - typedef typename Locate_types::Face_location Face_location; - typedef typename Locate_types::FT FT; + typedef typename Location_traits::Face_location Face_location; + typedef typename Location_traits::FT FT; if(loc.first == fd) return loc; @@ -1195,12 +1195,12 @@ locate_in_adjacent_face(const typename Locate_types::Face_location // note: not returning the query location to emphasis that the known location can change too. template bool -locate_in_common_face(typename Locate_types::Face_location& known_location, - const typename Locate_types::Point& query, - typename Locate_types::Face_location& query_location, +locate_in_common_face(typename Location_traits::Face_location& known_location, + const typename Location_traits::Point& query, + typename Location_traits::Face_location& query_location, const TriangleMesh& tm, - const typename Locate_types::FT tolerance = - std::numeric_limits::FT>::epsilon()) + const typename Location_traits::FT tolerance = + std::numeric_limits::FT>::epsilon()) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -1272,8 +1272,8 @@ locate_in_common_face(typename Locate_types::Face_location& known_ // - both locations must be known but can change template bool -locate_in_common_face(typename Locate_types::Face_location& first_location, - typename Locate_types::Face_location& second_location, +locate_in_common_face(typename Location_traits::Face_location& first_location, + typename Location_traits::Face_location& second_location, const TriangleMesh& tm) { typedef typename boost::graph_traits::face_descriptor face_descriptor; @@ -1339,41 +1339,41 @@ locate_in_common_face(typename Locate_types::Face_location& first_ namespace internal { -template::value> struct Point_to_Point_3 // 2D case { - typedef typename Locate_types::Geom_traits::Point_3 Point_3; + typedef typename Location_traits::Geom_traits::Point_3 Point_3; Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), 0); } }; -template -struct Point_to_Point_3::Geom_traits::Point_3, +template +struct Point_to_Point_3::Geom_traits::Point_3, 3> // 3D case with nothing to do { - typedef typename Locate_types::Geom_traits::Point_3 Point_3; + typedef typename Location_traits::Geom_traits::Point_3 Point_3; const Point_3& operator()(const Point_3& p) const { return p; } }; -template -struct Point_to_Point_3 // Generic 3D case +template +struct Point_to_Point_3 // Generic 3D case { - typedef typename Locate_types::Geom_traits::Point_3 Point_3; + typedef typename Location_traits::Geom_traits::Point_3 Point_3; Point_3 operator()(const Point& p) const { return Point_3(p.x(), p.y(), p.z()); } }; -template +template struct Ray_to_Ray_3 // 2D case { - typedef typename Locate_types::Geom_traits Geom_traits; + typedef typename Location_traits::Geom_traits Geom_traits; typedef typename Geom_traits::Ray_2 Ray_2; typedef typename Geom_traits::Ray_3 Ray_3; - typedef Point_to_Point_3 P2_to_P3; + typedef Point_to_Point_3 P2_to_P3; Ray_3 operator()(const Ray_2& r) const { @@ -1385,19 +1385,19 @@ struct Ray_to_Ray_3 // 2D case }; // Readable property map that converts the output of a given vertex point map to a 3D point -template::const_type> struct Point_to_Point_3_VPM { private: typedef VertexPointMap VPM; - typedef Point_to_Point_3_VPM Self; + typedef Point_to_Point_3_VPM Self; public: - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::property_traits::value_type Point; - typedef Point_to_Point_3 P_to_P3; + typedef Point_to_Point_3 P_to_P3; typedef typename CGAL::Kernel_traits::Kernel K; typedef typename K::Point_3 Point_3; @@ -1411,7 +1411,7 @@ public: // Constructors Point_to_Point_3_VPM() : conv_(), vpm_() { } // required for compilation by AABBtraits Point_to_Point_3_VPM(const VertexPointMap vpm) : conv_(), vpm_(vpm) { } - Point_to_Point_3_VPM(const PolygonMesh& mesh) + Point_to_Point_3_VPM(const TriangleMesh& mesh) : conv_(), vpm_(get_const_property_map(boost::vertex_point, mesh)) { } @@ -1536,13 +1536,13 @@ void build_AABB_tree(const TriangleMesh& tm, /// \cgalNamedParamsEnd /// template -typename Locate_types::Face_location -locate_with_AABB_tree(const typename Locate_types::Point& p, +typename Location_traits::Face_location +locate_with_AABB_tree(const typename Location_traits::Point& p, const AABB_tree& tree, const TriangleMesh& tm, const NamedParameters& np) { - typedef typename Locate_types::Point Point; + typedef typename Location_traits::Point Point; typedef internal::Point_to_Point_3 P_to_P3; typedef typename AABBTraits::Point_3 Point_3; CGAL_static_assertion((std::is_same::value)); @@ -1565,8 +1565,8 @@ locate_with_AABB_tree(const typename Locate_types #ifndef DOXYGEN_RUNNING template -typename Locate_types::Face_location -locate_with_AABB_tree(const typename Locate_types::Point& p, +typename Location_traits::Face_location +locate_with_AABB_tree(const typename Location_traits::Point& p, const AABB_tree& tree, const TriangleMesh& tm) { @@ -1599,8 +1599,8 @@ locate_with_AABB_tree(const typename Locate_types::Point& p, /// \cgalNamedParamsEnd /// template -typename Locate_types::Face_location -locate(const typename Locate_types::Point& p, +typename Location_traits::Face_location +locate(const typename Location_traits::Point& p, const TriangleMesh& tm, const NamedParameters& np) { @@ -1608,11 +1608,11 @@ locate(const typename Locate_types::Point& p, // already has value type Kernel::Point_3) typedef typename GetVertexPointMap::const_type VertexPointMap; typedef internal::Point_to_Point_3_VPM WrappedVPM; - typedef typename Locate_types::Point Intrinsic_point; + typedef typename Location_traits::Point Intrinsic_point; typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; typedef CGAL::AABB_traits< - typename Locate_types::Geom_traits, + typename Location_traits::Geom_traits, AABB_face_graph_primitive> AABB_face_graph_traits; typedef internal::Point_to_Point_3 P_to_P3; @@ -1633,7 +1633,7 @@ locate(const typename Locate_types::Point& p, #ifndef DOXYGEN_RUNNING template -typename Locate_types::Face_location +typename Location_traits::Face_location locate(const typename property_map_value::type& p, const TriangleMesh& tm) { @@ -1666,13 +1666,13 @@ locate(const typename property_map_value::t /// \cgalNamedParamsEnd /// template -typename Locate_types::Face_location -locate_with_AABB_tree(const typename Locate_types::Ray& ray, +typename Location_traits::Face_location +locate_with_AABB_tree(const typename Location_traits::Ray& ray, const AABB_tree& tree, const TriangleMesh& tm, const NamedParameters& np) { - typedef typename Locate_types::Geom_traits Geom_traits; + typedef typename Location_traits::Geom_traits Geom_traits; typedef typename Geom_traits::FT FT; typedef typename Geom_traits::Point_3 Point_3; @@ -1736,8 +1736,8 @@ locate_with_AABB_tree(const typename Locate_types #ifndef DOXYGEN_RUNNING template -typename Locate_types::Face_location -locate_with_AABB_tree(const typename Locate_types::Ray& ray, +typename Location_traits::Face_location +locate_with_AABB_tree(const typename Location_traits::Ray& ray, const AABB_tree& tree, const TriangleMesh& tm) { @@ -1774,8 +1774,8 @@ locate_with_AABB_tree(const typename Locate_types::Ray& ray, /// \cgalNamedParamsEnd /// template -typename Locate_types::Face_location -locate(const typename Locate_types::Ray& ray, +typename Location_traits::Face_location +locate(const typename Location_traits::Ray& ray, const TriangleMesh& tm, const NamedParameters& np) { @@ -1786,7 +1786,7 @@ locate(const typename Locate_types::Ray& ray, typedef internal::Point_to_Point_3_VPM VPM; typedef AABB_face_graph_triangle_primitive AABB_face_graph_primitive; - typedef CGAL::AABB_traits::Geom_traits, + typedef CGAL::AABB_traits::Geom_traits, AABB_face_graph_primitive> AABB_face_graph_traits; const VertexPointMap vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), @@ -1801,9 +1801,9 @@ locate(const typename Locate_types::Ray& ray, #ifndef DOXYGEN_RUNNING template -typename Locate_types::Face_location +typename Location_traits::Face_location locate(const typename internal::Ray_type_selector< - typename Locate_types::Point>::type& ray, + typename Location_traits::Point>::type& ray, const TriangleMesh& tm) { return locate(ray, tm, parameters::all_default()); diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index e7a838e3604..23863cadfcf 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -99,10 +99,10 @@ void test_snappers(const G& g) { std::cout << " test snappers..." << std::endl; - typedef typename PMP::Locate_types::FT FT; + typedef typename PMP::Location_traits::FT FT; - typename PMP::Locate_types::Barycentric_coordinates coords = CGAL::make_array(FT(1e-11), FT(0.99999999999999999), FT(1e-12)); - typename PMP::Locate_types::Face_location loc = std::make_pair(*(faces(g).first), coords); + typename PMP::Location_traits::Barycentric_coordinates coords = CGAL::make_array(FT(1e-11), FT(0.99999999999999999), FT(1e-12)); + typename PMP::Location_traits::Face_location loc = std::make_pair(*(faces(g).first), coords); // --------------------------------------------------------------------------- PMP::internal::snap_coordinates_to_border(coords); // uses numeric_limits' epsilon() @@ -140,15 +140,15 @@ void test_constructions(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::descriptor_variant descriptor_variant; + typedef typename PMP::Location_traits::descriptor_variant descriptor_variant; typedef typename boost::property_map_value::type Point; typedef typename CGAL::Kernel_traits::type Kernel; typedef typename Kernel::FT FT; typedef typename Point_to_bare_point::type Bare_point; - typedef typename PMP::Locate_types::Barycentric_coordinates Barycentric_coordinates; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Barycentric_coordinates Barycentric_coordinates; + typedef typename PMP::Location_traits::Face_location Face_location; typedef typename boost::property_map::const_type VPM; VPM vpm = CGAL::get_const_property_map(boost::vertex_point, g); @@ -226,7 +226,7 @@ void test_random_entities(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Face_location Face_location; typedef typename boost::property_map_value::type Point; typedef typename CGAL::Kernel_traits::type Kernel; @@ -272,7 +272,7 @@ void test_helpers(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Face_location Face_location; face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); @@ -320,7 +320,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Face_location Face_location; face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); @@ -412,7 +412,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Face_location Face_location; typedef typename boost::property_map::const_type VertexPointMap; VertexPointMap vpm = CGAL::get_const_property_map(boost::vertex_point, g); @@ -422,7 +422,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) const vertex_descriptor v = target(h, g); Face_location loc; - typename PMP::Locate_types::FT a = 0.1; + typename PMP::Location_traits::FT a = 0.1; Point p = get(vpm, v); loc = PMP::locate_in_face(v, g); @@ -493,7 +493,7 @@ struct Locate_with_AABB_tree_Tester // 2D case typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Face_location Face_location; face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); @@ -599,14 +599,14 @@ struct Locate_with_AABB_tree_Tester<3> // 3D typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename PMP::Locate_types::Face_location Face_location; + typedef typename PMP::Location_traits::Face_location Face_location; face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); halfedge_descriptor h = halfedge(f, g); vertex_descriptor v = target(h, g); // --------------------------------------------------------------------------- - typedef typename PMP::Locate_types::VPM VertexPointMap; + typedef typename PMP::Location_traits::VPM VertexPointMap; typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; typedef CGAL::AABB_traits AABB_face_graph_traits; @@ -684,7 +684,7 @@ void test_locate(const G& g, CGAL::Random& rnd) // This test has slight syntax changes between 2D and 3D (e.g. testing ray_2 in 3D makes no sense) Locate_with_AABB_tree_Tester< - CGAL::Ambient_dimension::Point>::value>()(g, rnd); + CGAL::Ambient_dimension::Point>::value>()(g, rnd); } template From 9664d8f774506ec5174216654580529c3acd7146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 18:20:32 +0200 Subject: [PATCH 41/68] Whether coordinate snapping is used or not is now a named parameter --- .../CGAL/boost/graph/parameters_interface.h | 1 + BGL/test/BGL/test_cgal_bgl_named_params.cpp | 3 ++ .../NamedParameters.txt | 11 +++++ .../CGAL/Polygon_mesh_processing/locate.h | 47 ++++++++++++++++++- 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index bd4f15d8e23..d53138c2f8a 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -82,6 +82,7 @@ CGAL_add_named_parameter(use_compact_clipper_t, use_compact_clipper, use_compact CGAL_add_named_parameter(output_iterator_t, output_iterator, output_iterator) CGAL_add_named_parameter(erase_all_duplicates_t, erase_all_duplicates, erase_all_duplicates) CGAL_add_named_parameter(require_same_orientation_t, require_same_orientation, require_same_orientation) +CGAL_add_named_parameter(snapping_tolerance_t, snapping_tolerance, snapping_tolerance) // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 346043ff037..21e070cfa34 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -88,6 +88,7 @@ void test(const NamedParameters& np) assert(get_param(np, CGAL::internal_np::erase_all_duplicates).v == 48); assert(get_param(np, CGAL::internal_np::require_same_orientation).v == 49); assert(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface).v == 50); + assert(get_param(np, CGAL::internal_np::snapping_tolerance).v == 53); // Named parameters that we use in the package 'Surface Mesh Simplification' assert(get_param(np, CGAL::internal_np::get_cost_policy).v == 34); @@ -169,6 +170,7 @@ void test(const NamedParameters& np) check_same_type<48>(get_param(np, CGAL::internal_np::erase_all_duplicates)); check_same_type<49>(get_param(np, CGAL::internal_np::require_same_orientation)); check_same_type<50>(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface)); + check_same_type<49>(get_param(np, CGAL::internal_np::snapping_tolerance)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -253,6 +255,7 @@ int main() .output_iterator(A<47>(47)) .erase_all_duplicates(A<48>(48)) .require_same_orientation(A<49>(49)) + .snapping_tolerance(A<53>(53)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 6176b34f75c..dfa33d17bde 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -388,6 +388,17 @@ if orientation should matter when determining whether two faces are duplicates. Default: `false` \cgalNPEnd +\cgalNPBegin{snapping_tolerance} \anchor PMP_snapping_tolerance +Parameter used in the function `locate_in_face()` to to snap barycentric coordinates. Depending on the geometric traits used, +the computation of the barycentric coordinates might be an inexact construction, thus leading +to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle +of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while +still ensuring that the total sum of the coordinates is `1`. +\n +Type: `Kernel::FT` \n +Default: `0` +\cgalNPEnd + \cgalNPTableEnd */ diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index e9e5028b496..ce72895e805 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -1040,6 +1040,13 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. /// \cgalParamEnd +/// \cgalParamBegin{snapping_tolerance} +/// a tolerance value used to snap barycentric coordinates. Depending on the geometric traits used, +/// the computation of the barycentric coordinates might be an inexact construction, thus leading +/// to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle +/// of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while +/// still ensuring that the total sum of the coordinates is `1`. By default, the tolerance is `0`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template @@ -1062,6 +1069,8 @@ locate_in_face(const typename Location_traits::Po get_const_property_map(boost::vertex_point, tm)); Geom_traits gt = choose_param(get_param(np, internal_np::geom_traits), Geom_traits()); + FT snap_tolerance = choose_param(get_param(np, internal_np::snapping_tolerance), 0); + vertex_descriptor vd0 = source(halfedge(fd, tm), tm); vertex_descriptor vd1 = target(halfedge(fd, tm), tm); vertex_descriptor vd2 = target(next(halfedge(fd, tm), tm), tm); @@ -1072,14 +1081,14 @@ locate_in_face(const typename Location_traits::Po std::array coords = barycentric_coordinates(p0, p1, p2, query, gt); - if(!is_in_face(coords, tm)) + if(snap_tolerance != FT(0) && !is_in_face(coords, tm)) { std::cerr << "Warning: point " << query << " is not in the input face" << std::endl; std::cerr << "Coordinates: " << coords[0] << " " << coords[1] << " " << coords[2] << std::endl; // Try to to snap the coordinates, hoping the problem is just a -1e-17ish epsilon // pushing the coordinates over the edge - internal::snap_coordinates_to_border(coords); // @tmp keep or not ? + internal::snap_coordinates_to_border(coords); } return std::make_pair(fd, coords); @@ -1465,6 +1474,13 @@ void build_AABB_tree(const TriangleMesh& tm, } // namespace internal /// \name Nearest Face Location Queries +/// The following functions can be used to find the closest point on a triangle mesh, given either +/// a point or a ray. This closest point is computed using a `CGAL::AABB_tree`. Users intending +/// to call location functions on more than a single point (or ray) should first compute an AABB +/// tree to store it (otherwise, it will be recomputed every time). Note that since the AABB tree +/// class is a 3D structure, it might be required to wrap your point property map to convert your +/// point type to the \cgal 3D point type if you are working with a 2D triangle structure. +/// /// @{ /// \ingroup PMP_locate_grp @@ -1533,6 +1549,16 @@ void build_AABB_tree(const TriangleMesh& tm, /// If this parameter is omitted, an internal property map for /// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd +/// \cgalParamBegin{geom_traits} +/// a geometric traits class instance, model of `Kernel`. +/// \cgalParamEnd +/// \cgalParamBegin{snapping_tolerance} +/// a tolerance value used to snap barycentric coordinates. Depending on the geometric traits used, +/// the computation of the barycentric coordinates might be an inexact construction, thus leading +/// to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle +/// of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while +/// still ensuring that the total sum of the coordinates is `1`. By default, the tolerance is `0`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template @@ -1596,6 +1622,16 @@ locate_with_AABB_tree(const typename Location_traits::Point& p, /// If this parameter is omitted, an internal property map for /// `boost::vertex_point_t` must be available in `TriangleMesh`. /// \cgalParamEnd +/// \cgalParamBegin{geom_traits} +/// a geometric traits class instance, model of `Kernel`. +/// \cgalParamEnd +/// \cgalParamBegin{snapping_tolerance} +/// a tolerance value used to snap barycentric coordinates. Depending on the geometric traits used, +/// the computation of the barycentric coordinates might be an inexact construction, thus leading +/// to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle +/// of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while +/// still ensuring that the total sum of the coordinates is `1`. By default, the tolerance is `0`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template @@ -1771,6 +1807,13 @@ locate_with_AABB_tree(const typename Location_traits::Ray& ray, /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. /// \cgalParamEnd +/// \cgalParamBegin{snapping_tolerance} +/// a tolerance value used to snap barycentric coordinates. Depending on the geometric traits used, +/// the computation of the barycentric coordinates might be an inexact construction, thus leading +/// to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle +/// of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while +/// still ensuring that the total sum of the coordinates is `1`. By default, the tolerance is `0`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// template From b1c9c993e27eee609e806ef9943d634857c8f3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 18:21:01 +0200 Subject: [PATCH 42/68] Be more restrictive on the AABB tree type --- .../CGAL/Polygon_mesh_processing/locate.h | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index ce72895e805..1c489b7adeb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -387,7 +387,7 @@ struct Barycentric_point_constructor // 3D version /// /// \pre `p`, `q`, and `r` are not collinear. /// \pre It must be possible to extract a kernel type model of `Kernel`, using `CGAL::Kernel_traits

` -/// (this is the case for all standard %CGAL point types). +/// (this is the case for all standard %CGAL point types and classes inheriting such point types). /// \pre `query` lies on the plane defined by `p`, `q`, and `r`. /// template @@ -1493,7 +1493,8 @@ void build_AABB_tree(const TriangleMesh& tm, /// multiple times, which will build a new AABB tree on every call. /// /// \tparam TriangleMesh A model of `FaceListGraph` -/// \tparam AABBTraits A model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam Point3VPM a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` +/// as key type and the \cgal 3D point type as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param tm a triangulated surface mesh @@ -1508,9 +1509,13 @@ void build_AABB_tree(const TriangleMesh& tm, /// \cgalParamEnd /// \cgalNamedParamsEnd /// -template +template void build_AABB_tree(const TriangleMesh& tm, - AABB_tree& outTree, + AABB_tree< + CGAL::AABB_traits< + typename Location_traits::Geom_traits, + CGAL::AABB_face_graph_triangle_primitive + > >& outTree, const NamedParameters& np) { typedef typename GetVertexPointMap::const_type VertexPointMap; @@ -1534,8 +1539,13 @@ void build_AABB_tree(const TriangleMesh& tm, /// /// \brief returns the face location nearest to the given point, as a `Face_location`. /// +/// Note that it is possible for the triangle mesh to have ambiant dimension `2` (e.g. the mesh +/// is a 2D triangulation, or a CGAL::Surface_mesh >), as long as an appropriate +/// vertex point property map is passed in the AABB tree, which will convert from 2D to 3D. +/// /// \tparam TriangleMesh A model of `FaceListGraph` -/// \tparam AABBTraits A model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam Point3VPM a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` +/// as key type and the \cgal 3D point type as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param p the point to locate on the input triangulated surface mesh @@ -1561,23 +1571,31 @@ void build_AABB_tree(const TriangleMesh& tm, /// \cgalParamEnd /// \cgalNamedParamsEnd /// -template +template typename Location_traits::Face_location locate_with_AABB_tree(const typename Location_traits::Point& p, - const AABB_tree& tree, + const AABB_tree< + CGAL::AABB_traits< + typename Location_traits::Geom_traits, + CGAL::AABB_face_graph_triangle_primitive + > >& tree, const TriangleMesh& tm, const NamedParameters& np) { typedef typename Location_traits::Point Point; typedef internal::Point_to_Point_3 P_to_P3; - typedef typename AABBTraits::Point_3 Point_3; + typedef typename boost::property_traits::value_type Point_3; CGAL_static_assertion((std::is_same::value)); + typedef typename Location_traits::Geom_traits Geom_traits; + typedef typename CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef typename CGAL::AABB_traits AABB_traits; + typedef typename GetVertexPointMap::const_type VertexPointMap; typedef internal::Point_to_Point_3_VPM WrappedVPM; const Point_3& p3 = P_to_P3()(p); - typename AABB_tree::Point_and_primitive_id result = tree.closest_point_and_primitive(p3); + typename AABB_tree::Point_and_primitive_id result = tree.closest_point_and_primitive(p3); // The VPM might return a point of any dimension, but the AABB tree necessarily returns // a Point_3. So, wrap the VPM (again) to give a Point_3. Even if it's already wrapped, we're just @@ -1609,7 +1627,6 @@ locate_with_AABB_tree(const typename Location_traits::Point& p, /// an `AABB_tree` that you can store and use the function `locate_with_AABB_tree()`. /// /// \tparam TriangleMesh must be a model of `FaceListGraph`. -/// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param p the point to locate on the input triangulated surface mesh @@ -1682,11 +1699,12 @@ locate(const typename property_map_value::t /// \brief Returns the face location along `ray` nearest to its source point. /// /// \tparam TriangleMesh must be a model of `FaceListGraph`. -/// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. +/// \tparam Point3VPM a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` +/// as key type and the \cgal 3D point type as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param ray Ray to intersect with the input triangulated surface mesh -/// \param tree A `AABB_tree` containing the triangular faces of the input surface mesh to perform the point location with +/// \param tree An `AABB_tree` containing the triangular faces of the input surface mesh to perform the point location with /// \param tm a triangulated surface mesh /// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: /// @@ -1699,12 +1717,23 @@ locate(const typename property_map_value::t /// \cgalParamBegin{geom_traits} /// a geometric traits class instance, model of `Kernel`. /// \cgalParamEnd +/// \cgalParamBegin{snapping_tolerance} +/// a tolerance value used to snap barycentric coordinates. Depending on the geometric traits used, +/// the computation of the barycentric coordinates might be an inexact construction, thus leading +/// to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle +/// of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while +/// still ensuring that the total sum of the coordinates is `1`. By default, the tolerance is `0`. +/// \cgalParamEnd /// \cgalNamedParamsEnd /// -template +template typename Location_traits::Face_location locate_with_AABB_tree(const typename Location_traits::Ray& ray, - const AABB_tree& tree, + const AABB_tree< + CGAL::AABB_traits< + typename Location_traits::Geom_traits, + CGAL::AABB_face_graph_triangle_primitive + > >& tree, const TriangleMesh& tm, const NamedParameters& np) { @@ -1720,7 +1749,10 @@ locate_with_AABB_tree(const typename Location_traits WrappedVPM; typedef internal::Ray_to_Ray_3 R_to_R3; - typedef AABB_tree AABB_face_graph_tree; + typedef typename Location_traits::Geom_traits Geom_traits; + typedef typename CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef typename CGAL::AABB_traits AABB_traits; + typedef AABB_tree AABB_face_graph_tree; typedef typename AABB_face_graph_tree::template Intersection_and_primitive_id::Type Intersection_type; typedef boost::optional Ray_intersection; From 28cdbb7df73c581aaa74eadd01944fae41efbd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 18:25:14 +0200 Subject: [PATCH 43/68] Fixed using random border halfedges --- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 23863cadfcf..a000a3030cf 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -236,6 +236,8 @@ void test_random_entities(const G& g, CGAL::Random& rnd) Face_location loc; halfedge_descriptor h = CGAL::internal::random_halfedge_in_mesh(g, rnd); + if(is_border(h, g)) + h = opposite(h, g); face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); int nn = 1e2; @@ -803,7 +805,7 @@ int main() std::cout.precision(17); std::cout << std::fixed; -// CGAL::Random rnd(1556198743); // if needed to debug with a fixed seed +// CGAL::Random rnd(1557332474); // if needed to debug with a fixed seed CGAL::Random rnd(CGAL::get_default_random()); std::cout << "The seed is " << rnd.get_seed() << std::endl; From 33c4c87a907cea446227bcc86b11864f61f77748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 18:28:27 +0200 Subject: [PATCH 44/68] Actually use the snapping tolerance... --- .../include/CGAL/Polygon_mesh_processing/locate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 1c489b7adeb..802d5d7fe4f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -1088,7 +1088,7 @@ locate_in_face(const typename Location_traits::Po // Try to to snap the coordinates, hoping the problem is just a -1e-17ish epsilon // pushing the coordinates over the edge - internal::snap_coordinates_to_border(coords); + internal::snap_coordinates_to_border(coords, snap_tolerance); } return std::make_pair(fd, coords); From af1280e34e77b1857f2ae4171f23a06cffee3704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 18:50:05 +0200 Subject: [PATCH 45/68] Clean documentation --- BGL/doc/BGL/Doxyfile.in | 1 + .../doc/Polygon_mesh_processing/PackageDescription.txt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 9681886835a..c676a95fc13 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -4,6 +4,7 @@ PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL and the Boost Graph Library" INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/iterator.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/helpers.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/generators.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/selection.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/split_graph_into_polylines.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph.h \ diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index a35edeffdfb..3b74aef20a4 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -127,8 +127,6 @@ and provides a list of the parameters that are used in this package. \cgalCRPSection{Location Functions} - \link PMP_locate_grp Point Location \endlink -- \link PMP_locate_grp Random Simplex Generation \endlink -- \link PMP_locate_grp Simplex Index \endlink - \link PMP_locate_grp Location Predicates \endlink - \link PMP_locate_grp Nearest Face Location Queries \endlink - \link PMP_locate_grp Random Location Generation \endlink From 75f9c7798e200bcce252622467c68ceac0f567cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 9 May 2019 08:06:10 +0200 Subject: [PATCH 46/68] Add a forward declaration --- BGL/include/CGAL/boost/graph/generators.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BGL/include/CGAL/boost/graph/generators.h b/BGL/include/CGAL/boost/graph/generators.h index 4df1422d895..8659f68738c 100644 --- a/BGL/include/CGAL/boost/graph/generators.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -43,6 +43,11 @@ typename boost::graph_traits::face_descriptor add_face(const VertexRange& namespace internal { +template +void swap_vertices(typename boost::graph_traits::vertex_descriptor& p, + typename boost::graph_traits::vertex_descriptor& q, + FaceGraph& g); + template typename std::iterator_traits::value_type random_entity_in_range(InputIterator first, InputIterator beyond, From 408ebbb7846fb932d70eac5716d8b1ad82100e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 10 May 2019 11:44:58 +0200 Subject: [PATCH 47/68] Dependency fixes --- BGL/include/CGAL/boost/graph/Euler_operations.h | 11 +++++++++++ BGL/include/CGAL/boost/graph/generators.h | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 64a2ac94226..c84816bf49c 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -35,6 +35,17 @@ namespace CGAL { /// \cond SKIP_IN_MANUAL +// Some forward declaration to break the helpers.h > generators.h > Euler_operations.h cycle +template +boost::optional::halfedge_descriptor> +is_border(typename boost::graph_traits::vertex_descriptor vd, const FaceGraph& g); +template +bool is_border(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g); +template +bool is_border(typename boost::graph_traits::edge_descriptor ed, const FaceGraph& g); +template +bool is_valid_polygon_mesh(const Mesh& g, bool verb); + namespace EulerImpl { template diff --git a/BGL/include/CGAL/boost/graph/generators.h b/BGL/include/CGAL/boost/graph/generators.h index 8659f68738c..d7b6f4ad379 100644 --- a/BGL/include/CGAL/boost/graph/generators.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -25,12 +25,15 @@ #include #include +#include + #include #include namespace CGAL { namespace Euler { +// Some forward declaration to break the helpers.h > generators.h > Euler_operations.h cycle template< typename Graph> void fill_hole(typename boost::graph_traits::halfedge_descriptor h, Graph& g); @@ -821,7 +824,4 @@ make_grid(typename boost::graph_traits::vertices_size_type w, } // namespace CGAL -// Include "Euler_operations.h" at the end, because its implementation requires this header. -#include - #endif // CGAL_BOOST_GRAPH_GENERATORS_H From 1e9ca61fba13e837918da417567c63d682a6903c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 10 May 2019 11:45:49 +0200 Subject: [PATCH 48/68] Doc fixes --- BGL/include/CGAL/boost/graph/generators.h | 12 +- BGL/include/CGAL/boost/graph/helpers.h | 4 +- .../Periodic_2_triangulation_2.txt | 2 +- .../Polygon_mesh_processing.txt | 5 +- .../CGAL/Polygon_mesh_processing/locate.h | 169 ++++++++++-------- 5 files changed, 104 insertions(+), 88 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/generators.h b/BGL/include/CGAL/boost/graph/generators.h index d7b6f4ad379..84453191537 100644 --- a/BGL/include/CGAL/boost/graph/generators.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -73,7 +73,7 @@ random_entity_in_range(const CGAL::Iterator_range& range, } // \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `g`. -// \tparam Graph A model of `HalfedgeGraph` +// \tparam Graph a model of `HalfedgeGraph` template typename boost::graph_traits::vertex_descriptor random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, @@ -84,7 +84,7 @@ random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, } // \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `g`. -// \tparam Graph A model of `HalfedgeGraph` +// \tparam Graph a model of `HalfedgeGraph` template typename boost::graph_traits::halfedge_descriptor random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, @@ -95,7 +95,7 @@ random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, } // \brief returns a random non-null vertex of the polygon mesh `g`. -// \tparam Graph A model of `VertexListGraph` +// \tparam Graph a model of `VertexListGraph` template typename boost::graph_traits::vertex_descriptor random_vertex_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) @@ -104,7 +104,7 @@ random_vertex_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) } // \brief returns a random non-null halfedge of the polygon mesh `g`. -// \tparam Graph A model of `HalfedgeListGraph` +// \tparam Graph a model of `HalfedgeListGraph` template typename boost::graph_traits::halfedge_descriptor random_halfedge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) @@ -113,7 +113,7 @@ random_halfedge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random() } // \brief returns a random non-null edge of the polygon mesh `g`. -// \tparam Graph A model of `EdgeListGraph` +// \tparam Graph a model of `EdgeListGraph` template typename boost::graph_traits::edge_descriptor random_edge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) @@ -122,7 +122,7 @@ random_edge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) } // \brief returns a random non-null face of the polygon mesh `g`. -// \tparam Graph A model of `FaceListGraph` +// \tparam Graph a model of `FaceListGraph` template typename boost::graph_traits::face_descriptor random_face_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index f4836c7f1dc..1104f8c06da 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -834,7 +834,7 @@ bool is_empty(const FaceGraph& g) /// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd` /// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. /// -/// \tparam Graph A model of `FaceGraph` +/// \tparam Graph a model of `FaceGraph` /// /// \param vd a vertex of `g` whose index is sought /// \param fd a face of `g` in which the index of `vd` is sought @@ -876,7 +876,7 @@ int vertex_index_in_face(const typename boost::graph_traits::vertex_descr /// \brief returns the number of calls to `next(hd, tm)` one has to apply to `hd` for `hd == he` /// to be true, starting from `hd = halfedge(face(he, tm), tm)`. /// -/// \tparam Graph A model of `FaceGraph`. +/// \tparam Graph a model of `FaceGraph`. /// /// \param he a halfedge of `g` whose index in `face(he, tm)` is sought /// \param g an object of type `Graph` diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt index a0a56502ead..ac02381048b 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt @@ -225,7 +225,7 @@ all objects, predicates and constructions with using offsets. The class `Periodic_2_Delaunay_triangulation_traits_2` provides the required functionality. It expects two template -parameters: A model of the concept `DelaunayTriangulationTraits_2` +parameters: a model of the concept `DelaunayTriangulationTraits_2` and a model of the concept `Periodic_2Offset_2`. Since the concept `TriangulationTraits_2` refines the concept `DelaunayTriangulationTraits_2`, the class diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 05cff8fb35c..b46ae4c1241 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -478,9 +478,8 @@ of the surface (i.e. 2) and not on the ambient dimension within which the surfac The functions of the group \ref PMP_locate_grp offer the following functionalities: location computations (`CGAL::Polygon_mesh_processing::locate()`, and similar) given a point, finding the nearest point on a mesh given a point or a ray -(`CGAL::Polygon_mesh_processing::locate_with_AABB_tree()`, and similar), location-based predicates -(for example, `CGAL::Polygon_mesh_processing::is_on_face_border()`), and random location generation -(for example, `CGAL::Polygon_mesh_processing::random_vertex_in_mesh()`). +(`CGAL::Polygon_mesh_processing::locate_with_AABB_tree()`, and similar), and location-based predicates +(for example, `CGAL::Polygon_mesh_processing::is_on_face_border()`). **************************************** \section PMPOrientation Orientation diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 802d5d7fe4f..df2b2301a35 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -88,7 +88,7 @@ struct Ray_type_selector /// /// \brief Helper class whose sole purpose is to make it easier to access some useful types. /// -/// \tparam TriangleMesh A model of `FaceListGraph` +/// \tparam TriangleMesh a model of `FaceListGraph` /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// template ::Face_location& l template struct Barycentric_coordinate_calculator // 2D version { - CGAL::array + std::array operator()(const P& ip, const P& iq, const P& ir, const P& iquery, const K& k) const { typedef typename K::FT FT; @@ -299,7 +299,7 @@ struct Barycentric_coordinate_calculator // 2D version template struct Barycentric_coordinate_calculator { - CGAL::array + std::array operator()(const P& ip, const P& iq, const P& ir, const P& iquery, const K& k) const { typedef typename K::FT FT; @@ -391,7 +391,7 @@ struct Barycentric_point_constructor // 3D version /// \pre `query` lies on the plane defined by `p`, `q`, and `r`. /// template -CGAL::array +std::array barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query, const K& k) { @@ -400,9 +400,8 @@ barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Po } template -CGAL::array::type::FT, 3> -barycentric_coordinates(const Point& p, const Point& q, const Point& r, - const Point& query) +std::array::type::FT, 3> +barycentric_coordinates(const Point& p, const Point& q, const Point& r, const Point& query) { typedef typename CGAL::Kernel_traits::type Kernel; @@ -414,14 +413,14 @@ barycentric_coordinates(const Point& p, const Point& q, const Point& r, /// \ingroup PMP_locate_grp /// -/// \brief Returns a random point over the halfedge `hd`, as a `Face_location`. +/// \brief Returns a random point over the halfedge `hd`, as a location. /// /// \details The random point is chosen on the halfedge, meaning that all /// its barycentric coordinates are positive. It is constructed by uniformly generating /// a value `t` between `0` and `1` and setting the barycentric coordinates to `t`, `1-t`, /// and `0` for respetively the source and target of `hd`, and the third vertex. /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// /// \param hd a halfedge of `tm` /// \param tm a triangulated surface mesh @@ -443,14 +442,14 @@ random_location_on_halfedge(typename boost::graph_traits::halfedge /// \ingroup PMP_locate_grp /// -/// \brief Returns a random point over the face `fd`, as a `Face_location`. +/// \brief Returns a random point over the face `fd`, as a location. /// /// \details The random point is on the face, meaning that all its barycentric coordinates /// are positive. It is constructed by uniformly picking a value `u` between `0` and `1`, /// a value `v` between `1-u`, and setting the barycentric coordinates to `u`, `v`, and /// `1-u-v` for respectively the source and target of `halfedge(fd, tm)`, and the third point. /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// /// \param fd a face of `tm` /// \param tm a triangulated surface mesh @@ -483,7 +482,7 @@ random_location_on_face(typename boost::graph_traits::face_descrip /// a random point on that face. The barycentric coordinates of the point in the face /// are thus all positive. Note that all faces have the same probability to be chosen. /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// /// \param tm a triangulated surface mesh /// \param rnd optional random number generator @@ -506,22 +505,26 @@ random_location_on_mesh(const TriangleMesh& tm, CGAL::Random& rnd = get_default_ /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns a descriptor to the simplex /// of smallest dimension on which the point corresponding to the location lies. /// /// \details In other words: -/// - if the point lies on a vertex, this function returns a `vertex_descriptor` `v`; -/// - if the point lies on a halfedge, this function returns a `halfedge_descriptor` `hd` +/// - if the point lies on a vertex, this function returns a `boost::graph_traits::%vertex_descriptor` `v`; +/// - if the point lies on a halfedge, this function returns a `boost::graph_traits::%halfedge_descriptor` `hd` /// (note that in that case, `loc.first == face(hd, tm)` holds). -/// - otherwise, this function returns a `boost::graph_traitsface_descriptor` +/// - otherwise, this function returns a `boost::graph_traits::%face_descriptor` /// `fd` (equal to `loc.first`). /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` +/// +/// \param loc a location with `loc.first` a face of `tm` +/// \param tm a triangulated surface mesh /// /// \pre the location corresponds to a point that is within a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. +/// \pre `loc` describes the barycentric coordinates of a point that lives on the face (boundary included), +/// meaning the barycentric coordinates are all positive. /// template typename Location_traits::descriptor_variant @@ -565,12 +568,12 @@ get_descriptor_from_location(const typename Location_traits::Face_ /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns the geometric position described /// by these coordinates, as a point. /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param loc the location to transform into a point @@ -589,7 +592,6 @@ get_descriptor_from_location(const typename Location_traits::Face_ /// \cgalNamedParamsEnd /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. /// template typename Location_traits::Point @@ -631,7 +633,7 @@ construct_point(const typename Location_traits::Face_location& loc /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// on the vertex `vd` or not. @@ -643,15 +645,18 @@ construct_point(const typename Location_traits::Face_location& loc /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` +/// +/// \param loc a location with `loc.first` a face of `tm` +/// \param vd a vertex of `tm` +/// \param tm a triangulated surface mesh /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. /// template bool is_on_vertex(const typename Location_traits::Face_location& loc, - const typename boost::graph_traits::vertex_descriptor v, + const typename boost::graph_traits::vertex_descriptor vd, const TriangleMesh& tm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -663,14 +668,14 @@ is_on_vertex(const typename Location_traits::Face_location& loc, descriptor_variant dv = get_descriptor_from_location(loc, tm); if(const vertex_descriptor* vd_ptr = boost::get(&dv)) - return (v == *vd_ptr); + return (vd == *vd_ptr); return false; } /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// on the halfedge `hd` or not. @@ -682,15 +687,18 @@ is_on_vertex(const typename Location_traits::Face_location& loc, /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` +/// +/// \param loc a location with `loc.first` a face of `tm` +/// \param hd a halfedge of `tm` +/// \param tm a triangulated surface mesh /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. /// template bool is_on_halfedge(const typename Location_traits::Face_location& loc, - const typename boost::graph_traits::halfedge_descriptor h, + const typename boost::graph_traits::halfedge_descriptor hd, const TriangleMesh& tm) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -703,9 +711,9 @@ is_on_halfedge(const typename Location_traits::Face_location& loc, descriptor_variant dv = get_descriptor_from_location(loc, tm); if(const vertex_descriptor* vd_ptr = boost::get(&dv)) - return (*vd_ptr == source(h, tm) || *vd_ptr == target(h, tm)); + return (*vd_ptr == source(hd, tm) || *vd_ptr == target(hd, tm)); else if(const halfedge_descriptor* hd_ptr = boost::get(&dv)) - return (*hd_ptr == h); + return (*hd_ptr == hd); return false; } @@ -723,9 +731,10 @@ is_on_halfedge(const typename Location_traits::Face_location& loc, /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// -/// \pre `tm` is a triangulated surface mesh. +/// \param bar an array of barycentric coordinates +/// \param tm a triangulated surface mesh /// template bool @@ -748,7 +757,7 @@ is_in_face(const typename Location_traits::Barycentric_coordinates /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// in the face (boundary included) or not. @@ -760,10 +769,12 @@ is_in_face(const typename Location_traits::Barycentric_coordinates /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` +/// +/// \param loc a location with `loc.first` a face of `tm` +/// \param tm a triangulated surface mesh /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. /// template bool @@ -775,7 +786,7 @@ is_in_face(const typename Location_traits::Face_location& loc, /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is on the boundary /// of the face or not. @@ -787,10 +798,12 @@ is_in_face(const typename Location_traits::Face_location& loc, /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` +/// +/// \param loc a location with `loc.first` a face of `tm` +/// \param tm a triangulated surface mesh /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. /// template bool @@ -814,7 +827,7 @@ is_on_face_border(const typename Location_traits::Face_location& l /// \ingroup PMP_locate_grp /// -/// \brief Given a `Face_location`, that is an ordered pair composed of a +/// \brief Given a location, that is an ordered pair composed of a /// `boost::graph_traits::%face_descriptor` and an array /// of barycentric coordinates, returns whether the location is /// on the border of the mesh or not. @@ -826,10 +839,12 @@ is_on_face_border(const typename Location_traits::Face_location& l /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` +/// +/// \param loc a location with `loc.first` a face of `tm` +/// \param tm a triangulated surface mesh /// /// \pre `loc.first` is a face descriptor corresponding to a face of `tm`. -/// \pre `tm` is a triangulated surface mesh. /// template bool @@ -879,7 +894,7 @@ is_on_mesh_border(const typename Location_traits::Face_location& l /// \ingroup PMP_locate_grp /// -/// \brief Returns the location of the given vertex `vd` as a `Face_location`, +/// \brief Returns the location of the given vertex `vd` as a location, /// that is an ordered pair specifying a face containing the location /// and the barycentric coordinates of the vertex `vd` in that face. /// @@ -890,7 +905,7 @@ is_on_mesh_border(const typename Location_traits::Face_location& l /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// /// \param vd a vertex of `tm` /// \param tm a triangulated surface mesh @@ -934,7 +949,7 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, /// \ingroup PMP_locate_grp /// -/// \brief Returns the location of a given vertex as a `Face_location` in `fd`, +/// \brief Returns the location of a given vertex as a location in `fd`, /// that is an ordered pair composed of `fd` and of the barycentric coordinates /// of the vertex in `fd`. /// @@ -945,7 +960,7 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// /// \param vd a vertex of `tm` and a vertex of the face `fd` /// \param fd a face of `tm` @@ -970,7 +985,7 @@ locate_in_face(const typename boost::graph_traits::vertex_descript /// /// \brief Given a point described by a halfedge `he` and a scalar `t` /// as `p = (1 - t) * source(he, tm) + t * target(he, tm)`, -/// returns this location along the given edge as a `Face_location`, that is +/// returns this location along the given edge as a location, that is /// an ordered pair specifying a face containing the location and the /// barycentric coordinates of that location in that face. /// @@ -981,13 +996,11 @@ locate_in_face(const typename boost::graph_traits::vertex_descript /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// /// \param he a halfedge of `tm` -/// \param t the parametric distance of the desired point along `he` -/// \param tm a triangulation surface mesh -/// -/// \pre `tm` is a triangulated surface mesh. +/// \param t the parametric distance of the desired point along `he` +/// \param tm a triangulated surface mesh /// template typename Location_traits::Face_location @@ -1011,8 +1024,8 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// \ingroup PMP_locate_grp /// -/// \brief Given a point `query` and a face `fd` of a triangulation surface mesh, -/// returns this location as a `Face_location`, that is +/// \brief Given a point `query` and a face `fd` of a triangulated surface mesh, +/// returns this location as a location, that is /// an ordered pair composed of `fd` and of the barycentric coordinates of /// `query` with respect to the vertices of `fd`. /// @@ -1023,7 +1036,7 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// - `w1` corresponds to `target(halfedge(f, tm), tm)` /// - `w2` corresponds to `target(next(halfedge(f, tm), tm), tm)` /// -/// \tparam TriangleMesh A model of `FaceGraph` +/// \tparam TriangleMesh a model of `FaceGraph` /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param query a point @@ -1107,10 +1120,10 @@ locate_in_face(const typename property_map_value::%face_descriptor` and an array /// of barycentric coordinates, and a second face adjacent to the first, -/// return the `Face_location` of the point in the second face. +/// return the location of the point in the second face. /// /// \details 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 correspondance @@ -1119,7 +1132,7 @@ locate_in_face(const typename property_map_value::%vertex_descriptor` -/// as key type and the \cgal 3D point type as value type. +/// as key type and the \cgal 3D point type (your kernel's `%Point_3`) as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param tm a triangulated surface mesh @@ -1537,19 +1551,19 @@ void build_AABB_tree(const TriangleMesh& tm, /// \ingroup PMP_locate_grp /// -/// \brief returns the face location nearest to the given point, as a `Face_location`. +/// \brief returns the face location nearest to the given point, as a location. /// /// Note that it is possible for the triangle mesh to have ambiant dimension `2` (e.g. the mesh /// is a 2D triangulation, or a CGAL::Surface_mesh >), as long as an appropriate /// vertex point property map is passed in the AABB tree, which will convert from 2D to 3D. /// -/// \tparam TriangleMesh A model of `FaceListGraph` +/// \tparam TriangleMesh a model of `FaceListGraph` /// \tparam Point3VPM a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` -/// as key type and the \cgal 3D point type as value type. +/// as key type and the \cgal 3D point type (your kernel's `%Point_3`) as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param p the point to locate on the input triangulated surface mesh -/// \param tree An `AABB_tree` containing the triangular faces of the input surface mesh to perform the point location with +/// \param tree an AABB tree containing the triangular faces of the input surface mesh to perform the point location with /// \param tm a triangulated surface mesh /// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: /// @@ -1622,9 +1636,9 @@ locate_with_AABB_tree(const typename Location_traits::Point& p, /// /// \brief returns the nearest face location to the given point. /// -/// \details Note that this function will build an `AABB_tree` on each call. If you need +/// \details Note that this function will build an AABB tree on each call. If you need /// to call this function more than once, first use `build_AABB_tree()` to create a -/// an `AABB_tree` that you can store and use the function `locate_with_AABB_tree()`. +/// an AABB tree that you can store and use the function `locate_with_AABB_tree()`. /// /// \tparam TriangleMesh must be a model of `FaceListGraph`. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" @@ -1698,13 +1712,15 @@ locate(const typename property_map_value::t /// /// \brief Returns the face location along `ray` nearest to its source point. /// +/// If the ray does not intersect the mesh, a default constructed location is returned. +/// /// \tparam TriangleMesh must be a model of `FaceListGraph`. /// \tparam Point3VPM a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` -/// as key type and the \cgal 3D point type as value type. +/// as key type and the \cgal 3D point type (your kernel's `%Point_3`) as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// -/// \param ray Ray to intersect with the input triangulated surface mesh -/// \param tree An `AABB_tree` containing the triangular faces of the input surface mesh to perform the point location with +/// \param ray a ray to intersect with the input triangulated surface mesh +/// \param tree an AABB tree containing the triangular faces of the input surface mesh to perform the point location with /// \param tm a triangulated surface mesh /// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: /// @@ -1817,16 +1833,17 @@ locate_with_AABB_tree(const typename Location_traits::Ray& ray, /// /// \brief Returns the face location along `ray` nearest to its source point. /// -/// \details Note that this function will build an `AABB_tree` on each call. If you need +/// If the ray does not intersect the mesh, a default constructed location is returned. +/// +/// \details Note that this function will build an AABB tree on each call. If you need /// to call this function more than once, use `build_AABB_tree()` to cache a /// copy of the `AABB_tree`, and use the overloads of this function -/// that accept a reference to an `AABB_tree` as input. +/// that accept a reference to an AABB tree as input. /// /// \tparam TriangleMesh must be a model of `FaceListGraph`. -/// \tparam AABBTraits must be a model of `AABBTraits` used to define a \cgal `AABB_tree`. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// -/// \param ray Ray to intersect with the input triangulated surface mesh +/// \param ray a ray to intersect with the input triangulated surface mesh /// \param tm the input triangulated surface mesh /// \param np an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below: /// From 05285920114e53e1347cd980a91d4480963337b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 10 May 2019 12:41:01 +0200 Subject: [PATCH 49/68] Fix cyclical header dependencies --- BGL/include/CGAL/boost/graph/Euler_operations.h | 11 ----------- BGL/include/CGAL/boost/graph/generators.h | 6 ++++-- BGL/include/CGAL/boost/graph/helpers.h | 5 ++++- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index c84816bf49c..64a2ac94226 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -35,17 +35,6 @@ namespace CGAL { /// \cond SKIP_IN_MANUAL -// Some forward declaration to break the helpers.h > generators.h > Euler_operations.h cycle -template -boost::optional::halfedge_descriptor> -is_border(typename boost::graph_traits::vertex_descriptor vd, const FaceGraph& g); -template -bool is_border(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g); -template -bool is_border(typename boost::graph_traits::edge_descriptor ed, const FaceGraph& g); -template -bool is_valid_polygon_mesh(const Mesh& g, bool verb); - namespace EulerImpl { template diff --git a/BGL/include/CGAL/boost/graph/generators.h b/BGL/include/CGAL/boost/graph/generators.h index 84453191537..5189bd7297d 100644 --- a/BGL/include/CGAL/boost/graph/generators.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -25,8 +25,6 @@ #include #include -#include - #include #include @@ -824,4 +822,8 @@ make_grid(typename boost::graph_traits::vertices_size_type w, } // namespace CGAL +// Here at the bottom because helpers.h must include generators (for backward compatibility reasons), +// and Euler_operations.h needs helpers.h +#include + #endif // CGAL_BOOST_GRAPH_GENERATORS_H diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 1104f8c06da..06a66e1b465 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -21,7 +21,6 @@ #ifndef CGAL_BOOST_GRAPH_HELPERS_H #define CGAL_BOOST_GRAPH_HELPERS_H -#include #include #include #include @@ -907,4 +906,8 @@ int halfedge_index_in_face(typename boost::graph_traits::halfedge_descrip } // namespace CGAL +// Here at the bottom because helpers.h must include generators (for backward compatibility reasons), +// and Euler_operations.h needs helpers.h +#include + #endif // CGAL_BOOST_GRAPH_HELPERS_H From 0b506f5cce44b09117b3c546c4197c8e249261d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 10 May 2019 12:41:25 +0200 Subject: [PATCH 50/68] Fix package dependencies --- .../package_info/Convex_decomposition_3/dependencies | 1 + Heat_method_3/package_info/Heat_method_3/dependencies | 1 + .../package_info/Linear_cell_complex/dependencies | 1 + Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies | 1 + Nef_3/package_info/Nef_3/dependencies | 1 + Ridges_3/package_info/Ridges_3/dependencies | 1 + .../package_info/Subdivision_method_3/dependencies | 1 + Surface_mesh/package_info/Surface_mesh/dependencies | 1 + .../package_info/Surface_mesh_approximation/dependencies | 1 + .../package_info/Surface_mesh_deformation/dependencies | 1 + .../package_info/Surface_mesh_parameterization/dependencies | 1 + .../package_info/Surface_mesh_shortest_path/dependencies | 1 + .../package_info/Surface_mesh_simplification/dependencies | 1 + Triangulation_3/package_info/Triangulation_3/dependencies | 1 + 14 files changed, 14 insertions(+) diff --git a/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies b/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies index 607af68f95f..67573918303 100644 --- a/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies +++ b/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies @@ -28,6 +28,7 @@ Polyhedron Polyhedron_IO Profiling_tools Property_map +Random_numbers STL_Extension Spatial_sorting Stream_support diff --git a/Heat_method_3/package_info/Heat_method_3/dependencies b/Heat_method_3/package_info/Heat_method_3/dependencies index 31c24f8489e..90510db1ab2 100644 --- a/Heat_method_3/package_info/Heat_method_3/dependencies +++ b/Heat_method_3/package_info/Heat_method_3/dependencies @@ -14,6 +14,7 @@ Number_types Polygon_mesh_processing Profiling_tools Property_map +Random_numbers STL_Extension Solver_interface Stream_support diff --git a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies index 4a46d8312a8..53e5ce3f153 100644 --- a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies +++ b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies @@ -23,5 +23,6 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Stream_support diff --git a/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies b/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies index 43b4d878440..f6fa9d65152 100644 --- a/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies +++ b/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies @@ -29,6 +29,7 @@ Polyhedron Polyhedron_IO Profiling_tools Property_map +Random_numbers STL_Extension Spatial_sorting Stream_support diff --git a/Nef_3/package_info/Nef_3/dependencies b/Nef_3/package_info/Nef_3/dependencies index a835f44af42..71b69c66df6 100644 --- a/Nef_3/package_info/Nef_3/dependencies +++ b/Nef_3/package_info/Nef_3/dependencies @@ -28,6 +28,7 @@ Polyhedron Polyhedron_IO Profiling_tools Property_map +Random_numbers STL_Extension Spatial_sorting Stream_support diff --git a/Ridges_3/package_info/Ridges_3/dependencies b/Ridges_3/package_info/Ridges_3/dependencies index f4b40909932..3d5486b85be 100644 --- a/Ridges_3/package_info/Ridges_3/dependencies +++ b/Ridges_3/package_info/Ridges_3/dependencies @@ -9,6 +9,7 @@ Number_types Principal_component_analysis_LGPL Profiling_tools Property_map +Random_numbers Ridges_3 STL_Extension Stream_support diff --git a/Subdivision_method_3/package_info/Subdivision_method_3/dependencies b/Subdivision_method_3/package_info/Subdivision_method_3/dependencies index 95d535dc571..b42b51ec6d8 100644 --- a/Subdivision_method_3/package_info/Subdivision_method_3/dependencies +++ b/Subdivision_method_3/package_info/Subdivision_method_3/dependencies @@ -9,6 +9,7 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Stream_support Subdivision_method_3 diff --git a/Surface_mesh/package_info/Surface_mesh/dependencies b/Surface_mesh/package_info/Surface_mesh/dependencies index 474db4e6713..bb41a0ba625 100644 --- a/Surface_mesh/package_info/Surface_mesh/dependencies +++ b/Surface_mesh/package_info/Surface_mesh/dependencies @@ -13,6 +13,7 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Stream_support Surface_mesh diff --git a/Surface_mesh_approximation/package_info/Surface_mesh_approximation/dependencies b/Surface_mesh_approximation/package_info/Surface_mesh_approximation/dependencies index aaf95de7e9d..b1ab146c636 100644 --- a/Surface_mesh_approximation/package_info/Surface_mesh_approximation/dependencies +++ b/Surface_mesh_approximation/package_info/Surface_mesh_approximation/dependencies @@ -14,6 +14,7 @@ Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools Property_map +Random_numbers STL_Extension Solver_interface Stream_support diff --git a/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies b/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies index 5263ccfb5b7..974b4a8f5f5 100644 --- a/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies +++ b/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies @@ -14,6 +14,7 @@ Number_types Polygon_mesh_processing Profiling_tools Property_map +Random_numbers STL_Extension Solver_interface Stream_support diff --git a/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies b/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies index 9dbfd435104..b5bfe486174 100644 --- a/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies +++ b/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies @@ -17,6 +17,7 @@ Polygon Polygon_mesh_processing Profiling_tools Property_map +Random_numbers STL_Extension Solver_interface Spatial_sorting diff --git a/Surface_mesh_shortest_path/package_info/Surface_mesh_shortest_path/dependencies b/Surface_mesh_shortest_path/package_info/Surface_mesh_shortest_path/dependencies index 1124ba800da..a903992f736 100644 --- a/Surface_mesh_shortest_path/package_info/Surface_mesh_shortest_path/dependencies +++ b/Surface_mesh_shortest_path/package_info/Surface_mesh_shortest_path/dependencies @@ -13,6 +13,7 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Spatial_searching Stream_support diff --git a/Surface_mesh_simplification/package_info/Surface_mesh_simplification/dependencies b/Surface_mesh_simplification/package_info/Surface_mesh_simplification/dependencies index 7c2cadf30fd..a6626ec4390 100644 --- a/Surface_mesh_simplification/package_info/Surface_mesh_simplification/dependencies +++ b/Surface_mesh_simplification/package_info/Surface_mesh_simplification/dependencies @@ -11,6 +11,7 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Stream_support Surface_mesh_simplification diff --git a/Triangulation_3/package_info/Triangulation_3/dependencies b/Triangulation_3/package_info/Triangulation_3/dependencies index df63288cf1d..e22da1bafd7 100644 --- a/Triangulation_3/package_info/Triangulation_3/dependencies +++ b/Triangulation_3/package_info/Triangulation_3/dependencies @@ -21,6 +21,7 @@ Number_types Polygon Profiling_tools Property_map +Random_numbers STL_Extension Spatial_sorting Stream_support From 55c90f101fbef5c94704654fcaa60258d4cc98e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 10 May 2019 12:44:46 +0200 Subject: [PATCH 51/68] Uniformize usages of 'must be' --- .../include/CGAL/Polygon_mesh_processing/locate.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index df2b2301a35..a1d663eb6ce 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -1640,7 +1640,7 @@ locate_with_AABB_tree(const typename Location_traits::Point& p, /// to call this function more than once, first use `build_AABB_tree()` to create a /// an AABB tree that you can store and use the function `locate_with_AABB_tree()`. /// -/// \tparam TriangleMesh must be a model of `FaceListGraph`. +/// \tparam TriangleMesh a model of `FaceListGraph`. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param p the point to locate on the input triangulated surface mesh @@ -1714,7 +1714,7 @@ locate(const typename property_map_value::t /// /// If the ray does not intersect the mesh, a default constructed location is returned. /// -/// \tparam TriangleMesh must be a model of `FaceListGraph`. +/// \tparam TriangleMesh a model of `FaceListGraph`. /// \tparam Point3VPM a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and the \cgal 3D point type (your kernel's `%Point_3`) as value type. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" @@ -1840,7 +1840,7 @@ locate_with_AABB_tree(const typename Location_traits::Ray& ray, /// copy of the `AABB_tree`, and use the overloads of this function /// that accept a reference to an AABB tree as input. /// -/// \tparam TriangleMesh must be a model of `FaceListGraph`. +/// \tparam TriangleMesh a model of `FaceListGraph`. /// \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" /// /// \param ray a ray to intersect with the input triangulated surface mesh From 55cede0960ea642751e59e0f174bbe3ae654512a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 10 Jun 2019 10:39:34 +0200 Subject: [PATCH 52/68] Remove duplicated typedefs That compiled on my machine, but not on the Fedora testsuites...? --- .../include/CGAL/Polygon_mesh_processing/locate.h | 3 +-- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index a1d663eb6ce..92abea8dbc8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -1753,7 +1753,7 @@ locate_with_AABB_tree(const typename Location_traits::Geom_traits Geom_traits; + typedef typename Location_traits::Geom_traits Geom_traits; typedef typename Geom_traits::FT FT; typedef typename Geom_traits::Point_3 Point_3; @@ -1765,7 +1765,6 @@ locate_with_AABB_tree(const typename Location_traits WrappedVPM; typedef internal::Ray_to_Ray_3 R_to_R3; - typedef typename Location_traits::Geom_traits Geom_traits; typedef typename CGAL::AABB_face_graph_triangle_primitive Primitive; typedef typename CGAL::AABB_traits AABB_traits; typedef AABB_tree AABB_face_graph_tree; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index a000a3030cf..61f97df187a 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -590,8 +590,6 @@ struct Locate_with_AABB_tree_Tester<3> // 3D typedef typename boost::property_map_value::type Point; - typedef typename boost::property_map::const_type VertexPointMap; - typedef typename CGAL::Kernel_traits::type Kernel; typedef typename Kernel::FT FT; typedef typename Kernel::Ray_3 Ray_3; From 22492ad9f88985e85623e7505cf88da3053deb94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 11 Jun 2019 10:11:06 +0200 Subject: [PATCH 53/68] Fix BGL test --- BGL/test/BGL/test_cgal_bgl_named_params.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 21e070cfa34..f5dff9d00ef 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -170,7 +170,7 @@ void test(const NamedParameters& np) check_same_type<48>(get_param(np, CGAL::internal_np::erase_all_duplicates)); check_same_type<49>(get_param(np, CGAL::internal_np::require_same_orientation)); check_same_type<50>(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface)); - check_same_type<49>(get_param(np, CGAL::internal_np::snapping_tolerance)); + check_same_type<53>(get_param(np, CGAL::internal_np::snapping_tolerance)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); From 6d1ee29280b75f5b121286be4246b9dabacde7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 14 Jun 2019 08:48:07 +0200 Subject: [PATCH 54/68] Add missing data files --- .../data/blobby_2D.off | 522 ++++++++++++++++++ .../Polygon_mesh_processing/data/stair.xy | 160 ++++++ 2 files changed, 682 insertions(+) create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/data/blobby_2D.off create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/data/stair.xy diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data/blobby_2D.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data/blobby_2D.off new file mode 100644 index 00000000000..24774d3cb35 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data/blobby_2D.off @@ -0,0 +1,522 @@ +OFF +195 325 0 +-0.24592500000000000 0.02013070000000000 +-0.23906300000000000 0.00917146000000000 +-0.22414600000000001 0.02627040000000000 +-0.21665699999999999 0.09137350000000000 +-0.20436900000000000 0.13125800000000001 +-0.22717399999999999 0.11141900000000000 +-0.23814700000000000 -0.00559741000000000 +-0.22804700000000000 -0.00611597000000000 +-0.23734700000000000 0.00223480000000000 +-0.17373700000000000 0.10742100000000000 +-0.18601799999999999 0.12388100000000001 +-0.28231400000000001 0.05716840000000000 +-0.26321000000000000 0.03789740000000000 +-0.24498400000000001 0.05559020000000000 +-0.20538999999999999 0.04444000000000000 +-0.20414800000000000 0.02031610000000000 +-0.25870100000000001 0.08402350000000000 +-0.26684400000000003 0.10788800000000000 +-0.22636600000000001 0.00430057000000000 +-0.18667000000000000 0.14006900000000000 +-0.16358800000000001 0.13642799999999999 +-0.20508599999999999 0.14620600000000000 +-0.26247900000000002 0.01860690000000000 +-0.24475300000000000 0.00128651000000000 +-0.17287900000000000 0.07846690000000001 +-0.14485700000000001 0.12063500000000001 +-0.13344700000000001 0.15071200000000001 +-0.25083600000000000 0.00914945000000000 +-0.18010599999999999 0.03686900000000000 +-0.18816300000000000 0.02293980000000000 +-0.20318600000000001 -0.03005060000000000 +-0.17436699999999999 -0.01695920000000000 +-0.20029500000000000 -0.00554548000000000 +-0.21379000000000001 -0.01019390000000000 +-0.22625999999999999 -0.01602680000000000 +-0.18674800000000000 -0.00071344700000000 +-0.03932460000000000 -0.02666830000000000 +-0.03925560000000000 -0.05397620000000000 +-0.01404300000000000 -0.05156900000000000 +-0.01281140000000000 -0.03297440000000000 +0.00025716100000000 -0.04038760000000000 +-0.00235339000000000 -0.06635020000000000 +0.00514285000000000 -0.02623370000000000 +-0.05370540000000000 -0.10002100000000000 +-0.06064010000000000 -0.07184490000000000 +-0.10332300000000000 -0.09791700000000000 +-0.09767480000000001 -0.06580080000000001 +-0.02287800000000000 -0.12280500000000000 +-0.01834440000000000 -0.10006500000000000 +-0.03703030000000000 -0.10977800000000000 +-0.22790700000000000 -0.03429780000000000 +-0.24421999999999999 -0.02160990000000000 +-0.21956100000000001 -0.00229464000000000 +-0.01882920000000000 -0.07918520000000000 +-0.19679700000000000 0.00930870000000000 +-0.17767800000000000 0.01133440000000000 +-0.15034600000000001 -0.03228640000000000 +-0.09626770000000000 -0.03217010000000000 +-0.12686400000000000 -0.01489330000000000 +-0.03686590000000000 -0.08920240000000000 +-0.04727000000000000 -0.12435800000000000 +-0.07423990000000000 -0.11637599999999999 +-0.28881000000000001 0.08273820000000000 +-0.19542799999999999 -0.05568390000000000 +-0.25102000000000002 -0.03770290000000000 +-0.25682800000000000 -0.01989910000000000 +-0.01044890000000000 -0.11426799999999999 +-0.15682900000000000 -0.07004180000000000 +-0.15470700000000001 0.02812290000000000 +-0.06659100000000000 -0.04315070000000000 +-0.06487910000000000 -0.14555499999999999 +-0.14442099999999999 -0.11574900000000000 +-0.15122400000000000 -0.15927800000000000 +-0.11173900000000000 -0.14992600000000000 +-0.03111620000000000 -0.14380999999999999 +-0.16651299999999999 -0.17455000000000001 +-0.13802300000000001 -0.17901800000000001 +-0.26305400000000001 -0.03008160000000000 +-0.21636000000000000 -0.14896999999999999 +-0.21421299999999999 -0.11310099999999999 +-0.24318400000000001 -0.14052799999999999 +-0.18837999999999999 -0.17875099999999999 +-0.18471000000000001 -0.14161699999999999 +-0.15202099999999999 0.00089938800000000 +-0.27395000000000003 -0.04066720000000000 +-0.18671699999999999 -0.09123320000000000 +-0.22246400000000000 -0.07536089999999999 +-0.09578760000000000 -0.13067799999999999 +-0.23696500000000001 0.12865599999999999 +-0.25777400000000000 -0.05791230000000000 +-0.28615400000000002 0.03984230000000000 +-0.00327775000000000 -0.00841017000000000 +-0.25280999999999998 -0.00309231000000000 +0.00121365000000000 -0.08619950000000000 +-0.17146900000000001 -0.00241387000000000 +-0.15892999999999999 -0.01343940000000000 +-0.21124000000000001 0.00524665000000000 +-0.06533350000000000 -0.01421250000000000 +-0.21189600000000000 -0.00271869000000000 +-0.25108000000000003 -0.09202000000000000 +-0.31369799999999998 0.03807740000000000 +-0.27149099999999998 -0.11406700000000000 +-0.28459699999999999 -0.07320550000000001 +-0.07589390000000000 -0.18407699999999999 +-0.06261100000000000 -0.17513000000000001 +-0.07609330000000000 -0.16314200000000001 +0.00016327700000000 -0.10355200000000001 +-0.02872410000000000 -0.00156414000000000 +-0.01435380000000000 0.00308408000000000 +-0.12731200000000001 0.01677310000000000 +-0.13466700000000001 0.00094315400000000 +0.00202303000000000 0.07827919999999999 +0.02841240000000000 0.08494169999999999 +0.01594670000000000 0.10307900000000000 +-0.00962830000000000 0.14879200000000001 +-0.01673320000000000 0.11896400000000000 +0.00534235000000000 0.12164000000000000 +-0.03012780000000000 0.10138900000000001 +-0.02854770000000000 0.07080069999999999 +-0.00592029000000000 0.10068500000000000 +-0.31689800000000001 0.06285480000000000 +-0.00926267000000000 0.01742490000000000 +-0.02594480000000000 0.01520790000000000 +0.03956540000000000 0.06584290000000000 +-0.00259196000000000 0.05460730000000000 +-0.04968400000000000 0.01822080000000000 +-0.07789880000000000 0.02296420000000000 +-0.06690250000000000 0.00647931000000000 +-0.04768020000000000 -0.14828000000000000 +0.02457530000000000 0.15474499999999999 +0.11276600000000001 0.09952060000000000 +0.07082629999999999 0.08771039999999999 +0.09508170000000001 0.07003930000000000 +0.08551670000000000 0.03420360000000000 +0.06843790000000000 0.05875820000000000 +0.04888310000000000 0.02946740000000000 +0.05944330000000000 0.01189650000000000 +0.08005260000000000 0.01455180000000000 +0.15004899999999999 0.10953400000000001 +0.15212899999999999 0.07574839999999999 +-0.03531200000000000 0.17809400000000000 +-0.05507500000000000 0.15928200000000001 +-0.02680130000000000 0.15953400000000001 +0.04326160000000000 0.16105800000000001 +0.05561930000000000 0.14540500000000001 +0.06160470000000000 0.16266600000000001 +0.12242400000000001 0.13998200000000000 +0.09908670000000000 0.13400400000000001 +-0.00513261000000000 0.16801199999999999 +0.02864610000000000 0.17255899999999999 +0.02302540000000000 0.18896600000000000 +0.05399200000000000 0.12448900000000000 +0.03694350000000000 0.13911499999999999 +0.03778010000000000 0.10418200000000000 +0.01162540000000000 0.03488840000000000 +-0.05307370000000000 0.13435200000000000 +-0.06687100000000000 0.11254300000000000 +-0.10134500000000000 0.00172185000000000 +0.07658940000000000 0.14677899999999999 +0.07598090000000000 0.12629000000000001 +0.01506890000000000 0.00949618000000000 +-0.08534820000000000 0.08532910000000000 +-0.02799170000000000 0.13784500000000000 +0.12397300000000000 0.07188710000000000 +0.00496704000000000 0.01990390000000000 +-0.07667960000000000 0.13824400000000001 +-0.09684780000000000 0.11329300000000000 +0.07175130000000000 -0.00410704000000000 +0.02393600000000000 -0.01454820000000000 +0.04050310000000000 0.00510915000000000 +-0.02270260000000000 0.04054320000000000 +-0.00573450000000000 0.03748440000000000 +-0.09173530000000001 0.04960090000000000 +-0.05740990000000000 -0.16077300000000000 +-0.11552800000000001 0.07408670000000001 +0.11186599999999999 0.04843290000000000 +-0.12656600000000001 0.10163000000000000 +-0.15584899999999999 0.05703930000000000 +-0.11467300000000000 -0.17524799999999999 +0.00996937000000000 -0.01298980000000000 +0.00042625600000000 0.00615835000000000 +-0.09476610000000001 -0.17258599999999999 +-0.10563200000000000 0.15925500000000001 +-0.11695800000000001 0.13199100000000000 +-0.12928400000000001 0.04635750000000000 +0.04950970000000000 0.17627999999999999 +0.03775450000000000 0.18965699999999999 +-0.05625970000000000 0.04608740000000000 +-0.05938180000000000 0.18434700000000001 +-0.07765430000000000 0.16547300000000001 +0.05390970000000000 -0.00800927000000000 +0.09879780000000001 0.00829006000000000 +-0.01792850000000000 0.19112499999999999 +0.00412912000000000 0.19402800000000001 +-0.28409000000000001 0.02300040000000000 +3 0 1 2 +3 3 4 5 +3 6 7 8 +3 9 10 3 +3 10 4 3 +3 11 12 13 +3 14 2 15 +3 16 5 17 +3 13 12 0 +3 18 1 8 +3 19 10 20 +3 19 21 4 +3 22 0 12 +3 16 3 5 +3 7 18 8 +3 1 18 2 +3 13 14 3 +3 23 8 1 +3 9 24 25 +3 25 26 20 +3 20 9 25 +3 3 24 9 +3 0 22 27 +3 16 13 3 +3 28 14 29 +3 4 10 19 +3 0 27 1 +3 14 24 3 +3 30 31 32 +3 30 33 34 +3 35 32 31 +3 36 37 38 +3 36 38 39 +3 40 39 38 +3 38 41 40 +3 39 40 42 +3 43 44 45 +3 45 44 46 +3 47 48 49 +3 50 34 51 +3 23 1 27 +3 7 33 52 +3 38 37 53 +3 29 54 55 +3 56 57 58 +3 59 48 53 +3 60 43 61 +3 62 11 16 +3 55 28 29 +3 63 56 31 +3 64 51 65 +3 66 48 47 +3 46 67 45 +3 55 68 28 +3 49 59 43 +3 37 69 44 +3 70 60 61 +3 71 72 73 +3 47 60 74 +3 37 44 59 +3 50 63 30 +3 43 45 61 +3 37 36 69 +3 72 75 76 +3 64 65 77 +3 78 79 80 +3 78 81 82 +3 68 55 83 +3 77 84 64 +3 6 51 34 +3 79 85 86 +3 30 34 50 +3 56 63 67 +3 70 61 87 +3 88 17 5 +3 84 89 64 +3 86 63 50 +3 90 12 11 +3 33 7 34 +3 45 67 71 +3 42 91 39 +3 92 51 6 +3 41 53 93 +3 86 64 89 +3 94 31 95 +3 83 94 95 +3 2 18 96 +3 69 97 57 +3 61 45 87 +3 52 98 96 +3 99 79 86 +3 54 96 32 +3 49 48 59 +3 38 53 41 +3 50 64 86 +3 11 100 90 +3 82 71 85 +3 82 72 71 +3 35 54 32 +3 78 82 79 +3 36 97 69 +3 80 99 101 +3 98 32 96 +3 52 18 7 +3 98 33 32 +3 102 101 99 +3 103 104 105 +3 106 48 66 +3 107 91 108 +3 109 83 110 +3 111 112 113 +3 34 7 6 +3 114 115 116 +3 59 44 43 +3 117 118 119 +3 29 15 54 +3 119 118 111 +3 62 120 11 +3 108 121 122 +3 123 111 124 +3 125 126 127 +3 102 89 84 +3 74 60 128 +3 116 129 114 +3 50 51 64 +3 130 131 132 +3 35 31 94 +3 133 134 135 +3 133 136 137 +3 83 95 58 +3 138 130 139 +3 115 117 119 +3 86 85 63 +3 17 62 16 +3 46 57 56 +3 107 122 125 +3 140 141 142 +3 79 99 80 +3 143 144 145 +3 130 146 147 +3 45 71 87 +3 148 149 150 +3 107 127 97 +3 151 152 153 +3 123 124 154 +3 117 155 156 +3 118 124 111 +3 56 67 46 +3 48 93 53 +3 71 73 87 +3 107 36 39 +3 110 58 157 +3 92 65 51 +3 60 49 43 +3 158 144 159 +3 160 135 154 +3 161 117 156 +3 117 115 162 +3 130 132 163 +3 29 14 15 +3 96 18 52 +3 47 49 60 +3 160 154 164 +3 156 165 166 +3 129 149 148 +3 52 33 98 +3 167 137 136 +3 143 152 144 +3 46 69 57 +3 160 168 169 +3 124 170 171 +3 136 135 169 +3 155 141 165 +3 125 122 170 +3 30 32 33 +3 131 153 112 +3 172 109 157 +3 134 123 135 +3 105 104 173 +3 166 174 161 +3 142 162 114 +3 2 96 15 +3 155 117 162 +3 59 53 37 +3 153 116 113 +3 107 39 91 +3 23 6 8 +3 139 130 163 +3 133 135 136 +3 163 132 175 +3 20 10 9 +3 176 24 177 +3 72 178 73 +3 127 126 157 +3 179 180 91 +3 178 181 73 +3 116 152 129 +3 182 26 183 +3 68 83 109 +3 89 102 99 +3 142 114 148 +3 118 117 161 +3 109 184 68 +3 149 185 186 +3 187 118 161 +3 134 131 123 +3 180 108 91 +3 126 125 187 +3 138 146 130 +3 86 89 99 +3 157 109 110 +3 184 109 172 +3 141 188 189 +3 157 126 172 +3 83 55 94 +3 83 58 110 +3 172 161 174 +3 180 179 160 +3 82 75 72 +3 93 48 106 +3 14 13 2 +3 132 133 175 +3 97 157 57 +3 183 26 25 +3 2 13 0 +3 120 100 11 +3 172 174 184 +3 144 151 159 +3 165 189 182 +3 164 121 180 +3 179 168 160 +3 16 11 13 +3 190 167 136 +3 131 112 123 +3 166 161 156 +3 149 129 143 +3 151 153 131 +3 170 187 125 +3 82 81 75 +3 143 145 185 +3 153 152 116 +3 148 140 142 +3 151 144 152 +3 95 31 56 +3 97 36 107 +3 5 4 88 +3 73 181 105 +3 149 143 185 +3 165 141 189 +3 112 111 123 +3 177 174 176 +3 187 170 118 +3 174 166 176 +3 114 129 148 +3 147 158 159 +3 85 67 63 +3 28 24 14 +3 158 145 144 +3 159 151 131 +3 187 161 172 +3 70 173 128 +3 55 35 94 +3 25 176 183 +3 105 173 70 +3 154 171 164 +3 24 176 25 +3 142 141 155 +3 55 54 35 +3 191 133 137 +3 130 159 131 +3 162 142 155 +3 180 160 164 +3 170 122 121 +3 147 159 130 +3 140 148 192 +3 68 177 28 +3 21 88 4 +3 162 115 114 +3 169 190 136 +3 87 73 105 +3 148 150 193 +3 179 91 42 +3 175 133 191 +3 87 105 70 +3 170 121 171 +3 116 115 119 +3 63 31 30 +3 148 193 192 +3 149 186 150 +3 141 140 188 +3 160 169 135 +3 118 170 124 +3 68 184 177 +3 129 152 143 +3 132 131 134 +3 15 96 54 +3 107 125 127 +3 113 116 119 +3 132 134 133 +3 128 60 70 +3 56 58 95 +3 111 113 119 +3 105 181 103 +3 164 171 121 +3 155 165 156 +3 85 71 67 +3 177 184 174 +3 154 124 171 +3 72 76 178 +3 135 123 154 +3 194 22 12 +3 113 112 153 +3 79 82 85 +3 57 157 58 +3 122 107 108 +3 121 108 180 +3 165 182 183 +3 177 24 28 +3 166 183 176 +3 127 157 97 +3 44 69 46 +3 90 194 12 +3 168 190 169 +3 165 183 166 +3 172 126 187 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data/stair.xy b/Polygon_mesh_processing/test/Polygon_mesh_processing/data/stair.xy new file mode 100644 index 00000000000..3d6f2434d85 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data/stair.xy @@ -0,0 +1,160 @@ +0.00605396 0.00360027 +0.0117095 0.00496933 +0.00292489 -0.0056444 +0.018654 -0.00345866 +0.0208731 -0.00712699 +0.0349622 0.00520127 +0.0226514 0.00273598 +0.0443469 0.00641652 +0.0320264 -0.00785089 +0.0536853 -0.00492172 +0.0477706 0.00445479 +0.0639807 0.00509629 +0.0673864 -0.000544755 +0.068878 0.00636891 +0.0786834 -0.00880306 +0.0838299 0.00977294 +0.087326 -0.0021897 +0.079062 0.000772423 +0.0984893 0.00905454 +0.0994487 -0.00770074 +0.100736 0.00717826 +0.0994229 0.00250389 +0.100252 0.0167278 +0.0960604 0.00802011 +0.103545 0.0289233 +0.108446 0.0183656 +0.106763 0.0262313 +0.106452 0.0420934 +0.0997256 0.0427598 +0.107064 0.0403298 +0.0928101 0.0560955 +0.10136 0.0583232 +0.104819 0.0562105 +0.0902899 0.0706163 +0.10994 0.0770702 +0.0923621 0.0704878 +0.0919434 0.0865538 +0.0963674 0.0842679 +0.103725 0.0803259 +0.102273 0.101166 +0.100319 0.0952791 +0.108403 0.0942299 +0.113529 0.0981625 +0.108027 0.103066 +0.126272 0.0950435 +0.133506 0.0939314 +0.124776 0.107205 +0.131076 0.107853 +0.136759 0.109119 +0.15444 0.102357 +0.143707 0.104111 +0.160272 0.0974776 +0.165379 0.103348 +0.173751 0.0916309 +0.174657 0.0937715 +0.167267 0.0980068 +0.170889 0.0905988 +0.185414 0.102092 +0.189813 0.10002 +0.199397 0.0909473 +0.198222 0.107717 +0.198974 0.099872 +0.201479 0.108827 +0.205074 0.107075 +0.202 0.124977 +0.191185 0.121976 +0.206848 0.134009 +0.196679 0.137767 +0.19255 0.148035 +0.190151 0.143856 +0.195263 0.155428 +0.20595 0.148822 +0.204421 0.152387 +0.191967 0.169495 +0.197981 0.169699 +0.191872 0.176798 +0.207398 0.170317 +0.194859 0.178978 +0.190444 0.183389 +0.196073 0.192833 +0.200019 0.190352 +0.205824 0.198579 +0.217043 0.198723 +0.210708 0.208976 +0.225591 0.209213 +0.224774 0.208331 +0.228376 0.201784 +0.233852 0.192014 +0.230703 0.196273 +0.241172 0.192107 +0.241027 0.203219 +0.257393 0.199803 +0.266244 0.190504 +0.263176 0.1902 +0.279822 0.191442 +0.267419 0.200092 +0.270919 0.209937 +0.294279 0.199399 +0.292596 0.208336 +0.302111 0.206854 +0.297261 0.193606 +0.302447 0.195568 +0.307461 0.217454 +0.302133 0.219113 +0.300152 0.216012 +0.296763 0.223723 +0.302571 0.234727 +0.298522 0.237272 +0.307834 0.234066 +0.296568 0.250613 +0.298385 0.251664 +0.29308 0.261943 +0.295426 0.266549 +0.293096 0.259791 +0.292439 0.271056 +0.291263 0.275271 +0.300944 0.286063 +0.308624 0.284206 +0.306603 0.285177 +0.302574 0.289769 +0.303807 0.303483 +0.308102 0.301263 +0.316854 0.306492 +0.313448 0.299638 +0.325862 0.304911 +0.328301 0.305416 +0.335535 0.300855 +0.327652 0.299601 +0.334895 0.301131 +0.339451 0.303238 +0.356128 0.293215 +0.359167 0.306227 +0.350648 0.309557 +0.359385 0.291005 +0.360515 0.305818 +0.377582 0.301763 +0.373333 0.308693 +0.375172 0.299768 +0.398744 0.298911 +0.390985 0.295462 +0.39465 0.305079 +0.397266 0.302934 +0.391293 0.303944 +0.401355 0.307406 +0.391301 0.312749 +0.401141 0.331346 +0.403843 0.339273 +0.397447 0.32984 +0.401007 0.345187 +0.401435 0.350856 +0.404534 0.358367 +0.40019 0.350997 +0.401021 0.359769 +0.398586 0.362409 +0.403735 0.370503 +0.400571 0.381428 +0.409145 0.374727 +0.402981 0.379619 +0.406312 0.38398 +0.405032 0.387826 From 0ea40f7602a9fbaa7b38604c72113c737e26949d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 14 Jun 2019 10:46:46 +0200 Subject: [PATCH 55/68] Add missing 'const' in conversion operator --- .../boost/graph/internal/graph_traits_2D_triangulation_helper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h index 81510aeb787..6c95937921f 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h @@ -71,7 +71,7 @@ struct T2_edge_descriptor T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { } // so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle - operator std::pair() { return std::make_pair(first, second); } + operator std::pair() const { return std::make_pair(first, second); } friend std::size_t hash_value(const T2_edge_descriptor& h) { From a189e826867d013a1d3105324917d5ca3f9c0ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 14 Jun 2019 10:47:20 +0200 Subject: [PATCH 56/68] Cache a descriptor within the iterators so operator*() can return a reference --- .../graph_traits_2D_triangulation_helper.h | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h index 6c95937921f..c05ca0598f1 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h @@ -185,19 +185,23 @@ public: bool operator==(const Self& other) const { return it == other.it; } bool operator!=(const Self& other) const { return !(*this == other); } - value_type operator*() const + reference operator*() const { - if(on_adjacent_face) { + if(on_adjacent_face) + { Face_handle neigh_f = it->first->neighbor(it->second); - return value_type(neigh_f, neigh_f->index(it->first)); - } else { - return value_type(*it); + hd = Descriptor(neigh_f, neigh_f->index(it->first)); + return hd; + } else { + hd = Descriptor(it->first, it->second); + return hd; } } private: Edge_iterator it; bool on_adjacent_face; + mutable Descriptor hd; }; template @@ -225,10 +229,16 @@ public: Self& operator--() { --it; return *this; } Self operator++(int) { Self tmp = *this; operator++(); return tmp; } Self operator--(int) { Self tmp = *this; operator--(); return tmp; } - value_type operator*() const { return value_type(*it); } + + reference operator*() const + { + ed = Descriptor(*it); + return ed; + } private: Edge_iterator it; + mutable Descriptor ed; }; // Must distinguish TDS and triangulations circulators (later are filtered) From 2d8124574460acd98c6d936cabe4e4b04eb7b370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Jun 2019 08:32:56 +0200 Subject: [PATCH 57/68] Fix conversion warning --- Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 223e4f7d1f0..8b0da4b4cc1 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -257,9 +257,9 @@ namespace CGAL { // increment. SM_Edge_index operator++(int) { SM_Edge_index tmp(*this); halfedge_ = SM_Halfedge_index((size_type)halfedge_ + 2); return tmp; } - SM_Edge_index operator+=(std::ptrdiff_t n) { halfedge_ = SM_Halfedge_index(std::ptrdiff_t(halfedge_) + 2*n); return *this; } + SM_Edge_index operator+=(std::ptrdiff_t n) { halfedge_ = SM_Halfedge_index(size_type(std::ptrdiff_t(halfedge_) + 2*n)); return *this; } - // prints the index and a short identification string to an ostream. + // prints the index and a short identification string to an ostream. friend std::ostream& operator<<(std::ostream& os, SM_Edge_index const& e) { return (os << 'e' << (size_type)e << " on " << e.halfedge()); From d75821f27aefc282cb9f2b36c38176b73b47ada5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 17 Jun 2019 08:33:23 +0200 Subject: [PATCH 58/68] Rename template parameter to help MSVC Seems like MSVC gets confused between 'Tr' being both a template paramter and a typedef in the class being passed as template parameter. --- .../include/CGAL/Triangulation_hierarchy_2.h | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h index 3ab4f62c28f..b70fe344d85 100644 --- a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h @@ -56,11 +56,11 @@ const int Triangulation_hierarchy_2__minsize = 20; const int Triangulation_hierarchy_2__maxlevel = 5; // maximal number of points is 30^5 = 24 millions ! -template < class Tr_> +template class Triangulation_hierarchy_2 : public Tr_ { - public: +public: typedef Tr_ Tr_Base; typedef typename Tr_Base::Geom_traits Geom_traits; typedef typename Tr_Base::size_type size_type; @@ -273,8 +273,8 @@ private: -template -Triangulation_hierarchy_2:: +template +Triangulation_hierarchy_2:: Triangulation_hierarchy_2(const Geom_traits& traits) : Tr_Base(traits) { @@ -285,9 +285,9 @@ Triangulation_hierarchy_2(const Geom_traits& traits) // copy constructor duplicates vertices and faces -template -Triangulation_hierarchy_2:: -Triangulation_hierarchy_2(const Triangulation_hierarchy_2 &tr) +template +Triangulation_hierarchy_2:: +Triangulation_hierarchy_2(const Triangulation_hierarchy_2 &tr) : Tr_Base() { // create an empty triangulation to be able to delete it ! @@ -299,20 +299,20 @@ Triangulation_hierarchy_2(const Triangulation_hierarchy_2 &tr) //Assignement -template -Triangulation_hierarchy_2 & -Triangulation_hierarchy_2:: -operator=(const Triangulation_hierarchy_2 &tr) +template +Triangulation_hierarchy_2 & +Triangulation_hierarchy_2:: +operator=(const Triangulation_hierarchy_2 &tr) { copy_triangulation(tr); return *this; } -template +template void -Triangulation_hierarchy_2:: -copy_triangulation(const Triangulation_hierarchy_2 &tr) +Triangulation_hierarchy_2:: +copy_triangulation(const Triangulation_hierarchy_2 &tr) { { for(int i=0;i &tr) } } -/* template */ +/* template */ /* void */ -/* Triangulation_hierarchy_2:: */ +/* Triangulation_hierarchy_2:: */ /* add_hidden_vertices_into_map(Tag_false, */ /* std::map& V) { */ /* return; */ /* } */ -/* template */ +/* template */ /* void */ -/* Triangulation_hierarchy_2:: */ +/* Triangulation_hierarchy_2:: */ /* add_hidden_vertices_into_map(Tag_true, */ /* std::map& V) */ /* { */ @@ -371,10 +371,10 @@ copy_triangulation(const Triangulation_hierarchy_2 &tr) /* } */ -template +template void -Triangulation_hierarchy_2:: -swap(Triangulation_hierarchy_2 &tr) +Triangulation_hierarchy_2:: +swap(Triangulation_hierarchy_2 &tr) { Tr_Base* temp; Tr_Base::swap(tr); @@ -385,8 +385,8 @@ swap(Triangulation_hierarchy_2 &tr) } } -template -Triangulation_hierarchy_2:: +template +Triangulation_hierarchy_2:: ~Triangulation_hierarchy_2() { clear(); @@ -395,9 +395,9 @@ Triangulation_hierarchy_2:: } } -template +template void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: clear() { for(int i=0;i +template bool -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: is_valid(bool verbose, int level) const { bool result = true; @@ -440,9 +440,9 @@ is_valid(bool verbose, int level) const } -template -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +template +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: insert(const Point &p, Face_handle loc) { int vertex_level = random_level(); @@ -466,9 +466,9 @@ insert(const Point &p, Face_handle loc) return first; } -template -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +template +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: insert(const Point& p, Locate_type lt, Face_handle loc, @@ -499,18 +499,18 @@ insert(const Point& p, return first; } -template +template inline -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: push_back(const Point &p) { return insert(p); } -template +template void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: remove(Vertex_handle v ) { Vertex_handle u=v->up(); @@ -523,10 +523,10 @@ remove(Vertex_handle v ) } } -template +template template void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: remove_and_give_new_faces(Vertex_handle v, OutputItFaces fit) { Vertex_handle u=v->up(); @@ -541,33 +541,33 @@ remove_and_give_new_faces(Vertex_handle v, OutputItFaces fit) } -template +template inline void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: remove_degree_3(Vertex_handle v ) { remove(v); } -template +template inline void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: remove_first(Vertex_handle v ) { remove(v); } -template +template inline void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: remove_second(Vertex_handle v ) { remove(v); } -template -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +template +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: move_if_no_collision(Vertex_handle v, const Point &p) { Vertex_handle u=v->up(), norm = v; int l = 0 ; @@ -581,9 +581,9 @@ move_if_no_collision(Vertex_handle v, const Point &p) { return norm; } -template -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +template +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: move(Vertex_handle v, const Point &p) { CGAL_triangulation_precondition(!is_infinite(v)); Vertex_handle w = move_if_no_collision(v,p); @@ -594,10 +594,10 @@ move(Vertex_handle v, const Point &p) { return v; } -template +template template -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: move_if_no_collision_and_give_new_faces(Vertex_handle v, const Point &p, OutputItFaces oif) { @@ -619,11 +619,11 @@ move_if_no_collision_and_give_new_faces(Vertex_handle v, const Point &p, return norm; } -template < class Tr > +template template < class OutputItFaces > inline -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2::insert_and_give_new_faces(const Point &p, +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2::insert_and_give_new_faces(const Point &p, OutputItFaces oif, Face_handle loc) { @@ -648,12 +648,12 @@ Triangulation_hierarchy_2::insert_and_give_new_faces(const Point &p, } return first; } - -template < class Tr > + +template template < class OutputItFaces > inline -typename Triangulation_hierarchy_2::Vertex_handle -Triangulation_hierarchy_2:: +typename Triangulation_hierarchy_2::Vertex_handle +Triangulation_hierarchy_2:: insert_and_give_new_faces(const Point &p, Locate_type lt, Face_handle loc, @@ -685,9 +685,9 @@ insert_and_give_new_faces(const Point &p, return first; } -template -typename Triangulation_hierarchy_2::Face_handle -Triangulation_hierarchy_2:: +template +typename Triangulation_hierarchy_2::Face_handle +Triangulation_hierarchy_2:: locate(const Point& p, Locate_type& lt, int& li, Face_handle loc) const { Face_handle positions[Triangulation_hierarchy_2__maxlevel]; @@ -695,9 +695,9 @@ locate(const Point& p, Locate_type& lt, int& li, Face_handle loc) const return positions[0]; } -template -typename Triangulation_hierarchy_2::Face_handle -Triangulation_hierarchy_2:: +template +typename Triangulation_hierarchy_2::Face_handle +Triangulation_hierarchy_2:: locate(const Point& p, Face_handle loc ) const { Locate_type lt; @@ -705,9 +705,9 @@ locate(const Point& p, Face_handle loc ) const return locate(p, lt, li, loc); } -template +template void -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: locate_in_all(const Point& p, Locate_type& lt, int& li, @@ -769,9 +769,9 @@ locate_in_all(const Point& p, pos[0]=hierarchy[0]->locate(p,lt,li,loc == Face_handle() ? position : loc); // at level 0 } -template +template int -Triangulation_hierarchy_2:: +Triangulation_hierarchy_2:: random_level() { boost::geometric_distribution<> proba(1.0/Triangulation_hierarchy_2__ratio); From bc32291d36d235098ec7f0851ef5784736afac2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Jun 2019 09:37:29 +0200 Subject: [PATCH 59/68] Re-enable using operator<< and operator>> with 2D meshes --- .../include/CGAL/Surface_mesh/Surface_mesh.h | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index b10f7fbd0de..17822714110 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -2089,6 +2090,24 @@ private: //------------------------------------------------------- private data return sm; } + /// \cond SKIP_IN_MANUAL + template ::value> + struct Output_point_23 + { + template + Stream& operator()(Stream& os, const Point& p) const { os << p.x() << " " << p.y() << " " << p.z(); return os; } + }; + + template + struct Output_point_23 // 2D Point specialization + { + template + Stream& operator()(Stream& os, const Point& p) const { os << p.x() << " " << p.y(); return os; } + }; + + /// \endcond + /// \relates Surface_mesh /// Inserts the surface mesh in an output stream in Ascii OFF format. @@ -2122,10 +2141,12 @@ private: //------------------------------------------------------- private data get_const_property_map(CGAL::vertex_point, sm)); reindex.resize(sm.num_vertices()); int n = 0; + + Output_point_23

op; for(Vertex_index v : sm.vertices()){ - P p = get(vpm, v); - os << p.x() << " " << p.y() << " " << p.z(); + op(os, get(vpm, v)); + if(has_vcolors) { CGAL::Color color = vcolors[v]; @@ -2361,6 +2382,30 @@ private: //------------------------------------------------------- private data return in; } + template ::value> + struct Read_point_23 + { + template + Point operator()(Stream& is) const + { + double x, y, z; + is >> iformat(x) >> iformat(y) >> iformat(z); + return Point(x, y, z); + } + }; + + template + struct Read_point_23 // 2D specialization + { + template + Point operator()(Stream& is) const + { + double x, y; + is >> iformat(x) >> iformat(y); + return Point(x, y); + } + }; /// @endcond @@ -2419,22 +2464,19 @@ private: //------------------------------------------------------- private data } char ci; + Read_point_23

point_reader; for(int i=0; i < n; i++){ is >> sm_skip_comments; - double x, y, z; - is >> iformat(x) >> iformat(y) >> iformat(z); - + Vertex_index vi = sm.add_vertex(); - put(vpm, vi, P(x, y, z)); - - + put(vpm, vi, point_reader(is)); + vertexmap[i] = vi; if(v_has_normals){ is >> v; vnormal[vi] = v; } - if(i == 0 && ((off == "COFF") || (off == "CNOFF"))){ std::string col; std::getline(is, col); From 1b53056cbd1f473e304b192010113a18cf27bf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Jun 2019 10:38:37 +0200 Subject: [PATCH 60/68] Precise some preconditions --- .../CGAL/Polygon_mesh_processing/locate.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 92abea8dbc8..462c22ab466 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -895,7 +895,7 @@ is_on_mesh_border(const typename Location_traits::Face_location& l /// \ingroup PMP_locate_grp /// /// \brief Returns the location of the given vertex `vd` as a location, -/// that is an ordered pair specifying a face containing the location +/// that is an ordered pair specifying a face incident to `vd` /// and the barycentric coordinates of the vertex `vd` in that face. /// /// \details If `tm` is the input triangulated surface mesh and given the pair (`f`, `bc`) @@ -910,6 +910,8 @@ is_on_mesh_border(const typename Location_traits::Face_location& l /// \param vd a vertex of `tm` /// \param tm a triangulated surface mesh /// +/// \pre `vd` is not an isolated vertex +/// template typename Location_traits::Face_location locate_in_face(typename boost::graph_traits::vertex_descriptor vd, @@ -919,6 +921,7 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename Location_traits::FT FT; + typedef typename Location_traits::Face_location Face_location; halfedge_descriptor he = halfedge(vd, tm); @@ -939,6 +942,10 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, CGAL_assertion(target(he, tm) == vd); CGAL_assertion(fd != boost::graph_traits::null_face()); + // isolated vertex + if(fd == boost::graph_traits::null_face()) + return Face_location(); + FT coords[3] = { FT(0), FT(0), FT(0) }; he = next(he, tm); // so that source(he, tm) == vd and it's simpler to handle 'index_in_face' std::size_t halfedge_local_index = halfedge_index_in_face(he, tm); @@ -966,6 +973,8 @@ locate_in_face(typename boost::graph_traits::vertex_descriptor vd, /// \param fd a face of `tm` /// \param tm a triangulated surface mesh /// +/// \pre `fd` is not the null face +/// template typename Location_traits::Face_location locate_in_face(const typename boost::graph_traits::vertex_descriptor vd, @@ -974,6 +983,8 @@ locate_in_face(const typename boost::graph_traits::vertex_descript { typedef typename Location_traits::FT FT; + CGAL_precondition(fd != boost::graph_traits::null_face()); + FT coords[3] = { FT(0), FT(0), FT(0) }; std::size_t vertex_local_index = vertex_index_in_face(vd, fd, tm); coords[vertex_local_index] = FT(1); @@ -1062,6 +1073,8 @@ locate_in_face(const typename boost::graph_traits::halfedge_descri /// \cgalParamEnd /// \cgalNamedParamsEnd /// +/// \pre `fd` is not the null face +/// template typename Location_traits::Face_location locate_in_face(const typename Location_traits::Point& query, @@ -1084,6 +1097,8 @@ locate_in_face(const typename Location_traits::Po FT snap_tolerance = choose_param(get_param(np, internal_np::snapping_tolerance), 0); + CGAL_precondition(fd != boost::graph_traits::null_face()); + vertex_descriptor vd0 = source(halfedge(fd, tm), tm); vertex_descriptor vd1 = target(halfedge(fd, tm), tm); vertex_descriptor vd2 = target(next(halfedge(fd, tm), tm), tm); From f15fbfe36c14232b4896ebdb351826beb0ecb3c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 20 Jun 2019 10:39:02 +0200 Subject: [PATCH 61/68] Fix some tests failing when unlucky with random elements --- .../test_pmp_locate.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 61f97df187a..a7c3df7faa3 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -455,15 +455,18 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) halfedge_descriptor neigh_hd = opposite(halfedge(f, g), g); face_descriptor neigh_f = face(neigh_hd, g); - int neigh_hd_id = CGAL::halfedge_index_in_face(neigh_hd, g); - Face_location neigh_loc; - neigh_loc.first = neigh_f; - neigh_loc.second[neigh_hd_id] = FT(0.3); - neigh_loc.second[(neigh_hd_id+1)%3] = FT(0.7); - neigh_loc.second[(neigh_hd_id+2)%3] = FT(0); + // Want to check good correspondence seen from one side and the other. If unfortunately + // we have selected a border face, can't do anything! if(neigh_f != boost::graph_traits::null_face()) { + int neigh_hd_id = CGAL::halfedge_index_in_face(neigh_hd, g); + Face_location neigh_loc; + neigh_loc.first = neigh_f; + neigh_loc.second[neigh_hd_id] = FT(0.3); + neigh_loc.second[(neigh_hd_id+1)%3] = FT(0.7); + neigh_loc.second[(neigh_hd_id+2)%3] = FT(0); + PMP::locate_in_adjacent_face(loc, neigh_f, g); assert(PMP::locate_in_common_face(loc, neigh_loc, g)); @@ -528,7 +531,8 @@ struct Locate_with_AABB_tree_Tester // 2D case assert(tree_b.size() == num_faces(g)); Face_location loc = PMP::locate_with_AABB_tree(p_a, tree_a, g); - assert(PMP::is_on_vertex(loc, v, g)); + + // assert(PMP::is_on_vertex(loc, v, g)); // might fail du to precision issues... assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0))); From 6f42e4be1563ffd07aeb125c5c0b82ac33bf2a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 24 Jun 2019 08:16:01 +0200 Subject: [PATCH 62/68] Fix warning --- .../include/CGAL/Polygon_mesh_processing/locate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 462c22ab466..c1620434bb1 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -1210,7 +1210,7 @@ locate_in_adjacent_face(const typename Location_traits::Face_locat } else { - const face_descriptor fd2 = boost::get(dv); + CGAL_assertion_code(const face_descriptor fd2 = boost::get(dv);) CGAL_assertion(fd2 != boost::graph_traits::null_face()); CGAL_assertion(fd2 != fd); From 40aae43c5d6bb7c9a52a444798cea11ad5c8163d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 25 Jun 2019 09:21:31 +0200 Subject: [PATCH 63/68] Fix warning --- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index a7c3df7faa3..b59b2a355a7 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -181,7 +181,7 @@ void test_constructions(const G& g, CGAL::Random& rnd) bar = PMP::barycentric_coordinates(p, q, r, mp); assert(is_equal(bar[0], FT(0.5)) && is_equal(bar[1], FT(0.5)) && is_equal(bar[2], FT(0))); - int n = 1e2; + int n = 100; while(n --> 0) // :) { const FT a = rnd.get_double(-1., 1.); @@ -240,8 +240,8 @@ void test_random_entities(const G& g, CGAL::Random& rnd) h = opposite(h, g); face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd); - int nn = 1e2; - while(nn --> 0) // the famous 'go to zero' operator + int nn = 100; + while(nn --> 0) // the infamous 'go to zero' operator { loc = PMP::random_location_on_mesh(g, rnd); assert(loc.first != boost::graph_traits::null_face()); @@ -367,7 +367,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) assert(!PMP::is_on_face_border(loc, g)); // --------------------------------------------------------------------------- - int max = 1e3, counter = 0; + int max = 1000, counter = 0; typename boost::graph_traits::halfedge_iterator hit, hend; boost::tie(hit, hend) = halfedges(g); for(; hit!=hend; ++hit) From 6d7b5ed8da8cd2b60cec182958aa3fd2a630e299 Mon Sep 17 00:00:00 2001 From: Mael Date: Tue, 25 Jun 2019 19:07:32 +0200 Subject: [PATCH 64/68] Renumber NP in test to smooth testing Another PR is also adding new named parameters --- BGL/test/BGL/test_cgal_bgl_named_params.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index cd42378e020..dead4cbdb85 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -88,7 +88,7 @@ void test(const NamedParameters& np) assert(get_param(np, CGAL::internal_np::require_same_orientation).v == 49); assert(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface).v == 50); assert(get_param(np, CGAL::internal_np::face_size_map).v == 52); - assert(get_param(np, CGAL::internal_np::snapping_tolerance).v == 53); + assert(get_param(np, CGAL::internal_np::snapping_tolerance).v == 57); // Named parameters that we use in the package 'Surface Mesh Simplification' assert(get_param(np, CGAL::internal_np::get_cost_policy).v == 34); @@ -170,7 +170,7 @@ void test(const NamedParameters& np) check_same_type<49>(get_param(np, CGAL::internal_np::require_same_orientation)); check_same_type<50>(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface)); check_same_type<52>(get_param(np, CGAL::internal_np::face_size_map)); - check_same_type<53>(get_param(np, CGAL::internal_np::snapping_tolerance)); + check_same_type<57>(get_param(np, CGAL::internal_np::snapping_tolerance)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -256,7 +256,7 @@ int main() .erase_all_duplicates(A<48>(48)) .require_same_orientation(A<49>(49)) .face_size_map(A<52>(52)) - .snapping_tolerance(A<53>(53)) + .snapping_tolerance(A<57>(57)) ); return EXIT_SUCCESS; From d3882274e51098ff952474fd05438cbcb083aff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 26 Jun 2019 08:08:20 +0200 Subject: [PATCH 65/68] Change test values to be compatible with 32 bit platforms --- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index b59b2a355a7..34a18f0c515 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -89,7 +89,7 @@ template bool is_equal(const FT& a, const FT& b) { if(boost::is_floating_point::value) - return (CGAL::abs(a - b) <= 1e-12); // numeric_limits' epsilon is too restrictive... + return (CGAL::abs(a - b) <= 1e-7); // numeric_limits' epsilon is too restrictive... else return (a == b); } @@ -101,21 +101,21 @@ void test_snappers(const G& g) typedef typename PMP::Location_traits::FT FT; - typename PMP::Location_traits::Barycentric_coordinates coords = CGAL::make_array(FT(1e-11), FT(0.99999999999999999), FT(1e-12)); + typename PMP::Location_traits::Barycentric_coordinates coords = CGAL::make_array(FT(1e-6), FT(0.9999999999999999999), FT(1e-7)); typename PMP::Location_traits::Face_location loc = std::make_pair(*(faces(g).first), coords); // --------------------------------------------------------------------------- PMP::internal::snap_coordinates_to_border(coords); // uses numeric_limits' epsilon() - assert(coords[0] == FT(1e-11) && coords[1] == FT(1) && coords[2] == FT(1e-12)); + assert(coords[0] == FT(1e-6) && coords[1] == FT(1) && coords[2] == FT(1e-7)); - PMP::internal::snap_coordinates_to_border(coords, 1e-10); + PMP::internal::snap_coordinates_to_border(coords, 1e-5); assert(coords[0] == FT(0) && coords[1] == FT(1) && coords[2] == FT(0)); // --------------------------------------------------------------------------- PMP::internal::snap_location_to_border(loc); // uses numeric_limits' epsilon() assert(!PMP::is_on_face_border(loc, g)); - PMP::internal::snap_location_to_border(loc, 1e-10); + PMP::internal::snap_location_to_border(loc, 1e-7); assert(PMP::is_on_face_border(loc, g)); } @@ -472,7 +472,7 @@ void test_locate_in_face(const G& g, CGAL::Random& rnd) assert(PMP::locate_in_common_face(loc, neigh_loc, g)); assert(PMP::locate_in_common_face(loc, p, neigh_loc, g)); - assert(PMP::locate_in_common_face(loc, p, neigh_loc, g, 1e-10)); + assert(PMP::locate_in_common_face(loc, p, neigh_loc, g, 1e-7)); } } From 2729098c292b79ded644081cbd19b97c360ad9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 26 Jun 2019 08:42:23 +0200 Subject: [PATCH 66/68] Update CHANGES.md --- Installation/CHANGES.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 15043a31843..c67a6d2935e 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -21,7 +21,16 @@ Release date: September 2019 ### 3D Triangulations - **Breaking change**: The constructor and the `insert()` function of `CGAL::Triangulation_3` which takes a range of points as argument no longer performs a `spatial_sort()` of the points. -- Add constructor and `insert()` function to `CGAL::Triangulation_3` that takes a range of points with info. + - Added constructor and `insert()` function to `CGAL::Triangulation_3` that takes a range of points with info. + - **breaking change** The graph traits enabling CGAL's 2D triangulations to be used as a parameter + for any graph-based algorithm of CGAL (or boost) have been improved to fully model the `FaceGraph` concept. + In addition, only the finite simplicies (those not incident to the infinite vertex) of the 2D triangulations + are now visibile through this scope. The complete triangulation can still be accessed as a graph, + by using the graph traits of the underlying triangulation data structure (usually, + `CGAL::Triangulation_data_structure_2`). + - Introduced a new face base class, `Triangulation_face_base_with_id_2` which enables storing + user-defined integer IDs in the face of any 2D triangulation, a precondition to use some + BGL algorithms. ### Surface Mesh - New functions to read and write using the PLY format, @@ -39,6 +48,11 @@ Release date: September 2019 Parameters. ### Polygon Mesh Processing + - Introduced a wide range of new functions related to location of queries on a triangle mesh, + such as `CGAL::Polygon_mesh_processing::locate(Point, Mesh)`, . The location of a point on a triangle mesh + is expressed as the pair of a face and the barycentric coordinates of the point in this face, + enabling robust manipulation of locations (for example, intersections of two 3D segments living + within the same face). - Added the function `CGAL::Polygon_mesh_processing::centroid()`, which computes the centroid of a closed triangle mesh. - Added the functions `CGAL::Polygon_mesh_processing::stitch_boundary_cycle()` and From 1791870f4c5c663e50156f215b9b4904159f2e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 26 Jun 2019 15:51:27 +0200 Subject: [PATCH 67/68] Fix warning --- .../test/Polygon_mesh_processing/test_pmp_locate.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index 34a18f0c515..f38b75ec7e2 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -25,16 +25,18 @@ #include #include -#include #include #include #include -#include #include #include #include +#include +#include +#include #include +#include namespace PMP = CGAL::Polygon_mesh_processing; @@ -88,7 +90,7 @@ random_3D_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd) template bool is_equal(const FT& a, const FT& b) { - if(boost::is_floating_point::value) + if(std::is_floating_point::value) return (CGAL::abs(a - b) <= 1e-7); // numeric_limits' epsilon is too restrictive... else return (a == b); @@ -209,8 +211,10 @@ void test_constructions(const G& g, CGAL::Random& rnd) assert(hd); loc = std::make_pair(f, CGAL::make_array(FT(1), FT(0), FT(0))); + assert(PMP::is_on_vertex(loc, source(halfedge(f, g), g), g)); dv = PMP::get_descriptor_from_location(loc, g); - assert(bool(boost::get(&dv))); + if(const vertex_descriptor* v = boost::get(&dv)) { } else { assert(false); } + // --------------------------------------------------------------------------- Point s = PMP::construct_point(loc, g, CGAL::parameters::all_default()); From ee99c929727c1162286fa543232fd35cee8a0869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 1 Jul 2019 09:14:04 +0200 Subject: [PATCH 68/68] Sanitize values to please 32 bit platforms --- .../Interpolation/nn_coordinates_2.cpp | 20 +++++++++++++------ .../test_pmp_locate.cpp | 5 ++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Interpolation/examples/Interpolation/nn_coordinates_2.cpp b/Interpolation/examples/Interpolation/nn_coordinates_2.cpp index 2570c69a3ff..6d84acdd82e 100644 --- a/Interpolation/examples/Interpolation/nn_coordinates_2.cpp +++ b/Interpolation/examples/Interpolation/nn_coordinates_2.cpp @@ -8,7 +8,6 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT Coord_type; typedef K::Point_2 Point; @@ -21,12 +20,20 @@ int main() { Delaunay_triangulation dt; - for(int y=0; y<3; ++y) - for(int x=0; x<3; ++x) - dt.insert(K::Point_2(x, y)); +// for(int y=0; y<3; ++y) +// for(int x=0; x<3; ++x) +// dt.insert(K::Point_2(x, y)); + + dt.insert(K::Point_2(50.18, -61.82)); + dt.insert(K::Point_2(50.18, -61.80)); + + dt.insert(K::Point_2(10, -61)); + dt.insert(K::Point_2(70, -61)); + dt.insert(K::Point_2(50, -30)); + dt.insert(K::Point_2(50, -90)); // coordinates computation - K::Point_2 p(1.2, 0.7); // query point + K::Point_2 p(50.18, -61.82); // query point Point_coordinate_vector coords; CGAL::Triple, K::FT, bool> result = @@ -42,9 +49,10 @@ int main() std::cout << "Coordinate computation successful." << std::endl; std::cout << "Normalization factor: " << norm << std::endl; + std::cout << "Coordinates for point: (" << p << ") are the following: " << std::endl; for(std::size_t i=0; i(loc, 1e-7); + + assert(PMP::is_on_vertex(loc, v, g)); // might fail du to precision issues... assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0)));