three-slicer-viewer 0.3.3 → 0.3.4

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.
@@ -1,32 +1,60 @@
1
- import { D as Nt, a as Rt } from "./viewer_defaults-B7UUZ582.js";
2
- import { R as t, e as Z } from "./toolpath_encoding-BuYs95qZ.js";
3
- import { T as ft } from "./toolpath_palette-B8xEl-qa.js";
4
- const K = 1e-6, It = 254, At = /^(filament|extruder)_colour\s*=\s*(.*)$/i, ut = (n) => n.split(/[;,]/).map((r) => {
5
- const o = /^"?#?([0-9a-f]{6})(?:[0-9a-f]{2})?"?$/i.exec(r.trim());
6
- return o ? "#" + o[1].toUpperCase() : null;
7
- }), dt = (n) => "#" + ft[n % ft.length].map((r) => Math.round(r * 255).toString(16).padStart(2, "0")).join("");
8
- function gt(n, r) {
9
- let o = [];
10
- Array.isArray(n?.colors) && (o = n.colors);
11
- const d = r ?? [], u = Math.max(o.length, d.length, n?.filament_mm_by_tool?.length ?? 0);
12
- return Array.from({ length: u }, (h, c) => o[c] || d[c] || dt(c));
1
+ import { D as At, a as St } from "./viewer_defaults-B7UUZ582.js";
2
+ import { R as t, S as ut, e as $ } from "./toolpath_encoding-BuYs95qZ.js";
3
+ import { T as mt } from "./toolpath_palette-B8xEl-qa.js";
4
+ const ht = ";_GP_FIRST_LINE_M73_PLACEHOLDER", gt = ";_GP_LAST_LINE_M73_PLACEHOLDER", Lt = "@PRINT_TIME_SEC@", pt = "@USED_FILAMENT_LENGTH@", Nt = (s) => Math.floor((Math.max(0, s) + 0.5) / 60), Z = (s, i) => `M73 P${s} R${i}`;
5
+ function Ct(s, i) {
6
+ let n = String(s ?? "");
7
+ const m = Number(i?.time_estimate) || 0;
8
+ if (n.includes(Lt) && (n = n.split(Lt).join(m.toFixed(2))), n.includes(pt) && (n = n.split(pt).join(((Number(i?.filament_mm) || 0) / 1e3).toFixed(2))), !n.includes(ht)) return n;
9
+ let a = [];
10
+ Array.isArray(i?.layer_times) && (a = i.layer_times);
11
+ const l = n.split(`
12
+ `), o = [];
13
+ let L = 0, E = 0, d = "";
14
+ for (const N of l) {
15
+ if (N === ht) {
16
+ d = Z(0, Nt(m)), o.push(d);
17
+ continue;
18
+ }
19
+ if (N === gt) {
20
+ o.push(Z(100, 0));
21
+ continue;
22
+ }
23
+ if (o.push(N), !N.startsWith("; LAYER ")) continue;
24
+ let A = 0;
25
+ m > 0 && (A = Math.min(100, Math.floor(100 * E / m)));
26
+ const S = Z(A, Nt(m - E));
27
+ S !== d && (o.push(S), d = S), E += Number(a[L]) || 0, L += 1;
28
+ }
29
+ return o.join(`
30
+ `);
13
31
  }
14
- function wt(n, r) {
15
- return St(n.gcode, gt(n.stats, r));
32
+ const B = 1e-6, Mt = 254, Tt = /^(filament|extruder)_colour\s*=\s*(.*)$/i, It = (s) => s.split(/[;,]/).map((i) => {
33
+ const n = /^"?#?([0-9a-f]{6})(?:[0-9a-f]{2})?"?$/i.exec(i.trim());
34
+ return n ? "#" + n[1].toUpperCase() : null;
35
+ }), Pt = (s) => "#" + mt[s % mt.length].map((i) => Math.round(i * 255).toString(16).padStart(2, "0")).join("");
36
+ function Ot(s, i) {
37
+ let n = [];
38
+ Array.isArray(s?.colors) && (n = s.colors);
39
+ const m = i ?? [], a = Math.max(n.length, m.length, s?.filament_mm_by_tool?.length ?? 0);
40
+ return Array.from({ length: a }, (l, o) => n[o] || m[o] || Pt(o));
16
41
  }
17
- function St(n, r) {
18
- const o = String(n ?? ""), d = [r].flat().filter(Boolean);
19
- if (!d.length || /^;\s*filament_colour\s*=/mi.test(o)) return o;
20
- const u = "; filament_colour = " + d.join(";") + `
21
- `, h = o.lastIndexOf(`
42
+ function Ut(s, i) {
43
+ return yt(s.gcode, Ot(s.stats, i));
44
+ }
45
+ function yt(s, i) {
46
+ const n = String(s ?? ""), m = [i].flat().filter(Boolean);
47
+ if (!m.length || /^;\s*filament_colour\s*=/mi.test(n)) return n;
48
+ const a = "; filament_colour = " + m.join(";") + `
49
+ `, l = n.lastIndexOf(`
22
50
  ; CONFIG_BLOCK_END`);
23
- if (h >= 0) return o.slice(0, h + 1) + u + o.slice(h + 1);
24
- let c = `
51
+ if (l >= 0) return n.slice(0, l + 1) + a + n.slice(l + 1);
52
+ let o = `
25
53
  `;
26
- return (!o || o.endsWith(`
27
- `)) && (c = ""), o + c + u;
54
+ return (!n || n.endsWith(`
55
+ `)) && (o = ""), n + o + a;
28
56
  }
29
- const ht = {
57
+ const _t = {
30
58
  // OrcaSlicer / PrusaSlicer ;TYPE: names
31
59
  "outer wall": t.WALL,
32
60
  "external perimeter": t.WALL,
@@ -69,7 +97,7 @@ const ht = {
69
97
  skin: t.SOLID,
70
98
  "support-interface": t.SUPPORT,
71
99
  "prime-tower": t.PRIME
72
- }, Pt = [
100
+ }, Gt = [
73
101
  ["skirt/brim", t.SKIRT],
74
102
  ["skirt", t.SKIRT],
75
103
  ["walls", t.WALL],
@@ -80,7 +108,7 @@ const ht = {
80
108
  ["support", t.SUPPORT],
81
109
  ["prime tower", t.PRIME],
82
110
  ["wipe_tower_real", t.PRIME]
83
- ], Ot = (n, r) => n === r || r.length < n.length && " (:/".includes(n[r.length]) && n.startsWith(r), Et = {
111
+ ], wt = (s, i) => s === i || i.length < s.length && " (:/".includes(s[i.length]) && s.startsWith(i), Wt = {
84
112
  1: t.WALL,
85
113
  2: t.WALL,
86
114
  3: t.WALL,
@@ -99,140 +127,151 @@ const ht = {
99
127
  16: t.SUPPORT,
100
128
  17: t.PRIME
101
129
  };
102
- function Wt(n, r = {}) {
103
- const o = Math.PI / 4 * (r.filamentDiameter > 0 ? r.filamentDiameter : Nt) ** 2, d = r.defaultLayerHeight > 0 ? r.defaultLayerHeight : Rt;
104
- let u = 0, h = 0, c = 0, b = 0, w = !0, y = !0, g = 0, O = t.WALL, W = 0, R = null;
105
- const E = [];
106
- let D = !1, x = !0, v = NaN, q = 0, X = 0, $ = 0;
107
- const z = /* @__PURE__ */ new Set([0]), H = [];
108
- let k = [], j = [], U = !1;
109
- const V = () => {
110
- O = t.WALL, W = 0;
111
- }, C = (s, a = !1) => {
112
- R = { z: s, p: [], w: [] }, E.push(R), x = !1, v = NaN, (a || !U) && V();
113
- }, mt = () => E.length > 1 ? E[E.length - 2].z : 0, J = (s, a, S, P, A, i, e) => {
114
- const m = Math.hypot(P - s, A - a, i - S);
115
- if (!(m < K))
116
- if (e > K) {
117
- $ += e, H[g] = (H[g] ?? 0) + e, x ? C(Number.isNaN(v) ? i : v) : !D && i > R.z + 1e-3 && C(i);
118
- const p = Z(O, g);
119
- R.p.push(s, a, S, p, P, A, i, p);
120
- const f = Math.max(0.02, R.z - mt() || d), L = W > 0 ? W : e * o / (m * f) + f * (1 - Math.PI / 4);
121
- R.w.push(Math.min(3, Math.max(0.05, L))), q++;
122
- } else R && (R.p.push(s, a, S, Z(t.TRAVEL, g), P, A, i, Z(t.TRAVEL, g)), R.w.push(0), X++);
130
+ function Ht(s, { center: i = { x: 0, y: 0 }, filamentDiameter: n, layerHeight: m } = {}) {
131
+ const a = bt(s, { filamentDiameter: n, defaultLayerHeight: m });
132
+ for (const l of a.layers) {
133
+ const o = l.paths;
134
+ for (let L = 0; L + ut <= o.length; L += ut)
135
+ o[L] -= i.x, o[L + 1] -= i.y, o[L + 4] -= i.x, o[L + 5] -= i.y;
136
+ }
137
+ return a;
138
+ }
139
+ function bt(s, i = {}) {
140
+ const n = Math.PI / 4 * (i.filamentDiameter > 0 ? i.filamentDiameter : At) ** 2, m = i.defaultLayerHeight > 0 ? i.defaultLayerHeight : St;
141
+ let a = 0, l = 0, o = 0, L = 0, E = !0, d = !0, N = 0, A = t.WALL, S = 0, g = null;
142
+ const y = [];
143
+ let x = !1, D = !0, v = NaN, q = 0, X = 0, V = 0;
144
+ const K = /* @__PURE__ */ new Set([0]), z = [];
145
+ let j = [], k = [], F = !1;
146
+ const J = () => {
147
+ A = t.WALL, S = 0;
148
+ }, C = (c, f = !1) => {
149
+ g = { z: c, p: [], w: [] }, y.push(g), D = !1, v = NaN, (f || !F) && J();
150
+ }, Rt = () => y.length > 1 ? y[y.length - 2].z : 0, Q = (c, f, P, O, T, r, e) => {
151
+ const p = Math.hypot(O - c, T - f, r - P);
152
+ if (!(p < B))
153
+ if (e > B) {
154
+ V += e, z[N] = (z[N] ?? 0) + e, D ? C(Number.isNaN(v) ? r : v) : !x && r > g.z + 1e-3 && C(r);
155
+ const I = $(A, N);
156
+ g.p.push(c, f, P, I, O, T, r, I);
157
+ const h = Math.max(0.02, g.z - Rt() || m), _ = S > 0 ? S : e * n / (p * h) + h * (1 - Math.PI / 4);
158
+ g.w.push(Math.min(3, Math.max(0.05, _))), q++;
159
+ } else g && (g.p.push(c, f, P, $(t.TRAVEL, N), O, T, r, $(t.TRAVEL, N)), g.w.push(0), X++);
123
160
  };
124
- for (const s of n.split(`
161
+ for (const c of s.split(`
125
162
  `)) {
126
- const a = s.indexOf(";"), S = (a < 0 ? s : s.slice(0, a)).trim(), P = a < 0 ? "" : s.slice(a + 1).trim();
127
- if (P && !S) {
128
- const e = P.toLowerCase(), m = At.exec(P);
129
- if (m) {
130
- m[1].toLowerCase() === "filament" ? k = ut(m[2]) : j = ut(m[2]);
163
+ const f = c.indexOf(";"), P = (f < 0 ? c : c.slice(0, f)).trim(), O = f < 0 ? "" : c.slice(f + 1).trim();
164
+ if (O && !P) {
165
+ const e = O.toLowerCase(), p = Tt.exec(O);
166
+ if (p) {
167
+ p[1].toLowerCase() === "filament" ? j = It(p[2]) : k = It(p[2]);
131
168
  continue;
132
169
  }
133
170
  if (e.startsWith("type:")) {
134
- O = ht[e.slice(5).trim()] ?? t.WALL, U = !0;
171
+ A = _t[e.slice(5).trim()] ?? t.WALL, F = !0;
135
172
  continue;
136
173
  }
137
174
  if (e.startsWith("feature:")) {
138
- O = ht[e.slice(8).trim()] ?? t.WALL, U = !0;
175
+ A = _t[e.slice(8).trim()] ?? t.WALL, F = !0;
139
176
  continue;
140
177
  }
141
178
  if (e.startsWith("_extrusion_role:")) {
142
- O = Et[parseInt(e.slice(16), 10)] ?? t.WALL, U = !0;
179
+ A = Wt[parseInt(e.slice(16), 10)] ?? t.WALL, F = !0;
143
180
  continue;
144
181
  }
145
182
  if (e.startsWith("width:") || e.startsWith("line_width:")) {
146
- const L = parseFloat(e.slice(e.indexOf(":") + 1));
147
- W = 0, L > 0 && (W = L);
183
+ const _ = parseFloat(e.slice(e.indexOf(":") + 1));
184
+ S = 0, _ > 0 && (S = _);
148
185
  continue;
149
186
  }
150
187
  if (e.startsWith("layer_change") || e.startsWith("change_layer") || e.startsWith("layer:")) {
151
- D = !0, x = !0, V();
188
+ x = !0, D = !0, J();
152
189
  continue;
153
190
  }
154
191
  if (e.startsWith("z:") || e.startsWith("z_height:")) {
155
- const L = parseFloat(e.slice(e.indexOf(":") + 1));
156
- x && L > 0 && (D = !0, C(L));
192
+ const _ = parseFloat(e.slice(e.indexOf(":") + 1));
193
+ D && _ > 0 && (x = !0, C(_));
157
194
  continue;
158
195
  }
159
- const p = /^layer \d+ z([-\d.]+)/.exec(e);
160
- if (p) {
161
- D = !0, C(parseFloat(p[1]), !0);
196
+ const I = /^layer \d+ z([-\d.]+)/.exec(e);
197
+ if (I) {
198
+ x = !0, C(parseFloat(I[1]), !0);
162
199
  continue;
163
200
  }
164
- const f = Pt.find(([L]) => Ot(e, L));
165
- f && (O = f[1]);
201
+ const h = Gt.find(([_]) => wt(e, _));
202
+ h && (A = h[1]);
166
203
  continue;
167
204
  }
168
- if (!S) continue;
169
- const A = S.split(/\s+/), i = A[0].toUpperCase();
170
- if (i === "G90") {
171
- w = !0;
205
+ if (!P) continue;
206
+ const T = P.split(/\s+/), r = T[0].toUpperCase();
207
+ if (r === "G90") {
208
+ E = !0;
172
209
  continue;
173
210
  }
174
- if (i === "G91") {
175
- w = !1;
211
+ if (r === "G91") {
212
+ E = !1;
176
213
  continue;
177
214
  }
178
- if (i === "M82") {
179
- y = !0;
215
+ if (r === "M82") {
216
+ d = !0;
180
217
  continue;
181
218
  }
182
- if (i === "M83") {
183
- y = !1;
219
+ if (r === "M83") {
220
+ d = !1;
184
221
  continue;
185
222
  }
186
- if (/^T\d+$/.test(i)) {
187
- const e = parseInt(i.slice(1), 10);
188
- e <= It && (g = e, z.add(g));
223
+ if (/^T\d+$/.test(r)) {
224
+ const e = parseInt(r.slice(1), 10);
225
+ e <= Mt && (N = e, K.add(N));
189
226
  continue;
190
227
  }
191
- if (i === "G92" || i === "G0" || i === "G1" || i === "G2" || i === "G3") {
192
- let e = NaN, m = NaN, p = NaN, f = NaN, L = 0, tt = 0;
193
- for (let I = 1; I < A.length; I++) {
194
- const l = A[I][0], N = parseFloat(A[I].slice(1));
195
- Number.isNaN(N) || (l === "X" || l === "x" ? e = N : l === "Y" || l === "y" ? m = N : l === "Z" || l === "z" ? p = N : l === "E" || l === "e" ? f = N : l === "I" || l === "i" ? L = N : (l === "J" || l === "j") && (tt = N));
228
+ if (r === "G92" || r === "G0" || r === "G1" || r === "G2" || r === "G3") {
229
+ let e = NaN, p = NaN, I = NaN, h = NaN, _ = 0, et = 0;
230
+ for (let M = 1; M < T.length; M++) {
231
+ const u = T[M][0], R = parseFloat(T[M].slice(1));
232
+ Number.isNaN(R) || (u === "X" || u === "x" ? e = R : u === "Y" || u === "y" ? p = R : u === "Z" || u === "z" ? I = R : u === "E" || u === "e" ? h = R : u === "I" || u === "i" ? _ = R : (u === "J" || u === "j") && (et = R));
196
233
  }
197
- if (i === "G92") {
198
- Number.isNaN(e) || (u = e), Number.isNaN(m) || (h = m), Number.isNaN(p) || (c = p), Number.isNaN(f) || (b = f);
234
+ if (r === "G92") {
235
+ Number.isNaN(e) || (a = e), Number.isNaN(p) || (l = p), Number.isNaN(I) || (o = I), Number.isNaN(h) || (L = h);
199
236
  continue;
200
237
  }
201
- const B = Number.isNaN(e) ? u : w ? e : u + e, F = Number.isNaN(m) ? h : w ? m : h + m, Y = Number.isNaN(p) ? c : w ? p : c + p, et = Number.isNaN(f) ? 0 : y ? f - b : f;
202
- if (i === "G2" || i === "G3") {
203
- const I = u + L, l = h + tt, N = Math.hypot(u - I, h - l), G = Math.atan2(h - l, u - I);
204
- let M = Math.atan2(F - l, B - I);
205
- const it = i === "G3";
206
- it && M <= G + K && (M += 2 * Math.PI), !it && M >= G - K && (M -= 2 * Math.PI);
207
- const _ = Math.max(1, Math.min(360, Math.ceil(Math.abs(M - G) * N / 0.3)));
208
- let nt = u, rt = h, st = c;
209
- for (let T = 1; T <= _; T++) {
210
- const ot = G + (M - G) * T / _, at = T === _ ? B : I + N * Math.cos(ot), lt = T === _ ? F : l + N * Math.sin(ot), ct = c + (Y - c) * T / _;
211
- J(nt, rt, st, at, lt, ct, et / _), nt = at, rt = lt, st = ct;
238
+ const U = Number.isNaN(e) ? a : E ? e : a + e, H = Number.isNaN(p) ? l : E ? p : l + p, Y = Number.isNaN(I) ? o : E ? I : o + I, it = Number.isNaN(h) ? 0 : d ? h - L : h;
239
+ if (r === "G2" || r === "G3") {
240
+ const M = a + _, u = l + et, R = Math.hypot(a - M, l - u), b = Math.atan2(l - u, a - M);
241
+ let G = Math.atan2(H - u, U - M);
242
+ const nt = r === "G3";
243
+ nt && G <= b + B && (G += 2 * Math.PI), !nt && G >= b - B && (G -= 2 * Math.PI);
244
+ const w = Math.max(1, Math.min(360, Math.ceil(Math.abs(G - b) * R / 0.3)));
245
+ let st = a, ot = l, rt = o;
246
+ for (let W = 1; W <= w; W++) {
247
+ const at = b + (G - b) * W / w, lt = W === w ? U : M + R * Math.cos(at), ct = W === w ? H : u + R * Math.sin(at), ft = o + (Y - o) * W / w;
248
+ Q(st, ot, rt, lt, ct, ft, it / w), st = lt, ot = ct, rt = ft;
212
249
  }
213
250
  } else
214
- J(u, h, c, B, F, Y, et);
215
- u = B, h = F, c = Y, Number.isNaN(f) || (b = y ? f : b + f);
251
+ Q(a, l, o, U, H, Y, it);
252
+ a = U, l = H, o = Y, Number.isNaN(h) || (L = d ? h : L + h);
216
253
  }
217
254
  }
218
- const pt = Math.max(k.length, j.length), Q = Array.from({ length: pt }, (s, a) => j[a] || k[a] || null), Lt = Array.from({ length: Math.max(...z) + 1 }, (s, a) => H[a] || 0);
255
+ const Et = Math.max(j.length, k.length), tt = Array.from({ length: Et }, (c, f) => k[f] || j[f] || null), dt = Array.from({ length: Math.max(...K) + 1 }, (c, f) => z[f] || 0);
219
256
  return {
220
- layers: E.map((s) => ({ z: s.z, paths: Float32Array.from(s.p), widths: Float32Array.from(s.w) })),
257
+ layers: y.map((c) => ({ z: c.z, paths: Float32Array.from(c.p), widths: Float32Array.from(c.w) })),
221
258
  stats: {
222
- layers: E.length,
259
+ layers: y.length,
223
260
  path_segments: q,
224
261
  travel_segments: X,
225
- filament_mm: $,
226
- tools: [...z].sort((s, a) => s - a),
262
+ filament_mm: V,
263
+ tools: [...K].sort((c, f) => c - f),
227
264
  // The kernel's own stat name, so the Filament-view switch and the stats card's per-tool split work unchanged.
228
- filament_mm_by_tool: Lt,
229
- ...Q.some(Boolean) && { colors: Q }
265
+ filament_mm_by_tool: dt,
266
+ ...tt.some(Boolean) && { colors: tt }
230
267
  }
231
268
  };
232
269
  }
233
270
  export {
234
- wt as exportedGcode,
235
- Wt as parseGcode,
236
- gt as resultToolColors,
237
- St as withFilamentColours
271
+ Ut as exportedGcode,
272
+ Ct as finalizeGcode,
273
+ bt as parseGcode,
274
+ Ht as previewFromGcode,
275
+ Ot as resultToolColors,
276
+ yt as withFilamentColours
238
277
  };