GridFormat 0.4.0
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
cgal.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2// SPDX-License-Identifier: MIT
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
41namespace GridFormat {
42namespace Concepts {
43
44#ifndef DOXYGEN
45namespace 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
66template<typename T>
67concept 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
76template<typename T>
77concept 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
88template<typename T>
90
91// Some point types in CGAL (as weighted_point) wrap a CGAL::Point
92template<typename T>
93concept CGALPointWrapper = requires(const T& wrapper) {
94 { wrapper.point() } -> CGALDetail::Point;
95};
96
97} // namespace Concepts
98
99#ifndef DOXYGEN
100namespace CGAL {
101
102template<typename T> struct CellType;
103template<Concepts::CGALGrid2D T> struct CellType<T> : public std::type_identity<typename T::Face_handle> {};
104template<Concepts::CGALGrid3D T> struct CellType<T> : public std::type_identity<typename T::Cell_handle> {};
105template<Concepts::CGALGrid T> using Cell = typename CellType<T>::type;
106
107template<Concepts::CGALGrid T>
108inline constexpr int dimension = Concepts::CGALGrid2D<T> ? 2 : 3;
109
110template<typename K>
111std::array<double, 2> to_double_array(const ::CGAL::Point_2<K>& p) {
112 return {::CGAL::to_double(p.x()), ::CGAL::to_double(p.y())};
113}
114
115template<typename K>
116std::array<double, 3> to_double_array(const ::CGAL::Point_3<K>& p) {
117 return {::CGAL::to_double(p.x()), ::CGAL::to_double(p.y()), ::CGAL::to_double(p.z())};
118}
119template<Concepts::CGALPointWrapper W>
120auto to_double_array(const W& wrapper) { return to_double_array(wrapper.point()); }
121
122} // namespace CGAL
123#endif // DOXYGEN
124
125namespace Traits {
126
127template<Concepts::CGALGrid Grid>
128struct Cells<Grid> {
129 static std::ranges::range auto get(const Grid& grid) {
130 if constexpr (Concepts::CGALGrid2D<Grid>)
131 return grid.finite_face_handles()
132 | std::views::transform([] (auto it) -> typename Grid::Face_handle { return it; });
133 else
134 return grid.finite_cell_handles()
135 | std::views::transform([] (auto it) -> typename Grid::Cell_handle { return it; });
136 }
137};
138
139template<Concepts::CGALGrid Grid>
140struct Points<Grid> {
141 static std::ranges::range auto get(const Grid& grid) {
142 return grid.finite_vertex_handles()
143 | std::views::transform([] (auto it) -> typename Grid::Vertex_handle { return it; });
144 }
145};
146
147template<Concepts::CGALGrid Grid>
148struct CellPoints<Grid, GridFormat::CGAL::Cell<Grid>> {
149 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 return std::views::iota(0, num_corners) | std::views::transform([=] (int i) {
152 return cell->vertex(i);
153 });
154 }
155};
156
157template<Concepts::CGALGrid Grid>
158struct PointCoordinates<Grid, typename Grid::Vertex_handle> {
159 static std::ranges::range auto get(const Grid&, const typename Grid::Vertex_handle& vertex) {
160 return CGAL::to_double_array(vertex->point());
161 }
162};
163
164template<Concepts::CGALGrid Grid>
165struct PointId<Grid, typename Grid::Vertex_handle> {
166 static std::size_t get(const Grid&, const typename Grid::Vertex_handle& v) {
167 return ::CGAL::Handle_hash_function{}(v);
168 }
169};
170
171template<Concepts::CGALGrid Grid>
172struct CellType<Grid, GridFormat::CGAL::Cell<Grid>> {
173 static GridFormat::CellType get(const Grid&, const GridFormat::CGAL::Cell<Grid>&) {
174 if constexpr (Concepts::CGALGrid2D<Grid>)
175 return GridFormat::CellType::triangle;
176 else
177 return GridFormat::CellType::tetrahedron;
178 }
179};
180
181template<Concepts::CGALGrid Grid>
182struct NumberOfPoints<Grid> {
183 static std::integral auto get(const Grid& grid) {
184 return grid.number_of_vertices();
185 }
186};
187
188template<Concepts::CGALGrid Grid>
189struct NumberOfCells<Grid> {
190 static std::integral auto get(const Grid& grid) {
191 if constexpr (Concepts::CGALGrid2D<Grid>)
192 return grid.number_of_faces();
193 else
194 return grid.number_of_finite_cells();
195 }
196};
197
198template<Concepts::CGALGrid Grid>
199struct NumberOfCellPoints<Grid, GridFormat::CGAL::Cell<Grid>> {
200 static constexpr unsigned int get(const Grid&, const GridFormat::CGAL::Cell<Grid>&) {
201 if constexpr (Concepts::CGALGrid2D<Grid>)
202 return 3;
203 else
204 return 4;
205 }
206};
207
208} // namespace Traits
209} // namespace GridFormat
210
211#endif // GRIDFORMAT_TRAITS_CGAL_HPP_
Definition: cgal.hpp:67
Definition: cgal.hpp:77
Definition: cgal.hpp:89