pcl_visualizer.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010, Willow Garage, Inc.
00006  *  Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of the copyright holder(s) nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  */
00038 
00039 #include <pcl/visualization/common/common.h>
00040 #include <pcl/conversions.h>
00041 #include <vtkTextActor.h>
00042 #include <vtkTextProperty.h>
00043 #include <vtkCellData.h>
00044 #include <vtkWorldPointPicker.h>
00045 #include <vtkPropPicker.h>
00046 #include <vtkPlatonicSolidSource.h>
00047 #include <vtkLoopSubdivisionFilter.h>
00048 #include <vtkTriangle.h>
00049 #include <vtkTransform.h>
00050 #include <vtkPolyDataNormals.h>
00051 #include <vtkMapper.h>
00052 #include <vtkDataSetMapper.h>
00053 
00054 #if VTK_MAJOR_VERSION==6 || (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION>4)
00055 #include <vtkHardwareSelector.h>
00056 #include <vtkSelectionNode.h>
00057 #else
00058 #include <vtkVisibleCellSelector.h>
00059 #endif
00060 
00061 #include <vtkSelection.h>
00062 #include <vtkPointPicker.h>
00063 
00064 #include <pcl/visualization/boost.h>
00065 #include <pcl/visualization/vtk/vtkVertexBufferObjectMapper.h>
00066 #include <pcl/visualization/vtk/vtkRenderWindowInteractorFix.h>
00067 
00068 #include <vtkPolyLine.h>
00069 #include <vtkPolyDataMapper.h>
00070 #include <vtkRenderWindow.h>
00071 #include <vtkRenderer.h>
00072 #include <vtkRendererCollection.h>
00073 #include <vtkCamera.h>
00074 #include <vtkAppendPolyData.h>
00075 #include <vtkPointData.h>
00076 #include <vtkTransformFilter.h>
00077 #include <vtkProperty.h>
00078 #include <vtkPLYReader.h>
00079 #include <vtkAxes.h>
00080 #include <vtkTubeFilter.h>
00081 #include <vtkLineSource.h>
00082 #include <vtkOrientationMarkerWidget.h>
00083 #include <vtkAxesActor.h>
00084 #include <vtkRenderWindowInteractor.h>
00085 #include <vtkAreaPicker.h>
00086 #include <vtkXYPlotActor.h>
00087 
00088 #include <pcl/visualization/common/shapes.h>
00089 #include <pcl/visualization/pcl_visualizer.h>
00090 #include <pcl/common/time.h>
00091 
00093 pcl::visualization::PCLVisualizer::PCLVisualizer (const std::string &name, const bool create_interactor)
00094   : interactor_ ()
00095   , update_fps_ (vtkSmartPointer<FPSCallback>::New ())
00096 #if !((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00097   , stopped_ ()
00098   , timer_id_ ()
00099 #endif
00100   , exit_main_loop_timer_callback_ ()
00101   , exit_callback_ ()
00102   , rens_ (vtkSmartPointer<vtkRendererCollection>::New ())
00103   , win_ ()
00104   , style_ (vtkSmartPointer<pcl::visualization::PCLVisualizerInteractorStyle>::New ())
00105   , cloud_actor_map_ (new CloudActorMap)
00106   , shape_actor_map_ (new ShapeActorMap)
00107   , coordinate_actor_map_ ()
00108   , camera_set_ ()
00109 {
00110   // Create a Renderer
00111   vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New ();
00112   ren->AddObserver (vtkCommand::EndEvent, update_fps_);
00113   // Add it to the list of renderers
00114   rens_->AddItem (ren);
00115 
00116   // FPS callback
00117   vtkSmartPointer<vtkTextActor> txt = vtkSmartPointer<vtkTextActor>::New ();
00118   update_fps_->actor = txt;
00119   update_fps_->pcl_visualizer = this;
00120   update_fps_->decimated = false;
00121   ren->AddActor (txt);
00122 
00123   // Create a RendererWindow
00124   win_ = vtkSmartPointer<vtkRenderWindow>::New ();
00125   win_->SetWindowName (name.c_str ());
00126 
00127   // Get screen size
00128   int *scr_size = win_->GetScreenSize ();
00129   // Set the window size as 1/2 of the screen size
00130   win_->SetSize (scr_size[0] / 2, scr_size[1] / 2);
00131 
00132   // By default, don't use vertex buffer objects
00133   use_vbos_ = false;
00134 
00135   // Add all renderers to the window
00136   rens_->InitTraversal ();
00137   vtkRenderer* renderer = NULL;
00138   while ((renderer = rens_->GetNextItem ()) != NULL)
00139     win_->AddRenderer (renderer);
00140 
00141   // Create the interactor style
00142   style_->Initialize ();
00143   style_->setRendererCollection (rens_);
00144   style_->setCloudActorMap (cloud_actor_map_);
00145   style_->UseTimersOn ();
00146   style_->setUseVbos(use_vbos_);
00147 
00148   if (create_interactor)
00149     createInteractor ();
00150 
00151   win_->SetWindowName (name.c_str ());
00152 }
00153 
00155 pcl::visualization::PCLVisualizer::PCLVisualizer (int &argc, char **argv, const std::string &name, PCLVisualizerInteractorStyle* style, const bool create_interactor)
00156   : interactor_ ()
00157   , update_fps_ (vtkSmartPointer<FPSCallback>::New ())
00158 #if !((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00159   , stopped_ ()
00160   , timer_id_ ()
00161 #endif
00162   , exit_main_loop_timer_callback_ ()
00163   , exit_callback_ ()
00164   , rens_ (vtkSmartPointer<vtkRendererCollection>::New ())
00165   , win_ ()
00166   , style_ (style)
00167   , cloud_actor_map_ (new CloudActorMap)
00168   , shape_actor_map_ (new ShapeActorMap)
00169   , coordinate_actor_map_ ()
00170   , camera_set_ ()
00171 {
00172   style_ = style;
00173 
00174   // Create a Renderer
00175   vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New ();
00176   ren->AddObserver (vtkCommand::EndEvent, update_fps_);
00177   // Add it to the list of renderers
00178   rens_->AddItem (ren);
00179 
00180   // FPS callback
00181   vtkSmartPointer<vtkTextActor> txt = vtkSmartPointer<vtkTextActor>::New ();
00182   update_fps_->actor = txt;
00183   update_fps_->pcl_visualizer = this;
00184   update_fps_->decimated = false;
00185   ren->AddActor (txt);
00186 
00187   // Create a RendererWindow
00188   win_ = vtkSmartPointer<vtkRenderWindow>::New ();
00189   win_->SetWindowName (name.c_str ());
00190 
00191   // Get screen size
00192   int *scr_size = win_->GetScreenSize ();
00193 
00194   // Set default camera parameters
00195   initCameraParameters ();
00196 
00197   // Parse the camera settings and update the internal camera
00198   camera_set_ = getCameraParameters (argc, argv);
00199   // Set the window size as 1/2 of the screen size or the user given parameter
00200   win_->SetSize (scr_size[0]/2, scr_size[1]/2);
00201   win_->SetPosition (0, 0);
00202 
00203   // By default, don't use vertex buffer objects
00204   use_vbos_ = false;
00205 
00206   // Add all renderers to the window
00207   rens_->InitTraversal ();
00208   vtkRenderer* renderer = NULL;
00209   while ((renderer = rens_->GetNextItem ()) != NULL)
00210     win_->AddRenderer (renderer);
00211 
00212   // Create the interactor style
00213   style_->Initialize ();
00214   style_->setRendererCollection (rens_);
00215   style_->setCloudActorMap (cloud_actor_map_);
00216   style_->UseTimersOn ();
00217 
00218   if (create_interactor)
00219     createInteractor ();
00220 
00221   win_->SetWindowName (name.c_str ());
00222 }
00223 
00225 void
00226 pcl::visualization::PCLVisualizer::createInteractor ()
00227 {
00228 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00229   interactor_ = vtkSmartPointer<PCLVisualizerInteractor>::New ();
00230 #else
00231   //interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New ();
00232   interactor_ = vtkSmartPointer <vtkRenderWindowInteractor>::Take (vtkRenderWindowInteractorFixNew ());
00233 #endif
00234 
00235   //win_->PointSmoothingOn ();
00236   //win_->LineSmoothingOn ();
00237   //win_->PolygonSmoothingOn ();
00238   win_->AlphaBitPlanesOff ();
00239   win_->PointSmoothingOff ();
00240   win_->LineSmoothingOff ();
00241   win_->PolygonSmoothingOff ();
00242   win_->SwapBuffersOn ();
00243   win_->SetStereoTypeToAnaglyph ();
00244 
00245   interactor_->SetRenderWindow (win_);
00246   interactor_->SetInteractorStyle (style_);
00247   //interactor_->SetStillUpdateRate (30.0);
00248   interactor_->SetDesiredUpdateRate (30.0);
00249 
00250   // Initialize and create timer, also create window
00251   interactor_->Initialize ();
00252 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00253   interactor_->timer_id_ = interactor_->CreateRepeatingTimer (5000L);
00254 #else
00255   timer_id_ = interactor_->CreateRepeatingTimer (5000L);
00256 #endif
00257 
00258   // Set a simple PointPicker
00259   vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New ();
00260   pp->SetTolerance (pp->GetTolerance () * 2);
00261   interactor_->SetPicker (pp);
00262 
00263   exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
00264   exit_main_loop_timer_callback_->pcl_visualizer = this;
00265   exit_main_loop_timer_callback_->right_timer_id = -1;
00266   interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
00267 
00268   exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
00269   exit_callback_->pcl_visualizer = this;
00270   interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_);
00271 
00272   resetStoppedFlag ();
00273 }
00274 
00276 void
00277 pcl::visualization::PCLVisualizer::setupInteractor (
00278   vtkRenderWindowInteractor *iren,
00279   vtkRenderWindow *win)
00280 {
00281   win->AlphaBitPlanesOff ();
00282   win->PointSmoothingOff ();
00283   win->LineSmoothingOff ();
00284   win->PolygonSmoothingOff ();
00285   win->SwapBuffersOn ();
00286   win->SetStereoTypeToAnaglyph ();
00287 
00288   iren->SetRenderWindow (win);
00289   iren->SetInteractorStyle (style_);
00290   //iren->SetStillUpdateRate (30.0);
00291   iren->SetDesiredUpdateRate (30.0);
00292 
00293   // Initialize and create timer, also create window
00294   iren->Initialize ();
00295 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00296 #else
00297   timer_id_ = iren->CreateRepeatingTimer (5000L);
00298 #endif
00299 
00300   // Set a simple PointPicker
00301   vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New ();
00302   pp->SetTolerance (pp->GetTolerance () * 2);
00303   iren->SetPicker (pp);
00304 
00305   exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
00306   exit_main_loop_timer_callback_->pcl_visualizer = this;
00307   exit_main_loop_timer_callback_->right_timer_id = -1;
00308   iren->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
00309 
00310   exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
00311   exit_callback_->pcl_visualizer = this;
00312   iren->AddObserver (vtkCommand::ExitEvent, exit_callback_);
00313 
00314   resetStoppedFlag ();
00315 }
00316 
00317 
00319 void
00320 pcl::visualization::PCLVisualizer::setupInteractor (
00321   vtkRenderWindowInteractor *iren,
00322   vtkRenderWindow *win,
00323   vtkInteractorStyle *style)
00324 {
00325   win->AlphaBitPlanesOff ();
00326   win->PointSmoothingOff ();
00327   win->LineSmoothingOff ();
00328   win->PolygonSmoothingOff ();
00329   win->SwapBuffersOn ();
00330   win->SetStereoTypeToAnaglyph ();
00331 
00332   iren->SetRenderWindow (win);
00333   iren->SetInteractorStyle (style);
00334   //iren->SetStillUpdateRate (30.0);
00335   iren->SetDesiredUpdateRate (30.0);
00336 
00337   // Initialize and create timer, also create window
00338   iren->Initialize ();
00339 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00340 #else
00341   timer_id_ = iren->CreateRepeatingTimer (5000L);
00342 #endif
00343 
00344   // Set a simple PointPicker
00345   // vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New ();
00346   // pp->SetTolerance (pp->GetTolerance () * 2);
00347   // iren->SetPicker (pp);
00348 
00349   exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
00350   exit_main_loop_timer_callback_->pcl_visualizer = this;
00351   exit_main_loop_timer_callback_->right_timer_id = -1;
00352   iren->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
00353 
00354   exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
00355   exit_callback_->pcl_visualizer = this;
00356   iren->AddObserver (vtkCommand::ExitEvent, exit_callback_);
00357 
00358   resetStoppedFlag ();
00359 }
00360 
00362 pcl::visualization::PCLVisualizer::~PCLVisualizer ()
00363 {
00364   if (interactor_ != NULL)
00365 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00366     interactor_->DestroyTimer (interactor_->timer_id_);
00367 #else
00368     interactor_->DestroyTimer (timer_id_);
00369 #endif
00370   // Clear the collections
00371   rens_->RemoveAllItems ();
00372 }
00373 
00375 void
00376 pcl::visualization::PCLVisualizer::saveScreenshot (const std::string &file)
00377 {
00378   style_->saveScreenshot (file);
00379 }
00380 
00382 boost::signals2::connection
00383 pcl::visualization::PCLVisualizer::registerKeyboardCallback (boost::function<void (const pcl::visualization::KeyboardEvent&)> callback)
00384 {
00385   return (style_->registerKeyboardCallback (callback));
00386 }
00387 
00389 boost::signals2::connection
00390 pcl::visualization::PCLVisualizer::registerMouseCallback (boost::function<void (const pcl::visualization::MouseEvent&)> callback)
00391 {
00392   return (style_->registerMouseCallback (callback));
00393 }
00394 
00396 boost::signals2::connection
00397 pcl::visualization::PCLVisualizer::registerPointPickingCallback (boost::function<void (const pcl::visualization::PointPickingEvent&)> callback)
00398 {
00399   return (style_->registerPointPickingCallback (callback));
00400 }
00401 
00403 boost::signals2::connection
00404 pcl::visualization::PCLVisualizer::registerPointPickingCallback (void (*callback) (const pcl::visualization::PointPickingEvent&, void*), void* cookie)
00405 {
00406   return (registerPointPickingCallback (boost::bind (callback, _1, cookie)));
00407 }
00408 
00410 boost::signals2::connection
00411 pcl::visualization::PCLVisualizer::registerAreaPickingCallback (boost::function<void (const pcl::visualization::AreaPickingEvent&)> callback)
00412 {
00413   return (style_->registerAreaPickingCallback (callback));
00414 }
00415 
00417 boost::signals2::connection
00418 pcl::visualization::PCLVisualizer::registerAreaPickingCallback (void (*callback) (const pcl::visualization::AreaPickingEvent&, void*), void* cookie)
00419 {
00420   return (registerAreaPickingCallback (boost::bind (callback, _1, cookie)));
00421 }
00422 
00424 void
00425 pcl::visualization::PCLVisualizer::spin ()
00426 {
00427   resetStoppedFlag ();
00428   // Render the window before we start the interactor
00429   win_->Render ();
00430   interactor_->Start ();
00431 }
00432 
00434 void
00435 pcl::visualization::PCLVisualizer::spinOnce (int time, bool force_redraw)
00436 {
00437   resetStoppedFlag ();
00438 
00439   if (time <= 0)
00440     time = 1;
00441 
00442   if (force_redraw)
00443     interactor_->Render ();
00444 
00445   DO_EVERY (1.0 / interactor_->GetDesiredUpdateRate (),
00446     exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer (time);
00447     interactor_->Start ();
00448     interactor_->DestroyTimer (exit_main_loop_timer_callback_->right_timer_id);
00449   );
00450 }
00451 
00453 void
00454 pcl::visualization::PCLVisualizer::addOrientationMarkerWidgetAxes (vtkRenderWindowInteractor* interactor)
00455 {
00456   if ( !axes_widget_ )
00457   {
00458     vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New ();
00459 
00460     axes_widget_ = vtkSmartPointer<vtkOrientationMarkerWidget>::New ();
00461     axes_widget_->SetOutlineColor (0.9300, 0.5700, 0.1300);
00462     axes_widget_->SetOrientationMarker (axes);
00463     axes_widget_->SetInteractor (interactor);
00464     axes_widget_->SetViewport (0.0, 0.0, 0.4, 0.4);
00465     axes_widget_->SetEnabled (true);
00466     axes_widget_->InteractiveOn ();
00467   }
00468   else
00469   {
00470     axes_widget_->SetEnabled (true);
00471     pcl::console::print_warn (stderr, "Orientation Widget Axes already exists, just enabling it");
00472   }
00473 
00474 }
00475 
00477 void
00478 pcl::visualization::PCLVisualizer::removeOrientationMarkerWidgetAxes ()
00479 {
00480   if (axes_widget_)
00481   {
00482     if (axes_widget_->GetEnabled ())
00483       axes_widget_->SetEnabled (false);
00484     else
00485       pcl::console::print_warn (stderr, "Orientation Widget Axes was already disabled, doing nothing.");
00486   }
00487   else
00488   {
00489     pcl::console::print_error ("Attempted to delete Orientation Widget Axes which does not exist!\n");
00490   }
00491 }
00492 
00494 void
00495 pcl::visualization::PCLVisualizer::addCoordinateSystem (double scale, int viewport)
00496 {
00497   vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New ();
00498   axes->SetOrigin (0, 0, 0);
00499   axes->SetScaleFactor (scale);
00500 
00501   vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New ();
00502   axes_colors->Allocate (6);
00503   axes_colors->InsertNextValue (0.0);
00504   axes_colors->InsertNextValue (0.0);
00505   axes_colors->InsertNextValue (0.5);
00506   axes_colors->InsertNextValue (0.5);
00507   axes_colors->InsertNextValue (1.0);
00508   axes_colors->InsertNextValue (1.0);
00509 
00510   vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput ();
00511   axes_data->Update ();
00512   axes_data->GetPointData ()->SetScalars (axes_colors);
00513 
00514   vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New ();
00515   axes_tubes->SetInput (axes_data);
00516   axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0);
00517   axes_tubes->SetNumberOfSides (6);
00518 
00519   vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00520   axes_mapper->SetScalarModeToUsePointData ();
00521   axes_mapper->SetInput (axes_tubes->GetOutput ());
00522 
00523   vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New ();
00524   axes_actor->SetMapper (axes_mapper);
00525 
00526   // Save the ID and actor pair to the global actor map
00527   coordinate_actor_map_[viewport] = axes_actor;
00528 
00529   addActorToRenderer (axes_actor, viewport);
00530 }
00531 
00533 void
00534 pcl::visualization::PCLVisualizer::addCoordinateSystem (double scale, float x, float y, float z, int viewport)
00535 {
00536   vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New ();
00537   axes->SetOrigin (0, 0, 0);
00538   axes->SetScaleFactor (scale);
00539 
00540   vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New ();
00541   axes_colors->Allocate (6);
00542   axes_colors->InsertNextValue (0.0);
00543   axes_colors->InsertNextValue (0.0);
00544   axes_colors->InsertNextValue (0.5);
00545   axes_colors->InsertNextValue (0.5);
00546   axes_colors->InsertNextValue (1.0);
00547   axes_colors->InsertNextValue (1.0);
00548 
00549   vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput ();
00550   axes_data->Update ();
00551   axes_data->GetPointData ()->SetScalars (axes_colors);
00552 
00553   vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New ();
00554   axes_tubes->SetInput (axes_data);
00555   axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0);
00556   axes_tubes->SetNumberOfSides (6);
00557 
00558   vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00559   axes_mapper->SetScalarModeToUsePointData ();
00560   axes_mapper->SetInput (axes_tubes->GetOutput ());
00561 
00562   vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New ();
00563   axes_actor->SetMapper (axes_mapper);
00564   axes_actor->SetPosition (x, y, z);
00565 
00566   // Save the ID and actor pair to the global actor map
00567   coordinate_actor_map_[viewport] = axes_actor;
00568 
00569   addActorToRenderer (axes_actor, viewport);
00570 }
00571 
00572 int
00573 feq (double a, double b) {
00574     return fabs (a - b) < 1e-9;
00575 }
00576 
00577 void
00578 quat_to_angle_axis (const Eigen::Quaternionf &qx, double &theta, double axis[3])
00579 {
00580 double q[4];
00581   q[0] = qx.w();
00582   q[1] = qx.x();
00583   q[2] = qx.y();
00584   q[3] = qx.z();
00585 
00586     double halftheta = acos (q[0]);
00587     theta = halftheta * 2;
00588     double sinhalftheta = sin (halftheta);
00589     if (feq (halftheta, 0)) {
00590         axis[0] = 0;
00591         axis[1] = 0;
00592         axis[2] = 1;
00593         theta = 0;
00594     } else {
00595         axis[0] = q[1] / sinhalftheta;
00596         axis[1] = q[2] / sinhalftheta;
00597         axis[2] = q[3] / sinhalftheta;
00598     }
00599 }
00600 
00601 
00603 void
00604 pcl::visualization::PCLVisualizer::addCoordinateSystem (double scale, const Eigen::Affine3f& t, int viewport)
00605 {
00606   vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New ();
00607   axes->SetOrigin (0, 0, 0);
00608   axes->SetScaleFactor (scale);
00609 
00610   vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New ();
00611   axes_colors->Allocate (6);
00612   axes_colors->InsertNextValue (0.0);
00613   axes_colors->InsertNextValue (0.0);
00614   axes_colors->InsertNextValue (0.5);
00615   axes_colors->InsertNextValue (0.5);
00616   axes_colors->InsertNextValue (1.0);
00617   axes_colors->InsertNextValue (1.0);
00618 
00619   vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput ();
00620   axes_data->Update ();
00621   axes_data->GetPointData ()->SetScalars (axes_colors);
00622 
00623   vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New ();
00624   axes_tubes->SetInput (axes_data);
00625   axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0);
00626   axes_tubes->SetNumberOfSides (6);
00627 
00628   vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00629   axes_mapper->SetScalarModeToUsePointData ();
00630   axes_mapper->SetInput (axes_tubes->GetOutput ());
00631 
00632   vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New ();
00633   axes_actor->SetMapper (axes_mapper);
00634 
00635   axes_actor->SetPosition (t (0, 3), t(1, 3), t(2, 3));
00636 
00637   Eigen::Matrix3f m;
00638   m =t.rotation();
00639   Eigen::Quaternionf rf;
00640   rf = Eigen::Quaternionf(m);
00641   double r_angle;
00642   double r_axis[3];
00643   quat_to_angle_axis(rf,r_angle,r_axis);
00644   //
00645   axes_actor->SetOrientation(0,0,0);
00646   axes_actor->RotateWXYZ(r_angle*180/M_PI,r_axis[0],r_axis[1],r_axis[2]);
00647   //WAS:  axes_actor->SetOrientation (roll, pitch, yaw);
00648 
00649   // Save the ID and actor pair to the global actor map
00650   coordinate_actor_map_[viewport] = axes_actor;
00651   addActorToRenderer (axes_actor, viewport);
00652 }
00653 
00655 bool
00656 pcl::visualization::PCLVisualizer::removeCoordinateSystem (int viewport)
00657 {
00658   // Check to see if the given ID entry exists
00659   CoordinateActorMap::iterator am_it = coordinate_actor_map_.find (viewport);
00660 
00661   if (am_it == coordinate_actor_map_.end ())
00662     return (false);
00663 
00664   // Remove it from all renderers
00665   if (removeActorFromRenderer (am_it->second, viewport))
00666   {
00667     // Remove the ID pair to the global actor map
00668     coordinate_actor_map_.erase (am_it);
00669     return (true);
00670   }
00671   return (false);
00672 }
00673 
00675 bool
00676 pcl::visualization::PCLVisualizer::removePointCloud (const std::string &id, int viewport)
00677 {
00678   // Check to see if the given ID entry exists
00679   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00680 
00681   if (am_it == cloud_actor_map_->end ())
00682     return (false);
00683 
00684   // Remove it from all renderers
00685   if (removeActorFromRenderer (am_it->second.actor, viewport))
00686   {
00687     // Remove the pointer/ID pair to the global actor map
00688     cloud_actor_map_->erase (am_it);
00689     return (true);
00690   }
00691   return (false);
00692 }
00693 
00695 bool
00696 pcl::visualization::PCLVisualizer::removeShape (const std::string &id, int viewport)
00697 {
00698   // Check to see if the given ID entry exists
00699   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
00700   // Extra step: check if there is a cloud with the same ID
00701   CloudActorMap::iterator ca_it = cloud_actor_map_->find (id);
00702 
00703   bool shape = true;
00704   // Try to find a shape first
00705   if (am_it == shape_actor_map_->end ())
00706   {
00707     // There is no cloud or shape with this ID, so just exit
00708     if (ca_it == cloud_actor_map_->end ())
00709       return (false);
00710     // Cloud found, set shape to false
00711     shape = false;
00712   }
00713 
00714   // Remove the pointer/ID pair to the global actor map
00715   if (shape)
00716   {
00717     if (removeActorFromRenderer (am_it->second, viewport))
00718     {
00719       shape_actor_map_->erase (am_it);
00720       return (true);
00721     }
00722   }
00723   else
00724   {
00725     if (removeActorFromRenderer (ca_it->second.actor, viewport))
00726     {
00727       cloud_actor_map_->erase (ca_it);
00728       return (true);
00729     }
00730   }
00731   return (false);
00732 }
00733 
00735 bool
00736 pcl::visualization::PCLVisualizer::removeText3D (const std::string &id, int viewport)
00737 {
00738   // Check to see if the given ID entry exists
00739   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
00740 
00741   if (am_it == shape_actor_map_->end ())
00742   {
00743     //pcl::console::print_warn (stderr, "[removeSape] Could not find any shape with id <%s>!\n", id.c_str ());
00744     return (false);
00745   }
00746 
00747   // Remove it from all renderers
00748   if (removeActorFromRenderer (am_it->second, viewport))
00749   {
00750     // Remove the pointer/ID pair to the global actor map
00751     shape_actor_map_->erase (am_it);
00752     return (true);
00753   }
00754   return (false);
00755 }
00756 
00758 bool
00759 pcl::visualization::PCLVisualizer::removeAllPointClouds (int viewport)
00760 {
00761   // Check to see if the given ID entry exists
00762   CloudActorMap::iterator am_it = cloud_actor_map_->begin ();
00763   while (am_it != cloud_actor_map_->end () )
00764   {
00765     if (removePointCloud (am_it->first, viewport))
00766       am_it = cloud_actor_map_->begin ();
00767     else
00768       ++am_it;
00769   }
00770   return (true);
00771 }
00772 
00774 bool
00775 pcl::visualization::PCLVisualizer::removeAllShapes (int viewport)
00776 {
00777   // Check to see if the given ID entry exists
00778   ShapeActorMap::iterator am_it = shape_actor_map_->begin ();
00779   while (am_it != shape_actor_map_->end ())
00780   {
00781     if (removeShape (am_it->first, viewport))
00782       am_it = shape_actor_map_->begin ();
00783     else
00784       ++am_it;
00785   }
00786   return (true);
00787 }
00788 
00790 bool
00791 pcl::visualization::PCLVisualizer::addPointCloudPrincipalCurvatures (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud,
00792                                                                      const pcl::PointCloud<pcl::Normal>::ConstPtr &normals,
00793                                                                      const pcl::PointCloud<pcl::PrincipalCurvatures>::ConstPtr &pcs,
00794                                                                      int level, float scale,
00795                                                                      const std::string &id, int viewport)
00796 {
00797   if (pcs->points.size () != cloud->points.size () || normals->points.size () != cloud->points.size ())
00798   {
00799     pcl::console::print_error ("[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
00800     return (false);
00801   }
00802   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00803   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00804 
00805   if (am_it != cloud_actor_map_->end ())
00806   {
00807     pcl::console::print_warn (stderr, "[addPointCloudPrincipalCurvatures] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
00808     return (false);
00809   }
00810 
00811   vtkSmartPointer<vtkAppendPolyData> polydata_1 = vtkSmartPointer<vtkAppendPolyData>::New ();
00812   vtkSmartPointer<vtkAppendPolyData> polydata_2 = vtkSmartPointer<vtkAppendPolyData>::New ();
00813 
00814   // Setup two colors - one for each line
00815   unsigned char green[3] = {0, 255, 0};
00816   unsigned char blue[3] = {0, 0, 255};
00817 
00818   // Setup the colors array
00819   vtkSmartPointer<vtkUnsignedCharArray> line_1_colors =vtkSmartPointer<vtkUnsignedCharArray>::New ();
00820   line_1_colors->SetNumberOfComponents (3);
00821   line_1_colors->SetName ("Colors");
00822   vtkSmartPointer<vtkUnsignedCharArray> line_2_colors =vtkSmartPointer<vtkUnsignedCharArray>::New ();
00823   line_2_colors->SetNumberOfComponents (3);
00824   line_2_colors->SetName ("Colors");
00825 
00826   // Create the first sets of lines
00827   for (size_t i = 0; i < cloud->points.size (); i+=level)
00828   {
00829     pcl::PointXYZ p = cloud->points[i];
00830     p.x += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[0]) * scale;
00831     p.y += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[1]) * scale;
00832     p.z += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[2]) * scale;
00833 
00834     vtkSmartPointer<vtkLineSource> line_1 = vtkSmartPointer<vtkLineSource>::New ();
00835     line_1->SetPoint1 (cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
00836     line_1->SetPoint2 (p.x, p.y, p.z);
00837     line_1->Update ();
00838     polydata_1->AddInput (line_1->GetOutput ());
00839     line_1_colors->InsertNextTupleValue (green);
00840   }
00841   polydata_1->Update ();
00842   vtkSmartPointer<vtkPolyData> line_1_data = polydata_1->GetOutput ();
00843   line_1_data->GetCellData ()->SetScalars (line_1_colors);
00844 
00845   // Create the second sets of lines
00846   for (size_t i = 0; i < cloud->points.size (); i += level)
00847   {
00848     Eigen::Vector3f pc (pcs->points[i].principal_curvature[0],
00849                         pcs->points[i].principal_curvature[1],
00850                         pcs->points[i].principal_curvature[2]);
00851     Eigen::Vector3f normal (normals->points[i].normal[0],
00852                             normals->points[i].normal[1],
00853                             normals->points[i].normal[2]);
00854     Eigen::Vector3f pc_c = pc.cross (normal);
00855 
00856     pcl::PointXYZ p = cloud->points[i];
00857     p.x += (pcs->points[i].pc2 * pc_c[0]) * scale;
00858     p.y += (pcs->points[i].pc2 * pc_c[1]) * scale;
00859     p.z += (pcs->points[i].pc2 * pc_c[2]) * scale;
00860 
00861     vtkSmartPointer<vtkLineSource> line_2 = vtkSmartPointer<vtkLineSource>::New ();
00862     line_2->SetPoint1 (cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
00863     line_2->SetPoint2 (p.x, p.y, p.z);
00864     line_2->Update ();
00865     polydata_2->AddInput (line_2->GetOutput ());
00866     line_2_colors->InsertNextTupleValue (blue);
00867   }
00868   polydata_2->Update ();
00869   vtkSmartPointer<vtkPolyData> line_2_data = polydata_2->GetOutput ();
00870   line_2_data->GetCellData ()->SetScalars (line_2_colors);
00871 
00872   // Assemble the two sets of lines
00873   vtkSmartPointer<vtkAppendPolyData> alldata = vtkSmartPointer<vtkAppendPolyData>::New ();
00874   alldata->AddInput (line_1_data);
00875   alldata->AddInput (line_2_data);
00876 
00877   // Create an Actor
00878   vtkSmartPointer<vtkLODActor> actor;
00879   createActorFromVTKDataSet (alldata->GetOutput (), actor);
00880   actor->GetMapper ()->SetScalarModeToUseCellData ();
00881 
00882   // Add it to all renderers
00883   addActorToRenderer (actor, viewport);
00884 
00885   // Save the pointer/ID pair to the global actor map
00886   CloudActor act;
00887   act.actor = actor;
00888   (*cloud_actor_map_)[id] = act;
00889   return (true);
00890 }
00891 
00893 bool
00894 pcl::visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkLODActor> &actor, int viewport)
00895 {
00896   vtkLODActor* actor_to_remove = vtkLODActor::SafeDownCast (actor);
00897 
00898   // Add it to all renderers
00899   rens_->InitTraversal ();
00900   vtkRenderer* renderer = NULL;
00901   int i = 0;
00902   while ((renderer = rens_->GetNextItem ()) != NULL)
00903   {
00904     // Should we remove the actor from all renderers?
00905     if (viewport == 0)
00906     {
00907       renderer->RemoveActor (actor);
00908 //      renderer->Render ();
00909     }
00910     else if (viewport == i)               // add the actor only to the specified viewport
00911     {
00912       // Iterate over all actors in this renderer
00913       vtkPropCollection* actors = renderer->GetViewProps ();
00914       actors->InitTraversal ();
00915       vtkProp* current_actor = NULL;
00916       while ((current_actor = actors->GetNextProp ()) != NULL)
00917       {
00918         if (current_actor != actor_to_remove)
00919           continue;
00920         renderer->RemoveActor (actor);
00921 //        renderer->Render ();
00922         // Found the correct viewport and removed the actor
00923         return (true);
00924       }
00925     }
00926     ++i;
00927   }
00928   if (viewport == 0) return (true);
00929   return (false);
00930 }
00931 
00933 bool
00934 pcl::visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkActor> &actor, int viewport)
00935 {
00936   vtkActor* actor_to_remove = vtkActor::SafeDownCast (actor);
00937 
00938   // Add it to all renderers
00939   rens_->InitTraversal ();
00940   vtkRenderer* renderer = NULL;
00941   int i = 1;
00942   while ((renderer = rens_->GetNextItem ()) != NULL)
00943   {
00944     // Should we remove the actor from all renderers?
00945     if (viewport == 0)
00946     {
00947       renderer->RemoveActor (actor);
00948 //      renderer->Render ();
00949     }
00950     else if (viewport == i)               // add the actor only to the specified viewport
00951     {
00952       // Iterate over all actors in this renderer
00953       vtkPropCollection* actors = renderer->GetViewProps ();
00954       actors->InitTraversal ();
00955       vtkProp* current_actor = NULL;
00956       while ((current_actor = actors->GetNextProp ()) != NULL)
00957       {
00958         if (current_actor != actor_to_remove)
00959           continue;
00960         renderer->RemoveActor (actor);
00961 //        renderer->Render ();
00962         // Found the correct viewport and removed the actor
00963         return (true);
00964       }
00965     }
00966     ++i;
00967   }
00968   if (viewport == 0) return (true);
00969   return (false);
00970 }
00971 
00973 void
00974 pcl::visualization::PCLVisualizer::addActorToRenderer (const vtkSmartPointer<vtkProp> &actor, int viewport)
00975 {
00976   // Add it to all renderers
00977   rens_->InitTraversal ();
00978   vtkRenderer* renderer = NULL;
00979   int i = 0;
00980   while ((renderer = rens_->GetNextItem ()) != NULL)
00981   {
00982     // Should we add the actor to all renderers?
00983     if (viewport == 0)
00984     {
00985       renderer->AddActor (actor);
00986 //      renderer->Render ();
00987     }
00988     else if (viewport == i)               // add the actor only to the specified viewport
00989     {
00990       renderer->AddActor (actor);
00991 //      renderer->Render ();
00992     }
00993     ++i;
00994   }
00995 }
00996 
00998 bool
00999 pcl::visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkProp> &actor, int viewport)
01000 {
01001   vtkProp* actor_to_remove = vtkProp::SafeDownCast (actor);
01002 
01003   // Initialize traversal
01004   rens_->InitTraversal ();
01005   vtkRenderer* renderer = NULL;
01006   int i = 0;
01007   while ((renderer = rens_->GetNextItem ()) != NULL)
01008   {
01009     // Should we remove the actor from all renderers?
01010     if (viewport == 0)
01011     {
01012       renderer->RemoveActor (actor);
01013 //      renderer->Render ();
01014     }
01015     else if (viewport == i)               // add the actor only to the specified viewport
01016     {
01017       // Iterate over all actors in this renderer
01018       vtkPropCollection* actors = renderer->GetViewProps ();
01019       actors->InitTraversal ();
01020       vtkProp* current_actor = NULL;
01021       while ((current_actor = actors->GetNextProp ()) != NULL)
01022       {
01023         if (current_actor != actor_to_remove)
01024           continue;
01025         renderer->RemoveActor (actor);
01026 //        renderer->Render ();
01027         // Found the correct viewport and removed the actor
01028         return (true);
01029       }
01030     }
01031     ++i;
01032   }
01033   if (viewport == 0) return (true);
01034   return (false);
01035 }
01036 
01038 namespace
01039 {
01040 // Helper function called by createActorFromVTKDataSet () methods.
01041 // This function determines the default setting of vtkMapper::InterpolateScalarsBeforeMapping.
01042 // Return 0, interpolation off, if data is a vtkPolyData that contains only vertices.
01043 // Return 1, interpolation on, for anything else.
01044 int
01045 getDefaultScalarInterpolationForDataSet (vtkDataSet* data)
01046 {
01047   vtkPolyData* polyData = vtkPolyData::SafeDownCast (data);
01048   return (polyData && polyData->GetNumberOfCells () != polyData->GetNumberOfVerts ());
01049 }
01050 
01051 }
01052 
01054 void
01055 pcl::visualization::PCLVisualizer::createActorFromVTKDataSet (const vtkSmartPointer<vtkDataSet> &data,
01056                                                               vtkSmartPointer<vtkLODActor> &actor,
01057                                                               bool use_scalars)
01058 {
01059   // If actor is not initialized, initialize it here
01060   if (!actor)
01061     actor = vtkSmartPointer<vtkLODActor>::New ();
01062 
01063   if (use_vbos_)
01064   {
01065     vtkSmartPointer<vtkVertexBufferObjectMapper> mapper = vtkSmartPointer<vtkVertexBufferObjectMapper>::New ();
01066 
01067     mapper->SetInput (data);
01068 
01069     if (use_scalars)
01070     {
01071       vtkSmartPointer<vtkDataArray> scalars = data->GetPointData ()->GetScalars ();
01072       double minmax[2];
01073       if (scalars)
01074       {
01075         scalars->GetRange (minmax);
01076         mapper->SetScalarRange (minmax);
01077 
01078         mapper->SetScalarModeToUsePointData ();
01079         mapper->SetInterpolateScalarsBeforeMapping (getDefaultScalarInterpolationForDataSet (data));
01080         mapper->ScalarVisibilityOn ();
01081       }
01082     }
01083 
01084     actor->SetNumberOfCloudPoints (int (std::max<vtkIdType> (1, data->GetNumberOfPoints () / 10)));
01085     actor->GetProperty ()->SetInterpolationToFlat ();
01086 
01090     // actor->GetProperty ()->BackfaceCullingOn ();
01091 
01092     actor->SetMapper (mapper);
01093   }
01094   else
01095   {
01096     vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New ();
01097     mapper->SetInput (data);
01098 
01099     if (use_scalars)
01100     {
01101       vtkSmartPointer<vtkDataArray> scalars = data->GetPointData ()->GetScalars ();
01102       double minmax[2];
01103       if (scalars)
01104       {
01105         scalars->GetRange (minmax);
01106         mapper->SetScalarRange (minmax);
01107 
01108         mapper->SetScalarModeToUsePointData ();
01109         mapper->SetInterpolateScalarsBeforeMapping (getDefaultScalarInterpolationForDataSet (data));
01110         mapper->ScalarVisibilityOn ();
01111       }
01112     }
01113     mapper->ImmediateModeRenderingOff ();
01114 
01115     actor->SetNumberOfCloudPoints (int (std::max<vtkIdType> (1, data->GetNumberOfPoints () / 10)));
01116     actor->GetProperty ()->SetInterpolationToFlat ();
01117 
01121     // actor->GetProperty ()->BackfaceCullingOn ();
01122 
01123     actor->SetMapper (mapper);
01124   }
01125 }
01126 
01128 void
01129 pcl::visualization::PCLVisualizer::createActorFromVTKDataSet (const vtkSmartPointer<vtkDataSet> &data,
01130                                                               vtkSmartPointer<vtkActor> &actor,
01131                                                               bool use_scalars)
01132 {
01133   // If actor is not initialized, initialize it here
01134   if (!actor)
01135     actor = vtkSmartPointer<vtkActor>::New ();
01136 
01137   if (use_vbos_)
01138   {
01139     vtkSmartPointer<vtkVertexBufferObjectMapper> mapper = vtkSmartPointer<vtkVertexBufferObjectMapper>::New ();
01140 
01141     mapper->SetInput (data);
01142 
01143     if (use_scalars)
01144     {
01145       vtkSmartPointer<vtkDataArray> scalars = data->GetPointData ()->GetScalars ();
01146       double minmax[2];
01147       if (scalars)
01148       {
01149         scalars->GetRange (minmax);
01150         mapper->SetScalarRange (minmax);
01151 
01152         mapper->SetScalarModeToUsePointData ();
01153         mapper->SetInterpolateScalarsBeforeMapping (getDefaultScalarInterpolationForDataSet (data));
01154         mapper->ScalarVisibilityOn ();
01155       }
01156     }
01157 
01158     //actor->SetNumberOfCloudPoints (int (std::max<vtkIdType> (1, data->GetNumberOfPoints () / 10)));
01159     actor->GetProperty ()->SetInterpolationToFlat ();
01160 
01164     // actor->GetProperty ()->BackfaceCullingOn ();
01165 
01166     actor->SetMapper (mapper);
01167   }
01168   else
01169   {
01170     vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New ();
01171     mapper->SetInput (data);
01172 
01173     if (use_scalars)
01174     {
01175       vtkSmartPointer<vtkDataArray> scalars = data->GetPointData ()->GetScalars ();
01176       double minmax[2];
01177       if (scalars)
01178       {
01179         scalars->GetRange (minmax);
01180         mapper->SetScalarRange (minmax);
01181 
01182         mapper->SetScalarModeToUsePointData ();
01183         mapper->SetInterpolateScalarsBeforeMapping (getDefaultScalarInterpolationForDataSet (data));
01184         mapper->ScalarVisibilityOn ();
01185       }
01186     }
01187     mapper->ImmediateModeRenderingOff ();
01188 
01189     //actor->SetNumberOfCloudPoints (int (std::max<vtkIdType> (1, data->GetNumberOfPoints () / 10)));
01190     actor->GetProperty ()->SetInterpolationToFlat ();
01191 
01195     // actor->GetProperty ()->BackfaceCullingOn ();
01196 
01197     actor->SetMapper (mapper);
01198   }
01199 
01200   //actor->SetNumberOfCloudPoints (std::max<vtkIdType> (1, data->GetNumberOfPoints () / 10));
01201   actor->GetProperty ()->SetInterpolationToFlat ();
01202 }
01203 
01205 void
01206 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
01207     const GeometryHandlerConstPtr &geometry_handler,
01208     vtkSmartPointer<vtkPolyData> &polydata,
01209     vtkSmartPointer<vtkIdTypeArray> &initcells)
01210 {
01211   vtkSmartPointer<vtkCellArray> vertices;
01212 
01213   if (!polydata)
01214   {
01215     allocVtkPolyData (polydata);
01216     vertices = vtkSmartPointer<vtkCellArray>::New ();
01217     polydata->SetVerts (vertices);
01218   }
01219 
01220   // Use the handler to obtain the geometry
01221   vtkSmartPointer<vtkPoints> points;
01222   geometry_handler->getGeometry (points);
01223   polydata->SetPoints (points);
01224 
01225   vtkIdType nr_points = points->GetNumberOfPoints ();
01226 
01227   // Create the supporting structures
01228   vertices = polydata->GetVerts ();
01229   if (!vertices)
01230     vertices = vtkSmartPointer<vtkCellArray>::New ();
01231 
01232   vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
01233   updateCells (cells, initcells, nr_points);
01234   // Set the cells and the vertices
01235   vertices->SetCells (nr_points, cells);
01236 }
01237 
01239 void
01240 pcl::visualization::PCLVisualizer::setBackgroundColor (
01241     const double &r, const double &g, const double &b, int viewport)
01242 {
01243   rens_->InitTraversal ();
01244   vtkRenderer* renderer = NULL;
01245   int i = 1;
01246   while ((renderer = rens_->GetNextItem ()) != NULL)
01247   {
01248     // Should we add the actor to all renderers?
01249     if (viewport == 0)
01250     {
01251       renderer->SetBackground (r, g, b);
01252 //      renderer->Render ();
01253     }
01254     else if (viewport == i)               // add the actor only to the specified viewport
01255     {
01256       renderer->SetBackground (r, g, b);
01257 //      renderer->Render ();
01258     }
01259     ++i;
01260   }
01261 }
01262 
01264 bool
01265 pcl::visualization::PCLVisualizer::setPointCloudRenderingProperties (
01266     int property, double val1, double val2, double val3, const std::string &id, int)
01267 {
01268   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01269   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01270 
01271   if (am_it == cloud_actor_map_->end ())
01272   {
01273     pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ());
01274     return (false);
01275   }
01276   // Get the actor pointer
01277   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
01278 
01279   switch (property)
01280   {
01281     case PCL_VISUALIZER_COLOR:
01282     {
01283       actor->GetProperty ()->SetColor (val1, val2, val3);
01284       actor->GetMapper ()->ScalarVisibilityOff ();
01285       actor->Modified ();
01286       break;
01287     }
01288     default:
01289     {
01290       pcl::console::print_error ("[setPointCloudRenderingProperties] Unknown property (%d) specified!\n", property);
01291       return (false);
01292     }
01293   }
01294   return (true);
01295 }
01296 
01298 bool
01299 pcl::visualization::PCLVisualizer::getPointCloudRenderingProperties (int property, double &value, const std::string &id)
01300 {
01301   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01302   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01303 
01304   if (am_it == cloud_actor_map_->end ())
01305     return (false);
01306   // Get the actor pointer
01307   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
01308 
01309   switch (property)
01310   {
01311     case PCL_VISUALIZER_POINT_SIZE:
01312     {
01313       value = actor->GetProperty ()->GetPointSize ();
01314       actor->Modified ();
01315       break;
01316     }
01317     case PCL_VISUALIZER_OPACITY:
01318     {
01319       value = actor->GetProperty ()->GetOpacity ();
01320       actor->Modified ();
01321       break;
01322     }
01323     case PCL_VISUALIZER_LINE_WIDTH:
01324     {
01325       value = actor->GetProperty ()->GetLineWidth ();
01326       actor->Modified ();
01327       break;
01328     }
01329     default:
01330     {
01331       pcl::console::print_error ("[getPointCloudRenderingProperties] Unknown property (%d) specified!\n", property);
01332       return (false);
01333     }
01334   }
01335   return (true);
01336 }
01337 
01339 bool
01340 pcl::visualization::PCLVisualizer::setPointCloudRenderingProperties (
01341     int property, double value, const std::string &id, int)
01342 {
01343   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01344   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01345 
01346   if (am_it == cloud_actor_map_->end ())
01347   {
01348     pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ());
01349     return (false);
01350   }
01351   // Get the actor pointer
01352   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
01353 
01354   switch (property)
01355   {
01356     case PCL_VISUALIZER_POINT_SIZE:
01357     {
01358       actor->GetProperty ()->SetPointSize (float (value));
01359       actor->Modified ();
01360       break;
01361     }
01362     case PCL_VISUALIZER_OPACITY:
01363     {
01364       actor->GetProperty ()->SetOpacity (value);
01365       actor->Modified ();
01366       break;
01367     }
01368     // Turn on/off flag to control whether data is rendered using immediate
01369     // mode or note. Immediate mode rendering tends to be slower but it can
01370     // handle larger datasets. The default value is immediate mode off. If you
01371     // are having problems rendering a large dataset you might want to consider
01372     // using immediate more rendering.
01373     case PCL_VISUALIZER_IMMEDIATE_RENDERING:
01374     {
01375       actor->GetMapper ()->SetImmediateModeRendering (int (value));
01376       actor->Modified ();
01377       break;
01378     }
01379     case PCL_VISUALIZER_LINE_WIDTH:
01380     {
01381       actor->GetProperty ()->SetLineWidth (float (value));
01382       actor->Modified ();
01383       break;
01384     }
01385     default:
01386     {
01387       pcl::console::print_error ("[setPointCloudRenderingProperties] Unknown property (%d) specified!\n", property);
01388       return (false);
01389     }
01390   }
01391   return (true);
01392 }
01393 
01395 bool
01396 pcl::visualization::PCLVisualizer::setPointCloudSelected (const bool selected, const std::string &id)
01397 {
01398    // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01399   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01400 
01401   if (am_it == cloud_actor_map_->end ())
01402   {
01403     pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ());
01404     return (false);
01405   }
01406   // Get the actor pointer
01407   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
01408 
01409   if (selected)
01410   {
01411     actor->GetProperty ()->EdgeVisibilityOn ();
01412     actor->GetProperty ()->SetEdgeColor (1.0,0.0,0.0);
01413     actor->Modified ();
01414   }
01415   else
01416   {
01417     actor->GetProperty ()->EdgeVisibilityOff ();
01418     actor->Modified ();
01419   }
01420 
01421   return (true);
01422 }
01423 
01425 bool
01426 pcl::visualization::PCLVisualizer::setShapeRenderingProperties (
01427     int property, double val1, double val2, double val3, const std::string &id, int)
01428 {
01429   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01430   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01431 
01432   if (am_it == shape_actor_map_->end ())
01433   {
01434     pcl::console::print_error ("[setShapeRenderingProperties] Could not find any shape with id <%s>!\n", id.c_str ());
01435     return (false);
01436   }
01437   // Get the actor pointer
01438   vtkActor* actor = vtkActor::SafeDownCast (am_it->second);
01439 
01440   switch (property)
01441   {
01442     case PCL_VISUALIZER_COLOR:
01443     {
01444       actor->GetMapper ()->ScalarVisibilityOff ();
01445       actor->GetProperty ()->SetColor (val1, val2, val3);
01446       actor->GetProperty ()->SetEdgeColor (val1, val2, val3);
01447       // The following 3 are set by SetColor automatically according to the VTK docs
01448       //actor->GetProperty ()->SetAmbientColor  (val1, val2, val3);
01449       //actor->GetProperty ()->SetDiffuseColor (val1, val2, val3);
01450       //actor->GetProperty ()->SetSpecularColor (val1, val2, val3);
01451       actor->GetProperty ()->SetAmbient (0.8);
01452       actor->GetProperty ()->SetDiffuse (0.8);
01453       actor->GetProperty ()->SetSpecular (0.8);
01454 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 4))
01455       actor->GetProperty ()->SetLighting (0);
01456 #endif
01457       actor->Modified ();
01458       break;
01459     }
01460     default:
01461     {
01462       pcl::console::print_error ("[setShapeRenderingProperties] Unknown property (%d) specified!\n", property);
01463       return (false);
01464     }
01465   }
01466   return (true);
01467 }
01468 
01470 bool
01471 pcl::visualization::PCLVisualizer::setShapeRenderingProperties (
01472     int property, double value, const std::string &id, int)
01473 {
01474   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01475   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01476 
01477   if (am_it == shape_actor_map_->end ())
01478   {
01479     pcl::console::print_error ("[setShapeRenderingProperties] Could not find any shape with id <%s>!\n", id.c_str ());
01480     return (false);
01481   }
01482   // Get the actor pointer
01483   vtkActor* actor = vtkActor::SafeDownCast (am_it->second);
01484 
01485   switch (property)
01486   {
01487     case PCL_VISUALIZER_POINT_SIZE:
01488     {
01489       actor->GetProperty ()->SetPointSize (float (value));
01490       actor->Modified ();
01491       break;
01492     }
01493     case PCL_VISUALIZER_OPACITY:
01494     {
01495       actor->GetProperty ()->SetOpacity (value);
01496       actor->Modified ();
01497       break;
01498     }
01499     case PCL_VISUALIZER_LINE_WIDTH:
01500     {
01501       actor->GetProperty ()->SetLineWidth (float (value));
01502       actor->Modified ();
01503       break;
01504     }
01505     case PCL_VISUALIZER_FONT_SIZE:
01506     {
01507       vtkTextActor* text_actor = vtkTextActor::SafeDownCast (am_it->second);
01508       vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty ();
01509       tprop->SetFontSize (int (value));
01510       text_actor->Modified ();
01511       break;
01512     }
01513     case PCL_VISUALIZER_REPRESENTATION:
01514     {
01515       switch (int (value))
01516       {
01517         case PCL_VISUALIZER_REPRESENTATION_POINTS:
01518         {
01519           actor->GetProperty ()->SetRepresentationToPoints ();
01520           break;
01521         }
01522         case PCL_VISUALIZER_REPRESENTATION_WIREFRAME:
01523         {
01524           actor->GetProperty ()->SetRepresentationToWireframe ();
01525           break;
01526         }
01527         case PCL_VISUALIZER_REPRESENTATION_SURFACE:
01528         {
01529           actor->GetProperty ()->SetRepresentationToSurface ();
01530           break;
01531         }
01532       }
01533       actor->Modified ();
01534       break;
01535     }
01536     case PCL_VISUALIZER_SHADING:
01537     {
01538       switch (int (value))
01539       {
01540         case PCL_VISUALIZER_SHADING_FLAT:
01541         {
01542           actor->GetProperty ()->SetInterpolationToFlat ();
01543           break;
01544         }
01545         case PCL_VISUALIZER_SHADING_GOURAUD:
01546         {
01547           if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ())
01548           {
01549             PCL_INFO ("[pcl::visualization::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Gouraud shading was requested. Estimating normals...\n");
01550             vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New ();
01551             normals->SetInput (actor->GetMapper ()->GetInput ());
01552             normals->Update ();
01553             vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ());
01554           }
01555           actor->GetProperty ()->SetInterpolationToGouraud ();
01556           break;
01557         }
01558         case PCL_VISUALIZER_SHADING_PHONG:
01559         {
01560           if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ())
01561           {
01562             PCL_INFO ("[pcl::visualization::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Phong shading was requested. Estimating normals...\n");
01563             vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New ();
01564             normals->SetInput (actor->GetMapper ()->GetInput ());
01565             normals->Update ();
01566             vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ());
01567           }
01568           actor->GetProperty ()->SetInterpolationToPhong ();
01569           break;
01570         }
01571       }
01572       actor->Modified ();
01573       break;
01574     }
01575     default:
01576     {
01577       pcl::console::print_error ("[setShapeRenderingProperties] Unknown property (%d) specified!\n", property);
01578       return (false);
01579     }
01580   }
01581   return (true);
01582 }
01583 
01585 void
01586 pcl::visualization::PCLVisualizer::initCameraParameters ()
01587 {
01588   Camera camera_temp;
01589   // Set default camera parameters to something meaningful
01590   camera_temp.clip[0] = 0.01;
01591   camera_temp.clip[1] = 1000.01;
01592 
01593   // Look straight along the z-axis
01594   camera_temp.focal[0] = 0.;
01595   camera_temp.focal[1] = 0.;
01596   camera_temp.focal[2] = 1.;
01597 
01598   // Position the camera at the origin
01599   camera_temp.pos[0] = 0.;
01600   camera_temp.pos[1] = 0.;
01601   camera_temp.pos[2] = 0.;
01602 
01603   // Set the up-vector of the camera to be the y-axis
01604   camera_temp.view[0] = 0.;
01605   camera_temp.view[1] = 1.;
01606   camera_temp.view[2] = 0.;
01607 
01608   // Set the camera field of view to about
01609   camera_temp.fovy = 0.8575;
01610 
01611   int *scr_size = win_->GetScreenSize ();
01612   camera_temp.window_size[0] = scr_size[0] / 2;
01613   camera_temp.window_size[1] = scr_size[1] / 2;
01614 
01615   setCameraParameters (camera_temp);
01616 }
01617 
01619 bool
01620 pcl::visualization::PCLVisualizer::cameraParamsSet () const
01621 {
01622   return (camera_set_);
01623 }
01624 
01626 void
01627 pcl::visualization::PCLVisualizer::updateCamera ()
01628 {
01629   PCL_WARN ("[pcl::visualization::PCLVisualizer::updateCamera()] This method was deprecated, just re-rendering all scenes now.");
01630   rens_->InitTraversal ();
01631   // Update the camera parameters
01632   vtkRenderer* renderer = NULL;
01633   while ((renderer = rens_->GetNextItem ()) != NULL)
01634     renderer->Render ();
01635 }
01636 
01638 bool
01639 pcl::visualization::PCLVisualizer::updateShapePose (const std::string &id, const Eigen::Affine3f& pose)
01640 {
01641   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01642 
01643   vtkLODActor* actor;
01644 
01645   if (am_it == shape_actor_map_->end ())
01646     return (false);
01647   else
01648     actor = vtkLODActor::SafeDownCast (am_it->second);
01649 
01650   vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New ();
01651 
01652   convertToVtkMatrix (pose.matrix (), matrix);
01653 
01654   actor->SetUserMatrix (matrix);
01655   actor->Modified ();
01656 
01657   return (true);
01658 }
01659 
01661 bool
01662 pcl::visualization::PCLVisualizer::updatePointCloudPose (const std::string &id, const Eigen::Affine3f& pose)
01663 {
01664   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01665   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01666 
01667   if (am_it == cloud_actor_map_->end ())
01668     return (false);
01669 
01670   vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New ();
01671   convertToVtkMatrix (pose.matrix (), transformation);
01672   am_it->second.viewpoint_transformation_ = transformation;
01673   am_it->second.actor->SetUserMatrix (transformation);
01674   am_it->second.actor->Modified ();
01675 
01676   return (true);
01677 }
01678 
01680 void
01681 pcl::visualization::PCLVisualizer::getCameras (std::vector<pcl::visualization::Camera>& cameras)
01682 {
01683   cameras.clear ();
01684   rens_->InitTraversal ();
01685   vtkRenderer* renderer = NULL;
01686   while ((renderer = rens_->GetNextItem ()) != NULL)
01687   {
01688     cameras.push_back(Camera());
01689     cameras.back ().pos[0] = renderer->GetActiveCamera ()->GetPosition ()[0];
01690     cameras.back ().pos[1] = renderer->GetActiveCamera ()->GetPosition ()[1];
01691     cameras.back ().pos[2] = renderer->GetActiveCamera ()->GetPosition ()[2];
01692     cameras.back ().focal[0] = renderer->GetActiveCamera ()->GetFocalPoint ()[0];
01693     cameras.back ().focal[1] = renderer->GetActiveCamera ()->GetFocalPoint ()[1];
01694     cameras.back ().focal[2] = renderer->GetActiveCamera ()->GetFocalPoint ()[2];
01695     cameras.back ().clip[0] = renderer->GetActiveCamera ()->GetClippingRange ()[0];
01696     cameras.back ().clip[1] = renderer->GetActiveCamera ()->GetClippingRange ()[1];
01697     cameras.back ().view[0] = renderer->GetActiveCamera ()->GetViewUp ()[0];
01698     cameras.back ().view[1] = renderer->GetActiveCamera ()->GetViewUp ()[1];
01699     cameras.back ().view[2] = renderer->GetActiveCamera ()->GetViewUp ()[2];
01700     cameras.back ().fovy = renderer->GetActiveCamera ()->GetViewAngle () / 180.0 * M_PI;
01701     cameras.back ().window_size[0] = renderer->GetRenderWindow ()->GetSize ()[0];
01702     cameras.back ().window_size[1] = renderer->GetRenderWindow ()->GetSize ()[1];
01703     cameras.back ().window_pos[0] = 0;
01704     cameras.back ().window_pos[1] = 0;
01705   }
01706 }
01707 
01709 Eigen::Affine3f
01710 pcl::visualization::PCLVisualizer::getViewerPose (int viewport)
01711 {
01712   Eigen::Affine3f ret (Eigen::Affine3f::Identity ());
01713 
01714   rens_->InitTraversal ();
01715   vtkRenderer* renderer = NULL;
01716   if (viewport == 0)
01717     viewport = 1;
01718   int viewport_i = 1;
01719   while ((renderer = rens_->GetNextItem ()) != NULL)
01720   {
01721     if (viewport_i == viewport)
01722     {
01723       vtkCamera& camera = *renderer->GetActiveCamera ();
01724       Eigen::Vector3d pos, x_axis, y_axis, z_axis;
01725       camera.GetPosition (pos[0], pos[1], pos[2]);
01726       camera.GetViewUp (y_axis[0], y_axis[1], y_axis[2]);
01727       camera.GetFocalPoint (z_axis[0], z_axis[1], z_axis[2]);
01728 
01729       z_axis = (z_axis - pos).normalized ();
01730       x_axis = y_axis.cross (z_axis).normalized ();
01731 
01733       ret (0, 0) = static_cast<float> (x_axis[0]);
01734       ret (0, 1) = static_cast<float> (y_axis[0]);
01735       ret (0, 2) = static_cast<float> (z_axis[0]);
01736       ret (0, 3) = static_cast<float> (pos[0]);
01737 
01738       ret (1, 0) = static_cast<float> (x_axis[1]);
01739       ret (1, 1) = static_cast<float> (y_axis[1]);
01740       ret (1, 2) = static_cast<float> (z_axis[1]);
01741       ret (1, 3) = static_cast<float> (pos[1]);
01742 
01743       ret (2, 0) = static_cast<float> (x_axis[2]);
01744       ret (2, 1) = static_cast<float> (y_axis[2]);
01745       ret (2, 2) = static_cast<float> (z_axis[2]);
01746       ret (2, 3) = static_cast<float> (pos[2]);
01747 
01748       return ret;
01749     }
01750     viewport_i ++;
01751   }
01752 
01753   return ret;
01754 }
01755 
01757 void
01758 pcl::visualization::PCLVisualizer::resetCamera ()
01759 {
01760   // Update the camera parameters
01761   rens_->InitTraversal ();
01762   vtkRenderer* renderer = NULL;
01763   while ((renderer = rens_->GetNextItem ()) != NULL)
01764     renderer->ResetCamera ();
01765 }
01766 
01767 
01769 void
01770 pcl::visualization::PCLVisualizer::setCameraPosition (
01771     double pos_x, double pos_y, double pos_z,
01772     double view_x, double view_y, double view_z,
01773     double up_x, double up_y, double up_z,
01774     int viewport)
01775 {
01776   rens_->InitTraversal ();
01777   vtkRenderer* renderer = NULL;
01778   int i = 1;
01779   while ((renderer = rens_->GetNextItem ()) != NULL)
01780   {
01781     // Modify all renderer's cameras
01782     if (viewport == 0 || viewport == i)
01783     {
01784       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01785       cam->SetPosition (pos_x, pos_y, pos_z);
01786       cam->SetFocalPoint (view_x, view_y, view_z);
01787       cam->SetViewUp (up_x, up_y, up_z);
01788       renderer->Render ();
01789     }
01790     ++i;
01791   }
01792 }
01793 
01795 void
01796 pcl::visualization::PCLVisualizer::setCameraPosition (
01797     double pos_x, double pos_y, double pos_z,
01798     double up_x, double up_y, double up_z, int viewport)
01799 {
01800   rens_->InitTraversal ();
01801   vtkRenderer* renderer = NULL;
01802   int i = 1;
01803   while ((renderer = rens_->GetNextItem ()) != NULL)
01804   {
01805     // Modify all renderer's cameras
01806     if (viewport == 0 || viewport == i)
01807     {
01808       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01809       cam->SetPosition (pos_x, pos_y, pos_z);
01810       cam->SetViewUp (up_x, up_y, up_z);
01811       renderer->Render ();
01812     }
01813     ++i;
01814   }
01815 }
01816 
01818 void
01819 pcl::visualization::PCLVisualizer::setCameraParameters (const Eigen::Matrix3f &intrinsics,
01820                                                         const Eigen::Matrix4f &extrinsics,
01821                                                         int viewport)
01822 {
01823   // Position = extrinsic translation
01824   Eigen::Vector3f pos_vec = extrinsics.block<3, 1> (0, 3);
01825 
01826   // Rotate the view vector
01827   Eigen::Matrix3f rotation = extrinsics.block<3, 3> (0, 0);
01828   Eigen::Vector3f y_axis (0.f, 1.f, 0.f);
01829   Eigen::Vector3f up_vec (rotation * y_axis);
01830 
01831   // Compute the new focal point
01832   Eigen::Vector3f z_axis (0.f, 0.f, 1.f);
01833   Eigen::Vector3f focal_vec = pos_vec + rotation * z_axis;
01834 
01835   // Get the width and height of the image - assume the calibrated centers are at the center of the image
01836   Eigen::Vector2i window_size;
01837   window_size[0] = static_cast<int> (intrinsics (0, 2));
01838   window_size[1] = static_cast<int> (intrinsics (1, 2));
01839 
01840   // Compute the vertical field of view based on the focal length and image heigh
01841   double fovy = 2 * atan (window_size[1] / (2. * intrinsics (1, 1))) * 180.0 / M_PI;
01842 
01843 
01844   rens_->InitTraversal ();
01845   vtkRenderer* renderer = NULL;
01846   int i = 1;
01847   while ((renderer = rens_->GetNextItem ()) != NULL)
01848   {
01849     // Modify all renderer's cameras
01850     if (viewport == 0 || viewport == i)
01851     {
01852       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01853       cam->SetPosition (pos_vec[0], pos_vec[1], pos_vec[2]);
01854       cam->SetFocalPoint (focal_vec[0], focal_vec[1], focal_vec[2]);
01855       cam->SetViewUp (up_vec[0], up_vec[1], up_vec[2]);
01856       cam->SetUseHorizontalViewAngle (0);
01857       cam->SetViewAngle (fovy);
01858       cam->SetClippingRange (0.01, 1000.01);
01859       win_->SetSize (window_size[0], window_size[1]);
01860 
01861       renderer->Render ();
01862     }
01863   }
01864 }
01865 
01867 void
01868 pcl::visualization::PCLVisualizer::setCameraParameters (const pcl::visualization::Camera &camera, int viewport)
01869 {
01870   rens_->InitTraversal ();
01871   vtkRenderer* renderer = NULL;
01872   int i = 1;
01873   while ((renderer = rens_->GetNextItem ()) != NULL)
01874   {
01875     // Modify all renderer's cameras
01876     if (viewport == 0 || viewport == i)
01877     {
01878       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01879       cam->SetPosition (camera.pos[0], camera.pos[1], camera.pos[2]);
01880       cam->SetFocalPoint (camera.focal[0], camera.focal[1], camera.focal[2]);
01881       cam->SetViewUp (camera.view[0], camera.view[1], camera.view[2]);
01882       cam->SetClippingRange (camera.clip);
01883       cam->SetUseHorizontalViewAngle (0);
01884       cam->SetViewAngle (camera.fovy * 180.0 / M_PI);
01885 
01886       win_->SetSize (static_cast<int> (camera.window_size[0]),
01887                      static_cast<int> (camera.window_size[1]));
01888     }
01889   }
01890 }
01891 
01893 void
01894 pcl::visualization::PCLVisualizer::setCameraClipDistances (double near, double far, int viewport)
01895 {
01896   rens_->InitTraversal ();
01897   vtkRenderer* renderer = NULL;
01898   int i = 1;
01899   while ((renderer = rens_->GetNextItem ()) != NULL)
01900   {
01901     // Modify all renderer's cameras
01902     if (viewport == 0 || viewport == i)
01903     {
01904       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01905       cam->SetClippingRange (near, far);
01906     }
01907   }
01908 }
01909 
01911 void
01912 pcl::visualization::PCLVisualizer::setCameraFieldOfView (double fovy, int viewport)
01913 {
01914   rens_->InitTraversal ();
01915   vtkRenderer* renderer = NULL;
01916   int i = 1;
01917   while ((renderer = rens_->GetNextItem ()) != NULL)
01918   {
01919     // Modify all renderer's cameras
01920     if (viewport == 0 || viewport == i)
01921     {
01922       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01923       cam->SetUseHorizontalViewAngle (0);
01924       cam->SetViewAngle (fovy * 180.0 / M_PI);
01925     }
01926   }
01927 }
01928 
01930 void
01931 pcl::visualization::PCLVisualizer::resetCameraViewpoint (const std::string &id)
01932 {
01933   vtkSmartPointer<vtkMatrix4x4> camera_pose;
01934   static CloudActorMap::iterator it = cloud_actor_map_->find (id);
01935   if (it != cloud_actor_map_->end ())
01936     camera_pose = it->second.viewpoint_transformation_;
01937   else
01938     return;
01939 
01940   // Prevent a segfault
01941   if (!camera_pose)
01942     return;
01943 
01944   // set all renderer to this viewpoint
01945   rens_->InitTraversal ();
01946   vtkRenderer* renderer = NULL;
01947   while ((renderer = rens_->GetNextItem ()) != NULL)
01948   {
01949     vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01950     cam->SetPosition (camera_pose->GetElement (0, 3),
01951                       camera_pose->GetElement (1, 3),
01952                       camera_pose->GetElement (2, 3));
01953 
01954     cam->SetFocalPoint (camera_pose->GetElement (0, 3) - camera_pose->GetElement (0, 2),
01955                         camera_pose->GetElement (1, 3) - camera_pose->GetElement (1, 2),
01956                         camera_pose->GetElement (2, 3) - camera_pose->GetElement (2, 2));
01957 
01958     cam->SetViewUp (camera_pose->GetElement (0, 1),
01959                     camera_pose->GetElement (1, 1),
01960                     camera_pose->GetElement (2, 1));
01961 
01962     renderer->SetActiveCamera (cam);
01963     renderer->ResetCameraClippingRange ();
01964     renderer->Render ();
01965   }
01966 }
01967 
01969 bool
01970 pcl::visualization::PCLVisualizer::getCameraParameters (int argc, char **argv)
01971 {
01972   Camera camera_temp;
01973   for (int i = 1; i < argc; i++)
01974   {
01975     if ((strcmp (argv[i], "-cam") == 0) && (++i < argc))
01976     {
01977       std::ifstream fs;
01978       std::string camfile = std::string (argv[i]);
01979       std::string line;
01980 
01981       std::vector<std::string> camera;
01982       if (camfile.find (".cam") == std::string::npos)
01983       {
01984         // Assume we have clip/focal/pos/view
01985         boost::split (camera, argv[i], boost::is_any_of ("/"), boost::token_compress_on);
01986       }
01987       else
01988       {
01989         // Assume that if we don't have clip/focal/pos/view, a filename.cam was given as a parameter
01990         fs.open (camfile.c_str ());
01991         while (!fs.eof ())
01992         {
01993           getline (fs, line);
01994           if (line == "")
01995             continue;
01996 
01997           boost::split (camera, line, boost::is_any_of ("/"), boost::token_compress_on);
01998           break;
01999         }
02000         fs.close ();
02001       }
02002 
02003       // look for '/' as a separator
02004       if (camera.size () != 7)
02005       {
02006         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Camera parameters given, but with an invalid number of options (%lu vs 7)!\n", static_cast<unsigned long> (camera.size ()));
02007         return (false);
02008       }
02009 
02010       std::string clip_str  = camera.at (0);
02011       std::string focal_str = camera.at (1);
02012       std::string pos_str   = camera.at (2);
02013       std::string view_str  = camera.at (3);
02014       std::string fovy_str  = camera.at (4);
02015       std::string win_size_str = camera.at (5);
02016       std::string win_pos_str  = camera.at (6);
02017 
02018       // Get each camera setting separately and parse for ','
02019       std::vector<std::string> clip_st;
02020       boost::split (clip_st, clip_str, boost::is_any_of (","), boost::token_compress_on);
02021       if (clip_st.size () != 2)
02022       {
02023         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera clipping angle!\n");
02024         return (false);
02025       }
02026       camera_temp.clip[0] = atof (clip_st.at (0).c_str ());
02027       camera_temp.clip[1] = atof (clip_st.at (1).c_str ());
02028 
02029       std::vector<std::string> focal_st;
02030       boost::split (focal_st, focal_str, boost::is_any_of (","), boost::token_compress_on);
02031       if (focal_st.size () != 3)
02032       {
02033         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera focal point!\n");
02034         return (false);
02035       }
02036       camera_temp.focal[0] = atof (focal_st.at (0).c_str ());
02037       camera_temp.focal[1] = atof (focal_st.at (1).c_str ());
02038       camera_temp.focal[2] = atof (focal_st.at (2).c_str ());
02039 
02040       std::vector<std::string> pos_st;
02041       boost::split (pos_st, pos_str, boost::is_any_of (","), boost::token_compress_on);
02042       if (pos_st.size () != 3)
02043       {
02044         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera position!\n");
02045         return (false);
02046       }
02047       camera_temp.pos[0] = atof (pos_st.at (0).c_str ());
02048       camera_temp.pos[1] = atof (pos_st.at (1).c_str ());
02049       camera_temp.pos[2] = atof (pos_st.at (2).c_str ());
02050 
02051       std::vector<std::string> view_st;
02052       boost::split (view_st, view_str, boost::is_any_of (","), boost::token_compress_on);
02053       if (view_st.size () != 3)
02054       {
02055         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera viewup!\n");
02056         return (false);
02057       }
02058       camera_temp.view[0] = atof (view_st.at (0).c_str ());
02059       camera_temp.view[1] = atof (view_st.at (1).c_str ());
02060       camera_temp.view[2] = atof (view_st.at (2).c_str ());
02061 
02062       std::vector<std::string> fovy_size_st;
02063       boost::split (fovy_size_st, fovy_str, boost::is_any_of (","), boost::token_compress_on);
02064       if (fovy_size_st.size () != 1)
02065       {
02066         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for field of view angle!\n");
02067         return (false);
02068       }
02069       camera_temp.fovy = atof (fovy_size_st.at (0).c_str ());
02070 
02071       std::vector<std::string> win_size_st;
02072       boost::split (win_size_st, win_size_str, boost::is_any_of (","), boost::token_compress_on);
02073       if (win_size_st.size () != 2)
02074       {
02075         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for window size!\n");
02076         return (false);
02077       }
02078       camera_temp.window_size[0] = atof (win_size_st.at (0).c_str ());
02079       camera_temp.window_size[1] = atof (win_size_st.at (1).c_str ());
02080 
02081       std::vector<std::string> win_pos_st;
02082       boost::split (win_pos_st, win_pos_str, boost::is_any_of (","), boost::token_compress_on);
02083       if (win_pos_st.size () != 2)
02084       {
02085         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for window position!\n");
02086         return (false);
02087       }
02088       camera_temp.window_pos[0] = atof (win_pos_st.at (0).c_str ());
02089       camera_temp.window_pos[1] = atof (win_pos_st.at (1).c_str ());
02090 
02091       setCameraParameters (camera_temp);
02092 
02093       return (true);
02094     }
02095   }
02096   return (false);
02097 }
02098 
02100 bool
02101 pcl::visualization::PCLVisualizer::addCylinder (const pcl::ModelCoefficients &coefficients,
02102                                                const std::string &id, int viewport)
02103 {
02104   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02105   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02106   if (am_it != shape_actor_map_->end ())
02107   {
02108     pcl::console::print_warn (stderr, "[addCylinder] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02109     return (false);
02110   }
02111 
02112   vtkSmartPointer<vtkDataSet> data = createCylinder (coefficients);
02113 
02114   // Create an Actor
02115   vtkSmartPointer<vtkLODActor> actor;
02116   createActorFromVTKDataSet (data, actor);
02117   actor->GetProperty ()->SetRepresentationToWireframe ();
02118   actor->GetProperty ()->SetLighting (false);
02119   addActorToRenderer (actor, viewport);
02120 
02121   // Save the pointer/ID pair to the global actor map
02122   (*shape_actor_map_)[id] = actor;
02123   return (true);
02124 }
02125 
02127 bool
02128 pcl::visualization::PCLVisualizer::addCube (const pcl::ModelCoefficients &coefficients,
02129                                             const std::string &id, int viewport)
02130 {
02131   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02132   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02133   if (am_it != shape_actor_map_->end ())
02134   {
02135     pcl::console::print_warn (stderr, "[addCube] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02136     return (false);
02137   }
02138 
02139   vtkSmartPointer<vtkDataSet> data = createCube (coefficients);
02140 
02141   // Create an Actor
02142   vtkSmartPointer<vtkLODActor> actor;
02143   createActorFromVTKDataSet (data, actor);
02144   actor->GetProperty ()->SetRepresentationToWireframe ();
02145   actor->GetProperty ()->SetLighting (false);
02146   addActorToRenderer (actor, viewport);
02147 
02148   // Save the pointer/ID pair to the global actor map
02149   (*shape_actor_map_)[id] = actor;
02150   return (true);
02151 }
02152 
02154 bool
02155 pcl::visualization::PCLVisualizer::addCube (
02156   const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation,
02157   double width, double height, double depth,
02158   const std::string &id, int viewport)
02159 {
02160   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02161   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02162   if (am_it != shape_actor_map_->end ())
02163   {
02164     pcl::console::print_warn (stderr, "[addCube] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02165     return (false);
02166   }
02167 
02168   vtkSmartPointer<vtkDataSet> data = createCube (translation, rotation, width, height, depth);
02169 
02170   // Create an Actor
02171   vtkSmartPointer<vtkLODActor> actor;
02172   createActorFromVTKDataSet (data, actor);
02173   actor->GetProperty ()->SetRepresentationToWireframe ();
02174   actor->GetProperty ()->SetLighting (false);
02175   addActorToRenderer (actor, viewport);
02176 
02177   // Save the pointer/ID pair to the global actor map
02178   (*shape_actor_map_)[id] = actor;
02179   return (true);
02180 }
02181 
02183 bool
02184 pcl::visualization::PCLVisualizer::addCube (float x_min, float x_max,
02185                                             float y_min, float y_max,
02186                                             float z_min, float z_max,
02187                                             double r, double g, double b,
02188                                             const std::string &id, int viewport)
02189 {
02190   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02191   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02192   if (am_it != shape_actor_map_->end ())
02193   {
02194     pcl::console::print_warn (stderr, "[addCube] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02195     return (false);
02196   }
02197 
02198   vtkSmartPointer<vtkDataSet> data = createCube (x_min, x_max, y_min, y_max, z_min, z_max);
02199 
02200   // Create an Actor
02201   vtkSmartPointer<vtkActor> actor;
02202   createActorFromVTKDataSet (data, actor);
02203   actor->GetProperty ()->SetRepresentationToWireframe ();
02204   actor->GetProperty ()->SetLighting (false);
02205   actor->GetProperty ()->SetColor (r,g,b);
02206   addActorToRenderer (actor, viewport);
02207 
02208   // Save the pointer/ID pair to the global actor map
02209   (*shape_actor_map_)[id] = actor;
02210   return (true);
02211 }
02212 
02214 bool
02215 pcl::visualization::PCLVisualizer::addSphere (const pcl::ModelCoefficients &coefficients,
02216                                              const std::string &id, int viewport)
02217 {
02218   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02219   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02220   if (am_it != shape_actor_map_->end ())
02221   {
02222     pcl::console::print_warn (stderr, "[addSphere] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02223     return (false);
02224   }
02225 
02226   vtkSmartPointer<vtkDataSet> data = createSphere (coefficients);
02227 
02228   // Create an Actor
02229   vtkSmartPointer<vtkLODActor> actor;
02230   createActorFromVTKDataSet (data, actor);
02231   actor->GetProperty ()->SetRepresentationToWireframe ();
02232   actor->GetProperty ()->SetLighting (false);
02233   addActorToRenderer (actor, viewport);
02234 
02235   // Save the pointer/ID pair to the global actor map
02236   (*shape_actor_map_)[id] = actor;
02237   return (true);
02238 }
02239 
02241 bool
02242 pcl::visualization::PCLVisualizer::addModelFromPolyData (
02243     vtkSmartPointer<vtkPolyData> polydata, const std::string & id, int viewport)
02244 {
02245   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02246   if (am_it != shape_actor_map_->end ())
02247   {
02248     pcl::console::print_warn (stderr,
02249                                 "[addModelFromPolyData] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02250                                 id.c_str ());
02251     return (false);
02252   }
02253 
02254   vtkSmartPointer<vtkLODActor> actor;
02255   createActorFromVTKDataSet (polydata, actor);
02256   actor->GetProperty ()->SetRepresentationToWireframe ();
02257   addActorToRenderer (actor, viewport);
02258 
02259   // Save the pointer/ID pair to the global actor map
02260   (*shape_actor_map_)[id] = actor;
02261   return (true);
02262 }
02263 
02265 bool
02266 pcl::visualization::PCLVisualizer::addModelFromPolyData (
02267     vtkSmartPointer<vtkPolyData> polydata, vtkSmartPointer<vtkTransform> transform, const std::string & id, int viewport)
02268 {
02269   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02270   if (am_it != shape_actor_map_->end ())
02271   {
02272     pcl::console::print_warn (stderr,
02273                                 "[addModelFromPolyData] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02274                                 id.c_str ());
02275     return (false);
02276   }
02277 
02278   vtkSmartPointer <vtkTransformFilter> trans_filter = vtkSmartPointer<vtkTransformFilter>::New ();
02279   trans_filter->SetTransform (transform);
02280   trans_filter->SetInput (polydata);
02281   trans_filter->Update();
02282 
02283   // Create an Actor
02284   vtkSmartPointer <vtkLODActor> actor;
02285   createActorFromVTKDataSet (trans_filter->GetOutput (), actor);
02286   actor->GetProperty ()->SetRepresentationToWireframe ();
02287   addActorToRenderer (actor, viewport);
02288 
02289   // Save the pointer/ID pair to the global actor map
02290   (*shape_actor_map_)[id] = actor;
02291   return (true);
02292 }
02293 
02294 
02296 bool
02297 pcl::visualization::PCLVisualizer::addModelFromPLYFile (const std::string &filename,
02298                                                        const std::string &id, int viewport)
02299 {
02300   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02301   if (am_it != shape_actor_map_->end ())
02302   {
02303     pcl::console::print_warn (stderr,
02304                                 "[addModelFromPLYFile] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02305                                 id.c_str ());
02306     return (false);
02307   }
02308 
02309   vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New ();
02310   reader->SetFileName (filename.c_str ());
02311 
02312   // Create an Actor
02313   vtkSmartPointer<vtkLODActor> actor;
02314   createActorFromVTKDataSet (reader->GetOutput (), actor);
02315   actor->GetProperty ()->SetRepresentationToWireframe ();
02316   addActorToRenderer (actor, viewport);
02317 
02318   // Save the pointer/ID pair to the global actor map
02319   (*shape_actor_map_)[id] = actor;
02320   return (true);
02321 }
02322 
02324 bool
02325 pcl::visualization::PCLVisualizer::addModelFromPLYFile (const std::string &filename,
02326                                                        vtkSmartPointer<vtkTransform> transform, const std::string &id,
02327                                                        int viewport)
02328 {
02329   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02330   if (am_it != shape_actor_map_->end ())
02331   {
02332     pcl::console::print_warn (stderr,
02333                                 "[addModelFromPLYFile] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02334                                 id.c_str ());
02335     return (false);
02336   }
02337 
02338   vtkSmartPointer <vtkPLYReader > reader = vtkSmartPointer<vtkPLYReader>::New ();
02339   reader->SetFileName (filename.c_str ());
02340 
02341   //create transformation filter
02342   vtkSmartPointer <vtkTransformFilter> trans_filter = vtkSmartPointer<vtkTransformFilter>::New ();
02343   trans_filter->SetTransform (transform);
02344   trans_filter->SetInputConnection (reader->GetOutputPort ());
02345 
02346   // Create an Actor
02347   vtkSmartPointer <vtkLODActor> actor;
02348   createActorFromVTKDataSet (trans_filter->GetOutput (), actor);
02349   actor->GetProperty ()->SetRepresentationToWireframe ();
02350   addActorToRenderer (actor, viewport);
02351 
02352   // Save the pointer/ID pair to the global actor map
02353   (*shape_actor_map_)[id] = actor;
02354   return (true);
02355 }
02356 
02358 bool
02359 pcl::visualization::PCLVisualizer::addLine (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
02360 {
02361   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02362   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02363   if (am_it != shape_actor_map_->end ())
02364   {
02365     pcl::console::print_warn (stderr, "[addLine] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02366     return (false);
02367   }
02368 
02369   vtkSmartPointer<vtkDataSet> data = createLine (coefficients);
02370 
02371   // Create an Actor
02372   vtkSmartPointer<vtkLODActor> actor;
02373   createActorFromVTKDataSet (data, actor);
02374   actor->GetProperty ()->SetRepresentationToWireframe ();
02375   actor->GetProperty ()->SetLighting (false);
02376   addActorToRenderer (actor, viewport);
02377 
02378   // Save the pointer/ID pair to the global actor map
02379   (*shape_actor_map_)[id] = actor;
02380   return (true);
02381 }
02382 
02384 
02389 bool
02390   pcl::visualization::PCLVisualizer::addPlane (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
02391 {
02392   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02393   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02394   if (am_it != shape_actor_map_->end ())
02395   {
02396     pcl::console::print_warn (stderr, "[addPlane] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02397     return (false);
02398   }
02399 
02400   vtkSmartPointer<vtkDataSet> data = createPlane (coefficients);
02401 
02402   // Create an Actor
02403   vtkSmartPointer<vtkLODActor> actor;
02404   createActorFromVTKDataSet (data, actor);
02405 //  actor->GetProperty ()->SetRepresentationToWireframe ();
02406   actor->GetProperty ()->SetRepresentationToSurface ();
02407   actor->GetProperty ()->SetLighting (false);
02408   addActorToRenderer (actor, viewport);
02409 
02410   // Save the pointer/ID pair to the global actor map
02411   (*shape_actor_map_)[id] = actor;
02412   return (true);
02413 }
02414 
02415 bool
02416   pcl::visualization::PCLVisualizer::addPlane (const pcl::ModelCoefficients &coefficients, double x, double y, double z, const std::string &id, int viewport)
02417 {
02418   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02419   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02420   if (am_it != shape_actor_map_->end ())
02421   {
02422     pcl::console::print_warn (stderr, "[addPlane] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02423     return (false);
02424   }
02425 
02426   vtkSmartPointer<vtkDataSet> data = createPlane (coefficients, x, y, z);
02427 
02428   // Create an Actor
02429   vtkSmartPointer<vtkLODActor> actor;
02430   createActorFromVTKDataSet (data, actor);
02431   actor->GetProperty ()->SetRepresentationToWireframe ();
02432   actor->GetProperty ()->SetLighting (false);
02433   addActorToRenderer (actor, viewport);
02434 
02435   // Save the pointer/ID pair to the global actor map
02436   (*shape_actor_map_)[id] = actor;
02437   return (true);
02438 }
02439 
02441 bool
02442 pcl::visualization::PCLVisualizer::addCircle (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
02443 {
02444   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02445   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02446   if (am_it != shape_actor_map_->end ())
02447   {
02448     pcl::console::print_warn (stderr, "[addCircle] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02449     return (false);
02450   }
02451 
02452   vtkSmartPointer<vtkDataSet> data = create2DCircle (coefficients);
02453 
02454   // Create an Actor
02455   vtkSmartPointer<vtkLODActor> actor;
02456   createActorFromVTKDataSet (data, actor);
02457   actor->GetProperty ()->SetRepresentationToWireframe ();
02458   actor->GetProperty ()->SetLighting (false);
02459   addActorToRenderer (actor, viewport);
02460 
02461   // Save the pointer/ID pair to the global actor map
02462   (*shape_actor_map_)[id] = actor;
02463   return (true);
02464 }
02465 
02467 bool
02468 pcl::visualization::PCLVisualizer::addCone (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
02469 {
02470   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02471   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02472   if (am_it != shape_actor_map_->end ())
02473   {
02474     pcl::console::print_warn (stderr, "[addCone] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
02475     return (false);
02476   }
02477 
02478   vtkSmartPointer<vtkDataSet> data = createCone (coefficients);
02479 
02480   // Create an Actor
02481   vtkSmartPointer<vtkLODActor> actor;
02482   createActorFromVTKDataSet (data, actor);
02483   actor->GetProperty ()->SetRepresentationToWireframe ();
02484   actor->GetProperty ()->SetLighting (false);
02485   addActorToRenderer (actor, viewport);
02486 
02487   // Save the pointer/ID pair to the global actor map
02488   (*shape_actor_map_)[id] = actor;
02489   return (true);
02490 }
02491 
02493 void
02494 pcl::visualization::PCLVisualizer::createViewPort (double xmin, double ymin, double xmax, double ymax, int &viewport)
02495 {
02496   // Create a new renderer
02497   vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New ();
02498   ren->SetViewport (xmin, ymin, xmax, ymax);
02499 
02500   if (rens_->GetNumberOfItems () > 0)
02501     ren->SetActiveCamera (rens_->GetFirstRenderer ()->GetActiveCamera ());
02502   ren->ResetCamera ();
02503 
02504   // Add it to the list of renderers
02505   rens_->AddItem (ren);
02506 
02507   if (rens_->GetNumberOfItems () <= 1)          // If only one renderer
02508     viewport = 0;                               // set viewport to 'all'
02509   else
02510     viewport = rens_->GetNumberOfItems () - 1;
02511 
02512   win_->AddRenderer (ren);
02513   win_->Modified ();
02514 }
02515 
02517 void
02518 pcl::visualization::PCLVisualizer::createViewPortCamera (const int viewport)
02519 {
02520   vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New ();
02521   rens_->InitTraversal ();
02522   vtkRenderer* renderer = NULL;
02523   int i = 0;
02524   while ((renderer = rens_->GetNextItem ()) != NULL)
02525   {
02526     if (viewport == 0)
02527       continue;
02528     else if (viewport == i)
02529     {
02530       renderer->SetActiveCamera (cam);
02531       renderer->ResetCamera ();
02532     }
02533     ++i;
02534   }
02535 }
02536 
02538 bool
02539 pcl::visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, const std::string &id, int viewport)
02540 {
02541   std::string tid;
02542   if (id.empty ())
02543     tid = text;
02544   else
02545     tid = id;
02546 
02547   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02548   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02549   if (am_it != shape_actor_map_->end ())
02550   {
02551     pcl::console::print_warn (stderr, "[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
02552     return (false);
02553   }
02554 
02555   // Create an Actor
02556   vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New ();
02557   actor->SetPosition (xpos, ypos);
02558   actor->SetInput (text.c_str ());
02559 
02560   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02561   tprop->SetFontSize (10);
02562   tprop->SetFontFamilyToArial ();
02563   tprop->SetJustificationToLeft ();
02564   tprop->BoldOn ();
02565   tprop->SetColor (1, 1, 1);
02566   addActorToRenderer (actor, viewport);
02567 
02568   // Save the pointer/ID pair to the global actor map
02569   (*shape_actor_map_)[tid] = actor;
02570   return (true);
02571 }
02572 
02574 bool
02575 pcl::visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, double r, double g, double b, const std::string &id, int viewport)
02576 {
02577   std::string tid;
02578   if (id.empty ())
02579     tid = text;
02580   else
02581     tid = id;
02582 
02583   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02584   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02585   if (am_it != shape_actor_map_->end ())
02586   {
02587     pcl::console::print_warn (stderr, "[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
02588     return (false);
02589   }
02590 
02591   // Create an Actor
02592   vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New ();
02593   actor->SetPosition (xpos, ypos);
02594   actor->SetInput (text.c_str ());
02595 
02596   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02597   tprop->SetFontSize (10);
02598   tprop->SetFontFamilyToArial ();
02599   tprop->SetJustificationToLeft ();
02600   tprop->BoldOn ();
02601   tprop->SetColor (r, g, b);
02602   addActorToRenderer (actor, viewport);
02603 
02604   // Save the pointer/ID pair to the global actor map
02605   (*shape_actor_map_)[tid] = actor;
02606   return (true);
02607 }
02608 
02610 bool
02611 pcl::visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, int fontsize, double r, double g, double b, const std::string &id, int viewport)
02612 {
02613   std::string tid;
02614   if (id.empty ())
02615     tid = text;
02616   else
02617     tid = id;
02618 
02619   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02620   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02621   if (am_it != shape_actor_map_->end ())
02622   {
02623     pcl::console::print_warn (stderr, "[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
02624     return (false);
02625   }
02626 
02627   // Create an Actor
02628   vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New ();
02629   actor->SetPosition (xpos, ypos);
02630   actor->SetInput (text.c_str ());
02631 
02632   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02633   tprop->SetFontSize (fontsize);
02634   tprop->SetFontFamilyToArial ();
02635   tprop->SetJustificationToLeft ();
02636   tprop->BoldOn ();
02637   tprop->SetColor (r, g, b);
02638   addActorToRenderer (actor, viewport);
02639 
02640   // Save the pointer/ID pair to the global actor map
02641   (*shape_actor_map_)[tid] = actor;
02642   return (true);
02643 }
02644 
02646 bool
02647 pcl::visualization::PCLVisualizer::updateText (const std::string &text, int xpos, int ypos, const std::string &id)
02648 {
02649   std::string tid;
02650   if (id.empty ())
02651     tid = text;
02652   else
02653     tid = id;
02654 
02655   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02656   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02657   if (am_it == shape_actor_map_->end ())
02658     return (false);
02659 
02660   // Retrieve the Actor
02661   vtkTextActor* actor = vtkTextActor::SafeDownCast (am_it->second);
02662   actor->SetPosition (xpos, ypos);
02663   actor->SetInput (text.c_str ());
02664 
02665   actor->Modified ();
02666 
02667   return (true);
02668 }
02669 
02671 bool
02672 pcl::visualization::PCLVisualizer::updateText (const std::string &text, int xpos, int ypos, double r, double g, double b, const std::string &id)
02673 {
02674   std::string tid;
02675   if (id.empty ())
02676     tid = text;
02677   else
02678     tid = id;
02679 
02680   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02681   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02682   if (am_it == shape_actor_map_->end ())
02683     return (false);
02684 
02685   // Create the Actor
02686   vtkTextActor* actor = vtkTextActor::SafeDownCast (am_it->second);
02687   actor->SetPosition (xpos, ypos);
02688   actor->SetInput (text.c_str ());
02689 
02690   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02691   tprop->SetColor (r, g, b);
02692   actor->Modified ();
02693 
02694   return (true);
02695 }
02696 
02698 bool
02699 pcl::visualization::PCLVisualizer::updateText (const std::string &text, int xpos, int ypos, int fontsize, double r, double g, double b, const std::string &id)
02700 {
02701   std::string tid;
02702   if (id.empty ())
02703     tid = text;
02704   else
02705     tid = id;
02706 
02707   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02708   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02709   if (am_it == shape_actor_map_->end ())
02710     return (false);
02711 
02712   // Retrieve the Actor
02713   vtkTextActor *actor = vtkTextActor::SafeDownCast (am_it->second);
02714 
02715   actor->SetPosition (xpos, ypos);
02716   actor->SetInput (text.c_str ());
02717 
02718   vtkTextProperty* tprop = actor->GetTextProperty ();
02719   tprop->SetFontSize (fontsize);
02720   tprop->SetColor (r, g, b);
02721 
02722   actor->Modified ();
02723 
02724   return (true);
02725 }
02726 
02728 bool
02729 pcl::visualization::PCLVisualizer::updateColorHandlerIndex (const std::string &id, int index)
02730 {
02731   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
02732   if (am_it == cloud_actor_map_->end ())
02733   {
02734     pcl::console::print_warn (stderr, "[updateColorHandlerIndex] PointCloud with id <%s> doesn't exist!\n", id.c_str ());
02735     return (false);
02736   }
02737 
02738   int color_handler_size = int (am_it->second.color_handlers.size ());
02739   if (index >= color_handler_size)
02740   {
02741     pcl::console::print_warn (stderr, "[updateColorHandlerIndex] Invalid index <%d> given! Maximum range is: 0-%lu.\n", index, static_cast<unsigned long> (am_it->second.color_handlers.size ()));
02742     return (false);
02743   }
02744   // Get the handler
02745   PointCloudColorHandler<pcl::PCLPointCloud2>::ConstPtr color_handler = am_it->second.color_handlers[index];
02746 
02747   vtkSmartPointer<vtkDataArray> scalars;
02748   color_handler->getColor (scalars);
02749   double minmax[2];
02750   scalars->GetRange (minmax);
02751   // Update the data
02752   vtkPolyData *data = static_cast<vtkPolyData*>(am_it->second.actor->GetMapper ()->GetInput ());
02753   data->GetPointData ()->SetScalars (scalars);
02754   data->Update ();
02755   // Modify the mapper
02756   if (use_vbos_)
02757   {
02758     vtkVertexBufferObjectMapper* mapper = static_cast<vtkVertexBufferObjectMapper*>(am_it->second.actor->GetMapper ());
02759     mapper->SetScalarRange (minmax);
02760     mapper->SetScalarModeToUsePointData ();
02761     mapper->SetInput (data);
02762     // Modify the actor
02763     am_it->second.actor->SetMapper (mapper);
02764     am_it->second.actor->Modified ();
02765     am_it->second.color_handler_index_ = index;
02766 
02767     //style_->setCloudActorMap (cloud_actor_map_);
02768   }
02769   else
02770   {
02771     vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ());
02772     mapper->SetScalarRange (minmax);
02773     mapper->SetScalarModeToUsePointData ();
02774     mapper->SetInput (data);
02775     // Modify the actor
02776     am_it->second.actor->SetMapper (mapper);
02777     am_it->second.actor->Modified ();
02778     am_it->second.color_handler_index_ = index;
02779 
02780     //style_->setCloudActorMap (cloud_actor_map_);
02781   }
02782 
02783   return (true);
02784 }
02785 
02786 
02787 
02789 bool
02790 pcl::visualization::PCLVisualizer::addPolygonMesh (const pcl::PolygonMesh &poly_mesh,
02791                                                    const std::string &id,
02792                                                    int viewport)
02793 {
02794   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
02795   if (am_it != cloud_actor_map_->end ())
02796   {
02797     pcl::console::print_warn (stderr,
02798                                 "[addPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02799                                 id.c_str ());
02800     return (false);
02801   }
02802 
02803   // Create points from polyMesh.cloud
02804   vtkSmartPointer<vtkPoints> poly_points = vtkSmartPointer<vtkPoints>::New ();
02805   pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
02806   pcl::fromPCLPointCloud2 (poly_mesh.cloud, *point_cloud);
02807   poly_points->SetNumberOfPoints (point_cloud->points.size ());
02808 
02809   size_t i;
02810   for (i = 0; i < point_cloud->points.size (); ++i)
02811     poly_points->InsertPoint (i, point_cloud->points[i].x, point_cloud->points[i].y, point_cloud->points[i].z);
02812 
02813   bool has_color = false;
02814   vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New ();
02815   if (pcl::getFieldIndex(poly_mesh.cloud, "rgb") != -1)
02816   {
02817     has_color = true;
02818     colors->SetNumberOfComponents (3);
02819     colors->SetName ("Colors");
02820     pcl::PointCloud<pcl::PointXYZRGB> cloud;
02821     pcl::fromPCLPointCloud2(poly_mesh.cloud, cloud);
02822     for (i = 0; i < cloud.points.size (); ++i)
02823     {
02824       const unsigned char color[3] = {cloud.points[i].r, cloud.points[i].g, cloud.points[i].b};
02825       colors->InsertNextTupleValue(color);
02826     }
02827   }
02828   if (pcl::getFieldIndex(poly_mesh.cloud, "rgba") != -1)
02829   {
02830     has_color = true;
02831     colors->SetNumberOfComponents (3);
02832     colors->SetName ("Colors");
02833     pcl::PointCloud<pcl::PointXYZRGBA> cloud;
02834     pcl::fromPCLPointCloud2(poly_mesh.cloud, cloud);
02835     for (i = 0; i < cloud.points.size (); ++i)
02836     {
02837       const unsigned char color[3] = {cloud.points[i].r, cloud.points[i].g, cloud.points[i].b};
02838       colors->InsertNextTupleValue(color);
02839     }
02840   }
02841 
02842   vtkSmartPointer<vtkLODActor> actor;
02843   if (poly_mesh.polygons.size() > 1)
02844   {
02845     //create polys from polyMesh.polygons
02846     vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New ();
02847 
02848     for (i = 0; i < poly_mesh.polygons.size (); i++)
02849     {
02850       size_t n_points (poly_mesh.polygons[i].vertices.size ());
02851       cell_array->InsertNextCell (int (n_points));
02852       for (size_t j = 0; j < n_points; j++)
02853         cell_array->InsertCellPoint (poly_mesh.polygons[i].vertices[j]);
02854     }
02855 
02856     vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
02857 //    polydata->SetStrips (cell_array);
02858     polydata->SetPolys (cell_array);
02859     polydata->SetPoints (poly_points);
02860 
02861     if (has_color)
02862       polydata->GetPointData()->SetScalars(colors);
02863 
02864     createActorFromVTKDataSet (polydata, actor);
02865   }
02866   else if (poly_mesh.polygons.size() == 1)
02867   {
02868     vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New ();
02869     size_t n_points = poly_mesh.polygons[0].vertices.size ();
02870     polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
02871 
02872     for (size_t j=0; j < (n_points - 1); j++)
02873       polygon->GetPointIds ()->SetId (j, poly_mesh.polygons[0].vertices[j]);
02874 
02875     vtkSmartPointer<vtkUnstructuredGrid> poly_grid = vtkSmartPointer<vtkUnstructuredGrid>::New ();
02876     poly_grid->Allocate (1, 1);
02877     poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
02878     poly_grid->SetPoints (poly_points);
02879     poly_grid->Update ();
02880 
02881     createActorFromVTKDataSet (poly_grid, actor);
02882     actor->GetProperty ()->SetRepresentationToWireframe ();
02883   }
02884   else
02885   {
02886     PCL_ERROR("PCLVisualizer::addPolygonMesh: No polygons\n");
02887     return false;
02888   }
02889 
02890   actor->GetProperty ()->SetRepresentationToSurface ();
02891   addActorToRenderer (actor, viewport);
02892 
02893   // Save the pointer/ID pair to the global actor map
02894   (*cloud_actor_map_)[id].actor = actor;
02895 
02896   // Save the viewpoint transformation matrix to the global actor map
02897   vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New ();
02898   convertToVtkMatrix (point_cloud->sensor_origin_, point_cloud->sensor_orientation_, transformation);
02899   (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
02900 
02901   return (true);
02902 }
02903 
02905 bool
02906 pcl::visualization::PCLVisualizer::updatePolygonMesh (
02907     const pcl::PolygonMesh &poly_mesh,
02908     const std::string &id)
02909 {
02910 
02911   if (poly_mesh.polygons.empty())
02912   {
02913     pcl::console::print_error ("[updatePolygonMesh] No vertices given!\n");
02914     return (false);
02915   }
02916 
02917   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02918   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
02919   if (am_it == cloud_actor_map_->end ())
02920     return (false);
02921 
02922   // Create points from polyMesh.cloud
02923   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ());
02924   pcl::fromPCLPointCloud2 (poly_mesh.cloud, *cloud);
02925 
02926   std::vector<pcl::Vertices> verts(poly_mesh.polygons); // copy vector
02927 
02928   // Get the current poly data
02929   vtkSmartPointer<vtkPolyData> polydata = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
02930   if (!polydata)
02931     return (false);
02932   vtkSmartPointer<vtkCellArray> cells = polydata->GetStrips ();
02933   if (!cells)
02934     return (false);
02935   vtkSmartPointer<vtkPoints> points   = polydata->GetPoints ();
02936   // Copy the new point array in
02937   vtkIdType nr_points = cloud->points.size ();
02938   points->SetNumberOfPoints (nr_points);
02939 
02940   // Get a pointer to the beginning of the data array
02941   float *data = static_cast<vtkFloatArray*> (points->GetData ())->GetPointer (0);
02942 
02943   int ptr = 0;
02944   std::vector<int> lookup;
02945   // If the dataset is dense (no NaNs)
02946   if (cloud->is_dense)
02947   {
02948     for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3)
02949       memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3);
02950   }
02951   else
02952   {
02953     lookup.resize (nr_points);
02954     vtkIdType j = 0;    // true point index
02955     for (vtkIdType i = 0; i < nr_points; ++i)
02956     {
02957       // Check if the point is invalid
02958       if (!isFinite (cloud->points[i]))
02959         continue;
02960 
02961       lookup [i] = static_cast<int> (j);
02962       memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3);
02963       j++;
02964       ptr += 3;
02965     }
02966     nr_points = j;
02967     points->SetNumberOfPoints (nr_points);
02968   }
02969 
02970   // Get the maximum size of a polygon
02971   int max_size_of_polygon = -1;
02972   for (size_t i = 0; i < verts.size (); ++i)
02973     if (max_size_of_polygon < static_cast<int> (verts[i].vertices.size ()))
02974       max_size_of_polygon = static_cast<int> (verts[i].vertices.size ());
02975 
02976   // Update the cells
02977   cells = vtkSmartPointer<vtkCellArray>::New ();
02978   vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1));
02979   int idx = 0;
02980   if (lookup.size () > 0)
02981   {
02982     for (size_t i = 0; i < verts.size (); ++i, ++idx)
02983     {
02984       size_t n_points = verts[i].vertices.size ();
02985       *cell++ = n_points;
02986       for (size_t j = 0; j < n_points; j++, cell++, ++idx)
02987         *cell = lookup[verts[i].vertices[j]];
02988     }
02989   }
02990   else
02991   {
02992     for (size_t i = 0; i < verts.size (); ++i, ++idx)
02993     {
02994       size_t n_points = verts[i].vertices.size ();
02995       *cell++ = n_points;
02996       for (size_t j = 0; j < n_points; j++, cell++, ++idx)
02997         *cell = verts[i].vertices[j];
02998     }
02999   }
03000   cells->GetData ()->SetNumberOfValues (idx);
03001   cells->Squeeze ();
03002   // Set the the vertices
03003   polydata->SetStrips (cells);
03004   polydata->Update ();
03005 
03006   return (true);
03007 }
03008 
03009 
03011 bool
03012 pcl::visualization::PCLVisualizer::addPolylineFromPolygonMesh (
03013     const pcl::PolygonMesh &polymesh, const std::string &id, int viewport)
03014 {
03015   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
03016   if (am_it != shape_actor_map_->end ())
03017   {
03018     pcl::console::print_warn (stderr,
03019                                 "[addPolylineFromPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n",
03020                                 id.c_str ());
03021     return (false);
03022   }
03023 
03024   // Create points from polyMesh.cloud
03025   vtkSmartPointer<vtkPoints> poly_points = vtkSmartPointer<vtkPoints>::New ();
03026   pcl::PointCloud<pcl::PointXYZ> point_cloud;
03027   pcl::fromPCLPointCloud2 (polymesh.cloud, point_cloud);
03028   poly_points->SetNumberOfPoints (point_cloud.points.size ());
03029 
03030   size_t i;
03031   for (i = 0; i < point_cloud.points.size (); ++i)
03032     poly_points->InsertPoint (i, point_cloud.points[i].x, point_cloud.points[i].y, point_cloud.points[i].z);
03033 
03034   // Create a cell array to store the lines in and add the lines to it
03035   vtkSmartPointer <vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New ();
03036   vtkSmartPointer <vtkPolyData> polyData;
03037   allocVtkPolyData (polyData);
03038 
03039   for (i = 0; i < polymesh.polygons.size (); i++)
03040   {
03041     vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New();
03042     polyLine->GetPointIds()->SetNumberOfIds(polymesh.polygons[i].vertices.size());
03043     for(unsigned int k = 0; k < polymesh.polygons[i].vertices.size(); k++)
03044     {
03045       polyLine->GetPointIds()->SetId(k,polymesh.polygons[i].vertices[k]);
03046     }
03047 
03048     cells->InsertNextCell (polyLine);
03049   }
03050 
03051   // Add the points to the dataset
03052   polyData->SetPoints (poly_points);
03053 
03054   // Add the lines to the dataset
03055   polyData->SetLines (cells);
03056 
03057   // Setup actor and mapper
03058   vtkSmartPointer < vtkPolyDataMapper > mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
03059   mapper->SetInput (polyData);
03060 
03061   vtkSmartPointer < vtkActor > actor = vtkSmartPointer<vtkActor>::New ();
03062   actor->SetMapper (mapper);
03063 
03064 
03065   addActorToRenderer (actor, viewport);
03066 
03067   // Save the pointer/ID pair to the global actor map
03068   (*shape_actor_map_)[id] = actor;
03069 
03070   return (true);
03071 }
03072 
03074 void
03075 pcl::visualization::PCLVisualizer::setRepresentationToSurfaceForAllActors ()
03076 {
03077   ShapeActorMap::iterator am_it;
03078   rens_->InitTraversal ();
03079   vtkRenderer* renderer = NULL;
03080   while ((renderer = rens_->GetNextItem ()) != NULL)
03081   {
03082     vtkActorCollection * actors = renderer->GetActors ();
03083     actors->InitTraversal ();
03084     vtkActor * actor;
03085     while ((actor = actors->GetNextActor ()) != NULL)
03086     {
03087       actor->GetProperty ()->SetRepresentationToSurface ();
03088     }
03089   }
03090 }
03091 
03093 void
03094 pcl::visualization::PCLVisualizer::setRepresentationToPointsForAllActors ()
03095 {
03096   ShapeActorMap::iterator am_it;
03097   rens_->InitTraversal ();
03098   vtkRenderer* renderer = NULL;
03099   while ((renderer = rens_->GetNextItem ()) != NULL)
03100   {
03101     vtkActorCollection * actors = renderer->GetActors ();
03102     actors->InitTraversal ();
03103     vtkActor * actor;
03104     while ((actor = actors->GetNextActor ()) != NULL)
03105     {
03106       actor->GetProperty ()->SetRepresentationToPoints ();
03107     }
03108   }
03109 }
03110 
03112 void
03113 pcl::visualization::PCLVisualizer::setRepresentationToWireframeForAllActors ()
03114 {
03115   ShapeActorMap::iterator am_it;
03116   rens_->InitTraversal ();
03117   vtkRenderer* renderer = NULL;
03118   while ((renderer = rens_->GetNextItem ()) != NULL)
03119   {
03120     vtkActorCollection * actors = renderer->GetActors ();
03121     actors->InitTraversal ();
03122     vtkActor * actor;
03123     while ((actor = actors->GetNextActor ()) != NULL)
03124     {
03125       actor->GetProperty ()->SetRepresentationToWireframe ();
03126     }
03127   }
03128 }
03129 
03130 
03132 void
03133 pcl::visualization::PCLVisualizer::setShowFPS (bool show_fps)
03134 {
03135   update_fps_->actor->SetVisibility (show_fps);
03136 }
03137 
03138 
03140 void
03141 pcl::visualization::PCLVisualizer::renderViewTesselatedSphere (
03142                                                                int xres,
03143                                                                int yres,
03144                                                                pcl::PointCloud<pcl::PointXYZ>::CloudVectorType &clouds,
03145                                                                std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<
03146                                                                Eigen::Matrix4f> > & poses,
03147                                                                std::vector<float> & enthropies, int tesselation_level,
03148                                                                float view_angle, float radius_sphere, bool use_vertices)
03149 {
03150   if (rens_->GetNumberOfItems () > 1)
03151   {
03152     PCL_WARN ("[renderViewTesselatedSphere] Method works only with one renderer.\n");
03153     return;
03154   }
03155 
03156   rens_->InitTraversal ();
03157   vtkRenderer* renderer_pcl_vis = rens_->GetNextItem ();
03158   vtkActorCollection * actors = renderer_pcl_vis->GetActors ();
03159 
03160   if (actors->GetNumberOfItems () > 1)
03161     PCL_INFO ("[renderViewTesselatedSphere] Method only consider the first actor on the scene, more than one found.\n");
03162 
03163   //get vtk object from the visualizer
03164   actors->InitTraversal ();
03165   vtkActor * actor = actors->GetNextActor ();
03166   vtkSmartPointer<vtkPolyData> polydata;
03167   allocVtkPolyData (polydata);
03168   polydata->CopyStructure (actor->GetMapper ()->GetInput ());
03169 
03170   //center object
03171   double CoM[3];
03172   vtkIdType npts_com = 0, *ptIds_com = NULL;
03173   vtkSmartPointer<vtkCellArray> cells_com = polydata->GetPolys ();
03174 
03175   double center[3], p1_com[3], p2_com[3], p3_com[3], area_com, totalArea_com = 0;
03176   double comx = 0, comy = 0, comz = 0;
03177   for (cells_com->InitTraversal (); cells_com->GetNextCell (npts_com, ptIds_com);)
03178   {
03179     polydata->GetPoint (ptIds_com[0], p1_com);
03180     polydata->GetPoint (ptIds_com[1], p2_com);
03181     polydata->GetPoint (ptIds_com[2], p3_com);
03182     vtkTriangle::TriangleCenter (p1_com, p2_com, p3_com, center);
03183     area_com = vtkTriangle::TriangleArea (p1_com, p2_com, p3_com);
03184     comx += center[0] * area_com;
03185     comy += center[1] * area_com;
03186     comz += center[2] * area_com;
03187     totalArea_com += area_com;
03188   }
03189 
03190   CoM[0] = comx / totalArea_com;
03191   CoM[1] = comy / totalArea_com;
03192   CoM[2] = comz / totalArea_com;
03193 
03194   vtkSmartPointer<vtkTransform> trans_center = vtkSmartPointer<vtkTransform>::New ();
03195   trans_center->Translate (-CoM[0], -CoM[1], -CoM[2]);
03196   vtkSmartPointer<vtkMatrix4x4> matrixCenter = trans_center->GetMatrix ();
03197 
03198   vtkSmartPointer<vtkTransformFilter> trans_filter_center = vtkSmartPointer<vtkTransformFilter>::New ();
03199   trans_filter_center->SetTransform (trans_center);
03200   trans_filter_center->SetInput (polydata);
03201   trans_filter_center->Update ();
03202 
03203   vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
03204   mapper->SetInputConnection (trans_filter_center->GetOutputPort ());
03205   mapper->Update ();
03206 
03207   //scale so it fits in the unit sphere!
03208   double bb[6];
03209   mapper->GetBounds (bb);
03210   double ms = (std::max) ((std::fabs) (bb[0] - bb[1]),
03211                           (std::max) ((std::fabs) (bb[2] - bb[3]), (std::fabs) (bb[4] - bb[5])));
03212   double max_side = radius_sphere / 2.0;
03213   double scale_factor = max_side / ms;
03214 
03215   vtkSmartPointer<vtkTransform> trans_scale = vtkSmartPointer<vtkTransform>::New ();
03216   trans_scale->Scale (scale_factor, scale_factor, scale_factor);
03217   vtkSmartPointer<vtkMatrix4x4> matrixScale = trans_scale->GetMatrix ();
03218 
03219   vtkSmartPointer<vtkTransformFilter> trans_filter_scale = vtkSmartPointer<vtkTransformFilter>::New ();
03220   trans_filter_scale->SetTransform (trans_scale);
03221   trans_filter_scale->SetInputConnection (trans_filter_center->GetOutputPort ());
03222   trans_filter_scale->Update ();
03223 
03224   mapper->SetInputConnection (trans_filter_scale->GetOutputPort ());
03225   mapper->Update ();
03226 
03228   // * Compute area of the mesh
03230   vtkSmartPointer<vtkCellArray> cells = mapper->GetInput ()->GetPolys ();
03231   vtkIdType npts = 0, *ptIds = NULL;
03232 
03233   double p1[3], p2[3], p3[3], area, totalArea = 0;
03234   for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds);)
03235   {
03236     polydata->GetPoint (ptIds[0], p1);
03237     polydata->GetPoint (ptIds[1], p2);
03238     polydata->GetPoint (ptIds[2], p3);
03239     area = vtkTriangle::TriangleArea (p1, p2, p3);
03240     totalArea += area;
03241   }
03242 
03243   //create icosahedron
03244   vtkSmartPointer<vtkPlatonicSolidSource> ico = vtkSmartPointer<vtkPlatonicSolidSource>::New ();
03245   ico->SetSolidTypeToIcosahedron ();
03246   ico->Update ();
03247 
03248   //tesselate cells from icosahedron
03249   vtkSmartPointer<vtkLoopSubdivisionFilter> subdivide = vtkSmartPointer<vtkLoopSubdivisionFilter>::New ();
03250   subdivide->SetNumberOfSubdivisions (tesselation_level);
03251   subdivide->SetInputConnection (ico->GetOutputPort ());
03252 
03253   // Get camera positions
03254   vtkPolyData *sphere = subdivide->GetOutput ();
03255   sphere->Update ();
03256 
03257   std::vector<Eigen::Vector3f> cam_positions;
03258   if (!use_vertices)
03259   {
03260     vtkSmartPointer<vtkCellArray> cells_sphere = sphere->GetPolys ();
03261     cam_positions.resize (sphere->GetNumberOfPolys ());
03262 
03263     size_t i=0;
03264     for (cells_sphere->InitTraversal (); cells_sphere->GetNextCell (npts_com, ptIds_com);)
03265     {
03266       sphere->GetPoint (ptIds_com[0], p1_com);
03267       sphere->GetPoint (ptIds_com[1], p2_com);
03268       sphere->GetPoint (ptIds_com[2], p3_com);
03269       vtkTriangle::TriangleCenter (p1_com, p2_com, p3_com, center);
03270       cam_positions[i] = Eigen::Vector3f (float (center[0]), float (center[1]), float (center[2]));
03271       i++;
03272     }
03273 
03274   }
03275   else
03276   {
03277     cam_positions.resize (sphere->GetNumberOfPoints ());
03278     for (int i = 0; i < sphere->GetNumberOfPoints (); i++)
03279     {
03280       double cam_pos[3];
03281       sphere->GetPoint (i, cam_pos);
03282       cam_positions[i] = Eigen::Vector3f (float (cam_pos[0]), float (cam_pos[1]), float (cam_pos[2]));
03283     }
03284   }
03285 
03286   double camera_radius = radius_sphere;
03287   double cam_pos[3];
03288   double first_cam_pos[3];
03289 
03290   first_cam_pos[0] = cam_positions[0][0] * radius_sphere;
03291   first_cam_pos[1] = cam_positions[0][1] * radius_sphere;
03292   first_cam_pos[2] = cam_positions[0][2] * radius_sphere;
03293 
03294   //create renderer and window
03295   vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New ();
03296   vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New ();
03297   render_win->AddRenderer (renderer);
03298   render_win->SetSize (xres, yres);
03299   renderer->SetBackground (1.0, 0, 0);
03300 
03301   //create picker
03302   vtkSmartPointer<vtkWorldPointPicker> worldPicker = vtkSmartPointer<vtkWorldPointPicker>::New ();
03303 
03304   vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New ();
03305   cam->SetFocalPoint (0, 0, 0);
03306 
03307   Eigen::Vector3f cam_pos_3f = cam_positions[0];
03308   Eigen::Vector3f perp = cam_pos_3f.cross (Eigen::Vector3f::UnitY ());
03309   cam->SetViewUp (perp[0], perp[1], perp[2]);
03310 
03311   cam->SetPosition (first_cam_pos);
03312   cam->SetViewAngle (view_angle);
03313   cam->Modified ();
03314 
03315   //For each camera position, traposesnsform the object and render view
03316   for (size_t i = 0; i < cam_positions.size (); i++)
03317   {
03318     cam_pos[0] = cam_positions[i][0];
03319     cam_pos[1] = cam_positions[i][1];
03320     cam_pos[2] = cam_positions[i][2];
03321 
03322     //create temporal virtual camera
03323     vtkSmartPointer<vtkCamera> cam_tmp = vtkSmartPointer<vtkCamera>::New ();
03324     cam_tmp->SetViewAngle (view_angle);
03325 
03326     Eigen::Vector3f cam_pos_3f (static_cast<float> (cam_pos[0]), static_cast<float> (cam_pos[1]), static_cast<float> (cam_pos[2]));
03327     cam_pos_3f = cam_pos_3f.normalized ();
03328     Eigen::Vector3f test = Eigen::Vector3f::UnitY ();
03329 
03330     //If the view up is parallel to ray cam_pos - focalPoint then the transformation
03331     //is singular and no points are rendered...
03332     //make sure it is perpendicular
03333     if (fabs (cam_pos_3f.dot (test)) == 1)
03334     {
03335       //parallel, create
03336       test = cam_pos_3f.cross (Eigen::Vector3f::UnitX ());
03337     }
03338 
03339     cam_tmp->SetViewUp (test[0], test[1], test[2]);
03340 
03341     for (int k = 0; k < 3; k++)
03342     {
03343       cam_pos[k] = cam_pos[k] * camera_radius;
03344     }
03345 
03346     cam_tmp->SetPosition (cam_pos);
03347     cam_tmp->SetFocalPoint (0, 0, 0);
03348     cam_tmp->Modified ();
03349 
03350     //rotate model so it looks the same as if we would look from the new position
03351     vtkSmartPointer<vtkMatrix4x4> view_trans_inverted = vtkSmartPointer<vtkMatrix4x4>::New ();
03352     vtkMatrix4x4::Invert (cam->GetViewTransformMatrix (), view_trans_inverted);
03353     vtkSmartPointer<vtkTransform> trans_rot_pose = vtkSmartPointer<vtkTransform>::New ();
03354     trans_rot_pose->Identity ();
03355     trans_rot_pose->Concatenate (view_trans_inverted);
03356     trans_rot_pose->Concatenate (cam_tmp->GetViewTransformMatrix ());
03357     vtkSmartPointer<vtkTransformFilter> trans_rot_pose_filter = vtkSmartPointer<vtkTransformFilter>::New ();
03358     trans_rot_pose_filter->SetTransform (trans_rot_pose);
03359     trans_rot_pose_filter->SetInputConnection (trans_filter_scale->GetOutputPort ());
03360 
03361     //translate model so we can place camera at (0,0,0)
03362     vtkSmartPointer<vtkTransform> translation = vtkSmartPointer<vtkTransform>::New ();
03363     translation->Translate (first_cam_pos[0] * -1, first_cam_pos[1] * -1, first_cam_pos[2] * -1);
03364     vtkSmartPointer<vtkTransformFilter> translation_filter = vtkSmartPointer<vtkTransformFilter>::New ();
03365     translation_filter->SetTransform (translation);
03366     translation_filter->SetInputConnection (trans_rot_pose_filter->GetOutputPort ());
03367 
03368     //modify camera
03369     cam_tmp->SetPosition (0, 0, 0);
03370     cam_tmp->SetFocalPoint (first_cam_pos[0] * -1, first_cam_pos[1] * -1, first_cam_pos[2] * -1);
03371     cam_tmp->Modified ();
03372 
03373     //notice transformations for final pose
03374     vtkSmartPointer<vtkMatrix4x4> matrixRotModel = trans_rot_pose->GetMatrix ();
03375     vtkSmartPointer<vtkMatrix4x4> matrixTranslation = translation->GetMatrix ();
03376 
03377     mapper->SetInputConnection (translation_filter->GetOutputPort ());
03378     mapper->Update ();
03379 
03380     //render view
03381     vtkSmartPointer<vtkActor> actor_view = vtkSmartPointer<vtkActor>::New ();
03382     actor_view->SetMapper (mapper);
03383     renderer->SetActiveCamera (cam_tmp);
03384     renderer->AddActor (actor_view);
03385     renderer->Modified ();
03386     //renderer->ResetCameraClippingRange ();
03387     render_win->Render ();
03388 
03389     //back to real scale transform
03390     vtkSmartPointer<vtkTransform> backToRealScale = vtkSmartPointer<vtkTransform>::New ();
03391     backToRealScale->PostMultiply ();
03392     backToRealScale->Identity ();
03393     backToRealScale->Concatenate (matrixScale);
03394     backToRealScale->Concatenate (matrixTranslation);
03395     backToRealScale->Inverse ();
03396     backToRealScale->Modified ();
03397     backToRealScale->Concatenate (matrixTranslation);
03398     backToRealScale->Modified ();
03399 
03400     Eigen::Matrix4f backToRealScale_eigen;
03401     backToRealScale_eigen.setIdentity ();
03402 
03403     for (int x = 0; x < 4; x++)
03404       for (int y = 0; y < 4; y++)
03405         backToRealScale_eigen (x, y) = static_cast<float> (backToRealScale->GetMatrix ()->GetElement (x, y));
03406 
03407     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
03408 
03409     cloud->points.resize (xres * yres);
03410     cloud->width = xres * yres;
03411     cloud->height = 1;
03412 
03413     double coords[3];
03414     float * depth = new float[xres * yres];
03415     render_win->GetZbufferData (0, 0, xres - 1, yres - 1, &(depth[0]));
03416 
03417     int count_valid_depth_pixels = 0;
03418     size_t xresolution (xres);
03419     size_t yresolution (yres);
03420     for (size_t x = 0; x < xresolution; x++)
03421     {
03422       for (size_t y = 0; y < yresolution; y++)
03423       {
03424         float value = depth[y * xres + x];
03425         if (value == 1.0)
03426           continue;
03427 
03428         worldPicker->Pick (static_cast<double> (x), static_cast<double> (y), value, renderer);
03429         worldPicker->GetPickPosition (coords);
03430         cloud->points[count_valid_depth_pixels].x = static_cast<float> (coords[0]);
03431         cloud->points[count_valid_depth_pixels].y = static_cast<float> (coords[1]);
03432         cloud->points[count_valid_depth_pixels].z = static_cast<float> (coords[2]);
03433         cloud->points[count_valid_depth_pixels].getVector4fMap () = backToRealScale_eigen
03434             * cloud->points[count_valid_depth_pixels].getVector4fMap ();
03435         count_valid_depth_pixels++;
03436       }
03437     }
03438 
03439     delete[] depth;
03440 
03442     // * Compute area of the mesh
03444 
03445     vtkSmartPointer<vtkPolyData> polydata = mapper->GetInput ();
03446     polydata->BuildCells ();
03447 
03448     vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();
03449     vtkIdType npts = 0, *ptIds = NULL;
03450 
03451     double p1[3], p2[3], p3[3], area, totalArea = 0;
03452     for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds);)
03453     {
03454       polydata->GetPoint (ptIds[0], p1);
03455       polydata->GetPoint (ptIds[1], p2);
03456       polydata->GetPoint (ptIds[2], p3);
03457       area = vtkTriangle::TriangleArea (p1, p2, p3);
03458       totalArea += area;
03459     }
03460 
03462     // * Select visible cells (triangles)
03464 #if  (VTK_MAJOR_VERSION==5 && VTK_MINOR_VERSION<6)
03465 
03466     vtkSmartPointer<vtkVisibleCellSelector> selector = vtkSmartPointer<vtkVisibleCellSelector>::New ();
03467     vtkSmartPointer<vtkIdTypeArray> selection = vtkSmartPointer<vtkIdTypeArray>::New ();
03468 
03469     selector->SetRenderer (renderer);
03470     selector->SetArea (0, 0, xres - 1, yres - 1);
03471     selector->Select ();
03472     selector->GetSelectedIds (selection);
03473 
03474     double visible_area = 0;
03475     for (int sel_id = 3; sel_id < (selection->GetNumberOfTuples () * selection->GetNumberOfComponents ()); sel_id
03476         += selection->GetNumberOfComponents ())
03477     {
03478       int id_mesh = selection->GetValue (sel_id);
03479 
03480       if (id_mesh >= polydata->GetNumberOfCells ())
03481         continue;
03482 
03483       vtkCell * cell = polydata->GetCell (id_mesh);
03484       vtkTriangle* triangle = dynamic_cast<vtkTriangle*> (cell);
03485       double p0[3];
03486       double p1[3];
03487       double p2[3];
03488       triangle->GetPoints ()->GetPoint (0, p0);
03489       triangle->GetPoints ()->GetPoint (1, p1);
03490       triangle->GetPoints ()->GetPoint (2, p2);
03491       visible_area += vtkTriangle::TriangleArea (p0, p1, p2);
03492     }
03493 
03494 #else
03495     //THIS CAN BE USED WHEN VTK >= 5.4 IS REQUIRED... vtkVisibleCellSelector is deprecated from VTK5.4
03496     vtkSmartPointer<vtkHardwareSelector> hardware_selector = vtkSmartPointer<vtkHardwareSelector>::New ();
03497      hardware_selector->ClearBuffers();
03498      vtkSmartPointer<vtkSelection> hdw_selection = vtkSmartPointer<vtkSelection>::New ();
03499      hardware_selector->SetRenderer (renderer);
03500      hardware_selector->SetArea (0, 0, xres - 1, yres - 1);
03501      hardware_selector->SetFieldAssociation(vtkDataObject::FIELD_ASSOCIATION_CELLS);
03502      hdw_selection = hardware_selector->Select ();
03503      vtkSmartPointer<vtkIdTypeArray> ids = vtkSmartPointer<vtkIdTypeArray>::New ();
03504      ids = vtkIdTypeArray::SafeDownCast(hdw_selection->GetNode(0)->GetSelectionList());
03505      double visible_area = 0;
03506      for (int sel_id = 0; sel_id < (ids->GetNumberOfTuples ()); sel_id++)
03507      {
03508        int id_mesh = static_cast<int> (ids->GetValue (sel_id));
03509        vtkCell * cell = polydata->GetCell (id_mesh);
03510        vtkTriangle* triangle = dynamic_cast<vtkTriangle*> (cell);
03511        double p0[3];
03512        double p1[3];
03513        double p2[3];
03514        triangle->GetPoints ()->GetPoint (0, p0);
03515        triangle->GetPoints ()->GetPoint (1, p1);
03516        triangle->GetPoints ()->GetPoint (2, p2);
03517        area = vtkTriangle::TriangleArea (p0, p1, p2);
03518        visible_area += area;
03519      }
03520 #endif
03521 
03522     enthropies.push_back (static_cast<float> (visible_area / totalArea));
03523 
03524     cloud->points.resize (count_valid_depth_pixels);
03525     cloud->width = count_valid_depth_pixels;
03526 
03527     //transform cloud to give camera coordinates instead of world coordinates!
03528     vtkSmartPointer<vtkMatrix4x4> view_transform = cam_tmp->GetViewTransformMatrix ();
03529     Eigen::Matrix4f trans_view;
03530     trans_view.setIdentity ();
03531 
03532     for (int x = 0; x < 4; x++)
03533       for (int y = 0; y < 4; y++)
03534         trans_view (x, y) = static_cast<float> (view_transform->GetElement (x, y));
03535 
03536     //NOTE: vtk view coordinate system is different than the standard camera coordinates (z forward, y down, x right)
03537     //thus, the fliping in y and z
03538     for (size_t i = 0; i < cloud->points.size (); i++)
03539     {
03540       cloud->points[i].getVector4fMap () = trans_view * cloud->points[i].getVector4fMap ();
03541       cloud->points[i].y *= -1.0f;
03542       cloud->points[i].z *= -1.0f;
03543     }
03544 
03545     renderer->RemoveActor (actor_view);
03546 
03547     clouds.push_back (*cloud);
03548 
03549     //create pose, from OBJECT coordinates to CAMERA coordinates!
03550     vtkSmartPointer<vtkTransform> transOCtoCC = vtkSmartPointer<vtkTransform>::New ();
03551     transOCtoCC->PostMultiply ();
03552     transOCtoCC->Identity ();
03553     transOCtoCC->Concatenate (matrixCenter);
03554     transOCtoCC->Concatenate (matrixRotModel);
03555     transOCtoCC->Concatenate (matrixTranslation);
03556     transOCtoCC->Concatenate (cam_tmp->GetViewTransformMatrix ());
03557 
03558     //NOTE: vtk view coordinate system is different than the standard camera coordinates (z forward, y down, x right)
03559     //thus, the fliping in y and z
03560     vtkSmartPointer<vtkMatrix4x4> cameraSTD = vtkSmartPointer<vtkMatrix4x4>::New ();
03561     cameraSTD->Identity ();
03562     cameraSTD->SetElement (0, 0, 1);
03563     cameraSTD->SetElement (1, 1, -1);
03564     cameraSTD->SetElement (2, 2, -1);
03565 
03566     transOCtoCC->Concatenate (cameraSTD);
03567     transOCtoCC->Modified ();
03568 
03569     Eigen::Matrix4f pose_view;
03570     pose_view.setIdentity ();
03571 
03572     for (int x = 0; x < 4; x++)
03573       for (int y = 0; y < 4; y++)
03574         pose_view (x, y) = static_cast<float> (transOCtoCC->GetMatrix ()->GetElement (x, y));
03575 
03576     poses.push_back (pose_view);
03577 
03578   }
03579 }
03580 
03582 void
03583 pcl::visualization::PCLVisualizer::renderView (int xres, int yres, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud)
03584 {
03585   if (rens_->GetNumberOfItems () > 1)
03586   {
03587     PCL_WARN("[renderView] Method will render only the first viewport\n");
03588     return;
03589   }
03590 
03591   win_->SetSize (xres, yres);
03592   win_->Render ();
03593 
03594   float dwidth = 2.0f / float (xres),
03595         dheight = 2.0f / float (yres);
03596 
03597   cloud->points.resize (xres * yres);
03598   cloud->width = xres;
03599   cloud->height = yres;
03600 
03601   float *depth = new float[xres * yres];
03602   win_->GetZbufferData (0, 0, xres - 1, yres - 1, &(depth[0]));
03603 
03604   // Transform cloud to give camera coordinates instead of world coordinates!
03605   vtkRenderer *ren = rens_->GetFirstRenderer ();
03606   vtkCamera *camera = ren->GetActiveCamera ();
03607   vtkSmartPointer<vtkMatrix4x4> composite_projection_transform = camera->GetCompositeProjectionTransformMatrix (ren->GetTiledAspectRatio (), 0, 1);
03608   vtkSmartPointer<vtkMatrix4x4> view_transform = camera->GetViewTransformMatrix ();
03609 
03610   Eigen::Matrix4f mat1, mat2;
03611   for (int i = 0; i < 4; ++i)
03612     for (int j = 0; j < 4; ++j)
03613     {
03614       mat1 (i, j) = static_cast<float> (composite_projection_transform->Element[i][j]);
03615       mat2 (i, j) = static_cast<float> (view_transform->Element[i][j]);
03616     }
03617 
03618   mat1 = mat1.inverse ();
03619 
03620   int ptr = 0;
03621   for (int y = 0; y < yres; ++y)
03622   {
03623     for (int x = 0; x < xres; ++x, ++ptr)
03624     {
03625       pcl::PointXYZ &pt = (*cloud)[ptr];
03626 
03627       if (depth[ptr] == 1.0)
03628       {
03629         pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN ();
03630         continue;
03631       }
03632 
03633       Eigen::Vector4f world_coords (dwidth  * float (x) - 1.0f,
03634                                     dheight * float (y) - 1.0f,
03635                                     depth[ptr],
03636                                     1.0f);
03637       world_coords = mat1 * world_coords;
03638 
03639       float w3 = 1.0f / world_coords[3];
03640       world_coords[0] *= w3;
03641       // vtk view coordinate system is different than the standard camera coordinates (z forward, y down, x right), thus, the fliping in y and z
03642       world_coords[1] *= -w3;
03643       world_coords[2] *= -w3;
03644 
03645       world_coords = mat2 * world_coords;
03646       pt.x = static_cast<float> (world_coords[0]);
03647       pt.y = static_cast<float> (world_coords[1]);
03648       pt.z = static_cast<float> (world_coords[2]);
03649     }
03650   }
03651 
03652   delete[] depth;
03653 }
03654 
03656 bool
03657 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
03658     const GeometryHandlerConstPtr &geometry_handler,
03659     const ColorHandlerConstPtr &color_handler,
03660     const std::string &id,
03661     int viewport,
03662     const Eigen::Vector4f& sensor_origin,
03663     const Eigen::Quaternion<float>& sensor_orientation)
03664 {
03665   if (!geometry_handler->isCapable ())
03666   {
03667     PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ());
03668     return (false);
03669   }
03670 
03671   if (!color_handler->isCapable ())
03672   {
03673     PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ());
03674     return (false);
03675   }
03676 
03677   vtkSmartPointer<vtkPolyData> polydata;
03678   vtkSmartPointer<vtkIdTypeArray> initcells;
03679   // Convert the PointCloud to VTK PolyData
03680   convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
03681   // use the given geometry handler
03682   polydata->Update ();
03683 
03684   // Get the colors from the handler
03685   bool has_colors = false;
03686   double minmax[2];
03687   vtkSmartPointer<vtkDataArray> scalars;
03688   if (color_handler->getColor (scalars))
03689   {
03690     polydata->GetPointData ()->SetScalars (scalars);
03691     scalars->GetRange (minmax);
03692     has_colors = true;
03693   }
03694 
03695   // Create an Actor
03696   vtkSmartPointer<vtkLODActor> actor;
03697   createActorFromVTKDataSet (polydata, actor);
03698   if (has_colors)
03699     actor->GetMapper ()->SetScalarRange (minmax);
03700 
03701   // Add it to all renderers
03702   addActorToRenderer (actor, viewport);
03703 
03704   // Save the pointer/ID pair to the global actor map
03705   CloudActor& cloud_actor = (*cloud_actor_map_)[id];
03706   cloud_actor.actor = actor;
03707   cloud_actor.cells = reinterpret_cast<vtkPolyDataMapper*>(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData ();
03708   cloud_actor.geometry_handlers.push_back (geometry_handler);
03709   cloud_actor.color_handlers.push_back (color_handler);
03710 
03711   // Save the viewpoint transformation matrix to the global actor map
03712   vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New ();
03713   convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
03714   cloud_actor.viewpoint_transformation_ = transformation;
03715   cloud_actor.actor->SetUserMatrix (transformation);
03716   cloud_actor.actor->Modified ();
03717 
03718   return (true);
03719 }
03720 
03722 void
03723 pcl::visualization::PCLVisualizer::updateCells (vtkSmartPointer<vtkIdTypeArray> &cells,
03724                                                 vtkSmartPointer<vtkIdTypeArray> &initcells,
03725                                                 vtkIdType nr_points)
03726 {
03727   // If no init cells and cells has not been initialized...
03728   if (!cells)
03729     cells = vtkSmartPointer<vtkIdTypeArray>::New ();
03730 
03731   // If we have less values then we need to recreate the array
03732   if (cells->GetNumberOfTuples () < nr_points)
03733   {
03734     cells = vtkSmartPointer<vtkIdTypeArray>::New ();
03735 
03736     // If init cells is given, and there's enough data in it, use it
03737     if (initcells && initcells->GetNumberOfTuples () >= nr_points)
03738     {
03739       cells->DeepCopy (initcells);
03740       cells->SetNumberOfComponents (2);
03741       cells->SetNumberOfTuples (nr_points);
03742     }
03743     else
03744     {
03745       // If the number of tuples is still too small, we need to recreate the array
03746       cells->SetNumberOfComponents (2);
03747       cells->SetNumberOfTuples (nr_points);
03748       vtkIdType *cell = cells->GetPointer (0);
03749       // Fill it with 1s
03750       std::fill_n (cell, nr_points * 2, 1);
03751       cell++;
03752       for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
03753         *cell = i;
03754       // Save the results in initcells
03755       initcells = vtkSmartPointer<vtkIdTypeArray>::New ();
03756       initcells->DeepCopy (cells);
03757     }
03758   }
03759   else
03760   {
03761     // The assumption here is that the current set of cells has more data than needed
03762     cells->SetNumberOfComponents (2);
03763     cells->SetNumberOfTuples (nr_points);
03764   }
03765 }
03766 
03768 void
03769 pcl::visualization::PCLVisualizer::allocVtkPolyData (vtkSmartPointer<vtkAppendPolyData> &polydata)
03770 {
03771   polydata = vtkSmartPointer<vtkAppendPolyData>::New ();
03772 }
03774 void
03775 pcl::visualization::PCLVisualizer::allocVtkPolyData (vtkSmartPointer<vtkPolyData> &polydata)
03776 {
03777   polydata = vtkSmartPointer<vtkPolyData>::New ();
03778 }
03780 void
03781 pcl::visualization::PCLVisualizer::allocVtkUnstructuredGrid (vtkSmartPointer<vtkUnstructuredGrid> &polydata)
03782 {
03783   polydata = vtkSmartPointer<vtkUnstructuredGrid>::New ();
03784 }
03785 
03787 void
03788 pcl::visualization::PCLVisualizer::getTransformationMatrix (
03789     const Eigen::Vector4f &origin,
03790     const Eigen::Quaternion<float> &orientation,
03791     Eigen::Matrix4f &transformation)
03792 {
03793   transformation.setIdentity ();
03794   transformation.block<3,3>(0,0) = orientation.toRotationMatrix ();
03795   transformation.block<3,1>(0,3) = origin.head (3);
03796 }
03797 
03799 void
03800 pcl::visualization::PCLVisualizer::convertToVtkMatrix (
03801     const Eigen::Vector4f &origin,
03802     const Eigen::Quaternion<float> &orientation,
03803     vtkSmartPointer<vtkMatrix4x4> &vtk_matrix)
03804 {
03805   // set rotation
03806   Eigen::Matrix3f rot = orientation.toRotationMatrix ();
03807   for (int i = 0; i < 3; i++)
03808     for (int k = 0; k < 3; k++)
03809       vtk_matrix->SetElement (i, k, rot (i, k));
03810 
03811   // set translation
03812   vtk_matrix->SetElement (0, 3, origin (0));
03813   vtk_matrix->SetElement (1, 3, origin (1));
03814   vtk_matrix->SetElement (2, 3, origin (2));
03815   vtk_matrix->SetElement (3, 3, 1.0f);
03816 }
03817 
03819 void
03820 pcl::visualization::PCLVisualizer::convertToVtkMatrix (
03821     const Eigen::Matrix4f &m,
03822     vtkSmartPointer<vtkMatrix4x4> &vtk_matrix)
03823 {
03824   for (int i = 0; i < 4; i++)
03825     for (int k = 0; k < 4; k++)
03826       vtk_matrix->SetElement (i, k, m (i, k));
03827 }
03828 
03830 void
03831 pcl::visualization::PCLVisualizer::convertToEigenMatrix (
03832     const vtkSmartPointer<vtkMatrix4x4> &vtk_matrix,
03833     Eigen::Matrix4f &m)
03834 {
03835   for (int i = 0; i < 4; i++)
03836     for (int k = 0; k < 4; k++)
03837       m (i,k) = static_cast<float> (vtk_matrix->GetElement (i, k));
03838 }
03839 
03841 bool
03842 pcl::visualization::PCLVisualizer::addPointCloud (
03843     const pcl::PCLPointCloud2::ConstPtr &,
03844     const GeometryHandlerConstPtr &geometry_handler,
03845     const ColorHandlerConstPtr &color_handler,
03846     const Eigen::Vector4f& sensor_origin,
03847     const Eigen::Quaternion<float>& sensor_orientation,
03848     const std::string &id, int viewport)
03849 {
03850   // Check to see if this entry already exists (has it been already added to the visualizer?)
03851   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
03852   if (am_it != cloud_actor_map_->end ())
03853   {
03854     // Here we're just pushing the handlers onto the queue. If needed, something fancier could
03855     // be done such as checking if a specific handler already exists, etc.
03856     am_it->second.geometry_handlers.push_back (geometry_handler);
03857     am_it->second.color_handlers.push_back (color_handler);
03858     return (true);
03859   }
03860   return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, sensor_origin, sensor_orientation));
03861 }
03862 
03864 bool
03865 pcl::visualization::PCLVisualizer::addPointCloud (
03866     const pcl::PCLPointCloud2::ConstPtr &cloud,
03867     const GeometryHandlerConstPtr &geometry_handler,
03868     const Eigen::Vector4f& sensor_origin,
03869     const Eigen::Quaternion<float>& sensor_orientation,
03870     const std::string &id, int viewport)
03871 {
03872   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
03873   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
03874 
03875   if (am_it != cloud_actor_map_->end ())
03876   {
03877     // Here we're just pushing the handlers onto the queue. If needed, something fancier could
03878     // be done such as checking if a specific handler already exists, etc.
03879     am_it->second.geometry_handlers.push_back (geometry_handler);
03880     return (true);
03881   }
03882 
03883   PointCloudColorHandlerCustom<pcl::PCLPointCloud2>::Ptr color_handler (new PointCloudColorHandlerCustom<pcl::PCLPointCloud2> (cloud, 255, 255, 255));
03884   return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, sensor_origin, sensor_orientation));
03885 }
03886 
03888 bool
03889 pcl::visualization::PCLVisualizer::addPointCloud (
03890     const pcl::PCLPointCloud2::ConstPtr &cloud,
03891     const ColorHandlerConstPtr &color_handler,
03892     const Eigen::Vector4f& sensor_origin,
03893     const Eigen::Quaternion<float>& sensor_orientation,
03894     const std::string &id, int viewport)
03895 {
03896   // Check to see if this entry already exists (has it been already added to the visualizer?)
03897   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
03898   if (am_it != cloud_actor_map_->end ())
03899   {
03900     // Here we're just pushing the handlers onto the queue. If needed, something fancier could
03901     // be done such as checking if a specific handler already exists, etc.
03902     am_it->second.color_handlers.push_back (color_handler);
03903     return (true);
03904   }
03905 
03906   PointCloudGeometryHandlerXYZ<pcl::PCLPointCloud2>::Ptr geometry_handler (new PointCloudGeometryHandlerXYZ<pcl::PCLPointCloud2> (cloud));
03907   return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, sensor_origin, sensor_orientation));
03908 }
03909 
03911 void
03912 pcl::visualization::PCLVisualizer::setFullScreen (bool mode)
03913 {
03914   if (win_)
03915     win_->SetFullScreen (mode);
03916 }
03917 
03919 void
03920 pcl::visualization::PCLVisualizer::setWindowName (const std::string &name)
03921 {
03922   if (win_)
03923     win_->SetWindowName (name.c_str ());
03924 }
03925 
03927 void
03928 pcl::visualization::PCLVisualizer::setWindowBorders (bool mode)
03929 {
03930   if (win_)
03931     win_->SetBorders (mode);
03932 }
03933    
03935 void
03936 pcl::visualization::PCLVisualizer::setPosition (int x, int y)
03937 {
03938   if (win_)
03939     win_->SetPosition (x, y);
03940 }
03941  
03943 void
03944 pcl::visualization::PCLVisualizer::setSize (int xw, int yw)
03945 {
03946   if (win_)
03947     win_->SetSize (xw, yw);
03948 }
03949 
03951 void
03952 pcl::visualization::PCLVisualizer::close ()
03953 {
03954 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
03955   interactor_->stopped = true;
03956   // This tends to close the window...
03957   interactor_->stopLoop ();
03958 #else
03959   stopped_ = true;
03960   // This tends to close the window...
03961   win_->Finalize ();
03962   interactor_->TerminateApp ();
03963 #endif
03964 }
03965 
03967 void
03968 pcl::visualization::PCLVisualizer::removeCorrespondences (
03969     const std::string &id, int viewport)
03970 { 
03971   removeShape (id, viewport);
03972 }
03973 
03975 int
03976 pcl::visualization::PCLVisualizer::getColorHandlerIndex (const std::string &id)
03977 {
03978   CloudActorMap::iterator am_it = style_->getCloudActorMap ()->find (id);
03979   if (am_it == cloud_actor_map_->end ())
03980     return (-1);
03981 
03982   return (am_it->second.color_handler_index_);
03983 }
03984 
03986 int
03987 pcl::visualization::PCLVisualizer::getGeometryHandlerIndex (const std::string &id)
03988 {
03989   CloudActorMap::iterator am_it = style_->getCloudActorMap ()->find (id);
03990   if (am_it != cloud_actor_map_->end ())
03991     return (-1);
03992 
03993   return (am_it->second.geometry_handler_index_);
03994 }
03995 
03997 bool
03998 pcl::visualization::PCLVisualizer::wasStopped () const
03999 {
04000   if (interactor_ != NULL) 
04001 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
04002     return (interactor_->stopped);
04003 #else
04004     return (stopped_); 
04005 #endif
04006   else 
04007     return (true);
04008 }
04009 
04011 void
04012 pcl::visualization::PCLVisualizer::resetStoppedFlag ()
04013 {
04014   if (interactor_ != NULL) 
04015 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
04016     interactor_->stopped = false;
04017 #else
04018     stopped_ = false; 
04019 #endif
04020 }
04021 
04023 void
04024 pcl::visualization::PCLVisualizer::setUseVbos (bool use_vbos)
04025 {
04026   use_vbos_ = use_vbos;
04027   style_->setUseVbos (use_vbos_);
04028 }
04029 
04031 void
04032 pcl::visualization::PCLVisualizer::ExitMainLoopTimerCallback::Execute (
04033     vtkObject*, unsigned long event_id, void* call_data)
04034 {
04035   if (event_id != vtkCommand::TimerEvent)
04036     return;
04037   int timer_id = * static_cast<int*> (call_data);
04038   //PCL_WARN ("[pcl::visualization::PCLVisualizer::ExitMainLoopTimerCallback] Timer %d called.\n", timer_id);
04039   if (timer_id != right_timer_id)
04040     return;
04041   // Stop vtk loop and send notification to app to wake it up
04042 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
04043   pcl_visualizer->interactor_->stopLoop ();
04044 #else
04045   pcl_visualizer->interactor_->TerminateApp ();
04046 #endif
04047 }
04048   
04050 void
04051 pcl::visualization::PCLVisualizer::ExitCallback::Execute (
04052     vtkObject*, unsigned long event_id, void*)
04053 {
04054   if (event_id != vtkCommand::ExitEvent)
04055     return;
04056 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
04057   pcl_visualizer->interactor_->stopped = true;
04058   // This tends to close the window...
04059   pcl_visualizer->interactor_->stopLoop ();
04060 #else
04061   pcl_visualizer->stopped_ = true;
04062   // This tends to close the window...
04063   pcl_visualizer->interactor_->TerminateApp ();
04064 #endif
04065 }
04066 
04070 void
04071 pcl::visualization::PCLVisualizer::FPSCallback::Execute (
04072     vtkObject* caller, unsigned long, void*)
04073 {
04074   vtkRenderer *ren = reinterpret_cast<vtkRenderer *> (caller);
04075   float fps = 1.0f / static_cast<float> (ren->GetLastRenderTimeInSeconds ());
04076   char buf[128];
04077   sprintf (buf, "%.1f FPS", fps);
04078   actor->SetInput (buf);
04079 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:28:13