Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/viz/src/vtk/vtkVizInteractorStyle.cpp
16358 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14
// Third party copyrights are property of their respective owners.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of the copyright holders may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
// Authors:
41
// * Ozan Tonkal, [email protected]
42
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
43
//
44
//M*/
45
46
#include "../precomp.hpp"
47
48
namespace cv { namespace viz
49
{
50
vtkStandardNewMacro(vtkVizInteractorStyle)
51
}}
52
53
//////////////////////////////////////////////////////////////////////////////////////////////
54
55
cv::viz::vtkVizInteractorStyle::vtkVizInteractorStyle()
56
{
57
FlyMode = false;
58
MotionFactor = 10.0;
59
60
keyboardCallback_ = 0;
61
keyboard_callback_cookie_ = 0;
62
63
mouseCallback_ = 0;
64
mouse_callback_cookie_ = 0;
65
66
// Set windows size (width, height) to unknown (-1)
67
win_size_ = Vec2i(-1, -1);
68
win_pos_ = Vec2i(0, 0);
69
max_win_size_ = Vec2i(-1, -1);
70
71
stereo_anaglyph_redblue_ = true;
72
73
//from fly
74
KeysDown = 0;
75
UseTimers = 1;
76
77
DiagonalLength = 1.0;
78
MotionStepSize = 1.0/100.0;
79
MotionUserScale = 1.0; // +/- key adjustment
80
MotionAccelerationFactor = 10.0;
81
AngleStepSize = 1.0;
82
}
83
84
cv::viz::vtkVizInteractorStyle::~vtkVizInteractorStyle() {}
85
86
//////////////////////////////////////////////////////////////////////////////////////////////
87
void cv::viz::vtkVizInteractorStyle::saveScreenshot(const String &file)
88
{
89
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
90
91
vtkSmartPointer<vtkWindowToImageFilter> wif = vtkSmartPointer<vtkWindowToImageFilter>::New();
92
wif->SetInput(Interactor->GetRenderWindow());
93
94
vtkSmartPointer<vtkPNGWriter> snapshot_writer = vtkSmartPointer<vtkPNGWriter>::New();
95
snapshot_writer->SetInputConnection(wif->GetOutputPort());
96
snapshot_writer->SetFileName(file.c_str());
97
snapshot_writer->Write();
98
99
cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl;
100
}
101
102
//////////////////////////////////////////////////////////////////////////////////////////////
103
104
void cv::viz::vtkVizInteractorStyle::exportScene(const String &file)
105
{
106
vtkSmartPointer<vtkExporter> exporter;
107
if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml")
108
{
109
exporter = vtkSmartPointer<vtkVRMLExporter>::New();
110
vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str());
111
}
112
else
113
{
114
exporter = vtkSmartPointer<vtkOBJExporter>::New();
115
vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str());
116
}
117
118
exporter->SetInput(Interactor->GetRenderWindow());
119
exporter->Write();
120
121
cout << "Scene successfully exported (" << file.c_str() << ")" << endl;
122
}
123
124
void cv::viz::vtkVizInteractorStyle::exportScene()
125
{
126
// Export scene as in obj or vrml format
127
String format = Interactor->GetAltKey() ? "scene-%d.vrml" : "scene-%d";
128
exportScene(cv::format(format.c_str(), (unsigned int)time(0)));
129
}
130
131
//////////////////////////////////////////////////////////////////////////////////////////////
132
133
void cv::viz::vtkVizInteractorStyle::changePointsSize(float delta)
134
{
135
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
136
vtkCollectionSimpleIterator ait;
137
138
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
139
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
140
{
141
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
142
float psize = apart->GetProperty()->GetPointSize() + delta;
143
psize = std::max(1.f, std::min(63.f, psize));
144
apart->GetProperty()->SetPointSize(psize);
145
}
146
}
147
148
void cv::viz::vtkVizInteractorStyle::setRepresentationToPoints()
149
{
150
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
151
vtkCollectionSimpleIterator ait;
152
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
153
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
154
{
155
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
156
apart->GetProperty()->SetRepresentationToPoints();
157
}
158
}
159
160
//////////////////////////////////////////////////////////////////////////////////////////////
161
162
void cv::viz::vtkVizInteractorStyle::printCameraParams()
163
{
164
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
165
166
Vec2d clip(cam->GetClippingRange());
167
Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp());
168
Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition());
169
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
170
double angle = cam->GetViewAngle () / 180.0 * CV_PI;
171
172
String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)",
173
clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2],
174
angle, win_size[0], win_size[1], win_pos[0], win_pos[1]);
175
176
std::cout << data.c_str() << std::endl;
177
}
178
179
//////////////////////////////////////////////////////////////////////////////////////////////
180
181
void cv::viz::vtkVizInteractorStyle::toggleFullScreen()
182
{
183
Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize());
184
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
185
186
// Is window size = max?
187
if (win_size == max_win_size_)
188
{
189
Interactor->GetRenderWindow()->SetSize(win_size_.val);
190
Interactor->GetRenderWindow()->SetPosition(win_pos_.val);
191
Interactor->Render();
192
}
193
// Set to max
194
else
195
{
196
win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition());
197
win_size_ = win_size;
198
199
Interactor->GetRenderWindow()->SetSize(screen_size.val);
200
Interactor->Render();
201
max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
202
}
203
}
204
205
//////////////////////////////////////////////////////////////////////////////////////////////
206
207
void cv::viz::vtkVizInteractorStyle::resetViewerPose()
208
{
209
WidgetActorMap::iterator it = widget_actor_map_->begin();
210
// it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
211
for (; it != widget_actor_map_->end(); ++it)
212
{
213
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
214
if (actor && actor->GetUserMatrix())
215
break;
216
}
217
218
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
219
220
// if a valid transformation was found, use it otherwise fall back to default view point.
221
if (it != widget_actor_map_->end())
222
{
223
vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix();
224
225
cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2),
226
m->GetElement(1, 3) - m->GetElement(1, 2),
227
m->GetElement(2, 3) - m->GetElement(2, 2));
228
229
cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1));
230
cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3));
231
}
232
else
233
{
234
cam->SetPosition(0, 0, 0);
235
cam->SetFocalPoint(0, 0, 1);
236
cam->SetViewUp(0, -1, 0);
237
}
238
239
// go to the next actor for the next key-press event.
240
if (it != widget_actor_map_->end())
241
++it;
242
else
243
it = widget_actor_map_->begin();
244
245
CurrentRenderer->SetActiveCamera(cam);
246
CurrentRenderer->ResetCameraClippingRange();
247
Interactor->Render();
248
}
249
250
//////////////////////////////////////////////////////////////////////////////////////////////
251
252
void cv::viz::vtkVizInteractorStyle::toggleStereo()
253
{
254
vtkSmartPointer<vtkRenderWindow> window = Interactor->GetRenderWindow();
255
if (!window->GetStereoRender())
256
{
257
static Vec2i red_blue(4, 3), magenta_green(2, 5);
258
window->SetAnaglyphColorMask (stereo_anaglyph_redblue_ ? red_blue.val : magenta_green.val);
259
stereo_anaglyph_redblue_ = !stereo_anaglyph_redblue_;
260
}
261
window->SetStereoRender(!window->GetStereoRender());
262
Interactor->Render();
263
264
}
265
266
//////////////////////////////////////////////////////////////////////////////////////////////
267
268
void cv::viz::vtkVizInteractorStyle::printHelp()
269
{
270
std::cout << "| Help:\n"
271
"-------\n"
272
" p, P : switch to a point-based representation\n"
273
" w, W : switch to a wireframe-based representation (where available)\n"
274
" s, S : switch to a surface-based representation (where available)\n"
275
"\n"
276
" j, J : take a .PNG snapshot of the current window view\n"
277
" k, K : export scene to Wavefront .obj format\n"
278
" ALT + k, K : export scene to VRML format\n"
279
" c, C : display current camera/window parameters\n"
280
" F5 : enable/disable fly mode (changes control style)\n"
281
"\n"
282
" e, E : exit the interactor\n"
283
" q, Q : stop and call VTK's TerminateApp\n"
284
"\n"
285
" +/- : increment/decrement overall point size\n"
286
" +/- [+ ALT] : zoom in/out \n"
287
"\n"
288
" r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n"
289
"\n"
290
" ALT + s, S : turn stereo mode on/off\n"
291
" ALT + f, F : switch between maximized window mode and original size\n"
292
"\n"
293
<< std::endl;
294
}
295
296
//////////////////////////////////////////////////////////////////////////////////////////////
297
void cv::viz::vtkVizInteractorStyle::zoomIn()
298
{
299
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
300
// Zoom in
301
StartDolly();
302
double factor = 10.0 * 0.2 * .5;
303
Dolly(std::pow(1.1, factor));
304
EndDolly();
305
}
306
307
//////////////////////////////////////////////////////////////////////////////////////////////
308
void cv::viz::vtkVizInteractorStyle::zoomOut()
309
{
310
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
311
// Zoom out
312
StartDolly();
313
double factor = 10.0 * -0.2 * .5;
314
Dolly(std::pow(1.1, factor));
315
EndDolly();
316
}
317
318
//////////////////////////////////////////////////////////////////////////////////////////////
319
void cv::viz::vtkVizInteractorStyle::OnChar()
320
{
321
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
322
323
String key(Interactor->GetKeySym());
324
if (key.find("XF86ZoomIn") != String::npos)
325
zoomIn();
326
else if (key.find("XF86ZoomOut") != String::npos)
327
zoomOut();
328
329
switch (Interactor->GetKeyCode())
330
{
331
// // All of the options below simply exit
332
// case 'l': case 'L': case 'j': case 'J': case 'c': case 'C': case 'q': case 'Q':
333
// case 'f': case 'F': case 'g': case 'G': case 'o': case 'O': case 'u': case 'U':
334
case 'p': case 'P':
335
break;
336
337
case '+':
338
if (FlyMode)
339
MotionUserScale = std::min(16.0, MotionUserScale*2.0);
340
break;
341
case '-':
342
if (FlyMode)
343
MotionUserScale = std::max(MotionUserScale * 0.5, 0.0625);
344
break;
345
346
case 'r': case 'R': case 's': case 'S':
347
if (!Interactor->GetAltKey())
348
Superclass::OnChar();
349
break;
350
default:
351
Superclass::OnChar();
352
break;
353
}
354
}
355
356
//////////////////////////////////////////////////////////////////////////////////////////////
357
void cv::viz::vtkVizInteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie)
358
{
359
mouseCallback_ = callback;
360
mouse_callback_cookie_ = cookie;
361
}
362
363
void cv::viz::vtkVizInteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie)
364
{
365
keyboardCallback_ = callback;
366
keyboard_callback_cookie_ = cookie;
367
}
368
369
//////////////////////////////////////////////////////////////////////////////////////////////
370
int cv::viz::vtkVizInteractorStyle::getModifiers()
371
{
372
int modifiers = KeyboardEvent::NONE;
373
374
if (Interactor->GetAltKey())
375
modifiers |= KeyboardEvent::ALT;
376
377
if (Interactor->GetControlKey())
378
modifiers |= KeyboardEvent::CTRL;
379
380
if (Interactor->GetShiftKey())
381
modifiers |= KeyboardEvent::SHIFT;
382
return modifiers;
383
}
384
385
//////////////////////////////////////////////////////////////////////////////////////////////
386
void cv::viz::vtkVizInteractorStyle::OnKeyDown()
387
{
388
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
389
390
String key(Interactor->GetKeySym());
391
if (key.find("XF86ZoomIn") != String::npos)
392
zoomIn();
393
else if (key.find("XF86ZoomOut") != String::npos)
394
zoomOut();
395
else if (key.find("F5") != String::npos)
396
{
397
FlyMode = !FlyMode;
398
std::cout << (FlyMode ? "Fly mode: on" : "Fly mode: off") << std::endl;
399
}
400
401
// Save the initial windows width/height
402
if (win_size_[0] == -1 || win_size_[1] == -1)
403
win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
404
405
switch (Interactor->GetKeyCode())
406
{
407
case 'a': case 'A' : KeysDown |=16; break;
408
case 'z': case 'Z' : KeysDown |=32; break;
409
case 'h': case 'H' : printHelp(); break;
410
case 'p': case 'P' : setRepresentationToPoints(); break;
411
case 'k': case 'K' : exportScene(); break;
412
case 'j': case 'J' : saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break;
413
case 'c': case 'C' : printCameraParams(); break;
414
case '=': zoomIn(); break;
415
case 43: // KEY_PLUS
416
{
417
if (FlyMode)
418
break;
419
if (Interactor->GetAltKey())
420
zoomIn();
421
else
422
changePointsSize(+1.f);
423
break;
424
}
425
case 45: // KEY_MINUS
426
{
427
if (FlyMode)
428
break;
429
if (Interactor->GetAltKey())
430
zoomOut();
431
else
432
changePointsSize(-1.f);
433
break;
434
}
435
// Switch between maximize and original window size
436
case 'f': case 'F':
437
{
438
if (Interactor->GetAltKey())
439
toggleFullScreen();
440
break;
441
}
442
// 's'/'S' w/out ALT
443
case 's': case 'S':
444
{
445
if (Interactor->GetAltKey())
446
toggleStereo();
447
break;
448
}
449
450
case 'o': case 'O':
451
{
452
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
453
cam->SetParallelProjection(!cam->GetParallelProjection());
454
Interactor->Render();
455
break;
456
}
457
458
// Overwrite the camera reset
459
case 'r': case 'R':
460
{
461
if (Interactor->GetAltKey())
462
resetViewerPose();
463
break;
464
}
465
case 'q': case 'Q':
466
Interactor->ExitCallback(); return;
467
default:
468
Superclass::OnKeyDown(); break;
469
}
470
471
KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
472
if (keyboardCallback_)
473
keyboardCallback_(event, keyboard_callback_cookie_);
474
475
if (FlyMode && (KeysDown & (32+16)) == (32+16))
476
{
477
if (State == VTKIS_FORWARDFLY || State == VTKIS_REVERSEFLY)
478
StopState();
479
}
480
else if (FlyMode && (KeysDown & 32) == 32)
481
{
482
if (State == VTKIS_FORWARDFLY)
483
StopState();
484
485
if (State == VTKIS_NONE)
486
StartState(VTKIS_REVERSEFLY);
487
}
488
else if (FlyMode && (KeysDown & 16) == 16)
489
{
490
if (State == VTKIS_REVERSEFLY)
491
StopState();
492
493
if (State == VTKIS_NONE)
494
StartState(VTKIS_FORWARDFLY);
495
}
496
497
Interactor->Render();
498
}
499
500
//////////////////////////////////////////////////////////////////////////////////////////////
501
void cv::viz::vtkVizInteractorStyle::OnKeyUp()
502
{
503
KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
504
if (keyboardCallback_)
505
keyboardCallback_(event, keyboard_callback_cookie_);
506
507
switch (Interactor->GetKeyCode())
508
{
509
case 'a': case 'A' : KeysDown &= ~16; break;
510
case 'z': case 'Z' : KeysDown &= ~32; break;
511
}
512
513
if (State == VTKIS_FORWARDFLY && (KeysDown & 16) == 0)
514
StopState();
515
516
if (State == VTKIS_REVERSEFLY && (KeysDown & 32) == 0)
517
StopState();
518
519
Superclass::OnKeyUp();
520
}
521
522
//////////////////////////////////////////////////////////////////////////////////////////////
523
void cv::viz::vtkVizInteractorStyle::OnMouseMove()
524
{
525
Vec2i p(Interactor->GetEventPosition());
526
MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers());
527
if (mouseCallback_)
528
mouseCallback_(event, mouse_callback_cookie_);
529
530
FindPokedRenderer(p[0], p[1]);
531
532
if (State == VTKIS_ROTATE || State == VTKIS_PAN || State == VTKIS_DOLLY || State == VTKIS_SPIN)
533
{
534
switch (State)
535
{
536
case VTKIS_ROTATE: Rotate(); break;
537
case VTKIS_PAN: Pan(); break;
538
case VTKIS_DOLLY: Dolly(); break;
539
case VTKIS_SPIN: Spin(); break;
540
}
541
542
InvokeEvent(vtkCommand::InteractionEvent, NULL);
543
}
544
545
if (State == VTKIS_FORWARDFLY || State == VTKIS_REVERSEFLY)
546
{
547
vtkCamera *cam = CurrentRenderer->GetActiveCamera();
548
Vec2i thispos(Interactor->GetEventPosition());
549
Vec2i lastpos(Interactor->GetLastEventPosition());
550
551
// we want to steer by an amount proportional to window viewangle and size
552
// compute dx and dy increments relative to last mouse click
553
Vec2i size(Interactor->GetSize());
554
double scalefactor = 5*cam->GetViewAngle()/size[0];
555
556
double dx = - (thispos[0] - lastpos[0])*scalefactor*AngleStepSize;
557
double dy = (thispos[1] - lastpos[1])*scalefactor*AngleStepSize;
558
559
// Temporary until I get smooth flight working
560
DeltaPitch = dy;
561
DeltaYaw = dx;
562
563
InvokeEvent(vtkCommand::InteractionEvent, NULL);
564
}
565
}
566
567
//////////////////////////////////////////////////////////////////////////////////////////////
568
void cv::viz::vtkVizInteractorStyle::OnLeftButtonDown()
569
{
570
Vec2i p(Interactor->GetEventPosition());
571
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
572
MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers());
573
if (mouseCallback_)
574
mouseCallback_(event, mouse_callback_cookie_);
575
576
FindPokedRenderer(p[0], p[1]);
577
if (!CurrentRenderer)
578
return;
579
580
GrabFocus(EventCallbackCommand);
581
582
if (FlyMode)
583
{
584
if(State == VTKIS_REVERSEFLY)
585
State = VTKIS_FORWARDFLY;
586
else
587
{
588
SetupMotionVars();
589
if (State == VTKIS_NONE)
590
StartState(VTKIS_FORWARDFLY);
591
}
592
}
593
else
594
{
595
if (Interactor->GetShiftKey())
596
{
597
if (Interactor->GetControlKey())
598
StartDolly();
599
else
600
StartPan();
601
}
602
else
603
{
604
if (Interactor->GetControlKey())
605
StartSpin();
606
else
607
StartRotate();
608
}
609
}
610
}
611
612
//////////////////////////////////////////////////////////////////////////////////////////////
613
void cv::viz::vtkVizInteractorStyle::OnLeftButtonUp()
614
{
615
Vec2i p(Interactor->GetEventPosition());
616
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers());
617
if (mouseCallback_)
618
mouseCallback_(event, mouse_callback_cookie_);
619
620
switch (State)
621
{
622
case VTKIS_DOLLY: EndDolly(); break;
623
case VTKIS_PAN: EndPan(); break;
624
case VTKIS_SPIN: EndSpin(); break;
625
case VTKIS_ROTATE: EndRotate(); break;
626
case VTKIS_FORWARDFLY: StopState(); break;
627
}
628
629
if (Interactor )
630
ReleaseFocus();
631
}
632
633
//////////////////////////////////////////////////////////////////////////////////////////////
634
void cv::viz::vtkVizInteractorStyle::OnMiddleButtonDown()
635
{
636
Vec2i p(Interactor->GetEventPosition());
637
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
638
MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers());
639
if (mouseCallback_)
640
mouseCallback_(event, mouse_callback_cookie_);
641
642
FindPokedRenderer(p[0], p[1]);
643
if (!CurrentRenderer)
644
return;
645
646
GrabFocus(EventCallbackCommand);
647
StartPan();
648
}
649
650
//////////////////////////////////////////////////////////////////////////////////////////////
651
void cv::viz::vtkVizInteractorStyle::OnMiddleButtonUp()
652
{
653
Vec2i p(Interactor->GetEventPosition());
654
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers());
655
if (mouseCallback_)
656
mouseCallback_(event, mouse_callback_cookie_);
657
658
if (State == VTKIS_PAN)
659
{
660
EndPan();
661
if (Interactor)
662
ReleaseFocus();
663
}
664
}
665
666
//////////////////////////////////////////////////////////////////////////////////////////////
667
void cv::viz::vtkVizInteractorStyle::OnRightButtonDown()
668
{
669
Vec2i p(Interactor->GetEventPosition());
670
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
671
MouseEvent event(type, MouseEvent::RightButton, p, getModifiers());
672
if (mouseCallback_)
673
mouseCallback_(event, mouse_callback_cookie_);
674
675
FindPokedRenderer(p[0], p[1]);
676
if (!CurrentRenderer)
677
return;
678
679
GrabFocus(EventCallbackCommand);
680
681
if (FlyMode)
682
{
683
if (State == VTKIS_FORWARDFLY)
684
State = VTKIS_REVERSEFLY;
685
else
686
{
687
SetupMotionVars();
688
if (State == VTKIS_NONE)
689
StartState(VTKIS_REVERSEFLY);
690
}
691
692
}
693
else
694
StartDolly();
695
}
696
697
698
//////////////////////////////////////////////////////////////////////////////////////////////
699
void cv::viz::vtkVizInteractorStyle::OnRightButtonUp()
700
{
701
Vec2i p(Interactor->GetEventPosition());
702
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers());
703
if (mouseCallback_)
704
mouseCallback_(event, mouse_callback_cookie_);
705
706
if(State == VTKIS_DOLLY)
707
{
708
EndDolly();
709
if (Interactor)
710
ReleaseFocus();
711
}
712
713
if (State == VTKIS_REVERSEFLY)
714
{
715
StopState();
716
if (Interactor)
717
ReleaseFocus();
718
}
719
}
720
721
//////////////////////////////////////////////////////////////////////////////////////////////
722
void cv::viz::vtkVizInteractorStyle::OnMouseWheelForward()
723
{
724
Vec2i p(Interactor->GetEventPosition());
725
MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers());
726
if (mouseCallback_)
727
mouseCallback_(event, mouse_callback_cookie_);
728
if (Interactor->GetRepeatCount() && mouseCallback_)
729
mouseCallback_(event, mouse_callback_cookie_);
730
731
if (Interactor->GetAltKey())
732
{
733
// zoom
734
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
735
double opening_angle = cam->GetViewAngle();
736
if (opening_angle > 15.0)
737
opening_angle -= 1.0;
738
739
cam->SetViewAngle(opening_angle);
740
cam->Modified();
741
CurrentRenderer->ResetCameraClippingRange();
742
CurrentRenderer->Modified();
743
Interactor->Render();
744
}
745
else
746
{
747
FindPokedRenderer(p[0], p[1]);
748
if (!CurrentRenderer)
749
return;
750
751
GrabFocus(EventCallbackCommand);
752
StartDolly();
753
Dolly(pow(1.1, MotionFactor * 0.2 * MouseWheelMotionFactor));
754
EndDolly();
755
ReleaseFocus();
756
}
757
}
758
759
//////////////////////////////////////////////////////////////////////////////////////////////
760
void cv::viz::vtkVizInteractorStyle::OnMouseWheelBackward()
761
{
762
Vec2i p(Interactor->GetEventPosition());
763
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers());
764
if (mouseCallback_)
765
mouseCallback_(event, mouse_callback_cookie_);
766
767
if (Interactor->GetRepeatCount() && mouseCallback_)
768
mouseCallback_(event, mouse_callback_cookie_);
769
770
if (Interactor->GetAltKey())
771
{
772
// zoom
773
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
774
double opening_angle = cam->GetViewAngle();
775
if (opening_angle < 170.0)
776
opening_angle += 1.0;
777
778
cam->SetViewAngle(opening_angle);
779
cam->Modified();
780
CurrentRenderer->ResetCameraClippingRange();
781
CurrentRenderer->Modified();
782
Interactor->Render();
783
}
784
else
785
{
786
FindPokedRenderer(p[0], p[1]);
787
if (!CurrentRenderer)
788
return;
789
790
GrabFocus(EventCallbackCommand);
791
StartDolly();
792
Dolly(pow(1.1, MotionFactor * -0.2 * MouseWheelMotionFactor));
793
EndDolly();
794
ReleaseFocus();
795
}
796
}
797
798
//////////////////////////////////////////////////////////////////////////////////////////////
799
void cv::viz::vtkVizInteractorStyle::OnTimer()
800
{
801
if (State == VTKIS_FORWARDFLY || State == VTKIS_REVERSEFLY)
802
Fly();
803
804
Interactor->Render();
805
}
806
807
//////////////////////////////////////////////////////////////////////////////////////////////
808
809
void cv::viz::vtkVizInteractorStyle::Rotate()
810
{
811
if (!CurrentRenderer)
812
return;
813
814
Vec2i dxy = Vec2i(Interactor->GetEventPosition()) - Vec2i(Interactor->GetLastEventPosition());
815
Vec2i size(CurrentRenderer->GetRenderWindow()->GetSize());
816
817
double delta_elevation = -20.0 / size[1];
818
double delta_azimuth = -20.0 / size[0];
819
820
double rxf = dxy[0] * delta_azimuth * MotionFactor;
821
double ryf = dxy[1] * delta_elevation * MotionFactor;
822
823
vtkCamera *camera = CurrentRenderer->GetActiveCamera();
824
camera->Azimuth(rxf);
825
camera->Elevation(ryf);
826
camera->OrthogonalizeViewUp();
827
828
if (AutoAdjustCameraClippingRange)
829
CurrentRenderer->ResetCameraClippingRange();
830
831
if (Interactor->GetLightFollowCamera())
832
CurrentRenderer->UpdateLightsGeometryToFollowCamera();
833
834
Interactor->Render();
835
}
836
837
//////////////////////////////////////////////////////////////////////////////////////////////
838
void cv::viz::vtkVizInteractorStyle::Spin()
839
{
840
if (!CurrentRenderer)
841
return;
842
843
vtkRenderWindowInteractor *rwi = Interactor;
844
845
double *center = CurrentRenderer->GetCenter();
846
847
double newAngle = vtkMath::DegreesFromRadians( atan2( rwi->GetEventPosition()[1] - center[1], rwi->GetEventPosition()[0] - center[0] ) );
848
double oldAngle = vtkMath::DegreesFromRadians( atan2( rwi->GetLastEventPosition()[1] - center[1], rwi->GetLastEventPosition()[0] - center[0] ) );
849
850
vtkCamera *camera = CurrentRenderer->GetActiveCamera();
851
camera->Roll( newAngle - oldAngle );
852
camera->OrthogonalizeViewUp();
853
854
rwi->Render();
855
}
856
857
//////////////////////////////////////////////////////////////////////////////////////////////
858
void cv::viz::vtkVizInteractorStyle::Pan()
859
{
860
if (!CurrentRenderer)
861
return;
862
863
vtkRenderWindowInteractor *rwi = Interactor;
864
865
double viewFocus[4], focalDepth, viewPoint[3];
866
double newPickPoint[4], oldPickPoint[4], motionVector[3];
867
868
// Calculate the focal depth since we'll be using it a lot
869
870
vtkCamera *camera = CurrentRenderer->GetActiveCamera();
871
camera->GetFocalPoint(viewFocus);
872
ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
873
focalDepth = viewFocus[2];
874
875
ComputeDisplayToWorld(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1], focalDepth, newPickPoint);
876
877
// Has to recalc old mouse point since the viewport has moved, so can't move it outside the loop
878
ComputeDisplayToWorld(rwi->GetLastEventPosition()[0], rwi->GetLastEventPosition()[1], focalDepth, oldPickPoint);
879
880
// Camera motion is reversed
881
motionVector[0] = oldPickPoint[0] - newPickPoint[0];
882
motionVector[1] = oldPickPoint[1] - newPickPoint[1];
883
motionVector[2] = oldPickPoint[2] - newPickPoint[2];
884
885
camera->GetFocalPoint(viewFocus);
886
camera->GetPosition(viewPoint);
887
camera->SetFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]);
888
camera->SetPosition( motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] + viewPoint[2]);
889
890
if (Interactor->GetLightFollowCamera())
891
CurrentRenderer->UpdateLightsGeometryToFollowCamera();
892
893
Interactor->Render();
894
}
895
896
//////////////////////////////////////////////////////////////////////////////////////////////
897
898
void cv::viz::vtkVizInteractorStyle::Dolly()
899
{
900
if (!CurrentRenderer)
901
return;
902
903
int dy = Interactor->GetEventPosition()[1] - Interactor->GetLastEventPosition()[1];
904
Dolly(pow(1.1, MotionFactor * dy / CurrentRenderer->GetCenter()[1]));
905
}
906
907
void cv::viz::vtkVizInteractorStyle::Dolly(double factor)
908
{
909
if (!CurrentRenderer)
910
return;
911
912
vtkCamera *camera = CurrentRenderer->GetActiveCamera();
913
if (camera->GetParallelProjection())
914
camera->SetParallelScale(camera->GetParallelScale() / factor);
915
else
916
{
917
camera->Dolly(factor);
918
if (AutoAdjustCameraClippingRange)
919
CurrentRenderer->ResetCameraClippingRange();
920
}
921
922
if (Interactor->GetLightFollowCamera())
923
CurrentRenderer->UpdateLightsGeometryToFollowCamera();
924
925
Interactor->Render();
926
}
927
//////////////////////////////////////////////////////////////////////////////////////////////
928
929
void cv::viz::vtkVizInteractorStyle::Fly()
930
{
931
if (CurrentRenderer == NULL)
932
return;
933
934
if (KeysDown)
935
FlyByKey();
936
else
937
FlyByMouse();
938
939
CurrentRenderer->GetActiveCamera()->OrthogonalizeViewUp();
940
941
if (AutoAdjustCameraClippingRange)
942
CurrentRenderer->ResetCameraClippingRange();
943
944
if (Interactor->GetLightFollowCamera())
945
CurrentRenderer->UpdateLightsGeometryToFollowCamera();
946
}
947
948
void cv::viz::vtkVizInteractorStyle::SetupMotionVars()
949
{
950
Vec6d bounds;
951
CurrentRenderer->ComputeVisiblePropBounds(bounds.val);
952
953
if ( !vtkMath::AreBoundsInitialized(bounds.val) )
954
DiagonalLength = 1.0;
955
else
956
DiagonalLength = norm(Vec3d(bounds[0], bounds[2], bounds[4]) - Vec3d(bounds[1], bounds[3], bounds[5]));
957
}
958
959
void cv::viz::vtkVizInteractorStyle::MotionAlongVector(const Vec3d& vector, double amount, vtkCamera* cam)
960
{
961
// move camera and focus along DirectionOfProjection
962
Vec3d campos = Vec3d(cam->GetPosition()) - amount * vector;
963
Vec3d camfoc = Vec3d(cam->GetFocalPoint()) - amount * vector;
964
965
cam->SetPosition(campos.val);
966
cam->SetFocalPoint(camfoc.val);
967
}
968
969
void cv::viz::vtkVizInteractorStyle::FlyByMouse()
970
{
971
vtkCamera* cam = CurrentRenderer->GetActiveCamera();
972
double speed = DiagonalLength * MotionStepSize * MotionUserScale;
973
speed = speed * ( Interactor->GetShiftKey() ? MotionAccelerationFactor : 1.0);
974
975
// Sidestep
976
if (Interactor->GetAltKey())
977
{
978
if (DeltaYaw!=0.0)
979
{
980
vtkMatrix4x4 *vtm = cam->GetViewTransformMatrix();
981
Vec3d a_vector(vtm->GetElement(0,0), vtm->GetElement(0,1), vtm->GetElement(0,2));
982
983
MotionAlongVector(a_vector, -DeltaYaw*speed, cam);
984
}
985
if (DeltaPitch!=0.0)
986
{
987
Vec3d a_vector(cam->GetViewUp());
988
MotionAlongVector(a_vector, DeltaPitch*speed, cam);
989
}
990
}
991
else
992
{
993
cam->Yaw(DeltaYaw);
994
cam->Pitch(DeltaPitch);
995
DeltaYaw = 0;
996
DeltaPitch = 0;
997
}
998
//
999
if (!Interactor->GetControlKey())
1000
{
1001
Vec3d a_vector(cam->GetDirectionOfProjection()); // reversed (use -speed)
1002
switch (State)
1003
{
1004
case VTKIS_FORWARDFLY: MotionAlongVector(a_vector, -speed, cam); break;
1005
case VTKIS_REVERSEFLY: MotionAlongVector(a_vector, speed, cam); break;
1006
}
1007
}
1008
}
1009
1010
void cv::viz::vtkVizInteractorStyle::FlyByKey()
1011
{
1012
vtkCamera* cam = CurrentRenderer->GetActiveCamera();
1013
1014
double speed = DiagonalLength * MotionStepSize * MotionUserScale;
1015
speed = speed * ( Interactor->GetShiftKey() ? MotionAccelerationFactor : 1.0);
1016
1017
// Left and right
1018
if (Interactor->GetAltKey())
1019
{ // Sidestep
1020
vtkMatrix4x4 *vtm = cam->GetViewTransformMatrix();
1021
Vec3d a_vector(vtm->GetElement(0,0), vtm->GetElement(0,1), vtm->GetElement(0,2));
1022
1023
if (KeysDown & 1)
1024
MotionAlongVector(a_vector, -speed, cam);
1025
1026
if (KeysDown & 2)
1027
MotionAlongVector(a_vector, speed, cam);
1028
}
1029
else
1030
{
1031
if (KeysDown & 1)
1032
cam->Yaw( AngleStepSize);
1033
1034
if (KeysDown & 2)
1035
cam->Yaw(-AngleStepSize);
1036
}
1037
1038
// Up and Down
1039
if (Interactor->GetControlKey())
1040
{ // Sidestep
1041
Vec3d a_vector = Vec3d(cam->GetViewUp());
1042
if (KeysDown & 4)
1043
MotionAlongVector(a_vector,-speed, cam);
1044
1045
if (KeysDown & 8)
1046
MotionAlongVector(a_vector, speed, cam);
1047
}
1048
else
1049
{
1050
if (KeysDown & 4)
1051
cam->Pitch(-AngleStepSize);
1052
1053
if (KeysDown & 8)
1054
cam->Pitch( AngleStepSize);
1055
}
1056
1057
// forward and backward
1058
Vec3d a_vector(cam->GetDirectionOfProjection());
1059
if (KeysDown & 16)
1060
MotionAlongVector(a_vector, speed, cam);
1061
1062
if (KeysDown & 32)
1063
MotionAlongVector(a_vector,-speed, cam);
1064
}
1065
1066
//////////////////////////////////////////////////////////////////////////////////////////////
1067
1068
void cv::viz::vtkVizInteractorStyle::PrintSelf(ostream& os, vtkIndent indent)
1069
{
1070
Superclass::PrintSelf(os, indent);
1071
os << indent << "MotionFactor: " << MotionFactor << "\n";
1072
os << indent << "MotionStepSize: " << MotionStepSize << "\n";
1073
os << indent << "MotionAccelerationFactor: "<< MotionAccelerationFactor << "\n";
1074
os << indent << "AngleStepSize: " << AngleStepSize << "\n";
1075
os << indent << "MotionUserScale: "<< MotionUserScale << "\n";
1076
}
1077
1078