/* * Software License Agreement (BSD License) * * Point Cloud Library (PCL) - www.pointclouds.org * Copyright (c) 2010, Willow Garage, Inc. * Copyright (c) 2012-, Open Perception, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the copyright holder(s) nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include "interactor_style_3dv.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include void interactor_style_3dv::OnChar() { // Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); if (Interactor->GetKeyCode () >= '0' && Interactor->GetKeyCode () <= '9') return; std::string key (Interactor->GetKeySym ()); if (key.find ("XF86ZoomIn") != std::string::npos) zoomIn (); else if (key.find ("XF86ZoomOut") != std::string::npos) zoomOut (); bool keymod = false; switch (modifier_) { case pcl::visualization::INTERACTOR_KB_MOD_ALT: { keymod = Interactor->GetAltKey (); break; } case pcl::visualization::INTERACTOR_KB_MOD_CTRL: { keymod = Interactor->GetControlKey (); break; } case pcl::visualization::INTERACTOR_KB_MOD_SHIFT: { keymod = Interactor->GetShiftKey (); break; } } switch (Interactor->GetKeyCode ()) { // All of the options below simply exit case 'h': case 'H': case 'c': case 'C': case 43: // KEY_PLUS case 45: // KEY_MINUS case 'f': case 'F': case 'g': case 'G': case 'q': case 'Q': case 'r': case 'R': case 'm': case 'M': { break; } default: { Superclass::OnChar (); break; } } } void interactor_style_3dv::OnKeyDown() { if (!init_) { pcl::console::print_error ("[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n"); return; } if (!rens_) { pcl::console::print_error ("[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing.\n"); return; } FindPokedRenderer(Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); // Save the initial windows width/height if (win_height_ == -1 || win_width_ == -1) { int *win_size = Interactor->GetRenderWindow ()->GetSize (); win_height_ = win_size[0]; win_width_ = win_size[1]; } // Get the status of special keys (Cltr+Alt+Shift) bool shift = Interactor->GetShiftKey (); bool ctrl = Interactor->GetControlKey (); bool alt = Interactor->GetAltKey (); bool keymod = false; switch (modifier_) { case pcl::visualization::INTERACTOR_KB_MOD_ALT: { keymod = alt; break; } case pcl::visualization::INTERACTOR_KB_MOD_CTRL: { keymod = ctrl; break; } case pcl::visualization::INTERACTOR_KB_MOD_SHIFT: { keymod = shift; break; } } // ---[ Check the rest of the key codes std::string key (Interactor->GetKeySym ()); if (key.find ("XF86ZoomIn") != std::string::npos) zoomIn (); else if (key.find ("XF86ZoomOut") != std::string::npos) zoomOut (); switch (Interactor->GetKeyCode ()) { case 'h': case 'H': { pcl::console::print_info ("\n\r[II] 3dv-client: 3D visualization window shortcuts\n\n\r" " p, P : toggle point cloud visualization\n\r" " o, O : toggle obstacles visualization\n\r" " t, T : toggle terrain visualization\n\r" " m, M : toggle terrain grid map visualization\n\r" " v, V : toggle orientation rate visualization\n\r" "\n\r" " c, C : display current camera/window parameters\n\r" " f, F : fly to point mode\n\r" "\n\r" " q, Q : stop and call VTK's TerminateApp\n\r" "\n\r" " +/- : increment/decrement overall point size\n\r" " +/- [+ ALT] : zoom in/out \n\r" "\n\r" " g, G : display scale grid (on/off)\n\r" "\n\r" " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n\r" "\n\r" " ALT + f, F : switch between maximized window mode and original size\n\r" ); break; } // display current camera settings/parameters case 'c': case 'C': { vtkSmartPointer cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); double clip[2], focal[3], pos[3], view[3]; cam->GetClippingRange (clip); cam->GetFocalPoint (focal); cam->GetPosition (pos); cam->GetViewUp (view); int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); int *win_size = Interactor->GetRenderWindow ()->GetSize (); std::cerr << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << cam->GetViewAngle () / 180.0 * M_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] << endl; break; } case '=': { zoomIn(); break; } case 43: // KEY_PLUS { if(alt) zoomIn (); else { vtkSmartPointer ac = CurrentRenderer->GetActors (); vtkCollectionSimpleIterator ait; for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) { for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) { vtkSmartPointer apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); float psize = apart->GetProperty ()->GetPointSize (); if (psize < 63.0f) apart->GetProperty ()->SetPointSize (psize + 1.0f); } } } break; } case 45: // KEY_MINUS { if(alt) zoomOut (); else { vtkSmartPointer ac = CurrentRenderer->GetActors (); vtkCollectionSimpleIterator ait; for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) { for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) { vtkSmartPointer apart = static_cast (path->GetLastNode ()->GetViewProp ()); float psize = apart->GetProperty ()->GetPointSize (); if (psize > 1.0f) apart->GetProperty ()->SetPointSize (psize - 1.0f); } } } break; } // Switch between maximize and original window size case 'f': case 'F': { if (keymod) { // Get screen size int *temp = Interactor->GetRenderWindow ()->GetScreenSize (); int scr_size[2]; scr_size[0] = temp[0]; scr_size[1] = temp[1]; // Get window size temp = Interactor->GetRenderWindow ()->GetSize (); int win_size[2]; win_size[0] = temp[0]; win_size[1] = temp[1]; // Is window size = max? if (win_size[0] == max_win_height_ && win_size[1] == max_win_width_) { // Set the previously saved 'current' window size Interactor->GetRenderWindow ()->SetSize (win_height_, win_width_); // Set the previously saved window position Interactor->GetRenderWindow ()->SetPosition (win_pos_x_, win_pos_y_); Interactor->GetRenderWindow ()->Render (); Interactor->Render (); } // Set to max else { int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); // Save the current window position win_pos_x_ = win_pos[0]; win_pos_y_ = win_pos[1]; // Save the current window size win_height_ = win_size[0]; win_width_ = win_size[1]; // Set the maximum window size Interactor->GetRenderWindow ()->SetSize (scr_size[0], scr_size[1]); Interactor->GetRenderWindow ()->Render (); Interactor->Render (); int *win_size = Interactor->GetRenderWindow ()->GetSize (); // Save the maximum window size max_win_height_ = win_size[0]; max_win_width_ = win_size[1]; } } else { AnimState = VTKIS_ANIM_ON; vtkAssemblyPath *path = NULL; Interactor->GetPicker ()->Pick (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1], 0.0, CurrentRenderer); vtkAbstractPropPicker *picker; if ((picker = vtkAbstractPropPicker::SafeDownCast (Interactor->GetPicker ()))) path = picker->GetPath (); if (path != NULL) Interactor->FlyTo (CurrentRenderer, picker->GetPickPosition ()); AnimState = VTKIS_ANIM_OFF; } break; } // Display a grid/scale over the screen case 'g': case 'G': { if (!grid_enabled_) { grid_actor_->TopAxisVisibilityOn (); CurrentRenderer->AddViewProp (grid_actor_); grid_enabled_ = true; } else { CurrentRenderer->RemoveViewProp (grid_actor_); grid_enabled_ = false; } break; } case 'm': case 'M': { break; } // Overwrite the camera reset case 'r': case 'R': { vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); /* if (!keymod) { FindPokedRenderer(Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); if(CurrentRenderer != 0) CurrentRenderer->ResetCamera (); else PCL_WARN ("no current renderer on the interactor style."); CurrentRenderer->Render (); break; } static pcl::visualization::CloudActorMap::iterator it = actors_->begin (); // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault. bool found_transformation = false; for (unsigned idx = 0; idx < actors_->size (); ++idx, ++it) { if (it == actors_->end ()) it = actors_->begin (); const pcl::visualization::CloudActor& actor = it->second; if (actor.viewpoint_transformation_.GetPointer ()) { found_transformation = true; break; } } // if a valid transformation was found, use it otherwise fall back to default view point. if (found_transformation) { const pcl::visualization::CloudActor& actor = it->second; cam->SetPosition (actor.viewpoint_transformation_->GetElement (0, 3), actor.viewpoint_transformation_->GetElement (1, 3), actor.viewpoint_transformation_->GetElement (2, 3)); cam->SetFocalPoint (actor.viewpoint_transformation_->GetElement (0, 3) - actor.viewpoint_transformation_->GetElement (0, 2), actor.viewpoint_transformation_->GetElement (1, 3) - actor.viewpoint_transformation_->GetElement (1, 2), actor.viewpoint_transformation_->GetElement (2, 3) - actor.viewpoint_transformation_->GetElement (2, 2)); cam->SetViewUp (actor.viewpoint_transformation_->GetElement (0, 1), actor.viewpoint_transformation_->GetElement (1, 1), actor.viewpoint_transformation_->GetElement (2, 1)); } else { //, 0.715357, 0.012124, 0.698653 cam->SetPosition (0.5, 0.0, 0.5); cam->SetFocalPoint (0, 0, 1); cam->SetViewUp (1.03093, -0.140037, 1.86098); } // go to the next actor for the next key-press event. if (it != actors_->end ()) ++it; else it = actors_->begin (); */ cam->SetPosition (-3.0, 0.0, 6.0); cam->SetFocalPoint (0, 0, 1); cam->SetViewUp (1.03093, -0.140037, 1.86098); CurrentRenderer->SetActiveCamera (cam); CurrentRenderer->ResetCameraClippingRange (); CurrentRenderer->Render (); break; } case 'q': case 'Q': { Interactor->ExitCallback (); return; } default: { Superclass::OnKeyDown (); break; } } pcl::visualization::KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); keyboard_signal_ (event); rens_->Render (); Interactor->Render (); } vtkStandardNewMacro(interactor_style_3dv);