Line | Branch | Exec | Source |
---|---|---|---|
1 | // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de> | ||
2 | // SPDX-License-Identifier: MIT | ||
3 | /*! | ||
4 | * \file | ||
5 | * \ingroup PredefinedTraits | ||
6 | * \brief Traits specializations for cgal triangulations in | ||
7 | * <a href="https://doc.cgal.org/latest/Triangulation_2/index.html">2D</a> | ||
8 | * <a href="https://doc.cgal.org/latest/Triangulation_3/index.html">3D</a>. | ||
9 | */ | ||
10 | #ifndef GRIDFORMAT_TRAITS_CGAL_HPP_ | ||
11 | #define GRIDFORMAT_TRAITS_CGAL_HPP_ | ||
12 | |||
13 | #include <cassert> | ||
14 | #include <ranges> | ||
15 | #include <vector> | ||
16 | #include <array> | ||
17 | #include <utility> | ||
18 | #include <concepts> | ||
19 | #include <type_traits> | ||
20 | |||
21 | #ifdef GRIDFORMAT_IGNORE_CGAL_WARNINGS | ||
22 | #pragma GCC diagnostic push | ||
23 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" | ||
24 | #pragma GCC diagnostic ignored "-Wnull-dereference" | ||
25 | #endif | ||
26 | #include <CGAL/number_utils.h> | ||
27 | #include <CGAL/Point_2.h> | ||
28 | #include <CGAL/Point_3.h> | ||
29 | #include <CGAL/Triangulation_2.h> | ||
30 | #include <CGAL/Triangulation_3.h> | ||
31 | #ifdef GRIDFORMAT_IGNORE_CGAL_WARNINGS | ||
32 | #pragma GCC diagnostic pop | ||
33 | #endif | ||
34 | |||
35 | #include <gridformat/common/type_traits.hpp> | ||
36 | #include <gridformat/grid/traits.hpp> | ||
37 | #include <gridformat/grid/type_traits.hpp> | ||
38 | #include <gridformat/grid/cell_type.hpp> | ||
39 | |||
40 | |||
41 | namespace GridFormat { | ||
42 | namespace Concepts { | ||
43 | |||
44 | #ifndef DOXYGEN | ||
45 | namespace CGALDetail { | ||
46 | |||
47 | // helper functions to deduce the actually set TriangulationDataStructure | ||
48 | // and LockDataStructure. The thing is that Triangulation_3 exports types | ||
49 | // that may be different from the one originally set by the user. For instance, | ||
50 | // per default it uses CGAL::Default, but then exports the actually chosen default. | ||
51 | template<typename K, typename TDS> | ||
52 | TDS deduce_tds(const CGAL::Triangulation_2<K, TDS>&) { return {}; } | ||
53 | template<typename K, typename TDS, typename LDS> | ||
54 | TDS deduce_tds(const CGAL::Triangulation_3<K, TDS, LDS>&) { return {}; } | ||
55 | template<typename K, typename TDS, typename LDS> | ||
56 | LDS deduce_lds(const CGAL::Triangulation_3<K, TDS, LDS>&) { return {}; } | ||
57 | |||
58 | template<typename T> struct IsPoint : public std::false_type {}; | ||
59 | template<typename K> struct IsPoint<CGAL::Point_2<K>> : public std::true_type {}; | ||
60 | template<typename K> struct IsPoint<CGAL::Point_3<K>> : public std::true_type {}; | ||
61 | template<typename T> concept Point = IsPoint<std::remove_cvref_t<T>>::value; | ||
62 | |||
63 | } // CGALDetail | ||
64 | #endif // DOXYGEN | ||
65 | |||
66 | template<typename T> | ||
67 | concept CGALGrid2D = requires(const T& grid) { | ||
68 | typename T::Geom_traits; | ||
69 | typename T::Triangulation_data_structure; | ||
70 | requires std::derived_from<T, CGAL::Triangulation_2< | ||
71 | typename T::Geom_traits, | ||
72 | decltype(CGALDetail::deduce_tds(grid)) | ||
73 | >>; | ||
74 | }; | ||
75 | |||
76 | template<typename T> | ||
77 | concept CGALGrid3D = requires(const T& grid) { | ||
78 | typename T::Geom_traits; | ||
79 | typename T::Triangulation_data_structure; | ||
80 | typename T::Lock_data_structure; | ||
81 | requires std::derived_from<T, CGAL::Triangulation_3< | ||
82 | typename T::Geom_traits, | ||
83 | decltype(CGALDetail::deduce_tds(grid)), | ||
84 | decltype(CGALDetail::deduce_lds(grid)) | ||
85 | >>; | ||
86 | }; | ||
87 | |||
88 | template<typename T> | ||
89 | concept CGALGrid = CGALGrid2D<T> or CGALGrid3D<T>; | ||
90 | |||
91 | // Some point types in CGAL (as weighted_point) wrap a CGAL::Point | ||
92 | template<typename T> | ||
93 | concept CGALPointWrapper = requires(const T& wrapper) { | ||
94 | { wrapper.point() } -> CGALDetail::Point; | ||
95 | }; | ||
96 | |||
97 | } // namespace Concepts | ||
98 | |||
99 | #ifndef DOXYGEN | ||
100 | namespace CGAL { | ||
101 | |||
102 | template<typename T> struct CellType; | ||
103 | template<Concepts::CGALGrid2D T> struct CellType<T> : public std::type_identity<typename T::Face_handle> {}; | ||
104 | template<Concepts::CGALGrid3D T> struct CellType<T> : public std::type_identity<typename T::Cell_handle> {}; | ||
105 | template<Concepts::CGALGrid T> using Cell = typename CellType<T>::type; | ||
106 | |||
107 | template<Concepts::CGALGrid T> | ||
108 | inline constexpr int dimension = Concepts::CGALGrid2D<T> ? 2 : 3; | ||
109 | |||
110 | template<typename K> | ||
111 | 242 | std::array<double, 2> to_double_array(const ::CGAL::Point_2<K>& p) { | |
112 |
4/8✓ Branch 1 taken 242 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 242 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 242 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 242 times.
✗ Branch 11 not taken.
|
242 | return {::CGAL::to_double(p.x()), ::CGAL::to_double(p.y())}; |
113 | } | ||
114 | |||
115 | template<typename K> | ||
116 | 420 | std::array<double, 3> to_double_array(const ::CGAL::Point_3<K>& p) { | |
117 |
6/12✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 420 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 420 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 420 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 420 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 420 times.
✗ Branch 17 not taken.
|
420 | return {::CGAL::to_double(p.x()), ::CGAL::to_double(p.y()), ::CGAL::to_double(p.z())}; |
118 | } | ||
119 | template<Concepts::CGALPointWrapper W> | ||
120 |
2/4✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 168 times.
✗ Branch 5 not taken.
|
336 | auto to_double_array(const W& wrapper) { return to_double_array(wrapper.point()); } |
121 | |||
122 | } // namespace CGAL | ||
123 | #endif // DOXYGEN | ||
124 | |||
125 | namespace Traits { | ||
126 | |||
127 | template<Concepts::CGALGrid Grid> | ||
128 | struct Cells<Grid> { | ||
129 | 2090 | static std::ranges::range auto get(const Grid& grid) { | |
130 | if constexpr (Concepts::CGALGrid2D<Grid>) | ||
131 |
1/2✓ Branch 1 taken 697 times.
✗ Branch 2 not taken.
|
1394 | return grid.finite_face_handles() |
132 |
2/4✓ Branch 1 taken 697 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 697 times.
✗ Branch 5 not taken.
|
4115 | | std::views::transform([] (auto it) -> typename Grid::Face_handle { return it; }); |
133 | else | ||
134 |
1/2✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
|
696 | return grid.finite_cell_handles() |
135 |
2/4✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 348 times.
✗ Branch 5 not taken.
|
3192 | | std::views::transform([] (auto it) -> typename Grid::Cell_handle { return it; }); |
136 | } | ||
137 | }; | ||
138 | |||
139 | template<Concepts::CGALGrid Grid> | ||
140 | struct Points<Grid> { | ||
141 | 136 | static std::ranges::range auto get(const Grid& grid) { | |
142 |
1/2✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
|
136 | return grid.finite_vertex_handles() |
143 |
2/4✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68 times.
✗ Branch 5 not taken.
|
548 | | std::views::transform([] (auto it) -> typename Grid::Vertex_handle { return it; }); |
144 | } | ||
145 | }; | ||
146 | |||
147 | template<Concepts::CGALGrid Grid> | ||
148 | struct CellPoints<Grid, GridFormat::CGAL::Cell<Grid>> { | ||
149 | 5368 | static std::ranges::range auto get(const Grid&, const GridFormat::CGAL::Cell<Grid>& cell) { | |
150 | static constexpr int num_corners = Concepts::CGALGrid2D<Grid> ? 3 : 4; | ||
151 |
3/6✓ Branch 1 taken 2684 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2684 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2684 times.
✗ Branch 8 not taken.
|
12626 | return std::views::iota(0, num_corners) | std::views::transform([=] (int i) { |
152 | 1890 | return cell->vertex(i); | |
153 | 10736 | }); | |
154 | } | ||
155 | }; | ||
156 | |||
157 | template<Concepts::CGALGrid Grid> | ||
158 | struct PointCoordinates<Grid, typename Grid::Vertex_handle> { | ||
159 | 1024 | static std::ranges::range auto get(const Grid&, const typename Grid::Vertex_handle& vertex) { | |
160 | 1024 | return CGAL::to_double_array(vertex->point()); | |
161 | } | ||
162 | }; | ||
163 | |||
164 | template<Concepts::CGALGrid Grid> | ||
165 | struct PointId<Grid, typename Grid::Vertex_handle> { | ||
166 | 788 | static std::size_t get(const Grid&, const typename Grid::Vertex_handle& v) { | |
167 |
1/2✓ Branch 1 taken 394 times.
✗ Branch 2 not taken.
|
788 | return ::CGAL::Handle_hash_function{}(v); |
168 | } | ||
169 | }; | ||
170 | |||
171 | template<Concepts::CGALGrid Grid> | ||
172 | struct CellType<Grid, GridFormat::CGAL::Cell<Grid>> { | ||
173 | 784 | static GridFormat::CellType get(const Grid&, const GridFormat::CGAL::Cell<Grid>&) { | |
174 | if constexpr (Concepts::CGALGrid2D<Grid>) | ||
175 | 568 | return GridFormat::CellType::triangle; | |
176 | else | ||
177 | 216 | return GridFormat::CellType::tetrahedron; | |
178 | } | ||
179 | }; | ||
180 | |||
181 | template<Concepts::CGALGrid Grid> | ||
182 | struct NumberOfPoints<Grid> { | ||
183 | 610 | static std::integral auto get(const Grid& grid) { | |
184 | 610 | return grid.number_of_vertices(); | |
185 | } | ||
186 | }; | ||
187 | |||
188 | template<Concepts::CGALGrid Grid> | ||
189 | struct NumberOfCells<Grid> { | ||
190 | 534 | static std::integral auto get(const Grid& grid) { | |
191 | if constexpr (Concepts::CGALGrid2D<Grid>) | ||
192 | 342 | return grid.number_of_faces(); | |
193 | else | ||
194 | 192 | return grid.number_of_finite_cells(); | |
195 | } | ||
196 | }; | ||
197 | |||
198 | template<Concepts::CGALGrid Grid> | ||
199 | struct NumberOfCellPoints<Grid, GridFormat::CGAL::Cell<Grid>> { | ||
200 | 174 | static constexpr unsigned int get(const Grid&, const GridFormat::CGAL::Cell<Grid>&) { | |
201 | if constexpr (Concepts::CGALGrid2D<Grid>) | ||
202 | 66 | return 3; | |
203 | else | ||
204 | 108 | return 4; | |
205 | } | ||
206 | }; | ||
207 | |||
208 | } // namespace Traits | ||
209 | } // namespace GridFormat | ||
210 | |||
211 | #endif // GRIDFORMAT_TRAITS_CGAL_HPP_ | ||
212 |