Point Cloud Library (PCL)  1.14.0-dev
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 
87 namespace 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  constexpr 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  constexpr 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  constexpr 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  constexpr 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  constexpr 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  constexpr 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  constexpr 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 > plusscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T1 >::value > mulscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< T1 >::value > minusscalar(T1 &p, const T2 &scalar)
std::enable_if_t<!std::is_array< NoArrayT >::value > divscalar2(NoArrayT &p, const ScalarT &scalar)
std::enable_if_t<!std::is_array< T1 >::value > divscalar(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)