Main MRPT website > C++ reference
MRPT logo
CPointCloud.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 
00029 #ifndef opengl_CPointCloud_H
00030 #define opengl_CPointCloud_H
00031 
00032 #include <mrpt/opengl/CRenderizable.h>
00033 #include <mrpt/opengl/COctreePointRenderer.h>
00034 #include <mrpt/utils/PLY_import_export.h>
00035 #include <mrpt/utils/adapters.h>
00036 
00037 namespace mrpt
00038 {
00039         namespace opengl
00040         {
00041                 class OPENGL_IMPEXP CPointCloud;
00042 
00043                 // This must be added to any CSerializable derived class:
00044                 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE( CPointCloud, CRenderizable, OPENGL_IMPEXP )
00045 
00046 
00047                 /** A cloud of points, all with the same color or each depending on its value along a particular coordinate axis.
00048                   *  This class is just an OpenGL representation of a point cloud. For operating with maps of points, see mrpt::slam::CPointsMap and derived classes.
00049                   *
00050                   *  To load from a points-map, CPointCloud::loadFromPointsMap().
00051                   *
00052                   *   This class uses smart optimizations while rendering to efficiently draw clouds of millions of points,
00053                   *   as described in this page: http://www.mrpt.org/Efficiently_rendering_point_clouds_of_millions_of_points
00054                   *
00055                   *  \sa opengl::CPlanarLaserScan, opengl::COpenGLScene, opengl::CPointCloudColoured, mrpt::slam::CPointsMap
00056                   *
00057                   *  <div align="center">
00058                   *  <table border="0" cellspan="4" cellspacing="4" style="border-width: 1px; border-style: solid;">
00059                   *   <tr> <td> mrpt::opengl::CPointCloud </td> <td> \image html preview_CPointCloud.png </td> </tr>
00060                   *  </table>
00061                   *  </div>
00062                   *
00063                   * \ingroup mrpt_opengl_grp
00064                   */
00065                 class OPENGL_IMPEXP CPointCloud :
00066                         public CRenderizable,
00067                         public COctreePointRenderer<CPointCloud>,
00068                         public mrpt::utils::PLY_Importer,
00069                         public mrpt::utils::PLY_Exporter
00070                 {
00071                         DEFINE_SERIALIZABLE( CPointCloud )
00072                 protected:
00073                         enum Axis { None=0, Z, Y, X} m_colorFromDepth;
00074                         std::vector<float>      m_xs,m_ys,m_zs;
00075                         float           m_pointSize; //!< By default is 1.0
00076                         bool                    m_pointSmooth; //!< Default: false
00077 
00078                         mutable volatile size_t m_last_rendered_count, m_last_rendered_count_ongoing;
00079 
00080                         void markAllPointsAsNew(); //!< Do needed internal work if all points are new (octree rebuilt,...)
00081 
00082                 protected:
00083                         /** @name PLY Import virtual methods to implement in base classes
00084                             @{ */
00085                         /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex */
00086                         virtual void PLY_import_set_vertex_count(const size_t N);
00087 
00088                         /** In a base class, reserve memory to prepare subsequent calls to PLY_import_set_face */
00089                         virtual void PLY_import_set_face_count(const size_t N) {  }
00090 
00091                         /** In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point.
00092                           *  \param pt_color Will be NULL if the loaded file does not provide color info.
00093                           */
00094                         virtual void PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::utils::TColorf *pt_color = NULL);
00095                         /** @} */
00096 
00097                         /** @name PLY Export virtual methods to implement in base classes
00098                             @{ */
00099 
00100                         /** In a base class, return the number of vertices */
00101                         virtual size_t PLY_export_get_vertex_count() const;
00102 
00103                         /** In a base class, return the number of faces */
00104                         virtual size_t PLY_export_get_face_count() const { return 0; }
00105 
00106                         /** In a base class, will be called after PLY_export_get_vertex_count() once for each exported point.
00107                           *  \param pt_color Will be NULL if the loaded file does not provide color info.
00108                           */
00109                         virtual void PLY_export_get_vertex(
00110                                 const size_t idx,
00111                                 mrpt::math::TPoint3Df &pt,
00112                                 bool &pt_has_color,
00113                                 mrpt::utils::TColorf &pt_color) const;
00114 
00115                         /** @} */
00116 
00117 
00118                 public:
00119 
00120                         /** @name Read/Write of the list of points to render
00121                             @{ */
00122 
00123                         inline size_t size() const { return m_xs.size(); }
00124 
00125                         /** Set the number of points (with contents undefined) */
00126                         inline void resize(size_t N) { m_xs.resize(N); m_ys.resize(N); m_zs.resize(N); m_minmax_valid = false; markAllPointsAsNew(); }
00127 
00128                         /** Like STL std::vector's reserve */
00129                         inline void reserve(size_t N) { m_xs.reserve(N); m_ys.reserve(N); m_zs.reserve(N);  }
00130 
00131                         /** Set the list of (X,Y,Z) point coordinates, all at once, from three vectors with their coordinates */
00132                         void setAllPoints(const std::vector<float> &x, const std::vector<float> &y, const std::vector<float> &z)
00133                         {
00134                                 m_xs = x;
00135                                 m_ys = y;
00136                                 m_zs = z;
00137                                 m_minmax_valid = false;
00138                                 markAllPointsAsNew();
00139                         }
00140 
00141                         /** Set the list of (X,Y,Z) point coordinates, DESTROYING the contents of the input vectors (via swap) */
00142                         void setAllPointsFast(std::vector<float> &x, std::vector<float> &y, std::vector<float> &z)
00143                         {
00144                                 this->clear();
00145                                 m_xs.swap(x);
00146                                 m_ys.swap(y);
00147                                 m_zs.swap(z);
00148                                 m_minmax_valid = false;
00149                                 markAllPointsAsNew();
00150                         }
00151 
00152                         inline const std::vector<float> & getArrayX() const {return m_xs;} //!< Get a const reference to the internal array of X coordinates
00153                         inline const std::vector<float> & getArrayY() const {return m_ys;} //!< Get a const reference to the internal array of Y coordinates
00154                         inline const std::vector<float> & getArrayZ() const {return m_zs;} //!< Get a const reference to the internal array of Z coordinates
00155 
00156                         void clear();   //!< Empty the list of points.
00157 
00158                         /** Adds a new point to the cloud */
00159                         void insertPoint( float x,float y, float z );
00160 
00161                         /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
00162                         inline mrpt::math::TPoint3D  operator [](size_t i) const {
00163 #ifdef _DEBUG
00164                                 ASSERT_BELOW_(i,size())
00165 #endif
00166                                 return mrpt::math::TPoint3D(m_xs[i],m_ys[i],m_zs[i]);
00167                         }
00168 
00169                         /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
00170                         inline mrpt::math::TPoint3D getPoint(size_t i) const {
00171 #ifdef _DEBUG
00172                                 ASSERT_BELOW_(i,size())
00173 #endif
00174                                 return mrpt::math::TPoint3D(m_xs[i],m_ys[i],m_zs[i]);
00175                         }
00176 
00177                         /** Read access to each individual point (checks for "i" in the valid range only in Debug). */
00178                         inline mrpt::math::TPoint3Df getPointf(size_t i) const {
00179 #ifdef _DEBUG
00180                                 ASSERT_BELOW_(i,size())
00181 #endif
00182                                 return mrpt::math::TPoint3Df(m_xs[i],m_ys[i],m_zs[i]);
00183                         }
00184 
00185                         /** Write an individual point (checks for "i" in the valid range only in Debug). */
00186                         void setPoint(size_t i, const float x,const float y, const float z);
00187 
00188                         /** Write an individual point (without checking validity of the index). */
00189                         inline void setPoint_fast(size_t i, const float x,const float y, const float z)
00190                         {
00191                                 m_xs[i] = x;
00192                                 m_ys[i] = y;
00193                                 m_zs[i] = z;
00194                                 m_minmax_valid = false;
00195                                 markAllPointsAsNew();
00196                         }
00197 
00198 
00199                         /** Load the points from any other point map class supported by the adapter mrpt::utils::PointCloudAdapter. */
00200                         template <class POINTSMAP>
00201                         void loadFromPointsMap( const POINTSMAP *themap);
00202                         // Must be implemented at the end of the header.
00203 
00204                         /** Load the points from a list of TPoint3D
00205                           */
00206                         template<class LISTOFPOINTS> void  loadFromPointsList( LISTOFPOINTS &pointsList)
00207                         {
00208                                 MRPT_START
00209                                 const size_t N = pointsList.size();
00210 
00211                                 m_xs.resize(N);
00212                                 m_ys.resize(N);
00213                                 m_zs.resize(N);
00214 
00215                                 size_t idx;
00216                                 typename LISTOFPOINTS::const_iterator it;
00217                                 for ( idx=0,it=pointsList.begin() ; idx<N ; ++idx,++it)
00218                                 {
00219                                         m_xs[idx]=it->x;
00220                                         m_ys[idx]=it->y;
00221                                         m_zs[idx]=it->z;
00222                                 }
00223                                 markAllPointsAsNew();
00224                                 MRPT_END
00225                         }
00226 
00227                         /** Get the number of elements actually rendered in the last render event. */
00228                         size_t getActuallyRendered() const { return m_last_rendered_count; }
00229 
00230                         /** @} */
00231 
00232 
00233                         /** @name Modify the appearance of the rendered points
00234                             @{ */
00235                         inline void enableColorFromX(bool v=true) { m_colorFromDepth = v ? CPointCloud::X : CPointCloud::None;  }
00236                         inline void enableColorFromY(bool v=true) { m_colorFromDepth = v ? CPointCloud::Y : CPointCloud::None; }
00237                         inline void enableColorFromZ(bool v=true) { m_colorFromDepth = v ? CPointCloud::Z : CPointCloud::None; }
00238 
00239                         inline void setPointSize(float p) { m_pointSize=p; }  //!< By default is 1.0
00240                         inline float getPointSize() const { return m_pointSize; }
00241 
00242                         inline void enablePointSmooth(bool enable=true) { m_pointSmooth=enable; }
00243                         inline void disablePointSmooth() { m_pointSmooth=false; }
00244                         inline bool isPointSmoothEnabled() const { return m_pointSmooth; }
00245 
00246                         /** Sets the colors used as extremes when colorFromDepth is enabled. */
00247                         void  setGradientColors( const mrpt::utils::TColorf &colorMin, const mrpt::utils::TColorf &colorMax );
00248 
00249                         /** @} */
00250 
00251                         /** Render */
00252                         void  render() const;
00253 
00254 
00255                         /** Render a subset of points (required by octree renderer) */
00256                         void  render_subset(const bool all, const std::vector<size_t>& idxs, const float render_area_sqpixels ) const;
00257 
00258                 private:
00259                         /** Constructor */
00260                         CPointCloud();
00261 
00262                         /** Private, virtual destructor: only can be deleted from smart pointers */
00263                         virtual ~CPointCloud() { }
00264 
00265                         mutable float  m_min, m_max,m_max_m_min,m_max_m_min_inv;        //!< Buffer for min/max coords when m_colorFromDepth is true.
00266                         mutable mrpt::utils::TColorf m_col_slop,m_col_slop_inv; //!< Color linear function slope
00267                         mutable bool   m_minmax_valid;
00268 
00269                         mrpt::utils::TColorf    m_colorFromDepth_min, m_colorFromDepth_max;     //!< The colors used to interpolate when m_colorFromDepth is true.
00270 
00271                         inline void internal_render_one_point(size_t i) const;
00272                 };
00273 
00274         } // end namespace
00275 
00276 
00277         namespace utils
00278         {
00279                 /** Specialization mrpt::utils::PointCloudAdapter<mrpt::opengl::CPointCloud> \ingroup mrpt_adapters_grp */
00280                 template <>
00281                 class PointCloudAdapter<mrpt::opengl::CPointCloud> : public detail::PointCloudAdapterHelperNoRGB<mrpt::opengl::CPointCloud,float>
00282                 {
00283                 private:
00284                         mrpt::opengl::CPointCloud &m_obj;
00285                 public:
00286                         typedef float  coords_t;         //!< The type of each point XYZ coordinates
00287                         static const int HAS_RGB   = 0;  //!< Has any color RGB info?
00288                         static const int HAS_RGBf  = 0;  //!< Has native RGB info (as floats)?
00289                         static const int HAS_RGBu8 = 0;  //!< Has native RGB info (as uint8_t)?
00290 
00291                         /** Constructor (accept a const ref for convenience) */
00292                         inline PointCloudAdapter(const mrpt::opengl::CPointCloud &obj) : m_obj(*const_cast<mrpt::opengl::CPointCloud*>(&obj)) { }
00293                         /** Get number of points */
00294                         inline size_t size() const { return m_obj.size(); }
00295                         /** Set number of points (to uninitialized values) */
00296                         inline void resize(const size_t N) { m_obj.resize(N); }
00297 
00298                         /** Get XYZ coordinates of i'th point */
00299                         template <typename T>
00300                         inline void getPointXYZ(const size_t idx, T &x,T &y, T &z) const {
00301                                 x=m_obj.getArrayX()[idx];
00302                                 y=m_obj.getArrayY()[idx];
00303                                 z=m_obj.getArrayZ()[idx];
00304                         }
00305                         /** Set XYZ coordinates of i'th point */
00306                         inline void setPointXYZ(const size_t idx, const coords_t x,const coords_t y, const coords_t z) {
00307                                 m_obj.setPoint_fast(idx,x,y,z);
00308                         }
00309 
00310                 }; // end of PointCloudAdapter<mrpt::opengl::CPointCloud>
00311         }
00312 
00313         namespace opengl
00314         {
00315                 // After declaring the adapter we can here implement this method:
00316                 template <class POINTSMAP>
00317                 void CPointCloud::loadFromPointsMap( const POINTSMAP *themap)
00318                 {
00319                         mrpt::utils::PointCloudAdapter<CPointCloud>     pc_dst(*this);
00320                         const mrpt::utils::PointCloudAdapter<POINTSMAP> pc_src(*themap);
00321                         const size_t N=pc_src.size();
00322                         pc_dst.resize(N);
00323                         for (size_t i=0;i<N;i++)
00324                         {
00325                                 float x,y,z;
00326                                 pc_src.getPointXYZ(i,x,y,z);
00327                                 pc_dst.setPointXYZ(i,x,y,z);
00328                         }
00329                 }
00330         }
00331 
00332 } // End of namespace
00333 
00334 
00335 #endif



Page generated by Doxygen 1.7.4 for MRPT 0.9.5 SVN:2717 at Sun Oct 16 16:08:03 PDT 2011 Hosted on:
SourceForge.net Logo