three-slicer 0.1.3 → 0.1.5
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/README.md +67 -8
- package/components/README.md +1 -1
- package/components/dist/SettingsPanel.js +12 -12
- package/data/README.md +39 -2
- package/data/config-schema.json +164 -0
- package/data/filaments.js +2 -0
- package/data/processes.js +1 -1
- package/data/ui-tree.json +21 -2
- package/engine/README.md +56 -4
- package/engine/src/data.js +2 -0
- package/engine/src/settings.js +214 -6
- package/engine/src/slicer.worker.js +154 -5
- package/engine/src/slicer_core.js +0 -0
- package/engine/src/slicer_core.mt.js +0 -0
- package/package.json +15 -2
- package/types/data/filaments.js.d.ts +27 -0
- package/types/data.d.ts +7 -0
- package/types/settings-keys.d.ts +35 -1
- package/types/settings.d.ts +42 -0
- package/types/viewer-gcode.d.ts +29 -0
- package/types/viewer-toolpath.d.ts +9 -1
- package/types/viewer.d.ts +53 -0
- package/viewer/README.md +48 -2
- package/viewer/dist/Viewport.js +2706 -1525
- package/viewer/dist/gcode_parse.js +190 -0
- package/viewer/dist/make_worker.js +7 -0
- package/viewer/dist/model_loaders.js +139 -211
- package/viewer/dist/parse_3mf-8oCnCJNK.js +216 -0
- package/viewer/dist/parse_3mf.worker.js +10 -0
- package/viewer/dist/toolpath_gpu.js +162 -137
- package/viewer/styles.css +56 -2
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { unzip as U, unzipSync as N } from "three/examples/jsm/libs/fflate.module.js";
|
|
2
|
+
function X(n) {
|
|
3
|
+
return new Promise((e) => {
|
|
4
|
+
let o = !1;
|
|
5
|
+
const t = (s) => {
|
|
6
|
+
o || (o = !0, e(s));
|
|
7
|
+
};
|
|
8
|
+
try {
|
|
9
|
+
U(n, (s, r) => t(s ? N(n) : r));
|
|
10
|
+
} catch {
|
|
11
|
+
t(N(n));
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const E = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0];
|
|
16
|
+
function G(n, e) {
|
|
17
|
+
const o = new Array(12);
|
|
18
|
+
for (let t = 0; t < 4; t++)
|
|
19
|
+
for (let s = 0; s < 3; s++)
|
|
20
|
+
o[t * 3 + s] = n[t * 3] * e[s] + n[t * 3 + 1] * e[3 + s] + n[t * 3 + 2] * e[6 + s] + (t === 3 ? e[9 + s] : 0);
|
|
21
|
+
return o;
|
|
22
|
+
}
|
|
23
|
+
function O(n) {
|
|
24
|
+
if (!n) return E;
|
|
25
|
+
const e = n.trim().split(/\s+/).map(Number);
|
|
26
|
+
return e.length === 12 && e.every(Number.isFinite) ? e : E;
|
|
27
|
+
}
|
|
28
|
+
const B = {};
|
|
29
|
+
function i(n, e) {
|
|
30
|
+
const t = (B[e] || (B[e] = new RegExp(`\\b${e}\\s*=\\s*"([^"]*)"`))).exec(n);
|
|
31
|
+
return t ? t[1] : null;
|
|
32
|
+
}
|
|
33
|
+
const $ = /<vertex\s+x="([^"]*)"\s+y="([^"]*)"\s+z="([^"]*)"/g, C = /<triangle\s+v1="([^"]*)"\s+v2="([^"]*)"\s+v3="([^"]*)"([^>]*)/g, R = [
|
|
34
|
+
["paint_color", "color"],
|
|
35
|
+
// multi-material: state 1..16 == Extruder1..16
|
|
36
|
+
["paint_supports", "supports"],
|
|
37
|
+
// support enforcer/blocker: states 1 and 2
|
|
38
|
+
["paint_seam", "seam"],
|
|
39
|
+
// unsupported by the kernel — collected for the warning only
|
|
40
|
+
["paint_fuzzy_skin", "fuzzy"]
|
|
41
|
+
// ditto
|
|
42
|
+
];
|
|
43
|
+
function J() {
|
|
44
|
+
return { color: /* @__PURE__ */ new Map(), supports: /* @__PURE__ */ new Map(), seam: /* @__PURE__ */ new Map(), fuzzy: /* @__PURE__ */ new Map() };
|
|
45
|
+
}
|
|
46
|
+
function H(n) {
|
|
47
|
+
return !n || R.every(([, e]) => n[e].size === 0);
|
|
48
|
+
}
|
|
49
|
+
function D(n, e, o) {
|
|
50
|
+
for (const [t, s] of R) {
|
|
51
|
+
if (!n.includes(t)) continue;
|
|
52
|
+
const r = i(n, t);
|
|
53
|
+
r && o[s].set(e, r);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function V(n) {
|
|
57
|
+
const e = [];
|
|
58
|
+
$.lastIndex = 0;
|
|
59
|
+
let o;
|
|
60
|
+
for (; o = $.exec(n); ) e.push(+o[1], +o[2], +o[3]);
|
|
61
|
+
if (!e.length)
|
|
62
|
+
for (const r of n.match(/<vertex\b[^>]*>/g) || []) e.push(+i(r, "x"), +i(r, "y"), +i(r, "z"));
|
|
63
|
+
if (e.length < 9) return null;
|
|
64
|
+
const t = [], s = J();
|
|
65
|
+
for (C.lastIndex = 0; o = C.exec(n); ) {
|
|
66
|
+
const r = t.length / 3;
|
|
67
|
+
t.push(+o[1], +o[2], +o[3]), o[4].length > 2 && D(o[4], r, s);
|
|
68
|
+
}
|
|
69
|
+
if (!t.length)
|
|
70
|
+
for (const r of n.match(/<triangle\b[^>]*>/g) || []) {
|
|
71
|
+
const c = t.length / 3;
|
|
72
|
+
t.push(+i(r, "v1"), +i(r, "v2"), +i(r, "v3")), D(r, c, s);
|
|
73
|
+
}
|
|
74
|
+
return t.length ? { verts: e, tris: t, paint: s } : null;
|
|
75
|
+
}
|
|
76
|
+
function Y(n) {
|
|
77
|
+
const e = /* @__PURE__ */ new Map(), o = /<object\b([^>]*)>([\s\S]*?)<\/object>/g;
|
|
78
|
+
let t;
|
|
79
|
+
for (; t = o.exec(n); ) {
|
|
80
|
+
const c = i(t[1], "id");
|
|
81
|
+
if (!c) continue;
|
|
82
|
+
const p = t[2], f = [];
|
|
83
|
+
for (const u of p.match(/<component\b[^>]*>/g) || []) {
|
|
84
|
+
const m = i(u, "objectid");
|
|
85
|
+
m && f.push({ objectid: m, path: i(u, "p:path") || i(u, "path"), transform: O(i(u, "transform")) });
|
|
86
|
+
}
|
|
87
|
+
e.set(c, f.length ? { components: f } : { mesh: V(p) });
|
|
88
|
+
}
|
|
89
|
+
const s = [], r = /<build\b[^>]*>([\s\S]*?)<\/build>/.exec(n);
|
|
90
|
+
if (r)
|
|
91
|
+
for (const c of r[1].match(/<item\b[^>]*>/g) || []) {
|
|
92
|
+
const p = i(c, "objectid");
|
|
93
|
+
p && s.push({ objectid: p, path: i(c, "p:path") || i(c, "path"), transform: O(i(c, "transform")) });
|
|
94
|
+
}
|
|
95
|
+
return { objects: e, items: s };
|
|
96
|
+
}
|
|
97
|
+
function P(n) {
|
|
98
|
+
const e = String(n).replace(/^\/+/, "");
|
|
99
|
+
return e.includes("%") ? decodeURIComponent(e) : e;
|
|
100
|
+
}
|
|
101
|
+
function A(n) {
|
|
102
|
+
const e = {};
|
|
103
|
+
for (const o of n.match(/<metadata\b[^>]*>/g) || []) {
|
|
104
|
+
const t = i(o, "key");
|
|
105
|
+
t && (e[t] = i(o, "value") ?? "");
|
|
106
|
+
}
|
|
107
|
+
return e;
|
|
108
|
+
}
|
|
109
|
+
function W(n) {
|
|
110
|
+
const e = /* @__PURE__ */ new Map(), o = /<object\b([^>]*)>([\s\S]*?)<\/object>/g;
|
|
111
|
+
let t;
|
|
112
|
+
for (; t = o.exec(n); ) {
|
|
113
|
+
const c = i(t[1], "id");
|
|
114
|
+
c && e.set(c, A(t[2].replace(/<part\b[\s\S]*?<\/part>/g, "")));
|
|
115
|
+
}
|
|
116
|
+
const s = [], r = /<plate\b[^>]*>([\s\S]*?)<\/plate>/g;
|
|
117
|
+
for (; t = r.exec(n); ) {
|
|
118
|
+
const c = t[1], p = A(c.replace(/<model_instance\b[\s\S]*?<\/model_instance>/g, "")), f = [];
|
|
119
|
+
for (const u of c.match(/<model_instance\b[\s\S]*?<\/model_instance>/g) || []) {
|
|
120
|
+
const m = A(u).object_id;
|
|
121
|
+
m && f.push(m);
|
|
122
|
+
}
|
|
123
|
+
s.push({ index: Math.max(0, (Number(p.plater_id) || s.length + 1) - 1), objectIds: f });
|
|
124
|
+
}
|
|
125
|
+
return { objects: e, plates: s };
|
|
126
|
+
}
|
|
127
|
+
function q(n, e) {
|
|
128
|
+
var c, p;
|
|
129
|
+
const o = (f) => {
|
|
130
|
+
const u = n.get(f);
|
|
131
|
+
return u ? e.decode(u) : null;
|
|
132
|
+
}, t = {
|
|
133
|
+
settings: null,
|
|
134
|
+
// Metadata/project_settings.config — the flattened preset (raw upstream strings)
|
|
135
|
+
objectMeta: /* @__PURE__ */ new Map(),
|
|
136
|
+
// 3mf object id -> per-object metadata (name, extruder, per-object overrides)
|
|
137
|
+
plates: [],
|
|
138
|
+
// [{index, objectIds}]
|
|
139
|
+
hasLayerHeightProfile: !1,
|
|
140
|
+
hasCustomGcodePerLayer: !1
|
|
141
|
+
}, s = o("Metadata/project_settings.config");
|
|
142
|
+
if (s)
|
|
143
|
+
try {
|
|
144
|
+
t.settings = JSON.parse(s);
|
|
145
|
+
} catch {
|
|
146
|
+
t.settings = null;
|
|
147
|
+
}
|
|
148
|
+
const r = o("Metadata/model_settings.config");
|
|
149
|
+
if (r) {
|
|
150
|
+
const f = W(r);
|
|
151
|
+
t.objectMeta = f.objects, t.plates = f.plates;
|
|
152
|
+
}
|
|
153
|
+
return t.hasLayerHeightProfile = !!((c = o("Metadata/layer_heights_profile.txt")) != null && c.trim()), t.hasCustomGcodePerLayer = !!((p = o("Metadata/custom_gcode_per_layer.xml")) != null && p.trim()), t;
|
|
154
|
+
}
|
|
155
|
+
async function Q(n, e = "model") {
|
|
156
|
+
const o = ArrayBuffer.isView(n) ? new Uint8Array(n.buffer, n.byteOffset, n.byteLength) : new Uint8Array(n), t = await X(o), s = /* @__PURE__ */ new Map();
|
|
157
|
+
for (const l of Object.keys(t)) s.set(P(l), t[l]);
|
|
158
|
+
const r = new TextDecoder(), c = /* @__PURE__ */ new Map(), p = (l) => {
|
|
159
|
+
const g = P(l);
|
|
160
|
+
if (c.has(g)) return c.get(g);
|
|
161
|
+
const a = s.get(g), d = a ? Y(r.decode(a)) : null;
|
|
162
|
+
return c.set(g, d), d;
|
|
163
|
+
};
|
|
164
|
+
let f = "3D/3dmodel.model";
|
|
165
|
+
const u = s.get("_rels/.rels");
|
|
166
|
+
if (u) {
|
|
167
|
+
for (const l of r.decode(u).match(/<Relationship\b[^>]*>/g) || [])
|
|
168
|
+
if ((i(l, "Type") || "").endsWith("/3dmodel")) {
|
|
169
|
+
f = P(i(l, "Target"));
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const m = p(f);
|
|
174
|
+
if (!m) throw new Error(`3MF root model not found: ${f}`);
|
|
175
|
+
const k = [], F = (l, g, a, d, y, x) => {
|
|
176
|
+
if (x > 16) return;
|
|
177
|
+
const j = p(g), b = j == null ? void 0 : j.objects.get(l);
|
|
178
|
+
if (!b) return;
|
|
179
|
+
if (b.components) {
|
|
180
|
+
for (const h of b.components) F(h.objectid, h.path || g, G(h.transform, a), d, y, x + 1);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (!b.mesh) return;
|
|
184
|
+
const { verts: w, tris: _, paint: M } = b.mesh, v = d.length / 9;
|
|
185
|
+
for (let h = 0; h < _.length; h++) {
|
|
186
|
+
const I = _[h] * 3, S = w[I], T = w[I + 1], z = w[I + 2];
|
|
187
|
+
d.push(
|
|
188
|
+
S * a[0] + T * a[3] + z * a[6] + a[9],
|
|
189
|
+
S * a[1] + T * a[4] + z * a[7] + a[10],
|
|
190
|
+
S * a[2] + T * a[5] + z * a[8] + a[11]
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
if (M) for (const [, h] of R)
|
|
194
|
+
for (const [I, S] of M[h]) y[h].set(v + I, S);
|
|
195
|
+
}, L = m.items.length ? m.items : [...m.objects.keys()].filter((l) => m.objects.get(l).mesh).map((l) => ({ objectid: l, path: f, transform: E }));
|
|
196
|
+
return L.forEach((l, g) => {
|
|
197
|
+
const a = [], d = J();
|
|
198
|
+
if (F(l.objectid, l.path || f, l.transform, a, d, 0), a.length < 9) return;
|
|
199
|
+
const y = new Float32Array(a);
|
|
200
|
+
let x = 1 / 0, j = 1 / 0, b = -1 / 0, w = -1 / 0;
|
|
201
|
+
for (let _ = 0; _ < y.length; _ += 3) {
|
|
202
|
+
const M = y[_], v = y[_ + 1];
|
|
203
|
+
M < x && (x = M), M > b && (b = M), v < j && (j = v), v > w && (w = v);
|
|
204
|
+
}
|
|
205
|
+
k.push({
|
|
206
|
+
name: L.length > 1 ? `${e}#${g + 1}` : e,
|
|
207
|
+
tris: y,
|
|
208
|
+
objectid: l.objectid,
|
|
209
|
+
paint: H(d) ? null : d,
|
|
210
|
+
bbox: { minX: x, minY: j, maxX: b, maxY: w }
|
|
211
|
+
});
|
|
212
|
+
}), { objects: k, project: q(s, r) };
|
|
213
|
+
}
|
|
214
|
+
export {
|
|
215
|
+
Q as p
|
|
216
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { p as f } from "./parse_3mf-8oCnCJNK.js";
|
|
2
|
+
self.onmessage = async (a) => {
|
|
3
|
+
const { id: s, buffer: r, baseName: t } = a.data || {};
|
|
4
|
+
try {
|
|
5
|
+
const { objects: e, project: o } = await f(r, t);
|
|
6
|
+
self.postMessage({ id: s, objects: e, project: o }, e.map((c) => c.tris.buffer));
|
|
7
|
+
} catch (e) {
|
|
8
|
+
self.postMessage({ id: s, error: e && e.message || String(e) });
|
|
9
|
+
}
|
|
10
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const W = {
|
|
2
2
|
0: [0.42, 0.45, 0.5],
|
|
3
3
|
1: [0.85, 0.51, 0.17],
|
|
4
4
|
2: [0.21, 0.45, 0.76],
|
|
@@ -11,12 +11,27 @@ const U = {
|
|
|
11
11
|
9: [0.9, 0.25, 0.25],
|
|
12
12
|
10: [0.6, 0.82, 0.55],
|
|
13
13
|
11: [0.3, 0.72, 0.7]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
}, _e = [
|
|
15
|
+
[0.85, 0.28, 0.25],
|
|
16
|
+
[0.2, 0.52, 0.85],
|
|
17
|
+
[0.25, 0.72, 0.38],
|
|
18
|
+
[0.96, 0.74, 0.16],
|
|
19
|
+
[0.62, 0.36, 0.82],
|
|
20
|
+
[0.18, 0.74, 0.74],
|
|
21
|
+
[0.95, 0.5, 0.15],
|
|
22
|
+
[0.55, 0.56, 0.6]
|
|
23
|
+
];
|
|
24
|
+
function de(t) {
|
|
25
|
+
const i = String(t ?? "").trim().replace(/^#/, "");
|
|
26
|
+
if (i.length !== 3 && i.length !== 6) return null;
|
|
27
|
+
const o = i.length === 3 ? i.split("").map((a) => a + a).join("") : i, n = [0, 2, 4].map((a) => parseInt(o.slice(a, a + 2), 16) / 255);
|
|
28
|
+
return n.some(Number.isNaN) ? null : n;
|
|
29
|
+
}
|
|
30
|
+
function re(t) {
|
|
31
|
+
const i = Math.round(t[0] * 255), o = Math.round(t[1] * 255), n = Math.round(t[2] * 255);
|
|
32
|
+
return i << 16 | o << 8 | n;
|
|
18
33
|
}
|
|
19
|
-
const
|
|
34
|
+
const fe = { 1: "Wall", 2: "Sparse", 3: "Solid", 4: "Skirt", 5: "Support", 6: "Raft", 7: "Gap fill", 8: "Thin wall", 9: "Bridge", 10: "Ironing", 11: "Prime" }, ue = [
|
|
20
35
|
[11, 44, 122],
|
|
21
36
|
[19, 89, 133],
|
|
22
37
|
[28, 136, 145],
|
|
@@ -29,92 +44,93 @@ const le = { 1: "Wall", 2: "Sparse", 3: "Solid", 4: "Skirt", 5: "Support", 6: "R
|
|
|
29
44
|
[194, 82, 60],
|
|
30
45
|
[148, 38, 22]
|
|
31
46
|
].map((t) => [t[0] / 255, t[1] / 255, t[2] / 255]);
|
|
32
|
-
function
|
|
33
|
-
const
|
|
34
|
-
if (!(
|
|
35
|
-
const
|
|
36
|
-
return [
|
|
47
|
+
function pe(t, i, o, n) {
|
|
48
|
+
const a = n.length;
|
|
49
|
+
if (!(o > i)) return n[0];
|
|
50
|
+
const l = (o - i) / (a - 1), h = (t - i) / l, _ = Math.max(0, Math.min(a - 1, Math.floor(h))), x = Math.max(0, Math.min(a - 1, _ + 1)), g = h - _, s = n[_], u = n[x];
|
|
51
|
+
return [s[0] + (u[0] - s[0]) * g, s[1] + (u[1] - s[1]) * g, s[2] + (u[2] - s[2]) * g];
|
|
37
52
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
const ge = 15, ve = 4;
|
|
54
|
+
function be(t, i) {
|
|
55
|
+
const o = t.length, n = i > 0 ? i : 0.42, a = new Array(o);
|
|
56
|
+
for (let e = 0; e < o; e++) {
|
|
57
|
+
const r = t[e].z;
|
|
58
|
+
a[e] = Math.max(0.02, e === 0 ? r : r - t[e - 1].z);
|
|
43
59
|
}
|
|
44
|
-
const
|
|
45
|
-
let
|
|
46
|
-
const
|
|
47
|
-
for (let e = 0; e <
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
for (let
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
53
|
-
|
|
60
|
+
const l = [], h = [], _ = [], x = [], g = [], s = [], u = [], v = [], z = [], S = [], I = [], P = new Float64Array(16), G = [], k = [];
|
|
61
|
+
let $ = -1, E = 0, ee = 0, te = 0, c = -1, f = 0;
|
|
62
|
+
const p = 1e-4, w = (e, r, m, y, d, F, A) => (l.push(e), h.push(r), _.push(m), s.push(y), u.push(d), x.push(F), g.push(A), v.push(f), z.push(!1), l.length - 1);
|
|
63
|
+
for (let e = 0; e < o; e++) {
|
|
64
|
+
const r = t[e].paths, m = t[e].widths, y = a[e];
|
|
65
|
+
if (f = e, !!r)
|
|
66
|
+
for (let d = 0; d < r.length; d += 8) {
|
|
67
|
+
const F = r[d + 3], A = F & ge, V = F >>> ve, B = r[d], O = r[d + 1], J = r[d + 2], L = r[d + 4], C = r[d + 5], D = r[d + 6];
|
|
68
|
+
if (A === 0) {
|
|
69
|
+
G.push(B, O, J, L, C, D), k.push(e);
|
|
54
70
|
continue;
|
|
55
71
|
}
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
let
|
|
59
|
-
|
|
72
|
+
const oe = m && m[d / 8] > 0 ? m[d / 8] : n;
|
|
73
|
+
P[A] += Math.hypot(L - B, C - O);
|
|
74
|
+
let Q;
|
|
75
|
+
$ >= 0 && c === F && Math.abs(E - B) < p && Math.abs(ee - O) < p && Math.abs(te - J) < p ? (Q = $, w(L, C, D, A, V, y, oe)) : (Q = w(B, O, J, A, V, y, oe), w(L, C, D, A, V, y, oe)), z[Q] = !0, $ = Q + 1, E = L, ee = C, te = D, c = F, S.push(Q), I.push(e);
|
|
60
76
|
}
|
|
61
77
|
}
|
|
62
|
-
const
|
|
63
|
-
let
|
|
64
|
-
for (let e = 0; e <
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
let
|
|
69
|
-
if (
|
|
70
|
-
const
|
|
71
|
-
|
|
78
|
+
const b = l.length, M = S.length, R = new Float32Array(b * 4), U = new Float32Array(b * 4);
|
|
79
|
+
let ie = 0, ae = !1, Y = 1 / 0, j = 1 / 0, X = 1 / 0, K = -1 / 0, Z = -1 / 0, q = -1 / 0;
|
|
80
|
+
for (let e = 0; e < b; e++) {
|
|
81
|
+
const r = x[e], m = l[e], y = h[e], d = _[e] - 0.5 * r;
|
|
82
|
+
R[e * 4] = m, R[e * 4 + 1] = y, R[e * 4 + 2] = d;
|
|
83
|
+
const F = e > 0 && z[e - 1], A = z[e];
|
|
84
|
+
let V = 0;
|
|
85
|
+
if (F || A) {
|
|
86
|
+
const B = F ? l[e] - l[e - 1] : 0, O = F ? h[e] - h[e - 1] : 0, J = F ? _[e] - _[e - 1] : 0, L = A ? l[e + 1] - l[e] : 0, C = A ? h[e + 1] - h[e] : 0, D = A ? _[e + 1] - _[e] : 0;
|
|
87
|
+
V = Math.atan2(B * C - O * L, B * L + O * C + J * D);
|
|
72
88
|
}
|
|
73
|
-
|
|
89
|
+
U[e * 4] = r, U[e * 4 + 1] = g[e], U[e * 4 + 2] = V, U[e * 4 + 3] = re(W[s[e]] || W[1]), (!Number.isFinite(m) || !Number.isFinite(y) || !Number.isFinite(d) || !Number.isFinite(V)) && (ae = !0), ie = Math.max(ie, Math.abs(m), Math.abs(y), Math.abs(d)), m < Y && (Y = m), m > K && (K = m), y < j && (j = y), y > Z && (Z = y), d < X && (X = d), d > q && (q = d);
|
|
74
90
|
}
|
|
75
|
-
const
|
|
76
|
-
for (let e = 0; e <
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
for (let e = 0; e <
|
|
80
|
-
|
|
81
|
-
const
|
|
91
|
+
const ne = new Uint32Array(M * 4);
|
|
92
|
+
for (let e = 0; e < M; e++)
|
|
93
|
+
ne[e * 4] = S[e], ne[e * 4 + 1] = I[e];
|
|
94
|
+
const T = { vType: new Uint8Array(b), vTool: new Uint8Array(b), vWidth: new Float32Array(b), vHeight: new Float32Array(b), vLayer: new Int32Array(b) };
|
|
95
|
+
for (let e = 0; e < b; e++)
|
|
96
|
+
T.vType[e] = s[e], T.vTool[e] = u[e], T.vWidth[e] = g[e], T.vHeight[e] = x[e], T.vLayer[e] = v[e];
|
|
97
|
+
const le = new Int32Array(o + 1);
|
|
82
98
|
{
|
|
83
99
|
let e = 0;
|
|
84
|
-
for (let
|
|
85
|
-
for (; e <
|
|
86
|
-
|
|
100
|
+
for (let r = 0; r < o; r++) {
|
|
101
|
+
for (; e < M && I[e] === r; ) e++;
|
|
102
|
+
le[r + 1] = e;
|
|
87
103
|
}
|
|
88
104
|
}
|
|
89
|
-
const
|
|
90
|
-
for (let e = 0; e < N.length; e++) N[e] =
|
|
105
|
+
const H = k.length, N = new Float32Array(H * 6);
|
|
106
|
+
for (let e = 0; e < N.length; e++) N[e] = G[e];
|
|
91
107
|
for (let e = 0; e < N.length; e += 3) {
|
|
92
|
-
const
|
|
93
|
-
|
|
108
|
+
const r = N[e], m = N[e + 1], y = N[e + 2];
|
|
109
|
+
r < Y && (Y = r), r > K && (K = r), m < j && (j = m), m > Z && (Z = m), y < X && (X = y), y > q && (q = y);
|
|
94
110
|
}
|
|
95
|
-
const
|
|
111
|
+
const se = new Int32Array(o + 1);
|
|
96
112
|
{
|
|
97
113
|
let e = 0;
|
|
98
|
-
for (let
|
|
99
|
-
for (; e <
|
|
100
|
-
|
|
114
|
+
for (let r = 0; r < o; r++) {
|
|
115
|
+
for (; e < H && k[e] === r; ) e++;
|
|
116
|
+
se[r + 1] = e;
|
|
101
117
|
}
|
|
102
118
|
}
|
|
103
|
-
const
|
|
104
|
-
return { position:
|
|
119
|
+
const he = b + H > 0 ? { min: [Y, j, X], max: [K, Z, q] } : null;
|
|
120
|
+
return { position: R, hwa: U, segIndex: ne, nV: b, nSeg: M, layerSegPrefix: le, travelPos: N, travelPrefix: se, nTrav: H, layerCount: o, maxAbs: ie, hasNaN: ae, meta: T, typeLengths: P, bbox: he };
|
|
105
121
|
}
|
|
106
|
-
function
|
|
122
|
+
function ze(t) {
|
|
107
123
|
let i = 0;
|
|
108
124
|
for (let n = 1; n < 16; n++) i += t[n] || 0;
|
|
109
|
-
const
|
|
110
|
-
if (i <= 0) return
|
|
125
|
+
const o = [];
|
|
126
|
+
if (i <= 0) return o;
|
|
111
127
|
for (let n = 1; n < 16; n++) {
|
|
112
|
-
const
|
|
113
|
-
|
|
128
|
+
const a = t[n] || 0;
|
|
129
|
+
a > 0 && o.push({ type: n, label: fe[n] || "t" + n, pct: 100 * a / i, color: W[n] || W[1] });
|
|
114
130
|
}
|
|
115
|
-
return
|
|
131
|
+
return o.sort((n, a) => a.pct - n.pct);
|
|
116
132
|
}
|
|
117
|
-
const
|
|
133
|
+
const me = `
|
|
118
134
|
precision highp float;
|
|
119
135
|
precision highp int;
|
|
120
136
|
precision highp sampler2D;
|
|
@@ -234,14 +250,14 @@ void main() {
|
|
|
234
250
|
color = color_base * lighting(eye_position, eye_normal);
|
|
235
251
|
gl_Position = projection_matrix * vec4(eye_position, 1.0);
|
|
236
252
|
}
|
|
237
|
-
`,
|
|
253
|
+
`, ye = `
|
|
238
254
|
precision highp float;
|
|
239
255
|
in vec3 color;
|
|
240
256
|
out vec4 fragment_color;
|
|
241
257
|
void main() {
|
|
242
258
|
fragment_color = vec4(color, 1.0);
|
|
243
259
|
}
|
|
244
|
-
`,
|
|
260
|
+
`, xe = [
|
|
245
261
|
0,
|
|
246
262
|
1,
|
|
247
263
|
2,
|
|
@@ -271,16 +287,16 @@ void main() {
|
|
|
271
287
|
6
|
|
272
288
|
// back spike
|
|
273
289
|
];
|
|
274
|
-
function
|
|
275
|
-
const
|
|
276
|
-
const p = Math.min(2048, Math.max(1,
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
return
|
|
280
|
-
}, n =
|
|
281
|
-
|
|
290
|
+
function Ae(t, i) {
|
|
291
|
+
const o = (c, f) => {
|
|
292
|
+
const p = Math.min(2048, Math.max(1, f)), w = Math.max(1, Math.ceil(f / p)), b = new Float32Array(p * w * 4);
|
|
293
|
+
b.set(c.subarray(0, Math.min(c.length, p * w * 4)));
|
|
294
|
+
const M = new t.DataTexture(b, p, w, t.RGBAFormat, t.FloatType);
|
|
295
|
+
return M.minFilter = M.magFilter = t.NearestFilter, M.generateMipmaps = !1, M.needsUpdate = !0, M;
|
|
296
|
+
}, n = o(i.position, i.nV), a = o(i.hwa, i.nV), l = new t.InstancedBufferGeometry();
|
|
297
|
+
l.setIndex(xe), l.setAttribute("position", new t.BufferAttribute(new Float32Array(8 * 3), 3)), l.setAttribute("vertex_id_float", new t.BufferAttribute(new Float32Array([0, 1, 2, 3, 4, 5, 6, 7]), 1));
|
|
282
298
|
const h = new t.InstancedInterleavedBuffer(i.segIndex, 4);
|
|
283
|
-
|
|
299
|
+
l.setAttribute("seg_id_a_u", new t.InterleavedBufferAttribute(h, 1, 0)), l.setAttribute("seg_layer_u", new t.InterleavedBufferAttribute(h, 1, 1)), l.instanceCount = 0;
|
|
284
300
|
const _ = new t.RawShaderMaterial({
|
|
285
301
|
glslVersion: t.GLSL3,
|
|
286
302
|
uniforms: {
|
|
@@ -288,98 +304,107 @@ function ge(t, i) {
|
|
|
288
304
|
projection_matrix: { value: new t.Matrix4() },
|
|
289
305
|
camera_position: { value: new t.Vector3() },
|
|
290
306
|
position_tex: { value: n },
|
|
291
|
-
height_width_angle_tex: { value:
|
|
307
|
+
height_width_angle_tex: { value: a },
|
|
292
308
|
layer_lo: { value: 0 },
|
|
293
309
|
layer_hi: { value: i.layerCount }
|
|
294
310
|
},
|
|
295
|
-
vertexShader:
|
|
296
|
-
fragmentShader:
|
|
311
|
+
vertexShader: me,
|
|
312
|
+
fragmentShader: ye,
|
|
297
313
|
side: t.DoubleSide
|
|
298
|
-
}),
|
|
299
|
-
let
|
|
314
|
+
}), x = new t.Mesh(l, _);
|
|
315
|
+
let g = null;
|
|
300
316
|
if (i.bbox) {
|
|
301
|
-
const { min: c, max:
|
|
302
|
-
|
|
317
|
+
const { min: c, max: f } = i.bbox, p = new t.Vector3((c[0] + f[0]) / 2, (c[1] + f[1]) / 2, (c[2] + f[2]) / 2), w = Math.hypot(f[0] - c[0], f[1] - c[1], f[2] - c[2]) / 2 + 2;
|
|
318
|
+
g = new t.Sphere(p, w);
|
|
303
319
|
}
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
_.uniforms.projection_matrix.value.copy(p.projectionMatrix), _.uniforms.view_matrix.value.multiplyMatrices(p.matrixWorldInverse,
|
|
320
|
+
x.frustumCulled = !!g, g && (l.boundingSphere = g);
|
|
321
|
+
const s = new t.Matrix4(), u = new t.Vector3();
|
|
322
|
+
x.onBeforeRender = (c, f, p) => {
|
|
323
|
+
_.uniforms.projection_matrix.value.copy(p.projectionMatrix), _.uniforms.view_matrix.value.multiplyMatrices(p.matrixWorldInverse, x.matrixWorld), s.copy(x.matrixWorld).invert(), p.getWorldPosition(u).applyMatrix4(s), _.uniforms.camera_position.value.copy(u);
|
|
308
324
|
};
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
let
|
|
314
|
-
const
|
|
315
|
-
const c = i.travelPrefix[
|
|
316
|
-
|
|
317
|
-
},
|
|
325
|
+
const v = new t.BufferGeometry();
|
|
326
|
+
v.setAttribute("position", new t.BufferAttribute(i.travelPos, 3)), v.setDrawRange(0, 0);
|
|
327
|
+
const z = new t.LineSegments(v, new t.LineBasicMaterial({ color: 7041658 }));
|
|
328
|
+
z.frustumCulled = !!g, z.visible = !1, g && (v.boundingSphere = g);
|
|
329
|
+
let S = !1, I = 0, P = i.layerCount - 1;
|
|
330
|
+
const G = () => {
|
|
331
|
+
const c = i.travelPrefix[I], f = i.travelPrefix[P + 1];
|
|
332
|
+
v.setDrawRange(S ? c * 2 : 0, S ? (f - c) * 2 : 0);
|
|
333
|
+
}, k = (c, f) => {
|
|
318
334
|
const p = i.layerCount;
|
|
319
|
-
|
|
335
|
+
I = Math.max(0, Math.min(p - 1, c | 0)), P = Math.max(I, Math.min(p - 1, f | 0)), _.uniforms.layer_lo.value = I, _.uniforms.layer_hi.value = P, l.instanceCount = i.layerSegPrefix[P + 1], G();
|
|
320
336
|
};
|
|
321
|
-
return { mesh:
|
|
322
|
-
|
|
337
|
+
return { mesh: x, travLines: z, setVisibleLayers: (c) => k(0, (c | 0) - 1), setLayerRange: k, setTravelVisible: (c) => {
|
|
338
|
+
S = !!c, z.visible = S, G();
|
|
323
339
|
}, setColors: (c) => {
|
|
324
|
-
const
|
|
325
|
-
for (let
|
|
326
|
-
|
|
340
|
+
const f = a.image.data, p = Math.min(c.length, f.length) / 4;
|
|
341
|
+
for (let w = 0; w < p; w++) f[w * 4 + 3] = c[w * 4];
|
|
342
|
+
a.needsUpdate = !0;
|
|
327
343
|
}, dispose: () => {
|
|
328
|
-
|
|
344
|
+
l.dispose(), _.dispose(), n.dispose(), a.dispose(), v.dispose(), z.material.dispose();
|
|
329
345
|
}, nSeg: i.nSeg, layerCount: i.layerCount };
|
|
330
346
|
}
|
|
331
|
-
const
|
|
347
|
+
const ce = [
|
|
332
348
|
{ key: "feature", label: "Feature type", cont: !1, unit: "" },
|
|
333
349
|
{ key: "speed", label: "Speed", cont: !0, unit: "mm/s" },
|
|
334
350
|
{ key: "height", label: "Layer Height", cont: !0, unit: "mm" },
|
|
335
351
|
{ key: "width", label: "Line Width", cont: !0, unit: "mm" },
|
|
336
352
|
{ key: "fan", label: "Fan Speed", cont: !0, unit: "%" },
|
|
337
|
-
{ key: "temp", label: "Temperature", cont: !0, unit: "°C" }
|
|
353
|
+
{ key: "temp", label: "Temperature", cont: !0, unit: "°C" },
|
|
354
|
+
// Last, like upstream's EViewType::Tool: it answers "did my painted regions come out on the extruder I assigned?",
|
|
355
|
+
// which is a check you run after slicing, not a property you scrub through. Discrete like the feature view — an
|
|
356
|
+
// extruder index is a label, and a heatmap over it would imply tool 2 sits "between" tools 1 and 3.
|
|
357
|
+
{ key: "filament", label: "Filament", cont: !1, unit: "" }
|
|
338
358
|
];
|
|
339
|
-
function
|
|
340
|
-
const
|
|
359
|
+
function we(t, i, o, n) {
|
|
360
|
+
const a = i.vType[o], l = i.vLayer[o], h = l === 0;
|
|
341
361
|
switch (t) {
|
|
342
362
|
case "height":
|
|
343
|
-
return i.vHeight[
|
|
363
|
+
return i.vHeight[o];
|
|
344
364
|
case "width":
|
|
345
|
-
return i.vWidth[
|
|
365
|
+
return i.vWidth[o];
|
|
346
366
|
case "speed":
|
|
347
|
-
return h ? n.firstLayerSpeed : n.speedByType[
|
|
367
|
+
return h ? n.firstLayerSpeed : n.speedByType[a] ?? n.speedByType[1];
|
|
348
368
|
case "fan":
|
|
349
|
-
return
|
|
369
|
+
return l < n.closeFanLayers ? 0 : a === 9 ? 100 : n.fanNormal;
|
|
350
370
|
case "temp":
|
|
351
371
|
return h ? n.tempFirst : n.tempNormal;
|
|
352
372
|
default:
|
|
353
373
|
return 0;
|
|
354
374
|
}
|
|
355
375
|
}
|
|
356
|
-
function
|
|
357
|
-
const { meta: n, nV:
|
|
376
|
+
function Fe(t, i, o) {
|
|
377
|
+
const { meta: n, nV: a } = t, l = new Float32Array(a * 4), h = ce.find((s) => s.key === i) || ce[0];
|
|
358
378
|
if (!h.cont) {
|
|
359
|
-
|
|
360
|
-
|
|
379
|
+
const s = ((o == null ? void 0 : o.toolColors) ?? []).map(de), u = h.key === "filament" ? (v) => {
|
|
380
|
+
const z = n.vTool ? n.vTool[v] : 0;
|
|
381
|
+
return s[z] || _e[z % _e.length];
|
|
382
|
+
} : (v) => W[n.vType[v]] || W[1];
|
|
383
|
+
for (let v = 0; v < a; v++) l[v * 4] = re(u(v));
|
|
384
|
+
return { color: l, min: 0, max: 0, viewType: i, label: h.label, unit: h.unit, cont: !1 };
|
|
361
385
|
}
|
|
362
|
-
let _ = 1 / 0,
|
|
363
|
-
const
|
|
364
|
-
for (let
|
|
365
|
-
const
|
|
366
|
-
|
|
386
|
+
let _ = 1 / 0, x = -1 / 0;
|
|
387
|
+
const g = new Float32Array(a);
|
|
388
|
+
for (let s = 0; s < a; s++) {
|
|
389
|
+
const u = we(i, n, s, o);
|
|
390
|
+
g[s] = u, u < _ && (_ = u), u > x && (x = u);
|
|
367
391
|
}
|
|
368
|
-
Number.isFinite(_) || (_ = 0,
|
|
369
|
-
for (let
|
|
370
|
-
const
|
|
371
|
-
|
|
392
|
+
Number.isFinite(_) || (_ = 0, x = 1);
|
|
393
|
+
for (let s = 0; s < a; s++) {
|
|
394
|
+
const u = pe(g[s], _, x, ue);
|
|
395
|
+
l[s * 4] = re(u);
|
|
372
396
|
}
|
|
373
|
-
return { color:
|
|
397
|
+
return { color: l, min: _, max: x, viewType: i, label: h.label, unit: h.unit, cont: !0 };
|
|
374
398
|
}
|
|
375
399
|
export {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
fe as
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
400
|
+
ue as DEFAULT_RANGES_COLORS,
|
|
401
|
+
_e as TOOL_COLOR,
|
|
402
|
+
W as TYPE_COLOR,
|
|
403
|
+
fe as TYPE_LABEL,
|
|
404
|
+
xe as VERTEX_DATA,
|
|
405
|
+
ce as VIEW_TYPES,
|
|
406
|
+
be as buildSegmentData,
|
|
407
|
+
Fe as computeColors,
|
|
408
|
+
Ae as makeToolpath,
|
|
409
|
+
ze as roleRatios
|
|
385
410
|
};
|