Home | History | Annotate | Download | only in vtk
      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