Point Cloud Library (PCL)  1.12.0
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  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
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< 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)