Point Cloud Library (PCL) 1.12.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}
194
195// Point operators
196#define PCL_PLUSEQ_POINT_TAG(r, data, elem) \
197 pcl::traits::plus (lhs.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
198 rhs.BOOST_PP_TUPLE_ELEM(3, 1, elem));
199 /***/
200
201#define PCL_PLUSEQSC_POINT_TAG(r, data, elem) \
202 pcl::traits::plusscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
203 scalar);
204 /***/
205 //p.BOOST_PP_TUPLE_ELEM(3, 1, elem) += scalar;
206
207#define PCL_MINUSEQ_POINT_TAG(r, data, elem) \
208 pcl::traits::minus (lhs.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
209 rhs.BOOST_PP_TUPLE_ELEM(3, 1, elem));
210 /***/
211
212#define PCL_MINUSEQSC_POINT_TAG(r, data, elem) \
213 pcl::traits::minusscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
214 scalar);
215 /***/
216 //p.BOOST_PP_TUPLE_ELEM(3, 1, elem) -= scalar;
217
218#define PCL_MULEQSC_POINT_TAG(r, data, elem) \
219 pcl::traits::mulscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
220 scalar);
221 /***/
222
223#define PCL_DIVEQSC_POINT_TAG(r, data, elem) \
224 pcl::traits::divscalar (p.BOOST_PP_TUPLE_ELEM(3, 1, elem), \
225 scalar);
226 /***/
227
228// Construct type traits given full sequence of (type, name, tag) triples
229// BOOST_MPL_ASSERT_MSG(std::is_pod<name>::value,
230// REGISTERED_POINT_TYPE_MUST_BE_PLAIN_OLD_DATA, (name));
231#define POINT_CLOUD_REGISTER_POINT_STRUCT_I(name, seq) \
232 namespace pcl \
233 { \
234 namespace fields \
235 { \
236 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_TAG, name, seq) \
237 } \
238 namespace traits \
239 { \
240 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_NAME, name, seq) \
241 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_OFFSET, name, seq) \
242 BOOST_PP_SEQ_FOR_EACH(POINT_CLOUD_REGISTER_FIELD_DATATYPE, name, seq) \
243 POINT_CLOUD_REGISTER_POINT_FIELD_LIST(name, POINT_CLOUD_EXTRACT_TAGS(seq)) \
244 } \
245 namespace common \
246 { \
247 inline const name& \
248 operator+= (name& lhs, const name& rhs) \
249 { \
250 BOOST_PP_SEQ_FOR_EACH(PCL_PLUSEQ_POINT_TAG, _, seq) \
251 return (lhs); \
252 } \
253 inline const name& \
254 operator+= (name& p, const float& scalar) \
255 { \
256 BOOST_PP_SEQ_FOR_EACH(PCL_PLUSEQSC_POINT_TAG, _, seq) \
257 return (p); \
258 } \
259 inline const name operator+ (const name& lhs, const name& rhs) \
260 { name result = lhs; result += rhs; return (result); } \
261 inline const name operator+ (const float& scalar, const name& p) \
262 { name result = p; result += scalar; return (result); } \
263 inline const name operator+ (const name& p, const float& scalar) \
264 { name result = p; result += scalar; return (result); } \
265 inline const name& \
266 operator-= (name& lhs, const name& rhs) \
267 { \
268 BOOST_PP_SEQ_FOR_EACH(PCL_MINUSEQ_POINT_TAG, _, seq) \
269 return (lhs); \
270 } \
271 inline const name& \
272 operator-= (name& p, const float& scalar) \
273 { \
274 BOOST_PP_SEQ_FOR_EACH(PCL_MINUSEQSC_POINT_TAG, _, seq) \
275 return (p); \
276 } \
277 inline const name operator- (const name& lhs, const name& rhs) \
278 { name result = lhs; result -= rhs; return (result); } \
279 inline const name operator- (const float& scalar, const name& p) \
280 { name result = p; result -= scalar; return (result); } \
281 inline const name operator- (const name& p, const float& scalar) \
282 { name result = p; result -= scalar; return (result); } \
283 inline const name& \
284 operator*= (name& p, const float& scalar) \
285 { \
286 BOOST_PP_SEQ_FOR_EACH(PCL_MULEQSC_POINT_TAG, _, seq) \
287 return (p); \
288 } \
289 inline const name operator* (const float& scalar, const name& p) \
290 { name result = p; result *= scalar; return (result); } \
291 inline const name operator* (const name& p, const float& scalar) \
292 { name result = p; result *= scalar; return (result); } \
293 inline const name& \
294 operator/= (name& p, const float& scalar) \
295 { \
296 BOOST_PP_SEQ_FOR_EACH(PCL_DIVEQSC_POINT_TAG, _, seq) \
297 return (p); \
298 } \
299 inline const name operator/ (const float& scalar, const name& p) \
300 { name result = p; result /= scalar; return (result); } \
301 inline const name operator/ (const name& p, const float& scalar) \
302 { name result = p; result /= scalar; return (result); } \
303 } \
304 }
305 /***/
306
307#define POINT_CLOUD_REGISTER_FIELD_TAG(r, name, elem) \
308 struct BOOST_PP_TUPLE_ELEM(3, 2, elem); \
309 /***/
310
311#define POINT_CLOUD_TAG_OP(s, data, elem) pcl::fields::BOOST_PP_TUPLE_ELEM(3, 2, elem)
312
313#define POINT_CLOUD_EXTRACT_TAGS(seq) BOOST_PP_SEQ_TRANSFORM(POINT_CLOUD_TAG_OP, _, seq)
314
315#if defined _MSC_VER
316 #pragma warning (pop)
317#endif
Iterator class for point clouds with or without given indices.
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< 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)