TestArrange.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. import numpy
  2. from cura.Arranging.Arrange import Arrange
  3. from cura.Arranging.ShapeArray import ShapeArray
  4. ## Triangle of area 12
  5. def gimmeTriangle():
  6. return numpy.array([[-3, 1], [3, 1], [0, -3]], dtype=numpy.int32)
  7. ## Boring square
  8. def gimmeSquare():
  9. return numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32)
  10. ## Triangle of area 12
  11. def gimmeShapeArray(scale = 1.0):
  12. vertices = gimmeTriangle()
  13. shape_arr = ShapeArray.fromPolygon(vertices, scale = scale)
  14. return shape_arr
  15. ## Boring square
  16. def gimmeShapeArraySquare(scale = 1.0):
  17. vertices = gimmeSquare()
  18. shape_arr = ShapeArray.fromPolygon(vertices, scale = scale)
  19. return shape_arr
  20. ## Smoke test for Arrange
  21. def test_smoke_arrange():
  22. ar = Arrange.create(fixed_nodes = [])
  23. ## Smoke test for ShapeArray
  24. def test_smoke_ShapeArray():
  25. shape_arr = gimmeShapeArray()
  26. ## Test ShapeArray
  27. def test_ShapeArray():
  28. scale = 1
  29. ar = Arrange(16, 16, 8, 8, scale = scale)
  30. ar.centerFirst()
  31. shape_arr = gimmeShapeArray(scale)
  32. print(shape_arr.arr)
  33. count = len(numpy.where(shape_arr.arr == 1)[0])
  34. print(count)
  35. assert count >= 10 # should approach 12
  36. ## Test ShapeArray with scaling
  37. def test_ShapeArray_scaling():
  38. scale = 2
  39. ar = Arrange(16, 16, 8, 8, scale = scale)
  40. ar.centerFirst()
  41. shape_arr = gimmeShapeArray(scale)
  42. print(shape_arr.arr)
  43. count = len(numpy.where(shape_arr.arr == 1)[0])
  44. print(count)
  45. assert count >= 40 # should approach 2*2*12 = 48
  46. ## Test ShapeArray with scaling
  47. def test_ShapeArray_scaling2():
  48. scale = 0.5
  49. ar = Arrange(16, 16, 8, 8, scale = scale)
  50. ar.centerFirst()
  51. shape_arr = gimmeShapeArray(scale)
  52. print(shape_arr.arr)
  53. count = len(numpy.where(shape_arr.arr == 1)[0])
  54. print(count)
  55. assert count >= 1 # should approach 3, but it can be inaccurate due to pixel rounding
  56. ## Test centerFirst
  57. def test_centerFirst():
  58. ar = Arrange(300, 300, 150, 150, scale = 1)
  59. ar.centerFirst()
  60. assert ar._priority[150][150] < ar._priority[170][150]
  61. assert ar._priority[150][150] < ar._priority[150][170]
  62. assert ar._priority[150][150] < ar._priority[170][170]
  63. assert ar._priority[150][150] < ar._priority[130][150]
  64. assert ar._priority[150][150] < ar._priority[150][130]
  65. assert ar._priority[150][150] < ar._priority[130][130]
  66. ## Test centerFirst
  67. def test_centerFirst_rectangular():
  68. ar = Arrange(400, 300, 200, 150, scale = 1)
  69. ar.centerFirst()
  70. assert ar._priority[150][200] < ar._priority[150][220]
  71. assert ar._priority[150][200] < ar._priority[170][200]
  72. assert ar._priority[150][200] < ar._priority[170][220]
  73. assert ar._priority[150][200] < ar._priority[180][150]
  74. assert ar._priority[150][200] < ar._priority[130][200]
  75. assert ar._priority[150][200] < ar._priority[130][180]
  76. ## Test centerFirst
  77. def test_centerFirst_rectangular():
  78. ar = Arrange(10, 20, 5, 10, scale = 1)
  79. ar.centerFirst()
  80. print(ar._priority)
  81. assert ar._priority[10][5] < ar._priority[10][7]
  82. ## Test backFirst
  83. def test_backFirst():
  84. ar = Arrange(300, 300, 150, 150, scale = 1)
  85. ar.backFirst()
  86. assert ar._priority[150][150] < ar._priority[170][150]
  87. assert ar._priority[150][150] < ar._priority[170][170]
  88. assert ar._priority[150][150] > ar._priority[130][150]
  89. assert ar._priority[150][150] > ar._priority[130][130]
  90. ## See if the result of bestSpot has the correct form
  91. def test_smoke_bestSpot():
  92. ar = Arrange(30, 30, 15, 15, scale = 1)
  93. ar.centerFirst()
  94. shape_arr = gimmeShapeArray()
  95. best_spot = ar.bestSpot(shape_arr)
  96. assert hasattr(best_spot, "x")
  97. assert hasattr(best_spot, "y")
  98. assert hasattr(best_spot, "penalty_points")
  99. assert hasattr(best_spot, "priority")
  100. ## Real life test
  101. def test_bestSpot():
  102. ar = Arrange(16, 16, 8, 8, scale = 1)
  103. ar.centerFirst()
  104. shape_arr = gimmeShapeArray()
  105. best_spot = ar.bestSpot(shape_arr)
  106. assert best_spot.x == 0
  107. assert best_spot.y == 0
  108. ar.place(best_spot.x, best_spot.y, shape_arr)
  109. # Place object a second time
  110. best_spot = ar.bestSpot(shape_arr)
  111. assert best_spot.x is not None # we found a location
  112. assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
  113. ar.place(best_spot.x, best_spot.y, shape_arr)
  114. print(ar._occupied) # For debugging
  115. ## Real life test rectangular build plate
  116. def test_bestSpot_rectangular_build_plate():
  117. ar = Arrange(16, 40, 8, 20, scale = 1)
  118. ar.centerFirst()
  119. shape_arr = gimmeShapeArray()
  120. best_spot = ar.bestSpot(shape_arr)
  121. ar.place(best_spot.x, best_spot.y, shape_arr)
  122. assert best_spot.x == 0
  123. assert best_spot.y == 0
  124. # Place object a second time
  125. best_spot2 = ar.bestSpot(shape_arr)
  126. assert best_spot2.x is not None # we found a location
  127. assert best_spot2.x != 0 or best_spot2.y != 0 # it can't be on the same location
  128. ar.place(best_spot2.x, best_spot2.y, shape_arr)
  129. # Place object a 3rd time
  130. best_spot3 = ar.bestSpot(shape_arr)
  131. assert best_spot3.x is not None # we found a location
  132. assert best_spot3.x != best_spot.x or best_spot3.y != best_spot.y # it can't be on the same location
  133. assert best_spot3.x != best_spot2.x or best_spot3.y != best_spot2.y # it can't be on the same location
  134. ar.place(best_spot3.x, best_spot3.y, shape_arr)
  135. best_spot_x = ar.bestSpot(shape_arr)
  136. ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
  137. best_spot_x = ar.bestSpot(shape_arr)
  138. ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
  139. best_spot_x = ar.bestSpot(shape_arr)
  140. ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
  141. print(ar._occupied) # For debugging
  142. ## Real life test
  143. def test_bestSpot_scale():
  144. scale = 0.5
  145. ar = Arrange(16, 16, 8, 8, scale = scale)
  146. ar.centerFirst()
  147. shape_arr = gimmeShapeArray(scale)
  148. best_spot = ar.bestSpot(shape_arr)
  149. assert best_spot.x == 0
  150. assert best_spot.y == 0
  151. ar.place(best_spot.x, best_spot.y, shape_arr)
  152. print(ar._occupied)
  153. # Place object a second time
  154. best_spot = ar.bestSpot(shape_arr)
  155. assert best_spot.x is not None # we found a location
  156. assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
  157. ar.place(best_spot.x, best_spot.y, shape_arr)
  158. print(ar._occupied) # For debugging
  159. ## Real life test
  160. def test_bestSpot_scale_rectangular():
  161. scale = 0.5
  162. ar = Arrange(16, 40, 8, 20, scale = scale)
  163. ar.centerFirst()
  164. shape_arr = gimmeShapeArray(scale)
  165. shape_arr_square = gimmeShapeArraySquare(scale)
  166. best_spot = ar.bestSpot(shape_arr_square)
  167. assert best_spot.x == 0
  168. assert best_spot.y == 0
  169. ar.place(best_spot.x, best_spot.y, shape_arr_square)
  170. print(ar._occupied)
  171. # Place object a second time
  172. best_spot = ar.bestSpot(shape_arr)
  173. assert best_spot.x is not None # we found a location
  174. assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
  175. ar.place(best_spot.x, best_spot.y, shape_arr)
  176. best_spot = ar.bestSpot(shape_arr_square)
  177. ar.place(best_spot.x, best_spot.y, shape_arr_square)
  178. print(ar._occupied) # For debugging
  179. ## Try to place an object and see if something explodes
  180. def test_smoke_place():
  181. ar = Arrange(30, 30, 15, 15)
  182. ar.centerFirst()
  183. shape_arr = gimmeShapeArray()
  184. assert not numpy.any(ar._occupied)
  185. ar.place(0, 0, shape_arr)
  186. assert numpy.any(ar._occupied)
  187. ## See of our center has less penalty points than out of the center
  188. def test_checkShape():
  189. ar = Arrange(30, 30, 15, 15)
  190. ar.centerFirst()
  191. shape_arr = gimmeShapeArray()
  192. points = ar.checkShape(0, 0, shape_arr)
  193. points2 = ar.checkShape(5, 0, shape_arr)
  194. points3 = ar.checkShape(0, 5, shape_arr)
  195. assert points2 > points
  196. assert points3 > points
  197. ## See of our center has less penalty points than out of the center
  198. def test_checkShape_rectangular():
  199. ar = Arrange(20, 30, 10, 15)
  200. ar.centerFirst()
  201. print(ar._priority)
  202. shape_arr = gimmeShapeArray()
  203. points = ar.checkShape(0, 0, shape_arr)
  204. points2 = ar.checkShape(5, 0, shape_arr)
  205. points3 = ar.checkShape(0, 5, shape_arr)
  206. assert points2 > points
  207. assert points3 > points
  208. ## Check that placing an object on occupied place returns None.
  209. def test_checkShape_place():
  210. ar = Arrange(30, 30, 15, 15)
  211. ar.centerFirst()
  212. shape_arr = gimmeShapeArray()
  213. points = ar.checkShape(3, 6, shape_arr)
  214. ar.place(3, 6, shape_arr)
  215. points2 = ar.checkShape(3, 6, shape_arr)
  216. assert points2 is None
  217. ## Test the whole sequence
  218. def test_smoke_place_objects():
  219. ar = Arrange(20, 20, 10, 10, scale = 1)
  220. ar.centerFirst()
  221. shape_arr = gimmeShapeArray()
  222. for i in range(5):
  223. best_spot_x, best_spot_y, score, prio = ar.bestSpot(shape_arr)
  224. ar.place(best_spot_x, best_spot_y, shape_arr)
  225. # Test some internals
  226. def test_compare_occupied_and_priority_tables():
  227. ar = Arrange(10, 15, 5, 7)
  228. ar.centerFirst()
  229. assert ar._priority.shape == ar._occupied.shape
  230. ## Polygon -> array
  231. def test_arrayFromPolygon():
  232. vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
  233. array = ShapeArray.arrayFromPolygon([5, 5], vertices)
  234. assert numpy.any(array)
  235. ## Polygon -> array
  236. def test_arrayFromPolygon2():
  237. vertices = numpy.array([[-3, 1], [3, 1], [2, -3]])
  238. array = ShapeArray.arrayFromPolygon([5, 5], vertices)
  239. assert numpy.any(array)
  240. ## Polygon -> array
  241. def test_fromPolygon():
  242. vertices = numpy.array([[0, 0.5], [0, 0], [0.5, 0]])
  243. array = ShapeArray.fromPolygon(vertices, scale=0.5)
  244. assert numpy.any(array.arr)
  245. ## Line definition -> array with true/false
  246. def test_check():
  247. base_array = numpy.zeros([5, 5], dtype=float)
  248. p1 = numpy.array([0, 0])
  249. p2 = numpy.array([4, 4])
  250. check_array = ShapeArray._check(p1, p2, base_array)
  251. assert numpy.any(check_array)
  252. assert check_array[3][0]
  253. assert not check_array[0][3]
  254. ## Line definition -> array with true/false
  255. def test_check2():
  256. base_array = numpy.zeros([5, 5], dtype=float)
  257. p1 = numpy.array([0, 3])
  258. p2 = numpy.array([4, 3])
  259. check_array = ShapeArray._check(p1, p2, base_array)
  260. assert numpy.any(check_array)
  261. assert not check_array[3][0]
  262. assert check_array[3][4]
  263. ## Just adding some stuff to ensure fromNode works as expected. Some parts should actually be in UM
  264. def test_parts_of_fromNode():
  265. from UM.Math.Polygon import Polygon
  266. p = Polygon(numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32))
  267. offset = 1
  268. print(p._points)
  269. p_offset = p.getMinkowskiHull(Polygon.approximatedCircle(offset))
  270. print("--------------")
  271. print(p_offset._points)
  272. assert len(numpy.where(p_offset._points[:, 0] >= 2.9)) > 0
  273. assert len(numpy.where(p_offset._points[:, 0] <= -2.9)) > 0
  274. assert len(numpy.where(p_offset._points[:, 1] >= 2.9)) > 0
  275. assert len(numpy.where(p_offset._points[:, 1] <= -2.9)) > 0
  276. def test_parts_of_fromNode2():
  277. from UM.Math.Polygon import Polygon
  278. p = Polygon(numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32) * 2) # 4x4
  279. offset = 13.3
  280. scale = 0.5
  281. p_offset = p.getMinkowskiHull(Polygon.approximatedCircle(offset))
  282. shape_arr1 = ShapeArray.fromPolygon(p._points, scale = scale)
  283. shape_arr2 = ShapeArray.fromPolygon(p_offset._points, scale = scale)
  284. assert shape_arr1.arr.shape[0] >= (4 * scale) - 1 # -1 is to account for rounding errors
  285. assert shape_arr2.arr.shape[0] >= (2 * offset + 4) * scale - 1