1 | /*
|
---|
2 | * Software License Agreement (BSD License)
|
---|
3 | *
|
---|
4 | * Point Cloud Library (PCL) - www.pointclouds.org
|
---|
5 | * Copyright (c) 2010, 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 | #include "interactor_style_3dv.h"
|
---|
40 |
|
---|
41 | #include <pcl/visualization/vtk/vtkVertexBufferObjectMapper.h>
|
---|
42 |
|
---|
43 | #include <vtkAssemblyPath.h>
|
---|
44 | #include <vtkAbstractPicker.h>
|
---|
45 | #include <vtkAbstractPropPicker.h>
|
---|
46 | #include <vtkCamera.h>
|
---|
47 | #include <vtkCellArray.h>
|
---|
48 | #include <vtkLegendScaleActor.h>
|
---|
49 | #include <vtkObjectFactory.h>
|
---|
50 | #include <vtkPointData.h>
|
---|
51 | #include <vtkPolyData.h>
|
---|
52 | #include <vtkPolyDataMapper.h>
|
---|
53 | #include <vtkProperty.h>
|
---|
54 | #include <vtkRendererCollection.h>
|
---|
55 | #include <vtkRenderWindow.h>
|
---|
56 |
|
---|
57 | void interactor_style_3dv::OnChar()
|
---|
58 | {
|
---|
59 | // Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice
|
---|
60 | FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]);
|
---|
61 | if (Interactor->GetKeyCode () >= '0' && Interactor->GetKeyCode () <= '9')
|
---|
62 | return;
|
---|
63 | std::string key (Interactor->GetKeySym ());
|
---|
64 | if (key.find ("XF86ZoomIn") != std::string::npos)
|
---|
65 | zoomIn ();
|
---|
66 | else if (key.find ("XF86ZoomOut") != std::string::npos)
|
---|
67 | zoomOut ();
|
---|
68 |
|
---|
69 | bool keymod = false;
|
---|
70 | switch (modifier_)
|
---|
71 | {
|
---|
72 | case pcl::visualization::INTERACTOR_KB_MOD_ALT:
|
---|
73 | {
|
---|
74 | keymod = Interactor->GetAltKey ();
|
---|
75 | break;
|
---|
76 | }
|
---|
77 | case pcl::visualization::INTERACTOR_KB_MOD_CTRL:
|
---|
78 | {
|
---|
79 | keymod = Interactor->GetControlKey ();
|
---|
80 | break;
|
---|
81 | }
|
---|
82 | case pcl::visualization::INTERACTOR_KB_MOD_SHIFT:
|
---|
83 | {
|
---|
84 | keymod = Interactor->GetShiftKey ();
|
---|
85 | break;
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | switch (Interactor->GetKeyCode ())
|
---|
90 | {
|
---|
91 | // All of the options below simply exit
|
---|
92 | case 'h': case 'H':
|
---|
93 | case 'c': case 'C':
|
---|
94 | case 43: // KEY_PLUS
|
---|
95 | case 45: // KEY_MINUS
|
---|
96 | case 'f': case 'F':
|
---|
97 | case 'g': case 'G':
|
---|
98 | case 'q': case 'Q':
|
---|
99 | case 'r': case 'R':
|
---|
100 | case 'm': case 'M':
|
---|
101 | {
|
---|
102 | break;
|
---|
103 | }
|
---|
104 | default:
|
---|
105 | {
|
---|
106 | Superclass::OnChar ();
|
---|
107 | break;
|
---|
108 | }
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 | void interactor_style_3dv::OnKeyDown()
|
---|
113 | {
|
---|
114 | if (!init_)
|
---|
115 | {
|
---|
116 | pcl::console::print_error ("[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n");
|
---|
117 | return;
|
---|
118 | }
|
---|
119 |
|
---|
120 | if (!rens_)
|
---|
121 | {
|
---|
122 | pcl::console::print_error ("[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing.\n");
|
---|
123 | return;
|
---|
124 | }
|
---|
125 |
|
---|
126 | FindPokedRenderer(Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]);
|
---|
127 |
|
---|
128 | // Save the initial windows width/height
|
---|
129 | if (win_height_ == -1 || win_width_ == -1)
|
---|
130 | {
|
---|
131 | int *win_size = Interactor->GetRenderWindow ()->GetSize ();
|
---|
132 | win_height_ = win_size[0];
|
---|
133 | win_width_ = win_size[1];
|
---|
134 | }
|
---|
135 |
|
---|
136 | // Get the status of special keys (Cltr+Alt+Shift)
|
---|
137 | bool shift = Interactor->GetShiftKey ();
|
---|
138 | bool ctrl = Interactor->GetControlKey ();
|
---|
139 | bool alt = Interactor->GetAltKey ();
|
---|
140 |
|
---|
141 | bool keymod = false;
|
---|
142 | switch (modifier_)
|
---|
143 | {
|
---|
144 | case pcl::visualization::INTERACTOR_KB_MOD_ALT:
|
---|
145 | {
|
---|
146 | keymod = alt;
|
---|
147 | break;
|
---|
148 | }
|
---|
149 | case pcl::visualization::INTERACTOR_KB_MOD_CTRL:
|
---|
150 | {
|
---|
151 | keymod = ctrl;
|
---|
152 | break;
|
---|
153 | }
|
---|
154 | case pcl::visualization::INTERACTOR_KB_MOD_SHIFT:
|
---|
155 | {
|
---|
156 | keymod = shift;
|
---|
157 | break;
|
---|
158 | }
|
---|
159 | }
|
---|
160 |
|
---|
161 | // ---[ Check the rest of the key codes
|
---|
162 |
|
---|
163 | std::string key (Interactor->GetKeySym ());
|
---|
164 | if (key.find ("XF86ZoomIn") != std::string::npos)
|
---|
165 | zoomIn ();
|
---|
166 | else if (key.find ("XF86ZoomOut") != std::string::npos)
|
---|
167 | zoomOut ();
|
---|
168 |
|
---|
169 | switch (Interactor->GetKeyCode ())
|
---|
170 | {
|
---|
171 | case 'h': case 'H':
|
---|
172 | {
|
---|
173 | pcl::console::print_info ("\n\r[II] 3dv-client: 3D visualization window shortcuts\n\n\r"
|
---|
174 | " p, P : toggle point cloud visualization\n\r"
|
---|
175 | " o, O : toggle obstacles visualization\n\r"
|
---|
176 | " t, T : toggle terrain visualization\n\r"
|
---|
177 | " m, M : toggle terrain grid map visualization\n\r"
|
---|
178 | " v, V : toggle orientation rate visualization\n\r"
|
---|
179 | "\n\r"
|
---|
180 | " c, C : display current camera/window parameters\n\r"
|
---|
181 | " f, F : fly to point mode\n\r"
|
---|
182 | "\n\r"
|
---|
183 | " q, Q : stop and call VTK's TerminateApp\n\r"
|
---|
184 | "\n\r"
|
---|
185 | " +/- : increment/decrement overall point size\n\r"
|
---|
186 | " +/- [+ ALT] : zoom in/out \n\r"
|
---|
187 | "\n\r"
|
---|
188 | " g, G : display scale grid (on/off)\n\r"
|
---|
189 | "\n\r"
|
---|
190 | " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n\r"
|
---|
191 | "\n\r"
|
---|
192 | " ALT + f, F : switch between maximized window mode and original size\n\r"
|
---|
193 | );
|
---|
194 | break;
|
---|
195 | }
|
---|
196 |
|
---|
197 | // display current camera settings/parameters
|
---|
198 | case 'c': case 'C':
|
---|
199 | {
|
---|
200 | vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera ();
|
---|
201 | double clip[2], focal[3], pos[3], view[3];
|
---|
202 | cam->GetClippingRange (clip);
|
---|
203 | cam->GetFocalPoint (focal);
|
---|
204 | cam->GetPosition (pos);
|
---|
205 | cam->GetViewUp (view);
|
---|
206 | int *win_pos = Interactor->GetRenderWindow ()->GetPosition ();
|
---|
207 | int *win_size = Interactor->GetRenderWindow ()->GetSize ();
|
---|
208 | std::cerr << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" <<
|
---|
209 | pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" <<
|
---|
210 | cam->GetViewAngle () / 180.0 * M_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1]
|
---|
211 | << endl;
|
---|
212 | break;
|
---|
213 | }
|
---|
214 | case '=':
|
---|
215 | {
|
---|
216 | zoomIn();
|
---|
217 | break;
|
---|
218 | }
|
---|
219 | case 43: // KEY_PLUS
|
---|
220 | {
|
---|
221 | if(alt)
|
---|
222 | zoomIn ();
|
---|
223 | else
|
---|
224 | {
|
---|
225 | vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors ();
|
---|
226 | vtkCollectionSimpleIterator ait;
|
---|
227 | for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); )
|
---|
228 | {
|
---|
229 | for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); )
|
---|
230 | {
|
---|
231 | vtkSmartPointer<vtkActor> apart = reinterpret_cast <vtkActor*> (path->GetLastNode ()->GetViewProp ());
|
---|
232 | float psize = apart->GetProperty ()->GetPointSize ();
|
---|
233 | if (psize < 63.0f)
|
---|
234 | apart->GetProperty ()->SetPointSize (psize + 1.0f);
|
---|
235 | }
|
---|
236 | }
|
---|
237 | }
|
---|
238 | break;
|
---|
239 | }
|
---|
240 | case 45: // KEY_MINUS
|
---|
241 | {
|
---|
242 | if(alt)
|
---|
243 | zoomOut ();
|
---|
244 | else
|
---|
245 | {
|
---|
246 | vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors ();
|
---|
247 | vtkCollectionSimpleIterator ait;
|
---|
248 | for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); )
|
---|
249 | {
|
---|
250 | for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); )
|
---|
251 | {
|
---|
252 | vtkSmartPointer<vtkActor> apart = static_cast<vtkActor*> (path->GetLastNode ()->GetViewProp ());
|
---|
253 | float psize = apart->GetProperty ()->GetPointSize ();
|
---|
254 | if (psize > 1.0f)
|
---|
255 | apart->GetProperty ()->SetPointSize (psize - 1.0f);
|
---|
256 | }
|
---|
257 | }
|
---|
258 | }
|
---|
259 | break;
|
---|
260 | }
|
---|
261 | // Switch between maximize and original window size
|
---|
262 | case 'f': case 'F':
|
---|
263 | {
|
---|
264 | if (keymod)
|
---|
265 | {
|
---|
266 | // Get screen size
|
---|
267 | int *temp = Interactor->GetRenderWindow ()->GetScreenSize ();
|
---|
268 | int scr_size[2]; scr_size[0] = temp[0]; scr_size[1] = temp[1];
|
---|
269 |
|
---|
270 | // Get window size
|
---|
271 | temp = Interactor->GetRenderWindow ()->GetSize ();
|
---|
272 | int win_size[2]; win_size[0] = temp[0]; win_size[1] = temp[1];
|
---|
273 | // Is window size = max?
|
---|
274 | if (win_size[0] == max_win_height_ && win_size[1] == max_win_width_)
|
---|
275 | {
|
---|
276 | // Set the previously saved 'current' window size
|
---|
277 | Interactor->GetRenderWindow ()->SetSize (win_height_, win_width_);
|
---|
278 | // Set the previously saved window position
|
---|
279 | Interactor->GetRenderWindow ()->SetPosition (win_pos_x_, win_pos_y_);
|
---|
280 | Interactor->GetRenderWindow ()->Render ();
|
---|
281 | Interactor->Render ();
|
---|
282 | }
|
---|
283 | // Set to max
|
---|
284 | else
|
---|
285 | {
|
---|
286 | int *win_pos = Interactor->GetRenderWindow ()->GetPosition ();
|
---|
287 | // Save the current window position
|
---|
288 | win_pos_x_ = win_pos[0];
|
---|
289 | win_pos_y_ = win_pos[1];
|
---|
290 | // Save the current window size
|
---|
291 | win_height_ = win_size[0];
|
---|
292 | win_width_ = win_size[1];
|
---|
293 | // Set the maximum window size
|
---|
294 | Interactor->GetRenderWindow ()->SetSize (scr_size[0], scr_size[1]);
|
---|
295 | Interactor->GetRenderWindow ()->Render ();
|
---|
296 | Interactor->Render ();
|
---|
297 | int *win_size = Interactor->GetRenderWindow ()->GetSize ();
|
---|
298 | // Save the maximum window size
|
---|
299 | max_win_height_ = win_size[0];
|
---|
300 | max_win_width_ = win_size[1];
|
---|
301 | }
|
---|
302 | }
|
---|
303 | else
|
---|
304 | {
|
---|
305 | AnimState = VTKIS_ANIM_ON;
|
---|
306 | vtkAssemblyPath *path = NULL;
|
---|
307 | Interactor->GetPicker ()->Pick (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1], 0.0, CurrentRenderer);
|
---|
308 | vtkAbstractPropPicker *picker;
|
---|
309 | if ((picker = vtkAbstractPropPicker::SafeDownCast (Interactor->GetPicker ())))
|
---|
310 | path = picker->GetPath ();
|
---|
311 | if (path != NULL)
|
---|
312 | Interactor->FlyTo (CurrentRenderer, picker->GetPickPosition ());
|
---|
313 | AnimState = VTKIS_ANIM_OFF;
|
---|
314 | }
|
---|
315 | break;
|
---|
316 | }
|
---|
317 |
|
---|
318 | // Display a grid/scale over the screen
|
---|
319 | case 'g': case 'G':
|
---|
320 | {
|
---|
321 | if (!grid_enabled_)
|
---|
322 | {
|
---|
323 | grid_actor_->TopAxisVisibilityOn ();
|
---|
324 | CurrentRenderer->AddViewProp (grid_actor_);
|
---|
325 | grid_enabled_ = true;
|
---|
326 | }
|
---|
327 | else
|
---|
328 | {
|
---|
329 | CurrentRenderer->RemoveViewProp (grid_actor_);
|
---|
330 | grid_enabled_ = false;
|
---|
331 | }
|
---|
332 | break;
|
---|
333 | }
|
---|
334 | case 'm': case 'M':
|
---|
335 | {
|
---|
336 | break;
|
---|
337 | }
|
---|
338 |
|
---|
339 |
|
---|
340 | // Overwrite the camera reset
|
---|
341 | case 'r': case 'R':
|
---|
342 | {
|
---|
343 | vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera ();
|
---|
344 | /*
|
---|
345 | if (!keymod)
|
---|
346 | {
|
---|
347 | FindPokedRenderer(Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]);
|
---|
348 | if(CurrentRenderer != 0)
|
---|
349 | CurrentRenderer->ResetCamera ();
|
---|
350 | else
|
---|
351 | PCL_WARN ("no current renderer on the interactor style.");
|
---|
352 |
|
---|
353 | CurrentRenderer->Render ();
|
---|
354 | break;
|
---|
355 | }
|
---|
356 |
|
---|
357 |
|
---|
358 |
|
---|
359 | static pcl::visualization::CloudActorMap::iterator it = actors_->begin ();
|
---|
360 | // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
|
---|
361 | bool found_transformation = false;
|
---|
362 | for (unsigned idx = 0; idx < actors_->size (); ++idx, ++it)
|
---|
363 | {
|
---|
364 | if (it == actors_->end ())
|
---|
365 | it = actors_->begin ();
|
---|
366 |
|
---|
367 | const pcl::visualization::CloudActor& actor = it->second;
|
---|
368 | if (actor.viewpoint_transformation_.GetPointer ())
|
---|
369 | {
|
---|
370 | found_transformation = true;
|
---|
371 | break;
|
---|
372 | }
|
---|
373 | }
|
---|
374 |
|
---|
375 | // if a valid transformation was found, use it otherwise fall back to default view point.
|
---|
376 | if (found_transformation)
|
---|
377 | {
|
---|
378 | const pcl::visualization::CloudActor& actor = it->second;
|
---|
379 | cam->SetPosition (actor.viewpoint_transformation_->GetElement (0, 3),
|
---|
380 | actor.viewpoint_transformation_->GetElement (1, 3),
|
---|
381 | actor.viewpoint_transformation_->GetElement (2, 3));
|
---|
382 |
|
---|
383 | cam->SetFocalPoint (actor.viewpoint_transformation_->GetElement (0, 3) - actor.viewpoint_transformation_->GetElement (0, 2),
|
---|
384 | actor.viewpoint_transformation_->GetElement (1, 3) - actor.viewpoint_transformation_->GetElement (1, 2),
|
---|
385 | actor.viewpoint_transformation_->GetElement (2, 3) - actor.viewpoint_transformation_->GetElement (2, 2));
|
---|
386 |
|
---|
387 | cam->SetViewUp (actor.viewpoint_transformation_->GetElement (0, 1),
|
---|
388 | actor.viewpoint_transformation_->GetElement (1, 1),
|
---|
389 | actor.viewpoint_transformation_->GetElement (2, 1));
|
---|
390 | }
|
---|
391 | else
|
---|
392 | {
|
---|
393 | //, 0.715357, 0.012124, 0.698653
|
---|
394 | cam->SetPosition (0.5, 0.0, 0.5);
|
---|
395 | cam->SetFocalPoint (0, 0, 1);
|
---|
396 | cam->SetViewUp (1.03093, -0.140037, 1.86098);
|
---|
397 | }
|
---|
398 |
|
---|
399 | // go to the next actor for the next key-press event.
|
---|
400 | if (it != actors_->end ())
|
---|
401 | ++it;
|
---|
402 | else
|
---|
403 | it = actors_->begin ();
|
---|
404 | */
|
---|
405 | cam->SetPosition (-3.0, 0.0, 6.0);
|
---|
406 | cam->SetFocalPoint (0, 0, 1);
|
---|
407 | cam->SetViewUp (1.03093, -0.140037, 1.86098);
|
---|
408 |
|
---|
409 | CurrentRenderer->SetActiveCamera (cam);
|
---|
410 | CurrentRenderer->ResetCameraClippingRange ();
|
---|
411 | CurrentRenderer->Render ();
|
---|
412 | break;
|
---|
413 | }
|
---|
414 |
|
---|
415 | case 'q': case 'Q':
|
---|
416 | {
|
---|
417 | Interactor->ExitCallback ();
|
---|
418 | return;
|
---|
419 | }
|
---|
420 | default:
|
---|
421 | {
|
---|
422 | Superclass::OnKeyDown ();
|
---|
423 | break;
|
---|
424 | }
|
---|
425 | }
|
---|
426 |
|
---|
427 | pcl::visualization::KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ());
|
---|
428 | keyboard_signal_ (event);
|
---|
429 |
|
---|
430 | rens_->Render ();
|
---|
431 | Interactor->Render ();
|
---|
432 | }
|
---|
433 |
|
---|
434 | vtkStandardNewMacro(interactor_style_3dv);
|
---|