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/VIEWER.md +26 -1
- package/dist/components.js +47 -43
- package/dist/gcode_parse.js +118 -72
- package/dist/index.js +4916 -4079
- package/dist/model_loaders-Dk9rqXFb.js +196 -0
- package/dist/model_loaders.js +9 -6
- package/dist/parse_3mf-CpbA-6Iq.js +666 -0
- package/dist/parse_3mf.worker.js +67 -5
- package/dist/toolpath.js +243 -249
- package/dist/toolpath_palette-B8xEl-qa.js +89 -0
- package/package.json +6 -1
- package/src/core/paint_tools.js +8 -0
- package/src/settings/kernel_setting_keys.js +28 -0
- package/src/settings/settings_core.js +55 -5
- package/types/gcode.d.ts +27 -1
- package/types/paint.d.ts +7 -0
- package/types/viewer.d.ts +4 -2
- package/dist/model_loaders-aHV5ix50.js +0 -188
- package/dist/parse_3mf-jEUAw8JM.js +0 -300
package/dist/toolpath.js
CHANGED
|
@@ -1,191 +1,113 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
88
|
-
const
|
|
89
|
-
e[
|
|
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
|
|
94
|
-
const e =
|
|
95
|
-
return e ? Math.floor(e.length /
|
|
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
|
|
98
|
-
const
|
|
99
|
-
let m = 0,
|
|
100
|
-
for (let
|
|
101
|
-
const
|
|
102
|
-
for (let
|
|
103
|
-
|
|
104
|
-
|
|
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
|
|
107
|
-
let
|
|
108
|
-
for (let
|
|
109
|
-
const
|
|
110
|
-
for (let
|
|
111
|
-
const
|
|
112
|
-
if (Number.isFinite(
|
|
113
|
-
const
|
|
114
|
-
|
|
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
|
|
118
|
-
Number.isFinite(vt) && (
|
|
119
|
-
const
|
|
120
|
-
for (const [
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
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
|
-
|
|
50
|
+
b++;
|
|
129
51
|
}
|
|
130
52
|
}
|
|
131
|
-
const
|
|
53
|
+
const N = l > 0 && Number.isFinite(z) ? { min: [z, k, X], max: [W, D, i] } : null;
|
|
132
54
|
return {
|
|
133
|
-
position:
|
|
134
|
-
hwa:
|
|
55
|
+
position: L,
|
|
56
|
+
hwa: I,
|
|
135
57
|
segIndex: v,
|
|
136
|
-
nV:
|
|
58
|
+
nV: l,
|
|
137
59
|
nSeg: m,
|
|
138
|
-
layerSegPrefix:
|
|
139
|
-
travelPos:
|
|
140
|
-
travelPrefix:
|
|
141
|
-
nTrav:
|
|
142
|
-
movePos:
|
|
143
|
-
moveKind:
|
|
144
|
-
movePrefix:
|
|
145
|
-
layerCount:
|
|
146
|
-
maxAbs:
|
|
147
|
-
hasNaN:
|
|
148
|
-
typeLengths:
|
|
149
|
-
bbox:
|
|
150
|
-
meta: { vType:
|
|
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
|
|
75
|
+
function Rt(t) {
|
|
154
76
|
const e = t ?? [];
|
|
155
|
-
let
|
|
156
|
-
for (let
|
|
157
|
-
if (
|
|
158
|
-
const
|
|
159
|
-
for (let
|
|
160
|
-
const
|
|
161
|
-
|
|
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
|
|
85
|
+
return n.sort((r, c) => c.pct - r.pct);
|
|
164
86
|
}
|
|
165
|
-
const
|
|
166
|
-
function
|
|
167
|
-
return
|
|
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
|
|
170
|
-
const
|
|
171
|
-
for (let
|
|
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
|
|
175
|
-
const
|
|
176
|
-
let
|
|
177
|
-
for (let m = 0; m <
|
|
178
|
-
t.moveKind[
|
|
179
|
-
if (
|
|
180
|
-
const
|
|
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[
|
|
183
|
-
segCount:
|
|
184
|
-
travCount:
|
|
185
|
-
onTravel: t.moveKind[
|
|
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
|
|
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
|
|
201
|
-
const
|
|
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[
|
|
126
|
+
return e.vHeight[o];
|
|
205
127
|
case "width":
|
|
206
|
-
return e.vWidth[
|
|
128
|
+
return e.vWidth[o];
|
|
207
129
|
case "speed":
|
|
208
|
-
return
|
|
130
|
+
return h ? n.firstLayerSpeed : n.speedByType[r] ?? n.speedByType[1];
|
|
209
131
|
case "fan":
|
|
210
|
-
return
|
|
132
|
+
return c < n.closeFanLayers ? 0 : r === 9 ? 100 : n.fanNormal;
|
|
211
133
|
case "temp":
|
|
212
|
-
return
|
|
134
|
+
return h ? n.tempFirst : n.tempNormal;
|
|
213
135
|
default:
|
|
214
136
|
return 0;
|
|
215
137
|
}
|
|
216
138
|
}
|
|
217
|
-
function
|
|
218
|
-
const { meta:
|
|
219
|
-
if (!
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
return
|
|
223
|
-
} : (
|
|
224
|
-
for (let
|
|
225
|
-
return { color:
|
|
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
|
|
228
|
-
const m = new Float32Array(
|
|
229
|
-
for (let
|
|
230
|
-
const
|
|
231
|
-
m[
|
|
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(
|
|
234
|
-
for (let
|
|
235
|
-
const
|
|
236
|
-
|
|
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:
|
|
160
|
+
return { color: c, min: d, max: u, viewType: e, label: h.label, unit: h.unit, cont: !0 };
|
|
239
161
|
}
|
|
240
|
-
const
|
|
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
|
-
`,
|
|
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
|
-
//
|
|
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
|
-
`,
|
|
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
|
-
]),
|
|
290
|
+
]), Zt = (() => {
|
|
336
291
|
const t = [];
|
|
337
292
|
for (let e = 0; e < 4; e++) {
|
|
338
|
-
const
|
|
339
|
-
t.push(n, r, o,
|
|
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
|
|
344
|
-
const { nSeg:
|
|
345
|
-
for (let
|
|
346
|
-
const
|
|
347
|
-
|
|
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(
|
|
351
|
-
const
|
|
352
|
-
v.setAttribute("iColor",
|
|
353
|
-
const
|
|
354
|
-
vertexShader:
|
|
355
|
-
fragmentShader:
|
|
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
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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
|
|
357
|
+
return D(0, u - 1), {
|
|
372
358
|
mesh: V,
|
|
373
|
-
travLines:
|
|
374
|
-
setLayerRange:
|
|
375
|
-
setVisibleLayers: (
|
|
376
|
-
setTravelVisible: (
|
|
377
|
-
|
|
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: (
|
|
382
|
-
if (!(!
|
|
383
|
-
for (let
|
|
384
|
-
|
|
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
|
-
|
|
381
|
+
for (const i of T) i.mesh.geometry.dispose();
|
|
382
|
+
v.dispose(), B.dispose(), k.dispose(), X.dispose();
|
|
389
383
|
},
|
|
390
|
-
nSeg:
|
|
391
|
-
layerCount:
|
|
384
|
+
nSeg: o,
|
|
385
|
+
layerCount: u
|
|
392
386
|
};
|
|
393
387
|
}
|
|
394
388
|
export {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
};
|