Skip to content

Commit 416cbbc

Browse files
committed
Merge pull request #4277 from MaelRL/PMP-Locate_rework_traits-GF
PMP: Replace `Location_traits` by a simpler API
2 parents 5715202 + 77e0937 commit 416cbbc

File tree

8 files changed

+1126
-558
lines changed

8 files changed

+1126
-558
lines changed

BGL/include/CGAL/boost/graph/generators.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -733,11 +733,12 @@ make_icosahedron(Graph& g,
733733
* If `triangulated` is `true`, the diagonal of each cell is oriented from (0,0) to (1,1)
734734
* in the cell coordinates.
735735
*
736-
*\tparam CoordinateFunctor a function object providing `Point_3 operator()(size_type I, size_type J)` with `Point_3` being
737-
* the value_type of the internal property_map for `CGAL::vertex_point_t`.
738-
* and outputs a `boost::property_traits<boost::property_map<Graph,CGAL::vertex_point_t>::%type>::%value_type`.
739-
* It will be called with arguments (`w`, `h`), with `w` in [0..`i`] and `h` in [0..`j`].
740-
* <p>%Default: a point with positive integer coordinates (`w`, `h`, 0), with `w` in [0..`i`] and `h` in [0..`j`]
736+
*\tparam CoordinateFunctor a function object providing:
737+
* `%Point_3 operator()(size_type I, size_type J)`, with `%Point_3` being the value_type
738+
* of the internal property_map for `CGAL::vertex_point_t` and outputs an object of type
739+
* `boost::property_traits<boost::property_map<Graph,CGAL::vertex_point_t>::%type>::%value_type`.
740+
* It will be called with arguments (`w`, `h`), with `w` in [0..`i`] and `h` in [0..`j`].<br>
741+
* %Default: a point with positive integer coordinates (`w`, `h`, 0), with `w` in [0..`i`] and `h` in [0..`j`]
741742
*
742743
* \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) ).
743744
*/

Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt

+2
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,8 @@ finding the nearest point on a mesh given a point or a ray
535535
(`CGAL::Polygon_mesh_processing::locate_with_AABB_tree()`, and similar), and location-based predicates
536536
(for example, `CGAL::Polygon_mesh_processing::is_on_face_border()`).
537537

538+
The example \ref Polygon_mesh_processing/locate_example.cpp presents a few of these functions.
539+
538540
****************************************
539541
\section PMPOrientation Orientation
540542

Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt

+1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@
2525
\example Polygon_mesh_processing/repair_polygon_soup_example.cpp
2626
\example Polygon_mesh_processing/mesh_smoothing_example.cpp
2727
\example Polygon_mesh_processing/shape_smoothing_example.cpp
28+
\example Polygon_mesh_processing/locate_example.cpp
2829
*/

Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ create_single_source_cgal_program( "detect_features_example.cpp" )
8585
create_single_source_cgal_program( "manifoldness_repair_example.cpp" )
8686
create_single_source_cgal_program( "repair_polygon_soup_example.cpp" )
8787
create_single_source_cgal_program( "mesh_smoothing_example.cpp")
88+
create_single_source_cgal_program( "locate_example.cpp")
8889

