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/elements/grid.py
CHANGED
@@ -1,316 +1,467 @@
|
|
1
|
-
"""
|
2
|
-
This
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
)
|
127
|
-
@self.
|
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
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
if
|
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
|
-
@self.
|
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
|
-
return
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
if
|
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
|
-
|
1
|
+
"""
|
2
|
+
This module provides a set of console commands for managing grid and radial operations within the application.
|
3
|
+
Users can create grids, radial patterns, and circular copies of elements, allowing for efficient arrangement and manipulation of graphical objects.
|
4
|
+
|
5
|
+
Functions:
|
6
|
+
- plugin(kernel, lifecycle=None): Initializes the plugin and sets up grid commands.
|
7
|
+
- init_commands(kernel): Initializes the grid commands and defines the associated operations.
|
8
|
+
- element_grid(command, channel, _, c: int, r: int, x: str, y: str, origin=None, relative=None, data=None, post=None, **kwargs): Creates a grid of elements based on specified rows, columns, and distances.
|
9
|
+
Args:
|
10
|
+
command: The command context.
|
11
|
+
channel: The communication channel for messages.
|
12
|
+
c: The number of columns in the grid.
|
13
|
+
r: The number of rows in the grid.
|
14
|
+
x: The distance between columns.
|
15
|
+
y: The distance between rows.
|
16
|
+
origin: The origin point for the grid.
|
17
|
+
relative: A flag indicating whether distances are relative.
|
18
|
+
data: The elements to arrange in the grid.
|
19
|
+
post: Additional processing information.
|
20
|
+
Returns:
|
21
|
+
A tuple containing the type of elements and the created grid elements.
|
22
|
+
- element_radial(command, channel, _, repeats: int, radius=None, startangle=None, endangle=None, rotate=None, deltaangle=None, data=None, post=None, **kwargs): Creates a radial arrangement of elements based on specified parameters.
|
23
|
+
Args:
|
24
|
+
command: The command context.
|
25
|
+
channel: The communication channel for messages.
|
26
|
+
repeats: The number of copies to create.
|
27
|
+
radius: The radius of the radial arrangement.
|
28
|
+
startangle: The starting angle for the arrangement.
|
29
|
+
endangle: The ending angle for the arrangement.
|
30
|
+
rotate: A flag indicating whether to rotate copies towards the center.
|
31
|
+
deltaangle: The angle increment for each copy.
|
32
|
+
data: The elements to arrange radially.
|
33
|
+
post: Additional processing information.
|
34
|
+
Returns:
|
35
|
+
A tuple containing the type of elements and the created radial elements.
|
36
|
+
- element_circularcopies(command, channel, _, copies: int, radius=None, startangle=None, endangle=None, rotate=None, deltaangle=None, data=None, post=None, **kwargs): Creates circular copies of elements based on specified parameters.
|
37
|
+
Args:
|
38
|
+
command: The command context.
|
39
|
+
channel: The communication channel for messages.
|
40
|
+
copies: The number of copies to create.
|
41
|
+
radius: The radius of the circular arrangement.
|
42
|
+
startangle: The starting angle for the arrangement.
|
43
|
+
endangle: The ending angle for the arrangement.
|
44
|
+
rotate: A flag indicating whether to rotate copies towards the center.
|
45
|
+
deltaangle: The angle increment for each copy.
|
46
|
+
data: The elements to arrange circularly.
|
47
|
+
post: Additional processing information.
|
48
|
+
Returns:
|
49
|
+
A tuple containing the type of elements and the created circular elements.
|
50
|
+
- element_subpath(data=None, post=None, **kwargs): Breaks elements into subpaths, creating separate nodes for each.
|
51
|
+
Args:
|
52
|
+
data: The elements to break into subpaths.
|
53
|
+
post: Additional processing information.
|
54
|
+
Returns:
|
55
|
+
A tuple containing the type of elements and the created subpath elements.
|
56
|
+
- operation_empty(channel, _, data=None, data_type=None, **kwargs): Removes all elements from the specified operations.
|
57
|
+
Args:
|
58
|
+
channel: The communication channel for messages.
|
59
|
+
data: The operations to clear.
|
60
|
+
data_type: The type of data being processed.
|
61
|
+
Returns:
|
62
|
+
A tuple containing the type of data and the cleared operations.
|
63
|
+
- operation_list(command, channel, _, data=None, **kwargs): Lists information about the specified operations.
|
64
|
+
Args:
|
65
|
+
command: The command context.
|
66
|
+
channel: The communication channel for messages.
|
67
|
+
data: The operations to list.
|
68
|
+
Returns:
|
69
|
+
A tuple containing the type of data and the listed operations.
|
70
|
+
- e_lock(data=None, **kwargs): Locks the specified elements to prevent manipulation.
|
71
|
+
Args:
|
72
|
+
data: The elements to lock.
|
73
|
+
Returns:
|
74
|
+
A tuple containing the type of data and the locked elements.
|
75
|
+
- e_unlock(data=None, **kwargs): Unlocks the specified elements to allow manipulation.
|
76
|
+
Args:
|
77
|
+
data: The elements to unlock.
|
78
|
+
Returns:
|
79
|
+
A tuple containing the type of data and the unlocked elements.
|
80
|
+
- e_copy(data=None, data_type=None, post=None, dx=None, dy=None, copies=None, **kwargs): Duplicates the specified elements a given number of times with optional offsets.
|
81
|
+
Args:
|
82
|
+
data: The elements to copy.
|
83
|
+
data_type: The type of data being processed.
|
84
|
+
post: Additional processing information.
|
85
|
+
dx: The x-offset for the copies.
|
86
|
+
dy: The y-offset for the copies.
|
87
|
+
copies: The number of copies to create.
|
88
|
+
Returns:
|
89
|
+
A tuple containing the type of data and the copied elements.
|
90
|
+
- e_delete(command, channel, _, data=None, data_type=None, **kwargs): Deletes the specified elements or operations.
|
91
|
+
Args:
|
92
|
+
command: The command context.
|
93
|
+
channel: The communication channel for messages.
|
94
|
+
data: The elements or operations to delete.
|
95
|
+
data_type: The type of data being processed.
|
96
|
+
Returns:
|
97
|
+
A tuple containing the type of data and the deleted elements.
|
98
|
+
"""
|
99
|
+
|
100
|
+
from copy import copy
|
101
|
+
from math import cos, sin, tau
|
102
|
+
|
103
|
+
from meerk40t.core.node.node import Node
|
104
|
+
from meerk40t.core.units import Angle, Length
|
105
|
+
from meerk40t.kernel import CommandSyntaxError
|
106
|
+
from meerk40t.svgelements import Matrix
|
107
|
+
|
108
|
+
|
109
|
+
def plugin(kernel, lifecycle=None):
|
110
|
+
_ = kernel.translation
|
111
|
+
if lifecycle == "postboot":
|
112
|
+
init_commands(kernel)
|
113
|
+
|
114
|
+
|
115
|
+
def init_commands(kernel):
|
116
|
+
self = kernel.elements
|
117
|
+
|
118
|
+
_ = kernel.translation
|
119
|
+
|
120
|
+
classify_new = self.post_classify
|
121
|
+
|
122
|
+
# ==========
|
123
|
+
# GRID SUBTYPE
|
124
|
+
# ==========
|
125
|
+
|
126
|
+
@self.console_argument("columns", type=int, help=_("Number of columns"), default=2,)
|
127
|
+
@self.console_argument("rows", type=int, help=_("Number of rows"), default=2,)
|
128
|
+
@self.console_argument("x_distance", type=str, help=_("x distance"), default="100%")
|
129
|
+
@self.console_argument("y_distance", type=str, help=_("y distance"), default="100%")
|
130
|
+
@self.console_option(
|
131
|
+
"origin",
|
132
|
+
"o",
|
133
|
+
type=int,
|
134
|
+
nargs=2,
|
135
|
+
default = (1, 1),
|
136
|
+
help=_("Position of original in matrix (e.g '2,2' or '4,3')"),
|
137
|
+
)
|
138
|
+
@self.console_option(
|
139
|
+
"relative",
|
140
|
+
"r",
|
141
|
+
type=bool,
|
142
|
+
action="store_true",
|
143
|
+
help=_("Distance not absolute but as relative gap"),
|
144
|
+
)
|
145
|
+
@self.console_command(
|
146
|
+
"grid",
|
147
|
+
help=_("grid <columns> <rows> <x_distance> <y_distance> <origin>"),
|
148
|
+
input_type=(None, "elements"),
|
149
|
+
output_type="elements",
|
150
|
+
)
|
151
|
+
def element_grid(
|
152
|
+
command,
|
153
|
+
channel,
|
154
|
+
_,
|
155
|
+
columns: int,
|
156
|
+
rows: int,
|
157
|
+
x_distance: str,
|
158
|
+
y_distance: str,
|
159
|
+
origin=None,
|
160
|
+
relative=None,
|
161
|
+
data=None,
|
162
|
+
post=None,
|
163
|
+
**kwargs,
|
164
|
+
):
|
165
|
+
"""
|
166
|
+
The grid command wil take the selection and create copies orienting them in a rectangular grid like fashion.
|
167
|
+
You can define the amount of rows/columns and how the grid should be orientated around the original elements
|
168
|
+
"""
|
169
|
+
if rows is None:
|
170
|
+
raise CommandSyntaxError
|
171
|
+
if data is None:
|
172
|
+
data = list(self.elems(emphasized=True))
|
173
|
+
if len(data) == 0:
|
174
|
+
channel(_("No item selected."))
|
175
|
+
return
|
176
|
+
if relative is None:
|
177
|
+
relative = False
|
178
|
+
try:
|
179
|
+
bounds = Node.union_bounds(data)
|
180
|
+
width = bounds[2] - bounds[0]
|
181
|
+
height = bounds[3] - bounds[1]
|
182
|
+
except TypeError:
|
183
|
+
raise CommandSyntaxError
|
184
|
+
if x_distance is None:
|
185
|
+
x_distance = "100%"
|
186
|
+
if y_distance is None:
|
187
|
+
y_distance = "100%"
|
188
|
+
try:
|
189
|
+
x_distance = float(Length(x_distance, relative_length=Length(amount=width).length_mm))
|
190
|
+
y_distance = float(Length(y_distance, relative_length=Length(amount=height).length_mm))
|
191
|
+
except ValueError:
|
192
|
+
raise CommandSyntaxError("Length could not be parsed.")
|
193
|
+
counted = 0
|
194
|
+
# _("Create grid")
|
195
|
+
with self.undoscope("Create grid"):
|
196
|
+
if relative:
|
197
|
+
x_distance += width
|
198
|
+
y_distance += height
|
199
|
+
if origin is None:
|
200
|
+
origin = (1, 1)
|
201
|
+
cx, cy = origin
|
202
|
+
data_out = list(data)
|
203
|
+
if cx is None:
|
204
|
+
cx = 1
|
205
|
+
if cy is None:
|
206
|
+
cy = 1
|
207
|
+
start_x = -1 * x_distance * (cx - 1)
|
208
|
+
start_y = -1 * y_distance * (cy - 1)
|
209
|
+
y_pos = start_y
|
210
|
+
for j in range(rows):
|
211
|
+
x_pos = start_x
|
212
|
+
for k in range(columns):
|
213
|
+
if j != (cy - 1) or k != (cx - 1):
|
214
|
+
add_elem = list(map(copy, data))
|
215
|
+
for e in add_elem:
|
216
|
+
e.matrix *= Matrix.translate(x_pos, y_pos)
|
217
|
+
self.elem_branch.add_node(e)
|
218
|
+
data_out.extend(add_elem)
|
219
|
+
counted += 1
|
220
|
+
x_pos += x_distance
|
221
|
+
y_pos += y_distance
|
222
|
+
channel(f"{counted} copies created")
|
223
|
+
# Newly created! Classification needed?
|
224
|
+
post.append(classify_new(data_out))
|
225
|
+
self.signal("refresh_scene", "Scene")
|
226
|
+
return "elements", data_out
|
227
|
+
|
228
|
+
@self.console_argument("repeats", type=int, help=_("Number of repeats"), default=3)
|
229
|
+
@self.console_argument("radius", type=self.length, help=_("Radius"), default="2cm")
|
230
|
+
@self.console_argument("startangle", type=Angle, help=_("Start-Angle"), default="0deg")
|
231
|
+
@self.console_argument("endangle", type=Angle, help=_("End-Angle"), default="360deg")
|
232
|
+
@self.console_option(
|
233
|
+
"unrotated",
|
234
|
+
"u",
|
235
|
+
type=bool,
|
236
|
+
action="store_true",
|
237
|
+
help=_("Leave copies unrotated?"),
|
238
|
+
)
|
239
|
+
@self.console_option(
|
240
|
+
"deltaangle",
|
241
|
+
"d",
|
242
|
+
type=Angle,
|
243
|
+
help=_("Delta-Angle (if omitted will take (end-start)/repeats )"),
|
244
|
+
)
|
245
|
+
@self.console_command(
|
246
|
+
"radial",
|
247
|
+
help=_("radial <repeats> <radius> <startangle> <endangle> <rotate>"),
|
248
|
+
input_type=(None, "elements"),
|
249
|
+
output_type="elements",
|
250
|
+
)
|
251
|
+
def element_radial(
|
252
|
+
command,
|
253
|
+
channel,
|
254
|
+
_,
|
255
|
+
repeats: int,
|
256
|
+
radius=None,
|
257
|
+
startangle=None,
|
258
|
+
endangle=None,
|
259
|
+
unrotated=None,
|
260
|
+
deltaangle=None,
|
261
|
+
data=None,
|
262
|
+
post=None,
|
263
|
+
**kwargs,
|
264
|
+
):
|
265
|
+
"""
|
266
|
+
Radial copy takes some parameters to create (potentially rotated) copies on a circular arc around a defined center
|
267
|
+
Notabene: While circ_copy is creating copies around the original elements, radial is creating all the copies
|
268
|
+
around a center just -1*radius to the left. So the original elements will be part of the circle.
|
269
|
+
"""
|
270
|
+
if data is None:
|
271
|
+
data = list(self.elems(emphasized=True))
|
272
|
+
if len(data) == 0 and self._emphasized_bounds is None:
|
273
|
+
channel(_("No item selected."))
|
274
|
+
return
|
275
|
+
if unrotated is None:
|
276
|
+
unrotated = False
|
277
|
+
rotate = not unrotated
|
278
|
+
if repeats is None:
|
279
|
+
raise CommandSyntaxError
|
280
|
+
if repeats <= 1:
|
281
|
+
raise CommandSyntaxError(_("repeats should be greater or equal to 2"))
|
282
|
+
if radius is None:
|
283
|
+
radius = 0
|
284
|
+
|
285
|
+
if startangle is None:
|
286
|
+
startangle = Angle("0deg")
|
287
|
+
if endangle is None:
|
288
|
+
endangle = Angle("360deg")
|
289
|
+
if rotate is None:
|
290
|
+
rotate = False
|
291
|
+
|
292
|
+
# print ("Segment to cover: %f - %f" % (startangle.as_degrees, endangle.as_degrees))
|
293
|
+
bounds = Node.union_bounds(data)
|
294
|
+
if bounds is None:
|
295
|
+
return
|
296
|
+
data_out = list(data)
|
297
|
+
|
298
|
+
segment_len = (endangle - startangle) / repeats if deltaangle is None else deltaangle
|
299
|
+
channel(f"Angle per step: {segment_len.angle_degrees}")
|
300
|
+
|
301
|
+
# Notabene: we are following the cartesian system here, but as the Y-Axis is top screen to bottom screen,
|
302
|
+
# the perceived angle travel is CCW (which is counter-intuitive)
|
303
|
+
center_x = (bounds[2] + bounds[0]) / 2.0 - radius
|
304
|
+
center_y = (bounds[3] + bounds[1]) / 2.0
|
305
|
+
|
306
|
+
# print (f"repeats: {repeats}, Radius: {radius}")
|
307
|
+
# print (f"Center: ({center_x}, {center_y})")
|
308
|
+
# print (f"Startangle, Endangle, segment_len: {startangle.angle_degrees}, {endangle.angle_degrees}, {segment_len.angle_degrees}")
|
309
|
+
images = []
|
310
|
+
counted = 0
|
311
|
+
# _("Create radial")
|
312
|
+
with self.undoscope("Create radial"):
|
313
|
+
currentangle = Angle(segment_len)
|
314
|
+
for cc in range(1, repeats):
|
315
|
+
# print (f"Angle: {currentangle.angle_degrees}")
|
316
|
+
add_elem = list(map(copy, data))
|
317
|
+
for e in add_elem:
|
318
|
+
if hasattr(e, "as_image"):
|
319
|
+
images.append(e)
|
320
|
+
if rotate:
|
321
|
+
# x_pos = -1 * radius
|
322
|
+
# y_pos = 0
|
323
|
+
# e *= "translate(%f, %f)" % (x_pos, y_pos)
|
324
|
+
e.matrix *= f"rotate({currentangle.angle_preferred}, {center_x}, {center_y})"
|
325
|
+
else:
|
326
|
+
x_pos = -1 * radius + radius * cos(currentangle)
|
327
|
+
y_pos = radius * sin(currentangle)
|
328
|
+
e.matrix *= f"translate({x_pos}, {y_pos})"
|
329
|
+
self.elem_branch.add_node(e)
|
330
|
+
|
331
|
+
counted += 1
|
332
|
+
data_out.extend(add_elem)
|
333
|
+
|
334
|
+
currentangle += segment_len
|
335
|
+
while (currentangle.angle >= tau):
|
336
|
+
currentangle.angle -= tau
|
337
|
+
while (currentangle.angle <= -tau):
|
338
|
+
currentangle.angle += tau
|
339
|
+
for e in images:
|
340
|
+
self.do_image_update(e)
|
341
|
+
|
342
|
+
channel(f"{counted} copies created")
|
343
|
+
# Newly created! Classification needed?
|
344
|
+
post.append(classify_new(data_out))
|
345
|
+
self.signal("refresh_scene", "Scene")
|
346
|
+
return "elements", data_out
|
347
|
+
|
348
|
+
@self.console_argument("copies", type=int, help=_("Number of copies"), default=1)
|
349
|
+
@self.console_argument("radius", type=self.length, help=_("Radius"), default="2cm")
|
350
|
+
@self.console_argument("startangle", type=Angle, help=_("Start-Angle"), default="0deg")
|
351
|
+
@self.console_argument("endangle", type=Angle, help=_("End-Angle"), default="360deg")
|
352
|
+
@self.console_option(
|
353
|
+
"rotate",
|
354
|
+
"r",
|
355
|
+
type=bool,
|
356
|
+
action="store_true",
|
357
|
+
help=_("Rotate copies towards center?"),
|
358
|
+
default=False,
|
359
|
+
)
|
360
|
+
@self.console_option(
|
361
|
+
"deltaangle",
|
362
|
+
"d",
|
363
|
+
type=Angle,
|
364
|
+
help=_("Delta-Angle (if omitted will take (end-start)/copies )"),
|
365
|
+
)
|
366
|
+
@self.console_command(
|
367
|
+
"circ_copy",
|
368
|
+
help=_("circ_copy <copies> <radius> <startangle> <endangle> <rotate>"),
|
369
|
+
input_type=(None, "elements"),
|
370
|
+
output_type="elements",
|
371
|
+
)
|
372
|
+
def element_circularcopies(
|
373
|
+
command,
|
374
|
+
channel,
|
375
|
+
_,
|
376
|
+
copies: int,
|
377
|
+
radius=None,
|
378
|
+
startangle=None,
|
379
|
+
endangle=None,
|
380
|
+
rotate=None,
|
381
|
+
deltaangle=None,
|
382
|
+
data=None,
|
383
|
+
post=None,
|
384
|
+
**kwargs,
|
385
|
+
):
|
386
|
+
"""
|
387
|
+
Circular copy takes some parameters to create (potentially rotated) copies on a circular arc around the orginal element(s)
|
388
|
+
Notabene: While circ_copy is creating copies around the original elements, radial is creating all the copies
|
389
|
+
around a center just -1*radius to the left. So the original elements will be part of the circle.
|
390
|
+
"""
|
391
|
+
if data is None:
|
392
|
+
data = list(self.elems(emphasized=True))
|
393
|
+
if len(data) == 0 and self._emphasized_bounds is None:
|
394
|
+
channel(_("No item selected."))
|
395
|
+
return
|
396
|
+
|
397
|
+
if copies is None:
|
398
|
+
raise CommandSyntaxError
|
399
|
+
if copies <= 0:
|
400
|
+
copies = 1
|
401
|
+
if radius is None:
|
402
|
+
radius = 0
|
403
|
+
|
404
|
+
if startangle is None:
|
405
|
+
startangle = Angle("0deg")
|
406
|
+
if endangle is None:
|
407
|
+
endangle = Angle("360deg")
|
408
|
+
if rotate is None:
|
409
|
+
rotate = False
|
410
|
+
|
411
|
+
# print ("Segment to cover: %f - %f" % (startangle.as_degrees, endangle.as_degrees))
|
412
|
+
bounds = Node.union_bounds(data)
|
413
|
+
if bounds is None:
|
414
|
+
return
|
415
|
+
# width = bounds[2] - bounds[0]
|
416
|
+
|
417
|
+
data_out = list(data)
|
418
|
+
if deltaangle is None:
|
419
|
+
segment_len = (endangle - startangle) / copies
|
420
|
+
else:
|
421
|
+
segment_len = deltaangle
|
422
|
+
# Notabene: we are following the cartesian system here, but as the Y-Axis is top screen to bottom screen,
|
423
|
+
# the perceived angle travel is CCW (which is counter-intuitive)
|
424
|
+
currentangle = Angle(startangle)
|
425
|
+
# bounds = self._emphasized_bounds
|
426
|
+
center_x = (bounds[2] + bounds[0]) / 2.0
|
427
|
+
center_y = (bounds[3] + bounds[1]) / 2.0
|
428
|
+
images = []
|
429
|
+
counted = 0
|
430
|
+
# _("Create circular copy")
|
431
|
+
with self.undoscope("Create circular copy"):
|
432
|
+
for cc in range(copies):
|
433
|
+
# print ("Angle: %f rad = %f deg" % (currentangle, currentangle/pi * 180))
|
434
|
+
add_elem = list(map(copy, data))
|
435
|
+
for e in add_elem:
|
436
|
+
if hasattr(e, "as_image"):
|
437
|
+
images.append(e)
|
438
|
+
if rotate:
|
439
|
+
x_pos = radius
|
440
|
+
y_pos = 0
|
441
|
+
e.matrix *= f"translate({x_pos}, {y_pos})"
|
442
|
+
e.matrix *= f"rotate({currentangle.angle_preferred}, {center_x}, {center_y})"
|
443
|
+
e.modified()
|
444
|
+
if hasattr(e, "update"):
|
445
|
+
images.append(e)
|
446
|
+
else:
|
447
|
+
x_pos = radius * cos(currentangle)
|
448
|
+
y_pos = radius * sin(currentangle)
|
449
|
+
e.matrix *= f"translate({x_pos}, {y_pos})"
|
450
|
+
e.translated(x_pos, y_pos)
|
451
|
+
self.elem_branch.add_node(e)
|
452
|
+
counted += 1
|
453
|
+
data_out.extend(add_elem)
|
454
|
+
currentangle += segment_len
|
455
|
+
while (currentangle.angle >= tau):
|
456
|
+
currentangle.angle -= tau
|
457
|
+
while (currentangle.angle <= -tau):
|
458
|
+
currentangle.angle += tau
|
459
|
+
for e in images:
|
460
|
+
self.do_image_update(e)
|
461
|
+
channel(f"{counted} copies created")
|
462
|
+
|
463
|
+
post.append(classify_new(data_out))
|
464
|
+
self.signal("refresh_scene", "Scene")
|
465
|
+
return "elements", data_out
|
466
|
+
|
467
|
+
# --------------------------- END COMMANDS ------------------------------
|