test_mutable_polygon.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include <catch2/catch.hpp>
  2. #include "libslic3r/Point.hpp"
  3. #include "libslic3r/MutablePolygon.hpp"
  4. using namespace Slic3r;
  5. SCENARIO("Iterators", "[MutablePolygon]") {
  6. GIVEN("Polygon with three points") {
  7. Slic3r::MutablePolygon p({ { 0, 0 }, { 0, 1 }, { 1, 0 } });
  8. WHEN("Iterating upwards") {
  9. auto begin = p.begin();
  10. auto end = p.end();
  11. auto it = begin;
  12. THEN("++ it is not equal to begin") {
  13. REQUIRE(++ it != begin);
  14. } THEN("++ it is not equal to end") {
  15. REQUIRE(++ it != end);
  16. } THEN("++ (++ it) is not equal to begin") {
  17. REQUIRE(++ (++ it) != begin);
  18. } THEN("++ (++ it) is equal to end") {
  19. REQUIRE(++ (++ it) == end);
  20. } THEN("++ (++ (++ it)) is equal to begin") {
  21. REQUIRE(++ (++ (++ it)) == begin);
  22. } THEN("++ (++ (++ it)) is not equal to end") {
  23. REQUIRE(++ (++ (++ it)) != end);
  24. }
  25. }
  26. WHEN("Iterating downwards") {
  27. auto begin = p.begin();
  28. auto end = p.end();
  29. auto it = begin;
  30. THEN("-- it is not equal to begin") {
  31. REQUIRE(-- it != begin);
  32. } THEN("-- it is equal to end") {
  33. REQUIRE(-- it == end);
  34. } THEN("-- (-- it) is not equal to begin") {
  35. REQUIRE(-- (-- it) != begin);
  36. } THEN("-- (-- it) is not equal to end") {
  37. REQUIRE(-- (-- it) != end);
  38. } THEN("-- (-- (-- it)) is equal to begin") {
  39. REQUIRE(-- (-- (-- it)) == begin);
  40. } THEN("-- (-- (-- it)) is not equal to end") {
  41. REQUIRE(-- (-- (-- it)) != end);
  42. }
  43. }
  44. WHEN("Deleting 1st point") {
  45. auto it_2nd = p.begin().next();
  46. auto it = p.begin().remove();
  47. THEN("Size is 2") {
  48. REQUIRE(p.size() == 2);
  49. } THEN("p.begin().remove() == it_2nd") {
  50. REQUIRE(it == it_2nd);
  51. } THEN("it_2nd == new begin()") {
  52. REQUIRE(it_2nd == p.begin());
  53. }
  54. }
  55. WHEN("Deleting 2nd point") {
  56. auto it_1st = p.begin();
  57. auto it_2nd = it_1st.next();
  58. auto it = it_2nd.remove();
  59. THEN("Size is 2") {
  60. REQUIRE(p.size() == 2);
  61. REQUIRE(! p.empty());
  62. } THEN("it_2nd.remove() == it_3rd") {
  63. REQUIRE(it == it_2nd);
  64. } THEN("it_1st == new begin()") {
  65. REQUIRE(it_1st == p.begin());
  66. }
  67. }
  68. WHEN("Deleting two points") {
  69. p.begin().remove().remove();
  70. THEN("Size is 1") {
  71. REQUIRE(p.size() == 1);
  72. } THEN("p.begin().next() == p.begin()") {
  73. REQUIRE(p.begin().next() == p.begin());
  74. } THEN("p.begin().prev() == p.begin()") {
  75. REQUIRE(p.begin().prev() == p.begin());
  76. }
  77. }
  78. WHEN("Deleting all points") {
  79. auto it = p.begin().remove().remove().remove();
  80. THEN("Size is 0") {
  81. REQUIRE(p.size() == 0);
  82. REQUIRE(p.empty());
  83. } THEN("! p.begin().valid()") {
  84. REQUIRE(!p.begin().valid());
  85. } THEN("last iterator not valid") {
  86. REQUIRE(! it.valid());
  87. }
  88. }
  89. WHEN("Inserting a point at the beginning") {
  90. p.insert(p.begin(), { 3, 4 });
  91. THEN("Polygon content is ok") {
  92. REQUIRE(p == MutablePolygon{ { 0, 0 }, { 0, 1 }, { 1, 0 }, { 3, 4 } });
  93. }
  94. }
  95. WHEN("Inserting a point at the 2nd position") {
  96. p.insert(++ p.begin(), { 3, 4 });
  97. THEN("Polygon content is ok") {
  98. REQUIRE(p == MutablePolygon{ { 0, 0 }, { 3, 4 }, { 0, 1 }, { 1, 0 } });
  99. }
  100. } WHEN("Inserting a point after a point was removed") {
  101. size_t capacity = p.capacity();
  102. THEN("Initial capacity is 3") {
  103. REQUIRE(capacity == 3);
  104. }
  105. p.begin().remove();
  106. THEN("After removal of the 1st point the capacity is still 3") {
  107. REQUIRE(p.capacity() == 3);
  108. }
  109. THEN("After removal of the 1st point the content is ok") {
  110. REQUIRE(p == MutablePolygon{ { 0, 1 }, { 1, 0 } });
  111. }
  112. p.insert(p.begin(), { 5, 6 });
  113. THEN("After insertion at head position the polygon content is ok") {
  114. REQUIRE(p == MutablePolygon{ { 0, 1 }, { 1, 0 }, { 5, 6 } });
  115. } THEN("and the capacity is still 3") {
  116. REQUIRE(p.capacity() == 3);
  117. }
  118. }
  119. }
  120. }
  121. SCENARIO("Remove degenerate points from MutablePolygon", "[MutablePolygon]") {
  122. GIVEN("Polygon with duplicate points"){
  123. Slic3r::MutablePolygon p({
  124. { 0, 0 },
  125. { 0, 100 }, { 0, 100 }, { 0, 100 },
  126. { 0, 150 },
  127. { 0, 200 },
  128. { 200, 200 },
  129. { 180, 200 }, { 180, 200 },
  130. { 180, 20 },
  131. { 180, 0 },
  132. });
  133. WHEN("Duplicate points are removed") {
  134. remove_duplicates(p);
  135. THEN("Polygon content is ok") {
  136. REQUIRE(p == Slic3r::MutablePolygon{ { 0, 0 }, { 0, 100 }, { 0, 150 }, { 0, 200 }, { 200, 200 }, { 180, 200 }, { 180, 20 }, { 180, 0 } });
  137. }
  138. }
  139. }
  140. }
  141. SCENARIO("smooth_outward", "[MutablePolygon]") {
  142. GIVEN("Convex polygon") {
  143. MutablePolygon p{ { 0, 0 }, { scaled<coord_t>(10.), 0 }, { 0, scaled<coord_t>(10.) } };
  144. WHEN("smooth_outward") {
  145. MutablePolygon p2{ p };
  146. smooth_outward(p2, scaled<double>(10.));
  147. THEN("Polygon is unmodified") {
  148. REQUIRE(p == p2);
  149. }
  150. }
  151. }
  152. GIVEN("Sharp tiny concave polygon (hole)") {
  153. MutablePolygon p{ { 0, 0 }, { 0, scaled<coord_t>(5.) }, { scaled<coord_t>(10.), 0 } };
  154. WHEN("smooth_outward") {
  155. MutablePolygon p2{ p };
  156. smooth_outward(p2, scaled<double>(10.));
  157. THEN("Hole is closed") {
  158. REQUIRE(p2.empty());
  159. }
  160. }
  161. }
  162. GIVEN("Two polygons") {
  163. Polygons p{ { { 0, 0 }, { scaled<coord_t>(10.), 0 }, { 0, scaled<coord_t>(10.) } },
  164. { { 0, 0 }, { 0, scaled<coord_t>(5.) }, { scaled<coord_t>(10.), 0 } } };
  165. WHEN("smooth_outward") {
  166. p = smooth_outward(p, scaled<double>(10.));
  167. THEN("CCW contour unmodified, CW contour removed.") {
  168. REQUIRE(p == Polygons{ { { 0, 0 }, { scaled<coord_t>(10.), 0 }, { 0, scaled<coord_t>(10.) } } });
  169. }
  170. }
  171. }
  172. }