VisitPointLikeContainer.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4
5#include <boost/preprocessor/seq/for_each.hpp>
6
7#include <pcl/point_cloud.h>
8#include <pcl/point_types.h>
9
10#pragma GCC diagnostic push
11#pragma GCC diagnostic ignored "-Wpedantic"
12#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
13#include <CGAL/Polyhedron_3.h>
14#pragma GCC diagnostic pop
15
17
18//point traits
19namespace armarx::meta
20{
21
22#define _detail_unpack(r, data, elem) , elem
23 template <class T>
24 static constexpr bool is_pcl_point_type_v =
25 is_any_of_v<T /*no ,*/ BOOST_PP_SEQ_FOR_EACH(_detail_unpack, , PCL_XYZ_POINT_TYPES)>;
26#undef _detail_unpack
27
28 template <class T, class = void>
29 struct is_eigen_vec3_type : std::false_type
30 {
31 };
32
33 template <class T>
34 struct is_eigen_vec3_type<Eigen::Matrix<T, 3, 1>, void> : std::true_type
35 {
36 };
37
38 template <class T>
39 struct is_eigen_vec3_type<Eigen::Matrix<T, 1, 3>, void> : std::true_type
40 {
41 };
42
43 template <class T>
44 static constexpr bool is_eigen_vec3_type_v = is_eigen_vec3_type<T>::value;
45
46 template <class T, class = void>
47 struct point_type_traits : std::false_type
48 {
49 };
50
51 template <class T>
52 struct point_type_traits<T, std::enable_if_t<is_pcl_point_type_v<T>>> : std::true_type
53 {
54 static const auto&
55 x(const T& v)
56 {
57 return v.x;
58 }
59
60 static const auto&
61 y(const T& v)
62 {
63 return v.y;
64 }
65
66 static const auto&
67 z(const T& v)
68 {
69 return v.z;
70 }
71 };
72
73 template <class T>
74 struct point_type_traits<T, std::enable_if_t<is_eigen_vec3_type_v<T>>> : std::true_type
75 {
76 static const auto&
77 x(const T& v)
78 {
79 return v.x();
80 }
81
82 static const auto&
83 y(const T& v)
84 {
85 return v.y();
86 }
87
88 static const auto&
89 z(const T& v)
90 {
91 return v.z();
92 }
93 };
94
95 template <>
96 struct point_type_traits<CGAL::Epick::Point_3, void> : std::true_type
97 {
98 using T = CGAL::Epick::Point_3;
99
100 static const auto&
101 x(const T& v)
102 {
103 return v.x();
104 }
105
106 static const auto&
107 y(const T& v)
108 {
109 return v.y();
110 }
111
112 static const auto&
113 z(const T& v)
114 {
115 return v.z();
116 }
117 };
118
119 template <class T>
120 static constexpr bool is_point_type_v = point_type_traits<T>::value;
121
122 static_assert(is_point_type_v<pcl::PointXYZ>);
123 static_assert(is_point_type_v<Eigen::Vector3f>);
124 static_assert(is_point_type_v<Eigen::Vector3i>);
125 static_assert(is_point_type_v<Eigen::RowVector3cd>);
126 static_assert(is_point_type_v<CGAL::Epick::Point_3>);
127} // namespace armarx::meta
128
129//container traits
130#include <deque>
131#include <forward_list>
132#include <list>
133#include <set>
134#include <unordered_set>
135#include <vector>
136
137namespace armarx::meta
138{
139#define _detail_containerlist \
140 std::vector, std::deque, std::list, std::forward_list, std::set, std::unordered_set
143
144 template <class T, class = void>
145 struct container_traits : std::false_type
146 {
147 };
148
149 template <class T>
151 T,
152 std::enable_if_t<TypeTemplateTraits::IsInstanceOfAnyV<T, _detail_containerlist>>> :
153 std::true_type
154 {
155 using element_t = typename T::value_type;
156
157 static auto
158 begin(const T& t)
159 {
160 return t.begin();
161 }
162
163 static auto
165 {
166 return t.begin();
167 }
168
169 static auto
170 end(const T& t)
171 {
172 return t.end();
173 }
174
175 static auto
176 end(T& t)
177 {
178 return t.end();
179 }
180
181 static const auto
182 deref(auto& it)
183 {
184 return *it;
185 }
186
187 static auto
188 size(const T& t)
189 {
190 return t.size();
191 }
192 };
193
194#undef _detail_containerlist
195
196 template <class PType>
197 struct container_traits<pcl::PointCloud<PType>, void> : std::true_type
198 {
199 using T = pcl::PointCloud<PType>;
200 using element_t = PType;
201
202 static auto
203 begin(const T& t)
204 {
205 return t.points.begin();
206 }
207
208 static auto
210 {
211 return t.points.begin();
212 }
213
214 static auto
215 end(const T& t)
216 {
217 return t.points.end();
218 }
219
220 static auto
221 end(T& t)
222 {
223 return t.points.end();
224 }
225
226 static const auto
227 deref(auto& it)
228 {
229 return *it;
230 }
231
232 static auto
233 size(const T& t)
234 {
235 return t.points.size();
236 }
237 };
238
239 template <class T>
240 static constexpr bool is_container_type_v = container_traits<T>::value;
241} // namespace armarx::meta
242
244{
245 static_assert(meta::is_container_type_v<std::vector<Eigen::Vector3f>>);
246 static_assert(meta::is_container_type_v<std::vector<Eigen::Vector3d>>);
247 static_assert(meta::is_container_type_v<std::vector<Eigen::RowVector3cd>>);
248 static_assert(meta::is_container_type_v<pcl::PointCloud<pcl::PointXYZ>>);
249
250 template <class T, class = void>
251 struct VisitPointLike : std::false_type
252 {
253 //template<class F, class F2>
254 //static void visit(const T& c, F& sizeinfo, F2& perElem);
255 //{
256 // sizeinfo(c.size());
257 // perElem(p.x(), p.y(), p.z());
258 //}
259 };
260
261 template <class T>
263 T,
264 std::enable_if_t<meta::is_container_type_v<T> &&
265 meta::is_point_type_v<typename meta::container_traits<T>::element_t>>> :
266 std::true_type
267 {
268 template <class F, class F2>
269 static void
270 visit(const T& c, F& sizeinfo, F2& perElem)
271 {
272 using ctr = meta::container_traits<T>;
274 sizeinfo(ctr::size(c));
275 auto f = ctr::begin(c);
276 auto l = ctr::end(c);
277 for (; f != l; ++f)
278 {
279 auto&& p = ctr::deref(f);
280 perElem(tr::x(p), tr::y(p), tr::z(p));
281 }
282 }
283 };
284
285 template <class T>
287 T,
288 std::enable_if_t<VisitPointLike<meta::pointer_type_pointee_t<T>>::value>> : std::true_type
289 {
290 template <class F, class F2>
291 static void
292 visit(const T& c, F& sizeinfo, F2& perElem)
293 {
296 }
297 };
298
299 template <class K>
300 struct VisitPointLike<CGAL::Polyhedron_3<K>, void> : std::true_type
301 {
302 template <class F, class F2>
303 static void
304 visit(const CGAL::Polyhedron_3<K>& c, F& sizeinfo, F2& perElem)
305 {
306 sizeinfo(c.size_of_vertices());
307 for (auto v = c.vertices_begin(); v != c.vertices_end(); ++v)
308 {
309 perElem(v->point().x(), v->point().y(), v->point().z());
310 }
311 }
312 };
313
314 template <class T>
315 struct VisitPointLike<const T> : VisitPointLike<T>
316 {
317 };
318
319 template <class T>
321 {
322 };
323
325 std::allocator<Eigen::Matrix<float, 3, 1>>>>::value);
326 static_assert(VisitPointLike<std::vector<Eigen::Vector3f>>::value);
327 static_assert(VisitPointLike<std::vector<Eigen::Vector3d>>::value);
331} // namespace armarx::detail::VisitPointLike
332
333namespace armarx
334{
335 inline void
336 VisitPointLikeContainer(const auto& cloud, auto&& perElem, auto&& sizeInfo)
337 {
338 using handler = ::armarx::detail::VisitPointLike::VisitPointLike<decltype(cloud)>;
339 static_assert(handler::value, "This type is not supported!");
340 handler::visit(cloud, perElem, sizeInfo);
341 }
342} // namespace armarx
constexpr T c
#define _detail_unpack(r, data, elem)
#define _detail_containerlist
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition Mesh.h:14
This file offers overloads of toIce() and fromIce() functions for STL container types.
void VisitPointLikeContainer(const auto &cloud, auto &&perElem, auto &&sizeInfo)
static void visit(const CGAL::Polyhedron_3< K > &c, F &sizeinfo, F2 &perElem)