example_nurbs_fitting_surface.cpp
Go to the documentation of this file.
00001 #include <pcl/point_cloud.h>
00002 #include <pcl/point_types.h>
00003 #include <pcl/io/pcd_io.h>
00004 
00005 #include <pcl/visualization/pcl_visualizer.h>
00006 #include <pcl/surface/on_nurbs/fitting_surface_tdm.h>
00007 #include <pcl/surface/on_nurbs/fitting_curve_2d_asdm.h>
00008 #include <pcl/surface/on_nurbs/triangulation.h>
00009 
00010 typedef pcl::PointXYZ Point;
00011 
00012 void
00013 PointCloud2Vector3d (pcl::PointCloud<Point>::Ptr cloud, pcl::on_nurbs::vector_vec3d &data)
00014 {
00015   for (unsigned i = 0; i < cloud->size (); i++)
00016   {
00017     Point &p = cloud->at (i);
00018     if (!pcl_isnan (p.x) && !pcl_isnan (p.y) && !pcl_isnan (p.z))
00019       data.push_back (Eigen::Vector3d (p.x, p.y, p.z));
00020   }
00021 }
00022 
00023 void
00024 visualizeCurve (ON_NurbsCurve &curve, ON_NurbsSurface &surface, pcl::visualization::PCLVisualizer &viewer)
00025 {
00026   pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
00027 
00028   pcl::on_nurbs::Triangulation::convertCurve2PointCloud (curve, surface, curve_cloud, 4);
00029   for (std::size_t i = 0; i < curve_cloud->size () - 1; i++)
00030   {
00031     pcl::PointXYZRGB &p1 = curve_cloud->at (i);
00032     pcl::PointXYZRGB &p2 = curve_cloud->at (i + 1);
00033     std::ostringstream os;
00034     os << "line" << i;
00035     viewer.removeShape (os.str ());
00036     viewer.addLine<pcl::PointXYZRGB> (p1, p2, 1.0, 0.0, 0.0, os.str ());
00037   }
00038 
00039   pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cps (new pcl::PointCloud<pcl::PointXYZRGB>);
00040   for (int i = 0; i < curve.CVCount (); i++)
00041   {
00042     ON_3dPoint p1;
00043     curve.GetCV (i, p1);
00044 
00045     double pnt[3];
00046     surface.Evaluate (p1.x, p1.y, 0, 3, pnt);
00047     pcl::PointXYZRGB p2;
00048     p2.x = float (pnt[0]);
00049     p2.y = float (pnt[1]);
00050     p2.z = float (pnt[2]);
00051 
00052     p2.r = 255;
00053     p2.g = 0;
00054     p2.b = 0;
00055 
00056     curve_cps->push_back (p2);
00057   }
00058   viewer.removePointCloud ("cloud_cps");
00059   viewer.addPointCloud (curve_cps, "cloud_cps");
00060 }
00061 
00062 int
00063 main (int argc, char *argv[])
00064 {
00065   std::string pcd_file;
00066 
00067   if (argc < 2)
00068   {
00069     printf ("\nUsage: pcl_example_nurbs_fitting_surface pcd<PointXYZ>-file\n\n");
00070     exit (0);
00071   }
00072 
00073   pcd_file = argv[1];
00074 
00075   unsigned order (3);
00076   unsigned refinement (6);
00077   unsigned iterations (10);
00078   unsigned mesh_resolution (256);
00079 
00080   pcl::visualization::PCLVisualizer viewer ("Test: NURBS surface fitting");
00081   viewer.setSize (800, 600);
00082 
00083   // ############################################################################
00084   // load point cloud
00085   printf ("  loading %s\n", pcd_file.c_str ());
00086   pcl::PointCloud<Point>::Ptr cloud (new pcl::PointCloud<Point>);
00087   pcl::PCLPointCloud2 cloud2;
00088   pcl::on_nurbs::NurbsDataSurface data;
00089 
00090   if (pcl::io::loadPCDFile (pcd_file, cloud2) == -1)
00091     throw std::runtime_error ("  PCD file not found.");
00092 
00093   fromPCLPointCloud2 (cloud2, *cloud);
00094   PointCloud2Vector3d (cloud, data.interior);
00095   pcl::visualization::PointCloudColorHandlerCustom<Point> handler (cloud, 0, 255, 0);
00096   viewer.addPointCloud<Point> (cloud, handler, "cloud_cylinder");
00097   printf ("  %zu points in data set\n", cloud->size ());
00098 
00099   // ############################################################################
00100   // fit NURBS surface
00101   printf ("  surface fitting ...\n");
00102   ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox (order, &data);
00103   pcl::on_nurbs::FittingSurface fit (&data, nurbs);
00104   //  fit.setQuiet (false);
00105 
00106   pcl::PolygonMesh mesh;
00107   pcl::PointCloud<pcl::PointXYZ>::Ptr mesh_cloud (new pcl::PointCloud<pcl::PointXYZ>);
00108   std::vector<pcl::Vertices> mesh_vertices;
00109 
00110   std::string mesh_id = "mesh_nurbs";
00111   pcl::on_nurbs::Triangulation::convertSurface2PolygonMesh (fit.m_nurbs, mesh, mesh_resolution);
00112   viewer.addPolygonMesh (mesh, mesh_id);
00113 
00114   pcl::on_nurbs::FittingSurface::Parameter params;
00115   params.interior_smoothness = 0.15;
00116   params.interior_weight = 1.0;
00117   params.boundary_smoothness = 0.15;
00118   params.boundary_weight = 0.0;
00119 
00120   // NURBS refinement
00121   for (unsigned i = 0; i < refinement; i++)
00122   {
00123     fit.refine (0);
00124     fit.refine (1);
00125     fit.assemble (params);
00126     fit.solve ();
00127     pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
00128     viewer.updatePolygonMesh<pcl::PointXYZ> (mesh_cloud, mesh_vertices, mesh_id);
00129     viewer.spinOnce ();
00130   }
00131 
00132   // fitting iterations
00133   for (unsigned i = 0; i < iterations; i++)
00134   {
00135     fit.assemble (params);
00136     fit.solve ();
00137     pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
00138     viewer.updatePolygonMesh<pcl::PointXYZ> (mesh_cloud, mesh_vertices, mesh_id);
00139     viewer.spinOnce ();
00140   }
00141 
00142   // ############################################################################
00143   // fit NURBS curve
00144   pcl::on_nurbs::FittingCurve2dAPDM::FitParameter curve_params;
00145   curve_params.addCPsAccuracy = 3e-2;
00146   curve_params.addCPsIteration = 3;
00147   curve_params.maxCPs = 200;
00148   curve_params.accuracy = 1e-3;
00149   curve_params.iterations = 10000;
00150 
00151   curve_params.param.closest_point_resolution = 0;
00152   curve_params.param.closest_point_weight = 1.0;
00153   curve_params.param.closest_point_sigma2 = 0.1;
00154   curve_params.param.interior_sigma2 = 0.0001;
00155   curve_params.param.smooth_concavity = 1.0;
00156   curve_params.param.smoothness = 1.0;
00157 
00158   pcl::on_nurbs::NurbsDataCurve2d curve_data;
00159   curve_data.interior = data.interior_param;
00160   curve_data.interior_weight_function.push_back (true);
00161 
00162   ON_NurbsCurve curve_nurbs = pcl::on_nurbs::FittingCurve2dAPDM::initNurbsCurve2D (order, curve_data.interior);
00163 
00164   pcl::on_nurbs::FittingCurve2dASDM curve_fit (&curve_data, curve_nurbs);
00165 //  curve_fit.setQuiet (false);
00166 
00167   // ############################### FITTING ###############################
00168   curve_fit.fitting (curve_params);
00169   visualizeCurve (curve_fit.m_nurbs, fit.m_nurbs, viewer);
00170 
00171   // ############################################################################
00172   // triangulation of trimmed surface
00173   printf ("  triangulate trimmed surface ...\n");
00174   viewer.removePolygonMesh (mesh_id);
00175   pcl::on_nurbs::Triangulation::convertTrimmedSurface2PolygonMesh (fit.m_nurbs, curve_fit.m_nurbs, mesh,
00176                                                                    mesh_resolution);
00177   viewer.addPolygonMesh (mesh, mesh_id);
00178 
00179   printf ("  ... done.\n");
00180 
00181   viewer.spin ();
00182   return 0;
00183 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:23:36