three-slicer-viewer 0.3.1 → 0.3.3

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.
package/dist/toolpath.js CHANGED
@@ -1,191 +1,113 @@
1
- import { U as St, b as It, a as kt } from "./viewer_defaults-B7UUZ582.js";
2
- import { r as bt, S as nt, R as et, t as Tt } from "./toolpath_encoding-BuYs95qZ.js";
3
- import { T as Pt } from "./theme-2oyfMuvf.js";
4
- const O = {
5
- 0: [0.35, 0.38, 0.44],
6
- // travel
7
- 1: [0.98, 0.45, 0.16],
8
- // wall
9
- 2: [0.36, 0.72, 0.94],
10
- // sparse infill
11
- 3: [0.2, 0.55, 0.86],
12
- // solid infill
13
- 4: [0.62, 0.66, 0.72],
14
- // skirt / brim
15
- 5: [0.5, 0.54, 0.6],
16
- // support
17
- 6: [0.42, 0.46, 0.52],
18
- // raft
19
- 7: [0.96, 0.76, 0.22],
20
- // gap fill
21
- 8: [0.88, 0.55, 0.3],
22
- // thin wall
23
- 9: [0.3, 0.8, 0.62],
24
- // bridge
25
- 10: [0.8, 0.42, 0.72],
26
- // ironing
27
- 11: [0.58, 0.5, 0.88]
28
- // prime tower
29
- }, Ot = {
30
- 0: "Travel",
31
- 1: "Wall",
32
- 2: "Sparse",
33
- 3: "Solid",
34
- 4: "Skirt",
35
- 5: "Support",
36
- 6: "Raft",
37
- 7: "Gap",
38
- 8: "Thin",
39
- 9: "Bridge",
40
- 10: "Ironing",
41
- 11: "Prime"
42
- }, gt = [
43
- [0.9, 0.26, 0.3],
44
- [0.27, 0.6, 0.93],
45
- [0.36, 0.78, 0.42],
46
- [0.98, 0.72, 0.2],
47
- [0.72, 0.42, 0.9],
48
- [0.2, 0.78, 0.8],
49
- [0.95, 0.5, 0.72],
50
- [0.6, 0.6, 0.64]
51
- ];
52
- function Lt(t) {
53
- const e = /^#?([0-9a-f]{6})$/i.exec(String(t ?? "").trim());
54
- if (!e) return Lt(St);
55
- const n = parseInt(e[1], 16);
56
- return [(n >> 16 & 255) / 255, (n >> 8 & 255) / 255, (n & 255) / 255];
57
- }
58
- function ot(t) {
59
- const e = (n) => Math.max(0, Math.min(255, Math.round((Number(n) || 0) * 255)));
60
- return e(t?.[0]) * 65536 + e(t?.[1]) * 256 + e(t?.[2]);
61
- }
62
- const xt = [
63
- [0.043, 0.173, 0.478],
64
- [0.055, 0.325, 0.639],
65
- [0.067, 0.478, 0.8],
66
- [0.078, 0.631, 0.961],
67
- [0.118, 0.749, 0.804],
68
- [0.157, 0.867, 0.647],
69
- [0.376, 0.902, 0.4],
70
- [0.667, 0.898, 0.157],
71
- [0.988, 0.976, 0.012],
72
- [0.988, 0.663, 0.012],
73
- [0.58, 0.149, 0.086]
74
- ];
75
- function _t(t, e, n, r = xt) {
76
- const o = r.length - 1;
77
- if (o < 0) return [0, 0, 0];
78
- if (!Number.isFinite(t) || !Number.isFinite(e) || !Number.isFinite(n) || n <= e || t <= e) return r[0];
79
- if (t >= n) return r[o];
80
- const i = (t - e) / (n - e) * o, f = Math.min(o - 1, Math.floor(i)), u = i - f, l = r[f], m = r[f + 1];
81
- return [l[0] + (m[0] - l[0]) * u, l[1] + (m[1] - l[1]) * u, l[2] + (m[2] - l[2]) * u];
82
- }
83
- const rt = {};
84
- for (const t of Object.keys(O)) rt[t] = ot(O[t]);
85
- function Vt(t) {
1
+ import { a as Z, b as It, p as at, h as St, T as wt, r as Nt, D as Pt } from "./toolpath_palette-B8xEl-qa.js";
2
+ import { b as Bt, a as Vt } from "./viewer_defaults-B7UUZ582.js";
3
+ import { r as At, S as lt, R as et, t as _t } from "./toolpath_encoding-BuYs95qZ.js";
4
+ import { T as kt } from "./theme-2oyfMuvf.js";
5
+ const ct = {};
6
+ for (const t of Object.keys(Z)) ct[t] = at(Z[t]);
7
+ function Wt(t) {
86
8
  const e = new Float32Array(t.length);
87
- for (let n = 0; n < t.length; n++) {
88
- const r = Number(t[n]?.z) || 0, o = n > 0 && Number(t[n - 1]?.z) || 0, i = n > 0 ? r - o : r;
89
- e[n] = i > 1e-6 ? i : kt;
9
+ for (let o = 0; o < t.length; o++) {
10
+ const n = Number(t[o]?.z) || 0, r = o > 0 && Number(t[o - 1]?.z) || 0, c = o > 0 ? n - r : n;
11
+ e[o] = c > 1e-6 ? c : Vt;
90
12
  }
91
13
  return e;
92
14
  }
93
- const it = (t) => t?.paths?.length ? t.paths : null, wt = (t) => {
94
- const e = it(t);
95
- return e ? Math.floor(e.length / nt) : 0;
15
+ const ft = (t) => t?.paths?.length ? t.paths : null, gt = (t) => {
16
+ const e = ft(t);
17
+ return e ? Math.floor(e.length / lt) : 0;
96
18
  };
97
- function Rt(t, e) {
98
- const n = Array.isArray(t) ? t : [], r = n.length, o = Number(e) > 0 ? Number(e) : It, i = Vt(n), f = new Uint32Array(r + 1), u = new Uint32Array(r + 1), l = new Uint32Array(r + 1);
99
- let m = 0, c = 0, h = 0;
100
- for (let y = 0; y < r; y++) {
101
- const U = it(n[y]), w = wt(n[y]);
102
- for (let D = 0; D < w; D++)
103
- bt(U[D * nt + 3]) === et.TRAVEL ? c++ : m++;
104
- h += w, f[y + 1] = m, u[y + 1] = c, l[y + 1] = h;
19
+ function Ht(t, e) {
20
+ const o = Array.isArray(t) ? t : [], n = o.length, r = Number(e) > 0 ? Number(e) : Bt, c = Wt(o), h = new Uint32Array(n + 1), d = new Uint32Array(n + 1), u = new Uint32Array(n + 1);
21
+ let m = 0, s = 0, f = 0;
22
+ for (let p = 0; p < n; p++) {
23
+ const P = ft(o[p]), C = gt(o[p]);
24
+ for (let A = 0; A < C; A++)
25
+ At(P[A * lt + 3]) === et.TRAVEL ? s++ : m++;
26
+ f += C, h[p + 1] = m, d[p + 1] = s, u[p + 1] = f;
105
27
  }
106
- const a = m * 2, b = new Float32Array(a * 4), x = new Float32Array(a * 4), v = new Uint32Array(a * 2), _ = new Uint8Array(a), F = new Uint8Array(a), V = new Float32Array(a), M = new Float32Array(a), W = new Int32Array(a), g = new Float32Array(c * 6), C = new Float32Array(h * 3), s = new Uint8Array(h), p = new Float64Array(16);
107
- let A = !1, S = 0, I = 1 / 0, T = 1 / 0, z = 1 / 0, $ = -1 / 0, J = -1 / 0, Q = -1 / 0, L = 0, st = 0, lt = 0, B = 0;
108
- for (let y = 0; y < r; y++) {
109
- const U = n[y], w = it(U), D = wt(U), ct = U?.widths, E = i[y], ft = E / 2;
110
- for (let j = 0; j < D; j++) {
111
- const k = j * nt, X = w[k], Z = w[k + 1], q = w[k + 2], G = w[k + 4], Y = w[k + 5], H = w[k + 6], ut = w[k + 3] | 0, R = bt(ut), Nt = Tt(ut);
112
- if (Number.isFinite(X + Z + q + G + Y + H) || (A = !0), s[B] = R === et.TRAVEL ? 0 : 1, C[B * 3] = G, C[B * 3 + 1] = Y, C[B * 3 + 2] = H, B++, R === et.TRAVEL) {
113
- const d = lt * 6;
114
- g[d] = X, g[d + 1] = Z, g[d + 2] = q, g[d + 3] = G, g[d + 4] = Y, g[d + 5] = H, lt++;
28
+ const l = m * 2, L = new Float32Array(l * 4), I = new Float32Array(l * 4), v = new Uint32Array(l * 2), q = new Uint8Array(l), B = new Uint8Array(l), V = new Float32Array(l), ot = new Float32Array(l), T = new Int32Array(l), F = new Float32Array(s * 6), _ = new Float32Array(f * 3), j = new Uint8Array(f), nt = new Float64Array(16);
29
+ let J = !1, Y = 0, z = 1 / 0, k = 1 / 0, X = 1 / 0, W = -1 / 0, D = -1 / 0, i = -1 / 0, a = 0, b = 0, w = 0, x = 0;
30
+ for (let p = 0; p < n; p++) {
31
+ const P = o[p], C = ft(P), A = gt(P), Q = P?.widths, O = c[p], y = O / 2;
32
+ for (let g = 0; g < A; g++) {
33
+ const S = g * lt, G = C[S], rt = C[S + 1], it = C[S + 2], $ = C[S + 4], H = C[S + 5], R = C[S + 6], ht = C[S + 3] | 0, E = At(ht), Ct = _t(ht);
34
+ if (Number.isFinite(G + rt + it + $ + H + R) || (J = !0), j[x] = E === et.TRAVEL ? 0 : 1, _[x * 3] = $, _[x * 3 + 1] = H, _[x * 3 + 2] = R, x++, E === et.TRAVEL) {
35
+ const M = w * 6;
36
+ F[M] = G, F[M + 1] = rt, F[M + 2] = it, F[M + 3] = $, F[M + 4] = H, F[M + 5] = R, w++;
115
37
  continue;
116
38
  }
117
- const tt = ct ? Number(ct[j]) : NaN, mt = Number.isFinite(tt) && tt > 0 ? tt : o, ht = G - X, pt = Y - Z, Ft = Math.atan2(pt, ht), vt = Math.hypot(ht, pt, H - q);
118
- Number.isFinite(vt) && (p[R] += vt);
119
- const Mt = rt[R] ?? rt[1];
120
- for (const [d, P, yt] of [[X, Z, q], [G, Y, H]]) {
121
- const N = L * 4;
122
- b[N] = d, b[N + 1] = P, b[N + 2] = yt - ft, b[N + 3] = 0, x[N] = E, x[N + 1] = mt, x[N + 2] = Ft, x[N + 3] = Mt, v[L * 2] = st, v[L * 2 + 1] = y, _[L] = R, F[L] = Nt, V[L] = mt, M[L] = E, W[L] = y, L++;
123
- const K = yt - ft;
124
- d < I && (I = d), d > $ && ($ = d), P < T && (T = P), P > J && (J = P), K < z && (z = K), K > Q && (Q = K);
125
- const dt = Math.max(Math.abs(d), Math.abs(P), Math.abs(K));
126
- dt > S && (S = dt);
39
+ const st = Q ? Number(Q[g]) : NaN, mt = Number.isFinite(st) && st > 0 ? st : r, pt = $ - G, yt = H - rt, Mt = Math.atan2(yt, pt), vt = Math.hypot(pt, yt, R - it);
40
+ Number.isFinite(vt) && (nt[E] += vt);
41
+ const Ft = ct[E] ?? ct[1];
42
+ for (const [M, K, dt] of [[G, rt, it], [$, H, R]]) {
43
+ const U = a * 4;
44
+ L[U] = M, L[U + 1] = K, L[U + 2] = dt - y, L[U + 3] = 0, I[U] = O, I[U + 1] = mt, I[U + 2] = Mt, I[U + 3] = Ft, v[a * 2] = b, v[a * 2 + 1] = p, q[a] = E, B[a] = Ct, V[a] = mt, ot[a] = O, T[a] = p, a++;
45
+ const tt = dt - y;
46
+ M < z && (z = M), M > W && (W = M), K < k && (k = K), K > D && (D = K), tt < X && (X = tt), tt > i && (i = tt);
47
+ const bt = Math.max(Math.abs(M), Math.abs(K), Math.abs(tt));
48
+ bt > Y && (Y = bt);
127
49
  }
128
- st++;
50
+ b++;
129
51
  }
130
52
  }
131
- const Ct = a > 0 && Number.isFinite(I) ? { min: [I, T, z], max: [$, J, Q] } : null;
53
+ const N = l > 0 && Number.isFinite(z) ? { min: [z, k, X], max: [W, D, i] } : null;
132
54
  return {
133
- position: b,
134
- hwa: x,
55
+ position: L,
56
+ hwa: I,
135
57
  segIndex: v,
136
- nV: a,
58
+ nV: l,
137
59
  nSeg: m,
138
- layerSegPrefix: f,
139
- travelPos: g,
140
- travelPrefix: u,
141
- nTrav: c,
142
- movePos: C,
143
- moveKind: s,
144
- movePrefix: l,
145
- layerCount: r,
146
- maxAbs: S,
147
- hasNaN: A,
148
- typeLengths: p,
149
- bbox: Ct,
150
- meta: { vType: _, vTool: F, vWidth: V, vHeight: M, vLayer: W }
60
+ layerSegPrefix: h,
61
+ travelPos: F,
62
+ travelPrefix: d,
63
+ nTrav: s,
64
+ movePos: _,
65
+ moveKind: j,
66
+ movePrefix: u,
67
+ layerCount: n,
68
+ maxAbs: Y,
69
+ hasNaN: J,
70
+ typeLengths: nt,
71
+ bbox: N,
72
+ meta: { vType: q, vTool: B, vWidth: V, vHeight: ot, vLayer: T }
151
73
  };
152
74
  }
153
- function Kt(t) {
75
+ function Rt(t) {
154
76
  const e = t ?? [];
155
- let n = 0;
156
- for (let o = 0; o < 16; o++) n += Number(e[o]) || 0;
157
- if (n <= 0) return [];
158
- const r = [];
159
- for (let o = 0; o < 16; o++) {
160
- const i = Number(e[o]) || 0;
161
- i <= 0 || r.push({ type: o, label: Ot[o] ?? String(o), pct: i / n * 100, color: O[o] ?? O[1] });
77
+ let o = 0;
78
+ for (let r = 0; r < 16; r++) o += Number(e[r]) || 0;
79
+ if (o <= 0) return [];
80
+ const n = [];
81
+ for (let r = 0; r < 16; r++) {
82
+ const c = Number(e[r]) || 0;
83
+ c <= 0 || n.push({ type: r, label: It[r] ?? String(r), pct: c / o * 100, color: Z[r] ?? Z[1] });
162
84
  }
163
- return r.sort((o, i) => i.pct - o.pct);
85
+ return n.sort((r, c) => c.pct - r.pct);
164
86
  }
165
- const at = (t, e) => e >= 0 && e < t.layerCount ? t.movePrefix[e + 1] - t.movePrefix[e] : 0;
166
- function jt(t, e) {
167
- return at(t, e);
87
+ const ut = (t, e) => e >= 0 && e < t.layerCount ? t.movePrefix[e + 1] - t.movePrefix[e] : 0;
88
+ function Et(t, e) {
89
+ return ut(t, e);
168
90
  }
169
- function Xt(t, e, n) {
170
- const r = Math.min(n, t.layerCount - 1);
171
- for (let o = r; o >= e; o--) if (at(t, o) > 0) return o;
91
+ function te(t, e, o) {
92
+ const n = Math.min(o, t.layerCount - 1);
93
+ for (let r = n; r >= e; r--) if (ut(t, r) > 0) return r;
172
94
  return e;
173
95
  }
174
- function Zt(t, e, n) {
175
- const r = at(t, e), o = Math.max(0, Math.min(Number(n) || 0, r)), i = e >= 0 && e < t.layerCount ? t.movePrefix[e] : 0;
176
- let f = 0, u = 0;
177
- for (let m = 0; m < o; m++)
178
- t.moveKind[i + m] === 0 ? u++ : f++;
179
- if (o === 0) return { point: null, segCount: 0, travCount: 0, onTravel: !1 };
180
- const l = i + o - 1;
96
+ function ee(t, e, o) {
97
+ const n = ut(t, e), r = Math.max(0, Math.min(Number(o) || 0, n)), c = e >= 0 && e < t.layerCount ? t.movePrefix[e] : 0;
98
+ let h = 0, d = 0;
99
+ for (let m = 0; m < r; m++)
100
+ t.moveKind[c + m] === 0 ? d++ : h++;
101
+ if (r === 0) return { point: null, segCount: 0, travCount: 0, onTravel: !1 };
102
+ const u = c + r - 1;
181
103
  return {
182
- point: [t.movePos[l * 3], t.movePos[l * 3 + 1], t.movePos[l * 3 + 2]],
183
- segCount: f,
184
- travCount: u,
185
- onTravel: t.moveKind[l] === 0
104
+ point: [t.movePos[u * 3], t.movePos[u * 3 + 1], t.movePos[u * 3 + 2]],
105
+ segCount: h,
106
+ travCount: d,
107
+ onTravel: t.moveKind[u] === 0
186
108
  };
187
109
  }
188
- const At = [
110
+ const Lt = [
189
111
  { key: "feature", label: "Feature type", cont: !1, unit: "" },
190
112
  { key: "speed", label: "Speed", cont: !0, unit: "mm/s" },
191
113
  { key: "height", label: "Layer Height", cont: !0, unit: "mm" },
@@ -197,47 +119,47 @@ const At = [
197
119
  // extruder index is a label, and a heatmap over it would imply tool 2 sits "between" tools 1 and 3.
198
120
  { key: "filament", label: "Filament", cont: !1, unit: "" }
199
121
  ];
200
- function Wt(t, e, n, r) {
201
- const o = e.vType[n], i = e.vLayer[n], f = i === 0;
122
+ function Ot(t, e, o, n) {
123
+ const r = e.vType[o], c = e.vLayer[o], h = c === 0;
202
124
  switch (t) {
203
125
  case "height":
204
- return e.vHeight[n];
126
+ return e.vHeight[o];
205
127
  case "width":
206
- return e.vWidth[n];
128
+ return e.vWidth[o];
207
129
  case "speed":
208
- return f ? r.firstLayerSpeed : r.speedByType[o] ?? r.speedByType[1];
130
+ return h ? n.firstLayerSpeed : n.speedByType[r] ?? n.speedByType[1];
209
131
  case "fan":
210
- return i < r.closeFanLayers ? 0 : o === 9 ? 100 : r.fanNormal;
132
+ return c < n.closeFanLayers ? 0 : r === 9 ? 100 : n.fanNormal;
211
133
  case "temp":
212
- return f ? r.tempFirst : r.tempNormal;
134
+ return h ? n.tempFirst : n.tempNormal;
213
135
  default:
214
136
  return 0;
215
137
  }
216
138
  }
217
- function qt(t, e, n) {
218
- const { meta: r, nV: o } = t, i = new Float32Array(o * 4), f = At.find((c) => c.key === e) || At[0];
219
- if (!f.cont) {
220
- const c = (n?.toolColors ?? []).map(Lt), h = f.key === "filament" ? (a) => {
221
- const b = r.vTool ? r.vTool[a] : 0;
222
- return c[b] || gt[b % gt.length];
223
- } : (a) => O[r.vType[a]] || O[1];
224
- for (let a = 0; a < o; a++) i[a * 4] = ot(h(a));
225
- return { color: i, min: 0, max: 0, viewType: e, label: f.label, unit: f.unit, cont: !1 };
139
+ function oe(t, e, o) {
140
+ const { meta: n, nV: r } = t, c = new Float32Array(r * 4), h = Lt.find((s) => s.key === e) || Lt[0];
141
+ if (!h.cont) {
142
+ const s = (o?.toolColors ?? []).map((l) => l && St(l)), f = h.key === "filament" ? (l) => {
143
+ const L = n.vTool ? n.vTool[l] : 0;
144
+ return s[L] || wt[L % wt.length];
145
+ } : (l) => Z[n.vType[l]] || Z[1];
146
+ for (let l = 0; l < r; l++) c[l * 4] = at(f(l));
147
+ return { color: c, min: 0, max: 0, viewType: e, label: h.label, unit: h.unit, cont: !1 };
226
148
  }
227
- let u = 1 / 0, l = -1 / 0;
228
- const m = new Float32Array(o);
229
- for (let c = 0; c < o; c++) {
230
- const h = Wt(e, r, c, n), a = Number.isFinite(h) ? h : 0;
231
- m[c] = a, a < u && (u = a), a > l && (l = a);
149
+ let d = 1 / 0, u = -1 / 0;
150
+ const m = new Float32Array(r);
151
+ for (let s = 0; s < r; s++) {
152
+ const f = Ot(e, n, s, o), l = Number.isFinite(f) ? f : 0;
153
+ m[s] = l, l < d && (d = l), l > u && (u = l);
232
154
  }
233
- Number.isFinite(u) || (u = 0, l = 1);
234
- for (let c = 0; c < o; c++) {
235
- const h = _t(m[c], u, l, xt);
236
- i[c * 4] = ot(h);
155
+ Number.isFinite(d) || (d = 0, u = 1);
156
+ for (let s = 0; s < r; s++) {
157
+ const f = Nt(m[s], d, u, Pt);
158
+ c[s * 4] = at(f);
237
159
  }
238
- return { color: i, min: u, max: l, viewType: e, label: f.label, unit: f.unit, cont: !0 };
160
+ return { color: c, min: d, max: u, viewType: e, label: h.label, unit: h.unit, cont: !0 };
239
161
  }
240
- const zt = `
162
+ const Ut = `
241
163
  precision highp float;
242
164
 
243
165
  uniform mat4 projectionMatrix;
@@ -297,7 +219,7 @@ void main() {
297
219
  vColor = unpackColor(iColor);
298
220
  gl_Position = projectionMatrix * modelViewMatrix * vec4(world, 1.0);
299
221
  }
300
- `, Bt = `
222
+ `, zt = `
301
223
  precision highp float;
302
224
 
303
225
  in vec3 vColor;
@@ -305,15 +227,48 @@ in vec3 vNormal;
305
227
  out vec4 fragColor;
306
228
 
307
229
  void main() {
308
- // Two-sided: the layer slider cuts the plate open, so back faces are seen and must not go black.
230
+ // Front faces only (the material culls the rest), so the normal never needs flipping.
309
231
  vec3 n = normalize(vNormal);
310
- if (!gl_FrontFacing) n = -n;
311
232
  // A single head-on light plus a generous ambient. The point is to read the bead's ROUNDING — which
312
233
  // face is up, which is the side — not to look lit.
313
234
  float lambert = max(dot(n, normalize(vec3(0.35, 0.35, 1.0))), 0.0);
314
235
  fragColor = vec4(vColor * (0.55 + 0.45 * lambert), 1.0);
315
236
  }
316
- `, Ut = new Float32Array([
237
+ `, xt = [2, 4], Dt = 1.5;
238
+ function Gt(t, e) {
239
+ let o = 0;
240
+ for (let n = 0; n < t.length; n += 2)
241
+ (t[n] === et.RAFT || t[n] === et.SKIRT) && e[n] > o && (o = e[n]);
242
+ return o;
243
+ }
244
+ function Tt(t, e, o, n) {
245
+ let r = 0;
246
+ for (let s = 0; s < e; s++) t(s) > r && (r = t(s));
247
+ const c = (s) => s <= n || (r - s) % o === 0;
248
+ let h = 0;
249
+ for (let s = 0; s < e; s++) c(t(s)) && h++;
250
+ const d = new Uint32Array(h), u = new Uint8Array(h);
251
+ let m = 0;
252
+ for (let s = 0; s < e; s++) {
253
+ const f = t(s);
254
+ c(f) && (d[m] = s, u[m] = 1, f > n && (u[m] = Math.min(o, f - n)), m++);
255
+ }
256
+ return { source: d, layers: u };
257
+ }
258
+ function jt(t, e) {
259
+ const o = Math.max(1, Math.floor(e / 4096)), n = [];
260
+ for (let r = 0; r < e; r += o) n.push(t(r));
261
+ return n.length ? (n.sort((r, c) => r - c), n[n.length >> 1]) : 0;
262
+ }
263
+ function Yt(t, e, o, n) {
264
+ return e > 0 ? t * (n / 2) / (e * Math.tan(o * Math.PI / 360)) : 1 / 0;
265
+ }
266
+ function Xt(t, e = xt) {
267
+ let o = 1;
268
+ for (const n of e) n * t <= Dt && n > o && (o = n);
269
+ return o;
270
+ }
271
+ const Kt = new Float32Array([
317
272
  0,
318
273
  0,
319
274
  0,
@@ -332,80 +287,119 @@ void main() {
332
287
  1,
333
288
  3
334
289
  // end ring
335
- ]), Dt = (() => {
290
+ ]), Zt = (() => {
336
291
  const t = [];
337
292
  for (let e = 0; e < 4; e++) {
338
- const n = e, r = (e + 1) % 4, o = 4 + (e + 1) % 4, i = 4 + e;
339
- t.push(n, r, o, n, o, i);
293
+ const o = e, n = (e + 1) % 4, r = 4 + (e + 1) % 4, c = 4 + e;
294
+ t.push(o, n, r, o, r, c);
340
295
  }
341
296
  return t;
342
297
  })();
343
- function $t(t, e) {
344
- const { nSeg: n, nV: r, position: o, hwa: i, travelPos: f, travelPrefix: u, layerCount: l, meta: m } = e, c = new Float32Array(n * 3), h = new Float32Array(n * 3), a = new Float32Array(n * 2), b = new Float32Array(n), x = new Float32Array(n);
345
- for (let s = 0; s < n; s++) {
346
- const p = s * 2 * 4, A = (s * 2 + 1) * 4;
347
- c[s * 3] = o[p], c[s * 3 + 1] = o[p + 1], c[s * 3 + 2] = o[p + 2], h[s * 3] = o[A], h[s * 3 + 1] = o[A + 1], h[s * 3 + 2] = o[A + 2], a[s * 2] = i[p], a[s * 2 + 1] = i[p + 1], b[s] = i[p + 3], x[s] = m.vLayer[s * 2];
298
+ function ne(t, e) {
299
+ const { nSeg: o, nV: n, position: r, hwa: c, travelPos: h, travelPrefix: d, layerCount: u, meta: m } = e, s = new Float32Array(o * 3), f = new Float32Array(o * 3), l = new Float32Array(o * 2), L = new Float32Array(o), I = new Float32Array(o);
300
+ for (let i = 0; i < o; i++) {
301
+ const a = i * 2 * 4, b = (i * 2 + 1) * 4;
302
+ s[i * 3] = r[a], s[i * 3 + 1] = r[a + 1], s[i * 3 + 2] = r[a + 2], f[i * 3] = r[b], f[i * 3 + 1] = r[b + 1], f[i * 3 + 2] = r[b + 2], l[i * 2] = c[a], l[i * 2 + 1] = c[a + 1], L[i] = c[a + 3], I[i] = m.vLayer[i * 2];
348
303
  }
349
304
  const v = new t.InstancedBufferGeometry();
350
- v.setAttribute("tpl", new t.BufferAttribute(Ut, 2)), v.setIndex(Dt), v.setAttribute("iStart", new t.InstancedBufferAttribute(c, 3)), v.setAttribute("iEnd", new t.InstancedBufferAttribute(h, 3)), v.setAttribute("iHW", new t.InstancedBufferAttribute(a, 2));
351
- const _ = new t.InstancedBufferAttribute(b, 1);
352
- v.setAttribute("iColor", _), v.setAttribute("iLayer", new t.InstancedBufferAttribute(x, 1)), v.instanceCount = n, v.boundingSphere = new t.Sphere(new t.Vector3(0, 0, 0), (e.maxAbs || 1) * 2);
353
- const F = new t.RawShaderMaterial({
354
- vertexShader: zt,
355
- fragmentShader: Bt,
305
+ v.setAttribute("tpl", new t.BufferAttribute(Kt, 2)), v.setIndex(Zt), v.setAttribute("iStart", new t.InstancedBufferAttribute(s, 3)), v.setAttribute("iEnd", new t.InstancedBufferAttribute(f, 3)), v.setAttribute("iHW", new t.InstancedBufferAttribute(l, 2));
306
+ const q = new t.InstancedBufferAttribute(L, 1);
307
+ v.setAttribute("iColor", q), v.setAttribute("iLayer", new t.InstancedBufferAttribute(I, 1)), v.instanceCount = o, v.boundingSphere = new t.Sphere(new t.Vector3(0, 0, 0), (e.maxAbs || 1) * 2);
308
+ const B = new t.RawShaderMaterial({
309
+ vertexShader: Ut,
310
+ fragmentShader: zt,
356
311
  glslVersion: t.GLSL3,
357
- side: t.DoubleSide,
358
- uniforms: { uLayerLo: { value: 0 }, uLayerHi: { value: Math.max(0, l - 1) } }
359
- }), V = new t.Mesh(v, F);
312
+ // Every face of the template winds outward (test_toolpath_contract.mjs), so a back face is only ever the
313
+ // inside of a bead seen through its open end. Drawing those doubled the GPU time of a frame: measured on a
314
+ // 14.6M-segment scene (6 plates, M5 Pro, DPR 2), 53.6 -> 29.4 ms with back faces culled.
315
+ side: t.FrontSide,
316
+ uniforms: { uLayerLo: { value: 0 }, uLayerHi: { value: Math.max(0, u - 1) } }
317
+ }), V = new t.Mesh(v, B);
360
318
  V.frustumCulled = !1;
361
- const M = new t.BufferGeometry();
362
- M.setAttribute("position", new t.BufferAttribute(f, 3));
363
- const W = new t.LineBasicMaterial({ color: Pt.travel, transparent: !0, opacity: 0.6 }), g = new t.LineSegments(M, W);
364
- g.visible = !1, g.frustumCulled = !1;
365
- const C = (s, p) => {
366
- const A = Math.max(0, l - 1), S = Math.max(0, Math.min(s | 0, A)), I = Math.max(S, Math.min(p | 0, A));
367
- F.uniforms.uLayerLo.value = S, F.uniforms.uLayerHi.value = I;
368
- const T = u[S] * 2, z = u[I + 1] * 2;
369
- M.setDrawRange(T, Math.max(0, z - T));
319
+ const ot = Gt(m.vType, m.vLayer), T = xt.map((i) => {
320
+ const { source: a, layers: b } = Tt((y) => I[y], o, i, ot), w = a.length, x = new Float32Array(w * 3), N = new Float32Array(w * 3), p = new Float32Array(w * 2), P = new Float32Array(w), C = new Float32Array(w);
321
+ for (let y = 0; y < w; y++) {
322
+ const g = a[y], S = l[g * 2], G = (b[y] - 1) * S / 2;
323
+ x[y * 3] = s[g * 3], x[y * 3 + 1] = s[g * 3 + 1], x[y * 3 + 2] = s[g * 3 + 2] - G, N[y * 3] = f[g * 3], N[y * 3 + 1] = f[g * 3 + 1], N[y * 3 + 2] = f[g * 3 + 2] - G, p[y * 2] = S * b[y], p[y * 2 + 1] = l[g * 2 + 1], P[y] = L[g], C[y] = I[g];
324
+ }
325
+ const A = new t.InstancedBufferGeometry();
326
+ A.setAttribute("tpl", v.attributes.tpl), A.setIndex(v.index), A.setAttribute("iStart", new t.InstancedBufferAttribute(x, 3)), A.setAttribute("iEnd", new t.InstancedBufferAttribute(N, 3)), A.setAttribute("iHW", new t.InstancedBufferAttribute(p, 2));
327
+ const Q = new t.InstancedBufferAttribute(P, 1);
328
+ A.setAttribute("iColor", Q), A.setAttribute("iLayer", new t.InstancedBufferAttribute(C, 1)), A.instanceCount = w;
329
+ const O = new t.Mesh(A, B);
330
+ return O.frustumCulled = !1, O.visible = !1, V.add(O), { k: i, mesh: O, source: a, colors: P, colorAttr: Q };
331
+ });
332
+ let F = 1, _ = !0;
333
+ const j = (i) => {
334
+ if (i !== F) {
335
+ F = i;
336
+ for (const a of T) a.mesh.visible = a.k === i;
337
+ v.instanceCount = 0, i === 1 && (v.instanceCount = o);
338
+ }
339
+ }, nt = jt((i) => l[i * 2], o), J = e.bbox && new t.Box3(new t.Vector3(...e.bbox.min), new t.Vector3(...e.bbox.max)), Y = new t.Box3(), z = (i, a) => {
340
+ if (!_ || !J || !i?.isPerspectiveCamera) {
341
+ j(1);
342
+ return;
343
+ }
344
+ Y.copy(J).applyMatrix4(V.matrixWorld), j(Xt(Yt(nt, Y.distanceToPoint(i.position), i.fov, a)));
345
+ };
346
+ V.userData.updateLod = z;
347
+ const k = new t.BufferGeometry();
348
+ k.setAttribute("position", new t.BufferAttribute(h, 3));
349
+ const X = new t.LineBasicMaterial({ color: kt.travel, transparent: !0, opacity: 0.6 }), W = new t.LineSegments(k, X);
350
+ W.visible = !1, W.frustumCulled = !1;
351
+ const D = (i, a) => {
352
+ const b = Math.max(0, u - 1), w = Math.max(0, Math.min(i | 0, b)), x = Math.max(w, Math.min(a | 0, b));
353
+ B.uniforms.uLayerLo.value = w, B.uniforms.uLayerHi.value = x, _ = w === 0 && x === b, _ || j(1);
354
+ const N = d[w] * 2, p = d[x + 1] * 2;
355
+ k.setDrawRange(N, Math.max(0, p - N));
370
356
  };
371
- return C(0, l - 1), {
357
+ return D(0, u - 1), {
372
358
  mesh: V,
373
- travLines: g,
374
- setLayerRange: C,
375
- setVisibleLayers: (s) => C(0, (s | 0) - 1),
376
- setTravelVisible: (s) => {
377
- g.visible = !!s;
359
+ travLines: W,
360
+ setLayerRange: D,
361
+ setVisibleLayers: (i) => D(0, (i | 0) - 1),
362
+ setTravelVisible: (i) => {
363
+ W.visible = !!i;
378
364
  },
379
365
  /** color is Float32Array(nV*4) with the packed value in .r — computeColors' output shape. One instance
380
366
  * takes the colour of its first vertex; the two agree, since a segment is one colour. */
381
- setColors: (s) => {
382
- if (!(!s || s.length < r * 4)) {
383
- for (let p = 0; p < n; p++) b[p] = s[p * 2 * 4];
384
- _.needsUpdate = !0;
367
+ setColors: (i) => {
368
+ if (!(!i || i.length < n * 4)) {
369
+ for (let a = 0; a < o; a++) L[a] = i[a * 2 * 4];
370
+ q.needsUpdate = !0;
371
+ for (const a of T) {
372
+ for (let b = 0; b < a.source.length; b++) a.colors[b] = L[a.source[b]];
373
+ a.colorAttr.needsUpdate = !0;
374
+ }
385
375
  }
386
376
  },
377
+ /** Call once per frame before rendering; viewportPixels is the drawing buffer's height. */
378
+ updateLod: z,
379
+ lodLevel: () => F,
387
380
  dispose: () => {
388
- v.dispose(), F.dispose(), M.dispose(), W.dispose();
381
+ for (const i of T) i.mesh.geometry.dispose();
382
+ v.dispose(), B.dispose(), k.dispose(), X.dispose();
389
383
  },
390
- nSeg: n,
391
- layerCount: l
384
+ nSeg: o,
385
+ layerCount: u
392
386
  };
393
387
  }
394
388
  export {
395
- xt as DEFAULT_RANGES_COLORS,
396
- gt as TOOL_COLOR,
397
- O as TYPE_COLOR,
398
- Ot as TYPE_LABEL,
399
- Dt as VERTEX_DATA,
400
- At as VIEW_TYPES,
401
- Rt as buildSegmentData,
402
- qt as computeColors,
403
- Lt as hexToRgb,
404
- jt as layerMoveCount,
405
- $t as makeToolpath,
406
- Zt as moveCursor,
407
- ot as packColor,
408
- _t as rangeColorAt,
409
- Kt as roleRatios,
410
- Xt as topMoveLayer
389
+ Pt as DEFAULT_RANGES_COLORS,
390
+ wt as TOOL_COLOR,
391
+ Z as TYPE_COLOR,
392
+ It as TYPE_LABEL,
393
+ Zt as VERTEX_DATA,
394
+ Lt as VIEW_TYPES,
395
+ Ht as buildSegmentData,
396
+ oe as computeColors,
397
+ St as hexToRgb,
398
+ Et as layerMoveCount,
399
+ ne as makeToolpath,
400
+ ee as moveCursor,
401
+ at as packColor,
402
+ Nt as rangeColorAt,
403
+ Rt as roleRatios,
404
+ te as topMoveLayer
411
405
  };