GCC Code Coverage Report


Directory: gridformat/
File: gridformat/traits/cgal.hpp
Date: 2024-11-20 14:41:59
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 68 68 100.0%
Branches: 25 50 50.0%

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