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/core/node/op_cut.py
CHANGED
@@ -1,335 +1,462 @@
|
|
1
|
-
from
|
2
|
-
|
3
|
-
|
4
|
-
from meerk40t.core.
|
5
|
-
from meerk40t.core.node.
|
6
|
-
from meerk40t.core.
|
7
|
-
from meerk40t.core.
|
8
|
-
from meerk40t.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
self.kerf = 0
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
self.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
"elem
|
36
|
-
"elem
|
37
|
-
"
|
38
|
-
"
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
"
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
"elem
|
47
|
-
"
|
48
|
-
"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
"
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
default_map
|
73
|
-
default_map["
|
74
|
-
default_map["
|
75
|
-
default_map["
|
76
|
-
|
77
|
-
|
78
|
-
default_map["
|
79
|
-
default_map["
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
else ""
|
86
|
-
)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
default_map["
|
102
|
-
if self.
|
103
|
-
|
104
|
-
|
105
|
-
default_map["
|
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
|
-
|
133
|
-
|
134
|
-
|
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
|
-
return True
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|
-
|
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
|
-
|
288
|
-
|
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
|
-
|
1
|
+
from math import isnan
|
2
|
+
|
3
|
+
from meerk40t.core.elements.element_types import *
|
4
|
+
from meerk40t.core.node.node import Node
|
5
|
+
from meerk40t.core.node.nutils import path_to_cutobjects
|
6
|
+
from meerk40t.core.parameters import Parameters
|
7
|
+
from meerk40t.core.units import UNITS_PER_MM, Length
|
8
|
+
from meerk40t.svgelements import Color, Path, Polygon
|
9
|
+
|
10
|
+
|
11
|
+
class CutOpNode(Node, Parameters):
|
12
|
+
"""
|
13
|
+
Default object defining a cut operation done on the laser.
|
14
|
+
|
15
|
+
This is a Node of type "op cut".
|
16
|
+
"""
|
17
|
+
|
18
|
+
def __init__(self, settings=None, **kwargs):
|
19
|
+
if settings is not None:
|
20
|
+
settings = dict(settings)
|
21
|
+
Parameters.__init__(self, settings, **kwargs)
|
22
|
+
# Is this op out of useful bounds?
|
23
|
+
self.dangerous = False
|
24
|
+
|
25
|
+
self.label = "Cut"
|
26
|
+
# Set this to a float!
|
27
|
+
# A simple self.kerf = 0 will lead to an interpretation as an int and
|
28
|
+
# will not be loaded properly via read_persistent.
|
29
|
+
# int("2180.534") throws a value error.
|
30
|
+
self.kerf = 0.0
|
31
|
+
self._device_factor = 1.0
|
32
|
+
|
33
|
+
# Which elements can be added to an operation (manually via DND)?
|
34
|
+
self._allowed_elements_dnd = (
|
35
|
+
"elem ellipse",
|
36
|
+
"elem path",
|
37
|
+
"elem polyline",
|
38
|
+
"elem rect",
|
39
|
+
"elem line",
|
40
|
+
"effect hatch",
|
41
|
+
"effect wobble",
|
42
|
+
"effect warp",
|
43
|
+
)
|
44
|
+
# Which elements do we consider for automatic classification?
|
45
|
+
self._allowed_elements = (
|
46
|
+
"elem ellipse",
|
47
|
+
"elem path",
|
48
|
+
"elem polyline",
|
49
|
+
"elem rect",
|
50
|
+
"elem line",
|
51
|
+
"effect hatch",
|
52
|
+
"effect wobble",
|
53
|
+
"effect warp",
|
54
|
+
)
|
55
|
+
# To which attributes responds the classification color check
|
56
|
+
self.allowed_attributes = [
|
57
|
+
"stroke",
|
58
|
+
]
|
59
|
+
super().__init__(type="op cut", **kwargs)
|
60
|
+
self._formatter = "{enabled}{pass}{element_type} {speed}mm/s @{power} {color}"
|
61
|
+
|
62
|
+
def __repr__(self):
|
63
|
+
return "CutOpNode()"
|
64
|
+
|
65
|
+
def offset_routine(self, path, offset_value=0):
|
66
|
+
# This is a placeholder that will be overloaded by plugin routines
|
67
|
+
# at runtime. It will return a new path with an offset to a given path
|
68
|
+
# As we don't have any logic, we just return the original path
|
69
|
+
return path
|
70
|
+
|
71
|
+
def default_map(self, default_map=None):
|
72
|
+
default_map = super().default_map(default_map=default_map)
|
73
|
+
default_map["element_type"] = "Cut"
|
74
|
+
default_map["speed"] = "default"
|
75
|
+
default_map["power"] = "default"
|
76
|
+
default_map["frequency"] = "default"
|
77
|
+
default_map["danger"] = "❌" if self.dangerous else ""
|
78
|
+
default_map["defop"] = "✓" if self.default else ""
|
79
|
+
default_map["enabled"] = "(Disabled) " if not self.output else ""
|
80
|
+
default_map["pass"] = (
|
81
|
+
f"{self.passes}X " if self.passes_custom and self.passes != 1 else ""
|
82
|
+
)
|
83
|
+
default_map["penpass"] = f"(p:{self.penbox_pass}) " if self.penbox_pass else ""
|
84
|
+
default_map["penvalue"] = (
|
85
|
+
f"(v:{self.penbox_value}) " if self.penbox_value else ""
|
86
|
+
)
|
87
|
+
default_map["kerf"] = (
|
88
|
+
f"{Length(self.kerf, digits=2, preferred_units='mm').preferred_length}"
|
89
|
+
if self.kerf != 0
|
90
|
+
else ""
|
91
|
+
)
|
92
|
+
ct = 0
|
93
|
+
t = ""
|
94
|
+
s = ""
|
95
|
+
for cc in self.allowed_attributes:
|
96
|
+
if len(cc) > 0:
|
97
|
+
t += cc[0].upper()
|
98
|
+
ct += 1
|
99
|
+
if ct > 0:
|
100
|
+
s = self.color.hex + "-" + t
|
101
|
+
default_map["colcode"] = s
|
102
|
+
default_map["opstop"] = "(stop)" if self.stopop else ""
|
103
|
+
default_map.update(self.settings)
|
104
|
+
default_map["color"] = self.color.hexrgb if self.color is not None else ""
|
105
|
+
default_map["percent"] = "100%"
|
106
|
+
default_map["ppi"] = "default"
|
107
|
+
if self.power is not None:
|
108
|
+
default_map["percent"] = f"{self.power / 10.0:.0f}%"
|
109
|
+
default_map["ppi"] = f"{self.power:.0f}"
|
110
|
+
default_map["speed_mm_min"] = (
|
111
|
+
"" if self.speed is None else f"{self.speed * 60:.0f}"
|
112
|
+
)
|
113
|
+
|
114
|
+
return default_map
|
115
|
+
|
116
|
+
def can_drop(self, drag_node):
|
117
|
+
# Default routine for drag + drop for an op node - irrelevant for others...
|
118
|
+
if drag_node.has_ancestor("branch reg"):
|
119
|
+
# Will be dealt with in elements -
|
120
|
+
# we don't implement a more sophisticated routine here
|
121
|
+
return False
|
122
|
+
if (
|
123
|
+
hasattr(drag_node, "as_geometry")
|
124
|
+
and drag_node.type in self._allowed_elements_dnd
|
125
|
+
):
|
126
|
+
return True
|
127
|
+
elif (
|
128
|
+
drag_node.type == "reference"
|
129
|
+
and drag_node.node.type in self._allowed_elements_dnd
|
130
|
+
):
|
131
|
+
return True
|
132
|
+
elif drag_node.type in op_nodes:
|
133
|
+
# Move operation to a different position.
|
134
|
+
return True
|
135
|
+
elif drag_node.type in ("file", "group"):
|
136
|
+
return not any(e.has_ancestor("branch reg") for e in drag_node.flat(elem_nodes))
|
137
|
+
return False
|
138
|
+
|
139
|
+
def drop(self, drag_node, modify=True, flag=False):
|
140
|
+
# Default routine for drag + drop for an op node - irrelevant for others...
|
141
|
+
if hasattr(drag_node, "as_geometry"):
|
142
|
+
if (
|
143
|
+
drag_node.type not in self._allowed_elements_dnd
|
144
|
+
or drag_node.has_ancestor("branch reg")
|
145
|
+
):
|
146
|
+
return False
|
147
|
+
# Dragging element onto operation adds that element to the op.
|
148
|
+
if modify:
|
149
|
+
self.add_reference(drag_node, pos=None if flag else 0)
|
150
|
+
return True
|
151
|
+
elif drag_node.type == "reference":
|
152
|
+
# Disallow drop of image refelems onto a Dot op.
|
153
|
+
if drag_node.node.type not in self._allowed_elements_dnd:
|
154
|
+
return False
|
155
|
+
# Move a refelem to end of op.
|
156
|
+
if modify:
|
157
|
+
self.append_child(drag_node)
|
158
|
+
return True
|
159
|
+
elif drag_node.type in op_nodes:
|
160
|
+
# Move operation to a different position.
|
161
|
+
if modify:
|
162
|
+
self.insert_sibling(drag_node)
|
163
|
+
return True
|
164
|
+
elif drag_node.type in ("file", "group") and not drag_node.has_ancestor(
|
165
|
+
"branch reg"
|
166
|
+
):
|
167
|
+
some_nodes = False
|
168
|
+
for e in drag_node.flat(elem_nodes):
|
169
|
+
# Add element to operation
|
170
|
+
if e.type in self._allowed_elements_dnd:
|
171
|
+
if modify:
|
172
|
+
self.add_reference(e)
|
173
|
+
some_nodes = True
|
174
|
+
return some_nodes
|
175
|
+
return False
|
176
|
+
|
177
|
+
def would_accept_drop(self, drag_nodes):
|
178
|
+
# drag_nodes can be a single node or a list of nodes
|
179
|
+
if isinstance(drag_nodes, (list, tuple)):
|
180
|
+
data = drag_nodes
|
181
|
+
else:
|
182
|
+
data = list(drag_nodes)
|
183
|
+
for drag_node in data:
|
184
|
+
if drag_node.has_ancestor("branch reg"):
|
185
|
+
continue
|
186
|
+
if (
|
187
|
+
(
|
188
|
+
hasattr(drag_node, "as_geometry")
|
189
|
+
and drag_node.type in self._allowed_elements_dnd
|
190
|
+
)
|
191
|
+
or drag_node.type in ("file", "group")
|
192
|
+
or drag_node.type in op_nodes
|
193
|
+
or drag_node.type == "reference"
|
194
|
+
):
|
195
|
+
return True
|
196
|
+
return False
|
197
|
+
|
198
|
+
def has_color_attribute(self, attribute):
|
199
|
+
return attribute in self.allowed_attributes
|
200
|
+
|
201
|
+
def add_color_attribute(self, attribute):
|
202
|
+
if not attribute in self.allowed_attributes:
|
203
|
+
self.allowed_attributes.append(attribute)
|
204
|
+
|
205
|
+
def remove_color_attribute(self, attribute):
|
206
|
+
if attribute in self.allowed_attributes:
|
207
|
+
self.allowed_attributes.remove(attribute)
|
208
|
+
|
209
|
+
def has_attributes(self):
|
210
|
+
return "stroke" in self.allowed_attributes or "fill" in self.allowed_attributes
|
211
|
+
|
212
|
+
def is_referenced(self, node):
|
213
|
+
for e in self.children:
|
214
|
+
if e is node:
|
215
|
+
return True
|
216
|
+
if hasattr(e, "node") and e.node is node:
|
217
|
+
return True
|
218
|
+
return False
|
219
|
+
|
220
|
+
def valid_node_for_reference(self, node):
|
221
|
+
if node.type in self._allowed_elements_dnd:
|
222
|
+
return True
|
223
|
+
else:
|
224
|
+
return False
|
225
|
+
|
226
|
+
def classify(self, node, fuzzy=False, fuzzydistance=100, usedefault=False):
|
227
|
+
def matching_color(col1, col2):
|
228
|
+
_result = False
|
229
|
+
if col1 is None and col2 is None:
|
230
|
+
_result = True
|
231
|
+
elif (
|
232
|
+
col1 is not None
|
233
|
+
and col1.argb is not None
|
234
|
+
and col2 is not None
|
235
|
+
and col2.argb is not None
|
236
|
+
):
|
237
|
+
if fuzzy:
|
238
|
+
distance = Color.distance(col1, col2)
|
239
|
+
_result = distance < fuzzydistance
|
240
|
+
else:
|
241
|
+
_result = col1 == col2
|
242
|
+
return _result
|
243
|
+
|
244
|
+
if self.is_referenced(node):
|
245
|
+
# No need to add it again...
|
246
|
+
return False, False, None
|
247
|
+
feedback = []
|
248
|
+
if node.type in self._allowed_elements:
|
249
|
+
if not self.default:
|
250
|
+
if self.has_attributes():
|
251
|
+
result = False
|
252
|
+
for attribute in self.allowed_attributes:
|
253
|
+
if (
|
254
|
+
hasattr(node, attribute)
|
255
|
+
and getattr(node, attribute) is not None
|
256
|
+
):
|
257
|
+
plain_color_op = abs(self.color)
|
258
|
+
plain_color_node = abs(getattr(node, attribute))
|
259
|
+
if matching_color(plain_color_op, plain_color_node):
|
260
|
+
if self.valid_node_for_reference(node):
|
261
|
+
result = True
|
262
|
+
self.add_reference(node)
|
263
|
+
# Have classified but more classification might be needed
|
264
|
+
feedback.append(attribute)
|
265
|
+
if result:
|
266
|
+
return True, self.stopop, feedback
|
267
|
+
else: # empty ? Anything goes
|
268
|
+
if self.valid_node_for_reference(node):
|
269
|
+
self.add_reference(node)
|
270
|
+
# Have classified but more classification might be needed
|
271
|
+
feedback.append("stroke")
|
272
|
+
feedback.append("fill")
|
273
|
+
return True, self.stopop, feedback
|
274
|
+
elif self.default and usedefault:
|
275
|
+
# Have classified but more classification might be needed
|
276
|
+
if self.valid_node_for_reference(node):
|
277
|
+
self.add_reference(node)
|
278
|
+
feedback.append("stroke")
|
279
|
+
feedback.append("fill")
|
280
|
+
return True, self.stopop, feedback
|
281
|
+
return False, False, None
|
282
|
+
|
283
|
+
def add_reference(self, node=None, pos=None, **kwargs):
|
284
|
+
# is the very first child an effect node?
|
285
|
+
# if yes then we will put that reference under this one
|
286
|
+
if node is None:
|
287
|
+
return
|
288
|
+
if not self.valid_node_for_reference(node):
|
289
|
+
# We could raise a ValueError but that will break things...
|
290
|
+
return
|
291
|
+
first_is_effect = (
|
292
|
+
len(self._children) > 0 and
|
293
|
+
self._children[0].type.startswith("effect ")
|
294
|
+
)
|
295
|
+
effect = self._children[0] if first_is_effect else None
|
296
|
+
ref = self.add(node=node, type="reference", pos=pos, **kwargs)
|
297
|
+
node._references.append(ref)
|
298
|
+
if first_is_effect:
|
299
|
+
effect.append_child(ref)
|
300
|
+
|
301
|
+
def load(self, settings, section):
|
302
|
+
settings.read_persistent_attributes(section, self)
|
303
|
+
hexa = self.settings.get("hex_color")
|
304
|
+
if hexa is not None:
|
305
|
+
self.color = Color(hexa)
|
306
|
+
self.updated()
|
307
|
+
|
308
|
+
def save(self, settings, section):
|
309
|
+
# Sync certain properties with self.settings
|
310
|
+
for attr in ("label", "lock", "id"):
|
311
|
+
if hasattr(self, attr) and attr in self.settings:
|
312
|
+
self.settings[attr] = getattr(self, attr)
|
313
|
+
if "hex_color" in self.settings:
|
314
|
+
self.settings["hex_color"] = self.color.hexa
|
315
|
+
|
316
|
+
settings.write_persistent_attributes(section, self)
|
317
|
+
settings.write_persistent(section, "hex_color", self.color.hexa)
|
318
|
+
settings.write_persistent_dict(section, self.settings)
|
319
|
+
|
320
|
+
def time_estimate(self):
|
321
|
+
estimate = 0
|
322
|
+
for node in self.children:
|
323
|
+
if node.type == "reference":
|
324
|
+
node = node.node
|
325
|
+
try:
|
326
|
+
path = node.as_path()
|
327
|
+
except AttributeError:
|
328
|
+
continue
|
329
|
+
try:
|
330
|
+
length = path.length(error=1e-2, min_depth=2)
|
331
|
+
except AttributeError:
|
332
|
+
length = 0
|
333
|
+
try:
|
334
|
+
estimate += length / (UNITS_PER_MM * self.speed)
|
335
|
+
except ZeroDivisionError:
|
336
|
+
estimate = float("inf")
|
337
|
+
if self.passes_custom and self.passes != 1:
|
338
|
+
estimate *= max(self.passes, 1)
|
339
|
+
|
340
|
+
if isnan(estimate):
|
341
|
+
estimate = 0
|
342
|
+
|
343
|
+
hours, remainder = divmod(estimate, 3600)
|
344
|
+
minutes, seconds = divmod(remainder, 60)
|
345
|
+
return f"{int(hours)}:{str(int(minutes)).zfill(2)}:{str(int(seconds)).zfill(2)}"
|
346
|
+
|
347
|
+
def preprocess(self, context, matrix, plan):
|
348
|
+
"""
|
349
|
+
Preprocess hatch values
|
350
|
+
|
351
|
+
@param context:
|
352
|
+
@param matrix:
|
353
|
+
@param plan: Plan value during preprocessor call
|
354
|
+
@return:
|
355
|
+
"""
|
356
|
+
if isinstance(self.speed, str):
|
357
|
+
try:
|
358
|
+
self.speed = float(self.speed)
|
359
|
+
except ValueError:
|
360
|
+
pass
|
361
|
+
native_mm = abs(complex(*matrix.transform_vector([0, UNITS_PER_MM])))
|
362
|
+
if self.kerf is None:
|
363
|
+
self.kerf = 0.0
|
364
|
+
self.settings["native_mm"] = native_mm
|
365
|
+
self.settings["native_speed"] = self.speed * native_mm
|
366
|
+
self.settings["native_rapid_speed"] = self.rapid_speed * native_mm
|
367
|
+
# We need to establish the native device resolution,
|
368
|
+
# as kerf is given in scene space but needs to be passed on in device space
|
369
|
+
device = context.device
|
370
|
+
self._device_factor = 1 / abs(
|
371
|
+
complex(device.view.native_scale_x, device.view.native_scale_y)
|
372
|
+
)
|
373
|
+
|
374
|
+
def as_cutobjects(self, closed_distance=15, passes=1):
|
375
|
+
"""Generator of cutobjects for a particular operation."""
|
376
|
+
|
377
|
+
def get_pathlist(node, factor):
|
378
|
+
from time import perf_counter
|
379
|
+
|
380
|
+
pathlist = []
|
381
|
+
if node.type == "reference":
|
382
|
+
node = node.node
|
383
|
+
if node.type == "elem image":
|
384
|
+
box = node.bbox()
|
385
|
+
pathlist.append(
|
386
|
+
(
|
387
|
+
None,
|
388
|
+
Path(
|
389
|
+
Polygon(
|
390
|
+
(box[0], box[1]),
|
391
|
+
(box[0], box[3]),
|
392
|
+
(box[2], box[3]),
|
393
|
+
(box[2], box[1]),
|
394
|
+
)
|
395
|
+
),
|
396
|
+
)
|
397
|
+
)
|
398
|
+
elif hasattr(node, "final_geometry"):
|
399
|
+
# This will deliver all relevant effects
|
400
|
+
# like tabs, dots/dashes applied to the element
|
401
|
+
path = node.final_geometry(unitfactor=factor).as_path()
|
402
|
+
path.approximate_arcs_with_cubics()
|
403
|
+
pathlist.append((None, path))
|
404
|
+
elif node.type == "elem path":
|
405
|
+
path = abs(node.path)
|
406
|
+
path.approximate_arcs_with_cubics()
|
407
|
+
pathlist.append((None, path))
|
408
|
+
elif node.type.startswith("effect"):
|
409
|
+
if hasattr(node, "as_geometries"):
|
410
|
+
time_indicator = f"{perf_counter():.5f}".replace(".", "")
|
411
|
+
pathlist.extend(
|
412
|
+
(f"hatch_{idx}_{time_indicator}", effect_geom.as_path())
|
413
|
+
for idx, effect_geom in enumerate(list(node.as_geometries()))
|
414
|
+
)
|
415
|
+
else:
|
416
|
+
pathlist.append((None, node.as_geometry().as_path()))
|
417
|
+
else:
|
418
|
+
path = abs(Path(node.shape))
|
419
|
+
path.approximate_arcs_with_cubics()
|
420
|
+
pathlist.append((None, path))
|
421
|
+
return pathlist
|
422
|
+
|
423
|
+
settings = self.derive()
|
424
|
+
factor = settings["native_mm"] / UNITS_PER_MM if "native_mm" in settings else 1
|
425
|
+
for node in self.children:
|
426
|
+
if (
|
427
|
+
hasattr(node, "hidden")
|
428
|
+
and node.hidden
|
429
|
+
or node.type not in self._allowed_elements_dnd
|
430
|
+
):
|
431
|
+
continue
|
432
|
+
|
433
|
+
pathlist = get_pathlist(node, factor)
|
434
|
+
try:
|
435
|
+
stroke = node.stroke
|
436
|
+
except AttributeError:
|
437
|
+
# ImageNode does not have a stroke.
|
438
|
+
stroke = None
|
439
|
+
for origin, path in pathlist:
|
440
|
+
yield from path_to_cutobjects(
|
441
|
+
path,
|
442
|
+
settings=settings,
|
443
|
+
closed_distance=closed_distance,
|
444
|
+
passes=passes,
|
445
|
+
original_op=self.type,
|
446
|
+
color=stroke,
|
447
|
+
kerf=self.kerf * self._device_factor,
|
448
|
+
offset_routine=self.offset_routine,
|
449
|
+
origin=origin,
|
450
|
+
)
|
451
|
+
|
452
|
+
@property
|
453
|
+
def bounds(self):
|
454
|
+
if not self._bounds_dirty:
|
455
|
+
return self._bounds
|
456
|
+
|
457
|
+
self._bounds = None
|
458
|
+
if self.output:
|
459
|
+
if self._children:
|
460
|
+
self._bounds = Node.union_bounds(self._children, bounds=self._bounds, ignore_locked=False, ignore_hidden=True)
|
461
|
+
self._bounds_dirty = False
|
462
|
+
return self._bounds
|