meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7020__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (446) hide show
  1. meerk40t/__init__.py +1 -1
  2. meerk40t/balormk/balor_params.py +167 -167
  3. meerk40t/balormk/clone_loader.py +457 -457
  4. meerk40t/balormk/controller.py +1566 -1512
  5. meerk40t/balormk/cylindermod.py +64 -0
  6. meerk40t/balormk/device.py +966 -1959
  7. meerk40t/balormk/driver.py +778 -591
  8. meerk40t/balormk/galvo_commands.py +1194 -0
  9. meerk40t/balormk/gui/balorconfig.py +237 -111
  10. meerk40t/balormk/gui/balorcontroller.py +191 -184
  11. meerk40t/balormk/gui/baloroperationproperties.py +116 -115
  12. meerk40t/balormk/gui/corscene.py +845 -0
  13. meerk40t/balormk/gui/gui.py +179 -147
  14. meerk40t/balormk/livelightjob.py +466 -382
  15. meerk40t/balormk/mock_connection.py +131 -109
  16. meerk40t/balormk/plugin.py +133 -135
  17. meerk40t/balormk/usb_connection.py +306 -301
  18. meerk40t/camera/__init__.py +1 -1
  19. meerk40t/camera/camera.py +514 -397
  20. meerk40t/camera/gui/camerapanel.py +1241 -1095
  21. meerk40t/camera/gui/gui.py +58 -58
  22. meerk40t/camera/plugin.py +441 -399
  23. meerk40t/ch341/__init__.py +27 -27
  24. meerk40t/ch341/ch341device.py +628 -628
  25. meerk40t/ch341/libusb.py +595 -589
  26. meerk40t/ch341/mock.py +171 -171
  27. meerk40t/ch341/windriver.py +157 -157
  28. meerk40t/constants.py +13 -0
  29. meerk40t/core/__init__.py +1 -1
  30. meerk40t/core/bindalias.py +550 -539
  31. meerk40t/core/core.py +47 -47
  32. meerk40t/core/cutcode/cubiccut.py +73 -73
  33. meerk40t/core/cutcode/cutcode.py +315 -312
  34. meerk40t/core/cutcode/cutgroup.py +141 -137
  35. meerk40t/core/cutcode/cutobject.py +192 -185
  36. meerk40t/core/cutcode/dwellcut.py +37 -37
  37. meerk40t/core/cutcode/gotocut.py +29 -29
  38. meerk40t/core/cutcode/homecut.py +29 -29
  39. meerk40t/core/cutcode/inputcut.py +34 -34
  40. meerk40t/core/cutcode/linecut.py +33 -33
  41. meerk40t/core/cutcode/outputcut.py +34 -34
  42. meerk40t/core/cutcode/plotcut.py +335 -335
  43. meerk40t/core/cutcode/quadcut.py +61 -61
  44. meerk40t/core/cutcode/rastercut.py +168 -148
  45. meerk40t/core/cutcode/waitcut.py +34 -34
  46. meerk40t/core/cutplan.py +1843 -1316
  47. meerk40t/core/drivers.py +330 -329
  48. meerk40t/core/elements/align.py +801 -669
  49. meerk40t/core/elements/branches.py +1858 -1507
  50. meerk40t/core/elements/clipboard.py +229 -219
  51. meerk40t/core/elements/element_treeops.py +4595 -2837
  52. meerk40t/core/elements/element_types.py +125 -105
  53. meerk40t/core/elements/elements.py +4315 -3617
  54. meerk40t/core/elements/files.py +117 -64
  55. meerk40t/core/elements/geometry.py +473 -224
  56. meerk40t/core/elements/grid.py +467 -316
  57. meerk40t/core/elements/materials.py +158 -94
  58. meerk40t/core/elements/notes.py +50 -38
  59. meerk40t/core/elements/offset_clpr.py +934 -912
  60. meerk40t/core/elements/offset_mk.py +963 -955
  61. meerk40t/core/elements/penbox.py +339 -267
  62. meerk40t/core/elements/placements.py +300 -83
  63. meerk40t/core/elements/render.py +785 -687
  64. meerk40t/core/elements/shapes.py +2618 -2092
  65. meerk40t/core/elements/testcases.py +105 -0
  66. meerk40t/core/elements/trace.py +651 -563
  67. meerk40t/core/elements/tree_commands.py +415 -409
  68. meerk40t/core/elements/undo_redo.py +116 -58
  69. meerk40t/core/elements/wordlist.py +319 -200
  70. meerk40t/core/exceptions.py +9 -9
  71. meerk40t/core/laserjob.py +220 -220
  72. meerk40t/core/logging.py +63 -63
  73. meerk40t/core/node/blobnode.py +83 -86
  74. meerk40t/core/node/bootstrap.py +105 -103
  75. meerk40t/core/node/branch_elems.py +40 -31
  76. meerk40t/core/node/branch_ops.py +45 -38
  77. meerk40t/core/node/branch_regmark.py +48 -41
  78. meerk40t/core/node/cutnode.py +29 -32
  79. meerk40t/core/node/effect_hatch.py +375 -257
  80. meerk40t/core/node/effect_warp.py +398 -0
  81. meerk40t/core/node/effect_wobble.py +441 -309
  82. meerk40t/core/node/elem_ellipse.py +404 -309
  83. meerk40t/core/node/elem_image.py +1082 -801
  84. meerk40t/core/node/elem_line.py +358 -292
  85. meerk40t/core/node/elem_path.py +259 -201
  86. meerk40t/core/node/elem_point.py +129 -102
  87. meerk40t/core/node/elem_polyline.py +310 -246
  88. meerk40t/core/node/elem_rect.py +376 -286
  89. meerk40t/core/node/elem_text.py +445 -418
  90. meerk40t/core/node/filenode.py +59 -40
  91. meerk40t/core/node/groupnode.py +138 -74
  92. meerk40t/core/node/image_processed.py +777 -766
  93. meerk40t/core/node/image_raster.py +156 -113
  94. meerk40t/core/node/layernode.py +31 -31
  95. meerk40t/core/node/mixins.py +135 -107
  96. meerk40t/core/node/node.py +1427 -1304
  97. meerk40t/core/node/nutils.py +117 -114
  98. meerk40t/core/node/op_cut.py +463 -335
  99. meerk40t/core/node/op_dots.py +296 -251
  100. meerk40t/core/node/op_engrave.py +414 -311
  101. meerk40t/core/node/op_image.py +755 -369
  102. meerk40t/core/node/op_raster.py +787 -522
  103. meerk40t/core/node/place_current.py +37 -40
  104. meerk40t/core/node/place_point.py +329 -126
  105. meerk40t/core/node/refnode.py +58 -47
  106. meerk40t/core/node/rootnode.py +225 -219
  107. meerk40t/core/node/util_console.py +48 -48
  108. meerk40t/core/node/util_goto.py +84 -65
  109. meerk40t/core/node/util_home.py +61 -61
  110. meerk40t/core/node/util_input.py +102 -102
  111. meerk40t/core/node/util_output.py +102 -102
  112. meerk40t/core/node/util_wait.py +65 -65
  113. meerk40t/core/parameters.py +709 -707
  114. meerk40t/core/planner.py +875 -785
  115. meerk40t/core/plotplanner.py +656 -652
  116. meerk40t/core/space.py +120 -113
  117. meerk40t/core/spoolers.py +706 -705
  118. meerk40t/core/svg_io.py +1836 -1549
  119. meerk40t/core/treeop.py +534 -445
  120. meerk40t/core/undos.py +278 -124
  121. meerk40t/core/units.py +784 -680
  122. meerk40t/core/view.py +393 -322
  123. meerk40t/core/webhelp.py +62 -62
  124. meerk40t/core/wordlist.py +513 -504
  125. meerk40t/cylinder/cylinder.py +247 -0
  126. meerk40t/cylinder/gui/cylindersettings.py +41 -0
  127. meerk40t/cylinder/gui/gui.py +24 -0
  128. meerk40t/device/__init__.py +1 -1
  129. meerk40t/device/basedevice.py +322 -123
  130. meerk40t/device/devicechoices.py +50 -0
  131. meerk40t/device/dummydevice.py +163 -128
  132. meerk40t/device/gui/defaultactions.py +618 -602
  133. meerk40t/device/gui/effectspanel.py +114 -0
  134. meerk40t/device/gui/formatterpanel.py +253 -290
  135. meerk40t/device/gui/warningpanel.py +337 -260
  136. meerk40t/device/mixins.py +13 -13
  137. meerk40t/dxf/__init__.py +1 -1
  138. meerk40t/dxf/dxf_io.py +766 -554
  139. meerk40t/dxf/plugin.py +47 -35
  140. meerk40t/external_plugins.py +79 -79
  141. meerk40t/external_plugins_build.py +28 -28
  142. meerk40t/extra/cag.py +112 -116
  143. meerk40t/extra/coolant.py +403 -0
  144. meerk40t/extra/encode_detect.py +204 -0
  145. meerk40t/extra/ezd.py +1165 -1165
  146. meerk40t/extra/hershey.py +834 -340
  147. meerk40t/extra/imageactions.py +322 -316
  148. meerk40t/extra/inkscape.py +628 -622
  149. meerk40t/extra/lbrn.py +424 -424
  150. meerk40t/extra/outerworld.py +283 -0
  151. meerk40t/extra/param_functions.py +1542 -1556
  152. meerk40t/extra/potrace.py +257 -253
  153. meerk40t/extra/serial_exchange.py +118 -0
  154. meerk40t/extra/updater.py +602 -453
  155. meerk40t/extra/vectrace.py +147 -146
  156. meerk40t/extra/winsleep.py +83 -83
  157. meerk40t/extra/xcs_reader.py +597 -0
  158. meerk40t/fill/fills.py +781 -335
  159. meerk40t/fill/patternfill.py +1061 -1061
  160. meerk40t/fill/patterns.py +614 -567
  161. meerk40t/grbl/control.py +87 -87
  162. meerk40t/grbl/controller.py +990 -903
  163. meerk40t/grbl/device.py +1084 -768
  164. meerk40t/grbl/driver.py +989 -771
  165. meerk40t/grbl/emulator.py +532 -497
  166. meerk40t/grbl/gcodejob.py +783 -767
  167. meerk40t/grbl/gui/grblconfiguration.py +373 -298
  168. meerk40t/grbl/gui/grblcontroller.py +485 -271
  169. meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
  170. meerk40t/grbl/gui/grbloperationconfig.py +105 -0
  171. meerk40t/grbl/gui/gui.py +147 -116
  172. meerk40t/grbl/interpreter.py +44 -44
  173. meerk40t/grbl/loader.py +22 -22
  174. meerk40t/grbl/mock_connection.py +56 -56
  175. meerk40t/grbl/plugin.py +294 -264
  176. meerk40t/grbl/serial_connection.py +93 -88
  177. meerk40t/grbl/tcp_connection.py +81 -79
  178. meerk40t/grbl/ws_connection.py +112 -0
  179. meerk40t/gui/__init__.py +1 -1
  180. meerk40t/gui/about.py +2042 -296
  181. meerk40t/gui/alignment.py +1644 -1608
  182. meerk40t/gui/autoexec.py +199 -0
  183. meerk40t/gui/basicops.py +791 -670
  184. meerk40t/gui/bufferview.py +77 -71
  185. meerk40t/gui/busy.py +232 -133
  186. meerk40t/gui/choicepropertypanel.py +1662 -1469
  187. meerk40t/gui/consolepanel.py +706 -542
  188. meerk40t/gui/devicepanel.py +687 -581
  189. meerk40t/gui/dialogoptions.py +110 -107
  190. meerk40t/gui/executejob.py +316 -306
  191. meerk40t/gui/fonts.py +90 -90
  192. meerk40t/gui/functionwrapper.py +252 -0
  193. meerk40t/gui/gui_mixins.py +729 -0
  194. meerk40t/gui/guicolors.py +205 -182
  195. meerk40t/gui/help_assets/help_assets.py +218 -201
  196. meerk40t/gui/helper.py +154 -0
  197. meerk40t/gui/hersheymanager.py +1440 -846
  198. meerk40t/gui/icons.py +3422 -2747
  199. meerk40t/gui/imagesplitter.py +555 -508
  200. meerk40t/gui/keymap.py +354 -344
  201. meerk40t/gui/laserpanel.py +897 -806
  202. meerk40t/gui/laserrender.py +1470 -1232
  203. meerk40t/gui/lasertoolpanel.py +805 -793
  204. meerk40t/gui/magnetoptions.py +436 -0
  205. meerk40t/gui/materialmanager.py +2944 -0
  206. meerk40t/gui/materialtest.py +1722 -1694
  207. meerk40t/gui/mkdebug.py +646 -359
  208. meerk40t/gui/mwindow.py +163 -140
  209. meerk40t/gui/navigationpanels.py +2605 -2467
  210. meerk40t/gui/notes.py +143 -142
  211. meerk40t/gui/opassignment.py +414 -410
  212. meerk40t/gui/operation_info.py +310 -299
  213. meerk40t/gui/plugin.py +500 -328
  214. meerk40t/gui/position.py +714 -669
  215. meerk40t/gui/preferences.py +901 -650
  216. meerk40t/gui/propertypanels/attributes.py +1461 -1131
  217. meerk40t/gui/propertypanels/blobproperty.py +117 -114
  218. meerk40t/gui/propertypanels/consoleproperty.py +83 -80
  219. meerk40t/gui/propertypanels/gotoproperty.py +77 -0
  220. meerk40t/gui/propertypanels/groupproperties.py +223 -217
  221. meerk40t/gui/propertypanels/hatchproperty.py +489 -469
  222. meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
  223. meerk40t/gui/propertypanels/inputproperty.py +59 -58
  224. meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
  225. meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
  226. meerk40t/gui/propertypanels/outputproperty.py +59 -58
  227. meerk40t/gui/propertypanels/pathproperty.py +389 -380
  228. meerk40t/gui/propertypanels/placementproperty.py +1214 -383
  229. meerk40t/gui/propertypanels/pointproperty.py +140 -136
  230. meerk40t/gui/propertypanels/propertywindow.py +313 -181
  231. meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
  232. meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
  233. meerk40t/gui/propertypanels/textproperty.py +770 -755
  234. meerk40t/gui/propertypanels/waitproperty.py +56 -55
  235. meerk40t/gui/propertypanels/warpproperty.py +121 -0
  236. meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
  237. meerk40t/gui/ribbon.py +2471 -2210
  238. meerk40t/gui/scene/scene.py +1100 -1051
  239. meerk40t/gui/scene/sceneconst.py +22 -22
  240. meerk40t/gui/scene/scenepanel.py +439 -349
  241. meerk40t/gui/scene/scenespacewidget.py +365 -365
  242. meerk40t/gui/scene/widget.py +518 -505
  243. meerk40t/gui/scenewidgets/affinemover.py +215 -215
  244. meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
  245. meerk40t/gui/scenewidgets/bedwidget.py +120 -97
  246. meerk40t/gui/scenewidgets/elementswidget.py +137 -107
  247. meerk40t/gui/scenewidgets/gridwidget.py +785 -745
  248. meerk40t/gui/scenewidgets/guidewidget.py +765 -765
  249. meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
  250. meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
  251. meerk40t/gui/scenewidgets/nodeselector.py +28 -28
  252. meerk40t/gui/scenewidgets/rectselectwidget.py +592 -346
  253. meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
  254. meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
  255. meerk40t/gui/scenewidgets/selectionwidget.py +2958 -2756
  256. meerk40t/gui/simpleui.py +362 -333
  257. meerk40t/gui/simulation.py +2451 -2094
  258. meerk40t/gui/snapoptions.py +208 -203
  259. meerk40t/gui/spoolerpanel.py +1227 -1180
  260. meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
  261. meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
  262. meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
  263. meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
  264. meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
  265. meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
  266. meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
  267. meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
  268. meerk40t/gui/themes.py +200 -78
  269. meerk40t/gui/tips.py +590 -0
  270. meerk40t/gui/toolwidgets/circlebrush.py +35 -35
  271. meerk40t/gui/toolwidgets/toolcircle.py +248 -242
  272. meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
  273. meerk40t/gui/toolwidgets/tooldraw.py +97 -90
  274. meerk40t/gui/toolwidgets/toolellipse.py +219 -212
  275. meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
  276. meerk40t/gui/toolwidgets/toolline.py +39 -144
  277. meerk40t/gui/toolwidgets/toollinetext.py +79 -236
  278. meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
  279. meerk40t/gui/toolwidgets/toolmeasure.py +163 -216
  280. meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
  281. meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
  282. meerk40t/gui/toolwidgets/toolparameter.py +754 -668
  283. meerk40t/gui/toolwidgets/toolplacement.py +108 -108
  284. meerk40t/gui/toolwidgets/toolpoint.py +68 -59
  285. meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
  286. meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
  287. meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
  288. meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
  289. meerk40t/gui/toolwidgets/toolrect.py +211 -207
  290. meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
  291. meerk40t/gui/toolwidgets/toolribbon.py +598 -113
  292. meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
  293. meerk40t/gui/toolwidgets/tooltext.py +98 -89
  294. meerk40t/gui/toolwidgets/toolvector.py +213 -204
  295. meerk40t/gui/toolwidgets/toolwidget.py +39 -39
  296. meerk40t/gui/usbconnect.py +98 -91
  297. meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
  298. meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
  299. meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
  300. meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
  301. meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
  302. meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
  303. meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
  304. meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
  305. meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
  306. meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
  307. meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
  308. meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
  309. meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
  310. meerk40t/gui/wordlisteditor.py +985 -931
  311. meerk40t/gui/wxmeerk40t.py +1447 -1169
  312. meerk40t/gui/wxmmain.py +5644 -4112
  313. meerk40t/gui/wxmribbon.py +1591 -1076
  314. meerk40t/gui/wxmscene.py +1631 -1453
  315. meerk40t/gui/wxmtree.py +2416 -2089
  316. meerk40t/gui/wxutils.py +1769 -1099
  317. meerk40t/gui/zmatrix.py +102 -102
  318. meerk40t/image/__init__.py +1 -1
  319. meerk40t/image/dither.py +429 -0
  320. meerk40t/image/imagetools.py +2793 -2269
  321. meerk40t/internal_plugins.py +150 -130
  322. meerk40t/kernel/__init__.py +63 -12
  323. meerk40t/kernel/channel.py +259 -212
  324. meerk40t/kernel/context.py +538 -538
  325. meerk40t/kernel/exceptions.py +41 -41
  326. meerk40t/kernel/functions.py +463 -414
  327. meerk40t/kernel/jobs.py +100 -100
  328. meerk40t/kernel/kernel.py +3828 -3571
  329. meerk40t/kernel/lifecycles.py +71 -71
  330. meerk40t/kernel/module.py +49 -49
  331. meerk40t/kernel/service.py +147 -147
  332. meerk40t/kernel/settings.py +383 -343
  333. meerk40t/lihuiyu/controller.py +883 -876
  334. meerk40t/lihuiyu/device.py +1181 -1069
  335. meerk40t/lihuiyu/driver.py +1466 -1372
  336. meerk40t/lihuiyu/gui/gui.py +127 -106
  337. meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
  338. meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
  339. meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
  340. meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
  341. meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
  342. meerk40t/lihuiyu/interpreter.py +53 -53
  343. meerk40t/lihuiyu/laserspeed.py +450 -450
  344. meerk40t/lihuiyu/loader.py +90 -90
  345. meerk40t/lihuiyu/parser.py +404 -404
  346. meerk40t/lihuiyu/plugin.py +101 -102
  347. meerk40t/lihuiyu/tcp_connection.py +111 -109
  348. meerk40t/main.py +231 -165
  349. meerk40t/moshi/builder.py +788 -781
  350. meerk40t/moshi/controller.py +505 -499
  351. meerk40t/moshi/device.py +495 -442
  352. meerk40t/moshi/driver.py +862 -696
  353. meerk40t/moshi/gui/gui.py +78 -76
  354. meerk40t/moshi/gui/moshicontrollergui.py +538 -522
  355. meerk40t/moshi/gui/moshidrivergui.py +87 -75
  356. meerk40t/moshi/plugin.py +43 -43
  357. meerk40t/network/console_server.py +140 -57
  358. meerk40t/network/kernelserver.py +10 -9
  359. meerk40t/network/tcp_server.py +142 -140
  360. meerk40t/network/udp_server.py +103 -77
  361. meerk40t/network/web_server.py +404 -0
  362. meerk40t/newly/controller.py +1158 -1144
  363. meerk40t/newly/device.py +874 -732
  364. meerk40t/newly/driver.py +540 -412
  365. meerk40t/newly/gui/gui.py +219 -188
  366. meerk40t/newly/gui/newlyconfig.py +116 -101
  367. meerk40t/newly/gui/newlycontroller.py +193 -186
  368. meerk40t/newly/gui/operationproperties.py +51 -51
  369. meerk40t/newly/mock_connection.py +82 -82
  370. meerk40t/newly/newly_params.py +56 -56
  371. meerk40t/newly/plugin.py +1214 -1246
  372. meerk40t/newly/usb_connection.py +322 -322
  373. meerk40t/rotary/gui/gui.py +52 -46
  374. meerk40t/rotary/gui/rotarysettings.py +240 -232
  375. meerk40t/rotary/rotary.py +202 -98
  376. meerk40t/ruida/control.py +291 -91
  377. meerk40t/ruida/controller.py +138 -1088
  378. meerk40t/ruida/device.py +676 -231
  379. meerk40t/ruida/driver.py +534 -472
  380. meerk40t/ruida/emulator.py +1494 -1491
  381. meerk40t/ruida/exceptions.py +4 -4
  382. meerk40t/ruida/gui/gui.py +71 -76
  383. meerk40t/ruida/gui/ruidaconfig.py +239 -72
  384. meerk40t/ruida/gui/ruidacontroller.py +187 -184
  385. meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
  386. meerk40t/ruida/loader.py +54 -52
  387. meerk40t/ruida/mock_connection.py +57 -109
  388. meerk40t/ruida/plugin.py +124 -87
  389. meerk40t/ruida/rdjob.py +2084 -945
  390. meerk40t/ruida/serial_connection.py +116 -0
  391. meerk40t/ruida/tcp_connection.py +146 -0
  392. meerk40t/ruida/udp_connection.py +73 -0
  393. meerk40t/svgelements.py +9671 -9669
  394. meerk40t/tools/driver_to_path.py +584 -579
  395. meerk40t/tools/geomstr.py +5583 -4680
  396. meerk40t/tools/jhfparser.py +357 -292
  397. meerk40t/tools/kerftest.py +904 -890
  398. meerk40t/tools/livinghinges.py +1168 -1033
  399. meerk40t/tools/pathtools.py +987 -949
  400. meerk40t/tools/pmatrix.py +234 -0
  401. meerk40t/tools/pointfinder.py +942 -942
  402. meerk40t/tools/polybool.py +941 -940
  403. meerk40t/tools/rasterplotter.py +1660 -547
  404. meerk40t/tools/shxparser.py +1047 -901
  405. meerk40t/tools/ttfparser.py +726 -446
  406. meerk40t/tools/zinglplotter.py +595 -593
  407. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/LICENSE +21 -21
  408. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/METADATA +150 -139
  409. meerk40t-0.9.7020.dist-info/RECORD +446 -0
  410. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/WHEEL +1 -1
  411. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/top_level.txt +0 -1
  412. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/zip-safe +1 -1
  413. meerk40t/balormk/elementlightjob.py +0 -159
  414. meerk40t-0.9.3001.dist-info/RECORD +0 -437
  415. test/bootstrap.py +0 -63
  416. test/test_cli.py +0 -12
  417. test/test_core_cutcode.py +0 -418
  418. test/test_core_elements.py +0 -144
  419. test/test_core_plotplanner.py +0 -397
  420. test/test_core_viewports.py +0 -312
  421. test/test_drivers_grbl.py +0 -108
  422. test/test_drivers_lihuiyu.py +0 -443
  423. test/test_drivers_newly.py +0 -113
  424. test/test_element_degenerate_points.py +0 -43
  425. test/test_elements_classify.py +0 -97
  426. test/test_elements_penbox.py +0 -22
  427. test/test_file_svg.py +0 -176
  428. test/test_fill.py +0 -155
  429. test/test_geomstr.py +0 -1523
  430. test/test_geomstr_nodes.py +0 -18
  431. test/test_imagetools_actualize.py +0 -306
  432. test/test_imagetools_wizard.py +0 -258
  433. test/test_kernel.py +0 -200
  434. test/test_laser_speeds.py +0 -3303
  435. test/test_length.py +0 -57
  436. test/test_lifecycle.py +0 -66
  437. test/test_operations.py +0 -251
  438. test/test_operations_hatch.py +0 -57
  439. test/test_ruida.py +0 -19
  440. test/test_spooler.py +0 -22
  441. test/test_tools_rasterplotter.py +0 -29
  442. test/test_wobble.py +0 -133
  443. test/test_zingl.py +0 -124
  444. {test → meerk40t/cylinder}/__init__.py +0 -0
  445. /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
  446. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/entry_points.txt +0 -0
