TEST (PCL, IINormalEstimationAverageDepthChange)
{
  PointCloud<Normal> output;
  ne.setRectSize (3, 3);
  ne.setNormalEstimationMethod (ne.AVERAGE_DEPTH_CHANGE);
  ne.compute (output);

  EXPECT_EQ (output.points.size (), cloud.points.size ());
  EXPECT_EQ (output.width, cloud.width);
  EXPECT_EQ (output.height, cloud.height);

  for (size_t v = 0; v < cloud.height; ++v)
  {
    for (size_t u = 0; u < cloud.width; ++u)
    {
      if (!pcl_isfinite(output (u, v).normal_x) &&
          !pcl_isfinite(output (u, v).normal_y) &&
          !pcl_isfinite(output (u, v).normal_z))
        continue;

      if (fabs(fabs (output (u, v).normal_z) - 1) > 1e-2)
      {
        std::cout << "T:" << u << " , " << v << " : " << output (u, v).normal_x << " , " << output (u, v).normal_y << " , " << output (u, v).normal_z <<std::endl;
      }
      EXPECT_NEAR (fabs (output (u, v).normal_x),   0, 1e-2);
      EXPECT_NEAR (fabs (output (u, v).normal_y),   0, 1e-2);
      //EXPECT_NEAR (fabs (output (u, v).normal_z), 1.0, 1e-2);
    }
  }
}
TEST (PCL, IINormalEstimationSimple3DGradient)
{
  PointCloud<Normal> output;
  ne.setRectSize (3, 3);
  ne.setNormalEstimationMethod (ne.SIMPLE_3D_GRADIENT);
  ne.compute (output);

  EXPECT_EQ (output.points.size (), cloud.points.size ());
  EXPECT_EQ (output.width, cloud.width);
  EXPECT_EQ (output.height, cloud.height);

  for (size_t v = 0; v < cloud.height; ++v)
  {
    for (size_t u = 0; u < cloud.width; ++u)
    {
      if (!pcl_isfinite(output (u, v).normal_x) &&
          !pcl_isfinite(output (u, v).normal_y) &&
          !pcl_isfinite(output (u, v).normal_z))
        continue;

      if (fabs(fabs (output (u, v).normal_z) - 1) > 1e-2)
      {
        std::cout << "T:" << u << " , " << v << " : " << output (u, v).normal_x << " , " << output (u, v).normal_y << " , " << output (u, v).normal_z <<std::endl;
      }
      EXPECT_NEAR (fabs (output (u, v).normal_x),   0, 1e-2);
      EXPECT_NEAR (fabs (output (u, v).normal_y),   0, 1e-2);
      //EXPECT_NEAR (fabs (output (u, v).normal_z), 1.0, 1e-2);
    }
  }
}
TEST (PCL, IINormalEstimationCovariance)
{
  PointCloud<Normal> output;
  ne.setRectSize (3, 3);
  ne.setNormalEstimationMethod (ne.COVARIANCE_MATRIX);
  ne.compute (output);

  EXPECT_EQ (output.points.size (), cloud.points.size ());
  EXPECT_EQ (output.width, cloud.width);
  EXPECT_EQ (output.height, cloud.height);

  for (size_t v = 0; v < cloud.height; ++v)
  {
    for (size_t u = 0; u < cloud.width; ++u)
    {
      if (!pcl_isfinite(output (u, v).normal_x) &&
          !pcl_isfinite(output (u, v).normal_y) &&
          !pcl_isfinite(output (u, v).normal_z))
        continue;

      EXPECT_NEAR (fabs (output (u, v).normal_x),   0, 1e-2);
      EXPECT_NEAR (fabs (output (u, v).normal_y),   0, 1e-2);
      EXPECT_NEAR (fabs (output (u, v).normal_z), 1.0, 1e-2);
    }
  }
}
TEST (PCL, IINormalEstimationSimple3DGradientUnorganized)
{
  PointCloud<Normal> output;
  cloud.height = 1;
  cloud.points.resize (cloud.height * cloud.width);
  ne.setInputCloud (cloud.makeShared ());
  ne.setRectSize (3, 3);
  ne.setNormalEstimationMethod (ne.SIMPLE_3D_GRADIENT);
  ne.compute (output);

  EXPECT_EQ (output.points.size (), 0);
  EXPECT_EQ (output.width, 0);
  EXPECT_EQ (output.height, 0);
}