Main MRPT website > C++ reference
MRPT logo
CPointCloudColoured.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 
29 #ifndef opengl_CPointCloudColoured_H
30 #define opengl_CPointCloudColoured_H
31 
35 #include <mrpt/utils/adapters.h>
36 
37 namespace mrpt
38 {
39  namespace opengl
40  {
42 
43  // This must be added to any CSerializable derived class:
45 
46 
47  /** A cloud of points, each one with an individual colour (R,G,B). The alpha component is shared by all the points and is stored in the base member m_color_A.
48  *
49  * To load from a points-map, CPointCloudColoured::loadFromPointsMap().
50  *
51  * This class uses smart optimizations while rendering to efficiently draw clouds of millions of points,
52  * as described in this page: http://www.mrpt.org/Efficiently_rendering_point_clouds_of_millions_of_points
53  *
54  * \sa opengl::COpenGLScene, opengl::CPointCloud
55  *
56  * <div align="center">
57  * <table border="0" cellspan="4" cellspacing="4" style="border-width: 1px; border-style: solid;">
58  * <tr> <td> mrpt::opengl::CPointCloudColoured </td> <td> \image html preview_CPointCloudColoured.png </td> </tr>
59  * </table>
60  * </div>
61  *
62  * \ingroup mrpt_opengl_grp
63  */
65  public CRenderizable,
67  public mrpt::utils::PLY_Importer,
68  public mrpt::utils::PLY_Exporter
69  {
70  DEFINE_SERIALIZABLE( CPointCloudColoured )
71 
72  public:
73  struct TPointColour
74  {
75  inline TPointColour() { }
76  inline TPointColour(float _x,float _y,float _z,float _R,float _G,float _B ) : x(_x),y(_y),z(_z),R(_R),G(_G),B(_B) { }
77  float x,y,z,R,G,B; // Float is precission enough for rendering
78  };
79 
80  private:
81  typedef std::vector<TPointColour> TListPointColour;
82  TListPointColour m_points;
83 
86  inline iterator begin() { return m_points.begin(); }
87  inline const_iterator begin() const { return m_points.begin(); }
88  inline iterator end() { return m_points.end(); }
89  inline const_iterator end() const { return m_points.end(); }
90 
91 
92  float m_pointSize; //!< By default is 1.0
93  bool m_pointSmooth; //!< Default: false
94  mutable volatile size_t m_last_rendered_count, m_last_rendered_count_ongoing;
95 
96  /** Constructor
97  */
99  m_points(),
100  m_pointSize(1),
101  m_pointSmooth(false),
102  m_last_rendered_count(0),
103  m_last_rendered_count_ongoing(0)
104  {
105  }
106  /** Private, virtual destructor: only can be deleted from smart pointers */
107  virtual ~CPointCloudColoured() { }
108 
109  void markAllPointsAsNew(); //!< Do needed internal work if all points are new (octree rebuilt,...)
110 
111  public:
112 
113  /** @name Read/Write of the list of points to render
114  @{ */
115 
116  /** Inserts a new point into the point cloud. */
117  void push_back(float x,float y,float z, float R, float G, float B);
118 
119  /** Set the number of points, with undefined contents */
120  inline void resize(size_t N) { m_points.resize(N); markAllPointsAsNew(); }
121 
122  /** Like STL std::vector's reserve */
123  inline void reserve(size_t N) { m_points.reserve(N); }
124 
125  /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
126  inline const TPointColour &operator [](size_t i) const {
127 #ifdef _DEBUG
128  ASSERT_BELOW_(i,size())
129 #endif
130  return m_points[i];
131  }
132 
133  /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
134  inline const TPointColour &getPoint(size_t i) const {
135 #ifdef _DEBUG
136  ASSERT_BELOW_(i,size())
137 #endif
138  return m_points[i];
139  }
140 
141  /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
142  inline mrpt::math::TPoint3Df getPointf(size_t i) const {
143 #ifdef _DEBUG
144  ASSERT_BELOW_(i,size())
145 #endif
146  return mrpt::math::TPoint3Df(m_points[i].x,m_points[i].y,m_points[i].z);
147  }
148 
149  /** Write an individual point (checks for "i" in the valid range only in Debug). */
150  void setPoint(size_t i, const TPointColour &p );
151 
152  /** Like \a setPoint() but does not check for index out of bounds */
153  inline void setPoint_fast(const size_t i, const TPointColour &p ) {
154  m_points[i] = p;
155  markAllPointsAsNew();
156  }
157 
158  /** Like \a setPoint() but does not check for index out of bounds */
159  inline void setPoint_fast(const size_t i, const float x,const float y, const float z ) {
160  TPointColour &p = m_points[i];
161  p.x=x; p.y=y; p.z=z;
162  markAllPointsAsNew();
163  }
164 
165  /** Like \c setPointColor but without checking for out-of-index erors */
166  inline void setPointColor_fast(size_t index,float R, float G, float B)
167  {
168  m_points[index].R=R;
169  m_points[index].G=G;
170  m_points[index].B=B;
171  }
172  /** Like \c getPointColor but without checking for out-of-index erors */
173  inline void getPointColor_fast( size_t index, float &R, float &G, float &B ) const
174  {
175  R = m_points[index].R;
176  G = m_points[index].G;
177  B = m_points[index].B;
178  }
179 
180  inline size_t size() const { return m_points.size(); } //!< Return the number of points
181 
182  inline void clear() { m_points.clear(); markAllPointsAsNew(); } //!< Erase all the points
183 
184  /** Load the points from any other point map class supported by the adapter mrpt::utils::PointCloudAdapter. */
185  template <class POINTSMAP>
186  void loadFromPointsMap( const POINTSMAP *themap);
187  // Must be implemented at the end of the header.
188 
189  /** Get the number of elements actually rendered in the last render event. */
190  size_t getActuallyRendered() const { return m_last_rendered_count; }
191 
192  /** @} */
193 
194 
195  /** @name Modify the appearance of the rendered points
196  @{ */
197 
198  inline void setPointSize(float pointSize) { m_pointSize = pointSize; }
199  inline float getPointSize() const { return m_pointSize; }
200 
201  inline void enablePointSmooth(bool enable=true) { m_pointSmooth=enable; }
202  inline void disablePointSmooth() { m_pointSmooth=false; }
203  inline bool isPointSmoothEnabled() const { return m_pointSmooth; }
204 
205  /** @} */
206 
207 
208  /** Render */
209  void render() const;
210 
211  /** Render a subset of points (required by octree renderer) */
212  void render_subset(const bool all, const std::vector<size_t>& idxs, const float render_area_sqpixels ) const;
213 
214  protected:
215  /** @name PLY Import virtual methods to implement in base classes
216  @{ */
217  /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex */
218  virtual void PLY_import_set_vertex_count(const size_t N);
219  /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_face */
220  virtual void PLY_import_set_face_count(const size_t N) { }
221  /** In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point.
222  * \param pt_color Will be NULL if the loaded file does not provide color info.
223  */
224  virtual void PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::utils::TColorf *pt_color = NULL);
225  /** @} */
226 
227  /** @name PLY Export virtual methods to implement in base classes
228  @{ */
229 
230  /** In a base class, return the number of vertices */
231  virtual size_t PLY_export_get_vertex_count() const;
232 
233  /** In a base class, return the number of faces */
234  virtual size_t PLY_export_get_face_count() const { return 0; }
235 
236  /** In a base class, will be called after PLY_export_get_vertex_count() once for each exported point.
237  * \param pt_color Will be NULL if the loaded file does not provide color info.
238  */
239  virtual void PLY_export_get_vertex(
240  const size_t idx,
242  bool &pt_has_color,
243  mrpt::utils::TColorf &pt_color) const;
244 
245  /** @} */
246 
247 
248  };
249 
250  OPENGL_IMPEXP mrpt::utils::CStream& operator>>(mrpt::utils::CStream& in, CPointCloudColoured::TPointColour &o);
251  OPENGL_IMPEXP mrpt::utils::CStream& operator<<(mrpt::utils::CStream& out, const CPointCloudColoured::TPointColour &o);
252 
253  } // end namespace
254 
255  namespace utils
256  {
257  using namespace mrpt::opengl;
258 
259  // Specialization must occur in the same namespace
261  }
262 
263  namespace utils
264  {
265  /** Specialization mrpt::utils::PointCloudAdapter<mrpt::opengl::CPointCloudColoured> \ingroup mrpt_adapters_grp*/
266  template <>
268  {
269  private:
271  public:
272  typedef float coords_t; //!< The type of each point XYZ coordinates
273  static const int HAS_RGB = 1; //!< Has any color RGB info?
274  static const int HAS_RGBf = 1; //!< Has native RGB info (as floats)?
275  static const int HAS_RGBu8 = 0; //!< Has native RGB info (as uint8_t)?
276 
277  /** Constructor (accept a const ref for convenience) */
278  inline PointCloudAdapter(const mrpt::opengl::CPointCloudColoured &obj) : m_obj(*const_cast<mrpt::opengl::CPointCloudColoured*>(&obj)) { }
279  /** Get number of points */
280  inline size_t size() const { return m_obj.size(); }
281  /** Set number of points (to uninitialized values) */
282  inline void resize(const size_t N) { m_obj.resize(N); }
283 
284  /** Get XYZ coordinates of i'th point */
285  template <typename T>
286  inline void getPointXYZ(const size_t idx, T &x,T &y, T &z) const {
288  x=pc.x;
289  y=pc.y;
290  z=pc.z;
291  }
292  /** Set XYZ coordinates of i'th point */
293  inline void setPointXYZ(const size_t idx, const coords_t x,const coords_t y, const coords_t z) {
294  m_obj.setPoint_fast(idx, x,y,z);
295  }
296 
297  /** Get XYZ_RGBf coordinates of i'th point */
298  template <typename T>
299  inline void getPointXYZ_RGBf(const size_t idx, T &x,T &y, T &z, float &r,float &g,float &b) const {
301  x=pc.x; y=pc.y; z=pc.z;
302  r=pc.R; g=pc.G; b=pc.B;
303  }
304  /** Set XYZ_RGBf coordinates of i'th point */
305  inline void setPointXYZ_RGBf(const size_t idx, const coords_t x,const coords_t y, const coords_t z, const float r,const float g,const float b) {
306  m_obj.setPoint_fast(idx, mrpt::opengl::CPointCloudColoured::TPointColour(x,y,z,r,g,b) );
307  }
308 
309  /** Get XYZ_RGBu8 coordinates of i'th point */
310  template <typename T>
311  inline void getPointXYZ_RGBu8(const size_t idx, T &x,T &y, T &z, uint8_t &r,uint8_t &g,uint8_t &b) const {
313  x=pc.x; y=pc.y; z=pc.z;
314  r=pc.R*255; g=pc.G*255; b=pc.B*255;
315  }
316  /** Set XYZ_RGBu8 coordinates of i'th point */
317  inline void setPointXYZ_RGBu8(const size_t idx, const coords_t x,const coords_t y, const coords_t z, const uint8_t r,const uint8_t g,const uint8_t b) {
318  m_obj.setPoint_fast(idx, mrpt::opengl::CPointCloudColoured::TPointColour(x,y,z,r/255.f,g/255.f,b/255.f) );
319  }
320 
321  /** Get RGBf color of i'th point */
322  inline void getPointRGBf(const size_t idx, float &r,float &g,float &b) const { m_obj.getPointColor_fast(idx,r,g,b); }
323  /** Set XYZ_RGBf coordinates of i'th point */
324  inline void setPointRGBf(const size_t idx, const float r,const float g,const float b) { m_obj.setPointColor_fast(idx,r,g,b); }
325 
326  /** Get RGBu8 color of i'th point */
327  inline void getPointRGBu8(const size_t idx, uint8_t &r,uint8_t &g,uint8_t &b) const {
328  float R,G,B;
329  m_obj.getPointColor_fast(idx,R,G,B);
330  r=R*255; g=G*255; b=B*255;
331  }
332  /** Set RGBu8 coordinates of i'th point */
333  inline void setPointRGBu8(const size_t idx,const uint8_t r,const uint8_t g,const uint8_t b) {
334  m_obj.setPointColor_fast(idx,r/255.f,g/255.f,b/255.f);
335  }
336 
337  }; // end of PointCloudAdapter<mrpt::opengl::CPointCloudColoured>
338 
339  }
340 
341  namespace opengl
342  {
343  // After declaring the adapter we can here implement this method:
344  template <class POINTSMAP>
345  void CPointCloudColoured::loadFromPointsMap( const POINTSMAP *themap)
346  {
347  mrpt::utils::PointCloudAdapter<CPointCloudColoured> pc_dst(*this);
348  const mrpt::utils::PointCloudAdapter<POINTSMAP> pc_src(*themap);
349  const size_t N=pc_src.size();
350  pc_dst.resize(N);
351  for (size_t i=0;i<N;i++)
352  {
353  float x,y,z,r,g,b;
354  pc_src.getPointXYZ_RGBf(i,x,y,z,r,g,b);
355  pc_dst.setPointXYZ_RGBf(i,x,y,z,r,g,b);
356  }
357  }
358  }
359 
360 } // End of namespace
361 
362 
363 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013