Пример #1
0
bool
pcl::visualization::PCLVisualizerInteractorStyle::loadCameraParameters (const std::string &file)
{
  std::ifstream fs;
  std::string line;
  std::vector<std::string> camera;
  bool ret;

  fs.open (file.c_str ());
  while (!fs.eof ())
  {
    getline (fs, line);
    if (line == "")
      continue;

    boost::split (camera, line, boost::is_any_of ("/"), boost::token_compress_on);
    break;
  }
  fs.close ();

  ret = getCameraParameters (camera);
  if (ret)
  {
    camera_file_ = file;
  }

  return (ret);
}
Пример #2
0
static int runFusibile (int argc,
                        char **argv,
                        AlgorithmParameters &algParameters
                       )
{
    InputFiles inputFiles;
    string ext = ".png";

    string results_folder = "results/";

    const char* results_folder_opt     = "-input_folder";
    const char* p_input_folder_opt = "-p_folder";
    const char* krt_file_opt = "-krt_file";
    const char* images_input_folder_opt = "-images_folder";
    const char* gt_opt = "-gt";
    const char* gt_nocc_opt = "-gt_nocc";
    const char* pmvs_folder_opt = "--pmvs_folder";
    const char* remove_black_background_opt = "-remove_black_background";
    //read in arguments
    for ( int i = 1; i < argc; i++ )
    {
        if ( strcmp ( argv[i], results_folder_opt ) == 0 ){
            results_folder = argv[++i];
            cout << "input folder is " << results_folder << endl;

        }else if ( strcmp ( argv[i], p_input_folder_opt ) == 0 ){
            inputFiles.p_folder = argv[++i];
        }
        else if ( strcmp ( argv[i], krt_file_opt ) == 0 )
            inputFiles.krt_file = argv[++i];
        else if ( strcmp ( argv[i], images_input_folder_opt ) == 0 ){
            inputFiles.images_folder = argv[++i];

        }else if ( strcmp ( argv[i], gt_opt ) == 0 ){
            inputFiles.gt_filename = argv[++i];

        }else if ( strcmp ( argv[i], gt_nocc_opt ) == 0 ){
            inputFiles.gt_nocc_filename = argv[++i];
        }
        else if ( strncmp ( argv[i], pmvs_folder_opt, strlen ( pmvs_folder_opt ) ) == 0 ) {
            inputFiles.pmvs_folder = argv[++i];
        }
        else if ( strcmp ( argv[i], remove_black_background_opt ) == 0 )
            algParameters.remove_black_background = true;
    }

    if (inputFiles.pmvs_folder.size()>0) {
        inputFiles.images_folder = inputFiles.pmvs_folder + "/visualize/";
        inputFiles.p_folder = inputFiles.pmvs_folder + "/txt/";
    }
    cout <<"image folder is " << inputFiles.images_folder << endl;
    cout <<"p folder is " << inputFiles.images_folder << endl;
    cout <<"pmvs folder is " << inputFiles.pmvs_folder << endl;

    GTcheckParameters gtParameters;

    gtParameters.dispTolGT = 0.1f;
    gtParameters.dispTolGT2 = 0.02f;
    gtParameters.divFactor = 1.0f;
    // create folder to store result images
    time_t timeObj;
    time ( &timeObj );
    tm *pTime = localtime ( &timeObj );

    vector <Mat_<Vec3f> > view_vectors;


    time(&timeObj);
    pTime = localtime(&timeObj);

    char output_folder[256];
    sprintf(output_folder, "%s/consistencyCheck-%04d%02d%02d-%02d%02d%02d/",results_folder.c_str(), pTime->tm_year+1900, pTime->tm_mon+1,pTime->tm_mday,pTime->tm_hour, pTime->tm_min, pTime->tm_sec);
#if defined(_WIN32)
    _mkdir(output_folder);
#else
    mkdir(output_folder, 0777);
#endif

    vector<string> subfolders;
    get_subfolders(results_folder.c_str(), subfolders);
    std::sort(subfolders.begin(), subfolders.end());

    vector< Mat_<Vec3b> > warpedImages;
    vector< Mat_<Vec3b> > warpedImages_inverse;
    //vector< Mat_<float> > depthMaps;
    vector< Mat_<float> > updateMaps;
    vector< Mat_<Vec3f> > updateNormals;
    vector< Mat_<float> > depthMapConsistent;
    vector< Mat_<Vec3f> > normalsConsistent;
    vector< Mat_<Vec3f> > groundTruthNormals;
    vector< Mat_<uint8_t> > valid;


    map< int,string> consideredIds;
    for(size_t i=0;i<subfolders.size();i++) {
        //make sure that it has the right format (DATE_TIME_INDEX)
        size_t n = std::count(subfolders[i].begin(), subfolders[i].end(), '_');
        if(n < 2)
            continue;
        if (subfolders[i][0] != '2')
            continue;

        //get index
        //unsigned found = subfolders[i].find_last_of("_");
        //find second index
        unsigned posFirst = subfolders[i].find_first_of("_") +1;
        unsigned found = subfolders[i].substr(posFirst).find_first_of("_") + posFirst +1;
        string id_string = subfolders[i].substr(found);
        //InputData dat;

        //consideredIds.push_back(id_string);
        consideredIds.insert(pair<int,string>(i,id_string));
        //cout << "id_string is " << id_string << endl;
        //cout << "i is " << i << endl;
        //char outputPath[256];
        //sprintf(outputPath, "%s.png", id_string);

        if( access( (inputFiles.images_folder + id_string + ".png").c_str(), R_OK ) != -1 )
            inputFiles.img_filenames.push_back((id_string + ".png"));
        else if( access( (inputFiles.images_folder + id_string + ".jpg").c_str(), R_OK ) != -1 )
            inputFiles.img_filenames.push_back((id_string + ".jpg"));
        else if( access( (inputFiles.images_folder + id_string + ".ppm").c_str(), R_OK ) != -1 )
            inputFiles.img_filenames.push_back((id_string + ".ppm"));
    }
    size_t numImages = inputFiles.img_filenames.size ();
    cout << "numImages is " << numImages << endl;
    cout << "img_filenames is " << inputFiles.img_filenames.size() << endl;
    algParameters.num_img_processed = min ( ( int ) numImages, algParameters.num_img_processed );

    vector<Mat_<Vec3b> > img_color; // imgLeft_color, imgRight_color;
    vector<Mat_<uint8_t> > img_grayscale;
    for ( size_t i = 0; i < numImages; i++ ) {
        //printf ( "Opening image %ld: %s\n", i, ( inputFiles.images_folder + inputFiles.img_filenames[i] ).c_str () );
        img_grayscale.push_back ( imread ( ( inputFiles.images_folder + inputFiles.img_filenames[i] ), IMREAD_GRAYSCALE ) );
        if ( algParameters.color_processing ) {
            img_color.push_back ( imread ( ( inputFiles.images_folder + inputFiles.img_filenames[i] ), IMREAD_COLOR ) );
        }

        if ( img_grayscale[i].rows == 0 ) {
            printf ( "Image seems to be invalid\n" );
            return -1;
        }
    }

    size_t avail;
    size_t total;
    cudaMemGetInfo( &avail, &total );
    size_t used = total - avail;
    printf("Device memory used: %fMB\n", used/1000000.0f);

    GlobalState *gs = new GlobalState;
	gs->cameras = new CameraParameters_cu;
	gs->pc = new PointCloud;
    cudaMemGetInfo( &avail, &total );
    used = total - avail;
    printf("Device memory used: %fMB\n", used/1000000.0f);

    uint32_t rows = img_grayscale[0].rows;
    uint32_t cols = img_grayscale[0].cols;

    CameraParameters camParams = getCameraParameters (*(gs->cameras),
                                                      inputFiles,algParameters.depthMin,
                                                      algParameters.depthMax,
                                                      algParameters.cam_scale,
                                                      false);
    printf("Camera size is %lu\n", camParams.cameras.size());

    for ( int i = 0; i < algParameters.num_img_processed; i++ ) {
        algParameters.min_disparity = disparityDepthConversion ( camParams.f, camParams.cameras[i].baseline, camParams.cameras[i].depthMax );
        algParameters.max_disparity = disparityDepthConversion ( camParams.f, camParams.cameras[i].baseline, camParams.cameras[i].depthMin );
    }

    selectViews ( camParams, cols, rows, false);
    int numSelViews = camParams.viewSelectionSubset.size ();
    cout << "Selected views: " << numSelViews << endl;
    gs->cameras->viewSelectionSubsetNumber = numSelViews;
    ofstream myfile;
    for ( int i = 0; i < numSelViews; i++ ) {
        cout << camParams.viewSelectionSubset[i] << ", ";
        gs->cameras->viewSelectionSubset[i] = camParams.viewSelectionSubset[i];
    }
    cout << endl;

    vector<InputData> inputData;

    cout << "Reading normals and depth from disk" << endl;
    cout << "Size consideredIds is " << consideredIds.size() << endl;
    for (map<int,string>::iterator it=consideredIds.begin(); it!=consideredIds.end(); ++it){

        //get corresponding camera
        int i = it->first;
        string id = it->second;//consideredIds[i];
        //int id = atoi(id_string.c_str());
        int camIdx = getCameraFromId(id,camParams.cameras);
        //cout << "id is " << id << endl;
        //cout << "camIdx is " << camIdx << endl;
        if(camIdx < 0)// || camIdx == camParams.idRef)
            continue;

        InputData dat;
        dat.id = id;
        dat.camId = camIdx;
        dat.cam = camParams.cameras[camIdx];
        dat.path = results_folder + subfolders[i];
        dat.inputImage = imread((inputFiles.images_folder + id + ext), IMREAD_COLOR);

        //read normal
        cout << "Reading normal " << i << endl;
        readDmbNormal((dat.path + "/normals.dmb").c_str(),dat.normals);

        //read depth
        cout << "Reading disp " << i << endl;
        readDmb((dat.path + "/disp.dmb").c_str(),dat.depthMap);

        //inputData.push_back(move(dat));
        inputData.push_back(dat);

    }
    // run gpu run
    // Init parameters
    gs->params = &algParameters;


    // Init ImageInfo
    //gs->iminfo.cols = img_grayscale[0].cols;
    //gs->iminfo.rows = img_grayscale[0].rows;
    gs->cameras->cols = img_grayscale[0].cols;
    gs->cameras->rows = img_grayscale[0].rows;
    gs->params->cols = img_grayscale[0].cols;
    gs->params->rows = img_grayscale[0].rows;
    gs->resize (img_grayscale.size());
    gs->pc->resize (img_grayscale[0].rows * img_grayscale[0].cols);
	PointCloudList pc_list;
    pc_list.resize (img_grayscale[0].rows * img_grayscale[0].cols);
    pc_list.size=0;
    pc_list.rows = img_grayscale[0].rows;
    pc_list.cols = img_grayscale[0].cols;
    gs->pc->rows = img_grayscale[0].rows;
    gs->pc->cols = img_grayscale[0].cols;

    // Resize lines
    for (size_t i = 0; i<img_grayscale.size(); i++)
    {
        gs->lines[i].resize(img_grayscale[0].rows * img_grayscale[0].cols);
        gs->lines[i].n = img_grayscale[0].rows * img_grayscale[0].cols;
        //gs->lines.s = img_grayscale[0].step[0];
        gs->lines[i].s = img_grayscale[0].cols;
        gs->lines[i].l = img_grayscale[0].cols;
    }

    vector<Mat > img_grayscale_float           (img_grayscale.size());
    vector<Mat > img_color_float               (img_grayscale.size());
    vector<Mat > img_color_float_alpha         (img_grayscale.size());
    vector<Mat > normals_and_depth             (img_grayscale.size());
    vector<Mat_<uint16_t> > img_grayscale_uint (img_grayscale.size());
    for (size_t i = 0; i<img_grayscale.size(); i++)
    {
        //img_grayscale[i].convertTo(img_grayscale_float[i], CV_32FC1, 1.0/255.0); // or CV_32F works (too)
        img_grayscale[i].convertTo(img_grayscale_float[i], CV_32FC1); // or CV_32F works (too)
        img_grayscale[i].convertTo(img_grayscale_uint[i], CV_16UC1); // or CV_32F works (too)
        if(algParameters.color_processing) {
            vector<Mat_<float> > rgbChannels ( 3 );
            img_color_float_alpha[i] = Mat::zeros ( img_grayscale[0].rows, img_grayscale[0].cols, CV_32FC4 );
            img_color[i].convertTo (img_color_float[i], CV_32FC3); // or CV_32F works (too)
            Mat alpha( img_grayscale[0].rows, img_grayscale[0].cols, CV_32FC1 );
            split (img_color_float[i], rgbChannels);
            rgbChannels.push_back( alpha);
            merge (rgbChannels, img_color_float_alpha[i]);
        }
        /* Create vector of normals and disparities */
        vector<Mat_<float> > normal ( 3 );
        normals_and_depth[i] = Mat::zeros ( img_grayscale[0].rows, img_grayscale[0].cols, CV_32FC4 );
        split (inputData[i].normals, normal);
        normal.push_back( inputData[i].depthMap);
        merge (normal, normals_and_depth[i]);

    }
    //int64_t t = getTickCount ();

    // Copy images to texture memory
    if (algParameters.saveTexture) {
        if (algParameters.color_processing)
            addImageToTextureFloatColor (img_color_float_alpha, gs->imgs);
        else
            addImageToTextureFloatGray (img_grayscale_float, gs->imgs);
    }

    addImageToTextureFloatColor (normals_and_depth, gs->normals_depths);

#define pow2(x) ((x)*(x))
#define get_pow2_norm(x,y) (pow2(x)+pow2(y))

    runcuda(*gs, pc_list, numSelViews);
    Mat_<Vec3f> norm0 = Mat::zeros ( img_grayscale[0].rows, img_grayscale[0].cols, CV_32FC3 );
    Mat_<float> distImg;
    char plyFile[256];
    sprintf ( plyFile, "%s/final3d_model.ply", output_folder);
    printf("Writing ply file %s\n", plyFile);
    //storePlyFileAsciiPointCloud ( plyFile, pc_list, inputData[0].cam, distImg);
    storePlyFileBinaryPointCloud ( plyFile, pc_list, distImg);
    char xyzFile[256];
    sprintf ( xyzFile, "%s/final3d_model.xyz", output_folder);
    printf("Writing ply file %s\n", xyzFile);
    //storeXYZPointCloud ( xyzFile, pc_list, inputData[0].cam, distImg);

    return 0;
}
Пример #3
0
void TurretShape::getCameraTransform(F32* pos,MatrixF* mat)
{
   // Returns camera to world space transform
   // Handles first person / third person camera position
   if (isServerObject() && mShapeInstance)
      mShapeInstance->animateNodeSubtrees(true);

   if (*pos == 0) {
      getRenderEyeTransform(mat);
      return;
   }

   // Get the shape's camera parameters.
   F32 min,max;
   MatrixF rot;
   Point3F offset;
   getCameraParameters(&min,&max,&offset,&rot);

   // Start with the current eye position
   MatrixF eye;
   getRenderEyeTransform(&eye);

   // Build a transform that points along the eye axis
   // but where the Z axis is always up.
   {
      MatrixF cam(1);
      VectorF x,y,z(0,0,1);
      eye.getColumn(1, &y);
      mCross(y, z, &x);
      x.normalize();
      mCross(x, y, &z);
      z.normalize();
      cam.setColumn(0,x);
      cam.setColumn(1,y);
      cam.setColumn(2,z);
      mat->mul(cam,rot);
   }

   // Camera is positioned straight back along the eye's -Y axis.
   // A ray is cast to make sure the camera doesn't go through
   // anything solid.
   VectorF vp,vec;
   vp.x = vp.z = 0;
   vp.y = -(max - min) * *pos;
   eye.mulV(vp,&vec);

   // Use the camera node as the starting position if it exists.
   Point3F osp,sp;
   if (mDataBlock->cameraNode != -1) 
   {
      mShapeInstance->mNodeTransforms[mDataBlock->cameraNode].getColumn(3,&osp);
      getRenderTransform().mulP(osp,&sp);
   }
   else
      eye.getColumn(3,&sp);

   // Make sure we don't hit ourself...
   disableCollision();
   if (isMounted())
      getObjectMount()->disableCollision();

   // Cast the ray into the container database to see if we're going
   // to hit anything.
   RayInfo collision;
   Point3F ep = sp + vec + offset;
   if (mContainer->castRay(sp, ep,
         ~(WaterObjectType | GameBaseObjectType | DefaultObjectType | sTriggerMask),
         &collision) == true) {

      // Shift the collision point back a little to try and
      // avoid clipping against the front camera plane.
      F32 t = collision.t - (-mDot(vec, collision.normal) / vec.len()) * 0.1;
      if (t > 0.0f)
         ep = sp + offset + (vec * t);
      else
         eye.getColumn(3,&ep);
   }
   mat->setColumn(3,ep);

   // Re-enable our collision.
   if (isMounted())
      getObjectMount()->enableCollision();
   enableCollision();

   // Apply Camera FX.
   mat->mul( gCamFXMgr.getTrans() );
}
Пример #4
0
void
pcl::visualization::PCLVisualizerInteractorStyle::OnKeyDown ()
{
  if (!init_)
  {
    pcl::console::print_error ("[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n");
    return;
  }

  if (!rens_)
  {
    pcl::console::print_error ("[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing.\n");
    return;
  }

  FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]);

  if (wif_->GetInput () == NULL)
  {
    wif_->SetInput (Interactor->GetRenderWindow ());
    wif_->Modified ();
    snapshot_writer_->Modified ();
  }

  // Save the initial windows width/height
  if (win_height_ == -1 || win_width_ == -1)
  {
    int *win_size = Interactor->GetRenderWindow ()->GetSize ();
    win_height_ = win_size[0];
    win_width_  = win_size[1];
  }

  // Get the status of special keys (Cltr+Alt+Shift)
  bool shift = Interactor->GetShiftKey   ();
  bool ctrl  = Interactor->GetControlKey ();
  bool alt   = Interactor->GetAltKey ();

  bool keymod = false;
  switch (modifier_)
  {
    case INTERACTOR_KB_MOD_ALT:
    {
      keymod = alt;
      break;
    }
    case INTERACTOR_KB_MOD_CTRL:
    {
      keymod = ctrl;
      break;
    }
    case INTERACTOR_KB_MOD_SHIFT:
    {
      keymod = shift;
      break;
    }
  }

  // ---[ Check the rest of the key codes

  // Save camera parameters
  if ((Interactor->GetKeySym ()[0] == 'S' || Interactor->GetKeySym ()[0] == 's') && ctrl && !alt && !shift)
  {
    if (camera_file_.empty ())
    {
      getCameraParameters (camera_);
      camera_saved_ = true;
      pcl::console::print_info ("Camera parameters saved, you can press CTRL + R to restore.\n");
    }
    else
    {
      if (saveCameraParameters (camera_file_))
      {
        pcl::console::print_info ("Save camera parameters to %s, you can press CTRL + R to restore.\n", camera_file_.c_str ());
      }
      else
      {
        pcl::console::print_error ("[PCLVisualizerInteractorStyle] Can't save camera parameters to file: %s.\n", camera_file_.c_str ());
      }
    }
  }

  // Restore camera parameters
  if ((Interactor->GetKeySym ()[0] == 'R' || Interactor->GetKeySym ()[0] == 'r') && ctrl && !alt && !shift)
  {
    if (camera_file_.empty ())
    {
      if (camera_saved_)
      {
        setCameraParameters (camera_);
        pcl::console::print_info ("Camera parameters restored.\n");
      }
      else
      {
        pcl::console::print_info ("No camera parameters saved for restoring.\n");
      }
    }
    else
    {
      if (boost::filesystem::exists (camera_file_))
      {
        if (loadCameraParameters (camera_file_))
        {
          pcl::console::print_info ("Restore camera parameters from %s.\n", camera_file_.c_str ());
        }
        else
        {
          pcl::console::print_error ("Can't restore camera parameters from file: %s.\n", camera_file_.c_str ());
        }
      }
      else
      {
        pcl::console::print_info ("No camera parameters saved in %s for restoring.\n", camera_file_.c_str ());
      }
    }
  }

  // Switch between point color/geometry handlers
  if (Interactor->GetKeySym () && Interactor->GetKeySym ()[0]  >= '0' && Interactor->GetKeySym ()[0] <= '9')
  {
    CloudActorMap::iterator it;
    int index = Interactor->GetKeySym ()[0] - '0' - 1;
    if (index == -1) index = 9;

    // Add 10 more for CTRL+0..9 keys
    if (ctrl)
      index += 10;

    // Geometry ?
    if (keymod)
    {
      for (it = actors_->begin (); it != actors_->end (); ++it)
      {
        CloudActor *act = &(*it).second;
        if (index >= static_cast<int> (act->geometry_handlers.size ()))
          continue;

        // Save the geometry handler index for later usage
        act->geometry_handler_index_ = index;

        // Create the new geometry
        PointCloudGeometryHandler<pcl::PCLPointCloud2>::ConstPtr geometry_handler = act->geometry_handlers[index];

        // Use the handler to obtain the geometry
        vtkSmartPointer<vtkPoints> points;
        geometry_handler->getGeometry (points);

        // Set the vertices
        vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New ();
        for (vtkIdType i = 0; i < static_cast<vtkIdType> (points->GetNumberOfPoints ()); ++i)
          vertices->InsertNextCell (static_cast<vtkIdType>(1), &i);

        // Create the data
        vtkSmartPointer<vtkPolyData> data = vtkSmartPointer<vtkPolyData>::New ();
        data->SetPoints (points);
        data->SetVerts (vertices);
        // Modify the mapper
        if (use_vbos_)
        {
          vtkVertexBufferObjectMapper* mapper = static_cast<vtkVertexBufferObjectMapper*>(act->actor->GetMapper ());
          mapper->SetInput (data);
          // Modify the actor
          act->actor->SetMapper (mapper);
        }
        else
        {
          vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(act->actor->GetMapper ());
#if VTK_MAJOR_VERSION < 6
          mapper->SetInput (data);
#else
          mapper->SetInputData (data);
#endif
          // Modify the actor
          act->actor->SetMapper (mapper);
        }
        act->actor->Modified ();
      }
    }
    else
    {
      for (it = actors_->begin (); it != actors_->end (); ++it)
      {
        CloudActor *act = &(*it).second;
        // Check for out of bounds
        if (index >= static_cast<int> (act->color_handlers.size ()))
          continue;

        // Save the color handler index for later usage
        act->color_handler_index_ = index;

        // Get the new color
        PointCloudColorHandler<pcl::PCLPointCloud2>::ConstPtr color_handler = act->color_handlers[index];

        vtkSmartPointer<vtkDataArray> scalars;
        color_handler->getColor (scalars);
        double minmax[2];
        scalars->GetRange (minmax);
        // Update the data
        vtkPolyData *data = static_cast<vtkPolyData*>(act->actor->GetMapper ()->GetInput ());
        data->GetPointData ()->SetScalars (scalars);
        // Modify the mapper
        if (use_vbos_)
        {
          vtkVertexBufferObjectMapper* mapper = static_cast<vtkVertexBufferObjectMapper*>(act->actor->GetMapper ());
          mapper->SetScalarRange (minmax);
          mapper->SetScalarModeToUsePointData ();
          mapper->SetInput (data);
          // Modify the actor
          act->actor->SetMapper (mapper);
        }
        else
        {
          vtkPolyDataMapper* mapper = static_cast<vtkPolyDataMapper*>(act->actor->GetMapper ());
          mapper->SetScalarRange (minmax);
          mapper->SetScalarModeToUsePointData ();
#if VTK_MAJOR_VERSION < 6
          mapper->SetInput (data);
#else
          mapper->SetInputData (data);
#endif
          // Modify the actor
          act->actor->SetMapper (mapper);
        }
        act->actor->Modified ();
      }
    }

    Interactor->Render ();
    return;
  }

  std::string key (Interactor->GetKeySym ());
  if (key.find ("XF86ZoomIn") != std::string::npos)
    zoomIn ();
  else if (key.find ("XF86ZoomOut") != std::string::npos)
    zoomOut ();

  switch (Interactor->GetKeyCode ())
  {
    case 'h': case 'H':
    {
      pcl::console::print_info ("| Help:\n"
                  "-------\n"
                  "          p, P   : switch to a point-based representation\n"
                  "          w, W   : switch to a wireframe-based representation (where available)\n"
                  "          s, S   : switch to a surface-based representation (where available)\n"
                  "\n"
                  "          j, J   : take a .PNG snapshot of the current window view\n"
                  "          c, C   : display current camera/window parameters\n"
                  "          f, F   : fly to point mode\n"
                  "\n"
                  "          e, E   : exit the interactor\n"
                  "          q, Q   : stop and call VTK's TerminateApp\n"
                  "\n"
                  "           +/-   : increment/decrement overall point size\n"
                  "     +/- [+ ALT] : zoom in/out \n"
                  "\n"
                  "          g, G   : display scale grid (on/off)\n"
                  "          u, U   : display lookup table (on/off)\n"
                  "\n"
                  "    r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n"
                  "    CTRL + s, S  : save camera parameters\n"
                  "    CTRL + r, R  : restore camera parameters\n"
                  "\n"
                  "    ALT + s, S   : turn stereo mode on/off\n"
                  "    ALT + f, F   : switch between maximized window mode and original size\n"
                  "\n"
                  "          l, L           : list all available geometric and color handlers for the current actor map\n"
                  "    ALT + 0..9 [+ CTRL]  : switch between different geometric handlers (where available)\n"
                  "          0..9 [+ CTRL]  : switch between different color handlers (where available)\n"
                  "\n"
                  "    SHIFT + left click   : select a point (start with -use_point_picking)\n"
                  "\n"
                  "          x, X   : toggle rubber band selection mode for left mouse button\n"
          );
      break;
    }

    // Get the list of available handlers
    case 'l': case 'L':
    {
      // Iterate over the entire actors list and extract the geomotry/color handlers list
      for (CloudActorMap::iterator it = actors_->begin (); it != actors_->end (); ++it)
      {
        std::list<std::string> geometry_handlers_list, color_handlers_list;
        CloudActor *act = &(*it).second;
        for (size_t i = 0; i < act->geometry_handlers.size (); ++i)
          geometry_handlers_list.push_back (act->geometry_handlers[i]->getFieldName ());
        for (size_t i = 0; i < act->color_handlers.size (); ++i)
          color_handlers_list.push_back (act->color_handlers[i]->getFieldName ());

        if (!geometry_handlers_list.empty ())
        {
          int i = 0;
          pcl::console::print_info ("List of available geometry handlers for actor "); pcl::console::print_value ("%s: ", (*it).first.c_str ());
          for (std::list<std::string>::iterator git = geometry_handlers_list.begin (); git != geometry_handlers_list.end (); ++git)
            pcl::console::print_value ("%s(%d) ", (*git).c_str (), ++i);
          pcl::console::print_info ("\n");
        }
        if (!color_handlers_list.empty ())
        {
          int i = 0;
          pcl::console::print_info ("List of available color handlers for actor "); pcl::console::print_value ("%s: ", (*it).first.c_str ());
          for (std::list<std::string>::iterator cit = color_handlers_list.begin (); cit != color_handlers_list.end (); ++cit)
            pcl::console::print_value ("%s(%d) ", (*cit).c_str (), ++i);
          pcl::console::print_info ("\n");
        }
      }

      break;
    }

    // Switch representation to points
    case 'p': case 'P':
    {
      vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors ();
      vtkCollectionSimpleIterator ait;
      for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); )
      {
        for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); )
        {
          vtkSmartPointer<vtkActor> apart = reinterpret_cast <vtkActor*> (path->GetLastNode ()->GetViewProp ());
          apart->GetProperty ()->SetRepresentationToPoints ();
        }
      }
      break;
    }
    // Save a PNG snapshot with the current screen
    case 'j': case 'J':
    {
      char cam_fn[80], snapshot_fn[80];
      unsigned t = static_cast<unsigned> (time (0));
      sprintf (snapshot_fn, "screenshot-%d.png" , t);
      saveScreenshot (snapshot_fn);

      sprintf (cam_fn, "screenshot-%d.cam", t);
      saveCameraParameters (cam_fn);

      pcl::console::print_info ("Screenshot (%s) and camera information (%s) successfully captured.\n", snapshot_fn, cam_fn);
      break;
    }
    // display current camera settings/parameters
    case 'c': case 'C':
    {
      vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera ();
      double clip[2], focal[3], pos[3], view[3];
      cam->GetClippingRange (clip);
      cam->GetFocalPoint (focal);
      cam->GetPosition (pos);
      cam->GetViewUp (view);
      int *win_pos = Interactor->GetRenderWindow ()->GetPosition ();
      int *win_size = Interactor->GetRenderWindow ()->GetSize ();
      std::cerr <<  "Clipping plane [near,far] "  << clip[0] << ", " << clip[1] << endl <<
                    "Focal point [x,y,z] " << focal[0] << ", " << focal[1] << ", " << focal[2] << endl <<
                    "Position [x,y,z] " << pos[0] << ", " << pos[1] << ", " << pos[2] << endl <<
                    "View up [x,y,z] " << view[0]  << ", " << view[1]  << ", " << view[2] << endl <<
                    "Camera view angle [degrees] " << cam->GetViewAngle () << endl <<
                    "Window size [x,y] " << win_size[0] << ", " << win_size[1] << endl <<
                    "Window position [x,y] " << win_pos[0] << ", " << win_pos[1] << endl;
      break;
    }
    case '=':
    {
      zoomIn();
      break;
    }
    case 43:        // KEY_PLUS
    {
      if(alt)
        zoomIn ();
      else
      {
        vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors ();
        vtkCollectionSimpleIterator ait;
        for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); )
        {
          for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); )
          {
            vtkSmartPointer<vtkActor> apart = reinterpret_cast <vtkActor*> (path->GetLastNode ()->GetViewProp ());
            float psize = apart->GetProperty ()->GetPointSize ();
            if (psize < 63.0f)
              apart->GetProperty ()->SetPointSize (psize + 1.0f);
          }
        }
      }
      break;
    }
    case 45:        // KEY_MINUS
    {
      if(alt)
        zoomOut ();
      else
      {
        vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors ();
        vtkCollectionSimpleIterator ait;
        for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); )
        {
          for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); )
          {
            vtkSmartPointer<vtkActor> apart = static_cast<vtkActor*> (path->GetLastNode ()->GetViewProp ());
            float psize = apart->GetProperty ()->GetPointSize ();
            if (psize > 1.0f)
              apart->GetProperty ()->SetPointSize (psize - 1.0f);
          }
        }
      }
      break;
    }
    // Switch between maximize and original window size
    case 'f': case 'F':
    {
      if (keymod)
      {
        // Get screen size
        int *temp = Interactor->GetRenderWindow ()->GetScreenSize ();
        int scr_size[2]; scr_size[0] = temp[0]; scr_size[1] = temp[1];

        // Get window size
        temp = Interactor->GetRenderWindow ()->GetSize ();
        int win_size[2]; win_size[0] = temp[0]; win_size[1] = temp[1];
        // Is window size = max?
        if (win_size[0] == max_win_height_ && win_size[1] == max_win_width_)
        {
          // Set the previously saved 'current' window size
          Interactor->GetRenderWindow ()->SetSize (win_height_, win_width_);
          // Set the previously saved window position
          Interactor->GetRenderWindow ()->SetPosition (win_pos_x_, win_pos_y_);
          Interactor->GetRenderWindow ()->Render ();
          Interactor->Render ();
        }
        // Set to max
        else
        {
          int *win_pos = Interactor->GetRenderWindow ()->GetPosition ();
          // Save the current window position
          win_pos_x_  = win_pos[0];
          win_pos_y_  = win_pos[1];
          // Save the current window size
          win_height_ = win_size[0];
          win_width_  = win_size[1];
          // Set the maximum window size
          Interactor->GetRenderWindow ()->SetSize (scr_size[0], scr_size[1]);
          Interactor->GetRenderWindow ()->Render ();
          Interactor->Render ();
          int *win_size = Interactor->GetRenderWindow ()->GetSize ();
          // Save the maximum window size
          max_win_height_ = win_size[0];
          max_win_width_  = win_size[1];
        }
      }
      else
      {
        AnimState = VTKIS_ANIM_ON;
        vtkAssemblyPath *path = NULL;
        Interactor->GetPicker ()->Pick (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1], 0.0, CurrentRenderer);
        vtkAbstractPropPicker *picker;
        if ((picker = vtkAbstractPropPicker::SafeDownCast (Interactor->GetPicker ())))
          path = picker->GetPath ();
        if (path != NULL)
          Interactor->FlyTo (CurrentRenderer, picker->GetPickPosition ());
        AnimState = VTKIS_ANIM_OFF;
      }
      break;
    }
    // 's'/'S' w/out ALT
    case 's': case 'S':
    {
      if (keymod)
      {
        int stereo_render = Interactor->GetRenderWindow ()->GetStereoRender ();
        if (!stereo_render)
        {
          if (stereo_anaglyph_mask_default_)
          {
            Interactor->GetRenderWindow ()->SetAnaglyphColorMask (4, 3);
            stereo_anaglyph_mask_default_ = false;
          }
          else
          {
            Interactor->GetRenderWindow ()->SetAnaglyphColorMask (2, 5);
            stereo_anaglyph_mask_default_ = true;
          }
        }
        Interactor->GetRenderWindow ()->SetStereoRender (!stereo_render);
        Interactor->GetRenderWindow ()->Render ();
        Interactor->Render ();
      }
      else
        Superclass::OnKeyDown ();
      break;
    }

    // Display a grid/scale over the screen
    case 'g': case 'G':
    {
      if (!grid_enabled_)
      {
        grid_actor_->TopAxisVisibilityOn ();
        CurrentRenderer->AddViewProp (grid_actor_);
        grid_enabled_ = true;
      }
      else
      {
        CurrentRenderer->RemoveViewProp (grid_actor_);
        grid_enabled_ = false;
      }
      break;
    }

    case 'o': case 'O':
    {
      vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera ();
      int flag = cam->GetParallelProjection ();
      cam->SetParallelProjection (!flag);

      CurrentRenderer->SetActiveCamera (cam);
      CurrentRenderer->Render ();
      break;
    }
    // Display a LUT actor on screen
    case 'u': case 'U':
    {
      CloudActorMap::iterator it;
      for (it = actors_->begin (); it != actors_->end (); ++it)
      {
        CloudActor *act = &(*it).second;

        vtkScalarsToColors* lut = act->actor->GetMapper ()->GetLookupTable ();
        lut_actor_->SetLookupTable (lut);
        lut_actor_->Modified ();
      }
      if (!lut_enabled_)
      {
        CurrentRenderer->AddActor (lut_actor_);
        lut_actor_->SetVisibility (true);
        lut_enabled_ = true;
      }
      else
      {
        CurrentRenderer->RemoveActor (lut_actor_);
        lut_enabled_ = false;
      }
      CurrentRenderer->Render ();
      break;
    }

    // Overwrite the camera reset
    case 'r': case 'R':
    {
      if (!keymod)
      {
        FindPokedRenderer(Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]);
        if(CurrentRenderer != 0)
          CurrentRenderer->ResetCamera ();
        else
          PCL_WARN ("no current renderer on the interactor style.");

        CurrentRenderer->Render ();
        break;
      }

      vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera ();
      
      static CloudActorMap::iterator it = actors_->begin ();
      // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
      bool found_transformation = false;
      for (unsigned idx = 0; idx < actors_->size (); ++idx, ++it)
      {
        if (it == actors_->end ())
          it = actors_->begin ();
        
        const CloudActor& actor = it->second;
        if (actor.viewpoint_transformation_.GetPointer ())
        {
          found_transformation = true;
          break;
        }
      }
      
      // if a valid transformation was found, use it otherwise fall back to default view point.
      if (found_transformation)
      {
        const CloudActor& actor = it->second;
        cam->SetPosition (actor.viewpoint_transformation_->GetElement (0, 3),
                          actor.viewpoint_transformation_->GetElement (1, 3),
                          actor.viewpoint_transformation_->GetElement (2, 3));

        cam->SetFocalPoint (actor.viewpoint_transformation_->GetElement (0, 3) - actor.viewpoint_transformation_->GetElement (0, 2),
                            actor.viewpoint_transformation_->GetElement (1, 3) - actor.viewpoint_transformation_->GetElement (1, 2),
                            actor.viewpoint_transformation_->GetElement (2, 3) - actor.viewpoint_transformation_->GetElement (2, 2));

        cam->SetViewUp (actor.viewpoint_transformation_->GetElement (0, 1),
                        actor.viewpoint_transformation_->GetElement (1, 1),
                        actor.viewpoint_transformation_->GetElement (2, 1));
      }
      else
      {
        cam->SetPosition (0, 0, 0);
        cam->SetFocalPoint (0, 0, 1);
        cam->SetViewUp (0, -1, 0);
      }

      // go to the next actor for the next key-press event.
      if (it != actors_->end ())
        ++it;
      else
        it = actors_->begin ();
      
      CurrentRenderer->SetActiveCamera (cam);
      CurrentRenderer->ResetCameraClippingRange ();
      CurrentRenderer->Render ();
      break;
    }

    case 'x' : case 'X' :
    {
      CurrentMode = (CurrentMode == ORIENT_MODE) ? SELECT_MODE : ORIENT_MODE;
      if (CurrentMode == SELECT_MODE)
      {
        // Save the point picker
        point_picker_ = static_cast<vtkPointPicker*> (Interactor->GetPicker ());
        // Switch for an area picker
        vtkSmartPointer<vtkAreaPicker> area_picker = vtkSmartPointer<vtkAreaPicker>::New ();
        Interactor->SetPicker (area_picker);
      }
      else
      {
        // Restore point picker
        Interactor->SetPicker (point_picker_);
      }
      break;
    }

    case 'q': case 'Q':
    {
      Interactor->ExitCallback ();
      return;
    }
    default:
    {
      Superclass::OnKeyDown ();
      break;
    }
  }

  KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ());
  keyboard_signal_ (event);

  rens_->Render ();
  Interactor->Render ();
}