pcl_visualizer.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: pcl_visualizer.cpp 6014 2012-06-25 21:00:39Z rusu $
00035  *
00036  */
00037 
00038 #include <pcl/visualization/common/common.h>
00039 #include <pcl/ros/conversions.h>
00040 #include <pcl/visualization/pcl_visualizer.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 <vtkVisibleCellSelector.h>
00051 #include <vtkSelection.h>
00052 #include <vtkPointPicker.h>
00053 
00055 pcl::visualization::PCLVisualizer::PCLVisualizer (const std::string &name, const bool create_interactor) :
00056     rens_ (vtkSmartPointer<vtkRendererCollection>::New ()),
00057     style_ (vtkSmartPointer<pcl::visualization::PCLVisualizerInteractorStyle>::New ()),
00058     cloud_actor_map_ (new CloudActorMap),
00059     shape_actor_map_ (new ShapeActorMap)
00060 {
00061   // FPS callback
00062   vtkSmartPointer<vtkTextActor> txt = vtkSmartPointer<vtkTextActor>::New ();
00063   vtkSmartPointer<FPSCallback> update_fps = vtkSmartPointer<FPSCallback>::New ();
00064   update_fps->setTextActor (txt);
00065 
00066   // Create a Renderer
00067   vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New ();
00068   ren->AddObserver (vtkCommand::EndEvent, update_fps);
00069   ren->AddActor (txt);
00070   // Add it to the list of renderers
00071   rens_->AddItem (ren);
00072 
00073   // Create a RendererWindow
00074   win_ = vtkSmartPointer<vtkRenderWindow>::New ();
00075   win_->SetWindowName (name.c_str ());
00076 
00077   // Get screen size
00078   int *scr_size = win_->GetScreenSize ();
00079   // Set the window size as 1/2 of the screen size
00080   win_->SetSize (scr_size[0] / 2, scr_size[1] / 2);
00081 
00082   // Add all renderers to the window
00083   rens_->InitTraversal ();
00084   vtkRenderer* renderer = NULL;
00085   while ((renderer = rens_->GetNextItem ()) != NULL)
00086     win_->AddRenderer (renderer);
00087 
00088   // Create the interactor style
00089   style_->Initialize ();
00090   style_->setRendererCollection (rens_);
00091   style_->setCloudActorMap (cloud_actor_map_);
00092   style_->UseTimersOn ();
00093 
00094   if (create_interactor)
00095     createInteractor ();
00096 
00097   win_->SetWindowName (name.c_str ());
00098 }
00099 
00101 pcl::visualization::PCLVisualizer::PCLVisualizer (int &argc, char **argv, const std::string &name, PCLVisualizerInteractorStyle* style, const bool create_interactor) :
00102     rens_ (vtkSmartPointer<vtkRendererCollection>::New ()),
00103     cloud_actor_map_ (new CloudActorMap),
00104     shape_actor_map_ (new ShapeActorMap)
00105 {
00106   style_ = style;
00107 
00108   // FPS callback
00109   vtkSmartPointer<vtkTextActor> txt = vtkSmartPointer<vtkTextActor>::New ();
00110   vtkSmartPointer<FPSCallback> update_fps = vtkSmartPointer<FPSCallback>::New ();
00111   update_fps->setTextActor (txt);
00112 
00113   // Create a Renderer
00114   vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New ();
00115   ren->AddObserver (vtkCommand::EndEvent, update_fps);
00116   ren->AddActor (txt);
00117   // Add it to the list of renderers
00118   rens_->AddItem (ren);
00119 
00120   // Create a RendererWindow
00121   win_ = vtkSmartPointer<vtkRenderWindow>::New ();
00122   win_->SetWindowName (name.c_str ());
00123 
00124   // Get screen size
00125   int *scr_size = win_->GetScreenSize ();
00126   camera_.window_size[0] = scr_size[0]; camera_.window_size[1] = scr_size[1] / 2;
00127   camera_.window_pos[0] = camera_.window_pos[1] = 0;
00128 
00129   // Set default camera parameters
00130   initCameraParameters ();
00131 
00132   // Parse the camera settings and update the internal camera
00133   camera_set_ = getCameraParameters (argc, argv);
00134   updateCamera ();
00135   // Set the window size as 1/2 of the screen size or the user given parameter
00136   win_->SetSize (camera_.window_size[0], camera_.window_size[1]);
00137   win_->SetPosition (camera_.window_pos[0], camera_.window_pos[1]);
00138 
00139   // Add all renderers to the window
00140   rens_->InitTraversal ();
00141   vtkRenderer* renderer = NULL;
00142   while ((renderer = rens_->GetNextItem ()) != NULL)
00143     win_->AddRenderer (renderer);
00144 
00145   // Create the interactor style
00146   style_->Initialize ();
00147   style_->setRendererCollection (rens_);
00148   style_->setCloudActorMap (cloud_actor_map_);
00149   style_->UseTimersOn ();
00150 
00151   if (create_interactor)
00152     createInteractor ();
00153 
00154   win_->SetWindowName (name.c_str ());
00155 }
00156 
00158 void
00159 pcl::visualization::PCLVisualizer::createInteractor ()
00160 {
00161 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00162   interactor_ = vtkSmartPointer<PCLVisualizerInteractor>::New ();
00163 #else
00164   interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New ();
00165 #endif
00166 
00167   //win_->PointSmoothingOn ();
00168   //win_->LineSmoothingOn ();
00169   //win_->PolygonSmoothingOn ();
00170   win_->AlphaBitPlanesOff ();
00171   win_->PointSmoothingOff ();
00172   win_->LineSmoothingOff ();
00173   win_->PolygonSmoothingOff ();
00174   win_->SwapBuffersOn ();
00175   win_->SetStereoTypeToAnaglyph ();
00176 
00177   interactor_->SetRenderWindow (win_);
00178   interactor_->SetInteractorStyle (style_);
00179   //interactor_->SetStillUpdateRate (30.0);
00180   interactor_->SetDesiredUpdateRate (30.0);
00181 
00182   // Initialize and create timer, also create window
00183   interactor_->Initialize ();
00184 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00185   interactor_->timer_id_ = interactor_->CreateRepeatingTimer (5000L);
00186 #else
00187   timer_id_ = interactor_->CreateRepeatingTimer (5000L);
00188 #endif
00189   // Set a simple PointPicker
00190   vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New ();
00191   pp->SetTolerance (pp->GetTolerance () * 2);
00192   interactor_->SetPicker (pp);
00193 
00194   exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
00195   exit_main_loop_timer_callback_->pcl_visualizer = this;
00196   exit_main_loop_timer_callback_->right_timer_id = -1;
00197   interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
00198 
00199   exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
00200   exit_callback_->pcl_visualizer = this;
00201   interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_);
00202 
00203   resetStoppedFlag ();
00204 }
00205 
00207 void
00208 pcl::visualization::PCLVisualizer::setupInteractor (
00209   vtkRenderWindowInteractor *iren,
00210   vtkRenderWindow *win)
00211 {
00212   win->AlphaBitPlanesOff ();
00213   win->PointSmoothingOff ();
00214   win->LineSmoothingOff ();
00215   win->PolygonSmoothingOff ();
00216   win->SwapBuffersOn ();
00217   win->SetStereoTypeToAnaglyph ();
00218 
00219   iren->SetRenderWindow (win);
00220   iren->SetInteractorStyle (style_);
00221   //iren->SetStillUpdateRate (30.0);
00222   iren->SetDesiredUpdateRate (30.0);
00223 
00224   // Initialize and create timer, also create window
00225   iren->Initialize ();
00226 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00227 #else
00228   timer_id_ = iren->CreateRepeatingTimer (5000L);
00229 #endif
00230 
00231   // Set a simple PointPicker
00232   vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New ();
00233   pp->SetTolerance (pp->GetTolerance () * 2);
00234   iren->SetPicker (pp);
00235 
00236   exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New ();
00237   exit_main_loop_timer_callback_->pcl_visualizer = this;
00238   exit_main_loop_timer_callback_->right_timer_id = -1;
00239   iren->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
00240 
00241   exit_callback_ = vtkSmartPointer<ExitCallback>::New ();
00242   exit_callback_->pcl_visualizer = this;
00243   iren->AddObserver (vtkCommand::ExitEvent, exit_callback_);
00244 
00245   resetStoppedFlag ();
00246 }
00247 
00249 pcl::visualization::PCLVisualizer::~PCLVisualizer ()
00250 {
00251   if (interactor_ != NULL)
00252 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00253     interactor_->DestroyTimer (interactor_->timer_id_);
00254 #else
00255     interactor_->DestroyTimer (timer_id_);
00256 #endif
00257   // Clear the collections
00258   rens_->RemoveAllItems ();
00259 }
00260 
00262 void
00263 pcl::visualization::PCLVisualizer::saveScreenshot (const std::string &file)
00264 {
00265   style_->saveScreenshot (file);
00266 }
00267 
00269 boost::signals2::connection
00270 pcl::visualization::PCLVisualizer::registerKeyboardCallback (boost::function<void (const pcl::visualization::KeyboardEvent&)> callback)
00271 {
00272   return (style_->registerKeyboardCallback (callback));
00273 }
00274 
00276 boost::signals2::connection
00277 pcl::visualization::PCLVisualizer::registerMouseCallback (boost::function<void (const pcl::visualization::MouseEvent&)> callback)
00278 {
00279   return (style_->registerMouseCallback (callback));
00280 }
00281 
00283 boost::signals2::connection
00284 pcl::visualization::PCLVisualizer::registerPointPickingCallback (boost::function<void (const pcl::visualization::PointPickingEvent&)> callback)
00285 {
00286   return (style_->registerPointPickingCallback (callback));
00287 }
00288 
00290 void
00291 pcl::visualization::PCLVisualizer::spin ()
00292 {
00293   resetStoppedFlag ();
00294   // Render the window before we start the interactor
00295   win_->Render ();
00296     interactor_->Start ();
00297 }
00298 
00300 void
00301 pcl::visualization::PCLVisualizer::spinOnce (int time, bool force_redraw)
00302 {
00303   resetStoppedFlag ();
00304 
00305   if (time <= 0)
00306     time = 1;
00307 
00308   if (force_redraw)
00309     interactor_->Render ();
00310 
00311   DO_EVERY (1.0 / interactor_->GetDesiredUpdateRate (),
00312     exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer (time);
00313     interactor_->Start ();
00314     interactor_->DestroyTimer (exit_main_loop_timer_callback_->right_timer_id);
00315   );
00316 }
00317 
00319 void
00320 pcl::visualization::PCLVisualizer::addCoordinateSystem (double scale, int viewport)
00321 {
00322   vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New ();
00323   axes->SetOrigin (0, 0, 0);
00324   axes->SetScaleFactor (scale);
00325 
00326   vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New ();
00327   axes_colors->Allocate (6);
00328   axes_colors->InsertNextValue (0.0);
00329   axes_colors->InsertNextValue (0.0);
00330   axes_colors->InsertNextValue (0.5);
00331   axes_colors->InsertNextValue (0.5);
00332   axes_colors->InsertNextValue (1.0);
00333   axes_colors->InsertNextValue (1.0);
00334 
00335   vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput ();
00336   axes_data->Update ();
00337   axes_data->GetPointData ()->SetScalars (axes_colors);
00338 
00339   vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New ();
00340   axes_tubes->SetInput (axes_data);
00341   axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0);
00342   axes_tubes->SetNumberOfSides (6);
00343 
00344   vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00345   axes_mapper->SetScalarModeToUsePointData ();
00346   axes_mapper->SetInput (axes_tubes->GetOutput ());
00347 
00348   vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New ();
00349   axes_actor->SetMapper (axes_mapper);
00350 
00351   // Save the ID and actor pair to the global actor map
00352   coordinate_actor_map_[viewport] = axes_actor;
00353 
00354   addActorToRenderer (axes_actor, viewport);
00355 }
00356 
00358 void
00359 pcl::visualization::PCLVisualizer::addCoordinateSystem (double scale, float x, float y, float z, int viewport)
00360 {
00361   vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New ();
00362   axes->SetOrigin (0, 0, 0);
00363   axes->SetScaleFactor (scale);
00364 
00365   vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New ();
00366   axes_colors->Allocate (6);
00367   axes_colors->InsertNextValue (0.0);
00368   axes_colors->InsertNextValue (0.0);
00369   axes_colors->InsertNextValue (0.5);
00370   axes_colors->InsertNextValue (0.5);
00371   axes_colors->InsertNextValue (1.0);
00372   axes_colors->InsertNextValue (1.0);
00373 
00374   vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput ();
00375   axes_data->Update ();
00376   axes_data->GetPointData ()->SetScalars (axes_colors);
00377 
00378   vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New ();
00379   axes_tubes->SetInput (axes_data);
00380   axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0);
00381   axes_tubes->SetNumberOfSides (6);
00382 
00383   vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00384   axes_mapper->SetScalarModeToUsePointData ();
00385   axes_mapper->SetInput (axes_tubes->GetOutput ());
00386 
00387   vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New ();
00388   axes_actor->SetMapper (axes_mapper);
00389   axes_actor->SetPosition (x, y, z);
00390 
00391   // Save the ID and actor pair to the global actor map
00392   coordinate_actor_map_[viewport] = axes_actor;
00393 
00394   addActorToRenderer (axes_actor, viewport);
00395 }
00396 
00398 void
00399 pcl::visualization::PCLVisualizer::addCoordinateSystem (double scale, const Eigen::Affine3f& t, int viewport)
00400 {
00401   vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New ();
00402   axes->SetOrigin (0, 0, 0);
00403   axes->SetScaleFactor (scale);
00404 
00405   vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New ();
00406   axes_colors->Allocate (6);
00407   axes_colors->InsertNextValue (0.0);
00408   axes_colors->InsertNextValue (0.0);
00409   axes_colors->InsertNextValue (0.5);
00410   axes_colors->InsertNextValue (0.5);
00411   axes_colors->InsertNextValue (1.0);
00412   axes_colors->InsertNextValue (1.0);
00413 
00414   vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput ();
00415   axes_data->Update ();
00416   axes_data->GetPointData ()->SetScalars (axes_colors);
00417 
00418   vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New ();
00419   axes_tubes->SetInput (axes_data);
00420   axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0);
00421   axes_tubes->SetNumberOfSides (6);
00422 
00423   vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
00424   axes_mapper->SetScalarModeToUsePointData ();
00425   axes_mapper->SetInput (axes_tubes->GetOutput ());
00426 
00427   vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New ();
00428   axes_actor->SetMapper (axes_mapper);
00429 
00430   // All Input values are radian.
00431   // To avoid singularity when inversion from Rotation matrix to angles.
00432   double pitch,yaw,roll;
00433   // pitch = 90 degree
00434   if (t(1,0) > 0.998)
00435   { // singularity at north pole
00436     pitch = atan2 (t (0, 2), t (2, 2));
00437     yaw = M_PI/2.0;
00438     roll = 0;
00439   }
00440   else
00441   {
00442     pitch = atan2(-t(2,0),t(0,0));
00443     roll = atan2(-t(1,2),t(1,1));
00444     yaw = asin(t(1,0));
00445   }
00446 
00447   // pitch = -90 degree
00448   if (t (1, 0) < -0.998)
00449   { // singularity at south pole
00450     pitch = atan2(t(0,2),t(2,2));
00451     yaw = -M_PI/2.0;
00452     roll = 0;
00453   }
00454   else
00455   {
00456     pitch = atan2(-t(2,0),t(0,0));
00457     roll = atan2(-t(1,2),t(1,1));
00458     yaw = asin(t(1,0));
00459   }
00460 
00461   // Convert from radian to degree.
00462   pitch = pitch * 180.0 / (double)M_PI;
00463   roll  = roll  * 180.0 / (double)M_PI;
00464   yaw   = yaw   * 180.0 / (double)M_PI;
00465 
00466   axes_actor->SetPosition (t (0, 3), t(1, 3), t(2, 3));
00467   axes_actor->SetOrientation (roll, pitch, yaw);
00468 
00469   // Save the ID and actor pair to the global actor map
00470   coordinate_actor_map_[viewport] = axes_actor;
00471   addActorToRenderer (axes_actor, viewport);
00472 }
00473 
00475 bool
00476 pcl::visualization::PCLVisualizer::removeCoordinateSystem (int viewport)
00477 {
00478   // Check to see if the given ID entry exists
00479   CoordinateActorMap::iterator am_it = coordinate_actor_map_.find (viewport);
00480 
00481   if (am_it == coordinate_actor_map_.end ())
00482     return (false);
00483 
00484   // Remove it from all renderers
00485   if (removeActorFromRenderer (am_it->second, viewport))
00486   {
00487     // Remove the ID pair to the global actor map
00488     coordinate_actor_map_.erase (am_it);
00489     return (true);
00490   }
00491   return (false);
00492 }
00493 
00495 bool
00496 pcl::visualization::PCLVisualizer::removePointCloud (const std::string &id, int viewport)
00497 {
00498   // Check to see if the given ID entry exists
00499   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00500 
00501   if (am_it == cloud_actor_map_->end ())
00502     return (false);
00503 
00504   // Remove it from all renderers
00505   if (removeActorFromRenderer (am_it->second.actor, viewport))
00506   {
00507     // Remove the pointer/ID pair to the global actor map
00508     cloud_actor_map_->erase (am_it);
00509     return (true);
00510   }
00511   return (false);
00512 }
00513 
00515 bool
00516 pcl::visualization::PCLVisualizer::removeShape (const std::string &id, int viewport)
00517 {
00518   // Check to see if the given ID entry exists
00519   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
00520   // Extra step: check if there is a cloud with the same ID
00521   CloudActorMap::iterator ca_it = cloud_actor_map_->find (id);
00522 
00523   bool shape = true;
00524   // Try to find a shape first
00525   if (am_it == shape_actor_map_->end ())
00526   {
00527     // There is no cloud or shape with this ID, so just exit
00528     if (ca_it == cloud_actor_map_->end ())
00529       return (false);
00530     // Cloud found, set shape to false
00531     shape = false;
00532   }
00533 
00534   // Remove the pointer/ID pair to the global actor map
00535   if (shape)
00536   {
00537     if (removeActorFromRenderer (am_it->second, viewport))
00538     {
00539       shape_actor_map_->erase (am_it);
00540       return (true);
00541     }
00542   }
00543   else
00544   {
00545     if (removeActorFromRenderer (ca_it->second.actor, viewport))
00546     {
00547       cloud_actor_map_->erase (ca_it);
00548       return (true);
00549     }
00550   }
00551   return (false);
00552 }
00553 
00555 bool
00556 pcl::visualization::PCLVisualizer::removeText3D (const std::string &id, int viewport)
00557 {
00558   // Check to see if the given ID entry exists
00559   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
00560 
00561   if (am_it == shape_actor_map_->end ())
00562   {
00563     //pcl::console::print_warn ("[removeSape] Could not find any shape with id <%s>!\n", id.c_str ());
00564     return (false);
00565   }
00566 
00567   // Remove it from all renderers
00568   if (removeActorFromRenderer (am_it->second, viewport))
00569   {
00570     // Remove the pointer/ID pair to the global actor map
00571     shape_actor_map_->erase (am_it);
00572     return (true);
00573   }
00574   return (false);
00575 }
00576 
00578 bool
00579 pcl::visualization::PCLVisualizer::removeAllPointClouds (int viewport)
00580 {
00581   // Check to see if the given ID entry exists
00582   CloudActorMap::iterator am_it = cloud_actor_map_->begin ();
00583   while (am_it != cloud_actor_map_->end () )
00584   {
00585     if (removePointCloud (am_it->first, viewport))
00586       am_it = cloud_actor_map_->begin ();
00587     else
00588       ++am_it;
00589   }
00590   return (true);
00591 }
00592 
00594 bool
00595 pcl::visualization::PCLVisualizer::removeAllShapes (int viewport)
00596 {
00597   // Check to see if the given ID entry exists
00598   ShapeActorMap::iterator am_it = shape_actor_map_->begin ();
00599   while (am_it != shape_actor_map_->end ())
00600   {
00601     if (removeShape (am_it->first, viewport))
00602       am_it = shape_actor_map_->begin ();
00603     else
00604       ++am_it;
00605   }
00606   return (true);
00607 }
00608 
00610 bool
00611 pcl::visualization::PCLVisualizer::addPointCloudPrincipalCurvatures (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud,
00612                                                                     const pcl::PointCloud<pcl::Normal>::ConstPtr &normals,
00613                                                                     const pcl::PointCloud<pcl::PrincipalCurvatures>::ConstPtr &pcs,
00614                                                                     int level, double scale,
00615                                                                     const std::string &id, int viewport)
00616 {
00617   if (pcs->points.size () != cloud->points.size () || normals->points.size () != cloud->points.size ())
00618   {
00619     pcl::console::print_error ("[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n");
00620     return (false);
00621   }
00622   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00623   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00624 
00625   if (am_it != cloud_actor_map_->end ())
00626   {
00627     pcl::console::print_warn ("[addPointCloudPrincipalCurvatures] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
00628     return (false);
00629   }
00630 
00631   vtkSmartPointer<vtkAppendPolyData> polydata_1 = vtkSmartPointer<vtkAppendPolyData>::New ();
00632   vtkSmartPointer<vtkAppendPolyData> polydata_2 = vtkSmartPointer<vtkAppendPolyData>::New ();
00633 
00634   // Setup two colors - one for each line
00635   unsigned char green[3] = {0, 255, 0};
00636   unsigned char blue[3] = {0, 0, 255};
00637 
00638   // Setup the colors array
00639   vtkSmartPointer<vtkUnsignedCharArray> line_1_colors =vtkSmartPointer<vtkUnsignedCharArray>::New ();
00640   line_1_colors->SetNumberOfComponents (3);
00641   line_1_colors->SetName ("Colors");
00642   vtkSmartPointer<vtkUnsignedCharArray> line_2_colors =vtkSmartPointer<vtkUnsignedCharArray>::New ();
00643   line_2_colors->SetNumberOfComponents (3);
00644   line_2_colors->SetName ("Colors");
00645 
00646   // Create the first sets of lines
00647   for (size_t i = 0; i < cloud->points.size (); i+=level)
00648   {
00649     pcl::PointXYZ p = cloud->points[i];
00650     p.x += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[0]) * scale;
00651     p.y += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[1]) * scale;
00652     p.z += (pcs->points[i].pc1 * pcs->points[i].principal_curvature[2]) * scale;
00653 
00654     vtkSmartPointer<vtkLineSource> line_1 = vtkSmartPointer<vtkLineSource>::New ();
00655     line_1->SetPoint1 (cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
00656     line_1->SetPoint2 (p.x, p.y, p.z);
00657     line_1->Update ();
00658     polydata_1->AddInput (line_1->GetOutput ());
00659     line_1_colors->InsertNextTupleValue (green);
00660   }
00661   polydata_1->Update ();
00662   vtkSmartPointer<vtkPolyData> line_1_data = polydata_1->GetOutput ();
00663   line_1_data->GetCellData ()->SetScalars (line_1_colors);
00664 
00665   // Create the second sets of lines
00666   for (size_t i = 0; i < cloud->points.size (); i += level)
00667   {
00668     Eigen::Vector3f pc (pcs->points[i].principal_curvature[0],
00669                         pcs->points[i].principal_curvature[1],
00670                         pcs->points[i].principal_curvature[2]);
00671     Eigen::Vector3f normal (normals->points[i].normal[0],
00672                             normals->points[i].normal[1],
00673                             normals->points[i].normal[2]);
00674     Eigen::Vector3f pc_c = pc.cross (normal);
00675 
00676     pcl::PointXYZ p = cloud->points[i];
00677     p.x += (pcs->points[i].pc2 * pc_c[0]) * scale;
00678     p.y += (pcs->points[i].pc2 * pc_c[1]) * scale;
00679     p.z += (pcs->points[i].pc2 * pc_c[2]) * scale;
00680 
00681     vtkSmartPointer<vtkLineSource> line_2 = vtkSmartPointer<vtkLineSource>::New ();
00682     line_2->SetPoint1 (cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
00683     line_2->SetPoint2 (p.x, p.y, p.z);
00684     line_2->Update ();
00685     polydata_2->AddInput (line_2->GetOutput ());
00686     line_2_colors->InsertNextTupleValue (blue);
00687   }
00688   polydata_2->Update ();
00689   vtkSmartPointer<vtkPolyData> line_2_data = polydata_2->GetOutput ();
00690   line_2_data->GetCellData ()->SetScalars (line_2_colors);
00691 
00692   // Assemble the two sets of lines
00693   vtkSmartPointer<vtkAppendPolyData> alldata = vtkSmartPointer<vtkAppendPolyData>::New ();
00694   alldata->AddInput (line_1_data);
00695   alldata->AddInput (line_2_data);
00696 
00697   // Create an Actor
00698   vtkSmartPointer<vtkLODActor> actor;
00699   createActorFromVTKDataSet (alldata->GetOutput (), actor);
00700   actor->GetMapper ()->SetScalarModeToUseCellData ();
00701 
00702   // Add it to all renderers
00703   addActorToRenderer (actor, viewport);
00704 
00705   // Save the pointer/ID pair to the global actor map
00706   CloudActor act;
00707   act.actor = actor;
00708   (*cloud_actor_map_)[id] = act;
00709   return (true);
00710 }
00711 
00713 bool
00714 pcl::visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkLODActor> &actor, int viewport)
00715 {
00716   vtkLODActor* actor_to_remove = vtkLODActor::SafeDownCast (actor);
00717   
00718   // Add it to all renderers
00719   rens_->InitTraversal ();
00720   vtkRenderer* renderer = NULL;
00721   int i = 0;
00722   while ((renderer = rens_->GetNextItem ()) != NULL)
00723   {
00724     // Should we remove the actor from all renderers?
00725     if (viewport == 0)
00726     {
00727       renderer->RemoveActor (actor);
00728       renderer->Render ();
00729     }
00730     else if (viewport == i)               // add the actor only to the specified viewport
00731     {
00732       // Iterate over all actors in this renderer
00733       vtkPropCollection* actors = renderer->GetViewProps ();
00734       actors->InitTraversal ();
00735       vtkProp* current_actor = NULL;
00736       while ((current_actor = actors->GetNextProp ()) != NULL)
00737       {
00738         if (current_actor != actor_to_remove)
00739           continue;
00740         renderer->RemoveActor (actor);
00741         renderer->Render ();
00742         // Found the correct viewport and removed the actor
00743         return (true);
00744       }
00745     }
00746     ++i;
00747   }
00748   if (viewport == 0) return (true);
00749   return (false);
00750 }
00751 
00753 void
00754 pcl::visualization::PCLVisualizer::addActorToRenderer (const vtkSmartPointer<vtkProp> &actor, int viewport)
00755 {
00756   // Add it to all renderers
00757   rens_->InitTraversal ();
00758   vtkRenderer* renderer = NULL;
00759   int i = 0;
00760   while ((renderer = rens_->GetNextItem ()) != NULL)
00761   {
00762     // Should we add the actor to all renderers?
00763     if (viewport == 0)
00764     {
00765       renderer->AddActor (actor);
00766       renderer->Render ();
00767     }
00768     else if (viewport == i)               // add the actor only to the specified viewport
00769     {
00770       renderer->AddActor (actor);
00771       renderer->Render ();
00772     }
00773     ++i;
00774   }
00775 }
00776 
00778 bool
00779 pcl::visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkProp> &actor, int viewport)
00780 {
00781   vtkProp* actor_to_remove = vtkProp::SafeDownCast (actor);
00782   
00783   // Initialize traversal
00784   rens_->InitTraversal ();
00785   vtkRenderer* renderer = NULL;
00786   int i = 0;
00787   while ((renderer = rens_->GetNextItem ()) != NULL)
00788   {
00789     // Should we remove the actor from all renderers?
00790     if (viewport == 0)
00791     {
00792       renderer->RemoveActor (actor);
00793       renderer->Render ();
00794     }
00795     else if (viewport == i)               // add the actor only to the specified viewport
00796     {
00797       // Iterate over all actors in this renderer
00798       vtkPropCollection* actors = renderer->GetViewProps ();
00799       actors->InitTraversal ();
00800       vtkProp* current_actor = NULL;
00801       while ((current_actor = actors->GetNextProp ()) != NULL)
00802       {
00803         if (current_actor != actor_to_remove)
00804           continue;
00805         renderer->RemoveActor (actor);
00806         renderer->Render ();
00807         // Found the correct viewport and removed the actor
00808         return (true);
00809       }
00810     }
00811     ++i;
00812   }
00813   if (viewport == 0) return (true);
00814   return (false);
00815 }
00816 
00818 void
00819 pcl::visualization::PCLVisualizer::createActorFromVTKDataSet (const vtkSmartPointer<vtkDataSet> &data,
00820                                                               vtkSmartPointer<vtkLODActor> &actor,
00821                                                               bool use_scalars)
00822 {
00823   // If actor is not initialized, initialize it here
00824   if (!actor)
00825     actor = vtkSmartPointer<vtkLODActor>::New ();
00826 
00827   vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New ();
00828   mapper->SetInput (data);
00829 
00830   if (use_scalars)
00831   {
00832     vtkSmartPointer<vtkDataArray> scalars = data->GetPointData ()->GetScalars ();
00833     double minmax[2];
00834     if (scalars)
00835     {
00836       scalars->GetRange (minmax);
00837       mapper->SetScalarRange (minmax);
00838 
00839       mapper->SetScalarModeToUsePointData ();
00840       mapper->InterpolateScalarsBeforeMappingOn ();
00841       mapper->ScalarVisibilityOn ();
00842     }
00843   }
00844   mapper->ImmediateModeRenderingOff ();
00845 
00846   actor->SetNumberOfCloudPoints (std::max<vtkIdType> (1, data->GetNumberOfPoints () / 10));
00847   actor->GetProperty ()->SetInterpolationToFlat ();
00848 
00852   // actor->GetProperty ()->BackfaceCullingOn ();
00853 
00854   actor->SetMapper (mapper);
00855 }
00856 
00858 void
00859 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData (
00860     const GeometryHandlerConstPtr &geometry_handler,
00861     vtkSmartPointer<vtkPolyData> &polydata,
00862     vtkSmartPointer<vtkIdTypeArray> &initcells)
00863 {
00864   vtkSmartPointer<vtkCellArray> vertices;
00865 
00866   if (!polydata)
00867   {
00868     allocVtkPolyData (polydata);
00869     vertices = vtkSmartPointer<vtkCellArray>::New ();
00870     polydata->SetVerts (vertices);
00871   }
00872 
00873   // Use the handler to obtain the geometry
00874   vtkSmartPointer<vtkPoints> points;
00875   geometry_handler->getGeometry (points);
00876   polydata->SetPoints (points);
00877 
00878   vtkIdType nr_points = points->GetNumberOfPoints ();
00879 
00880   // Create the supporting structures
00881   vertices = polydata->GetVerts ();
00882   if (!vertices)
00883     vertices = vtkSmartPointer<vtkCellArray>::New ();
00884 
00885   vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
00886   updateCells (cells, initcells, nr_points);
00887   // Set the cells and the vertices
00888   vertices->SetCells (nr_points, cells);
00889 }
00890 
00892 void
00893 pcl::visualization::PCLVisualizer::setBackgroundColor (
00894     const double &r, const double &g, const double &b, int viewport)
00895 {
00896   rens_->InitTraversal ();
00897   vtkRenderer* renderer = NULL;
00898   int i = 0;
00899   while ((renderer = rens_->GetNextItem ()) != NULL)
00900   {
00901     // Should we add the actor to all renderers?
00902     if (viewport == 0)
00903     {
00904       renderer->SetBackground (r, g, b);
00905       renderer->Render ();
00906     }
00907     else if (viewport == i)               // add the actor only to the specified viewport
00908     {
00909       renderer->SetBackground (r, g, b);
00910       renderer->Render ();
00911     }
00912     ++i;
00913   }
00914 }
00915 
00917 bool
00918 pcl::visualization::PCLVisualizer::setPointCloudRenderingProperties (
00919     int property, double val1, double val2, double val3, const std::string &id, int viewport)
00920 {
00921   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00922   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00923 
00924   if (am_it == cloud_actor_map_->end ())
00925   {
00926     pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ());
00927     return (false);
00928   }
00929   // Get the actor pointer
00930   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
00931 
00932   switch (property)
00933   {
00934     case PCL_VISUALIZER_COLOR:
00935     {
00936       actor->GetProperty ()->SetColor (val1, val2, val3);
00937       actor->GetMapper ()->ScalarVisibilityOff ();
00938       actor->Modified ();
00939       break;
00940     }
00941     default:
00942     {
00943       pcl::console::print_error ("[setPointCloudRenderingProperties] Unknown property (%d) specified!\n", property);
00944       return (false);
00945     }
00946   }
00947   return (true);
00948 }
00949 
00951 bool
00952 pcl::visualization::PCLVisualizer::getPointCloudRenderingProperties (int property, double &value, const std::string &id)
00953 {
00954   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00955   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00956 
00957   if (am_it == cloud_actor_map_->end ())
00958     return (false);
00959   // Get the actor pointer
00960   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
00961 
00962   switch (property)
00963   {
00964     case PCL_VISUALIZER_POINT_SIZE:
00965     {
00966       value = actor->GetProperty ()->GetPointSize ();
00967       actor->Modified ();
00968       break;
00969     }
00970     case PCL_VISUALIZER_OPACITY:
00971     {
00972       value = actor->GetProperty ()->GetOpacity ();
00973       actor->Modified ();
00974       break;
00975     }
00976     case PCL_VISUALIZER_LINE_WIDTH:
00977     {
00978       value = actor->GetProperty ()->GetLineWidth ();
00979       actor->Modified ();
00980       break;
00981     }
00982     default:
00983     {
00984       pcl::console::print_error ("[getPointCloudRenderingProperties] Unknown property (%d) specified!\n", property);
00985       return (false);
00986     }
00987   }
00988   return (true);
00989 }
00990 
00992 bool
00993 pcl::visualization::PCLVisualizer::setPointCloudRenderingProperties (
00994     int property, double value, const std::string &id, int viewport)
00995 {
00996   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00997   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00998 
00999   if (am_it == cloud_actor_map_->end ())
01000   {
01001     pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ());
01002     return (false);
01003   }
01004   // Get the actor pointer
01005   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor);
01006 
01007   switch (property)
01008   {
01009     case PCL_VISUALIZER_POINT_SIZE:
01010     {
01011       actor->GetProperty ()->SetPointSize (value);
01012       actor->Modified ();
01013       break;
01014     }
01015     case PCL_VISUALIZER_OPACITY:
01016     {
01017       actor->GetProperty ()->SetOpacity (value);
01018       actor->Modified ();
01019       break;
01020     }
01021     // Turn on/off flag to control whether data is rendered using immediate
01022     // mode or note. Immediate mode rendering tends to be slower but it can
01023     // handle larger datasets. The default value is immediate mode off. If you
01024     // are having problems rendering a large dataset you might want to consider
01025     // using immediate more rendering.
01026     case PCL_VISUALIZER_IMMEDIATE_RENDERING:
01027     {
01028       actor->GetMapper ()->SetImmediateModeRendering ((int)value);
01029       actor->Modified ();
01030       break;
01031     }
01032     case PCL_VISUALIZER_LINE_WIDTH:
01033     {
01034       actor->GetProperty ()->SetLineWidth (value);
01035       actor->Modified ();
01036       break;
01037     }
01038     default:
01039     {
01040       pcl::console::print_error ("[setPointCloudRenderingProperties] Unknown property (%d) specified!\n", property);
01041       return (false);
01042     }
01043   }
01044   return (true);
01045 }
01046 
01048 bool
01049 pcl::visualization::PCLVisualizer::setShapeRenderingProperties (
01050     int property, double val1, double val2, double val3, const std::string &id, int viewport)
01051 {
01052   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01053   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01054 
01055   if (am_it == shape_actor_map_->end ())
01056   {
01057     pcl::console::print_error ("[setShapeRenderingProperties] Could not find any shape with id <%s>!\n", id.c_str ());
01058     return (false);
01059   }
01060   // Get the actor pointer
01061   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
01062 
01063   switch (property)
01064   {
01065     case PCL_VISUALIZER_COLOR:
01066     {
01067       actor->GetProperty ()->SetColor (val1, val2, val3);
01068       actor->GetProperty ()->SetEdgeColor (val1, val2, val3);
01069       // The following 3 are set by SetColor automatically according to the VTK docs
01070       //actor->GetProperty ()->SetAmbientColor  (val1, val2, val3);
01071       //actor->GetProperty ()->SetDiffuseColor (val1, val2, val3);
01072       //actor->GetProperty ()->SetSpecularColor (val1, val2, val3);
01073       actor->GetProperty ()->SetAmbient (0.8);
01074       actor->GetProperty ()->SetDiffuse (0.8);
01075       actor->GetProperty ()->SetSpecular (0.8);
01076 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 4))
01077       actor->GetProperty ()->SetLighting (0);
01078 #endif
01079       actor->Modified ();
01080       break;
01081     }
01082     default:
01083     {
01084       pcl::console::print_error ("[setShapeRenderingProperties] Unknown property (%d) specified!\n", property);
01085       return (false);
01086     }
01087   }
01088   return (true);
01089 }
01090 
01092 bool
01093 pcl::visualization::PCLVisualizer::setShapeRenderingProperties (
01094     int property, double value, const std::string &id, int viewport)
01095 {
01096   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01097   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01098 
01099   if (am_it == shape_actor_map_->end ())
01100   {
01101     pcl::console::print_error ("[setShapeRenderingProperties] Could not find any shape with id <%s>!\n", id.c_str ());
01102     return (false);
01103   }
01104   // Get the actor pointer
01105   vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second);
01106 
01107   switch (property)
01108   {
01109     case PCL_VISUALIZER_POINT_SIZE:
01110     {
01111       actor->GetProperty ()->SetPointSize (value);
01112       actor->Modified ();
01113       break;
01114     }
01115     case PCL_VISUALIZER_OPACITY:
01116     {
01117       actor->GetProperty ()->SetOpacity (value);
01118       actor->Modified ();
01119       break;
01120     }
01121     case PCL_VISUALIZER_LINE_WIDTH:
01122     {
01123       actor->GetProperty ()->SetLineWidth (value);
01124       actor->Modified ();
01125       break;
01126     }
01127     case PCL_VISUALIZER_FONT_SIZE:
01128     {
01129       vtkTextActor* text_actor = vtkTextActor::SafeDownCast (am_it->second);
01130       vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty ();
01131       tprop->SetFontSize (value);
01132       text_actor->Modified ();
01133       break;
01134     }
01135     case PCL_VISUALIZER_REPRESENTATION:
01136     {
01137       switch ((int)value)
01138       {
01139         case PCL_VISUALIZER_REPRESENTATION_POINTS:
01140         {
01141           actor->GetProperty ()->SetRepresentationToPoints ();
01142           break;
01143         }
01144         case PCL_VISUALIZER_REPRESENTATION_WIREFRAME:
01145         {
01146           actor->GetProperty ()->SetRepresentationToWireframe ();
01147           break;
01148         }
01149         case PCL_VISUALIZER_REPRESENTATION_SURFACE:
01150         {
01151           actor->GetProperty ()->SetRepresentationToSurface ();
01152           break;
01153         }
01154       }
01155       actor->Modified ();
01156       break;
01157     }
01158     default:
01159     {
01160       pcl::console::print_error ("[setShapeRenderingProperties] Unknown property (%d) specified!\n", property);
01161       return (false);
01162     }
01163   }
01164   return (true);
01165 }
01166 
01168 void
01169 pcl::visualization::PCLVisualizer::initCameraParameters ()
01170 {
01171   // Set default camera parameters
01172   camera_.clip[0] = 0.01; camera_.clip[1] = 1000.01;
01173   camera_.focal[0] = camera_.focal[1] = camera_.focal[2] = 0;
01174   camera_.pos[0] = camera_.pos[1] = 0; camera_.pos[2] = 1;
01175   camera_.view[0] = camera_.view[2] = 0; camera_.view[1] = 1;
01176 }
01177 
01179 bool
01180 pcl::visualization::PCLVisualizer::cameraParamsSet () const
01181 {
01182   return (camera_set_);
01183 }
01184 
01186 void
01187 pcl::visualization::PCLVisualizer::updateCamera ()
01188 {
01189    // Update the camera parameters
01190    rens_->InitTraversal ();
01191    vtkRenderer* renderer = NULL;
01192    while ((renderer = rens_->GetNextItem ()) != NULL)
01193    {
01194      renderer->GetActiveCamera ()->SetPosition (camera_.pos);
01195      renderer->GetActiveCamera ()->SetFocalPoint (camera_.focal);
01196      renderer->GetActiveCamera ()->SetViewUp (camera_.view);
01197      renderer->GetActiveCamera ()->SetClippingRange (camera_.clip);
01198    }
01199 }
01200 
01202 bool
01203 pcl::visualization::PCLVisualizer::updateShapePose (const std::string &id, const Eigen::Affine3f& pose)
01204 {
01205   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01206 
01207   vtkLODActor* actor;
01208 
01209   if (am_it == shape_actor_map_->end ())
01210     return (false);
01211   else 
01212     actor = vtkLODActor::SafeDownCast (am_it->second);
01213 
01214   vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New ();
01215   
01216   convertToVtkMatrix (pose.matrix (), matrix);
01217 
01218   actor->SetUserMatrix (matrix);
01219   actor->Modified ();
01220 
01221   return (true);
01222 }
01223 
01225 void
01226 pcl::visualization::PCLVisualizer::getCameras (std::vector<pcl::visualization::Camera>& cameras)
01227 {
01228   cameras.clear();
01229   rens_->InitTraversal ();
01230   vtkRenderer* renderer = NULL;
01231   while ((renderer = rens_->GetNextItem ()) != NULL)
01232   {
01233     cameras.push_back(Camera());
01234     cameras.back ().pos[0] = renderer->GetActiveCamera ()->GetPosition ()[0];
01235     cameras.back ().pos[1] = renderer->GetActiveCamera ()->GetPosition ()[1];
01236     cameras.back ().pos[2] = renderer->GetActiveCamera ()->GetPosition ()[2];
01237     cameras.back ().focal[0] = renderer->GetActiveCamera ()->GetFocalPoint ()[0];
01238     cameras.back ().focal[1] = renderer->GetActiveCamera ()->GetFocalPoint ()[1];
01239     cameras.back ().focal[2] = renderer->GetActiveCamera ()->GetFocalPoint ()[2];
01240     cameras.back ().clip[0] = renderer->GetActiveCamera ()->GetClippingRange ()[0];
01241     cameras.back ().clip[1] = renderer->GetActiveCamera ()->GetClippingRange ()[1];
01242     cameras.back ().view[0] = renderer->GetActiveCamera ()->GetViewUp ()[0];
01243     cameras.back ().view[1] = renderer->GetActiveCamera ()->GetViewUp ()[1];
01244     cameras.back ().view[2] = renderer->GetActiveCamera ()->GetViewUp ()[2];
01245     cameras.back().fovy = renderer->GetActiveCamera ()->GetViewAngle () / 180.0 * M_PI;
01246     cameras.back ().window_size[0] = renderer->GetRenderWindow ()->GetSize()[0];
01247     cameras.back ().window_size[1] = renderer->GetRenderWindow ()->GetSize()[1];
01248     cameras.back ().window_pos[0] = 0;
01249     cameras.back ().window_pos[1] = 0;
01250   }
01251 }
01252 
01254 Eigen::Affine3f
01255 pcl::visualization::PCLVisualizer::getViewerPose ()
01256 {
01257   Eigen::Affine3f ret(Eigen::Affine3f::Identity());
01258   if (rens_->GetNumberOfItems () < 1)
01259     return ret;
01260   vtkCamera& camera = *rens_->GetFirstRenderer ()->GetActiveCamera ();
01261   Eigen::Vector3d pos, x_axis, y_axis, z_axis;
01262   camera.GetPosition (pos[0], pos[1], pos[2]);
01263   camera.GetViewPlaneNormal (x_axis[0], x_axis[1], x_axis[2]);
01264   x_axis = -x_axis;
01265   camera.GetViewUp (z_axis[0], z_axis[1], z_axis[2]);
01266   y_axis = z_axis.cross(x_axis).normalized();
01267   ret(0,0)=x_axis[0], ret(0,1)=y_axis[0], ret(0,2)=z_axis[0], ret(0,3)=pos[0],
01268   ret(1,0)=x_axis[1], ret(1,1)=y_axis[1], ret(1,2)=z_axis[1], ret(1,3)=pos[1],
01269   ret(2,0)=x_axis[2], ret(2,1)=y_axis[2], ret(2,2)=z_axis[2], ret(2,3)=pos[2];
01270   return ret;
01271 }
01272 
01274 void
01275 pcl::visualization::PCLVisualizer::resetCamera ()
01276 {
01277   // Update the camera parameters
01278   rens_->InitTraversal ();
01279   vtkRenderer* renderer = NULL;
01280   while ((renderer = rens_->GetNextItem ()) != NULL)
01281   {
01282     renderer->ResetCamera ();
01283   }
01284 }
01285 
01286 
01288 void
01289 pcl::visualization::PCLVisualizer::setCameraPose (double posX, double posY, double posZ,
01290                                                   double viewX, double viewY, double viewZ,
01291                                                   double upX, double upY, double upZ, int viewport)
01292 {
01293   rens_->InitTraversal ();
01294   vtkRenderer* renderer = NULL;
01295   int i = 1;
01296   while ((renderer = rens_->GetNextItem ()) != NULL)
01297   {
01298     // Modify all renderer's cameras
01299     if (viewport == 0 || viewport == i)
01300     {
01301       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01302       cam->SetPosition (posX, posY, posZ);
01303       cam->SetFocalPoint (viewX, viewY, viewZ);
01304       cam->SetViewUp (upX, upY, upZ);
01305       renderer->Render ();
01306     }
01307     ++i;
01308   }
01309 }
01310 
01312 void
01313 pcl::visualization::PCLVisualizer::setCameraPosition (
01314     double posX,double posY, double posZ,
01315     double vx, double vy, double vz, int viewport)
01316 {
01317   rens_->InitTraversal ();
01318   vtkRenderer* renderer = NULL;
01319   int i = 1;
01320   while ((renderer = rens_->GetNextItem ()) != NULL)
01321   {
01322     // Modify all renderer's cameras
01323     if (viewport == 0 || viewport == i)
01324     {
01325       vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01326       cam->SetPosition (posX, posY, posZ);
01327       cam->SetViewUp (vx, vy, vz);
01328       renderer->Render ();
01329     }
01330     ++i;
01331   }
01332 
01333 }
01334 
01336 void
01337 pcl::visualization::PCLVisualizer::resetCameraViewpoint (const std::string &id)
01338 {
01339   // Check to see if the given ID entry exists
01340   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01341 
01342   if (am_it == cloud_actor_map_->end ())
01343     return;
01344 
01345   // Get all the data
01346   double bounds[6];
01347   vtkPolyDataMapper *mapper = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ());
01348   if (!mapper)
01349     return;
01350   vtkPolyData *data = mapper->GetInput ();
01351   if (!data)
01352     return;
01353 
01354   // Don't need this anymore!!!!!
01355 
01356   data->GetBounds (bounds);
01357 
01358   double focal[3];
01359   focal[0] = (bounds[0] + bounds[1]) / 2.0;
01360   focal[1] = (bounds[2] + bounds[3]) / 2.0;
01361   focal[2] = (bounds[4] + bounds[5]) / 2.0;
01362 
01363 
01364   // Update the camera parameters
01365   rens_->InitTraversal ();
01366   vtkRenderer* renderer = NULL;
01367   while ((renderer = rens_->GetNextItem ()) != NULL)
01368   {
01369     vtkSmartPointer<vtkCamera> cam = renderer->GetActiveCamera ();
01370     double view[3];
01371     cam->SetFocalPoint (focal);
01372     cam->SetPosition (0 - .25 * focal[0], 0 - .25 * focal[1], 0 - .25 * focal[2]);
01373     //cam->SetPosition (0.0, 0.0, 0.0);
01374     cam->GetViewUp (view);
01375 
01376 
01377     // Dataset negative on Z?
01378     if (focal[2] > 0)
01379       for (int i = 0; i < 3; i++) view[i] *= -1;
01380     cam->SetViewUp (view[0], view[1], view[2]);
01381 
01382 
01383     /*
01384     Eigen::Matrix4f T;
01385     T <<  0, 0, 1, 0,
01386          1, 0,  0, 0,
01387           0, -1,  0, 0,
01388           0, 0,  0, 1;
01389 
01390     Eigen::Matrix4f T2;
01391     T2 <<  -1,  0,  0, 0,
01392            0, 1,  0, 0,
01393            0,  0, 1, 0,
01394            0,  0,  0, 1;
01395 
01396     Eigen::Matrix4f T3;
01397     T3 <<  0,  0, -1, 0,
01398           1,  0, 0, 0,
01399            0, 1, 0, 0,
01400            0,  0, 0, 1;
01401 
01402     Eigen::Matrix4f T4;
01403     T4 <<  0,  -1, 0, 0,
01404            0,   0, 1, 0,
01405           -1,   0, 0, 0,
01406            0,   0, 0, 1;
01407 
01408 
01409     vtkSmartPointer<vtkMatrix4x4> post_trans = vtkSmartPointer<vtkMatrix4x4>::New();
01410     convertToVtkMatrix (T, post_trans);
01411 
01412     // post-transformation for the viewpoint transformation matrix
01413     vtkSmartPointer<vtkMatrix4x4> final_trans = vtkSmartPointer<vtkMatrix4x4>::New();
01414     vtkMatrix4x4::Multiply4x4 (am_it->second.viewpoint_transformation_, post_trans, final_trans);
01415     //vtkMatrix4x4::Multiply4x4 (post_trans, am_it->second.viewpoint_transformation_, final_trans);
01416 
01417 
01418     // Apply the viepoint transformation matrix to the camera
01419     vtkSmartPointer<vtkTransform> viewpoint_trans = vtkSmartPointer<vtkTransform>::New();
01420     viewpoint_trans->SetMatrix (am_it->second.viewpoint_transformation_);
01421     cam->ApplyTransform (viewpoint_trans);
01422     */
01423 
01424     renderer->SetActiveCamera (cam);
01425     renderer->ResetCameraClippingRange (bounds);
01426     renderer->Render ();
01427   }
01428 }
01429 
01431 bool
01432 pcl::visualization::PCLVisualizer::getCameraParameters (int argc, char **argv)
01433 {
01434   for (int i = 1; i < argc; i++)
01435   {
01436     if ((strcmp (argv[i], "-cam") == 0) && (++i < argc))
01437     {
01438       std::ifstream fs;
01439       std::string camfile = std::string (argv[i]);
01440       std::string line;
01441 
01442       std::vector<std::string> camera;
01443       if (camfile.find (".cam") == std::string::npos)
01444       {
01445         // Assume we have clip/focal/pos/view
01446         boost::split (camera, argv[i], boost::is_any_of ("/"), boost::token_compress_on);
01447       }
01448       else
01449       {
01450         // Assume that if we don't have clip/focal/pos/view, a filename.cam was given as a parameter
01451         fs.open (camfile.c_str ());
01452         while (!fs.eof ())
01453         {
01454           getline (fs, line);
01455           if (line == "")
01456             continue;
01457 
01458           boost::split (camera, line, boost::is_any_of ("/"), boost::token_compress_on);
01459           break;
01460         }
01461         fs.close ();
01462       }
01463 
01464       // look for '/' as a separator
01465       if (camera.size () != 7)
01466       {
01467         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Camera parameters given, but with an invalid number of options (%lu vs 7)!\n", (unsigned long)camera.size ());
01468         return (false);
01469       }
01470 
01471       std::string clip_str  = camera.at (0);
01472       std::string focal_str = camera.at (1);
01473       std::string pos_str   = camera.at (2);
01474       std::string view_str  = camera.at (3);
01475       std::string fovy_str  = camera.at (4);
01476       std::string win_size_str = camera.at (5);
01477       std::string win_pos_str  = camera.at (6);
01478 
01479       // Get each camera setting separately and parse for ','
01480       std::vector<std::string> clip_st;
01481       boost::split (clip_st, clip_str, boost::is_any_of (","), boost::token_compress_on);
01482       if (clip_st.size () != 2)
01483       {
01484         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera clipping angle!\n");
01485         return (false);
01486       }
01487       camera_.clip[0] = atof (clip_st.at (0).c_str ());
01488       camera_.clip[1] = atof (clip_st.at (1).c_str ());
01489 
01490       std::vector<std::string> focal_st;
01491       boost::split (focal_st, focal_str, boost::is_any_of (","), boost::token_compress_on);
01492       if (focal_st.size () != 3)
01493       {
01494         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera focal point!\n");
01495         return (false);
01496       }
01497       camera_.focal[0] = atof (focal_st.at (0).c_str ());
01498       camera_.focal[1] = atof (focal_st.at (1).c_str ());
01499       camera_.focal[2] = atof (focal_st.at (2).c_str ());
01500 
01501       std::vector<std::string> pos_st;
01502       boost::split (pos_st, pos_str, boost::is_any_of (","), boost::token_compress_on);
01503       if (pos_st.size () != 3)
01504       {
01505         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera position!\n");
01506         return (false);
01507       }
01508       camera_.pos[0] = atof (pos_st.at (0).c_str ());
01509       camera_.pos[1] = atof (pos_st.at (1).c_str ());
01510       camera_.pos[2] = atof (pos_st.at (2).c_str ());
01511 
01512       std::vector<std::string> view_st;
01513       boost::split (view_st, view_str, boost::is_any_of (","), boost::token_compress_on);
01514       if (view_st.size () != 3)
01515       {
01516         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera viewup!\n");
01517         return (false);
01518       }
01519       camera_.view[0] = atof (view_st.at (0).c_str ());
01520       camera_.view[1] = atof (view_st.at (1).c_str ());
01521       camera_.view[2] = atof (view_st.at (2).c_str ());
01522 
01523       std::vector<std::string> fovy_size_st;
01524       boost::split (fovy_size_st, fovy_str, boost::is_any_of (","), boost::token_compress_on);
01525       if (fovy_size_st.size () != 1)
01526       {
01527         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for field of view angle!\n");
01528         return (false);
01529       }
01530       camera_.fovy = atof (fovy_size_st.at (0).c_str ());
01531 
01532       std::vector<std::string> win_size_st;
01533       boost::split (win_size_st, win_size_str, boost::is_any_of (","), boost::token_compress_on);
01534       if (win_size_st.size () != 2)
01535       {
01536         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for window size!\n");
01537         return (false);
01538       }
01539       camera_.window_size[0] = atof (win_size_st.at (0).c_str ());
01540       camera_.window_size[1] = atof (win_size_st.at (1).c_str ());
01541 
01542       std::vector<std::string> win_pos_st;
01543       boost::split (win_pos_st, win_pos_str, boost::is_any_of (","), boost::token_compress_on);
01544       if (win_pos_st.size () != 2)
01545       {
01546         pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for window position!\n");
01547         return (false);
01548       }
01549       camera_.window_pos[0] = atof (win_pos_st.at (0).c_str ());
01550       camera_.window_pos[1] = atof (win_pos_st.at (1).c_str ());
01551 
01552       return (true);
01553     }
01554   }
01555   return (false);
01556 }
01557 
01559 bool
01560 pcl::visualization::PCLVisualizer::addCylinder (const pcl::ModelCoefficients &coefficients,
01561                                                const std::string &id, int viewport)
01562 {
01563   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01564   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01565   if (am_it != shape_actor_map_->end ())
01566   {
01567     pcl::console::print_warn ("[addCylinder] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01568     return (false);
01569   }
01570 
01571   vtkSmartPointer<vtkDataSet> data = createCylinder (coefficients);
01572 
01573   // Create an Actor
01574   vtkSmartPointer<vtkLODActor> actor;
01575   createActorFromVTKDataSet (data, actor);
01576   actor->GetProperty ()->SetRepresentationToWireframe ();
01577   addActorToRenderer (actor, viewport);
01578 
01579   // Save the pointer/ID pair to the global actor map
01580   (*shape_actor_map_)[id] = actor;
01581   return (true);
01582 }
01583 
01585 bool
01586 pcl::visualization::PCLVisualizer::addCube (const pcl::ModelCoefficients &coefficients,
01587                                             const std::string &id, int viewport)
01588 {
01589   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01590   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01591   if (am_it != shape_actor_map_->end ())
01592   {
01593     pcl::console::print_warn ("[addCube] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01594     return (false);
01595   }
01596 
01597   vtkSmartPointer<vtkDataSet> data = createCube (coefficients);
01598 
01599   // Create an Actor
01600   vtkSmartPointer<vtkLODActor> actor;
01601   createActorFromVTKDataSet (data, actor);
01602   actor->GetProperty ()->SetRepresentationToWireframe ();
01603   addActorToRenderer (actor, viewport);
01604 
01605   // Save the pointer/ID pair to the global actor map
01606   (*shape_actor_map_)[id] = actor;
01607   return (true);
01608 }
01609 
01611 bool
01612 pcl::visualization::PCLVisualizer::addCube (
01613   const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation,
01614   double width, double height, double depth,
01615   const std::string &id, int viewport)
01616 {
01617   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01618   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01619   if (am_it != shape_actor_map_->end ())
01620   {
01621     pcl::console::print_warn ("[addCube] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01622     return (false);
01623   }
01624 
01625   vtkSmartPointer<vtkDataSet> data = createCube (translation, rotation, width, height, depth);
01626 
01627   // Create an Actor
01628   vtkSmartPointer<vtkLODActor> actor;
01629   createActorFromVTKDataSet (data, actor);
01630   actor->GetProperty ()->SetRepresentationToWireframe ();
01631   addActorToRenderer (actor, viewport);
01632 
01633   // Save the pointer/ID pair to the global actor map
01634   (*shape_actor_map_)[id] = actor;
01635   return (true);
01636 }
01637 
01639 bool
01640 pcl::visualization::PCLVisualizer::addCube (double x_min, double x_max,
01641                                             double y_min, double y_max,
01642                                             double z_min, double z_max,
01643                                             double r, double g, double b,
01644                                             const std::string &id, int viewport)
01645 {
01646   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01647   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01648   if (am_it != shape_actor_map_->end ())
01649   {
01650     pcl::console::print_warn ("[addCube] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01651     return (false);
01652   }
01653 
01654   vtkSmartPointer<vtkDataSet> data = createCube (x_min, x_max, y_min, y_max, z_min, z_max);
01655 
01656   // Create an Actor
01657   vtkSmartPointer<vtkLODActor> actor;
01658   createActorFromVTKDataSet (data, actor);
01659   actor->GetProperty ()->SetRepresentationToWireframe ();
01660   actor->GetProperty ()->SetColor (r,g,b);
01661   addActorToRenderer (actor, viewport);
01662 
01663   // Save the pointer/ID pair to the global actor map
01664   (*shape_actor_map_)[id] = actor;
01665   return (true);
01666 }
01667 
01669 bool
01670 pcl::visualization::PCLVisualizer::addSphere (const pcl::ModelCoefficients &coefficients,
01671                                              const std::string &id, int viewport)
01672 {
01673   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01674   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01675   if (am_it != shape_actor_map_->end ())
01676   {
01677     pcl::console::print_warn ("[addSphere] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01678     return (false);
01679   }
01680 
01681   vtkSmartPointer<vtkDataSet> data = createSphere (coefficients);
01682 
01683   // Create an Actor
01684   vtkSmartPointer<vtkLODActor> actor;
01685   createActorFromVTKDataSet (data, actor);
01686   actor->GetProperty ()->SetRepresentationToWireframe ();
01687   addActorToRenderer (actor, viewport);
01688 
01689   // Save the pointer/ID pair to the global actor map
01690   (*shape_actor_map_)[id] = actor;
01691   return (true);
01692 }
01693 
01695 bool
01696 pcl::visualization::PCLVisualizer::addModelFromPolyData (
01697     vtkSmartPointer<vtkPolyData> polydata, const std::string & id, int viewport)
01698 {
01699   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01700   if (am_it != shape_actor_map_->end ())
01701   {
01702     pcl::console::print_warn (
01703                                 "[addModelFromPolyData] A shape with id <%s> already exists! Please choose a different id and retry.\n",
01704                                 id.c_str ());
01705     return (false);
01706   }
01707 
01708   vtkSmartPointer<vtkLODActor> actor;
01709   createActorFromVTKDataSet (polydata, actor);
01710   actor->GetProperty ()->SetRepresentationToWireframe ();
01711   addActorToRenderer (actor, viewport);
01712 
01713   // Save the pointer/ID pair to the global actor map
01714   (*shape_actor_map_)[id] = actor;
01715   return (true);
01716 }
01717 
01719 bool
01720 pcl::visualization::PCLVisualizer::addModelFromPolyData (
01721     vtkSmartPointer<vtkPolyData> polydata, vtkSmartPointer<vtkTransform> transform, const std::string & id, int viewport)
01722 {
01723   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01724   if (am_it != shape_actor_map_->end ())
01725   {
01726     pcl::console::print_warn (
01727                                 "[addModelFromPolyData] A shape with id <%s> already exists! Please choose a different id and retry.\n",
01728                                 id.c_str ());
01729     return (false);
01730   }
01731 
01732   vtkSmartPointer <vtkTransformFilter> trans_filter = vtkSmartPointer<vtkTransformFilter>::New ();
01733   trans_filter->SetTransform (transform);
01734   trans_filter->SetInput (polydata);
01735   trans_filter->Update();
01736 
01737   // Create an Actor
01738   vtkSmartPointer <vtkLODActor> actor;
01739   createActorFromVTKDataSet (trans_filter->GetOutput (), actor);
01740   actor->GetProperty ()->SetRepresentationToWireframe ();
01741   addActorToRenderer (actor, viewport);
01742 
01743   // Save the pointer/ID pair to the global actor map
01744   (*shape_actor_map_)[id] = actor;
01745   return (true);
01746 }
01747 
01748 
01750 bool
01751 pcl::visualization::PCLVisualizer::addModelFromPLYFile (const std::string &filename,
01752                                                        const std::string &id, int viewport)
01753 {
01754   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01755   if (am_it != shape_actor_map_->end ())
01756   {
01757     pcl::console::print_warn (
01758                                 "[addModelFromPLYFile] A shape with id <%s> already exists! Please choose a different id and retry.\n",
01759                                 id.c_str ());
01760     return (false);
01761   }
01762 
01763   vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New ();
01764   reader->SetFileName (filename.c_str ());
01765 
01766   // Create an Actor
01767   vtkSmartPointer<vtkLODActor> actor;
01768   createActorFromVTKDataSet (reader->GetOutput (), actor);
01769   actor->GetProperty ()->SetRepresentationToWireframe ();
01770   addActorToRenderer (actor, viewport);
01771 
01772   // Save the pointer/ID pair to the global actor map
01773   (*shape_actor_map_)[id] = actor;
01774   return (true);
01775 }
01776 
01778 bool
01779 pcl::visualization::PCLVisualizer::addModelFromPLYFile (const std::string &filename,
01780                                                        vtkSmartPointer<vtkTransform> transform, const std::string &id,
01781                                                        int viewport)
01782 {
01783   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01784   if (am_it != shape_actor_map_->end ())
01785   {
01786     pcl::console::print_warn (
01787                                 "[addModelFromPLYFile] A shape with id <%s> already exists! Please choose a different id and retry.\n",
01788                                 id.c_str ());
01789     return (false);
01790   }
01791 
01792   vtkSmartPointer <vtkPLYReader > reader = vtkSmartPointer<vtkPLYReader>::New ();
01793   reader->SetFileName (filename.c_str ());
01794 
01795   //create transformation filter
01796   vtkSmartPointer <vtkTransformFilter> trans_filter = vtkSmartPointer<vtkTransformFilter>::New ();
01797   trans_filter->SetTransform (transform);
01798   trans_filter->SetInputConnection (reader->GetOutputPort ());
01799 
01800   // Create an Actor
01801   vtkSmartPointer <vtkLODActor> actor;
01802   createActorFromVTKDataSet (trans_filter->GetOutput (), actor);
01803   actor->GetProperty ()->SetRepresentationToWireframe ();
01804   addActorToRenderer (actor, viewport);
01805 
01806   // Save the pointer/ID pair to the global actor map
01807   (*shape_actor_map_)[id] = actor;
01808   return (true);
01809 }
01810 
01812 bool
01813 pcl::visualization::PCLVisualizer::addLine (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
01814 {
01815   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01816   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01817   if (am_it != shape_actor_map_->end ())
01818   {
01819     pcl::console::print_warn ("[addLine] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01820     return (false);
01821   }
01822 
01823   vtkSmartPointer<vtkDataSet> data = createLine (coefficients);
01824 
01825   // Create an Actor
01826   vtkSmartPointer<vtkLODActor> actor;
01827   createActorFromVTKDataSet (data, actor);
01828   actor->GetProperty ()->SetRepresentationToWireframe ();
01829   addActorToRenderer (actor, viewport);
01830 
01831   // Save the pointer/ID pair to the global actor map
01832   (*shape_actor_map_)[id] = actor;
01833   return (true);
01834 }
01835 
01837 
01842 bool
01843   pcl::visualization::PCLVisualizer::addPlane (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
01844 {
01845   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01846   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01847   if (am_it != shape_actor_map_->end ())
01848   {
01849     pcl::console::print_warn ("[addPlane] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01850     return (false);
01851   }
01852 
01853   vtkSmartPointer<vtkDataSet> data = createPlane (coefficients);
01854 
01855   // Create an Actor
01856   vtkSmartPointer<vtkLODActor> actor;
01857   createActorFromVTKDataSet (data, actor);
01858   actor->GetProperty ()->SetRepresentationToWireframe ();
01859   addActorToRenderer (actor, viewport);
01860 
01861   // Save the pointer/ID pair to the global actor map
01862   (*shape_actor_map_)[id] = actor;
01863   return (true);
01864 }
01865 
01867 bool
01868 pcl::visualization::PCLVisualizer::addCircle (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
01869 {
01870   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01871   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01872   if (am_it != shape_actor_map_->end ())
01873   {
01874     pcl::console::print_warn ("[addCircle] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01875     return (false);
01876   }
01877 
01878   vtkSmartPointer<vtkDataSet> data = create2DCircle (coefficients);
01879 
01880   // Create an Actor
01881   vtkSmartPointer<vtkLODActor> actor;
01882   createActorFromVTKDataSet (data, actor);
01883   actor->GetProperty ()->SetRepresentationToWireframe ();
01884   addActorToRenderer (actor, viewport);
01885 
01886   // Save the pointer/ID pair to the global actor map
01887   (*shape_actor_map_)[id] = actor;
01888   return (true);
01889 }
01890 
01892 bool
01893 pcl::visualization::PCLVisualizer::addCone (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport)
01894 {
01895   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01896   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01897   if (am_it != shape_actor_map_->end ())
01898   {
01899     pcl::console::print_warn ("[addCone] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ());
01900     return (false);
01901   }
01902 
01903   vtkSmartPointer<vtkDataSet> data = createCone (coefficients);
01904 
01905   // Create an Actor
01906   vtkSmartPointer<vtkLODActor> actor;
01907   createActorFromVTKDataSet (data, actor);
01908   actor->GetProperty ()->SetRepresentationToWireframe ();
01909   addActorToRenderer (actor, viewport);
01910 
01911   // Save the pointer/ID pair to the global actor map
01912   (*shape_actor_map_)[id] = actor;
01913   return (true);
01914 }
01915 
01917 void
01918 pcl::visualization::PCLVisualizer::createViewPort (double xmin, double ymin, double xmax, double ymax, int &viewport)
01919 {
01920   // Create a new renderer
01921   vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New ();
01922   ren->SetViewport (xmin, ymin, xmax, ymax);
01923 
01924   if (rens_->GetNumberOfItems () > 0)
01925     ren->SetActiveCamera (rens_->GetFirstRenderer ()->GetActiveCamera ());
01926   ren->ResetCamera ();
01927 
01928   // Add it to the list of renderers
01929   rens_->AddItem (ren);
01930 
01931   if (rens_->GetNumberOfItems () <= 1)          // If only one renderer
01932     viewport = 0;                               // set viewport to 'all'
01933   else
01934     viewport = rens_->GetNumberOfItems () - 1;
01935 
01936   win_->AddRenderer (ren);
01937   win_->Modified ();
01938 }
01939 
01941 bool
01942 pcl::visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, const std::string &id, int viewport)
01943 {
01944   std::string tid;
01945   if (id.empty ())
01946     tid = text;
01947   else
01948     tid = id;
01949 
01950   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01951   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
01952   if (am_it != shape_actor_map_->end ())
01953   {
01954     pcl::console::print_warn ("[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
01955     return (false);
01956   }
01957 
01958   // Create an Actor
01959   vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New ();
01960   actor->SetPosition (xpos, ypos);
01961   actor->SetInput (text.c_str ());
01962 
01963   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
01964   tprop->SetFontSize (10);
01965   tprop->SetFontFamilyToArial ();
01966   tprop->SetJustificationToLeft ();
01967   tprop->BoldOn ();
01968   tprop->SetColor (1, 1, 1);
01969   addActorToRenderer (actor, viewport);
01970 
01971   // Save the pointer/ID pair to the global actor map
01972   (*shape_actor_map_)[tid] = actor;
01973   return (true);
01974 }
01975 
01977 bool
01978 pcl::visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, double r, double g, double b, const std::string &id, int viewport)
01979 {
01980   std::string tid;
01981   if (id.empty ())
01982     tid = text;
01983   else
01984     tid = id;
01985 
01986   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01987   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
01988   if (am_it != shape_actor_map_->end ())
01989   {
01990     pcl::console::print_warn ("[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
01991     return (false);
01992   }
01993 
01994   // Create an Actor
01995   vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New ();
01996   actor->SetPosition (xpos, ypos);
01997   actor->SetInput (text.c_str ());
01998 
01999   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02000   tprop->SetFontSize (10);
02001   tprop->SetFontFamilyToArial ();
02002   tprop->SetJustificationToLeft ();
02003   tprop->BoldOn ();
02004   tprop->SetColor (r, g, b);
02005   addActorToRenderer (actor, viewport);
02006 
02007   // Save the pointer/ID pair to the global actor map
02008   (*shape_actor_map_)[tid] = actor;
02009   return (true);
02010 }
02011 
02013 bool
02014 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)
02015 {
02016   std::string tid;
02017   if (id.empty ())
02018     tid = text;
02019   else
02020     tid = id;
02021 
02022   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02023   ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02024   if (am_it != shape_actor_map_->end ())
02025   {
02026     pcl::console::print_warn ("[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ());
02027     return (false);
02028   }
02029 
02030   // Create an Actor
02031   vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New ();
02032   actor->SetPosition (xpos, ypos);
02033   actor->SetInput (text.c_str ());
02034 
02035   vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02036   tprop->SetFontSize (fontsize);
02037   tprop->SetFontFamilyToArial ();
02038   tprop->SetJustificationToLeft ();
02039   tprop->BoldOn ();
02040   tprop->SetColor (r, g, b);
02041   addActorToRenderer (actor, viewport);
02042 
02043   // Save the pointer/ID pair to the global actor map
02044   (*shape_actor_map_)[tid] = actor;
02045   return (true);
02046 }
02047 
02049 bool
02050 pcl::visualization::PCLVisualizer::updateText (const std::string &text, int xpos, int ypos, const std::string &id)
02051 {
02052         std::string tid;
02053         if (id.empty ())
02054     tid = text;
02055         else
02056     tid = id;
02057 
02058         // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02059         ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02060         if (am_it == shape_actor_map_->end ())
02061     return (false);
02062 
02063         // Retrieve the Actor
02064         vtkTextActor* actor = vtkTextActor::SafeDownCast (am_it->second); 
02065         actor->SetPosition (xpos, ypos);
02066         actor->SetInput (text.c_str ());
02067 
02068         actor->Modified ();
02069 
02070         return (true);
02071 }
02072 
02074 bool
02075 pcl::visualization::PCLVisualizer::updateText (const std::string &text, int xpos, int ypos, double r, double g, double b, const std::string &id)
02076 {
02077         std::string tid;
02078         if (id.empty ())
02079     tid = text;
02080         else
02081     tid = id;
02082 
02083         // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02084         ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02085         if (am_it == shape_actor_map_->end ())
02086     return (false);
02087 
02088         // Create the Actor
02089         vtkTextActor* actor = vtkTextActor::SafeDownCast (am_it->second); 
02090         actor->SetPosition (xpos, ypos);
02091         actor->SetInput (text.c_str ());
02092 
02093         vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty ();
02094         tprop->SetColor (r, g, b);
02095         actor->Modified ();
02096 
02097         return (true);
02098 }
02099 
02101 bool
02102 pcl::visualization::PCLVisualizer::updateText (const std::string &text, int xpos, int ypos, int fontsize, double r, double g, double b, const std::string &id)
02103 {
02104         std::string tid;
02105         if (id.empty ())
02106     tid = text;
02107         else
02108     tid = id;
02109 
02110         // Check to see if this ID entry already exists (has it been already added to the visualizer?)
02111         ShapeActorMap::iterator am_it = shape_actor_map_->find (tid);
02112         if (am_it == shape_actor_map_->end ())
02113     return (false);
02114 
02115         // Retrieve the Actor
02116         vtkTextActor *actor = vtkTextActor::SafeDownCast (am_it->second);
02117         
02118         actor->SetPosition (xpos, ypos);
02119         actor->SetInput (text.c_str ());
02120 
02121         vtkTextProperty* tprop = actor->GetTextProperty ();
02122         tprop->SetFontSize (fontsize);
02123         tprop->SetColor (r, g, b);
02124 
02125         actor->Modified ();
02126 
02127         return (true);
02128 }
02129 
02131 bool
02132 pcl::visualization::PCLVisualizer::updateColorHandlerIndex (const std::string &id, int index)
02133 {
02134   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
02135   if (am_it == cloud_actor_map_->end ())
02136   {
02137     pcl::console::print_warn ("[updateColorHandlerIndex] PointCloud with id <%s> doesn't exist!\n", id.c_str ());
02138     return (false);
02139   }
02140 
02141   if (index >= (int)am_it->second.color_handlers.size ())
02142   {
02143     pcl::console::print_warn ("[updateColorHandlerIndex] Invalid index <%d> given! Maximum range is: 0-%lu.\n", index, (unsigned long)am_it->second.color_handlers.size ());
02144     return (false);
02145   }
02146   // Get the handler
02147   PointCloudColorHandler<sensor_msgs::PointCloud2>::ConstPtr color_handler = am_it->second.color_handlers[index];
02148 
02149   vtkSmartPointer<vtkDataArray> scalars;
02150   color_handler->getColor (scalars);
02151   double minmax[2];
02152   scalars->GetRange (minmax);
02153   // Update the data
02154   vtkPolyData *data = static_cast<vtkPolyData*>(am_it->second.actor->GetMapper ()->GetInput ());
02155   data->GetPointData ()->SetScalars (scalars);
02156   data->Update ();
02157   // Modify the mapper
02158   vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ());
02159   mapper->SetScalarRange (minmax);
02160   mapper->SetScalarModeToUsePointData ();
02161   mapper->SetInput (data);
02162   // Modify the actor
02163   am_it->second.actor->SetMapper (mapper);
02164   am_it->second.actor->Modified ();
02165   am_it->second.color_handler_index_ = index;
02166 
02167   //style_->setCloudActorMap (cloud_actor_map_);
02168 
02169   return (true);
02170 }
02171 
02172 
02173 
02175 bool
02176 pcl::visualization::PCLVisualizer::addPolygonMesh (const pcl::PolygonMesh &poly_mesh,
02177                                                    const std::string &id,
02178                                                    int viewport)
02179 {
02180   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
02181   if (am_it != cloud_actor_map_->end ())
02182   {
02183     pcl::console::print_warn (
02184                                 "[addPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02185                                 id.c_str ());
02186     return (false);
02187   }
02188 
02189   // Create points from polyMesh.cloud
02190   vtkSmartPointer<vtkPoints> poly_points = vtkSmartPointer<vtkPoints>::New ();
02191   pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
02192   pcl::fromROSMsg (poly_mesh.cloud, *point_cloud);
02193   poly_points->SetNumberOfPoints (point_cloud->points.size ());
02194 
02195   size_t i;
02196   for (i = 0; i < point_cloud->points.size (); ++i)
02197     poly_points->InsertPoint (i, point_cloud->points[i].x, point_cloud->points[i].y, point_cloud->points[i].z);
02198 
02199   bool has_color = false;
02200   vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New ();
02201   if (pcl::getFieldIndex(poly_mesh.cloud, "rgb") != -1)
02202   {
02203     has_color = true;
02204     colors->SetNumberOfComponents (3);
02205     colors->SetName ("Colors");
02206     pcl::PointCloud<pcl::PointXYZRGB> cloud;
02207     pcl::fromROSMsg(poly_mesh.cloud, cloud);
02208     for (i = 0; i < cloud.points.size (); ++i)
02209     {
02210       const unsigned char color[3] = {cloud.points[i].r, cloud.points[i].g, cloud.points[i].b};
02211       colors->InsertNextTupleValue(color);
02212     }
02213   }
02214   if (pcl::getFieldIndex(poly_mesh.cloud, "rgba") != -1)
02215   {
02216     has_color = true;
02217     colors->SetNumberOfComponents (3);
02218     colors->SetName ("Colors");
02219     pcl::PointCloud<pcl::PointXYZRGBA> cloud;
02220     pcl::fromROSMsg(poly_mesh.cloud, cloud);
02221     for (i = 0; i < cloud.points.size (); ++i)
02222     {
02223       const unsigned char color[3] = {cloud.points[i].r, cloud.points[i].g, cloud.points[i].b};
02224       colors->InsertNextTupleValue(color);
02225     }
02226   }
02227 
02228   vtkSmartPointer<vtkLODActor> actor;
02229   if (poly_mesh.polygons.size() > 1)
02230   {
02231     //create polys from polyMesh.polygons
02232     vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New ();
02233 
02234     for (i = 0; i < poly_mesh.polygons.size (); i++)
02235     {
02236       size_t n_points = poly_mesh.polygons[i].vertices.size ();
02237       cell_array->InsertNextCell (n_points);
02238       for (size_t j = 0; j < n_points; j++)
02239         cell_array->InsertCellPoint (poly_mesh.polygons[i].vertices[j]);
02240     }
02241 
02242     vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
02243 //    polydata->SetStrips (cell_array);
02244     polydata->SetPolys (cell_array);
02245     polydata->SetPoints (poly_points);
02246 
02247     if (has_color)
02248       polydata->GetPointData()->SetScalars(colors);
02249 
02250     createActorFromVTKDataSet (polydata, actor);
02251   }
02252   else if (poly_mesh.polygons.size() == 1)
02253   {
02254     vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New ();
02255     size_t n_points = poly_mesh.polygons[0].vertices.size ();
02256     polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
02257 
02258     for (size_t j=0; j < (n_points - 1); j++)
02259       polygon->GetPointIds ()->SetId (j, poly_mesh.polygons[0].vertices[j]);
02260 
02261     vtkSmartPointer<vtkUnstructuredGrid> poly_grid = vtkSmartPointer<vtkUnstructuredGrid>::New ();
02262     poly_grid->Allocate (1, 1);
02263     poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
02264     poly_grid->SetPoints (poly_points);
02265     poly_grid->Update ();
02266 
02267     createActorFromVTKDataSet (poly_grid, actor);
02268     actor->GetProperty ()->SetRepresentationToWireframe ();
02269   }
02270   else
02271   {
02272     PCL_ERROR("PCLVisualizer::addPolygonMesh: No polygons\n");
02273     return false;
02274   }
02275 
02276   actor->GetProperty ()->SetRepresentationToSurface ();
02277   addActorToRenderer (actor, viewport);
02278 
02279   // Save the pointer/ID pair to the global actor map
02280   (*cloud_actor_map_)[id].actor = actor;
02281   return (true);
02282 }
02283 
02284 
02286 bool
02287 pcl::visualization::PCLVisualizer::addPolylineFromPolygonMesh (
02288     const pcl::PolygonMesh &polymesh, const std::string &id, int viewport)
02289 {
02290   ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
02291   if (am_it != shape_actor_map_->end ())
02292   {
02293     pcl::console::print_warn (
02294                                 "[addPolylineFromPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n",
02295                                 id.c_str ());
02296     return (false);
02297   }
02298 
02299   // Create points from polyMesh.cloud
02300   vtkSmartPointer<vtkPoints> poly_points = vtkSmartPointer<vtkPoints>::New ();
02301   pcl::PointCloud<pcl::PointXYZ> point_cloud;
02302   pcl::fromROSMsg (polymesh.cloud, point_cloud);
02303   poly_points->SetNumberOfPoints (point_cloud.points.size ());
02304 
02305   size_t i;
02306   for (i = 0; i < point_cloud.points.size (); ++i)
02307     poly_points->InsertPoint (i, point_cloud.points[i].x, point_cloud.points[i].y, point_cloud.points[i].z);
02308 
02309   // Create a cell array to store the lines in and add the lines to it
02310   vtkSmartPointer <vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New ();
02311   vtkSmartPointer <vtkPolyData> polyData;
02312   allocVtkPolyData (polyData);
02313 
02314   for (i = 0; i < polymesh.polygons.size (); i++)
02315   {
02316     vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New();
02317     polyLine->GetPointIds()->SetNumberOfIds(polymesh.polygons[i].vertices.size());
02318     for(unsigned int k = 0; k < polymesh.polygons[i].vertices.size(); k++)
02319     {
02320       polyLine->GetPointIds()->SetId(k,polymesh.polygons[i].vertices[k]);
02321     }
02322 
02323     cells->InsertNextCell (polyLine);
02324   }
02325 
02326   // Add the points to the dataset
02327   polyData->SetPoints (poly_points);
02328 
02329   // Add the lines to the dataset
02330   polyData->SetLines (cells);
02331 
02332   // Setup actor and mapper
02333   vtkSmartPointer < vtkPolyDataMapper > mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
02334   mapper->SetInput (polyData);
02335 
02336   vtkSmartPointer < vtkActor > actor = vtkSmartPointer<vtkActor>::New ();
02337   actor->SetMapper (mapper);
02338 
02339 
02340   addActorToRenderer (actor, viewport);
02341 
02342   // Save the pointer/ID pair to the global actor map
02343   (*shape_actor_map_)[id] = actor;
02344 
02345   return (true);
02346 }
02347 
02349 void
02350 pcl::visualization::PCLVisualizer::setRepresentationToSurfaceForAllActors ()
02351 {
02352   ShapeActorMap::iterator am_it;
02353   rens_->InitTraversal ();
02354   vtkRenderer* renderer = NULL;
02355   while ((renderer = rens_->GetNextItem ()) != NULL)
02356   {
02357     vtkActorCollection * actors = renderer->GetActors ();
02358     actors->InitTraversal ();
02359     vtkActor * actor;
02360     while ((actor = actors->GetNextActor ()) != NULL)
02361     {
02362       actor->GetProperty ()->SetRepresentationToSurface ();
02363     }
02364   }
02365 }
02366 
02368 void
02369 pcl::visualization::PCLVisualizer::setRepresentationToPointsForAllActors ()
02370 {
02371   ShapeActorMap::iterator am_it;
02372   rens_->InitTraversal ();
02373   vtkRenderer* renderer = NULL;
02374   while ((renderer = rens_->GetNextItem ()) != NULL)
02375   {
02376     vtkActorCollection * actors = renderer->GetActors ();
02377     actors->InitTraversal ();
02378     vtkActor * actor;
02379     while ((actor = actors->GetNextActor ()) != NULL)
02380     {
02381       actor->GetProperty ()->SetRepresentationToPoints ();
02382     }
02383   }
02384 }
02385 
02387 void
02388 pcl::visualization::PCLVisualizer::setRepresentationToWireframeForAllActors ()
02389 {
02390   ShapeActorMap::iterator am_it;
02391   rens_->InitTraversal ();
02392   vtkRenderer* renderer = NULL;
02393   while ((renderer = rens_->GetNextItem ()) != NULL)
02394   {
02395     vtkActorCollection * actors = renderer->GetActors ();
02396     actors->InitTraversal ();
02397     vtkActor * actor;
02398     while ((actor = actors->GetNextActor ()) != NULL)
02399     {
02400       actor->GetProperty ()->SetRepresentationToWireframe ();
02401     }
02402   }
02403 }
02404 
02406 void
02407 pcl::visualization::PCLVisualizer::renderViewTesselatedSphere (
02408                                                                int xres,
02409                                                                int yres,
02410                                                                std::vector<pcl::PointCloud<pcl::PointXYZ>,
02411                                                                    Eigen::aligned_allocator<pcl::PointCloud<
02412                                                                        pcl::PointXYZ> > > & clouds,
02413                                                                std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<
02414                                                                    Eigen::Matrix4f> > & poses,
02415                                                                std::vector<float> & enthropies, int tesselation_level,
02416                                                                float view_angle, float radius_sphere, bool use_vertices)
02417 {
02418   if (rens_->GetNumberOfItems () > 1)
02419   {
02420     PCL_WARN ("[renderViewTesselatedSphere] Method works only with one renderer.\n");
02421     return;
02422   }
02423 
02424   rens_->InitTraversal ();
02425   vtkRenderer* renderer_pcl_vis = rens_->GetNextItem ();
02426   vtkActorCollection * actors = renderer_pcl_vis->GetActors ();
02427 
02428   if (actors->GetNumberOfItems () > 1)
02429     PCL_INFO ("[renderViewTesselatedSphere] Method only consider the first actor on the scene, more than one found.\n");
02430 
02431   //get vtk object from the visualizer
02432   actors->InitTraversal ();
02433   vtkActor * actor = actors->GetNextActor ();
02434   vtkSmartPointer<vtkPolyData> polydata;
02435   allocVtkPolyData (polydata);
02436   polydata->CopyStructure (actor->GetMapper ()->GetInput ());
02437 
02438   //center object
02439   double CoM[3];
02440   vtkIdType npts_com = 0, *ptIds_com = NULL;
02441   vtkSmartPointer<vtkCellArray> cells_com = polydata->GetPolys ();
02442 
02443   double center[3], p1_com[3], p2_com[3], p3_com[3], area_com, totalArea_com = 0;
02444   double comx = 0, comy = 0, comz = 0;
02445   for (cells_com->InitTraversal (); cells_com->GetNextCell (npts_com, ptIds_com);)
02446   {
02447     polydata->GetPoint (ptIds_com[0], p1_com);
02448     polydata->GetPoint (ptIds_com[1], p2_com);
02449     polydata->GetPoint (ptIds_com[2], p3_com);
02450     vtkTriangle::TriangleCenter (p1_com, p2_com, p3_com, center);
02451     area_com = vtkTriangle::TriangleArea (p1_com, p2_com, p3_com);
02452     comx += center[0] * area_com;
02453     comy += center[1] * area_com;
02454     comz += center[2] * area_com;
02455     totalArea_com += area_com;
02456   }
02457 
02458   CoM[0] = comx / totalArea_com;
02459   CoM[1] = comy / totalArea_com;
02460   CoM[2] = comz / totalArea_com;
02461 
02462   vtkSmartPointer<vtkTransform> trans_center = vtkSmartPointer<vtkTransform>::New ();
02463   trans_center->Translate (-CoM[0], -CoM[1], -CoM[2]);
02464   vtkSmartPointer<vtkMatrix4x4> matrixCenter = trans_center->GetMatrix ();
02465 
02466   vtkSmartPointer<vtkTransformFilter> trans_filter_center = vtkSmartPointer<vtkTransformFilter>::New ();
02467   trans_filter_center->SetTransform (trans_center);
02468   trans_filter_center->SetInput (polydata);
02469   trans_filter_center->Update ();
02470 
02471   vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
02472   mapper->SetInputConnection (trans_filter_center->GetOutputPort ());
02473   mapper->Update ();
02474 
02475   //scale so it fits in the unit sphere!
02476   double bb[6];
02477   mapper->GetBounds (bb);
02478   double ms = (std::max) ((std::fabs) (bb[0] - bb[1]),
02479                           (std::max) ((std::fabs) (bb[2] - bb[3]), (std::fabs) (bb[4] - bb[5])));
02480   double max_side = radius_sphere / 2.0;
02481   double scale_factor = max_side / ms;
02482 
02483   vtkSmartPointer<vtkTransform> trans_scale = vtkSmartPointer<vtkTransform>::New ();
02484   trans_scale->Scale (scale_factor, scale_factor, scale_factor);
02485   vtkSmartPointer<vtkMatrix4x4> matrixScale = trans_scale->GetMatrix ();
02486 
02487   vtkSmartPointer<vtkTransformFilter> trans_filter_scale = vtkSmartPointer<vtkTransformFilter>::New ();
02488   trans_filter_scale->SetTransform (trans_scale);
02489   trans_filter_scale->SetInputConnection (trans_filter_center->GetOutputPort ());
02490   trans_filter_scale->Update ();
02491 
02492   mapper->SetInputConnection (trans_filter_scale->GetOutputPort ());
02493   mapper->Update ();
02494 
02496   // * Compute area of the mesh
02498   vtkSmartPointer<vtkCellArray> cells = mapper->GetInput ()->GetPolys ();
02499   vtkIdType npts = 0, *ptIds = NULL;
02500 
02501   double p1[3], p2[3], p3[3], area, totalArea = 0;
02502   for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds);)
02503   {
02504     polydata->GetPoint (ptIds[0], p1);
02505     polydata->GetPoint (ptIds[1], p2);
02506     polydata->GetPoint (ptIds[2], p3);
02507     area = vtkTriangle::TriangleArea (p1, p2, p3);
02508     totalArea += area;
02509   }
02510 
02511   //create icosahedron
02512   vtkSmartPointer<vtkPlatonicSolidSource> ico = vtkSmartPointer<vtkPlatonicSolidSource>::New ();
02513   ico->SetSolidTypeToIcosahedron ();
02514   ico->Update ();
02515 
02516   //tesselate cells from icosahedron
02517   vtkSmartPointer<vtkLoopSubdivisionFilter> subdivide = vtkSmartPointer<vtkLoopSubdivisionFilter>::New ();
02518   subdivide->SetNumberOfSubdivisions (tesselation_level);
02519   subdivide->SetInputConnection (ico->GetOutputPort ());
02520 
02521   // Get camera positions
02522   vtkPolyData *sphere = subdivide->GetOutput ();
02523   sphere->Update ();
02524 
02525   std::vector<Eigen::Vector3f> cam_positions;
02526   if (!use_vertices)
02527   {
02528     vtkSmartPointer<vtkCellArray> cells_sphere = sphere->GetPolys ();
02529     cam_positions.resize (sphere->GetNumberOfPolys ());
02530 
02531     size_t i=0;
02532     for (cells_sphere->InitTraversal (); cells_sphere->GetNextCell (npts_com, ptIds_com);)
02533     {
02534       sphere->GetPoint (ptIds_com[0], p1_com);
02535       sphere->GetPoint (ptIds_com[1], p2_com);
02536       sphere->GetPoint (ptIds_com[2], p3_com);
02537       vtkTriangle::TriangleCenter (p1_com, p2_com, p3_com, center);
02538       cam_positions[i] = Eigen::Vector3f (center[0], center[1], center[2]);
02539       i++;
02540     }
02541 
02542   }
02543   else
02544   {
02545     cam_positions.resize (sphere->GetNumberOfPoints ());
02546     for (int i = 0; i < sphere->GetNumberOfPoints (); i++)
02547     {
02548       double cam_pos[3];
02549       sphere->GetPoint (i, cam_pos);
02550       cam_positions[i] = Eigen::Vector3f (cam_pos[0], cam_pos[1], cam_pos[2]);
02551     }
02552   }
02553 
02554   double camera_radius = radius_sphere;
02555   double cam_pos[3];
02556   double first_cam_pos[3];
02557 
02558   first_cam_pos[0] = cam_positions[0][0] * radius_sphere;
02559   first_cam_pos[1] = cam_positions[0][1] * radius_sphere;
02560   first_cam_pos[2] = cam_positions[0][2] * radius_sphere;
02561 
02562   //create renderer and window
02563   vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New ();
02564   vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New ();
02565   render_win->AddRenderer (renderer);
02566   render_win->SetSize (xres, yres);
02567   renderer->SetBackground (1.0, 0, 0);
02568 
02569   //create picker
02570   vtkSmartPointer<vtkWorldPointPicker> worldPicker = vtkSmartPointer<vtkWorldPointPicker>::New ();
02571 
02572   vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New ();
02573   cam->SetFocalPoint (0, 0, 0);
02574 
02575   Eigen::Vector3f cam_pos_3f = cam_positions[0];
02576   Eigen::Vector3f perp = cam_pos_3f.cross (Eigen::Vector3f::UnitY ());
02577   cam->SetViewUp (perp[0], perp[1], perp[2]);
02578 
02579   cam->SetPosition (first_cam_pos);
02580   cam->SetViewAngle (view_angle);
02581   cam->Modified ();
02582 
02583   //For each camera position, traposesnsform the object and render view
02584   for (size_t i = 0; i < cam_positions.size (); i++)
02585   {
02586     cam_pos[0] = cam_positions[i][0];
02587     cam_pos[1] = cam_positions[i][1];
02588     cam_pos[2] = cam_positions[i][2];
02589 
02590     //create temporal virtual camera
02591     vtkSmartPointer<vtkCamera> cam_tmp = vtkSmartPointer<vtkCamera>::New ();
02592     cam_tmp->SetViewAngle (view_angle);
02593 
02594     Eigen::Vector3f cam_pos_3f (cam_pos[0], cam_pos[1], cam_pos[2]);
02595     cam_pos_3f = cam_pos_3f.normalized ();
02596     Eigen::Vector3f test = Eigen::Vector3f::UnitY ();
02597 
02598     //If the view up is parallel to ray cam_pos - focalPoint then the transformation
02599     //is singular and no points are rendered...
02600     //make sure it is perpendicular
02601     if (fabs (cam_pos_3f.dot (test)) == 1)
02602     {
02603       //parallel, create
02604       test = cam_pos_3f.cross (Eigen::Vector3f::UnitX ());
02605     }
02606 
02607     cam_tmp->SetViewUp (test[0], test[1], test[2]);
02608 
02609     for (int k = 0; k < 3; k++)
02610     {
02611       cam_pos[k] = cam_pos[k] * camera_radius;
02612     }
02613 
02614     cam_tmp->SetPosition (cam_pos);
02615     cam_tmp->SetFocalPoint (0, 0, 0);
02616     cam_tmp->Modified ();
02617 
02618     //rotate model so it looks the same as if we would look from the new position
02619     vtkSmartPointer<vtkMatrix4x4> view_trans_inverted = vtkSmartPointer<vtkMatrix4x4>::New ();
02620     vtkMatrix4x4::Invert (cam->GetViewTransformMatrix (), view_trans_inverted);
02621     vtkSmartPointer<vtkTransform> trans_rot_pose = vtkSmartPointer<vtkTransform>::New ();
02622     trans_rot_pose->Identity ();
02623     trans_rot_pose->Concatenate (view_trans_inverted);
02624     trans_rot_pose->Concatenate (cam_tmp->GetViewTransformMatrix ());
02625     vtkSmartPointer<vtkTransformFilter> trans_rot_pose_filter = vtkSmartPointer<vtkTransformFilter>::New ();
02626     trans_rot_pose_filter->SetTransform (trans_rot_pose);
02627     trans_rot_pose_filter->SetInputConnection (trans_filter_scale->GetOutputPort ());
02628 
02629     //translate model so we can place camera at (0,0,0)
02630     vtkSmartPointer<vtkTransform> translation = vtkSmartPointer<vtkTransform>::New ();
02631     translation->Translate (first_cam_pos[0] * -1, first_cam_pos[1] * -1, first_cam_pos[2] * -1);
02632     vtkSmartPointer<vtkTransformFilter> translation_filter = vtkSmartPointer<vtkTransformFilter>::New ();
02633     translation_filter->SetTransform (translation);
02634     translation_filter->SetInputConnection (trans_rot_pose_filter->GetOutputPort ());
02635 
02636     //modify camera
02637     cam_tmp->SetPosition (0, 0, 0);
02638     cam_tmp->SetFocalPoint (first_cam_pos[0] * -1, first_cam_pos[1] * -1, first_cam_pos[2] * -1);
02639     cam_tmp->Modified ();
02640 
02641     //notice transformations for final pose
02642     vtkSmartPointer<vtkMatrix4x4> matrixRotModel = trans_rot_pose->GetMatrix ();
02643     vtkSmartPointer<vtkMatrix4x4> matrixTranslation = translation->GetMatrix ();
02644 
02645     mapper->SetInputConnection (translation_filter->GetOutputPort ());
02646     mapper->Update ();
02647 
02648     //render view
02649     vtkSmartPointer<vtkActor> actor_view = vtkSmartPointer<vtkActor>::New ();
02650     actor_view->SetMapper (mapper);
02651     renderer->SetActiveCamera (cam_tmp);
02652     renderer->AddActor (actor_view);
02653     renderer->Modified ();
02654     //renderer->ResetCameraClippingRange ();
02655     render_win->Render ();
02656 
02657     //back to real scale transform
02658     vtkSmartPointer<vtkTransform> backToRealScale = vtkSmartPointer<vtkTransform>::New ();
02659     backToRealScale->PostMultiply ();
02660     backToRealScale->Identity ();
02661     backToRealScale->Concatenate (matrixScale);
02662     backToRealScale->Concatenate (matrixTranslation);
02663     backToRealScale->Inverse ();
02664     backToRealScale->Modified ();
02665     backToRealScale->Concatenate (matrixTranslation);
02666     backToRealScale->Modified ();
02667 
02668     Eigen::Matrix4f backToRealScale_eigen;
02669     backToRealScale_eigen.setIdentity ();
02670 
02671     for (size_t x = 0; x < 4; x++)
02672       for (size_t y = 0; y < 4; y++)
02673         backToRealScale_eigen (x, y) = backToRealScale->GetMatrix ()->GetElement (x, y);
02674 
02675     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
02676 
02677     cloud->points.resize (xres * yres);
02678     cloud->width = xres * yres;
02679     cloud->height = 1;
02680 
02681     double coords[3];
02682     float * depth = new float[xres * yres];
02683     render_win->GetZbufferData (0, 0, xres - 1, yres - 1, &(depth[0]));
02684 
02685     int count_valid_depth_pixels = 0;
02686     for (size_t x = 0; x < (size_t)xres; x++)
02687     {
02688       for (size_t y = 0; y < (size_t)yres; y++)
02689       {
02690         float value = depth[y * xres + x];
02691         if (value == 1.0)
02692           continue;
02693 
02694         worldPicker->Pick (x, y, value, renderer);
02695         worldPicker->GetPickPosition (coords);
02696         cloud->points[count_valid_depth_pixels].x = coords[0];
02697         cloud->points[count_valid_depth_pixels].y = coords[1];
02698         cloud->points[count_valid_depth_pixels].z = coords[2];
02699         cloud->points[count_valid_depth_pixels].getVector4fMap () = backToRealScale_eigen
02700             * cloud->points[count_valid_depth_pixels].getVector4fMap ();
02701         count_valid_depth_pixels++;
02702       }
02703     }
02704 
02705     delete[] depth;
02706 
02708     // * Compute area of the mesh
02710 
02711     vtkSmartPointer<vtkPolyData> polydata = mapper->GetInput ();
02712     polydata->BuildCells ();
02713 
02714     vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();
02715     vtkIdType npts = 0, *ptIds = NULL;
02716 
02717     double p1[3], p2[3], p3[3], area, totalArea = 0;
02718     for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds);)
02719     {
02720       polydata->GetPoint (ptIds[0], p1);
02721       polydata->GetPoint (ptIds[1], p2);
02722       polydata->GetPoint (ptIds[2], p3);
02723       area = vtkTriangle::TriangleArea (p1, p2, p3);
02724       totalArea += area;
02725     }
02726 
02728     // * Select visible cells (triangles)
02730     vtkSmartPointer<vtkVisibleCellSelector> selector = vtkSmartPointer<vtkVisibleCellSelector>::New ();
02731     vtkSmartPointer<vtkIdTypeArray> selection = vtkSmartPointer<vtkIdTypeArray>::New ();
02732 
02733     selector->SetRenderer (renderer);
02734     selector->SetArea (0, 0, xres - 1, yres - 1);
02735     selector->Select ();
02736     selector->GetSelectedIds (selection);
02737 
02738     double visible_area = 0;
02739     for (int sel_id = 3; sel_id < (selection->GetNumberOfTuples () * selection->GetNumberOfComponents ()); sel_id
02740         += selection->GetNumberOfComponents ())
02741     {
02742       int id_mesh = selection->GetValue (sel_id);
02743 
02744       if (id_mesh >= polydata->GetNumberOfCells ())
02745         continue;
02746 
02747       vtkCell * cell = polydata->GetCell (id_mesh);
02748       vtkTriangle* triangle = dynamic_cast<vtkTriangle*> (cell);
02749       double p0[3];
02750       double p1[3];
02751       double p2[3];
02752       triangle->GetPoints ()->GetPoint (0, p0);
02753       triangle->GetPoints ()->GetPoint (1, p1);
02754       triangle->GetPoints ()->GetPoint (2, p2);
02755       visible_area += vtkTriangle::TriangleArea (p0, p1, p2);
02756     }
02757 
02758     //THIS CAN BE USED WHEN VTK >= 5.4 IS REQUIRED... vtkVisibleCellSelector is deprecated from VTK5.4
02759     /*vtkSmartPointer<vtkHardwareSelector> hardware_selector = vtkSmartPointer<vtkHardwareSelector>::New ();
02760      hardware_selector->ClearBuffers();
02761      vtkSmartPointer<vtkSelection> hdw_selection = vtkSmartPointer<vtkSelection>::New ();
02762      hardware_selector->SetRenderer (renderer);
02763      hardware_selector->SetArea (0, 0, xres - 1, yres - 1);
02764      hardware_selector->SetFieldAssociation(vtkDataObject::FIELD_ASSOCIATION_CELLS);
02765      hdw_selection = hardware_selector->Select ();
02766      vtkSmartPointer<vtkIdTypeArray> ids = vtkSmartPointer<vtkIdTypeArray>::New ();
02767      ids = vtkIdTypeArray::SafeDownCast(hdw_selection->GetNode(0)->GetSelectionList());
02768      double visible_area = 0;
02769      for (int sel_id = 0; sel_id < (ids->GetNumberOfTuples ()); sel_id++)
02770      {
02771      int id_mesh = selection->GetValue (sel_id);
02772      vtkCell * cell = polydata->GetCell (id_mesh);
02773      vtkTriangle* triangle = dynamic_cast<vtkTriangle*> (cell);
02774      double p0[3];
02775      double p1[3];
02776      double p2[3];
02777      triangle->GetPoints ()->GetPoint (0, p0);
02778      triangle->GetPoints ()->GetPoint (1, p1);
02779      triangle->GetPoints ()->GetPoint (2, p2);
02780      area = vtkTriangle::TriangleArea (p0, p1, p2);
02781      visible_area += area;
02782      }*/
02783 
02784     enthropies.push_back (visible_area / totalArea);
02785 
02786     cloud->points.resize (count_valid_depth_pixels);
02787     cloud->width = count_valid_depth_pixels;
02788 
02789     //transform cloud to give camera coordinates instead of world coordinates!
02790     vtkSmartPointer<vtkMatrix4x4> view_transform = cam_tmp->GetViewTransformMatrix ();
02791     Eigen::Matrix4f trans_view;
02792     trans_view.setIdentity ();
02793 
02794     for (size_t x = 0; x < 4; x++)
02795       for (size_t y = 0; y < 4; y++)
02796         trans_view (x, y) = view_transform->GetElement (x, y);
02797 
02798     //NOTE: vtk view coordinate system is different than the standard camera coordinates (z forward, y down, x right)
02799     //thus, the fliping in y and z
02800     for (size_t i = 0; i < cloud->points.size (); i++)
02801     {
02802       cloud->points[i].getVector4fMap () = trans_view * cloud->points[i].getVector4fMap ();
02803       cloud->points[i].y *= -1.0;
02804       cloud->points[i].z *= -1.0;
02805     }
02806 
02807     renderer->RemoveActor (actor_view);
02808 
02809     clouds.push_back (*cloud);
02810 
02811     //create pose, from OBJECT coordinates to CAMERA coordinates!
02812     vtkSmartPointer<vtkTransform> transOCtoCC = vtkSmartPointer<vtkTransform>::New ();
02813     transOCtoCC->PostMultiply ();
02814     transOCtoCC->Identity ();
02815     transOCtoCC->Concatenate (matrixCenter);
02816     transOCtoCC->Concatenate (matrixRotModel);
02817     transOCtoCC->Concatenate (matrixTranslation);
02818     transOCtoCC->Concatenate (cam_tmp->GetViewTransformMatrix ());
02819 
02820     //NOTE: vtk view coordinate system is different than the standard camera coordinates (z forward, y down, x right)
02821     //thus, the fliping in y and z
02822     vtkSmartPointer<vtkMatrix4x4> cameraSTD = vtkSmartPointer<vtkMatrix4x4>::New ();
02823     cameraSTD->Identity ();
02824     cameraSTD->SetElement (0, 0, 1);
02825     cameraSTD->SetElement (1, 1, -1);
02826     cameraSTD->SetElement (2, 2, -1);
02827 
02828     transOCtoCC->Concatenate (cameraSTD);
02829     transOCtoCC->Modified ();
02830 
02831     Eigen::Matrix4f pose_view;
02832     pose_view.setIdentity ();
02833 
02834     for (size_t x = 0; x < 4; x++)
02835       for (size_t y = 0; y < 4; y++)
02836         pose_view (x, y) = transOCtoCC->GetMatrix ()->GetElement (x, y);
02837 
02838     poses.push_back (pose_view);
02839 
02840   }
02841 }
02842 
02844 void
02845 pcl::visualization::PCLVisualizer::renderView (int xres, int yres, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud)
02846 {
02847   if (rens_->GetNumberOfItems () > 1)
02848   {
02849     PCL_WARN("[renderView] Method will render only the first viewport\n");
02850     return;
02851   }
02852 
02853   //create render window with first element of rens_ (viewport 0)
02854   vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New ();
02855   rens_->InitTraversal ();
02856   vtkSmartPointer<vtkRenderer> renderer = rens_->GetNextItem ();
02857   render_win->AddRenderer (renderer);
02858   render_win->SetSize (xres, yres);
02859   renderer->SetBackground (1.0, 0.5, 0.5);
02860 
02861   vtkSmartPointer<vtkWorldPointPicker> worldPicker = vtkSmartPointer<vtkWorldPointPicker>::New ();
02862 
02863   render_win->Render ();
02864 
02865   cloud->points.resize (xres * yres);
02866   cloud->width = xres * yres;
02867   cloud->height = 1;
02868 
02869   double coords[3];
02870   float * depth = new float[xres * yres];
02871   render_win->GetZbufferData (0, 0, xres - 1, yres - 1, &(depth[0]));
02872 
02873   int count_valid_depth_pixels = 0;
02874   for (size_t x = 0; x < (size_t)xres; x++)
02875   {
02876     for (size_t y = 0; y < (size_t)yres; y++)
02877     {
02878       float value = depth[y * xres + x];
02879 
02880       if (value == 1.0)
02881         continue;
02882 
02883       worldPicker->Pick (x, y, value, renderer);
02884       worldPicker->GetPickPosition (coords);
02885       cloud->points[count_valid_depth_pixels].x = coords[0];
02886       cloud->points[count_valid_depth_pixels].y = coords[1];
02887       cloud->points[count_valid_depth_pixels].z = coords[2];
02888       count_valid_depth_pixels++;
02889     }
02890   }
02891 
02892   delete[] depth;
02893 
02894   cloud->points.resize (count_valid_depth_pixels);
02895   cloud->width = count_valid_depth_pixels;
02896 
02897   //transform cloud to give camera coordinates instead of world coordinates!
02898   vtkSmartPointer<vtkCamera> active_camera = renderer->GetActiveCamera ();
02899   vtkSmartPointer<vtkMatrix4x4> view_transform = active_camera->GetViewTransformMatrix ();
02900   Eigen::Matrix4f trans_view;
02901   trans_view.setIdentity ();
02902 
02903   for (size_t x = 0; x < 4; x++)
02904     for (size_t y = 0; y < 4; y++)
02905       trans_view (x, y) = view_transform->GetElement (x, y);
02906 
02907   //NOTE: vtk view coordinate system is different than the standard camera coordinates (z forward, y down, x right)
02908   //thus, the fliping in y and z
02909   for (size_t i = 0; i < cloud->points.size (); i++)
02910   {
02911     cloud->points[i].getVector4fMap () = trans_view * cloud->points[i].getVector4fMap ();
02912     cloud->points[i].y *= -1.0;
02913     cloud->points[i].z *= -1.0;
02914   }
02915 }
02916 
02918 bool
02919 pcl::visualization::PCLVisualizer::fromHandlersToScreen (
02920     const GeometryHandlerConstPtr &geometry_handler,
02921     const ColorHandlerConstPtr &color_handler,
02922     const std::string &id,
02923     int viewport,
02924     const Eigen::Vector4f& sensor_origin,
02925     const Eigen::Quaternion<float>& sensor_orientation)
02926 {
02927   if (!geometry_handler->isCapable ())
02928   {
02929     PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ());
02930     return (false);
02931   }
02932 
02933   if (!color_handler->isCapable ())
02934   {
02935     PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ());
02936     return (false);
02937   }
02938 
02939   vtkSmartPointer<vtkPolyData> polydata;
02940   vtkSmartPointer<vtkIdTypeArray> initcells;
02941   // Convert the PointCloud to VTK PolyData
02942   convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
02943   // use the given geometry handler
02944   polydata->Update ();
02945 
02946   // Get the colors from the handler
02947   vtkSmartPointer<vtkDataArray> scalars;
02948   color_handler->getColor (scalars);
02949   polydata->GetPointData ()->SetScalars (scalars);
02950   double minmax[2];
02951   scalars->GetRange (minmax);
02952 
02953   // Create an Actor
02954   vtkSmartPointer<vtkLODActor> actor;
02955   createActorFromVTKDataSet (polydata, actor);
02956   actor->GetMapper ()->SetScalarRange (minmax);
02957 
02958   // Add it to all renderers
02959   addActorToRenderer (actor, viewport);
02960 
02961   // Save the pointer/ID pair to the global actor map
02962   (*cloud_actor_map_)[id].actor = actor;
02963   (*cloud_actor_map_)[id].cells = reinterpret_cast<vtkPolyDataMapper*>(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData ();
02964   (*cloud_actor_map_)[id].geometry_handlers.push_back (geometry_handler);
02965   (*cloud_actor_map_)[id].color_handlers.push_back (color_handler);
02966 
02967   // Save the viewpoint transformation matrix to the global actor map
02968   vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New();
02969   convertToVtkMatrix (sensor_origin, sensor_orientation, transformation);
02970   (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation;
02971 
02972   return (true);
02973 }
02974 
02976 void
02977 pcl::visualization::PCLVisualizer::updateCells (vtkSmartPointer<vtkIdTypeArray> &cells,
02978                                                 vtkSmartPointer<vtkIdTypeArray> &initcells,
02979                                                 vtkIdType nr_points)
02980 {
02981   // If no init cells and cells has not been initialized...
02982   if (!cells)
02983     cells = vtkSmartPointer<vtkIdTypeArray>::New ();
02984 
02985   // If we have less values then we need to recreate the array
02986   if (cells->GetNumberOfTuples () < nr_points)
02987   {
02988     cells = vtkSmartPointer<vtkIdTypeArray>::New ();
02989 
02990     // If init cells is given, and there's enough data in it, use it
02991     if (initcells && initcells->GetNumberOfTuples () >= nr_points)
02992     {
02993       cells->DeepCopy (initcells);
02994       cells->SetNumberOfComponents (2);
02995       cells->SetNumberOfTuples (nr_points);
02996     }
02997     else
02998     {
02999       // If the number of tuples is still too small, we need to recreate the array
03000       cells->SetNumberOfComponents (2);
03001       cells->SetNumberOfTuples (nr_points);
03002       vtkIdType *cell = cells->GetPointer (0);
03003       // Fill it with 1s
03004       std::fill_n (cell, nr_points * 2, 1);
03005       cell++;
03006       for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
03007         *cell = i;
03008       // Save the results in initcells
03009       initcells = vtkSmartPointer<vtkIdTypeArray>::New ();
03010       initcells->DeepCopy (cells);
03011     }
03012   }
03013   else
03014   {
03015     // The assumption here is that the current set of cells has more data than needed
03016     cells->SetNumberOfComponents (2);
03017     cells->SetNumberOfTuples (nr_points);
03018   }
03019 }
03020 
03022 void
03023 pcl::visualization::PCLVisualizer::allocVtkPolyData (vtkSmartPointer<vtkAppendPolyData> &polydata)
03024 {
03025   polydata = vtkSmartPointer<vtkAppendPolyData>::New ();
03026 }
03028 void
03029 pcl::visualization::PCLVisualizer::allocVtkPolyData (vtkSmartPointer<vtkPolyData> &polydata)
03030 {
03031   polydata = vtkSmartPointer<vtkPolyData>::New ();
03032 }
03034 void
03035 pcl::visualization::PCLVisualizer::allocVtkUnstructuredGrid (vtkSmartPointer<vtkUnstructuredGrid> &polydata)
03036 {
03037   polydata = vtkSmartPointer<vtkUnstructuredGrid>::New ();
03038 }
03039 
03041 void
03042 pcl::visualization::PCLVisualizer::getTransformationMatrix (
03043     const Eigen::Vector4f &origin,
03044     const Eigen::Quaternion<float> &orientation,
03045     Eigen::Matrix4f &transformation)
03046 {
03047   transformation.setIdentity ();
03048   transformation.block<3,3>(0,0) = orientation.toRotationMatrix ();
03049   transformation.block<3,1>(0,3) = origin.head (3);
03050 }
03051 
03053 void
03054 pcl::visualization::PCLVisualizer::convertToVtkMatrix (
03055     const Eigen::Vector4f &origin,
03056     const Eigen::Quaternion<float> &orientation,
03057     vtkSmartPointer<vtkMatrix4x4> &vtk_matrix)
03058 {
03059   // set rotation
03060   Eigen::Matrix3f rot = orientation.toRotationMatrix ();
03061   for (int i = 0; i < 3; i++)
03062     for (int k = 0; k < 3; k++)
03063       vtk_matrix->SetElement (i, k, rot (i, k));
03064 
03065   // set translation
03066   vtk_matrix->SetElement (0, 3, origin (0));
03067   vtk_matrix->SetElement (1, 3, origin (1));
03068   vtk_matrix->SetElement (2, 3, origin (2));
03069   vtk_matrix->SetElement (3, 3, 1.0f);
03070 }
03071 
03073 void
03074 pcl::visualization::PCLVisualizer::convertToVtkMatrix (
03075     const Eigen::Matrix4f &m,
03076     vtkSmartPointer<vtkMatrix4x4> &vtk_matrix)
03077 {
03078   for (int i = 0; i < 4; i++)
03079     for (int k = 0; k < 4; k++)
03080       vtk_matrix->SetElement (i, k, m (i, k));
03081 }
03082 
03084 bool
03085 pcl::visualization::PCLVisualizer::addPointCloud (
03086     const sensor_msgs::PointCloud2::ConstPtr &cloud,
03087     const GeometryHandlerConstPtr &geometry_handler,
03088     const ColorHandlerConstPtr &color_handler,
03089     const Eigen::Vector4f& sensor_origin,
03090     const Eigen::Quaternion<float>& sensor_orientation,
03091     const std::string &id, int viewport)
03092 {
03093   // Check to see if this entry already exists (has it been already added to the visualizer?)
03094   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
03095   if (am_it != cloud_actor_map_->end ())
03096   {
03097     // Here we're just pushing the handlers onto the queue. If needed, something fancier could
03098     // be done such as checking if a specific handler already exists, etc.
03099     am_it->second.geometry_handlers.push_back (geometry_handler);
03100     am_it->second.color_handlers.push_back (color_handler);
03101     return (true);
03102   }
03103   return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, sensor_origin, sensor_orientation));
03104 }
03105 
03107 bool
03108 pcl::visualization::PCLVisualizer::addPointCloud (
03109     const sensor_msgs::PointCloud2::ConstPtr &cloud,
03110     const GeometryHandlerConstPtr &geometry_handler,
03111     const Eigen::Vector4f& sensor_origin,
03112     const Eigen::Quaternion<float>& sensor_orientation,
03113     const std::string &id, int viewport)
03114 {
03115   // Check to see if this ID entry already exists (has it been already added to the visualizer?)
03116   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
03117 
03118   if (am_it != cloud_actor_map_->end ())
03119   {
03120     // Here we're just pushing the handlers onto the queue. If needed, something fancier could
03121     // be done such as checking if a specific handler already exists, etc.
03122     am_it->second.geometry_handlers.push_back (geometry_handler);
03123     return (true);
03124   }
03125 
03126   PointCloudColorHandlerCustom<sensor_msgs::PointCloud2>::Ptr color_handler (new PointCloudColorHandlerCustom<sensor_msgs::PointCloud2> (cloud, 255, 255, 255));
03127   return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, sensor_origin, sensor_orientation));
03128 }
03129 
03131 bool
03132 pcl::visualization::PCLVisualizer::addPointCloud (
03133     const sensor_msgs::PointCloud2::ConstPtr &cloud,
03134     const ColorHandlerConstPtr &color_handler,
03135     const Eigen::Vector4f& sensor_origin,
03136     const Eigen::Quaternion<float>& sensor_orientation,
03137     const std::string &id, int viewport)
03138 {
03139   // Check to see if this entry already exists (has it been already added to the visualizer?)
03140   CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
03141   if (am_it != cloud_actor_map_->end ())
03142   {
03143     // Here we're just pushing the handlers onto the queue. If needed, something fancier could
03144     // be done such as checking if a specific handler already exists, etc.
03145     am_it->second.color_handlers.push_back (color_handler);
03146     return (true);
03147   }
03148 
03149   PointCloudGeometryHandlerXYZ<sensor_msgs::PointCloud2>::Ptr geometry_handler (new PointCloudGeometryHandlerXYZ<sensor_msgs::PointCloud2> (cloud));
03150   return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport, sensor_origin, sensor_orientation));
03151 }
03152 
03153 
03157 void
03158 pcl::visualization::FPSCallback::Execute (vtkObject *caller, unsigned long, void*)
03159 {
03160   vtkRenderer *ren = reinterpret_cast<vtkRenderer *> (caller);
03161   float fps = 1.0 / ren->GetLastRenderTimeInSeconds ();
03162   char buf[128];
03163   sprintf (buf, "%.1f FPS", fps);
03164   actor_->SetInput (buf);
03165 }


pcl
Author(s): Open Perception
autogenerated on Mon Oct 6 2014 03:16:28