three-slicer 0.1.1 → 0.1.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/components/dist/SettingsPanel.js +112 -112
- package/components/styles.css +9 -9
- package/data/config-schema.json +999 -900
- package/data/invalidation-map.json +6 -5
- package/data/printers.json +1 -0
- package/data/processes.js +2 -0
- package/data/toggle-rules.json +44 -44
- package/data/ui-tree.json +170 -494
- package/engine/examples/headless.mjs +2 -2
- package/engine/index.js +2 -2
- package/engine/src/data.js +13 -7
- package/engine/src/settings.js +120 -35
- package/engine/src/slicer.worker.js +23 -21
- package/engine/src/slicer_core.js +0 -0
- package/engine/src/slicer_core.mt.js +0 -0
- package/engine/src/toggle_eval.js +11 -11
- package/package.json +4 -2
- package/types/components.d.ts +5 -5
- package/types/data/config-schema.json.d.ts +6 -6
- package/types/data/invalidation-map.json.d.ts +5 -5
- package/types/data/printers.json.d.ts +23 -0
- package/types/data/processes.js.d.ts +21 -0
- package/types/data/toggle-rules.json.d.ts +5 -5
- package/types/data/ui-tree.json.d.ts +3 -3
- package/types/data.d.ts +10 -7
- package/types/gen_settings_types.mjs +10 -10
- package/types/settings-keys.d.ts +18 -7
- package/types/settings.d.ts +6 -6
- package/types/toggle.d.ts +6 -6
- package/types/viewer-loaders.d.ts +8 -8
- package/types/viewer-toolpath.d.ts +17 -17
- package/types/viewer.d.ts +3 -3
- package/types/wasm.d.ts +3 -3
- package/types/worker.d.ts +2 -2
- package/viewer/dist/Viewport.js +1760 -966
- package/viewer/dist/make_worker.js +6 -6
- package/viewer/dist/model_loaders.js +35 -35
- package/viewer/dist/toolpath_gpu.js +146 -147
- package/viewer/styles.css +46 -25
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// npm
|
|
1
|
+
// Slicer worker factory — this file is not bundled; the build script copies it verbatim into dist/.
|
|
2
|
+
// Why: for consumer bundlers (Vite/webpack) to recognize the worker as a chunk, the static
|
|
3
|
+
// `new Worker(new URL('literal', import.meta.url))` pattern must survive in a file the consumer sees. If the viewer's own
|
|
4
|
+
// lib build handled it, the worker would be frozen into a site-root-absolute asset path and 404 in consumer apps.
|
|
5
|
+
// The '../../engine/…' path is relative to dist/: it resolves to the engine package both in the monorepo
|
|
6
|
+
// (packages/viewer/dist -> packages/engine) and in an npm install (sibling directory under the @three-slicer/ scope).
|
|
7
7
|
export function makeSlicerWorker() {
|
|
8
8
|
return new Worker(new URL('../../engine/src/slicer.worker.js', import.meta.url), { type: 'module' })
|
|
9
9
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { OBJLoader as
|
|
3
|
-
import { PLYLoader as
|
|
4
|
-
import { AMFLoader as
|
|
5
|
-
import { unzipSync as
|
|
1
|
+
import * as B from "three";
|
|
2
|
+
import { OBJLoader as C } from "three/examples/jsm/loaders/OBJLoader.js";
|
|
3
|
+
import { PLYLoader as N } from "three/examples/jsm/loaders/PLYLoader.js";
|
|
4
|
+
import { AMFLoader as V } from "three/examples/jsm/loaders/AMFLoader.js";
|
|
5
|
+
import { unzipSync as W } from "three/examples/jsm/libs/fflate.module.js";
|
|
6
6
|
const x = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0];
|
|
7
|
-
function
|
|
7
|
+
function X(t, e) {
|
|
8
8
|
const s = new Array(12);
|
|
9
9
|
for (let n = 0; n < 4; n++)
|
|
10
10
|
for (let o = 0; o < 3; o++)
|
|
@@ -22,7 +22,7 @@ function w(t, e) {
|
|
|
22
22
|
return n ? n[1] : null;
|
|
23
23
|
}
|
|
24
24
|
const z = /<vertex\s+x="([^"]*)"\s+y="([^"]*)"\s+z="([^"]*)"/g, I = /<triangle\s+v1="([^"]*)"\s+v2="([^"]*)"\s+v3="([^"]*)"/g;
|
|
25
|
-
function
|
|
25
|
+
function J(t) {
|
|
26
26
|
const e = [];
|
|
27
27
|
z.lastIndex = 0;
|
|
28
28
|
let s;
|
|
@@ -36,7 +36,7 @@ function Y(t) {
|
|
|
36
36
|
for (const o of t.match(/<triangle\b[^>]*>/g) || []) n.push(+w(o, "v1"), +w(o, "v2"), +w(o, "v3"));
|
|
37
37
|
return n.length ? { verts: e, tris: n } : null;
|
|
38
38
|
}
|
|
39
|
-
function
|
|
39
|
+
function Y(t) {
|
|
40
40
|
const e = /* @__PURE__ */ new Map(), s = /<object\b([^>]*)>([\s\S]*?)<\/object>/g;
|
|
41
41
|
let n;
|
|
42
42
|
for (; n = s.exec(t); ) {
|
|
@@ -47,7 +47,7 @@ function H(t) {
|
|
|
47
47
|
const h = w(d, "objectid");
|
|
48
48
|
h && p.push({ objectid: h, path: w(d, "p:path") || w(d, "path"), transform: R(w(d, "transform")) });
|
|
49
49
|
}
|
|
50
|
-
e.set(i, p.length ? { components: p } : { mesh:
|
|
50
|
+
e.set(i, p.length ? { components: p } : { mesh: J(c) });
|
|
51
51
|
}
|
|
52
52
|
const o = [], u = /<build\b[^>]*>([\s\S]*?)<\/build>/.exec(t);
|
|
53
53
|
if (u)
|
|
@@ -61,13 +61,13 @@ function L(t) {
|
|
|
61
61
|
const e = String(t).replace(/^\/+/, "");
|
|
62
62
|
return e.includes("%") ? decodeURIComponent(e) : e;
|
|
63
63
|
}
|
|
64
|
-
function
|
|
65
|
-
const s = ArrayBuffer.isView(t) ? new Uint8Array(t.buffer, t.byteOffset, t.byteLength) : new Uint8Array(t), n =
|
|
64
|
+
function H(t, e = "model") {
|
|
65
|
+
const s = ArrayBuffer.isView(t) ? new Uint8Array(t.buffer, t.byteOffset, t.byteLength) : new Uint8Array(t), n = W(s), o = /* @__PURE__ */ new Map();
|
|
66
66
|
for (const a of Object.keys(n)) o.set(L(a), n[a]);
|
|
67
67
|
const u = new TextDecoder(), i = /* @__PURE__ */ new Map(), c = (a) => {
|
|
68
68
|
const m = L(a);
|
|
69
69
|
if (i.has(m)) return i.get(m);
|
|
70
|
-
const l = o.get(m), M = l ?
|
|
70
|
+
const l = o.get(m), M = l ? Y(u.decode(l)) : null;
|
|
71
71
|
return i.set(m, M), M;
|
|
72
72
|
};
|
|
73
73
|
let p = "3D/3dmodel.model";
|
|
@@ -80,13 +80,13 @@ function Q(t, e = "model") {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
const h = c(p);
|
|
83
|
-
if (!h) throw new Error(`3MF
|
|
83
|
+
if (!h) throw new Error(`3MF root model not found: ${p}`);
|
|
84
84
|
const r = [], f = (a, m, l, M, $) => {
|
|
85
85
|
if ($ > 16) return;
|
|
86
86
|
const T = c(m), E = T == null ? void 0 : T.objects.get(a);
|
|
87
87
|
if (!E) return;
|
|
88
88
|
if (E.components) {
|
|
89
|
-
for (const y of E.components) f(y.objectid, y.path || m,
|
|
89
|
+
for (const y of E.components) f(y.objectid, y.path || m, X(y.transform, l), M, $ + 1);
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
92
|
if (!E.mesh) return;
|
|
@@ -105,16 +105,16 @@ function Q(t, e = "model") {
|
|
|
105
105
|
f(a.objectid, a.path || p, a.transform, l, 0), l.length >= 9 && r.push({ name: g.length > 1 ? `${e}#${m + 1}` : e, tris: new Float32Array(l) });
|
|
106
106
|
}), r;
|
|
107
107
|
}
|
|
108
|
-
const P = ["stl", "obj", "3mf", "amf", "ply"],
|
|
108
|
+
const P = ["stl", "obj", "3mf", "amf", "ply"], U = /* @__PURE__ */ new Map();
|
|
109
109
|
function et(t, e) {
|
|
110
110
|
for (const s of (Array.isArray(t) ? t : String(t).split(",")).map((n) => n.trim().toLowerCase()))
|
|
111
|
-
|
|
111
|
+
U.set(s, e), P.includes(s) || P.push(s);
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function Q(t) {
|
|
114
114
|
const e = t.lastIndexOf(".");
|
|
115
115
|
return e < 0 ? "" : t.slice(e + 1).toLowerCase();
|
|
116
116
|
}
|
|
117
|
-
function
|
|
117
|
+
function q(t) {
|
|
118
118
|
const e = new DataView(t);
|
|
119
119
|
if (t.byteLength >= 84) {
|
|
120
120
|
const i = e.getUint32(80, !0);
|
|
@@ -135,11 +135,11 @@ function G(t) {
|
|
|
135
135
|
for (; u = n.exec(s); ) o.push(+u[1], +u[2], +u[3]);
|
|
136
136
|
return o.length < 9 ? null : new Float32Array(o);
|
|
137
137
|
}
|
|
138
|
-
function
|
|
138
|
+
function _(t, e) {
|
|
139
139
|
var d;
|
|
140
140
|
const s = (d = t == null ? void 0 : t.attributes) == null ? void 0 : d.position;
|
|
141
141
|
if (!s || s.count < 3) return null;
|
|
142
|
-
const n = t.index, o = new
|
|
142
|
+
const n = t.index, o = new B.Vector3(), u = Math.floor((n ? n.count : s.count) / 3), i = new Float32Array(u * 9);
|
|
143
143
|
let c = 0;
|
|
144
144
|
const p = (h) => {
|
|
145
145
|
o.fromBufferAttribute(s, h), e && o.applyMatrix4(e), i[c++] = o.x, i[c++] = o.y, i[c++] = o.z;
|
|
@@ -158,7 +158,7 @@ function D(t) {
|
|
|
158
158
|
}), e;
|
|
159
159
|
}
|
|
160
160
|
function O(t, e, s) {
|
|
161
|
-
const n = e.map((c) =>
|
|
161
|
+
const n = e.map((c) => _(c.geometry, c.matrix)).filter(Boolean);
|
|
162
162
|
if (!n.length) return [];
|
|
163
163
|
if (s && n.length > 1)
|
|
164
164
|
return n.map((c, p) => ({ name: `${t}#${p + 1}`, modelPos: c }));
|
|
@@ -172,37 +172,37 @@ function O(t, e, s) {
|
|
|
172
172
|
return [{ name: t, modelPos: u }];
|
|
173
173
|
}
|
|
174
174
|
async function nt(t, e) {
|
|
175
|
-
const s =
|
|
175
|
+
const s = Q(t);
|
|
176
176
|
switch (s) {
|
|
177
177
|
case "stl": {
|
|
178
|
-
const n =
|
|
179
|
-
if (!n) throw new Error("
|
|
178
|
+
const n = q(e);
|
|
179
|
+
if (!n) throw new Error("Failed to parse STL");
|
|
180
180
|
return [{ name: t, modelPos: n }];
|
|
181
181
|
}
|
|
182
182
|
case "obj": {
|
|
183
|
-
const n = new
|
|
183
|
+
const n = new C().parse(new TextDecoder().decode(e));
|
|
184
184
|
return O(t, D(n), !1);
|
|
185
185
|
}
|
|
186
186
|
case "ply": {
|
|
187
|
-
const n = new
|
|
188
|
-
if (!o) throw new Error("PLY
|
|
187
|
+
const n = new N().parse(e), o = _(n, null);
|
|
188
|
+
if (!o) throw new Error("No PLY geometry");
|
|
189
189
|
return [{ name: t, modelPos: o }];
|
|
190
190
|
}
|
|
191
191
|
case "3mf": {
|
|
192
|
-
const n =
|
|
193
|
-
if (!n.length) throw new Error("
|
|
192
|
+
const n = H(e, t).map((o) => ({ name: o.name, modelPos: o.tris }));
|
|
193
|
+
if (!n.length) throw new Error("No mesh in 3MF");
|
|
194
194
|
return n;
|
|
195
195
|
}
|
|
196
196
|
case "amf": {
|
|
197
|
-
const n = new
|
|
198
|
-
if (!o.length) throw new Error("
|
|
197
|
+
const n = new V().parse(e), o = O(t, D(n), !0);
|
|
198
|
+
if (!o.length) throw new Error("No mesh in AMF");
|
|
199
199
|
return o;
|
|
200
200
|
}
|
|
201
201
|
default: {
|
|
202
|
-
const n =
|
|
203
|
-
if (!n) throw new Error(
|
|
202
|
+
const n = U.get(s);
|
|
203
|
+
if (!n) throw new Error(`Unsupported format: .${s}`);
|
|
204
204
|
const o = await n(e, t);
|
|
205
|
-
if (!(o != null && o.length)) throw new Error(
|
|
205
|
+
if (!(o != null && o.length)) throw new Error(`No mesh in .${s}`);
|
|
206
206
|
return o;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
@@ -249,7 +249,7 @@ function ot(t) {
|
|
|
249
249
|
}
|
|
250
250
|
export {
|
|
251
251
|
P as SUPPORTED_EXT,
|
|
252
|
-
|
|
252
|
+
Q as fileExt,
|
|
253
253
|
nt as loadModel,
|
|
254
254
|
et as registerLoader,
|
|
255
255
|
ot as splitConnectedComponents
|
|
@@ -1,33 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
0,
|
|
3
|
-
1,
|
|
4
|
-
2,
|
|
5
|
-
0,
|
|
6
|
-
2,
|
|
7
|
-
3,
|
|
8
|
-
// front spike
|
|
9
|
-
0,
|
|
10
|
-
3,
|
|
11
|
-
4,
|
|
12
|
-
0,
|
|
13
|
-
4,
|
|
14
|
-
5,
|
|
15
|
-
// right/bottom body
|
|
16
|
-
0,
|
|
17
|
-
5,
|
|
18
|
-
6,
|
|
19
|
-
0,
|
|
20
|
-
6,
|
|
21
|
-
1,
|
|
22
|
-
// left/top body
|
|
23
|
-
5,
|
|
24
|
-
4,
|
|
25
|
-
7,
|
|
26
|
-
5,
|
|
27
|
-
7,
|
|
28
|
-
6
|
|
29
|
-
// back spike
|
|
30
|
-
], U = {
|
|
1
|
+
const U = {
|
|
31
2
|
0: [0.42, 0.45, 0.5],
|
|
32
3
|
1: [0.85, 0.51, 0.17],
|
|
33
4
|
2: [0.21, 0.45, 0.76],
|
|
@@ -45,42 +16,61 @@ function ie(t) {
|
|
|
45
16
|
const i = Math.round(t[0] * 255), s = Math.round(t[1] * 255), n = Math.round(t[2] * 255);
|
|
46
17
|
return i << 16 | s << 8 | n;
|
|
47
18
|
}
|
|
48
|
-
|
|
19
|
+
const le = { 1: "Wall", 2: "Sparse", 3: "Solid", 4: "Skirt", 5: "Support", 6: "Raft", 7: "Gap fill", 8: "Thin wall", 9: "Bridge", 10: "Ironing", 11: "Prime" }, _e = [
|
|
20
|
+
[11, 44, 122],
|
|
21
|
+
[19, 89, 133],
|
|
22
|
+
[28, 136, 145],
|
|
23
|
+
[4, 214, 15],
|
|
24
|
+
[170, 242, 0],
|
|
25
|
+
[252, 249, 3],
|
|
26
|
+
[245, 206, 10],
|
|
27
|
+
[227, 136, 32],
|
|
28
|
+
[209, 104, 48],
|
|
29
|
+
[194, 82, 60],
|
|
30
|
+
[148, 38, 22]
|
|
31
|
+
].map((t) => [t[0] / 255, t[1] / 255, t[2] / 255]);
|
|
32
|
+
function ce(t, i, s, n) {
|
|
33
|
+
const l = n.length;
|
|
34
|
+
if (!(s > i)) return n[0];
|
|
35
|
+
const a = (s - i) / (l - 1), h = (t - i) / a, _ = Math.max(0, Math.min(l - 1, Math.floor(h))), y = Math.max(0, Math.min(l - 1, _ + 1)), v = h - _, r = n[_], x = n[y];
|
|
36
|
+
return [r[0] + (x[0] - r[0]) * v, r[1] + (x[1] - r[1]) * v, r[2] + (x[2] - r[2]) * v];
|
|
37
|
+
}
|
|
38
|
+
function pe(t, i) {
|
|
49
39
|
const s = t.length, n = i > 0 ? i : 0.42, l = new Array(s);
|
|
50
40
|
for (let e = 0; e < s; e++) {
|
|
51
41
|
const o = t[e].z;
|
|
52
42
|
l[e] = Math.max(0.02, e === 0 ? o : o - t[e - 1].z);
|
|
53
43
|
}
|
|
54
|
-
const a = [], h = [], _ = [], y = [], v = [], r = [], x = [], b = [], A = [], M = [], L = new Float64Array(16), P = [],
|
|
44
|
+
const a = [], h = [], _ = [], y = [], v = [], r = [], x = [], b = [], A = [], M = [], L = new Float64Array(16), P = [], D = [];
|
|
55
45
|
let W = -1, $ = 0, R = 0, H = 0, E = -1, c = 0;
|
|
56
|
-
const d = 1e-4,
|
|
46
|
+
const d = 1e-4, p = (e, o, g, m, u, w) => (a.push(e), h.push(o), _.push(g), r.push(m), y.push(u), v.push(w), x.push(c), b.push(!1), a.length - 1);
|
|
57
47
|
for (let e = 0; e < s; e++) {
|
|
58
48
|
const o = t[e].paths, g = t[e].widths, m = l[e];
|
|
59
49
|
if (c = e, !!o)
|
|
60
|
-
for (let
|
|
61
|
-
const w = o[
|
|
50
|
+
for (let u = 0; u < o.length; u += 8) {
|
|
51
|
+
const w = o[u + 3], F = o[u], S = o[u + 1], G = o[u + 2], I = o[u + 4], V = o[u + 5], B = o[u + 6];
|
|
62
52
|
if (w === 0) {
|
|
63
|
-
P.push(F,
|
|
53
|
+
P.push(F, S, G, I, V, B), D.push(e);
|
|
64
54
|
continue;
|
|
65
55
|
}
|
|
66
|
-
const O = g && g[
|
|
67
|
-
w < 16 && (L[w] += Math.hypot(
|
|
68
|
-
let
|
|
69
|
-
W >= 0 && E === w && Math.abs($ - F) < d && Math.abs(R -
|
|
56
|
+
const O = g && g[u / 8] > 0 ? g[u / 8] : n;
|
|
57
|
+
w < 16 && (L[w] += Math.hypot(I - F, V - S));
|
|
58
|
+
let k;
|
|
59
|
+
W >= 0 && E === w && Math.abs($ - F) < d && Math.abs(R - S) < d && Math.abs(H - G) < d ? (k = W, p(I, V, B, w, m, O)) : (k = p(F, S, G, w, m, O), p(I, V, B, w, m, O)), b[k] = !0, W = k + 1, $ = I, R = V, H = B, E = w, A.push(k), M.push(e);
|
|
70
60
|
}
|
|
71
61
|
}
|
|
72
62
|
const f = a.length, C = A.length, z = new Float32Array(f * 4), Y = new Float32Array(f * 4);
|
|
73
|
-
let ee = 0, ne = !1,
|
|
63
|
+
let ee = 0, ne = !1, T = 1 / 0, j = 1 / 0, X = 1 / 0, Z = -1 / 0, q = -1 / 0, J = -1 / 0;
|
|
74
64
|
for (let e = 0; e < f; e++) {
|
|
75
|
-
const o = y[e], g = a[e], m = h[e],
|
|
76
|
-
z[e * 4] = g, z[e * 4 + 1] = m, z[e * 4 + 2] =
|
|
65
|
+
const o = y[e], g = a[e], m = h[e], u = _[e] - 0.5 * o;
|
|
66
|
+
z[e * 4] = g, z[e * 4 + 1] = m, z[e * 4 + 2] = u;
|
|
77
67
|
const w = e > 0 && b[e - 1], F = b[e];
|
|
78
|
-
let
|
|
68
|
+
let S = 0;
|
|
79
69
|
if (w || F) {
|
|
80
|
-
const G = w ? a[e] - a[e - 1] : 0,
|
|
81
|
-
|
|
70
|
+
const G = w ? a[e] - a[e - 1] : 0, I = w ? h[e] - h[e - 1] : 0, V = w ? _[e] - _[e - 1] : 0, B = F ? a[e + 1] - a[e] : 0, O = F ? h[e + 1] - h[e] : 0, k = F ? _[e + 1] - _[e] : 0;
|
|
71
|
+
S = Math.atan2(G * O - I * B, G * B + I * O + V * k);
|
|
82
72
|
}
|
|
83
|
-
Y[e * 4] = o, Y[e * 4 + 1] = v[e], Y[e * 4 + 2] =
|
|
73
|
+
Y[e * 4] = o, Y[e * 4 + 1] = v[e], Y[e * 4 + 2] = S, Y[e * 4 + 3] = ie(U[r[e]] || U[1]), (!Number.isFinite(g) || !Number.isFinite(m) || !Number.isFinite(u) || !Number.isFinite(S)) && (ne = !0), ee = Math.max(ee, Math.abs(g), Math.abs(m), Math.abs(u)), g < T && (T = g), g > Z && (Z = g), m < j && (j = m), m > q && (q = m), u < X && (X = u), u > J && (J = u);
|
|
84
74
|
}
|
|
85
75
|
const te = new Uint32Array(C * 4);
|
|
86
76
|
for (let e = 0; e < C; e++)
|
|
@@ -96,24 +86,23 @@ function ue(t, i) {
|
|
|
96
86
|
oe[o + 1] = e;
|
|
97
87
|
}
|
|
98
88
|
}
|
|
99
|
-
const Q =
|
|
89
|
+
const Q = D.length, N = new Float32Array(Q * 6);
|
|
100
90
|
for (let e = 0; e < N.length; e++) N[e] = P[e];
|
|
101
91
|
for (let e = 0; e < N.length; e += 3) {
|
|
102
92
|
const o = N[e], g = N[e + 1], m = N[e + 2];
|
|
103
|
-
o <
|
|
93
|
+
o < T && (T = o), o > Z && (Z = o), g < j && (j = g), g > q && (q = g), m < X && (X = m), m > J && (J = m);
|
|
104
94
|
}
|
|
105
95
|
const re = new Int32Array(s + 1);
|
|
106
96
|
{
|
|
107
97
|
let e = 0;
|
|
108
98
|
for (let o = 0; o < s; o++) {
|
|
109
|
-
for (; e < Q &&
|
|
99
|
+
for (; e < Q && D[e] === o; ) e++;
|
|
110
100
|
re[o + 1] = e;
|
|
111
101
|
}
|
|
112
102
|
}
|
|
113
|
-
const se = f + Q > 0 ? { min: [
|
|
103
|
+
const se = f + Q > 0 ? { min: [T, j, X], max: [Z, q, J] } : null;
|
|
114
104
|
return { position: z, hwa: Y, segIndex: te, nV: f, nSeg: C, layerSegPrefix: oe, travelPos: N, travelPrefix: re, nTrav: Q, layerCount: s, maxAbs: ee, hasNaN: ne, meta: K, typeLengths: L, bbox: se };
|
|
115
105
|
}
|
|
116
|
-
const _e = { 1: "벽", 2: "스파스", 3: "솔리드", 4: "스커트", 5: "서포트", 6: "래프트", 7: "갭필", 8: "씬월", 9: "브리지", 10: "아이어닝", 11: "프라임" };
|
|
117
106
|
function ve(t) {
|
|
118
107
|
let i = 0;
|
|
119
108
|
for (let n = 1; n < 16; n++) i += t[n] || 0;
|
|
@@ -121,74 +110,11 @@ function ve(t) {
|
|
|
121
110
|
if (i <= 0) return s;
|
|
122
111
|
for (let n = 1; n < 16; n++) {
|
|
123
112
|
const l = t[n] || 0;
|
|
124
|
-
l > 0 && s.push({ type: n, label:
|
|
113
|
+
l > 0 && s.push({ type: n, label: le[n] || "t" + n, pct: 100 * l / i, color: U[n] || U[1] });
|
|
125
114
|
}
|
|
126
115
|
return s.sort((n, l) => l.pct - n.pct);
|
|
127
116
|
}
|
|
128
|
-
const
|
|
129
|
-
[11, 44, 122],
|
|
130
|
-
[19, 89, 133],
|
|
131
|
-
[28, 136, 145],
|
|
132
|
-
[4, 214, 15],
|
|
133
|
-
[170, 242, 0],
|
|
134
|
-
[252, 249, 3],
|
|
135
|
-
[245, 206, 10],
|
|
136
|
-
[227, 136, 32],
|
|
137
|
-
[209, 104, 48],
|
|
138
|
-
[194, 82, 60],
|
|
139
|
-
[148, 38, 22]
|
|
140
|
-
].map((t) => [t[0] / 255, t[1] / 255, t[2] / 255]);
|
|
141
|
-
function he(t, i, s, n) {
|
|
142
|
-
const l = n.length;
|
|
143
|
-
if (!(s > i)) return n[0];
|
|
144
|
-
const a = (s - i) / (l - 1), h = (t - i) / a, _ = Math.max(0, Math.min(l - 1, Math.floor(h))), y = Math.max(0, Math.min(l - 1, _ + 1)), v = h - _, r = n[_], x = n[y];
|
|
145
|
-
return [r[0] + (x[0] - r[0]) * v, r[1] + (x[1] - r[1]) * v, r[2] + (x[2] - r[2]) * v];
|
|
146
|
-
}
|
|
147
|
-
const ae = [
|
|
148
|
-
{ key: "feature", label: "Feature type", cont: !1, unit: "" },
|
|
149
|
-
{ key: "speed", label: "Speed", cont: !0, unit: "mm/s" },
|
|
150
|
-
{ key: "height", label: "Layer Height", cont: !0, unit: "mm" },
|
|
151
|
-
{ key: "width", label: "Line Width", cont: !0, unit: "mm" },
|
|
152
|
-
{ key: "fan", label: "Fan Speed", cont: !0, unit: "%" },
|
|
153
|
-
{ key: "temp", label: "Temperature", cont: !0, unit: "°C" }
|
|
154
|
-
];
|
|
155
|
-
function de(t, i, s, n) {
|
|
156
|
-
const l = i.vType[s], a = i.vLayer[s], h = a === 0;
|
|
157
|
-
switch (t) {
|
|
158
|
-
case "height":
|
|
159
|
-
return i.vHeight[s];
|
|
160
|
-
case "width":
|
|
161
|
-
return i.vWidth[s];
|
|
162
|
-
case "speed":
|
|
163
|
-
return h ? n.firstLayerSpeed : n.speedByType[l] ?? n.speedByType[1];
|
|
164
|
-
case "fan":
|
|
165
|
-
return a < n.closeFanLayers ? 0 : l === 9 ? 100 : n.fanNormal;
|
|
166
|
-
case "temp":
|
|
167
|
-
return h ? n.tempFirst : n.tempNormal;
|
|
168
|
-
default:
|
|
169
|
-
return 0;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
function ge(t, i, s) {
|
|
173
|
-
const { meta: n, nV: l } = t, a = new Float32Array(l * 4), h = ae.find((r) => r.key === i) || ae[0];
|
|
174
|
-
if (!h.cont) {
|
|
175
|
-
for (let r = 0; r < l; r++) a[r * 4] = ie(U[n.vType[r]] || U[1]);
|
|
176
|
-
return { color: a, min: 0, max: 0, viewType: i, label: h.label, unit: h.unit, cont: !1 };
|
|
177
|
-
}
|
|
178
|
-
let _ = 1 / 0, y = -1 / 0;
|
|
179
|
-
const v = new Float32Array(l);
|
|
180
|
-
for (let r = 0; r < l; r++) {
|
|
181
|
-
const x = de(i, n, r, s);
|
|
182
|
-
v[r] = x, x < _ && (_ = x), x > y && (y = x);
|
|
183
|
-
}
|
|
184
|
-
Number.isFinite(_) || (_ = 0, y = 1);
|
|
185
|
-
for (let r = 0; r < l; r++) {
|
|
186
|
-
const x = he(v[r], _, y, ce);
|
|
187
|
-
a[r * 4] = ie(x);
|
|
188
|
-
}
|
|
189
|
-
return { color: a, min: _, max: y, viewType: i, label: h.label, unit: h.unit, cont: !0 };
|
|
190
|
-
}
|
|
191
|
-
const fe = `
|
|
117
|
+
const he = `
|
|
192
118
|
precision highp float;
|
|
193
119
|
precision highp int;
|
|
194
120
|
precision highp sampler2D;
|
|
@@ -209,11 +135,11 @@ uniform mat4 projection_matrix;
|
|
|
209
135
|
uniform vec3 camera_position;
|
|
210
136
|
uniform sampler2D position_tex;
|
|
211
137
|
uniform sampler2D height_width_angle_tex;
|
|
212
|
-
uniform int layer_lo; // 25
|
|
213
|
-
uniform int layer_hi; //
|
|
138
|
+
uniform int layer_lo; // stage 25: dual slider lower bound (layer). The shader clips out-of-range segments in O(1).
|
|
139
|
+
uniform int layer_hi; // the upper bound is cut via instanceCount (sorted by layer).
|
|
214
140
|
in float vertex_id_float;
|
|
215
|
-
in uint seg_id_a_u; //
|
|
216
|
-
in uint seg_layer_u; //
|
|
141
|
+
in uint seg_id_a_u; // instance attribute (formerly segment_index_tex.r) — attribute fetch is cheaper than texelFetch
|
|
142
|
+
in uint seg_layer_u; // instance attribute (formerly segment_index_tex.g)
|
|
217
143
|
out vec3 color;
|
|
218
144
|
vec3 decode_color(float col) {
|
|
219
145
|
int c = int(round(col));
|
|
@@ -236,7 +162,7 @@ ivec2 tex_coord(sampler2D sampler, int id) {
|
|
|
236
162
|
void main() {
|
|
237
163
|
int vertex_id = int(vertex_id_float);
|
|
238
164
|
int seg_layer = int(seg_layer_u);
|
|
239
|
-
if (seg_layer < layer_lo || seg_layer > layer_hi) { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; } //
|
|
165
|
+
if (seg_layer < layer_lo || seg_layer > layer_hi) { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; } // out of range -> clip
|
|
240
166
|
int id_a = int(seg_id_a_u);
|
|
241
167
|
int id_b = id_a + 1;
|
|
242
168
|
vec3 pos_a = texelFetch(position_tex, tex_coord(position_tex, id_a), 0).xyz;
|
|
@@ -308,22 +234,51 @@ void main() {
|
|
|
308
234
|
color = color_base * lighting(eye_position, eye_normal);
|
|
309
235
|
gl_Position = projection_matrix * vec4(eye_position, 1.0);
|
|
310
236
|
}
|
|
311
|
-
`,
|
|
237
|
+
`, de = `
|
|
312
238
|
precision highp float;
|
|
313
239
|
in vec3 color;
|
|
314
240
|
out vec4 fragment_color;
|
|
315
241
|
void main() {
|
|
316
242
|
fragment_color = vec4(color, 1.0);
|
|
317
243
|
}
|
|
318
|
-
|
|
319
|
-
|
|
244
|
+
`, fe = [
|
|
245
|
+
0,
|
|
246
|
+
1,
|
|
247
|
+
2,
|
|
248
|
+
0,
|
|
249
|
+
2,
|
|
250
|
+
3,
|
|
251
|
+
// front spike
|
|
252
|
+
0,
|
|
253
|
+
3,
|
|
254
|
+
4,
|
|
255
|
+
0,
|
|
256
|
+
4,
|
|
257
|
+
5,
|
|
258
|
+
// right/bottom body
|
|
259
|
+
0,
|
|
260
|
+
5,
|
|
261
|
+
6,
|
|
262
|
+
0,
|
|
263
|
+
6,
|
|
264
|
+
1,
|
|
265
|
+
// left/top body
|
|
266
|
+
5,
|
|
267
|
+
4,
|
|
268
|
+
7,
|
|
269
|
+
5,
|
|
270
|
+
7,
|
|
271
|
+
6
|
|
272
|
+
// back spike
|
|
273
|
+
];
|
|
274
|
+
function ge(t, i) {
|
|
320
275
|
const s = (c, d) => {
|
|
321
|
-
const
|
|
322
|
-
C.set(c.subarray(0, Math.min(c.length,
|
|
323
|
-
const z = new t.DataTexture(C,
|
|
276
|
+
const p = Math.min(2048, Math.max(1, d)), f = Math.max(1, Math.ceil(d / p)), C = new Float32Array(p * f * 4);
|
|
277
|
+
C.set(c.subarray(0, Math.min(c.length, p * f * 4)));
|
|
278
|
+
const z = new t.DataTexture(C, p, f, t.RGBAFormat, t.FloatType);
|
|
324
279
|
return z.minFilter = z.magFilter = t.NearestFilter, z.generateMipmaps = !1, z.needsUpdate = !0, z;
|
|
325
280
|
}, n = s(i.position, i.nV), l = s(i.hwa, i.nV), a = new t.InstancedBufferGeometry();
|
|
326
|
-
a.setIndex(
|
|
281
|
+
a.setIndex(fe), a.setAttribute("position", new t.BufferAttribute(new Float32Array(8 * 3), 3)), a.setAttribute("vertex_id_float", new t.BufferAttribute(new Float32Array([0, 1, 2, 3, 4, 5, 6, 7]), 1));
|
|
327
282
|
const h = new t.InstancedInterleavedBuffer(i.segIndex, 4);
|
|
328
283
|
a.setAttribute("seg_id_a_u", new t.InterleavedBufferAttribute(h, 1, 0)), a.setAttribute("seg_layer_u", new t.InterleavedBufferAttribute(h, 1, 1)), a.instanceCount = 0;
|
|
329
284
|
const _ = new t.RawShaderMaterial({
|
|
@@ -337,50 +292,94 @@ function me(t, i) {
|
|
|
337
292
|
layer_lo: { value: 0 },
|
|
338
293
|
layer_hi: { value: i.layerCount }
|
|
339
294
|
},
|
|
340
|
-
vertexShader:
|
|
341
|
-
fragmentShader:
|
|
295
|
+
vertexShader: he,
|
|
296
|
+
fragmentShader: de,
|
|
342
297
|
side: t.DoubleSide
|
|
343
298
|
}), y = new t.Mesh(a, _);
|
|
344
299
|
let v = null;
|
|
345
300
|
if (i.bbox) {
|
|
346
|
-
const { min: c, max: d } = i.bbox,
|
|
347
|
-
v = new t.Sphere(
|
|
301
|
+
const { min: c, max: d } = i.bbox, p = new t.Vector3((c[0] + d[0]) / 2, (c[1] + d[1]) / 2, (c[2] + d[2]) / 2), f = Math.hypot(d[0] - c[0], d[1] - c[1], d[2] - c[2]) / 2 + 2;
|
|
302
|
+
v = new t.Sphere(p, f);
|
|
348
303
|
}
|
|
349
304
|
y.frustumCulled = !!v, v && (a.boundingSphere = v);
|
|
350
305
|
const r = new t.Matrix4(), x = new t.Vector3();
|
|
351
|
-
y.onBeforeRender = (c, d,
|
|
352
|
-
_.uniforms.projection_matrix.value.copy(
|
|
306
|
+
y.onBeforeRender = (c, d, p) => {
|
|
307
|
+
_.uniforms.projection_matrix.value.copy(p.projectionMatrix), _.uniforms.view_matrix.value.multiplyMatrices(p.matrixWorldInverse, y.matrixWorld), r.copy(y.matrixWorld).invert(), p.getWorldPosition(x).applyMatrix4(r), _.uniforms.camera_position.value.copy(x);
|
|
353
308
|
};
|
|
354
309
|
const b = new t.BufferGeometry();
|
|
355
310
|
b.setAttribute("position", new t.BufferAttribute(i.travelPos, 3)), b.setDrawRange(0, 0);
|
|
356
311
|
const A = new t.LineSegments(b, new t.LineBasicMaterial({ color: 7041658 }));
|
|
357
312
|
A.frustumCulled = !!v, A.visible = !1, v && (b.boundingSphere = v);
|
|
358
313
|
let M = !1, L = 0, P = i.layerCount - 1;
|
|
359
|
-
const
|
|
314
|
+
const D = () => {
|
|
360
315
|
const c = i.travelPrefix[L], d = i.travelPrefix[P + 1];
|
|
361
316
|
b.setDrawRange(M ? c * 2 : 0, M ? (d - c) * 2 : 0);
|
|
362
317
|
}, W = (c, d) => {
|
|
363
|
-
const
|
|
364
|
-
L = Math.max(0, Math.min(
|
|
318
|
+
const p = i.layerCount;
|
|
319
|
+
L = Math.max(0, Math.min(p - 1, c | 0)), P = Math.max(L, Math.min(p - 1, d | 0)), _.uniforms.layer_lo.value = L, _.uniforms.layer_hi.value = P, a.instanceCount = i.layerSegPrefix[P + 1], D();
|
|
365
320
|
};
|
|
366
321
|
return { mesh: y, travLines: A, setVisibleLayers: (c) => W(0, (c | 0) - 1), setLayerRange: W, setTravelVisible: (c) => {
|
|
367
|
-
M = !!c, A.visible = M,
|
|
322
|
+
M = !!c, A.visible = M, D();
|
|
368
323
|
}, setColors: (c) => {
|
|
369
|
-
const d = l.image.data,
|
|
370
|
-
for (let f = 0; f <
|
|
324
|
+
const d = l.image.data, p = Math.min(c.length, d.length) / 4;
|
|
325
|
+
for (let f = 0; f < p; f++) d[f * 4 + 3] = c[f * 4];
|
|
371
326
|
l.needsUpdate = !0;
|
|
372
327
|
}, dispose: () => {
|
|
373
328
|
a.dispose(), _.dispose(), n.dispose(), l.dispose(), b.dispose(), A.material.dispose();
|
|
374
329
|
}, nSeg: i.nSeg, layerCount: i.layerCount };
|
|
375
330
|
}
|
|
331
|
+
const ae = [
|
|
332
|
+
{ key: "feature", label: "Feature type", cont: !1, unit: "" },
|
|
333
|
+
{ key: "speed", label: "Speed", cont: !0, unit: "mm/s" },
|
|
334
|
+
{ key: "height", label: "Layer Height", cont: !0, unit: "mm" },
|
|
335
|
+
{ key: "width", label: "Line Width", cont: !0, unit: "mm" },
|
|
336
|
+
{ key: "fan", label: "Fan Speed", cont: !0, unit: "%" },
|
|
337
|
+
{ key: "temp", label: "Temperature", cont: !0, unit: "°C" }
|
|
338
|
+
];
|
|
339
|
+
function ue(t, i, s, n) {
|
|
340
|
+
const l = i.vType[s], a = i.vLayer[s], h = a === 0;
|
|
341
|
+
switch (t) {
|
|
342
|
+
case "height":
|
|
343
|
+
return i.vHeight[s];
|
|
344
|
+
case "width":
|
|
345
|
+
return i.vWidth[s];
|
|
346
|
+
case "speed":
|
|
347
|
+
return h ? n.firstLayerSpeed : n.speedByType[l] ?? n.speedByType[1];
|
|
348
|
+
case "fan":
|
|
349
|
+
return a < n.closeFanLayers ? 0 : l === 9 ? 100 : n.fanNormal;
|
|
350
|
+
case "temp":
|
|
351
|
+
return h ? n.tempFirst : n.tempNormal;
|
|
352
|
+
default:
|
|
353
|
+
return 0;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function me(t, i, s) {
|
|
357
|
+
const { meta: n, nV: l } = t, a = new Float32Array(l * 4), h = ae.find((r) => r.key === i) || ae[0];
|
|
358
|
+
if (!h.cont) {
|
|
359
|
+
for (let r = 0; r < l; r++) a[r * 4] = ie(U[n.vType[r]] || U[1]);
|
|
360
|
+
return { color: a, min: 0, max: 0, viewType: i, label: h.label, unit: h.unit, cont: !1 };
|
|
361
|
+
}
|
|
362
|
+
let _ = 1 / 0, y = -1 / 0;
|
|
363
|
+
const v = new Float32Array(l);
|
|
364
|
+
for (let r = 0; r < l; r++) {
|
|
365
|
+
const x = ue(i, n, r, s);
|
|
366
|
+
v[r] = x, x < _ && (_ = x), x > y && (y = x);
|
|
367
|
+
}
|
|
368
|
+
Number.isFinite(_) || (_ = 0, y = 1);
|
|
369
|
+
for (let r = 0; r < l; r++) {
|
|
370
|
+
const x = ce(v[r], _, y, _e);
|
|
371
|
+
a[r * 4] = ie(x);
|
|
372
|
+
}
|
|
373
|
+
return { color: a, min: _, max: y, viewType: i, label: h.label, unit: h.unit, cont: !0 };
|
|
374
|
+
}
|
|
376
375
|
export {
|
|
377
|
-
|
|
376
|
+
_e as DEFAULT_RANGES_COLORS,
|
|
378
377
|
U as TYPE_COLOR,
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
le as TYPE_LABEL,
|
|
379
|
+
fe as VERTEX_DATA,
|
|
381
380
|
ae as VIEW_TYPES,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
381
|
+
pe as buildSegmentData,
|
|
382
|
+
me as computeColors,
|
|
383
|
+
ge as makeToolpath,
|
|
385
384
|
ve as roleRatios
|
|
386
385
|
};
|