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.
Files changed (35) hide show
  1. meerk40t/balormk/controller.py +46 -13
  2. meerk40t/balormk/livelightjob.py +34 -7
  3. meerk40t/core/cutcode/plotcut.py +2 -1
  4. meerk40t/core/elements/branches.py +35 -14
  5. meerk40t/core/elements/clipboard.py +10 -12
  6. meerk40t/core/elements/elements.py +23 -0
  7. meerk40t/core/elements/geometry.py +48 -14
  8. meerk40t/core/elements/grid.py +56 -24
  9. meerk40t/core/elements/offset_clpr.py +2 -4
  10. meerk40t/core/elements/placements.py +17 -22
  11. meerk40t/core/elements/render.py +30 -11
  12. meerk40t/core/elements/shapes.py +205 -125
  13. meerk40t/core/spoolers.py +1 -1
  14. meerk40t/core/units.py +4 -0
  15. meerk40t/grbl/emulator.py +10 -8
  16. meerk40t/grbl/gcodejob.py +11 -3
  17. meerk40t/grbl/plugin.py +10 -1
  18. meerk40t/gui/help_assets/help_assets.py +126 -2
  19. meerk40t/gui/navigationpanels.py +9 -1
  20. meerk40t/gui/wxmeerk40t.py +45 -17
  21. meerk40t/gui/wxmmain.py +7 -0
  22. meerk40t/lihuiyu/driver.py +6 -6
  23. meerk40t/main.py +2 -2
  24. meerk40t/ruida/emulator.py +12 -9
  25. meerk40t/ruida/plugin.py +5 -0
  26. meerk40t/ruida/rdjob.py +5 -5
  27. meerk40t/tools/geomstr.py +89 -1
  28. meerk40t/tools/ttfparser.py +793 -113
  29. {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/METADATA +1 -1
  30. {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/RECORD +35 -35
  31. {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/LICENSE +0 -0
  32. {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/WHEEL +0 -0
  33. {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/entry_points.txt +0 -0
  34. {meerk40t-0.9.7900.dist-info → meerk40t-0.9.7930.dist-info}/top_level.txt +0 -0
  35. {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 cag(self, cag_op, *args):
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
  """