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.
- 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 +1195 -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 +1844 -1507
- meerk40t/core/elements/clipboard.py +229 -219
- meerk40t/core/elements/element_treeops.py +4561 -2837
- meerk40t/core/elements/element_types.py +125 -105
- meerk40t/core/elements/elements.py +4329 -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 +933 -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/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 +462 -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 +198 -0
- meerk40t/extra/ezd.py +1165 -1165
- meerk40t/extra/hershey.py +835 -340
- meerk40t/extra/imageactions.py +322 -316
- meerk40t/extra/inkscape.py +630 -622
- meerk40t/extra/lbrn.py +424 -424
- meerk40t/extra/outerworld.py +284 -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 +1081 -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 +170 -133
- meerk40t/gui/choicepropertypanel.py +1673 -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 +1430 -846
- meerk40t/gui/icons.py +3422 -2747
- meerk40t/gui/imagesplitter.py +555 -508
- meerk40t/gui/keymap.py +354 -344
- meerk40t/gui/laserpanel.py +892 -806
- meerk40t/gui/laserrender.py +1470 -1232
- meerk40t/gui/lasertoolpanel.py +805 -793
- meerk40t/gui/magnetoptions.py +436 -0
- meerk40t/gui/materialmanager.py +2917 -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 +494 -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 +2468 -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 +589 -346
- meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
- meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
- meerk40t/gui/scenewidgets/selectionwidget.py +2952 -2756
- meerk40t/gui/simpleui.py +357 -333
- meerk40t/gui/simulation.py +2431 -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 +591 -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 +160 -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 +1444 -1169
- meerk40t/gui/wxmmain.py +5578 -4112
- meerk40t/gui/wxmribbon.py +1591 -1076
- meerk40t/gui/wxmscene.py +1635 -1453
- meerk40t/gui/wxmtree.py +2410 -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 +2778 -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 +3809 -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 +102 -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 +390 -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 +672 -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 +940 -940
- meerk40t/tools/rasterplotter.py +1660 -547
- meerk40t/tools/shxparser.py +989 -901
- meerk40t/tools/ttfparser.py +726 -446
- meerk40t/tools/zinglplotter.py +595 -593
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/LICENSE +21 -21
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/METADATA +150 -139
- meerk40t-0.9.7010.dist-info/RECORD +445 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/WHEEL +1 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/top_level.txt +0 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.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.7010.dist-info}/entry_points.txt +0 -0
meerk40t/moshi/driver.py
CHANGED
@@ -1,696 +1,862 @@
|
|
1
|
-
"""
|
2
|
-
Moshiboard Driver
|
3
|
-
|
4
|
-
Governs the generic commands issued by laserjob and spooler and converts that into regular Moshi laser output.
|
5
|
-
"""
|
6
|
-
|
7
|
-
import time
|
8
|
-
|
9
|
-
from ..core.cutcode.cubiccut import CubicCut
|
10
|
-
from ..core.cutcode.dwellcut import DwellCut
|
11
|
-
from ..core.cutcode.gotocut import GotoCut
|
12
|
-
from ..core.cutcode.homecut import HomeCut
|
13
|
-
from ..core.cutcode.inputcut import InputCut
|
14
|
-
from ..core.cutcode.linecut import LineCut
|
15
|
-
from ..core.cutcode.outputcut import OutputCut
|
16
|
-
from ..core.cutcode.plotcut import PlotCut
|
17
|
-
from ..core.cutcode.quadcut import QuadCut
|
18
|
-
from ..core.cutcode.waitcut import WaitCut
|
19
|
-
from ..core.parameters import Parameters
|
20
|
-
from ..core.plotplanner import PlotPlanner
|
21
|
-
from ..device.basedevice import (
|
22
|
-
DRIVER_STATE_FINISH,
|
23
|
-
DRIVER_STATE_MODECHANGE,
|
24
|
-
DRIVER_STATE_PROGRAM,
|
25
|
-
DRIVER_STATE_RAPID,
|
26
|
-
DRIVER_STATE_RASTER,
|
27
|
-
PLOT_FINISH,
|
28
|
-
PLOT_JOG,
|
29
|
-
PLOT_LEFT_UPPER,
|
30
|
-
PLOT_RAPID,
|
31
|
-
PLOT_SETTING,
|
32
|
-
PLOT_START,
|
33
|
-
)
|
34
|
-
from .
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
the
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
self.
|
49
|
-
self.
|
50
|
-
|
51
|
-
|
52
|
-
self.
|
53
|
-
|
54
|
-
|
55
|
-
self.
|
56
|
-
|
57
|
-
self.
|
58
|
-
|
59
|
-
|
60
|
-
self.
|
61
|
-
|
62
|
-
|
63
|
-
self.
|
64
|
-
self.
|
65
|
-
|
66
|
-
|
67
|
-
self.
|
68
|
-
|
69
|
-
|
70
|
-
self.
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
self.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
return
|
91
|
-
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def
|
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
|
-
self.
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
def
|
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
|
-
|
179
|
-
|
180
|
-
|
181
|
-
""
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
self.
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
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
|
-
self.
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
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
|
-
@param
|
288
|
-
@return:
|
289
|
-
"""
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
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
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
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
|
-
self.
|
482
|
-
|
483
|
-
def
|
484
|
-
"""
|
485
|
-
This
|
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
|
-
self.
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
if
|
571
|
-
|
572
|
-
if
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
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
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
self.
|
682
|
-
self.
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
self.
|
694
|
-
|
695
|
-
|
696
|
-
self.
|
1
|
+
"""
|
2
|
+
Moshiboard Driver
|
3
|
+
|
4
|
+
Governs the generic commands issued by laserjob and spooler and converts that into regular Moshi laser output.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import time
|
8
|
+
|
9
|
+
from ..core.cutcode.cubiccut import CubicCut
|
10
|
+
from ..core.cutcode.dwellcut import DwellCut
|
11
|
+
from ..core.cutcode.gotocut import GotoCut
|
12
|
+
from ..core.cutcode.homecut import HomeCut
|
13
|
+
from ..core.cutcode.inputcut import InputCut
|
14
|
+
from ..core.cutcode.linecut import LineCut
|
15
|
+
from ..core.cutcode.outputcut import OutputCut
|
16
|
+
from ..core.cutcode.plotcut import PlotCut
|
17
|
+
from ..core.cutcode.quadcut import QuadCut
|
18
|
+
from ..core.cutcode.waitcut import WaitCut
|
19
|
+
from ..core.parameters import Parameters
|
20
|
+
from ..core.plotplanner import PlotPlanner
|
21
|
+
from ..device.basedevice import (
|
22
|
+
DRIVER_STATE_FINISH,
|
23
|
+
DRIVER_STATE_MODECHANGE,
|
24
|
+
DRIVER_STATE_PROGRAM,
|
25
|
+
DRIVER_STATE_RAPID,
|
26
|
+
DRIVER_STATE_RASTER,
|
27
|
+
PLOT_FINISH,
|
28
|
+
PLOT_JOG,
|
29
|
+
PLOT_LEFT_UPPER,
|
30
|
+
PLOT_RAPID,
|
31
|
+
PLOT_SETTING,
|
32
|
+
PLOT_START,
|
33
|
+
)
|
34
|
+
from ..tools.geomstr import Geomstr
|
35
|
+
from .builder import MoshiBuilder
|
36
|
+
|
37
|
+
|
38
|
+
class MoshiDriver(Parameters):
|
39
|
+
"""
|
40
|
+
A driver takes spoolable commands and turns those commands into states and code in a language
|
41
|
+
agnostic fashion. The Moshiboard Driver overloads the Driver class to take spoolable values from
|
42
|
+
the spooler and converts them into Moshiboard specific actions.
|
43
|
+
|
44
|
+
"""
|
45
|
+
|
46
|
+
def __init__(self, service, channel=None, *args, **kwargs):
|
47
|
+
super().__init__()
|
48
|
+
self.service = service
|
49
|
+
self.name = str(self.service)
|
50
|
+
self.state = 0
|
51
|
+
|
52
|
+
self.native_x = 0
|
53
|
+
self.native_y = 0
|
54
|
+
|
55
|
+
self.plot_planner = PlotPlanner(self.settings)
|
56
|
+
self.queue = []
|
57
|
+
self._queue_current = 0
|
58
|
+
self._queue_total = 0
|
59
|
+
|
60
|
+
self.program = MoshiBuilder()
|
61
|
+
|
62
|
+
self.paused = False
|
63
|
+
self.holds = []
|
64
|
+
self.temp_holds = []
|
65
|
+
|
66
|
+
self.preferred_offset_x = 0
|
67
|
+
self.preferred_offset_y = 0
|
68
|
+
|
69
|
+
self.pipe_channel = service.channel(f"{service.safe_label}/events")
|
70
|
+
self.program.channel = self.pipe_channel
|
71
|
+
|
72
|
+
self.out_pipe = None
|
73
|
+
self.out_real = None
|
74
|
+
|
75
|
+
self._signal_updates = self.service.setting(bool, "signal_updates", True)
|
76
|
+
|
77
|
+
def primary_hold():
|
78
|
+
if self.out_pipe is None:
|
79
|
+
return True
|
80
|
+
if (
|
81
|
+
hasattr(self.service.controller, "is_shutdown")
|
82
|
+
and self.service.controller.is_shutdown
|
83
|
+
):
|
84
|
+
raise ConnectionAbortedError("Cannot hold for a shutdown pipe.")
|
85
|
+
return self.paused
|
86
|
+
|
87
|
+
self.holds.append(primary_hold)
|
88
|
+
|
89
|
+
def __repr__(self):
|
90
|
+
return f"MoshiDriver({self.name})"
|
91
|
+
|
92
|
+
def __call__(self, e, real=False):
|
93
|
+
if real:
|
94
|
+
self.out_real(e)
|
95
|
+
else:
|
96
|
+
self.out_pipe(e)
|
97
|
+
|
98
|
+
def get_internal_queue_status(self):
|
99
|
+
return self._queue_current, self._queue_total
|
100
|
+
|
101
|
+
def _set_queue_status(self, current, total):
|
102
|
+
self._queue_current = current
|
103
|
+
self._queue_total = total
|
104
|
+
|
105
|
+
def hold_work(self, priority):
|
106
|
+
"""
|
107
|
+
Holds are criteria to use to pause the data interpretation. These halt the production of new data until the
|
108
|
+
criteria is met. A hold is constant and will always halt the data while true. A temp_hold will be removed
|
109
|
+
as soon as it does not hold the data.
|
110
|
+
|
111
|
+
@return: Whether data interpretation should hold.
|
112
|
+
"""
|
113
|
+
if priority > 0:
|
114
|
+
# Don't hold realtime work.
|
115
|
+
return False
|
116
|
+
|
117
|
+
temp_hold = False
|
118
|
+
fail_hold = False
|
119
|
+
for i, hold in enumerate(self.temp_holds):
|
120
|
+
if not hold():
|
121
|
+
self.temp_holds[i] = None
|
122
|
+
fail_hold = True
|
123
|
+
else:
|
124
|
+
temp_hold = True
|
125
|
+
if fail_hold:
|
126
|
+
self.temp_holds = [hold for hold in self.temp_holds if hold is not None]
|
127
|
+
if temp_hold:
|
128
|
+
return True
|
129
|
+
for hold in self.holds:
|
130
|
+
if hold():
|
131
|
+
return True
|
132
|
+
return False
|
133
|
+
|
134
|
+
def job_start(self, job):
|
135
|
+
pass
|
136
|
+
|
137
|
+
def job_finish(self, job):
|
138
|
+
self.rapid_mode()
|
139
|
+
|
140
|
+
def get(self, key, default=None):
|
141
|
+
"""
|
142
|
+
Required.
|
143
|
+
|
144
|
+
@param key: Key to get.
|
145
|
+
@param default: Default value to use.
|
146
|
+
@return:
|
147
|
+
"""
|
148
|
+
return self.settings.get(key, default=default)
|
149
|
+
|
150
|
+
def set(self, key, value):
|
151
|
+
"""
|
152
|
+
Required.
|
153
|
+
|
154
|
+
Sets a laser parameter this could be speed, power, wobble, number_of_unicorns, or any unknown parameters for
|
155
|
+
yet to be written drivers.
|
156
|
+
|
157
|
+
@param key:
|
158
|
+
@param value:
|
159
|
+
@return:
|
160
|
+
"""
|
161
|
+
if key == "power":
|
162
|
+
self._set_power(value)
|
163
|
+
elif key == "ppi":
|
164
|
+
self._set_power(value)
|
165
|
+
elif key == "pwm":
|
166
|
+
self._set_power(value)
|
167
|
+
elif key == "overscan":
|
168
|
+
self._set_overscan(value)
|
169
|
+
elif key == "speed":
|
170
|
+
self._set_speed(value)
|
171
|
+
elif key == "step":
|
172
|
+
self._set_step(value)
|
173
|
+
else:
|
174
|
+
self.settings[key] = value
|
175
|
+
|
176
|
+
def status(self):
|
177
|
+
"""
|
178
|
+
Wants a status report of what the driver is doing.
|
179
|
+
@return:
|
180
|
+
"""
|
181
|
+
state_major = "idle"
|
182
|
+
state_minor = "idle"
|
183
|
+
if self.state == DRIVER_STATE_RAPID:
|
184
|
+
state_major = "idle"
|
185
|
+
state_minor = "idle"
|
186
|
+
elif self.state == DRIVER_STATE_FINISH:
|
187
|
+
state_major = "idle"
|
188
|
+
state_minor = "finished"
|
189
|
+
elif self.state == DRIVER_STATE_PROGRAM:
|
190
|
+
state_major = "busy"
|
191
|
+
state_minor = "program"
|
192
|
+
elif self.state == DRIVER_STATE_RASTER:
|
193
|
+
state_major = "busy"
|
194
|
+
state_minor = "raster"
|
195
|
+
elif self.state == DRIVER_STATE_MODECHANGE:
|
196
|
+
state_major = "busy"
|
197
|
+
state_minor = "changing"
|
198
|
+
return (self.native_x, self.native_y), state_major, state_minor
|
199
|
+
|
200
|
+
def laser_off(self, *values):
|
201
|
+
"""
|
202
|
+
Turn laser off in place.
|
203
|
+
|
204
|
+
Moshiboards do not support this command.
|
205
|
+
|
206
|
+
@param values:
|
207
|
+
@return:
|
208
|
+
"""
|
209
|
+
pass
|
210
|
+
|
211
|
+
def laser_on(self, *values):
|
212
|
+
"""
|
213
|
+
Turn laser on in place.
|
214
|
+
|
215
|
+
Moshiboards do not support this command.
|
216
|
+
|
217
|
+
@param values:
|
218
|
+
@return:
|
219
|
+
"""
|
220
|
+
pass
|
221
|
+
|
222
|
+
def geometry(self, geom):
|
223
|
+
"""
|
224
|
+
Called at the end of plot commands to ensure the driver can deal with them all as a group.
|
225
|
+
|
226
|
+
@return:
|
227
|
+
"""
|
228
|
+
# TODO: Raster geom strokes need to be run in raster mode for moshi.
|
229
|
+
g = Geomstr()
|
230
|
+
for segment_type, start, c1, c2, end, sets in geom.as_lines():
|
231
|
+
x = self.native_x
|
232
|
+
y = self.native_y
|
233
|
+
if x != start.real or y != start.imag:
|
234
|
+
self._goto_absolute(start.real, start.imag, 0)
|
235
|
+
self.settings.update(sets)
|
236
|
+
|
237
|
+
if segment_type == "line":
|
238
|
+
self._goto_absolute(end.real, end.imag, 1)
|
239
|
+
elif segment_type == "end":
|
240
|
+
pass
|
241
|
+
elif segment_type == "quad":
|
242
|
+
interp = self.service.interp
|
243
|
+
g.clear()
|
244
|
+
g.quad(start, c1, end)
|
245
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
246
|
+
while self.hold_work(0):
|
247
|
+
time.sleep(0.05)
|
248
|
+
self._goto_absolute(p.real, p.imag, 1)
|
249
|
+
elif segment_type == "cubic":
|
250
|
+
interp = self.service.interp
|
251
|
+
g.clear()
|
252
|
+
g.cubic(start, c1, c2, end)
|
253
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
254
|
+
while self.hold_work(0):
|
255
|
+
time.sleep(0.05)
|
256
|
+
self._goto_absolute(p.real, p.imag, 1)
|
257
|
+
elif segment_type == "arc":
|
258
|
+
interp = self.service.interp
|
259
|
+
g.clear()
|
260
|
+
g.arc(start, c1, end)
|
261
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
262
|
+
while self.hold_work(0):
|
263
|
+
time.sleep(0.05)
|
264
|
+
self._goto_absolute(p.real, p.imag, 1)
|
265
|
+
elif segment_type == "point":
|
266
|
+
function = sets.get("function")
|
267
|
+
if function == "dwell":
|
268
|
+
# Moshi cannot fire in place.
|
269
|
+
pass
|
270
|
+
elif function == "wait":
|
271
|
+
# Moshi has no forced wait functionality.
|
272
|
+
pass
|
273
|
+
elif function == "home":
|
274
|
+
self.home()
|
275
|
+
elif function == "goto":
|
276
|
+
self._goto_absolute(start.real, start.imag, 0)
|
277
|
+
elif function == "input":
|
278
|
+
# Moshi has no core GPIO functionality
|
279
|
+
pass
|
280
|
+
elif function == "output":
|
281
|
+
# Moshi has no core GPIO functionality
|
282
|
+
pass
|
283
|
+
|
284
|
+
def plot(self, plot):
|
285
|
+
"""
|
286
|
+
Gives the driver a bit of cutcode that should be plotted.
|
287
|
+
@param plot:
|
288
|
+
@return:
|
289
|
+
"""
|
290
|
+
self.queue.append(plot)
|
291
|
+
|
292
|
+
def plot_start(self):
|
293
|
+
"""
|
294
|
+
Called at the end of plot commands to ensure the driver can deal with them all as a group.
|
295
|
+
|
296
|
+
@return:
|
297
|
+
"""
|
298
|
+
total = len(self.queue)
|
299
|
+
current = 0
|
300
|
+
for q in self.queue:
|
301
|
+
current += 1
|
302
|
+
self._set_queue_status(current, total)
|
303
|
+
p_set = Parameters(q.settings)
|
304
|
+
if p_set.power != self.power:
|
305
|
+
self._set_power(p_set.power)
|
306
|
+
if (
|
307
|
+
p_set.speed != self.speed
|
308
|
+
or p_set.raster_step_x != self.raster_step_x
|
309
|
+
or p_set.raster_step_y != self.raster_step_y
|
310
|
+
):
|
311
|
+
self._set_speed(p_set.speed)
|
312
|
+
self._set_step(p_set.raster_step_x, p_set.raster_step_y)
|
313
|
+
self.rapid_mode()
|
314
|
+
self.settings.update(q.settings)
|
315
|
+
|
316
|
+
x = self.native_x
|
317
|
+
y = self.native_y
|
318
|
+
start_x, start_y = q.start
|
319
|
+
if x != start_x or y != start_y:
|
320
|
+
self._goto_absolute(start_x, start_y, 0)
|
321
|
+
if isinstance(q, LineCut):
|
322
|
+
x0, y0, x1, y1 = int(q.start[0]), int(q.start[1]), int(q.end[0]), int(q.end[1])
|
323
|
+
dx, dy = abs(x1 - x0), abs(y1 - y0)
|
324
|
+
# horizontal, vertical or 45 deg angled line
|
325
|
+
if dx == 0 or dy == 0 or dx == dy:
|
326
|
+
self._goto_absolute(*q.end, 1)
|
327
|
+
else:
|
328
|
+
# other oblique line
|
329
|
+
if dx > dy:
|
330
|
+
d = dy
|
331
|
+
sx = float((x1 - x0) / dy)
|
332
|
+
if y1 - y0 > 0:
|
333
|
+
sy = 1
|
334
|
+
else:
|
335
|
+
sy = -1
|
336
|
+
else:
|
337
|
+
d = dx
|
338
|
+
if x1 - x0 > 0:
|
339
|
+
sx = 1
|
340
|
+
else:
|
341
|
+
sx = -1
|
342
|
+
sy = float((y1 - y0) / dx)
|
343
|
+
x = x0
|
344
|
+
y = y0
|
345
|
+
self._goto_absolute(*q.start, 0)
|
346
|
+
for i in range(d):
|
347
|
+
while self.hold_work(0):
|
348
|
+
time.sleep(0.05)
|
349
|
+
x += sx
|
350
|
+
y += sy
|
351
|
+
self._goto_absolute(int(x), int(y), 1)
|
352
|
+
elif isinstance(q, QuadCut):
|
353
|
+
interp = self.service.interp
|
354
|
+
g = Geomstr()
|
355
|
+
g.quad(complex(*q.start), complex(*q.c()), complex(*q.end))
|
356
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
357
|
+
while self.hold_work(0):
|
358
|
+
time.sleep(0.05)
|
359
|
+
self._goto_absolute(p.real, p.imag, 1)
|
360
|
+
elif isinstance(q, CubicCut):
|
361
|
+
interp = self.service.interp
|
362
|
+
g = Geomstr()
|
363
|
+
g.cubic(
|
364
|
+
complex(*q.start),
|
365
|
+
complex(*q.c1()),
|
366
|
+
complex(*q.c2()),
|
367
|
+
complex(*q.end),
|
368
|
+
)
|
369
|
+
for p in list(g.as_equal_interpolated_points(distance=interp))[1:]:
|
370
|
+
while self.hold_work(0):
|
371
|
+
time.sleep(0.05)
|
372
|
+
self._goto_absolute(p.real, p.imag, 1)
|
373
|
+
elif isinstance(q, HomeCut):
|
374
|
+
self.home()
|
375
|
+
elif isinstance(q, GotoCut):
|
376
|
+
start = q.start
|
377
|
+
self._goto_absolute(start[0], start[1], 0)
|
378
|
+
elif isinstance(q, WaitCut):
|
379
|
+
# Moshi has no forced wait functionality.
|
380
|
+
# self.wait_finish()
|
381
|
+
# self.wait(q.dwell_time)
|
382
|
+
pass
|
383
|
+
elif isinstance(q, DwellCut):
|
384
|
+
# Moshi cannot fire in place.
|
385
|
+
pass
|
386
|
+
elif isinstance(q, (InputCut, OutputCut)):
|
387
|
+
# Moshi has no core GPIO functionality
|
388
|
+
pass
|
389
|
+
else:
|
390
|
+
# Rastercut, PlotCut
|
391
|
+
if isinstance(q, PlotCut):
|
392
|
+
q.check_if_rasterable()
|
393
|
+
self.plot_planner.push(q)
|
394
|
+
for x, y, on in self.plot_planner.gen():
|
395
|
+
if self.hold_work(0):
|
396
|
+
time.sleep(0.05)
|
397
|
+
continue
|
398
|
+
on = int(on)
|
399
|
+
if on > 1:
|
400
|
+
# Special Command.
|
401
|
+
if on & (
|
402
|
+
PLOT_RAPID | PLOT_JOG
|
403
|
+
): # Plot planner requests position change.
|
404
|
+
# self.rapid_jog(x, y)
|
405
|
+
self.native_x = x
|
406
|
+
self.native_y = y
|
407
|
+
if self.state != DRIVER_STATE_RAPID:
|
408
|
+
self._move_absolute(x, y)
|
409
|
+
continue
|
410
|
+
elif on & PLOT_FINISH: # Plot planner is ending.
|
411
|
+
self.finished_mode()
|
412
|
+
break
|
413
|
+
elif on & PLOT_START:
|
414
|
+
self._ensure_program_or_raster_mode(
|
415
|
+
self.preferred_offset_x,
|
416
|
+
self.preferred_offset_y,
|
417
|
+
self.native_x,
|
418
|
+
self.native_y,
|
419
|
+
)
|
420
|
+
elif on & PLOT_LEFT_UPPER:
|
421
|
+
self.preferred_offset_x = x
|
422
|
+
self.preferred_offset_y = y
|
423
|
+
elif on & PLOT_SETTING:
|
424
|
+
# Plot planner settings have changed.
|
425
|
+
p_set = Parameters(self.plot_planner.settings)
|
426
|
+
if p_set.power != self.power:
|
427
|
+
self._set_power(p_set.power)
|
428
|
+
if (
|
429
|
+
p_set.speed != self.speed
|
430
|
+
or p_set.raster_step_x != self.raster_step_x
|
431
|
+
or p_set.raster_step_y != self.raster_step_y
|
432
|
+
):
|
433
|
+
self._set_speed(p_set.speed)
|
434
|
+
self._set_step(p_set.raster_step_x, p_set.raster_step_y)
|
435
|
+
self.rapid_mode()
|
436
|
+
self.settings.update(p_set.settings)
|
437
|
+
continue
|
438
|
+
self._goto_absolute(x, y, on & 1)
|
439
|
+
self.queue.clear()
|
440
|
+
self._set_queue_status(0, 0)
|
441
|
+
|
442
|
+
def move_abs(self, x, y):
|
443
|
+
"""
|
444
|
+
Requests laser move to absolute position x, y in physical units
|
445
|
+
|
446
|
+
@param x:
|
447
|
+
@param y:
|
448
|
+
@return:
|
449
|
+
"""
|
450
|
+
x, y = self.service.view.position(x, y)
|
451
|
+
self.rapid_mode()
|
452
|
+
self._move_absolute(int(x), int(y))
|
453
|
+
|
454
|
+
def move_rel(self, dx, dy):
|
455
|
+
"""
|
456
|
+
Requests laser move relative position dx, dy in physical units
|
457
|
+
|
458
|
+
@param dx:
|
459
|
+
@param dy:
|
460
|
+
@return:
|
461
|
+
"""
|
462
|
+
unit_dx, unit_dy = self.service.view.position(dx, dy, vector=True)
|
463
|
+
self.rapid_mode()
|
464
|
+
x = self.native_x + unit_dx
|
465
|
+
y = self.native_y + unit_dy
|
466
|
+
self._move_absolute(int(x), int(y))
|
467
|
+
self.rapid_mode()
|
468
|
+
|
469
|
+
def home(self):
|
470
|
+
"""
|
471
|
+
Send a home command to the device. In the case of Moshiboards this is merely a move to
|
472
|
+
0,0 in absolute position.
|
473
|
+
"""
|
474
|
+
if self.service.rotary.active and self.service.rotary.suppress_home:
|
475
|
+
return
|
476
|
+
self.rapid_mode()
|
477
|
+
self.set("speed", 40)
|
478
|
+
self.program_mode(0, 0, 0, 0)
|
479
|
+
self.rapid_mode()
|
480
|
+
self.native_x = 0
|
481
|
+
self.native_y = 0
|
482
|
+
|
483
|
+
def physical_home(self):
|
484
|
+
""" "
|
485
|
+
This would be the command to go to a real physical home position (i.e. hitting endstops)
|
486
|
+
"""
|
487
|
+
self.home()
|
488
|
+
|
489
|
+
def unlock_rail(self):
|
490
|
+
"""
|
491
|
+
Unlock the Rail or send a "FreeMotor" command.
|
492
|
+
"""
|
493
|
+
self.rapid_mode()
|
494
|
+
self.pipe_channel("Realtime: FreeMotor")
|
495
|
+
MoshiBuilder.freemotor(self.out_real, self.pipe_channel)
|
496
|
+
|
497
|
+
def rapid_mode(self, *values):
|
498
|
+
"""
|
499
|
+
Ensure the driver is currently in a default state. If we are not in a default state the driver
|
500
|
+
should end the current program.
|
501
|
+
"""
|
502
|
+
if self.state == DRIVER_STATE_RAPID:
|
503
|
+
return
|
504
|
+
self.commit()
|
505
|
+
if self.pipe_channel:
|
506
|
+
self.pipe_channel("Rapid Mode")
|
507
|
+
self.state = DRIVER_STATE_RAPID
|
508
|
+
|
509
|
+
def finished_mode(self, *values):
|
510
|
+
"""
|
511
|
+
Ensure the driver is currently in a finished state. If we are not in a finished state the driver
|
512
|
+
should end the current program and return to rapid mode.
|
513
|
+
|
514
|
+
Finished is required between rasters since it's an absolute home.
|
515
|
+
"""
|
516
|
+
if self.state == DRIVER_STATE_FINISH:
|
517
|
+
return
|
518
|
+
|
519
|
+
if self.pipe_channel:
|
520
|
+
self.pipe_channel("Finished Mode")
|
521
|
+
if self.state in (DRIVER_STATE_PROGRAM, DRIVER_STATE_MODECHANGE):
|
522
|
+
self.rapid_mode()
|
523
|
+
|
524
|
+
if self.state == self.state == DRIVER_STATE_RASTER:
|
525
|
+
self.pipe_channel("Final Raster Home")
|
526
|
+
self.home()
|
527
|
+
self.state = DRIVER_STATE_FINISH
|
528
|
+
|
529
|
+
def program_mode(self, *values):
|
530
|
+
"""
|
531
|
+
Ensure the laser is currently in a program state. If it is not currently in a program state we begin
|
532
|
+
a program state.
|
533
|
+
|
534
|
+
If the driver is currently in a program state the assurance is made.
|
535
|
+
"""
|
536
|
+
if self.state == DRIVER_STATE_PROGRAM:
|
537
|
+
return
|
538
|
+
|
539
|
+
if self.pipe_channel:
|
540
|
+
self.pipe_channel("Program Mode")
|
541
|
+
if self.state == DRIVER_STATE_RASTER:
|
542
|
+
self.finished_mode()
|
543
|
+
self.rapid_mode()
|
544
|
+
try:
|
545
|
+
offset_x = int(values[0])
|
546
|
+
except (ValueError, IndexError):
|
547
|
+
offset_x = 0
|
548
|
+
try:
|
549
|
+
offset_y = int(values[1])
|
550
|
+
except (ValueError, IndexError):
|
551
|
+
offset_y = 0
|
552
|
+
try:
|
553
|
+
move_x = int(values[2])
|
554
|
+
except (ValueError, IndexError):
|
555
|
+
move_x = 0
|
556
|
+
try:
|
557
|
+
move_y = int(values[3])
|
558
|
+
except (ValueError, IndexError):
|
559
|
+
move_y = 0
|
560
|
+
self._start_program_mode(offset_x, offset_y, move_x, move_y)
|
561
|
+
|
562
|
+
def raster_mode(self, *values):
|
563
|
+
"""
|
564
|
+
Ensure the driver is currently in a raster program state. If it is not in a raster program state
|
565
|
+
we write the raster program state.
|
566
|
+
"""
|
567
|
+
if self.state == DRIVER_STATE_RASTER:
|
568
|
+
return
|
569
|
+
|
570
|
+
if self.pipe_channel:
|
571
|
+
self.pipe_channel("Raster Mode")
|
572
|
+
if self.state == DRIVER_STATE_PROGRAM:
|
573
|
+
self.finished_mode()
|
574
|
+
self.rapid_mode()
|
575
|
+
try:
|
576
|
+
offset_x = int(values[0])
|
577
|
+
except (ValueError, IndexError):
|
578
|
+
offset_x = 0
|
579
|
+
try:
|
580
|
+
offset_y = int(values[1])
|
581
|
+
except (ValueError, IndexError):
|
582
|
+
offset_y = 0
|
583
|
+
try:
|
584
|
+
move_x = int(values[2])
|
585
|
+
except (ValueError, IndexError):
|
586
|
+
move_x = 0
|
587
|
+
try:
|
588
|
+
move_y = int(values[3])
|
589
|
+
except (ValueError, IndexError):
|
590
|
+
move_y = 0
|
591
|
+
self._start_raster_mode(offset_x, offset_y, move_x, move_y)
|
592
|
+
|
593
|
+
def wait(self, time_in_ms):
|
594
|
+
"""
|
595
|
+
Wait asks that the work be stalled or current process held for the time time_in_ms in ms. If wait_finished is
|
596
|
+
called first this will attempt to stall the machine while performing no work. If the driver in question permits
|
597
|
+
waits to be placed within code this should insert waits into the current job. Returning instantly rather than
|
598
|
+
holding the processes.
|
599
|
+
|
600
|
+
@param time_in_ms:
|
601
|
+
@return:
|
602
|
+
"""
|
603
|
+
time.sleep(time_in_ms / 1000.0)
|
604
|
+
|
605
|
+
def wait_finish(self, *values):
|
606
|
+
"""
|
607
|
+
Wait finish should hold the calling thread until the current work has completed. Or otherwise prevent any data
|
608
|
+
from being sent with returning True for the until that criteria is met.
|
609
|
+
|
610
|
+
@param values:
|
611
|
+
@return:
|
612
|
+
"""
|
613
|
+
|
614
|
+
def temp_hold():
|
615
|
+
try:
|
616
|
+
return (
|
617
|
+
self.service.controller.state == "wait"
|
618
|
+
or len(self.service.controller) != 0
|
619
|
+
)
|
620
|
+
except TypeError:
|
621
|
+
return False
|
622
|
+
|
623
|
+
self.temp_holds.append(temp_hold)
|
624
|
+
|
625
|
+
def function(self, function):
|
626
|
+
"""
|
627
|
+
This command asks that this function be executed at the appropriate time within the spooled cycle.
|
628
|
+
|
629
|
+
@param function:
|
630
|
+
@return:
|
631
|
+
"""
|
632
|
+
function()
|
633
|
+
|
634
|
+
def beep(self):
|
635
|
+
"""
|
636
|
+
Wants a system beep to be issued.
|
637
|
+
This command asks that a beep be executed at the appropriate time within the spooled cycle.
|
638
|
+
|
639
|
+
@return:
|
640
|
+
"""
|
641
|
+
self.service("beep\n")
|
642
|
+
|
643
|
+
def console(self, value):
|
644
|
+
"""
|
645
|
+
This asks that the console command be executed at the appropriate time within the spooled cycle.
|
646
|
+
|
647
|
+
@param value: console command
|
648
|
+
@return:
|
649
|
+
"""
|
650
|
+
self.service(value)
|
651
|
+
|
652
|
+
def signal(self, signal, *args):
|
653
|
+
"""
|
654
|
+
This asks that this signal be broadcast at the appropriate time within the spooling cycle.
|
655
|
+
|
656
|
+
@param signal:
|
657
|
+
@param args:
|
658
|
+
@return:
|
659
|
+
"""
|
660
|
+
self.service.signal(signal, *args)
|
661
|
+
|
662
|
+
def pause(self, *args):
|
663
|
+
"""
|
664
|
+
Asks that the laser be paused.
|
665
|
+
|
666
|
+
@param args:
|
667
|
+
@return:
|
668
|
+
"""
|
669
|
+
self.paused = True
|
670
|
+
self.service.signal("pause")
|
671
|
+
|
672
|
+
def resume(self, *args):
|
673
|
+
"""
|
674
|
+
Asks that the laser be resumed.
|
675
|
+
|
676
|
+
To work this command should usually be put into the realtime work queue for the laser.
|
677
|
+
|
678
|
+
@param args:
|
679
|
+
@return:
|
680
|
+
"""
|
681
|
+
self.paused = False
|
682
|
+
self.service.signal("pause")
|
683
|
+
|
684
|
+
def reset(self, *args):
|
685
|
+
"""
|
686
|
+
This command asks that this device be emergency stopped and reset. Usually that queue data from the spooler be
|
687
|
+
deleted.
|
688
|
+
|
689
|
+
@param args:
|
690
|
+
@return:
|
691
|
+
"""
|
692
|
+
self.service.spooler.clear_queue()
|
693
|
+
self.rapid_mode()
|
694
|
+
self.queue.clear()
|
695
|
+
self.pipe_channel("Realtime: Stop")
|
696
|
+
MoshiBuilder.stop(self.out_real)
|
697
|
+
self.pipe_channel("Control Request: Stop")
|
698
|
+
self.paused = False
|
699
|
+
self.service.signal("pause")
|
700
|
+
|
701
|
+
####################
|
702
|
+
# Protected Driver Functions
|
703
|
+
####################
|
704
|
+
|
705
|
+
def _start_program_mode(
|
706
|
+
self,
|
707
|
+
offset_x,
|
708
|
+
offset_y,
|
709
|
+
move_x=None,
|
710
|
+
move_y=None,
|
711
|
+
speed=None,
|
712
|
+
normal_speed=None,
|
713
|
+
):
|
714
|
+
if move_x is None:
|
715
|
+
move_x = offset_x
|
716
|
+
if move_y is None:
|
717
|
+
move_y = offset_y
|
718
|
+
if speed is None and self.speed is not None:
|
719
|
+
speed = int(self.speed)
|
720
|
+
if speed is None:
|
721
|
+
speed = 20
|
722
|
+
if normal_speed is None:
|
723
|
+
normal_speed = speed
|
724
|
+
# Normal speed is rapid. Passing same speed so PPI isn't crazy.
|
725
|
+
self.program.vector_speed(speed, normal_speed)
|
726
|
+
self.program.set_offset(0, offset_x, offset_y)
|
727
|
+
self.state = DRIVER_STATE_PROGRAM
|
728
|
+
|
729
|
+
self.program.move_abs(move_x, move_y)
|
730
|
+
self.native_x = move_x
|
731
|
+
self.native_y = move_y
|
732
|
+
|
733
|
+
def _start_raster_mode(
|
734
|
+
self, offset_x, offset_y, move_x=None, move_y=None, speed=None
|
735
|
+
):
|
736
|
+
if move_x is None:
|
737
|
+
move_x = offset_x
|
738
|
+
if move_y is None:
|
739
|
+
move_y = offset_y
|
740
|
+
if speed is None and self.speed is not None:
|
741
|
+
speed = int(self.speed)
|
742
|
+
if speed is None:
|
743
|
+
speed = 160
|
744
|
+
self.program.raster_speed(speed)
|
745
|
+
self.program.set_offset(0, offset_x, offset_y)
|
746
|
+
self.state = DRIVER_STATE_RASTER
|
747
|
+
|
748
|
+
self.program.move_abs(move_x, move_y)
|
749
|
+
self.native_x = move_x
|
750
|
+
self.native_y = move_y
|
751
|
+
|
752
|
+
def _set_power(self, power=1000.0):
|
753
|
+
self.power = max(0, min(1000, power))
|
754
|
+
|
755
|
+
def _set_overscan(self, overscan=None):
|
756
|
+
self.overscan = overscan
|
757
|
+
|
758
|
+
def _set_speed(self, speed=None):
|
759
|
+
"""
|
760
|
+
Set the speed for the driver.
|
761
|
+
"""
|
762
|
+
if self.speed != speed:
|
763
|
+
self.speed = speed
|
764
|
+
if self.state in (DRIVER_STATE_PROGRAM, DRIVER_STATE_RASTER):
|
765
|
+
self.state = DRIVER_STATE_MODECHANGE
|
766
|
+
|
767
|
+
def _set_step(self, step_x=None, step_y=None):
|
768
|
+
"""
|
769
|
+
Set the raster step for the driver.
|
770
|
+
"""
|
771
|
+
if self.raster_step_x != step_x or self.raster_step_y != step_y:
|
772
|
+
self.raster_step_x = step_x
|
773
|
+
self.raster_step_y = step_y
|
774
|
+
if self.state in (DRIVER_STATE_PROGRAM, DRIVER_STATE_RASTER):
|
775
|
+
self.state = DRIVER_STATE_MODECHANGE
|
776
|
+
|
777
|
+
def commit(self):
|
778
|
+
self.pipe_channel("Pushed program to output...")
|
779
|
+
if len(self.program):
|
780
|
+
self.program.termination()
|
781
|
+
if self.service.mock:
|
782
|
+
self.program.debug(self.pipe_channel)
|
783
|
+
self(bytearray(self.program.data))
|
784
|
+
self.program.clear()
|
785
|
+
|
786
|
+
def _ensure_program_or_raster_mode(self, x, y, x1=None, y1=None):
|
787
|
+
"""
|
788
|
+
Ensure builder is needed. Makes sure it's in program or raster mode.
|
789
|
+
"""
|
790
|
+
if self.state in (DRIVER_STATE_RASTER, DRIVER_STATE_PROGRAM):
|
791
|
+
return
|
792
|
+
|
793
|
+
if x1 is None:
|
794
|
+
x1 = x
|
795
|
+
if y1 is None:
|
796
|
+
y1 = y
|
797
|
+
if self.raster_step_x == 0 and self.raster_step_y == 0:
|
798
|
+
self.program_mode(x, y, x1, y1)
|
799
|
+
else:
|
800
|
+
if self.service.enable_raster:
|
801
|
+
self.raster_mode(x, y, x1, y1)
|
802
|
+
else:
|
803
|
+
self.program_mode(x, y, x1, y1)
|
804
|
+
|
805
|
+
def _goto_absolute(self, x, y, cut):
|
806
|
+
"""
|
807
|
+
Goto absolute position. Cut flags whether this should be with or without the laser.
|
808
|
+
"""
|
809
|
+
self._ensure_program_or_raster_mode(x, y)
|
810
|
+
old_current = self.service.current
|
811
|
+
|
812
|
+
if self.state == DRIVER_STATE_PROGRAM:
|
813
|
+
if cut:
|
814
|
+
self.program.cut_abs(x, y)
|
815
|
+
else:
|
816
|
+
self.program.move_abs(x, y)
|
817
|
+
else:
|
818
|
+
# DRIVER_STATE_RASTER
|
819
|
+
if x == self.native_x and y == self.native_y:
|
820
|
+
return
|
821
|
+
if cut:
|
822
|
+
if x == self.native_x:
|
823
|
+
self.program.cut_vertical_abs(y=y)
|
824
|
+
if y == self.native_y:
|
825
|
+
self.program.cut_horizontal_abs(x=x)
|
826
|
+
else:
|
827
|
+
if x == self.native_x:
|
828
|
+
self.program.move_vertical_abs(y=y)
|
829
|
+
if y == self.native_y:
|
830
|
+
self.program.move_horizontal_abs(x=x)
|
831
|
+
self.native_x = x
|
832
|
+
self.native_y = y
|
833
|
+
|
834
|
+
new_current = self.service.current
|
835
|
+
if self._signal_updates:
|
836
|
+
self.service.signal(
|
837
|
+
"driver;position",
|
838
|
+
(old_current[0], old_current[1], new_current[0], new_current[1]),
|
839
|
+
)
|
840
|
+
|
841
|
+
def _move_absolute(self, x, y):
|
842
|
+
"""
|
843
|
+
Move to a position x, y. This is an absolute position.
|
844
|
+
"""
|
845
|
+
old_current = self.service.current
|
846
|
+
self._ensure_program_or_raster_mode(x, y)
|
847
|
+
self.program.move_abs(x, y)
|
848
|
+
self.native_x = x
|
849
|
+
self.native_y = y
|
850
|
+
|
851
|
+
new_current = self.service.current
|
852
|
+
if self._signal_updates:
|
853
|
+
self.service.signal(
|
854
|
+
"driver;position",
|
855
|
+
(old_current[0], old_current[1], new_current[0], new_current[1]),
|
856
|
+
)
|
857
|
+
|
858
|
+
def laser_disable(self, *values):
|
859
|
+
self.laser_enabled = False
|
860
|
+
|
861
|
+
def laser_enable(self, *values):
|
862
|
+
self.laser_enabled = True
|