meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7010__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 (445) 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 +1195 -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 +1844 -1507
  50. meerk40t/core/elements/clipboard.py +229 -219
  51. meerk40t/core/elements/element_treeops.py +4561 -2837
  52. meerk40t/core/elements/element_types.py +125 -105
  53. meerk40t/core/elements/elements.py +4329 -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 +933 -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/trace.py +651 -563
  66. meerk40t/core/elements/tree_commands.py +415 -409
  67. meerk40t/core/elements/undo_redo.py +116 -58
  68. meerk40t/core/elements/wordlist.py +319 -200
  69. meerk40t/core/exceptions.py +9 -9
  70. meerk40t/core/laserjob.py +220 -220
  71. meerk40t/core/logging.py +63 -63
  72. meerk40t/core/node/blobnode.py +83 -86
  73. meerk40t/core/node/bootstrap.py +105 -103
  74. meerk40t/core/node/branch_elems.py +40 -31
  75. meerk40t/core/node/branch_ops.py +45 -38
  76. meerk40t/core/node/branch_regmark.py +48 -41
  77. meerk40t/core/node/cutnode.py +29 -32
  78. meerk40t/core/node/effect_hatch.py +375 -257
  79. meerk40t/core/node/effect_warp.py +398 -0
  80. meerk40t/core/node/effect_wobble.py +441 -309
  81. meerk40t/core/node/elem_ellipse.py +404 -309
  82. meerk40t/core/node/elem_image.py +1082 -801
  83. meerk40t/core/node/elem_line.py +358 -292
  84. meerk40t/core/node/elem_path.py +259 -201
  85. meerk40t/core/node/elem_point.py +129 -102
  86. meerk40t/core/node/elem_polyline.py +310 -246
  87. meerk40t/core/node/elem_rect.py +376 -286
  88. meerk40t/core/node/elem_text.py +445 -418
  89. meerk40t/core/node/filenode.py +59 -40
  90. meerk40t/core/node/groupnode.py +138 -74
  91. meerk40t/core/node/image_processed.py +777 -766
  92. meerk40t/core/node/image_raster.py +156 -113
  93. meerk40t/core/node/layernode.py +31 -31
  94. meerk40t/core/node/mixins.py +135 -107
  95. meerk40t/core/node/node.py +1427 -1304
  96. meerk40t/core/node/nutils.py +117 -114
  97. meerk40t/core/node/op_cut.py +462 -335
  98. meerk40t/core/node/op_dots.py +296 -251
  99. meerk40t/core/node/op_engrave.py +414 -311
  100. meerk40t/core/node/op_image.py +755 -369
  101. meerk40t/core/node/op_raster.py +787 -522
  102. meerk40t/core/node/place_current.py +37 -40
  103. meerk40t/core/node/place_point.py +329 -126
  104. meerk40t/core/node/refnode.py +58 -47
  105. meerk40t/core/node/rootnode.py +225 -219
  106. meerk40t/core/node/util_console.py +48 -48
  107. meerk40t/core/node/util_goto.py +84 -65
  108. meerk40t/core/node/util_home.py +61 -61
  109. meerk40t/core/node/util_input.py +102 -102
  110. meerk40t/core/node/util_output.py +102 -102
  111. meerk40t/core/node/util_wait.py +65 -65
  112. meerk40t/core/parameters.py +709 -707
  113. meerk40t/core/planner.py +875 -785
  114. meerk40t/core/plotplanner.py +656 -652
  115. meerk40t/core/space.py +120 -113
  116. meerk40t/core/spoolers.py +706 -705
  117. meerk40t/core/svg_io.py +1836 -1549
  118. meerk40t/core/treeop.py +534 -445
  119. meerk40t/core/undos.py +278 -124
  120. meerk40t/core/units.py +784 -680
  121. meerk40t/core/view.py +393 -322
  122. meerk40t/core/webhelp.py +62 -62
  123. meerk40t/core/wordlist.py +513 -504
  124. meerk40t/cylinder/cylinder.py +247 -0
  125. meerk40t/cylinder/gui/cylindersettings.py +41 -0
  126. meerk40t/cylinder/gui/gui.py +24 -0
  127. meerk40t/device/__init__.py +1 -1
  128. meerk40t/device/basedevice.py +322 -123
  129. meerk40t/device/devicechoices.py +50 -0
  130. meerk40t/device/dummydevice.py +163 -128
  131. meerk40t/device/gui/defaultactions.py +618 -602
  132. meerk40t/device/gui/effectspanel.py +114 -0
  133. meerk40t/device/gui/formatterpanel.py +253 -290
  134. meerk40t/device/gui/warningpanel.py +337 -260
  135. meerk40t/device/mixins.py +13 -13
  136. meerk40t/dxf/__init__.py +1 -1
  137. meerk40t/dxf/dxf_io.py +766 -554
  138. meerk40t/dxf/plugin.py +47 -35
  139. meerk40t/external_plugins.py +79 -79
  140. meerk40t/external_plugins_build.py +28 -28
  141. meerk40t/extra/cag.py +112 -116
  142. meerk40t/extra/coolant.py +403 -0
  143. meerk40t/extra/encode_detect.py +198 -0
  144. meerk40t/extra/ezd.py +1165 -1165
  145. meerk40t/extra/hershey.py +835 -340
  146. meerk40t/extra/imageactions.py +322 -316
  147. meerk40t/extra/inkscape.py +630 -622
  148. meerk40t/extra/lbrn.py +424 -424
  149. meerk40t/extra/outerworld.py +284 -0
  150. meerk40t/extra/param_functions.py +1542 -1556
  151. meerk40t/extra/potrace.py +257 -253
  152. meerk40t/extra/serial_exchange.py +118 -0
  153. meerk40t/extra/updater.py +602 -453
  154. meerk40t/extra/vectrace.py +147 -146
  155. meerk40t/extra/winsleep.py +83 -83
  156. meerk40t/extra/xcs_reader.py +597 -0
  157. meerk40t/fill/fills.py +781 -335
  158. meerk40t/fill/patternfill.py +1061 -1061
  159. meerk40t/fill/patterns.py +614 -567
  160. meerk40t/grbl/control.py +87 -87
  161. meerk40t/grbl/controller.py +990 -903
  162. meerk40t/grbl/device.py +1081 -768
  163. meerk40t/grbl/driver.py +989 -771
  164. meerk40t/grbl/emulator.py +532 -497
  165. meerk40t/grbl/gcodejob.py +783 -767
  166. meerk40t/grbl/gui/grblconfiguration.py +373 -298
  167. meerk40t/grbl/gui/grblcontroller.py +485 -271
  168. meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
  169. meerk40t/grbl/gui/grbloperationconfig.py +105 -0
  170. meerk40t/grbl/gui/gui.py +147 -116
  171. meerk40t/grbl/interpreter.py +44 -44
  172. meerk40t/grbl/loader.py +22 -22
  173. meerk40t/grbl/mock_connection.py +56 -56
  174. meerk40t/grbl/plugin.py +294 -264
  175. meerk40t/grbl/serial_connection.py +93 -88
  176. meerk40t/grbl/tcp_connection.py +81 -79
  177. meerk40t/grbl/ws_connection.py +112 -0
  178. meerk40t/gui/__init__.py +1 -1
  179. meerk40t/gui/about.py +2042 -296
  180. meerk40t/gui/alignment.py +1644 -1608
  181. meerk40t/gui/autoexec.py +199 -0
  182. meerk40t/gui/basicops.py +791 -670
  183. meerk40t/gui/bufferview.py +77 -71
  184. meerk40t/gui/busy.py +170 -133
  185. meerk40t/gui/choicepropertypanel.py +1673 -1469
  186. meerk40t/gui/consolepanel.py +706 -542
  187. meerk40t/gui/devicepanel.py +687 -581
  188. meerk40t/gui/dialogoptions.py +110 -107
  189. meerk40t/gui/executejob.py +316 -306
  190. meerk40t/gui/fonts.py +90 -90
  191. meerk40t/gui/functionwrapper.py +252 -0
  192. meerk40t/gui/gui_mixins.py +729 -0
  193. meerk40t/gui/guicolors.py +205 -182
  194. meerk40t/gui/help_assets/help_assets.py +218 -201
  195. meerk40t/gui/helper.py +154 -0
  196. meerk40t/gui/hersheymanager.py +1430 -846
  197. meerk40t/gui/icons.py +3422 -2747
  198. meerk40t/gui/imagesplitter.py +555 -508
  199. meerk40t/gui/keymap.py +354 -344
  200. meerk40t/gui/laserpanel.py +892 -806
  201. meerk40t/gui/laserrender.py +1470 -1232
  202. meerk40t/gui/lasertoolpanel.py +805 -793
  203. meerk40t/gui/magnetoptions.py +436 -0
  204. meerk40t/gui/materialmanager.py +2917 -0
  205. meerk40t/gui/materialtest.py +1722 -1694
  206. meerk40t/gui/mkdebug.py +646 -359
  207. meerk40t/gui/mwindow.py +163 -140
  208. meerk40t/gui/navigationpanels.py +2605 -2467
  209. meerk40t/gui/notes.py +143 -142
  210. meerk40t/gui/opassignment.py +414 -410
  211. meerk40t/gui/operation_info.py +310 -299
  212. meerk40t/gui/plugin.py +494 -328
  213. meerk40t/gui/position.py +714 -669
  214. meerk40t/gui/preferences.py +901 -650
  215. meerk40t/gui/propertypanels/attributes.py +1461 -1131
  216. meerk40t/gui/propertypanels/blobproperty.py +117 -114
  217. meerk40t/gui/propertypanels/consoleproperty.py +83 -80
  218. meerk40t/gui/propertypanels/gotoproperty.py +77 -0
  219. meerk40t/gui/propertypanels/groupproperties.py +223 -217
  220. meerk40t/gui/propertypanels/hatchproperty.py +489 -469
  221. meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
  222. meerk40t/gui/propertypanels/inputproperty.py +59 -58
  223. meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
  224. meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
  225. meerk40t/gui/propertypanels/outputproperty.py +59 -58
  226. meerk40t/gui/propertypanels/pathproperty.py +389 -380
  227. meerk40t/gui/propertypanels/placementproperty.py +1214 -383
  228. meerk40t/gui/propertypanels/pointproperty.py +140 -136
  229. meerk40t/gui/propertypanels/propertywindow.py +313 -181
  230. meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
  231. meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
  232. meerk40t/gui/propertypanels/textproperty.py +770 -755
  233. meerk40t/gui/propertypanels/waitproperty.py +56 -55
  234. meerk40t/gui/propertypanels/warpproperty.py +121 -0
  235. meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
  236. meerk40t/gui/ribbon.py +2468 -2210
  237. meerk40t/gui/scene/scene.py +1100 -1051
  238. meerk40t/gui/scene/sceneconst.py +22 -22
  239. meerk40t/gui/scene/scenepanel.py +439 -349
  240. meerk40t/gui/scene/scenespacewidget.py +365 -365
  241. meerk40t/gui/scene/widget.py +518 -505
  242. meerk40t/gui/scenewidgets/affinemover.py +215 -215
  243. meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
  244. meerk40t/gui/scenewidgets/bedwidget.py +120 -97
  245. meerk40t/gui/scenewidgets/elementswidget.py +137 -107
  246. meerk40t/gui/scenewidgets/gridwidget.py +785 -745
  247. meerk40t/gui/scenewidgets/guidewidget.py +765 -765
  248. meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
  249. meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
  250. meerk40t/gui/scenewidgets/nodeselector.py +28 -28
  251. meerk40t/gui/scenewidgets/rectselectwidget.py +589 -346
  252. meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
  253. meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
  254. meerk40t/gui/scenewidgets/selectionwidget.py +2952 -2756
  255. meerk40t/gui/simpleui.py +357 -333
  256. meerk40t/gui/simulation.py +2431 -2094
  257. meerk40t/gui/snapoptions.py +208 -203
  258. meerk40t/gui/spoolerpanel.py +1227 -1180
  259. meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
  260. meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
  261. meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
  262. meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
  263. meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
  264. meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
  265. meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
  266. meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
  267. meerk40t/gui/themes.py +200 -78
  268. meerk40t/gui/tips.py +591 -0
  269. meerk40t/gui/toolwidgets/circlebrush.py +35 -35
  270. meerk40t/gui/toolwidgets/toolcircle.py +248 -242
  271. meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
  272. meerk40t/gui/toolwidgets/tooldraw.py +97 -90
  273. meerk40t/gui/toolwidgets/toolellipse.py +219 -212
  274. meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
  275. meerk40t/gui/toolwidgets/toolline.py +39 -144
  276. meerk40t/gui/toolwidgets/toollinetext.py +79 -236
  277. meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
  278. meerk40t/gui/toolwidgets/toolmeasure.py +160 -216
  279. meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
  280. meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
  281. meerk40t/gui/toolwidgets/toolparameter.py +754 -668
  282. meerk40t/gui/toolwidgets/toolplacement.py +108 -108
  283. meerk40t/gui/toolwidgets/toolpoint.py +68 -59
  284. meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
  285. meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
  286. meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
  287. meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
  288. meerk40t/gui/toolwidgets/toolrect.py +211 -207
  289. meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
  290. meerk40t/gui/toolwidgets/toolribbon.py +598 -113
  291. meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
  292. meerk40t/gui/toolwidgets/tooltext.py +98 -89
  293. meerk40t/gui/toolwidgets/toolvector.py +213 -204
  294. meerk40t/gui/toolwidgets/toolwidget.py +39 -39
  295. meerk40t/gui/usbconnect.py +98 -91
  296. meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
  297. meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
  298. meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
  299. meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
  300. meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
  301. meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
  302. meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
  303. meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
  304. meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
  305. meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
  306. meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
  307. meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
  308. meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
  309. meerk40t/gui/wordlisteditor.py +985 -931
  310. meerk40t/gui/wxmeerk40t.py +1444 -1169
  311. meerk40t/gui/wxmmain.py +5578 -4112
  312. meerk40t/gui/wxmribbon.py +1591 -1076
  313. meerk40t/gui/wxmscene.py +1635 -1453
  314. meerk40t/gui/wxmtree.py +2410 -2089
  315. meerk40t/gui/wxutils.py +1769 -1099
  316. meerk40t/gui/zmatrix.py +102 -102
  317. meerk40t/image/__init__.py +1 -1
  318. meerk40t/image/dither.py +429 -0
  319. meerk40t/image/imagetools.py +2778 -2269
  320. meerk40t/internal_plugins.py +150 -130
  321. meerk40t/kernel/__init__.py +63 -12
  322. meerk40t/kernel/channel.py +259 -212
  323. meerk40t/kernel/context.py +538 -538
  324. meerk40t/kernel/exceptions.py +41 -41
  325. meerk40t/kernel/functions.py +463 -414
  326. meerk40t/kernel/jobs.py +100 -100
  327. meerk40t/kernel/kernel.py +3809 -3571
  328. meerk40t/kernel/lifecycles.py +71 -71
  329. meerk40t/kernel/module.py +49 -49
  330. meerk40t/kernel/service.py +147 -147
  331. meerk40t/kernel/settings.py +383 -343
  332. meerk40t/lihuiyu/controller.py +883 -876
  333. meerk40t/lihuiyu/device.py +1181 -1069
  334. meerk40t/lihuiyu/driver.py +1466 -1372
  335. meerk40t/lihuiyu/gui/gui.py +127 -106
  336. meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
  337. meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
  338. meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
  339. meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
  340. meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
  341. meerk40t/lihuiyu/interpreter.py +53 -53
  342. meerk40t/lihuiyu/laserspeed.py +450 -450
  343. meerk40t/lihuiyu/loader.py +90 -90
  344. meerk40t/lihuiyu/parser.py +404 -404
  345. meerk40t/lihuiyu/plugin.py +101 -102
  346. meerk40t/lihuiyu/tcp_connection.py +111 -109
  347. meerk40t/main.py +231 -165
  348. meerk40t/moshi/builder.py +788 -781
  349. meerk40t/moshi/controller.py +505 -499
  350. meerk40t/moshi/device.py +495 -442
  351. meerk40t/moshi/driver.py +862 -696
  352. meerk40t/moshi/gui/gui.py +78 -76
  353. meerk40t/moshi/gui/moshicontrollergui.py +538 -522
  354. meerk40t/moshi/gui/moshidrivergui.py +87 -75
  355. meerk40t/moshi/plugin.py +43 -43
  356. meerk40t/network/console_server.py +102 -57
  357. meerk40t/network/kernelserver.py +10 -9
  358. meerk40t/network/tcp_server.py +142 -140
  359. meerk40t/network/udp_server.py +103 -77
  360. meerk40t/network/web_server.py +390 -0
  361. meerk40t/newly/controller.py +1158 -1144
  362. meerk40t/newly/device.py +874 -732
  363. meerk40t/newly/driver.py +540 -412
  364. meerk40t/newly/gui/gui.py +219 -188
  365. meerk40t/newly/gui/newlyconfig.py +116 -101
  366. meerk40t/newly/gui/newlycontroller.py +193 -186
  367. meerk40t/newly/gui/operationproperties.py +51 -51
  368. meerk40t/newly/mock_connection.py +82 -82
  369. meerk40t/newly/newly_params.py +56 -56
  370. meerk40t/newly/plugin.py +1214 -1246
  371. meerk40t/newly/usb_connection.py +322 -322
  372. meerk40t/rotary/gui/gui.py +52 -46
  373. meerk40t/rotary/gui/rotarysettings.py +240 -232
  374. meerk40t/rotary/rotary.py +202 -98
  375. meerk40t/ruida/control.py +291 -91
  376. meerk40t/ruida/controller.py +138 -1088
  377. meerk40t/ruida/device.py +672 -231
  378. meerk40t/ruida/driver.py +534 -472
  379. meerk40t/ruida/emulator.py +1494 -1491
  380. meerk40t/ruida/exceptions.py +4 -4
  381. meerk40t/ruida/gui/gui.py +71 -76
  382. meerk40t/ruida/gui/ruidaconfig.py +239 -72
  383. meerk40t/ruida/gui/ruidacontroller.py +187 -184
  384. meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
  385. meerk40t/ruida/loader.py +54 -52
  386. meerk40t/ruida/mock_connection.py +57 -109
  387. meerk40t/ruida/plugin.py +124 -87
  388. meerk40t/ruida/rdjob.py +2084 -945
  389. meerk40t/ruida/serial_connection.py +116 -0
  390. meerk40t/ruida/tcp_connection.py +146 -0
  391. meerk40t/ruida/udp_connection.py +73 -0
  392. meerk40t/svgelements.py +9671 -9669
  393. meerk40t/tools/driver_to_path.py +584 -579
  394. meerk40t/tools/geomstr.py +5583 -4680
  395. meerk40t/tools/jhfparser.py +357 -292
  396. meerk40t/tools/kerftest.py +904 -890
  397. meerk40t/tools/livinghinges.py +1168 -1033
  398. meerk40t/tools/pathtools.py +987 -949
  399. meerk40t/tools/pmatrix.py +234 -0
  400. meerk40t/tools/pointfinder.py +942 -942
  401. meerk40t/tools/polybool.py +940 -940
  402. meerk40t/tools/rasterplotter.py +1660 -547
  403. meerk40t/tools/shxparser.py +989 -901
  404. meerk40t/tools/ttfparser.py +726 -446
  405. meerk40t/tools/zinglplotter.py +595 -593
  406. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/LICENSE +21 -21
  407. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/METADATA +150 -139
  408. meerk40t-0.9.7010.dist-info/RECORD +445 -0
  409. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/WHEEL +1 -1
  410. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/top_level.txt +0 -1
  411. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/zip-safe +1 -1
  412. meerk40t/balormk/elementlightjob.py +0 -159
  413. meerk40t-0.9.3001.dist-info/RECORD +0 -437
  414. test/bootstrap.py +0 -63
  415. test/test_cli.py +0 -12
  416. test/test_core_cutcode.py +0 -418
  417. test/test_core_elements.py +0 -144
  418. test/test_core_plotplanner.py +0 -397
  419. test/test_core_viewports.py +0 -312
  420. test/test_drivers_grbl.py +0 -108
  421. test/test_drivers_lihuiyu.py +0 -443
  422. test/test_drivers_newly.py +0 -113
  423. test/test_element_degenerate_points.py +0 -43
  424. test/test_elements_classify.py +0 -97
  425. test/test_elements_penbox.py +0 -22
  426. test/test_file_svg.py +0 -176
  427. test/test_fill.py +0 -155
  428. test/test_geomstr.py +0 -1523
  429. test/test_geomstr_nodes.py +0 -18
  430. test/test_imagetools_actualize.py +0 -306
  431. test/test_imagetools_wizard.py +0 -258
  432. test/test_kernel.py +0 -200
  433. test/test_laser_speeds.py +0 -3303
  434. test/test_length.py +0 -57
  435. test/test_lifecycle.py +0 -66
  436. test/test_operations.py +0 -251
  437. test/test_operations_hatch.py +0 -57
  438. test/test_ruida.py +0 -19
  439. test/test_spooler.py +0 -22
  440. test/test_tools_rasterplotter.py +0 -29
  441. test/test_wobble.py +0 -133
  442. test/test_zingl.py +0 -124
  443. {test → meerk40t/cylinder}/__init__.py +0 -0
  444. /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
  445. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.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)