meerk40t 0.9.7030__py2.py3-none-any.whl → 0.9.7050__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/balormk/clone_loader.py +3 -2
- meerk40t/balormk/controller.py +38 -13
- meerk40t/balormk/cylindermod.py +1 -0
- meerk40t/balormk/device.py +13 -9
- meerk40t/balormk/driver.py +9 -2
- meerk40t/balormk/galvo_commands.py +3 -1
- meerk40t/balormk/gui/gui.py +6 -0
- meerk40t/balormk/livelightjob.py +338 -321
- meerk40t/balormk/mock_connection.py +4 -3
- meerk40t/balormk/usb_connection.py +11 -2
- meerk40t/camera/camera.py +19 -14
- meerk40t/camera/gui/camerapanel.py +6 -0
- meerk40t/core/cutplan.py +101 -78
- meerk40t/core/elements/element_treeops.py +435 -140
- meerk40t/core/elements/elements.py +100 -9
- meerk40t/core/elements/shapes.py +259 -72
- meerk40t/core/elements/tree_commands.py +10 -5
- meerk40t/core/node/blobnode.py +19 -4
- meerk40t/core/node/elem_ellipse.py +18 -8
- meerk40t/core/node/elem_image.py +51 -19
- meerk40t/core/node/elem_line.py +18 -8
- meerk40t/core/node/elem_path.py +18 -8
- meerk40t/core/node/elem_point.py +10 -4
- meerk40t/core/node/elem_polyline.py +19 -11
- meerk40t/core/node/elem_rect.py +18 -8
- meerk40t/core/node/elem_text.py +11 -5
- meerk40t/core/node/filenode.py +2 -8
- meerk40t/core/node/groupnode.py +11 -11
- meerk40t/core/node/image_processed.py +11 -5
- meerk40t/core/node/image_raster.py +11 -5
- meerk40t/core/node/node.py +64 -16
- meerk40t/core/node/refnode.py +2 -1
- meerk40t/core/planner.py +25 -11
- meerk40t/core/svg_io.py +91 -34
- meerk40t/device/dummydevice.py +7 -1
- meerk40t/extra/vtracer.py +222 -0
- meerk40t/grbl/device.py +96 -9
- meerk40t/grbl/driver.py +15 -5
- meerk40t/gui/about.py +20 -0
- meerk40t/gui/devicepanel.py +20 -16
- meerk40t/gui/gui_mixins.py +4 -0
- meerk40t/gui/icons.py +330 -253
- meerk40t/gui/laserpanel.py +27 -3
- meerk40t/gui/laserrender.py +41 -21
- meerk40t/gui/magnetoptions.py +158 -65
- meerk40t/gui/materialtest.py +569 -310
- meerk40t/gui/navigationpanels.py +229 -24
- meerk40t/gui/propertypanels/hatchproperty.py +2 -0
- meerk40t/gui/propertypanels/imageproperty.py +160 -106
- meerk40t/gui/propertypanels/wobbleproperty.py +6 -2
- meerk40t/gui/ribbon.py +6 -1
- meerk40t/gui/scenewidgets/gridwidget.py +29 -32
- meerk40t/gui/scenewidgets/rectselectwidget.py +190 -192
- meerk40t/gui/simulation.py +75 -77
- meerk40t/gui/spoolerpanel.py +27 -7
- meerk40t/gui/statusbarwidgets/defaultoperations.py +84 -48
- meerk40t/gui/statusbarwidgets/infowidget.py +2 -2
- meerk40t/gui/tips.py +15 -1
- meerk40t/gui/toolwidgets/toolpointmove.py +3 -1
- meerk40t/gui/wxmmain.py +242 -114
- meerk40t/gui/wxmscene.py +107 -24
- meerk40t/gui/wxmtree.py +4 -2
- meerk40t/gui/wxutils.py +286 -15
- meerk40t/image/imagetools.py +129 -65
- meerk40t/internal_plugins.py +4 -0
- meerk40t/kernel/kernel.py +67 -18
- meerk40t/kernel/settings.py +28 -9
- meerk40t/lihuiyu/device.py +24 -12
- meerk40t/main.py +14 -9
- meerk40t/moshi/device.py +20 -6
- meerk40t/network/console_server.py +22 -6
- meerk40t/newly/device.py +10 -3
- meerk40t/newly/gui/gui.py +10 -0
- meerk40t/ruida/device.py +22 -2
- meerk40t/ruida/loader.py +9 -4
- meerk40t/ruida/rdjob.py +48 -8
- meerk40t/tools/geomstr.py +240 -123
- meerk40t/tools/rasterplotter.py +185 -94
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/METADATA +1 -1
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/RECORD +85 -84
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/entry_points.txt +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.7030.dist-info → meerk40t-0.9.7050.dist-info}/zip-safe +0 -0
meerk40t/core/node/elem_image.py
CHANGED
@@ -27,19 +27,21 @@ Methods:
|
|
27
27
|
bbox(transformed=True, with_stroke=False): Returns the bounding box of the image.
|
28
28
|
"""
|
29
29
|
|
30
|
-
import numpy as np
|
31
30
|
import threading
|
32
31
|
import time
|
33
32
|
from copy import copy
|
34
33
|
from math import ceil, floor
|
35
34
|
|
36
|
-
|
35
|
+
import numpy as np
|
36
|
+
|
37
37
|
from meerk40t.core.node.mixins import LabelDisplay, Suppressable
|
38
|
+
from meerk40t.core.node.node import Node
|
38
39
|
from meerk40t.core.units import UNITS_PER_INCH, UNITS_PER_MM
|
39
40
|
from meerk40t.image.imagetools import RasterScripts
|
40
41
|
from meerk40t.svgelements import Matrix, Path, Polygon
|
41
42
|
from meerk40t.tools.geomstr import Geomstr
|
42
43
|
|
44
|
+
|
43
45
|
class ImageNode(Node, LabelDisplay, Suppressable):
|
44
46
|
"""
|
45
47
|
ImageNode is the bootstrapped node type for the 'elem image' type.
|
@@ -153,7 +155,12 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
153
155
|
self._process_image_failed = False
|
154
156
|
|
155
157
|
self.message = None
|
156
|
-
if (
|
158
|
+
if (
|
159
|
+
self.operations
|
160
|
+
or self.dither
|
161
|
+
or self.prevent_crop
|
162
|
+
or self.keyhole_reference
|
163
|
+
) and startup:
|
157
164
|
step = self._default_units / self.dpi
|
158
165
|
step_x = step
|
159
166
|
step_y = step
|
@@ -186,7 +193,6 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
186
193
|
time.sleep(0.05)
|
187
194
|
counter += 1
|
188
195
|
if self._processed_image is None:
|
189
|
-
|
190
196
|
step = self._default_units / self.dpi
|
191
197
|
step_x = step
|
192
198
|
step_y = step
|
@@ -320,18 +326,24 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
320
326
|
return default_map
|
321
327
|
|
322
328
|
def can_drop(self, drag_node):
|
329
|
+
if self.is_a_child_of(drag_node):
|
330
|
+
return False
|
323
331
|
# Dragging element into element.
|
324
332
|
return bool(
|
325
|
-
hasattr(drag_node, "as_geometry")
|
326
|
-
hasattr(drag_node, "as_image")
|
327
|
-
drag_node.type in ("op image", "op raster", "file", "group")
|
333
|
+
hasattr(drag_node, "as_geometry")
|
334
|
+
or hasattr(drag_node, "as_image")
|
335
|
+
or drag_node.type in ("op image", "op raster", "file", "group")
|
328
336
|
)
|
329
337
|
|
330
338
|
def drop(self, drag_node, modify=True, flag=False):
|
331
339
|
# Dragging element into element.
|
332
340
|
if not self.can_drop(drag_node):
|
333
341
|
return False
|
334
|
-
if
|
342
|
+
if (
|
343
|
+
hasattr(drag_node, "as_geometry")
|
344
|
+
or hasattr(drag_node, "as_image")
|
345
|
+
or drag_node.type in ("file", "group")
|
346
|
+
):
|
335
347
|
if modify:
|
336
348
|
self.insert_sibling(drag_node)
|
337
349
|
return True
|
@@ -418,12 +430,18 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
418
430
|
# Unset cache.
|
419
431
|
self._cache = None
|
420
432
|
else:
|
421
|
-
if
|
433
|
+
if (
|
434
|
+
self._keyhole_reference is not None
|
435
|
+
and self._keyhole_geometry is None
|
436
|
+
):
|
422
437
|
get_keyhole_geometry()
|
423
438
|
|
424
439
|
# We need to have a thread per image, so we need to provide a node specific thread_name!
|
425
440
|
self._update_thread = context.threaded(
|
426
|
-
self._process_image_thread,
|
441
|
+
self._process_image_thread,
|
442
|
+
result=clear,
|
443
|
+
daemon=True,
|
444
|
+
thread_name=f"image_update_{self.id}_{str(time.perf_counter())}",
|
427
445
|
)
|
428
446
|
|
429
447
|
def _process_image_thread(self):
|
@@ -460,6 +478,7 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
460
478
|
"""
|
461
479
|
|
462
480
|
from PIL import Image, ImageDraw
|
481
|
+
|
463
482
|
while self._processing:
|
464
483
|
time.sleep(0.05)
|
465
484
|
|
@@ -491,6 +510,7 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
491
510
|
@property
|
492
511
|
def opaque_image(self):
|
493
512
|
from PIL import Image
|
513
|
+
|
494
514
|
img = self.image
|
495
515
|
if img is not None and img.mode == "RGBA":
|
496
516
|
r, g, b, a = img.split()
|
@@ -503,6 +523,7 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
503
523
|
# Convert image to L type.
|
504
524
|
if image.mode == "I":
|
505
525
|
from PIL import Image
|
526
|
+
|
506
527
|
# Load the 32-bit signed grayscale image
|
507
528
|
img = np.array(image, dtype=np.int32)
|
508
529
|
|
@@ -510,7 +531,9 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
510
531
|
# img = img.reshape((image.width, image.height))
|
511
532
|
|
512
533
|
# Normalize the image to the range 0-255
|
513
|
-
img_normalized = ((img - img.min()) / (img.max() - img.min()) * 255).astype(
|
534
|
+
img_normalized = ((img - img.min()) / (img.max() - img.min()) * 255).astype(
|
535
|
+
np.uint8
|
536
|
+
)
|
514
537
|
|
515
538
|
# Convert the NumPy array to a Pillow Image
|
516
539
|
img_pil = Image.fromarray(img_normalized)
|
@@ -684,7 +707,9 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
684
707
|
pass
|
685
708
|
elif name == "contrast":
|
686
709
|
try:
|
687
|
-
if op["enable"] and (
|
710
|
+
if op["enable"] and (
|
711
|
+
op["contrast"] is not None and op["brightness"] is not None
|
712
|
+
):
|
688
713
|
contrast = ImageEnhance.Contrast(image)
|
689
714
|
c = (op["contrast"] + 128.0) / 128.0
|
690
715
|
image = contrast.enhance(c)
|
@@ -924,7 +949,9 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
924
949
|
try:
|
925
950
|
image = ImageOps.invert(image)
|
926
951
|
except OSError as e:
|
927
|
-
print
|
952
|
+
print(
|
953
|
+
f"Image inversion crashed: {e}\nMode: {image.mode}, {image.width}x{image.height} pixel"
|
954
|
+
)
|
928
955
|
|
929
956
|
# Find rejection mask of white pixels. (already inverted)
|
930
957
|
reject_mask = image.point(lambda e: 0 if e == 255 else 255)
|
@@ -950,7 +977,10 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
950
977
|
image = self.image
|
951
978
|
if self._keyhole_geometry is not None:
|
952
979
|
# Let's check whether the keyhole dimensions match
|
953
|
-
if self._keyhole_image is not None and (
|
980
|
+
if self._keyhole_image is not None and (
|
981
|
+
self._keyhole_image.width != image.width
|
982
|
+
or self._keyhole_image.height != image.height
|
983
|
+
):
|
954
984
|
self._keyhole_image = None
|
955
985
|
if self._keyhole_image is None:
|
956
986
|
actualized_matrix = self._actualized_matrix
|
@@ -973,19 +1003,21 @@ class ImageNode(Node, LabelDisplay, Suppressable):
|
|
973
1003
|
# Let's simplify things, if we don't have any overlap then we don't need to do something
|
974
1004
|
# if x0 > bounds[2] or x2 < bounds [0] or y0 > bounds[3] or y2 < bounds[1]:
|
975
1005
|
# continue
|
976
|
-
geom_points = list(
|
1006
|
+
geom_points = list(
|
1007
|
+
geom.as_interpolated_points(int(UNITS_PER_MM / 10))
|
1008
|
+
)
|
977
1009
|
points = list()
|
978
1010
|
for pt in geom_points:
|
979
1011
|
if pt is None:
|
980
1012
|
continue
|
981
1013
|
gx = pt.real
|
982
1014
|
gy = pt.imag
|
983
|
-
x = int(maskimage.width * (gx - x0) / i_wd
|
984
|
-
y = int(maskimage.height * (gy - y0) / i_ht
|
985
|
-
points.append(
|
1015
|
+
x = int(maskimage.width * (gx - x0) / i_wd)
|
1016
|
+
y = int(maskimage.height * (gy - y0) / i_ht)
|
1017
|
+
points.append((x, y))
|
986
1018
|
|
987
1019
|
# print (points)
|
988
|
-
draw.polygon(
|
1020
|
+
draw.polygon(points, fill="white", outline="white")
|
989
1021
|
self._keyhole_image = maskimage
|
990
1022
|
# For debug purposes...
|
991
1023
|
# maskimage.save("C:\\temp\\maskimage.png")
|
meerk40t/core/node/elem_line.py
CHANGED
@@ -2,8 +2,8 @@ from copy import copy
|
|
2
2
|
|
3
3
|
from meerk40t.core.node.mixins import (
|
4
4
|
FunctionalParameter,
|
5
|
-
Stroked,
|
6
5
|
LabelDisplay,
|
6
|
+
Stroked,
|
7
7
|
Suppressable,
|
8
8
|
)
|
9
9
|
from meerk40t.core.node.node import Fillrule, Linecap, Linejoin, Node
|
@@ -150,12 +150,16 @@ class LineNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
150
150
|
numtabs = 4
|
151
151
|
numtabs = 0
|
152
152
|
if tablen and numtabs:
|
153
|
-
path = Geomstr.wobble_tab(
|
153
|
+
path = Geomstr.wobble_tab(
|
154
|
+
path, tablen, resolution, numtabs, unit_factor=unit_factor
|
155
|
+
)
|
154
156
|
# Is there a dash/dot pattern to apply?
|
155
157
|
dashlen = self.stroke_dash
|
156
158
|
irrelevant = 50
|
157
159
|
if dashlen:
|
158
|
-
path = Geomstr.wobble_dash(
|
160
|
+
path = Geomstr.wobble_dash(
|
161
|
+
path, dashlen, resolution, irrelevant, unit_factor=unit_factor
|
162
|
+
)
|
159
163
|
return path
|
160
164
|
|
161
165
|
def scaled(self, sx, sy, ox, oy, interim=False):
|
@@ -235,19 +239,25 @@ class LineNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
235
239
|
return default_map
|
236
240
|
|
237
241
|
def can_drop(self, drag_node):
|
242
|
+
if self.is_a_child_of(drag_node):
|
243
|
+
return False
|
238
244
|
# Dragging element into element.
|
239
245
|
return bool(
|
240
|
-
hasattr(drag_node, "as_geometry")
|
241
|
-
hasattr(drag_node, "as_image")
|
242
|
-
(drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
243
|
-
drag_node.type in ("file", "group")
|
246
|
+
hasattr(drag_node, "as_geometry")
|
247
|
+
or hasattr(drag_node, "as_image")
|
248
|
+
or (drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
249
|
+
or drag_node.type in ("file", "group")
|
244
250
|
)
|
245
251
|
|
246
252
|
def drop(self, drag_node, modify=True, flag=False):
|
247
253
|
# Dragging element into element.
|
248
254
|
if not self.can_drop(drag_node):
|
249
255
|
return False
|
250
|
-
if
|
256
|
+
if (
|
257
|
+
hasattr(drag_node, "as_geometry")
|
258
|
+
or hasattr(drag_node, "as_image")
|
259
|
+
or drag_node.type in ("file", "group")
|
260
|
+
):
|
251
261
|
if modify:
|
252
262
|
self.insert_sibling(drag_node)
|
253
263
|
return True
|
meerk40t/core/node/elem_path.py
CHANGED
@@ -2,8 +2,8 @@ from copy import copy
|
|
2
2
|
|
3
3
|
from meerk40t.core.node.mixins import (
|
4
4
|
FunctionalParameter,
|
5
|
-
Stroked,
|
6
5
|
LabelDisplay,
|
6
|
+
Stroked,
|
7
7
|
Suppressable,
|
8
8
|
)
|
9
9
|
from meerk40t.core.node.node import Fillrule, Linecap, Linejoin, Node
|
@@ -122,12 +122,16 @@ class PathNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
122
122
|
tablen = self.mktablength
|
123
123
|
numtabs = self.mktabpositions
|
124
124
|
if tablen and numtabs:
|
125
|
-
path = Geomstr.wobble_tab(
|
125
|
+
path = Geomstr.wobble_tab(
|
126
|
+
path, tablen, resolution, numtabs, unit_factor=unit_factor
|
127
|
+
)
|
126
128
|
# Is there a dash/dot pattern to apply?
|
127
129
|
dashlen = self.stroke_dash
|
128
130
|
irrelevant = 50
|
129
131
|
if dashlen:
|
130
|
-
path = Geomstr.wobble_dash(
|
132
|
+
path = Geomstr.wobble_dash(
|
133
|
+
path, dashlen, resolution, irrelevant, unit_factor=unit_factor
|
134
|
+
)
|
131
135
|
return path
|
132
136
|
|
133
137
|
def scaled(self, sx, sy, ox, oy, interim=False):
|
@@ -201,19 +205,25 @@ class PathNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
201
205
|
return default_map
|
202
206
|
|
203
207
|
def can_drop(self, drag_node):
|
208
|
+
if self.is_a_child_of(drag_node):
|
209
|
+
return False
|
204
210
|
# Dragging element into element.
|
205
211
|
return bool(
|
206
|
-
hasattr(drag_node, "as_geometry")
|
207
|
-
hasattr(drag_node, "as_image")
|
208
|
-
(drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
209
|
-
drag_node.type in ("file", "group")
|
212
|
+
hasattr(drag_node, "as_geometry")
|
213
|
+
or hasattr(drag_node, "as_image")
|
214
|
+
or (drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
215
|
+
or drag_node.type in ("file", "group")
|
210
216
|
)
|
211
217
|
|
212
218
|
def drop(self, drag_node, modify=True, flag=False):
|
213
219
|
# Dragging element into element.
|
214
220
|
if not self.can_drop(drag_node):
|
215
221
|
return False
|
216
|
-
if
|
222
|
+
if (
|
223
|
+
hasattr(drag_node, "as_geometry")
|
224
|
+
or hasattr(drag_node, "as_image")
|
225
|
+
or drag_node.type in ("file", "group")
|
226
|
+
):
|
217
227
|
if modify:
|
218
228
|
self.insert_sibling(drag_node)
|
219
229
|
return True
|
meerk40t/core/node/elem_point.py
CHANGED
@@ -85,18 +85,24 @@ class PointNode(Node, FunctionalParameter, LabelDisplay, Suppressable):
|
|
85
85
|
return default_map
|
86
86
|
|
87
87
|
def can_drop(self, drag_node):
|
88
|
+
if self.is_a_child_of(drag_node):
|
89
|
+
return False
|
88
90
|
# Dragging element into element.
|
89
91
|
return bool(
|
90
|
-
hasattr(drag_node, "as_geometry")
|
91
|
-
hasattr(drag_node, "as_image")
|
92
|
-
drag_node.type in ("op dots", "file", "group")
|
92
|
+
hasattr(drag_node, "as_geometry")
|
93
|
+
or hasattr(drag_node, "as_image")
|
94
|
+
or drag_node.type in ("op dots", "file", "group")
|
93
95
|
)
|
94
96
|
|
95
97
|
def drop(self, drag_node, modify=True, flag=False):
|
96
98
|
# Dragging element into element.
|
97
99
|
if not self.can_drop(drag_node):
|
98
100
|
return False
|
99
|
-
if
|
101
|
+
if (
|
102
|
+
hasattr(drag_node, "as_geometry")
|
103
|
+
or hasattr(drag_node, "as_image")
|
104
|
+
or drag_node.type in ("file", "group")
|
105
|
+
):
|
100
106
|
if modify:
|
101
107
|
self.insert_sibling(drag_node)
|
102
108
|
return True
|
@@ -2,8 +2,8 @@ from copy import copy
|
|
2
2
|
|
3
3
|
from meerk40t.core.node.mixins import (
|
4
4
|
FunctionalParameter,
|
5
|
-
Stroked,
|
6
5
|
LabelDisplay,
|
6
|
+
Stroked,
|
7
7
|
Suppressable,
|
8
8
|
)
|
9
9
|
from meerk40t.core.node.node import Fillrule, Linecap, Linejoin, Node
|
@@ -18,9 +18,7 @@ from meerk40t.svgelements import (
|
|
18
18
|
from meerk40t.tools.geomstr import Geomstr
|
19
19
|
|
20
20
|
|
21
|
-
class PolylineNode(
|
22
|
-
Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable
|
23
|
-
):
|
21
|
+
class PolylineNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
24
22
|
"""
|
25
23
|
PolylineNode is the bootstrapped node type for the 'elem polyline' type.
|
26
24
|
"""
|
@@ -152,12 +150,16 @@ class PolylineNode(
|
|
152
150
|
tablen = self.mktablength
|
153
151
|
numtabs = self.mktabpositions
|
154
152
|
if tablen and numtabs:
|
155
|
-
path = Geomstr.wobble_tab(
|
153
|
+
path = Geomstr.wobble_tab(
|
154
|
+
path, tablen, resolution, numtabs, unit_factor=unit_factor
|
155
|
+
)
|
156
156
|
# Is there a dash/dot pattern to apply?
|
157
157
|
dashlen = self.stroke_dash
|
158
158
|
irrelevant = 50
|
159
159
|
if dashlen:
|
160
|
-
path = Geomstr.wobble_dash(
|
160
|
+
path = Geomstr.wobble_dash(
|
161
|
+
path, dashlen, resolution, irrelevant, unit_factor=unit_factor
|
162
|
+
)
|
161
163
|
return path
|
162
164
|
|
163
165
|
def scaled(self, sx, sy, ox, oy, interim=False):
|
@@ -232,19 +234,25 @@ class PolylineNode(
|
|
232
234
|
return default_map
|
233
235
|
|
234
236
|
def can_drop(self, drag_node):
|
237
|
+
if self.is_a_child_of(drag_node):
|
238
|
+
return False
|
235
239
|
# Dragging element into element.
|
236
240
|
return bool(
|
237
|
-
hasattr(drag_node, "as_geometry")
|
238
|
-
hasattr(drag_node, "as_image")
|
239
|
-
(drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
240
|
-
drag_node.type in ("file", "group")
|
241
|
+
hasattr(drag_node, "as_geometry")
|
242
|
+
or hasattr(drag_node, "as_image")
|
243
|
+
or (drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
244
|
+
or drag_node.type in ("file", "group")
|
241
245
|
)
|
242
246
|
|
243
247
|
def drop(self, drag_node, modify=True, flag=False):
|
244
248
|
# Dragging element into element.
|
245
249
|
if not self.can_drop(drag_node):
|
246
250
|
return False
|
247
|
-
if
|
251
|
+
if (
|
252
|
+
hasattr(drag_node, "as_geometry")
|
253
|
+
or hasattr(drag_node, "as_image")
|
254
|
+
or drag_node.type in ("file", "group")
|
255
|
+
):
|
248
256
|
if modify:
|
249
257
|
self.insert_sibling(drag_node)
|
250
258
|
return True
|
meerk40t/core/node/elem_rect.py
CHANGED
@@ -2,8 +2,8 @@ from copy import copy
|
|
2
2
|
|
3
3
|
from meerk40t.core.node.mixins import (
|
4
4
|
FunctionalParameter,
|
5
|
-
Stroked,
|
6
5
|
LabelDisplay,
|
6
|
+
Stroked,
|
7
7
|
Suppressable,
|
8
8
|
)
|
9
9
|
from meerk40t.core.node.node import Fillrule, Linejoin, Node
|
@@ -157,12 +157,16 @@ class RectNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
157
157
|
tablen = self.mktablength
|
158
158
|
numtabs = self.mktabpositions
|
159
159
|
if tablen and numtabs:
|
160
|
-
path = Geomstr.wobble_tab(
|
160
|
+
path = Geomstr.wobble_tab(
|
161
|
+
path, tablen, resolution, numtabs, unit_factor=unit_factor
|
162
|
+
)
|
161
163
|
# Is there a dash/dot pattern to apply?
|
162
164
|
dashlen = self.stroke_dash
|
163
165
|
irrelevant = 50
|
164
166
|
if dashlen:
|
165
|
-
path = Geomstr.wobble_dash(
|
167
|
+
path = Geomstr.wobble_dash(
|
168
|
+
path, dashlen, resolution, irrelevant, unit_factor=unit_factor
|
169
|
+
)
|
166
170
|
return path
|
167
171
|
|
168
172
|
def scaled(self, sx, sy, ox, oy, interim=False):
|
@@ -241,18 +245,24 @@ class RectNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
241
245
|
|
242
246
|
def can_drop(self, drag_node):
|
243
247
|
# Dragging element into element.
|
248
|
+
if self.is_a_child_of(drag_node):
|
249
|
+
return False
|
244
250
|
return bool(
|
245
|
-
hasattr(drag_node, "as_geometry")
|
246
|
-
hasattr(drag_node, "as_image")
|
247
|
-
(drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
248
|
-
drag_node.type in ("file", "group")
|
251
|
+
hasattr(drag_node, "as_geometry")
|
252
|
+
or hasattr(drag_node, "as_image")
|
253
|
+
or (drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
254
|
+
or drag_node.type in ("file", "group")
|
249
255
|
)
|
250
256
|
|
251
257
|
def drop(self, drag_node, modify=True, flag=False):
|
252
258
|
# Dragging element into element.
|
253
259
|
if not self.can_drop(drag_node):
|
254
260
|
return False
|
255
|
-
if
|
261
|
+
if (
|
262
|
+
hasattr(drag_node, "as_geometry")
|
263
|
+
or hasattr(drag_node, "as_image")
|
264
|
+
or drag_node.type in ("file", "group")
|
265
|
+
):
|
256
266
|
if modify:
|
257
267
|
self.insert_sibling(drag_node)
|
258
268
|
return True
|
meerk40t/core/node/elem_text.py
CHANGED
@@ -4,8 +4,8 @@ from math import tau
|
|
4
4
|
|
5
5
|
from meerk40t.core.node.mixins import (
|
6
6
|
FunctionalParameter,
|
7
|
-
Stroked,
|
8
7
|
LabelDisplay,
|
8
|
+
Stroked,
|
9
9
|
Suppressable,
|
10
10
|
)
|
11
11
|
from meerk40t.core.node.node import Node
|
@@ -196,18 +196,24 @@ class TextNode(Node, Stroked, FunctionalParameter, LabelDisplay, Suppressable):
|
|
196
196
|
return default_map
|
197
197
|
|
198
198
|
def can_drop(self, drag_node):
|
199
|
+
if self.is_a_child_of(drag_node):
|
200
|
+
return False
|
199
201
|
# Dragging element into element.
|
200
202
|
return bool(
|
201
|
-
hasattr(drag_node, "as_geometry")
|
202
|
-
hasattr(drag_node, "as_image")
|
203
|
-
drag_node.type in ("op raster", "file", "group")
|
203
|
+
hasattr(drag_node, "as_geometry")
|
204
|
+
or hasattr(drag_node, "as_image")
|
205
|
+
or drag_node.type in ("op raster", "file", "group")
|
204
206
|
)
|
205
207
|
|
206
208
|
def drop(self, drag_node, modify=True, flag=False):
|
207
209
|
# Dragging element into element.
|
208
210
|
if not self.can_drop(drag_node):
|
209
211
|
return False
|
210
|
-
if
|
212
|
+
if (
|
213
|
+
hasattr(drag_node, "as_geometry")
|
214
|
+
or hasattr(drag_node, "as_image")
|
215
|
+
or drag_node.type in ("file", "group")
|
216
|
+
):
|
211
217
|
if modify:
|
212
218
|
self.insert_sibling(drag_node)
|
213
219
|
return True
|
meerk40t/core/node/filenode.py
CHANGED
@@ -25,21 +25,15 @@ class FileNode(Node):
|
|
25
25
|
default_map["filename"] = s
|
26
26
|
return default_map
|
27
27
|
|
28
|
-
def is_a_child_of(self, node):
|
29
|
-
candidate = self
|
30
|
-
while candidate is not None:
|
31
|
-
if candidate is node:
|
32
|
-
return True
|
33
|
-
candidate = candidate.parent
|
34
28
|
return False
|
35
|
-
|
29
|
+
|
36
30
|
def can_drop(self, drag_node):
|
37
31
|
if self.is_a_child_of(drag_node):
|
38
32
|
return False
|
39
33
|
if drag_node.type == "group":
|
40
34
|
return True
|
41
35
|
return False
|
42
|
-
|
36
|
+
|
43
37
|
def drop(self, drag_node, modify=True, flag=False):
|
44
38
|
# Do not allow dragging onto children
|
45
39
|
if not self.can_drop(drag_node):
|
meerk40t/core/node/groupnode.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
from meerk40t.core.node.node import Node
|
2
1
|
from meerk40t.core.node.mixins import LabelDisplay
|
2
|
+
from meerk40t.core.node.node import Node
|
3
3
|
|
4
4
|
|
5
5
|
class GroupNode(Node, LabelDisplay):
|
@@ -76,18 +76,14 @@ class GroupNode(Node, LabelDisplay):
|
|
76
76
|
default_map["id"] = str(self.id)
|
77
77
|
return default_map
|
78
78
|
|
79
|
-
def is_a_child_of(self, node):
|
80
|
-
candidate = self
|
81
|
-
while candidate is not None:
|
82
|
-
if candidate is node:
|
83
|
-
return True
|
84
|
-
candidate = candidate.parent
|
85
|
-
return False
|
86
|
-
|
87
79
|
def can_drop(self, drag_node):
|
88
80
|
if self.is_a_child_of(drag_node):
|
89
81
|
return False
|
90
|
-
if
|
82
|
+
if (
|
83
|
+
hasattr(drag_node, "as_geometry")
|
84
|
+
or hasattr(drag_node, "as_image")
|
85
|
+
or drag_node.type == "group"
|
86
|
+
):
|
91
87
|
# Move a group
|
92
88
|
return True
|
93
89
|
elif drag_node.type.startswith("op"):
|
@@ -121,7 +117,11 @@ class GroupNode(Node, LabelDisplay):
|
|
121
117
|
if result and modify:
|
122
118
|
# changed = []
|
123
119
|
for e in self.flat():
|
124
|
-
if
|
120
|
+
if (
|
121
|
+
hasattr(drag_node, "color")
|
122
|
+
and drag_node.color is not None
|
123
|
+
and hasattr(e, "stroke")
|
124
|
+
):
|
125
125
|
e.stroke = drag_node.color
|
126
126
|
# changed.append(e)
|
127
127
|
for ref in old_references:
|
@@ -163,19 +163,25 @@ class ImageProcessedNode(Node):
|
|
163
163
|
return default_map
|
164
164
|
|
165
165
|
def can_drop(self, drag_node):
|
166
|
+
if self.is_a_child_of(drag_node):
|
167
|
+
return False
|
166
168
|
# Dragging element into element.
|
167
169
|
return bool(
|
168
|
-
hasattr(drag_node, "as_geometry")
|
169
|
-
hasattr(drag_node, "as_image")
|
170
|
-
(drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
171
|
-
drag_node.type in ("file", "group")
|
170
|
+
hasattr(drag_node, "as_geometry")
|
171
|
+
or hasattr(drag_node, "as_image")
|
172
|
+
or (drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
173
|
+
or drag_node.type in ("file", "group")
|
172
174
|
)
|
173
175
|
|
174
176
|
def drop(self, drag_node, modify=True, flag=False):
|
175
177
|
# Dragging element into element.
|
176
178
|
if not self.can_drop(drag_node):
|
177
179
|
return False
|
178
|
-
if
|
180
|
+
if (
|
181
|
+
hasattr(drag_node, "as_geometry")
|
182
|
+
or hasattr(drag_node, "as_image")
|
183
|
+
or drag_node.type in ("file", "group")
|
184
|
+
):
|
179
185
|
if modify:
|
180
186
|
self.insert_sibling(drag_node)
|
181
187
|
return True
|
@@ -92,19 +92,25 @@ class ImageRasterNode(Node):
|
|
92
92
|
return default_map
|
93
93
|
|
94
94
|
def can_drop(self, drag_node):
|
95
|
+
if self.is_a_child_of(drag_node):
|
96
|
+
return False
|
95
97
|
# Dragging element into element.
|
96
98
|
return bool(
|
97
|
-
hasattr(drag_node, "as_geometry")
|
98
|
-
hasattr(drag_node, "as_image")
|
99
|
-
(drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
100
|
-
drag_node.type in ("file", "group")
|
99
|
+
hasattr(drag_node, "as_geometry")
|
100
|
+
or hasattr(drag_node, "as_image")
|
101
|
+
or (drag_node.type.startswith("op ") and drag_node.type != "op dots")
|
102
|
+
or drag_node.type in ("file", "group")
|
101
103
|
)
|
102
104
|
|
103
105
|
def drop(self, drag_node, modify=True, flag=False):
|
104
106
|
# Dragging element into element.
|
105
107
|
if not self.can_drop(drag_node):
|
106
108
|
return False
|
107
|
-
if
|
109
|
+
if (
|
110
|
+
hasattr(drag_node, "as_geometry")
|
111
|
+
or hasattr(drag_node, "as_image")
|
112
|
+
or drag_node.type in ("file", "group")
|
113
|
+
):
|
108
114
|
if modify:
|
109
115
|
self.insert_sibling(drag_node)
|
110
116
|
return True
|