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/node.py
CHANGED
@@ -193,7 +193,7 @@ class Node:
|
|
193
193
|
def targeted(self, value):
|
194
194
|
self._target = value
|
195
195
|
self.notify_targeted(self)
|
196
|
-
|
196
|
+
|
197
197
|
@property
|
198
198
|
def expanded(self):
|
199
199
|
return self._expanded
|
@@ -457,17 +457,23 @@ class Node:
|
|
457
457
|
|
458
458
|
def restore_tree(self, tree_data):
|
459
459
|
# Takes a backup and reapplies it again to the tree
|
460
|
-
# Caveat: we can't just simply take the backup and load it into the tree,
|
461
|
-
# although it is already a perfectly independent copy.
|
460
|
+
# Caveat: we can't just simply take the backup and load it into the tree,
|
461
|
+
# although it is already a perfectly independent copy.
|
462
462
|
# self._children.extend(tree_data)
|
463
|
-
# If loaded directly as above then this stored state will be used
|
464
|
-
# as the basis for further modifications consequently changing the
|
463
|
+
# If loaded directly as above then this stored state will be used
|
464
|
+
# as the basis for further modifications consequently changing the
|
465
465
|
# original data (as it is still the original structure) used in the undostack.
|
466
466
|
# tree_data contains the copied branch nodes
|
467
|
-
|
467
|
+
|
468
468
|
self._children.clear()
|
469
469
|
links = {id(self): (self, None)}
|
470
|
-
attrib_list = (
|
470
|
+
attrib_list = (
|
471
|
+
"_selected",
|
472
|
+
"_emphasized",
|
473
|
+
"_emphasized_time",
|
474
|
+
"_highlighted",
|
475
|
+
"_expanded",
|
476
|
+
)
|
471
477
|
for c in tree_data:
|
472
478
|
c._build_copy_nodes(links=links)
|
473
479
|
node_copy = copy(c)
|
@@ -528,12 +534,23 @@ class Node:
|
|
528
534
|
"""
|
529
535
|
if links is None:
|
530
536
|
links = {id(self): (self, None)}
|
531
|
-
attrib_list = (
|
537
|
+
attrib_list = (
|
538
|
+
"_selected",
|
539
|
+
"_emphasized",
|
540
|
+
"_emphasized_time",
|
541
|
+
"_highlighted",
|
542
|
+
"_expanded",
|
543
|
+
"_translated_text",
|
544
|
+
)
|
532
545
|
for c in self._children:
|
533
546
|
c._build_copy_nodes(links=links)
|
534
547
|
node_copy = copy(c)
|
535
548
|
for att in attrib_list:
|
536
|
-
if
|
549
|
+
if not hasattr(c, att):
|
550
|
+
continue
|
551
|
+
if not hasattr(node_copy, att) or getattr(node_copy, att) != getattr(
|
552
|
+
c, att
|
553
|
+
):
|
537
554
|
# print (f"Strange {att} not identical, fixing")
|
538
555
|
setattr(node_copy, att, getattr(c, att))
|
539
556
|
node_copy._root = self._root
|
@@ -583,7 +600,7 @@ class Node:
|
|
583
600
|
result = "<invalid pattern>"
|
584
601
|
return result
|
585
602
|
|
586
|
-
def default_map(self, default_map=None):
|
603
|
+
def default_map(self, default_map=None): # , skip_label=False
|
587
604
|
if default_map is None:
|
588
605
|
default_map = self._default_map
|
589
606
|
default_map["id"] = str(self.id) if self.id is not None else "-"
|
@@ -817,7 +834,9 @@ class Node:
|
|
817
834
|
node = self
|
818
835
|
self._parent.notify_modified(node=node, **kwargs)
|
819
836
|
|
820
|
-
def notify_translated(
|
837
|
+
def notify_translated(
|
838
|
+
self, node=None, dx=0, dy=0, invalidate=False, interim=False, **kwargs
|
839
|
+
):
|
821
840
|
if invalidate:
|
822
841
|
self.set_dirty_bounds()
|
823
842
|
if self._parent is not None:
|
@@ -829,7 +848,15 @@ class Node:
|
|
829
848
|
)
|
830
849
|
|
831
850
|
def notify_scaled(
|
832
|
-
self,
|
851
|
+
self,
|
852
|
+
node=None,
|
853
|
+
sx=1,
|
854
|
+
sy=1,
|
855
|
+
ox=0,
|
856
|
+
oy=0,
|
857
|
+
invalidate=False,
|
858
|
+
interim=False,
|
859
|
+
**kwargs,
|
833
860
|
):
|
834
861
|
if invalidate:
|
835
862
|
self.set_dirty_bounds()
|
@@ -838,7 +865,14 @@ class Node:
|
|
838
865
|
node = self
|
839
866
|
# Any change to position / size needs a recalculation of the bounds
|
840
867
|
self._parent.notify_scaled(
|
841
|
-
node=node,
|
868
|
+
node=node,
|
869
|
+
sx=sx,
|
870
|
+
sy=sy,
|
871
|
+
ox=ox,
|
872
|
+
oy=oy,
|
873
|
+
invalidate=True,
|
874
|
+
interim=interim,
|
875
|
+
**kwargs,
|
842
876
|
)
|
843
877
|
|
844
878
|
def notify_altered(self, node=None, **kwargs):
|
@@ -953,6 +987,7 @@ class Node:
|
|
953
987
|
This is a special case of the modified call, we are scaling
|
954
988
|
the node without fundamentally altering its properties
|
955
989
|
"""
|
990
|
+
|
956
991
|
def apply_it(box):
|
957
992
|
x0, y0, x1, y1 = box
|
958
993
|
if sx != 1.0:
|
@@ -1220,7 +1255,9 @@ class Node:
|
|
1220
1255
|
If the node exists elsewhere in the tree it will be removed from that location.
|
1221
1256
|
"""
|
1222
1257
|
reference_sibling = self
|
1223
|
-
source_siblings =
|
1258
|
+
source_siblings = (
|
1259
|
+
None if new_sibling.parent is None else new_sibling.parent.children
|
1260
|
+
)
|
1224
1261
|
destination_siblings = reference_sibling.parent.children
|
1225
1262
|
|
1226
1263
|
if source_siblings:
|
@@ -1334,7 +1371,8 @@ class Node:
|
|
1334
1371
|
if children:
|
1335
1372
|
self.remove_all_children(fast=fast)
|
1336
1373
|
if self._parent:
|
1337
|
-
self._parent._children
|
1374
|
+
if self in self._parent._children:
|
1375
|
+
self._parent._children.remove(self)
|
1338
1376
|
self._parent.set_dirty_bounds()
|
1339
1377
|
if not fast:
|
1340
1378
|
self.notify_detached(self)
|
@@ -1356,6 +1394,14 @@ class Node:
|
|
1356
1394
|
child.remove_all_children(fast=fast, destroy=destroy)
|
1357
1395
|
child.remove_node(fast=fast, destroy=destroy)
|
1358
1396
|
|
1397
|
+
def is_a_child_of(self, node):
|
1398
|
+
candidate = self
|
1399
|
+
while candidate is not None:
|
1400
|
+
if candidate is node:
|
1401
|
+
return True
|
1402
|
+
candidate = candidate.parent
|
1403
|
+
return False
|
1404
|
+
|
1359
1405
|
def has_ancestor(self, type):
|
1360
1406
|
"""
|
1361
1407
|
Return whether this node has an ancestor node that matches the given type, or matches the major type.
|
@@ -1394,7 +1440,9 @@ class Node:
|
|
1394
1440
|
dest.insert_node(self, pos=pos)
|
1395
1441
|
|
1396
1442
|
@staticmethod
|
1397
|
-
def union_bounds(
|
1443
|
+
def union_bounds(
|
1444
|
+
nodes, bounds=None, attr="bounds", ignore_locked=True, ignore_hidden=False
|
1445
|
+
):
|
1398
1446
|
"""
|
1399
1447
|
Returns the union of the node list given, optionally unioned the given bounds value
|
1400
1448
|
|
meerk40t/core/node/refnode.py
CHANGED
@@ -54,5 +54,6 @@ class ReferenceNode(Node):
|
|
54
54
|
return False
|
55
55
|
|
56
56
|
def notify_destroyed(self, node=None, **kwargs):
|
57
|
-
self.node._references
|
57
|
+
if self.node is not None and self in self.node._references:
|
58
|
+
self.node._references.remove(self)
|
58
59
|
super().notify_destroyed()
|
meerk40t/core/planner.py
CHANGED
@@ -43,7 +43,9 @@ def plugin(kernel, lifecycle=None):
|
|
43
43
|
},
|
44
44
|
]
|
45
45
|
kernel.register_choices("planner", choices)
|
46
|
-
|
46
|
+
INNER_WARNING = _(
|
47
|
+
"Notabene: Reduce Travel Time and Burn Inner First cannot be used at the same time."
|
48
|
+
)
|
47
49
|
choices = [
|
48
50
|
{
|
49
51
|
"attr": "opt_raster_optimisation",
|
@@ -97,7 +99,9 @@ def plugin(kernel, lifecycle=None):
|
|
97
99
|
"When this option IS checked, Meerk40t will burn each subpath "
|
98
100
|
+ "and then move to the nearest remaining subpath instead, "
|
99
101
|
+ "reducing the time taken moving between burn items."
|
100
|
-
)
|
102
|
+
)
|
103
|
+
+ "\n"
|
104
|
+
+ INNER_WARNING,
|
101
105
|
"page": "Optimisations",
|
102
106
|
"section": "_20_Reducing Movements",
|
103
107
|
},
|
@@ -187,9 +191,11 @@ def plugin(kernel, lifecycle=None):
|
|
187
191
|
"default": False,
|
188
192
|
"type": bool,
|
189
193
|
"label": _("Combine path segments"),
|
190
|
-
"tip":
|
191
|
-
|
192
|
-
|
194
|
+
"tip": _(
|
195
|
+
"Stitch segments together that are very close (ideally having joint start/end points)."
|
196
|
+
)
|
197
|
+
+ "\n"
|
198
|
+
+ _("Only inside a single cut/engrave operation."),
|
193
199
|
"page": "Optimisations",
|
194
200
|
"section": "_05_Stitching",
|
195
201
|
},
|
@@ -199,7 +205,9 @@ def plugin(kernel, lifecycle=None):
|
|
199
205
|
"default": "0",
|
200
206
|
"type": Length,
|
201
207
|
"label": _("Tolerance"),
|
202
|
-
"tip": _(
|
208
|
+
"tip": _(
|
209
|
+
"Tolerance to decide whether two path segments should be joined."
|
210
|
+
),
|
203
211
|
"page": "Optimisations",
|
204
212
|
"section": "_05_Stitching",
|
205
213
|
"conditional": (context, "opt_stitching"),
|
@@ -221,7 +229,9 @@ def plugin(kernel, lifecycle=None):
|
|
221
229
|
+ "* Deselecting Cut Inner First if you are not cutting fully through your material \n"
|
222
230
|
+ "* Putting the inner paths into a separate earlier operation(s) and not using Merge Operations or Cut Inner First \n"
|
223
231
|
+ "* If you are using multiple passes, check Merge Passes"
|
224
|
-
)
|
232
|
+
)
|
233
|
+
+ "\n"
|
234
|
+
+ INNER_WARNING,
|
225
235
|
"page": "Optimisations",
|
226
236
|
"section": "_10_Burn sequence",
|
227
237
|
},
|
@@ -285,8 +295,11 @@ def plugin(kernel, lifecycle=None):
|
|
285
295
|
"type": bool,
|
286
296
|
"label": _("Keep effect lines together"),
|
287
297
|
"tip": (
|
288
|
-
_("Active: effects like hatches are dealt with as a bigger shape")
|
289
|
-
|
298
|
+
_("Active: effects like hatches are dealt with as a bigger shape")
|
299
|
+
+ "\n"
|
300
|
+
+ _(
|
301
|
+
"Inactive: every single line segment will be dealt with individually."
|
302
|
+
)
|
290
303
|
),
|
291
304
|
"page": "Optimisations",
|
292
305
|
"section": "_25_Effects",
|
@@ -298,8 +311,9 @@ def plugin(kernel, lifecycle=None):
|
|
298
311
|
"type": bool,
|
299
312
|
"label": _("Optimize internally"),
|
300
313
|
"tip": (
|
301
|
-
_("Active: hatch lines will be optimized internally")
|
302
|
-
|
314
|
+
_("Active: hatch lines will be optimized internally")
|
315
|
+
+ "\n"
|
316
|
+
+ _("Inactive: hatch lines will be burnt sequentially.")
|
303
317
|
),
|
304
318
|
"page": "Optimisations",
|
305
319
|
"section": "_25_Effects",
|
meerk40t/core/svg_io.py
CHANGED
@@ -124,7 +124,6 @@ def plugin(kernel, lifecycle=None):
|
|
124
124
|
"page": "Input/Output",
|
125
125
|
"section": "Input",
|
126
126
|
},
|
127
|
-
|
128
127
|
]
|
129
128
|
kernel.register_choices("preferences", choices)
|
130
129
|
# The order is relevant as both loaders support SVG
|
@@ -237,7 +236,9 @@ class SVGWriter:
|
|
237
236
|
if elements.last_file_autoexec is not None:
|
238
237
|
subelement = SubElement(root, "autoexec")
|
239
238
|
subelement.set("autoexec", str(elements.last_file_autoexec))
|
240
|
-
subelement.set(
|
239
|
+
subelement.set(
|
240
|
+
"autoexec-active", str(elements.last_file_autoexec_active)
|
241
|
+
)
|
241
242
|
|
242
243
|
SVGWriter._write_tree(root, elements._tree, version)
|
243
244
|
|
@@ -279,7 +280,7 @@ class SVGWriter:
|
|
279
280
|
if len(c.children) > 1:
|
280
281
|
flag = False
|
281
282
|
return flag
|
282
|
-
|
283
|
+
|
283
284
|
if c.type == "elem ellipse":
|
284
285
|
subelement = SubElement(xml_tree, SVG_TAG_ELLIPSE)
|
285
286
|
subelement.set(SVG_ATTR_CENTER_X, str(c.cx))
|
@@ -632,7 +633,12 @@ class SVGWriter:
|
|
632
633
|
pass
|
633
634
|
# Node does not have settings, write object dict
|
634
635
|
for key, value in node.__dict__.items():
|
635
|
-
if
|
636
|
+
if (
|
637
|
+
not key
|
638
|
+
or key.startswith("_")
|
639
|
+
or key in saved_attributes
|
640
|
+
or value is None
|
641
|
+
):
|
636
642
|
continue
|
637
643
|
if key in (
|
638
644
|
"references",
|
@@ -663,7 +669,8 @@ class SVGWriter:
|
|
663
669
|
for c in node.children:
|
664
670
|
if c.type == "reference":
|
665
671
|
c = c.node # Contain direct reference not reference node reference.
|
666
|
-
|
672
|
+
if c.id is not None: # Something strange happened here...
|
673
|
+
contains.append(c.id)
|
667
674
|
if contains:
|
668
675
|
subelement.set("references", " ".join(contains))
|
669
676
|
|
@@ -706,7 +713,13 @@ class SVGProcessor:
|
|
706
713
|
Special care is taken to load MK specific objects like `note` and `operations`
|
707
714
|
"""
|
708
715
|
|
709
|
-
def __init__(
|
716
|
+
def __init__(
|
717
|
+
self,
|
718
|
+
elements,
|
719
|
+
load_operations,
|
720
|
+
load_hidden_to_regmarks=True,
|
721
|
+
reuse_operations=True,
|
722
|
+
):
|
710
723
|
self.elements = elements
|
711
724
|
|
712
725
|
self.operation_list = list()
|
@@ -789,7 +802,7 @@ class SVGProcessor:
|
|
789
802
|
self.elements.classify(self.element_list)
|
790
803
|
|
791
804
|
def check_for_bound_information(self, node, element):
|
792
|
-
# Do we have existing boundary information?
|
805
|
+
# Do we have existing boundary information?
|
793
806
|
if "bounds" not in element.values:
|
794
807
|
return False
|
795
808
|
bbstr = element.values["bounds"]
|
@@ -816,15 +829,16 @@ class SVGProcessor:
|
|
816
829
|
bbox[idx] = val
|
817
830
|
except Exception:
|
818
831
|
# Whatever it was, we don't continue...
|
819
|
-
pass
|
832
|
+
pass
|
820
833
|
node._paint_bounds = list(bbox)
|
821
834
|
node._paint_bounds_dirty = False
|
822
835
|
return True
|
823
836
|
|
824
|
-
def check_for_mk_path_attributes(self, node, element):
|
837
|
+
def check_for_mk_path_attributes(self, node, element, skip=None):
|
825
838
|
"""
|
826
839
|
Checks for some mk special parameters starting with mk. Especially mkparam, and uses this property to fill in
|
827
|
-
the functional_parameter attribute for the node.
|
840
|
+
the functional_parameter attribute for the node. This can be skipped if needed (eg. for basic shapes) as this
|
841
|
+
is not needed for them.
|
828
842
|
|
829
843
|
@param node:
|
830
844
|
@param element:
|
@@ -833,7 +847,8 @@ class SVGProcessor:
|
|
833
847
|
for prop in element.values:
|
834
848
|
lc = element.values.get(prop)
|
835
849
|
if prop.startswith("mk"):
|
836
|
-
|
850
|
+
if skip and prop in skip:
|
851
|
+
continue
|
837
852
|
if lc is not None:
|
838
853
|
setattr(node, prop, lc)
|
839
854
|
# This needs to be done as some node types are not based on Parameters
|
@@ -975,7 +990,9 @@ class SVGProcessor:
|
|
975
990
|
return tag_label
|
976
991
|
return local_dict.get("label")
|
977
992
|
|
978
|
-
def _parse_text(
|
993
|
+
def _parse_text(
|
994
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
995
|
+
):
|
979
996
|
"""
|
980
997
|
Parses an SVGText object, into an `elem text` node.
|
981
998
|
|
@@ -1024,7 +1041,9 @@ class SVGProcessor:
|
|
1024
1041
|
self.check_for_bound_information(node, element)
|
1025
1042
|
e_list.append(node)
|
1026
1043
|
|
1027
|
-
def _parse_path(
|
1044
|
+
def _parse_path(
|
1045
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
1046
|
+
):
|
1028
1047
|
"""
|
1029
1048
|
Parses an SVG Path object.
|
1030
1049
|
|
@@ -1055,7 +1074,12 @@ class SVGProcessor:
|
|
1055
1074
|
pass
|
1056
1075
|
element.approximate_arcs_with_cubics()
|
1057
1076
|
node = context_node.add(
|
1058
|
-
path=element,
|
1077
|
+
path=element,
|
1078
|
+
type="elem path",
|
1079
|
+
id=ident,
|
1080
|
+
label=label,
|
1081
|
+
lock=lock,
|
1082
|
+
hidden=set_hidden,
|
1059
1083
|
)
|
1060
1084
|
self.check_for_label_display(node, element)
|
1061
1085
|
self.check_for_line_attributes(node, element)
|
@@ -1064,7 +1088,9 @@ class SVGProcessor:
|
|
1064
1088
|
self.check_for_bound_information(node, element)
|
1065
1089
|
e_list.append(node)
|
1066
1090
|
|
1067
|
-
def _parse_polyline(
|
1091
|
+
def _parse_polyline(
|
1092
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
1093
|
+
):
|
1068
1094
|
"""
|
1069
1095
|
Parses svg Polyline and Polygon objects into `elem polyline` nodes.
|
1070
1096
|
|
@@ -1089,7 +1115,7 @@ class SVGProcessor:
|
|
1089
1115
|
self.check_for_label_display(node, element)
|
1090
1116
|
self.check_for_line_attributes(node, element)
|
1091
1117
|
self.check_for_fill_attributes(node, element)
|
1092
|
-
self.check_for_mk_path_attributes(node, element)
|
1118
|
+
self.check_for_mk_path_attributes(node, element, skip=("mkparam",))
|
1093
1119
|
if not self.check_for_bound_information(node, element) and self.precalc_bbox:
|
1094
1120
|
# bounds will be done here, paintbounds won't...
|
1095
1121
|
if element.transform.is_identity():
|
@@ -1113,7 +1139,9 @@ class SVGProcessor:
|
|
1113
1139
|
node._points_dirty = False
|
1114
1140
|
e_list.append(node)
|
1115
1141
|
|
1116
|
-
def _parse_ellipse(
|
1142
|
+
def _parse_ellipse(
|
1143
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
1144
|
+
):
|
1117
1145
|
"""
|
1118
1146
|
Parses the SVG Circle, and Ellipse nodes into `elem ellipse` nodes.
|
1119
1147
|
|
@@ -1137,11 +1165,13 @@ class SVGProcessor:
|
|
1137
1165
|
)
|
1138
1166
|
self.check_for_label_display(node, element)
|
1139
1167
|
self.check_for_line_attributes(node, element)
|
1140
|
-
self.check_for_mk_path_attributes(node, element)
|
1168
|
+
self.check_for_mk_path_attributes(node, element, skip=("mkparam",))
|
1141
1169
|
self.check_for_bound_information(node, element)
|
1142
1170
|
e_list.append(node)
|
1143
1171
|
|
1144
|
-
def _parse_rect(
|
1172
|
+
def _parse_rect(
|
1173
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
1174
|
+
):
|
1145
1175
|
"""
|
1146
1176
|
Parse SVG Rect objects into `elem rect` objects.
|
1147
1177
|
|
@@ -1165,7 +1195,7 @@ class SVGProcessor:
|
|
1165
1195
|
)
|
1166
1196
|
self.check_for_label_display(node, element)
|
1167
1197
|
self.check_for_line_attributes(node, element)
|
1168
|
-
self.check_for_mk_path_attributes(node, element)
|
1198
|
+
self.check_for_mk_path_attributes(node, element, skip=("mkparam",))
|
1169
1199
|
if not self.check_for_bound_information(node, element) and self.precalc_bbox:
|
1170
1200
|
# bounds will be done here, paintbounds won't...
|
1171
1201
|
points = (
|
@@ -1191,7 +1221,9 @@ class SVGProcessor:
|
|
1191
1221
|
node._points_dirty = False
|
1192
1222
|
e_list.append(node)
|
1193
1223
|
|
1194
|
-
def _parse_line(
|
1224
|
+
def _parse_line(
|
1225
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
1226
|
+
):
|
1195
1227
|
"""
|
1196
1228
|
Parse SVG Line objects into `elem line`
|
1197
1229
|
|
@@ -1215,7 +1247,7 @@ class SVGProcessor:
|
|
1215
1247
|
)
|
1216
1248
|
self.check_for_label_display(node, element)
|
1217
1249
|
self.check_for_line_attributes(node, element)
|
1218
|
-
self.check_for_mk_path_attributes(node, element)
|
1250
|
+
self.check_for_mk_path_attributes(node, element, skip=("mkparam",))
|
1219
1251
|
if not self.check_for_bound_information(node, element) and self.precalc_bbox:
|
1220
1252
|
# bounds will be done here, paintbounds won't...
|
1221
1253
|
points = (
|
@@ -1239,7 +1271,9 @@ class SVGProcessor:
|
|
1239
1271
|
node._points_dirty = False
|
1240
1272
|
e_list.append(node)
|
1241
1273
|
|
1242
|
-
def _parse_image(
|
1274
|
+
def _parse_image(
|
1275
|
+
self, element, ident, label, lock, context_node, e_list, set_hidden
|
1276
|
+
):
|
1243
1277
|
"""
|
1244
1278
|
Parse SVG Image objects into either `image raster` or `elem image` objects, potentially other classes.
|
1245
1279
|
|
@@ -1516,7 +1550,6 @@ class SVGProcessor:
|
|
1516
1550
|
if branch not in ("elements", "regmarks"):
|
1517
1551
|
return
|
1518
1552
|
if element.values.get("visibility") == "hidden" or display == "none":
|
1519
|
-
|
1520
1553
|
if self.load_hidden_to_regmarks:
|
1521
1554
|
if branch != "regmarks":
|
1522
1555
|
self.parse(
|
@@ -1554,19 +1587,33 @@ class SVGProcessor:
|
|
1554
1587
|
self.check_for_bound_information(node, element)
|
1555
1588
|
e_list.append(node)
|
1556
1589
|
elif isinstance(element, SVGText):
|
1557
|
-
self._parse_text(
|
1590
|
+
self._parse_text(
|
1591
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1592
|
+
)
|
1558
1593
|
elif isinstance(element, Path):
|
1559
|
-
self._parse_path(
|
1594
|
+
self._parse_path(
|
1595
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1596
|
+
)
|
1560
1597
|
elif isinstance(element, (Polygon, Polyline)):
|
1561
|
-
self._parse_polyline(
|
1598
|
+
self._parse_polyline(
|
1599
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1600
|
+
)
|
1562
1601
|
elif isinstance(element, (Circle, Ellipse)):
|
1563
|
-
self._parse_ellipse(
|
1602
|
+
self._parse_ellipse(
|
1603
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1604
|
+
)
|
1564
1605
|
elif isinstance(element, Rect):
|
1565
|
-
self._parse_rect(
|
1606
|
+
self._parse_rect(
|
1607
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1608
|
+
)
|
1566
1609
|
elif isinstance(element, SimpleLine):
|
1567
|
-
self._parse_line(
|
1610
|
+
self._parse_line(
|
1611
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1612
|
+
)
|
1568
1613
|
elif isinstance(element, SVGImage):
|
1569
|
-
self._parse_image(
|
1614
|
+
self._parse_image(
|
1615
|
+
element, ident, _label, _lock, context_node, e_list, set_hidden
|
1616
|
+
)
|
1570
1617
|
elif isinstance(element, SVG):
|
1571
1618
|
# SVG is type of group, it must be processed before Group. Nothing special is done with the type.
|
1572
1619
|
if self.reverse:
|
@@ -1708,7 +1755,9 @@ class SVGProcessor:
|
|
1708
1755
|
file_node = context_node.add(type="file", filepath=self.pathname)
|
1709
1756
|
for node in self.regmark_list:
|
1710
1757
|
if node._parent is context_node:
|
1711
|
-
if node.type == "group" and (
|
1758
|
+
if node.type == "group" and (
|
1759
|
+
node.id == "regmarks" or node.label == "regmarks"
|
1760
|
+
):
|
1712
1761
|
for n in list(node.children):
|
1713
1762
|
file_node.append_child(n)
|
1714
1763
|
node.remove_node() # Removing group/file node.
|
@@ -1740,6 +1789,7 @@ class SVGProcessor:
|
|
1740
1789
|
if needs_update:
|
1741
1790
|
self.elements.process_keyhole_updates(None)
|
1742
1791
|
|
1792
|
+
|
1743
1793
|
class SVGLoader:
|
1744
1794
|
"""
|
1745
1795
|
SVG loader - loading elements, regmarks and operations
|
@@ -1783,7 +1833,12 @@ class SVGLoader:
|
|
1783
1833
|
reuse = elements_service.reuse_operations_on_load
|
1784
1834
|
to_regmarks = elements_service.load_hidden_to_regmarks
|
1785
1835
|
elements_service._loading_cleared = True
|
1786
|
-
svg_processor = SVGProcessor(
|
1836
|
+
svg_processor = SVGProcessor(
|
1837
|
+
elements_service,
|
1838
|
+
load_operations=True,
|
1839
|
+
reuse_operations=reuse,
|
1840
|
+
load_hidden_to_regmarks=to_regmarks,
|
1841
|
+
)
|
1787
1842
|
svg_processor.process(svg, pathname)
|
1788
1843
|
svg_processor.cleanup()
|
1789
1844
|
return True
|
@@ -1830,7 +1885,9 @@ class SVGLoaderPlain:
|
|
1830
1885
|
raise BadFileError(str(e)) from e
|
1831
1886
|
elements_service._loading_cleared = True
|
1832
1887
|
to_regmarks = elements_service.load_hidden_to_regmarks
|
1833
|
-
svg_processor = SVGProcessor(
|
1888
|
+
svg_processor = SVGProcessor(
|
1889
|
+
elements_service, load_operations=False, load_hidden_to_regmarks=to_regmarks
|
1890
|
+
)
|
1834
1891
|
svg_processor.process(svg, pathname)
|
1835
1892
|
svg_processor.cleanup()
|
1836
1893
|
return True
|
meerk40t/device/dummydevice.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from meerk40t.core.spoolers import Spooler
|
2
2
|
from meerk40t.core.view import View
|
3
|
-
from meerk40t.kernel import Service, signal_listener
|
4
3
|
from meerk40t.device.devicechoices import get_effect_choices
|
4
|
+
from meerk40t.kernel import Service, signal_listener
|
5
5
|
|
6
6
|
from .mixins import Status
|
7
7
|
|
@@ -161,3 +161,9 @@ class DummyDevice(Service, Status):
|
|
161
161
|
@return: the location in device native units for the current known position.
|
162
162
|
"""
|
163
163
|
return self.native_x, self.native_y
|
164
|
+
|
165
|
+
def location(self):
|
166
|
+
"""
|
167
|
+
Provide information about the device interface
|
168
|
+
"""
|
169
|
+
return "mock"
|