outofcore_viewer.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *
00035  *  \author Justin Rosen (jmylesrosen@gmail.com)
00036  * */
00037 
00038 // C++
00039 #include <iostream>
00040 #include <string>
00041 
00042 // PCL
00043 #include <pcl/common/time.h>
00044 #include <pcl/point_cloud.h>
00045 #include <pcl/point_types.h>
00046 
00047 #include <pcl/PCLPointCloud2.h>
00048 
00049 #include <pcl/io/pcd_io.h>
00050 #include <pcl/io/vtk_lib_io.h>
00051 #include <pcl/pcl_macros.h>
00052 
00053 #include <pcl/console/print.h>
00054 #include <pcl/console/parse.h>
00055 
00056 // PCL - visualziation
00057 //#include <pcl/visualization/pcl_visualizer.h>
00058 #include <pcl/visualization/common/common.h>
00059 #include <pcl/visualization/vtk/vtkVertexBufferObjectMapper.h>
00060 
00061 //#include "vtkVBOPolyDataMapper.h"
00062 
00063 // PCL - outofcore
00064 #include <pcl/outofcore/outofcore.h>
00065 #include <pcl/outofcore/outofcore_impl.h>
00066 
00067 #include <pcl/outofcore/visualization/axes.h>
00068 #include <pcl/outofcore/visualization/camera.h>
00069 #include <pcl/outofcore/visualization/grid.h>
00070 #include <pcl/outofcore/visualization/object.h>
00071 #include <pcl/outofcore/visualization/outofcore_cloud.h>
00072 #include <pcl/outofcore/visualization/scene.h>
00073 #include <pcl/outofcore/visualization/viewport.h>
00074 
00075 using namespace pcl;
00076 using namespace pcl::outofcore;
00077 
00078 using pcl::console::parse_argument;
00079 using pcl::console::find_switch;
00080 using pcl::console::print_error;
00081 using pcl::console::print_warn;
00082 using pcl::console::print_info;
00083 
00084 //typedef PCLPointCloud2 PointT;
00085 typedef PointXYZ PointT;
00086 
00087 typedef OutofcoreOctreeBase<OutofcoreOctreeDiskContainer<PointT>, PointT> octree_disk;
00088 typedef OutofcoreOctreeBaseNode<OutofcoreOctreeDiskContainer<PointT>, PointT> octree_disk_node;
00089 
00090 //typedef octree_base<OutofcoreOctreeDiskContainer<PointT> , PointT> octree_disk;
00091 typedef boost::shared_ptr<octree_disk> OctreeDiskPtr;
00092 //typedef octree_base_node<octree_disk_container<PointT> , PointT> octree_disk_node;
00093 typedef Eigen::aligned_allocator<PointT> AlignedPointT;
00094 
00095 // VTK
00096 #include <vtkActor.h>
00097 #include <vtkActorCollection.h>
00098 #include <vtkActor2DCollection.h>
00099 #include <vtkAppendPolyData.h>
00100 #include <vtkAppendFilter.h>
00101 #include <vtkCamera.h>
00102 #include <vtkCameraActor.h>
00103 #include <vtkCellArray.h>
00104 #include <vtkCellData.h>
00105 #include <vtkCommand.h>
00106 #include <vtkConeSource.h>
00107 #include <vtkCubeSource.h>
00108 #include <vtkDataSetMapper.h>
00109 #include <vtkHull.h>
00110 #include <vtkInformation.h>
00111 #include <vtkInformationStringKey.h>
00112 #include <vtkInteractorStyleTrackballCamera.h>
00113 #include <vtkLODActor.h>
00114 #include <vtkMath.h>
00115 #include <vtkMatrix4x4.h>
00116 #include <vtkMutexLock.h>
00117 #include <vtkObjectFactory.h>
00118 #include <vtkPolyData.h>
00119 #include <vtkProperty.h>
00120 #include <vtkTextActor.h>
00121 #include <vtkRectilinearGrid.h>
00122 #include <vtkRenderer.h>
00123 #include <vtkRenderWindow.h>
00124 #include <vtkRenderWindowInteractor.h>
00125 #include <vtkSmartPointer.h>
00126 #include <vtkUnsignedCharArray.h>
00127 
00128 #include <vtkInteractorStyleRubberBand3D.h>
00129 #include <vtkParallelCoordinatesInteractorStyle.h>
00130 
00131 // Boost
00132 #include <boost/date_time.hpp>
00133 #include <boost/filesystem.hpp>
00134 #include <boost/thread.hpp>
00135 
00136 // Definitions
00137 const int MAX_DEPTH (-1);
00138 
00139 // Globals
00140 vtkSmartPointer<vtkRenderWindow> window;
00141 
00142 
00143 class KeyboardCallback : public vtkCommand
00144 {
00145 public:
00146   vtkTypeMacro(KeyboardCallback, vtkCommand)
00147   ;
00148 
00149   static KeyboardCallback *
00150   New ()
00151   {
00152     return new KeyboardCallback;
00153   }
00154 
00155   void
00156   Execute (vtkObject *caller, unsigned long vtkNotUsed(eventId), void* vtkNotUsed(callData))
00157   {
00158     vtkRenderWindowInteractor *interactor = vtkRenderWindowInteractor::SafeDownCast (caller);
00159     vtkRenderer *renderer = interactor->FindPokedRenderer (interactor->GetEventPosition ()[0],
00160                                                            interactor->GetEventPosition ()[1]);
00161 
00162     std::string key (interactor->GetKeySym ());
00163     bool shift_down = interactor->GetShiftKey();
00164 
00165     cout << "Key Pressed: " << key << endl;
00166 
00167     Scene *scene = Scene::instance ();
00168     OutofcoreCloud *cloud = static_cast<OutofcoreCloud*> (scene->getObjectByName ("my_octree"));
00169 
00170     if (key == "Up" || key == "Down")
00171     {
00172       if (key == "Up" && cloud)
00173       {
00174         if (shift_down)
00175         {
00176           cloud->increaseLodPixelThreshold();
00177         }
00178         else
00179         {
00180           cloud->setDisplayDepth (cloud->getDisplayDepth () + 1);
00181         }
00182       }
00183       else if (key == "Down" && cloud)
00184       {
00185         if (shift_down)
00186         {
00187           cloud->decreaseLodPixelThreshold();
00188         }
00189         else
00190         {
00191           cloud->setDisplayDepth (cloud->getDisplayDepth () - 1);
00192         }
00193       }
00194     }
00195 
00196     if (key == "o")
00197     {
00198       cloud->setDisplayVoxels(1-static_cast<int> (cloud->getDisplayVoxels()));
00199     }
00200 
00201     if (key == "Escape")
00202     {
00203       Eigen::Vector3d min (cloud->getBoundingBoxMin ());
00204       Eigen::Vector3d max (cloud->getBoundingBoxMax ());
00205       renderer->ResetCamera (min.x (), max.x (), min.y (), max.y (), min.z (), max.z ());
00206     }
00207   }
00208 };
00209 
00210 void
00211 renderTimerCallback(vtkObject* caller, unsigned long int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData))
00212 {
00213   vtkRenderWindowInteractor *interactor = vtkRenderWindowInteractor::SafeDownCast (caller);
00214   interactor->Render ();
00215 }
00216 
00217 void
00218 renderStartCallback(vtkObject* vtkNotUsed(caller), unsigned long int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData))
00219 {
00220   //std::cout << "Start...";
00221 }
00222 
00223 void
00224 renderEndCallback(vtkObject* vtkNotUsed(caller), unsigned long int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData))
00225 {
00226   //std::cout << "End" << std::endl;
00227 }
00228 
00229 int
00230 outofcoreViewer (boost::filesystem::path tree_root, int depth, bool display_octree=true, unsigned int gpu_cache_size=512)
00231 {
00232   cout << boost::filesystem::absolute (tree_root) << endl;
00233 
00234   // Create top level scene
00235   Scene *scene = Scene::instance ();
00236 
00237   // Clouds
00238   OutofcoreCloud *cloud = new OutofcoreCloud ("my_octree", tree_root);
00239   cloud->setDisplayDepth (depth);
00240   cloud->setDisplayVoxels (display_octree);
00241   OutofcoreCloud::cloud_data_cache.setCapacity(gpu_cache_size*1024);
00242   scene->addObject (cloud);
00243 
00244 //  OutofcoreCloud *cloud2 = new OutofcoreCloud ("my_octree2", tree_root);
00245 //  cloud2->setDisplayDepth (depth);
00246 //  cloud2->setDisplayVoxels (display_octree);
00247 //  scene->addObject (cloud2);
00248 
00249   // Add Scene Renderables
00250   Grid *grid = new Grid ("origin_grid");
00251   Axes *axes = new Axes ("origin_axes");
00252   scene->addObject (grid);
00253   scene->addObject (axes);
00254 
00255   // Create smart pointer with arguments
00256 //  Grid *grid_raw = new Grid("origin_grid");
00257 //  vtkSmartPointer<Grid> grid;
00258 //  grid.Take(grid_raw);
00259 
00260   // Create window and interactor
00261   vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New ();
00262   window = vtkSmartPointer<vtkRenderWindow>::New ();
00263   window->SetSize (1000, 500);
00264 
00265   interactor->SetRenderWindow (window);
00266   interactor->Initialize ();
00267   interactor->CreateRepeatingTimer (100);
00268 
00269   // Viewports
00270   Viewport octree_viewport (window, 0.0, 0.0, 0.5, 1.0);
00271   Viewport persp_viewport (window, 0.5, 0.0, 1.0, 1.0);
00272 
00273   // Cameras
00274   Camera *persp_camera = new Camera ("persp", persp_viewport.getRenderer ()->GetActiveCamera ());
00275   Camera *octree_camera = new Camera ("octree", octree_viewport.getRenderer ()->GetActiveCamera ());
00276   scene->addCamera (persp_camera);
00277   scene->addCamera (octree_camera);
00278   octree_camera->setDisplay(true);
00279 
00280   // Set viewport cameras
00281   persp_viewport.setCamera (persp_camera);
00282   octree_viewport.setCamera (octree_camera);
00283 
00284   // Render once
00285   window->Render ();
00286 
00287   // Frame cameras
00288   Eigen::Vector3d min (cloud->getBoundingBoxMin ());
00289   Eigen::Vector3d max (cloud->getBoundingBoxMax ());
00290   octree_viewport.getRenderer ()->ResetCamera (min.x (), max.x (), min.y (), max.y (), min.z (), max.z ());
00291   persp_viewport.getRenderer ()->ResetCamera (min.x (), max.x (), min.y (), max.y (), min.z (), max.z ());
00292 
00293   cloud->setRenderCamera(octree_camera);
00294 
00295   // Interactor
00296   // -------------------------------------------------------------------------
00297   vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New ();
00298   style->SetAutoAdjustCameraClippingRange(false);
00299   interactor->SetInteractorStyle (style);
00300 
00301   // Callbacks
00302   // -------------------------------------------------------------------------
00303   vtkSmartPointer<vtkCallbackCommand> render_start_callback = vtkSmartPointer<vtkCallbackCommand>::New();
00304   render_start_callback->SetCallback(renderStartCallback);
00305   window->AddObserver(vtkCommand::StartEvent, render_start_callback);
00306 
00307   vtkSmartPointer<vtkCallbackCommand> render_end_callback = vtkSmartPointer<vtkCallbackCommand>::New();
00308   render_end_callback->SetCallback(renderEndCallback);
00309   window->AddObserver(vtkCommand::EndEvent, render_end_callback);
00310 
00311   vtkSmartPointer<KeyboardCallback> keyboard_callback = vtkSmartPointer<KeyboardCallback>::New ();
00312   interactor->AddObserver (vtkCommand::KeyPressEvent, keyboard_callback);
00313 
00314   interactor->CreateRepeatingTimer(1000);
00315   vtkSmartPointer<vtkCallbackCommand> render_timer_callback = vtkSmartPointer<vtkCallbackCommand>::New();
00316   render_timer_callback->SetCallback(renderTimerCallback);
00317   interactor->AddObserver(vtkCommand::TimerEvent, render_timer_callback);
00318 
00319   interactor->Start ();
00320 
00321   return 0;
00322 }
00323 
00324 void
00325 print_help (int argc, char **argv)
00326 {
00327   //suppress unused parameter warning
00328   assert(argc == argc);
00329 
00330   print_info ("This program is used to visualize outofcore data structure");
00331   print_info ("%s <options> <input_tree_dir> \n", argv[0]);
00332   print_info ("\n");
00333   print_info ("Options:\n");
00334   print_info ("\t -depth <depth>                \t Octree depth\n");
00335   print_info ("\t -display_octree               \t Toggles octree display\n");
00336 //  print_info ("\t -mem_cache_size <size>        \t Size of pointcloud memory cache in MB (Defaults to 1024MB)\n");
00337   print_info ("\t -gpu_cache_size <size>        \t Size of pointcloud gpu cache in MB (512MB)\n");
00338   print_info ("\t -lod_threshold <pixels>       \t Bounding box screen projection threshold (10000)\n");
00339   print_info ("\t -v                            \t Print more verbosity\n");
00340   print_info ("\t -h                            \t Display help\n");
00341   print_info ("\n");
00342 
00343   exit (1);
00344 }
00345 
00346 int
00347 main (int argc, char* argv[])
00348 {
00349 
00350   // Check for help (-h) flag
00351   if (argc > 1)
00352   {
00353     if (find_switch (argc, argv, "-h"))
00354     {
00355       print_help (argc, argv);
00356       return (-1);
00357     }
00358   }
00359 
00360   // If no arguments specified
00361   if (argc - 1 < 1)
00362   {
00363     print_help (argc, argv);
00364     return (-1);
00365   }
00366 
00367   if (find_switch (argc, argv, "-v"))
00368     console::setVerbosityLevel (console::L_DEBUG);
00369 
00370   // Defaults
00371   int depth = 4;
00372 //  unsigned int mem_cache_size = 1024;
00373   unsigned int gpu_cache_size = 512;
00374   unsigned int lod_threshold = 10000;
00375   bool display_octree = find_switch (argc, argv, "-display_octree");
00376 
00377   // Parse options
00378   parse_argument (argc, argv, "-depth", depth);
00379 //  parse_argument (argc, argv, "-mem_cache_size", mem_cache_size);
00380   parse_argument (argc, argv, "-gpu_cache_size", gpu_cache_size);
00381   parse_argument (argc, argv, "-lod_threshold", lod_threshold);
00382 
00383   // Parse non-option arguments
00384   boost::filesystem::path tree_root (argv[argc - 1]);
00385 
00386   // Check if a root directory was specified, use directory of pcd file
00387   if (boost::filesystem::is_directory (tree_root))
00388   {
00389     boost::filesystem::directory_iterator diterend;
00390     for (boost::filesystem::directory_iterator diter (tree_root); diter != diterend; ++diter)
00391     {
00392       const boost::filesystem::path& file = *diter;
00393       if (!boost::filesystem::is_directory (file))
00394       {
00395         if (boost::filesystem::extension (file) == octree_disk_node::node_index_extension)
00396         {
00397           tree_root = file;
00398         }
00399       }
00400     }
00401   }
00402 
00403   return outofcoreViewer (tree_root, depth, display_octree, gpu_cache_size);
00404 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:30