Point Cloud Library (PCL)  1.7.0
pcl_plotter.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, 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  */
38 #ifndef PCL_VISUALUALIZATION_PCL_PLOTTER_H_
39 #define PCL_VISUALUALIZATION_PCL_PLOTTER_H_
40 
41 #include <iostream>
42 #include <vector>
43 #include <utility>
44 #include <cfloat>
45 
46 #include <pcl/visualization/common/common.h>
47 #include <pcl/point_types.h>
48 #include <pcl/correspondence.h>
49 #include <pcl/point_cloud.h>
50 #include <pcl/common/io.h>
51 
52 class PCLVisualizerInteractor;
53 template <typename T> class vtkSmartPointer;
54 class vtkRenderWindowInteractor;
55 class vtkContextView;
56 class vtkChartXY;
57 class vtkColorSeries;
58 
59 #include <vtkCommand.h>
60 #include <vtkChart.h>
61 
62 namespace pcl
63 {
64  namespace visualization
65  {
66  /** \brief PCL Plotter main class. Given point correspondences this class
67  * can be used to plot the data one against the other and display it on the
68  * screen. It also has methods for providing plot for important functions
69  * like histogram etc. Important functions of PCLHistogramVisualizer are
70  * redefined here so that this single class can take responsibility of all
71  * plotting related functionalities.
72  *
73  * \author Kripasindhu Sarkar
74  * \ingroup visualization
75  */
76  class PCL_EXPORTS PCLPlotter
77  {
78  public:
79 
80  /**\brief A representation of polynomial function. i'th element of the vector denotes the coefficient of x^i of the polynomial in variable x.
81  */
82  typedef std::vector<double> PolynomialFunction;
83 
84  /**\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.
85  */
86  typedef std::pair<PolynomialFunction, PolynomialFunction> RationalFunction;
87 
88  /** \brief PCL Plotter constructor.
89  * \param[in] name Name of the window
90  */
91  PCLPlotter (char const * name = "PCL Plotter");
92 
93  /** \brief Destructor. */
94  ~PCLPlotter();
95 
96  /** \brief Adds a plot with correspondences in the arrays arrayX and arrayY
97  * \param[in] array_X X coordinates of point correspondence array
98  * \param[in] array_Y Y coordinates of point correspondence array
99  * \param[in] size length of the array arrayX and arrayY
100  * \param[in] name name of the plot which appears in the legend when toggled on
101  * \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
102  * \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
103  */
104  void
105  addPlotData (double const *array_X,
106  double const *array_Y,
107  unsigned long size,
108  char const * name = "Y Axis",
109  int type = vtkChart::LINE ,
110  char const *color=NULL);
111 
112  /** \brief Adds a plot with correspondences in vectors arrayX and arrayY. This is the vector version of the addPlotData function.
113  * \param[in] array_X X coordinates of point correspondence array
114  * \param[in] array_Y Y coordinates of point correspondence array
115  * \param[in] size length of the array arrayX and arrayY
116  * \param[in] name name of the plot which appears in the legend when toggled on
117  * \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
118  * \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
119  */
120  void
121  addPlotData (std::vector<double> const &array_X,
122  std::vector<double>const &array_Y,
123  char const * name = "Y Axis",
124  int type = vtkChart::LINE,
125  std::vector<char> const &color = std::vector<char> ());
126 
127  /** \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.
128  * \param[in] name name of the plot which appears in the legend when toggled on
129  * \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
130  * \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
131  */
132  void
133  addPlotData (std::vector<std::pair<double, double> > const &plot_data,
134  char const * name = "Y Axis",
135  int type = vtkChart::LINE,
136  std::vector<char> const &color = std::vector<char>());
137 
138  /** \brief Adds a plot based on the given polynomial function and the range in X axis.
139  * \param[in] p_function A polynomial function which is represented by a vector which stores the coefficients. See description on the typedef.
140  * \param[in] x_min the left boundary of the range for displaying the plot
141  * \param[in] x_max the right boundary of the range for displaying the plot
142  * \param[in] name name of the plot which appears in the legend when toggled on
143  * \param[in] num_points Number of points plotted to show the graph. More this number, more is the resolution.
144  * \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
145  * \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
146  */
147  void
148  addPlotData (PolynomialFunction const & p_function,
149  double x_min, double x_max,
150  char const *name = "Y Axis",
151  int num_points = 100,
152  int type = vtkChart::LINE,
153  std::vector<char> const &color = std::vector<char>());
154 
155  /** \brief Adds a plot based on the given rational function and the range in X axis.
156  * \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.
157  * \param[in] x_min the left boundary of the range for displaying the plot
158  * \param[in] x_max the right boundary of the range for displaying the plot
159  * \param[in] name name of the plot which appears in the legend when toggled on
160  * \param[in] num_points Number of points plotted to show the graph. More this number, more is the resolution.
161  * \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
162  * \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
163  */
164  void
165  addPlotData (RationalFunction const & r_function,
166  double x_min, double x_max,
167  char const *name = "Y Axis",
168  int num_points = 100,
169  int type = vtkChart::LINE,
170  std::vector<char> const &color = std::vector<char>());
171 
172  /** \brief Adds a plot based on a user defined callback function representing the function to plot
173  * \param[in] function a user defined callback function representing the relation y = function(x)
174  * \param[in] x_min the left boundary of the range for displaying the plot
175  * \param[in] x_max the right boundary of the range for displaying the plot
176  * \param[in] name name of the plot which appears in the legend when toggled on
177  * \param[in] num_points Number of points plotted to show the graph. More this number, more is the resolution.
178  * \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
179  * \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
180  */
181  void
182  addPlotData (double (*function)(double),
183  double x_min, double x_max,
184  char const *name = "Y Axis",
185  int num_points = 100,
186  int type = vtkChart::LINE,
187  std::vector<char> const &color = std::vector<char>());
188 
189  /** \brief Adds a plot based on a space/tab delimited table provided in a file
190  * \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.
191  * \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
192  */
193  void
194  addPlotData (char const * filename,
195  int type = vtkChart::LINE);
196 
197  /** \brief Bins the elements in vector data into nbins equally spaced containers and plots the resulted histogram
198  * \param[in] data the raw data
199  * \param[in] nbins the number of bins for the histogram
200  * \param[in] name name of this histogram which will appear on legends if toggled on
201  * \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
202  */
203  void
204  addHistogramData (std::vector<double> const & data,
205  int const nbins = 10,
206  char const * name = "Histogram",
207  std::vector<char> const &color = std::vector<char>());
208 
209  //##PCLHistogramVisulizer methods##
210  /** \brief Add a histogram feature to screen as a separate window, from a cloud containing a single histogram.
211  * \param[in] cloud the PointCloud dataset containing the histogram
212  * \param[in] hsize the length of the histogram
213  * \param[in] id the point cloud object id (default: cloud)
214  * \param[in] win_width the width of the window
215  * \param[in] win_height the height of the window
216  */
217  template <typename PointT> bool
218  addFeatureHistogram (const pcl::PointCloud<PointT> &cloud,
219  int hsize,
220  const std::string &id = "cloud", int win_width = 640, int win_height = 200);
221 
222  /** \brief Add a histogram feature to screen as a separate window from a cloud containing a single histogram.
223  * \param[in] cloud the PointCloud dataset containing the histogram
224  * \param[in] field_name the field name containing the histogram
225  * \param[in] id the point cloud object id (default: cloud)
226  * \param[in] win_width the width of the window
227  * \param[in] win_height the height of the window
228  */
229  bool
230  addFeatureHistogram (const pcl::PCLPointCloud2 &cloud,
231  const std::string &field_name,
232  const std::string &id = "cloud", int win_width = 640, int win_height = 200);
233 
234  /** \brief Add a histogram feature to screen as a separate window.
235  * \param[in] cloud the PointCloud dataset containing the histogram
236  * \param[in] field_name the field name containing the histogram
237  * \param[in] index the point index to extract the histogram from
238  * \param[in] id the point cloud object id (default: cloud)
239  * \param[in] win_width the width of the window
240  * \param[in] win_height the height of the window
241  */
242  template <typename PointT> bool
243  addFeatureHistogram (const pcl::PointCloud<PointT> &cloud,
244  const std::string &field_name,
245  const int index,
246  const std::string &id = "cloud", int win_width = 640, int win_height = 200);
247 
248  /** \brief Add a histogram feature to screen as a separate window.
249  * \param[in] cloud the PointCloud dataset containing the histogram
250  * \param[in] field_name the field name containing the histogram
251  * \param[in] index the point index to extract the histogram from
252  * \param[in] id the point cloud object id (default: cloud)
253  * \param[in] win_width the width of the window
254  * \param[in] win_height the height of the window
255  */
256  bool
257  addFeatureHistogram (const pcl::PCLPointCloud2 &cloud,
258  const std::string &field_name,
259  const int index,
260  const std::string &id = "cloud", int win_width = 640, int win_height = 200);
261 
262  /** \brief Draws all the plots added by addPlotData() or addHistogramData() till now */
263  void
264  plot ();
265 
266  /** \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.
267  * \param[in] spin_time - How long (in ms) should the visualization loop be allowed to run.
268  */
269  void
270  spinOnce (const int spin_time = 1);
271 
272  /** \brief Spins (runs the event loop) the interactor indefinitely. Same as plot() - added to retain the similarity between other existing visualization classes. */
273  void
274  spin ();
275 
276  /** \brief Remove all plots from the window. */
277  void
278  clearPlots();
279 
280  /** \brief Set method for the color scheme of the plot. The plots gets autocolored differently based on the color scheme.
281  * \param[in] scheme the color scheme. Possible values are vtkColorSeries::SPECTRUM, vtkColorSeries::WARM, vtkColorSeries::COOL, vtkColorSeries::BLUES, vtkColorSeries::WILD_FLOWER, vtkColorSeries::CITRUS
282  */
283  void
284  setColorScheme (int scheme);
285 
286  /** \brief get the currently used color scheme
287  * \return[out] the currently used color scheme. Values include WARM, COOL, BLUES, WILD_FLOWER, CITRUS, CUSTOM
288  */
289  int
290  getColorScheme ();
291 
292  /** \brief set/get method for the viewport's background color.
293  * \param[in] r the red component of the RGB color
294  * \param[in] g the green component of the RGB color
295  * \param[in] b the blue component of the RGB color
296  */
297  void
298  setBackgroundColor (const double r, const double g, const double b);
299 
300  /** \brief set/get method for the viewport's background color.
301  * \param [in] color the array containing the 3 component of the RGB color
302  */
303  void
304  setBackgroundColor (const double color[3]);
305 
306  /** \brief set/get method for the viewport's background color.
307  * \return [out] color the array containing the 3 component of the RGB color
308  */
309  double *
310  getBackgroundColor ();
311 
312  /** \brief Set logical range of the X-Axis in plot coordinates
313  * \param[in] min the left boundary of the range
314  * \param[in] max the right boundary of the range
315  */
316  void
317  setXRange (double min, double max);
318 
319  /** \brief Set logical range of the Y-Axis in plot coordinates
320  * \param[in] min the left boundary of the range
321  * \param[in] max the right boundary of the range
322  */
323  void
324  setYRange (double min, double max);
325 
326  /** \brief Set the main title of the plot
327  * \param[in] title the title to set
328  */
329  void
330  setTitle (const char *title);
331 
332  /** \brief Set the title of the X-Axis
333  * \param[in] title the title to set
334  */
335  void
336  setXTitle (const char *title);
337 
338  /** \brief Set the title of the Y-Axis
339  * \param[in] title the title to set
340  */
341  void
342  setYTitle (const char *title);
343 
344  /** \brief Shows the legend of the graph
345  * \param[in] flag pass flag = true for the display of the legend of the graph
346  */
347  void
348  setShowLegend (bool flag);
349 
350  /** \brief set/get method for the window size.
351  * \param[in] w the width of the window
352  * \param[in] h the height of the window
353  */
354  void
355  setWindowSize (int w, int h);
356 
357  /** \brief set/get method for the window size.
358  * \return[in] array containing the width and height of the window
359  */
360  int*
361  getWindowSize ();
362 
363  /** \brief Return a pointer to the underlying VTK RenderWindow used. */
365  getRenderWindow ();
366 
367  /** \brief Set the view's interactor. */
368  void
369  setViewInteractor (vtkSmartPointer<vtkRenderWindowInteractor> interactor);
370 
371  /** \brief Initialize and Start the view's interactor. */
372  void
373  startInteractor ();
374 
375  /** \brief Render the vtkWindow once. */
376  void renderOnce();
377 
378  /** \brief Returns true when the user tried to close the window */
379  bool
380  wasStopped () const;
381 
382  /** \brief Stop the interaction and close the visualizaton window. */
383  void
384  close ();
385 
386  private:
389  vtkSmartPointer<vtkColorSeries> color_series_; //for automatic coloring
390 
391  //extra state variables
392  int current_plot_; //stores the id of the current (most recent) plot, used in automatic coloring and other state change schemes
393  int win_width_, win_height_;
394  double bkg_color_[3];
395 
396  //####event callback class####
397  struct ExitMainLoopTimerCallback : public vtkCommand
398  {
399  static ExitMainLoopTimerCallback* New ()
400  {
401  return (new ExitMainLoopTimerCallback);
402  }
403  virtual void
404  Execute (vtkObject*, unsigned long event_id, void* call_data);
405 
406  int right_timer_id;
407 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
408  PCLVisualizerInteractor *interactor;
409 #else
410  vtkRenderWindowInteractor *interactor;
411 #endif
412  };
413 
414  struct ExitCallback : public vtkCommand
415  {
416  static ExitCallback* New ()
417  {
418  return new ExitCallback;
419  }
420  virtual void
421  Execute (vtkObject*, unsigned long event_id, void*);
422 
423  PCLPlotter *plotter;
424  };
425 
426  /** \brief Set to false if the interaction loop is running. */
427  bool stopped_;
428 
429  /** \brief Callback object enabling us to leave the main loop, when a timer fires. */
431  vtkSmartPointer<ExitCallback> exit_callback_;
432 
433  ////////////////////////////////////IMPORTANT PRIVATE COMPUTING FUNCTIONS////////////////////////////////////////////////////
434  /** \brief computes the value of the polynomial function at val
435  * \param[in] p_function polynomial function
436  * \param[in] value the value at which the function is to be computed
437  */
438  double
439  compute (PolynomialFunction const & p_function, double val);
440 
441  /** \brief computes the value of the rational function at val
442  * \param[in] r_function the rational function
443  * \param[in] value the value at which the function is to be computed
444  */
445  double
446  compute (RationalFunction const & r_function, double val);
447 
448  /** \brief bins the elements in vector data into nbins equally spaced containers and returns the histogram form, ie, computes the histogram for 'data'
449  * \param[in] data data who's frequency distribution is to be found
450  * \param[in] nbins number of bins for the histogram
451  * \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.
452  */
453  void
454  computeHistogram (std::vector<double> const & data, int const nbins, std::vector<std::pair<double, double> > &histogram);
455  };
456  }
457 }
458 
459 #include <pcl/visualization/impl/pcl_plotter.hpp>
460 
461 #endif /* PCL_VISUALUALIZATION_PCL_PLOTTER_H_ */
462