GCODEReader.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. # Copyright (c) 2015 Ultimaker B.V.
  2. # Copyright (c) 2013 David Braam
  3. # Uranium is released under the terms of the AGPLv3 or higher.
  4. from UM.Mesh.MeshReader import MeshReader
  5. from UM.Mesh.MeshBuilder import MeshBuilder
  6. from UM.Mesh.MeshData import MeshData
  7. import os
  8. from UM.Scene.SceneNode import SceneNode
  9. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
  10. from UM.Math.Vector import Vector
  11. from UM.Math.Color import Color
  12. from UM.Math.AxisAlignedBox import AxisAlignedBox
  13. from UM.Application import Application
  14. from UM.Preferences import Preferences
  15. from cura import LayerDataBuilder
  16. from cura import LayerDataDecorator
  17. from cura import LayerPolygon
  18. import numpy
  19. from UM.Job import Job
  20. class GCODEReader(MeshReader):
  21. def __init__(self):
  22. super(GCODEReader, self).__init__()
  23. self._supported_extensions = [".gcode", ".g"]
  24. def getInt(self, line, code):
  25. n = line.find(code) + 1
  26. if n < 1:
  27. return None
  28. m = line.find(' ', n)
  29. # m2 = line.find(';', n)
  30. # if m < 0:
  31. # m = m2
  32. try:
  33. if m < 0:
  34. return int(line[n:])
  35. return int(line[n:m])
  36. except:
  37. return None
  38. def getFloat(self, line, code):
  39. n = line.find(code) + 1
  40. if n < 1:
  41. return None
  42. m = line.find(' ', n)
  43. # m2 = line.find(';', n)
  44. # if m < 0:
  45. # m = m2
  46. try:
  47. if m < 0:
  48. return float(line[n:])
  49. return float(line[n:m])
  50. except:
  51. return None
  52. def onSceneChanged(self, obj):
  53. scene = Application.getInstance().getController().getScene()
  54. def findAny():
  55. for node in DepthFirstIterator(scene.getRoot()):
  56. if hasattr(node, "gcode"):
  57. return True
  58. return False
  59. if not findAny():
  60. # Preferences.getInstance().setValue("cura/jobname_prefix", True)
  61. backend = Application.getInstance().getBackend()
  62. backend._pauseSlicing = False
  63. Application.getInstance().setHideSettings(False)
  64. #Application.getInstance().getPrintInformation()._setAbbreviatedMachineName()
  65. else:
  66. backend = Application.getInstance().getBackend()
  67. backend._pauseSlicing = True
  68. backend.backendStateChange.emit(1)
  69. Application.getInstance().getPrintInformation()._abbr_machine = "Pre-sliced"
  70. Application.getInstance().setHideSettings(True)
  71. def read(self, file_name):
  72. scene_node = None
  73. extension = os.path.splitext(file_name)[1]
  74. if extension.lower() in self._supported_extensions:
  75. scene = Application.getInstance().getController().getScene()
  76. scene.sceneChanged.connect(self.onSceneChanged)
  77. # for node in DepthFirstIterator(scene.getRoot()):
  78. # if node.callDecoration("getLayerData"):
  79. # node.getParent().removeChild(node)
  80. Application.getInstance().deleteAll()
  81. scene_node = SceneNode()
  82. # mesh_builder = MeshBuilder()
  83. # mesh_builder.setFileName(file_name)
  84. #
  85. # mesh_builder.addCube(
  86. # width=5,
  87. # height=5,
  88. # depth=5,
  89. # center=Vector(0, 2.5, 0)
  90. # )
  91. #
  92. # scene_node.setMeshData(mesh_builder.build())
  93. def getBoundingBox():
  94. return AxisAlignedBox(minimum=Vector(0, 0, 0), maximum=Vector(10, 10, 10))
  95. scene_node.getBoundingBox = getBoundingBox
  96. scene_node.gcode = True
  97. backend = Application.getInstance().getBackend()
  98. backend._pauseSlicing = True
  99. backend.close()
  100. backend.backendStateChange.emit(1)
  101. file = open(file_name, "r")
  102. layer_data = LayerDataBuilder.LayerDataBuilder()
  103. layer_id = 0
  104. layer_data.addLayer(layer_id)
  105. this_layer = layer_data.getLayer(layer_id)
  106. layer_data.setLayerHeight(layer_id, 0)
  107. layer_data.setLayerThickness(layer_id, 0.1)
  108. current_extruder = 1
  109. current_path = []
  110. current_x = 0
  111. current_y = 0
  112. current_z = 0
  113. current_e = 0
  114. def CreatePolygon():
  115. count = len(current_path)
  116. line_types = numpy.empty((count-1, 1), numpy.int32)
  117. line_types[:, 0] = 1
  118. line_widths = numpy.empty((count-1, 1), numpy.int32)
  119. line_widths[:, 0] = 1
  120. points = numpy.empty((count, 3), numpy.float32)
  121. i = 0
  122. for point in current_path:
  123. points[i, 0] = point[0]
  124. points[i, 1] = point[1]
  125. points[i, 2] = point[2]
  126. i += 1
  127. this_poly = LayerPolygon.LayerPolygon(layer_data, current_extruder, line_types, points, line_widths)
  128. this_poly.buildCache()
  129. this_layer.polygons.append(this_poly)
  130. current_path.clear()
  131. # current_path.append([0, 0, 0])
  132. # current_path.append([10, 10, 10])
  133. # while file.readable():
  134. for line in file:
  135. if len(line) == 0:
  136. continue
  137. if line[0] == ";":
  138. continue
  139. G = self.getInt(line, "G")
  140. if G is not None:
  141. if G == 0 or G == 1:
  142. x = self.getFloat(line, "X")
  143. y = self.getFloat(line, "Y")
  144. z = self.getFloat(line, "Z")
  145. e = self.getFloat(line, "E")
  146. if x is not None:
  147. current_x = x
  148. if y is not None:
  149. current_y = y
  150. if z is not None:
  151. current_z = z
  152. if e is not None:
  153. if e > current_e:
  154. current_path.append([current_x, current_z, -current_y])
  155. else:
  156. if len(current_path) > 1:
  157. CreatePolygon()
  158. else:
  159. current_path.clear()
  160. current_e = e
  161. else:
  162. if len(current_path) > 1:
  163. CreatePolygon()
  164. elif G == 1:
  165. current_path.clear()
  166. elif G == 28:
  167. x = self.getFloat(line, "X")
  168. y = self.getFloat(line, "Y")
  169. if x is not None:
  170. current_x = x
  171. if y is not None:
  172. current_y = y
  173. current_z = 0
  174. elif G == 92:
  175. x = self.getFloat(line, "X")
  176. y = self.getFloat(line, "Y")
  177. z = self.getFloat(line, "Z")
  178. if x is not None:
  179. current_x += x
  180. if y is not None:
  181. current_y += y
  182. if z is not None:
  183. current_z += z
  184. if len(current_path) > 1:
  185. CreatePolygon()
  186. layer_mesh = layer_data.build()
  187. decorator = LayerDataDecorator.LayerDataDecorator()
  188. decorator.setLayerData(layer_mesh)
  189. scene_node.addDecorator(decorator)
  190. Application.getInstance().getPrintInformation()._abbr_machine = "Pre-sliced"
  191. scene_node_parent = Application.getInstance().getBuildVolume()
  192. scene_node.setParent(scene_node_parent)
  193. settings = Application.getInstance().getGlobalContainerStack()
  194. machine_width = settings.getProperty("machine_width", "value")
  195. machine_depth = settings.getProperty("machine_depth", "value")
  196. scene_node.setPosition(Vector(-machine_width / 2, 0, machine_depth / 2))
  197. # mesh_builder = MeshBuilder()
  198. # mesh_builder.setFileName(file_name)
  199. #
  200. # mesh_builder.addCube(10, 10, 10, Vector(0, -5, 0))
  201. # scene_node.setMeshData(mesh_builder.build())
  202. # scene_node.setMeshData(MeshData(file_name=file_name))
  203. Preferences.getInstance().setValue("cura/jobname_prefix", True)
  204. view = Application.getInstance().getController().getActiveView()
  205. if view.getPluginId() == "LayerView":
  206. view.resetLayerData()
  207. # scene_node.setEnabled(False)
  208. #scene_node.setSelectable(False)
  209. return scene_node