test_paint.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import unittest
  2. from shapely.geometry import LineString, Polygon
  3. from shapely.ops import unary_union
  4. from matplotlib.pyplot import plot, subplot, show, cla, clf, xlim, ylim, title
  5. from matplotlib.axes import *
  6. from camlib import *
  7. from copy import deepcopy
  8. def mkstorage(paths):
  9. def get_pts(o):
  10. return [o.coords[0], o.coords[-1]]
  11. storage = FlatCAMRTreeStorage()
  12. storage.get_points = get_pts
  13. for p in paths:
  14. storage.insert(p)
  15. return storage
  16. def plotg2(geo, solid_poly=False, color="black", linestyle='solid'):
  17. try:
  18. for sub_geo in geo:
  19. plotg2(sub_geo, solid_poly=solid_poly, color=color, linestyle=linestyle)
  20. except TypeError:
  21. if type(geo) == Polygon:
  22. if solid_poly:
  23. patch = PolygonPatch(geo,
  24. #facecolor="#BBF268",
  25. facecolor=color,
  26. edgecolor="#006E20",
  27. alpha=0.5,
  28. zorder=2)
  29. ax = subplot(111)
  30. ax.add_patch(patch)
  31. else:
  32. x, y = geo.exterior.coords.xy
  33. plot(x, y, color=color, linestyle=linestyle)
  34. for ints in geo.interiors:
  35. x, y = ints.coords.xy
  36. plot(x, y, color=color, linestyle=linestyle)
  37. if type(geo) == LineString or type(geo) == LinearRing:
  38. x, y = geo.coords.xy
  39. plot(x, y, color=color, linestyle=linestyle)
  40. if type(geo) == Point:
  41. x, y = geo.coords.xy
  42. plot(x, y, 'o')
  43. class PaintTestCase(unittest.TestCase):
  44. # def __init__(self):
  45. # super(PaintTestCase, self).__init__()
  46. # self.boundary = None
  47. # self.descr = None
  48. def plot_summary_A(self, paths, tooldia, result, msg):
  49. plotg2(self.boundary, solid_poly=True, color="green")
  50. plotg2(paths, color="red")
  51. plotg2([r.buffer(tooldia / 2) for r in result], solid_poly=True, color="blue")
  52. plotg2(result, color="black", linestyle='dashed')
  53. title(msg)
  54. xlim(0, 5)
  55. ylim(0, 5)
  56. show()
  57. class PaintConnectTest(PaintTestCase):
  58. """
  59. Simple rectangular boundary and paths inside.
  60. """
  61. def setUp(self):
  62. self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
  63. def test_jump(self):
  64. print("Test: WALK Expected")
  65. paths = [
  66. LineString([[0.5, 2], [2, 4.5]]),
  67. LineString([[2, 0.5], [4.5, 2]])
  68. ]
  69. for p in paths:
  70. print(p)
  71. tooldia = 1.0
  72. print("--")
  73. result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
  74. result = list(result.get_objects())
  75. for r in result:
  76. print(r)
  77. self.assertEqual(len(result), 1)
  78. # self.plot_summary_A(paths, tooldia, result, "WALK expected.")
  79. def test_no_jump1(self):
  80. print("Test: FLY Expected")
  81. paths = [
  82. LineString([[0, 2], [2, 5]]),
  83. LineString([[2, 0], [5, 2]])
  84. ]
  85. for p in paths:
  86. print(p)
  87. tooldia = 1.0
  88. print("--")
  89. result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
  90. result = list(result.get_objects())
  91. for r in result:
  92. print(r)
  93. self.assertEqual(len(result), len(paths))
  94. # self.plot_summary_A(paths, tooldia, result, "FLY Expected")
  95. def test_no_jump2(self):
  96. print("Test: FLY Expected")
  97. paths = [
  98. LineString([[0.5, 2], [2, 4.5]]),
  99. LineString([[2, 0.5], [4.5, 2]])
  100. ]
  101. for p in paths:
  102. print(p)
  103. tooldia = 1.1
  104. print("--")
  105. result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
  106. result = list(result.get_objects())
  107. for r in result:
  108. print(r)
  109. self.assertEqual(len(result), len(paths))
  110. # self.plot_summary_A(paths, tooldia, result, "FLY Expected")
  111. class PaintConnectTest2(PaintTestCase):
  112. """
  113. Boundary with an internal cutout.
  114. """
  115. def setUp(self):
  116. self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
  117. self.boundary = self.boundary.difference(
  118. Polygon([[2, 1], [3, 1], [3, 4], [2, 4]])
  119. )
  120. def test_no_jump3(self):
  121. print("TEST: No jump expected")
  122. paths = [
  123. LineString([[0.5, 1], [1.5, 3]]),
  124. LineString([[4, 1], [4, 4]])
  125. ]
  126. for p in paths:
  127. print(p)
  128. tooldia = 1.0
  129. print("--")
  130. result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
  131. result = list(result.get_objects())
  132. for r in result:
  133. print(r)
  134. self.assertEqual(len(result), len(paths))
  135. # self.plot_summary_A(paths, tooldia, result, "FLY Expected")
  136. class PaintConnectTest3(PaintTestCase):
  137. """
  138. Tests with linerings among elements.
  139. """
  140. def setUp(self):
  141. self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
  142. print("TEST w/ LinearRings")
  143. def test_jump2(self):
  144. print("Test: WALK Expected")
  145. paths = [
  146. LineString([[0.5, 2], [2, 4.5]]),
  147. LineString([[2, 0.5], [4.5, 2]]),
  148. self.boundary.buffer(-0.5).exterior
  149. ]
  150. for p in paths:
  151. print(p)
  152. tooldia = 1.0
  153. print("--")
  154. result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
  155. result = list(result.get_objects())
  156. for r in result:
  157. print(r)
  158. self.assertEqual(len(result), 1)
  159. # self.plot_summary_A(paths, tooldia, result, "WALK Expected")
  160. if __name__ == '__main__':
  161. unittest.main()