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, ozantonkal (at) gmail.com 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