meerk40t 0.9.7900__py2.py3-none-any.whl → 0.9.7930__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/controller.py +46 -13
- meerk40t/balormk/livelightjob.py +34 -7
- meerk40t/core/cutcode/plotcut.py +2 -1
- meerk40t/core/elements/branches.py +35 -14
- meerk40t/core/elements/clipboard.py +10 -12
- meerk40t/core/elements/elements.py +23 -0
- meerk40t/core/elements/geometry.py +48 -14
- meerk40t/core/elements/grid.py +56 -24
- meerk40t/core/elements/offset_clpr.py +2 -4
- meerk40t/core/elements/placements.py +17 -22
- meerk40t/core/elements/render.py +30 -11
- meerk40t/core/elements/shapes.py +205 -125
- meerk40t/core/spoolers.py +1 -1
- meerk40t/core/units.py +4 -0
- meerk40t/grbl/emulator.py +10 -8
- meerk40t/grbl/gcodejob.py +11 -3
- meerk40t/grbl/plugin.py +10 -1
- meerk40t/gui/help_assets/help_assets.py +126 -2
- meerk40t/gui/navigationpanels.py +9 -1
- meerk40t/gui/wxmeerk40t.py +45 -17
- meerk40t/gui/wxmmain.py +7 -0
- meerk40t/lihuiyu/driver.py +6 -6
- meerk40t/main.py +2 -2
- meerk40t/ruida/emulator.py +12 -9
- meerk40t/ruida/plugin.py +5 -0
- meerk40t/ruida/rdjob.py +5 -5
- meerk40t/tools/geomstr.py +89 -1
- meerk40t/tools/ttfparser.py +793 -113
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/METADATA +1 -1
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/RECORD +35 -35
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/entry_points.txt +0 -0
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/zip-safe +0 -0
meerk40t/tools/geomstr.py
CHANGED
@@ -658,6 +658,14 @@ class Pattern:
|
|
658
658
|
current = 0j
|
659
659
|
|
660
660
|
for entry in pattern(a, b, *args, **kwargs):
|
661
|
+
if (
|
662
|
+
not isinstance(entry, (list, tuple))
|
663
|
+
or len(entry) < 3
|
664
|
+
or np.isnan(entry[1])
|
665
|
+
or np.isnan(entry[2])
|
666
|
+
):
|
667
|
+
# If the entry is not a list or tuple, or if the first element is NaN, we just skip it.
|
668
|
+
continue
|
661
669
|
key = entry[0].lower()
|
662
670
|
if key == "m":
|
663
671
|
current = complex(entry[1], entry[2])
|
@@ -715,6 +723,13 @@ class Pattern:
|
|
715
723
|
@param y1:
|
716
724
|
@return:
|
717
725
|
"""
|
726
|
+
try:
|
727
|
+
if np.isnan(x0) or np.isnan(y0) or np.isnan(x1) or np.isnan(y1):
|
728
|
+
# If any of the coordinates are NaN, we cannot generate a pattern.
|
729
|
+
return Geomstr()
|
730
|
+
except TypeError:
|
731
|
+
# If the coordinates are not numbers, we cannot generate a pattern.
|
732
|
+
return Geomstr()
|
718
733
|
cw = self.cell_width
|
719
734
|
ch = self.cell_height
|
720
735
|
px = self.padding_x
|
@@ -1156,7 +1171,7 @@ class BeamTable:
|
|
1156
1171
|
def difference(self, *args):
|
1157
1172
|
return self.cag("difference", *args)
|
1158
1173
|
|
1159
|
-
def
|
1174
|
+
def cag_org(self, cag_op, *args):
|
1160
1175
|
if self.geometry.index == 0:
|
1161
1176
|
return Geomstr()
|
1162
1177
|
if self._nb_scan is None:
|
@@ -1207,6 +1222,79 @@ class BeamTable:
|
|
1207
1222
|
g.append_lines(segments)
|
1208
1223
|
return g
|
1209
1224
|
|
1225
|
+
def cag(self, cag_op, *args):
|
1226
|
+
"""
|
1227
|
+
Vectorized CAG function that processes all arguments at once to reduce
|
1228
|
+
Python loop overhead.
|
1229
|
+
"""
|
1230
|
+
if self.geometry.index == 0:
|
1231
|
+
return Geomstr()
|
1232
|
+
if self._nb_scan is None:
|
1233
|
+
self.compute_beam()
|
1234
|
+
|
1235
|
+
g = Geomstr()
|
1236
|
+
actives = self._nb_scan[:-1]
|
1237
|
+
lines = self.geometry.segments[actives, 2]
|
1238
|
+
|
1239
|
+
# Create a 3D mask for all arguments at once. Shape: (args, events, actives)
|
1240
|
+
# This avoids the Python loop over `args`.
|
1241
|
+
m = (np.imag(lines)[None, :, :] == np.array(args)[:, None, None]) & (
|
1242
|
+
actives != -1
|
1243
|
+
)
|
1244
|
+
|
1245
|
+
# Perform cumsum on the 3D array and combine results.
|
1246
|
+
# This is the most computationally expensive part.
|
1247
|
+
qq = (np.cumsum(m, axis=2) & 1).astype(bool)
|
1248
|
+
|
1249
|
+
# Combine the results from all arguments based on the CAG operation.
|
1250
|
+
if cag_op == "union":
|
1251
|
+
cc = np.any(qq, axis=0)
|
1252
|
+
elif cag_op == "intersection":
|
1253
|
+
cc = np.all(qq, axis=0)
|
1254
|
+
elif cag_op == "xor":
|
1255
|
+
# XOR is a reduction, so we sum the boolean values and check for oddness.
|
1256
|
+
cc = (np.sum(qq, axis=0) & 1).astype(bool)
|
1257
|
+
elif cag_op == "difference":
|
1258
|
+
# A \ B is equivalent to A & ~B. For multiple args: A \ B \ C -> A & ~B & ~C
|
1259
|
+
cc = qq[0]
|
1260
|
+
if len(args) > 1:
|
1261
|
+
cc &= np.all(~qq[1:], axis=0)
|
1262
|
+
else: # "eq"
|
1263
|
+
# Check if all rows in qq are identical for each event/active pair.
|
1264
|
+
cc = np.all(qq == qq[0], axis=0)
|
1265
|
+
|
1266
|
+
# manual pad (faster than np.pad), then diff
|
1267
|
+
hshape = (cc.shape[0], cc.shape[1] + 1)
|
1268
|
+
yy = np.zeros(hshape, dtype=np.int8)
|
1269
|
+
yy[:, 1:] = cc.view(np.int8)
|
1270
|
+
hh = np.diff(yy, axis=1)
|
1271
|
+
|
1272
|
+
# prepare event arrays only once
|
1273
|
+
ev0, ev1 = self._nb_events[:-1], self._nb_events[1:]
|
1274
|
+
r0, i0 = np.real(ev0), np.imag(ev0)
|
1275
|
+
r1, i1 = np.real(ev1), np.imag(ev1)
|
1276
|
+
|
1277
|
+
# compute all intercepts
|
1278
|
+
y0 = self.geometry.y_intercept(actives, r0, i0)
|
1279
|
+
y1 = self.geometry.y_intercept(actives, r1, i1)
|
1280
|
+
|
1281
|
+
# broadcast real parts to match y-shapes (views, no copy)
|
1282
|
+
starts = r0[:, None] + y0 * 1j
|
1283
|
+
ends = r1[:, None] + y1 * 1j
|
1284
|
+
|
1285
|
+
# one-shot filter
|
1286
|
+
valid = (starts != ends) & ~np.isnan(starts) & (hh != 0)
|
1287
|
+
if np.any(valid):
|
1288
|
+
segs = np.empty((np.count_nonzero(valid), 5), dtype=complex)
|
1289
|
+
segs[:, 0] = starts[valid]
|
1290
|
+
segs[:, 1] = 0
|
1291
|
+
segs[:, 2] = TYPE_LINE
|
1292
|
+
segs[:, 3] = 0
|
1293
|
+
segs[:, 4] = ends[valid]
|
1294
|
+
g.append_lines(segs)
|
1295
|
+
|
1296
|
+
return g
|
1297
|
+
|
1210
1298
|
|
1211
1299
|
class Scanbeam:
|
1212
1300
|
"""
|