meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7020__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerk40t/__init__.py +1 -1
- meerk40t/balormk/balor_params.py +167 -167
- meerk40t/balormk/clone_loader.py +457 -457
- meerk40t/balormk/controller.py +1566 -1512
- meerk40t/balormk/cylindermod.py +64 -0
- meerk40t/balormk/device.py +966 -1959
- meerk40t/balormk/driver.py +778 -591
- meerk40t/balormk/galvo_commands.py +1194 -0
- meerk40t/balormk/gui/balorconfig.py +237 -111
- meerk40t/balormk/gui/balorcontroller.py +191 -184
- meerk40t/balormk/gui/baloroperationproperties.py +116 -115
- meerk40t/balormk/gui/corscene.py +845 -0
- meerk40t/balormk/gui/gui.py +179 -147
- meerk40t/balormk/livelightjob.py +466 -382
- meerk40t/balormk/mock_connection.py +131 -109
- meerk40t/balormk/plugin.py +133 -135
- meerk40t/balormk/usb_connection.py +306 -301
- meerk40t/camera/__init__.py +1 -1
- meerk40t/camera/camera.py +514 -397
- meerk40t/camera/gui/camerapanel.py +1241 -1095
- meerk40t/camera/gui/gui.py +58 -58
- meerk40t/camera/plugin.py +441 -399
- meerk40t/ch341/__init__.py +27 -27
- meerk40t/ch341/ch341device.py +628 -628
- meerk40t/ch341/libusb.py +595 -589
- meerk40t/ch341/mock.py +171 -171
- meerk40t/ch341/windriver.py +157 -157
- meerk40t/constants.py +13 -0
- meerk40t/core/__init__.py +1 -1
- meerk40t/core/bindalias.py +550 -539
- meerk40t/core/core.py +47 -47
- meerk40t/core/cutcode/cubiccut.py +73 -73
- meerk40t/core/cutcode/cutcode.py +315 -312
- meerk40t/core/cutcode/cutgroup.py +141 -137
- meerk40t/core/cutcode/cutobject.py +192 -185
- meerk40t/core/cutcode/dwellcut.py +37 -37
- meerk40t/core/cutcode/gotocut.py +29 -29
- meerk40t/core/cutcode/homecut.py +29 -29
- meerk40t/core/cutcode/inputcut.py +34 -34
- meerk40t/core/cutcode/linecut.py +33 -33
- meerk40t/core/cutcode/outputcut.py +34 -34
- meerk40t/core/cutcode/plotcut.py +335 -335
- meerk40t/core/cutcode/quadcut.py +61 -61
- meerk40t/core/cutcode/rastercut.py +168 -148
- meerk40t/core/cutcode/waitcut.py +34 -34
- meerk40t/core/cutplan.py +1843 -1316
- meerk40t/core/drivers.py +330 -329
- meerk40t/core/elements/align.py +801 -669
- meerk40t/core/elements/branches.py +1858 -1507
- meerk40t/core/elements/clipboard.py +229 -219
- meerk40t/core/elements/element_treeops.py +4595 -2837
- meerk40t/core/elements/element_types.py +125 -105
- meerk40t/core/elements/elements.py +4315 -3617
- meerk40t/core/elements/files.py +117 -64
- meerk40t/core/elements/geometry.py +473 -224
- meerk40t/core/elements/grid.py +467 -316
- meerk40t/core/elements/materials.py +158 -94
- meerk40t/core/elements/notes.py +50 -38
- meerk40t/core/elements/offset_clpr.py +934 -912
- meerk40t/core/elements/offset_mk.py +963 -955
- meerk40t/core/elements/penbox.py +339 -267
- meerk40t/core/elements/placements.py +300 -83
- meerk40t/core/elements/render.py +785 -687
- meerk40t/core/elements/shapes.py +2618 -2092
- meerk40t/core/elements/testcases.py +105 -0
- meerk40t/core/elements/trace.py +651 -563
- meerk40t/core/elements/tree_commands.py +415 -409
- meerk40t/core/elements/undo_redo.py +116 -58
- meerk40t/core/elements/wordlist.py +319 -200
- meerk40t/core/exceptions.py +9 -9
- meerk40t/core/laserjob.py +220 -220
- meerk40t/core/logging.py +63 -63
- meerk40t/core/node/blobnode.py +83 -86
- meerk40t/core/node/bootstrap.py +105 -103
- meerk40t/core/node/branch_elems.py +40 -31
- meerk40t/core/node/branch_ops.py +45 -38
- meerk40t/core/node/branch_regmark.py +48 -41
- meerk40t/core/node/cutnode.py +29 -32
- meerk40t/core/node/effect_hatch.py +375 -257
- meerk40t/core/node/effect_warp.py +398 -0
- meerk40t/core/node/effect_wobble.py +441 -309
- meerk40t/core/node/elem_ellipse.py +404 -309
- meerk40t/core/node/elem_image.py +1082 -801
- meerk40t/core/node/elem_line.py +358 -292
- meerk40t/core/node/elem_path.py +259 -201
- meerk40t/core/node/elem_point.py +129 -102
- meerk40t/core/node/elem_polyline.py +310 -246
- meerk40t/core/node/elem_rect.py +376 -286
- meerk40t/core/node/elem_text.py +445 -418
- meerk40t/core/node/filenode.py +59 -40
- meerk40t/core/node/groupnode.py +138 -74
- meerk40t/core/node/image_processed.py +777 -766
- meerk40t/core/node/image_raster.py +156 -113
- meerk40t/core/node/layernode.py +31 -31
- meerk40t/core/node/mixins.py +135 -107
- meerk40t/core/node/node.py +1427 -1304
- meerk40t/core/node/nutils.py +117 -114
- meerk40t/core/node/op_cut.py +463 -335
- meerk40t/core/node/op_dots.py +296 -251
- meerk40t/core/node/op_engrave.py +414 -311
- meerk40t/core/node/op_image.py +755 -369
- meerk40t/core/node/op_raster.py +787 -522
- meerk40t/core/node/place_current.py +37 -40
- meerk40t/core/node/place_point.py +329 -126
- meerk40t/core/node/refnode.py +58 -47
- meerk40t/core/node/rootnode.py +225 -219
- meerk40t/core/node/util_console.py +48 -48
- meerk40t/core/node/util_goto.py +84 -65
- meerk40t/core/node/util_home.py +61 -61
- meerk40t/core/node/util_input.py +102 -102
- meerk40t/core/node/util_output.py +102 -102
- meerk40t/core/node/util_wait.py +65 -65
- meerk40t/core/parameters.py +709 -707
- meerk40t/core/planner.py +875 -785
- meerk40t/core/plotplanner.py +656 -652
- meerk40t/core/space.py +120 -113
- meerk40t/core/spoolers.py +706 -705
- meerk40t/core/svg_io.py +1836 -1549
- meerk40t/core/treeop.py +534 -445
- meerk40t/core/undos.py +278 -124
- meerk40t/core/units.py +784 -680
- meerk40t/core/view.py +393 -322
- meerk40t/core/webhelp.py +62 -62
- meerk40t/core/wordlist.py +513 -504
- meerk40t/cylinder/cylinder.py +247 -0
- meerk40t/cylinder/gui/cylindersettings.py +41 -0
- meerk40t/cylinder/gui/gui.py +24 -0
- meerk40t/device/__init__.py +1 -1
- meerk40t/device/basedevice.py +322 -123
- meerk40t/device/devicechoices.py +50 -0
- meerk40t/device/dummydevice.py +163 -128
- meerk40t/device/gui/defaultactions.py +618 -602
- meerk40t/device/gui/effectspanel.py +114 -0
- meerk40t/device/gui/formatterpanel.py +253 -290
- meerk40t/device/gui/warningpanel.py +337 -260
- meerk40t/device/mixins.py +13 -13
- meerk40t/dxf/__init__.py +1 -1
- meerk40t/dxf/dxf_io.py +766 -554
- meerk40t/dxf/plugin.py +47 -35
- meerk40t/external_plugins.py +79 -79
- meerk40t/external_plugins_build.py +28 -28
- meerk40t/extra/cag.py +112 -116
- meerk40t/extra/coolant.py +403 -0
- meerk40t/extra/encode_detect.py +204 -0
- meerk40t/extra/ezd.py +1165 -1165
- meerk40t/extra/hershey.py +834 -340
- meerk40t/extra/imageactions.py +322 -316
- meerk40t/extra/inkscape.py +628 -622
- meerk40t/extra/lbrn.py +424 -424
- meerk40t/extra/outerworld.py +283 -0
- meerk40t/extra/param_functions.py +1542 -1556
- meerk40t/extra/potrace.py +257 -253
- meerk40t/extra/serial_exchange.py +118 -0
- meerk40t/extra/updater.py +602 -453
- meerk40t/extra/vectrace.py +147 -146
- meerk40t/extra/winsleep.py +83 -83
- meerk40t/extra/xcs_reader.py +597 -0
- meerk40t/fill/fills.py +781 -335
- meerk40t/fill/patternfill.py +1061 -1061
- meerk40t/fill/patterns.py +614 -567
- meerk40t/grbl/control.py +87 -87
- meerk40t/grbl/controller.py +990 -903
- meerk40t/grbl/device.py +1084 -768
- meerk40t/grbl/driver.py +989 -771
- meerk40t/grbl/emulator.py +532 -497
- meerk40t/grbl/gcodejob.py +783 -767
- meerk40t/grbl/gui/grblconfiguration.py +373 -298
- meerk40t/grbl/gui/grblcontroller.py +485 -271
- meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
- meerk40t/grbl/gui/grbloperationconfig.py +105 -0
- meerk40t/grbl/gui/gui.py +147 -116
- meerk40t/grbl/interpreter.py +44 -44
- meerk40t/grbl/loader.py +22 -22
- meerk40t/grbl/mock_connection.py +56 -56
- meerk40t/grbl/plugin.py +294 -264
- meerk40t/grbl/serial_connection.py +93 -88
- meerk40t/grbl/tcp_connection.py +81 -79
- meerk40t/grbl/ws_connection.py +112 -0
- meerk40t/gui/__init__.py +1 -1
- meerk40t/gui/about.py +2042 -296
- meerk40t/gui/alignment.py +1644 -1608
- meerk40t/gui/autoexec.py +199 -0
- meerk40t/gui/basicops.py +791 -670
- meerk40t/gui/bufferview.py +77 -71
- meerk40t/gui/busy.py +232 -133
- meerk40t/gui/choicepropertypanel.py +1662 -1469
- meerk40t/gui/consolepanel.py +706 -542
- meerk40t/gui/devicepanel.py +687 -581
- meerk40t/gui/dialogoptions.py +110 -107
- meerk40t/gui/executejob.py +316 -306
- meerk40t/gui/fonts.py +90 -90
- meerk40t/gui/functionwrapper.py +252 -0
- meerk40t/gui/gui_mixins.py +729 -0
- meerk40t/gui/guicolors.py +205 -182
- meerk40t/gui/help_assets/help_assets.py +218 -201
- meerk40t/gui/helper.py +154 -0
- meerk40t/gui/hersheymanager.py +1440 -846
- meerk40t/gui/icons.py +3422 -2747
- meerk40t/gui/imagesplitter.py +555 -508
- meerk40t/gui/keymap.py +354 -344
- meerk40t/gui/laserpanel.py +897 -806
- meerk40t/gui/laserrender.py +1470 -1232
- meerk40t/gui/lasertoolpanel.py +805 -793
- meerk40t/gui/magnetoptions.py +436 -0
- meerk40t/gui/materialmanager.py +2944 -0
- meerk40t/gui/materialtest.py +1722 -1694
- meerk40t/gui/mkdebug.py +646 -359
- meerk40t/gui/mwindow.py +163 -140
- meerk40t/gui/navigationpanels.py +2605 -2467
- meerk40t/gui/notes.py +143 -142
- meerk40t/gui/opassignment.py +414 -410
- meerk40t/gui/operation_info.py +310 -299
- meerk40t/gui/plugin.py +500 -328
- meerk40t/gui/position.py +714 -669
- meerk40t/gui/preferences.py +901 -650
- meerk40t/gui/propertypanels/attributes.py +1461 -1131
- meerk40t/gui/propertypanels/blobproperty.py +117 -114
- meerk40t/gui/propertypanels/consoleproperty.py +83 -80
- meerk40t/gui/propertypanels/gotoproperty.py +77 -0
- meerk40t/gui/propertypanels/groupproperties.py +223 -217
- meerk40t/gui/propertypanels/hatchproperty.py +489 -469
- meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
- meerk40t/gui/propertypanels/inputproperty.py +59 -58
- meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
- meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
- meerk40t/gui/propertypanels/outputproperty.py +59 -58
- meerk40t/gui/propertypanels/pathproperty.py +389 -380
- meerk40t/gui/propertypanels/placementproperty.py +1214 -383
- meerk40t/gui/propertypanels/pointproperty.py +140 -136
- meerk40t/gui/propertypanels/propertywindow.py +313 -181
- meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
- meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
- meerk40t/gui/propertypanels/textproperty.py +770 -755
- meerk40t/gui/propertypanels/waitproperty.py +56 -55
- meerk40t/gui/propertypanels/warpproperty.py +121 -0
- meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
- meerk40t/gui/ribbon.py +2471 -2210
- meerk40t/gui/scene/scene.py +1100 -1051
- meerk40t/gui/scene/sceneconst.py +22 -22
- meerk40t/gui/scene/scenepanel.py +439 -349
- meerk40t/gui/scene/scenespacewidget.py +365 -365
- meerk40t/gui/scene/widget.py +518 -505
- meerk40t/gui/scenewidgets/affinemover.py +215 -215
- meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
- meerk40t/gui/scenewidgets/bedwidget.py +120 -97
- meerk40t/gui/scenewidgets/elementswidget.py +137 -107
- meerk40t/gui/scenewidgets/gridwidget.py +785 -745
- meerk40t/gui/scenewidgets/guidewidget.py +765 -765
- meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
- meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
- meerk40t/gui/scenewidgets/nodeselector.py +28 -28
- meerk40t/gui/scenewidgets/rectselectwidget.py +592 -346
- meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
- meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
- meerk40t/gui/scenewidgets/selectionwidget.py +2958 -2756
- meerk40t/gui/simpleui.py +362 -333
- meerk40t/gui/simulation.py +2451 -2094
- meerk40t/gui/snapoptions.py +208 -203
- meerk40t/gui/spoolerpanel.py +1227 -1180
- meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
- meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
- meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
- meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
- meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
- meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
- meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
- meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
- meerk40t/gui/themes.py +200 -78
- meerk40t/gui/tips.py +590 -0
- meerk40t/gui/toolwidgets/circlebrush.py +35 -35
- meerk40t/gui/toolwidgets/toolcircle.py +248 -242
- meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
- meerk40t/gui/toolwidgets/tooldraw.py +97 -90
- meerk40t/gui/toolwidgets/toolellipse.py +219 -212
- meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
- meerk40t/gui/toolwidgets/toolline.py +39 -144
- meerk40t/gui/toolwidgets/toollinetext.py +79 -236
- meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
- meerk40t/gui/toolwidgets/toolmeasure.py +163 -216
- meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
- meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
- meerk40t/gui/toolwidgets/toolparameter.py +754 -668
- meerk40t/gui/toolwidgets/toolplacement.py +108 -108
- meerk40t/gui/toolwidgets/toolpoint.py +68 -59
- meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
- meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
- meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
- meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
- meerk40t/gui/toolwidgets/toolrect.py +211 -207
- meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
- meerk40t/gui/toolwidgets/toolribbon.py +598 -113
- meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
- meerk40t/gui/toolwidgets/tooltext.py +98 -89
- meerk40t/gui/toolwidgets/toolvector.py +213 -204
- meerk40t/gui/toolwidgets/toolwidget.py +39 -39
- meerk40t/gui/usbconnect.py +98 -91
- meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
- meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
- meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
- meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
- meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
- meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
- meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
- meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
- meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
- meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
- meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
- meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
- meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
- meerk40t/gui/wordlisteditor.py +985 -931
- meerk40t/gui/wxmeerk40t.py +1447 -1169
- meerk40t/gui/wxmmain.py +5644 -4112
- meerk40t/gui/wxmribbon.py +1591 -1076
- meerk40t/gui/wxmscene.py +1631 -1453
- meerk40t/gui/wxmtree.py +2416 -2089
- meerk40t/gui/wxutils.py +1769 -1099
- meerk40t/gui/zmatrix.py +102 -102
- meerk40t/image/__init__.py +1 -1
- meerk40t/image/dither.py +429 -0
- meerk40t/image/imagetools.py +2793 -2269
- meerk40t/internal_plugins.py +150 -130
- meerk40t/kernel/__init__.py +63 -12
- meerk40t/kernel/channel.py +259 -212
- meerk40t/kernel/context.py +538 -538
- meerk40t/kernel/exceptions.py +41 -41
- meerk40t/kernel/functions.py +463 -414
- meerk40t/kernel/jobs.py +100 -100
- meerk40t/kernel/kernel.py +3828 -3571
- meerk40t/kernel/lifecycles.py +71 -71
- meerk40t/kernel/module.py +49 -49
- meerk40t/kernel/service.py +147 -147
- meerk40t/kernel/settings.py +383 -343
- meerk40t/lihuiyu/controller.py +883 -876
- meerk40t/lihuiyu/device.py +1181 -1069
- meerk40t/lihuiyu/driver.py +1466 -1372
- meerk40t/lihuiyu/gui/gui.py +127 -106
- meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
- meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
- meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
- meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
- meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
- meerk40t/lihuiyu/interpreter.py +53 -53
- meerk40t/lihuiyu/laserspeed.py +450 -450
- meerk40t/lihuiyu/loader.py +90 -90
- meerk40t/lihuiyu/parser.py +404 -404
- meerk40t/lihuiyu/plugin.py +101 -102
- meerk40t/lihuiyu/tcp_connection.py +111 -109
- meerk40t/main.py +231 -165
- meerk40t/moshi/builder.py +788 -781
- meerk40t/moshi/controller.py +505 -499
- meerk40t/moshi/device.py +495 -442
- meerk40t/moshi/driver.py +862 -696
- meerk40t/moshi/gui/gui.py +78 -76
- meerk40t/moshi/gui/moshicontrollergui.py +538 -522
- meerk40t/moshi/gui/moshidrivergui.py +87 -75
- meerk40t/moshi/plugin.py +43 -43
- meerk40t/network/console_server.py +140 -57
- meerk40t/network/kernelserver.py +10 -9
- meerk40t/network/tcp_server.py +142 -140
- meerk40t/network/udp_server.py +103 -77
- meerk40t/network/web_server.py +404 -0
- meerk40t/newly/controller.py +1158 -1144
- meerk40t/newly/device.py +874 -732
- meerk40t/newly/driver.py +540 -412
- meerk40t/newly/gui/gui.py +219 -188
- meerk40t/newly/gui/newlyconfig.py +116 -101
- meerk40t/newly/gui/newlycontroller.py +193 -186
- meerk40t/newly/gui/operationproperties.py +51 -51
- meerk40t/newly/mock_connection.py +82 -82
- meerk40t/newly/newly_params.py +56 -56
- meerk40t/newly/plugin.py +1214 -1246
- meerk40t/newly/usb_connection.py +322 -322
- meerk40t/rotary/gui/gui.py +52 -46
- meerk40t/rotary/gui/rotarysettings.py +240 -232
- meerk40t/rotary/rotary.py +202 -98
- meerk40t/ruida/control.py +291 -91
- meerk40t/ruida/controller.py +138 -1088
- meerk40t/ruida/device.py +676 -231
- meerk40t/ruida/driver.py +534 -472
- meerk40t/ruida/emulator.py +1494 -1491
- meerk40t/ruida/exceptions.py +4 -4
- meerk40t/ruida/gui/gui.py +71 -76
- meerk40t/ruida/gui/ruidaconfig.py +239 -72
- meerk40t/ruida/gui/ruidacontroller.py +187 -184
- meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
- meerk40t/ruida/loader.py +54 -52
- meerk40t/ruida/mock_connection.py +57 -109
- meerk40t/ruida/plugin.py +124 -87
- meerk40t/ruida/rdjob.py +2084 -945
- meerk40t/ruida/serial_connection.py +116 -0
- meerk40t/ruida/tcp_connection.py +146 -0
- meerk40t/ruida/udp_connection.py +73 -0
- meerk40t/svgelements.py +9671 -9669
- meerk40t/tools/driver_to_path.py +584 -579
- meerk40t/tools/geomstr.py +5583 -4680
- meerk40t/tools/jhfparser.py +357 -292
- meerk40t/tools/kerftest.py +904 -890
- meerk40t/tools/livinghinges.py +1168 -1033
- meerk40t/tools/pathtools.py +987 -949
- meerk40t/tools/pmatrix.py +234 -0
- meerk40t/tools/pointfinder.py +942 -942
- meerk40t/tools/polybool.py +941 -940
- meerk40t/tools/rasterplotter.py +1660 -547
- meerk40t/tools/shxparser.py +1047 -901
- meerk40t/tools/ttfparser.py +726 -446
- meerk40t/tools/zinglplotter.py +595 -593
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/LICENSE +21 -21
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/METADATA +150 -139
- meerk40t-0.9.7020.dist-info/RECORD +446 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/WHEEL +1 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/top_level.txt +0 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/zip-safe +1 -1
- meerk40t/balormk/elementlightjob.py +0 -159
- meerk40t-0.9.3001.dist-info/RECORD +0 -437
- test/bootstrap.py +0 -63
- test/test_cli.py +0 -12
- test/test_core_cutcode.py +0 -418
- test/test_core_elements.py +0 -144
- test/test_core_plotplanner.py +0 -397
- test/test_core_viewports.py +0 -312
- test/test_drivers_grbl.py +0 -108
- test/test_drivers_lihuiyu.py +0 -443
- test/test_drivers_newly.py +0 -113
- test/test_element_degenerate_points.py +0 -43
- test/test_elements_classify.py +0 -97
- test/test_elements_penbox.py +0 -22
- test/test_file_svg.py +0 -176
- test/test_fill.py +0 -155
- test/test_geomstr.py +0 -1523
- test/test_geomstr_nodes.py +0 -18
- test/test_imagetools_actualize.py +0 -306
- test/test_imagetools_wizard.py +0 -258
- test/test_kernel.py +0 -200
- test/test_laser_speeds.py +0 -3303
- test/test_length.py +0 -57
- test/test_lifecycle.py +0 -66
- test/test_operations.py +0 -251
- test/test_operations_hatch.py +0 -57
- test/test_ruida.py +0 -19
- test/test_spooler.py +0 -22
- test/test_tools_rasterplotter.py +0 -29
- test/test_wobble.py +0 -133
- test/test_zingl.py +0 -124
- {test → meerk40t/cylinder}/__init__.py +0 -0
- /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/entry_points.txt +0 -0
meerk40t/grbl/driver.py
CHANGED
@@ -1,771 +1,989 @@
|
|
1
|
-
"""
|
2
|
-
GRBL Driver
|
3
|
-
|
4
|
-
Governs the generic commands issued by laserjob and spooler and converts that into regular GRBL Gcode output.
|
5
|
-
"""
|
6
|
-
|
7
|
-
import time
|
8
|
-
|
9
|
-
from meerk40t.core.cutcode.cubiccut import CubicCut
|
10
|
-
from meerk40t.core.cutcode.dwellcut import DwellCut
|
11
|
-
from meerk40t.core.cutcode.gotocut import GotoCut
|
12
|
-
from meerk40t.core.cutcode.homecut import HomeCut
|
13
|
-
from meerk40t.core.cutcode.inputcut import InputCut
|
14
|
-
from meerk40t.core.cutcode.linecut import LineCut
|
15
|
-
from meerk40t.core.cutcode.outputcut import OutputCut
|
16
|
-
from meerk40t.core.cutcode.plotcut import PlotCut
|
17
|
-
from meerk40t.core.cutcode.quadcut import QuadCut
|
18
|
-
from meerk40t.core.cutcode.waitcut import WaitCut
|
19
|
-
|
20
|
-
from ..core.parameters import Parameters
|
21
|
-
from ..core.plotplanner import PlotPlanner
|
22
|
-
from ..core.units import UNITS_PER_INCH, UNITS_PER_MIL, UNITS_PER_MM
|
23
|
-
from ..device.basedevice import PLOT_FINISH, PLOT_JOG, PLOT_RAPID, PLOT_SETTING
|
24
|
-
from ..kernel import signal_listener
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
self.
|
32
|
-
self.
|
33
|
-
self.
|
34
|
-
self.
|
35
|
-
self.
|
36
|
-
self.
|
37
|
-
|
38
|
-
|
39
|
-
self.
|
40
|
-
self.
|
41
|
-
|
42
|
-
|
43
|
-
self.
|
44
|
-
self.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
self.
|
53
|
-
|
54
|
-
self.
|
55
|
-
self.
|
56
|
-
|
57
|
-
self.
|
58
|
-
self.
|
59
|
-
self.
|
60
|
-
|
61
|
-
|
62
|
-
self.
|
63
|
-
self.
|
64
|
-
self.
|
65
|
-
self.
|
66
|
-
|
67
|
-
self.
|
68
|
-
self.
|
69
|
-
self.
|
70
|
-
self.
|
71
|
-
|
72
|
-
self.
|
73
|
-
self.
|
74
|
-
|
75
|
-
self.
|
76
|
-
|
77
|
-
self.
|
78
|
-
self.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
"""
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
@param key:
|
133
|
-
@param value
|
134
|
-
@return:
|
135
|
-
"""
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
"""
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
self.
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
self.
|
202
|
-
self.
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
self.
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
self
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
self.
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
self._move(
|
297
|
-
|
298
|
-
self.
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
self.
|
309
|
-
|
310
|
-
self.
|
311
|
-
|
312
|
-
self.
|
313
|
-
|
314
|
-
|
315
|
-
self.
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
self.
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
self.
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
self.
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
self.
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
@
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
""
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
self.
|
548
|
-
self.
|
549
|
-
|
550
|
-
self.
|
551
|
-
self.
|
552
|
-
self.
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
@param
|
561
|
-
@
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
self.service.
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
self
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
def
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
self.
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
def
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
self.
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
self.
|
754
|
-
self
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
1
|
+
"""
|
2
|
+
GRBL Driver
|
3
|
+
|
4
|
+
Governs the generic commands issued by laserjob and spooler and converts that into regular GRBL Gcode output.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import time
|
8
|
+
|
9
|
+
from meerk40t.core.cutcode.cubiccut import CubicCut
|
10
|
+
from meerk40t.core.cutcode.dwellcut import DwellCut
|
11
|
+
from meerk40t.core.cutcode.gotocut import GotoCut
|
12
|
+
from meerk40t.core.cutcode.homecut import HomeCut
|
13
|
+
from meerk40t.core.cutcode.inputcut import InputCut
|
14
|
+
from meerk40t.core.cutcode.linecut import LineCut
|
15
|
+
from meerk40t.core.cutcode.outputcut import OutputCut
|
16
|
+
from meerk40t.core.cutcode.plotcut import PlotCut
|
17
|
+
from meerk40t.core.cutcode.quadcut import QuadCut
|
18
|
+
from meerk40t.core.cutcode.waitcut import WaitCut
|
19
|
+
|
20
|
+
from ..core.parameters import Parameters
|
21
|
+
from ..core.plotplanner import PlotPlanner
|
22
|
+
from ..core.units import UNITS_PER_INCH, UNITS_PER_MIL, UNITS_PER_MM, Length
|
23
|
+
from ..device.basedevice import PLOT_FINISH, PLOT_JOG, PLOT_RAPID, PLOT_SETTING
|
24
|
+
from ..kernel import signal_listener
|
25
|
+
from ..tools.geomstr import Geomstr
|
26
|
+
|
27
|
+
|
28
|
+
class GRBLDriver(Parameters):
|
29
|
+
def __init__(self, service, **kwargs):
|
30
|
+
super().__init__(**kwargs)
|
31
|
+
self.service = service
|
32
|
+
self.name = str(service)
|
33
|
+
self.line_end = None
|
34
|
+
self._set_line_end()
|
35
|
+
self.paused = False
|
36
|
+
self.native_x = 0
|
37
|
+
self.native_y = 0
|
38
|
+
|
39
|
+
self.mpos_x = 0
|
40
|
+
self.mpos_y = 0
|
41
|
+
self.mpos_z = 0
|
42
|
+
|
43
|
+
self.wpos_x = 0
|
44
|
+
self.wpos_y = 0
|
45
|
+
self.wpos_z = 0
|
46
|
+
|
47
|
+
self.stepper_step_size = UNITS_PER_MIL
|
48
|
+
|
49
|
+
self.plot_planner = PlotPlanner(
|
50
|
+
self.settings, single=True, ppi=False, shift=False, group=True, require_uniform_movement = False,
|
51
|
+
)
|
52
|
+
self.queue = []
|
53
|
+
self._queue_current = 0
|
54
|
+
self._queue_total = 0
|
55
|
+
self.plot_data = None
|
56
|
+
|
57
|
+
self.on_value = 0
|
58
|
+
self.power_dirty = True
|
59
|
+
self.speed_dirty = True
|
60
|
+
# Zaxis should not be used by default, so we set the dirty flag to False
|
61
|
+
self.zaxis_dirty = False
|
62
|
+
self.absolute_dirty = True
|
63
|
+
self.feedrate_dirty = True
|
64
|
+
self.units_dirty = True
|
65
|
+
self.move_mode = 0
|
66
|
+
|
67
|
+
self._absolute = True
|
68
|
+
self.feed_mode = None
|
69
|
+
self.feed_convert = None
|
70
|
+
self._g94_feedrate() # G94 DEFAULT, mm mode
|
71
|
+
|
72
|
+
self.unit_scale = None
|
73
|
+
self.units = None
|
74
|
+
self._g21_units_mm()
|
75
|
+
self._g90_absolute()
|
76
|
+
|
77
|
+
self.out_pipe = None
|
78
|
+
self.out_real = None
|
79
|
+
|
80
|
+
self.reply = None
|
81
|
+
self.elements = None
|
82
|
+
self.power_scale = 1.0
|
83
|
+
self.speed_scale = 1.0
|
84
|
+
self._signal_updates = self.service.setting(bool, "signal_updates", True)
|
85
|
+
|
86
|
+
def __repr__(self):
|
87
|
+
return f"GRBLDriver({self.name})"
|
88
|
+
|
89
|
+
def __call__(self, e, real=False):
|
90
|
+
if real:
|
91
|
+
self.out_real(e)
|
92
|
+
else:
|
93
|
+
self.out_pipe(e)
|
94
|
+
|
95
|
+
def get_internal_queue_status(self):
|
96
|
+
return self._queue_current, self._queue_total
|
97
|
+
|
98
|
+
def _set_queue_status(self, current, total):
|
99
|
+
self._queue_current = current
|
100
|
+
self._queue_total = total
|
101
|
+
|
102
|
+
@signal_listener("line_end")
|
103
|
+
def _set_line_end(self, origin=None, *args):
|
104
|
+
line_end = self.service.setting(str, "line_end", "CR")
|
105
|
+
line_end = line_end.replace(" ", "")
|
106
|
+
line_end = line_end.replace("CR", "\r")
|
107
|
+
line_end = line_end.replace("LF", "\n")
|
108
|
+
self.line_end = line_end
|
109
|
+
|
110
|
+
def hold_work(self, priority):
|
111
|
+
"""
|
112
|
+
Required.
|
113
|
+
|
114
|
+
Spooler check. to see if the work cycle should be held.
|
115
|
+
|
116
|
+
@return: hold?
|
117
|
+
"""
|
118
|
+
if priority > 0:
|
119
|
+
# Don't hold realtime work.
|
120
|
+
return False
|
121
|
+
if (
|
122
|
+
self.service.limit_buffer
|
123
|
+
and len(self.service.controller) > self.service.max_buffer
|
124
|
+
):
|
125
|
+
return True
|
126
|
+
return self.paused
|
127
|
+
|
128
|
+
def get(self, key, default=None):
|
129
|
+
"""
|
130
|
+
Required.
|
131
|
+
|
132
|
+
@param key: Key to get.
|
133
|
+
@param default: Default value to use.
|
134
|
+
@return:
|
135
|
+
"""
|
136
|
+
return self.settings.get(key, default=default)
|
137
|
+
|
138
|
+
def set(self, key, value):
|
139
|
+
"""
|
140
|
+
Required.
|
141
|
+
|
142
|
+
Sets a laser parameter this could be speed, power, wobble, number_of_unicorns, or any unknown parameters for
|
143
|
+
yet to be written drivers.
|
144
|
+
|
145
|
+
@param key:
|
146
|
+
@param value:
|
147
|
+
@return:
|
148
|
+
"""
|
149
|
+
if key == "power":
|
150
|
+
self.power_dirty = True
|
151
|
+
if key == "speed":
|
152
|
+
self.speed_dirty = True
|
153
|
+
self.settings[key] = value
|
154
|
+
|
155
|
+
def status(self):
|
156
|
+
"""
|
157
|
+
Wants a status report of what the driver is doing.
|
158
|
+
@return:
|
159
|
+
"""
|
160
|
+
# TODO: To calculate status correctly we need to actually have access to the response
|
161
|
+
self.out_real("?")
|
162
|
+
return (self.native_x, self.native_y), "idle", "unknown"
|
163
|
+
|
164
|
+
def move_abs(self, x, y):
|
165
|
+
"""
|
166
|
+
Requests laser move to absolute position x, y in physical units
|
167
|
+
|
168
|
+
@param x:
|
169
|
+
@param y:
|
170
|
+
@return:
|
171
|
+
"""
|
172
|
+
self._g90_absolute()
|
173
|
+
self._clean()
|
174
|
+
old_current = self.service.current
|
175
|
+
x, y = self.service.view.position(x, y)
|
176
|
+
self._move(x, y)
|
177
|
+
new_current = self.service.current
|
178
|
+
if self._signal_updates:
|
179
|
+
self.service.signal(
|
180
|
+
"driver;position",
|
181
|
+
(old_current[0], old_current[1], new_current[0], new_current[1]),
|
182
|
+
)
|
183
|
+
|
184
|
+
def move_rel(self, dx, dy):
|
185
|
+
"""
|
186
|
+
Requests laser move relative position dx, dy in physical units
|
187
|
+
|
188
|
+
@param dx:
|
189
|
+
@param dy:
|
190
|
+
@return:
|
191
|
+
"""
|
192
|
+
# self._g90_absolute()
|
193
|
+
# self._clean()
|
194
|
+
# old_current = self.service.current
|
195
|
+
# x, y = old_current
|
196
|
+
# x += dx
|
197
|
+
# y += dy
|
198
|
+
# x, y = self.service.view.position(x, y)
|
199
|
+
# self._move(x, y)
|
200
|
+
|
201
|
+
self._g91_relative()
|
202
|
+
self._clean()
|
203
|
+
old_current = self.service.current
|
204
|
+
|
205
|
+
unit_dx, unit_dy = self.service.view.position(dx, dy, vector=True)
|
206
|
+
self._move(unit_dx, unit_dy)
|
207
|
+
|
208
|
+
new_current = self.service.current
|
209
|
+
if self._signal_updates:
|
210
|
+
self.service.signal(
|
211
|
+
"driver;position",
|
212
|
+
(old_current[0], old_current[1], new_current[0], new_current[1]),
|
213
|
+
)
|
214
|
+
|
215
|
+
def dwell(self, time_in_ms):
|
216
|
+
"""
|
217
|
+
Requests that the laser fire in place for the given time period. This could be done in a series of commands,
|
218
|
+
move to a location, turn laser on, wait, turn laser off. However, some drivers have specific laser-in-place
|
219
|
+
commands so calling dwell is preferred.
|
220
|
+
|
221
|
+
@param time_in_ms:
|
222
|
+
@return:
|
223
|
+
"""
|
224
|
+
self.laser_on() # This can't be sent early since these are timed operations.
|
225
|
+
self.wait(time_in_ms)
|
226
|
+
self.laser_off()
|
227
|
+
|
228
|
+
def laser_off(self, power=0, *values):
|
229
|
+
"""
|
230
|
+
Turn laser off in place.
|
231
|
+
|
232
|
+
@param power: Power after laser turn off (0=default).
|
233
|
+
@param values:
|
234
|
+
@return:
|
235
|
+
"""
|
236
|
+
if power is not None:
|
237
|
+
spower = f" S{power:.1f}"
|
238
|
+
self.power = power
|
239
|
+
self.power_dirty = False
|
240
|
+
self(f"G1 {spower}{self.line_end}")
|
241
|
+
self(f"M5{self.line_end}")
|
242
|
+
|
243
|
+
def laser_on(self, power=None, speed=None, *values):
|
244
|
+
"""
|
245
|
+
Turn laser on in place. This is done specifically with an M3 command so that the laser is on while stationary
|
246
|
+
|
247
|
+
@param speed: Speed for laser turn on.
|
248
|
+
@param power: Power at the laser turn on.
|
249
|
+
@param values:
|
250
|
+
@return:
|
251
|
+
"""
|
252
|
+
spower = ""
|
253
|
+
sspeed = ""
|
254
|
+
if power is not None:
|
255
|
+
spower = f" S{power:.1f}"
|
256
|
+
# We already established power, so no need for power_dirty
|
257
|
+
self.power = power
|
258
|
+
self.power_dirty = False
|
259
|
+
if speed is not None:
|
260
|
+
sspeed = f"G1 F{speed}{self.line_end}"
|
261
|
+
self.speed = speed
|
262
|
+
self.speed_dirty = False
|
263
|
+
self(f"M3{spower}{self.line_end}{sspeed}")
|
264
|
+
|
265
|
+
def geometry(self, geom):
|
266
|
+
"""
|
267
|
+
Called at the end of plot commands to ensure the driver can deal with them all as a group.
|
268
|
+
|
269
|
+
@return:
|
270
|
+
"""
|
271
|
+
# TODO: estop cannot clear the geom.
|
272
|
+
self.signal("grbl_red_dot", False) # We are not using red-dot if we're cutting.
|
273
|
+
self.clear_states()
|
274
|
+
self._g90_absolute()
|
275
|
+
self._g94_feedrate()
|
276
|
+
self._clean()
|
277
|
+
if self.service.use_m3:
|
278
|
+
self(f"M3{self.line_end}")
|
279
|
+
else:
|
280
|
+
self(f"M4{self.line_end}")
|
281
|
+
first = True
|
282
|
+
g = Geomstr()
|
283
|
+
for segment_type, start, c1, c2, end, sets in geom.as_lines():
|
284
|
+
while self.hold_work(0):
|
285
|
+
if self.service.kernel.is_shutdown:
|
286
|
+
return
|
287
|
+
time.sleep(0.05)
|
288
|
+
x = self.native_x
|
289
|
+
y = self.native_y
|
290
|
+
start_x, start_y = start.real, start.imag
|
291
|
+
if x != start_x or y != start_y or first:
|
292
|
+
self.on_value = 0
|
293
|
+
self.power_dirty = True
|
294
|
+
self.move_mode = 0
|
295
|
+
first = False
|
296
|
+
self._move(start_x, start_y)
|
297
|
+
if self.on_value != 1.0:
|
298
|
+
self.power_dirty = True
|
299
|
+
self.on_value = 1.0
|
300
|
+
# Default-Values?!
|
301
|
+
qpower = sets.get("power", self.power)
|
302
|
+
qspeed = sets.get("speed", self.speed)
|
303
|
+
qraster_step_x = sets.get("raster_step_x")
|
304
|
+
qraster_step_y = sets.get("raster_step_y")
|
305
|
+
if qpower != self.power:
|
306
|
+
self.set("power", qpower)
|
307
|
+
if (
|
308
|
+
qspeed != self.speed
|
309
|
+
or qraster_step_x != self.raster_step_x
|
310
|
+
or qraster_step_y != self.raster_step_y
|
311
|
+
):
|
312
|
+
self.set("speed", qspeed)
|
313
|
+
self.settings.update(sets)
|
314
|
+
if segment_type == "line":
|
315
|
+
self.move_mode = 1
|
316
|
+
self._move(end.real, end.imag)
|
317
|
+
elif segment_type == "end":
|
318
|
+
self.on_value = 0
|
319
|
+
self.power_dirty = True
|
320
|
+
self.move_mode = 0
|
321
|
+
first = False
|
322
|
+
elif segment_type == "quad":
|
323
|
+
self.move_mode = 1
|
324
|
+
interp = self.service.interp
|
325
|
+
g.clear()
|
326
|
+
g.quad(complex(start), complex(c1), complex(end))
|
327
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
328
|
+
while self.paused:
|
329
|
+
time.sleep(0.05)
|
330
|
+
self._move(p.real, p.imag)
|
331
|
+
elif segment_type == "cubic":
|
332
|
+
self.move_mode = 1
|
333
|
+
interp = self.service.interp
|
334
|
+
g.clear()
|
335
|
+
g.cubic(
|
336
|
+
complex(start),
|
337
|
+
complex(c1),
|
338
|
+
complex(c2),
|
339
|
+
complex(end),
|
340
|
+
)
|
341
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
342
|
+
while self.paused:
|
343
|
+
time.sleep(0.05)
|
344
|
+
self._move(p.real, p.imag)
|
345
|
+
elif segment_type == "arc":
|
346
|
+
# TODO: Allow arcs to be directly executed by GRBL which can actually use them.
|
347
|
+
self.move_mode = 1
|
348
|
+
interp = self.service.interp
|
349
|
+
g.clear()
|
350
|
+
g.arc(
|
351
|
+
complex(start),
|
352
|
+
complex(c1),
|
353
|
+
complex(end),
|
354
|
+
)
|
355
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
356
|
+
while self.paused:
|
357
|
+
time.sleep(0.05)
|
358
|
+
self._move(p.real, p.imag)
|
359
|
+
elif segment_type == "point":
|
360
|
+
function = sets.get("function")
|
361
|
+
if function == "dwell":
|
362
|
+
self.dwell(sets.get("dwell_time"))
|
363
|
+
elif function == "wait":
|
364
|
+
self.wait(sets.get("dwell_time"))
|
365
|
+
elif function == "home":
|
366
|
+
self.home()
|
367
|
+
elif function == "goto":
|
368
|
+
self._move(start.real, start.imag)
|
369
|
+
elif function == "input":
|
370
|
+
# GRBL has no core GPIO functionality
|
371
|
+
pass
|
372
|
+
elif function == "output":
|
373
|
+
# GRBL has no core GPIO functionality
|
374
|
+
pass
|
375
|
+
self(f"G1 S0{self.line_end}")
|
376
|
+
self(f"M5{self.line_end}")
|
377
|
+
self.clear_states()
|
378
|
+
self.wait_finish()
|
379
|
+
return False
|
380
|
+
|
381
|
+
def plot(self, plot):
|
382
|
+
"""
|
383
|
+
Gives the driver a bit of cutcode that should be plotted.
|
384
|
+
@param plot:
|
385
|
+
@return:
|
386
|
+
"""
|
387
|
+
self.queue.append(plot)
|
388
|
+
|
389
|
+
def plot_start(self):
|
390
|
+
"""
|
391
|
+
Called at the end of plot commands to ensure the driver can deal with them all as a group.
|
392
|
+
|
393
|
+
@return:
|
394
|
+
"""
|
395
|
+
self.signal("grbl_red_dot", False) # We are not using red-dot if we're cutting.
|
396
|
+
self.clear_states()
|
397
|
+
self._g90_absolute()
|
398
|
+
self._g94_feedrate()
|
399
|
+
self._clean()
|
400
|
+
if self.service.use_m3:
|
401
|
+
self(f"M3{self.line_end}")
|
402
|
+
else:
|
403
|
+
self(f"M4{self.line_end}")
|
404
|
+
first = True
|
405
|
+
total = len(self.queue)
|
406
|
+
current = 0
|
407
|
+
for q in self.queue:
|
408
|
+
# Are there any custom commands to be executed?
|
409
|
+
# Usecase (as described in issue https://github.com/meerk40t/meerk40t/issues/2764 ):
|
410
|
+
# Switch between M3 and M4 mode for cut / raster
|
411
|
+
# M3=used to cut as gantry acceleration doesn't matter on a cut.
|
412
|
+
# M4=used for Raster/Engrave operations, as grblHAL will
|
413
|
+
# adjust power based on gantry speed including acceleration.
|
414
|
+
|
415
|
+
cmd_string = q.settings.get("custom_commands", "")
|
416
|
+
if cmd_string:
|
417
|
+
for cmd in cmd_string.splitlines():
|
418
|
+
self(f"{cmd}{self.line_end}")
|
419
|
+
|
420
|
+
current += 1
|
421
|
+
self._set_queue_status(current, total)
|
422
|
+
while self.hold_work(0):
|
423
|
+
if self.service.kernel.is_shutdown:
|
424
|
+
return
|
425
|
+
time.sleep(0.05)
|
426
|
+
x = self.native_x
|
427
|
+
y = self.native_y
|
428
|
+
start_x, start_y = q.start
|
429
|
+
if x != start_x or y != start_y or first:
|
430
|
+
self.on_value = 0
|
431
|
+
self.power_dirty = True
|
432
|
+
self.move_mode = 0
|
433
|
+
first = False
|
434
|
+
self._move(start_x, start_y)
|
435
|
+
if self.on_value != 1.0:
|
436
|
+
self.power_dirty = True
|
437
|
+
self.on_value = 1.0
|
438
|
+
# Do we have a custom z-Value?
|
439
|
+
# NB: zaxis is not a property inside Parameters like power/or speed
|
440
|
+
# so we need to deal with it more directly
|
441
|
+
# (e.g. self.power is the equivalent to self.settings.["power"]))
|
442
|
+
qzaxis = q.settings.get("zaxis", self.zaxis)
|
443
|
+
if qzaxis != self.zaxis:
|
444
|
+
self.zaxis = qzaxis
|
445
|
+
self.zaxis_dirty = True
|
446
|
+
# Default-Values?!
|
447
|
+
qpower = q.settings.get("power", self.power)
|
448
|
+
qspeed = q.settings.get("speed", self.speed)
|
449
|
+
qraster_step_x = q.settings.get("raster_step_x")
|
450
|
+
qraster_step_y = q.settings.get("raster_step_y")
|
451
|
+
if qpower != self.power:
|
452
|
+
self.set("power", qpower)
|
453
|
+
if (
|
454
|
+
qspeed != self.speed
|
455
|
+
or qraster_step_x != self.raster_step_x
|
456
|
+
or qraster_step_y != self.raster_step_y
|
457
|
+
):
|
458
|
+
self.set("speed", qspeed)
|
459
|
+
self.settings.update(q.settings)
|
460
|
+
if isinstance(q, LineCut):
|
461
|
+
self.move_mode = 1
|
462
|
+
self._move(*q.end)
|
463
|
+
elif isinstance(q, QuadCut):
|
464
|
+
self.move_mode = 1
|
465
|
+
interp = self.service.interp
|
466
|
+
g = Geomstr()
|
467
|
+
g.quad(complex(*q.start), complex(*q.c()), complex(*q.end))
|
468
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
469
|
+
while self.paused:
|
470
|
+
time.sleep(0.05)
|
471
|
+
self._move(p.real, p.imag)
|
472
|
+
elif isinstance(q, CubicCut):
|
473
|
+
self.move_mode = 1
|
474
|
+
interp = self.service.interp
|
475
|
+
g = Geomstr()
|
476
|
+
g.cubic(
|
477
|
+
complex(*q.start),
|
478
|
+
complex(*q.c1()),
|
479
|
+
complex(*q.c2()),
|
480
|
+
complex(*q.end),
|
481
|
+
)
|
482
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
483
|
+
while self.paused:
|
484
|
+
time.sleep(0.05)
|
485
|
+
self._move(p.real, p.imag)
|
486
|
+
elif isinstance(q, WaitCut):
|
487
|
+
self.wait(q.dwell_time)
|
488
|
+
elif isinstance(q, HomeCut):
|
489
|
+
self.home()
|
490
|
+
elif isinstance(q, GotoCut):
|
491
|
+
start = q.start
|
492
|
+
self._move(start[0], start[1])
|
493
|
+
elif isinstance(q, DwellCut):
|
494
|
+
self.dwell(q.dwell_time)
|
495
|
+
elif isinstance(q, (InputCut, OutputCut)):
|
496
|
+
# GRBL has no core GPIO functionality
|
497
|
+
pass
|
498
|
+
elif isinstance(q, PlotCut):
|
499
|
+
self.move_mode = 1
|
500
|
+
self.set("power", 1000)
|
501
|
+
for ox, oy, on, x, y in q.plot:
|
502
|
+
while self.hold_work(0):
|
503
|
+
time.sleep(0.05)
|
504
|
+
# q.plot can have different on values, these are parsed
|
505
|
+
if self.on_value != on:
|
506
|
+
self.power_dirty = True
|
507
|
+
self.on_value = on
|
508
|
+
self._move(x, y)
|
509
|
+
else:
|
510
|
+
# Rastercut
|
511
|
+
self.plot_planner.push(q)
|
512
|
+
self.move_mode = 1
|
513
|
+
for x, y, on in self.plot_planner.gen():
|
514
|
+
while self.hold_work(0):
|
515
|
+
time.sleep(0.05)
|
516
|
+
if on > 1:
|
517
|
+
# Special Command.
|
518
|
+
if isinstance(on, float):
|
519
|
+
on = int(on)
|
520
|
+
if on & PLOT_FINISH: # Plot planner is ending.
|
521
|
+
break
|
522
|
+
elif on & PLOT_SETTING: # Plot planner settings have changed.
|
523
|
+
p_set = Parameters(self.plot_planner.settings)
|
524
|
+
if p_set.power != self.power:
|
525
|
+
self.set("power", p_set.power)
|
526
|
+
if (
|
527
|
+
p_set.speed != self.speed
|
528
|
+
or p_set.raster_step_x != self.raster_step_x
|
529
|
+
or p_set.raster_step_y != self.raster_step_y
|
530
|
+
):
|
531
|
+
self.set("speed", p_set.speed)
|
532
|
+
self.settings.update(p_set.settings)
|
533
|
+
elif on & (
|
534
|
+
PLOT_RAPID | PLOT_JOG
|
535
|
+
): # Plot planner requests position change.
|
536
|
+
# self.move_mode = 0
|
537
|
+
self._move(x, y)
|
538
|
+
continue
|
539
|
+
# if on == 0:
|
540
|
+
# self.move_mode = 0
|
541
|
+
# else:
|
542
|
+
# self.move_mode = 1
|
543
|
+
if self.on_value != on:
|
544
|
+
self.power_dirty = True
|
545
|
+
self.on_value = on
|
546
|
+
self._move(x, y)
|
547
|
+
self.queue.clear()
|
548
|
+
self._set_queue_status(0, 0)
|
549
|
+
|
550
|
+
self(f"G1 S0{self.line_end}")
|
551
|
+
self(f"M5{self.line_end}")
|
552
|
+
self.clear_states()
|
553
|
+
self.wait_finish()
|
554
|
+
return False
|
555
|
+
|
556
|
+
def blob(self, data_type, data):
|
557
|
+
"""
|
558
|
+
This is intended to send a blob of gcode to be processed and executed.
|
559
|
+
|
560
|
+
@param data_type:
|
561
|
+
@param data:
|
562
|
+
@return:
|
563
|
+
"""
|
564
|
+
if data_type != "grbl":
|
565
|
+
return
|
566
|
+
grbl = bytes.decode(data, "latin-1")
|
567
|
+
for split in grbl.split("\r"):
|
568
|
+
g = split.strip()
|
569
|
+
if g:
|
570
|
+
self(f"{g}{self.line_end}")
|
571
|
+
|
572
|
+
def physical_home(self):
|
573
|
+
"""
|
574
|
+
Home the laser physically (i.e. run into endstops).
|
575
|
+
|
576
|
+
@return:
|
577
|
+
"""
|
578
|
+
old_current = self.service.current
|
579
|
+
self.native_x = 0
|
580
|
+
self.native_y = 0
|
581
|
+
if self.service.has_endstops:
|
582
|
+
self(f"$H{self.line_end}")
|
583
|
+
else:
|
584
|
+
self(f"G28{self.line_end}")
|
585
|
+
new_current = self.service.current
|
586
|
+
if self._signal_updates:
|
587
|
+
self.service.signal(
|
588
|
+
"driver;position",
|
589
|
+
(old_current[0], old_current[1], new_current[0], new_current[1]),
|
590
|
+
)
|
591
|
+
|
592
|
+
def home(self):
|
593
|
+
"""
|
594
|
+
Home the laser (i.e. goto defined origin)
|
595
|
+
|
596
|
+
@return:
|
597
|
+
"""
|
598
|
+
self.native_x = 0
|
599
|
+
self.native_y = 0
|
600
|
+
if self.service.rotary.active and self.service.rotary.suppress_home:
|
601
|
+
return
|
602
|
+
self(f"G28{self.line_end}")
|
603
|
+
|
604
|
+
def rapid_mode(self, *values):
|
605
|
+
"""
|
606
|
+
Rapid mode sets the laser to rapid state. This is usually moving the laser around without it executing a large
|
607
|
+
batch of commands.
|
608
|
+
|
609
|
+
@param values:
|
610
|
+
@return:
|
611
|
+
"""
|
612
|
+
|
613
|
+
def finished_mode(self, *values):
|
614
|
+
"""
|
615
|
+
Finished mode is after a large batch of jobs is done.
|
616
|
+
|
617
|
+
@param values:
|
618
|
+
@return:
|
619
|
+
"""
|
620
|
+
self(f"M5{self.line_end}")
|
621
|
+
|
622
|
+
def program_mode(self, *values):
|
623
|
+
"""
|
624
|
+
Program mode is the state lasers often use to send a large batch of commands.
|
625
|
+
@param values:
|
626
|
+
@return:
|
627
|
+
"""
|
628
|
+
self(f"M3{self.line_end}")
|
629
|
+
|
630
|
+
def raster_mode(self, *values):
|
631
|
+
"""
|
632
|
+
Raster mode is a special form of program mode that suggests the batch of commands will be a raster operation
|
633
|
+
many lasers have specialty values
|
634
|
+
@param values:
|
635
|
+
@return:
|
636
|
+
"""
|
637
|
+
|
638
|
+
def wait(self, time_in_ms):
|
639
|
+
"""
|
640
|
+
Wait asks that the work be stalled or current process held for the time time_in_ms in ms. If wait_finished is
|
641
|
+
called first this will attempt to stall the machine while performing no work. If the driver in question permits
|
642
|
+
waits to be placed within code this should insert waits into the current job. Returning instantly rather than
|
643
|
+
holding the processes.
|
644
|
+
|
645
|
+
@param time_in_ms:
|
646
|
+
@return:
|
647
|
+
"""
|
648
|
+
self(f"G04 S{time_in_ms / 1000.0}{self.line_end}")
|
649
|
+
|
650
|
+
def wait_finish(self, *values):
|
651
|
+
"""
|
652
|
+
Wait finish should hold the calling thread until the current work has completed. Or otherwise prevent any data
|
653
|
+
from being sent with returning True for the until that criteria is met.
|
654
|
+
|
655
|
+
@param values:
|
656
|
+
@return:
|
657
|
+
"""
|
658
|
+
while True:
|
659
|
+
if self.queue or len(self.service.controller):
|
660
|
+
time.sleep(0.05)
|
661
|
+
continue
|
662
|
+
break
|
663
|
+
|
664
|
+
def function(self, function):
|
665
|
+
"""
|
666
|
+
This command asks that this function be executed at the appropriate time within the spooled cycle.
|
667
|
+
|
668
|
+
@param function:
|
669
|
+
@return:
|
670
|
+
"""
|
671
|
+
function()
|
672
|
+
|
673
|
+
def beep(self):
|
674
|
+
"""
|
675
|
+
Wants a system beep to be issued.
|
676
|
+
This command asks that a beep be executed at the appropriate time within the spooled cycle.
|
677
|
+
|
678
|
+
@return:
|
679
|
+
"""
|
680
|
+
self.service("beep\n")
|
681
|
+
|
682
|
+
def console(self, value):
|
683
|
+
"""
|
684
|
+
This asks that the console command be executed at the appropriate time within the spooled cycle.
|
685
|
+
|
686
|
+
@param value: console command
|
687
|
+
@return:
|
688
|
+
"""
|
689
|
+
self.service(value)
|
690
|
+
|
691
|
+
def signal(self, signal, *args):
|
692
|
+
"""
|
693
|
+
This asks that this signal be broadcast at the appropriate time within the spooling cycle.
|
694
|
+
|
695
|
+
@param signal:
|
696
|
+
@param args:
|
697
|
+
@return:
|
698
|
+
"""
|
699
|
+
if signal == "coolant":
|
700
|
+
onoff = args[0]
|
701
|
+
coolid = None
|
702
|
+
if hasattr(self.service, "coolant"):
|
703
|
+
coolid = self.service.device_coolant
|
704
|
+
if not coolid:
|
705
|
+
return
|
706
|
+
routine = None
|
707
|
+
try:
|
708
|
+
cool = self.service.context.kernel.root.coolant
|
709
|
+
routine = cool.claim_coolant(self.service, coolid)
|
710
|
+
except AttributeError:
|
711
|
+
routine = None
|
712
|
+
if routine:
|
713
|
+
try:
|
714
|
+
routine(self.service, onoff)
|
715
|
+
except RuntimeError:
|
716
|
+
pass
|
717
|
+
|
718
|
+
else:
|
719
|
+
self.service.signal(signal, *args)
|
720
|
+
|
721
|
+
def pause(self, *args):
|
722
|
+
"""
|
723
|
+
Asks that the laser be paused.
|
724
|
+
|
725
|
+
@param args:
|
726
|
+
@return:
|
727
|
+
"""
|
728
|
+
self.paused = True
|
729
|
+
# self(f"!{self.line_end}", real=True)
|
730
|
+
self(chr(0x21), real=True) # Hex 21 = !
|
731
|
+
# Let's make sure we reestablish power...
|
732
|
+
self.power_dirty = True
|
733
|
+
self.service.signal("pause")
|
734
|
+
|
735
|
+
def resume(self, *args):
|
736
|
+
"""
|
737
|
+
Asks that the laser be resumed.
|
738
|
+
|
739
|
+
To work this command should usually be put into the realtime work queue for the laser.
|
740
|
+
|
741
|
+
@param args:
|
742
|
+
@return:
|
743
|
+
"""
|
744
|
+
self.paused = False
|
745
|
+
# self(f"~{self.line_end}", real=True)
|
746
|
+
self(chr(0x7E), real=True) # hex 7e = ~
|
747
|
+
self.service.signal("pause")
|
748
|
+
|
749
|
+
def clear_states(self):
|
750
|
+
self.power_dirty = True
|
751
|
+
self.speed_dirty = True
|
752
|
+
self.zaxis_dirty = True
|
753
|
+
self.absolute_dirty = True
|
754
|
+
self.feedrate_dirty = True
|
755
|
+
self.units_dirty = True
|
756
|
+
self.move_mode = 0
|
757
|
+
|
758
|
+
def reset(self, *args):
|
759
|
+
"""
|
760
|
+
This command asks that this device be emergency stopped and reset. Usually that queue data from the spooler be
|
761
|
+
deleted.
|
762
|
+
Asks that the device resets, and clears all current work.
|
763
|
+
|
764
|
+
@param args:
|
765
|
+
@return:
|
766
|
+
"""
|
767
|
+
self.service.spooler.clear_queue()
|
768
|
+
self.queue.clear()
|
769
|
+
self.plot_planner.clear()
|
770
|
+
self(f"\x18{self.line_end}", real=True)
|
771
|
+
self._g94_feedrate()
|
772
|
+
self._g21_units_mm()
|
773
|
+
self._g90_absolute()
|
774
|
+
|
775
|
+
self.power_dirty = True
|
776
|
+
self.speed_dirty = True
|
777
|
+
self.zaxis_dirty = True
|
778
|
+
self.absolute_dirty = True
|
779
|
+
self.feedrate_dirty = True
|
780
|
+
self.units_dirty = True
|
781
|
+
|
782
|
+
self.paused = False
|
783
|
+
self.service.signal("pause")
|
784
|
+
|
785
|
+
def clear_alarm(self):
|
786
|
+
"""
|
787
|
+
GRBL clear alarm signal.
|
788
|
+
|
789
|
+
@return:
|
790
|
+
"""
|
791
|
+
self(f"$X{self.line_end}", real=True)
|
792
|
+
if self.service.extended_alarm_clear:
|
793
|
+
self.reset()
|
794
|
+
|
795
|
+
def declare_modals(self, modals):
|
796
|
+
self.move_mode = 0 if "G0" in modals else 1
|
797
|
+
if "G90" in modals:
|
798
|
+
self._g90_absolute()
|
799
|
+
self.absolute_dirty = False
|
800
|
+
if "G91" in modals:
|
801
|
+
self._g91_relative()
|
802
|
+
self.absolute_dirty = False
|
803
|
+
if "G94" in modals:
|
804
|
+
self._g94_feedrate()
|
805
|
+
self.feedrate_dirty = False
|
806
|
+
if "G93" in modals:
|
807
|
+
self._g93_feedrate()
|
808
|
+
self.feedrate_dirty = False
|
809
|
+
if "G20" in modals:
|
810
|
+
self._g20_units_inch()
|
811
|
+
self.units_dirty = False
|
812
|
+
if "G21" in modals:
|
813
|
+
self._g21_units_mm()
|
814
|
+
self.units_dirty = False
|
815
|
+
|
816
|
+
def declare_position(self, x, y):
|
817
|
+
self.native_x = x * self.unit_scale
|
818
|
+
self.native_y = y * self.unit_scale
|
819
|
+
|
820
|
+
####################
|
821
|
+
# PROTECTED DRIVER CODE
|
822
|
+
####################
|
823
|
+
|
824
|
+
def _move(self, x, y, absolute=False):
|
825
|
+
old_current = self.service.current
|
826
|
+
if self._absolute:
|
827
|
+
self.native_x = x
|
828
|
+
self.native_y = y
|
829
|
+
else:
|
830
|
+
self.native_x += x
|
831
|
+
self.native_y += y
|
832
|
+
line = []
|
833
|
+
if self.move_mode == 0:
|
834
|
+
line.append("G0")
|
835
|
+
else:
|
836
|
+
line.append("G1")
|
837
|
+
x /= self.unit_scale
|
838
|
+
y /= self.unit_scale
|
839
|
+
line.append(f"X{x:.3f}")
|
840
|
+
line.append(f"Y{y:.3f}")
|
841
|
+
if self.zaxis_dirty:
|
842
|
+
self.zaxis_dirty = False
|
843
|
+
if self.zaxis is not None:
|
844
|
+
try:
|
845
|
+
z = float(Length(self.zaxis) / self.service.view.native_scale_x)
|
846
|
+
z /= self.unit_scale
|
847
|
+
line.append(f"Z{z:.3f}")
|
848
|
+
except ValueError:
|
849
|
+
pass
|
850
|
+
|
851
|
+
if self.power_dirty:
|
852
|
+
if self.power is not None:
|
853
|
+
line.append(f"S{self.power * self.on_value:.1f}")
|
854
|
+
self.power_dirty = False
|
855
|
+
if self.speed_dirty:
|
856
|
+
line.append(f"F{self.feed_convert(self.speed):.1f}")
|
857
|
+
self.speed_dirty = False
|
858
|
+
self(" ".join(line) + self.line_end)
|
859
|
+
new_current = self.service.current
|
860
|
+
if self._signal_updates:
|
861
|
+
self.service.signal(
|
862
|
+
"driver;position",
|
863
|
+
(old_current[0], old_current[1], new_current[0], new_current[1]),
|
864
|
+
)
|
865
|
+
|
866
|
+
def _clean_motion(self):
|
867
|
+
if self.absolute_dirty:
|
868
|
+
if self._absolute:
|
869
|
+
self(f"G90{self.line_end}")
|
870
|
+
else:
|
871
|
+
self(f"G91{self.line_end}")
|
872
|
+
self.absolute_dirty = False
|
873
|
+
|
874
|
+
def _clean_feed_mode(self):
|
875
|
+
if self.feedrate_dirty:
|
876
|
+
if self.feed_mode == 94:
|
877
|
+
self(f"G94{self.line_end}")
|
878
|
+
else:
|
879
|
+
self(f"G93{self.line_end}")
|
880
|
+
self.feedrate_dirty = False
|
881
|
+
|
882
|
+
def _clean_units(self):
|
883
|
+
if self.units_dirty:
|
884
|
+
if self.units == 20:
|
885
|
+
self(f"G20{self.line_end}")
|
886
|
+
else:
|
887
|
+
self(f"G21{self.line_end}")
|
888
|
+
self.units_dirty = False
|
889
|
+
|
890
|
+
def _clean(self):
|
891
|
+
self._clean_motion()
|
892
|
+
self._clean_feed_mode()
|
893
|
+
self._clean_units()
|
894
|
+
|
895
|
+
def _g91_relative(self):
|
896
|
+
if not self._absolute:
|
897
|
+
return
|
898
|
+
self._absolute = False
|
899
|
+
self.absolute_dirty = True
|
900
|
+
|
901
|
+
def _g90_absolute(self):
|
902
|
+
if self._absolute:
|
903
|
+
return
|
904
|
+
self._absolute = True
|
905
|
+
self.absolute_dirty = True
|
906
|
+
|
907
|
+
def _g93_mms_to_minutes_per_gunits(self, mms):
|
908
|
+
millimeters_per_minute = 60.0 * mms
|
909
|
+
distance = UNITS_PER_MIL / self.stepper_step_size
|
910
|
+
return distance / millimeters_per_minute
|
911
|
+
|
912
|
+
def _g93_feedrate(self):
|
913
|
+
if self.feed_mode == 93:
|
914
|
+
return
|
915
|
+
self.feed_mode = 93
|
916
|
+
# Feed Rate in Minutes / Unit
|
917
|
+
self.feed_convert = self._g93_mms_to_minutes_per_gunits
|
918
|
+
self.feedrate_dirty = True
|
919
|
+
|
920
|
+
def _g94_mms_to_gunits_per_minute(self, mms):
|
921
|
+
millimeters_per_minute = 60.0 * mms
|
922
|
+
distance = UNITS_PER_MIL / self.stepper_step_size
|
923
|
+
return millimeters_per_minute / distance
|
924
|
+
|
925
|
+
def _g94_feedrate(self):
|
926
|
+
if self.feed_mode == 94:
|
927
|
+
return
|
928
|
+
self.feed_mode = 94
|
929
|
+
# Feed Rate in Units / Minute
|
930
|
+
self.feed_convert = self._g94_mms_to_gunits_per_minute
|
931
|
+
# units to mm, seconds to minutes.
|
932
|
+
self.feedrate_dirty = True
|
933
|
+
|
934
|
+
def _g20_units_inch(self):
|
935
|
+
self.units = 20
|
936
|
+
self.unit_scale = UNITS_PER_INCH / self.stepper_step_size # g20 is inch mode.
|
937
|
+
self.units_dirty = True
|
938
|
+
|
939
|
+
def _g21_units_mm(self):
|
940
|
+
self.units = 21
|
941
|
+
self.unit_scale = UNITS_PER_MM / self.stepper_step_size # g21 is mm mode.
|
942
|
+
self.units_dirty = True
|
943
|
+
|
944
|
+
def set_power_scale(self, factor):
|
945
|
+
# Grbl can only deal with factors between 10% and 200%
|
946
|
+
if factor <= 0 or factor > 2.0:
|
947
|
+
factor = 1.0
|
948
|
+
if self.power_scale == factor:
|
949
|
+
return
|
950
|
+
self.power_scale = factor
|
951
|
+
|
952
|
+
# Grbl can only deal with factors between 10% and 200%
|
953
|
+
self("\x99\r", real=True)
|
954
|
+
# Upward loop
|
955
|
+
start = 1.0
|
956
|
+
while start < 2.0 and start < factor:
|
957
|
+
self("\x9B\r", real=True)
|
958
|
+
start += 0.1
|
959
|
+
# Downward loop
|
960
|
+
start = 1.0
|
961
|
+
while start > 0.0 and start > factor:
|
962
|
+
self("\x9A\r", real=True)
|
963
|
+
start -= 0.1
|
964
|
+
|
965
|
+
def set_speed_scale(self, factor):
|
966
|
+
# Grbl can only deal with factors between 10% and 200%
|
967
|
+
if factor <= 0 or factor > 2.0:
|
968
|
+
factor = 1.0
|
969
|
+
if self.speed_scale == factor:
|
970
|
+
return
|
971
|
+
self.speed_scale = factor
|
972
|
+
self("\x90\r", real=True)
|
973
|
+
start = 1.0
|
974
|
+
while start < 2.0 and start < factor:
|
975
|
+
self("\x91\r", real=True)
|
976
|
+
start += 0.1
|
977
|
+
# Downward loop
|
978
|
+
start = 1.0
|
979
|
+
while start > 0.0 and start > factor:
|
980
|
+
self("\x92\r", real=True)
|
981
|
+
start -= 0.1
|
982
|
+
|
983
|
+
@staticmethod
|
984
|
+
def has_adjustable_power():
|
985
|
+
return True
|
986
|
+
|
987
|
+
@staticmethod
|
988
|
+
def has_adjustable_speed():
|
989
|
+
return True
|