$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2010, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * $Id: pcl_visualizer.cpp 36905 2011-05-27 00:34:09Z michael.s.dixon $ 00035 * 00036 */ 00037 00038 #include <pcl/common/common_headers.h> 00039 #include <pcl/console/print.h> 00040 #include <pcl_visualization/common/common.h> 00041 #include <pcl_visualization/pcl_visualizer.h> 00042 #include <vtkTextActor.h> 00043 #include <vtkTextProperty.h> 00044 #include <vtkCellData.h> 00045 00047 pcl_visualization::PCLVisualizer::PCLVisualizer (const std::string &name) : 00048 rens_ (vtkSmartPointer<vtkRendererCollection>::New ()), 00049 style_ (vtkSmartPointer<pcl_visualization::PCLVisualizerInteractorStyle>::New ()) 00050 { 00051 // FPS callback 00052 vtkSmartPointer<vtkTextActor> txt = vtkSmartPointer<vtkTextActor>::New (); 00053 vtkSmartPointer<FPSCallback> update_fps = vtkSmartPointer<FPSCallback>::New (); 00054 update_fps->setTextActor (txt); 00055 00056 // Create a Renderer 00057 vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New (); 00058 ren->AddObserver (vtkCommand::EndEvent, update_fps); 00059 ren->AddActor (txt); 00060 // Add it to the list of renderers 00061 rens_->AddItem (ren); 00062 00063 // Create a RendererWindow 00064 win_ = vtkSmartPointer<vtkRenderWindow>::New (); 00065 win_->SetWindowName (name.c_str ()); 00066 win_->SetStereoTypeToAnaglyph (); 00067 00068 // Get screen size 00069 int *scr_size = win_->GetScreenSize (); 00070 // Set the window size as 1/2 of the screen size 00071 win_->SetSize (scr_size[0] / 2, scr_size[1] / 2); 00072 00073 // Add all renderers to the window 00074 rens_->InitTraversal (); 00075 vtkRenderer* renderer = NULL; 00076 while ((renderer = rens_->GetNextItem ()) != NULL) 00077 win_->AddRenderer (renderer); 00078 00079 // Create the interactor style 00080 style_->Initialize (); 00081 style_->setRendererCollection (rens_); 00082 style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00083 style_->UseTimersOn (); 00084 00085 // Create the interactor 00086 //interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New (); 00087 interactor_ = vtkSmartPointer<PCLVisualizerInteractor>::New (); 00088 00089 interactor_->SetRenderWindow (win_); 00090 interactor_->SetInteractorStyle (style_); 00091 interactor_->SetDesiredUpdateRate (30.0); 00092 // Initialize and create timer 00093 interactor_->Initialize (); 00094 interactor_->CreateRepeatingTimer (5000L); 00095 00096 exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New (); 00097 exit_main_loop_timer_callback_->pcl_visualizer = this; 00098 exit_main_loop_timer_callback_->right_timer_id = -1; 00099 interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_); 00100 00101 exit_callback_ = vtkSmartPointer<ExitCallback>::New (); 00102 exit_callback_->pcl_visualizer = this; 00103 interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_); 00104 00105 resetStoppedFlag (); 00106 } 00107 00109 pcl_visualization::PCLVisualizer::PCLVisualizer (int &argc, char **argv, const std::string &name, PCLVisualizerInteractorStyle* style) : 00110 rens_ (vtkSmartPointer<vtkRendererCollection>::New ()) 00111 { 00112 style_ = style; 00113 00114 // FPS callback 00115 vtkSmartPointer<vtkTextActor> txt = vtkSmartPointer<vtkTextActor>::New (); 00116 vtkSmartPointer<FPSCallback> update_fps = vtkSmartPointer<FPSCallback>::New (); 00117 update_fps->setTextActor (txt); 00118 00119 // Create a Renderer 00120 vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New (); 00121 ren->AddObserver (vtkCommand::EndEvent, update_fps); 00122 ren->AddActor (txt); 00123 // Add it to the list of renderers 00124 rens_->AddItem (ren); 00125 00126 // Create a RendererWindow 00127 win_ = vtkSmartPointer<vtkRenderWindow>::New (); 00128 win_->SetWindowName (name.c_str ()); 00129 win_->SetStereoTypeToAnaglyph (); 00130 00131 // Get screen size 00132 int *scr_size = win_->GetScreenSize (); 00133 camera_.window_size[0] = scr_size[0]; camera_.window_size[1] = scr_size[1] / 2; 00134 camera_.window_pos[0] = camera_.window_pos[1] = 0; 00135 00136 // Set default camera parameters 00137 initCameraParameters (); 00138 00139 // Parse the camera settings and update the internal camera 00140 getCameraParameters (argc, argv); 00141 updateCamera (); 00142 // Set the window size as 1/2 of the screen size or the user given parameter 00143 win_->SetSize (camera_.window_size[0], camera_.window_size[1]); 00144 win_->SetPosition (camera_.window_pos[0], camera_.window_pos[1]); 00145 00146 // Add all renderers to the window 00147 rens_->InitTraversal (); 00148 vtkRenderer* renderer = NULL; 00149 while ((renderer = rens_->GetNextItem ()) != NULL) 00150 win_->AddRenderer (renderer); 00151 00152 // Create the interactor style 00153 style_->Initialize (); 00154 style_->setRendererCollection (rens_); 00155 style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00156 style_->UseTimersOn (); 00157 00158 // Create the interactor 00159 //interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New (); 00160 interactor_ = vtkSmartPointer<PCLVisualizerInteractor>::New (); 00161 00162 interactor_->SetRenderWindow (win_); 00163 interactor_->SetInteractorStyle (style_); 00164 interactor_->SetDesiredUpdateRate (30.0); 00165 // Initialize and create timer 00166 interactor_->Initialize (); 00167 interactor_->CreateRepeatingTimer (5000L); 00168 00169 exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New(); 00170 exit_main_loop_timer_callback_->pcl_visualizer = this; 00171 exit_main_loop_timer_callback_->right_timer_id = -1; 00172 interactor_->AddObserver(vtkCommand::TimerEvent, exit_main_loop_timer_callback_); 00173 00174 exit_callback_ = vtkSmartPointer<ExitCallback>::New(); 00175 exit_callback_->pcl_visualizer = this; 00176 interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_); 00177 00178 resetStoppedFlag (); 00179 } 00180 00182 pcl_visualization::PCLVisualizer::~PCLVisualizer () 00183 { 00184 // Clear the collections 00185 rens_->RemoveAllItems (); 00186 } 00187 00189 void 00190 pcl_visualization::PCLVisualizer::spin () 00191 { 00192 resetStoppedFlag (); 00193 // Render the window before we start the interactor 00194 win_->Render(); 00195 interactor_->Start (); 00196 } 00197 00199 void 00200 pcl_visualization::PCLVisualizer::spinOnce (int time, bool force_redraw) 00201 { 00202 resetStoppedFlag (); 00203 00204 if (time <= 0) 00205 time = 1; 00206 00207 if (force_redraw) 00208 { 00209 interactor_->Render(); 00210 exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer(time); 00211 interactor_->Start(); 00212 interactor_->DestroyTimer(exit_main_loop_timer_callback_->right_timer_id); 00213 return; 00214 } 00215 00216 DO_EVERY(1.0/interactor_->GetDesiredUpdateRate(), 00217 interactor_->Render(); 00218 exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer(time); 00219 interactor_->Start(); 00220 interactor_->DestroyTimer(exit_main_loop_timer_callback_->right_timer_id); 00221 ); 00222 } 00223 00225 void 00226 pcl_visualization::PCLVisualizer::addCoordinateSystem (double scale, int viewport) 00227 { 00228 vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New (); 00229 axes->SetOrigin (0, 0, 0); 00230 axes->SetScaleFactor (scale); 00231 00232 vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New (); 00233 axes_colors->Allocate (6); 00234 axes_colors->InsertNextValue (0.0); 00235 axes_colors->InsertNextValue (0.0); 00236 axes_colors->InsertNextValue (0.5); 00237 axes_colors->InsertNextValue (0.5); 00238 axes_colors->InsertNextValue (1.0); 00239 axes_colors->InsertNextValue (1.0); 00240 00241 vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput (); 00242 axes_data->Update (); 00243 axes_data->GetPointData ()->SetScalars (axes_colors); 00244 00245 vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New (); 00246 axes_tubes->SetInput (axes_data); 00247 axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); 00248 axes_tubes->SetNumberOfSides (6); 00249 00250 vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New (); 00251 axes_mapper->SetScalarModeToUsePointData (); 00252 axes_mapper->SetInput (axes_tubes->GetOutput ()); 00253 00254 vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New (); 00255 axes_actor->SetMapper (axes_mapper); 00256 00257 addActorToRenderer (axes_actor, viewport); 00258 } 00259 00261 void 00262 pcl_visualization::PCLVisualizer::addCoordinateSystem (double scale, float x, float y, float z, int viewport) 00263 { 00264 vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New (); 00265 axes->SetOrigin (0, 0, 0); 00266 axes->SetScaleFactor (scale); 00267 00268 vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New (); 00269 axes_colors->Allocate (6); 00270 axes_colors->InsertNextValue (0.0); 00271 axes_colors->InsertNextValue (0.0); 00272 axes_colors->InsertNextValue (0.5); 00273 axes_colors->InsertNextValue (0.5); 00274 axes_colors->InsertNextValue (1.0); 00275 axes_colors->InsertNextValue (1.0); 00276 00277 vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput (); 00278 axes_data->Update (); 00279 axes_data->GetPointData ()->SetScalars (axes_colors); 00280 00281 vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New (); 00282 axes_tubes->SetInput (axes_data); 00283 axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); 00284 axes_tubes->SetNumberOfSides (6); 00285 00286 vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New (); 00287 axes_mapper->SetScalarModeToUsePointData (); 00288 axes_mapper->SetInput (axes_tubes->GetOutput ()); 00289 00290 vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New (); 00291 axes_actor->SetMapper (axes_mapper); 00292 axes_actor->SetPosition (x, y, z); 00293 00294 addActorToRenderer (axes_actor, viewport); 00295 } 00296 00298 void 00299 pcl_visualization::PCLVisualizer::removeCoordinateSystem (int viewport) 00300 { 00301 /* vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New (); 00302 axes->SetOrigin (0, 0, 0); 00303 axes->SetScaleFactor (scale); 00304 00305 vtkSmartPointer<vtkFloatArray> axes_colors = vtkSmartPointer<vtkFloatArray>::New (); 00306 axes_colors->Allocate (6); 00307 axes_colors->InsertNextValue (0.0); 00308 axes_colors->InsertNextValue (0.0); 00309 axes_colors->InsertNextValue (0.5); 00310 axes_colors->InsertNextValue (0.5); 00311 axes_colors->InsertNextValue (1.0); 00312 axes_colors->InsertNextValue (1.0); 00313 00314 vtkSmartPointer<vtkPolyData> axes_data = axes->GetOutput (); 00315 axes_data->Update (); 00316 axes_data->GetPointData ()->SetScalars (axes_colors); 00317 00318 vtkSmartPointer<vtkTubeFilter> axes_tubes = vtkSmartPointer<vtkTubeFilter>::New (); 00319 axes_tubes->SetInput (axes_data); 00320 axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); 00321 axes_tubes->SetNumberOfSides (6); 00322 00323 vtkSmartPointer<vtkPolyDataMapper> axes_mapper = vtkSmartPointer<vtkPolyDataMapper>::New (); 00324 axes_mapper->SetScalarModeToUsePointData (); 00325 axes_mapper->SetInput (axes_tubes->GetOutput ()); 00326 00327 vtkSmartPointer<vtkLODActor> axes_actor = vtkSmartPointer<vtkLODActor>::New (); 00328 axes_actor->SetMapper (axes_mapper); 00329 00330 addActorToRenderer (axes_actor, viewport);*/ 00331 } 00332 00334 bool 00335 pcl_visualization::PCLVisualizer::removePointCloud (const std::string &id, int viewport) 00336 { 00337 // Check to see if the given ID entry exists 00338 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 00339 00340 if (am_it == cloud_actor_map_.end ()) 00341 { 00342 //pcl::console::print_warn ("[removePointCloud] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ()); 00343 return (false); 00344 } 00345 00346 // Get the actor pointer 00347 CloudActor act = am_it->second; 00348 vtkSmartPointer<vtkLODActor> actor = act.actor; 00349 am_it->second.geometry_handlers.clear (); 00350 am_it->second.color_handlers.clear (); 00351 //vtkSmartPointer<vtkLODActor> actor = am_it->second; 00352 00353 // Remove it from all renderers 00354 removeActorFromRenderer (actor, viewport); 00355 00356 // Remove the pointer/ID pair to the global actor map 00357 cloud_actor_map_.erase (am_it); 00358 style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00359 return (true); 00360 } 00361 00363 bool 00364 pcl_visualization::PCLVisualizer::removeShape (const std::string &id, int viewport) 00365 { 00366 // Check to see if the given ID entry exists 00367 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 00368 00369 if (am_it == shape_actor_map_.end ()) 00370 { 00371 //pcl::console::print_warn ("[removeSape] Could not find any shape with id <%s>!\n", id.c_str ()); 00372 return (false); 00373 } 00374 00375 // Remove it from all renderers 00376 removeActorFromRenderer (am_it->second, viewport); 00377 00378 // Remove the pointer/ID pair to the global actor map 00379 shape_actor_map_.erase (am_it); 00380 return (true); 00381 } 00382 00384 bool 00385 pcl_visualization::PCLVisualizer::addPointCloudPrincipalCurvatures (const pcl::PointCloud<pcl::PointXYZ> &cloud, 00386 const pcl::PointCloud<pcl::Normal> &normals, 00387 const pcl::PointCloud<pcl::PrincipalCurvatures> &pcs, 00388 int level, double scale, 00389 const std::string &id, int viewport) 00390 { 00391 if (pcs.points.size () != cloud.points.size () || normals.points.size () != cloud.points.size ()) 00392 { 00393 pcl::console::print_error ("[addPointCloudPrincipalCurvatures] The number of points differs from the number of principal curvatures/normals!\n"); 00394 return (false); 00395 } 00396 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00397 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 00398 00399 if (am_it != cloud_actor_map_.end ()) 00400 { 00401 pcl::console::print_warn ("[addPointCloudPrincipalCurvatures] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00402 return (false); 00403 } 00404 00405 vtkSmartPointer<vtkAppendPolyData> polydata_1 = vtkSmartPointer<vtkAppendPolyData>::New (); 00406 vtkSmartPointer<vtkAppendPolyData> polydata_2 = vtkSmartPointer<vtkAppendPolyData>::New (); 00407 00408 // Setup two colors - one for each line 00409 unsigned char green[3] = {0, 255, 0}; 00410 unsigned char blue[3] = {0, 0, 255}; 00411 00412 // Setup the colors array 00413 vtkSmartPointer<vtkUnsignedCharArray> line_1_colors =vtkSmartPointer<vtkUnsignedCharArray>::New (); 00414 line_1_colors->SetNumberOfComponents (3); 00415 line_1_colors->SetName ("Colors"); 00416 vtkSmartPointer<vtkUnsignedCharArray> line_2_colors =vtkSmartPointer<vtkUnsignedCharArray>::New (); 00417 line_2_colors->SetNumberOfComponents (3); 00418 line_2_colors->SetName ("Colors"); 00419 00420 // Create the first sets of lines 00421 for (size_t i = 0; i < cloud.points.size (); i+=level) 00422 { 00423 pcl::PointXYZ p = cloud.points[i]; 00424 p.x += (pcs.points[i].pc1 * pcs.points[i].principal_curvature[0]) * scale; 00425 p.y += (pcs.points[i].pc1 * pcs.points[i].principal_curvature[1]) * scale; 00426 p.z += (pcs.points[i].pc1 * pcs.points[i].principal_curvature[2]) * scale; 00427 00428 vtkSmartPointer<vtkLineSource> line_1 = vtkSmartPointer<vtkLineSource>::New (); 00429 line_1->SetPoint1 (cloud.points[i].x, cloud.points[i].y, cloud.points[i].z); 00430 line_1->SetPoint2 (p.x, p.y, p.z); 00431 line_1->Update (); 00432 polydata_1->AddInput (line_1->GetOutput ()); 00433 line_1_colors->InsertNextTupleValue (green); 00434 } 00435 polydata_1->Update (); 00436 vtkSmartPointer<vtkPolyData> line_1_data = polydata_1->GetOutput (); 00437 line_1_data->GetCellData ()->SetScalars (line_1_colors); 00438 00439 // Create the second sets of lines 00440 for (size_t i = 0; i < cloud.points.size (); i+=level) 00441 { 00442 Eigen::Vector3f pc (pcs.points[i].principal_curvature[0], pcs.points[i].principal_curvature[1], pcs.points[i].principal_curvature[2]); 00443 Eigen::Vector3f normal (normals.points[i].normal[0], normals.points[i].normal[1], normals.points[i].normal[2]); 00444 Eigen::Vector3f pc_c = pc.cross (normal); 00445 00446 pcl::PointXYZ p = cloud.points[i]; 00447 p.x += (pcs.points[i].pc2 * pc_c[0]) * scale; 00448 p.y += (pcs.points[i].pc2 * pc_c[1]) * scale; 00449 p.z += (pcs.points[i].pc2 * pc_c[2]) * scale; 00450 00451 vtkSmartPointer<vtkLineSource> line_2 = vtkSmartPointer<vtkLineSource>::New (); 00452 line_2->SetPoint1 (cloud.points[i].x, cloud.points[i].y, cloud.points[i].z); 00453 line_2->SetPoint2 (p.x, p.y, p.z); 00454 line_2->Update (); 00455 polydata_2->AddInput (line_2->GetOutput ()); 00456 line_2_colors->InsertNextTupleValue (blue); 00457 } 00458 polydata_2->Update (); 00459 vtkSmartPointer<vtkPolyData> line_2_data = polydata_2->GetOutput (); 00460 line_2_data->GetCellData ()->SetScalars (line_2_colors); 00461 00462 // Assemble the two sets of lines 00463 vtkSmartPointer<vtkAppendPolyData> alldata = vtkSmartPointer<vtkAppendPolyData>::New (); 00464 alldata->AddInput (line_1_data); 00465 alldata->AddInput (line_2_data); 00466 00467 // Create an Actor 00468 vtkSmartPointer<vtkLODActor> actor; 00469 createActorFromVTKDataSet (alldata->GetOutput (), actor); 00470 actor->GetMapper ()->SetScalarModeToUseCellData (); 00471 00472 // Add it to all renderers 00473 addActorToRenderer (actor, viewport); 00474 00475 // Save the pointer/ID pair to the global actor map 00476 CloudActor act; 00477 //act.color_handlers.push_back (handler); 00478 act.actor = actor; 00479 cloud_actor_map_[id] = act; 00480 //style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00481 return (true); 00482 } 00483 00485 bool 00486 pcl_visualization::PCLVisualizer::addPointCloud (const pcl::PointCloud<pcl::PointXYZ> &cloud, 00487 const std::string &id, int viewport) 00488 { 00489 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00490 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 00491 00492 if (am_it != cloud_actor_map_.end ()) 00493 { 00494 pcl::console::print_warn ("[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00495 return (false); 00496 } 00497 vtkSmartPointer<vtkPolyData> polydata; 00498 00499 // Convert the PointCloud to VTK PolyData 00500 convertPointCloudToVTKPolyData (cloud, polydata); 00501 polydata->Update (); 00502 00503 // Get the colors from the handler 00504 vtkSmartPointer<vtkDataArray> scalars; 00505 PointCloudColorHandlerRandom<pcl::PointXYZ> handler (cloud); 00506 handler.getColor (scalars); 00507 polydata->GetPointData ()->SetScalars (scalars); 00508 00509 // Create an Actor 00510 vtkSmartPointer<vtkLODActor> actor; 00511 createActorFromVTKDataSet (polydata, actor); 00512 00513 // Add it to all renderers 00514 addActorToRenderer (actor, viewport); 00515 00516 // Save the pointer/ID pair to the global actor map 00517 CloudActor act; 00518 //act.color_handlers.push_back (handler); 00519 act.actor = actor; 00520 cloud_actor_map_[id] = act; 00521 //cloud_actor_map_[id] = actor; 00522 style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00523 return (true); 00524 } 00525 00527 void 00528 pcl_visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkLODActor> &actor, int viewport) 00529 { 00530 // Add it to all renderers 00531 rens_->InitTraversal (); 00532 vtkRenderer* renderer = NULL; 00533 int i = 1; 00534 while ((renderer = rens_->GetNextItem ()) != NULL) 00535 { 00536 // Should we add the actor to all renderers? 00537 if (viewport == 0) 00538 { 00539 renderer->RemoveActor (actor); 00540 renderer->Render (); 00541 } 00542 else if (viewport == i) // add the actor only to the specified viewport 00543 { 00544 renderer->RemoveActor (actor); 00545 renderer->Render (); 00546 } 00547 ++i; 00548 } 00549 } 00550 00552 void 00553 pcl_visualization::PCLVisualizer::addActorToRenderer (const vtkSmartPointer<vtkProp> &actor, int viewport) 00554 { 00555 // Add it to all renderers 00556 rens_->InitTraversal (); 00557 vtkRenderer* renderer = NULL; 00558 int i = 1; 00559 while ((renderer = rens_->GetNextItem ()) != NULL) 00560 { 00561 // Should we add the actor to all renderers? 00562 if (viewport == 0) 00563 { 00564 renderer->AddActor (actor); 00565 renderer->Render (); 00566 } 00567 else if (viewport == i) // add the actor only to the specified viewport 00568 { 00569 renderer->AddActor (actor); 00570 renderer->Render (); 00571 } 00572 ++i; 00573 } 00574 } 00575 00577 void 00578 pcl_visualization::PCLVisualizer::removeActorFromRenderer (const vtkSmartPointer<vtkProp> &actor, int viewport) 00579 { 00580 // Add it to all renderers 00581 rens_->InitTraversal (); 00582 vtkRenderer* renderer = NULL; 00583 int i = 1; 00584 while ((renderer = rens_->GetNextItem ()) != NULL) 00585 { 00586 // Should we add the actor to all renderers? 00587 if (viewport == 0) 00588 { 00589 renderer->RemoveActor (actor); 00590 renderer->Render (); 00591 } 00592 else if (viewport == i) // add the actor only to the specified viewport 00593 { 00594 renderer->RemoveActor (actor); 00595 renderer->Render (); 00596 } 00597 ++i; 00598 } 00599 } 00600 00602 void 00603 pcl_visualization::PCLVisualizer::createActorFromVTKDataSet (const vtkSmartPointer<vtkDataSet> &data, 00604 vtkSmartPointer<vtkLODActor> &actor) 00605 { 00606 // If actor is not initialized, initialize it here 00607 if (!actor) 00608 actor = vtkSmartPointer<vtkLODActor>::New (); 00609 00610 vtkSmartPointer<vtkDataArray> scalars = data->GetPointData ()->GetScalars (); 00611 double minmax[2]; 00612 if (scalars) 00613 scalars->GetRange (minmax); 00614 00615 vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New (); 00616 mapper->SetInput (data); 00617 if (scalars) 00618 mapper->SetScalarRange (minmax); 00619 mapper->SetScalarModeToUsePointData (); 00620 mapper->ScalarVisibilityOn (); 00621 00622 actor->SetNumberOfCloudPoints (data->GetNumberOfPoints () / 10); 00623 actor->GetProperty ()->SetInterpolationToFlat (); 00624 00625 actor->SetMapper (mapper); 00626 } 00627 00629 void 00630 pcl_visualization::PCLVisualizer::convertPointCloudToVTKPolyData (const pcl::PointCloud<pcl::PointXYZ> &cloud, 00631 vtkSmartPointer<vtkPolyData> &polydata) 00632 { 00633 if (!polydata) 00634 polydata = vtkSmartPointer<vtkPolyData>::New (); 00635 00636 // Create the supporting structures 00637 vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New (); 00638 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New (); 00639 00640 // Set the points 00641 points->SetDataTypeToFloat (); 00642 points->SetNumberOfPoints (cloud.points.size ()); 00643 // 00644 double p[3]; 00645 for (vtkIdType i = 0; i < (int)cloud.points.size (); ++i) 00646 { 00647 p[0] = cloud.points[i].x; 00648 p[1] = cloud.points[i].y; 00649 p[2] = cloud.points[i].z; 00650 points->SetPoint (i, p); 00651 vertices->InsertNextCell ((vtkIdType)1, &i); 00652 } 00653 polydata->SetPoints (points); 00654 polydata->SetVerts (vertices); 00655 } 00656 00658 void 00659 pcl_visualization::PCLVisualizer::convertPointCloudToVTKPolyData (const GeometryHandlerConstPtr &geometry_handler, vtkSmartPointer<vtkPolyData> &polydata) 00660 { 00661 if (!polydata) 00662 polydata = vtkSmartPointer<vtkPolyData>::New (); 00663 00664 // Create the supporting structures 00665 vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New (); 00666 00667 // Use the handler to obtain the geometry 00668 vtkSmartPointer<vtkPoints> points; 00669 geometry_handler->getGeometry (points); 00670 00671 // Set the vertices 00672 for (vtkIdType i = 0; i < (int)points->GetNumberOfPoints (); ++i) 00673 vertices->InsertNextCell ((vtkIdType)1, &i); 00674 polydata->SetPoints (points); 00675 polydata->SetVerts (vertices); 00676 } 00677 00679 void 00680 pcl_visualization::PCLVisualizer::setBackgroundColor (const double &r, const double &g, const double &b, int viewport) 00681 { 00682 rens_->InitTraversal (); 00683 vtkRenderer* renderer = NULL; 00684 int i = 1; 00685 while ((renderer = rens_->GetNextItem ()) != NULL) 00686 { 00687 // Should we add the actor to all renderers? 00688 if (viewport == 0) 00689 { 00690 renderer->SetBackground (r, g, b); 00691 renderer->Render (); 00692 } 00693 else if (viewport == i) // add the actor only to the specified viewport 00694 { 00695 renderer->SetBackground (r, g, b); 00696 renderer->Render (); 00697 } 00698 ++i; 00699 } 00700 } 00701 00703 bool 00704 pcl_visualization::PCLVisualizer::setPointCloudRenderingProperties (int property, double val1, double val2, double val3, const std::string &id, int viewport) 00705 { 00706 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00707 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 00708 00709 if (am_it == cloud_actor_map_.end ()) 00710 { 00711 pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ()); 00712 return (false); 00713 } 00714 // Get the actor pointer 00715 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); 00716 00717 switch (property) 00718 { 00719 case PCL_VISUALIZER_COLOR: 00720 { 00721 actor->GetProperty ()->SetColor (val1, val2, val3); 00722 actor->Modified (); 00723 break; 00724 } 00725 default: 00726 { 00727 pcl::console::print_error ("[setPointCloudRenderingProperties] Unknown property (%d) specified!\n", property); 00728 return (false); 00729 } 00730 } 00731 return (true); 00732 } 00733 00735 bool 00736 pcl_visualization::PCLVisualizer::getPointCloudRenderingProperties (int property, double &value, const std::string &id) 00737 { 00738 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00739 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 00740 00741 if (am_it == cloud_actor_map_.end ()) 00742 return (false); 00743 // Get the actor pointer 00744 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); 00745 00746 switch (property) 00747 { 00748 case PCL_VISUALIZER_POINT_SIZE: 00749 { 00750 value = actor->GetProperty ()->GetPointSize (); 00751 actor->Modified (); 00752 break; 00753 } 00754 case PCL_VISUALIZER_OPACITY: 00755 { 00756 value = actor->GetProperty ()->GetOpacity (); 00757 actor->Modified (); 00758 break; 00759 } 00760 case PCL_VISUALIZER_LINE_WIDTH: 00761 { 00762 value = actor->GetProperty ()->GetLineWidth (); 00763 actor->Modified (); 00764 break; 00765 } 00766 default: 00767 { 00768 pcl::console::print_error ("[getPointCloudRenderingProperties] Unknown property (%d) specified!\n", property); 00769 return (false); 00770 } 00771 } 00772 return (true); 00773 } 00774 00776 bool 00777 pcl_visualization::PCLVisualizer::setPointCloudRenderingProperties (int property, double value, const std::string &id, int viewport) 00778 { 00779 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00780 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 00781 00782 if (am_it == cloud_actor_map_.end ()) 00783 { 00784 pcl::console::print_error ("[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <%s>!\n", id.c_str ()); 00785 return (false); 00786 } 00787 // Get the actor pointer 00788 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); 00789 00790 switch (property) 00791 { 00792 case PCL_VISUALIZER_POINT_SIZE: 00793 { 00794 actor->GetProperty ()->SetPointSize (value); 00795 actor->Modified (); 00796 break; 00797 } 00798 case PCL_VISUALIZER_OPACITY: 00799 { 00800 actor->GetProperty ()->SetOpacity (value); 00801 actor->Modified (); 00802 break; 00803 } 00804 case PCL_VISUALIZER_LINE_WIDTH: 00805 { 00806 actor->GetProperty ()->SetLineWidth (value); 00807 actor->Modified (); 00808 break; 00809 } 00810 default: 00811 { 00812 pcl::console::print_error ("[setPointCloudRenderingProperties] Unknown property (%d) specified!\n", property); 00813 return (false); 00814 } 00815 } 00816 return (true); 00817 } 00818 00820 bool 00821 pcl_visualization::PCLVisualizer::setShapeRenderingProperties (int property, double value, const std::string &id, int viewport) 00822 { 00823 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00824 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 00825 00826 if (am_it == shape_actor_map_.end ()) 00827 { 00828 pcl::console::print_error ("[setShapeRenderingProperties] Could not find any shape with id <%s>!\n", id.c_str ()); 00829 return (false); 00830 } 00831 // Get the actor pointer 00832 vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); 00833 00834 switch (property) 00835 { 00836 case PCL_VISUALIZER_OPACITY: 00837 { 00838 actor->GetProperty ()->SetOpacity (value); 00839 actor->Modified (); 00840 break; 00841 } 00842 case PCL_VISUALIZER_LINE_WIDTH: 00843 { 00844 actor->GetProperty ()->SetLineWidth (value); 00845 actor->Modified (); 00846 break; 00847 } 00848 case PCL_VISUALIZER_FONT_SIZE: 00849 { 00850 vtkTextActor* text_actor = vtkTextActor::SafeDownCast (am_it->second); 00851 vtkSmartPointer<vtkTextProperty> tprop = text_actor->GetTextProperty (); 00852 tprop->SetFontSize (value); 00853 text_actor->Modified (); 00854 break; 00855 } 00856 default: 00857 { 00858 pcl::console::print_error ("[setShapeRenderingProperties] Unknown property (%d) specified!\n", property); 00859 return (false); 00860 } 00861 } 00862 return (true); 00863 } 00864 00865 00867 void 00868 pcl_visualization::PCLVisualizer::initCameraParameters () 00869 { 00870 // Set default camera parameters 00871 camera_.clip[0] = 0.01; camera_.clip[1] = 1000.01; 00872 camera_.focal[0] = camera_.focal[1] = camera_.focal[2] = 0; 00873 camera_.pos[0] = camera_.pos[1] = 0; camera_.pos[2] = 1; 00874 camera_.view[0] = camera_.view[2] = 0; camera_.view[1] = 1; 00875 } 00876 00878 void 00879 pcl_visualization::PCLVisualizer::updateCamera () 00880 { 00881 // Update the camera parameters 00882 rens_->InitTraversal (); 00883 vtkRenderer* renderer = NULL; 00884 while ((renderer = rens_->GetNextItem ()) != NULL) 00885 { 00886 renderer->GetActiveCamera ()->SetPosition (camera_.pos); 00887 renderer->GetActiveCamera ()->SetFocalPoint (camera_.focal); 00888 renderer->GetActiveCamera ()->SetViewUp (camera_.view); 00889 renderer->GetActiveCamera ()->SetClippingRange (camera_.clip); 00890 } 00891 } 00893 void 00894 pcl_visualization::PCLVisualizer::resetCamera () 00895 { 00896 // Update the camera parameters 00897 rens_->InitTraversal (); 00898 vtkRenderer* renderer = NULL; 00899 while ((renderer = rens_->GetNextItem ()) != NULL) 00900 { 00901 renderer->ResetCamera (); 00902 } 00903 } 00904 00906 bool 00907 pcl_visualization::PCLVisualizer::getCameraParameters (int argc, char **argv) 00908 { 00909 for (int i = 1; i < argc; i++) 00910 { 00911 if ((strcmp (argv[i], "-cam") == 0) && (++i < argc)) 00912 { 00913 std::ifstream fs; 00914 std::string camfile = std::string (argv[i]); 00915 std::string line; 00916 00917 std::vector<std::string> camera; 00918 if (camfile.find (".cam") == std::string::npos) 00919 { 00920 // Assume we have clip/focal/pos/view 00921 boost::split (camera, argv[i], boost::is_any_of ("/"), boost::token_compress_on); 00922 } 00923 else 00924 { 00925 // Assume that if we don't have clip/focal/pos/view, a filename.cam was given as a parameter 00926 fs.open (camfile.c_str ()); 00927 while (!fs.eof ()) 00928 { 00929 getline (fs, line); 00930 if (line == "") 00931 continue; 00932 00933 boost::split (camera, line, boost::is_any_of ("/"), boost::token_compress_on); 00934 break; 00935 } 00936 fs.close (); 00937 } 00938 00939 // look for '/' as a separator 00940 if (camera.size () != 6) 00941 { 00942 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Camera parameters given, but with an invalid number of options (%zu vs 6)!\n", camera.size ()); 00943 return (false); 00944 } 00945 00946 std::string clip_str = camera.at (0); 00947 std::string focal_str = camera.at (1); 00948 std::string pos_str = camera.at (2); 00949 std::string view_str = camera.at (3); 00950 std::string win_size_str = camera.at (4); 00951 std::string win_pos_str = camera.at (5); 00952 00953 // Get each camera setting separately and parse for ',' 00954 std::vector<std::string> clip_st; 00955 boost::split (clip_st, clip_str, boost::is_any_of (","), boost::token_compress_on); 00956 if (clip_st.size () != 2) 00957 { 00958 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera clipping angle!\n"); 00959 return (false); 00960 } 00961 camera_.clip[0] = atof (clip_st.at (0).c_str ()); 00962 camera_.clip[1] = atof (clip_st.at (1).c_str ()); 00963 00964 std::vector<std::string> focal_st; 00965 boost::split (focal_st, focal_str, boost::is_any_of (","), boost::token_compress_on); 00966 if (focal_st.size () != 3) 00967 { 00968 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera focal point!\n"); 00969 return (false); 00970 } 00971 camera_.focal[0] = atof (focal_st.at (0).c_str ()); 00972 camera_.focal[1] = atof (focal_st.at (1).c_str ()); 00973 camera_.focal[2] = atof (focal_st.at (2).c_str ()); 00974 00975 std::vector<std::string> pos_st; 00976 boost::split (pos_st, pos_str, boost::is_any_of (","), boost::token_compress_on); 00977 if (pos_st.size () != 3) 00978 { 00979 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera position!\n"); 00980 return (false); 00981 } 00982 camera_.pos[0] = atof (pos_st.at (0).c_str ()); 00983 camera_.pos[1] = atof (pos_st.at (1).c_str ()); 00984 camera_.pos[2] = atof (pos_st.at (2).c_str ()); 00985 00986 std::vector<std::string> view_st; 00987 boost::split (view_st, view_str, boost::is_any_of (","), boost::token_compress_on); 00988 if (view_st.size () != 3) 00989 { 00990 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for camera viewup!\n"); 00991 return (false); 00992 } 00993 camera_.view[0] = atof (view_st.at (0).c_str ()); 00994 camera_.view[1] = atof (view_st.at (1).c_str ()); 00995 camera_.view[2] = atof (view_st.at (2).c_str ()); 00996 00997 std::vector<std::string> win_size_st; 00998 boost::split (win_size_st, win_size_str, boost::is_any_of (","), boost::token_compress_on); 00999 if (win_size_st.size () != 2) 01000 { 01001 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for window size!\n"); 01002 return (false); 01003 } 01004 camera_.window_size[0] = atof (win_size_st.at (0).c_str ()); 01005 camera_.window_size[1] = atof (win_size_st.at (1).c_str ()); 01006 01007 std::vector<std::string> win_pos_st; 01008 boost::split (win_pos_st, win_pos_str, boost::is_any_of (","), boost::token_compress_on); 01009 if (win_pos_st.size () != 2) 01010 { 01011 pcl::console::print_error ("[PCLVisualizer::getCameraParameters] Invalid parameters given for window position!\n"); 01012 return (false); 01013 } 01014 camera_.window_pos[0] = atof (win_pos_st.at (0).c_str ()); 01015 camera_.window_pos[1] = atof (win_pos_st.at (1).c_str ()); 01016 01017 return (true); 01018 } 01019 } 01020 return (false); 01021 } 01022 01024 bool 01025 pcl_visualization::PCLVisualizer::addCylinder (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport) 01026 { 01027 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01028 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01029 if (am_it != shape_actor_map_.end ()) 01030 { 01031 pcl::console::print_warn ("[addCylinder] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 01032 return (false); 01033 } 01034 01035 vtkSmartPointer<vtkDataSet> data = createCylinder (coefficients); 01036 01037 // Create an Actor 01038 vtkSmartPointer<vtkLODActor> actor; 01039 createActorFromVTKDataSet (data, actor); 01040 actor->GetProperty ()->SetRepresentationToWireframe (); 01041 addActorToRenderer (actor, viewport); 01042 01043 // Save the pointer/ID pair to the global actor map 01044 shape_actor_map_[id] = actor; 01045 return (true); 01046 } 01047 01049 bool 01050 pcl_visualization::PCLVisualizer::addSphere (const pcl::ModelCoefficients &coefficients, 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 if (am_it != shape_actor_map_.end ()) 01055 { 01056 pcl::console::print_warn ("[addSphere] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 01057 return (false); 01058 } 01059 01060 vtkSmartPointer<vtkDataSet> data = createSphere (coefficients); 01061 01062 // Create an Actor 01063 vtkSmartPointer<vtkLODActor> actor; 01064 createActorFromVTKDataSet (data, actor); 01065 actor->GetProperty ()->SetRepresentationToWireframe (); 01066 addActorToRenderer (actor, viewport); 01067 01068 // Save the pointer/ID pair to the global actor map 01069 shape_actor_map_[id] = actor; 01070 return (true); 01071 } 01072 01074 bool 01075 pcl_visualization::PCLVisualizer::addModelFromPLYFile (const std::string &filename, const std::string &id, int viewport) 01076 { 01077 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01078 if (am_it != shape_actor_map_.end ()) 01079 { 01080 pcl::console::print_warn ( 01081 "[addModelFromPLYFile] A shape with id <%s> already exists! Please choose a different id and retry.\n", 01082 id.c_str ()); 01083 return (false); 01084 } 01085 01086 vtkSmartPointer < vtkPLYReader > reader = vtkSmartPointer<vtkPLYReader>::New (); 01087 reader->SetFileName (filename.c_str ()); 01088 01089 // Create an Actor 01090 vtkSmartPointer < vtkLODActor > actor; 01091 createActorFromVTKDataSet (reader->GetOutput (), actor); 01092 actor->GetProperty ()->SetRepresentationToWireframe (); 01093 addActorToRenderer (actor, viewport); 01094 01095 // Save the pointer/ID pair to the global actor map 01096 shape_actor_map_[id] = actor; 01097 return (true); 01098 } 01099 01101 bool 01102 pcl_visualization::PCLVisualizer::addModelFromPLYFile (const std::string &filename, 01103 vtkSmartPointer<vtkTransform> transform, const std::string &id, 01104 int viewport) 01105 { 01106 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01107 if (am_it != shape_actor_map_.end ()) 01108 { 01109 pcl::console::print_warn ( 01110 "[addModelFromPLYFile] A shape with id <%s> already exists! Please choose a different id and retry.\n", 01111 id.c_str ()); 01112 return (false); 01113 } 01114 01115 vtkSmartPointer < vtkPLYReader > reader = vtkSmartPointer<vtkPLYReader>::New (); 01116 reader->SetFileName (filename.c_str ()); 01117 01118 //create transformation filter 01119 vtkSmartPointer < vtkTransformFilter > trans_filter = vtkSmartPointer<vtkTransformFilter>::New (); 01120 trans_filter->SetTransform (transform); 01121 trans_filter->SetInputConnection (reader->GetOutputPort ()); 01122 01123 // Create an Actor 01124 vtkSmartPointer < vtkLODActor > actor; 01125 createActorFromVTKDataSet (trans_filter->GetOutput (), actor); 01126 actor->GetProperty ()->SetRepresentationToWireframe (); 01127 addActorToRenderer (actor, viewport); 01128 01129 // Save the pointer/ID pair to the global actor map 01130 shape_actor_map_[id] = actor; 01131 return (true); 01132 } 01133 01135 bool 01136 pcl_visualization::PCLVisualizer::addLine (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport) 01137 { 01138 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01139 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01140 if (am_it != shape_actor_map_.end ()) 01141 { 01142 pcl::console::print_warn ("[addLine] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 01143 return (false); 01144 } 01145 01146 vtkSmartPointer<vtkDataSet> data = createLine (coefficients); 01147 01148 // Create an Actor 01149 vtkSmartPointer<vtkLODActor> actor; 01150 createActorFromVTKDataSet (data, actor); 01151 actor->GetProperty ()->SetRepresentationToWireframe (); 01152 addActorToRenderer (actor, viewport); 01153 01154 // Save the pointer/ID pair to the global actor map 01155 shape_actor_map_[id] = actor; 01156 return (true); 01157 } 01158 01160 01165 bool 01166 pcl_visualization::PCLVisualizer::addPlane (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport) 01167 { 01168 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01169 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01170 if (am_it != shape_actor_map_.end ()) 01171 { 01172 pcl::console::print_warn ("[addPlane] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 01173 return (false); 01174 } 01175 01176 vtkSmartPointer<vtkDataSet> data = createPlane (coefficients); 01177 01178 // Create an Actor 01179 vtkSmartPointer<vtkLODActor> actor; 01180 createActorFromVTKDataSet (data, actor); 01181 actor->GetProperty ()->SetRepresentationToWireframe (); 01182 addActorToRenderer (actor, viewport); 01183 01184 // Save the pointer/ID pair to the global actor map 01185 shape_actor_map_[id] = actor; 01186 return (true); 01187 } 01188 01190 bool 01191 pcl_visualization::PCLVisualizer::addCircle (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport) 01192 { 01193 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01194 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01195 if (am_it != shape_actor_map_.end ()) 01196 { 01197 pcl::console::print_warn ("[addCircle] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 01198 return (false); 01199 } 01200 01201 vtkSmartPointer<vtkDataSet> data = create2DCircle (coefficients); 01202 01203 // Create an Actor 01204 vtkSmartPointer<vtkLODActor> actor; 01205 createActorFromVTKDataSet (data, actor); 01206 actor->GetProperty ()->SetRepresentationToWireframe (); 01207 addActorToRenderer (actor, viewport); 01208 01209 // Save the pointer/ID pair to the global actor map 01210 shape_actor_map_[id] = actor; 01211 return (true); 01212 } 01213 01215 bool 01216 pcl_visualization::PCLVisualizer::addCone (const pcl::ModelCoefficients &coefficients, const std::string &id, int viewport) 01217 { 01218 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01219 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01220 if (am_it != shape_actor_map_.end ()) 01221 { 01222 pcl::console::print_warn ("[addCone] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 01223 return (false); 01224 } 01225 01226 vtkSmartPointer<vtkDataSet> data = createCone (coefficients); 01227 01228 // Create an Actor 01229 vtkSmartPointer<vtkLODActor> actor; 01230 createActorFromVTKDataSet (data, actor); 01231 actor->GetProperty ()->SetRepresentationToWireframe (); 01232 addActorToRenderer (actor, viewport); 01233 01234 // Save the pointer/ID pair to the global actor map 01235 shape_actor_map_[id] = actor; 01236 return (true); 01237 } 01238 01240 void 01241 pcl_visualization::PCLVisualizer::createViewPort (double xmin, double ymin, double xmax, double ymax, int &viewport) 01242 { 01243 // Create a new renderer 01244 vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New (); 01245 ren->SetViewport (xmin, ymin, xmax, ymax); 01246 01247 if (rens_->GetNumberOfItems () > 0) 01248 ren->SetActiveCamera (rens_->GetFirstRenderer ()->GetActiveCamera ()); 01249 ren->ResetCamera (); 01250 01251 // Add it to the list of renderers 01252 rens_->AddItem (ren); 01253 01254 if (rens_->GetNumberOfItems () <= 1) // If only one renderer 01255 viewport = 0; // set viewport to 'all' 01256 else 01257 viewport = rens_->GetNumberOfItems (); 01258 01259 win_->AddRenderer (ren); 01260 win_->Modified (); 01261 } 01262 01264 bool 01265 pcl_visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, const std::string &id, int viewport) 01266 { 01267 std::string tid; 01268 if (id.empty ()) 01269 tid = text; 01270 else 01271 tid = id; 01272 01273 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01274 ShapeActorMap::iterator am_it = shape_actor_map_.find (tid); 01275 if (am_it != shape_actor_map_.end ()) 01276 { 01277 pcl::console::print_warn ("[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ()); 01278 return (false); 01279 } 01280 01281 // Create an Actor 01282 vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New (); 01283 actor->SetPosition (xpos, ypos); 01284 actor->SetInput (text.c_str ()); 01285 01286 vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty (); 01287 tprop->SetFontSize (10); 01288 tprop->SetFontFamilyToArial (); 01289 tprop->SetJustificationToLeft (); 01290 tprop->BoldOn (); 01291 tprop->SetColor (1, 1, 1); 01292 addActorToRenderer (actor, viewport); 01293 01294 // Save the pointer/ID pair to the global actor map 01295 shape_actor_map_[tid] = actor; 01296 return (true); 01297 } 01298 01300 bool 01301 pcl_visualization::PCLVisualizer::addText (const std::string &text, int xpos, int ypos, int r, int g, int b, const std::string &id, int viewport) 01302 { 01303 std::string tid; 01304 if (id.empty ()) 01305 tid = text; 01306 else 01307 tid = id; 01308 01309 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01310 ShapeActorMap::iterator am_it = shape_actor_map_.find (tid); 01311 if (am_it != shape_actor_map_.end ()) 01312 { 01313 pcl::console::print_warn ("[addText] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ()); 01314 return (false); 01315 } 01316 01317 // Create an Actor 01318 vtkSmartPointer<vtkTextActor> actor = vtkSmartPointer<vtkTextActor>::New (); 01319 actor->SetPosition (xpos, ypos); 01320 actor->SetInput (text.c_str ()); 01321 01322 vtkSmartPointer<vtkTextProperty> tprop = actor->GetTextProperty (); 01323 tprop->SetFontSize (10); 01324 tprop->SetFontFamilyToArial (); 01325 tprop->SetJustificationToLeft (); 01326 tprop->BoldOn (); 01327 tprop->SetColor (r, g, b); 01328 addActorToRenderer (actor, viewport); 01329 01330 // Save the pointer/ID pair to the global actor map 01331 shape_actor_map_[tid] = actor; 01332 return (true); 01333 } 01334 01336 bool 01337 pcl_visualization::PCLVisualizer::updateColorHandlerIndex (const std::string &id, int index) 01338 { 01339 CloudActorMap::iterator am_it = cloud_actor_map_.find (id); 01340 if (am_it == cloud_actor_map_.end ()) 01341 { 01342 pcl::console::print_warn ("[updateColorHandlerIndex] PointCloud with id <%s> doesn't exist!\n", id.c_str ()); 01343 return (false); 01344 } 01345 01346 if (index >= (int)am_it->second.color_handlers.size ()) 01347 { 01348 pcl::console::print_warn ("[updateColorHandlerIndex] Invalid index <%d> given! Maximum range is: 0-%zu.\n", index, am_it->second.color_handlers.size ()); 01349 return (false); 01350 } 01351 // Get the handler 01352 PointCloudColorHandler<sensor_msgs::PointCloud2>::ConstPtr color_handler = am_it->second.color_handlers[index]; 01353 01354 vtkSmartPointer<vtkDataArray> scalars; 01355 color_handler->getColor (scalars); 01356 double minmax[2]; 01357 scalars->GetRange (minmax); 01358 // Update the data 01359 vtkPolyData *data = static_cast<vtkPolyData*>(am_it->second.actor->GetMapper ()->GetInput ()); 01360 data->GetPointData ()->SetScalars (scalars); 01361 data->Update (); 01362 // Modify the mapper 01363 vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ()); 01364 mapper->SetScalarRange (minmax); 01365 mapper->SetScalarModeToUsePointData (); 01366 mapper->SetInput (data); 01367 // Modify the actor 01368 am_it->second.actor->SetMapper (mapper); 01369 am_it->second.actor->Modified (); 01370 am_it->second.color_handler_index_ = index; 01371 01372 style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 01373 01374 return (true); 01375 } 01376 01378 bool 01379 pcl_visualization::PCLVisualizer::addPolygonMesh (const pcl::PolygonMesh & polyMesh, const std::string & id, 01380 int viewport) 01381 { 01382 ShapeActorMap::iterator am_it = shape_actor_map_.find (id); 01383 if (am_it != shape_actor_map_.end ()) 01384 { 01385 pcl::console::print_warn ( 01386 "[addPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n", 01387 id.c_str ()); 01388 return (false); 01389 } 01390 01391 //build polygonMesh structure... 01392 01393 //create points from polyMesh.cloud 01394 vtkSmartPointer<vtkPoints> poly_points = vtkSmartPointer<vtkPoints>::New (); 01395 pcl::PointCloud<pcl::PointXYZ> point_cloud; 01396 pcl::fromROSMsg(polyMesh.cloud, point_cloud); 01397 poly_points->SetNumberOfPoints (point_cloud.points.size ()); 01398 01399 size_t i; 01400 for (i = 0; i < point_cloud.points.size (); ++i) 01401 { 01402 poly_points->InsertPoint (i, point_cloud.points[i].x, point_cloud.points[i].y, point_cloud.points[i].z); 01403 } 01404 01405 01406 vtkSmartPointer<vtkLODActor> actor; 01407 if (polyMesh.polygons.size() > 1) { 01408 //create polys from polyMesh.polygons 01409 vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New(); 01410 01411 for(i=0; i < polyMesh.polygons.size(); i++) { 01412 size_t n_points = polyMesh.polygons[i].vertices.size(); 01413 cell_array->InsertNextCell(n_points); 01414 //std::cout << " size of poly " << n_points << std::endl; 01415 for(size_t j=0; j < n_points; j++) { 01416 cell_array->InsertCellPoint(polyMesh.polygons[i].vertices[j]); 01417 } 01418 } 01419 01420 vtkPolyData* polydata = vtkPolyData::New(); 01421 polydata->SetPolys(cell_array); 01422 polydata->SetPoints(poly_points); 01423 01424 createActorFromVTKDataSet (polydata, actor); 01425 } else { 01426 vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New (); 01427 size_t n_points = polyMesh.polygons[0].vertices.size(); 01428 polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); 01429 01430 for(size_t j=0; j < (n_points - 1); j++) { 01431 polygon->GetPointIds ()->SetId (j, polyMesh.polygons[0].vertices[j]); 01432 } 01433 01434 vtkSmartPointer<vtkUnstructuredGrid> poly_grid = vtkSmartPointer<vtkUnstructuredGrid>::New (); 01435 poly_grid->Allocate (1, 1); 01436 poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); 01437 poly_grid->SetPoints (poly_points); 01438 poly_grid->Update (); 01439 01440 createActorFromVTKDataSet (poly_grid, actor); 01441 actor->GetProperty ()->SetRepresentationToWireframe (); 01442 } 01443 01444 actor->GetProperty ()->SetRepresentationToSurface (); 01445 addActorToRenderer (actor, viewport); 01446 01447 // Save the pointer/ID pair to the global actor map 01448 shape_actor_map_[id] = actor; 01449 return (true); 01450 } 01451 01455 void 01456 pcl_visualization::FPSCallback::Execute (vtkObject *caller, unsigned long, void*) 01457 { 01458 vtkRenderer *ren = reinterpret_cast<vtkRenderer *> (caller); 01459 float fps = 1.0 / ren->GetLastRenderTimeInSeconds (); 01460 char buf[128]; 01461 snprintf (buf, 127, "%.1f FPS", fps); 01462 actor_->SetInput (buf); 01463 } 01464