Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/visualization/include/pcl/visualization/pcl_plotter.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2011, Willow Garage, Inc.
00006  *  Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of the copyright holder(s) nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  */
00038 #ifndef PCL_VISUALUALIZATION_PCL_PLOTTER_H_
00039 #define PCL_VISUALUALIZATION_PCL_PLOTTER_H_
00040 
00041 #include <iostream>
00042 #include <vector>
00043 #include <utility>
00044 #include <cfloat>
00045 
00046 #include <pcl/visualization/common/common.h>
00047 #include <pcl/point_types.h>
00048 #include <pcl/correspondence.h>
00049 #include <pcl/point_cloud.h>
00050 #include <pcl/common/io.h>
00051 
00052 class PCLVisualizerInteractor;
00053 template <typename T> class vtkSmartPointer;
00054 class vtkRenderWindowInteractor;
00055 class vtkContextView;
00056 class vtkChartXY;
00057 class vtkColorSeries;
00058 
00059 #include <vtkCommand.h>
00060 #include <vtkChart.h>
00061 
00062 namespace pcl
00063 {
00064   namespace visualization
00065   {
00066     /** \brief PCL Plotter main class. Given point correspondences this class
00067       * can be used to plot the data one against the other and display it on the
00068       * screen. It also has methods for providing plot for important functions
00069       * like histogram etc. Important functions of PCLHistogramVisualizer are
00070       * redefined here so that this single class can take responsibility of all
00071       * plotting related functionalities.
00072       *
00073       * \author Kripasindhu Sarkar
00074       * \ingroup visualization
00075       */
00076     class PCL_EXPORTS PCLPlotter
00077     {
00078       public:
00079   
00080         /**\brief A representation of polynomial function. i'th element of the vector denotes the coefficient of x^i of the polynomial in variable x. 
00081          */
00082         typedef std::vector<double> PolynomialFunction;
00083         
00084         /**\brief A representation of rational function, defined as the ratio of two polynomial functions. pair::first denotes the numerator and pair::second denotes the denominator of the Rational function. 
00085          */
00086         typedef std::pair<PolynomialFunction, PolynomialFunction> RationalFunction;
00087         
00088         /** \brief PCL Plotter constructor.  
00089           * \param[in] name Name of the window
00090           */
00091         PCLPlotter (char const * name = "PCL Plotter");
00092 
00093         /** \brief Destructor. */
00094         ~PCLPlotter();
00095 
00096         /** \brief Adds a plot with correspondences in the arrays arrayX and arrayY
00097           * \param[in] array_X X coordinates of point correspondence array
00098           * \param[in] array_Y Y coordinates of point correspondence array
00099           * \param[in] size length of the array arrayX and arrayY
00100           * \param[in] name name of the plot which appears in the legend when toggled on
00101           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00102           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or NULL is passed) the plot is colored based on a color scheme 
00103           */
00104         void 
00105         addPlotData (double const *array_X, 
00106                      double const *array_Y, 
00107                      unsigned long size, 
00108                      char const * name = "Y Axis", 
00109                      int type  = vtkChart::LINE ,
00110                      char const *color=NULL);
00111   
00112         /** \brief Adds a plot with correspondences in vectors arrayX and arrayY. This is the vector version of the addPlotData function. 
00113           * \param[in] array_X X coordinates of point correspondence array
00114           * \param[in] array_Y Y coordinates of point correspondence array
00115           * \param[in] size length of the array arrayX and arrayY
00116           * \param[in] name name of the plot which appears in the legend when toggled on
00117           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00118           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or NULL is passed) the plot is colored based on a color scheme 
00119          */
00120         void 
00121         addPlotData (std::vector<double> const &array_X, 
00122                      std::vector<double>const &array_Y, 
00123                      char const * name = "Y Axis", 
00124                      int type = vtkChart::LINE,
00125                      std::vector<char> const &color = std::vector<char> ());
00126         
00127         /** \brief Adds a plot with correspondences in vector of pairs. The the first and second field of the pairs of the vector forms the correspondence. 
00128           * \param[in] name name of the plot which appears in the legend when toggled on
00129           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00130           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or NULL is passed) the plot is colored based on a color scheme 
00131           */
00132         void
00133         addPlotData (std::vector<std::pair<double, double> > const &plot_data, 
00134                     char const * name = "Y Axis",
00135                     int type = vtkChart::LINE,
00136                     std::vector<char> const &color = std::vector<char>());
00137         
00138         /** \brief Adds a plot based on the given polynomial function and the range in X axis. 
00139           * \param[in] p_function A polynomial function which is represented by a vector which stores the coefficients. See description on the  typedef.   
00140           * \param[in] x_min the left boundary of the range for displaying the plot
00141           * \param[in] x_max the right boundary of the range for displaying the plot
00142           * \param[in] name name of the plot which appears in the legend when toggled on
00143           * \param[in] num_points Number of points plotted to show the graph. More this number, more is the resolution.
00144           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00145           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or NULL is passed) the plot is colored based on a color scheme 
00146           */
00147         void
00148         addPlotData (PolynomialFunction const & p_function,
00149                      double x_min, double x_max,
00150                      char const *name = "Y Axis",
00151                      int num_points = 100,
00152                      int type = vtkChart::LINE,
00153                      std::vector<char> const &color = std::vector<char>());
00154         
00155         /** \brief Adds a plot based on the given rational function and the range in X axis. 
00156           * \param[in] r_function A rational function which is represented by the ratio of two polynomial functions. See description on the  typedef for more details.
00157           * \param[in] x_min the left boundary of the range for displaying the plot
00158           * \param[in] x_max the right boundary of the range for displaying the plot
00159           * \param[in] name name of the plot which appears in the legend when toggled on
00160           * \param[in] num_points Number of points plotted to show the graph. More this number, more is the resolution.
00161           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00162           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or NULL is passed) the plot is colored based on a color scheme 
00163           */
00164         void
00165         addPlotData (RationalFunction const & r_function,
00166                      double x_min, double x_max,
00167                      char const *name = "Y Axis",
00168                      int num_points = 100,
00169                      int type = vtkChart::LINE,
00170                      std::vector<char> const &color = std::vector<char>());
00171         
00172         /** \brief Adds a plot based on a user defined callback function representing the function to plot
00173           * \param[in] function a user defined callback function representing the relation y = function(x)
00174           * \param[in] x_min the left boundary of the range for displaying the plot
00175           * \param[in] x_max the right boundary of the range for displaying the plot
00176           * \param[in] name name of the plot which appears in the legend when toggled on
00177           * \param[in] num_points Number of points plotted to show the graph. More this number, more is the resolution.
00178           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00179           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or NULL is passed) the plot is colored based on a color scheme 
00180           */
00181         void
00182         addPlotData (double (*function)(double),
00183                      double x_min, double x_max,
00184                      char const *name = "Y Axis",
00185                      int num_points = 100,
00186                      int type = vtkChart::LINE,
00187                      std::vector<char> const &color = std::vector<char>());
00188         
00189         /** \brief Adds a plot based on a space/tab delimited table provided in a file
00190           * \param[in] filename name of the file containing the table. 1st column represents the values of X-Axis. Rest of the columns represent the corresponding values in Y-Axes. First row of the file is concidered for naming/labling of the plot. The plot-names should not contain any space in between.
00191           * \param[in] type type of the graph plotted. vtkChart::LINE for line plot, vtkChart::BAR for bar plot, and vtkChart::POINTS for a scattered point plot
00192           */
00193         void
00194         addPlotData (char const * filename,
00195                      int type = vtkChart::LINE);
00196                     
00197         /** \brief Bins the elements in vector data into nbins equally spaced containers and plots the resulted histogram 
00198           * \param[in] data the raw data 
00199           * \param[in] nbins the number of bins for the histogram
00200           * \param[in] name name of this histogram which will appear on legends if toggled on
00201           * \param[in] color a character array of 4 fields denoting the R,G,B and A component of the color of the plot ranging from 0 to 255. If this argument is not passed (or an empty vector is passed) the histogram is colored based on the current color scheme 
00202           */
00203         void
00204         addHistogramData (std::vector<double> const & data, 
00205                           int const nbins = 10, 
00206                           char const * name = "Histogram", 
00207                           std::vector<char> const &color = std::vector<char>());
00208         
00209         //##PCLHistogramVisulizer methods##
00210         /** \brief Add a histogram feature to screen as a separate window, from a cloud containing a single histogram.
00211           * \param[in] cloud the PointCloud dataset containing the histogram
00212           * \param[in] hsize the length of the histogram
00213           * \param[in] id the point cloud object id (default: cloud)
00214           * \param[in] win_width the width of the window
00215           * \param[in] win_height the height of the window
00216           */
00217         template <typename PointT> bool 
00218         addFeatureHistogram (const pcl::PointCloud<PointT> &cloud, 
00219                              int hsize, 
00220                              const std::string &id = "cloud", int win_width = 640, int win_height = 200);
00221         
00222         /** \brief Add a histogram feature to screen as a separate window from a cloud containing a single histogram.
00223           * \param[in] cloud the PointCloud dataset containing the histogram
00224           * \param[in] field_name the field name containing the histogram
00225           * \param[in] id the point cloud object id (default: cloud)
00226           * \param[in] win_width the width of the window
00227           * \param[in] win_height the height of the window
00228           */
00229         bool 
00230         addFeatureHistogram (const pcl::PCLPointCloud2 &cloud,
00231                              const std::string &field_name, 
00232                              const std::string &id = "cloud", int win_width = 640, int win_height = 200);
00233         
00234         /** \brief Add a histogram feature to screen as a separate window.
00235           * \param[in] cloud the PointCloud dataset containing the histogram
00236           * \param[in] field_name the field name containing the histogram
00237           * \param[in] index the point index to extract the histogram from
00238           * \param[in] id the point cloud object id (default: cloud)
00239           * \param[in] win_width the width of the window
00240           * \param[in] win_height the height of the window 
00241           */
00242         template <typename PointT> bool 
00243         addFeatureHistogram (const pcl::PointCloud<PointT> &cloud, 
00244                              const std::string &field_name, 
00245                              const int index,
00246                              const std::string &id = "cloud", int win_width = 640, int win_height = 200);
00247         
00248         /** \brief Add a histogram feature to screen as a separate window.
00249           * \param[in] cloud the PointCloud dataset containing the histogram
00250           * \param[in] field_name the field name containing the histogram
00251           * \param[in] index the point index to extract the histogram from
00252           * \param[in] id the point cloud object id (default: cloud)
00253           * \param[in] win_width the width of the window
00254           * \param[in] win_height the height of the window
00255           */
00256         bool 
00257         addFeatureHistogram (const pcl::PCLPointCloud2 &cloud,
00258                              const std::string &field_name, 
00259                              const int index,
00260                              const std::string &id = "cloud", int win_width = 640, int win_height = 200);
00261         
00262         /** \brief Draws all the plots added by addPlotData() or addHistogramData() till now */
00263         void 
00264         plot ();
00265         
00266         /** \brief Spins (runs the event loop) the interactor for spin_time amount of time. The name is confusing and will be probably obsolete in the future release with a single overloaded spin()/display() function.
00267           *  \param[in] spin_time - How long (in ms) should the visualization loop be allowed to run.
00268           */
00269         void 
00270         spinOnce (const int spin_time = 1);
00271         
00272         /** \brief Spins (runs the event loop) the interactor indefinitely. Same as plot() - added to retain the similarity between other existing visualization classes. */
00273         void 
00274         spin ();
00275         
00276         /** \brief Remove all plots from the window. */
00277         void
00278         clearPlots();
00279         
00280         /** \brief Set method for the color scheme of the plot. The plots gets autocolored differently based on the color scheme.
00281           * \param[in] scheme the color scheme. Possible values are vtkColorSeries::SPECTRUM, vtkColorSeries::WARM, vtkColorSeries::COOL, vtkColorSeries::BLUES, vtkColorSeries::WILD_FLOWER, vtkColorSeries::CITRUS
00282           */       
00283         void
00284         setColorScheme (int scheme);
00285         
00286         /** \brief get the currently used color scheme
00287           * \return[out] the currently used color scheme. Values include WARM, COOL, BLUES, WILD_FLOWER, CITRUS, CUSTOM
00288           */  
00289         int 
00290         getColorScheme ();
00291         
00292         /** \brief set/get method for the viewport's background color.
00293           * \param[in] r the red component of the RGB color
00294           * \param[in] g the green component of the RGB color
00295           * \param[in] b the blue component of the RGB color
00296           */
00297         void 
00298         setBackgroundColor (const double r, const double g, const double b);
00299         
00300         /** \brief set/get method for the viewport's background color.
00301          * \param [in] color the array containing the 3 component of the RGB color
00302          */
00303         void
00304         setBackgroundColor (const double color[3]);
00305         
00306         /** \brief set/get method for the viewport's background color.
00307          * \return [out] color the array containing the 3 component of the RGB color
00308          */
00309         double *
00310         getBackgroundColor ();
00311         
00312         /** \brief Set logical range of the X-Axis in plot coordinates 
00313           * \param[in] min the left boundary of the range
00314           * \param[in] max the right boundary of the range
00315           */
00316         void 
00317         setXRange (double min, double max);
00318         
00319         /** \brief Set logical range of the Y-Axis in plot coordinates 
00320           * \param[in] min the left boundary of the range
00321           * \param[in] max the right boundary of the range
00322           */
00323         void
00324         setYRange (double min, double max);
00325         
00326         /** \brief Set the main title of the plot
00327           * \param[in] title the title to set 
00328           */
00329         void 
00330         setTitle (const char *title);
00331         
00332         /** \brief Set the title of the X-Axis
00333           * \param[in] title the title to set 
00334           */
00335         void 
00336         setXTitle (const char *title);
00337         
00338         /** \brief Set the title of the Y-Axis
00339           * \param[in] title the title to set 
00340           */
00341         void 
00342         setYTitle (const char *title);
00343         
00344         /** \brief Shows the legend of the graph
00345           * \param[in] flag pass flag = true for the display of the legend of the graph
00346           */
00347         void 
00348         setShowLegend (bool flag);
00349         
00350         /** \brief set/get method for the window size.
00351           * \param[in] w the width of the window
00352           * \param[in] h the height of the window
00353           */
00354         void
00355         setWindowSize (int w, int h);
00356         
00357         /** \brief set/get method for the window size.
00358           * \return[in] array containing the width and height of the window
00359           */
00360         int*
00361         getWindowSize ();
00362 
00363         /** \brief Return a pointer to the underlying VTK RenderWindow used. */
00364         vtkSmartPointer<vtkRenderWindow>
00365         getRenderWindow ();
00366         
00367         /** \brief Set the view's interactor. */
00368         void
00369         setViewInteractor (vtkSmartPointer<vtkRenderWindowInteractor> interactor);
00370         
00371         /** \brief Initialize and Start the view's interactor. */
00372         void
00373         startInteractor ();
00374         
00375         /** \brief Render the vtkWindow once. */
00376         void renderOnce();
00377 
00378         /** \brief Returns true when the user tried to close the window */
00379         bool
00380         wasStopped () const;
00381         
00382         /** \brief Stop the interaction and close the visualizaton window. */
00383         void
00384         close ();
00385       
00386       private:
00387         vtkSmartPointer<vtkContextView> view_;  
00388         vtkSmartPointer<vtkChartXY> chart_;
00389         vtkSmartPointer<vtkColorSeries> color_series_;   //for automatic coloring
00390         
00391         //extra state variables
00392         int current_plot_;          //stores the id of the current (most recent) plot, used in automatic coloring and other state change schemes 
00393         int win_width_, win_height_;
00394         double bkg_color_[3];
00395           
00396         //####event callback class####
00397         struct ExitMainLoopTimerCallback : public vtkCommand
00398         {
00399           static ExitMainLoopTimerCallback* New ()
00400           {
00401             return (new ExitMainLoopTimerCallback);
00402           }
00403           virtual void 
00404           Execute (vtkObject*, unsigned long event_id, void* call_data);
00405 
00406           int right_timer_id;
00407 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00408           PCLVisualizerInteractor *interactor;
00409 #else
00410           vtkRenderWindowInteractor *interactor;
00411 #endif
00412         };
00413         
00414         struct ExitCallback : public vtkCommand
00415         {
00416           static ExitCallback* New ()
00417           {
00418             return new ExitCallback;
00419           }
00420           virtual void 
00421           Execute (vtkObject*, unsigned long event_id, void*);
00422 
00423           PCLPlotter *plotter;
00424         };
00425         
00426          /** \brief Set to false if the interaction loop is running. */
00427         bool stopped_;
00428         
00429         /** \brief Callback object enabling us to leave the main loop, when a timer fires. */
00430         vtkSmartPointer<ExitMainLoopTimerCallback> exit_loop_timer_;
00431         vtkSmartPointer<ExitCallback> exit_callback_;
00432         
00433         ////////////////////////////////////IMPORTANT PRIVATE COMPUTING FUNCTIONS////////////////////////////////////////////////////
00434         /** \brief computes the value of the polynomial function at val
00435           * \param[in] p_function polynomial function
00436           * \param[in] value the value at which the function is to be computed
00437           */
00438         double 
00439         compute (PolynomialFunction const & p_function, double val);
00440         
00441         /** \brief computes the value of the rational function at val
00442           * \param[in] r_function the rational function
00443           * \param[in] value the value at which the function is to be computed
00444           */
00445         double 
00446         compute (RationalFunction const & r_function, double val);
00447         
00448         /** \brief bins the elements in vector data into nbins equally spaced containers and returns the histogram form, ie, computes the histogram for 'data'
00449           * \param[in] data data who's frequency distribution is to be found
00450           * \param[in] nbins number of bins for the histogram
00451           * \param[out] histogram vector of pairs containing the histogram. The first field of the pair represent the middle value of the corresponding bin. The second field denotes the frequency of data in that bin.
00452           */
00453         void 
00454         computeHistogram (std::vector<double> const & data, int const nbins, std::vector<std::pair<double, double> > &histogram);
00455     };
00456   }
00457 }
00458 
00459 #include <pcl/visualization/impl/pcl_plotter.hpp>
00460 
00461 #endif  /* PCL_VISUALUALIZATION_PCL_PLOTTER_H_ */
00462