1 /*
2  * Software License Agreement (BSD License)
3  *
4  *  Point Cloud Library (PCL) - www.pointclouds.org
5  *  Copyright (c) 2009-2012, 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 #include <pcl/pcl_macros.h>
42 #include <boost/signals2/signal.hpp>
43 
44 #include <vtkCommand.h>
45 
46 template <typename T> class vtkSmartPointer;
47 class vtkObject;
48 class vtkRenderWindow;
49 class vtkRenderWindowInteractor;
50 class vtkCallbackCommand;
51 class vtkRendererCollection;
52 class PCLVisualizerInteractorStyle;
53 
54 namespace pcl
55 {
56   namespace visualization
57   {
58     class MouseEvent;
59     class KeyboardEvent;
60 
61     class PCL_EXPORTS Window
62     {
63       public:
64         Window (const std::string& window_name = "");
65         Window (const Window &src);
66         Window& operator = (const Window &src);
67 
68         virtual ~Window ();
69 
70         /** \brief Spin method. Calls the interactor and runs an internal loop. */
71         void
72         spin ();
73 
74         /** \brief Spin once method. Calls the interactor and updates the screen once.
75           *  \param time - How long (in ms) should the visualization loop be allowed to run.
76           *  \param force_redraw - if false it might return without doing anything if the
77           *  interactor's framerate does not require a redraw yet.
78           */
79         void
80         spinOnce (int time = 1, bool force_redraw = false);
81 
82         /** \brief Returns true when the user tried to close the window */
83         bool
wasStopped()84         wasStopped () const { return (stopped_); }
85 
86         /**
87           * @brief registering a callback function for keyboard events
88           * @param callback  the function that will be registered as a callback for a keyboard event
89           * @param cookie    user data that is passed to the callback
90           * @return          connection object that allows to disconnect the callback function.
91           */
92         boost::signals2::connection
93         registerKeyboardCallback (void (*callback) (const pcl::visualization::KeyboardEvent&, void*),
94                                   void* cookie = nullptr)
95         {
96           return registerKeyboardCallback ([=] (const pcl::visualization::KeyboardEvent& e) { (*callback) (e, cookie); });
97         }
98 
99         /**
100           * @brief registering a callback function for keyboard events
101           * @param callback  the member function that will be registered as a callback for a keyboard event
102           * @param instance  instance to the class that implements the callback function
103           * @param cookie    user data that is passed to the callback
104           * @return          connection object that allows to disconnect the callback function.
105           */
106         template<typename T> boost::signals2::connection
107         registerKeyboardCallback (void (T::*callback) (const pcl::visualization::KeyboardEvent&, void*),
108                                   T& instance, void* cookie = nullptr)
109         {
110           return registerKeyboardCallback ([=, &instance] (const pcl::visualization::KeyboardEvent& e) { (instance.*callback) (e, cookie); });
111         }
112 
113         /**
114           * @brief
115           * @param callback  the function that will be registered as a callback for a mouse event
116           * @param cookie    user data that is passed to the callback
117           * @return          connection object that allows to disconnect the callback function.
118           */
119         boost::signals2::connection
120         registerMouseCallback (void (*callback) (const pcl::visualization::MouseEvent&, void*),
121                                void* cookie = nullptr)
122         {
123           return registerMouseCallback ([=] (const pcl::visualization::MouseEvent& e) { (*callback) (e, cookie); });
124         }
125 
126         /**
127           * @brief registering a callback function for mouse events
128           * @param callback  the member function that will be registered as a callback for a mouse event
129           * @param instance  instance to the class that implements the callback function
130           * @param cookie    user data that is passed to the callback
131           * @return          connection object that allows to disconnect the callback function.
132           */
133         template<typename T> boost::signals2::connection
134         registerMouseCallback (void (T::*callback) (const pcl::visualization::MouseEvent&, void*),
135                                T& instance, void* cookie = nullptr)
136         {
137           return registerMouseCallback ([=, &instance] (const pcl::visualization::MouseEvent& e) { (instance.*callback) (e, cookie); });
138         }
139 
140       protected: // methods
141 
142         /** \brief Set the stopped flag back to false */
143         void
resetStoppedFlag()144         resetStoppedFlag () { stopped_ = false; }
145 
146         /**
147           * @brief   registering a callback function for mouse events
148           * @return  connection object that allows to disconnect the callback function.
149           */
150          // param   the std function that will be registered as a callback for a mouse event
151         boost::signals2::connection
152         registerMouseCallback (std::function<void (const pcl::visualization::MouseEvent&)> );
153 
154         /**
155          * @brief   registering a callback std::function for keyboard events
156          * @return  connection object that allows to disconnect the callback function.
157          */
158          // param   the std function that will be registered as a callback for a keyboard event
159         boost::signals2::connection
160         registerKeyboardCallback (std::function<void (const pcl::visualization::KeyboardEvent&)> );
161 
162         void
163         emitMouseEvent (unsigned long event_id);
164 
165         void
166         emitKeyboardEvent (unsigned long event_id);
167 
168         // Callbacks used to register for vtk command
169         static void
170         MouseCallback (vtkObject*, unsigned long eid, void* clientdata, void *calldata);
171         static void
172         KeyboardCallback (vtkObject*, unsigned long eid, void* clientdata, void *calldata);
173 
174       protected: // types
175         struct ExitMainLoopTimerCallback : public vtkCommand
176         {
NewExitMainLoopTimerCallback177           static ExitMainLoopTimerCallback* New ()
178           {
179             return (new ExitMainLoopTimerCallback);
180           }
181 
182           ExitMainLoopTimerCallback ();
183 
184           void
185           Execute (vtkObject*, unsigned long event_id, void* call_data) override;
186 
187           int right_timer_id;
188           Window* window;
189         };
190 
191         struct ExitCallback : public vtkCommand
192         {
NewExitCallback193           static ExitCallback* New ()
194           {
195             return (new ExitCallback);
196           }
197 
198           ExitCallback ();
199 
200           void
201           Execute (vtkObject*, unsigned long event_id, void*) override;
202 
203           Window* window;
204         };
205 
206         bool stopped_;
207         int timer_id_;
208 
209     protected: // member fields
210         boost::signals2::signal<void (const pcl::visualization::MouseEvent&)> mouse_signal_;
211         boost::signals2::signal<void (const pcl::visualization::KeyboardEvent&)> keyboard_signal_;
212 
213         vtkSmartPointer<vtkRenderWindow> win_;
214         vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
215         vtkCallbackCommand* mouse_command_;
216         vtkCallbackCommand* keyboard_command_;
217         /** \brief The render window interactor style. */
218         vtkSmartPointer<PCLVisualizerInteractorStyle> style_;
219         /** \brief The collection of renderers used. */
220         vtkSmartPointer<vtkRendererCollection> rens_;
221         vtkSmartPointer<ExitMainLoopTimerCallback> exit_main_loop_timer_callback_;
222         vtkSmartPointer<ExitCallback> exit_callback_;
223     };
224   }
225 }
226