TEST (PCL, NormalEstimationOpenMPEigen)
  {
    NormalEstimationOMP<PointXYZ, Eigen::MatrixXf> n (4); // instantiate 4 threads

    // Object
    PointCloud<Eigen::MatrixXf>::Ptr normals (new PointCloud<Eigen::MatrixXf>);

    // set parameters
    PointCloud<PointXYZ>::Ptr cloudptr = cloud.makeShared ();
    n.setInputCloud (cloudptr);
    EXPECT_EQ (n.getInputCloud (), cloudptr);
    boost::shared_ptr<vector<int> > indicesptr (new vector<int> (indices));
    n.setIndices (indicesptr);
    EXPECT_EQ (n.getIndices (), indicesptr);
    n.setSearchMethod (tree);
    EXPECT_EQ (n.getSearchMethod (), tree);
    n.setKSearch (static_cast<int> (indices.size ()));

    // estimate
    n.computeEigen (*normals);
    EXPECT_EQ (normals->points.rows (), indices.size ());

    for (int i = 0; i < normals->points.rows (); ++i)
    {
      EXPECT_NEAR (normals->points.row (i)[0], -0.035592, 1e-4);
      EXPECT_NEAR (normals->points.row (i)[1], -0.369596, 1e-4);
      EXPECT_NEAR (normals->points.row (i)[2], -0.928511, 1e-4);
      EXPECT_NEAR (normals->points.row (i)[3], 0.0693136, 1e-4);
    }
  }
int
  main (int argc, char** argv)
{
  PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);

  if(io::loadPLYFile<PointXYZ> (argv[1], *cloud) == -1){
    cout << "ERROR: couldn't find file" << endl;
    return (1);
  } else {
    cout << "loaded" << endl;

    NormalEstimationOMP<PointXYZ, Normal> ne;
    search::KdTree<PointXYZ>::Ptr tree1 (new search::KdTree<PointXYZ>);
    tree1->setInputCloud (cloud);
    ne.setInputCloud (cloud);
    ne.setSearchMethod (tree1);
    ne.setKSearch (20);
    PointCloud<Normal>::Ptr normals (new PointCloud<Normal>);
    ne.compute (*normals);
         
    // Concatenate the XYZ and normal fields*
    PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
    concatenateFields(*cloud, *normals, *cloud_with_normals);
 
    // Create search tree*
    search::KdTree<PointNormal>::Ptr tree (new search::KdTree<PointNormal>);
    tree->setInputCloud (cloud_with_normals);
    
    cout << "begin marching cubes reconstruction" << endl;    

    MarchingCubesRBF<PointNormal> mc;
    PolygonMesh::Ptr triangles(new PolygonMesh);
    mc.setInputCloud (cloud_with_normals);
    mc.setSearchMethod (tree);
    mc.reconstruct (*triangles);

    cout << triangles->polygons.size() << " triangles created" << endl;
  }
  return (0);
}