8990
if(OpenMesh_FOUND)
9091
create_single_source_cgal_program( "compute_normals_example_OM.cpp" )
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
2+
3+
#include <CGAL/Surface_mesh.h>
4+
5+
#include <CGAL/AABB_face_graph_triangle_primitive.h>
6+
#include <CGAL/AABB_tree.h>
7+
#include <CGAL/AABB_traits.h>
8+
#include <CGAL/boost/graph/helpers.h>
9+
#include <CGAL/Dynamic_property_map.h>
10+
#include <CGAL/Polygon_mesh_processing/locate.h>
11+
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
12+
13+
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
14+
typedef K::FT FT;
15+
typedef K::Point_2 Point_2;
16+
typedef K::Ray_2 Ray_2;
17+
typedef K::Point_3 Point_3;
18+
typedef K::Ray_3 Ray_3;
19+
20+
typedef CGAL::Surface_mesh<Point_3> Mesh;
21+
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
22+
typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor;
23+
24+
namespace CP = CGAL::parameters;
25+
namespace PMP = CGAL::Polygon_mesh_processing;
26+
27+
typedef PMP::Barycentric_coordinates<FT> Barycentric_coordinates;
28+
typedef PMP::Face_location<Mesh, FT> Face_location;
29+
30+
int main(int /*argc*/, char** /*argv*/)
31+
{
32+
// Generate a simple 3D triangle mesh that with vertices on the plane xOy
33+
Mesh tm;
34+
CGAL::make_grid(10, 10, tm);
35+
PMP::triangulate_faces(tm);
36+
37+
// Basic usage
38+
Face_location random_location = PMP::random_location_on_mesh<FT>(tm);
39+
const face_descriptor f = random_location.first;
40+
const Barycentric_coordinates& coordinates = random_location.second;
41+
42+
std::cout << "Random location on the mesh: face " << f
43+
<< " and with coordinates [" << coordinates[0] << "; "
44+
<< coordinates[1] << "; "
45+
<< coordinates[2] << "]\n";
46+
std::cout << "It corresponds to point (" << PMP::construct_point(random_location, tm) << ")\n\n";
47+
48+
// Locate a known 3D point in the mesh
49+
const Point_3 query(1.2, 7.4, 0);
50+
Face_location query_location = PMP::locate(query, tm);
51+
52+
std::cout << "Point (" << query << ") is located in face " << query_location.first
53+
<< " with barycentric coordinates [" << query_location.second[0] << "; "
54+
<< query_location.second[1] << "; "
55+
<< query_location.second[2] << "]\n\n";
56+
57+
// Locate a 3D point in the mesh as the intersection of the mesh and a 3D ray.
58+
// The AABB tree can be cached in case many queries are performed (otherwise, it is rebuilt
59+
// on each call, which is expensive).
60+
typedef CGAL::AABB_face_graph_triangle_primitive<Mesh> AABB_face_graph_primitive;
61+
typedef CGAL::AABB_traits<K, AABB_face_graph_primitive> AABB_face_graph_traits;
62+
63+
CGAL::AABB_tree<AABB_face_graph_traits> tree;
64+
PMP::build_AABB_tree(tm, tree);
65+
66+
const Ray_3 ray_3(Point_3(4.2, 6.8, 2.4), Point_3(7.2, 2.3, -5.8));
67+
Face_location ray_location = PMP::locate_with_AABB_tree(ray_3, tree, tm);
68+
69+
std::cout << "Intersection of the 3D ray and the mesh is in face " << ray_location.first
70+
<< " with barycentric coordinates [" << ray_location.second[0] << " "
71+
<< ray_location.second[1] << " "
72+
<< ray_location.second[2] << "]\n";
73+
std::cout << "It corresponds to point (" << PMP::construct_point(ray_location, tm) << ")\n";
74+
std::cout << "Is it on the face's border? " << (PMP::is_on_face_border(ray_location, tm) ? "Yes" : "No") << "\n\n";
75+
76+
// -----------------------------------------------------------------------------------------------
77+
// Now, we artifically project the mesh to the natural 2D dimensional plane, with a little translation
78+
// via a custom vertex point property map
79+
80+
typedef CGAL::dynamic_vertex_property_t<Point_2> Point_2_property;
81+
typedef typename boost::property_map<Mesh, Point_2_property>::type Projection_pmap;
82+
Projection_pmap projection_pmap = get(Point_2_property(), tm);
83+
84+
for(vertex_descriptor v : vertices(tm))
85+
{
86+
const Point_3& p = tm.point(v);
87+
put(projection_pmap, v, Point_2(p.x() + 1, p.y())); // simply ignoring the z==0 coordinate and translating along Ox
88+
}
89+
90+
// Locate the same 3D point but in a 2D context
91+
const Point_2 query_2(query.x() + 1, query.y());
92+
Face_location query_location_2 = PMP::locate(query_2, tm, CP::vertex_point_map(projection_pmap));
93+
94+
std::cout << "Point (" << query_2 << ") is located in face " << query_location_2.first
95+
<< " with barycentric coordinates [" << query_location_2.second[0] << "; "
96+
<< query_location_2.second[1] << "; "
97+
<< query_location_2.second[2] << "]\n\n";
98+
99+
// Shoot a 2D ray and locate the intersection with the mesh in 2D
100+
const Ray_2 ray_2(Point_2(-10, -10), Point_2(10, 10));
101+
Face_location ray_location_2 = PMP::locate(ray_2, tm, CP::vertex_point_map(projection_pmap)); // This rebuilds an AABB tree on each call
102+
103+
std::cout << "Intersection of the 2D ray and the mesh is in face " << ray_location_2.first
104+
<< " with barycentric coordinates [" << ray_location_2.second[0] << "; "
105+
<< ray_location_2.second[1] << "; "
106+
<< ray_location_2.second[2] << "]\n";
107+
std::cout << "It corresponds to point (" << PMP::construct_point(ray_location_2, tm, CP::vertex_point_map(projection_pmap)) << ")\n";
108+
109+
if(PMP::is_on_mesh_border(ray_location_2, tm))
110+
std::cout << "It is on the border of the mesh!\n" << std::endl;
111+
112+
return EXIT_SUCCESS;
113+
}

0 commit comments

Comments
 (0)