$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2010, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * $Id: interactor_style.cpp 36905 2011-05-27 00:34:09Z michael.s.dixon $ 00035 * 00036 */ 00037 00038 #include <list> 00039 #include <pcl_visualization/common/io.h> 00040 #include <pcl_visualization/interactor_style.h> 00041 #include <vtkPolyData.h> 00042 #include <vtkMapper.h> 00043 #include <vtkPolyDataMapper.h> 00044 #include <vtkPointData.h> 00045 #include <vtkCellArray.h> 00046 #include <vtkAppendPolyData.h> 00047 #include <vtkTextProperty.h> 00048 #include <vtkAbstractPicker.h> 00049 #include <vtkAbstractPropPicker.h> 00050 #include <vtkPlanes.h> 00051 00053 00054 void 00055 pcl_visualization::PCLVisualizerInteractorStyle::Initialize () 00056 { 00057 // Set windows size (width, height) to unknown (-1) 00058 win_height_ = win_width_ = -1; 00059 win_pos_x_ = win_pos_y_ = 0; 00060 max_win_height_ = max_win_width_ = -1; 00061 00062 // Grid is disabled by default 00063 grid_enabled_ = false; 00064 grid_actor_ = vtkSmartPointer<vtkLegendScaleActor>::New (); 00065 00066 // LUT is disabled by default 00067 lut_enabled_ = false; 00068 lut_actor_ = vtkSmartPointer<vtkScalarBarActor>::New (); 00069 lut_actor_->SetTitle (""); 00070 lut_actor_->SetOrientationToHorizontal (); 00071 lut_actor_->SetPosition (0.05, 0.01); 00072 lut_actor_->SetWidth (0.9); 00073 lut_actor_->SetHeight (0.1); 00074 lut_actor_->SetNumberOfLabels (lut_actor_->GetNumberOfLabels () * 2); 00075 vtkSmartPointer<vtkTextProperty> prop = lut_actor_->GetLabelTextProperty (); 00076 prop->SetFontSize (10); 00077 lut_actor_->SetLabelTextProperty (prop); 00078 lut_actor_->SetTitleTextProperty (prop); 00079 00080 // Create the image filter and PNG writer objects 00081 wif_ = vtkSmartPointer<vtkWindowToImageFilter>::New (); 00082 snapshot_writer_ = vtkSmartPointer<vtkPNGWriter>::New (); 00083 snapshot_writer_->SetInputConnection (wif_->GetOutputPort ()); 00084 00085 init_ = true; 00086 } 00087 00089 00090 void 00091 pcl_visualization::PCLVisualizerInteractorStyle::zoomIn () 00092 { 00093 FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); 00094 // Zoom in 00095 StartDolly (); 00096 double factor = 10.0 * 0.2 * .5; 00097 Dolly (pow (1.1, factor)); 00098 EndDolly (); 00099 } 00100 00102 00103 void 00104 pcl_visualization::PCLVisualizerInteractorStyle::zoomOut () 00105 { 00106 FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); 00107 // Zoom out 00108 StartDolly (); 00109 double factor = 10.0 * -0.2 * .5; 00110 Dolly (pow (1.1, factor)); 00111 EndDolly (); 00112 } 00113 00115 00116 void 00117 pcl_visualization::PCLVisualizerInteractorStyle::OnChar () 00118 { 00119 if (!init_) 00120 { 00121 pcl::console::print_error ("[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n"); 00122 return; 00123 } 00124 00125 if (!rens_) 00126 { 00127 pcl::console::print_error ("[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing.\n"); 00128 return; 00129 } 00130 00131 FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); 00132 00133 if (wif_->GetInput () == NULL) 00134 { 00135 wif_->SetInput (Interactor->GetRenderWindow ()); 00136 wif_->Modified (); 00137 snapshot_writer_->Modified (); 00138 } 00139 00140 // Save the initial windows width/height 00141 if (win_height_ == -1 || win_width_ == -1) 00142 { 00143 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00144 win_height_ = win_size[0]; 00145 win_width_ = win_size[1]; 00146 } 00147 00148 // Get the status of special keys (Cltr+Alt+Shift) 00149 //bool shift = Interactor->GetShiftKey (); 00150 bool ctrl = Interactor->GetControlKey (); 00151 bool alt = Interactor->GetAltKey (); 00152 00153 //fprintf (stderr, "Key sym: %s\n", Interactor->GetKeySym ()); 00154 // ---[ Check the rest of the key codes 00155 00156 // Switch between point color/geometry handlers 00157 if (Interactor->GetKeyCode () >= '0' && Interactor->GetKeyCode () <= '9') 00158 { 00159 CloudActorMap::iterator it; 00160 int index = Interactor->GetKeyCode () - '0' - 1; 00161 if (index == -1) index = 9; 00162 00163 // Add 10 more for CTRL+0..9 keys 00164 if (ctrl) 00165 index += 10; 00166 00167 // Geometry ? 00168 if (alt) 00169 { 00170 for (it = actors_->begin (); it != actors_->end (); ++it) 00171 { 00172 CloudActor *act = &(*it).second; 00173 if (index >= (int)act->geometry_handlers.size ()) 00174 continue; 00175 00176 // Save the geometry handler index for later usage 00177 act->geometry_handler_index_ = index; 00178 00179 // Create the new geometry 00180 PointCloudGeometryHandler<sensor_msgs::PointCloud2>::ConstPtr geometry_handler = act->geometry_handlers[index]; 00181 //pcl::console::print_debug ("[OnChar] Setting a new geometry handler (%s) for actor %s\n", geometry_handler->getFieldName ().c_str (), (*it).first.c_str ()); 00182 00183 // Use the handler to obtain the geometry 00184 vtkSmartPointer<vtkPoints> points; 00185 geometry_handler->getGeometry (points); 00186 00187 // Set the vertices 00188 vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New (); 00189 for (vtkIdType i = 0; i < (int)points->GetNumberOfPoints (); ++i) 00190 vertices->InsertNextCell ((vtkIdType)1, &i); 00191 00192 // Create the data 00193 vtkSmartPointer<vtkPolyData> data = vtkSmartPointer<vtkPolyData>::New (); 00194 data->SetPoints (points); 00195 data->SetVerts (vertices); 00196 // Modify the mapper 00197 vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(act->actor->GetMapper ()); 00198 mapper->SetInput (data); 00199 // Modify the actor 00200 act->actor->SetMapper (mapper); 00201 act->actor->Modified (); 00202 } 00203 } 00204 else 00205 { 00206 for (it = actors_->begin (); it != actors_->end (); ++it) 00207 { 00208 CloudActor *act = &(*it).second; 00209 // Check for out of bounds 00210 if (index >= (int)act->color_handlers.size ()) 00211 continue; 00212 00213 // Save the color handler index for later usage 00214 act->color_handler_index_ = index; 00215 00216 // Get the new color 00217 PointCloudColorHandler<sensor_msgs::PointCloud2>::ConstPtr color_handler = act->color_handlers[index]; 00218 00219 //pcl::console::print_debug ("[OnChar] Setting a new color handler (%s) for actor %s\n", color_handler->getFieldName ().c_str (), (*it).first.c_str ()); 00220 00221 vtkSmartPointer<vtkDataArray> scalars; 00222 color_handler->getColor (scalars); 00223 double minmax[2]; 00224 scalars->GetRange (minmax); 00225 // Update the data 00226 vtkPolyData *data = static_cast<vtkPolyData*>(act->actor->GetMapper ()->GetInput ()); 00227 data->GetPointData ()->SetScalars (scalars); 00228 data->Update (); 00229 // Modify the mapper 00230 vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(act->actor->GetMapper ()); 00231 mapper->SetScalarRange (minmax); 00232 mapper->SetScalarModeToUsePointData (); 00233 mapper->SetInput (data); 00234 // Modify the actor 00235 act->actor->SetMapper (mapper); 00236 act->actor->Modified (); 00237 } 00238 } 00239 00240 Interactor->Render (); 00241 return; 00242 } 00243 00244 std::string key (Interactor->GetKeySym ()); 00245 if (key.find ("XF86ZoomIn") != std::string::npos) 00246 zoomIn (); 00247 else if (key.find ("XF86ZoomOut") != std::string::npos) 00248 zoomOut (); 00249 00250 switch (Interactor->GetKeyCode ()) 00251 { 00252 case 'h': case 'H': 00253 { 00254 pcl::console::print_info ("| Help:\n" 00255 "-------\n" 00256 " p, P : switch to a point-based representation\n" 00257 " w, W : switch to a wireframe-based representation (where available)\n" 00258 " s, S : switch to a surface-based representation (where available)\n" 00259 "\n" 00260 " j, J : take a .PNG snapshot of the current window view\n" 00261 " c, C : display current camera/window parameters\n" 00262 " f, F : fly to point mode\n" 00263 "\n" 00264 " + / - : increment/decrement overall point size\n" 00265 "\n" 00266 " g, G : display scale grid (on/off)\n" 00267 " u, U : display lookup table (on/off)\n" 00268 "\n" 00269 " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n" 00270 "\n" 00271 " ALT + s, S : turn stereo mode on/off\n" 00272 " ALT + f, F : switch between maximized window mode and original size\n" 00273 "\n" 00274 " l, L : list all available geometric and color handlers for the current actor map\n" 00275 " ALT + 0..9 [+ CTRL] : switch between different geometric handlers (where available)\n" 00276 " 0..9 [+ CTRL] : switch between different color handlers (where available)\n" 00277 ); 00278 break; 00279 } 00280 00281 // Get the list of available handlers 00282 case 'l': case 'L': 00283 { 00284 // Iterate over the entire actors list and extract the geomotry/color handlers list 00285 for (CloudActorMap::iterator it = actors_->begin (); it != actors_->end (); ++it) 00286 { 00287 std::list<std::string> geometry_handlers_list, color_handlers_list; 00288 CloudActor *act = &(*it).second; 00289 for (size_t i = 0; i < act->geometry_handlers.size (); ++i) 00290 geometry_handlers_list.push_back (act->geometry_handlers[i]->getFieldName ()); 00291 for (size_t i = 0; i < act->color_handlers.size (); ++i) 00292 color_handlers_list.push_back (act->color_handlers[i]->getFieldName ()); 00293 00294 if (!geometry_handlers_list.empty ()) 00295 { 00296 int i = 0; 00297 pcl::console::print_info ("List of available geometry handlers for actor "); pcl::console::print_value ("%s: ", (*it).first.c_str ()); 00298 for (std::list<std::string>::iterator git = geometry_handlers_list.begin (); git != geometry_handlers_list.end (); ++git) 00299 pcl::console::print_value ("%s(%d) ", (*git).c_str (), ++i); 00300 pcl::console::print_info ("\n"); 00301 } 00302 if (!color_handlers_list.empty ()) 00303 { 00304 int i = 0; 00305 pcl::console::print_info ("List of available color handlers for actor "); pcl::console::print_value ("%s: ", (*it).first.c_str ()); 00306 for (std::list<std::string>::iterator cit = color_handlers_list.begin (); cit != color_handlers_list.end (); ++cit) 00307 pcl::console::print_value ("%s(%d) ", (*cit).c_str (), ++i); 00308 pcl::console::print_info ("\n"); 00309 } 00310 } 00311 00312 break; 00313 } 00314 00315 // Switch representation to points 00316 case 'p': case 'P': 00317 { 00318 vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors (); 00319 vtkCollectionSimpleIterator ait; 00320 for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) 00321 { 00322 for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) 00323 { 00324 vtkSmartPointer<vtkActor> apart = (vtkActor*)path->GetLastNode ()->GetViewProp (); 00325 apart->GetProperty ()->SetRepresentationToPoints (); 00326 } 00327 } 00328 break; 00329 } 00330 // Save a PNG snapshot with the current screen 00331 case 'j': case 'J': 00332 { 00333 wif_->Modified (); // Update the WindowToImageFilter 00334 snapshot_writer_->Modified (); 00335 char cam_fn[80], snapshot_fn[80]; 00336 unsigned t = time (0); 00337 sprintf (snapshot_fn, "screenshot-%d.png" , t); 00338 snapshot_writer_->SetFileName (snapshot_fn); 00339 snapshot_writer_->Write (); 00340 00341 sprintf (cam_fn, "screenshot-%d.cam", t); 00342 ofstream ofs_cam; 00343 ofs_cam.open (cam_fn); 00344 vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); 00345 double clip[2], focal[3], pos[3], view[3]; 00346 cam->GetClippingRange (clip); 00347 cam->GetFocalPoint (focal); 00348 cam->GetPosition (pos); 00349 cam->GetViewUp (view); 00350 int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); 00351 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00352 ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << 00353 pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << 00354 win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] 00355 << endl; 00356 ofs_cam.close (); 00357 00358 pcl::console::print_info ("Screenshot (%s) and camera information (%s) successfully captured.\n", snapshot_fn, cam_fn); 00359 break; 00360 } 00361 // display current camera settings/parameters 00362 case 'c': case 'C': 00363 { 00364 vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); 00365 double clip[2], focal[3], pos[3], view[3]; 00366 cam->GetClippingRange (clip); 00367 cam->GetFocalPoint (focal); 00368 cam->GetPosition (pos); 00369 cam->GetViewUp (view); 00370 int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); 00371 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00372 std::cerr << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << 00373 pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << 00374 win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] 00375 << endl; 00376 break; 00377 } 00378 case 43: // KEY_PLUS 00379 { 00380 vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors (); 00381 vtkCollectionSimpleIterator ait; 00382 for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) 00383 { 00384 for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) 00385 { 00386 vtkSmartPointer<vtkActor> apart = (vtkActor*)path->GetLastNode ()->GetViewProp (); 00387 int psize = apart->GetProperty ()->GetPointSize (); 00388 if (psize < 63) 00389 apart->GetProperty ()->SetPointSize (psize + 1); 00390 } 00391 } 00392 break; 00393 } 00394 case 45: // KEY_MINUS 00395 { 00396 vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors (); 00397 vtkCollectionSimpleIterator ait; 00398 for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) 00399 { 00400 for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) 00401 { 00402 vtkSmartPointer<vtkActor> apart = (vtkActor*)path->GetLastNode ()->GetViewProp (); 00403 int psize = apart->GetProperty ()->GetPointSize (); 00404 if (psize > 1) 00405 apart->GetProperty ()->SetPointSize (psize - 1); 00406 } 00407 } 00408 break; 00409 } 00410 // Switch between maximize and original window size 00411 case 'f': case 'F': 00412 { 00413 if (alt) 00414 { 00415 // Get screen size 00416 int *scr_size = Interactor->GetRenderWindow ()->GetScreenSize (); 00417 // Get window size 00418 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00419 // Is window size = max? 00420 if (win_size[0] == max_win_height_ && win_size[1] == max_win_width_) 00421 { 00422 // Set the previously saved 'current' window size 00423 Interactor->GetRenderWindow ()->SetSize (win_height_, win_width_); 00424 // Set the previously saved window position 00425 Interactor->GetRenderWindow ()->SetPosition (win_pos_x_, win_pos_y_); 00426 Interactor->GetRenderWindow ()->Render (); 00427 Interactor->Render (); 00428 } 00429 // Set to max 00430 else 00431 { 00432 int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); 00433 // Save the current window position 00434 win_pos_x_ = win_pos[0]; 00435 win_pos_y_ = win_pos[1]; 00436 // Save the current window size 00437 win_height_ = win_size[0]; 00438 win_width_ = win_size[1]; 00439 // Set the maximum window size 00440 Interactor->GetRenderWindow ()->SetSize (scr_size[0], scr_size[1]); 00441 Interactor->GetRenderWindow ()->Render (); 00442 Interactor->Render (); 00443 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00444 // Save the maximum window size 00445 max_win_height_ = win_size[0]; 00446 max_win_width_ = win_size[1]; 00447 } 00448 } 00449 else 00450 { 00451 AnimState = VTKIS_ANIM_ON; 00452 vtkAssemblyPath *path = NULL; 00453 Interactor->GetPicker ()->Pick (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1], 0.0, CurrentRenderer); 00454 vtkAbstractPropPicker *picker; 00455 if ((picker = vtkAbstractPropPicker::SafeDownCast (Interactor->GetPicker ()))) 00456 path = picker->GetPath (); 00457 if (path != NULL) 00458 Interactor->FlyTo (CurrentRenderer, picker->GetPickPosition ()); 00459 AnimState = VTKIS_ANIM_OFF; 00460 } 00461 break; 00462 } 00463 // 's'/'S' w/out ALT 00464 case 's': case 'S': 00465 { 00466 if (alt) 00467 { 00468 int stereo_render = Interactor->GetRenderWindow ()->GetStereoRender (); 00469 Interactor->GetRenderWindow ()->SetStereoRender (!stereo_render); 00470 Interactor->GetRenderWindow ()->Render (); 00471 Interactor->Render (); 00472 } 00473 else 00474 Superclass::OnChar (); 00475 break; 00476 } 00477 00478 // Display a grid/scale over the screen 00479 case 'g': case 'G': 00480 { 00481 if (!grid_enabled_) 00482 { 00483 grid_actor_->TopAxisVisibilityOn (); 00484 CurrentRenderer->AddViewProp (grid_actor_); 00485 grid_enabled_ = true; 00486 } 00487 else 00488 { 00489 CurrentRenderer->RemoveViewProp (grid_actor_); 00490 grid_enabled_ = false; 00491 } 00492 break; 00493 } 00494 00495 // Display a LUT actor on screen 00496 case 'u': case 'U': 00497 { 00498 CloudActorMap::iterator it; 00499 for (it = actors_->begin (); it != actors_->end (); ++it) 00500 { 00501 CloudActor *act = &(*it).second; 00502 00503 vtkScalarsToColors* lut = act->actor->GetMapper ()->GetLookupTable (); 00504 lut_actor_->SetLookupTable (lut); 00505 lut_actor_->Modified (); 00506 } 00507 if (!lut_enabled_) 00508 { 00509 CurrentRenderer->AddActor (lut_actor_); 00510 lut_actor_->SetVisibility (true); 00511 lut_enabled_ = true; 00512 } 00513 else 00514 { 00515 CurrentRenderer->RemoveActor (lut_actor_); 00516 lut_enabled_ = false; 00517 } 00518 CurrentRenderer->Render (); 00519 break; 00520 } 00521 00522 // Overwrite the camera reset 00523 case 'r': case 'R': 00524 { 00525 if (!alt) 00526 { 00527 Superclass::OnChar (); 00528 break; 00529 } 00530 // Get all the data 00531 double bounds[6]; 00532 double focal[3]; 00533 CurrentRenderer->ComputeVisiblePropBounds (bounds); 00534 focal[0] = (bounds[0] + bounds[1]) / 2.0; 00535 focal[1] = (bounds[2] + bounds[3]) / 2.0; 00536 focal[2] = (bounds[4] + bounds[5]) / 2.0; 00537 00538 vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera (); 00539 double view[3]; 00540 cam->SetFocalPoint (focal); 00541 cam->SetPosition (0 - .25 * focal[0], 0 - .25 * focal[1], 0 - .25 * focal[2]); 00542 cam->GetViewUp (view); 00543 00544 // Dataset negative on Z? 00545 if (focal[2] > 0) 00546 for (int i = 0; i < 3; i++) view[i] *= -1; 00547 cam->SetViewUp (view[0], view[1], view[2]); 00548 CurrentRenderer->SetActiveCamera (cam); 00549 CurrentRenderer->ResetCameraClippingRange (bounds); 00550 CurrentRenderer->Render (); 00551 break; 00552 } 00553 00554 default: 00555 { 00556 Superclass::OnChar (); 00557 break; 00558 } 00559 } 00560 rens_->Render (); 00561 Interactor->Render (); 00562 } 00563 00565 00566 void 00567 pcl_visualization::PCLVisualizerInteractorStyle::OnTimer () 00568 { 00569 if (!init_) 00570 { 00571 pcl::console::print_error ("[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n"); 00572 return; 00573 } 00574 00575 if (!rens_) 00576 { 00577 pcl::console::print_error ("[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing.\n"); 00578 return; 00579 } 00580 rens_->Render (); 00581 Interactor->Render (); 00582 } 00583 00586 00587 void 00588 pcl_visualization::PCLHistogramVisualizerInteractorStyle::Initialize () 00589 { 00590 // Set windows size (width, height) to unknown (-1) 00591 win_height_ = win_width_ = -1; 00592 win_pos_x_ = win_pos_y_ = 0; 00593 max_win_height_ = max_win_width_ = -1; 00594 00595 // Create the image filter and PNG writer objects 00596 wif_ = vtkSmartPointer<vtkWindowToImageFilter>::New (); 00597 snapshot_writer_ = vtkSmartPointer<vtkPNGWriter>::New (); 00598 snapshot_writer_->SetInputConnection (wif_->GetOutputPort ()); 00599 00600 init_ = true; 00601 } 00602 00604 00605 void 00606 pcl_visualization::PCLHistogramVisualizerInteractorStyle::OnChar () 00607 { 00608 if (!init_) 00609 { 00610 pcl::console::print_error ("[PCLHistogramVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n"); 00611 return; 00612 } 00613 00614 /* if (!wins_) 00615 { 00616 pcl::console::print_error ("[PCLHistogramVisualizerInteractorStyle] No renderer-window-interactor map given! Use setRenWinInteractMap () before continuing.\n"); 00617 return; 00618 }*/ 00619 00620 FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); 00621 00622 if (wif_->GetInput () == NULL) 00623 { 00624 wif_->SetInput (Interactor->GetRenderWindow ()); 00625 wif_->Modified (); 00626 snapshot_writer_->Modified (); 00627 } 00628 00629 // Save the initial windows width/height 00630 if (win_height_ == -1 || win_width_ == -1) 00631 { 00632 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00633 win_height_ = win_size[0]; 00634 win_width_ = win_size[1]; 00635 } 00636 00637 // Get the status of special keys (Cltr+Alt+Shift) 00638 bool alt = Interactor->GetAltKey (); 00639 00640 //fprintf (stderr, "Key sym: %s\n", Interactor->GetKeySym ()); 00641 // ---[ Check the rest of the key codes 00642 switch (Interactor->GetKeyCode ()) 00643 { 00644 case 'h': case 'H': 00645 { 00646 pcl::console::print_info ("| Help:\n" 00647 "-------\n" 00648 " p, P : switch to a point-based representation\n" 00649 " w, W : switch to a wireframe-based representation (where available)\n" 00650 " s, S : switch to a surface-based representation (where available)\n" 00651 "\n" 00652 " j, J : take a .PNG snapshot of the current window view\n" 00653 " c, C : display current camera/window parameters\n" 00654 "\n" 00655 " + / - : increment/decrement overall point size\n" 00656 "\n" 00657 " ALT + f, F : switch between maximized window mode and original size\n" 00658 ); 00659 break; 00660 } 00661 00662 // Switch representation to points 00663 case 'p': case 'P': 00664 { 00665 vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors (); 00666 vtkCollectionSimpleIterator ait; 00667 for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) 00668 { 00669 for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) 00670 { 00671 vtkSmartPointer<vtkActor> apart = (vtkActor*)path->GetLastNode ()->GetViewProp (); 00672 apart->GetProperty ()->SetRepresentationToPoints (); 00673 } 00674 } 00675 break; 00676 } 00677 // Save a PNG snapshot with the current screen 00678 case 'j': case 'J': 00679 { 00680 char cam_fn[80], snapshot_fn[80]; 00681 unsigned t = time (0); 00682 sprintf (snapshot_fn, "screenshot-%d.png" , t); 00683 snapshot_writer_->SetFileName (snapshot_fn); 00684 snapshot_writer_->Write (); 00685 00686 sprintf (cam_fn, "screenshot-%d.cam", t); 00687 ofstream ofs_cam; 00688 ofs_cam.open (cam_fn); 00689 vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); 00690 double clip[2], focal[3], pos[3], view[3]; 00691 cam->GetClippingRange (clip); 00692 cam->GetFocalPoint (focal); 00693 cam->GetPosition (pos); 00694 cam->GetViewUp (view); 00695 int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); 00696 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00697 ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << 00698 pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << 00699 win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] 00700 << endl; 00701 ofs_cam.close (); 00702 00703 pcl::console::print_info ("Screenshot (%s) and camera information (%s) successfully captured.\n", snapshot_fn, cam_fn); 00704 break; 00705 } 00706 case 43: // KEY_PLUS 00707 { 00708 vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors (); 00709 vtkCollectionSimpleIterator ait; 00710 for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) 00711 { 00712 for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) 00713 { 00714 vtkSmartPointer<vtkActor> apart = (vtkActor*)path->GetLastNode ()->GetViewProp (); 00715 int psize = apart->GetProperty ()->GetPointSize (); 00716 if (psize < 63) 00717 apart->GetProperty ()->SetPointSize (psize + 1); 00718 } 00719 } 00720 break; 00721 } 00722 case 45: // KEY_MINUS 00723 { 00724 vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors (); 00725 vtkCollectionSimpleIterator ait; 00726 for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) 00727 { 00728 for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) 00729 { 00730 vtkSmartPointer<vtkActor> apart = (vtkActor*)path->GetLastNode ()->GetViewProp (); 00731 int psize = apart->GetProperty ()->GetPointSize (); 00732 if (psize > 1) 00733 apart->GetProperty ()->SetPointSize (psize - 1); 00734 } 00735 } 00736 break; 00737 } 00738 // Switch between maximize and original window size 00739 case 'f': case 'F': 00740 { 00741 if (alt) 00742 { 00743 // Get screen size 00744 int *scr_size = Interactor->GetRenderWindow ()->GetScreenSize (); 00745 // Get window size 00746 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00747 // Is window size = max? 00748 if (win_size[0] == max_win_height_ && win_size[1] == max_win_width_) 00749 { 00750 // Set the previously saved 'current' window size 00751 Interactor->GetRenderWindow ()->SetSize (win_height_, win_width_); 00752 // Set the previously saved window position 00753 Interactor->GetRenderWindow ()->SetPosition (win_pos_x_, win_pos_y_); 00754 Interactor->GetRenderWindow ()->Render (); 00755 Interactor->Render (); 00756 } 00757 // Set to max 00758 else 00759 { 00760 int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); 00761 // Save the current window position 00762 win_pos_x_ = win_pos[0]; 00763 win_pos_y_ = win_pos[1]; 00764 // Save the current window size 00765 win_height_ = win_size[0]; 00766 win_width_ = win_size[1]; 00767 // Set the maximum window size 00768 Interactor->GetRenderWindow ()->SetSize (scr_size[0], scr_size[1]); 00769 Interactor->GetRenderWindow ()->Render (); 00770 Interactor->Render (); 00771 int *win_size = Interactor->GetRenderWindow ()->GetSize (); 00772 // Save the maximum window size 00773 max_win_height_ = win_size[0]; 00774 max_win_width_ = win_size[1]; 00775 } 00776 } 00777 else 00778 Superclass::OnChar (); 00779 break; 00780 } 00781 // Switch representation to wireframe 00782 default: 00783 { 00784 Superclass::OnChar (); 00785 } 00786 } 00787 Interactor->Render (); 00788 } 00789 00791 00792 void 00793 pcl_visualization::PCLHistogramVisualizerInteractorStyle::OnTimer () 00794 { 00795 if (!init_) 00796 { 00797 pcl::console::print_error ("[PCLHistogramVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n"); 00798 return; 00799 } 00800 00801 for (RenWinInteractMap::iterator am_it = wins_.begin (); am_it != wins_.end (); ++am_it) 00802 (*am_it).second.ren_->Render (); 00803 } 00804 00805 namespace pcl_visualization 00806 { 00807 // Standard VTK macro for *New () 00808 vtkStandardNewMacro (PCLVisualizerInteractorStyle); 00809 vtkStandardNewMacro (PCLHistogramVisualizerInteractorStyle); 00810 } 00811