three-slicer-viewer 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/TOOLPATH_SPEC.md +8 -1
- package/VIEWER.md +24 -0
- package/data/config-schema-lean.json +1 -1
- package/dist/components.js +47 -43
- package/dist/gcode_parse.js +154 -111
- package/dist/index.js +4409 -4069
- package/dist/{model_loaders-DxlFNFOu.js → model_loaders-Dk9rqXFb.js} +27 -27
- package/dist/model_loaders.js +2 -2
- package/dist/parse_3mf-CpbA-6Iq.js +666 -0
- package/dist/parse_3mf.worker.js +67 -5
- package/dist/sl1_encode.worker.js +1 -1
- package/dist/sl1_write-B6nWmCUu.js +313 -0
- package/dist/sla_slice.worker.js +1 -1
- package/dist/toolpath.js +303 -177
- package/package.json +6 -1
- package/src/core/paint_tools.js +8 -0
- package/src/settings/bed_frame.js +28 -0
- package/src/settings/index.js +1 -0
- package/src/settings/kernel_setting_keys.js +79 -0
- package/src/settings/settings_core.js +194 -8
- package/types/gcode.d.ts +13 -0
- package/types/paint.d.ts +7 -0
- package/types/settings.d.ts +14 -1
- package/types/toolpath.d.ts +6 -0
- package/types/viewer.d.ts +1 -1
- package/dist/parse_3mf-BZISF3eW.js +0 -327
- package/dist/sl1_write-BovHbg3k.js +0 -303
|
@@ -0,0 +1,666 @@
|
|
|
1
|
+
import { inflateSync as pt, unzip as mt, unzipSync as Y } from "three/examples/jsm/libs/fflate.module.js";
|
|
2
|
+
import { S as ht } from "./viewer_defaults-B7UUZ582.js";
|
|
3
|
+
const ot = [
|
|
4
|
+
1,
|
|
5
|
+
10,
|
|
6
|
+
100,
|
|
7
|
+
1e3,
|
|
8
|
+
1e4,
|
|
9
|
+
1e5,
|
|
10
|
+
1e6,
|
|
11
|
+
1e7,
|
|
12
|
+
1e8,
|
|
13
|
+
1e9,
|
|
14
|
+
1e10,
|
|
15
|
+
1e11,
|
|
16
|
+
1e12,
|
|
17
|
+
1e13,
|
|
18
|
+
1e14,
|
|
19
|
+
1e15,
|
|
20
|
+
1e16,
|
|
21
|
+
1e17,
|
|
22
|
+
1e18,
|
|
23
|
+
1e19,
|
|
24
|
+
1e20,
|
|
25
|
+
1e21,
|
|
26
|
+
1e22
|
|
27
|
+
], dt = new TextDecoder(), N = (t, e, i) => dt.decode(t.subarray(e, i));
|
|
28
|
+
function $(t, e, i) {
|
|
29
|
+
let n = e, o = !1;
|
|
30
|
+
n < i && (t[n] === 45 || t[n] === 43) && (o = t[n] === 45, n++);
|
|
31
|
+
let r = 0, c = -1, a = 0;
|
|
32
|
+
for (; n < i; n++) {
|
|
33
|
+
const p = t[n];
|
|
34
|
+
if (p >= 48 && p <= 57)
|
|
35
|
+
r = r * 10 + (p - 48), a++, c >= 0 && c++;
|
|
36
|
+
else if (p === 46 && c < 0) c = 0;
|
|
37
|
+
else return Number(N(t, e, i));
|
|
38
|
+
}
|
|
39
|
+
if (!a || r > 9007199254740991 || c > 22) return Number(N(t, e, i));
|
|
40
|
+
let s = r;
|
|
41
|
+
return c > 0 && (s = r / ot[c]), o ? -s : s;
|
|
42
|
+
}
|
|
43
|
+
let T = 0;
|
|
44
|
+
function B(t, e) {
|
|
45
|
+
let i = e, n = !1, o = t[i];
|
|
46
|
+
(o === 45 || o === 43) && (n = o === 45, o = t[++i]);
|
|
47
|
+
let r = 0, c = -1, a = 0;
|
|
48
|
+
for (; ; o = t[++i])
|
|
49
|
+
if (o >= 48 && o <= 57)
|
|
50
|
+
r = r * 10 + (o - 48), a++, c >= 0 && c++;
|
|
51
|
+
else if (o === 46 && c < 0) c = 0;
|
|
52
|
+
else break;
|
|
53
|
+
if (o !== 34) {
|
|
54
|
+
const p = t.indexOf(34, i);
|
|
55
|
+
return T = p + 1, Number(N(t, e, p));
|
|
56
|
+
}
|
|
57
|
+
if (T = i + 1, !a || r > 9007199254740991 || c > 22) return Number(N(t, e, i));
|
|
58
|
+
let s = r;
|
|
59
|
+
return c > 0 && (s = r / ot[c]), n ? -s : s;
|
|
60
|
+
}
|
|
61
|
+
const V = (t, e, i) => t[e] === 32 && t[e + 1] === i && t[e + 2] === 61 && t[e + 3] === 34, q = (t, e, i) => t[e] === 32 && t[e + 1] === 118 && t[e + 2] === i && t[e + 3] === 61 && t[e + 4] === 34, H = (t) => t === 32 || t === 10 || t === 13 || t === 9, O = (t, e, i, n) => {
|
|
62
|
+
if (i - e !== n.length) return !1;
|
|
63
|
+
for (let o = 0; o < n.length; o++) if (t[e + o] !== n.charCodeAt(o)) return !1;
|
|
64
|
+
return !0;
|
|
65
|
+
};
|
|
66
|
+
function U(t, e, i) {
|
|
67
|
+
const n = t.length;
|
|
68
|
+
for (; e < n; ) {
|
|
69
|
+
let o = t[e];
|
|
70
|
+
for (; H(o); ) o = t[++e];
|
|
71
|
+
if (o === 62) return e + 1;
|
|
72
|
+
if (o === 47) {
|
|
73
|
+
e++;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const r = e;
|
|
77
|
+
for (; e < n && t[e] !== 61 && t[e] !== 62 && !H(t[e]); ) e++;
|
|
78
|
+
const c = e;
|
|
79
|
+
for (; H(t[e]); ) e++;
|
|
80
|
+
if (t[e] !== 61) continue;
|
|
81
|
+
for (e++; H(t[e]); ) e++;
|
|
82
|
+
const a = t[e];
|
|
83
|
+
if (a !== 34 && a !== 39) continue;
|
|
84
|
+
const s = e + 1, p = t.indexOf(a, s);
|
|
85
|
+
if (p < 0) return n;
|
|
86
|
+
a === 34 && i(r, c, s, p), e = p + 1;
|
|
87
|
+
}
|
|
88
|
+
return n;
|
|
89
|
+
}
|
|
90
|
+
const K = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0];
|
|
91
|
+
function gt(t) {
|
|
92
|
+
if (!t) return K;
|
|
93
|
+
const e = t.trim().split(/\s+/).map(Number);
|
|
94
|
+
return e.length === 12 && e.every(Number.isFinite) ? e : K;
|
|
95
|
+
}
|
|
96
|
+
const G = [
|
|
97
|
+
["paint_color", "color"],
|
|
98
|
+
// multi-material: state 1..16 == Extruder1..16
|
|
99
|
+
["paint_supports", "supports"],
|
|
100
|
+
// support enforcer/blocker: states 1 and 2
|
|
101
|
+
["paint_seam", "seam"],
|
|
102
|
+
// unsupported by the kernel — collected for the warning only
|
|
103
|
+
["paint_fuzzy_skin", "fuzzy"]
|
|
104
|
+
// ditto
|
|
105
|
+
], wt = Object.fromEntries(G);
|
|
106
|
+
function it() {
|
|
107
|
+
return { color: /* @__PURE__ */ new Map(), supports: /* @__PURE__ */ new Map(), seam: /* @__PURE__ */ new Map(), fuzzy: /* @__PURE__ */ new Map() };
|
|
108
|
+
}
|
|
109
|
+
function jt(t) {
|
|
110
|
+
return !t || G.every(([, e]) => t[e].size === 0);
|
|
111
|
+
}
|
|
112
|
+
class Q {
|
|
113
|
+
constructor() {
|
|
114
|
+
this.data = new Float64Array(1024), this.length = 0;
|
|
115
|
+
}
|
|
116
|
+
push3(e, i, n) {
|
|
117
|
+
if (this.length + 3 > this.data.length) {
|
|
118
|
+
const o = new Float64Array(this.data.length * 2);
|
|
119
|
+
o.set(this.data), this.data = o;
|
|
120
|
+
}
|
|
121
|
+
this.data[this.length] = e, this.data[this.length + 1] = i, this.data[this.length + 2] = n, this.length += 3;
|
|
122
|
+
}
|
|
123
|
+
view() {
|
|
124
|
+
return this.data.subarray(0, this.length);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function W(t) {
|
|
128
|
+
const e = /* @__PURE__ */ new Map(), i = [];
|
|
129
|
+
let n = null, o = 0, r = 0, c = 0, a = 0, s = 0, p = 0, u = 0, l = null, h = null, m = null, w = null, M = null;
|
|
130
|
+
const S = () => {
|
|
131
|
+
if (n.id)
|
|
132
|
+
if (n.components.length) e.set(n.id, { components: n.components });
|
|
133
|
+
else {
|
|
134
|
+
let g = null;
|
|
135
|
+
n.verts.length >= 9 && n.tris.length && (g = { verts: n.verts.view(), tris: n.tris.view(), paint: n.paint }), e.set(n.id, { mesh: g });
|
|
136
|
+
}
|
|
137
|
+
n = null;
|
|
138
|
+
}, A = () => ({ objectid: l, path: h || m, transform: gt(w) }), k = (g, z, I, f) => {
|
|
139
|
+
O(t, g, z, "objectid") ? l = N(t, I, f) : O(t, g, z, "p:path") ? h = N(t, I, f) : O(t, g, z, "path") ? m = N(t, I, f) : O(t, g, z, "transform") && (w = N(t, I, f));
|
|
140
|
+
}, F = (g, z, I, f) => {
|
|
141
|
+
if (z - g !== 1) return;
|
|
142
|
+
const d = t[g];
|
|
143
|
+
d === 120 ? r = $(t, I, f) : d === 121 ? c = $(t, I, f) : d === 122 && (a = $(t, I, f));
|
|
144
|
+
}, b = (g, z, I, f) => {
|
|
145
|
+
if (z - g === 2 && t[g] === 118) {
|
|
146
|
+
const d = t[g + 1];
|
|
147
|
+
d === 49 ? s = $(t, I, f) : d === 50 ? p = $(t, I, f) : d === 51 && (u = $(t, I, f));
|
|
148
|
+
} else if (t[g] === 112 && z - g > 6) {
|
|
149
|
+
const d = wt[N(t, g, z)];
|
|
150
|
+
d && f > I && (M ??= []).push(d, N(t, I, f));
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
let j = null;
|
|
154
|
+
const P = (g, z, I, f) => {
|
|
155
|
+
O(t, g, z, "id") && (j = N(t, I, f));
|
|
156
|
+
}, _ = t.length;
|
|
157
|
+
let x = 0;
|
|
158
|
+
for (; x = t.indexOf(60, x), !(x < 0); ) {
|
|
159
|
+
let g = x + 1;
|
|
160
|
+
const z = t[g] === 47;
|
|
161
|
+
z && g++;
|
|
162
|
+
const I = t[g];
|
|
163
|
+
if (I === 33 || I === 63) {
|
|
164
|
+
if (t[g + 1] === 45 && t[g + 2] === 45) {
|
|
165
|
+
let d = g + 3;
|
|
166
|
+
for (; (d = t.indexOf(45, d)) >= 0 && !(t[d + 1] === 45 && t[d + 2] === 62); ) d++;
|
|
167
|
+
x = _, d >= 0 && (x = d + 3);
|
|
168
|
+
} else x = t.indexOf(62, g) + 1 || _;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
let f = g;
|
|
172
|
+
for (; f < _ && !H(t[f]) && t[f] !== 62 && t[f] !== 47; ) f++;
|
|
173
|
+
if (z) {
|
|
174
|
+
n && O(t, g, f, "object") ? S() : o === 1 && O(t, g, f, "build") && (o = 2), x = t.indexOf(62, f) + 1 || _;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (n) {
|
|
178
|
+
if (O(t, g, f, "vertex")) {
|
|
179
|
+
if (V(t, f, 120) && (r = B(t, f + 4), V(t, T, 121) && (c = B(t, T + 4), V(t, T, 122) && (a = B(t, T + 4), t[T] === 47 && t[T + 1] === 62)))) {
|
|
180
|
+
x = T + 2, n.id && n.verts.push3(r, c, a);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
r = 0, c = 0, a = 0, x = U(t, f, F), n.id && n.verts.push3(r, c, a);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (O(t, g, f, "triangle")) {
|
|
187
|
+
s = 0, p = 0, u = 0, M = null;
|
|
188
|
+
let d = f;
|
|
189
|
+
if (q(t, f, 49)) {
|
|
190
|
+
const L = B(t, f + 5);
|
|
191
|
+
if (q(t, T, 50)) {
|
|
192
|
+
const ft = B(t, T + 5);
|
|
193
|
+
if (q(t, T, 51)) {
|
|
194
|
+
const ut = B(t, T + 5);
|
|
195
|
+
s = L, p = ft, u = ut, d = T;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (d !== f && t[d] === 47 && t[d + 1] === 62 ? x = d + 2 : x = U(t, d, b), !n.id) continue;
|
|
200
|
+
const E = n.tris.length / 3;
|
|
201
|
+
if (n.tris.push3(s, p, u), M) for (let L = 0; L < M.length; L += 2) n.paint[M[L]].set(E, M[L + 1]);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (O(t, g, f, "component")) {
|
|
205
|
+
l = null, h = null, m = null, w = null, x = U(t, f, k), l && n.components.push(A());
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
} else if (O(t, g, f, "object")) {
|
|
209
|
+
j = null, x = U(t, f, P), n = { id: j, components: [], verts: new Q(), tris: new Q(), paint: it() }, t[x - 2] === 47 && S();
|
|
210
|
+
continue;
|
|
211
|
+
} else if (o === 0 && O(t, g, f, "build")) {
|
|
212
|
+
x = U(t, f, () => {
|
|
213
|
+
}), o = 1, t[x - 2] === 47 && (o = 2);
|
|
214
|
+
continue;
|
|
215
|
+
} else if (o === 1 && O(t, g, f, "item")) {
|
|
216
|
+
l = null, h = null, m = null, w = null, x = U(t, f, k), l && i.push(A());
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
x = t.indexOf(62, f) + 1 || _;
|
|
220
|
+
}
|
|
221
|
+
return { objects: e, items: i };
|
|
222
|
+
}
|
|
223
|
+
const Mt = new TextDecoder(), v = (t, e) => t[e] | t[e + 1] << 8, C = (t, e) => (t[e] | t[e + 1] << 8 | t[e + 2] << 16 | t[e + 3] << 24) >>> 0;
|
|
224
|
+
function _t(t) {
|
|
225
|
+
let e = -1;
|
|
226
|
+
for (let r = t.length - 22; r >= Math.max(0, t.length - 65557); r--)
|
|
227
|
+
if (C(t, r) === 101010256) {
|
|
228
|
+
e = r;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
if (e < 0) return null;
|
|
232
|
+
const i = v(t, e + 10);
|
|
233
|
+
let n = C(t, e + 16);
|
|
234
|
+
if (i === 65535 || n === 4294967295) return null;
|
|
235
|
+
const o = /* @__PURE__ */ new Map();
|
|
236
|
+
for (let r = 0; r < i; r++) {
|
|
237
|
+
if (C(t, n) !== 33639248) return null;
|
|
238
|
+
const c = v(t, n + 8), a = v(t, n + 10), s = C(t, n + 20), p = C(t, n + 24), u = v(t, n + 28), l = v(t, n + 30), h = v(t, n + 32), m = C(t, n + 42);
|
|
239
|
+
if (c & 1 || s === 4294967295 || p === 4294967295 || m === 4294967295 || a !== 0 && a !== 8 || C(t, m) !== 67324752) return null;
|
|
240
|
+
const w = Mt.decode(t.subarray(n + 46, n + 46 + u)), M = m + 30 + v(t, m + 26) + v(t, m + 28);
|
|
241
|
+
o.set(w, { method: a, compressedSize: s, size: p, dataStart: M }), n += 46 + u + l + h;
|
|
242
|
+
}
|
|
243
|
+
return o;
|
|
244
|
+
}
|
|
245
|
+
function rt(t, e) {
|
|
246
|
+
return t.subarray(e.dataStart, e.dataStart + e.compressedSize);
|
|
247
|
+
}
|
|
248
|
+
async function st(t, e) {
|
|
249
|
+
if (e.method === 0) return t.slice();
|
|
250
|
+
if (typeof DecompressionStream == "function" && typeof Response == "function") {
|
|
251
|
+
const i = new Blob([t]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
|
|
252
|
+
return new Uint8Array(await new Response(i).arrayBuffer());
|
|
253
|
+
}
|
|
254
|
+
return pt(t, { out: new Uint8Array(e.size) });
|
|
255
|
+
}
|
|
256
|
+
function It(t) {
|
|
257
|
+
const e = t.length, i = new Float32Array(e);
|
|
258
|
+
for (let l = 0; l < e; l += 3)
|
|
259
|
+
i[l] = t[l], i[l + 1] = t[l + 2], i[l + 2] = -t[l + 1];
|
|
260
|
+
let n = 1 / 0, o = 1 / 0, r = 1 / 0, c = -1 / 0, a = -1 / 0, s = -1 / 0;
|
|
261
|
+
for (let l = 0; l < e; l += 3)
|
|
262
|
+
n = Math.min(n, i[l]), c = Math.max(c, i[l]), o = Math.min(o, i[l + 1]), a = Math.max(a, i[l + 1]), r = Math.min(r, i[l + 2]), s = Math.max(s, i[l + 2]);
|
|
263
|
+
const p = (n + c) / 2, u = (r + s) / 2;
|
|
264
|
+
for (let l = 0; l < e; l += 3)
|
|
265
|
+
i[l] -= p, i[l + 1] -= o, i[l + 2] -= u;
|
|
266
|
+
return { localPos: i, size: { w: c - n, d: s - r, h: a - o } };
|
|
267
|
+
}
|
|
268
|
+
function xt(t) {
|
|
269
|
+
const e = new Float32Array(t.length), i = t;
|
|
270
|
+
for (let n = 0; n < i.length; n += 9) {
|
|
271
|
+
const o = i[n], r = i[n + 1], c = i[n + 2], a = i[n + 3], s = i[n + 4], p = i[n + 5], u = i[n + 6] - a, l = i[n + 7] - s, h = i[n + 8] - p, m = o - a, w = r - s, M = c - p;
|
|
272
|
+
e[n] = l * M - h * w, e[n + 1] = h * m - u * M, e[n + 2] = u * w - l * m;
|
|
273
|
+
const S = e[n], A = e[n + 1], k = e[n + 2], F = 1 / (Math.sqrt(S * S + A * A + k * k) || 1);
|
|
274
|
+
e[n] = S * F, e[n + 1] = A * F, e[n + 2] = k * F, e[n + 3] = e[n + 6] = e[n], e[n + 4] = e[n + 7] = e[n + 1], e[n + 5] = e[n + 8] = e[n + 2];
|
|
275
|
+
}
|
|
276
|
+
return e;
|
|
277
|
+
}
|
|
278
|
+
function Pt(t) {
|
|
279
|
+
const e = [1 / 0, 1 / 0, 1 / 0], i = [-1 / 0, -1 / 0, -1 / 0];
|
|
280
|
+
for (let n = 0; n < t.length; n += 3)
|
|
281
|
+
for (let o = 0; o < 3; o++) {
|
|
282
|
+
const r = t[n + o];
|
|
283
|
+
r < e[o] && (e[o] = r), r > i[o] && (i[o] = r);
|
|
284
|
+
}
|
|
285
|
+
return { min: e, max: i };
|
|
286
|
+
}
|
|
287
|
+
function zt(t, e) {
|
|
288
|
+
const i = [0, 0, 0];
|
|
289
|
+
if (!(e.max[0] < e.min[0] || e.max[1] < e.min[1] || e.max[2] < e.min[2])) for (let r = 0; r < 3; r++) i[r] = (e.min[r] + e.max[r]) * 0.5;
|
|
290
|
+
let o = 0;
|
|
291
|
+
for (let r = 0; r < t.length; r += 3) {
|
|
292
|
+
const c = i[0] - t[r], a = i[1] - t[r + 1], s = i[2] - t[r + 2];
|
|
293
|
+
o = Math.max(o, c * c + a * a + s * s);
|
|
294
|
+
}
|
|
295
|
+
return { center: i, radius: Math.sqrt(o) };
|
|
296
|
+
}
|
|
297
|
+
function St(t) {
|
|
298
|
+
const { localPos: e, size: i } = It(t), n = Pt(e);
|
|
299
|
+
return { localPos: e, size: i, normals: xt(e), bounds: n, sphere: zt(e, n) };
|
|
300
|
+
}
|
|
301
|
+
function Tt(t) {
|
|
302
|
+
return new Promise((e) => {
|
|
303
|
+
let i = !1;
|
|
304
|
+
const n = (o) => {
|
|
305
|
+
i || (i = !0, e(o));
|
|
306
|
+
};
|
|
307
|
+
try {
|
|
308
|
+
mt(t, (o, r) => {
|
|
309
|
+
n(o ? Y(t) : r);
|
|
310
|
+
});
|
|
311
|
+
} catch {
|
|
312
|
+
n(Y(t));
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
const At = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0];
|
|
317
|
+
function ct(t, e) {
|
|
318
|
+
const i = new Array(12);
|
|
319
|
+
for (let n = 0; n < 4; n++)
|
|
320
|
+
for (let o = 0; o < 3; o++) {
|
|
321
|
+
let r = 0;
|
|
322
|
+
n === 3 && (r = e[9 + o]), i[n * 3 + o] = t[n * 3] * e[o] + t[n * 3 + 1] * e[3 + o] + t[n * 3 + 2] * e[6 + o] + r;
|
|
323
|
+
}
|
|
324
|
+
return i;
|
|
325
|
+
}
|
|
326
|
+
const Z = {};
|
|
327
|
+
function D(t, e) {
|
|
328
|
+
return (Z[e] || (Z[e] = new RegExp(`\\b${e}\\s*=\\s*"([^"]*)"`))).exec(t)?.[1] ?? null;
|
|
329
|
+
}
|
|
330
|
+
function R(t) {
|
|
331
|
+
const e = String(t).replace(/^\/+/, "");
|
|
332
|
+
return e.includes("%") ? decodeURIComponent(e) : e;
|
|
333
|
+
}
|
|
334
|
+
function J(t) {
|
|
335
|
+
const e = {};
|
|
336
|
+
for (const i of t.match(/<metadata\b[^>]*>/g) || []) {
|
|
337
|
+
const n = D(i, "key");
|
|
338
|
+
n && (e[n] = D(i, "value") ?? "");
|
|
339
|
+
}
|
|
340
|
+
return e;
|
|
341
|
+
}
|
|
342
|
+
function Ot(t) {
|
|
343
|
+
const e = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), n = /<object\b([^>]*)>([\s\S]*?)<\/object>/g;
|
|
344
|
+
let o;
|
|
345
|
+
for (; o = n.exec(t); ) {
|
|
346
|
+
const a = D(o[1], "id");
|
|
347
|
+
if (a) {
|
|
348
|
+
const s = o[2];
|
|
349
|
+
e.set(a, J(s.replace(/<(?:part|volume)\b[\s\S]*?<\/(?:part|volume)>/g, "")));
|
|
350
|
+
const p = [];
|
|
351
|
+
for (const u of s.match(/<volume\b[\s\S]*?<\/volume>/g) || []) {
|
|
352
|
+
const l = J(u).volume_type, h = l === "SupportBlocker" ? "blocker" : l === "SupportEnforcer" ? "enforcer" : null, m = Number(D(u, "firstid")), w = Number(D(u, "lastid"));
|
|
353
|
+
h && Number.isInteger(m) && Number.isInteger(w) && m >= 0 && w >= m && p.push({ firstTriangle: m, lastTriangle: w, kind: h });
|
|
354
|
+
}
|
|
355
|
+
p.length && i.set(a, p);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const r = [], c = /<plate\b[^>]*>([\s\S]*?)<\/plate>/g;
|
|
359
|
+
for (; o = c.exec(t); ) {
|
|
360
|
+
const a = o[1], s = J(a.replace(/<model_instance\b[\s\S]*?<\/model_instance>/g, "")), p = [];
|
|
361
|
+
for (const u of a.match(/<model_instance\b[\s\S]*?<\/model_instance>/g) || []) {
|
|
362
|
+
const l = J(u).object_id;
|
|
363
|
+
l && p.push(l);
|
|
364
|
+
}
|
|
365
|
+
r.push({ index: Math.max(0, (Number(s.plater_id) || r.length + 1) - 1), objectIds: p, gcodeFile: s.gcode_file || null });
|
|
366
|
+
}
|
|
367
|
+
return { objects: e, plates: r, volumes: i };
|
|
368
|
+
}
|
|
369
|
+
const Nt = Object.freeze({
|
|
370
|
+
manualSupportPoints: "prepared-roundtrip",
|
|
371
|
+
drainHoles: "preserved-unsupported",
|
|
372
|
+
modifierVolumes: "prepared-mask-filtering",
|
|
373
|
+
uiEditing: "unavailable"
|
|
374
|
+
});
|
|
375
|
+
function y(t, e, i, n, o) {
|
|
376
|
+
const r = /* @__PURE__ */ new Map();
|
|
377
|
+
if (!t?.trim()) return r;
|
|
378
|
+
const c = t.trim().split(/\r?\n/), a = new RegExp(`^${e}_format_version=(\\d+)$`).exec(c[0]), s = a ? Number(a[1]) : 0;
|
|
379
|
+
for (const p of c.slice(a ? 1 : 0)) {
|
|
380
|
+
const u = /^object_id=(\d+)\|(.*)$/.exec(p);
|
|
381
|
+
if (!u || r.has(Number(u?.[1]))) continue;
|
|
382
|
+
const l = Number(u[1]), h = u[2].trim() ? u[2].trim().split(/\s+/).map(Number) : [], m = i(s);
|
|
383
|
+
if (!m || h.length % m !== 0 || h.some((M) => !Number.isFinite(M))) {
|
|
384
|
+
n.push({ code: e === "support_points" ? "SLA_SUPPORT_POINT_COUNT" : "SLA_DRAIN_HOLE_COUNT", object: l }), r.set(l, []);
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const w = [];
|
|
388
|
+
for (let M = 0; M < h.length; M += m) w.push(o(h.slice(M, M + m), s));
|
|
389
|
+
r.set(l, w);
|
|
390
|
+
}
|
|
391
|
+
return r;
|
|
392
|
+
}
|
|
393
|
+
function tt(t, e) {
|
|
394
|
+
const [i, n, o] = e;
|
|
395
|
+
return [i * t[0] + n * t[3] + o * t[6] + t[9], i * t[1] + n * t[4] + o * t[7] + t[10], i * t[2] + n * t[5] + o * t[8] + t[11]];
|
|
396
|
+
}
|
|
397
|
+
function kt(t, e) {
|
|
398
|
+
const [i, n, o] = e, r = [i * t[0] + n * t[3] + o * t[6], i * t[1] + n * t[4] + o * t[7], i * t[2] + n * t[5] + o * t[8]], c = Math.hypot(...r);
|
|
399
|
+
return c ? r.map((a) => a / c) : r;
|
|
400
|
+
}
|
|
401
|
+
function Lt(t, e) {
|
|
402
|
+
const i = (s) => {
|
|
403
|
+
const p = t.get(s);
|
|
404
|
+
return p ? e.decode(p) : null;
|
|
405
|
+
}, n = {
|
|
406
|
+
settings: null,
|
|
407
|
+
// Metadata/project_settings.config — the flattened preset (raw upstream strings)
|
|
408
|
+
objectMeta: /* @__PURE__ */ new Map(),
|
|
409
|
+
// 3mf object id -> per-object metadata (name, extruder, per-object overrides)
|
|
410
|
+
plates: [],
|
|
411
|
+
// [{index, objectIds}]
|
|
412
|
+
hasLayerHeightProfile: !1,
|
|
413
|
+
hasCustomGcodePerLayer: !1,
|
|
414
|
+
volumeMeta: /* @__PURE__ */ new Map(),
|
|
415
|
+
sla: { capabilities: { ...Nt }, issues: [], supportPoints: /* @__PURE__ */ new Map(), drainHoles: /* @__PURE__ */ new Map() },
|
|
416
|
+
viewerSettings: null,
|
|
417
|
+
// Metadata/three_slicer_settings.json — this package's own member (write_3mf.js)
|
|
418
|
+
plateSettings: null,
|
|
419
|
+
// ...its two halves: global viewer knobs, and per-plate overrides keyed by plate index
|
|
420
|
+
plateCount: null,
|
|
421
|
+
// ...and the plate count it was saved with (empty plates hold no <plate> record)
|
|
422
|
+
gcodePlates: null
|
|
423
|
+
// a .gcode.3mf's sliced plates: [{index, gcode}] (write_3mf.js writeGcode3MF), else null
|
|
424
|
+
}, o = i("Metadata/project_settings.config");
|
|
425
|
+
if (o)
|
|
426
|
+
try {
|
|
427
|
+
n.settings = JSON.parse(o);
|
|
428
|
+
} catch {
|
|
429
|
+
n.settings = null;
|
|
430
|
+
}
|
|
431
|
+
const r = i("Metadata/three_slicer_settings.json");
|
|
432
|
+
if (r) {
|
|
433
|
+
let s = null;
|
|
434
|
+
try {
|
|
435
|
+
s = JSON.parse(r);
|
|
436
|
+
} catch {
|
|
437
|
+
s = null;
|
|
438
|
+
}
|
|
439
|
+
const p = (u) => u && typeof u == "object" && !Array.isArray(u);
|
|
440
|
+
if (p(s)) {
|
|
441
|
+
p(s.viewer) && Object.keys(s.viewer).length && (n.viewerSettings = s.viewer);
|
|
442
|
+
let u = [];
|
|
443
|
+
p(s.plates) && (u = Object.entries(s.plates));
|
|
444
|
+
const l = u.filter(([h, m]) => /^\d+$/.test(h) && p(m) && Object.keys(m).length);
|
|
445
|
+
l.length && (n.plateSettings = Object.fromEntries(l.map(([h, m]) => [Number(h), m]))), Number.isInteger(s.plateCount) && s.plateCount >= 1 && (n.plateCount = s.plateCount);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const c = i("Metadata/model_settings.config");
|
|
449
|
+
if (c) {
|
|
450
|
+
const s = Ot(c);
|
|
451
|
+
n.objectMeta = s.objects, n.plates = s.plates, n.volumeMeta = s.volumes;
|
|
452
|
+
}
|
|
453
|
+
const a = n.plates.map((s) => ({ index: s.index, gcode: s.gcodeFile && i(R(s.gcodeFile)) })).filter((s) => s.gcode);
|
|
454
|
+
return a.length && (n.gcodePlates = a), n.sla.supportPoints = y(
|
|
455
|
+
i("Metadata/Slic3r_PE_sla_support_points.txt"),
|
|
456
|
+
"support_points",
|
|
457
|
+
(s) => s === 0 ? 3 : s === 1 ? 5 : 0,
|
|
458
|
+
n.sla.issues,
|
|
459
|
+
(s, p) => ({
|
|
460
|
+
position: s.slice(0, 3),
|
|
461
|
+
radius: p === 0 ? ht : s[3],
|
|
462
|
+
type: p === 0 || s[4] === 2 ? "manual" : s[4] === 1 ? "island" : "slope"
|
|
463
|
+
})
|
|
464
|
+
), n.sla.drainHoles = y(
|
|
465
|
+
i("Metadata/Slic3r_PE_sla_drain_holes.txt"),
|
|
466
|
+
"drain_holes",
|
|
467
|
+
(s) => s === 1 ? 8 : 0,
|
|
468
|
+
n.sla.issues,
|
|
469
|
+
(s) => {
|
|
470
|
+
const p = Math.hypot(s[3], s[4], s[5]), u = p ? s.slice(3, 6).map((l) => l / p) : s.slice(3, 6);
|
|
471
|
+
return { position: s.slice(0, 3).map((l, h) => l + u[h]), normal: u, radius: s[6], height: s[7] - 1 };
|
|
472
|
+
}
|
|
473
|
+
), n.hasLayerHeightProfile = !!i("Metadata/layer_heights_profile.txt")?.trim(), n.hasCustomGcodePerLayer = !!i("Metadata/custom_gcode_per_layer.xml")?.trim(), n;
|
|
474
|
+
}
|
|
475
|
+
const et = Symbol("part not in job");
|
|
476
|
+
function X(t, e, i, n, o, r) {
|
|
477
|
+
if (n > 16) return;
|
|
478
|
+
const c = o(e)?.objects.get(t);
|
|
479
|
+
if (c) {
|
|
480
|
+
if (c.components) {
|
|
481
|
+
for (const a of c.components) X(a.objectid, a.path || e, ct(a.transform, i), n + 1, o, r);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
c.mesh && r(c.mesh, i);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function at(t, e) {
|
|
488
|
+
let i = 0;
|
|
489
|
+
for (const c of t) X(c.objectid, c.path, c.xf, c.depth, e, (a) => {
|
|
490
|
+
i += a.tris.length * 3;
|
|
491
|
+
});
|
|
492
|
+
const n = new Float32Array(i), o = it();
|
|
493
|
+
let r = 0;
|
|
494
|
+
for (const c of t) X(c.objectid, c.path, c.xf, c.depth, e, ({ verts: a, tris: s, paint: p }, u) => {
|
|
495
|
+
const l = r / 9;
|
|
496
|
+
for (let h = 0; h < s.length; h++) {
|
|
497
|
+
const m = s[h] * 3, w = a[m], M = a[m + 1], S = a[m + 2];
|
|
498
|
+
n[r] = w * u[0] + M * u[3] + S * u[6] + u[9], n[r + 1] = w * u[1] + M * u[4] + S * u[7] + u[10], n[r + 2] = w * u[2] + M * u[5] + S * u[8] + u[11], r += 3;
|
|
499
|
+
}
|
|
500
|
+
for (const [, h] of G)
|
|
501
|
+
for (const [m, w] of p[h]) o[h].set(l + m, w);
|
|
502
|
+
});
|
|
503
|
+
return { sink: n, paintSink: o };
|
|
504
|
+
}
|
|
505
|
+
function lt({ sink: t, paintSink: e }, i, n) {
|
|
506
|
+
if (t.length < 9) return null;
|
|
507
|
+
let o = t;
|
|
508
|
+
const r = [];
|
|
509
|
+
if (i.length) {
|
|
510
|
+
const h = /* @__PURE__ */ new Set();
|
|
511
|
+
for (let m = 0; m < i.length; m++) {
|
|
512
|
+
const w = i[m], M = w.firstTriangle * 9, S = Math.min(t.length, (w.lastTriangle + 1) * 9);
|
|
513
|
+
if (!(M >= S)) {
|
|
514
|
+
for (let A = w.firstTriangle; A <= w.lastTriangle; A++) h.add(A);
|
|
515
|
+
r.push({ volume: m, kind: w.kind, tris: t.slice(M, S) });
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (h.size) {
|
|
519
|
+
const m = new Float32Array(t.length - [...h].filter((M) => M < t.length / 9).length * 9);
|
|
520
|
+
let w = 0;
|
|
521
|
+
for (let M = 0; M < t.length / 9; M++)
|
|
522
|
+
h.has(M) || (m.set(t.subarray(M * 9, M * 9 + 9), w), w += 9);
|
|
523
|
+
o = m;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
let c = 1 / 0, a = 1 / 0, s = -1 / 0, p = -1 / 0;
|
|
527
|
+
for (let h = 0; h < o.length; h += 3) {
|
|
528
|
+
const m = o[h], w = o[h + 1];
|
|
529
|
+
m < c && (c = m), m > s && (s = m), w < a && (a = w), w > p && (p = w);
|
|
530
|
+
}
|
|
531
|
+
let u = e;
|
|
532
|
+
jt(e) && (u = null);
|
|
533
|
+
const l = { tris: o, paint: u, modifiers: r, bbox: { minX: c, minY: a, maxX: s, maxY: p } };
|
|
534
|
+
return n && (l.baked = St(o)), l;
|
|
535
|
+
}
|
|
536
|
+
async function vt(t) {
|
|
537
|
+
const e = /* @__PURE__ */ new Map();
|
|
538
|
+
await Promise.all(t.members.map(async (o) => {
|
|
539
|
+
e.set(o.path, W(await st(o.data, o.entry)));
|
|
540
|
+
}));
|
|
541
|
+
const i = new Set(t.names), n = (o) => {
|
|
542
|
+
const r = R(o);
|
|
543
|
+
if (e.has(r)) return e.get(r);
|
|
544
|
+
if (i.has(r)) throw et;
|
|
545
|
+
return null;
|
|
546
|
+
};
|
|
547
|
+
return {
|
|
548
|
+
items: t.items.map((o) => {
|
|
549
|
+
try {
|
|
550
|
+
return { index: o.index, built: lt(at(o.refs, n), o.volumeRecords, t.bake) };
|
|
551
|
+
} catch (r) {
|
|
552
|
+
if (r === et) return { index: o.index, local: !0 };
|
|
553
|
+
throw r;
|
|
554
|
+
}
|
|
555
|
+
})
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
const Rt = (t) => Promise.all(t.map(vt));
|
|
559
|
+
async function Ft(t) {
|
|
560
|
+
const e = _t(t);
|
|
561
|
+
if (!e) {
|
|
562
|
+
const o = /* @__PURE__ */ new Map(), r = await Tt(t);
|
|
563
|
+
for (const c of Object.keys(r)) o.set(R(c), r[c]);
|
|
564
|
+
return { names: [...o.keys()], entry: () => null, read: async (c) => o.get(c) ?? null };
|
|
565
|
+
}
|
|
566
|
+
const i = /* @__PURE__ */ new Map();
|
|
567
|
+
for (const [o, r] of e) i.set(R(o), r);
|
|
568
|
+
const n = /* @__PURE__ */ new Map();
|
|
569
|
+
return {
|
|
570
|
+
names: [...i.keys()],
|
|
571
|
+
entry: (o) => i.get(o) ?? null,
|
|
572
|
+
read: (o) => {
|
|
573
|
+
const r = i.get(o);
|
|
574
|
+
return r ? (n.has(o) || n.set(o, st(rt(t, r), r)), n.get(o)) : Promise.resolve(null);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
const nt = (t) => t.toLowerCase().endsWith(".model");
|
|
579
|
+
async function Et(t, e = "model", { runJobs: i = Rt, bake: n = !1 } = {}) {
|
|
580
|
+
let o = new Uint8Array(t);
|
|
581
|
+
ArrayBuffer.isView(t) && (o = new Uint8Array(t.buffer, t.byteOffset, t.byteLength));
|
|
582
|
+
const r = await Ft(o), c = new TextDecoder(), a = /* @__PURE__ */ new Map();
|
|
583
|
+
await Promise.all(r.names.filter((j) => !nt(j)).map(async (j) => a.set(j, await r.read(j))));
|
|
584
|
+
let s = "3D/3dmodel.model";
|
|
585
|
+
const p = a.get("_rels/.rels");
|
|
586
|
+
if (p) {
|
|
587
|
+
for (const j of c.decode(p).match(/<Relationship\b[^>]*>/g) || [])
|
|
588
|
+
if ((D(j, "Type") || "").endsWith("/3dmodel")) {
|
|
589
|
+
s = R(D(j, "Target"));
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
const u = Lt(a, c), l = await r.read(s), h = l && W(l);
|
|
594
|
+
if (!h && u.gcodePlates) return { objects: [], project: u };
|
|
595
|
+
if (!h) throw new Error(`3MF root model not found: ${s}`);
|
|
596
|
+
let m = h.items;
|
|
597
|
+
m.length || (m = [...h.objects.keys()].filter((j) => h.objects.get(j).mesh).map((j) => ({ objectid: j, path: s, transform: At })));
|
|
598
|
+
const w = [], M = /* @__PURE__ */ new Map(), S = [], A = (j) => {
|
|
599
|
+
const P = m[j];
|
|
600
|
+
return { index: j, refs: [{ objectid: P.objectid, path: P.path || s, xf: P.transform, depth: 0 }], volumeRecords: u.volumeMeta.get(P.objectid) || [] };
|
|
601
|
+
};
|
|
602
|
+
m.forEach((j, P) => {
|
|
603
|
+
const _ = j.path || s, x = u.volumeMeta.get(j.objectid) || [];
|
|
604
|
+
let g = [{ objectid: j.objectid, path: _, xf: j.transform, depth: 0 }];
|
|
605
|
+
if (R(_) === s) {
|
|
606
|
+
const f = h.objects.get(j.objectid);
|
|
607
|
+
f?.components && (g = f.components.map((d) => ({ objectid: d.objectid, path: d.path || _, xf: ct(d.transform, j.transform), depth: 1 })));
|
|
608
|
+
}
|
|
609
|
+
const z = [...new Set(g.map((f) => R(f.path)))];
|
|
610
|
+
if (z.some((f) => f === s || !r.entry(f))) {
|
|
611
|
+
S.push(A(P));
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
let I = z.map((f) => M.get(f)).find(Boolean);
|
|
615
|
+
I || (I = { parts: /* @__PURE__ */ new Set(), items: [] }, w.push(I));
|
|
616
|
+
for (const f of z) {
|
|
617
|
+
const d = M.get(f);
|
|
618
|
+
if (d && d !== I) {
|
|
619
|
+
for (const E of d.parts)
|
|
620
|
+
I.parts.add(E), M.set(E, I);
|
|
621
|
+
I.items.push(...d.items), w.splice(w.indexOf(d), 1);
|
|
622
|
+
}
|
|
623
|
+
I.parts.add(f), M.set(f, I);
|
|
624
|
+
}
|
|
625
|
+
I.items.push({ index: P, refs: g, volumeRecords: x });
|
|
626
|
+
});
|
|
627
|
+
const k = new Array(m.length).fill(null), F = w.map((j) => ({
|
|
628
|
+
members: [...j.parts].map((P) => {
|
|
629
|
+
const _ = r.entry(P);
|
|
630
|
+
return { path: P, data: rt(o, _).slice(), entry: { method: _.method, size: _.size } };
|
|
631
|
+
}),
|
|
632
|
+
names: r.names,
|
|
633
|
+
items: j.items,
|
|
634
|
+
bake: n
|
|
635
|
+
})).sort((j, P) => P.members.reduce((_, x) => _ + x.data.length, 0) - j.members.reduce((_, x) => _ + x.data.length, 0));
|
|
636
|
+
for (const j of await i(F))
|
|
637
|
+
for (const P of j.items)
|
|
638
|
+
P.local ? S.push(A(P.index)) : k[P.index] = P.built;
|
|
639
|
+
if (S.length) {
|
|
640
|
+
const j = /* @__PURE__ */ new Map([[s, h]]);
|
|
641
|
+
for (const _ of r.names) nt(_) && _ !== s && j.set(_, W(await r.read(_)));
|
|
642
|
+
const P = (_) => j.get(R(_)) ?? null;
|
|
643
|
+
for (const _ of S) k[_.index] = lt(at(_.refs, P), _.volumeRecords, n);
|
|
644
|
+
}
|
|
645
|
+
const b = [];
|
|
646
|
+
return m.forEach((j, P) => {
|
|
647
|
+
const _ = k[P];
|
|
648
|
+
if (!_) return;
|
|
649
|
+
const x = (u.sla.supportPoints.get(P + 1) || []).map((d) => ({ ...d, position: tt(j.transform, d.position) })), g = (u.sla.drainHoles.get(P + 1) || []).map((d) => ({
|
|
650
|
+
...d,
|
|
651
|
+
position: tt(j.transform, d.position),
|
|
652
|
+
normal: kt(j.transform, d.normal)
|
|
653
|
+
})), z = _.modifiers.map(({ volume: d, kind: E, tris: L }) => ({ id: `${j.objectid}:modifier:${d}`, kind: E, tris: L }));
|
|
654
|
+
let I = e;
|
|
655
|
+
m.length > 1 && (I = `${e}#${P + 1}`);
|
|
656
|
+
const f = { name: I, tris: _.tris, objectid: j.objectid, paint: _.paint, sla: { supportPoints: x, drainHoles: g, modifierVolumes: z }, bbox: _.bbox };
|
|
657
|
+
_.baked && (f.baked = _.baked), b.push(f);
|
|
658
|
+
}), { objects: b, project: u };
|
|
659
|
+
}
|
|
660
|
+
export {
|
|
661
|
+
Pt as a,
|
|
662
|
+
St as b,
|
|
663
|
+
xt as f,
|
|
664
|
+
Et as p,
|
|
665
|
+
vt as r
|
|
666
|
+
};
|