test_paint.py 5.7 KB

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