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 
39 #pragma once
40 
41 // PCL includes
42 #include <pcl/correspondence.h>
43 #include <pcl/ModelCoefficients.h>
44 #include <pcl/PolygonMesh.h>
45 #include <pcl/TextureMesh.h>
46 //
47 #include <pcl/console/print.h>
48 #include <pcl/visualization/common/actor_map.h>
49 #include <pcl/visualization/common/common.h>
50 #include <pcl/visualization/point_cloud_geometry_handlers.h>
51 #include <pcl/visualization/point_cloud_color_handlers.h>
52 #include <pcl/visualization/point_picking_event.h>
53 #include <pcl/visualization/area_picking_event.h>
54 #include <pcl/visualization/interactor_style.h>
55 
56 #include <vtkOrientationMarkerWidget.h>
57 #include <vtkRenderWindowInteractor.h>
58 
59 // VTK includes
60 class vtkPolyData;
61 class vtkTextActor;
62 class vtkRenderWindow;
63 class vtkAppendPolyData;
64 class vtkRenderWindow;
65 class vtkTransform;
66 class vtkInteractorStyle;
67 class vtkLODActor;
68 class vtkProp;
69 class vtkActor;
70 class vtkDataSet;
71 class vtkUnstructuredGrid;
72 class vtkCellArray;
73 
74 namespace pcl
75 {
76   template <typename T> class PointCloud;
77   template <typename T> class PlanarPolygon;
78 
79   namespace visualization
80   {
81     namespace details
82     {
83       PCL_EXPORTS vtkIdType fillCells(std::vector<int>& lookup, const std::vector<pcl::Vertices>& vertices, vtkSmartPointer<vtkCellArray> cell_array, int max_size_of_polygon);
84     }
85 
86     /** \brief PCL Visualizer main class.
87       * \author Radu B. Rusu
88       * \ingroup visualization
89       * \note This class can NOT be used across multiple threads. Only call functions of objects of this class
90       * from the same thread that they were created in! Some methods, e.g. addPointCloud, will crash if called
91       * from other threads.
92       */
93     class PCL_EXPORTS PCLVisualizer
94     {
95       public:
96         using Ptr = shared_ptr<PCLVisualizer>;
97         using ConstPtr = shared_ptr<const PCLVisualizer>;
98 
99         using GeometryHandler = PointCloudGeometryHandler<pcl::PCLPointCloud2>;
100         using GeometryHandlerPtr = GeometryHandler::Ptr;
101         using GeometryHandlerConstPtr = GeometryHandler::ConstPtr;
102 
103         using ColorHandler = PointCloudColorHandler<pcl::PCLPointCloud2>;
104         using ColorHandlerPtr = ColorHandler::Ptr;
105         using ColorHandlerConstPtr = ColorHandler::ConstPtr;
106 
107         /** \brief PCL Visualizer constructor.
108           * \param[in] name the window name (empty by default)
109           * \param[in] create_interactor if true (default), create an interactor, false otherwise
110           */
111         PCLVisualizer (const std::string &name = "", const bool create_interactor = true);
112 
113         /** \brief PCL Visualizer constructor. It looks through the passed argv arguments to find the "-cam *.cam" argument.
114           *        If the search failed, the name for cam file is calculated with boost uuid. If there is no such file, camera is not initilalized.
115           * \param[in] argc
116           * \param[in] argv
117           * \param[in] name the window name (empty by default)
118           * \param[in] style interactor style (defaults to PCLVisualizerInteractorStyle)
119           * \param[in] create_interactor if true (default), create an interactor, false otherwise
120           */
121         PCLVisualizer (int &argc, char **argv, const std::string &name = "",
122             PCLVisualizerInteractorStyle* style = PCLVisualizerInteractorStyle::New (), const bool create_interactor = true);
123 
124         /** \brief PCL Visualizer constructor.
125           * \param[in] ren custom vtk renderer
126           * \param[in] wind custom vtk render window
127           * \param[in] create_interactor if true (default), create an interactor, false otherwise
128           */
129         PCLVisualizer (vtkSmartPointer<vtkRenderer> ren, vtkSmartPointer<vtkRenderWindow> wind, const std::string &name = "", const bool create_interactor = true);
130 
131         /** \brief PCL Visualizer constructor.
132           * \param[in] argc
133           * \param[in] argv
134           * \param[in] ren custom vtk renderer
135           * \param[in] wind custom vtk render window
136           * \param[in] style interactor style (defaults to PCLVisualizerInteractorStyle)
137           * \param[in] create_interactor if true (default), create an interactor, false otherwise
138           */
139         PCLVisualizer (int &argc, char **argv, vtkSmartPointer<vtkRenderer> ren, vtkSmartPointer<vtkRenderWindow> wind, const std::string &name = "",
140                        PCLVisualizerInteractorStyle* style = PCLVisualizerInteractorStyle::New (),
141                        const bool create_interactor = true);
142 
143 
144         /** \brief PCL Visualizer destructor. */
145         virtual ~PCLVisualizer ();
146 
147         /** \brief Enables/Disabled the underlying window mode to full screen.
148           * \note This might or might not work, depending on your window manager.
149           * See the VTK documentation for additional details.
150           * \param[in] mode true for full screen, false otherwise
151           */
152         void
153         setFullScreen (bool mode);
154 
155         /** \brief Set the visualizer window name.
156           * \param[in] name the name of the window
157           */
158         void
159         setWindowName (const std::string &name);
160 
161         /** \brief Enables or disable the underlying window borders.
162           * \note This might or might not work, depending on your window manager.
163           * See the VTK documentation for additional details.
164           * \param[in] mode true for borders, false otherwise
165           */
166         void
167         setWindowBorders (bool mode);
168 
169         /** \brief Register a callback std::function for keyboard events
170           * \param[in] cb a std function that will be registered as a callback for a keyboard event
171           * \return a connection object that allows to disconnect the callback function.
172           */
173         boost::signals2::connection
174         registerKeyboardCallback (std::function<void (const pcl::visualization::KeyboardEvent&)> cb);
175 
176         /** \brief Register a callback function for keyboard events
177           * \param[in] callback  the function that will be registered as a callback for a keyboard event
178           * \param[in] cookie    user data that is passed to the callback
179           * \return a connection object that allows to disconnect the callback function.
180           */
181         inline boost::signals2::connection
182         registerKeyboardCallback (void (*callback) (const pcl::visualization::KeyboardEvent&, void*), void* cookie = nullptr)
183         {
184           return (registerKeyboardCallback ([=] (const pcl::visualization::KeyboardEvent& e) { (*callback) (e, cookie); }));
185         }
186 
187         /** \brief Register a callback function for keyboard events
188           * \param[in] callback  the member function that will be registered as a callback for a keyboard event
189           * \param[in] instance  instance to the class that implements the callback function
190           * \param[in] cookie    user data that is passed to the callback
191           * \return a connection object that allows to disconnect the callback function.
192           */
193         template<typename T> inline boost::signals2::connection
194         registerKeyboardCallback (void (T::*callback) (const pcl::visualization::KeyboardEvent&, void*), T& instance, void* cookie = nullptr)
195         {
196           return (registerKeyboardCallback ([=, &instance] (const pcl::visualization::KeyboardEvent& e) { (instance.*callback) (e, cookie); }));
197         }
198 
199         /** \brief Register a callback function for mouse events
200           * \param[in] cb a std function that will be registered as a callback for a mouse event
201           * \return a connection object that allows to disconnect the callback function.
202           */
203         boost::signals2::connection
204         registerMouseCallback (std::function<void (const pcl::visualization::MouseEvent&)> cb);
205 
206         /** \brief Register a callback function for mouse events
207           * \param[in] callback  the function that will be registered as a callback for a mouse event
208           * \param[in] cookie    user data that is passed to the callback
209           * \return a connection object that allows to disconnect the callback function.
210           */
211         inline boost::signals2::connection
212         registerMouseCallback (void (*callback) (const pcl::visualization::MouseEvent&, void*), void* cookie = nullptr)
213         {
214           return (registerMouseCallback ([=] (const pcl::visualization::MouseEvent& e) { (*callback) (e, cookie); }));
215         }
216 
217         /** \brief Register a callback function for mouse events
218           * \param[in] callback  the member function that will be registered as a callback for a mouse event
219           * \param[in] instance  instance to the class that implements the callback function
220           * \param[in] cookie    user data that is passed to the callback
221           * \return a connection object that allows to disconnect the callback function.
222           */
223         template<typename T> inline boost::signals2::connection
224         registerMouseCallback (void (T::*callback) (const pcl::visualization::MouseEvent&, void*), T& instance, void* cookie = nullptr)
225         {
226           return (registerMouseCallback ([=, &instance] (const pcl::visualization::MouseEvent& e) { (instance.*callback) (e, cookie); }));
227         }
228 
229         /** \brief Register a callback function for point picking events
230           * \param[in] cb a std function that will be registered as a callback for a point picking event
231           * \return a connection object that allows to disconnect the callback function.
232           */
233         boost::signals2::connection
234         registerPointPickingCallback (std::function<void (const pcl::visualization::PointPickingEvent&)> cb);
235 
236         /** \brief Register a callback function for point picking events
237           * \param[in] callback  the function that will be registered as a callback for a point picking event
238           * \param[in] cookie    user data that is passed to the callback
239           * \return a connection object that allows to disconnect the callback function.
240           */
241         boost::signals2::connection
242         registerPointPickingCallback (void (*callback) (const pcl::visualization::PointPickingEvent&, void*), void* cookie = nullptr);
243 
244         /** \brief Register a callback function for point picking events
245           * \param[in] callback  the member function that will be registered as a callback for a point picking event
246           * \param[in] instance  instance to the class that implements the callback function
247           * \param[in] cookie    user data that is passed to the callback
248           * \return a connection object that allows to disconnect the callback function.
249           */
250         template<typename T> inline boost::signals2::connection
251         registerPointPickingCallback (void (T::*callback) (const pcl::visualization::PointPickingEvent&, void*), T& instance, void* cookie = nullptr)
252         {
253           return (registerPointPickingCallback ([=, &instance] (const pcl::visualization::PointPickingEvent& e) { (instance.*callback) (e, cookie); }));
254         }
255 
256         /** \brief Register a callback function for area picking events
257           * \param[in] cb a std function that will be registered as a callback for an area picking event
258           * \return a connection object that allows to disconnect the callback function.
259           */
260         boost::signals2::connection
261         registerAreaPickingCallback (std::function<void (const pcl::visualization::AreaPickingEvent&)> cb);
262 
263         /** \brief Register a callback function for area picking events
264           * \param[in] callback  the function that will be registered as a callback for an area picking event
265           * \param[in] cookie    user data that is passed to the callback
266           * \return a connection object that allows to disconnect the callback function.
267           */
268         boost::signals2::connection
269         registerAreaPickingCallback (void (*callback) (const pcl::visualization::AreaPickingEvent&, void*), void* cookie = nullptr);
270 
271         /** \brief Register a callback function for area picking events
272           * \param[in] callback  the member function that will be registered as a callback for an area picking event
273           * \param[in] instance  instance to the class that implements the callback function
274           * \param[in] cookie    user data that is passed to the callback
275           * \return a connection object that allows to disconnect the callback function.
276           */
277         template<typename T> inline boost::signals2::connection
278         registerAreaPickingCallback (void (T::*callback) (const pcl::visualization::AreaPickingEvent&, void*), T& instance, void* cookie = nullptr)
279         {
280           return (registerAreaPickingCallback ([=, &instance] (const pcl::visualization::AreaPickingEvent& e) { (instance.*callback) (e, cookie); }));
281         }
282 
283         /** \brief Spin method. Calls the interactor and runs an internal loop. */
284         void
285         spin ();
286 
287         /** \brief Spin once method. Calls the interactor and updates the screen once.
288           *  \param[in] time - How long (in ms) should the visualization loop be allowed to run.
289           *  \param[in] force_redraw - if false it might return without doing anything if the
290           *  interactor's framerate does not require a redraw yet.
291           */
292         void
293         spinOnce (int time = 1, bool force_redraw = false);
294 
295         /** \brief Adds a widget which shows an interactive axes display for orientation
296          *  \param[in] interactor - Pointer to the vtk interactor object used by the PCLVisualizer window
297          */
298         void
299         addOrientationMarkerWidgetAxes (vtkRenderWindowInteractor* interactor);
300 
301         /** \brief Disables the Orientatation Marker Widget so it is removed from the renderer */
302         void
303         removeOrientationMarkerWidgetAxes ();
304 
305         /** \brief Adds 3D axes describing a coordinate system to screen at 0,0,0.
306           * \param[in] scale the scale of the axes (default: 1)
307           * \param[in] id the coordinate system object id (default: reference)
308           * \param[in] viewport the view port where the 3D axes should be added (default: all)
309           */
310         void
311         addCoordinateSystem (double scale = 1.0, const std::string& id = "reference", int viewport = 0);
312 
313         /** \brief Adds 3D axes describing a coordinate system to screen at x, y, z
314           * \param[in] scale the scale of the axes (default: 1)
315           * \param[in] x the X position of the axes
316           * \param[in] y the Y position of the axes
317           * \param[in] z the Z position of the axes
318           * \param[in] id the coordinate system object id (default: reference)
319           * \param[in] viewport the view port where the 3D axes should be added (default: all)
320           */
321         void
322         addCoordinateSystem (double scale, float x, float y, float z, const std::string &id = "reference", int viewport = 0);
323 
324          /** \brief Adds 3D axes describing a coordinate system to screen at x, y, z, Roll,Pitch,Yaw
325            *
326            * \param[in] scale the scale of the axes (default: 1)
327            * \param[in] t transformation matrix
328            * \param[in] id the coordinate system object id (default: reference)
329            * \param[in] viewport the view port where the 3D axes should be added (default: all)
330            *
331            * RPY Angles
332            * Rotate the reference frame by the angle roll about axis x
333            * Rotate the reference frame by the angle pitch about axis y
334            * Rotate the reference frame by the angle yaw about axis z
335            *
336            * Description:
337            * Sets the orientation of the Prop3D.  Orientation is specified as
338            * X,Y and Z rotations in that order, but they are performed as
339            * RotateZ, RotateX, and finally RotateY.
340            *
341            * All axies use right hand rule. x=red axis, y=green axis, z=blue axis
342            * z direction is point into the screen.
343            * \code
344            *     z
345            *      \
346            *       \
347            *        \
348            *         -----------> x
349            *         |
350            *         |
351            *         |
352            *         |
353            *         |
354            *         |
355            *         y
356            * \endcode
357            */
358 
359         void
360         addCoordinateSystem (double scale, const Eigen::Affine3f& t, const std::string &id = "reference", int viewport = 0);
361 
362         /** \brief Removes a previously added 3D axes (coordinate system)
363           * \param[in] id the coordinate system object id (default: reference)
364           * \param[in] viewport view port where the 3D axes should be removed from (default: all)
365           */
366         bool
367         removeCoordinateSystem (const std::string &id = "reference", int viewport = 0);
368 
369         /** \brief Removes a Point Cloud from screen, based on a given ID.
370           * \param[in] id the point cloud object id (i.e., given on \a addPointCloud)
371           * \param[in] viewport view port from where the Point Cloud should be removed (default: all)
372           * \return true if the point cloud is successfully removed and false if the point cloud is
373           * not actually displayed
374           */
375         bool
376         removePointCloud (const std::string &id = "cloud", int viewport = 0);
377 
378         /** \brief Removes a PolygonMesh from screen, based on a given ID.
379           * \param[in] id the polygon object id (i.e., given on \a addPolygonMesh)
380           * \param[in] viewport view port from where the PolygonMesh should be removed (default: all)
381           */
382         inline bool
383         removePolygonMesh (const std::string &id = "polygon", int viewport = 0)
384         {
385           // Polygon Meshes are represented internally as point clouds with special cell array structures since 1.4
386           return (removePointCloud (id, viewport));
387         }
388 
389         /** \brief Removes an added shape from screen (line, polygon, etc.), based on a given ID
390           * \note This methods also removes PolygonMesh objects and PointClouds, if they match the ID
391           * \param[in] id the shape object id (i.e., given on \a addLine etc.)
392           * \param[in] viewport view port from where the Point Cloud should be removed (default: all)
393           */
394         bool
395         removeShape (const std::string &id = "cloud", int viewport = 0);
396 
397         /** \brief Removes an added 3D text from the scene, based on a given ID
398           * \param[in] id the 3D text id (i.e., given on \a addText3D etc.)
399           * \param[in] viewport view port from where the 3D text should be removed (default: all)
400           */
401         bool
402         removeText3D (const std::string &id = "cloud", int viewport = 0);
403 
404         /** \brief Remove all point cloud data on screen from the given viewport.
405           * \param[in] viewport view port from where the clouds should be removed (default: all)
406           */
407         bool
408         removeAllPointClouds (int viewport = 0);
409 
410         /** \brief Remove all 3D shape data on screen from the given viewport.
411           * \param[in] viewport view port from where the shapes should be removed (default: all)
412           */
413         bool
414         removeAllShapes (int viewport = 0);
415 
416         /** \brief Removes  all existing 3D axes (coordinate systems)
417           * \param[in] viewport view port where the 3D axes should be removed from (default: all)
418           */
419         bool
420         removeAllCoordinateSystems (int viewport = 0);
421 
422         /** \brief Set the viewport's background color.
423           * \param[in] r the red component of the RGB color
424           * \param[in] g the green component of the RGB color
425           * \param[in] b the blue component of the RGB color
426           * \param[in] viewport the view port (default: all)
427           */
428         void
429         setBackgroundColor (const double &r, const double &g, const double &b, int viewport = 0);
430 
431         /** \brief Add a text to screen
432           * \param[in] text the text to add
433           * \param[in] xpos the X position on screen where the text should be added
434           * \param[in] ypos the Y position on screen where the text should be added
435           * \param[in] id the text object id (default: equal to the "text" parameter)
436           * \param[in] viewport the view port (default: all)
437           */
438         bool
439         addText (const std::string &text,
440                  int xpos, int ypos,
441                  const std::string &id = "", int viewport = 0);
442 
443         /** \brief Add a text to screen
444           * \param[in] text the text to add
445           * \param[in] xpos the X position on screen where the text should be added
446           * \param[in] ypos the Y position on screen where the text should be added
447           * \param[in] r the red color value
448           * \param[in] g the green color value
449           * \param[in] b the blue color value
450           * \param[in] id the text object id (default: equal to the "text" parameter)
451           * \param[in] viewport the view port (default: all)
452           */
453         bool
454         addText (const std::string &text, int xpos, int ypos, double r, double g, double b,
455                  const std::string &id = "", int viewport = 0);
456 
457         /** \brief Add a text to screen
458           * \param[in] text the text to add
459           * \param[in] xpos the X position on screen where the text should be added
460           * \param[in] ypos the Y position on screen where the text should be added
461           * \param[in] fontsize the fontsize of the text
462           * \param[in] r the red color value
463           * \param[in] g the green color value
464           * \param[in] b the blue color value
465           * \param[in] id the text object id (default: equal to the "text" parameter)
466           * \param[in] viewport the view port (default: all)
467           */
468         bool
469         addText (const std::string &text, int xpos, int ypos, int fontsize, double r, double g, double b,
470                  const std::string &id = "", int viewport = 0);
471 
472 
473         /** \brief Update a text to screen
474           * \param[in] text the text to update
475           * \param[in] xpos the new X position on screen
476           * \param[in] ypos the new Y position on screen
477           * \param[in] id the text object id (default: equal to the "text" parameter)
478           */
479         bool
480         updateText (const std::string &text,
481                     int xpos, int ypos,
482                     const std::string &id = "");
483 
484         /** \brief Update a text to screen
485           * \param[in] text the text to update
486           * \param[in] xpos the new X position on screen
487           * \param[in] ypos the new Y position on screen
488           * \param[in] r the red color value
489           * \param[in] g the green color value
490           * \param[in] b the blue color value
491           * \param[in] id the text object id (default: equal to the "text" parameter)
492           */
493         bool
494         updateText (const std::string &text,
495                     int xpos, int ypos, double r, double g, double b,
496                     const std::string &id = "");
497 
498         /** \brief Update a text to screen
499           * \param[in] text the text to update
500           * \param[in] xpos the new X position on screen
501           * \param[in] ypos the new Y position on screen
502           * \param[in] fontsize the fontsize of the text
503           * \param[in] r the red color value
504           * \param[in] g the green color value
505           * \param[in] b the blue color value
506           * \param[in] id the text object id (default: equal to the "text" parameter)
507           */
508         bool
509         updateText (const std::string &text,
510                     int xpos, int ypos, int fontsize, double r, double g, double b,
511                     const std::string &id = "");
512 
513         /** \brief Set the pose of an existing shape.
514           *
515           * Returns false if the shape doesn't exist, true if the pose was successfully
516           * updated.
517           *
518           * \param[in] id the shape or cloud object id (i.e., given on \a addLine etc.)
519           * \param[in] pose the new pose
520           * \return false if no shape or cloud with the specified ID was found
521           */
522         bool
523         updateShapePose (const std::string &id, const Eigen::Affine3f& pose);
524 
525         /** \brief Set the pose of an existing coordinate system.
526           *
527           * Returns false if the coordinate system doesn't exist, true if the pose was successfully
528           * updated.
529           *
530           * \param[in] id the point cloud object id (i.e., given on \a addCoordinateSystem etc.)
531           * \param[in] pose the new pose
532           * \return false if no coordinate system with the specified ID was found
533           */
534         bool
535         updateCoordinateSystemPose (const std::string &id, const Eigen::Affine3f& pose);
536 
537         /** \brief Set the pose of an existing point cloud.
538           *
539           * Returns false if the point cloud doesn't exist, true if the pose was successfully
540           * updated.
541           *
542           * \param[in] id the point cloud object id (i.e., given on \a addPointCloud etc.)
543           * \param[in] pose the new pose
544           * \return false if no point cloud with the specified ID was found
545           */
546         bool
547         updatePointCloudPose (const std::string &id, const Eigen::Affine3f& pose);
548 
549         /** \brief Add a 3d text to the scene
550           * \param[in] text the text to add
551           * \param[in] position the world position where the text should be added
552           * \param[in] textScale the scale of the text to render
553           * \param[in] r the red color value
554           * \param[in] g the green color value
555           * \param[in] b the blue color value
556           * \param[in] id the text object id (default: equal to the "text" parameter)
557           * \param[in] viewport the view port (default: all)
558           */
559         template <typename PointT> bool
560         addText3D (const std::string &text,
561                    const PointT &position,
562                    double textScale = 1.0,
563                    double r = 1.0, double g = 1.0, double b = 1.0,
564                    const std::string &id = "", int viewport = 0);
565 
566         /** \brief Add a 3d text to the scene
567           * \param[in] text the text to add
568           * \param[in] position the world position where the text should be added
569           * \param[in] orientation the angles of rotation of the text around X, Y and Z axis,
570                        in this order. The way the rotations are effectively done is the
571                        Z-X-Y intrinsic rotations:
572                        https://en.wikipedia.org/wiki/Euler_angles#Definition_by_intrinsic_rotations
573           * \param[in] textScale the scale of the text to render
574           * \param[in] r the red color value
575           * \param[in] g the green color value
576           * \param[in] b the blue color value
577           * \param[in] id the text object id (default: equal to the "text" parameter)
578           * \param[in] viewport the view port (default: all)
579           */
580         template <typename PointT> bool
581         addText3D (const std::string &text,
582                    const PointT &position,
583                    double orientation[3],
584                    double textScale = 1.0,
585                    double r = 1.0, double g = 1.0, double b = 1.0,
586                    const std::string &id = "", int viewport = 0);
587 
588         /** \brief Check if the cloud, shape, or coordinate with the given id was already added to this visualizer.
589           * \param[in] id the id of the cloud, shape, or coordinate to check
590           * \return true if a cloud, shape, or coordinate with the specified id was found
591           */
592         inline bool
contains(const std::string & id)593         contains(const std::string &id) const
594         {
595           return (cloud_actor_map_->find (id) != cloud_actor_map_->end () ||
596                   shape_actor_map_->find (id) != shape_actor_map_->end () ||
597                   coordinate_actor_map_->find (id) != coordinate_actor_map_-> end());
598         }
599 
600         /** \brief Add the estimated surface normals of a Point Cloud to screen.
601           * \param[in] cloud the input point cloud dataset containing XYZ data and normals
602           * \param[in] level display only every level'th point (default: 100)
603           * \param[in] scale the normal arrow scale (default: 0.02m)
604           * \param[in] id the point cloud object id (default: cloud)
605           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
606           */
607         template <typename PointNT> bool
608         addPointCloudNormals (const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
609                               int level = 100, float scale = 0.02f,
610                               const std::string &id = "cloud", int viewport = 0);
611 
612         /** \brief Add the estimated surface normals of a Point Cloud to screen.
613           * \param[in] cloud the input point cloud dataset containing the XYZ data
614           * \param[in] normals the input point cloud dataset containing the normal data
615           * \param[in] level display only every level'th point (default: 100)
616           * \param[in] scale the normal arrow scale (default: 0.02m)
617           * \param[in] id the point cloud object id (default: cloud)
618           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
619           */
620         template <typename PointT, typename PointNT> bool
621         addPointCloudNormals (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
622                               const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
623                               int level = 100, float scale = 0.02f,
624                               const std::string &id = "cloud", int viewport = 0);
625 
626         /** \brief Add the estimated principal curvatures of a Point Cloud to screen.
627           * \param[in] cloud the input point cloud dataset containing the XYZ data and normals
628           * \param[in] pcs the input point cloud dataset containing the principal curvatures data
629           * \param[in] level display only every level'th point. Default: 100
630           * \param[in] scale the normal arrow scale. Default: 1.0
631           * \param[in] id the point cloud object id. Default: "cloud"
632           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
633           */
634         template <typename PointNT> bool
635         addPointCloudPrincipalCurvatures (
636             const typename pcl::PointCloud<PointNT>::ConstPtr &cloud,
637             const typename pcl::PointCloud<pcl::PrincipalCurvatures>::ConstPtr &pcs,
638             int level = 100, float scale = 1.0f,
639             const std::string &id = "cloud", int viewport = 0);
640 
641         /** \brief Add the estimated principal curvatures of a Point Cloud to screen.
642           * \param[in] cloud the input point cloud dataset containing the XYZ data
643           * \param[in] normals the input point cloud dataset containing the normal data
644           * \param[in] pcs the input point cloud dataset containing the principal curvatures data
645           * \param[in] level display only every level'th point. Default: 100
646           * \param[in] scale the normal arrow scale. Default: 1.0
647           * \param[in] id the point cloud object id. Default: "cloud"
648           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
649           */
650         template <typename PointT, typename PointNT> bool
651         addPointCloudPrincipalCurvatures (
652             const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
653             const typename pcl::PointCloud<PointNT>::ConstPtr &normals,
654             const pcl::PointCloud<pcl::PrincipalCurvatures>::ConstPtr &pcs,
655             int level = 100, float scale = 1.0f,
656             const std::string &id = "cloud", int viewport = 0);
657 
658         /** \brief Add the estimated surface intensity gradients of a Point Cloud to screen.
659           * \param[in] cloud the input point cloud dataset containing the XYZ data
660           * \param[in] gradients the input point cloud dataset containing the intensity gradient data
661           * \param[in] level display only every level'th point (default: 100)
662           * \param[in] scale the intensity gradient arrow scale (default: 1e-6m)
663           * \param[in] id the point cloud object id (default: cloud)
664           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
665           */
666         template <typename PointT, typename GradientT> bool
667         addPointCloudIntensityGradients (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
668                                          const typename pcl::PointCloud<GradientT>::ConstPtr &gradients,
669                                          int level = 100, double scale = 1e-6,
670                                          const std::string &id = "cloud", int viewport = 0);
671 
672         /** \brief Add a Point Cloud (templated) to screen.
673           * \param[in] cloud the input point cloud dataset
674           * \param[in] id the point cloud object id (default: cloud)
675           * \param viewport the view port where the Point Cloud should be added (default: all)
676           */
677         template <typename PointT> bool
678         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
679                        const std::string &id = "cloud", int viewport = 0);
680 
681         /** \brief Updates the XYZ data for an existing cloud object id on screen.
682           * \param[in] cloud the input point cloud dataset
683           * \param[in] id the point cloud object id to update (default: cloud)
684           * \return false if no cloud with the specified ID was found
685           */
686         template <typename PointT> bool
687         updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
688                           const std::string &id = "cloud");
689 
690          /** \brief Updates the XYZ data for an existing cloud object id on screen.
691            * \param[in] cloud the input point cloud dataset
692            * \param[in] geometry_handler the geometry handler to use
693            * \param[in] id the point cloud object id to update (default: cloud)
694            * \return false if no cloud with the specified ID was found
695            */
696         template <typename PointT> bool
697         updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
698                           const PointCloudGeometryHandler<PointT> &geometry_handler,
699                           const std::string &id = "cloud");
700 
701          /** \brief Updates the XYZ data for an existing cloud object id on screen.
702            * \param[in] cloud the input point cloud dataset
703            * \param[in] color_handler the color handler to use
704            * \param[in] id the point cloud object id to update (default: cloud)
705            * \return false if no cloud with the specified ID was found
706            */
707         template <typename PointT> bool
708         updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
709                           const PointCloudColorHandler<PointT> &color_handler,
710                           const std::string &id = "cloud");
711 
712         /** \brief Add a Point Cloud (templated) to screen.
713           * \param[in] cloud the input point cloud dataset
714           * \param[in] geometry_handler use a geometry handler object to extract the XYZ data
715           * \param[in] id the point cloud object id (default: cloud)
716           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
717           */
718         template <typename PointT> bool
719         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
720                        const PointCloudGeometryHandler<PointT> &geometry_handler,
721                        const std::string &id = "cloud", int viewport = 0);
722 
723         /** \brief Add a Point Cloud (templated) to screen.
724           *
725           * Because the geometry handler is given as a pointer, it will be pushed back to the list of available
726           * handlers, rather than replacing the current active geometric handler. This makes it possible to
727           * switch between different geometric handlers 'on-the-fly' at runtime, from the PCLVisualizer
728           * interactor interface (using Alt+0..9).
729           *
730           * \param[in] cloud the input point cloud dataset
731           * \param[in] geometry_handler use a geometry handler object to extract the XYZ data
732           * \param[in] id the point cloud object id (default: cloud)
733           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
734           */
735         template <typename PointT> bool
736         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
737                        const GeometryHandlerConstPtr &geometry_handler,
738                        const std::string &id = "cloud", int viewport = 0);
739 
740         /** \brief Add a Point Cloud (templated) to screen.
741           * \param[in] cloud the input point cloud dataset
742           * \param[in] color_handler a specific PointCloud visualizer handler for colors
743           * \param[in] id the point cloud object id (default: cloud)
744           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
745           */
746         template <typename PointT> bool
747         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
748                        const PointCloudColorHandler<PointT> &color_handler,
749                        const std::string &id = "cloud", int viewport = 0);
750 
751         /** \brief Add a Point Cloud (templated) to screen.
752           *
753           * Because the color handler is given as a pointer, it will be pushed back to the list of available
754           * handlers, rather than replacing the current active color handler. This makes it possible to
755           * switch between different color handlers 'on-the-fly' at runtime, from the PCLVisualizer
756           * interactor interface (using 0..9).
757           *
758           * \param[in] cloud the input point cloud dataset
759           * \param[in] color_handler a specific PointCloud visualizer handler for colors
760           * \param[in] id the point cloud object id (default: cloud)
761           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
762           */
763         template <typename PointT> bool
764         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
765                        const ColorHandlerConstPtr &color_handler,
766                        const std::string &id = "cloud", int viewport = 0);
767 
768         /** \brief Add a Point Cloud (templated) to screen.
769           *
770           * Because the geometry/color handler is given as a pointer, it will be pushed back to the list of
771           * available handlers, rather than replacing the current active handler. This makes it possible to
772           * switch between different handlers 'on-the-fly' at runtime, from the PCLVisualizer interactor
773           * interface (using [Alt+]0..9).
774           *
775           * \param[in] cloud the input point cloud dataset
776           * \param[in] geometry_handler a specific PointCloud visualizer handler for geometry
777           * \param[in] color_handler a specific PointCloud visualizer handler for colors
778           * \param[in] id the point cloud object id (default: cloud)
779           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
780           */
781         template <typename PointT> bool
782         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
783                        const GeometryHandlerConstPtr &geometry_handler,
784                        const ColorHandlerConstPtr &color_handler,
785                        const std::string &id = "cloud", int viewport = 0);
786 
787         /** \brief Add a binary blob Point Cloud to screen.
788           *
789           * Because the geometry/color handler is given as a pointer, it will be pushed back to the list of
790           * available handlers, rather than replacing the current active handler. This makes it possible to
791           * switch between different handlers 'on-the-fly' at runtime, from the PCLVisualizer interactor
792           * interface (using [Alt+]0..9).
793           *
794           * \param[in] cloud the input point cloud dataset
795           * \param[in] geometry_handler a specific PointCloud visualizer handler for geometry
796           * \param[in] color_handler a specific PointCloud visualizer handler for colors
797           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
798           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
799           * \param[in] id the point cloud object id (default: cloud)
800           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
801           */
802         bool
803         addPointCloud (const pcl::PCLPointCloud2::ConstPtr &cloud,
804                        const GeometryHandlerConstPtr &geometry_handler,
805                        const ColorHandlerConstPtr &color_handler,
806                        const Eigen::Vector4f& sensor_origin,
807                        const Eigen::Quaternion<float>& sensor_orientation,
808                        const std::string &id = "cloud", int viewport = 0);
809 
810         /** \brief Add a binary blob Point Cloud to screen.
811           *
812           * Because the geometry/color handler is given as a pointer, it will be pushed back to the list of
813           * available handlers, rather than replacing the current active handler. This makes it possible to
814           * switch between different handlers 'on-the-fly' at runtime, from the PCLVisualizer interactor
815           * interface (using [Alt+]0..9).
816           *
817           * \param[in] cloud the input point cloud dataset
818           * \param[in] geometry_handler a specific PointCloud visualizer handler for geometry
819           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
820           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
821           * \param[in] id the point cloud object id (default: cloud)
822           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
823           */
824         bool
825         addPointCloud (const pcl::PCLPointCloud2::ConstPtr &cloud,
826                        const GeometryHandlerConstPtr &geometry_handler,
827                        const Eigen::Vector4f& sensor_origin,
828                        const Eigen::Quaternion<float>& sensor_orientation,
829                        const std::string &id = "cloud", int viewport = 0);
830 
831         /** \brief Add a binary blob Point Cloud to screen.
832           *
833           * Because the geometry/color handler is given as a pointer, it will be pushed back to the list of
834           * available handlers, rather than replacing the current active handler. This makes it possible to
835           * switch between different handlers 'on-the-fly' at runtime, from the PCLVisualizer interactor
836           * interface (using [Alt+]0..9).
837           *
838           * \param[in] cloud the input point cloud dataset
839           * \param[in] color_handler a specific PointCloud visualizer handler for colors
840           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
841           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
842           * \param[in] id the point cloud object id (default: cloud)
843           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
844           */
845         bool
846         addPointCloud (const pcl::PCLPointCloud2::ConstPtr &cloud,
847                        const ColorHandlerConstPtr &color_handler,
848                        const Eigen::Vector4f& sensor_origin,
849                        const Eigen::Quaternion<float>& sensor_orientation,
850                        const std::string &id = "cloud", int viewport = 0);
851 
852         /** \brief Add a Point Cloud (templated) to screen.
853           * \param[in] cloud the input point cloud dataset
854           * \param[in] color_handler a specific PointCloud visualizer handler for colors
855           * \param[in] geometry_handler use a geometry handler object to extract the XYZ data
856           * \param[in] id the point cloud object id (default: cloud)
857           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
858           */
859         template <typename PointT> bool
860         addPointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
861                        const PointCloudColorHandler<PointT> &color_handler,
862                        const PointCloudGeometryHandler<PointT> &geometry_handler,
863                        const std::string &id = "cloud", int viewport = 0);
864 
865         /** \brief Add a PointXYZ Point Cloud to screen.
866           * \param[in] cloud the input point cloud dataset
867           * \param[in] id the point cloud object id (default: cloud)
868           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
869           */
870         inline bool
871         addPointCloud (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud,
872                        const std::string &id = "cloud", int viewport = 0)
873         {
874           return (addPointCloud<pcl::PointXYZ> (cloud, id, viewport));
875         }
876 
877 
878         /** \brief Add a PointXYZRGB Point Cloud to screen.
879           * \param[in] cloud the input point cloud dataset
880           * \param[in] id the point cloud object id (default: cloud)
881           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
882           */
883         inline bool
884         addPointCloud (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud,
885                        const std::string &id = "cloud", int viewport = 0)
886         {
887           pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> color_handler (cloud);
888           return (addPointCloud<pcl::PointXYZRGB> (cloud, color_handler, id, viewport));
889         }
890 
891         /** \brief Add a PointXYZRGBA Point Cloud to screen.
892           * \param[in] cloud the input point cloud dataset
893           * \param[in] id the point cloud object id (default: cloud)
894           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
895           */
896         inline bool
897         addPointCloud (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud,
898                        const std::string &id = "cloud", int viewport = 0)
899         {
900           pcl::visualization::PointCloudColorHandlerRGBAField<pcl::PointXYZRGBA> color_handler (cloud);
901           return (addPointCloud<pcl::PointXYZRGBA> (cloud, color_handler, id, viewport));
902         }
903 
904         /** \brief Add a PointXYZL Point Cloud to screen.
905           * \param[in] cloud the input point cloud dataset
906           * \param[in] id the point cloud object id (default: cloud)
907           * \param[in] viewport the view port where the Point Cloud should be added (default: all)
908           */
909         inline bool
910         addPointCloud (const pcl::PointCloud<pcl::PointXYZL>::ConstPtr &cloud,
911                        const std::string &id = "cloud", int viewport = 0)
912         {
913           pcl::visualization::PointCloudColorHandlerLabelField<pcl::PointXYZL> color_handler (cloud);
914           return (addPointCloud<pcl::PointXYZL> (cloud, color_handler, id, viewport));
915         }
916 
917         /** \brief Updates the XYZ data for an existing cloud object id on screen.
918           * \param[in] cloud the input point cloud dataset
919           * \param[in] id the point cloud object id to update (default: cloud)
920           * \return false if no cloud with the specified ID was found
921           */
922         inline bool
923         updatePointCloud (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud,
924                           const std::string &id = "cloud")
925         {
926           return (updatePointCloud<pcl::PointXYZ> (cloud, id));
927         }
928 
929         /** \brief Updates the XYZRGB data for an existing cloud object id on screen.
930           * \param[in] cloud the input point cloud dataset
931           * \param[in] id the point cloud object id to update (default: cloud)
932           * \return false if no cloud with the specified ID was found
933           */
934         inline bool
935         updatePointCloud (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud,
936                           const std::string &id = "cloud")
937         {
938           pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> color_handler (cloud);
939           return (updatePointCloud<pcl::PointXYZRGB> (cloud, color_handler, id));
940         }
941 
942         /** \brief Updates the XYZRGBA data for an existing cloud object id on screen.
943           * \param[in] cloud the input point cloud dataset
944           * \param[in] id the point cloud object id to update (default: cloud)
945           * \return false if no cloud with the specified ID was found
946           */
947         inline bool
948         updatePointCloud (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud,
949                           const std::string &id = "cloud")
950         {
951           pcl::visualization::PointCloudColorHandlerRGBAField<pcl::PointXYZRGBA> color_handler (cloud);
952           return (updatePointCloud<pcl::PointXYZRGBA> (cloud, color_handler, id));
953         }
954 
955         /** \brief Updates the XYZL data for an existing cloud object id on screen.
956           * \param[in] cloud the input point cloud dataset
957           * \param[in] id the point cloud object id to update (default: cloud)
958           * \return false if no cloud with the specified ID was found
959           */
960         inline bool
961         updatePointCloud (const pcl::PointCloud<pcl::PointXYZL>::ConstPtr &cloud,
962                           const std::string &id = "cloud")
963         {
964           pcl::visualization::PointCloudColorHandlerLabelField<pcl::PointXYZL> color_handler (cloud);
965           return (updatePointCloud<pcl::PointXYZL> (cloud, color_handler, id));
966         }
967 
968         /** \brief Add a PolygonMesh object to screen
969           * \param[in] polymesh the polygonal mesh
970           * \param[in] id the polygon object id (default: "polygon")
971           * \param[in] viewport the view port where the PolygonMesh should be added (default: all)
972           */
973         bool
974         addPolygonMesh (const pcl::PolygonMesh &polymesh,
975                         const std::string &id = "polygon",
976                         int viewport = 0);
977 
978         /** \brief Add a PolygonMesh object to screen
979           * \param[in] cloud the polygonal mesh point cloud
980           * \param[in] vertices the polygonal mesh vertices
981           * \param[in] id the polygon object id (default: "polygon")
982           * \param[in] viewport the view port where the PolygonMesh should be added (default: all)
983           */
984         template <typename PointT> bool
985         addPolygonMesh (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
986                         const std::vector<pcl::Vertices> &vertices,
987                         const std::string &id = "polygon",
988                         int viewport = 0);
989 
990         /** \brief Update a PolygonMesh object on screen
991           * \param[in] cloud the polygonal mesh point cloud
992           * \param[in] vertices the polygonal mesh vertices
993           * \param[in] id the polygon object id (default: "polygon")
994           * \return false if no polygonmesh with the specified ID was found
995           */
996         template <typename PointT> bool
997         updatePolygonMesh (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
998                            const std::vector<pcl::Vertices> &vertices,
999                            const std::string &id = "polygon");
1000 
1001         /** \brief Update a PolygonMesh object on screen
1002           * \param[in] polymesh the polygonal mesh
1003           * \param[in] id the polygon object id (default: "polygon")
1004           * \return false if no polygonmesh with the specified ID was found
1005           */
1006         bool
1007         updatePolygonMesh (const pcl::PolygonMesh &polymesh,
1008                            const std::string &id = "polygon");
1009 
1010         /** \brief Add a Polygonline from a polygonMesh object to screen
1011           * \param[in] polymesh the polygonal mesh from where the polylines will be extracted
1012           * \param[in] id the polygon object id (default: "polygon")
1013           * \param[in] viewport the view port where the PolygonMesh should be added (default: all)
1014           */
1015         bool
1016         addPolylineFromPolygonMesh (const pcl::PolygonMesh &polymesh,
1017                                     const std::string &id = "polyline",
1018                                     int viewport = 0);
1019 
1020         /** \brief Add the specified correspondences to the display.
1021           * \param[in] source_points The source points
1022           * \param[in] target_points The target points
1023           * \param[in] correspondences The mapping from source points to target points. Each element must be an index into target_points
1024           * \param[in] id the polygon object id (default: "correspondences")
1025           * \param[in] viewport the view port where the correspondences should be added (default: all)
1026           */
1027         template <typename PointT> bool
1028         addCorrespondences (const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1029                             const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1030                             const std::vector<int> & correspondences,
1031                             const std::string &id = "correspondences",
1032                             int viewport = 0);
1033 
1034         /** \brief Add a TextureMesh object to screen
1035           * \param[in] polymesh the textured polygonal mesh
1036           * \param[in] id the texture mesh object id (default: "texture")
1037           * \param[in] viewport the view port where the TextureMesh should be added (default: all)
1038           */
1039         bool
1040         addTextureMesh (const pcl::TextureMesh &polymesh,
1041                         const std::string &id = "texture",
1042                         int viewport = 0);
1043 
1044         /** \brief Add the specified correspondences to the display.
1045           * \param[in] source_points The source points
1046           * \param[in] target_points The target points
1047           * \param[in] correspondences The mapping from source points to target points. Each element must be an index into target_points
1048           * \param[in] nth display only the Nth correspondence (e.g., skip the rest)
1049           * \param[in] id the polygon object id (default: "correspondences")
1050           * \param[in] viewport the view port where the correspondences should be added (default: all)
1051           * \param[in] overwrite allow to overwrite already existing correspondences
1052           */
1053         template <typename PointT> bool
1054         addCorrespondences (const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1055                             const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1056                             const pcl::Correspondences &correspondences,
1057                             int nth,
1058                             const std::string &id = "correspondences",
1059                             int viewport = 0,
1060                             bool overwrite = false);
1061 
1062         /** \brief Add the specified correspondences to the display.
1063           * \param[in] source_points The source points
1064           * \param[in] target_points The target points
1065           * \param[in] correspondences The mapping from source points to target points. Each element must be an index into target_points
1066           * \param[in] id the polygon object id (default: "correspondences")
1067           * \param[in] viewport the view port where the correspondences should be added (default: all)
1068           */
1069         template <typename PointT> bool
1070         addCorrespondences (const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1071                             const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1072                             const pcl::Correspondences &correspondences,
1073                             const std::string &id = "correspondences",
1074                             int viewport = 0)
1075         {
1076           // If Nth not given, display all correspondences
1077           return (addCorrespondences<PointT> (source_points, target_points,
1078                                               correspondences, 1, id, viewport));
1079         }
1080 
1081         /** \brief Update the specified correspondences to the display.
1082           * \param[in] source_points The source points
1083           * \param[in] target_points The target points
1084           * \param[in] correspondences The mapping from source points to target points. Each element must be an index into target_points
1085           * \param[in] nth display only the Nth correspondence (e.g., skip the rest)
1086           * \param[in] id the polygon object id (default: "correspondences")
1087           * \param[in] viewport the view port where the correspondences should be updated (default: all)
1088           */
1089         template <typename PointT> bool
1090         updateCorrespondences (
1091             const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1092             const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1093             const pcl::Correspondences &correspondences,
1094             int nth,
1095             const std::string &id = "correspondences",
1096             int viewport = 0);
1097 
1098         /** \brief Update the specified correspondences to the display.
1099           * \param[in] source_points The source points
1100           * \param[in] target_points The target points
1101           * \param[in] correspondences The mapping from source points to target points. Each element must be an index into target_points
1102           * \param[in] id the polygon object id (default: "correspondences")
1103           * \param[in] viewport the view port where the correspondences should be updated (default: all)
1104           */
1105         template <typename PointT> bool
1106         updateCorrespondences (
1107             const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
1108             const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
1109             const pcl::Correspondences &correspondences,
1110             const std::string &id = "correspondences",
1111             int viewport = 0)
1112         {
1113           // If Nth not given, display all correspondences
1114           return (updateCorrespondences<PointT> (source_points, target_points,
1115                                               correspondences, 1, id, viewport));
1116         }
1117 
1118         /** \brief Remove the specified correspondences from the display.
1119           * \param[in] id the polygon correspondences object id (i.e., given on \ref addCorrespondences)
1120           * \param[in] viewport view port from where the correspondences should be removed (default: all)
1121           */
1122         void
1123         removeCorrespondences (const std::string &id = "correspondences", int viewport = 0);
1124 
1125         /** \brief Get the color handler index of a rendered PointCloud based on its ID
1126           * \param[in] id the point cloud object id
1127           */
1128         int
1129         getColorHandlerIndex (const std::string &id);
1130 
1131         /** \brief Get the geometry handler index of a rendered PointCloud based on its ID
1132           * \param[in] id the point cloud object id
1133           */
1134         int
1135         getGeometryHandlerIndex (const std::string &id);
1136 
1137         /** \brief Update/set the color index of a rendered PointCloud based on its ID
1138           * \param[in] id the point cloud object id
1139           * \param[in] index the color handler index to use
1140           */
1141         bool
1142         updateColorHandlerIndex (const std::string &id, int index);
1143 
1144         /** \brief Set the rendering properties of a PointCloud (3x values - e.g., RGB)
1145           * \param[in] property the property type
1146           * \param[in] val1 the first value to be set
1147           * \param[in] val2 the second value to be set
1148           * \param[in] val3 the third value to be set
1149           * \param[in] id the point cloud object id (default: cloud)
1150           * \param[in] viewport the view port where the Point Cloud's rendering properties should be modified (default: all)
1151           * \note The list of properties can be found in \ref pcl::visualization::LookUpTableRepresentationProperties.
1152           */
1153         bool
1154         setPointCloudRenderingProperties (int property, double val1, double val2, double val3,
1155                                           const std::string &id = "cloud", int viewport = 0);
1156 
1157         /** \brief Set the rendering properties of a PointCloud (2x values - e.g., LUT minmax values)
1158           * \param[in] property the property type
1159           * \param[in] val1 the first value to be set
1160           * \param[in] val2 the second value to be set
1161           * \param[in] id the point cloud object id (default: cloud)
1162           * \param[in] viewport the view port where the Point Cloud's rendering properties should be modified (default: all)
1163           * \note The list of properties can be found in \ref pcl::visualization::LookUpTableRepresentationProperties.
1164           */
1165         bool
1166         setPointCloudRenderingProperties (int property, double val1, double val2,
1167                                           const std::string &id = "cloud", int viewport = 0);
1168 
1169        /** \brief Set the rendering properties of a PointCloud
1170          * \param[in] property the property type
1171          * \param[in] value the value to be set
1172          * \param[in] id the point cloud object id (default: cloud)
1173          * \param[in] viewport the view port where the Point Cloud's rendering properties should be modified (default: all)
1174          * \note The list of properties can be found in \ref pcl::visualization::LookUpTableRepresentationProperties.
1175          */
1176         bool
1177         setPointCloudRenderingProperties (int property, double value,
1178                                           const std::string &id = "cloud", int viewport = 0);
1179 
1180        /** \brief Get the rendering properties of a PointCloud
1181          * \param[in] property the property type
1182          * \param[in] value the resultant property value
1183          * \param[in] id the point cloud object id (default: cloud)
1184          * \note The list of properties can be found in \ref pcl::visualization::LookUpTableRepresentationProperties.
1185          */
1186         bool
1187         getPointCloudRenderingProperties (int property, double &value,
1188                                           const std::string &id = "cloud");
1189 
1190        /** \brief Get the rendering properties of a PointCloud
1191          * \param[in] property the property type
1192          * \param[out] val1 the resultant property value
1193          * \param[out] val2 the resultant property value
1194          * \param[out] val3 the resultant property value
1195          * \param[in] id the point cloud object id (default: cloud)
1196          * \return True if the property is effectively retrieved.
1197          * \note The list of properties can be found in \ref pcl::visualization::LookUpTableRepresentationProperties.
1198          */
1199         bool
1200         getPointCloudRenderingProperties (RenderingProperties property, double &val1, double &val2, double &val3,
1201                                           const std::string &id = "cloud");
1202 
1203         /** \brief Set whether the point cloud is selected or not
1204          *  \param[in] selected whether the cloud is selected or not (true = selected)
1205          *  \param[in] id the point cloud object id (default: cloud)
1206          */
1207         bool
1208         setPointCloudSelected (const bool selected, const std::string &id = "cloud" );
1209 
1210        /** \brief Set the rendering properties of a shape
1211          * \param[in] property the property type
1212          * \param[in] value the value to be set
1213          * \param[in] id the shape object id
1214          * \param[in] viewport the view port where the shape's properties should be modified (default: all)
1215          * \note When using \ref addPolygonMesh you you should use \ref setPointCloudRenderingProperties
1216          * \note The list of properties can be found in \ref pcl::visualization::LookUpTableRepresentationProperties.
1217          */
1218         bool
1219         setShapeRenderingProperties (int property, double value,
1220                                      const std::string &id, int viewport = 0);
1221 
1222         /** \brief Set the rendering properties of a shape (2x values - e.g., LUT minmax values)
1223           * \param[in] property the property type
1224           * \param[in] val1 the first value to be set
1225           * \param[in] val2 the second value to be set
1226           * \param[in] id the shape object id
1227           * \param[in] viewport the view port where the shape's properties should be modified (default: all)
1228           * \note When using \ref addPolygonMesh you you should use \ref setPointCloudRenderingProperties
1229           */
1230          bool
1231          setShapeRenderingProperties (int property, double val1, double val2,
1232                                       const std::string &id, int viewport = 0);
1233 
1234          /** \brief Set the rendering properties of a shape (3x values - e.g., RGB)
1235           * \param[in] property the property type
1236           * \param[in] val1 the first value to be set
1237           * \param[in] val2 the second value to be set
1238           * \param[in] val3 the third value to be set
1239           * \param[in] id the shape object id
1240           * \param[in] viewport the view port where the shape's properties should be modified (default: all)
1241           * \note When using \ref addPolygonMesh you you should use \ref setPointCloudRenderingProperties
1242           */
1243          bool
1244          setShapeRenderingProperties (int property, double val1, double val2, double val3,
1245                                       const std::string &id, int viewport = 0);
1246 
1247         /** \brief Returns true when the user tried to close the window */
1248         bool
1249         wasStopped () const;
1250 
1251         /** \brief Set the stopped flag back to false */
1252         void
1253         resetStoppedFlag ();
1254 
1255         /** \brief Stop the interaction and close the visualizaton window. */
1256         void
1257         close ();
1258 
1259         /** \brief Create a new viewport from [xmin,ymin] -> [xmax,ymax].
1260           * \param[in] xmin the minimum X coordinate for the viewport (0.0 <= 1.0)
1261           * \param[in] ymin the minimum Y coordinate for the viewport (0.0 <= 1.0)
1262           * \param[in] xmax the maximum X coordinate for the viewport (0.0 <= 1.0)
1263           * \param[in] ymax the maximum Y coordinate for the viewport (0.0 <= 1.0)
1264           * \param[in] viewport the id of the new viewport
1265           *
1266           * \note If no renderer for the current window exists, one will be created, and
1267           * the viewport will be set to 0 ('all'). In case one or multiple renderers do
1268           * exist, the viewport ID will be set to the total number of renderers - 1.
1269           */
1270         void
1271         createViewPort (double xmin, double ymin, double xmax, double ymax, int &viewport);
1272 
1273         /** \brief Create a new separate camera for the given viewport.
1274           * \param[in] viewport the viewport to create a new camera for.
1275           */
1276         void
1277         createViewPortCamera (const int viewport);
1278 
1279         /** \brief Add a polygon (polyline) that represents the input point cloud (connects all
1280           * points in order)
1281           * \param[in] cloud the point cloud dataset representing the polygon
1282           * \param[in] r the red channel of the color that the polygon should be rendered with
1283           * \param[in] g the green channel of the color that the polygon should be rendered with
1284           * \param[in] b the blue channel of the color that the polygon should be rendered with
1285           * \param[in] id (optional) the polygon id/name (default: "polygon")
1286           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1287           */
1288         template <typename PointT> bool
1289         addPolygon (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1290                     double r, double g, double b,
1291                     const std::string &id = "polygon", int viewport = 0);
1292 
1293         /** \brief Add a polygon (polyline) that represents the input point cloud (connects all
1294           * points in order)
1295           * \param[in] cloud the point cloud dataset representing the polygon
1296           * \param[in] id the polygon id/name (default: "polygon")
1297           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1298           */
1299         template <typename PointT> bool
1300         addPolygon (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
1301                     const std::string &id = "polygon",
1302                     int viewport = 0);
1303 
1304         /** \brief Add a planar polygon that represents the input point cloud (connects all points in order)
1305           * \param[in] polygon the polygon to draw
1306           * \param[in] r the red channel of the color that the polygon should be rendered with
1307           * \param[in] g the green channel of the color that the polygon should be rendered with
1308           * \param[in] b the blue channel of the color that the polygon should be rendered with
1309           * \param[in] id the polygon id/name (default: "polygon")
1310           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1311           */
1312         template <typename PointT> bool
1313         addPolygon (const pcl::PlanarPolygon<PointT> &polygon,
1314                     double r, double g, double b,
1315                     const std::string &id = "polygon",
1316                     int viewport = 0);
1317 
1318         /** \brief Add a line segment from two points
1319           * \param[in] pt1 the first (start) point on the line
1320           * \param[in] pt2 the second (end) point on the line
1321           * \param[in] id the line id/name (default: "line")
1322           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1323           */
1324         template <typename P1, typename P2> bool
1325         addLine (const P1 &pt1, const P2 &pt2, const std::string &id = "line",
1326                  int viewport = 0);
1327 
1328         /** \brief Add a line segment from two points
1329           * \param[in] pt1 the first (start) point on the line
1330           * \param[in] pt2 the second (end) point on the line
1331           * \param[in] r the red channel of the color that the line should be rendered with
1332           * \param[in] g the green channel of the color that the line should be rendered with
1333           * \param[in] b the blue channel of the color that the line should be rendered with
1334           * \param[in] id the line id/name (default: "line")
1335           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1336           */
1337         template <typename P1, typename P2> bool
1338         addLine (const P1 &pt1, const P2 &pt2, double r, double g, double b,
1339                  const std::string &id = "line", int viewport = 0);
1340 
1341         /** \brief Add a line arrow segment between two points, and display the distance between them
1342           *
1343           * Arrow heads are attached to both end points of the arrow.
1344           *
1345           * \param[in] pt1 the first (start) point on the line
1346           * \param[in] pt2 the second (end) point on the line
1347           * \param[in] r the red channel of the color that the line should be rendered with
1348           * \param[in] g the green channel of the color that the line should be rendered with
1349           * \param[in] b the blue channel of the color that the line should be rendered with
1350           * \param[in] id the arrow id/name (default: "arrow")
1351           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1352           */
1353         template <typename P1, typename P2> bool
1354         addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b,
1355                   const std::string &id = "arrow", int viewport = 0);
1356 
1357         /** \brief Add a line arrow segment between two points, and (optionally) display the distance between them
1358           *
1359           * Arrow head is attached on the **start** point (\c pt1) of the arrow.
1360           *
1361           * \param[in] pt1 the first (start) point on the line
1362           * \param[in] pt2 the second (end) point on the line
1363           * \param[in] r the red channel of the color that the line should be rendered with
1364           * \param[in] g the green channel of the color that the line should be rendered with
1365           * \param[in] b the blue channel of the color that the line should be rendered with
1366           * \param[in] display_length true if the length should be displayed on the arrow as text
1367           * \param[in] id the line id/name (default: "arrow")
1368           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1369           */
1370         template <typename P1, typename P2> bool
1371         addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, bool display_length,
1372                   const std::string &id = "arrow", int viewport = 0);
1373 
1374         /** \brief Add a line arrow segment between two points, and display the distance between them in a given color
1375           *
1376           * Arrow heads are attached to both end points of the arrow.
1377           *
1378           * \param[in] pt1 the first (start) point on the line
1379           * \param[in] pt2 the second (end) point on the line
1380           * \param[in] r_line the red channel of the color that the line should be rendered with
1381           * \param[in] g_line the green channel of the color that the line should be rendered with
1382           * \param[in] b_line the blue channel of the color that the line should be rendered with
1383           * \param[in] r_text the red channel of the color that the text should be rendered with
1384           * \param[in] g_text the green channel of the color that the text should be rendered with
1385           * \param[in] b_text the blue channel of the color that the text should be rendered with
1386           * \param[in] id the line id/name (default: "arrow")
1387           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1388           */
1389               template <typename P1, typename P2> bool
1390               addArrow (const P1 &pt1, const P2 &pt2,
1391                               double r_line, double g_line, double b_line,
1392                               double r_text, double g_text, double b_text,
1393                               const std::string &id = "arrow", int viewport = 0);
1394 
1395 
1396         /** \brief Add a sphere shape from a point and a radius
1397           * \param[in] center the center of the sphere
1398           * \param[in] radius the radius of the sphere
1399           * \param[in] id the sphere id/name (default: "sphere")
1400           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1401           */
1402         template <typename PointT> bool
1403         addSphere (const PointT &center, double radius, const std::string &id = "sphere",
1404                    int viewport = 0);
1405 
1406         /** \brief Add a sphere shape from a point and a radius
1407           * \param[in] center the center of the sphere
1408           * \param[in] radius the radius of the sphere
1409           * \param[in] r the red channel of the color that the sphere should be rendered with
1410           * \param[in] g the green channel of the color that the sphere should be rendered with
1411           * \param[in] b the blue channel of the color that the sphere should be rendered with
1412           * \param[in] id the sphere id/name (default: "sphere")
1413           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1414           */
1415         template <typename PointT> bool
1416         addSphere (const PointT &center, double radius, double r, double g, double b,
1417                    const std::string &id = "sphere", int viewport = 0);
1418 
1419         /** \brief Update an existing sphere shape from a point and a radius
1420           * \param[in] center the center of the sphere
1421           * \param[in] radius the radius of the sphere
1422           * \param[in] r the red channel of the color that the sphere should be rendered with
1423           * \param[in] g the green channel of the color that the sphere should be rendered with
1424           * \param[in] b the blue channel of the color that the sphere should be rendered with
1425           * \param[in] id the sphere id/name (default: "sphere")
1426           */
1427         template <typename PointT> bool
1428         updateSphere (const PointT &center, double radius, double r, double g, double b,
1429                       const std::string &id = "sphere");
1430 
1431          /** \brief Add a vtkPolydata as a mesh
1432           * \param[in] polydata vtkPolyData
1433           * \param[in] id the model id/name (default: "PolyData")
1434           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1435           */
1436         bool
1437         addModelFromPolyData (vtkSmartPointer<vtkPolyData> polydata,
1438                               const std::string & id = "PolyData",
1439                               int viewport = 0);
1440 
1441         /** \brief Add a vtkPolydata as a mesh
1442           * \param[in] polydata vtkPolyData
1443           * \param[in] transform transformation to apply
1444           * \param[in] id the model id/name (default: "PolyData")
1445           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1446           */
1447         bool
1448         addModelFromPolyData (vtkSmartPointer<vtkPolyData> polydata,
1449                               vtkSmartPointer<vtkTransform> transform,
1450                               const std::string &id = "PolyData",
1451                               int viewport = 0);
1452 
1453         /** \brief Add a PLYmodel as a mesh
1454           * \param[in] filename of the ply file
1455           * \param[in] id the model id/name (default: "PLYModel")
1456           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1457           */
1458         bool
1459         addModelFromPLYFile (const std::string &filename,
1460                              const std::string &id = "PLYModel",
1461                              int viewport = 0);
1462 
1463         /** \brief Add a PLYmodel as a mesh and applies given transformation
1464           * \param[in] filename of the ply file
1465           * \param[in] transform transformation to apply
1466           * \param[in] id the model id/name (default: "PLYModel")
1467           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1468           */
1469         bool
1470         addModelFromPLYFile (const std::string &filename,
1471                              vtkSmartPointer<vtkTransform> transform,
1472                              const std::string &id = "PLYModel",
1473                              int viewport = 0);
1474 
1475         /** \brief Add a cylinder from a set of given model coefficients
1476           * \param[in] coefficients the model coefficients (point_on_axis, axis_direction, radius)
1477           * \param[in] id the cylinder id/name (default: "cylinder")
1478           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1479           *
1480           * \code
1481           * // The following are given (or computed using sample consensus techniques)
1482           * // See SampleConsensusModelCylinder for more information.
1483           * // Eigen::Vector3f pt_on_axis, axis_direction;
1484           * // float radius;
1485           *
1486           * pcl::ModelCoefficients cylinder_coeff;
1487           * cylinder_coeff.values.resize (7);    // We need 7 values
1488           * cylinder_coeff.values[0] = pt_on_axis.x ();
1489           * cylinder_coeff.values[1] = pt_on_axis.y ();
1490           * cylinder_coeff.values[2] = pt_on_axis.z ();
1491           *
1492           * cylinder_coeff.values[3] = axis_direction.x ();
1493           * cylinder_coeff.values[4] = axis_direction.y ();
1494           * cylinder_coeff.values[5] = axis_direction.z ();
1495           *
1496           * cylinder_coeff.values[6] = radius;
1497           *
1498           * addCylinder (cylinder_coeff);
1499           * \endcode
1500           */
1501         bool
1502         addCylinder (const pcl::ModelCoefficients &coefficients,
1503                      const std::string &id = "cylinder",
1504                      int viewport = 0);
1505 
1506         /** \brief Add a sphere from a set of given model coefficients
1507           * \param[in] coefficients the model coefficients (sphere center, radius)
1508           * \param[in] id the sphere id/name (default: "sphere")
1509           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1510           *
1511           * \code
1512           * // The following are given (or computed using sample consensus techniques)
1513           * // See SampleConsensusModelSphere for more information
1514           * // Eigen::Vector3f sphere_center;
1515           * // float radius;
1516           *
1517           * pcl::ModelCoefficients sphere_coeff;
1518           * sphere_coeff.values.resize (4);    // We need 4 values
1519           * sphere_coeff.values[0] = sphere_center.x ();
1520           * sphere_coeff.values[1] = sphere_center.y ();
1521           * sphere_coeff.values[2] = sphere_center.z ();
1522           *
1523           * sphere_coeff.values[3] = radius;
1524           *
1525           * addSphere (sphere_coeff);
1526           * \endcode
1527           */
1528         bool
1529         addSphere (const pcl::ModelCoefficients &coefficients,
1530                    const std::string &id = "sphere",
1531                    int viewport = 0);
1532 
1533         /** \brief Add a line from a set of given model coefficients
1534           * \param[in] coefficients the model coefficients (point_on_line, direction)
1535           * \param[in] id the line id/name (default: "line")
1536           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1537           *
1538           * \code
1539           * // The following are given (or computed using sample consensus techniques)
1540           * // See SampleConsensusModelLine for more information
1541           * // Eigen::Vector3f point_on_line, line_direction;
1542           *
1543           * pcl::ModelCoefficients line_coeff;
1544           * line_coeff.values.resize (6);    // We need 6 values
1545           * line_coeff.values[0] = point_on_line.x ();
1546           * line_coeff.values[1] = point_on_line.y ();
1547           * line_coeff.values[2] = point_on_line.z ();
1548           *
1549           * line_coeff.values[3] = line_direction.x ();
1550           * line_coeff.values[4] = line_direction.y ();
1551           * line_coeff.values[5] = line_direction.z ();
1552           *
1553           * addLine (line_coeff);
1554           * \endcode
1555           */
1556         bool
1557         addLine (const pcl::ModelCoefficients &coefficients,
1558                  const std::string &id = "line",
1559                  int viewport = 0);
1560 
1561         /** \brief Add a line from a set of given model coefficients
1562           * \param[in] coefficients the model coefficients (point_on_line, direction)
1563           * \param[in] id the line id/name (default: "line")
1564           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1565           *
1566           * \code
1567           * // The following are given (or computed using sample consensus techniques)
1568           * // See SampleConsensusModelLine for more information
1569           * // Eigen::Vector3f point_on_line, line_direction;
1570           *
1571           * pcl::ModelCoefficients line_coeff;
1572           * line_coeff.values.resize (6);    // We need 6 values
1573           * line_coeff.values[0] = point_on_line.x ();
1574           * line_coeff.values[1] = point_on_line.y ();
1575           * line_coeff.values[2] = point_on_line.z ();
1576           *
1577           * line_coeff.values[3] = line_direction.x ();
1578           * line_coeff.values[4] = line_direction.y ();
1579           * line_coeff.values[5] = line_direction.z ();
1580           *
1581           * addLine (line_coeff);
1582           * \endcode
1583           */
1584         bool
1585         addLine (const pcl::ModelCoefficients &coefficients,
1586                  const char *id = "line",
1587                  int viewport = 0)
1588         {
1589           return addLine (coefficients, std::string (id), viewport);
1590         }
1591 
1592         /** \brief Add a plane from a set of given model coefficients
1593           * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0)
1594           * \param[in] id the plane id/name (default: "plane")
1595           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1596           *
1597           * \code
1598           * // The following are given (or computed using sample consensus techniques)
1599           * // See SampleConsensusModelPlane for more information
1600           * // Eigen::Vector4f plane_parameters;
1601           *
1602           * pcl::ModelCoefficients plane_coeff;
1603           * plane_coeff.values.resize (4);    // We need 4 values
1604           * plane_coeff.values[0] = plane_parameters.x ();
1605           * plane_coeff.values[1] = plane_parameters.y ();
1606           * plane_coeff.values[2] = plane_parameters.z ();
1607           * plane_coeff.values[3] = plane_parameters.w ();
1608           *
1609           * addPlane (plane_coeff);
1610           * \endcode
1611           */
1612         bool
1613         addPlane (const pcl::ModelCoefficients &coefficients,
1614                   const std::string &id = "plane",
1615                   int viewport = 0);
1616 
1617         bool
1618         addPlane (const pcl::ModelCoefficients &coefficients, double x, double y, double z,
1619                   const std::string &id = "plane",
1620                   int viewport = 0);
1621         /** \brief Add a circle from a set of given model coefficients
1622           * \param[in] coefficients the model coefficients (x, y, radius)
1623           * \param[in] id the circle id/name (default: "circle")
1624           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1625           *
1626           * \code
1627           * // The following are given (or computed using sample consensus techniques)
1628           * // See SampleConsensusModelCircle2D for more information
1629           * // float x, y, radius;
1630           *
1631           * pcl::ModelCoefficients circle_coeff;
1632           * circle_coeff.values.resize (3);    // We need 3 values
1633           * circle_coeff.values[0] = x;
1634           * circle_coeff.values[1] = y;
1635           * circle_coeff.values[2] = radius;
1636           *
1637           * vtkSmartPointer<vtkDataSet> data = pcl::visualization::create2DCircle (circle_coeff, z);
1638           * \endcode
1639            */
1640         bool
1641         addCircle (const pcl::ModelCoefficients &coefficients,
1642                    const std::string &id = "circle",
1643                    int viewport = 0);
1644 
1645         /** \brief Add a cone from a set of given model coefficients
1646           * \param[in] coefficients the model coefficients (see \ref pcl::visualization::createCone)
1647           * \param[in] id the cone id/name (default: "cone")
1648           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1649           */
1650         bool
1651         addCone (const pcl::ModelCoefficients &coefficients,
1652                  const std::string &id = "cone",
1653                  int viewport = 0);
1654 
1655         /** \brief Add a cube from a set of given model coefficients
1656           * \param[in] coefficients the model coefficients (see \ref pcl::visualization::createCube)
1657           * \param[in] id the cube id/name (default: "cube")
1658           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1659           */
1660         bool
1661         addCube (const pcl::ModelCoefficients &coefficients,
1662                  const std::string &id = "cube",
1663                  int viewport = 0);
1664 
1665         /** \brief Add a cube from a set of given model coefficients
1666           * \param[in] translation a translation to apply to the cube from 0,0,0
1667           * \param[in] rotation a quaternion-based rotation to apply to the cube
1668           * \param[in] width the cube's width
1669           * \param[in] height the cube's height
1670           * \param[in] depth the cube's depth
1671           * \param[in] id the cube id/name (default: "cube")
1672           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1673           */
1674         bool
1675         addCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation,
1676                  double width, double height, double depth,
1677                  const std::string &id = "cube",
1678                  int viewport = 0);
1679 
1680         /** \brief Add a cube
1681           * \param[in] x_min the min X coordinate
1682           * \param[in] x_max the max X coordinate
1683           * \param[in] y_min the min Y coordinate
1684           * \param[in] y_max the max Y coordinate
1685           * \param[in] z_min the min Z coordinate
1686           * \param[in] z_max the max Z coordinate
1687           * \param[in] r how much red (0.0 -> 1.0)
1688           * \param[in] g how much green (0.0 -> 1.0)
1689           * \param[in] b how much blue (0.0 -> 1.0)
1690           * \param[in] id the cube id/name (default: "cube")
1691           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1692           */
1693         bool
1694         addCube (float x_min, float x_max, float y_min, float y_max, float z_min, float z_max,
1695                  double r = 1.0, double g = 1.0, double b = 1.0, const std::string &id = "cube", int viewport = 0);
1696 
1697         /** \brief Add an ellipsoid from the given parameters
1698           * \param[in] transform a transformation to apply to the ellipsoid from 0,0,0
1699           * \param[in] radius_x the ellipsoid's radius along its local x-axis
1700           * \param[in] radius_y the ellipsoid's radius along its local y-axis
1701           * \param[in] radius_z the ellipsoid's radius along its local z-axis
1702           * \param[in] id the ellipsoid id/name (default: "ellipsoid")
1703           * \param[in] viewport (optional) the id of the new viewport (default: 0)
1704           */
1705         bool
1706         addEllipsoid (const Eigen::Isometry3d &transform,
1707                       double radius_x, double radius_y, double radius_z,
1708                       const std::string &id = "ellipsoid",
1709                       int viewport = 0);
1710 
1711         /** \brief Changes the visual representation for all actors to surface representation. */
1712         void
1713         setRepresentationToSurfaceForAllActors ();
1714 
1715         /** \brief Changes the visual representation for all actors to points representation. */
1716         void
1717         setRepresentationToPointsForAllActors ();
1718 
1719         /** \brief Changes the visual representation for all actors to wireframe representation. */
1720         void
1721         setRepresentationToWireframeForAllActors ();
1722 
1723         /** \brief Sets whether the 2D overlay text showing the framerate of the window is displayed or not.
1724           * \param[in] show_fps determines whether the fps text will be shown or not.
1725           */
1726         void
1727         setShowFPS (bool show_fps);
1728 
1729         /** Get the current rendering framerate.
1730           * \see setShowFPS */
1731         float
1732         getFPS () const;
1733 
1734         /** \brief Renders a virtual scene as seen from the camera viewpoint and returns the rendered point cloud.
1735           * ATT: This method will only render the scene if only on viewport exists. Otherwise, returns an empty
1736           * point cloud and exits immediately.
1737           * \param[in] xres is the size of the window (X) used to render the scene
1738           * \param[in] yres is the size of the window (Y) used to render the scene
1739           * \param[in] cloud is the rendered point cloud
1740           */
1741         void
1742         renderView (int xres, int yres, pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud);
1743 
1744         /** \brief The purpose of this method is to render a CAD model added to the visualizer from different viewpoints
1745           * in order to simulate partial views of model. The viewpoint locations are the vertices of a tessellated sphere
1746           * build from an icosaheadron. The tessellation parameter controls how many times the triangles of the original
1747           * icosahedron are divided to approximate the sphere and thus the number of partial view generated for a model,
1748           * with a tesselation_level of 0, 12 views are generated if use_vertices=true and 20 views if use_vertices=false
1749           *
1750           * \param[in] xres the size of the window (X) used to render the partial view of the object
1751           * \param[in] yres the size of the window (Y) used to render the partial view of the object
1752           * \param[in] cloud is a vector of pointcloud with XYZ information that represent the model as seen from the respective viewpoints.
1753           * \param[out] poses represent the transformation from object coordinates to camera coordinates for the respective viewpoint.
1754           * \param[out] enthropies are values between 0 and 1 representing which percentage of the model is seen from the respective viewpoint.
1755           * \param[in] tesselation_level represents the number of subdivisions applied to the triangles of original icosahedron.
1756           * \param[in] view_angle field of view of the virtual camera. Default: 45
1757           * \param[in] radius_sphere the tessellated sphere radius. Default: 1
1758           * \param[in] use_vertices if true, use the vertices of tessellated icosahedron (12,42,...) or if false, use the faces of tessellated
1759           * icosahedron (20,80,...). Default: true
1760           */
1761         void
1762         renderViewTesselatedSphere (
1763             int xres, int yres,
1764             pcl::PointCloud<pcl::PointXYZ>::CloudVectorType & cloud,
1765             std::vector<Eigen::Matrix4f,Eigen::aligned_allocator< Eigen::Matrix4f > > & poses, std::vector<float> & enthropies, int tesselation_level,
1766             float view_angle = 45, float radius_sphere = 1, bool use_vertices = true);
1767 
1768 
1769         /** \brief Initialize camera parameters with some default values. */
1770         void
1771         initCameraParameters ();
1772 
1773         /** \brief Search for camera parameters at the command line and set them internally.
1774           * \param[in] argc
1775           * \param[in] argv
1776           */
1777         bool
1778         getCameraParameters (int argc, char **argv);
1779 
1780         /** \brief Load camera parameters from a camera parameters file.
1781           * \param[in] file the name of the camera parameters file
1782           */
1783         bool
1784         loadCameraParameters (const std::string &file);
1785 
1786         /** \brief Checks whether the camera parameters were manually loaded.
1787           * \return True if valid "-cam" option is available in command line.
1788           * \sa cameraFileLoaded ()
1789           */
1790         bool
1791         cameraParamsSet () const;
1792 
1793         /** \brief Checks whether a camera file were automatically loaded.
1794           * \return True if a valid camera file is automatically loaded.
1795           * \note The camera file is saved by pressing "ctrl + s" during last run of the program
1796           * and restored automatically when the program runs this time.
1797           * \sa cameraParamsSet ()
1798           */
1799         bool
1800         cameraFileLoaded () const;
1801 
1802         /** \brief Get camera file for camera parameter saving/restoring.
1803           * \note This will be valid only when valid "-cam" option were available in command line
1804           * or a saved camera file were automatically loaded.
1805           * \sa cameraParamsSet (), cameraFileLoaded ()
1806           */
1807         std::string
1808         getCameraFile () const;
1809 
1810         /** \brief Update camera parameters and render. */
1811         void
1812         updateCamera ();
1813 
1814         /** \brief Reset camera parameters and render. */
1815         void
1816         resetCamera ();
1817 
1818         /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset.
1819           * \param[in] id the point cloud object id (default: cloud)
1820           */
1821         void
1822         resetCameraViewpoint (const std::string &id = "cloud");
1823 
1824         /** \brief Set the camera pose given by position, viewpoint and up vector
1825           * \param[in] pos_x the x coordinate of the camera location
1826           * \param[in] pos_y the y coordinate of the camera location
1827           * \param[in] pos_z the z coordinate of the camera location
1828           * \param[in] view_x the x component of the view point of the camera
1829           * \param[in] view_y the y component of the view point of the camera
1830           * \param[in] view_z the z component of the view point of the camera
1831           * \param[in] up_x the x component of the view up direction of the camera
1832           * \param[in] up_y the y component of the view up direction of the camera
1833           * \param[in] up_z the z component of the view up direction of the camera
1834           * \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
1835           */
1836         void
1837         setCameraPosition (double pos_x, double pos_y, double pos_z,
1838                            double view_x, double view_y, double view_z,
1839                            double up_x, double up_y, double up_z, int viewport = 0);
1840 
1841         /** \brief Set the camera location and viewup according to the given arguments
1842           * \param[in] pos_x the x coordinate of the camera location
1843           * \param[in] pos_y the y coordinate of the camera location
1844           * \param[in] pos_z the z coordinate of the camera location
1845           * \param[in] up_x the x component of the view up direction of the camera
1846           * \param[in] up_y the y component of the view up direction of the camera
1847           * \param[in] up_z the z component of the view up direction of the camera
1848           * \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
1849           */
1850         void
1851         setCameraPosition (double pos_x, double pos_y, double pos_z,
1852                            double up_x, double up_y, double up_z, int viewport = 0);
1853 
1854         /** \brief Set the camera parameters via an intrinsics and and extrinsics matrix
1855           * \note This assumes that the pixels are square and that the center of the image is at the center of the sensor.
1856           * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters
1857           * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters
1858           * \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
1859           */
1860         void
1861         setCameraParameters (const Eigen::Matrix3f &intrinsics, const Eigen::Matrix4f &extrinsics, int viewport = 0);
1862 
1863         /** \brief Set the camera parameters by given a full camera data structure.
1864           * \param[in] camera camera structure containing all the camera parameters.
1865           * \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
1866           */
1867         void
1868         setCameraParameters (const Camera &camera, int viewport = 0);
1869 
1870         /** \brief Set the camera clipping distances.
1871           * \param[in] near the near clipping distance (no objects closer than this to the camera will be drawn)
1872           * \param[in] far the far clipping distance (no objects further away than this to the camera will be drawn)
1873           * \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
1874           */
1875         void
1876         setCameraClipDistances (double near, double far, int viewport = 0);
1877 
1878         /** \brief Set the camera vertical field of view.
1879           * \param[in] fovy vertical field of view in radians
1880           * \param[in] viewport the viewport to modify camera of (0 modifies all cameras)
1881           */
1882         void
1883         setCameraFieldOfView (double fovy, int viewport = 0);
1884 
1885         /** \brief Get the current camera parameters. */
1886         void
1887         getCameras (std::vector<Camera>& cameras);
1888 
1889 
1890         /** \brief Get the current viewing pose. */
1891         Eigen::Affine3f
1892         getViewerPose (int viewport = 0);
1893 
1894         /** \brief Save the current rendered image to disk, as a PNG screenshot.
1895           * \param[in] file the name of the PNG file
1896           */
1897         void
1898         saveScreenshot (const std::string &file);
1899 
1900         /** \brief Save the camera parameters to disk, as a .cam file.
1901           * \param[in] file the name of the .cam file
1902           */
1903         void
1904         saveCameraParameters (const std::string &file);
1905 
1906         /** \brief Get camera parameters of a given viewport (0 means default viewport). */
1907         void
1908         getCameraParameters (Camera &camera, int viewport = 0) const;
1909 
1910         /** \brief Return a pointer to the underlying VTK Render Window used. */
1911         vtkSmartPointer<vtkRenderWindow>
getRenderWindow()1912         getRenderWindow ()
1913         {
1914           return (win_);
1915         }
1916 
1917         /** \brief Return a pointer to the underlying VTK Renderer Collection. */
1918         vtkSmartPointer<vtkRendererCollection>
getRendererCollection()1919         getRendererCollection ()
1920         {
1921           return (rens_);
1922         }
1923 
1924         /** \brief Return a pointer to the CloudActorMap this visualizer uses. */
1925         CloudActorMapPtr
getCloudActorMap()1926         getCloudActorMap ()
1927         {
1928           return (cloud_actor_map_);
1929         }
1930 
1931         /** \brief Return a pointer to the ShapeActorMap this visualizer uses. */
1932         ShapeActorMapPtr
getShapeActorMap()1933         getShapeActorMap ()
1934         {
1935           return (shape_actor_map_);
1936         }
1937 
1938         /** \brief Set the position in screen coordinates.
1939           * \param[in] x where to move the window to (X)
1940           * \param[in] y where to move the window to (Y)
1941           */
1942         void
1943         setPosition (int x, int y);
1944 
1945         /** \brief Set the window size in screen coordinates.
1946           * \param[in] xw window size in horizontal (pixels)
1947           * \param[in] yw window size in vertical (pixels)
1948           */
1949         void
1950         setSize (int xw, int yw);
1951 
1952         /** \brief Use Vertex Buffer Objects renderers.
1953           * This is an optimization for the obsolete OpenGL backend. Modern OpenGL2 backend (VTK ≥ 6.3) uses vertex
1954           * buffer objects by default, transparently for the user.
1955           * \param[in] use_vbos set to true to use VBOs
1956           */
1957         void
1958         setUseVbos (bool use_vbos);
1959 
1960         /** \brief Set the ID of a cloud or shape to be used for LUT display
1961           * \param[in] id The id of the cloud/shape look up table to be displayed
1962           * The look up table is displayed by pressing 'u' in the PCLVisualizer */
1963         void
1964         setLookUpTableID (const std::string id);
1965 
1966         /** \brief Create the internal Interactor object. */
1967         void
1968         createInteractor ();
1969 
1970         /** \brief Set up our unique PCL interactor style for a given vtkRenderWindowInteractor object
1971           * attached to a given vtkRenderWindow
1972           * \param[in,out] iren the vtkRenderWindowInteractor object to set up
1973           * \param[in,out] win a vtkRenderWindow object that the interactor is attached to
1974           */
1975         void
1976         setupInteractor (vtkRenderWindowInteractor *iren,
1977                          vtkRenderWindow *win);
1978 
1979         /** \brief Set up PCLVisualizer with custom interactor style for a given vtkRenderWindowInteractor object
1980           * attached to a given vtkRenderWindow
1981           * \param[in,out] iren the vtkRenderWindowInteractor object to set up
1982           * \param[in,out] win a vtkRenderWindow object that the interactor is attached to
1983           * \param[in,out] style a vtkInteractorStyle object
1984           */
1985         void
1986         setupInteractor (vtkRenderWindowInteractor *iren,
1987                          vtkRenderWindow *win,
1988                          vtkInteractorStyle *style);
1989 
1990         /** \brief Get a pointer to the current interactor style used. */
1991         inline vtkSmartPointer<PCLVisualizerInteractorStyle>
getInteractorStyle()1992         getInteractorStyle ()
1993         {
1994           return (style_);
1995         }
1996       protected:
1997         /** \brief The render window interactor. */
1998         vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
1999       private:
2000         /** \brief Internal function for renderer setup
2001          * \param[in] vtk renderer
2002          */
2003         void setupRenderer (vtkSmartPointer<vtkRenderer> ren);
2004 
2005         /** \brief Internal function for setting up FPS callback
2006          * \param[in] vtk renderer
2007          */
2008         void setupFPSCallback (const vtkSmartPointer<vtkRenderer>& ren);
2009 
2010         /** \brief Internal function for setting up render window
2011          * \param[in] name the window name
2012          */
2013         void setupRenderWindow (const std::string& name);
2014 
2015         /** \brief Internal function for setting up interactor style
2016          */
2017         void setupStyle ();
2018 
2019         /** \brief Internal function for setting the default render window size and position on screen
2020          */
2021         void setDefaultWindowSizeAndPos ();
2022 
2023         /** \brief Set up camera parameters.
2024          *
2025          * Parses command line arguments to find camera parameters (either explicit numbers or a path to a .cam file).
2026          * If not found, will generate a unique .cam file path (based on the rest of command line arguments) and try
2027          * to load that. If it is also not found, just set the defaults.
2028          */
2029         void setupCamera (int argc, char **argv);
2030 
2031         struct PCL_EXPORTS ExitMainLoopTimerCallback : public vtkCommand
2032         {
NewExitMainLoopTimerCallback2033           static ExitMainLoopTimerCallback* New ()
2034           {
2035             return (new ExitMainLoopTimerCallback);
2036           }
2037           void
2038           Execute (vtkObject*, unsigned long event_id, void*) override;
2039 
2040           int right_timer_id;
2041           PCLVisualizer* pcl_visualizer;
2042         };
2043 
2044         struct PCL_EXPORTS ExitCallback : public vtkCommand
2045         {
NewExitCallback2046           static ExitCallback* New ()
2047           {
2048             return (new ExitCallback);
2049           }
2050           void
2051           Execute (vtkObject*, unsigned long event_id, void*) override;
2052 
2053           PCLVisualizer* pcl_visualizer;
2054         };
2055 
2056         //////////////////////////////////////////////////////////////////////////////////////////////
2057         struct PCL_EXPORTS FPSCallback : public vtkCommand
2058         {
NewFPSCallback2059           static FPSCallback *New () { return (new FPSCallback); }
2060 
FPSCallbackFPSCallback2061           FPSCallback () : actor (), pcl_visualizer (), decimated (), last_fps(0.0f) {}
FPSCallbackFPSCallback2062           FPSCallback (const FPSCallback& src) : vtkCommand (src), actor (src.actor), pcl_visualizer (src.pcl_visualizer), decimated (src.decimated), last_fps (src.last_fps) {}
2063           FPSCallback& operator = (const FPSCallback& src) { actor = src.actor; pcl_visualizer = src.pcl_visualizer; decimated = src.decimated; last_fps = src.last_fps; return (*this); }
2064 
2065           void
2066           Execute (vtkObject*, unsigned long event_id, void*) override;
2067 
2068           vtkTextActor *actor;
2069           PCLVisualizer* pcl_visualizer;
2070           bool decimated;
2071           float last_fps;
2072         };
2073 
2074         /** \brief The FPSCallback object for the current visualizer. */
2075         vtkSmartPointer<FPSCallback> update_fps_;
2076 
2077         /** \brief Set to false if the interaction loop is running. */
2078         bool stopped_;
2079 
2080         /** \brief Global timer ID. Used in destructor only. */
2081         int timer_id_;
2082 
2083         /** \brief Callback object enabling us to leave the main loop, when a timer fires. */
2084         vtkSmartPointer<ExitMainLoopTimerCallback> exit_main_loop_timer_callback_;
2085         vtkSmartPointer<ExitCallback> exit_callback_;
2086 
2087         /** \brief The collection of renderers used. */
2088         vtkSmartPointer<vtkRendererCollection> rens_;
2089 
2090         /** \brief The render window. */
2091         vtkSmartPointer<vtkRenderWindow> win_;
2092 
2093         /** \brief The render window interactor style. */
2094         vtkSmartPointer<PCLVisualizerInteractorStyle> style_;
2095 
2096         /** \brief Internal list with actor pointers and name IDs for point clouds. */
2097         CloudActorMapPtr cloud_actor_map_;
2098 
2099         /** \brief Internal list with actor pointers and name IDs for shapes. */
2100         ShapeActorMapPtr shape_actor_map_;
2101 
2102         /** \brief Internal list with actor pointers and viewpoint for coordinates. */
2103         CoordinateActorMapPtr coordinate_actor_map_;
2104 
2105         /** \brief Internal pointer to widget which contains a set of axes */
2106         vtkSmartPointer<vtkOrientationMarkerWidget> axes_widget_;
2107 
2108         /** \brief Boolean that holds whether or not the camera parameters were manually initialized */
2109         bool camera_set_;
2110 
2111         /** \brief Boolean that holds whether or not a camera file were automatically loaded */
2112         bool camera_file_loaded_;
2113 
2114         /** \brief Boolean that holds whether or not to use the vtkVertexBufferObjectMapper*/
2115         bool use_vbos_;
2116 
2117         /** \brief Internal method. Removes a vtk actor from the screen.
2118           * \param[in] actor a pointer to the vtk actor object
2119           * \param[in] viewport the view port where the actor should be removed from (default: all)
2120           */
2121         bool
2122         removeActorFromRenderer (const vtkSmartPointer<vtkLODActor> &actor,
2123                                  int viewport = 0);
2124 
2125         /** \brief Internal method. Removes a vtk actor from the screen.
2126           * \param[in] actor a pointer to the vtk actor object
2127           * \param[in] viewport the view port where the actor should be removed from (default: all)
2128           */
2129         bool
2130         removeActorFromRenderer (const vtkSmartPointer<vtkActor> &actor,
2131                                  int viewport = 0);
2132 
2133         /** \brief Internal method. Adds a vtk actor to screen.
2134           * \param[in] actor a pointer to the vtk actor object
2135           * \param[in] viewport port where the actor should be added to (default: 0/all)
2136           *
2137           * \note If viewport is set to 0, the actor will be added to all existing
2138           * renders. To select a specific viewport use an integer between 1 and N.
2139           */
2140         void
2141         addActorToRenderer (const vtkSmartPointer<vtkProp> &actor,
2142                             int viewport = 0);
2143 
2144         /** \brief Internal method. Adds a vtk actor to screen.
2145           * \param[in] actor a pointer to the vtk actor object
2146           * \param[in] viewport the view port where the actor should be added to (default: all)
2147           */
2148         bool
2149         removeActorFromRenderer (const vtkSmartPointer<vtkProp> &actor,
2150                                  int viewport = 0);
2151 
2152         /** \brief Internal method. Creates a vtk actor from a vtk polydata object.
2153           * \param[in] data the vtk polydata object to create an actor for
2154           * \param[out] actor the resultant vtk actor object
2155           * \param[in] use_scalars set scalar properties to the mapper if it exists in the data. Default: true.
2156           */
2157         void
2158         createActorFromVTKDataSet (const vtkSmartPointer<vtkDataSet> &data,
2159                                    vtkSmartPointer<vtkActor> &actor,
2160                                    bool use_scalars = true) const;
2161 
2162         /** \brief Internal method. Creates a vtk actor from a vtk polydata object.
2163           * \param[in] data the vtk polydata object to create an actor for
2164           * \param[out] actor the resultant vtk actor object
2165           * \param[in] use_scalars set scalar properties to the mapper if it exists in the data. Default: true.
2166           */
2167         void
2168         createActorFromVTKDataSet (const vtkSmartPointer<vtkDataSet> &data,
2169                                    vtkSmartPointer<vtkLODActor> &actor,
2170                                    bool use_scalars = true) const;
2171 
2172         /** \brief Converts a PCL templated PointCloud object to a vtk polydata object.
2173           * \param[in] cloud the input PCL PointCloud dataset
2174           * \param[out] polydata the resultant polydata containing the cloud
2175           * \param[out] initcells a list of cell indices used for the conversion. This can be set once and then passed
2176           * around to speed up the conversion.
2177           */
2178         template <typename PointT> void
2179         convertPointCloudToVTKPolyData (const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
2180                                         vtkSmartPointer<vtkPolyData> &polydata,
2181                                         vtkSmartPointer<vtkIdTypeArray> &initcells);
2182 
2183         /** \brief Converts a PCL templated PointCloud object to a vtk polydata object.
2184           * \param[in] geometry_handler the geometry handler object used to extract the XYZ data
2185           * \param[out] polydata the resultant polydata containing the cloud
2186           * \param[out] initcells a list of cell indices used for the conversion. This can be set once and then passed
2187           * around to speed up the conversion.
2188           */
2189         template <typename PointT> void
2190         convertPointCloudToVTKPolyData (const PointCloudGeometryHandler<PointT> &geometry_handler,
2191                                         vtkSmartPointer<vtkPolyData> &polydata,
2192                                         vtkSmartPointer<vtkIdTypeArray> &initcells);
2193 
2194         /** \brief Converts a PCL object to a vtk polydata object.
2195           * \param[in] geometry_handler the geometry handler object used to extract the XYZ data
2196           * \param[out] polydata the resultant polydata containing the cloud
2197           * \param[out] initcells a list of cell indices used for the conversion. This can be set once and then passed
2198           * around to speed up the conversion.
2199           */
2200         void
2201         convertPointCloudToVTKPolyData (const GeometryHandlerConstPtr &geometry_handler,
2202                                         vtkSmartPointer<vtkPolyData> &polydata,
2203                                         vtkSmartPointer<vtkIdTypeArray> &initcells);
2204 
2205         /** \brief Updates a set of cells (vtkIdTypeArray) if the number of points in a cloud changes
2206           * \param[out] cells the vtkIdTypeArray object (set of cells) to update
2207           * \param[out] initcells a previously saved set of cells. If the number of points in the current cloud is
2208           * higher than the number of cells in \a cells, and initcells contains enough data, then a copy from it
2209           * will be made instead of regenerating the entire array.
2210           * \param[in] nr_points the number of points in the new cloud. This dictates how many cells we need to
2211           * generate
2212           */
2213         void
2214         updateCells (vtkSmartPointer<vtkIdTypeArray> &cells,
2215                      vtkSmartPointer<vtkIdTypeArray> &initcells,
2216                      vtkIdType nr_points);
2217 
2218         /** \brief Internal function which converts the information present in the geometric
2219           * and color handlers into VTK PolyData+Scalars, constructs a vtkActor object, and adds
2220           * all the required information to the internal cloud_actor_map_ object.
2221           * \param[in] geometry_handler the geometric handler that contains the XYZ data
2222           * \param[in] color_handler the color handler that contains the "RGB" (scalar) data
2223           * \param[in] id the point cloud object id
2224           * \param[in] viewport the view port where the Point Cloud should be added
2225           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
2226           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
2227           */
2228         template <typename PointT> bool
2229         fromHandlersToScreen (const PointCloudGeometryHandler<PointT> &geometry_handler,
2230                               const PointCloudColorHandler<PointT> &color_handler,
2231                               const std::string &id,
2232                               int viewport,
2233                               const Eigen::Vector4f& sensor_origin = Eigen::Vector4f (0, 0, 0, 0),
2234                               const Eigen::Quaternion<float>& sensor_orientation = Eigen::Quaternion<float> (1, 0, 0 ,0));
2235 
2236         /** \brief Internal function which converts the information present in the geometric
2237           * and color handlers into VTK PolyData+Scalars, constructs a vtkActor object, and adds
2238           * all the required information to the internal cloud_actor_map_ object.
2239           * \param[in] geometry_handler the geometric handler that contains the XYZ data
2240           * \param[in] color_handler the color handler that contains the "RGB" (scalar) data
2241           * \param[in] id the point cloud object id
2242           * \param[in] viewport the view port where the Point Cloud should be added
2243           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
2244           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
2245           */
2246         template <typename PointT> bool
2247         fromHandlersToScreen (const PointCloudGeometryHandler<PointT> &geometry_handler,
2248                               const ColorHandlerConstPtr &color_handler,
2249                               const std::string &id,
2250                               int viewport,
2251                               const Eigen::Vector4f& sensor_origin = Eigen::Vector4f (0, 0, 0, 0),
2252                               const Eigen::Quaternion<float>& sensor_orientation = Eigen::Quaternion<float> (1, 0, 0 ,0));
2253 
2254         /** \brief Internal function which converts the information present in the geometric
2255           * and color handlers into VTK PolyData+Scalars, constructs a vtkActor object, and adds
2256           * all the required information to the internal cloud_actor_map_ object.
2257           * \param[in] geometry_handler the geometric handler that contains the XYZ data
2258           * \param[in] color_handler the color handler that contains the "RGB" (scalar) data
2259           * \param[in] id the point cloud object id
2260           * \param[in] viewport the view port where the Point Cloud should be added
2261           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
2262           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
2263           */
2264         bool
2265         fromHandlersToScreen (const GeometryHandlerConstPtr &geometry_handler,
2266                               const ColorHandlerConstPtr &color_handler,
2267                               const std::string &id,
2268                               int viewport,
2269                               const Eigen::Vector4f& sensor_origin = Eigen::Vector4f (0, 0, 0, 0),
2270                               const Eigen::Quaternion<float>& sensor_orientation = Eigen::Quaternion<float> (1, 0, 0 ,0));
2271 
2272         /** \brief Internal function which converts the information present in the geometric
2273           * and color handlers into VTK PolyData+Scalars, constructs a vtkActor object, and adds
2274           * all the required information to the internal cloud_actor_map_ object.
2275           * \param[in] geometry_handler the geometric handler that contains the XYZ data
2276           * \param[in] color_handler the color handler that contains the "RGB" (scalar) data
2277           * \param[in] id the point cloud object id
2278           * \param[in] viewport the view port where the Point Cloud should be added
2279           * \param[in] sensor_origin the origin of the cloud data in global coordinates (defaults to 0,0,0)
2280           * \param[in] sensor_orientation the orientation of the cloud data in global coordinates (defaults to 1,0,0,0)
2281           */
2282         template <typename PointT> bool
2283         fromHandlersToScreen (const GeometryHandlerConstPtr &geometry_handler,
2284                               const PointCloudColorHandler<PointT> &color_handler,
2285                               const std::string &id,
2286                               int viewport,
2287                               const Eigen::Vector4f& sensor_origin = Eigen::Vector4f (0, 0, 0, 0),
2288                               const Eigen::Quaternion<float>& sensor_orientation = Eigen::Quaternion<float> (1, 0, 0 ,0));
2289 
2290         /** \brief Allocate a new polydata smartpointer. Internal
2291           * \param[out] polydata the resultant poly data
2292           */
2293         void
2294         allocVtkPolyData (vtkSmartPointer<vtkAppendPolyData> &polydata);
2295 
2296         /** \brief Allocate a new polydata smartpointer. Internal
2297           * \param[out] polydata the resultant poly data
2298           */
2299         void
2300         allocVtkPolyData (vtkSmartPointer<vtkPolyData> &polydata);
2301 
2302         /** \brief Allocate a new unstructured grid smartpointer. Internal
2303           * \param[out] polydata the resultant poly data
2304           */
2305         void
2306         allocVtkUnstructuredGrid (vtkSmartPointer<vtkUnstructuredGrid> &polydata);
2307 
2308         /** \brief Transform the point cloud viewpoint to a transformation matrix
2309           * \param[in] origin the camera origin
2310           * \param[in] orientation the camera orientation
2311           * \param[out] transformation the camera transformation matrix
2312           */
2313         void
2314         getTransformationMatrix (const Eigen::Vector4f &origin,
2315                                  const Eigen::Quaternion<float> &orientation,
2316                                  Eigen::Matrix4f &transformation);
2317 
2318         /** \brief Fills a vtkTexture structure from pcl::TexMaterial.
2319           * \param[in] tex_mat texture material in PCL format
2320           * \param[out] vtk_tex texture material in VTK format
2321           * \return 0 on success and -1 else.
2322           * \note for now only image based textures are supported, image file must be in
2323           * tex_file attribute of \a tex_mat.
2324           */
2325         int
2326         textureFromTexMaterial (const pcl::TexMaterial& tex_mat,
2327                                 vtkTexture* vtk_tex) const;
2328 
2329         /** \brief Get camera file for camera parameter saving/restoring from command line.
2330           * Camera filename is calculated using sha1 value of all paths of input .pcd files
2331           * \return empty string if failed.
2332           */
2333         std::string
2334         getUniqueCameraFile (int argc, char **argv);
2335 
2336         //There's no reason these conversion functions shouldn't be public and static so others can use them.
2337       public:
2338         /** \brief Convert Eigen::Matrix4f to vtkMatrix4x4
2339           * \param[in] m the input Eigen matrix
2340           * \param[out] vtk_matrix the resultant VTK matrix
2341           */
2342         static void
2343         convertToVtkMatrix (const Eigen::Matrix4f &m,
2344                             vtkSmartPointer<vtkMatrix4x4> &vtk_matrix);
2345 
2346         /** \brief Convert origin and orientation to vtkMatrix4x4
2347           * \param[in] origin the point cloud origin
2348           * \param[in] orientation the point cloud orientation
2349           * \param[out] vtk_matrix the resultant VTK 4x4 matrix
2350           */
2351         static void
2352         convertToVtkMatrix (const Eigen::Vector4f &origin,
2353                             const Eigen::Quaternion<float> &orientation,
2354                             vtkSmartPointer<vtkMatrix4x4> &vtk_matrix);
2355 
2356         /** \brief Convert vtkMatrix4x4 to an Eigen4f
2357           * \param[in] vtk_matrix the original VTK 4x4 matrix
2358           * \param[out] m the resultant Eigen 4x4 matrix
2359           */
2360         static void
2361         convertToEigenMatrix (const vtkSmartPointer<vtkMatrix4x4> &vtk_matrix,
2362                               Eigen::Matrix4f &m);
2363 
2364     };
2365   }
2366 }
2367 
2368 #include <pcl/visualization/impl/pcl_visualizer.hpp>
2369