meerk40t/ruida/rdjob.py CHANGED
@@ -1,945 +1,2084 @@
1
- import threading
2
- import time
3
-
4
- from meerk40t.core.cutcode.plotcut import PlotCut
5
- from meerk40t.core.units import UNITS_PER_uM
6
- from meerk40t.svgelements import Color
7
-
8
- from .exceptions import RuidaCommandError
9
-
10
-
11
- def signed35(v):
12
- v &= 0x7FFFFFFFF
13
- if v > 0x3FFFFFFFF:
14
- return -0x800000000 + v
15
- else:
16
- return v
17
-
18
-
19
- def signed32(v):
20
- v &= 0xFFFFFFFF
21
- if v > 0x7FFFFFFF:
22
- return -0x100000000 + v
23
- else:
24
- return v
25
-
26
-
27
- def signed14(v):
28
- v &= 0x7FFF
29
- if v > 0x1FFF:
30
- return -0x4000 + v
31
- else:
32
- return v
33
-
34
-
35
- def decode14(data):
36
- return signed14(decodeu14(data))
37
-
38
-
39
- def decodeu14(data):
40
- return (data[0] & 0x7F) << 7 | (data[1] & 0x7F)
41
-
42
-
43
- def encode14(v):
44
- return [
45
- (v >> 7) & 0x7F,
46
- v & 0x7F,
47
- ]
48
-
49
-
50
- def decode35(data):
51
- return signed35(decodeu35(data))
52
-
53
-
54
- def decode32(data):
55
- return signed32(decodeu35(data))
56
-
57
-
58
- def decodeu35(data):
59
- return (
60
- (data[0] & 0x7F) << 28
61
- | (data[1] & 0x7F) << 21
62
- | (data[2] & 0x7F) << 14
63
- | (data[3] & 0x7F) << 7
64
- | (data[4] & 0x7F)
65
- )
66
-
67
-
68
- def encode32(v):
69
- return [
70
- (v >> 28) & 0x7F,
71
- (v >> 21) & 0x7F,
72
- (v >> 14) & 0x7F,
73
- (v >> 7) & 0x7F,
74
- v & 0x7F,
75
- ]
76
-
77
-
78
- def abscoord(data):
79
- return decode32(data)
80
-
81
-
82
- def relcoord(data):
83
- return decode14(data)
84
-
85
-
86
- def parse_mem(data):
87
- return decode14(data)
88
-
89
-
90
- def parse_filenumber(data):
91
- return decode14(data)
92
-
93
-
94
- def parse_speed(data):
95
- return decode35(data) / 1000.0
96
-
97
-
98
- def parse_frequency(data):
99
- return decodeu35(data)
100
-
101
-
102
- def parse_power(data):
103
- return decodeu14(data) / 163.84 # 16384 / 100%
104
-
105
-
106
- def parse_time(data):
107
- return decodeu35(data) / 1000.0
108
-
109
-
110
- def parse_commands(data):
111
- array = list()
112
- for b in data:
113
- if b >= 0x80 and len(array) > 0:
114
- yield list(array)
115
- array.clear()
116
- array.append(b)
117
- if len(array) > 0:
118
- yield array
119
-
120
-
121
- def swizzle_byte(b, magic):
122
- b ^= (b >> 7) & 0xFF
123
- b ^= (b << 7) & 0xFF
124
- b ^= (b >> 7) & 0xFF
125
- b ^= magic
126
- b = (b + 1) & 0xFF
127
- return b
128
-
129
-
130
- def unswizzle_byte(b, magic):
131
- b = (b - 1) & 0xFF
132
- b ^= magic
133
- b ^= (b >> 7) & 0xFF
134
- b ^= (b << 7) & 0xFF
135
- b ^= (b >> 7) & 0xFF
136
- return b
137
-
138
-
139
- def swizzles_lut(magic):
140
- lut_swizzle = [swizzle_byte(s, magic) for s in range(256)]
141
- lut_unswizzle = [unswizzle_byte(s, magic) for s in range(256)]
142
- return lut_swizzle, lut_unswizzle
143
-
144
-
145
- def decode_bytes(data, magic=0x88):
146
- lut_swizzle, lut_unswizzle = swizzles_lut(magic)
147
- array = list()
148
- for b in data:
149
- array.append(lut_unswizzle[b])
150
- return bytes(array)
151
-
152
-
153
- def determine_magic_via_histogram(data):
154
- """
155
- Determines magic number via histogram. The number which occurs most in RDWorks files is overwhelmingly 0. It's
156
- about 50% of all data. The swizzle algorithm means that the swizzle for 0 is magic + 1, so we find the most
157
- frequent number and subtract one from that and that is *most* likely the magic number.
158
-
159
- @param data:
160
- @return:
161
- """
162
- histogram = [0] * 256
163
- for d in data:
164
- histogram[d] += 1
165
- m = 0
166
- magic = None
167
- for i in range(len(histogram)):
168
- v = histogram[i]
169
- if v > m:
170
- m = v
171
- magic = i - 1
172
- return magic
173
-
174
-
175
- def encode_bytes(data, magic=0x88):
176
- lut_swizzle, lut_unswizzle = swizzles_lut(magic)
177
- array = list()
178
- for b in data:
179
- array.append(lut_swizzle[b])
180
- return bytes(array)
181
-
182
-
183
- def magic_keys():
184
- mk = dict()
185
- for g in range(256):
186
- mk[encode_bytes(b"\xda\x00\x05\x7E", magic=g)] = g
187
- return mk
188
-
189
-
190
- class RDJob:
191
- def __init__(
192
- self, driver=None, units_to_device_matrix=None, priority=0, channel=None
193
- ):
194
- self.units_to_device_matrix = units_to_device_matrix
195
- self._driver = driver
196
- self.channel = channel
197
- self.reply = None
198
- self.buffer = list()
199
- self.plotcut = None
200
-
201
- self.priority = priority
202
-
203
- self.time_submitted = time.time()
204
- self.time_started = None
205
- self.runtime = 0
206
-
207
- self._stopped = True
208
- self.enabled = True
209
- self._estimate = 0
210
-
211
- self.scale = UNITS_PER_uM
212
-
213
- self.speed = None
214
- self.power = None
215
- self.frequency = None
216
- self.power1_max = None
217
- self.power1_min = None
218
- self.power2_max = None
219
- self.power2_min = None
220
-
221
- self.color = None
222
- self.magic = 0x11 # 0x11 for the 634XG
223
- # self.magic = 0x88
224
- self.lut_swizzle, self.lut_unswizzle = swizzles_lut(self.magic)
225
-
226
- self.x = 0.0
227
- self.y = 0.0
228
- self.z = 0.0
229
- self.u = 0.0
230
-
231
- self.a = 0.0
232
- self.b = 0.0
233
- self.c = 0.0
234
- self.d = 0.0
235
-
236
- self.lock = threading.Lock()
237
-
238
- def __str__(self):
239
- return f"{self.__class__.__name__}({len(self.buffer)} lines)"
240
-
241
- @property
242
- def status(self):
243
- if self.is_running():
244
- if self.time_started:
245
- return "Running"
246
- else:
247
- return "Queued"
248
- else:
249
- if self.enabled:
250
- return "Waiting"
251
- else:
252
- return "Disabled"
253
-
254
- def write_blob(self, data, magic=None):
255
- """
256
- Procedural commands sent in large data chunks. This can be through USB or UDP or a loaded file. These are
257
- expected to be unswizzled with the swizzle_mode set for the reply. Write will parse out the individual commands
258
- and send those to the command routine.
259
-
260
- @param data:
261
- @param magic: magic number for unswizzling
262
- @return:
263
- """
264
- if magic is None:
265
- magic = determine_magic_via_histogram(data)
266
- if magic is not None and magic != self.magic:
267
- self.magic = magic
268
- self.lut_swizzle, self.lut_unswizzle = swizzles_lut(self.magic)
269
- packet = self.unswizzle(data)
270
- with self.lock:
271
- self.buffer.extend(parse_commands(packet))
272
-
273
- def write_command(self, command):
274
- with self.lock:
275
- self.buffer.append(command)
276
-
277
- def execute(self, driver=None):
278
- """
279
- Execute calls each item in the list of items in order. This is intended to be called by the spooler thread. And
280
- hold the spooler while these items are executing.
281
- @return:
282
- """
283
- self._stopped = False
284
- if self.time_started is None:
285
- self.time_started = time.time()
286
- with self.lock:
287
- array = self.buffer.pop(0)
288
- try:
289
- self.process(array)
290
- except IndexError as e:
291
- raise RuidaCommandError(
292
- f"Could not process Ruida buffer, {self.buffer[:25]} with magic: {self.magic:02}"
293
- ) from e
294
- if not self.buffer:
295
- # Buffer is empty now. Job is complete
296
- self.runtime += time.time() - self.time_started
297
- self._stopped = True
298
- return True # All steps were executed.
299
- return False
300
-
301
- def stop(self):
302
- """
303
- Stop this current laser-job, cannot be called from the spooler thread.
304
- @return:
305
- """
306
- if not self._stopped:
307
- self.runtime += time.time() - self.time_started
308
- self._stopped = True
309
-
310
- def is_running(self):
311
- return not self._stopped
312
-
313
- def elapsed_time(self):
314
- """
315
- How long is this job already running...
316
- """
317
- result = 0
318
- if self.is_running():
319
- result = time.time() - self.time_started
320
- else:
321
- result = self.runtime
322
- return result
323
-
324
- def estimate_time(self):
325
- """
326
- Give laser job time estimate.
327
- @return:
328
- """
329
- return self._estimate
330
-
331
- def plot_location(self, x, y, power):
332
- """
333
- Adds this particular location to the current plotcut.
334
-
335
- Or, starts a new plotcut if one is not already started.
336
-
337
- First plotcut is a 0-power move to the current position. X and Y are set to plotted location
338
-
339
- @param x:
340
- @param y:
341
- @param power:
342
- @return:
343
- """
344
- matrix = self.units_to_device_matrix
345
- if matrix is None:
346
- # Using job for something other than point plotting
347
- return
348
- if self.plotcut is None:
349
- self.x = x
350
- self.y = y
351
- ox, oy = matrix.transform_point([self.x, self.y])
352
- self.plotcut = PlotCut(
353
- settings={
354
- "speed": self.speed,
355
- "power": self.power,
356
- "frequency": self.frequency,
357
- }
358
- )
359
- self.plotcut.plot_init(int(round(ox)), int(round(oy)))
360
- tx, ty = matrix.transform_point([x, y])
361
- self.plotcut.plot_append(
362
- int(round(tx)), int(round(ty)), power * (self.power / 1000.0)
363
- )
364
- self.x = x
365
- self.y = y
366
-
367
- def plot_commit(self):
368
- """
369
- Force commits the old plotcut and unsets the current plotcut.
370
-
371
- @return:
372
- """
373
- if self.plotcut is None:
374
- return
375
- self.plot(self.plotcut)
376
- self.plotcut = None
377
-
378
- def plot(self, plot):
379
- try:
380
- self._driver.plot(plot)
381
- except AttributeError:
382
- pass
383
-
384
- def __repr__(self):
385
- return f"RuidaEmulator(@{hex(id(self))})"
386
-
387
- @property
388
- def current(self):
389
- return self.x, self.y
390
-
391
- def set_color(self, color):
392
- self.color = color
393
-
394
- def process(self, array):
395
- """
396
- Parses an individual unswizzled ruida command, updating the emulator state.
397
-
398
- These commands can change the position, settings, speed, color, power, create elements.
399
- @param array:
400
- @return:
401
- """
402
- desc = ""
403
- if array[0] < 0x80:
404
- if self.channel:
405
- self.channel(f"NOT A COMMAND: {array[0]}")
406
- raise RuidaCommandError
407
- elif array[0] == 0x80:
408
- value = abscoord(array[2:7])
409
- if array[1] == 0x00:
410
- desc = f"Axis X Move {value}"
411
- self.x += value
412
- elif array[1] == 0x08:
413
- desc = f"Axis Z Move {value}"
414
- self.z += value
415
- elif array[0] == 0x88: # 0b10001000 11 characters.
416
- x = abscoord(array[1:6]) * self.scale
417
- y = abscoord(array[6:11]) * self.scale
418
- self.plot_location(x, y, 0)
419
- desc = f"Move Absolute ({x} units, {y} units)"
420
- elif array[0] == 0x89: # 0b10001001 5 characters
421
- if len(array) > 1:
422
- dx = relcoord(array[1:3]) * self.scale
423
- dy = relcoord(array[3:5]) * self.scale
424
- self.plot_location(self.x + dx, self.y + dy, 0)
425
- desc = f"Move Relative ({dx} units, {dy} units)"
426
- else:
427
- desc = "Move Relative (no coords)"
428
- elif array[0] == 0x8A: # 0b10101010 3 characters
429
- dx = relcoord(array[1:3]) * self.scale
430
- self.plot_location(self.x + dx, self.y, 0)
431
- desc = f"Move Horizontal Relative ({dx} units)"
432
- elif array[0] == 0x8B: # 0b10101011 3 characters
433
- dy = relcoord(array[1:3]) * self.scale
434
- self.plot_location(self.x, self.y + dy, 0)
435
- desc = f"Move Vertical Relative ({dy} units)"
436
- elif array[0] == 0x97:
437
- desc = "Lightburn Swizzle Modulation 97"
438
- elif array[0] == 0x9B:
439
- desc = "Lightburn Swizzle Modulation 9b"
440
- elif array[0] == 0x9E:
441
- desc = "Lightburn Swizzle Modulation 9e"
442
- elif array[0] == 0xA0:
443
- value = abscoord(array[2:7])
444
- if array[1] == 0x00:
445
- desc = f"Axis Y Move {value}"
446
- elif array[1] == 0x08:
447
- desc = f"Axis U Move {value}"
448
- elif array[0] == 0xA8: # 0b10101000 11 characters.
449
- x = abscoord(array[1:6]) * self.scale
450
- y = abscoord(array[6:11]) * self.scale
451
- self.plot_location(x, y, 1)
452
- desc = f"Cut Absolute ({x} units, {y} units)"
453
- elif array[0] == 0xA9: # 0b10101001 5 characters
454
- dx = relcoord(array[1:3]) * self.scale
455
- dy = relcoord(array[3:5]) * self.scale
456
- self.plot_location(self.x + dx, self.y + dy, 1)
457
- desc = f"Cut Relative ({dx} units, {dy} units)"
458
- elif array[0] == 0xAA: # 0b10101010 3 characters
459
- dx = relcoord(array[1:3]) * self.scale
460
- self.plot_location(self.x + dx, self.y, 1)
461
- desc = f"Cut Horizontal Relative ({dx} units)"
462
- elif array[0] == 0xAB: # 0b10101011 3 characters
463
- dy = relcoord(array[1:3]) * self.scale
464
- self.plot_location(self.x, self.y + dy, 1)
465
- desc = f"Cut Vertical Relative ({dy} units)"
466
- elif array[0] == 0xC7:
467
- try:
468
- v0 = parse_power(array[1:3])
469
- except IndexError:
470
- v0 = 0
471
- desc = f"Imd Power 1 ({v0})"
472
- elif array[0] == 0xC2:
473
- v0 = parse_power(array[1:3])
474
- desc = f"Imd Power 3 ({v0})"
475
- elif array[0] == 0xC0:
476
- v0 = parse_power(array[1:3])
477
- desc = f"Imd Power 2 ({v0})"
478
- elif array[0] == 0xC3:
479
- v0 = parse_power(array[1:3])
480
- desc = f"Imd Power 4 ({v0})"
481
- elif array[0] == 0xC8:
482
- v0 = parse_power(array[1:3])
483
- desc = f"End Power 1 ({v0})"
484
- elif array[0] == 0xC4:
485
- v0 = parse_power(array[1:3])
486
- desc = f"End Power 3 ({v0})"
487
- elif array[0] == 0xC1:
488
- v0 = parse_power(array[1:3])
489
- desc = f"End Power 2 ({v0})"
490
- elif array[0] == 0xC5:
491
- v0 = parse_power(array[1:3])
492
- desc = f"End Power 4 ({v0})"
493
- elif array[0] == 0xC6:
494
- if array[1] == 0x01:
495
- power = parse_power(array[2:4])
496
- self.power1_min = power
497
- power = self.power1_min
498
- desc = f"Power 1 min={power}"
499
- self.power = power * 10 # 1000 / 100
500
- elif array[1] == 0x02:
501
- power = parse_power(array[2:4])
502
- self.power1_max = power
503
- power = self.power1_max
504
- desc = f"Power 1 max={power}"
505
- self.power = power * 10 # 1000 / 100
506
- elif array[1] == 0x05:
507
- power = parse_power(array[2:4])
508
- desc = f"Power 3 min={power}"
509
- elif array[1] == 0x06:
510
- power = parse_power(array[2:4])
511
- desc = f"Power 3 max={power}"
512
- elif array[1] == 0x07:
513
- power = parse_power(array[2:4])
514
- desc = f"Power 4 min={power}"
515
- elif array[1] == 0x08:
516
- power = parse_power(array[2:4])
517
- desc = f"Power 4 max={power}"
518
- elif array[1] == 0x10:
519
- interval = parse_time(array[2:7])
520
- desc = f"Laser Interval {interval}ms"
521
- elif array[1] == 0x11:
522
- interval = parse_time(array[2:7])
523
- desc = f"Add Delay {interval}ms"
524
- elif array[1] == 0x12:
525
- interval = parse_time(array[2:7])
526
- desc = f"Laser On Delay {interval}ms"
527
- elif array[1] == 0x13:
528
- interval = parse_time(array[2:7])
529
- desc = f"Laser Off Delay {interval}ms"
530
- elif array[1] == 0x15:
531
- interval = parse_time(array[2:7])
532
- desc = f"Laser On2 {interval}ms"
533
- elif array[1] == 0x16:
534
- interval = parse_time(array[2:7])
535
- desc = f"Laser Off2 {interval}ms"
536
- elif array[1] == 0x21:
537
- power = parse_power(array[2:4])
538
- desc = f"Power 2 min={power}"
539
- self.power2_min = power
540
- elif array[1] == 0x22:
541
- power = parse_power(array[2:4])
542
- desc = f"Power 2 max={power}"
543
- self.power2_max = power
544
- elif array[1] == 0x31:
545
- part = array[2]
546
- self.power1_min = parse_power(array[3:5])
547
- desc = f"{part}, Power 1 Min=({self.power1_min})"
548
- elif array[1] == 0x32:
549
- part = array[2]
550
- self.power1_max = parse_power(array[3:5])
551
- desc = f"{part}, Power 1 Max=({self.power1_max})"
552
- elif array[1] == 0x35:
553
- part = array[2]
554
- power = parse_power(array[3:5])
555
- desc = f"{part}, Power 3 Min ({power})"
556
- elif array[1] == 0x36:
557
- part = array[2]
558
- power = parse_power(array[3:5])
559
- desc = f"{part}, Power 3 Max ({power})"
560
- elif array[1] == 0x37:
561
- part = array[2]
562
- power = parse_power(array[3:5])
563
- desc = f"{part}, Power 4 Min ({power})"
564
- elif array[1] == 0x38:
565
- part = array[2]
566
- power = parse_power(array[3:5])
567
- desc = f"{part}, Power 4 Max ({power})"
568
- elif array[1] == 0x41:
569
- part = array[2]
570
- power = parse_power(array[3:5])
571
- desc = f"{part}, Power 2 Min ({power})"
572
- elif array[1] == 0x42:
573
- part = array[2]
574
- power = parse_power(array[3:5])
575
- desc = f"{part}, Power 2 Max ({power})"
576
- elif array[1] == 0x50:
577
- power = parse_power(array[2:4])
578
- desc = f"Through Power 1 ({power})"
579
- elif array[1] == 0x51:
580
- power = parse_power(array[2:4])
581
- desc = f"Through Power 2 ({power})"
582
- elif array[1] == 0x55:
583
- power = parse_power(array[2:4])
584
- desc = f"Through Power 3 ({power})"
585
- elif array[1] == 0x56:
586
- power = parse_power(array[2:4])
587
- desc = f"Through Power 4 ({power})"
588
- elif array[1] == 0x60:
589
- laser = array[2]
590
- part = array[3]
591
- frequency = parse_frequency(array[4:9])
592
- desc = f"part, Laser {laser}, Frequency ({frequency})"
593
- if frequency != self.frequency:
594
- self.frequency = frequency
595
- elif array[0] == 0xC9:
596
- if array[1] == 0x02:
597
- self.plot_commit()
598
- speed = parse_speed(array[2:7])
599
- if speed != self.speed:
600
- self.speed = speed
601
- desc = f"Speed Laser 1 {speed}mm/s"
602
- elif array[1] == 0x03:
603
- speed = parse_speed(array[2:7])
604
- desc = f"Axis Speed {speed}mm/s"
605
- elif array[1] == 0x04:
606
- self.plot_commit()
607
- part = array[2]
608
- speed = parse_speed(array[3:8])
609
- if speed != self.speed:
610
- self.speed = speed
611
- desc = f"{part}, Speed {speed}mm/s"
612
- elif array[1] == 0x05:
613
- speed = parse_speed(array[2:7]) / 1000.0
614
- desc = f"Force Eng Speed {speed}mm/s"
615
- elif array[1] == 0x06:
616
- speed = parse_speed(array[2:7]) / 1000.0
617
- desc = f"Axis Move Speed {speed}mm/s"
618
- elif array[0] == 0xCA:
619
- if array[1] == 0x01:
620
- if array[2] == 0x00:
621
- desc = "End Layer"
622
- elif array[2] == 0x01:
623
- desc = "Work Mode 1"
624
- elif array[2] == 0x02:
625
- desc = "Work Mode 2"
626
- elif array[2] == 0x03:
627
- desc = "Work Mode 3"
628
- elif array[2] == 0x04:
629
- desc = "Work Mode 4"
630
- elif array[2] == 0x55:
631
- desc = "Work Mode 5"
632
- elif array[2] == 0x05:
633
- desc = "Work Mode 6"
634
- elif array[2] == 0x10:
635
- desc = "Layer Device 0"
636
- elif array[2] == 0x11:
637
- desc = "Layer Device 1"
638
- elif array[2] == 0x12:
639
- desc = "Air Assist Off"
640
- elif array[2] == 0x13:
641
- desc = "Air Assist On"
642
- elif array[2] == 0x14:
643
- desc = "DbHead"
644
- elif array[2] == 0x30:
645
- desc = "EnLaser2Offset 0"
646
- elif array[2] == 0x31:
647
- desc = "EnLaser2Offset 1"
648
- elif array[1] == 0x02:
649
- part = array[2]
650
- desc = f"{part}, Layer Number"
651
- elif array[1] == 0x03:
652
- desc = "EnLaserTube Start"
653
- elif array[1] == 0x04:
654
- value = array[2]
655
- desc = f"X Sign Map {value}"
656
- elif array[1] == 0x05:
657
- self.plot_commit()
658
- c = decodeu35(array[2:7])
659
- r = c & 0xFF
660
- g = (c >> 8) & 0xFF
661
- b = (c >> 16) & 0xFF
662
- c = Color(red=r, blue=b, green=g)
663
- self.set_color(c.hex)
664
- desc = f"Layer Color {str(self.color)}"
665
- elif array[1] == 0x06:
666
- part = array[2]
667
- c = decodeu35(array[3:8])
668
- r = c & 0xFF
669
- g = (c >> 8) & 0xFF
670
- b = (c >> 16) & 0xFF
671
- c = Color(red=r, blue=b, green=g)
672
- self.set_color(c.hex)
673
- desc = f"{part}, Color {self.color}"
674
- elif array[1] == 0x10:
675
- value = array[2]
676
- desc = f"EnExIO Start {value}"
677
- elif array[1] == 0x22:
678
- part = array[2]
679
- desc = f"{part}, Max Layer"
680
- elif array[1] == 0x30:
681
- filenumber = parse_filenumber(array[2:4])
682
- desc = f"U File ID {filenumber}"
683
- elif array[1] == 0x40:
684
- value = array[2]
685
- desc = f"ZU Map {value}"
686
- elif array[1] == 0x41:
687
- part = array[2]
688
- mode = array[3]
689
- desc = f"{part}, Work Mode {mode}"
690
- elif array[0] == 0xCC:
691
- desc = "ACK from machine"
692
- elif array[0] == 0xCD:
693
- desc = "ERR from machine"
694
- elif array[0] == 0xCE:
695
- desc = "Keep Alive"
696
- elif array[0] == 0xD0:
697
- zone = array[1]
698
- desc = f"Set Inhale Zone {zone}"
699
- elif array[0] == 0xD7:
700
- self.plot_commit()
701
- try:
702
- self._driver.plot_start()
703
- except AttributeError:
704
- pass
705
- desc = "End Of File"
706
- elif array[0] == 0xD8:
707
- if array[1] == 0x00:
708
- desc = "Start Process"
709
- if array[1] == 0x10:
710
- desc = "Ref Point Mode 2, Machine Zero/Absolute Position"
711
- if array[1] == 0x11:
712
- desc = "Ref Point Mode 1, Anchor Point"
713
- if array[1] == 0x12:
714
- desc = "Ref Point Mode 0, Current Position"
715
- elif array[0] == 0xDA:
716
- mem = parse_mem(array[2:4])
717
- if array[1] == 0x01:
718
- value0 = array[4:9]
719
- value1 = array[9:14]
720
- v0 = decodeu35(value0)
721
- v1 = decodeu35(value1)
722
- desc = f"Set {array[2]:02x} {array[3]:02x} (mem: {mem:04x})= {v0} (0x{v0:08x}) {v1} (0x{v1:08x})"
723
- elif array[0] == 0xE5: # 0xE502
724
- if len(array) == 1:
725
- desc = "Lightburn Swizzle Modulation E5"
726
- else:
727
- if array[1] == 0x00:
728
- # RDWorks File Upload
729
- filenumber = array[2]
730
- desc = f"Document Page Number {filenumber}"
731
- # TODO: Requires Response.
732
- if array[1] == 0x02:
733
- # len 3
734
- desc = "Document Data End"
735
- elif array[1] == 0x05:
736
- sum = decodeu35(array[2:7])
737
- desc = f"Set File Sum {sum}"
738
-
739
- elif array[0] == 0xE6:
740
- if array[1] == 0x01:
741
- desc = "Set Absolute"
742
- # Only seen in Absolute Coords. MachineZero is Ref2 but does not Set Absolute.
743
- elif array[0] == 0xE7:
744
- if array[1] == 0x00:
745
- self.plot_commit()
746
- desc = "Block End"
747
- elif array[1] == 0x01:
748
- pass # Set filename for job (only realtime, see emulator)
749
- elif array[1] == 0x03:
750
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
751
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
752
- desc = f"Process TopLeft ({c_x}, {c_y})"
753
- elif array[1] == 0x04:
754
- v0 = decode14(array[2:4])
755
- v1 = decode14(array[4:6])
756
- v2 = decode14(array[6:8])
757
- v3 = decode14(array[8:10])
758
- v4 = decode14(array[10:12])
759
- v5 = decode14(array[12:14])
760
- v6 = decode14(array[14:16])
761
- desc = f"Process Repeat ({v0}, {v1}, {v2}, {v3}, {v4}, {v5}, {v6})"
762
- elif array[1] == 0x05:
763
- direction = array[2]
764
- desc = f"Array Direction ({direction})"
765
- elif array[1] == 0x06:
766
- v1 = decodeu35(array[2:7])
767
- v2 = decodeu35(array[7:12])
768
- desc = f"Feed Repeat ({v1}, {v2})"
769
- elif array[1] == 0x07:
770
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
771
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
772
- desc = f"Process BottomRight({c_x}, {c_y})"
773
- elif array[1] == 0x08: # Same value given to F2 04
774
- v0 = decode14(array[2:4])
775
- v1 = decode14(array[4:6])
776
- v2 = decode14(array[6:8])
777
- v3 = decode14(array[8:10])
778
- v4 = decode14(array[10:12])
779
- v5 = decode14(array[12:14])
780
- v6 = decode14(array[14:16])
781
- desc = f"Array Repeat ({v0}, {v1}, {v2}, {v3}, {v4}, {v5}, {v6})"
782
- elif array[1] == 0x09:
783
- v1 = decodeu35(array[2:7])
784
- desc = f"Feed Length {v1}"
785
- elif array[1] == 0x0A:
786
- desc = f"Feed Info"
787
- elif array[1] == 0x0B:
788
- v1 = array[2]
789
- desc = f"Array En Mirror Cut {v1}"
790
- elif array[1] == 0x0C:
791
- v1 = array[2]
792
- desc = f"Array Mirror Cut Distance {v1}"
793
- elif array[1] == 0x0C:
794
- v1 = array[2]
795
- desc = f"Set File Head Distance {v1}"
796
- elif array[1] == 0x13:
797
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
798
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
799
- desc = f"Array Min Point ({c_x},{c_y})"
800
- elif array[1] == 0x17:
801
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
802
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
803
- desc = f"Array Max Point ({c_x},{c_y})"
804
- elif array[1] == 0x23:
805
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
806
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
807
- desc = f"Array Add ({c_x},{c_y})"
808
- elif array[1] == 0x24:
809
- v1 = array[2]
810
- desc = f"Array Mirror {v1}"
811
- elif array[1] == 0x32:
812
- v1 = decodeu35(array[2:7])
813
- desc = f"Set Tick Count {v1}"
814
- elif array[1] == 0x35:
815
- v1 = decodeu35(array[2:7])
816
- v2 = decodeu35(array[7:12])
817
- desc = f"Block X Size {v1} {v2}"
818
- elif array[1] == 0x32:
819
- desc = f"Set File Empty"
820
- elif array[1] == 0x37:
821
- v1 = decodeu35(array[2:7])
822
- desc = f"Array Even Distance {v1}"
823
- elif array[1] == 0x38:
824
- v1 = array[2]
825
- desc = f"Set Feed Auto Pause {v1}"
826
- elif array[1] == 0x3A:
827
- desc = f"Union Block Property"
828
- elif array[1] == 0x3B:
829
- v1 = array[2]
830
- desc = f"Set File Property {v1}"
831
- elif array[1] == 0x46:
832
- desc = "BY Test 0x11227766"
833
- elif array[1] == 0x50:
834
- c_x = abscoord(array[1:6]) * UNITS_PER_uM
835
- c_y = abscoord(array[6:11]) * UNITS_PER_uM
836
- desc = f"Document Min Point({c_x}, {c_y})"
837
- elif array[1] == 0x51:
838
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
839
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
840
- desc = f"Document Max Point({c_x}, {c_y})"
841
- elif array[1] == 0x52:
842
- part = array[2]
843
- c_x = abscoord(array[3:8]) * UNITS_PER_uM
844
- c_y = abscoord(array[8:13]) * UNITS_PER_uM
845
- desc = f"{part}, Min Point({c_x}, {c_y})"
846
- elif array[1] == 0x53:
847
- part = array[2]
848
- c_x = abscoord(array[3:8]) * UNITS_PER_uM
849
- c_y = abscoord(array[8:13]) * UNITS_PER_uM
850
- desc = f"{part}, MaxPoint({c_x}, {c_y})"
851
- elif array[1] == 0x54:
852
- axis = array[2]
853
- c_x = abscoord(array[3:8]) * UNITS_PER_uM
854
- desc = f"Pen Offset {axis}: {c_x}"
855
- elif array[1] == 0x55:
856
- axis = array[2]
857
- c_x = abscoord(array[3:8]) * UNITS_PER_uM
858
- desc = f"Layer Offset {axis}: {c_x}"
859
- elif array[1] == 0x57:
860
- desc = f"PList Feed"
861
- elif array[1] == 0x60:
862
- desc = f"Set Current Element Index ({array[2]})"
863
- elif array[1] == 0x61:
864
- part = array[2]
865
- c_x = abscoord(array[3:8]) * UNITS_PER_uM
866
- c_y = abscoord(array[8:13]) * UNITS_PER_uM
867
- desc = f"{part}, MinPointEx({c_x}, {c_y})"
868
- elif array[1] == 0x62:
869
- part = array[2]
870
- c_x = abscoord(array[3:8]) * UNITS_PER_uM
871
- c_y = abscoord(array[8:13]) * UNITS_PER_uM
872
- desc = f"{part}, MaxPointEx({c_x}, {c_y})"
873
- elif array[0] == 0xE8:
874
- # Realtime command.
875
- pass
876
- elif array[0] == 0xEA:
877
- index = array[1] # TODO: Index error raised here.
878
- desc = f"Array Start ({index})"
879
- elif array[0] == 0xEB:
880
- desc = "Array End"
881
- elif array[0] == 0xF0:
882
- desc = "Ref Point Set"
883
- elif array[0] == 0xF1:
884
- if array[1] == 0x00:
885
- index = array[2]
886
- desc = f"Element Max Index ({index})"
887
- elif array[1] == 0x01:
888
- index = array[2]
889
- desc = f"Element Name Max Index({index})"
890
- elif array[1] == 0x02:
891
- enable = array[2]
892
- desc = f"Enable Block Cutting ({enable})"
893
- elif array[1] == 0x03:
894
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
895
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
896
- desc = f"Display Offset ({c_x},{c_y})"
897
- elif array[1] == 0x04:
898
- enable = array[2]
899
- desc = f"Feed Auto Calc ({enable})"
900
- elif array[1] == 0x20:
901
- desc = f"Unknown ({array[2]},{array[3]})"
902
- elif array[0] == 0xF2:
903
- if array[1] == 0x00:
904
- index = array[2]
905
- desc = f"Element Index ({index})"
906
- if array[1] == 0x01:
907
- index = array[2]
908
- desc = f"Element Name Index ({index})"
909
- if array[1] == 0x02:
910
- name = bytes(array[2:12])
911
- desc = f"Element Name ({str(name)})"
912
- if array[1] == 0x03:
913
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
914
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
915
- desc = f"Element Array Min Point ({c_x},{c_y})"
916
- if array[1] == 0x04:
917
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
918
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
919
- desc = f"Element Array Max Point ({c_x},{c_y})"
920
- if array[1] == 0x05:
921
- v0 = decode14(array[2:4])
922
- v1 = decode14(array[4:6])
923
- v2 = decode14(array[6:8])
924
- v3 = decode14(array[8:10])
925
- v4 = decode14(array[10:12])
926
- v5 = decode14(array[12:14])
927
- v6 = decode14(array[14:16])
928
- desc = f"Element Array ({v0}, {v1}, {v2}, {v3}, {v4}, {v5}, {v6})"
929
- if array[1] == 0x06:
930
- c_x = abscoord(array[2:7]) * UNITS_PER_uM
931
- c_y = abscoord(array[7:12]) * UNITS_PER_uM
932
- desc = f"Element Array Add ({c_x},{c_y})"
933
- if array[1] == 0x07:
934
- index = array[2]
935
- desc = f"Element Array Mirror ({index})"
936
- else:
937
- desc = "Unknown Command!"
938
- if self.channel:
939
- self.channel(f"-**-> {str(bytes(array).hex())}\t({desc})")
940
-
941
- def unswizzle(self, data):
942
- return bytes([self.lut_unswizzle[b] for b in data])
943
-
944
- def swizzle(self, data):
945
- return bytes([self.lut_swizzle[b] for b in data])
1
+ import threading
2
+ import time
3
+
4
+ from meerk40t.core.cutcode.plotcut import PlotCut
5
+ from meerk40t.core.units import UNITS_PER_uM
6
+ from meerk40t.svgelements import Color
7
+
8
+ from .exceptions import RuidaCommandError
9
+
10
+ INTERFACE_FRAME = b"\xA5\x53\x00"
11
+ INTERFACE_PLUS_X_DOWN = b"\xA5\x50\x02"
12
+ INTERFACE_PLUS_X_UP = b"\xA5\x51\x02"
13
+ INTERFACE_MINUS_X_DOWN = b"\xA5\x50\x01"
14
+ INTERFACE_MINUS_X_UP = b"\xA5\x51\x01"
15
+ INTERFACE_PLUS_Y_DOWN = b"\xA5\x50\x03"
16
+ INTERFACE_PLUS_Y_UP = b"\xA5\x51\x03"
17
+ INTERFACE_MINUS_Y_DOWN = b"\xA5\x50\x04"
18
+ INTERFACE_MINUS_Y_UP = b"\xA5\x51\x04"
19
+ INTERFACE_PLUS_Z_DOWN = b"\xA5\x50\x0A"
20
+ INTERFACE_PLUS_Z_UP = b"\xA5\x51\x0A"
21
+ INTERFACE_MINUS_Z_DOWN = b"\xA5\x50\x0B"
22
+ INTERFACE_MINUS_Z_UP = b"\xA5\x51\x0B"
23
+ INTERFACE_PLUS_U_DOWN = b"\xA5\x50\x0C"
24
+ INTERFACE_PLUS_U_UP = b"\xA5\x51\x0C"
25
+ INTERFACE_MINUS_U_DOWN = b"\xA5\x50\x0D"
26
+ INTERFACE_MINUS_U_UP = b"\xA5\x51\x0D"
27
+ INTERFACE_PULSE_DOWN = b"\xA5\x50\x05"
28
+ INTERFACE_PULSE_UP = b"\xA5\x51\x05"
29
+ INTERFACE_SPEED_DOWN = b"\xA5\x50\x11"
30
+ INTERFACE_SPEED_UP = b"\xA5\x51\x11"
31
+ INTERFACE_PAUSE_DOWN = b"\xA5\x50\x06"
32
+ INTERFACE_PAUSE_UP = b"\xA5\x51\x06"
33
+ INTERFACE_STOP_DOWN = b"\xA5\x50\x09"
34
+ INTERFACE_STOP_UP = b"\xA5\x51\x09"
35
+ INTERFACE_RESET_DOWN = b"\xA5\x50\x5A"
36
+ INTERFACE_RESET_UP = b"\xA5\x51\x5A"
37
+ INTERFACE_TRACE_DOWN = b"\xA5\x50\x0F"
38
+ INTERFACE_TRACE_UP = b"\xA5\x51\x0F"
39
+ INTERFACE_ESCAPE_DOWN = b"\xA5\x50\x07"
40
+ INTERFACE_ESCAPE_UP = b"\xA5\x51\x07"
41
+ INTERFACE_LASER_GATE_DOWN = b"\xA5\x50\x12"
42
+ INTERFACE_LASER_GATE_UP = b"\xA5\x51\x12"
43
+ INTERFACE_ORIGIN_DOWN = b"\xA5\x50\x08"
44
+ INTERFACE_ORIGIN_UP = b"\xA5\x51\x08"
45
+ AXIS_X_MOVE = b"\x80\x00" # abscoord(x)
46
+ AXIS_Z_MOVE = b"\x80\x01" # abscoord(z),
47
+ MOVE_ABS_XY = b"\x88" # abscoord(x), abscoord(y)
48
+ MOVE_REL_XY = b"\x89" # relcoord(dx), relcoord(dy)
49
+ AXIS_A_MOVE = b"\xA0\x00" # abscoord(a)
50
+ AXIS_U_MOVE = b"\xA0\x08" # abscoord(u)
51
+ MOVE_REL_X = b"\x8A" # relcoord(dx)
52
+ MOVE_REL_Y = b"\x8B" # relcoord(dy)
53
+ CUT_ABS_XY = b"\xA8" # abscoord(x), abscoord(y)
54
+ CUT_REL_XY = b"\xA9" # relcoord(dx), relcoord(dy)
55
+ CUT_REL_X = b"\xAA" # relcoord(dx)
56
+ CUT_REL_Y = b"\xAB" # relcoord(dy)
57
+ IMD_POWER_1 = b"\xC7" # power(2)
58
+ IMD_POWER_2 = b"\xC0" # power(2)
59
+ IMD_POWER_3 = b"\xC2" # power(2)
60
+ IMD_POWER_4 = b"\xC3" # power(2)
61
+ END_POWER_1 = b"\xC8" # power(2)
62
+ END_POWER_2 = b"\xC1" # power(2)
63
+ END_POWER_3 = b"\xC4" # power(2)
64
+ END_POWER_4 = b"\xC5" # power(2)
65
+ MIN_POWER_1 = b"\xC6\x01" # power(2)
66
+ MAX_POWER_1 = b"\xC6\x02" # power(2)
67
+ MIN_POWER_2 = b"\xC6\x21" # power(2)
68
+ MAX_POWER_2 = b"\xC6\x22" # power(2)
69
+ MIN_POWER_3 = b"\xC6\x05" # power(2)
70
+ MAX_POWER_3 = b"\xC6\x06" # power(2)
71
+ MIN_POWER_4 = b"\xC6\x07" # power(2)
72
+ MAX_POWER_4 = b"\xC6\x08" # power(2)
73
+ LASER_INTERVAL = b"\xC6\x10" # time(5)
74
+ ADD_DELAY = b"\xC6\x11" # time(5)
75
+ LASER_ON_DELAY = b"\xC6\x12" # time(5)
76
+ LASER_OFF_DELAY = b"\xC6\x13" # time(5)
77
+ LASER_ON_DELAY2 = b"\xC6\x15" # time(5)
78
+ LASER_OFF_DELAY2 = b"\xC6\x16" # time(5)
79
+ MIN_POWER_1_PART = b"\xC6\x31" # part(1), power(2)
80
+ MAX_POWER_1_PART = b"\xC6\x32" # part(1), power(2)
81
+ MIN_POWER_2_PART = b"\xC6\x41" # part(1), power(2)
82
+ MAX_POWER_2_PART = b"\xC6\x42" # part(1), power(2)
83
+ MIN_POWER_3_PART = b"\xC6\x35" # part(1), power(2)
84
+ MAX_POWER_3_PART = b"\xC6\x36" # part(1), power(2
85
+ MIN_POWER_4_PART = b"\xC6\x37" # part(1), power(2)
86
+ MAX_POWER_4_PART = b"\xC6\x38" # part(1), power(2)
87
+ THROUGH_POWER_1 = b"\xC6\x50" # power(2)
88
+ THROUGH_POWER_2 = b"\xC6\x51" # power(2)
89
+ THROUGH_POWER_3 = b"\xC6\x55" # power(2)
90
+ THROUGH_POWER_4 = b"\xC6\x56" # power(2)
91
+ FREQUENCY_PART = b"\xC6\x60" # laser(1), part(1), frequency(5)
92
+ SPEED_LASER_1 = b"\xC9\x02" # speed(5)
93
+ SPEED_AXIS = b"\xC9\x03" # speed(5)
94
+ SPEED_LASER_1_PART = b"\xC9\x04" # part(1), speed(5)
95
+ FORCE_ENG_SPEED = b"\xC9\x05" # speed(5)
96
+ SPEED_AXIS_MOVE = b"\xC9\x06" # speed(5)
97
+ LAYER_END = b"\xCA\x01\x00"
98
+ WORK_MODE_1 = b"\xCA\x01\x01"
99
+ WORK_MODE_2 = b"\xCA\x01\x02"
100
+ WORK_MODE_3 = b"\xCA\x01\x03"
101
+ WORK_MODE_4 = b"\xCA\x01\x04"
102
+ WORK_MODE_5 = b"\xCA\x01\x55"
103
+ WORK_MODE_6 = b"\xCA\x01\x05"
104
+ LASER_DEVICE_0 = b"\xCA\x01\x10"
105
+ LASER_DEVICE_1 = b"\xCA\x01\x11"
106
+ AIR_ASSIST_OFF = b"\xCA\x01\x12"
107
+ AIR_ASSIST_ON = b"\xCA\x01\x13"
108
+ DB_HEAD = b"\xCA\x01\x14"
109
+ EN_LASER_2_OFFSET_0 = b"\xCA\x01\x30"
110
+ EN_LASER_2_OFFSET_1 = b"\xCA\x01\x31"
111
+ LAYER_NUMBER_PART = b"\xCA\x02" # part(1)
112
+ EN_LASER_TUBE_START = b"\xCA\x03" # part(1)
113
+ X_SIGN_MAP = b"\xCA\x04" # value(1)
114
+ LAYER_COLOR = b"\xCA\x05" # color(5)
115
+ LAYER_COLOR_PART = b"\xCA\x06" # part(1), color(5)
116
+ EN_EX_IO = b"\xCA\x10" # value(1)
117
+ MAX_LAYER_PART = b"\xCA\x22" # part(1)
118
+ U_FILE_ID = b"\xCA\x30" # file_number(2)
119
+ ZU_MAP = b"\xCA\x40" # value(1)
120
+ WORK_MODE_PART = b"\xCA\x41" # part(1), mode(1)
121
+ ACK = b"\xCC"
122
+ ERR = b"\xCD"
123
+ KEEP_ALIVE = b"\xCE"
124
+ END_OF_FILE = b"\xD7"
125
+ START_PROCESS = b"\xD8\x00"
126
+ STOP_PROCESS = b"\xD8\x01"
127
+ PAUSE_PROCESS = b"\xD8\x02"
128
+ RESTORE_PROCESS = b"\xD8\x03"
129
+ REF_POINT_2 = b"\xD8\x10" # MACHINE_ZERO/ABS POSITION
130
+ REF_POINT_1 = b"\xD8\x11" # ANCHOR_POINT
131
+ REF_POINT_0 = b"\xD8\x12" # CURRENT_POSITION
132
+ HOME_Z = b"\xD8\x2C"
133
+ HOME_U = b"\xD8\x2D"
134
+ HOME_XY = b"\xD8\x2A"
135
+ FOCUS_Z = b"\xD8\x2E"
136
+ KEYDOWN_X_LEFT = b"\xD8\x20"
137
+ KEYDOWN_X_RIGHT = b"\xD8\x21"
138
+ KEYDOWN_Y_TOP = b"\xD8\x22"
139
+ KEYDOWN_Y_BOTTOM = b"\xD8\x23"
140
+ KEYDOWN_Z_UP = b"\xD8\x24"
141
+ KEYDOWN_Z_DOWN = b"\xD8\x25"
142
+ KEYDOWN_U_FORWARD = b"\xD8\x26"
143
+ KEYDOWN_U_BACKWARDS = b"\xD8\x27"
144
+ KEYUP_X_LEFT = b"\xD8\x30"
145
+ KEYUP_X_RIGHT = b"\xD8\x31"
146
+ KEYUP_Y_TOP = b"\xD8\x32"
147
+ KEYUP_Y_BOTTOM = b"\xD8\x33"
148
+ KEYUP_Z_UP = b"\xD8\x34"
149
+ KEYUP_Z_DOWN = b"\xD8\x35"
150
+ KEYUP_U_FORWARD = b"\xD8\x36"
151
+ KEYUP_U_BACKWARDS = b"\xD8\x37"
152
+ RAPID_OPTION_LIGHT = b"\x03"
153
+ RAPID_OPTION_LIGHTORIGIN = b"\x01"
154
+ RAPID_OPTION_ORIGIN = b"\x00"
155
+ RAPID_OPTION_NONE = b"\x02"
156
+ RAPID_MOVE_X = b"\xD9\x00" # options(1), abscoord(5)
157
+ RAPID_MOVE_Y = b"\xD9\x01" # options(1), abscoord(5)
158
+ RAPID_MOVE_Z = b"\xD9\x02" # options(1), abscoord(5)
159
+ RAPID_MOVE_U = b"\xD9\x03" # options(1), abscoord(5)
160
+ RAPID_FEED_AXIS_MOVE = b"\xD9\x0F" # options(1)
161
+ RAPID_MOVE_XY = b"\xD9\x10" # options(1), abscoord(5), abscoord(5)
162
+ RAPID_MOVE_XYU = b"\xD9\x30" # options(1), abscoord(5), abscoord(5), abscoord(5)
163
+ GET_SETTING = b"\xDA\x00" # memory(2)
164
+ SET_SETTING = b"\xDA\x01" # memory(2), v0(5), v1(5)
165
+ DOCUMENT_FILE_UPLOAD = b"\xE5\x00" # file_number(2), v0(5), v1(5)
166
+ DOCUMENT_FILE_END = b"\xE5\x02"
167
+ SET_FILE_SUM = b"\xE5\x05"
168
+ SET_ABSOLUTE = b"\xE6\x01"
169
+ BLOCK_END = b"\xE7\x00"
170
+ SET_FILENAME = b"\xE7\x01" # filename (null terminated).
171
+ PROCESS_TOP_LEFT = b"\xE7\x03" # abscoord(5), abscoord(5)
172
+ PROCESS_REPEAT = b"\xE7\x04" # v0(2), v1(2), v2(2), v3(2), v4(2), v5(2), v6(2)
173
+ ARRAY_DIRECTION = b"\xE7\x05" # direction(1)
174
+ FEED_REPEAT = b"\xE7\x06" # v0(5), v1(5)
175
+ PROCESS_BOTTOM_RIGHT = b"\xE7\x07" # abscoord(5), abscoord(5)
176
+ ARRAY_REPEAT = b"\xE7\x08" # v0(2), v1(2), v2(2), v3(2), v4(2), v5(2), v6(2)
177
+ FEED_LENGTH = b"\xE7\x09" # value(5)
178
+ FEED_INFO = b"\xE7\x0A"
179
+ ARRAY_EN_MIRROR_CUT = b"\xE7\x0B" # value(1)
180
+ ARRAY_MIN_POINT = b"\xE7\x13" # abscoord(5), abscoord(5)
181
+ ARRAY_MAX_POINT = b"\xE7\x17" # abscoord(5), abscoord(5)
182
+ ARRAY_ADD = b"\xE7\x23" # abscoord(5), abscoord(5)
183
+ ARRAY_MIRROR = b"\xE7\x24" # mirror(1)
184
+ BLOCK_X_SIZE = b"\xE7\x35" # abscoord(5), abscoord(5)
185
+ BY_TEST = b"\xE7\x35" # 0x11227766
186
+ ARRAY_EVEN_DISTANCE = b"\xE7\x37"
187
+ SET_FEED_AUTO_PAUSE = b"\xE7\x38"
188
+ UNION_BLOCK_PROPERTY = b"\xE7\x3A"
189
+ DOCUMENT_MIN_POINT = b"\xE7\x50" # abscoord(5), abscoord(5)
190
+ DOCUMENT_MAX_POINT = b"\xE7\x51" # abscoord(5), abscoord(5)
191
+ PART_MIN_POINT = b"\xE7\x52" # part(1), abscoord(5), abscoord(5)
192
+ PART_MAX_POINT = b"\xE7\x53" # part(1), abscoord(5), abscoord(5)
193
+ PEN_OFFSET = b"\xE7\x54" # axis(1), coord(5)
194
+ LAYER_OFFSET = b"\xE7\x55" # axis(1), coord(5)
195
+ SET_CURRENT_ELEMENT_INDEX = b"\xE7\x60" # index(1)
196
+ PART_MIN_POINT_EX = b"\xE7\x61" # part(1), abscoord(5), abscoord(5)
197
+ PART_MAX_POINT_EX = b"\xE7\x62" # part(1), abscoord(5), abscoord(5)
198
+ ARRAY_START = b"\xEA" # index(1)
199
+ ARRAY_END = b"\xEB"
200
+ REF_POINT_SET = b"\xF0"
201
+ ELEMENT_MAX_INDEX = b"\xF1\x00" # index(1)
202
+ ELEMENT_NAME_MAX_INDEX = b"\xF1\x01" # index(1)
203
+ ENABLE_BLOCK_CUTTING = b"\xF1\x02" # enable(1)
204
+ DISPLAY_OFFSET = b"\xF1\x03" # abscoord(5), abscoord(5)
205
+ FEED_AUTO_CALC = b"\xF1\x04" # enable(1)
206
+ ELEMENT_INDEX = b"\xF2\x00" # index(1)
207
+ ELEMENT_NAME = b"\xF2\x02" # name(10)
208
+ ELEMENT_ARRAY_MIN_POINT = b"\xF2\x03" # abscoord(5), abscoord(5)
209
+ ELEMENT_ARRAY_MAX_POINT = b"\xF2\x04" # abscoord(5), abscoord(5)
210
+ ELEMENT_ARRAY = b"\xF2\x05" # v0(2), v1(2), v2(2), v3(2), v4(2), v5(2), v6(2)
211
+ ELEMENT_ARRAY_ADD = b"\xF2\x06" # abscoord(5), abscoord(5)
212
+ ELEMENT_ARRAY_MIRROR = b"\xF2\x07" # mirror(1)
213
+
214
+ MEM_CARD_ID = 0x02FE
215
+
216
+
217
+ def encode_part(part):
218
+ assert 0 <= part <= 255
219
+ return bytes([part])
220
+
221
+
222
+ def encode_index(index):
223
+ assert 0 <= index <= 255
224
+ return bytes([index])
225
+
226
+
227
+ def encode14(v):
228
+ v = int(v)
229
+ return bytes(
230
+ [
231
+ (v >> 7) & 0x7F,
232
+ v & 0x7F,
233
+ ]
234
+ )
235
+
236
+
237
+ def encode32(v):
238
+ v = int(v)
239
+ return bytes(
240
+ [
241
+ (v >> 28) & 0x7F,
242
+ (v >> 21) & 0x7F,
243
+ (v >> 14) & 0x7F,
244
+ (v >> 7) & 0x7F,
245
+ v & 0x7F,
246
+ ]
247
+ )
248
+
249
+
250
+ def encode_coord(coord):
251
+ return encode32(coord)
252
+
253
+
254
+ def encode_relcoord(coord):
255
+ return encode14(coord)
256
+
257
+
258
+ def encode_color(color):
259
+ return encode32(int(color))
260
+
261
+
262
+ def encode_file_number(file_number):
263
+ return encode14(file_number)
264
+
265
+
266
+ def encode_mem(file_number):
267
+ return encode14(file_number)
268
+
269
+
270
+ def encode_value(value):
271
+ return encode32(value)
272
+
273
+
274
+ def encode_power(power):
275
+ # 16384 / 100%
276
+ return encode14(power * 16383 / 100.0)
277
+
278
+
279
+ def encode_speed(speed):
280
+ # uM/sec
281
+ return encode32(speed * 1000)
282
+
283
+
284
+ def encode_time(time):
285
+ return encode32(time * 1000)
286
+
287
+
288
+ def encode_frequency(freq_hz):
289
+ return encode32(freq_hz)
290
+
291
+
292
+ def signed35(v):
293
+ v = int(v)
294
+ v &= 0x7FFFFFFFF
295
+ if v > 0x3FFFFFFFF:
296
+ return -0x800000000 + v
297
+ else:
298
+ return v
299
+
300
+
301
+ def signed32(v):
302
+ v = int(v)
303
+ v &= 0xFFFFFFFF
304
+ if v > 0x7FFFFFFF:
305
+ return -0x100000000 + v
306
+ else:
307
+ return v
308
+
309
+
310
+ def signed14(v):
311
+ v = int(v)
312
+ v &= 0x7FFF
313
+ if v > 0x1FFF:
314
+ return -0x4000 + v
315
+ else:
316
+ return v
317
+
318
+
319
+ def decode14(data):
320
+ return signed14(decodeu14(data))
321
+
322
+
323
+ def decodeu14(data):
324
+ return (data[0] & 0x7F) << 7 | (data[1] & 0x7F)
325
+
326
+
327
+ def decode35(data):
328
+ return signed35(decodeu35(data))
329
+
330
+
331
+ def decode32(data):
332
+ return signed32(decodeu35(data))
333
+
334
+
335
+ def decodeu35(data):
336
+ return (
337
+ (data[0] & 0x7F) << 28
338
+ | (data[1] & 0x7F) << 21
339
+ | (data[2] & 0x7F) << 14
340
+ | (data[3] & 0x7F) << 7
341
+ | (data[4] & 0x7F)
342
+ )
343
+
344
+
345
+ def abscoord(data):
346
+ return decode32(data)
347
+
348
+
349
+ def relcoord(data):
350
+ return decode14(data)
351
+
352
+
353
+ def parse_mem(data):
354
+ return decode14(data)
355
+
356
+
357
+ def parse_filenumber(data):
358
+ return decode14(data)
359
+
360
+
361
+ def parse_speed(data):
362
+ return decode35(data) / 1000.0
363
+
364
+
365
+ def parse_frequency(data):
366
+ return decodeu35(data)
367
+
368
+
369
+ def parse_power(data):
370
+ return decodeu14(data) / 163.84 # 16384 / 100%
371
+
372
+
373
+ def parse_time(data):
374
+ return decodeu35(data) / 1000.0
375
+
376
+
377
+ def parse_commands(data):
378
+ """
379
+ Parses data blob into command chunk sized pieces.
380
+ @param data:
381
+ @return:
382
+ """
383
+ mark = 0
384
+ for i, b in enumerate(data):
385
+ if b >= 0x80 and mark != i:
386
+ yield data[mark:i]
387
+ mark = i
388
+ if mark != len(data):
389
+ yield data[mark:]
390
+
391
+
392
+ def swizzle_byte(b, magic):
393
+ b ^= (b >> 7) & 0xFF
394
+ b ^= (b << 7) & 0xFF
395
+ b ^= (b >> 7) & 0xFF
396
+ b ^= magic
397
+ b = (b + 1) & 0xFF
398
+ return b
399
+
400
+
401
+ def unswizzle_byte(b, magic):
402
+ b = (b - 1) & 0xFF
403
+ b ^= magic
404
+ b ^= (b >> 7) & 0xFF
405
+ b ^= (b << 7) & 0xFF
406
+ b ^= (b >> 7) & 0xFF
407
+ return b
408
+
409
+
410
+ def swizzles_lut(magic):
411
+ if magic == -1:
412
+ lut = [s for s in range(256)]
413
+ return lut, lut
414
+ lut_swizzle = [swizzle_byte(s, magic) for s in range(256)]
415
+ lut_unswizzle = [unswizzle_byte(s, magic) for s in range(256)]
416
+ return lut_swizzle, lut_unswizzle
417
+
418
+
419
+ def decode_bytes(data, magic=0x88):
420
+ lut_swizzle, lut_unswizzle = swizzles_lut(magic)
421
+ array = list()
422
+ for b in data:
423
+ array.append(lut_unswizzle[b])
424
+ return bytes(array)
425
+
426
+
427
+ def determine_magic_via_histogram(data):
428
+ """
429
+ Determines magic number via histogram. The number which occurs most in RDWorks files is overwhelmingly 0. It's
430
+ about 50% of all data. The swizzle algorithm means that the swizzle for 0 is magic + 1, so we find the most
431
+ frequent number and subtract one from that and that is *most* likely the magic number.
432
+
433
+ @param data:
434
+ @return:
435
+ """
436
+ histogram = [0] * 256
437
+ prev = -1
438
+ for d in data:
439
+ histogram[d] += 5 if prev == d else 1
440
+ prev = d
441
+ m = 0
442
+ magic = None
443
+ for i in range(len(histogram)):
444
+ v = histogram[i]
445
+ if v > m:
446
+ m = v
447
+ magic = i - 1
448
+ return magic
449
+
450
+
451
+ def encode_bytes(data, magic=0x88):
452
+ lut_swizzle, lut_unswizzle = swizzles_lut(magic)
453
+ array = list()
454
+ for b in data:
455
+ array.append(lut_swizzle[b])
456
+ return bytes(array)
457
+
458
+
459
+ def magic_keys():
460
+ mk = dict()
461
+ for g in range(256):
462
+ mk[encode_bytes(b"\xda\x00\x05\x7E", magic=g)] = g
463
+ return mk
464
+
465
+
466
+ class RDJob:
467
+ def __init__(
468
+ self,
469
+ driver=None,
470
+ units_to_device_matrix=None,
471
+ priority=0,
472
+ channel=None,
473
+ magic=0x11,
474
+ ):
475
+ self.units_to_device_matrix = units_to_device_matrix
476
+ self._driver = driver
477
+ self.channel = channel
478
+ self.reply = None
479
+ self.buffer = list()
480
+ self.plotcut = None
481
+
482
+ self.priority = priority
483
+
484
+ self.time_submitted = time.time()
485
+ self.time_started = None
486
+ self.runtime = 0
487
+
488
+ self._stopped = True
489
+ self.enabled = True
490
+ self._estimate = 0
491
+
492
+ self.scale = UNITS_PER_uM
493
+
494
+ self.speed = None
495
+ self.power = None
496
+ self.frequency = None
497
+ self.power1_max = None
498
+ self.power1_min = None
499
+ self.power2_max = None
500
+ self.power2_min = None
501
+
502
+ self.color = None
503
+ # 0x11 for the 634XG
504
+ self.magic = magic
505
+ self.lut_swizzle, self.lut_unswizzle = swizzles_lut(self.magic)
506
+
507
+ self.x = 0.0
508
+ self.y = 0.0
509
+ self.z = 0.0
510
+ self.u = 0.0
511
+
512
+ self.a = 0.0
513
+ self.b = 0.0
514
+ self.c = 0.0
515
+ self.d = 0.0
516
+
517
+ self.lock = threading.Lock()
518
+
519
+ def __str__(self):
520
+ return f"{self.__class__.__name__}({len(self.buffer)} lines)"
521
+
522
+ def __call__(self, *args, output=None, swizzle=True):
523
+ e = b"".join(args)
524
+ if output is None:
525
+ self.write_command(e)
526
+ else:
527
+ if swizzle:
528
+ e = bytes([self.lut_swizzle[b] for b in e])
529
+ output(e)
530
+
531
+ @property
532
+ def status(self):
533
+ if self.is_running():
534
+ if self.time_started:
535
+ return "Running"
536
+ else:
537
+ return "Queued"
538
+ else:
539
+ if self.enabled:
540
+ return "Waiting"
541
+ else:
542
+ return "Disabled"
543
+
544
+ def clear(self):
545
+ self.buffer.clear()
546
+
547
+ def set_magic(self, magic):
548
+ """
549
+ Sets the magic number for blob decoding.
550
+
551
+ @param magic: magic number to unswizzling.
552
+ @return:
553
+ """
554
+ if magic is not None and magic != self.magic:
555
+ self.magic = magic
556
+ self.lut_swizzle, self.lut_unswizzle = swizzles_lut(self.magic)
557
+
558
+ def write_blob(self, data, magic=None):
559
+ """
560
+ Procedural commands sent in large data chunks. This can be through USB or UDP or a loaded file. These are
561
+ expected to be unswizzled with the swizzle_mode set for the reply. Write will parse out the individual commands
562
+ and send those to the command routine.
563
+
564
+ @param data:
565
+ @param magic: magic number for unswizzling
566
+ @return:
567
+ """
568
+ if magic is None:
569
+ magic = determine_magic_via_histogram(data)
570
+ self.set_magic(magic)
571
+ data = self.unswizzle(data)
572
+ with self.lock:
573
+ self.buffer.extend(parse_commands(data))
574
+
575
+ def write_command(self, command):
576
+ with self.lock:
577
+ self.buffer.append(command)
578
+
579
+ def file_sum(self):
580
+ return sum([sum(list(g)) for g in self.buffer])
581
+
582
+ def get_contents(self, first=None, last=None, swizzled=True):
583
+ data = b"".join(self.buffer[first:last])
584
+ if swizzled:
585
+ return self.swizzle(data)
586
+ return data
587
+
588
+ def execute(self, driver=None):
589
+ """
590
+ Execute calls each item in the list of items in order. This is intended to be called by the spooler thread. And
591
+ hold the spooler while these items are executing.
592
+ @return:
593
+ """
594
+ self._stopped = False
595
+ if self.time_started is None:
596
+ self.time_started = time.time()
597
+ with self.lock:
598
+ command = self.buffer.pop(0)
599
+ try:
600
+ array = list(command)
601
+ self.process(array)
602
+ except IndexError as e:
603
+ raise RuidaCommandError(
604
+ f"Could not process Ruida buffer, {self.buffer[:25]} with magic: {self.magic:02}"
605
+ ) from e
606
+ if not self.buffer:
607
+ # Buffer is empty now. Job is complete
608
+ self.runtime += time.time() - self.time_started
609
+ self._stopped = True
610
+ return True # All steps were executed.
611
+ return False
612
+
613
+ def stop(self):
614
+ """
615
+ Stop this current laser-job, cannot be called from the spooler thread.
616
+ @return:
617
+ """
618
+ if not self._stopped:
619
+ self.runtime += time.time() - self.time_started
620
+ self._stopped = True
621
+
622
+ def is_running(self):
623
+ return not self._stopped
624
+
625
+ def elapsed_time(self):
626
+ """
627
+ How long is this job already running...
628
+ """
629
+ if self.is_running():
630
+ return time.time() - self.time_started
631
+ else:
632
+ return self.runtime
633
+
634
+ def estimate_time(self):
635
+ """
636
+ Give laser job time estimate.
637
+ @return:
638
+ """
639
+ return self._estimate
640
+
641
+ def plot_location(self, x, y, power):
642
+ """
643
+ Adds this particular location to the current plotcut.
644
+
645
+ Or, starts a new plotcut if one is not already started.
646
+
647
+ First plotcut is a 0-power move to the current position. X and Y are set to plotted location
648
+
649
+ @param x:
650
+ @param y:
651
+ @param power:
652
+ @return:
653
+ """
654
+ matrix = self.units_to_device_matrix
655
+ if matrix is None:
656
+ # Using job for something other than point plotting
657
+ return
658
+ if self.plotcut is None:
659
+ self.x = x
660
+ self.y = y
661
+ ox, oy = matrix.transform_point([self.x, self.y])
662
+ self.plotcut = PlotCut(
663
+ settings={
664
+ "speed": self.speed,
665
+ "power": self.power,
666
+ "frequency": self.frequency,
667
+ }
668
+ )
669
+ self.plotcut.plot_init(int(round(ox)), int(round(oy)))
670
+ tx, ty = matrix.transform_point([x, y])
671
+ self.plotcut.plot_append(
672
+ int(round(tx)), int(round(ty)), power * (self.power / 1000.0)
673
+ )
674
+ self.x = x
675
+ self.y = y
676
+
677
+ def plot_commit(self):
678
+ """
679
+ Force commits the old plotcut and unsets the current plotcut.
680
+
681
+ @return:
682
+ """
683
+ if self.plotcut is None:
684
+ return
685
+ self.plot(self.plotcut)
686
+ self.plotcut = None
687
+
688
+ def plot(self, plot):
689
+ try:
690
+ self._driver.plot(plot)
691
+ except AttributeError:
692
+ pass
693
+
694
+ def __repr__(self):
695
+ return f"RuidaEmulator(@{hex(id(self))})"
696
+
697
+ @property
698
+ def current(self):
699
+ return self.x, self.y
700
+
701
+ def set_color(self, color):
702
+ self.color = color
703
+
704
+ def process(self, array):
705
+ """
706
+ Parses an individual unswizzled ruida command, updating the emulator state.
707
+
708
+ These commands can change the position, settings, speed, color, power, create elements.
709
+ @param array:
710
+ @return:
711
+ """
712
+ desc = ""
713
+ if array[0] < 0x80:
714
+ if self.channel:
715
+ self.channel(f"NOT A COMMAND: {array[0]}")
716
+ raise RuidaCommandError("Not a command.")
717
+ elif array[0] == 0x80:
718
+ value = abscoord(array[2:7])
719
+ if array[1] == 0x00:
720
+ desc = f"Axis X Move {value}"
721
+ self.x += value
722
+ elif array[1] == 0x08:
723
+ desc = f"Axis Z Move {value}"
724
+ self.z += value
725
+ elif array[0] == 0x88: # 0b10001000 11 characters.
726
+ x = abscoord(array[1:6])
727
+ y = abscoord(array[6:11])
728
+ self.plot_location(x * self.scale, y * self.scale, 0)
729
+ desc = f"Move Absolute ({x}μm, {y}μm)"
730
+ elif array[0] == 0x89: # 0b10001001 5 characters
731
+ if len(array) > 1:
732
+ dx = relcoord(array[1:3])
733
+ dy = relcoord(array[3:5])
734
+ self.plot_location(
735
+ self.x + dx * self.scale, self.y + dy * self.scale, 0
736
+ )
737
+ desc = f"Move Relative ({dx:+}μm, {dy:+}μm)"
738
+ else:
739
+ desc = "Move Relative (no coords)"
740
+ elif array[0] == 0x8A: # 0b10101010 3 characters
741
+ dx = relcoord(array[1:3])
742
+ self.plot_location(self.x + dx * self.scale, self.y, 0)
743
+ desc = f"Move Horizontal Relative ({dx:+}μm)"
744
+ elif array[0] == 0x8B: # 0b10101011 3 characters
745
+ dy = relcoord(array[1:3])
746
+ self.plot_location(self.x, self.y + dy * self.scale, 0)
747
+ desc = f"Move Vertical Relative ({dy:+}μm)"
748
+ elif array[0] == 0xA0:
749
+ value = abscoord(array[2:7])
750
+ if array[1] == 0x00:
751
+ desc = f"Axis Y Move {value}"
752
+ elif array[1] == 0x08:
753
+ desc = f"Axis U Move {value}"
754
+ elif array[0] == 0xA8: # 0b10101000 11 characters.
755
+ x = abscoord(array[1:6])
756
+ y = abscoord(array[6:11])
757
+ self.plot_location(x * self.scale, y * self.scale, 1)
758
+ desc = f"Cut Absolute ({x}μm, {y}μm)"
759
+ elif array[0] == 0xA9: # 0b10101001 5 characters
760
+ dx = relcoord(array[1:3])
761
+ dy = relcoord(array[3:5])
762
+ self.plot_location(self.x + dx * self.scale, self.y + dy * self.scale, 1)
763
+ desc = f"Cut Relative ({dx:+}μm, {dy:+}μm)"
764
+ elif array[0] == 0xAA: # 0b10101010 3 characters
765
+ dx = relcoord(array[1:3])
766
+ self.plot_location(self.x + dx * self.scale, self.y, 1)
767
+ desc = f"Cut Horizontal Relative ({dx:+}μm)"
768
+ elif array[0] == 0xAB: # 0b10101011 3 characters
769
+ dy = relcoord(array[1:3])
770
+ self.plot_location(self.x, self.y + dy * self.scale, 1)
771
+ desc = f"Cut Vertical Relative ({dy:+}μm)"
772
+ elif array[0] == 0xC7:
773
+ try:
774
+ v0 = parse_power(array[1:3])
775
+ except IndexError:
776
+ v0 = 0
777
+ desc = f"Imd Power 1 ({v0})"
778
+ elif array[0] == 0xC2:
779
+ v0 = parse_power(array[1:3])
780
+ desc = f"Imd Power 3 ({v0})"
781
+ elif array[0] == 0xC0:
782
+ v0 = parse_power(array[1:3])
783
+ desc = f"Imd Power 2 ({v0})"
784
+ elif array[0] == 0xC3:
785
+ v0 = parse_power(array[1:3])
786
+ desc = f"Imd Power 4 ({v0})"
787
+ elif array[0] == 0xC8:
788
+ v0 = parse_power(array[1:3])
789
+ desc = f"End Power 1 ({v0})"
790
+ elif array[0] == 0xC4:
791
+ v0 = parse_power(array[1:3])
792
+ desc = f"End Power 3 ({v0})"
793
+ elif array[0] == 0xC1:
794
+ v0 = parse_power(array[1:3])
795
+ desc = f"End Power 2 ({v0})"
796
+ elif array[0] == 0xC5:
797
+ v0 = parse_power(array[1:3])
798
+ desc = f"End Power 4 ({v0})"
799
+ elif array[0] == 0xC6:
800
+ if array[1] == 0x01:
801
+ power = parse_power(array[2:4])
802
+ self.power1_min = power
803
+ power = self.power1_min
804
+ desc = f"Power 1 min={power}"
805
+ self.power = power * 10 # 1000 / 100
806
+ elif array[1] == 0x02:
807
+ power = parse_power(array[2:4])
808
+ self.power1_max = power
809
+ power = self.power1_max
810
+ desc = f"Power 1 max={power}"
811
+ self.power = power * 10 # 1000 / 100
812
+ elif array[1] == 0x05:
813
+ power = parse_power(array[2:4])
814
+ desc = f"Power 3 min={power}"
815
+ elif array[1] == 0x06:
816
+ power = parse_power(array[2:4])
817
+ desc = f"Power 3 max={power}"
818
+ elif array[1] == 0x07:
819
+ power = parse_power(array[2:4])
820
+ desc = f"Power 4 min={power}"
821
+ elif array[1] == 0x08:
822
+ power = parse_power(array[2:4])
823
+ desc = f"Power 4 max={power}"
824
+ elif array[1] == 0x10:
825
+ interval = parse_time(array[2:7])
826
+ desc = f"Laser Interval {interval}ms"
827
+ elif array[1] == 0x11:
828
+ interval = parse_time(array[2:7])
829
+ desc = f"Add Delay {interval}ms"
830
+ elif array[1] == 0x12:
831
+ interval = parse_time(array[2:7])
832
+ desc = f"Laser On Delay {interval}ms"
833
+ elif array[1] == 0x13:
834
+ interval = parse_time(array[2:7])
835
+ desc = f"Laser Off Delay {interval}ms"
836
+ elif array[1] == 0x15:
837
+ interval = parse_time(array[2:7])
838
+ desc = f"Laser On2 {interval}ms"
839
+ elif array[1] == 0x16:
840
+ interval = parse_time(array[2:7])
841
+ desc = f"Laser Off2 {interval}ms"
842
+ elif array[1] == 0x21:
843
+ power = parse_power(array[2:4])
844
+ desc = f"Power 2 min={power}"
845
+ self.power2_min = power
846
+ elif array[1] == 0x22:
847
+ power = parse_power(array[2:4])
848
+ desc = f"Power 2 max={power}"
849
+ self.power2_max = power
850
+ elif array[1] == 0x31:
851
+ part = array[2]
852
+ self.power1_min = parse_power(array[3:5])
853
+ desc = f"{part}, Power 1 Min=({self.power1_min})"
854
+ elif array[1] == 0x32:
855
+ part = array[2]
856
+ self.power1_max = parse_power(array[3:5])
857
+ desc = f"{part}, Power 1 Max=({self.power1_max})"
858
+ elif array[1] == 0x35:
859
+ part = array[2]
860
+ power = parse_power(array[3:5])
861
+ desc = f"{part}, Power 3 Min ({power})"
862
+ elif array[1] == 0x36:
863
+ part = array[2]
864
+ power = parse_power(array[3:5])
865
+ desc = f"{part}, Power 3 Max ({power})"
866
+ elif array[1] == 0x37:
867
+ part = array[2]
868
+ power = parse_power(array[3:5])
869
+ desc = f"{part}, Power 4 Min ({power})"
870
+ elif array[1] == 0x38:
871
+ part = array[2]
872
+ power = parse_power(array[3:5])
873
+ desc = f"{part}, Power 4 Max ({power})"
874
+ elif array[1] == 0x41:
875
+ part = array[2]
876
+ power = parse_power(array[3:5])
877
+ desc = f"{part}, Power 2 Min ({power})"
878
+ elif array[1] == 0x42:
879
+ part = array[2]
880
+ power = parse_power(array[3:5])
881
+ desc = f"{part}, Power 2 Max ({power})"
882
+ elif array[1] == 0x50:
883
+ power = parse_power(array[2:4])
884
+ desc = f"Through Power 1 ({power})"
885
+ elif array[1] == 0x51:
886
+ power = parse_power(array[2:4])
887
+ desc = f"Through Power 2 ({power})"
888
+ elif array[1] == 0x55:
889
+ power = parse_power(array[2:4])
890
+ desc = f"Through Power 3 ({power})"
891
+ elif array[1] == 0x56:
892
+ power = parse_power(array[2:4])
893
+ desc = f"Through Power 4 ({power})"
894
+ elif array[1] == 0x60:
895
+ laser = array[2]
896
+ part = array[3]
897
+ frequency = parse_frequency(array[4:9])
898
+ desc = f"{part}, Laser {laser}, Frequency ({frequency})"
899
+ if frequency != self.frequency:
900
+ self.frequency = frequency
901
+ elif array[0] == 0xC9:
902
+ if array[1] == 0x02:
903
+ self.plot_commit()
904
+ speed = parse_speed(array[2:7])
905
+ if speed != self.speed:
906
+ self.speed = speed
907
+ desc = f"Speed Laser 1 {speed}mm/s"
908
+ elif array[1] == 0x03:
909
+ speed = parse_speed(array[2:7])
910
+ desc = f"Axis Speed {speed}mm/s"
911
+ elif array[1] == 0x04:
912
+ self.plot_commit()
913
+ part = array[2]
914
+ speed = parse_speed(array[3:8])
915
+ if speed != self.speed:
916
+ self.speed = speed
917
+ desc = f"{part}, Speed {speed}mm/s"
918
+ elif array[1] == 0x05:
919
+ speed = parse_speed(array[2:7]) / 1000.0
920
+ desc = f"Force Eng Speed {speed}mm/s"
921
+ elif array[1] == 0x06:
922
+ speed = parse_speed(array[2:7]) / 1000.0
923
+ desc = f"Axis Move Speed {speed}mm/s"
924
+ elif array[0] == 0xCA:
925
+ if array[1] == 0x01:
926
+ if array[2] == 0x00:
927
+ desc = "End Layer"
928
+ elif array[2] == 0x01:
929
+ desc = "Work Mode 1"
930
+ elif array[2] == 0x02:
931
+ desc = "Work Mode 2"
932
+ elif array[2] == 0x03:
933
+ desc = "Work Mode 3"
934
+ elif array[2] == 0x04:
935
+ desc = "Work Mode 4"
936
+ elif array[2] == 0x55:
937
+ desc = "Work Mode 5"
938
+ elif array[2] == 0x05:
939
+ desc = "Work Mode 6"
940
+ elif array[2] == 0x10:
941
+ desc = "Layer Device 0"
942
+ elif array[2] == 0x11:
943
+ desc = "Layer Device 1"
944
+ elif array[2] == 0x12:
945
+ desc = "Air Assist Off"
946
+ elif array[2] == 0x13:
947
+ desc = "Air Assist On"
948
+ elif array[2] == 0x14:
949
+ desc = "DbHead"
950
+ elif array[2] == 0x30:
951
+ desc = "EnLaser2Offset 0"
952
+ elif array[2] == 0x31:
953
+ desc = "EnLaser2Offset 1"
954
+ elif array[1] == 0x02:
955
+ part = array[2]
956
+ desc = f"{part}, Layer Number"
957
+ elif array[1] == 0x03:
958
+ desc = "EnLaserTube Start"
959
+ elif array[1] == 0x04:
960
+ value = array[2]
961
+ desc = f"X Sign Map {value}"
962
+ elif array[1] == 0x05:
963
+ self.plot_commit()
964
+ c = decodeu35(array[2:7])
965
+ r = c & 0xFF
966
+ g = (c >> 8) & 0xFF
967
+ b = (c >> 16) & 0xFF
968
+ c = Color(red=r, blue=b, green=g)
969
+ self.set_color(c.hex)
970
+ desc = f"Layer Color {str(self.color)}"
971
+ elif array[1] == 0x06:
972
+ part = array[2]
973
+ c = decodeu35(array[3:8])
974
+ r = c & 0xFF
975
+ g = (c >> 8) & 0xFF
976
+ b = (c >> 16) & 0xFF
977
+ c = Color(red=r, blue=b, green=g)
978
+ self.set_color(c.hex)
979
+ desc = f"{part}, Color {self.color}"
980
+ elif array[1] == 0x10:
981
+ value = array[2]
982
+ desc = f"EnExIO Start {value}"
983
+ elif array[1] == 0x22:
984
+ part = array[2]
985
+ desc = f"{part}, Max Layer"
986
+ elif array[1] == 0x30:
987
+ filenumber = parse_filenumber(array[2:4])
988
+ desc = f"U File ID {filenumber}"
989
+ elif array[1] == 0x40:
990
+ value = array[2]
991
+ desc = f"ZU Map {value}"
992
+ elif array[1] == 0x41:
993
+ part = array[2]
994
+ mode = array[3]
995
+ desc = f"{part}, Work Mode {mode}"
996
+ elif array[0] == 0xCC:
997
+ desc = "ACK from machine"
998
+ elif array[0] == 0xCD:
999
+ desc = "ERR from machine"
1000
+ elif array[0] == 0xCE:
1001
+ desc = "Keep Alive"
1002
+ elif array[0] == 0xD0:
1003
+ zone = array[1]
1004
+ desc = f"Set Inhale Zone {zone}"
1005
+ elif array[0] == 0xD7:
1006
+ self.plot_commit()
1007
+ try:
1008
+ self._driver.plot_start()
1009
+ except AttributeError:
1010
+ pass
1011
+ desc = "End Of File"
1012
+ elif array[0] == 0xD8:
1013
+ if array[1] == 0x00:
1014
+ desc = "Start Process"
1015
+ if array[1] == 0x10:
1016
+ desc = "Ref Point Mode 2, Machine Zero/Absolute Position"
1017
+ if array[1] == 0x11:
1018
+ desc = "Ref Point Mode 1, Anchor Point"
1019
+ if array[1] == 0x12:
1020
+ desc = "Ref Point Mode 0, Current Position"
1021
+ elif array[0] == 0xDA:
1022
+ mem = parse_mem(array[2:4])
1023
+ if array[1] == 0x01:
1024
+ value0 = array[4:9]
1025
+ value1 = array[9:14]
1026
+ v0 = decodeu35(value0)
1027
+ v1 = decodeu35(value1)
1028
+ desc = f"Set {array[2]:02x} {array[3]:02x} (mem: {mem:04x})= {v0} (0x{v0:08x}) {v1} (0x{v1:08x})"
1029
+ elif array[0] == 0xE5: # 0xE502
1030
+ if array[1] == 0x00:
1031
+ # RDWorks File Upload
1032
+ filenumber = array[2]
1033
+ desc = f"Document Page Number {filenumber}"
1034
+ # TODO: Requires Response.
1035
+ if array[1] == 0x02:
1036
+ # len 3
1037
+ desc = "Document Data End"
1038
+ elif array[1] == 0x05:
1039
+ _sum = decodeu35(array[2:7])
1040
+ desc = f"Set File Sum {_sum}"
1041
+
1042
+ elif array[0] == 0xE6:
1043
+ if array[1] == 0x01:
1044
+ desc = "Set Absolute"
1045
+ # Only seen in Absolute Coords. MachineZero is Ref2 but does not Set Absolute.
1046
+ elif array[0] == 0xE7:
1047
+ if array[1] == 0x00:
1048
+ self.plot_commit()
1049
+ desc = "Block End"
1050
+ elif array[1] == 0x01:
1051
+ pass # Set filename for job (only realtime, see emulator)
1052
+ elif array[1] == 0x03:
1053
+ c_x = abscoord(array[2:7])
1054
+ c_y = abscoord(array[7:12])
1055
+ desc = f"Process TopLeft ({c_x}μm, {c_y}μm)"
1056
+ elif array[1] == 0x04:
1057
+ v0 = decode14(array[2:4])
1058
+ v1 = decode14(array[4:6])
1059
+ v2 = decode14(array[6:8])
1060
+ v3 = decode14(array[8:10])
1061
+ v4 = decode14(array[10:12])
1062
+ v5 = decode14(array[12:14])
1063
+ v6 = decode14(array[14:16])
1064
+ desc = f"Process Repeat ({v0}, {v1}, {v2}, {v3}, {v4}, {v5}, {v6})"
1065
+ elif array[1] == 0x05:
1066
+ direction = array[2]
1067
+ desc = f"Array Direction ({direction})"
1068
+ elif array[1] == 0x06:
1069
+ v1 = decodeu35(array[2:7])
1070
+ v2 = decodeu35(array[7:12])
1071
+ desc = f"Feed Repeat ({v1}, {v2})"
1072
+ elif array[1] == 0x07:
1073
+ c_x = abscoord(array[2:7])
1074
+ c_y = abscoord(array[7:12])
1075
+ desc = f"Process BottomRight({c_x}μm, {c_y}μm)"
1076
+ elif array[1] == 0x08: # Same value given to F2 04
1077
+ v0 = decode14(array[2:4])
1078
+ v1 = decode14(array[4:6])
1079
+ v2 = decode14(array[6:8])
1080
+ v3 = decode14(array[8:10])
1081
+ v4 = decode14(array[10:12])
1082
+ v5 = decode14(array[12:14])
1083
+ v6 = decode14(array[14:16])
1084
+ desc = f"Array Repeat ({v0}, {v1}, {v2}, {v3}, {v4}, {v5}, {v6})"
1085
+ elif array[1] == 0x09:
1086
+ v1 = decodeu35(array[2:7])
1087
+ desc = f"Feed Length {v1}"
1088
+ elif array[1] == 0x0A:
1089
+ desc = f"Feed Info"
1090
+ elif array[1] == 0x0B:
1091
+ v1 = array[2]
1092
+ desc = f"Array En Mirror Cut {v1}"
1093
+ elif array[1] == 0x0C:
1094
+ v1 = array[2]
1095
+ desc = f"Array Mirror Cut Distance {v1}"
1096
+ elif array[1] == 0x0C:
1097
+ v1 = array[2]
1098
+ desc = f"Set File Head Distance {v1}"
1099
+ elif array[1] == 0x13:
1100
+ c_x = abscoord(array[2:7])
1101
+ c_y = abscoord(array[7:12])
1102
+ desc = f"Array Min Point ({c_x}μm, {c_y}μm)"
1103
+ elif array[1] == 0x17:
1104
+ c_x = abscoord(array[2:7])
1105
+ c_y = abscoord(array[7:12])
1106
+ desc = f"Array Max Point ({c_x}μm, {c_y}μm)"
1107
+ elif array[1] == 0x23:
1108
+ c_x = abscoord(array[2:7])
1109
+ c_y = abscoord(array[7:12])
1110
+ desc = f"Array Add ({c_x}μm, {c_y}μm)"
1111
+ elif array[1] == 0x24:
1112
+ v1 = array[2]
1113
+ desc = f"Array Mirror {v1}"
1114
+ elif array[1] == 0x32:
1115
+ v1 = decodeu35(array[2:7])
1116
+ desc = f"Set Tick Count {v1}"
1117
+ elif array[1] == 0x35:
1118
+ v1 = decodeu35(array[2:7])
1119
+ v2 = decodeu35(array[7:12])
1120
+ desc = f"Block X Size {v1} {v2}"
1121
+ elif array[1] == 0x32:
1122
+ desc = f"Set File Empty"
1123
+ elif array[1] == 0x37:
1124
+ v1 = abscoord(array[2:7])
1125
+ v2 = abscoord(array[7:12])
1126
+ desc = f"Array Even Distance {v1} {v2}"
1127
+ elif array[1] == 0x38:
1128
+ v1 = array[2]
1129
+ desc = f"Set Feed Auto Pause {v1}"
1130
+ elif array[1] == 0x3A:
1131
+ desc = f"Union Block Property"
1132
+ elif array[1] == 0x3B:
1133
+ v1 = array[2]
1134
+ desc = f"Set File Property {v1}"
1135
+ elif array[1] == 0x46:
1136
+ desc = "BY Test 0x11227766"
1137
+ elif array[1] == 0x50:
1138
+ c_x = abscoord(array[1:6])
1139
+ c_y = abscoord(array[6:11])
1140
+ desc = f"Document Min Point({c_x}μm, {c_y}μm)"
1141
+ elif array[1] == 0x51:
1142
+ c_x = abscoord(array[2:7])
1143
+ c_y = abscoord(array[7:12])
1144
+ desc = f"Document Max Point({c_x}μm, {c_y}μm)"
1145
+ elif array[1] == 0x52:
1146
+ part = array[2]
1147
+ c_x = abscoord(array[3:8])
1148
+ c_y = abscoord(array[8:13])
1149
+ desc = f"{part}, Min Point({c_x}μm, {c_y}μm)"
1150
+ elif array[1] == 0x53:
1151
+ part = array[2]
1152
+ c_x = abscoord(array[3:8])
1153
+ c_y = abscoord(array[8:13])
1154
+ desc = f"{part}, MaxPoint({c_x}μm, {c_y}μm)"
1155
+ elif array[1] == 0x54:
1156
+ axis = array[2]
1157
+ c_x = abscoord(array[3:8])
1158
+ desc = f"Pen Offset {axis}: {c_x}μm"
1159
+ elif array[1] == 0x55:
1160
+ axis = array[2]
1161
+ c_x = abscoord(array[3:8])
1162
+ desc = f"Layer Offset {axis}: {c_x}μm"
1163
+ elif array[1] == 0x57:
1164
+ desc = f"PList Feed"
1165
+ elif array[1] == 0x60:
1166
+ desc = f"Set Current Element Index ({array[2]})"
1167
+ elif array[1] == 0x61:
1168
+ part = array[2]
1169
+ c_x = abscoord(array[3:8])
1170
+ c_y = abscoord(array[8:13])
1171
+ desc = f"{part}, MinPointEx({c_x}μm, {c_y}μm)"
1172
+ elif array[1] == 0x62:
1173
+ part = array[2]
1174
+ c_x = abscoord(array[3:8])
1175
+ c_y = abscoord(array[8:13])
1176
+ desc = f"{part}, MaxPointEx({c_x}μm, {c_y}μm)"
1177
+ elif array[0] == 0xE8:
1178
+ # Realtime command.
1179
+ pass
1180
+ elif array[0] == 0xEA:
1181
+ index = array[1]
1182
+ desc = f"Array Start ({index})"
1183
+ elif array[0] == 0xEB:
1184
+ desc = "Array End"
1185
+ elif array[0] == 0xF0:
1186
+ desc = "Ref Point Set"
1187
+ elif array[0] == 0xF1:
1188
+ if array[1] == 0x00:
1189
+ index = array[2]
1190
+ desc = f"Element Max Index ({index})"
1191
+ elif array[1] == 0x01:
1192
+ index = array[2]
1193
+ desc = f"Element Name Max Index({index})"
1194
+ elif array[1] == 0x02:
1195
+ enable = array[2]
1196
+ desc = f"Enable Block Cutting ({enable})"
1197
+ elif array[1] == 0x03:
1198
+ c_x = abscoord(array[2:7])
1199
+ c_y = abscoord(array[7:12])
1200
+ desc = f"Display Offset ({c_x}μm, {c_y}μm)"
1201
+ elif array[1] == 0x04:
1202
+ enable = array[2]
1203
+ desc = f"Feed Auto Calc ({enable})"
1204
+ elif array[1] == 0x20:
1205
+ desc = f"Unknown ({array[2]},{array[3]})"
1206
+ elif array[0] == 0xF2:
1207
+ if array[1] == 0x00:
1208
+ index = array[2]
1209
+ desc = f"Element Index ({index})"
1210
+ if array[1] == 0x01:
1211
+ index = array[2]
1212
+ desc = f"Element Name Index ({index})"
1213
+ if array[1] == 0x02:
1214
+ name = bytes(array[2:12])
1215
+ desc = f"Element Name ({str(name)})"
1216
+ if array[1] == 0x03:
1217
+ c_x = abscoord(array[2:7])
1218
+ c_y = abscoord(array[7:12])
1219
+ desc = f"Element Array Min Point ({c_x}μm, {c_y}μm)"
1220
+ if array[1] == 0x04:
1221
+ c_x = abscoord(array[2:7])
1222
+ c_y = abscoord(array[7:12])
1223
+ desc = f"Element Array Max Point ({c_x}μm, {c_y}μm)"
1224
+ if array[1] == 0x05:
1225
+ v0 = decode14(array[2:4])
1226
+ v1 = decode14(array[4:6])
1227
+ v2 = decode14(array[6:8])
1228
+ v3 = decode14(array[8:10])
1229
+ v4 = decode14(array[10:12])
1230
+ v5 = decode14(array[12:14])
1231
+ v6 = decode14(array[14:16])
1232
+ desc = f"Element Array ({v0}, {v1}, {v2}, {v3}, {v4}, {v5}, {v6})"
1233
+ if array[1] == 0x06:
1234
+ c_x = abscoord(array[2:7])
1235
+ c_y = abscoord(array[7:12])
1236
+ desc = f"Element Array Add ({c_x}μm, {c_y}μm)"
1237
+ if array[1] == 0x07:
1238
+ index = array[2]
1239
+ desc = f"Element Array Mirror ({index})"
1240
+ else:
1241
+ desc = "Unknown Command!"
1242
+ if self.channel:
1243
+ self.channel(f"-**-> {str(bytes(array).hex())}\t({desc})")
1244
+
1245
+ def unswizzle(self, data):
1246
+ return bytes([self.lut_unswizzle[b] for b in data])
1247
+
1248
+ def swizzle(self, data):
1249
+ return bytes([self.lut_swizzle[b] for b in data])
1250
+
1251
+ def _calculate_layer_bounds(self, layer):
1252
+ max_x = float("-inf")
1253
+ max_y = float("-inf")
1254
+ min_x = float("inf")
1255
+ min_y = float("inf")
1256
+ for item in layer:
1257
+ try:
1258
+ ny = item.upper()
1259
+ nx = item.left()
1260
+
1261
+ my = item.lower()
1262
+ mx = item.right()
1263
+ except AttributeError:
1264
+ continue
1265
+
1266
+ if mx > max_x:
1267
+ max_x = mx
1268
+ if my > max_y:
1269
+ max_y = my
1270
+ if nx < min_x:
1271
+ min_x = nx
1272
+ if ny < min_y:
1273
+ min_y = ny
1274
+ return min_x, min_y, max_x, max_y
1275
+
1276
+ def write_header(self, data):
1277
+ if not data:
1278
+ return
1279
+ # Optional: Set Tick count.
1280
+ self.ref_point_2() # abs_pos
1281
+ self.set_absolute()
1282
+ self.ref_point_set()
1283
+ self.enable_block_cutting(0)
1284
+ # Optional: Set File Property 1
1285
+ self.start_process()
1286
+ self.feed_repeat(0, 0)
1287
+ self.set_feed_auto_pause(0)
1288
+ b = self._calculate_layer_bounds(data)
1289
+ min_x, min_y, max_x, max_y = b
1290
+ self.process_top_left(min_x, min_y)
1291
+ self.process_bottom_right(max_x, max_y)
1292
+ self.document_min_point(0, 0) # Unknown
1293
+ self.document_max_point(max_x, max_y)
1294
+ self.process_repeat(1, 1, 0, 0, 0, 0, 0)
1295
+ self.array_direction(0)
1296
+ last_settings = None
1297
+ layers = list()
1298
+
1299
+ # Sort out data by layers.
1300
+ for item in data:
1301
+ if not hasattr(item, "settings"):
1302
+ continue
1303
+ current_settings = item.settings
1304
+ if last_settings is not current_settings:
1305
+ if "part" not in current_settings:
1306
+ current_settings["part"] = len(layers)
1307
+ layers.append(list())
1308
+ layers[current_settings["part"]].append(item)
1309
+
1310
+ part = 0
1311
+ # Write layer Information
1312
+ for layer in layers:
1313
+ (
1314
+ layer_min_x,
1315
+ layer_min_y,
1316
+ layer_max_x,
1317
+ layer_max_y,
1318
+ ) = self._calculate_layer_bounds(layer)
1319
+ current_settings = layer[0].settings
1320
+
1321
+ # Current Settings is New.
1322
+ part = current_settings.get("part", 0)
1323
+ speed = current_settings.get("speed", 10)
1324
+ power = current_settings.get("power", 1000) / 10.0
1325
+ color = current_settings.get("line_color", 0)
1326
+ frequency = current_settings.get("frequency")
1327
+
1328
+ self.speed_laser_1_part(part, speed)
1329
+ if frequency:
1330
+ self.frequency_part(0, part, frequency)
1331
+ self.min_power_1_part(part, power)
1332
+ self.max_power_1_part(part, power)
1333
+ self.min_power_2_part(part, power)
1334
+ self.max_power_2_part(part, power)
1335
+ self.layer_color_part(part, color)
1336
+ self.work_mode_part(part, 0)
1337
+ self.part_min_point(part, layer_min_x, layer_min_y)
1338
+ self.part_max_point(part, layer_max_x, layer_max_y)
1339
+ self.part_min_point_ex(part, layer_min_x, layer_min_y)
1340
+ self.part_max_point_ex(part, layer_max_x, layer_max_y)
1341
+ self.max_layer_part(part)
1342
+ self.pen_offset(0, 0)
1343
+ self.pen_offset(1, 0)
1344
+ self.layer_offset(0, 0)
1345
+ self.layer_offset(1, 0)
1346
+ self.display_offset(0, 0)
1347
+
1348
+ # Element Info
1349
+ # self.encoder.element_max_index(0)
1350
+ # self.encoder.element_name_max_index(0)
1351
+ # self.encoder.element_index(0)
1352
+ # self.encoder.element_name_max_index(0)
1353
+ # self.encoder.element_name('\x05*9\x1cA\x04j\x15\x08 ')
1354
+ # self.encoder.element_array_min_point(min_x, min_y)
1355
+ # self.encoder.element_array_max_point(max_x, max_y)
1356
+ # self.encoder.element_array(1, 1, 0, 257, -3072, 2, 5232)
1357
+ # self.encoder.element_array_add(0,0)
1358
+ # self.encoder.element_array_mirror(0)
1359
+
1360
+ self.feed_info(0)
1361
+
1362
+ # Array Info
1363
+ array_index = 0
1364
+ self.array_start(array_index)
1365
+ self.set_current_element_index(array_index)
1366
+ self.array_en_mirror_cut(array_index)
1367
+ self.array_min_point(min_x, min_y)
1368
+ self.array_max_point(max_x, max_y)
1369
+ self.array_add(0, 0)
1370
+ self.array_mirror(0)
1371
+ # self.encoder.array_even_distance(0) # Unknown.
1372
+ self.array_repeat(1, 1, 0, 1123, -3328, 4, 3480) # Unknown.
1373
+ # Layer and cut information.
1374
+
1375
+ def write_settings(self, current_settings):
1376
+ part = current_settings.get("part", 0)
1377
+ speed = current_settings.get("speed", 0)
1378
+ power = current_settings.get("power", 0) / 10.0
1379
+ air = current_settings.get("air_assist", True)
1380
+ self.layer_end()
1381
+ self.layer_number_part(part)
1382
+ self.laser_device_0()
1383
+ if air:
1384
+ self.air_assist_on()
1385
+ else:
1386
+ self.air_assist_off()
1387
+ self.speed_laser_1(speed)
1388
+ self.laser_on_delay(0)
1389
+ self.laser_off_delay(0)
1390
+ self.min_power_1(power)
1391
+ self.max_power_1(power)
1392
+ self.min_power_2(power)
1393
+ self.max_power_2(power)
1394
+ self.en_laser_tube_start()
1395
+ self.en_ex_io(0)
1396
+
1397
+ def write_tail(self):
1398
+ # End layer and cut information.
1399
+ self.array_end()
1400
+ self.block_end()
1401
+ # self.encoder.set_setting(0x320, 142, 142)
1402
+ self.set_file_sum(self.file_sum())
1403
+ self.end_of_file()
1404
+
1405
+ def jump(self, x, y, dx, dy):
1406
+ if dx == 0 and dy == 0:
1407
+ # We are not moving.
1408
+ return
1409
+
1410
+ if abs(dx) > 8192 or abs(dy) > 8192:
1411
+ # Exceeds encoding limit, use abs.
1412
+ self.move_abs_xy(x, y)
1413
+ return
1414
+
1415
+ if dx == 0:
1416
+ # Y-relative.
1417
+ self.move_rel_y(dy)
1418
+ return
1419
+ if dy == 0:
1420
+ # X-relative.
1421
+ self.move_rel_x(dx)
1422
+ return
1423
+ self.move_rel_xy(dx, dy)
1424
+
1425
+ def mark(self, x, y, dx, dy):
1426
+ if dx == 0 and dy == 0:
1427
+ # We are not moving.
1428
+ return
1429
+
1430
+ if abs(dx) > 8192 or abs(dy) > 8192:
1431
+ # Exceeds encoding limit, use abs.
1432
+ self.cut_abs_xy(x, y)
1433
+ return
1434
+
1435
+ if dx == 0:
1436
+ # Y-relative.
1437
+ self.cut_rel_y(dy)
1438
+ return
1439
+ if dy == 0:
1440
+ # X-relative.
1441
+ self.cut_rel_x(dx)
1442
+ return
1443
+ self.cut_rel_xy(dx, dy)
1444
+
1445
+ #######################
1446
+ # Specific Commands
1447
+ #######################
1448
+
1449
+ def axis_x_move(self, x, output=None):
1450
+ self(AXIS_X_MOVE, encode32(x), output=output)
1451
+
1452
+ def axis_z_move(self, z, output=None):
1453
+ self(AXIS_Z_MOVE, encode32(z), output=output)
1454
+
1455
+ def axis_a_move(self, a, output=None):
1456
+ self(AXIS_A_MOVE, encode32(a), output=output)
1457
+
1458
+ def axis_u_move(self, u, output=None):
1459
+ self(AXIS_U_MOVE, encode32(u), output=output)
1460
+
1461
+ def move_abs_xy(self, x, y, output=None):
1462
+ self(MOVE_ABS_XY, encode_coord(x), encode_coord(y), output=output)
1463
+
1464
+ def move_rel_xy(self, dx, dy, output=None):
1465
+ self(MOVE_REL_XY, encode_relcoord(dx), encode_relcoord(dy), output=output)
1466
+
1467
+ def move_rel_x(self, dx, output=None):
1468
+ self(MOVE_REL_X, encode_relcoord(dx), output=output)
1469
+
1470
+ def move_rel_y(self, dy, output=None):
1471
+ self(MOVE_REL_Y, encode_relcoord(dy), output=output)
1472
+
1473
+ def cut_abs_xy(self, x, y, output=None):
1474
+ self(CUT_ABS_XY, encode_coord(x), encode_coord(y), output=output)
1475
+
1476
+ def cut_rel_xy(self, dx, dy, output=None):
1477
+ self(CUT_REL_XY, encode_relcoord(dx), encode_relcoord(dy), output=output)
1478
+
1479
+ def cut_rel_x(self, dx, output=None):
1480
+ self(CUT_REL_X, encode_relcoord(dx), output=output)
1481
+
1482
+ def cut_rel_y(self, dy, output=None):
1483
+ self(CUT_REL_Y, encode_relcoord(dy), output=output)
1484
+
1485
+ def imd_power_1(self, power, output=None):
1486
+ self(IMD_POWER_1, encode_power(power), output=output)
1487
+
1488
+ def imd_power_2(self, power, output=None):
1489
+ self(IMD_POWER_2, encode_power(power), output=output)
1490
+
1491
+ def imd_power_3(self, power, output=None):
1492
+ self(IMD_POWER_3, encode_power(power), output=output)
1493
+
1494
+ def imd_power_4(self, power, output=None):
1495
+ self(IMD_POWER_4, encode_power(power), output=output)
1496
+
1497
+ def end_power_1(self, power, output=None):
1498
+ self(END_POWER_1, encode_power(power), output=output)
1499
+
1500
+ def end_power_2(self, power, output=None):
1501
+ self(END_POWER_2, encode_power(power), output=output)
1502
+
1503
+ def end_power_3(self, power, output=None):
1504
+ self(END_POWER_3, encode_power(power), output=output)
1505
+
1506
+ def end_power_4(self, power, output=None):
1507
+ self(END_POWER_4, encode_power(power), output=output)
1508
+
1509
+ def min_power_1(self, power, output=None):
1510
+ self(MIN_POWER_1, encode_power(power), output=output)
1511
+
1512
+ def max_power_1(self, power, output=None):
1513
+ self(MAX_POWER_1, encode_power(power), output=output)
1514
+
1515
+ def min_power_2(self, power, output=None):
1516
+ self(MIN_POWER_2, encode_power(power), output=output)
1517
+
1518
+ def max_power_2(self, power, output=None):
1519
+ self(MAX_POWER_2, encode_power(power), output=output)
1520
+
1521
+ def min_power_3(self, power, output=None):
1522
+ self(MIN_POWER_3, encode_power(power), output=output)
1523
+
1524
+ def max_power_3(self, power, output=None):
1525
+ self(MAX_POWER_3, encode_power(power), output=output)
1526
+
1527
+ def min_power_4(self, power, output=None):
1528
+ self(MIN_POWER_4, encode_power(power), output=output)
1529
+
1530
+ def max_power_4(self, power, output=None):
1531
+ self(MAX_POWER_4, encode_power(power), output=output)
1532
+
1533
+ def laser_interval(self, time, output=None):
1534
+ self(LASER_INTERVAL, encode_time(time), output=output)
1535
+
1536
+ def add_delay(self, time, output=None):
1537
+ self(ADD_DELAY, encode_time(time), output=output)
1538
+
1539
+ def laser_on_delay(self, time, output=None):
1540
+ self(LASER_ON_DELAY, encode_time(time), output=output)
1541
+
1542
+ def laser_off_delay(self, time, output=None):
1543
+ self(LASER_OFF_DELAY, encode_time(time), output=output)
1544
+
1545
+ def laser_on_delay_2(self, time, output=None):
1546
+ self(LASER_ON_DELAY2, encode_time(time), output=output)
1547
+
1548
+ def laser_off_delay_2(self, time, output=None):
1549
+ self(LASER_OFF_DELAY2, encode_time(time), output=output)
1550
+
1551
+ def min_power_1_part(self, part, power, output=None):
1552
+ self(MIN_POWER_1_PART, encode_part(part), encode_power(power), output=output)
1553
+
1554
+ def max_power_1_part(self, part, power, output=None):
1555
+ self(MAX_POWER_1_PART, encode_part(part), encode_power(power), output=output)
1556
+
1557
+ def min_power_2_part(self, part, power, output=None):
1558
+ self(MIN_POWER_2_PART, encode_part(part), encode_power(power), output=output)
1559
+
1560
+ def max_power_2_part(self, part, power, output=None):
1561
+ self(MAX_POWER_2_PART, encode_part(part), encode_power(power), output=output)
1562
+
1563
+ def min_power_3_part(self, part, power, output=None):
1564
+ self(MIN_POWER_3_PART, encode_part(part), encode_power(power), output=output)
1565
+
1566
+ def max_power_3_part(self, part, power, output=None):
1567
+ self(MAX_POWER_3_PART, encode_part(part), encode_power(power), output=output)
1568
+
1569
+ def min_power_4_part(self, part, power, output=None):
1570
+ self(MIN_POWER_4_PART, encode_part(part), encode_power(power), output=output)
1571
+
1572
+ def max_power_4_part(self, part, power, output=None):
1573
+ self(MAX_POWER_4_PART, encode_part(part), encode_power(power), output=output)
1574
+
1575
+ def through_power_1(self, power, output=None):
1576
+ """
1577
+ This is the power used for the Laser On / Laser Off Delay.
1578
+
1579
+ @param power:
1580
+ @param output:
1581
+ @return:
1582
+ """
1583
+ self(THROUGH_POWER_1, encode_power(power), output=output)
1584
+
1585
+ def through_power_2(self, power, output=None):
1586
+ self(THROUGH_POWER_2, encode_power(power), output=output)
1587
+
1588
+ def through_power_3(self, power, output=None):
1589
+ self(THROUGH_POWER_3, encode_power(power), output=output)
1590
+
1591
+ def through_power_4(self, power, output=None):
1592
+ self(THROUGH_POWER_4, encode_power(power), output=output)
1593
+
1594
+ def frequency_part(self, laser, part, frequency, output=None):
1595
+ self(
1596
+ FREQUENCY_PART,
1597
+ encode_index(laser),
1598
+ encode_part(part),
1599
+ encode_frequency(frequency),
1600
+ output=output,
1601
+ )
1602
+
1603
+ def speed_laser_1(self, speed, output=None):
1604
+ self(SPEED_LASER_1, encode_speed(speed), output=output)
1605
+
1606
+ def speed_axis(self, speed, output=None):
1607
+ self(SPEED_AXIS, encode_speed(speed), output=output)
1608
+
1609
+ def speed_laser_1_part(self, part, speed, output=None):
1610
+ self(SPEED_LASER_1_PART, encode_part(part), encode_speed(speed), output=output)
1611
+
1612
+ def force_eng_speed(self, speed, output=None):
1613
+ self(FORCE_ENG_SPEED, encode_speed(speed), output=output)
1614
+
1615
+ def speed_axis_move(self, speed, output=None):
1616
+ self(SPEED_AXIS_MOVE, encode_speed(speed), output=output)
1617
+
1618
+ def layer_end(self, output=None):
1619
+ self(LAYER_END, output=output)
1620
+
1621
+ def work_mode_1(self, output=None):
1622
+ self(WORK_MODE_1, output=output)
1623
+
1624
+ def work_mode_2(self, output=None):
1625
+ self(WORK_MODE_2, output=output)
1626
+
1627
+ def work_mode_3(self, output=None):
1628
+ self(WORK_MODE_3, output=output)
1629
+
1630
+ def work_mode_4(self, output=None):
1631
+ self(WORK_MODE_4, output=output)
1632
+
1633
+ def work_mode_5(self, output=None):
1634
+ self(WORK_MODE_5, output=output)
1635
+
1636
+ def work_mode_6(self, output=None):
1637
+ self(WORK_MODE_6, output=output)
1638
+
1639
+ def laser_device_0(self, output=None):
1640
+ self(LASER_DEVICE_0, output=output)
1641
+
1642
+ def laser_device_1(self, output=None):
1643
+ self(LASER_DEVICE_1, output=output)
1644
+
1645
+ def air_assist_off(self, output=None):
1646
+ self(AIR_ASSIST_OFF, output=output)
1647
+
1648
+ def air_assist_on(self, output=None):
1649
+ self(AIR_ASSIST_ON, output=output)
1650
+
1651
+ def db_head(self, output=None):
1652
+ self(DB_HEAD, output=output)
1653
+
1654
+ def en_laser_2_offset_0(self, output=None):
1655
+ self(EN_LASER_2_OFFSET_0, output=output)
1656
+
1657
+ def en_laser_2_offset_1(self, output=None):
1658
+ self(EN_LASER_2_OFFSET_1, output=output)
1659
+
1660
+ def layer_number_part(self, part, output=None):
1661
+ self(LAYER_NUMBER_PART, encode_part(part), output=output)
1662
+
1663
+ def en_laser_tube_start(self, output=None):
1664
+ self(EN_LASER_TUBE_START, output=output)
1665
+
1666
+ def x_sign_map(self, value, output=None):
1667
+ self(X_SIGN_MAP, encode_index(value), output=output)
1668
+
1669
+ def layer_color(self, color, output=None):
1670
+ self(LAYER_COLOR, encode_color(color), output=output)
1671
+
1672
+ def layer_color_part(self, part, color, output=None):
1673
+ self(LAYER_COLOR, encode_part(part), encode_color(color), output=output)
1674
+
1675
+ def en_ex_io(self, value, output=None):
1676
+ """
1677
+ Enable External IO.
1678
+
1679
+ @param value:
1680
+ @param output:
1681
+ @return:
1682
+ """
1683
+ self(EN_EX_IO, encode_index(value), output=output)
1684
+
1685
+ def max_layer_part(self, part, output=None):
1686
+ self(MAX_LAYER_PART, encode_part(part), output=output)
1687
+
1688
+ def u_file_id(self, file_number, output=None):
1689
+ self(MAX_LAYER_PART, encode_file_number(file_number), output=output)
1690
+
1691
+ def zu_map(self, value, output=None):
1692
+ self(ZU_MAP, encode_index(value), output=output)
1693
+
1694
+ def work_mode_part(self, part, mode, output=None):
1695
+ self(WORK_MODE_PART, encode_part(part), encode_index(mode), output=output)
1696
+
1697
+ def ack(self, output=None):
1698
+ self(ACK, output=output)
1699
+
1700
+ def err(self, output=None):
1701
+ self(ERR, output=output)
1702
+
1703
+ def keep_alive(self, output=None):
1704
+ self(KEEP_ALIVE, output=output)
1705
+
1706
+ def end_of_file(self, output=None):
1707
+ self(END_OF_FILE, output=output)
1708
+
1709
+ def start_process(self, output=None):
1710
+ self(START_PROCESS, output=output)
1711
+
1712
+ def stop_process(self, output=None):
1713
+ self(STOP_PROCESS, output=output)
1714
+
1715
+ def pause_process(self, output=None):
1716
+ self(PAUSE_PROCESS, output=output)
1717
+
1718
+ def restore_process(self, output=None):
1719
+ self(RESTORE_PROCESS, output=output)
1720
+
1721
+ def ref_point_2(self, output=None):
1722
+ """
1723
+ Machine zero. Absolute position.
1724
+ @return:
1725
+ """
1726
+ self(REF_POINT_2, output=output)
1727
+
1728
+ def ref_point_1(self, output=None):
1729
+ """
1730
+ Anchor Point, Origin.
1731
+ @return:
1732
+ """
1733
+ self(REF_POINT_1, output=output)
1734
+
1735
+ def ref_point_0(self, output=None):
1736
+ """
1737
+ Current position.
1738
+
1739
+ @return:
1740
+ """
1741
+ self(REF_POINT_0, output=output)
1742
+
1743
+ def home_z(self, output=None):
1744
+ self(HOME_Z, output=output)
1745
+
1746
+ def home_u(self, output=None):
1747
+ self(HOME_U, output=output)
1748
+
1749
+ def home_xy(self, output=None):
1750
+ self(HOME_XY, output=output)
1751
+
1752
+ def focus_z(self, output=None):
1753
+ self(FOCUS_Z, output=output)
1754
+
1755
+ def keydown_x_left(self, output=None):
1756
+ self(KEYDOWN_X_LEFT, output=output)
1757
+
1758
+ def keyup_x_left(self, output=None):
1759
+ self(KEYUP_X_LEFT, output=output)
1760
+
1761
+ def keydown_x_right(self, output=None):
1762
+ self(KEYDOWN_X_RIGHT, output=output)
1763
+
1764
+ def keyup_x_right(self, output=None):
1765
+ self(KEYUP_X_RIGHT, output=output)
1766
+
1767
+ def keydown_y_top(self, output=None):
1768
+ self(KEYDOWN_Y_TOP, output=output)
1769
+
1770
+ def keyup_y_top(self, output=None):
1771
+ self(KEYUP_Y_TOP, output=output)
1772
+
1773
+ def keydown_y_bottom(self, output=None):
1774
+ self(KEYDOWN_Y_BOTTOM, output=output)
1775
+
1776
+ def keyup_y_bottom(self, output=None):
1777
+ self(KEYUP_Y_BOTTOM, output=output)
1778
+
1779
+ def keydown_z_up(self, output=None):
1780
+ self(KEYDOWN_Z_UP, output=output)
1781
+
1782
+ def keyup_z_up(self, output=None):
1783
+ self(KEYUP_Z_UP, output=output)
1784
+
1785
+ def keydown_z_down(self, output=None):
1786
+ self(KEYDOWN_Z_DOWN, output=output)
1787
+
1788
+ def keyup_z_down(self, output=None):
1789
+ self(KEYUP_Z_DOWN, output=output)
1790
+
1791
+ def _rapid_options(self, light=False, origin=False):
1792
+ if light and origin:
1793
+ return RAPID_OPTION_LIGHTORIGIN
1794
+ if light and not origin:
1795
+ return RAPID_OPTION_LIGHT
1796
+ if origin:
1797
+ return RAPID_OPTION_ORIGIN
1798
+ return RAPID_OPTION_NONE
1799
+
1800
+ def rapid_move_x(self, x, light=False, origin=False, output=None):
1801
+ self(
1802
+ RAPID_MOVE_X,
1803
+ self._rapid_options(light=light, origin=origin),
1804
+ encode_coord(x),
1805
+ output=output,
1806
+ )
1807
+
1808
+ def rapid_move_y(self, y, light=False, origin=False, output=None):
1809
+ self(
1810
+ RAPID_MOVE_Y,
1811
+ self._rapid_options(light=light, origin=origin),
1812
+ encode_coord(y),
1813
+ output=output,
1814
+ )
1815
+
1816
+ def rapid_move_z(self, z, light=False, origin=False, output=None):
1817
+ self(
1818
+ RAPID_MOVE_Z,
1819
+ self._rapid_options(light=light, origin=origin),
1820
+ encode_coord(z),
1821
+ output=output,
1822
+ )
1823
+
1824
+ def rapid_move_u(self, u, light=False, origin=False, output=None):
1825
+ self(
1826
+ RAPID_MOVE_U,
1827
+ self._rapid_options(light=light, origin=origin),
1828
+ encode_coord(u),
1829
+ output=output,
1830
+ )
1831
+
1832
+ def rapid_move_xy(self, x, y, light=False, origin=False, output=None):
1833
+ self(
1834
+ RAPID_MOVE_XY,
1835
+ self._rapid_options(light=light, origin=origin),
1836
+ encode_coord(x),
1837
+ encode_coord(y),
1838
+ output=output,
1839
+ )
1840
+
1841
+ def rapid_move_xyu(self, x, y, u, light=False, origin=False, output=None):
1842
+ self(
1843
+ RAPID_MOVE_XYU,
1844
+ self._rapid_options(light=light, origin=origin),
1845
+ encode_coord(x),
1846
+ encode_coord(y),
1847
+ encode_coord(u),
1848
+ output=output,
1849
+ )
1850
+
1851
+ def rapid_feed_axis(self, light=False, origin=False, output=None):
1852
+ self(
1853
+ RAPID_FEED_AXIS_MOVE,
1854
+ self._rapid_options(light=light, origin=origin),
1855
+ output=output,
1856
+ )
1857
+
1858
+ def get_setting(self, mem, output=None):
1859
+ self(GET_SETTING, encode_mem(mem), output=output)
1860
+
1861
+ def set_setting(self, mem, value, output=None):
1862
+ self(
1863
+ SET_SETTING,
1864
+ encode_mem(mem),
1865
+ encode_value(value),
1866
+ encode_value(value),
1867
+ output=output,
1868
+ )
1869
+
1870
+ def document_file_upload(self, file_number, value, value1, output=None):
1871
+ self(
1872
+ DOCUMENT_FILE_UPLOAD,
1873
+ encode_value(value),
1874
+ encode_value(value1),
1875
+ output=output,
1876
+ )
1877
+
1878
+ def document_file_end(self, output=None):
1879
+ self(DOCUMENT_FILE_END, output=output)
1880
+
1881
+ def set_file_sum(self, value, output=None):
1882
+ self(SET_FILE_SUM, encode_value(value), output=output)
1883
+
1884
+ def set_absolute(self, output=None):
1885
+ self(SET_ABSOLUTE, output=output)
1886
+
1887
+ def block_end(self, output=None):
1888
+ self(BLOCK_END, output=output)
1889
+
1890
+ def set_filename(self, filename, output=None):
1891
+ self(
1892
+ SET_FILENAME, bytes(filename[:9], encoding="utf-8"), b"\x00", output=output
1893
+ )
1894
+
1895
+ def process_top_left(self, top, left, output=None):
1896
+ self(PROCESS_TOP_LEFT, encode_coord(top), encode_coord(left), output=output)
1897
+
1898
+ def process_repeat(self, v0, v1, v2, v3, v4, v5, v6, output=None):
1899
+ self(
1900
+ PROCESS_REPEAT,
1901
+ encode14(v0),
1902
+ encode14(v1),
1903
+ encode14(v2),
1904
+ encode14(v3),
1905
+ encode14(v4),
1906
+ encode14(v5),
1907
+ encode14(v6),
1908
+ output=output,
1909
+ )
1910
+
1911
+ def array_direction(self, direction, output=None):
1912
+ self(ARRAY_DIRECTION, encode_index(direction), output=output)
1913
+
1914
+ def feed_repeat(self, value, value1, output=None):
1915
+ self(FEED_REPEAT, encode32(value), encode32(value1), output=output)
1916
+
1917
+ def process_bottom_right(self, bottom, right, output=None):
1918
+ self(
1919
+ PROCESS_BOTTOM_RIGHT,
1920
+ encode_coord(bottom),
1921
+ encode_coord(right),
1922
+ output=output,
1923
+ )
1924
+
1925
+ def array_repeat(self, v0, v1, v2, v3, v4, v5, v6, output=None):
1926
+ self(
1927
+ ARRAY_REPEAT,
1928
+ encode14(v0),
1929
+ encode14(v1),
1930
+ encode14(v2),
1931
+ encode14(v3),
1932
+ encode14(v4),
1933
+ encode14(v5),
1934
+ encode14(v6),
1935
+ output=output,
1936
+ )
1937
+
1938
+ def feed_length(self, length, output=None):
1939
+ self(FEED_LENGTH, encode32(length), output=output)
1940
+
1941
+ def feed_info(self, value, output=None):
1942
+ self(FEED_INFO, encode_value(value), output=output)
1943
+
1944
+ def array_en_mirror_cut(self, index, output=None):
1945
+ self(ARRAY_EN_MIRROR_CUT, encode_index(index), output=output)
1946
+
1947
+ def array_min_point(self, min_x, min_y, output=None):
1948
+ self(ARRAY_MIN_POINT, encode_coord(min_x), encode_coord(min_y), output=output)
1949
+
1950
+ def array_max_point(self, max_x, max_y, output=None):
1951
+ self(ARRAY_MAX_POINT, encode_coord(max_x), encode_coord(max_y), output=output)
1952
+
1953
+ def array_add(self, x, y, output=None):
1954
+ self(ARRAY_ADD, encode_coord(x), encode_coord(y), output=output)
1955
+
1956
+ def array_mirror(self, mirror, output=None):
1957
+ self(ARRAY_MIRROR, encode_index(mirror), output=output)
1958
+
1959
+ def block_x_size(self, x0, x1, output=None):
1960
+ self(BLOCK_X_SIZE, encode_coord(x0), encode_coord(x1), output=output)
1961
+
1962
+ def by_test(self, output=None):
1963
+ self(BY_TEST, encode32(0x11227766), output=output)
1964
+
1965
+ def array_even_distance(self, max_x, max_y, output=None):
1966
+ self(
1967
+ ARRAY_EVEN_DISTANCE, encode_coord(max_x), encode_coord(max_y), output=output
1968
+ )
1969
+
1970
+ def set_feed_auto_pause(self, index, output=None):
1971
+ self(SET_FEED_AUTO_PAUSE, encode_index(index), output=output)
1972
+
1973
+ def union_block_property(self, output=None):
1974
+ self(UNION_BLOCK_PROPERTY, output=output)
1975
+
1976
+ def document_min_point(self, min_x, min_y, output=None):
1977
+ self(
1978
+ DOCUMENT_MIN_POINT, encode_coord(min_x), encode_coord(min_y), output=output
1979
+ )
1980
+
1981
+ def document_max_point(self, max_x, max_y, output=None):
1982
+ self(
1983
+ DOCUMENT_MAX_POINT, encode_coord(max_x), encode_coord(max_y), output=output
1984
+ )
1985
+
1986
+ def part_min_point(self, part, min_x, min_y, output=None):
1987
+ self(
1988
+ PART_MIN_POINT,
1989
+ encode_part(part),
1990
+ encode_coord(min_x),
1991
+ encode_coord(min_y),
1992
+ output=output,
1993
+ )
1994
+
1995
+ def part_max_point(self, part, max_x, max_y, output=None):
1996
+ self(
1997
+ PART_MAX_POINT,
1998
+ encode_part(part),
1999
+ encode_coord(max_x),
2000
+ encode_coord(max_y),
2001
+ output=output,
2002
+ )
2003
+
2004
+ def pen_offset(self, axis, coord, output=None):
2005
+ self(PEN_OFFSET, encode_index(axis), encode_coord(coord), output=output)
2006
+
2007
+ def layer_offset(self, axis, coord, output=None):
2008
+ self(LAYER_OFFSET, encode_index(axis), encode_coord(coord), output=output)
2009
+
2010
+ def set_current_element_index(self, index, output=None):
2011
+ self(SET_CURRENT_ELEMENT_INDEX, encode_index(index), output=output)
2012
+
2013
+ def part_min_point_ex(self, part, min_x, min_y, output=None):
2014
+ self(
2015
+ PART_MIN_POINT_EX,
2016
+ encode_part(part),
2017
+ encode_coord(min_x),
2018
+ encode_coord(min_y),
2019
+ output=output,
2020
+ )
2021
+
2022
+ def part_max_point_ex(self, part, max_x, max_y, output=None):
2023
+ self(
2024
+ PART_MAX_POINT_EX,
2025
+ encode_part(part),
2026
+ encode_coord(max_x),
2027
+ encode_coord(max_y),
2028
+ output=output,
2029
+ )
2030
+
2031
+ def array_start(self, index, output=None):
2032
+ self(ARRAY_START, encode_index(index), output=output)
2033
+
2034
+ def array_end(self, output=None):
2035
+ self(ARRAY_END, output=output)
2036
+
2037
+ def ref_point_set(self, output=None):
2038
+ self(REF_POINT_SET, output=output)
2039
+
2040
+ def element_max_index(self, index, output=None):
2041
+ self(ELEMENT_MAX_INDEX, encode_index(index), output=output)
2042
+
2043
+ def element_name_max_index(self, index, output=None):
2044
+ self(ELEMENT_NAME_MAX_INDEX, encode_index(index), output=output)
2045
+
2046
+ def enable_block_cutting(self, enable, output=None):
2047
+ self(ENABLE_BLOCK_CUTTING, encode_index(enable), output=output)
2048
+
2049
+ def display_offset(self, dx, dy, output=None):
2050
+ self(DISPLAY_OFFSET, encode_coord(dx), encode_coord(dy), output=output)
2051
+
2052
+ def feed_auto_calc(self, enable, output=None):
2053
+ self(FEED_AUTO_CALC, encode_index(enable), output=output)
2054
+
2055
+ def element_index(self, index, output=None):
2056
+ self(ELEMENT_INDEX, encode_index(index), output=output)
2057
+
2058
+ def element_name(self, name, output=None):
2059
+ self(ELEMENT_NAME, bytes(name[:9], encoding="utf-8"), b"\x00", output=output)
2060
+
2061
+ def element_array_min_point(self, x, y, output=None):
2062
+ self(ELEMENT_ARRAY_MIN_POINT, encode_coord(x), encode_coord(y), output=output)
2063
+
2064
+ def element_array_max_point(self, x, y, output=None):
2065
+ self(ELEMENT_ARRAY_MAX_POINT, encode_coord(x), encode_coord(y), output=output)
2066
+
2067
+ def element_array(self, v0, v1, v2, v3, v4, v5, v6, output=None):
2068
+ self(
2069
+ ELEMENT_ARRAY,
2070
+ encode14(v0),
2071
+ encode14(v1),
2072
+ encode14(v2),
2073
+ encode14(v3),
2074
+ encode14(v4),
2075
+ encode14(v5),
2076
+ encode14(v6),
2077
+ output=output,
2078
+ )
2079
+
2080
+ def element_array_add(self, x, y, output=None):
2081
+ self(ELEMENT_ARRAY_ADD, encode_coord(x), encode_coord(y), output=output)
2082
+
2083
+ def element_array_mirror(self, mirror, output=None):
2084
+ self(ELEMENT_ARRAY_MIRROR, encode_index(mirror), output=output)