1. /* geodoer
  2. @Time: 2021/8/20
  3. @desc: 多个表面模型,合并成一个
  4. */
  5. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  6. #include <CGAL/Polyhedron_3.h>
  7. #include <CGAL/Surface_mesh.h>
  8. #include <CGAL/Nef_polyhedron_3.h>
  9. #include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>
  10. #include<vector>
  11. #include<QDir>
  12. #include<QTime>
  13. //将PolygonSoup转PolygonMesh
  14. #include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
  15. #include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
  16. #include <CGAL/Polygon_mesh_processing/orientation.h>
  17. #include <CGAL/IO/polygon_soup_io.h>
  18. typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
  19. typedef Exact_kernel::Point_3 Point;
  20. typedef CGAL::Polyhedron_3<Exact_kernel> Polyhedron;
  21. typedef CGAL::Surface_mesh<Exact_kernel::Point_3> Surface_mesh;
  22. typedef CGAL::Nef_polyhedron_3<Exact_kernel> Nef_polyhedron;
  23. using namespace std;
  24. Polyhedron read_off(const std::string& dir, const std::string& fn)
  25. {
  26. auto fp = dir + "\\" + fn;
  27. //表面模型不一定是PolygonMesh,只是PolygonSoup
  28. //所以要当成PolygonSoup读入
  29. std::vector<Point> points;
  30. std::vector<std::vector<std::size_t> > polygons;
  31. if (!CGAL::IO::read_polygon_soup(fp, points, polygons) || points.empty())
  32. {
  33. throw "Cannot open file ";
  34. }
  35. //转换成PolygonMesh
  36. CGAL::Polygon_mesh_processing::orient_polygon_soup(points, polygons);
  37. Polyhedron mesh;
  38. CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, mesh);
  39. return mesh;
  40. }
  41. void save(const Nef_polyhedron& nef, const std::string& outfp)
  42. {
  43. Surface_mesh output;
  44. CGAL::convert_nef_polyhedron_to_polygon_mesh(nef, output);
  45. std::ofstream out;
  46. out.open(outfp);
  47. out << output;
  48. out.close();
  49. }
  50. void printTime(const QTime& time)
  51. {
  52. int time_Diff = time.elapsed(); //返回从上次start()或restart()开始以来的时间差,单位ms
  53. //以下方法是将ms转为s
  54. float f = time_Diff / 1000.0;
  55. QString tr_timeDiff = QString("%1").arg(f); //float->QString
  56. std::cout << tr_timeDiff.toStdString() << "s" << std::endl;
  57. }
  58. int main()
  59. {
  60. //找到dirPath下的off,然后融合
  61. QString dirPath = R"(F:\00data\00work\GridToBrep20210819\data\wmodeler)";
  62. QString outFp = dirPath + "\\out.off";
  63. QTime time;
  64. time.start(); //开始计时,以ms为单位
  65. QDir dir(dirPath);
  66. dir.setNameFilters(QStringList() << "*.off");
  67. QStringList fileNames = dir.entryList();
  68. if (fileNames.size() == 0)
  69. {
  70. return 1;
  71. }
  72. auto first = read_off(dirPath.toStdString(), fileNames[0].toStdString());
  73. Nef_polyhedron nef(
  74. first
  75. );
  76. int errorCnt = 0;
  77. std::cout << "个数\t时间(s)" << std::endl;
  78. //for (int i = 1; i < fileNames.size(); ++i)
  79. for (int i = 1; i < 1000; ++i)
  80. {
  81. auto fn = fileNames[i];
  82. auto mesh = read_off(dirPath.toStdString(), fn.toStdString());
  83. try
  84. {
  85. Nef_polyhedron tmp(mesh);
  86. nef = nef + tmp;
  87. }
  88. catch (...)
  89. {
  90. errorCnt++;
  91. }
  92. if (i % 100 == 1)
  93. {
  94. save(nef, outFp.toStdString());
  95. cout << i << '\t';
  96. printTime(time);
  97. }
  98. }
  99. save(nef, outFp.toStdString());
  100. printTime(time);
  101. }

测试

N个长方体的融合
image.png