Point Cloud Library (PCL) 1.13.0
Loading...
Searching...
No Matches
register_point_struct.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2010-2012, Willow Garage, Inc.
6 * Copyright (c) 2012-, Open Perception, Inc.
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * * Neither the name of the copyright holder(s) nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 *
39 */
40
41#pragma once
42
43#ifdef __GNUC__
44#pragma GCC system_header
45#endif
46
47#if defined _MSC_VER
48 #pragma warning (push, 2)
49 // 4244 : conversion from 'type1' to 'type2', possible loss of data
50 #pragma warning (disable: 4244)
51#endif
52
53#include <pcl/point_struct_traits.h> // for pcl::traits::POD, POINT_CLOUD_REGISTER_FIELD_(NAME, OFFSET, DATATYPE), POINT_CLOUD_REGISTER_POINT_FIELD_LIST
54#include <boost/mpl/assert.hpp> // for BOOST_MPL_ASSERT_MSG
55#include <boost/preprocessor/seq/for_each.hpp> // for BOOST_PP_SEQ_FOR_EACH
56#include <boost/preprocessor/seq/transform.hpp> // for BOOST_PP_SEQ_TRANSFORM
57#include <boost/preprocessor/tuple/elem.hpp> // for BOOST_PP_TUPLE_ELEM
58#include <boost/preprocessor/cat.hpp> // for BOOST_PP_CAT
59
60#include <cstdint> // for std::uint32_t
61#include <type_traits> // for std::enable_if_t, std::is_array, std::remove_const_t, std::remove_all_extents_t
62
63// Must be used in global namespace with name fully qualified
64#define POINT_CLOUD_REGISTER_POINT_STRUCT(name, fseq) \
65 POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, \
66 BOOST_PP_CAT(POINT_CLOUD_REGISTER_POINT_STRUCT_X fseq, 0))
67 /***/
68
69#define POINT_CLOUD_REGISTER_POINT_WRAPPER(wrapper, pod) \
70 BOOST_MPL_ASSERT_MSG(sizeof(wrapper) == sizeof(pod), POINT_WRAPPER_AND_POD_TYPES_HAVE_DIFFERENT_SIZES, (wrapper&, pod&)); \
71 namespace pcl { \
72 namespace traits { \
73 template<> struct POD<wrapper> { using type = pod; }; \
74 } \
75 }
76 /***/
77
78// These macros help transform the unusual data structure (type, name, tag)(type, name, tag)...
79// into a proper preprocessor sequence of 3-tuples ((type, name, tag))((type, name, tag))...
80#define POINT_CLOUD_REGISTER_POINT_STRUCT_X(type, name, tag) \
81 ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_Y
82#define POINT_CLOUD_REGISTER_POINT_STRUCT_Y(type, name, tag) \
83 ((type, name, tag)) POINT_CLOUD_REGISTER_POINT_STRUCT_X
84#define POINT_CLOUD_REGISTER_POINT_STRUCT_X0
85#define POINT_CLOUD_REGISTER_POINT_STRUCT_Y0
86
87namespace pcl
88{
89 namespace traits
90 {
91 template<typename T> inline
92 std::enable_if_t<!std::is_array<T>::value>
93 plus (T &l, const T &r)
94 {
95 l += r;
96 }
97
98 template<typename T> inline
99 std::enable_if_t<std::is_array<T>::value>
100 plus (std::remove_const_t<T> &l, const T &r)
101 {
102 using type = std::remove_all_extents_t<T>;
103 static const std::uint32_t count = sizeof (T) / sizeof (type);
104 for (std::uint32_t i = 0; i < count; ++i)
105 l[i] += r[i];
106 }
107
108 template<typename T1, typename T2> inline
109 std::enable_if_t<!std::is_array<T1>::value>
110 plusscalar (T1 &p, const T2 &scalar)
111 {
112 p += scalar;
113 }
114
115 template<typename T1, typename T2> inline
116 std::enable_if_t<std::is_array<T1>::value>
117 plusscalar (T1 &p, const T2 &scalar)
118 {
119 using type = std::remove_all_extents_t<T1>;
120 static const std::uint32_t count = sizeof (T1) / sizeof (type);
121 for (std::uint32_t i = 0; i < count; ++i)
122 p[i] += scalar;
123 }
124
125 template<typename T> inline
126 std::enable_if_t<!std::is_array<T>::value>
127 minus (T &l, const T &r)
128 {
129 l -= r;
130 }
131
132 template<typename T> inline
133 std::enable_if_t<std::is_array<T>::value>
134 minus (std::remove_const_t<T> &l, const T &r)
135 {
136 using type = std::remove_all_extents_t<T>;
137 static const std::uint32_t count = sizeof (T) / sizeof (type);
138 for (std::uint32_t i = 0; i < count; ++i)
139 l[i] -= r[i];
140 }
141
142 template<typename T1, typename T2> inline
143 std::enable_if_t<!std::is_array<T1>::value>
144 minusscalar (T1 &p, const T2 &scalar)
145 {
146 p -= scalar;
147 }
148
149 template<typename T1, typename T2> inline
150 std::enable_if_t<std::is_array<T1>::value>
151 minusscalar (T1 &p, const T2 &scalar)
152 {
153 using type = std::remove_all_extents_t<T1>;
154 static const std::uint32_t count = sizeof (T1) / sizeof (type);
155 for (std::uint32_t i = 0; i < count; ++i)
156 p[i] -= scalar;
157 }
158
159 template<typename T1, typename T2> inline
160 std::enable_if_t<!std::is_array<T1>::value>
161 mulscalar (T1 &p, const T2 &scalar)
162 {
163 p *= scalar;
164 }
165
166 template<typename T1, typename T2> inline
167 std::enable_if_t<std::is_array<T1>::value>
168 mulscalar (T1 &p, const T2 &scalar)
169 {
170 using type = std::remove_all_extents_t<T1>;
171 static const std::uint32_t count = sizeof (T1) / sizeof (type);
172 for (std::uint32_t i = 0; i < count; ++i)
173 p[i] *= scalar;
174 }
175
176 template<typename T1, typename T2> inline
177 std::enable_if_t<!std::is_array<T1>::value>
178 divscalar (T1 &p, const T2 &scalar)
179 {
180 p /= scalar;
181 }
182
183 template<typename T1, typename T2> inline
184 std::enable_if_t<std::is_array<T1>::value>
185 divscalar (T1 &p, const T2 &scalar)
186 {
187 using type = std::remove_all_extents_t<T1>;
188 static const std::uint32_t count = sizeof (T1) / sizeof (type);
189 for (std::uint32_t i = 0; i < count; ++i)
190 p[i] /= scalar;
191 }
192
193 template<typename NoArrayT, typename ScalarT> inline
194 std::enable_if_t<!std::is_array<NoArrayT>::value>
195 divscalar2 (NoArrayT &p, const ScalarT &scalar)
196 {
197 p = scalar / p;
198 }
199
200 template<typename ArrayT, typename ScalarT> inline
201 std::enable_if_t<std::is_array<ArrayT>::value>
202 divscalar2 (ArrayT &p, const ScalarT &scalar)
203 {
204 using type = std::remove_all_extents_t<ArrayT>;
205 static const std::uint32_t count = sizeof (ArrayT) / sizeof (type);
206 for (std::uint32_t i = 0; i < count; ++i)
207 p[i] = scalar / p[i];
208 }
209 }
210}
211
212// Point operators
213#define PCL_PLUSEQ_POINT_TAG(r, data, elem) \
214 pcl::traits::plus (lhs.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
215 rhs.BOOST_PP_TUPLE_ELEM(3, 1, elem));
216 /***/
217
218#define PCL_PLUSEQSC_POINT_TAG(r, data, elem) \
219 pcl::traits::plusscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
220 scalar);
221 /***/
222 //p.BOOST_PP_TUPLE_ELEM(3, 1, elem) += scalar;
223
224#define PCL_MINUSEQ_POINT_TAG(r, data, elem) \
225 pcl::traits::minus (lhs.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
226 rhs.BOOST_PP_TUPLE_ELEM(3, 1, elem));
227 /***/
228
229#define PCL_MINUSEQSC_POINT_TAG(r, data, elem) \
230 pcl::traits::minusscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
231 scalar);
232 /***/
233 //p.BOOST_PP_TUPLE_ELEM(3, 1, elem) -= scalar;
234
235#define PCL_MULEQSC_POINT_TAG(r, data, elem) \
236 pcl::traits::mulscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
237 scalar);
238 /***/
239
240#define PCL_DIVEQSC_POINT_TAG(r, data, elem) \
241 pcl::traits::divscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
242 scalar);
243 /***/
244
245#define PCL_DIVEQSC2_POINT_TAG(r, data, elem) \
246 pcl::traits::divscalar2 (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
247 scalar);
248 /***/
249
250// Construct type traits given full sequence of (type, name, tag) triples
251// BOOST_MPL_ASSERT_MSG(std::is_pod<name>::value,
252// REGISTERED_POINT_TYPE_MUST_BE_PLAIN_OLD_DATA, (name));
253#define POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, seq) \
254 namespace pcl \
255 { \
256 namespace fields \
257 { \
258 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_TAG, name, seq) \
259 } \
260 namespace traits \
261 { \
262 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_NAME, name, seq) \
263 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_OFFSET, name, seq) \
264 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_DATATYPE, name, seq) \
265 POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, POINT_CLOUD_EXTRACT_TAGS(seq)) \
266 } \
267 namespace common \
268 { \
269 inline const name& \
270 operator+= (name& lhs, const name& rhs) \
271 { \
272 BOOST_PP_SEQ_FOR_EACH(PCL_PLUSEQ_POINT_TAG, _, seq) \
273 return (lhs); \
274 } \
275 inline const name& \
276 operator+= (name& p, const float& scalar) \
277 { \
278 BOOST_PP_SEQ_FOR_EACH(PCL_PLUSEQSC_POINT_TAG, _, seq) \
279 return (p); \
280 } \
281 inline const name operator+ (const name& lhs, const name& rhs) \
282 { name result = lhs; result += rhs; return (result); } \
283 inline const name operator+ (const float& scalar, const name& p) \
284 { name result = p; result += scalar; return (result); } \
285 inline const name operator+ (const name& p, const float& scalar) \
286 { name result = p; result += scalar; return (result); } \
287 inline const name& \
288 operator*= (name& p, const float& scalar) \
289 { \
290 BOOST_PP_SEQ_FOR_EACH(PCL_MULEQSC_POINT_TAG, _, seq) \
291 return (p); \
292 } \
293 inline const name operator* (const float& scalar, const name& p) \
294 { name result = p; result *= scalar; return (result); } \
295 inline const name operator* (const name& p, const float& scalar) \
296 { name result = p; result *= scalar; return (result); } \
297 inline const name& \
298 operator-= (name& lhs, const name& rhs) \
299 { \
300 BOOST_PP_SEQ_FOR_EACH(PCL_MINUSEQ_POINT_TAG, _, seq) \
301 return (lhs); \
302 } \
303 inline const name& \
304 operator-= (name& p, const float& scalar) \
305 { \
306 BOOST_PP_SEQ_FOR_EACH(PCL_MINUSEQSC_POINT_TAG, _, seq) \
307 return (p); \
308 } \
309 inline const name operator- (const name& lhs, const name& rhs) \
310 { name result = lhs; result -= rhs; return (result); } \
311 inline const name operator- (const float& scalar, const name& p) \
312 { name result = p; result *= -1.0f; result += scalar; return (result); } \
313 inline const name operator- (const name& p, const float& scalar) \
314 { name result = p; result -= scalar; return (result); } \
315 inline const name& \
316 operator/= (name& p, const float& scalar) \
317 { \
318 BOOST_PP_SEQ_FOR_EACH(PCL_DIVEQSC_POINT_TAG, _, seq) \
319 return (p); \
320 } \
321 inline const name operator/ (const float& scalar, const name& p_in) \
322 { name p = p_in; BOOST_PP_SEQ_FOR_EACH(PCL_DIVEQSC2_POINT_TAG, _, seq) \
323 return (p); } \
324 inline const name operator/ (const name& p, const float& scalar) \
325 { name result = p; result /= scalar; return (result); } \
326 } \
327 }
328 /***/
329
330#define POINT_CLOUD_REGISTER_FIELD_TAG(r, name, elem) \
331 struct BOOST_PP_TUPLE_ELEM(3, 2, elem); \
332 /***/
333
334#define POINT_CLOUD_TAG_OP(s, data, elem) pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)
335
336#define POINT_CLOUD_EXTRACT_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_TAG_OP, _, seq)
337
338#if defined _MSC_VER
339 #pragma warning (pop)
340#endif
std::enable_if_t<!std::is_array< T1 >::value > mulscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T >::value > plus(T &l, const T &r)
std::enable_if_t<!std::is_array< NoArrayT >::value > divscalar2(NoArrayT &p, const ScalarT &scalar)
std::enable_if_t<!std::is_array< T >::value > minus(T &l, const T &r)
std::enable_if_t<!std::is_array< T1 >::value > divscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T1 >::value > plusscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T1 >::value > minusscalar(T1 &p, const T2 &scalar)