|
Point Cloud Library (PCL)
1.4.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id: pcl_visualizer.hpp 3771 2012-01-01 06:58:14Z rusu $ 00037 * 00038 */ 00039 00040 #ifndef PCL_PCL_VISUALIZER_IMPL_H_ 00041 #define PCL_PCL_VISUALIZER_IMPL_H_ 00042 00043 #include <vtkCellData.h> 00044 #include <vtkSmartPointer.h> 00045 #include <vtkCellArray.h> 00046 #include <vtkProperty2D.h> 00047 #include <vtkMapper2D.h> 00048 #include <vtkLeaderActor2D.h> 00049 #include <pcl/common/time.h> 00050 00052 template <typename PointT> bool 00053 pcl::visualization::PCLVisualizer::addPointCloud ( 00054 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00055 const std::string &id, int viewport) 00056 { 00057 // Convert the PointCloud to VTK PolyData 00058 PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud); 00059 return (addPointCloud<PointT> (cloud, geometry_handler, id, viewport)); 00060 } 00061 00063 template <typename PointT> bool 00064 pcl::visualization::PCLVisualizer::addPointCloud ( 00065 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00066 const PointCloudGeometryHandler<PointT> &geometry_handler, 00067 const std::string &id, int viewport) 00068 { 00069 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00070 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00071 00072 if (am_it != cloud_actor_map_->end ()) 00073 { 00074 PCL_WARN ("[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00075 return (false); 00076 } 00077 00078 //PointCloudColorHandlerRandom<PointT> color_handler (cloud); 00079 PointCloudColorHandlerCustom<PointT> color_handler (cloud, 255, 255, 255); 00080 return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport)); 00081 } 00082 00084 template <typename PointT> bool 00085 pcl::visualization::PCLVisualizer::addPointCloud ( 00086 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00087 const GeometryHandlerConstPtr &geometry_handler, 00088 const std::string &id, int viewport) 00089 { 00090 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00091 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00092 00093 if (am_it != cloud_actor_map_->end ()) 00094 { 00095 // Here we're just pushing the handlers onto the queue. If needed, something fancier could 00096 // be done such as checking if a specific handler already exists, etc. 00097 am_it->second.geometry_handlers.push_back (geometry_handler); 00098 return (true); 00099 } 00100 00101 //PointCloudColorHandlerRandom<PointT> color_handler (cloud); 00102 PointCloudColorHandlerCustom<PointT> color_handler (cloud, 255, 255, 255); 00103 return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport)); 00104 } 00105 00107 template <typename PointT> bool 00108 pcl::visualization::PCLVisualizer::addPointCloud ( 00109 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00110 const PointCloudColorHandler<PointT> &color_handler, 00111 const std::string &id, int viewport) 00112 { 00113 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00114 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00115 00116 if (am_it != cloud_actor_map_->end ()) 00117 { 00118 PCL_WARN ("[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00119 00120 // Here we're just pushing the handlers onto the queue. If needed, something fancier could 00121 // be done such as checking if a specific handler already exists, etc. 00122 //cloud_actor_map_[id].color_handlers.push_back (color_handler); 00123 //style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00124 return (false); 00125 } 00126 // Convert the PointCloud to VTK PolyData 00127 PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud); 00128 return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport)); 00129 } 00130 00132 template <typename PointT> bool 00133 pcl::visualization::PCLVisualizer::addPointCloud ( 00134 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00135 const ColorHandlerConstPtr &color_handler, 00136 const std::string &id, int viewport) 00137 { 00138 // Check to see if this entry already exists (has it been already added to the visualizer?) 00139 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00140 if (am_it != cloud_actor_map_->end ()) 00141 { 00142 // Here we're just pushing the handlers onto the queue. If needed, something fancier could 00143 // be done such as checking if a specific handler already exists, etc. 00144 am_it->second.color_handlers.push_back (color_handler); 00145 return (true); 00146 } 00147 00148 PointCloudGeometryHandlerXYZ<PointT> geometry_handler (cloud); 00149 return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport)); 00150 } 00151 00153 template <typename PointT> bool 00154 pcl::visualization::PCLVisualizer::addPointCloud ( 00155 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00156 const GeometryHandlerConstPtr &geometry_handler, 00157 const ColorHandlerConstPtr &color_handler, 00158 const std::string &id, int viewport) 00159 { 00160 // Check to see if this entry already exists (has it been already added to the visualizer?) 00161 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00162 if (am_it != cloud_actor_map_->end ()) 00163 { 00164 // Here we're just pushing the handlers onto the queue. If needed, something fancier could 00165 // be done such as checking if a specific handler already exists, etc. 00166 am_it->second.geometry_handlers.push_back (geometry_handler); 00167 am_it->second.color_handlers.push_back (color_handler); 00168 return (true); 00169 } 00170 return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport)); 00171 } 00172 00174 template <typename PointT> bool 00175 pcl::visualization::PCLVisualizer::addPointCloud ( 00176 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00177 const PointCloudColorHandler<PointT> &color_handler, 00178 const PointCloudGeometryHandler<PointT> &geometry_handler, 00179 const std::string &id, int viewport) 00180 { 00181 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00182 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00183 00184 if (am_it != cloud_actor_map_->end ()) 00185 { 00186 PCL_WARN ("[addPointCloud] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00187 // Here we're just pushing the handlers onto the queue. If needed, something fancier could 00188 // be done such as checking if a specific handler already exists, etc. 00189 //cloud_actor_map_[id].geometry_handlers.push_back (geometry_handler); 00190 //cloud_actor_map_[id].color_handlers.push_back (color_handler); 00191 //style_->setCloudActorMap (boost::make_shared<CloudActorMap> (cloud_actor_map_)); 00192 return (false); 00193 } 00194 return (fromHandlersToScreen (geometry_handler, color_handler, id, viewport)); 00195 } 00196 00198 template <typename PointT> void 00199 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData ( 00200 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00201 vtkSmartPointer<vtkPolyData> &polydata, 00202 vtkSmartPointer<vtkIdTypeArray> &initcells) 00203 { 00204 vtkSmartPointer<vtkCellArray> vertices; 00205 if (!polydata) 00206 { 00207 allocVtkPolyData (polydata); 00208 vertices = vtkSmartPointer<vtkCellArray>::New (); 00209 polydata->SetVerts (vertices); 00210 } 00211 00212 // Create the supporting structures 00213 vertices = polydata->GetVerts (); 00214 if (!vertices) 00215 vertices = vtkSmartPointer<vtkCellArray>::New (); 00216 00217 vtkIdType nr_points = cloud->points.size (); 00218 // Create the point set 00219 vtkSmartPointer<vtkPoints> points = polydata->GetPoints (); 00220 if (!points) 00221 { 00222 points = vtkSmartPointer<vtkPoints>::New (); 00223 points->SetDataTypeToFloat (); 00224 polydata->SetPoints (points); 00225 } 00226 points->SetNumberOfPoints (nr_points); 00227 00228 // Get a pointer to the beginning of the data array 00229 float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0); 00230 00231 // Set the points 00232 if (cloud->is_dense) 00233 { 00234 for (vtkIdType i = 0; i < nr_points; ++i) 00235 memcpy (&data[i * 3], &cloud->points[i].x, 12); // sizeof (float) * 3 00236 } 00237 else 00238 { 00239 vtkIdType j = 0; // true point index 00240 for (vtkIdType i = 0; i < nr_points; ++i) 00241 { 00242 // Check if the point is invalid 00243 if (!pcl_isfinite (cloud->points[i].x) || 00244 !pcl_isfinite (cloud->points[i].y) || 00245 !pcl_isfinite (cloud->points[i].z)) 00246 continue; 00247 00248 memcpy (&data[j * 3], &cloud->points[i].x, 12); // sizeof (float) * 3 00249 j++; 00250 } 00251 nr_points = j; 00252 points->SetNumberOfPoints (nr_points); 00253 } 00254 00255 vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData (); 00256 updateCells (cells, initcells, nr_points); 00257 00258 // Set the cells and the vertices 00259 vertices->SetCells (nr_points, cells); 00260 } 00261 00263 template <typename PointT> void 00264 pcl::visualization::PCLVisualizer::convertPointCloudToVTKPolyData ( 00265 const pcl::visualization::PointCloudGeometryHandler<PointT> &geometry_handler, 00266 vtkSmartPointer<vtkPolyData> &polydata, 00267 vtkSmartPointer<vtkIdTypeArray> &initcells) 00268 { 00269 vtkSmartPointer<vtkCellArray> vertices; 00270 if (!polydata) 00271 { 00272 allocVtkPolyData (polydata); 00273 vertices = vtkSmartPointer<vtkCellArray>::New (); 00274 polydata->SetVerts (vertices); 00275 } 00276 00277 // Use the handler to obtain the geometry 00278 vtkSmartPointer<vtkPoints> points; 00279 geometry_handler.getGeometry (points); 00280 polydata->SetPoints (points); 00281 00282 vtkIdType nr_points = points->GetNumberOfPoints (); 00283 00284 // Create the supporting structures 00285 vertices = polydata->GetVerts (); 00286 if (!vertices) 00287 vertices = vtkSmartPointer<vtkCellArray>::New (); 00288 00289 vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData (); 00290 updateCells (cells, initcells, nr_points); 00291 // Set the cells and the vertices 00292 vertices->SetCells (nr_points, cells); 00293 } 00294 00296 template <typename PointT> bool 00297 pcl::visualization::PCLVisualizer::addPolygon ( 00298 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00299 double r, double g, double b, const std::string &id, int viewport) 00300 { 00301 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00302 ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00303 if (am_it != shape_actor_map_->end ()) 00304 { 00305 PCL_WARN ("[addPolygon] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00306 return (false); 00307 } 00308 00309 vtkSmartPointer<vtkDataSet> data = createPolygon<PointT> (cloud); 00310 00311 // Create an Actor 00312 vtkSmartPointer<vtkLODActor> actor; 00313 createActorFromVTKDataSet (data, actor); 00314 actor->GetProperty ()->SetRepresentationToWireframe (); 00315 actor->GetProperty ()->SetColor (r, g, b); 00316 actor->GetMapper ()->ScalarVisibilityOff (); 00317 addActorToRenderer (actor, viewport); 00318 00319 // Save the pointer/ID pair to the global actor map 00320 (*shape_actor_map_)[id] = actor; 00321 return (true); 00322 } 00323 00325 template <typename PointT> bool 00326 pcl::visualization::PCLVisualizer::addPolygon ( 00327 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00328 const std::string &id, int viewport) 00329 { 00330 return (!addPolygon<PointT> (cloud, 0.5, 0.5, 0.5, id, viewport)); 00331 return (false); 00332 } 00333 00335 template <typename P1, typename P2> bool 00336 pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport) 00337 { 00338 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00339 ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00340 if (am_it != shape_actor_map_->end ()) 00341 { 00342 PCL_WARN ("[addLine] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00343 return (false); 00344 } 00345 00346 vtkSmartPointer<vtkDataSet> data = createLine (pt1.getVector4fMap (), pt2.getVector4fMap ()); 00347 00348 // Create an Actor 00349 vtkSmartPointer<vtkLODActor> actor; 00350 createActorFromVTKDataSet (data, actor); 00351 actor->GetProperty ()->SetRepresentationToWireframe (); 00352 actor->GetProperty ()->SetColor (r, g, b); 00353 actor->GetMapper ()->ScalarVisibilityOff (); 00354 addActorToRenderer (actor, viewport); 00355 00356 // Save the pointer/ID pair to the global actor map 00357 (*shape_actor_map_)[id] = actor; 00358 return (true); 00359 } 00360 00362 template <typename P1, typename P2> bool 00363 pcl::visualization::PCLVisualizer::addArrow (const P1 &pt1, const P2 &pt2, double r, double g, double b, const std::string &id, int viewport) 00364 { 00365 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00366 ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00367 if (am_it != shape_actor_map_->end ()) 00368 { 00369 PCL_WARN ("[addArrow] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00370 return (false); 00371 } 00372 00373 // Create an Actor 00374 vtkSmartPointer<vtkLeaderActor2D> leader = vtkSmartPointer<vtkLeaderActor2D>::New (); 00375 leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld (); 00376 leader->GetPositionCoordinate ()->SetValue (pt1.x, pt1.y, pt1.z); 00377 leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld (); 00378 leader->GetPosition2Coordinate ()->SetValue (pt2.x, pt2.y, pt2.z); 00379 leader->SetArrowStyleToFilled (); 00380 leader->AutoLabelOn (); 00381 00382 leader->GetProperty ()->SetColor (r, g, b); 00383 addActorToRenderer (leader, viewport); 00384 00385 // Save the pointer/ID pair to the global actor map 00386 (*shape_actor_map_)[id] = leader; 00387 return (true); 00388 } 00389 00391 template <typename P1, typename P2> bool 00392 pcl::visualization::PCLVisualizer::addLine (const P1 &pt1, const P2 &pt2, const std::string &id, int viewport) 00393 { 00394 return (!addLine (pt1, pt2, 0.5, 0.5, 0.5, id, viewport)); 00395 } 00396 00398 /*template <typename P1, typename P2> bool 00399 pcl::visualization::PCLVisualizer::addLineToGroup (const P1 &pt1, const P2 &pt2, const std::string &group_id, int viewport) 00400 { 00401 vtkSmartPointer<vtkDataSet> data = createLine<P1, P2> (pt1, pt2); 00402 00403 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00404 ShapeActorMap::iterator am_it = shape_actor_map_->find (group_id); 00405 if (am_it != shape_actor_map_->end ()) 00406 { 00407 // Get the old data 00408 vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(am_it->second->GetMapper ()); 00409 vtkPolyData* olddata = static_cast<vtkPolyData*>(mapper->GetInput ()); 00410 // Add it to the current data 00411 vtkSmartPointer<vtkAppendPolyData> alldata = vtkSmartPointer<vtkAppendPolyData>::New (); 00412 alldata->AddInput (olddata); 00413 00414 // Convert to vtkPolyData 00415 vtkSmartPointer<vtkPolyData> curdata = (vtkPolyData::SafeDownCast (data)); 00416 alldata->AddInput (curdata); 00417 00418 mapper->SetInput (alldata->GetOutput ()); 00419 00420 am_it->second->SetMapper (mapper); 00421 am_it->second->Modified (); 00422 return (true); 00423 } 00424 00425 // Create an Actor 00426 vtkSmartPointer<vtkLODActor> actor; 00427 createActorFromVTKDataSet (data, actor); 00428 actor->GetProperty ()->SetRepresentationToWireframe (); 00429 actor->GetProperty ()->SetColor (1, 0, 0); 00430 addActorToRenderer (actor, viewport); 00431 00432 // Save the pointer/ID pair to the global actor map 00433 (*shape_actor_map_)[group_id] = actor; 00434 00435 //ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00436 //vtkSmartPointer<vtkLODActor> actor = am_it->second; 00437 //actor->GetProperty ()->SetColor (r, g, b); 00438 //actor->Modified (); 00439 return (true); 00440 }*/ 00441 00443 template <typename PointT> bool 00444 pcl::visualization::PCLVisualizer::addSphere (const PointT ¢er, double radius, double r, double g, double b, const std::string &id, int viewport) 00445 { 00446 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00447 ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00448 if (am_it != shape_actor_map_->end ()) 00449 { 00450 PCL_WARN ("[addSphere] A shape with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00451 return (false); 00452 } 00453 00454 vtkSmartPointer<vtkDataSet> data = createSphere (center.getVector4fMap (), radius); 00455 00456 // Create an Actor 00457 vtkSmartPointer<vtkLODActor> actor; 00458 createActorFromVTKDataSet (data, actor); 00459 actor->GetProperty ()->SetRepresentationToWireframe (); 00460 actor->GetProperty ()->SetInterpolationToGouraud (); 00461 actor->GetMapper ()->ScalarVisibilityOff (); 00462 actor->GetProperty ()->SetColor (r, g, b); 00463 addActorToRenderer (actor, viewport); 00464 00465 // Save the pointer/ID pair to the global actor map 00466 (*shape_actor_map_)[id] = actor; 00467 return (true); 00468 } 00469 00471 template <typename PointT> bool 00472 pcl::visualization::PCLVisualizer::addSphere (const PointT ¢er, double radius, const std::string &id, int viewport) 00473 { 00474 return (addSphere (center, radius, 0.5, 0.5, 0.5, id, viewport)); 00475 } 00476 00478 template <typename PointT> bool 00479 pcl::visualization::PCLVisualizer::addText3D ( 00480 const std::string &text, 00481 const PointT& position, 00482 double textScale, 00483 double r, 00484 double g, 00485 double b, 00486 const std::string &id, 00487 int viewport) 00488 { 00489 std::string tid; 00490 if (id.empty ()) 00491 tid = text; 00492 else 00493 tid = id; 00494 00495 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00496 ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); 00497 if (am_it != shape_actor_map_->end ()) 00498 { 00499 pcl::console::print_warn ("[addText3d] A text with id <%s> already exists! Please choose a different id and retry.\n", tid.c_str ()); 00500 return (false); 00501 } 00502 00503 vtkSmartPointer<vtkVectorText> textSource = vtkSmartPointer<vtkVectorText>::New (); 00504 textSource->SetText (text.c_str()); 00505 textSource->Update (); 00506 00507 vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New (); 00508 textMapper->SetInputConnection (textSource->GetOutputPort ()); 00509 00510 // Since each follower may follow a different camera, we need different followers 00511 rens_->InitTraversal (); 00512 vtkRenderer* renderer = NULL; 00513 int i = 1; 00514 while ((renderer = rens_->GetNextItem ()) != NULL) 00515 { 00516 // Should we add the actor to all renderers or just to i-nth renderer? 00517 if (viewport == 0 || viewport == i) 00518 { 00519 vtkSmartPointer<vtkFollower> textActor = vtkSmartPointer<vtkFollower>::New (); 00520 textActor->SetMapper (textMapper); 00521 textActor->SetPosition (position.x, position.y, position.z); 00522 textActor->SetScale (textScale); 00523 textActor->GetProperty ()->SetColor (r, g, b); 00524 textActor->SetCamera (renderer->GetActiveCamera ()); 00525 00526 renderer->AddActor (textActor); 00527 renderer->Render (); 00528 00529 // Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers 00530 // for multiple viewport 00531 std::string alternate_tid = tid; 00532 alternate_tid.append(i, '*'); 00533 00534 (*shape_actor_map_)[(viewport == 0) ? tid : alternate_tid] = textActor; 00535 } 00536 00537 ++i; 00538 } 00539 00540 return (true); 00541 } 00542 00544 template <typename PointNT> bool 00545 pcl::visualization::PCLVisualizer::addPointCloudNormals ( 00546 const typename pcl::PointCloud<PointNT>::ConstPtr &cloud, 00547 int level, double scale, const std::string &id, int viewport) 00548 { 00549 return (addPointCloudNormals<PointNT, PointNT>(cloud, cloud, level, scale, id, viewport)); 00550 } 00551 00553 template <typename PointT, typename PointNT> bool 00554 pcl::visualization::PCLVisualizer::addPointCloudNormals ( 00555 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00556 const typename pcl::PointCloud<PointNT>::ConstPtr &normals, 00557 int level, double scale, 00558 const std::string &id, int viewport) 00559 { 00560 if (normals->points.size () != cloud->points.size ()) 00561 { 00562 PCL_ERROR ("[addPointCloudNormals] The number of points differs from the number of normals!\n"); 00563 return (false); 00564 } 00565 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00566 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00567 00568 if (am_it != cloud_actor_map_->end ()) 00569 { 00570 PCL_WARN ("[addPointCloudNormals] A PointCloud with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00571 return (false); 00572 } 00573 00574 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); 00575 vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); 00576 00577 points->SetDataTypeToFloat (); 00578 vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New (); 00579 data->SetNumberOfComponents (3); 00580 00581 vtkIdType nr_normals = (cloud->points.size () - 1) / level + 1 ; 00582 float* pts = new float[2 * nr_normals * 3]; 00583 00584 for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level) 00585 { 00586 PointT p = cloud->points[i]; 00587 p.x += normals->points[i].normal[0] * scale; 00588 p.y += normals->points[i].normal[1] * scale; 00589 p.z += normals->points[i].normal[2] * scale; 00590 00591 pts[2 * j * 3 + 0] = cloud->points[i].x; 00592 pts[2 * j * 3 + 1] = cloud->points[i].y; 00593 pts[2 * j * 3 + 2] = cloud->points[i].z; 00594 pts[2 * j * 3 + 3] = p.x; 00595 pts[2 * j * 3 + 4] = p.y; 00596 pts[2 * j * 3 + 5] = p.z; 00597 00598 lines->InsertNextCell(2); 00599 lines->InsertCellPoint(2*j); 00600 lines->InsertCellPoint(2*j+1); 00601 } 00602 00603 data->SetArray (&pts[0], 2 * nr_normals * 3, 0); 00604 points->SetData (data); 00605 00606 vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); 00607 polyData->SetPoints(points); 00608 polyData->SetLines(lines); 00609 00610 vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New (); 00611 mapper->SetInput (polyData); 00612 mapper->SetColorModeToMapScalars(); 00613 mapper->SetScalarModeToUsePointData(); 00614 00615 // create actor 00616 vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New(); 00617 actor->SetMapper(mapper); 00618 00619 // Add it to all renderers 00620 addActorToRenderer (actor, viewport); 00621 00622 // Save the pointer/ID pair to the global actor map 00623 (*cloud_actor_map_)[id].actor = actor; 00624 return (true); 00625 } 00626 00628 template <typename PointT> bool 00629 pcl::visualization::PCLVisualizer::addCorrespondences ( 00630 const typename pcl::PointCloud<PointT>::ConstPtr &source_points, 00631 const typename pcl::PointCloud<PointT>::ConstPtr &target_points, 00632 const std::vector<int> &correspondences, 00633 const std::string &id, 00634 int viewport) 00635 { 00636 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00637 ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00638 if (am_it != shape_actor_map_->end ()) 00639 { 00640 PCL_WARN ("[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00641 return (false); 00642 } 00643 00644 vtkSmartPointer<vtkAppendPolyData> polydata = vtkSmartPointer<vtkAppendPolyData>::New (); 00645 00646 vtkSmartPointer<vtkUnsignedCharArray> line_colors = vtkSmartPointer<vtkUnsignedCharArray>::New (); 00647 line_colors->SetNumberOfComponents (3); 00648 line_colors->SetName ("Colors"); 00649 // Use Red by default (can be changed later) 00650 unsigned char rgb[3]; 00651 rgb[0] = 1 * 255.0; 00652 rgb[1] = 0 * 255.0; 00653 rgb[2] = 0 * 255.0; 00654 00655 // Draw lines between the best corresponding points 00656 for (size_t i = 0; i < source_points->size (); ++i) 00657 { 00658 const PointT &p_src = source_points->points[i]; 00659 const PointT &p_tgt = target_points->points[correspondences[i]]; 00660 00661 // Add the line 00662 vtkSmartPointer<vtkLineSource> line = vtkSmartPointer<vtkLineSource>::New (); 00663 line->SetPoint1 (p_src.x, p_src.y, p_src.z); 00664 line->SetPoint2 (p_tgt.x, p_tgt.y, p_tgt.z); 00665 line->Update (); 00666 polydata->AddInput (line->GetOutput ()); 00667 line_colors->InsertNextTupleValue (rgb); 00668 } 00669 polydata->Update (); 00670 vtkSmartPointer<vtkPolyData> line_data = polydata->GetOutput (); 00671 line_data->GetCellData ()->SetScalars (line_colors); 00672 00673 // Create an Actor 00674 vtkSmartPointer<vtkLODActor> actor; 00675 createActorFromVTKDataSet (line_data, actor); 00676 actor->GetProperty ()->SetRepresentationToWireframe (); 00677 actor->GetProperty ()->SetOpacity (0.5); 00678 addActorToRenderer (actor, viewport); 00679 00680 // Save the pointer/ID pair to the global actor map 00681 (*shape_actor_map_)[id] = actor; 00682 00683 return (true); 00684 } 00685 00687 template <typename PointT> bool 00688 pcl::visualization::PCLVisualizer::addCorrespondences ( 00689 const typename pcl::PointCloud<PointT>::ConstPtr &source_points, 00690 const typename pcl::PointCloud<PointT>::ConstPtr &target_points, 00691 const pcl::Correspondences &correspondences, 00692 const std::string &id, 00693 int viewport) 00694 { 00695 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00696 ShapeActorMap::iterator am_it = shape_actor_map_->find (id); 00697 if (am_it != shape_actor_map_->end ()) 00698 { 00699 PCL_WARN ("[addCorrespondences] A set of correspondences with id <%s> already exists! Please choose a different id and retry.\n", id.c_str ()); 00700 return (false); 00701 } 00702 00703 vtkSmartPointer<vtkAppendPolyData> polydata = vtkSmartPointer<vtkAppendPolyData>::New (); 00704 00705 vtkSmartPointer<vtkUnsignedCharArray> line_colors = vtkSmartPointer<vtkUnsignedCharArray>::New (); 00706 line_colors->SetNumberOfComponents (3); 00707 line_colors->SetName ("Colors"); 00708 unsigned char rgb[3]; 00709 // Use Red by default (can be changed later) 00710 rgb[0] = 1 * 255.0; 00711 rgb[1] = 0 * 255.0; 00712 rgb[2] = 0 * 255.0; 00713 00714 // Draw lines between the best corresponding points 00715 for (size_t i = 0; i < correspondences.size (); ++i) 00716 { 00717 const PointT &p_src = source_points->points[correspondences[i].index_query]; 00718 const PointT &p_tgt = target_points->points[correspondences[i].index_match]; 00719 00720 // Add the line 00721 vtkSmartPointer<vtkLineSource> line = vtkSmartPointer<vtkLineSource>::New (); 00722 line->SetPoint1 (p_src.x, p_src.y, p_src.z); 00723 line->SetPoint2 (p_tgt.x, p_tgt.y, p_tgt.z); 00724 line->Update (); 00725 polydata->AddInput (line->GetOutput ()); 00726 line_colors->InsertNextTupleValue (rgb); 00727 } 00728 polydata->Update (); 00729 vtkSmartPointer<vtkPolyData> line_data = polydata->GetOutput (); 00730 line_data->GetCellData ()->SetScalars (line_colors); 00731 00732 // Create an Actor 00733 vtkSmartPointer<vtkLODActor> actor; 00734 createActorFromVTKDataSet (line_data, actor); 00735 actor->GetProperty ()->SetRepresentationToWireframe (); 00736 actor->GetProperty ()->SetOpacity (0.5); 00737 addActorToRenderer (actor, viewport); 00738 00739 // Save the pointer/ID pair to the global actor map 00740 (*shape_actor_map_)[id] = actor; 00741 00742 return (true); 00743 } 00744 00746 template <typename PointT> bool 00747 pcl::visualization::PCLVisualizer::fromHandlersToScreen ( 00748 const PointCloudGeometryHandler<PointT> &geometry_handler, 00749 const PointCloudColorHandler<PointT> &color_handler, 00750 const std::string &id, 00751 int viewport) 00752 { 00753 if (!geometry_handler.isCapable ()) 00754 { 00755 PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ()); 00756 return (false); 00757 } 00758 00759 if (!color_handler.isCapable ()) 00760 { 00761 PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ()); 00762 return (false); 00763 } 00764 00765 vtkSmartPointer<vtkPolyData> polydata; 00766 vtkSmartPointer<vtkIdTypeArray> initcells; 00767 // Convert the PointCloud to VTK PolyData 00768 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells); 00769 // use the given geometry handler 00770 polydata->Update (); 00771 00772 // Get the colors from the handler 00773 vtkSmartPointer<vtkDataArray> scalars; 00774 color_handler.getColor (scalars); 00775 polydata->GetPointData ()->SetScalars (scalars); 00776 00777 // Create an Actor 00778 vtkSmartPointer<vtkLODActor> actor; 00779 createActorFromVTKDataSet (polydata, actor); 00780 00781 // Add it to all renderers 00782 addActorToRenderer (actor, viewport); 00783 00784 // Save the pointer/ID pair to the global actor map 00785 (*cloud_actor_map_)[id].actor = actor; 00786 (*cloud_actor_map_)[id].cells = initcells; 00787 00788 // Save the viewpoint transformation matrix to the global actor map 00789 vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New(); 00790 Eigen::Vector4f origin = geometry_handler.getOrigin (); 00791 Eigen::Quaternion<float> orientation = geometry_handler.getOrientation (); 00792 convertToVtkMatrix (origin, orientation, transformation); 00793 (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; 00794 00795 return (true); 00796 } 00797 00799 template <typename PointT> bool 00800 pcl::visualization::PCLVisualizer::fromHandlersToScreen ( 00801 const PointCloudGeometryHandler<PointT> &geometry_handler, 00802 const ColorHandlerConstPtr &color_handler, 00803 const std::string &id, 00804 int viewport) 00805 { 00806 if (!geometry_handler.isCapable ()) 00807 { 00808 PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ()); 00809 return (false); 00810 } 00811 00812 if (!color_handler->isCapable ()) 00813 { 00814 PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ()); 00815 return (false); 00816 } 00817 00818 vtkSmartPointer<vtkPolyData> polydata; 00819 vtkSmartPointer<vtkIdTypeArray> initcells; 00820 // Convert the PointCloud to VTK PolyData 00821 convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells); 00822 // use the given geometry handler 00823 polydata->Update (); 00824 00825 // Get the colors from the handler 00826 vtkSmartPointer<vtkDataArray> scalars; 00827 color_handler->getColor (scalars); 00828 polydata->GetPointData ()->SetScalars (scalars); 00829 00830 // Create an Actor 00831 vtkSmartPointer<vtkLODActor> actor; 00832 createActorFromVTKDataSet (polydata, actor); 00833 00834 // Add it to all renderers 00835 addActorToRenderer (actor, viewport); 00836 00837 // Save the pointer/ID pair to the global actor map 00838 (*cloud_actor_map_)[id].actor = actor; 00839 (*cloud_actor_map_)[id].cells = initcells; 00840 (*cloud_actor_map_)[id].color_handlers.push_back (color_handler); 00841 00842 // Save the viewpoint transformation matrix to the global actor map 00843 // Save the viewpoint transformation matrix to the global actor map 00844 vtkSmartPointer<vtkMatrix4x4> transformation = vtkSmartPointer<vtkMatrix4x4>::New(); 00845 Eigen::Vector4f origin = geometry_handler.getOrigin (); 00846 Eigen::Quaternion<float> orientation = geometry_handler.getOrientation (); 00847 convertToVtkMatrix (origin, orientation, transformation); 00848 (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; 00849 00850 return (true); 00851 } 00852 00854 template <typename PointT> bool 00855 pcl::visualization::PCLVisualizer::fromHandlersToScreen ( 00856 const GeometryHandlerConstPtr &geometry_handler, 00857 const PointCloudColorHandler<PointT> &color_handler, 00858 const std::string &id, 00859 int viewport) 00860 { 00861 if (!geometry_handler->isCapable ()) 00862 { 00863 PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ()); 00864 return (false); 00865 } 00866 00867 if (!color_handler.isCapable ()) 00868 { 00869 PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ()); 00870 return (false); 00871 } 00872 00873 vtkSmartPointer<vtkPolyData> polydata; 00874 vtkSmartPointer<vtkIdTypeArray> initcells; 00875 // Convert the PointCloud to VTK PolyData 00876 convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells); 00877 // use the given geometry handler 00878 polydata->Update (); 00879 00880 // Get the colors from the handler 00881 vtkSmartPointer<vtkDataArray> scalars; 00882 color_handler.getColor (scalars); 00883 polydata->GetPointData ()->SetScalars (scalars); 00884 00885 // Create an Actor 00886 vtkSmartPointer<vtkLODActor> actor; 00887 createActorFromVTKDataSet (polydata, actor); 00888 00889 // Add it to all renderers 00890 addActorToRenderer (actor, viewport); 00891 00892 // Save the pointer/ID pair to the global actor map 00893 (*cloud_actor_map_)[id].actor = actor; 00894 (*cloud_actor_map_)[id].cells = initcells; 00895 (*cloud_actor_map_)[id].geometry_handlers.push_back (geometry_handler); 00896 return (true); 00897 } 00898 00900 template <typename PointT> bool 00901 pcl::visualization::PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00902 const std::string &id) 00903 { 00904 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00905 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00906 00907 if (am_it == cloud_actor_map_->end ()) 00908 return (false); 00909 00910 vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput (); 00911 // Convert the PointCloud to VTK PolyData 00912 convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells); 00913 polydata->Update (); 00914 00915 // Set scalars to blank, since there is no way we can update them here. 00916 vtkSmartPointer<vtkDataArray> scalars; 00917 polydata->GetPointData ()->SetScalars (scalars); 00918 polydata->Update (); 00919 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); 00920 00921 // Update the mapper 00922 reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata); 00923 return (true); 00924 } 00925 00927 template <typename PointT> bool 00928 pcl::visualization::PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00929 const PointCloudGeometryHandler<PointT> &geometry_handler, 00930 const std::string &id) 00931 { 00932 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00933 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00934 00935 if (am_it == cloud_actor_map_->end ()) 00936 return (false); 00937 00938 vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput (); 00939 if (!polydata) 00940 return (false); 00941 // Convert the PointCloud to VTK PolyData 00942 convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells); 00943 00944 // Set scalars to blank, since there is no way we can update them here. 00945 vtkSmartPointer<vtkDataArray> scalars; 00946 polydata->GetPointData ()->SetScalars (scalars); 00947 polydata->Update (); 00948 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); 00949 00950 // Update the mapper 00951 reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata); 00952 return (true); 00953 } 00954 00955 00957 template <typename PointT> bool 00958 pcl::visualization::PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 00959 const PointCloudColorHandler<PointT> &color_handler, 00960 const std::string &id) 00961 { 00962 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 00963 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 00964 00965 if (am_it == cloud_actor_map_->end ()) 00966 return (false); 00967 00968 // Get the current poly data 00969 vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput (); 00970 if (!polydata) 00971 return (false); 00972 vtkSmartPointer<vtkCellArray> vertices = polydata->GetVerts (); 00973 vtkSmartPointer<vtkPoints> points = polydata->GetPoints (); 00974 // Copy the new point array in 00975 vtkIdType nr_points = cloud->points.size (); 00976 points->SetNumberOfPoints (nr_points); 00977 00978 // Get a pointer to the beginning of the data array 00979 float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0); 00980 00981 // If the dataset is dense (no NaNs) 00982 if (cloud->is_dense) 00983 { 00984 for (vtkIdType i = 0; i < nr_points; ++i) 00985 memcpy (&data[i * 3], &cloud->points[i].x, 12); // sizeof (float) * 3 00986 } 00987 else 00988 { 00989 vtkIdType j = 0; // true point index 00990 for (vtkIdType i = 0; i < nr_points; ++i) 00991 { 00992 // Check if the point is invalid 00993 if (!pcl_isfinite (cloud->points[i].x) || 00994 !pcl_isfinite (cloud->points[i].y) || 00995 !pcl_isfinite (cloud->points[i].z)) 00996 continue; 00997 00998 memcpy (&data[j * 3], &cloud->points[i].x, 12); // sizeof (float) * 3 00999 j++; 01000 } 01001 nr_points = j; 01002 points->SetNumberOfPoints (nr_points); 01003 } 01004 01005 vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData (); 01006 updateCells (cells, am_it->second.cells, nr_points); 01007 01008 // Set the cells and the vertices 01009 vertices->SetCells (nr_points, cells); 01010 01011 // Get the colors from the handler 01012 vtkSmartPointer<vtkDataArray> scalars; 01013 color_handler.getColor (scalars); 01014 polydata->GetPointData ()->SetScalars (scalars); 01015 polydata->Update (); 01016 01017 am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); 01018 01019 // Update the mapper 01020 reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata); 01021 return (true); 01022 } 01023 01025 template <typename PointT> bool 01026 pcl::visualization::PCLVisualizer::addPolygonMesh ( 01027 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 01028 const std::vector<pcl::Vertices> &vertices, 01029 const std::string &id, 01030 int viewport) 01031 { 01032 if (vertices.empty ()) 01033 { 01034 pcl::console::print_error ("[addPolygonMesh] No vertices given!\n"); 01035 return (false); 01036 } 01037 01038 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 01039 if (am_it != cloud_actor_map_->end ()) 01040 { 01041 pcl::console::print_warn ( 01042 "[addPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n", 01043 id.c_str ()); 01044 return (false); 01045 } 01046 01047 // Create points from polyMesh.cloud 01048 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New (); 01049 vtkIdType nr_points = cloud->points.size (); 01050 points->SetNumberOfPoints (nr_points); 01051 vtkSmartPointer<vtkLODActor> actor; 01052 01053 // Get a pointer to the beginning of the data array 01054 float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0); 01055 01056 int ptr = 0; 01057 std::vector<int> lookup; 01058 // If the dataset is dense (no NaNs) 01059 if (cloud->is_dense) 01060 { 01061 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3) 01062 memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3); 01063 } 01064 else 01065 { 01066 lookup.resize (nr_points); 01067 vtkIdType j = 0; // true point index 01068 for (vtkIdType i = 0; i < nr_points; ++i) 01069 { 01070 // Check if the point is invalid 01071 if (!isFinite (cloud->points[i])) 01072 continue; 01073 01074 lookup [i] = j; 01075 memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3); 01076 j++; 01077 ptr += 3; 01078 } 01079 nr_points = j; 01080 points->SetNumberOfPoints (nr_points); 01081 } 01082 01083 // Get the maximum size of a polygon 01084 int max_size_of_polygon = -1; 01085 for (size_t i = 0; i < vertices.size (); ++i) 01086 if (max_size_of_polygon < (int)vertices[i].vertices.size ()) 01087 max_size_of_polygon = vertices[i].vertices.size (); 01088 01089 if (vertices.size () > 1) 01090 { 01091 // Create polys from polyMesh.polygons 01092 vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New (); 01093 vtkIdType *cell = cell_array->WritePointer (vertices.size (), vertices.size () * (max_size_of_polygon + 1)); 01094 int idx = 0; 01095 if (lookup.size () > 0) 01096 { 01097 for (size_t i = 0; i < vertices.size (); ++i, ++idx) 01098 { 01099 size_t n_points = vertices[i].vertices.size (); 01100 *cell++ = n_points; 01101 //cell_array->InsertNextCell (n_points); 01102 for (size_t j = 0; j < n_points; j++, ++idx) 01103 *cell++ = lookup[vertices[i].vertices[j]]; 01104 //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); 01105 } 01106 } 01107 else 01108 { 01109 for (size_t i = 0; i < vertices.size (); ++i, ++idx) 01110 { 01111 size_t n_points = vertices[i].vertices.size (); 01112 *cell++ = n_points; 01113 //cell_array->InsertNextCell (n_points); 01114 for (size_t j = 0; j < n_points; j++, ++idx) 01115 *cell++ = lookup[vertices[i].vertices[j]]; 01116 //cell_array->InsertCellPoint (vertices[i].vertices[j]); 01117 } 01118 } 01119 vtkSmartPointer<vtkPolyData> polydata; 01120 allocVtkPolyData (polydata); 01121 cell_array->GetData ()->SetNumberOfValues (idx); 01122 cell_array->Squeeze (); 01123 polydata->SetStrips (cell_array); 01124 polydata->SetPoints (points); 01125 01126 createActorFromVTKDataSet (polydata, actor, false); 01127 } 01128 else 01129 { 01130 vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New (); 01131 size_t n_points = vertices[0].vertices.size (); 01132 polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); 01133 01134 if (lookup.size () > 0) 01135 { 01136 for (size_t j = 0; j < (n_points - 1); ++j) 01137 polygon->GetPointIds ()->SetId (j, lookup[vertices[0].vertices[j]]); 01138 } 01139 else 01140 { 01141 for (size_t j = 0; j < (n_points - 1); ++j) 01142 polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]); 01143 } 01144 vtkSmartPointer<vtkUnstructuredGrid> poly_grid; 01145 allocVtkUnstructuredGrid (poly_grid); 01146 poly_grid->Allocate (1, 1); 01147 poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); 01148 poly_grid->SetPoints (points); 01149 poly_grid->Update (); 01150 01151 createActorFromVTKDataSet (poly_grid, actor, false); 01152 } 01153 01154 actor->GetProperty ()->SetRepresentationToSurface (); 01155 actor->GetProperty ()->BackfaceCullingOn (); 01156 actor->GetProperty ()->EdgeVisibilityOff (); 01157 actor->GetProperty ()->ShadingOff (); 01158 addActorToRenderer (actor, viewport); 01159 01160 // Save the pointer/ID pair to the global actor map 01161 (*cloud_actor_map_)[id].actor = actor; 01162 (*cloud_actor_map_)[id].cells = static_cast<vtkPolyDataMapper*>(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); 01163 return (true); 01164 } 01165 01167 template <typename PointT> bool 01168 pcl::visualization::PCLVisualizer::updatePolygonMesh ( 01169 const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 01170 const std::vector<pcl::Vertices> &verts, 01171 const std::string &id) 01172 { 01173 if (verts.empty ()) 01174 { 01175 pcl::console::print_error ("[addPolygonMesh] No vertices given!\n"); 01176 return (false); 01177 } 01178 01179 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01180 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 01181 if (am_it == cloud_actor_map_->end ()) 01182 return (false); 01183 01184 // Get the current poly data 01185 vtkSmartPointer<vtkPolyData> polydata = static_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput (); 01186 if (!polydata) 01187 return (false); 01188 vtkSmartPointer<vtkCellArray> cells = polydata->GetStrips (); 01189 if (!cells) 01190 return (false); 01191 vtkSmartPointer<vtkPoints> points = polydata->GetPoints (); 01192 // Copy the new point array in 01193 vtkIdType nr_points = cloud->points.size (); 01194 points->SetNumberOfPoints (nr_points); 01195 01196 // Get a pointer to the beginning of the data array 01197 float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0); 01198 01199 int ptr = 0; 01200 std::vector<int> lookup; 01201 // If the dataset is dense (no NaNs) 01202 if (cloud->is_dense) 01203 { 01204 for (vtkIdType i = 0; i < nr_points; ++i, ptr += 3) 01205 memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3); 01206 } 01207 else 01208 { 01209 lookup.resize (nr_points); 01210 vtkIdType j = 0; // true point index 01211 for (vtkIdType i = 0; i < nr_points; ++i) 01212 { 01213 // Check if the point is invalid 01214 if (!isFinite (cloud->points[i])) 01215 continue; 01216 01217 lookup [i] = j; 01218 memcpy (&data[ptr], &cloud->points[i].x, sizeof (float) * 3); 01219 j++; 01220 ptr += 3; 01221 } 01222 nr_points = j; 01223 points->SetNumberOfPoints (nr_points); 01224 } 01225 01226 // Get the maximum size of a polygon 01227 int max_size_of_polygon = -1; 01228 for (size_t i = 0; i < verts.size (); ++i) 01229 if (max_size_of_polygon < (int)verts[i].vertices.size ()) 01230 max_size_of_polygon = verts[i].vertices.size (); 01231 01232 // Update the cells 01233 cells = vtkSmartPointer<vtkCellArray>::New (); 01234 vtkIdType *cell = cells->WritePointer (verts.size (), verts.size () * (max_size_of_polygon + 1)); 01235 int idx = 0; 01236 if (lookup.size () > 0) 01237 { 01238 for (size_t i = 0; i < verts.size (); ++i, ++idx) 01239 { 01240 size_t n_points = verts[i].vertices.size (); 01241 *cell++ = n_points; 01242 for (size_t j = 0; j < n_points; j++, cell++, ++idx) 01243 *cell = lookup[verts[i].vertices[j]]; 01244 } 01245 } 01246 else 01247 { 01248 for (size_t i = 0; i < verts.size (); ++i, ++idx) 01249 { 01250 size_t n_points = verts[i].vertices.size (); 01251 *cell++ = n_points; 01252 for (size_t j = 0; j < n_points; j++, cell++, ++idx) 01253 *cell = verts[i].vertices[j]; 01254 } 01255 } 01256 cells->GetData ()->SetNumberOfValues (idx); 01257 cells->Squeeze (); 01258 // Set the the vertices 01259 polydata->SetStrips (cells); 01260 polydata->Update (); 01261 01262 /* 01263 vtkSmartPointer<vtkLODActor> actor; 01264 if (vertices.size () > 1) 01265 { 01266 } 01267 else 01268 { 01269 vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New (); 01270 size_t n_points = vertices[0].vertices.size (); 01271 polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); 01272 01273 for (size_t j = 0; j < (n_points - 1); ++j) 01274 polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]); 01275 01276 vtkSmartPointer<vtkUnstructuredGrid> poly_grid; 01277 allocVtkUnstructuredGrid (poly_grid); 01278 poly_grid->Allocate (1, 1); 01279 poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); 01280 poly_grid->SetPoints (points); 01281 poly_grid->Update (); 01282 01283 createActorFromVTKDataSet (poly_grid, actor); 01284 } 01285 */ 01286 01287 // Get the colors from the handler 01288 //vtkSmartPointer<vtkDataArray> scalars; 01289 //color_handler.getColor (scalars); 01290 //polydata->GetPointData ()->SetScalars (scalars); 01291 // polydata->Update (); 01292 01293 am_it->second.actor->GetProperty ()->BackfaceCullingOn (); 01294 // am_it->second.actor->Modified (); 01295 01296 return (true); 01297 } 01298 01299 01301 /* Optimized function: need to do something with the signature as it colides with the general T one 01302 bool 01303 pcl::visualization::PCLVisualizer::updatePointCloud (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud, 01304 const PointCloudColorHandlerRGBField<pcl::PointXYZRGB> &color_handler, 01305 const std::string &id) 01306 { 01307 win_->SetAbortRender (1); 01308 // Check to see if this ID entry already exists (has it been already added to the visualizer?) 01309 CloudActorMap::iterator am_it = cloud_actor_map_->find (id); 01310 01311 if (am_it == cloud_actor_map_->end ()) 01312 return (false); 01313 01314 // Get the current poly data 01315 vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput (); 01316 if (!polydata) 01317 return (false); 01318 vtkSmartPointer<vtkCellArray> vertices = polydata->GetVerts (); 01319 vtkSmartPointer<vtkPoints> points = polydata->GetPoints (); 01320 // vtkUnsignedCharArray* scalars = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); 01321 vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New (); 01322 // Copy the new point array in 01323 vtkIdType nr_points = cloud->points.size (); 01324 points->SetNumberOfPoints (nr_points); 01325 scalars->SetNumberOfComponents (3); 01326 scalars->SetNumberOfTuples (nr_points); 01327 polydata->GetPointData ()->SetScalars (scalars); 01328 unsigned char* colors = scalars->GetPointer (0); 01329 01330 // Get a pointer to the beginning of the data array 01331 float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0); 01332 01333 // If the dataset is dense (no NaNs) 01334 if (cloud->is_dense) 01335 { 01336 for (vtkIdType i = 0; i < nr_points; ++i) 01337 { 01338 memcpy (&data[i * 3], &cloud->points[i].x, 12); // sizeof (float) * 3 01339 int idx = i * 3; 01340 colors[idx ] = cloud->points[i].r; 01341 colors[idx + 1] = cloud->points[i].g; 01342 colors[idx + 2] = cloud->points[i].b; 01343 } 01344 } 01345 else 01346 { 01347 vtkIdType j = 0; // true point index 01348 for (vtkIdType i = 0; i < nr_points; ++i) 01349 { 01350 // Check if the point is invalid 01351 if (!pcl_isfinite (cloud->points[i].x) || 01352 !pcl_isfinite (cloud->points[i].y) || 01353 !pcl_isfinite (cloud->points[i].z)) 01354 continue; 01355 01356 memcpy (&data[j * 3], &cloud->points[i].x, 12); // sizeof (float) * 3 01357 int idx = j * 3; 01358 colors[idx ] = cloud->points[i].r; 01359 colors[idx + 1] = cloud->points[i].g; 01360 colors[idx + 2] = cloud->points[i].b; 01361 j++; 01362 } 01363 nr_points = j; 01364 points->SetNumberOfPoints (nr_points); 01365 scalars->SetNumberOfTuples (nr_points); 01366 } 01367 01368 vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData (); 01369 updateCells (cells, am_it->second.cells, nr_points); 01370 01371 // Set the cells and the vertices 01372 vertices->SetCells (nr_points, cells); 01373 01374 // Update the mapper 01375 reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata); 01376 return (true); 01377 }*/ 01378 01379 01380 #endif
1.7.6.1