pcl_visualizer.hpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-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 1816 2011-07-15 22:25:18Z rusu $
00037  *
00038  */
00039 
00040 #ifndef MEGATREE_PCL_VISUALIZER_IMPL_H_
00041 #define MEGATREE_PCL_VISUALIZER_IMPL_H_
00042 
00043 #include <vtkCellData.h>
00044 #include <vtkProperty2D.h>
00045 #include <vtkMapper2D.h>
00046 #include <vtkLeaderActor2D.h>
00047 
00048 namespace megatree {
00049   namespace visualization {
00050   
00052     template <typename PointT> bool 
00053     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     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     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     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     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     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     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     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     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     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 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     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 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 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       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     PCLVisualizer::addSphere (const PointT &center, 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 PCLVisualizer::addSphere (const PointT &center, 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 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     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     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 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       //style_->setCloudActorMap (cloud_actor_map_);
00683       return (true);
00684     }
00685 
00687     template <typename PointT> bool
00688 PCLVisualizer::addCorrespondences (
00689    const typename pcl::PointCloud<PointT>::ConstPtr &source_points,
00690    const typename pcl::PointCloud<PointT>::ConstPtr &target_points,
00691    const std::vector<pcl::Correspondence> &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 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       return (true);
00788     }
00789 
00791     template <typename PointT> bool
00792     PCLVisualizer::fromHandlersToScreen (
00793       const PointCloudGeometryHandler<PointT> &geometry_handler,
00794       const ColorHandlerConstPtr &color_handler, 
00795       const std::string &id,
00796       int viewport)
00797     {
00798       if (!geometry_handler.isCapable ())
00799       {
00800         PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler.getName ().c_str ());
00801         return (false);
00802       }
00803 
00804       if (!color_handler->isCapable ())
00805       {
00806         PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler->getName ().c_str ());
00807         return (false);
00808       }
00809 
00810       vtkSmartPointer<vtkPolyData> polydata;
00811       vtkSmartPointer<vtkIdTypeArray> initcells;
00812       // Convert the PointCloud to VTK PolyData
00813       convertPointCloudToVTKPolyData<PointT> (geometry_handler, polydata, initcells);
00814       // use the given geometry handler
00815       polydata->Update ();
00816 
00817       // Get the colors from the handler
00818       vtkSmartPointer<vtkDataArray> scalars;
00819       color_handler->getColor (scalars);
00820       polydata->GetPointData ()->SetScalars (scalars);
00821 
00822       // Create an Actor
00823       vtkSmartPointer<vtkLODActor> actor;
00824       createActorFromVTKDataSet (polydata, actor);
00825 
00826       // Add it to all renderers
00827       addActorToRenderer (actor, viewport);
00828 
00829       // Save the pointer/ID pair to the global actor map
00830       (*cloud_actor_map_)[id].actor = actor;
00831       (*cloud_actor_map_)[id].cells = initcells;
00832       (*cloud_actor_map_)[id].color_handlers.push_back (color_handler);
00833       return (true);
00834     }
00835 
00837     template <typename PointT> bool
00838     PCLVisualizer::fromHandlersToScreen (
00839       const GeometryHandlerConstPtr &geometry_handler,
00840       const PointCloudColorHandler<PointT> &color_handler, 
00841       const std::string &id,
00842       int viewport)
00843     {
00844       if (!geometry_handler->isCapable ())
00845       {
00846         PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid geometry handler (%s)!\n", id.c_str (), geometry_handler->getName ().c_str ());
00847         return (false);
00848       }
00849 
00850       if (!color_handler.isCapable ())
00851       {
00852         PCL_WARN ("[fromHandlersToScreen] PointCloud <%s> requested with an invalid color handler (%s)!\n", id.c_str (), color_handler.getName ().c_str ());
00853         return (false);
00854       }
00855 
00856       vtkSmartPointer<vtkPolyData> polydata;
00857       vtkSmartPointer<vtkIdTypeArray> initcells;
00858       // Convert the PointCloud to VTK PolyData
00859       convertPointCloudToVTKPolyData (geometry_handler, polydata, initcells);
00860       // use the given geometry handler
00861       polydata->Update ();
00862 
00863       // Get the colors from the handler
00864       vtkSmartPointer<vtkDataArray> scalars;
00865       color_handler.getColor (scalars);
00866       polydata->GetPointData ()->SetScalars (scalars);
00867 
00868       // Create an Actor
00869       vtkSmartPointer<vtkLODActor> actor;
00870       createActorFromVTKDataSet (polydata, actor);
00871 
00872       // Add it to all renderers
00873       addActorToRenderer (actor, viewport);
00874 
00875       // Save the pointer/ID pair to the global actor map
00876       (*cloud_actor_map_)[id].actor = actor;
00877       (*cloud_actor_map_)[id].cells = initcells;
00878       (*cloud_actor_map_)[id].geometry_handlers.push_back (geometry_handler);
00879       return (true);
00880     }
00881 
00883     template <typename PointT> bool
00884     PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 
00885                                      const std::string &id)
00886     {
00887       // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00888       CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00889 
00890       if (am_it == cloud_actor_map_->end ())
00891         return (false);
00892 
00893       vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
00894       // Convert the PointCloud to VTK PolyData
00895       convertPointCloudToVTKPolyData<PointT> (cloud, polydata, am_it->second.cells);
00896       polydata->Update ();
00897 
00898       // Set scalars to blank, since there is no way we can update them here. 
00899       vtkSmartPointer<vtkDataArray> scalars;
00900       polydata->GetPointData ()->SetScalars (scalars);
00901       polydata->Update ();
00902       am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
00903 
00904       // Update the mapper
00905       reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
00906       return (true);
00907     }
00908 
00910     template <typename PointT> bool
00911     PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 
00912                                      const PointCloudGeometryHandler<PointT> &geometry_handler,
00913                                      const std::string &id)
00914     {
00915       // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00916       CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00917 
00918       if (am_it == cloud_actor_map_->end ())
00919         return (false);
00920 
00921       vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
00922       if (!polydata)
00923         return (false);
00924       // Convert the PointCloud to VTK PolyData
00925       convertPointCloudToVTKPolyData (geometry_handler, polydata, am_it->second.cells);
00926 
00927       // Set scalars to blank, since there is no way we can update them here. 
00928       vtkSmartPointer<vtkDataArray> scalars;
00929       polydata->GetPointData ()->SetScalars (scalars);
00930       polydata->Update ();
00931       am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
00932 
00933       // Update the mapper
00934       reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
00935       return (true);
00936     }
00937 
00938 
00940     template <typename PointT> bool
00941     PCLVisualizer::updatePointCloud (const typename pcl::PointCloud<PointT>::ConstPtr &cloud, 
00942                                      const PointCloudColorHandler<PointT> &color_handler,
00943                                      const std::string &id)
00944     {
00945       // Check to see if this ID entry already exists (has it been already added to the visualizer?)
00946       CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
00947 
00948       if (am_it == cloud_actor_map_->end ())
00949         return (false);
00950 
00951       // Get the current poly data
00952       vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
00953       if (!polydata)
00954         return (false);
00955       vtkSmartPointer<vtkCellArray> vertices = polydata->GetVerts ();
00956       vtkSmartPointer<vtkPoints> points      = polydata->GetPoints ();
00957       // Copy the new point array in
00958       vtkIdType nr_points = cloud->points.size ();
00959       points->SetNumberOfPoints (nr_points);
00960   
00961       // Get a pointer to the beginning of the data array
00962       float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0);
00963 
00964       // If the dataset is dense (no NaNs)
00965       if (cloud->is_dense)
00966       {
00967         for (vtkIdType i = 0; i < nr_points; ++i)
00968           memcpy (&data[i * 3], &cloud->points[i].x, 12);    // sizeof (float) * 3
00969       }
00970       else
00971       {
00972         vtkIdType j = 0;    // true point index
00973         for (vtkIdType i = 0; i < nr_points; ++i)
00974         {
00975           // Check if the point is invalid
00976           if (!pcl_isfinite (cloud->points[i].x) || 
00977               !pcl_isfinite (cloud->points[i].y) || 
00978               !pcl_isfinite (cloud->points[i].z))
00979             continue;
00980 
00981           memcpy (&data[j * 3], &cloud->points[i].x, 12);    // sizeof (float) * 3
00982           j++;
00983         }
00984         nr_points = j;
00985         points->SetNumberOfPoints (nr_points);
00986       }
00987 
00988       vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
00989       updateCells (cells, am_it->second.cells, nr_points);
00990 
00991       // Set the cells and the vertices
00992       vertices->SetCells (nr_points, cells);
00993 
00994       // Get the colors from the handler
00995       vtkSmartPointer<vtkDataArray> scalars;
00996       color_handler.getColor (scalars);
00997       polydata->GetPointData ()->SetScalars (scalars);
00998       polydata->Update ();
00999   
01000       am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff ();
01001 
01002       // Update the mapper
01003       reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
01004       return (true);
01005     }
01006 
01008     template <typename PointT> bool
01009     PCLVisualizer::addPolygonMesh (
01010       const typename pcl::PointCloud<PointT>::ConstPtr &cloud,
01011       const std::vector<pcl::Vertices> &vertices,
01012       const std::string &id,
01013       int viewport)
01014     {
01015       ShapeActorMap::iterator am_it = shape_actor_map_->find (id);
01016       if (am_it != shape_actor_map_->end ())
01017       {
01018         pcl::console::print_warn (
01019           "[addPolygonMesh] A shape with id <%s> already exists! Please choose a different id and retry.\n",
01020           id.c_str ());
01021         return (false);
01022       }
01023 
01024       // Create points from polyMesh.cloud
01025       vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New ();
01026       vtkIdType nr_points = cloud->points.size ();
01027       points->SetNumberOfPoints (nr_points);
01028 
01029       // Get a pointer to the beginning of the data array
01030       float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0);
01031 
01032       // If the dataset is dense (no NaNs)
01033       if (cloud->is_dense)
01034       {
01035         for (vtkIdType i = 0; i < nr_points; ++i)
01036           memcpy (&data[i * 3], &cloud->points[i].x, 12);    // sizeof (float) * 3
01037       }
01038       else
01039       {
01040         vtkIdType j = 0;    // true point index
01041         for (vtkIdType i = 0; i < nr_points; ++i)
01042         {
01043           // Check if the point is invalid
01044           if (!pcl_isfinite (cloud->points[i].x) || 
01045               !pcl_isfinite (cloud->points[i].y) || 
01046               !pcl_isfinite (cloud->points[i].z))
01047             continue;
01048 
01049           memcpy (&data[j * 3], &cloud->points[i].x, 12);    // sizeof (float) * 3
01050           j++;
01051         }
01052         nr_points = j;
01053         points->SetNumberOfPoints (nr_points);
01054       }
01055 
01056       vtkSmartPointer<vtkLODActor> actor;
01057       if (vertices.size () > 1) 
01058       {
01059         //create polys from polyMesh.polygons
01060         vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New ();
01061     
01062         for (size_t i = 0; i < vertices.size (); ++i) 
01063         {
01064           size_t n_points = vertices[i].vertices.size ();
01065           cell_array->InsertNextCell (n_points);
01066           for (size_t j = 0; j < n_points; j++) 
01067             cell_array->InsertCellPoint (vertices[i].vertices[j]);
01068         }
01069 
01070         vtkSmartPointer<vtkPolyData> polydata;
01071         allocVtkPolyData (polydata);
01072         polydata->SetStrips (cell_array);
01073         polydata->SetPoints (points);
01074 
01075         createActorFromVTKDataSet (polydata, actor);
01076       } 
01077       else 
01078       {
01079         vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New ();
01080         size_t n_points = vertices[0].vertices.size ();
01081         polygon->GetPointIds ()->SetNumberOfIds (n_points - 1);
01082 
01083         for (size_t j = 0; j < (n_points - 1); ++j) 
01084           polygon->GetPointIds ()->SetId (j, vertices[0].vertices[j]);
01085 
01086         vtkSmartPointer<vtkUnstructuredGrid> poly_grid;
01087         allocVtkUnstructuredGrid (poly_grid);
01088         poly_grid->Allocate (1, 1);
01089         poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ());
01090         poly_grid->SetPoints (points);
01091         poly_grid->Update ();
01092 
01093         createActorFromVTKDataSet (poly_grid, actor);
01094       }
01095 
01096       actor->GetProperty ()->SetRepresentationToWireframe ();
01097       addActorToRenderer (actor, viewport);
01098 
01099       // Save the pointer/ID pair to the global actor map
01100       (*shape_actor_map_)[id] = actor;
01101       return (true);
01102     }
01103 
01104 
01106     /* Optimized function: need to do something with the signature as it colides with the general T one
01107        bool
01108        PCLVisualizer::updatePointCloud (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud, 
01109        const PointCloudColorHandlerRGBField<pcl::PointXYZRGB> &color_handler,
01110        const std::string &id)
01111        {
01112        win_->SetAbortRender (1);
01113        // Check to see if this ID entry already exists (has it been already added to the visualizer?)
01114        CloudActorMap::iterator am_it = cloud_actor_map_->find (id);
01115 
01116        if (am_it == cloud_actor_map_->end ())
01117        return (false);
01118 
01119        // Get the current poly data
01120        vtkSmartPointer<vtkPolyData> polydata = reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->GetInput ();
01121        if (!polydata)
01122        return (false);
01123        vtkSmartPointer<vtkCellArray> vertices = polydata->GetVerts ();
01124        vtkSmartPointer<vtkPoints> points      = polydata->GetPoints ();
01125        //  vtkUnsignedCharArray* scalars = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ());
01126        vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New ();
01127        // Copy the new point array in
01128        vtkIdType nr_points = cloud->points.size ();
01129        points->SetNumberOfPoints (nr_points);
01130        scalars->SetNumberOfComponents (3);
01131        scalars->SetNumberOfTuples (nr_points);
01132        polydata->GetPointData ()->SetScalars (scalars);
01133        unsigned char* colors = scalars->GetPointer (0);
01134  
01135        // Get a pointer to the beginning of the data array
01136        float *data = ((vtkFloatArray*)points->GetData ())->GetPointer (0);
01137 
01138        // If the dataset is dense (no NaNs)
01139        if (cloud->is_dense)
01140        {
01141        for (vtkIdType i = 0; i < nr_points; ++i)
01142        {
01143        memcpy (&data[i * 3], &cloud->points[i].x, 12);    // sizeof (float) * 3
01144        int idx = i * 3;
01145        colors[idx    ] = cloud->points[i].r;
01146        colors[idx + 1] = cloud->points[i].g;
01147        colors[idx + 2] = cloud->points[i].b;
01148        }
01149        }
01150        else
01151        {
01152        vtkIdType j = 0;    // true point index
01153        for (vtkIdType i = 0; i < nr_points; ++i)
01154        {
01155        // Check if the point is invalid
01156        if (!pcl_isfinite (cloud->points[i].x) || 
01157        !pcl_isfinite (cloud->points[i].y) || 
01158        !pcl_isfinite (cloud->points[i].z))
01159        continue;
01160 
01161        memcpy (&data[j * 3], &cloud->points[i].x, 12);    // sizeof (float) * 3
01162        int idx = j * 3;
01163        colors[idx    ] = cloud->points[i].r;
01164        colors[idx + 1] = cloud->points[i].g;
01165        colors[idx + 2] = cloud->points[i].b;
01166        j++;
01167        }
01168        nr_points = j;
01169        points->SetNumberOfPoints (nr_points);
01170        scalars->SetNumberOfTuples (nr_points);
01171        }
01172 
01173        vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData ();
01174        updateCells (cells, am_it->second.cells, nr_points);
01175 
01176        // Set the cells and the vertices
01177        vertices->SetCells (nr_points, cells);
01178 
01179        // Update the mapper
01180        reinterpret_cast<vtkPolyDataMapper*>(am_it->second.actor->GetMapper ())->SetInput (polydata);
01181        return (true);
01182        }*/
01183 
01184   } // namespace
01185 } // namespace
01186 
01187 #endif


megatree_cpp
Author(s): Stuart Glaser
autogenerated on Mon Dec 2 2013 13:01:28