test_triangulation.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <catch2/catch.hpp>
  2. #include <libslic3r/Triangulation.hpp>
  3. #include <libslic3r/SVG.hpp> // only debug visualization
  4. using namespace Slic3r;
  5. namespace Private{
  6. void store_trinagulation(const ExPolygons &shape,
  7. const std::vector<Vec3i> &triangles,
  8. const char* file_name = "C:/data/temp/triangulation.svg",
  9. double scale = 1e5)
  10. {
  11. BoundingBox bb;
  12. for (const auto &expoly : shape) bb.merge(expoly.contour.points);
  13. bb.scale(scale);
  14. SVG svg_vis(file_name, bb);
  15. svg_vis.draw(shape, "gray", .7f);
  16. Points pts = to_points(shape);
  17. svg_vis.draw(pts, "black", 4 * scale);
  18. for (const Vec3i &t : triangles) {
  19. Slic3r::Polygon triangle({pts[t[0]], pts[t[1]], pts[t[2]]});
  20. triangle.scale(scale);
  21. svg_vis.draw(triangle, "green");
  22. }
  23. // prevent visualization in test
  24. CHECK(false);
  25. }
  26. } // namespace
  27. TEST_CASE("Triangulate rectangle with restriction on edge", "[Triangulation]")
  28. {
  29. // 0 1 2 3
  30. Points points = {Point(1, 1), Point(2, 1), Point(2, 2), Point(1, 2)};
  31. Triangulation::HalfEdges edges1 = {{1, 3}};
  32. std::vector<Vec3i> indices1 = Triangulation::triangulate(points, edges1);
  33. auto check = [](int i1, int i2, Vec3i t) -> bool {
  34. return true;
  35. return (t[0] == i1 || t[1] == i1 || t[2] == i1) &&
  36. (t[0] == i2 || t[1] == i2 || t[2] == i2);
  37. };
  38. REQUIRE(indices1.size() == 2);
  39. int i1 = edges1.begin()->first, i2 = edges1.begin()->second;
  40. CHECK(check(i1, i2, indices1[0]));
  41. CHECK(check(i1, i2, indices1[1]));
  42. Triangulation::HalfEdges edges2 = {{0, 2}};
  43. std::vector<Vec3i> indices2 = Triangulation::triangulate(points, edges2);
  44. REQUIRE(indices2.size() == 2);
  45. i1 = edges2.begin()->first;
  46. i2 = edges2.begin()->second;
  47. CHECK(check(i1, i2, indices2[0]));
  48. CHECK(check(i1, i2, indices2[1]));
  49. }
  50. TEST_CASE("Triangulation polygon", "[triangulation]")
  51. {
  52. Points points = {Point(416, 346), Point(445, 362), Point(463, 389),
  53. Point(469, 427), Point(445, 491)};
  54. Polygon polygon(points);
  55. Polygons polygons({polygon});
  56. ExPolygon expolygon(points);
  57. ExPolygons expolygons({expolygon});
  58. std::vector<Vec3i> tp = Triangulation::triangulate(polygon);
  59. std::vector<Vec3i> tps = Triangulation::triangulate(polygons);
  60. std::vector<Vec3i> tep = Triangulation::triangulate(expolygon);
  61. std::vector<Vec3i> teps = Triangulation::triangulate(expolygons);
  62. //Private::store_trinagulation(expolygons, teps);
  63. CHECK(tp.size() == tps.size());
  64. CHECK(tep.size() == teps.size());
  65. CHECK(tp.size() == tep.size());
  66. CHECK(tp.size() == 3);
  67. }
  68. TEST_CASE("Triangulation M shape polygon", "[triangulation]")
  69. {
  70. // 0 1 2 3 4
  71. Polygon shape_M = {Point(0, 0), Point(2, 0), Point(2, 2), Point(1, 1), Point(0, 2)};
  72. std::vector<Vec3i> triangles = Triangulation::triangulate(shape_M);
  73. // Check outer triangle is not contain
  74. std::set<int> outer_triangle = {2, 3, 4};
  75. bool is_in = false;
  76. for (const Vec3i &t : triangles) {
  77. for (size_t i = 0; i < 3; i++) {
  78. int index = t[i];
  79. if (outer_triangle.find(index) == outer_triangle.end()) {
  80. is_in = false;
  81. break;
  82. } else {
  83. is_in = true;
  84. }
  85. }
  86. if (is_in) break;
  87. }
  88. //Private::store_trinagulation({ExPolygon(shape_M)}, triangles);
  89. CHECK(triangles.size() == 3);
  90. CHECK(!is_in);
  91. }
  92. // same point in triangulation are not Supported
  93. TEST_CASE("Triangulation 2 polygons with same point", "[triangulation]")
  94. {
  95. Slic3r::Polygon polygon1 = {
  96. Point(416, 346), Point(445, 362),
  97. Point(463, 389), Point(469, 427) /* This point */,
  98. Point(445, 491)
  99. };
  100. Slic3r::Polygon polygon2 = {
  101. Point(495, 488), Point(469, 427) /* This point */,
  102. Point(495, 364)
  103. };
  104. ExPolygons shape2d = {ExPolygon(polygon1), ExPolygon(polygon2)};
  105. std::vector<Vec3i> shape_triangles = Triangulation::triangulate(shape2d);
  106. //Private::store_trinagulation(shape2d, shape_triangles);
  107. CHECK(shape_triangles.size() == 4);
  108. }