00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00044 #include <iostream>
00045 #include <string>
00046 #include <vector>
00047 #include <math.h>
00048 #include <sstream>
00049 
00050 
00051 #include <terminal_tools/print.h>
00052 #include <terminal_tools/parse.h>
00053 #include <terminal_tools/time.h>
00054 
00055 #include <vtk3DSImporter.h>
00056 #include <vtkDataSet.h>
00057 #include <vtkRenderer.h>
00058 #include <vtkSmartPointer.h>
00059 #include <vtkPolyData.h>
00060 #include <vtkPolyDataReader.h>
00061 #include <vtkDataSetMapper.h>
00062 #include <vtkMaskPoints.h>
00063 #include <vtkLODActor.h> 
00064 #include <vtkFloatArray.h>
00065 #include <vtkPointData.h> 
00066 #include <vtkVectorText.h> 
00067 #include <vtkPolyDataMapper.h> 
00068 #include <vtkFollower.h> 
00069 #include <vtkLightKit.h> 
00070 
00071 #include <pcl_vtk_tools/misc.h>
00072 
00073 using namespace std;
00074 using terminal_tools::print_color;
00075 using terminal_tools::print_error;
00076 using terminal_tools::print_warn;
00077 using terminal_tools::print_info;
00078 using terminal_tools::print_debug;
00079 using terminal_tools::print_value;
00080 using terminal_tools::print_highlight;
00081 using terminal_tools::TT_BRIGHT;
00082 using terminal_tools::TT_RED;
00083 using terminal_tools::TT_GREEN;
00084 using terminal_tools::TT_BLUE;
00085 
00086 #define SQR(x) ((x)*(x))
00087 
00088 
00090 void
00091 GetRandomColors (double &r, double &g, double &b)
00092 {
00093   r = (double)(rand () / (RAND_MAX + 1.0));
00094   g = (double)(rand () / (RAND_MAX + 1.0));
00095   b = (double)(rand () / (RAND_MAX + 1.0));
00096   print_warn (stderr, "Using the following random colors: [");
00097   print_value (stderr, "%g", r); print_warn (stderr, ",");
00098   print_value (stderr, "%g", g); print_warn (stderr, ",");
00099   print_value (stderr, "%g", b);
00100   print_warn (stderr, "] as foreground color.\n");
00101 }
00102 
00103 
00104 int
00105 main (int argc, char** argv)
00106 {
00107   terminal_tools::TicToc tictoc;
00108   srand ((unsigned)time (0));
00109   vector<int> pFileIndices;
00110 
00111   vector<int> psize;
00112   double scale = 0.0;
00113   bool lut_enable = false;
00114   bool lod_enable = false;
00115   bool cell_scalar = false;
00116   bool no_shadows = false;
00117 
00118   if (argc < 2)
00119   {
00120     print_error (stderr, "Syntax is: %s [fileName1..N] <options>\n", argv[0]);
00121     fprintf (stderr, "  where options are: -fc r,g,b = foreground color\n");
00122     fprintf (stderr, "                     -ps X     = point size\n");
00123     fprintf (stderr, "                     -lw X     = line width\n");
00124     fprintf (stderr, "                     -sc X     = add X to scale the color (useful when using remission/distance)\n");
00125     fprintf (stderr, "                     -lod 0/1  = use a LOD (Level Of Detail) actor instead (enabled by default)\n");
00126     fprintf (stderr, "                     -text X   = add point indices as text labels with size as X * BB_DIAM (disabled by default)\n");
00127     fprintf (stderr, "                     -minmaxIdx N,M  = use a minimum/maximum threshold for indices to be shown. OPTIONAL\n");
00128     fprintf (stderr, "                     -lut_enable 0/1 = add a color rainbow legend (disabled by default)\n");
00129     fprintf (stderr, "                     -save_cam 0/1   = save the last camera position to file on exit (default "); print_value (stderr, "enabled"); fprintf (stderr, ")\n");
00130     fprintf (stderr, "                     -movie 0/1      = {dis/en}able movie mode (default "); print_value (stderr, "disabled"); fprintf (stderr, ")"); print_error (stderr, " NOTE: resolution set at 640x480!\n");
00131     fprintf (stderr, "                     -cell 0/1       = put colors as scalars for cell data (1) or point data (0) (default : "); print_value (stderr, "point"); fprintf (stderr, ")\n");
00132     fprintf (stderr, "                     -no_shadows 0/1 = turns shadows off (default : "); print_value (stderr, "disabled"); fprintf (stderr, ")\n");
00133     fprintf (stderr, "\n");
00134     fprintf (stderr, "                     -play   0/1    = replays the events and motions specified in the given <logdata.log> file\n");
00135     
00136     return (-1);
00137   }
00138   int minIdx = 0, maxIdx = INT_MAX;
00139   terminal_tools::parse_2x_arguments (argc, argv, "-minmaxIdx", minIdx, maxIdx);
00140   
00141   bool play = false;
00142   terminal_tools::parse_argument (argc, argv, "-play", play);
00143   std::vector<int> pLogFileIndices;
00144   if (play)
00145   {
00146     pLogFileIndices = terminal_tools::parse_file_extension_argument (argc, argv, ".log");
00147     if (pLogFileIndices.size () != 1)
00148     {
00149       print_error (stderr, "Need exactly 1 logfile!\n"); 
00150       return (-1);
00151     }
00152   }
00153   bool save_camera_position = true;
00154   terminal_tools::parse_argument (argc, argv, "-save_cam", save_camera_position);
00155   terminal_tools::parse_argument (argc, argv, "-cell", cell_scalar);
00156   terminal_tools::parse_argument (argc, argv, "-no_shadows", no_shadows);
00157   
00158   double text = 0;
00159   terminal_tools::parse_argument (argc, argv, "-text", text);
00160   int movieMode = 0;
00161   terminal_tools::parse_argument (argc, argv, "-movie", movieMode);
00162   const char* movieFile = "output.avi";
00163 
00164   double fcolor[3] = {0.9, 0.9, 0.9};
00165   std::vector<double> fcolorR, fcolorB, fcolorG;
00166   bool fcolorparam = terminal_tools::parse_multiple_3x_arguments (argc, argv, "-fc", fcolorR, fcolorG, fcolorB);
00167    
00168   double line_width = -1;
00169   terminal_tools::parse_argument (argc, argv, "-lw", line_width);
00170   terminal_tools::parse_multiple_arguments (argc, argv, "-ps", psize);
00171   terminal_tools::parse_argument (argc, argv, "-sc", scale);
00172   terminal_tools::parse_argument (argc, argv, "-lut", lut_enable);
00173   terminal_tools::parse_argument (argc, argv, "-lod", lod_enable);
00174   if (lod_enable)
00175     print_info (stdout, "LOD enabled.\n");
00176 
00177   
00178   pFileIndices = terminal_tools::parse_file_extension_argument (argc, argv, ".vtk");;
00179   
00180 
00181   vtkSmartPointer<vtkPolyData> data;
00182   
00183   
00184   vtkRenderer* ren = vtkRenderer::New ();
00185   
00186   
00187   
00188   if (psize.size () != pFileIndices.size ())
00189     for (unsigned int i = psize.size (); i < pFileIndices.size (); i++)
00190       psize.push_back (1);
00191 
00192   
00193   for (unsigned int i = 0; i < pFileIndices.size (); i++)
00194   {
00195     vtkActor *dataActor;
00196     double minmax[2];
00197     print_info (stderr, "Loading ");
00198     print_value (stderr, "%s ... ", argv[pFileIndices.at(i)]);
00199     tictoc.tic ();
00200     if (pFileIndices.size() != 0)
00201     {
00202       data = load_poly_data_as_data_set(argv[pFileIndices.at (i)]);
00203       
00204       
00205       
00206       print_info ("Loading vtk model with %d vertices/points.", (int)data->GetNumberOfPoints ());
00207     }
00208 
00209     data->GetScalarRange (minmax);
00210     
00211     data->Update ();
00212     fprintf (stderr, "[done, "); print_value (stderr, "%g", tictoc.toc ()); fprintf (stderr, " seconds : "); print_value (stderr, "%d", data->GetNumberOfPoints ()); fprintf (stderr, " 3D points]\n");
00213 
00214     
00215     if ((minmax[0] == 0) && (minmax[1] == 1))
00216     {
00217       if (!fcolorparam)
00218         GetRandomColors (fcolor[0], fcolor[1], fcolor[2]);
00219       
00220       else
00221             {
00222               
00223               if (fcolorR.size () > i)
00224         {
00225           fcolor[0] = fcolorR[i];
00226           fcolor[1] = fcolorG[i];
00227           fcolor[2] = fcolorB[i];
00228         }
00229               
00230               else
00231           GetRandomColors (fcolor[0], fcolor[1], fcolor[2]);
00232             }
00233 
00234       
00235       dataActor = create_actor_from_data_set(data, fcolor[0], fcolor[1], fcolor[2], psize[i], lod_enable);
00236     }
00237     else
00238     {
00239       print_info (stderr, "Scalar values found for %s: ", argv[pFileIndices.at (i)]);
00240       print_value (stderr, "%g", minmax[0]); fprintf (stderr, " -> ");
00241       print_value (stderr, "%g\n", minmax[1]);
00242 
00243       
00244       
00245       
00246       
00247       
00248       {
00249         vtkSmartPointer<vtkLookupTable> lut = create_LUT (minmax, argc, argv);
00250 
00251         if (lut_enable)
00252           ren->AddActor (create_scalar_bar_actor (lut, argc, argv));
00253         
00254         
00255         if (scale > 0)
00256         {
00257           vtkFloatArray *distances = (vtkFloatArray*)data->GetPointData ()->GetScalars ();
00258           for (long int j = 0; j < distances->GetNumberOfTuples (); j++)
00259           {
00260             double c[1];
00261             distances->GetTuple (j, c);
00262             c[0] += scale;
00263             distances->SetTuple (j, c);
00264           }
00265           
00266           data->GetPointData ()->SetScalars (distances);
00267         }
00268         dataActor = create_actor_from_data_set (data, psize[i], lut, minmax, lod_enable);
00269         if (cell_scalar)
00270           dataActor->GetMapper ()->SetScalarModeToUseCellData ();
00271         
00272       }
00273     }
00274     dataActor->GetProperty ()->SetRepresentationToPoints ();
00275     
00276     
00277     if (no_shadows)
00278     {
00279       dataActor->GetProperty ()->ShadingOff (); 
00280       dataActor->GetProperty ()->SetAmbient (1);
00281       dataActor->GetProperty ()->SetDiffuse (0);
00282     }
00283 
00284     if (line_width != -1)
00285       dataActor->GetProperty ()->SetLineWidth (line_width);
00286     
00287     ren->AddActor (dataActor);
00288     
00289     if ((text > 0) && (i == 0))
00290     {
00291       char idx[10];
00292       
00293       double bounds[6];
00294       data->GetBounds (bounds);
00295       double text_scale = text * sqrt ( SQR(bounds[0]-bounds[1]) + SQR(bounds[2]-bounds[3]) +SQR(bounds[4]-bounds[5]) );
00296       double point[3];
00297       int start = max (minIdx, 0);
00298       int stop = min (maxIdx, int(data->GetNumberOfPoints ())-1);
00299       print_info (stderr, "Labeling points with their indices in ");
00300       print_value (stderr, "[%d,%d]\n", start, stop);
00301       for (int j = start; j <= stop; j++)
00302       {
00303         data->GetPoint (j, point);
00304         sprintf (idx, "%d", j);
00305         vtkVectorText *atext = vtkVectorText::New ();
00306         atext->SetText (idx);
00307         vtkPolyDataMapper *textMapper = vtkPolyDataMapper::New ();
00308         textMapper->SetInputConnection (atext->GetOutputPort ());
00309         vtkFollower *textActor = vtkFollower::New ();
00310         textActor->SetMapper (textMapper);
00311         textActor->SetScale (text_scale);
00312         textActor->SetPosition (point[0], point[1], point[2]);
00313         
00314         textActor->SetCamera (ren->GetActiveCamera ());
00315         ren->AddActor (textActor);
00316       }
00317     }
00318   }
00319 
00320   vtkLightKit* lightKit = vtkLightKit::New ();
00321   lightKit->AddLightsToRenderer (ren);
00322 
00323   
00324   char title[256];
00325   if (pFileIndices.size () == 1)
00326     sprintf (title, "3D PointCloud viewer - %s", argv[pFileIndices.at (0)]);
00327   else
00328     sprintf (title, "3D PointCloud viewer");
00329   vtkRenderWindowInteractor* iren;
00330   
00331   
00332   
00333   
00334   
00335   
00336   
00337   
00338   iren = CreateRenderWindowAndInteractor (ren, title, argc, argv);
00339 
00340   vtkSmartPointer<vtkInteractorStyleTUM> style = (vtkSmartPointer<vtkInteractorStyleTUM>)reinterpret_cast<vtkInteractorStyleTUM*>(iren->GetInteractorStyle ());
00341   style->setAdvancedMode (true);
00342   
00343   if (play)
00344   {
00345     vtkSmartPointer<vtkInteractorEventRecorder> recorder = vtkSmartPointer<vtkInteractorEventRecorder>::New ();
00346     recorder->SetInteractor (iren);
00347     recorder->SetFileName (argv[pLogFileIndices.at (0)]);
00348     recorder->SetEnabled (1);
00349     recorder->Play ();
00350   }
00351   
00352   iren->Start ();
00353   
00354   
00355 }
00356