cloud_viewer.cpp
Go to the documentation of this file.
00001 
00038 #include <pcl/visualization/cloud_viewer.h>
00039 #include <pcl/visualization/pcl_visualizer.h>
00040 
00041 #include <boost/thread.hpp>
00042 #include <boost/thread/mutex.hpp>
00043 #include <boost/foreach.hpp>
00044 
00045 namespace pcl
00046 {
00047   struct cloud_show_base
00048   {
00049     virtual void pop () = 0;
00050     virtual bool popped () const = 0;
00051     typedef boost::shared_ptr<cloud_show_base> Ptr;
00052   };
00053 
00054   template <typename CloudT> 
00055   struct cloud_show : cloud_show_base
00056   {
00057     cloud_show (const std::string &cloud_name, typename CloudT::ConstPtr cloud,
00058       boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer) :
00059       cloud_name (cloud_name), cloud (cloud), viewer (viewer),popped_ (false)
00060     {}
00061 
00062     template <typename Handler> void
00063     pop (const Handler &handler)
00064     {
00065       double psize = 1.0, opacity = 1.0, linesize =1.0;
00066       viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, linesize, cloud_name);
00067       viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opacity, cloud_name);
00068       viewer->getPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, cloud_name);
00069 
00070       if (!viewer->updatePointCloud (cloud, handler, cloud_name))
00071       {
00072         viewer->addPointCloud (cloud, handler, cloud_name);
00073         viewer->resetCameraViewpoint (cloud_name);
00074       }
00075 
00076       // viewer->removePointCloud (cloud_name);
00077       viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, linesize, cloud_name);
00078       viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opacity, cloud_name);
00079       viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, cloud_name);
00080       popped_ = true;
00081     }
00082 
00083     virtual void pop ();
00084     
00085     virtual bool
00086     popped () const
00087     {
00088       return popped_;
00089     }
00090     
00091     std::string cloud_name;
00092     typename CloudT::ConstPtr cloud;
00093     boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
00094     bool popped_;
00095   };
00096   
00097   typedef pcl::PointCloud<pcl::PointXYZRGBA> cca;
00098   typedef pcl::PointCloud<pcl::PointXYZRGB> cc;
00099   typedef pcl::PointCloud<pcl::PointXYZI> gc;
00100   typedef pcl::PointCloud<pcl::PointXYZ> mc;
00101 
00102   template <> void
00103   cloud_show<cca>::pop ()
00104   {
00105     pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGBA> handler (cloud);
00106     pop (handler);
00107   }
00108   
00109   template <> void
00110   cloud_show<cc>::pop ()
00111   {
00112     pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> handler (cloud);
00113     pop (handler);
00114   }
00115   
00116   template <> void
00117   cloud_show<gc>::pop ()
00118   {
00119     pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> handler (cloud, "intensity");
00120     pop (handler);
00121   }
00122   
00123   template <> void
00124   cloud_show<mc>::pop ()
00125   {
00126     pcl::visualization::PointCloudGeometryHandlerXYZ<pcl::PointXYZ> handler (cloud);
00127     pop (handler);
00128   }
00129 }
00130 
00131 struct pcl::visualization::CloudViewer::CloudViewer_impl
00132 {
00134   CloudViewer_impl (const std::string& window_name) :
00135     window_name_ (window_name), has_cloud_ (false), quit_ (false)
00136   {
00137     viewer_thread_ = boost::thread (boost::ref (*this));
00138     while (!viewer_)
00139     {
00140       boost::thread::yield ();
00141     }
00142   }
00143 
00144   ~CloudViewer_impl ()
00145   {
00146   }
00147 
00149   template <typename T> void
00150   block_post_cloud (const typename T::ConstPtr &cloud, const std::string &name)
00151   {
00152     cloud_show_base::Ptr cs (new cloud_show<T>(name,cloud,viewer_));
00153     {
00154       boost::mutex::scoped_lock lock (mtx_);
00155       cloud_shows_.push_back (cs);
00156     }
00157     while (!cs->popped ())
00158     {
00159       boost::thread::yield ();
00160     }
00161   }
00162 
00163   template <typename T> void
00164   nonblock_post_cloud (const typename T::ConstPtr &cloud, const std::string &name)
00165   {
00166     cloud_show_base::Ptr cs (new cloud_show<T>(name,cloud,viewer_));
00167     {
00168       boost::mutex::scoped_lock lock (mtx_);
00169 
00170       cloud_shows_.push_back (cs);
00171     }
00172   }
00173 
00175   void
00176   operator() ()
00177   {
00178     using namespace pcl::visualization;
00179 
00180 #if ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION <= 4))
00181     viewer_ = boost::shared_ptr<PCLVisualizer>(new PCLVisualizer (window_name_));
00182 #else
00183     viewer_ = boost::shared_ptr<PCLVisualizer>(new PCLVisualizer (window_name_, true));
00184 #endif
00185     viewer_->setBackgroundColor (0.1, 0.1, 0.1);
00186     viewer_->addCoordinateSystem (0.1);
00187 
00188     while (!quit_)
00189     {
00190       {
00191         boost::mutex::scoped_lock lock (mtx_);
00192         while (!cloud_shows_.empty ())
00193         {
00194           cloud_shows_.back ()->pop ();
00195           cloud_shows_.pop_back ();
00196         }
00197       }
00198       {
00199         boost::mutex::scoped_lock lock (once_mtx);
00200         BOOST_FOREACH (CallableList::value_type& x, callables_once)
00201         {
00202           (x)(*viewer_);
00203         }
00204         callables_once.clear ();
00205       }
00206       {
00207         boost::mutex::scoped_lock lock (c_mtx);
00208         BOOST_FOREACH (CallableMap::value_type& x, callables)
00209         {
00210           (x.second)(*viewer_);
00211         }
00212       }
00213       if (viewer_->wasStopped ())
00214       {
00215           quit_ = true;
00216       }else
00217       {
00218         boost::mutex::scoped_lock lock (spin_mtx_);
00219         //TODO some smart waitkey like stuff here, so that wasStoped() can hold for a long time
00220         //maybe a counter
00221         viewer_->spinOnce (10); // Give the GUI millis to handle events, then return
00222       }
00223 
00224     }
00225     viewer_.reset ();
00226   }
00227 
00229   void
00230   post (VizCallable x, const std::string &key)
00231   {
00232     boost::mutex::scoped_lock lock (c_mtx);
00233     callables[key] = x;
00234   }
00235 
00236   void
00237   post (VizCallable x)
00238   {
00239     boost::mutex::scoped_lock lock (once_mtx);
00240     callables_once.push_back (x);
00241   }
00242 
00244   void
00245   remove (const std::string &key)
00246   {
00247     boost::mutex::scoped_lock lock (c_mtx);
00248     if (callables.find (key) != callables.end ())
00249       callables.erase (key);
00250   }
00251 
00252   std::string window_name_;
00253   boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer_;
00254   boost::mutex mtx_, spin_mtx_, c_mtx, once_mtx;
00255   boost::thread viewer_thread_;
00256   bool has_cloud_;
00257   bool quit_;
00258   std::list<boost::shared_ptr<cloud_show_base> > cloud_shows_;
00259   typedef std::map<std::string, VizCallable> CallableMap;
00260   CallableMap callables;
00261   typedef std::list<VizCallable> CallableList;
00262   CallableList callables_once;
00263 };
00264 
00266 pcl::visualization::CloudViewer::CloudViewer (const std::string &window_name) :
00267   impl_ (new CloudViewer_impl (window_name))
00268 {}
00269 
00270 pcl::visualization::CloudViewer::~CloudViewer ()
00271 {
00272   impl_->quit_ = true;
00273   impl_->viewer_thread_.join();
00274 }
00275 
00277 void
00278 pcl::visualization::CloudViewer::showCloud (const ColorACloud::ConstPtr &cloud,
00279                                             const std::string &cloudname)
00280 {
00281   if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
00282     return;
00283   impl_->block_post_cloud<ColorACloud>(cloud, cloudname);
00284 }
00285 
00287 void
00288 pcl::visualization::CloudViewer::showCloud (const ColorCloud::ConstPtr &cloud,
00289                                             const std::string &cloudname)
00290 {
00291   if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
00292     return;
00293   impl_->block_post_cloud<ColorCloud>(cloud, cloudname);
00294 }
00295 
00297 void
00298 pcl::visualization::CloudViewer::showCloud (const GrayCloud::ConstPtr &cloud,
00299                                             const std::string &cloudname)
00300 {
00301   if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
00302     return;
00303   impl_->block_post_cloud<GrayCloud>(cloud, cloudname);
00304 }
00305 
00307 void
00308 pcl::visualization::CloudViewer::showCloud (const MonochromeCloud::ConstPtr &cloud,
00309                                             const std::string &cloudname)
00310 {
00311   if (!impl_->viewer_ || impl_->viewer_->wasStopped ())
00312     return;
00313   impl_->block_post_cloud<MonochromeCloud>(cloud, cloudname);
00314 }
00315 
00317 void
00318 pcl::visualization::CloudViewer::runOnVisualizationThread (VizCallable x, const std::string &key)
00319 {
00320   impl_->post (x, key);
00321 }
00322 
00324 void
00325 pcl::visualization::CloudViewer::runOnVisualizationThreadOnce (VizCallable x)
00326 {
00327   impl_->post (x);
00328 }
00329 
00331 void
00332 pcl::visualization::CloudViewer::removeVisualizationCallable (const std::string &key)
00333 {
00334   impl_->remove (key);
00335 }
00336 
00338 bool
00339 pcl::visualization::CloudViewer::wasStopped (int)
00340 {
00341   boost::thread::yield (); //allow this to be called in a loop
00342   return !impl_->viewer_;
00343 }
00344 
00346 boost::signals2::connection
00347 pcl::visualization::CloudViewer::registerKeyboardCallback (boost::function<void (const pcl::visualization::KeyboardEvent&)> callback)
00348 {
00349   return impl_->viewer_->registerKeyboardCallback (callback);
00350 }
00351 
00353 boost::signals2::connection
00354 pcl::visualization::CloudViewer::registerMouseCallback (boost::function<void (const pcl::visualization::MouseEvent&)> callback)
00355 {
00356   return impl_->viewer_->registerMouseCallback (callback);
00357 }
00358 
00360 boost::signals2::connection
00361 pcl::visualization::CloudViewer::registerPointPickingCallback (boost::function<void (const pcl::visualization::PointPickingEvent&)> callback)
00362 {
00363   return (impl_->viewer_->registerPointPickingCallback (callback));
00364 }
00365 


pcl
Author(s): Open Perception
autogenerated on Mon Oct 6 2014 03:14:40