Point Cloud Library (PCL)  1.7.1
pcl_painter2D.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2012-, Open Perception, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  *
37  */
38 
39 #ifndef PCL_VISUALUALIZATION_PCL_PAINTER2D_H_
40 #define PCL_VISUALUALIZATION_PCL_PAINTER2D_H_
41 
42 #include <iostream>
43 #include <map>
44 #include <vector>
45 #include <vtkRenderer.h>
46 #include <vtkRenderWindow.h>
47 #include <vtkRenderWindowInteractor.h>
48 #include <vtkSmartPointer.h>
49 #include <vtkObjectFactory.h>
50 #include <vtkContext2D.h>
51 #include <vtkTransform2D.h>
52 #include <vtkContextItem.h>
53 #include <vtkContextView.h>
54 #include <vtkContextScene.h>
55 #include <vtkPen.h>
56 #include <vtkBrush.h>
57 #include <vtkTextProperty.h>
58 #include <vtkOpenGLContextDevice2D.h>
59 #include <vtkPoints2D.h>
60 #include "vtkCommand.h"
61 
62 #include <vtkRegressionTestImage.h>
63 
64 namespace pcl
65 {
66  namespace visualization
67  {
68 
69  /** \brief Abstract class for storing figure information. All the derived class uses the same method draw() to invoke different drawing function of vtkContext2D
70  * \author Kripasindhu Sarkar
71  * \ingroup visualization
72  */
73  struct Figure2D
74  {
75  std::vector<float> info_; //information stored in a general form for every object
76  vtkPen *pen_; //the corresponding pen and brush for the figure
77  vtkBrush *brush_;
78  vtkTransform2D *transform_;
79 
80  Figure2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t)
81  {
82  this->pen_ = vtkPen::New ();
83  this->brush_ = vtkBrush::New ();
84  this->transform_ = vtkTransform2D::New();
85 
86  this->pen_->DeepCopy (p);
87  this->brush_->DeepCopy (b);
88  this->transform_->SetMatrix (t->GetMatrix());
89  this->info_ = info; //note: it copies :-)
90  }
91 
92  Figure2D (vtkPen *p, vtkBrush * b, vtkTransform2D *t)
93  {
94  this->pen_ = vtkPen::New ();
95  this->brush_ = vtkBrush::New ();
96  this->transform_ = vtkTransform2D::New();
97 
98  this->pen_->DeepCopy (p);
99  this->brush_->DeepCopy (b);
100  this->transform_->SetMatrix (t->GetMatrix());
101  }
102 
103  void applyInternals (vtkContext2D *painter)
104  {
105  painter->ApplyPen (pen_);
106  painter->ApplyBrush (brush_);
107  painter->GetDevice ()->SetMatrix (transform_->GetMatrix());
108  }
109 
110  virtual void draw (vtkContext2D *) {}
111  };
112 
113  /** \brief Class for PolyLine
114  */
115  struct FPolyLine2D : public Figure2D
116  {
117 
118  FPolyLine2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t){}
119 
120  void draw (vtkContext2D * painter)
121  {
122  applyInternals(painter);
123  painter->DrawPoly (&info_[0], static_cast<unsigned int> (info_.size ()) / 2);
124  }
125  };
126 
127  /** \brief Class for storing Points
128  */
129  struct FPoints2D : public Figure2D
130  {
131 
132  FPoints2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t) {}
133 
134  void draw (vtkContext2D * painter)
135  {
136  applyInternals(painter);
137  painter->DrawPoints (&info_[0], static_cast<unsigned int> (info_.size ()) / 2);
138  }
139  };
140 
141  /** \brief Class for storing Quads
142  */
143  struct FQuad2D : public Figure2D
144  {
145 
146  FQuad2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t) {}
147 
148  void draw (vtkContext2D * painter)
149  {
150  applyInternals(painter);
151  painter->DrawQuad (&info_[0]);
152  }
153  };
154 
155  /** \brief Class for Polygon
156  */
157  struct FPolygon2D : public Figure2D
158  {
159 
160  FPolygon2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t){}
161 
162  void draw (vtkContext2D * painter)
163  {
164  applyInternals(painter);
165  painter->DrawPolygon (&info_[0], static_cast<unsigned int> (info_.size ()) / 2);
166  }
167  };
168 
169  /** \brief Class for storing EllipticArc; every ellipse , circle are covered by this
170  */
171  struct FEllipticArc2D : public Figure2D
172  {
173 
174  FEllipticArc2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t) {}
175 
176  FEllipticArc2D (float x, float y, float rx, float ry, float sa, float ea, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (p, b, t)
177  {
178  info_.resize (6);
179  info_[0] = x;
180  info_[1] = y;
181  info_[2] = rx;
182  info_[3] = ry;
183  info_[4] = sa;
184  info_[5] = ea;
185  }
186 
187  void draw (vtkContext2D * painter)
188  {
189  applyInternals(painter);
190  painter->DrawEllipticArc (info_[0], info_[1], info_[2], info_[3], info_[4], info_[5]);
191  }
192  };
193 
194 
195  ////////////////////////////////////The Main Painter Class begins here//////////////////////////////////////
196  /** \brief PCL Painter2D main class. Class for drawing 2D figures
197  * \author Kripasindhu Sarkar
198  * \ingroup visualization
199  */
200  class PCLPainter2D: public vtkContextItem
201  {
202  public:
203 
204  //static PCLPainter2D *New();
205 
206  /** \brief Constructor of the class
207  */
208  PCLPainter2D (char const * name = "PCLPainter2D");
209  vtkTypeRevisionMacro (PCLPainter2D, vtkContextItem);
210 
211  /** \brief Paint event for the chart, called whenever the chart needs to be drawn
212  * \param[in] name Name of the window
213  */
214  virtual bool
215  Paint (vtkContext2D *painter);
216 
217  /** \brief Draw a line between the specified points.
218  * \param[in] x1 X coordinate of the starting point of the line
219  * \param[in] y1 Y coordinate of the starting point of the line
220  * \param[in] x2 X coordinate of the ending point of the line
221  * \param[in] y2 Y coordinate of the ending point of the line
222  */
223  void
224  addLine (float x1, float y1, float x2, float y2);
225 
226  /** \brief Draw line(s) between the specified points
227  * \param[in] p a vector of size 2*n and the points are packed x1, y1, x2, y2 etc.
228  */
229  void
230  addLine (std::vector<float> p);
231 
232 
233  /** \brief Draw specified point(s).
234  * \param[in] x X coordinate of the point
235  * \param[in] y Y coordinate of the point
236  */
237  void
238  addPoint (float x, float y);
239  /** \brief Draw specified point(s).
240  * \param[in] points a vector of size 2*n and the points are packed x1, y1, x2, y2 etc.
241  */
242 
243  void
244  addPoints (std::vector<float> points);
245 
246 
247  /** \brief Draw a rectangle based on the given points
248  * \param[in] x X coordinate of the origin
249  * \param[in] y Y coordinate of the origin
250  * \param[in] width width of the rectangle
251  * \param[in] height height of the rectangle
252  */
253  void
254  addRect (float x, float y, float width, float height);
255 
256  /** \brief Draw a quadrilateral based on the given points
257  * \param[in] p a vector of size 8 and the points are packed x1, y1, x2, y2, x3, y3 and x4, y4.
258  */
259  void
260  addQuad (std::vector<float> p);
261 
262  /** \brief Draw a polygon between the specified points
263  * \param[in] p a vector of size 2*n and the points are packed x1, y1, x2, y2 etc.
264  */
265  void
266  addPolygon (std::vector<float> p);
267 
268 
269  /** \brief Draw an ellipse based on the inputs
270  * \param[in] x X coordinate of the origin
271  * \param[in] y Y coordinate of the origin
272  * \param[in] rx X radius of the ellipse
273  * \param[in] ry Y radius of the ellipse
274  */
275  void
276  addEllipse (float x, float y, float rx, float ry);
277 
278  /** \brief Draw a circle based on the inputs
279  * \param[in] x X coordinate of the origin
280  * \param[in] y Y coordinate of the origin
281  * \param[in] r radius of the circle
282  */
283  void
284  addCircle (float x, float y, float r);
285 
286  /** \brief Draw an elliptic arc based on the inputs
287  * \param[in] x X coordinate of the origin
288  * \param[in] y Y coordinate of the origin
289  * \param[in] rx X radius of the ellipse
290  * \param[in] ry Y radius of the ellipse
291  * \param[in] start_angle the starting angle of the arc expressed in degrees
292  * \param[in] end_angle the ending angle of the arc expressed in degrees
293  */
294  void
295  addEllipticArc (float x, float y, float rx, float ry, float start_angle, float end_angle);
296 
297  /** \brief Draw an arc based on the inputs
298  * \param[in] x X coordinate of the origin
299  * \param[in] y Y coordinate of the origin
300  * \param[in] r radius of the circle
301  * \param[in] start_angle the starting angle of the arc expressed in degrees
302  * \param[in] end_angle the ending angle of the arc expressed in degrees
303  */
304  void
305  addArc (float x, float y, float r, float start_angle, float end_angle);
306 
307 
308  /** \brief Create a translation matrix and concatenate it with the current transformation.
309  * \param[in] x translation along X axis
310  * \param[in] y translation along Y axis
311  */
312  void
313  translatePen (double x, double y);
314 
315  /** \brief Create a rotation matrix and concatenate it with the current transformation.
316  * \param[in] angle angle in degrees
317  */
318  void
319  rotatePen(double angle);
320 
321  /** \brief Create a scale matrix and concatenate it with the current transformation.
322  * \param[in] x translation along X axis
323  * \param[in] y translation along Y axis
324  */
325  void
326  scalePen(double x, double y);
327 
328  /** \brief Create a translation matrix and concatenate it with the current transformation.
329  * \param[in] x translation along X axis
330  * \param[in] y translation along Y axis
331  */
332  void
333  setTransform(vtkMatrix3x3 *matrix);
334 
335  /** \brief Returns the current transformation matrix.
336  */
337  vtkMatrix3x3 *
338  getTransform();
339 
340  /** \brief Clears all the transformation applied. Sets the transformation matrix to Identity
341  */
342  void
343  clearTransform();
344 
345  /** \brief remove all the figures from the window
346  */
347  void
348  clearFigures();
349 
350  /** \brief set/get methods for current working vtkPen
351  */
352  void setPenColor (unsigned char r, unsigned char g, unsigned char b, unsigned char a);
353  void setPenWidth (float w);
354  void setPenType (int type);
355 
356  /** \brief set/get methods for current working vtkPen
357  */
358  unsigned char* getPenColor ();
359  float getPenWidth ();
360  int getPenType ();
361  void setPen (vtkPen *pen);
362  vtkPen* getPen ();
363 
364  /** \brief set/get methods for current working vtkBrush
365  */
366  void setBrush (vtkBrush *brush);
367  vtkBrush* getBrush ();
368  void setBrushColor (unsigned char r, unsigned char g, unsigned char b, unsigned char a);
369  unsigned char* getBrushColor ();
370 
371  /** \brief set/get method for the viewport's background color.
372  * \param[in] r the red component of the RGB color
373  * \param[in] g the green component of the RGB color
374  * \param[in] b the blue component of the RGB color
375  */
376  void
377  setBackgroundColor (const double r, const double g, const double b);
378 
379  /** \brief set/get method for the viewport's background color.
380  * \param [in] color the array containing the 3 component of the RGB color
381  */
382  void
383  setBackgroundColor (const double color[3]);
384 
385  /** \brief set/get method for the viewport's background color.
386  * \return [out] color the array containing the 3 component of the RGB color
387  */
388  double *
390 
391 
392  /** \brief set/get method for the window size.
393  * \param[in] w the width of the window
394  * \param[in] h the height of the window
395  */
396  void
397  setWindowSize (int w, int h);
398 
399  /** \brief set/get method for the window size.
400  * \return[in] array containing the width and height of the window
401  */
402  int *
403  getWindowSize ();
404 
405  /** \brief displays all the figures added in a window.
406  */
407  void display ();
408 
409  /** \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.
410  * \param[in] spin_time - How long (in ms) should the visualization loop be allowed to run.
411  */
412  void spinOnce ( const int spin_time = 0 );
413 
414  /** \brief spins (runs the event loop) the interactor indefinitely. Same as display() - added to retain the similarity between other existing visualization classes
415  */
416  void spin ();
417 
418  private:
419  //std::map< int, std::vector< std::vector<float> > > figures_; //FIG_TYPE -> vector<array>
420 
421  //All the figures drawn till now gets stored here
422  std::vector<Figure2D *> figures_;
423 
424  //state variables of the class
425  vtkPen *current_pen_;
426  vtkBrush *current_brush_;
427  vtkTransform2D *current_transform_;
428  int win_width_, win_height_;
429  double bkg_color_[3];
430 
431  vtkContextView *view_;
432 
433  //####event callback class####
434  struct ExitMainLoopTimerCallback : public vtkCommand
435  {
436  static ExitMainLoopTimerCallback* New ()
437  {
438  return (new ExitMainLoopTimerCallback);
439  }
440  virtual void
441  Execute (vtkObject* vtkNotUsed (caller), unsigned long event_id, void* call_data)
442  {
443  if (event_id != vtkCommand::TimerEvent)
444  return;
445  int timer_id = *(reinterpret_cast<int*> (call_data));
446 
447  if (timer_id != right_timer_id)
448  return;
449 
450  // Stop vtk loop and send notification to app to wake it up
451 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
452  interactor->stopLoop ();
453 #else
454  interactor->TerminateApp ();
455 #endif
456  }
457  int right_timer_id;
458 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
459  PCLVisualizerInteractor *interactor;
460 #else
461  vtkRenderWindowInteractor *interactor;
462 #endif
463  };
464 
465  /** \brief Callback object enabling us to leave the main loop, when a timer fires. */
467  };
468 
469  }
470 }
471 
472 #endif /* PCL_VISUALUALIZATION_PCL_PAINTER2D_H_ */
473