Point Cloud Library (PCL)  1.11.0
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 #pragma once
40 
41 #include <iostream>
42 #include <map>
43 #include <vector>
44 #include <pcl/pcl_exports.h>
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 namespace pcl
63 {
64  namespace visualization
65  {
66 
67  /** \brief Abstract class for storing figure information. All the derived class uses the same method draw() to invoke different drawing function of vtkContext2D
68  * \author Kripasindhu Sarkar
69  * \ingroup visualization
70  */
71  struct Figure2D
72  {
73  std::vector<float> info_; //information stored in a general form for every object
74  vtkPen *pen_; //the corresponding pen and brush for the figure
75  vtkBrush *brush_;
76  vtkTransform2D *transform_;
77 
78  Figure2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t)
79  {
80  this->pen_ = vtkPen::New ();
81  this->brush_ = vtkBrush::New ();
82  this->transform_ = vtkTransform2D::New();
83 
84  this->pen_->DeepCopy (p);
85  this->brush_->DeepCopy (b);
86  this->transform_->SetMatrix (t->GetMatrix());
87  this->info_ = info; //note: it copies :-)
88  }
89 
90  Figure2D (vtkPen *p, vtkBrush * b, vtkTransform2D *t)
91  {
92  this->pen_ = vtkPen::New ();
93  this->brush_ = vtkBrush::New ();
94  this->transform_ = vtkTransform2D::New();
95 
96  this->pen_->DeepCopy (p);
97  this->brush_->DeepCopy (b);
98  this->transform_->SetMatrix (t->GetMatrix());
99  }
100 
101  void applyInternals (vtkContext2D *painter) const
102  {
103  painter->ApplyPen (pen_);
104  painter->ApplyBrush (brush_);
105  painter->GetDevice ()->SetMatrix (transform_->GetMatrix());
106  }
107 
108  virtual void draw (vtkContext2D *) {}
109  };
110 
111  /** \brief Class for PolyLine
112  */
113  struct FPolyLine2D : public Figure2D
114  {
115 
116  FPolyLine2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t){}
117 
118  void draw (vtkContext2D * painter) override
119  {
120  applyInternals(painter);
121  painter->DrawPoly (&info_[0], static_cast<unsigned int> (info_.size ()) / 2);
122  }
123  };
124 
125  /** \brief Class for storing Points
126  */
127  struct FPoints2D : public Figure2D
128  {
129 
130  FPoints2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t) {}
131 
132  void draw (vtkContext2D * painter) override
133  {
134  applyInternals(painter);
135  painter->DrawPoints (&info_[0], static_cast<unsigned int> (info_.size ()) / 2);
136  }
137  };
138 
139  /** \brief Class for storing Quads
140  */
141  struct FQuad2D : public Figure2D
142  {
143 
144  FQuad2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t) {}
145 
146  void draw (vtkContext2D * painter) override
147  {
148  applyInternals(painter);
149  painter->DrawQuad (&info_[0]);
150  }
151  };
152 
153  /** \brief Class for Polygon
154  */
155  struct FPolygon2D : public Figure2D
156  {
157 
158  FPolygon2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t){}
159 
160  void draw (vtkContext2D * painter) override
161  {
162  applyInternals(painter);
163  painter->DrawPolygon (&info_[0], static_cast<unsigned int> (info_.size ()) / 2);
164  }
165  };
166 
167  /** \brief Class for storing EllipticArc; every ellipse , circle are covered by this
168  */
169  struct FEllipticArc2D : public Figure2D
170  {
171 
172  FEllipticArc2D (std::vector<float> info, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (info, p, b, t) {}
173 
174  FEllipticArc2D (float x, float y, float rx, float ry, float sa, float ea, vtkPen *p, vtkBrush * b, vtkTransform2D *t) : Figure2D (p, b, t)
175  {
176  info_.resize (6);
177  info_[0] = x;
178  info_[1] = y;
179  info_[2] = rx;
180  info_[3] = ry;
181  info_[4] = sa;
182  info_[5] = ea;
183  }
184 
185  void draw (vtkContext2D * painter) override
186  {
187  applyInternals(painter);
188  painter->DrawEllipticArc (info_[0], info_[1], info_[2], info_[3], info_[4], info_[5]);
189  }
190  };
191 
192 
193  ////////////////////////////////////The Main Painter Class begins here//////////////////////////////////////
194  /** \brief PCL Painter2D main class. Class for drawing 2D figures
195  * \author Kripasindhu Sarkar
196  * \ingroup visualization
197  */
198  class PCL_EXPORTS PCLPainter2D: public vtkContextItem
199  {
200  public:
201 
202  //static PCLPainter2D *New();
203 
204  /** \brief Constructor of the class
205  */
206  PCLPainter2D (char const * name = "PCLPainter2D");
207  vtkTypeMacro (PCLPainter2D, vtkContextItem);
208 
209  /** \brief Paint event for the chart, called whenever the chart needs to be drawn
210  * \param[in] painter Name of the window
211  */
212  bool
213  Paint (vtkContext2D *painter) override;
214 
215  /** \brief Draw a line between the specified points.
216  * \param[in] x1 X coordinate of the starting point of the line
217  * \param[in] y1 Y coordinate of the starting point of the line
218  * \param[in] x2 X coordinate of the ending point of the line
219  * \param[in] y2 Y coordinate of the ending point of the line
220  */
221  void
222  addLine (float x1, float y1, float x2, float y2);
223 
224  /** \brief Draw line(s) between the specified points
225  * \param[in] p a vector of size 2*n and the points are packed x1, y1, x2, y2 etc.
226  */
227  void
228  addLine (std::vector<float> p);
229 
230 
231  /** \brief Draw specified point(s).
232  * \param[in] x X coordinate of the point
233  * \param[in] y Y coordinate of the point
234  */
235  void
236  addPoint (float x, float y);
237  /** \brief Draw specified point(s).
238  * \param[in] points a vector of size 2*n and the points are packed x1, y1, x2, y2 etc.
239  */
240 
241  void
242  addPoints (std::vector<float> points);
243 
244 
245  /** \brief Draw a rectangle based on the given points
246  * \param[in] x X coordinate of the origin
247  * \param[in] y Y coordinate of the origin
248  * \param[in] width width of the rectangle
249  * \param[in] height height of the rectangle
250  */
251  void
252  addRect (float x, float y, float width, float height);
253 
254  /** \brief Draw a quadrilateral based on the given points
255  * \param[in] p a vector of size 8 and the points are packed x1, y1, x2, y2, x3, y3 and x4, y4.
256  */
257  void
258  addQuad (std::vector<float> p);
259 
260  /** \brief Draw a polygon between the specified points
261  * \param[in] p a vector of size 2*n and the points are packed x1, y1, x2, y2 etc.
262  */
263  void
264  addPolygon (std::vector<float> p);
265 
266 
267  /** \brief Draw an ellipse based on the inputs
268  * \param[in] x X coordinate of the origin
269  * \param[in] y Y coordinate of the origin
270  * \param[in] rx X radius of the ellipse
271  * \param[in] ry Y radius of the ellipse
272  */
273  void
274  addEllipse (float x, float y, float rx, float ry);
275 
276  /** \brief Draw a circle based on the inputs
277  * \param[in] x X coordinate of the origin
278  * \param[in] y Y coordinate of the origin
279  * \param[in] r radius of the circle
280  */
281  void
282  addCircle (float x, float y, float r);
283 
284  /** \brief Draw an elliptic arc based on the inputs
285  * \param[in] x X coordinate of the origin
286  * \param[in] y Y coordinate of the origin
287  * \param[in] rx X radius of the ellipse
288  * \param[in] ry Y radius of the ellipse
289  * \param[in] start_angle the starting angle of the arc expressed in degrees
290  * \param[in] end_angle the ending angle of the arc expressed in degrees
291  */
292  void
293  addEllipticArc (float x, float y, float rx, float ry, float start_angle, float end_angle);
294 
295  /** \brief Draw an arc based on the inputs
296  * \param[in] x X coordinate of the origin
297  * \param[in] y Y coordinate of the origin
298  * \param[in] r radius of the circle
299  * \param[in] start_angle the starting angle of the arc expressed in degrees
300  * \param[in] end_angle the ending angle of the arc expressed in degrees
301  */
302  void
303  addArc (float x, float y, float r, float start_angle, float end_angle);
304 
305 
306  /** \brief Create a translation matrix and concatenate it with the current transformation.
307  * \param[in] x translation along X axis
308  * \param[in] y translation along Y axis
309  */
310  void
311  translatePen (double x, double y);
312 
313  /** \brief Create a rotation matrix and concatenate it with the current transformation.
314  * \param[in] angle angle in degrees
315  */
316  void
317  rotatePen(double angle);
318 
319  /** \brief Create a scale matrix and concatenate it with the current transformation.
320  * \param[in] x translation along X axis
321  * \param[in] y translation along Y axis
322  */
323  void
324  scalePen(double x, double y);
325 
326  /** \brief Create a translation matrix and concatenate it with the current transformation.
327  * \param[in] matrix the transformation matrix
328  */
329  void
330  setTransform(vtkMatrix3x3 *matrix);
331 
332  /** \brief Returns the current transformation matrix.
333  */
334  vtkMatrix3x3 *
335  getTransform();
336 
337  /** \brief Clears all the transformation applied. Sets the transformation matrix to Identity
338  */
339  void
340  clearTransform();
341 
342  /** \brief remove all the figures from the window
343  */
344  void
345  clearFigures();
346 
347  /** \brief set/get methods for current working vtkPen
348  */
349  void setPenColor (unsigned char r, unsigned char g, unsigned char b, unsigned char a);
350  void setPenWidth (float w);
351  void setPenType (int type);
352 
353  /** \brief set/get methods for current working vtkPen
354  */
355  unsigned char* getPenColor ();
356  float getPenWidth ();
357  int getPenType ();
358  void setPen (vtkPen *pen);
359  vtkPen* getPen ();
360 
361  /** \brief set/get methods for current working vtkBrush
362  */
363  void setBrush (vtkBrush *brush);
364  vtkBrush* getBrush ();
365  void setBrushColor (unsigned char r, unsigned char g, unsigned char b, unsigned char a);
366  unsigned char* getBrushColor ();
367 
368  /** \brief set/get method for the viewport's background color.
369  * \param[in] r the red component of the RGB color
370  * \param[in] g the green component of the RGB color
371  * \param[in] b the blue component of the RGB color
372  */
373  void
374  setBackgroundColor (const double r, const double g, const double b);
375 
376  /** \brief set/get method for the viewport's background color.
377  * \param [in] color the array containing the 3 component of the RGB color
378  */
379  void
380  setBackgroundColor (const double color[3]);
381 
382  /** \brief set/get method for the viewport's background color.
383  * \return [out] color the array containing the 3 component of the RGB color
384  */
385  double *
386  getBackgroundColor ();
387 
388 
389  /** \brief set/get method for the window size.
390  * \param[in] w the width of the window
391  * \param[in] h the height of the window
392  */
393  void
394  setWindowSize (int w, int h);
395 
396  /** \brief set/get method for the window size.
397  * \return[in] array containing the width and height of the window
398  */
399  int *
400  getWindowSize () const;
401 
402  /** \brief displays all the figures added in a window.
403  */
404  void display ();
405 
406  /** \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.
407  * \param[in] spin_time - How long (in ms) should the visualization loop be allowed to run.
408  */
409  void spinOnce ( const int spin_time = 0 );
410 
411  /** \brief spins (runs the event loop) the interactor indefinitely. Same as display() - added to retain the similarity between other existing visualization classes
412  */
413  void spin ();
414 
415  private:
416  //std::map< int, std::vector< std::vector<float> > > figures_; //FIG_TYPE -> std::vector<array>
417 
418  //All the figures drawn till now gets stored here
419  std::vector<Figure2D *> figures_;
420 
421  //state variables of the class
422  vtkPen *current_pen_;
423  vtkBrush *current_brush_;
424  vtkTransform2D *current_transform_;
425  int win_width_, win_height_;
426  double bkg_color_[3];
427 
428  vtkContextView *view_;
429 
430  //####event callback class####
431  struct ExitMainLoopTimerCallback : public vtkCommand
432  {
433  static ExitMainLoopTimerCallback* New ()
434  {
435  return (new ExitMainLoopTimerCallback);
436  }
437  void
438  Execute (vtkObject* vtkNotUsed (caller), unsigned long event_id, void* call_data) override
439  {
440  if (event_id != vtkCommand::TimerEvent)
441  return;
442  int timer_id = *(reinterpret_cast<int*> (call_data));
443 
444  if (timer_id != right_timer_id)
445  return;
446 
447  // Stop vtk loop and send notification to app to wake it up
448  interactor->TerminateApp ();
449  }
450  int right_timer_id;
451  vtkRenderWindowInteractor *interactor;
452  };
453 
454  /** \brief Callback object enabling us to leave the main loop, when a timer fires. */
456  };
457 
458  }
459 }
Figure2D(std::vector< float > info, vtkPen *p, vtkBrush *b, vtkTransform2D *t)
Definition: pcl_painter2D.h:78
vtkTransform2D * transform_
Definition: pcl_painter2D.h:76
FQuad2D(std::vector< float > info, vtkPen *p, vtkBrush *b, vtkTransform2D *t)
PCL Painter2D main class.
virtual void draw(vtkContext2D *)
void draw(vtkContext2D *painter) override
FPolyLine2D(std::vector< float > info, vtkPen *p, vtkBrush *b, vtkTransform2D *t)
Class for storing Points.
FPoints2D(std::vector< float > info, vtkPen *p, vtkBrush *b, vtkTransform2D *t)
void draw(vtkContext2D *painter) override
void applyInternals(vtkContext2D *painter) const
Class for storing Quads.
FEllipticArc2D(float x, float y, float rx, float ry, float sa, float ea, vtkPen *p, vtkBrush *b, vtkTransform2D *t)
void draw(vtkContext2D *painter) override
std::vector< float > info_
Definition: pcl_painter2D.h:73
FEllipticArc2D(std::vector< float > info, vtkPen *p, vtkBrush *b, vtkTransform2D *t)
void draw(vtkContext2D *painter) override
Figure2D(vtkPen *p, vtkBrush *b, vtkTransform2D *t)
Definition: pcl_painter2D.h:90
Class for storing EllipticArc; every ellipse , circle are covered by this.
Abstract class for storing figure information.
Definition: pcl_painter2D.h:71
void draw(vtkContext2D *painter) override
FPolygon2D(std::vector< float > info, vtkPen *p, vtkBrush *b, vtkTransform2D *t)