ldr 0.33.1 → 0.33.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/README.md +1 -1
- package/dist/cli.js +347 -81
- package/dist/cull.d.ts +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +208 -67
- package/dist/load-worker.gen.d.ts +1 -1
- package/dist/model.d.ts +12 -1
- package/dist/node/build-pack.d.ts +4 -1
- package/dist/node/compile.d.ts +8 -0
- package/dist/node/index.js +490 -124
- package/dist/node/library.d.ts +10 -0
- package/dist/spec.d.ts +16 -0
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/cli.ts
|
|
4
4
|
import fs4 from "node:fs";
|
|
5
5
|
import zlib from "node:zlib";
|
|
6
6
|
|
|
7
|
-
// ../../../../../../../tmp/ldr-build-
|
|
7
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/build-pack.ts
|
|
8
8
|
import fs3 from "node:fs";
|
|
9
9
|
import path3 from "node:path";
|
|
10
10
|
|
|
11
|
-
// ../../../../../../../tmp/ldr-build-
|
|
11
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/resolver.ts
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
|
|
15
|
-
// ../../../../../../../tmp/ldr-build-
|
|
15
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/spec.ts
|
|
16
16
|
var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
17
17
|
var COLOUR_ID_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
18
18
|
var namedCodes = new Map;
|
|
@@ -39,6 +39,8 @@ function parseColor(tok) {
|
|
|
39
39
|
}
|
|
40
40
|
var MOVED_RE = /^~?\s*moved\s+to\s+(.+)$/i;
|
|
41
41
|
var SPECIAL0 = new Set(["FILE", "NOFILE", "!DATA", "!:", "STEP", "BFC", "ROTSTEP", "BUFEXCHG", "!TEXMAP"]);
|
|
42
|
+
var BLOCK0 = new Set(["FILE", "NOFILE", "!DATA"]);
|
|
43
|
+
var MAX_COORD = 1000000000000000;
|
|
42
44
|
var PART_ORG = new Set(["part", "subpart", "primitive", "8_primitive", "48_primitive", "shortcut", "helper"]);
|
|
43
45
|
var MODEL_ORG = new Set(["model", "submodel", "configuration"]);
|
|
44
46
|
var ORG_RE = /^(?:!?LDRAW_ORG|Unofficial|Official\s+LCAD)\s+(\S+)/i;
|
|
@@ -89,7 +91,9 @@ function parseTexMap(tail, next = false) {
|
|
|
89
91
|
if (parts.length < n + 1)
|
|
90
92
|
return null;
|
|
91
93
|
const v = parts.slice(0, n).map(Number);
|
|
92
|
-
if (!v.every(Number.isFinite))
|
|
94
|
+
if (!v.every((x) => Number.isFinite(x) && Math.abs(x) <= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))
|
|
95
|
+
return null;
|
|
96
|
+
if (n >= 10 && !(Math.abs(v[9]) >= 0.000001) || n === 11 && !(Math.abs(v[10]) >= 0.000001))
|
|
93
97
|
return null;
|
|
94
98
|
let rest = m[2].trim();
|
|
95
99
|
for (let k = 0;k < n; k++)
|
|
@@ -110,7 +114,9 @@ function parseTexMap(tail, next = false) {
|
|
|
110
114
|
return t;
|
|
111
115
|
}
|
|
112
116
|
var b64 = (s) => {
|
|
113
|
-
|
|
117
|
+
let clean = s.replace(/[^A-Za-z0-9+/]/g, "");
|
|
118
|
+
if (clean.length % 4 === 1)
|
|
119
|
+
clean = clean.slice(0, -1);
|
|
114
120
|
const pad = clean + "=".repeat((4 - clean.length % 4) % 4);
|
|
115
121
|
const bin = atob(pad);
|
|
116
122
|
const out = new Uint8Array(bin.length);
|
|
@@ -138,7 +144,10 @@ function type1Fast(line) {
|
|
|
138
144
|
const t = next();
|
|
139
145
|
if (t === null)
|
|
140
146
|
return null;
|
|
141
|
-
|
|
147
|
+
const v = +t;
|
|
148
|
+
if (!Number.isFinite(v))
|
|
149
|
+
return null;
|
|
150
|
+
m[k] = v;
|
|
142
151
|
}
|
|
143
152
|
while (i < n && ws(line.charCodeAt(i)))
|
|
144
153
|
i++;
|
|
@@ -146,23 +155,37 @@ function type1Fast(line) {
|
|
|
146
155
|
return null;
|
|
147
156
|
const rest = line.slice(i);
|
|
148
157
|
const file = /[ \t]{2,}|\t/.test(rest) ? rest.split(/\s+/).join(" ") : rest;
|
|
149
|
-
|
|
158
|
+
const color = parseColor(ct);
|
|
159
|
+
if (!Number.isFinite(color))
|
|
160
|
+
return null;
|
|
161
|
+
return { t: 1, color, m, file: norm(file) };
|
|
150
162
|
}
|
|
163
|
+
var NUMS = [0, 12, 6, 9, 12, 12];
|
|
151
164
|
function geomLine(tk) {
|
|
152
165
|
const t = +tk[0];
|
|
153
|
-
if (!(t >= 1 && t <= 5) || tk.length < 2)
|
|
166
|
+
if (!(t >= 1 && t <= 5 && Number.isInteger(t)) || tk.length < 2)
|
|
154
167
|
return null;
|
|
155
|
-
const color = parseColor(tk[1]);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
168
|
+
const color = parseColor(tk[1]), n = NUMS[t];
|
|
169
|
+
if (!Number.isFinite(color) || tk.length < 2 + n + (t === 1 ? 1 : 0))
|
|
170
|
+
return null;
|
|
171
|
+
const nums = new Array(n);
|
|
172
|
+
for (let k = 0;k < n; k++) {
|
|
173
|
+
const v = +tk[2 + k];
|
|
174
|
+
if (!Number.isFinite(v))
|
|
175
|
+
return null;
|
|
176
|
+
nums[k] = v;
|
|
177
|
+
}
|
|
178
|
+
if (t === 1) {
|
|
179
|
+
const file = norm(tk.slice(14).join(" "));
|
|
180
|
+
return file ? { t: 1, color, m: nums, file } : null;
|
|
181
|
+
}
|
|
159
182
|
if (t === 2)
|
|
160
|
-
return { t: 2, color, p: nums
|
|
183
|
+
return { t: 2, color, p: nums };
|
|
161
184
|
if (t === 3)
|
|
162
|
-
return { t: 3, color, p: nums
|
|
185
|
+
return { t: 3, color, p: nums };
|
|
163
186
|
if (t === 4)
|
|
164
|
-
return { t: 4, color, p: nums
|
|
165
|
-
return { t: 5, color, p: nums
|
|
187
|
+
return { t: 4, color, p: nums };
|
|
188
|
+
return { t: 5, color, p: nums };
|
|
166
189
|
}
|
|
167
190
|
function parse(src, name = "main.ldr", popts = {}) {
|
|
168
191
|
const gtext = !!popts.geometryText;
|
|
@@ -242,7 +265,8 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
242
265
|
while (b < line.length && line.charCodeAt(b) !== 32 && line.charCodeAt(b) !== 9)
|
|
243
266
|
b++;
|
|
244
267
|
const kw = line.slice(a, b);
|
|
245
|
-
|
|
268
|
+
const k2 = /[^\x21-\x7e]/.test(kw) ? line.slice(a).trim().split(/\s+/)[0] : kw;
|
|
269
|
+
if (!SPECIAL0.has(k2) && !(k2.length >= 4 && k2.length <= 6 && BLOCK0.has(k2.toUpperCase()))) {
|
|
246
270
|
if (skip || dataCur)
|
|
247
271
|
continue;
|
|
248
272
|
if (!cur)
|
|
@@ -283,19 +307,23 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
283
307
|
const t = +tk[0];
|
|
284
308
|
if (t === 0) {
|
|
285
309
|
const text = line.slice(1).trim();
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
310
|
+
const k1 = tk.length > 1 && tk[1].length >= 4 && tk[1].length <= 6 ? tk[1].toUpperCase() : tk[1];
|
|
311
|
+
if (k1 === "FILE") {
|
|
312
|
+
const fn = text.slice(5).trimStart().split("\r")[0].trim();
|
|
313
|
+
if (fn) {
|
|
314
|
+
firstBlock();
|
|
315
|
+
skip = false;
|
|
316
|
+
start(fn);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
291
319
|
}
|
|
292
|
-
if (
|
|
320
|
+
if (k1 === "NOFILE") {
|
|
293
321
|
closeData();
|
|
294
322
|
cur = null;
|
|
295
323
|
skip = true;
|
|
296
324
|
continue;
|
|
297
325
|
}
|
|
298
|
-
if (
|
|
326
|
+
if (k1 === "!DATA") {
|
|
299
327
|
firstBlock();
|
|
300
328
|
closeData();
|
|
301
329
|
cur = null;
|
|
@@ -328,7 +356,11 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
328
356
|
c.rotstep = { x: 0, y: 0, z: 0, mode: "END" };
|
|
329
357
|
else {
|
|
330
358
|
const mode = (tk[5] ?? "REL").toUpperCase();
|
|
331
|
-
|
|
359
|
+
const ang = (s) => {
|
|
360
|
+
const v = Number(s);
|
|
361
|
+
return Number.isFinite(v) ? v : 0;
|
|
362
|
+
};
|
|
363
|
+
c.rotstep = { x: ang(tk[2]), y: ang(tk[3]), z: ang(tk[4]), mode: ["REL", "ABS", "ADD"].includes(mode) ? mode : "REL" };
|
|
332
364
|
}
|
|
333
365
|
} else if (tk[1] === "BUFEXCHG") {
|
|
334
366
|
c.meta = "BUFEXCHG";
|
|
@@ -387,8 +419,11 @@ function parse(src, name = "main.ldr", popts = {}) {
|
|
|
387
419
|
if (!cur)
|
|
388
420
|
start(name);
|
|
389
421
|
const g = geomLine(tk);
|
|
390
|
-
if (!g)
|
|
422
|
+
if (!g) {
|
|
423
|
+
if (/^[2-5][ \t]/.test(line))
|
|
424
|
+
inHeader = false;
|
|
391
425
|
continue;
|
|
426
|
+
}
|
|
392
427
|
annotate(g, false);
|
|
393
428
|
cur.cmds.push(g);
|
|
394
429
|
inHeader = false;
|
|
@@ -463,12 +498,18 @@ function texmapTriangleUV(map, pts) {
|
|
|
463
498
|
} else {
|
|
464
499
|
const pd = unit3(sub3(p, p1));
|
|
465
500
|
const c = dot3(pd, n);
|
|
501
|
+
const q = radial(p, p1, n);
|
|
466
502
|
if (Math.abs(c) > 1 - 0.000000001) {
|
|
467
503
|
miss.push(i);
|
|
468
504
|
out[i * 2 + 1] = 0.5 + (c > 0 ? -Math.PI / 2 : Math.PI / 2) / B;
|
|
469
505
|
return;
|
|
470
506
|
}
|
|
471
|
-
|
|
507
|
+
if (!q) {
|
|
508
|
+
miss.push(i);
|
|
509
|
+
out[i * 2 + 1] = 0.5;
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const a = sAng(q);
|
|
472
513
|
uSum += a;
|
|
473
514
|
out[i * 2] = 0.5 + a / A;
|
|
474
515
|
const th = -a, ct = Math.cos(th), st = Math.sin(th), cr = cross3(n, pd), k = dot3(n, pd) * (1 - ct);
|
|
@@ -543,18 +584,48 @@ function smoothNormals(pos, edges, cond, creaseDeg = 35) {
|
|
|
543
584
|
};
|
|
544
585
|
for (const [key, corners] of byV) {
|
|
545
586
|
const faces = corners.map((c) => c / 3 | 0), par = faces.map((_, i) => i);
|
|
546
|
-
const f = (i) =>
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
587
|
+
const f = (i) => {
|
|
588
|
+
let r = i;
|
|
589
|
+
while (par[r] !== r)
|
|
590
|
+
r = par[r];
|
|
591
|
+
while (par[i] !== r) {
|
|
592
|
+
const n = par[i];
|
|
593
|
+
par[i] = r;
|
|
594
|
+
i = n;
|
|
595
|
+
}
|
|
596
|
+
return r;
|
|
597
|
+
};
|
|
598
|
+
const byO = new Map;
|
|
599
|
+
for (let i = 0;i < faces.length; i++) {
|
|
600
|
+
const A = faces[i];
|
|
601
|
+
for (let k = 0;k < 3; k++) {
|
|
602
|
+
const o = vk[A * 3 + k];
|
|
603
|
+
if (o === key)
|
|
604
|
+
continue;
|
|
605
|
+
const l = byO.get(o);
|
|
606
|
+
if (!l)
|
|
607
|
+
byO.set(o, [i]);
|
|
608
|
+
else if (l[l.length - 1] !== i)
|
|
609
|
+
l.push(i);
|
|
557
610
|
}
|
|
611
|
+
}
|
|
612
|
+
for (const [o, L] of byO) {
|
|
613
|
+
if (L.length < 2)
|
|
614
|
+
continue;
|
|
615
|
+
const e = ek(key, o);
|
|
616
|
+
if ((edgeFaces.get(e)?.length ?? 0) < 2)
|
|
617
|
+
continue;
|
|
618
|
+
if (L.length > 256) {
|
|
619
|
+
for (let a = 0;a + 1 < L.length; a++)
|
|
620
|
+
if (joinable(e, faces[L[a]], faces[L[a + 1]]))
|
|
621
|
+
par[f(L[a])] = f(L[a + 1]);
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
for (let a = 0;a < L.length; a++)
|
|
625
|
+
for (let b = a + 1;b < L.length; b++)
|
|
626
|
+
if (joinable(e, faces[L[a]], faces[L[b]]))
|
|
627
|
+
par[f(L[a])] = f(L[b]);
|
|
628
|
+
}
|
|
558
629
|
const acc = new Map;
|
|
559
630
|
faces.forEach((F, i) => {
|
|
560
631
|
const r = f(i), s = acc.get(r) ?? [0, 0, 0];
|
|
@@ -671,6 +742,29 @@ function invert(m) {
|
|
|
671
742
|
const r = [A * k, -(b * i - c * h) * k, (b * f - c * e) * k, B * k, (a * i - c * g) * k, -(a * f - c * d) * k, C * k, -(a * h - b * g) * k, (a * e - b * d) * k];
|
|
672
743
|
return [-(r[0] * x + r[1] * y + r[2] * z), -(r[3] * x + r[4] * y + r[5] * z), -(r[6] * x + r[7] * y + r[8] * z), ...r];
|
|
673
744
|
}
|
|
745
|
+
function singularFix(m, flatY) {
|
|
746
|
+
const det = (q) => q[3] * (q[7] * q[11] - q[8] * q[10]) - q[4] * (q[6] * q[11] - q[8] * q[9]) + q[5] * (q[6] * q[10] - q[7] * q[9]);
|
|
747
|
+
const rows = Math.hypot(m[3], m[4], m[5]) * Math.hypot(m[6], m[7], m[8]) * Math.hypot(m[9], m[10], m[11]);
|
|
748
|
+
if (!(Math.abs(det(m)) <= 0.000000001 * rows))
|
|
749
|
+
return null;
|
|
750
|
+
if (!flatY())
|
|
751
|
+
return { m, cull: false };
|
|
752
|
+
const q = [...m];
|
|
753
|
+
const ok = () => Math.abs(det(q)) > 0.000000001 * Math.hypot(q[3], q[4], q[5]) * Math.hypot(q[6], q[7], q[8]) * Math.hypot(q[9], q[10], q[11]);
|
|
754
|
+
for (let i = 0;i < 3; i++)
|
|
755
|
+
if (q[3 + 3 * i] === 0 && q[4 + 3 * i] === 0 && q[5 + 3 * i] === 0) {
|
|
756
|
+
q[4 + 3 * i] = 1;
|
|
757
|
+
if (ok())
|
|
758
|
+
return { m: q, cull: true };
|
|
759
|
+
}
|
|
760
|
+
if (q[4] === 0 && q[7] === 0 && q[10] === 0)
|
|
761
|
+
for (let i = 0;i < 3; i++) {
|
|
762
|
+
q[4 + 3 * i] = 1;
|
|
763
|
+
if (ok())
|
|
764
|
+
return { m: q, cull: true };
|
|
765
|
+
}
|
|
766
|
+
return { m, cull: false };
|
|
767
|
+
}
|
|
674
768
|
var num = (x) => String(+x.toFixed(6) || 0);
|
|
675
769
|
var quote = (s) => '"' + s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + '"';
|
|
676
770
|
function texWrapper(part, map) {
|
|
@@ -723,7 +817,22 @@ function fileStepViews(f) {
|
|
|
723
817
|
return out;
|
|
724
818
|
}
|
|
725
819
|
|
|
726
|
-
// ../../../../../../../tmp/ldr-build-
|
|
820
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/model.ts
|
|
821
|
+
class ModelLimitError extends Error {
|
|
822
|
+
limit;
|
|
823
|
+
code = "ldr-model-limit";
|
|
824
|
+
constructor(what, limit) {
|
|
825
|
+
super(`ldr: ${what} expands past ${limit.toLocaleString("en-US")} (see maxInstances)`);
|
|
826
|
+
this.limit = limit;
|
|
827
|
+
this.name = "ModelLimitError";
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
var inRange12 = (m) => {
|
|
831
|
+
for (let i = 0;i < 12; i++)
|
|
832
|
+
if (!(Math.abs(m[i]) <= MAX_COORD))
|
|
833
|
+
return false;
|
|
834
|
+
return true;
|
|
835
|
+
};
|
|
727
836
|
var CALLOUT_END = 999999;
|
|
728
837
|
var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
|
|
729
838
|
var defLine = new WeakMap;
|
|
@@ -758,6 +867,9 @@ function flatten(doc, opts = {}) {
|
|
|
758
867
|
const loose = opts.looseGeometry !== false, tx = !!opts.textures, co = !!opts.callouts;
|
|
759
868
|
const src = new Map;
|
|
760
869
|
let subs = 0;
|
|
870
|
+
const open = new Set;
|
|
871
|
+
const maxN = opts.maxInstances ?? 2000000;
|
|
872
|
+
let work = 0;
|
|
761
873
|
const lazy = (f, k) => {
|
|
762
874
|
const key = f.name + "#" + k;
|
|
763
875
|
let fn = src.get(key);
|
|
@@ -770,8 +882,11 @@ function flatten(doc, opts = {}) {
|
|
|
770
882
|
};
|
|
771
883
|
const walk = (d, fname, m, color, path, stepPath, depth, texIn, fixed = null, subPath = [], subMats = [], colour = undefined, scope0 = null) => {
|
|
772
884
|
const f = d.files.get(fname);
|
|
773
|
-
if (!f || depth > maxDepth)
|
|
885
|
+
if (!f || depth > maxDepth || open.has(f))
|
|
774
886
|
return;
|
|
887
|
+
if (++work > maxN)
|
|
888
|
+
throw new ModelLimitError("model", maxN);
|
|
889
|
+
open.add(f);
|
|
775
890
|
let scope = scope0;
|
|
776
891
|
let s = 0;
|
|
777
892
|
const subId = depth > 0 ? ++subs : 0;
|
|
@@ -799,6 +914,8 @@ function flatten(doc, opts = {}) {
|
|
|
799
914
|
const emit = (part, col, mm, sp, k, embedded, tex, cd, sc) => {
|
|
800
915
|
if (fixed)
|
|
801
916
|
sp = fixed;
|
|
917
|
+
if (++work > maxN)
|
|
918
|
+
throw new ModelLimitError("model", maxN);
|
|
802
919
|
const i = { part, color: col, m: mm, step: sp[0], steps: sp, localStep: k, path };
|
|
803
920
|
if (cd)
|
|
804
921
|
i.colour = cd;
|
|
@@ -860,7 +977,10 @@ function flatten(doc, opts = {}) {
|
|
|
860
977
|
continue;
|
|
861
978
|
if (tx && c.fallback)
|
|
862
979
|
continue;
|
|
863
|
-
const
|
|
980
|
+
const mm = mul(m, c.m);
|
|
981
|
+
if (!inRange12(mm))
|
|
982
|
+
continue;
|
|
983
|
+
const col = c.color === 16 ? color : c.color, cd = c.color === 16 ? colour : scope?.get(c.color), sp = [...stepPath, s];
|
|
864
984
|
const tex = tx ? c.tex ?? texIn : null;
|
|
865
985
|
const local = tex ? invert(c.m) : null;
|
|
866
986
|
const lt = tex && local ? transformTexMap(tex, local) : null;
|
|
@@ -880,6 +1000,7 @@ function flatten(doc, opts = {}) {
|
|
|
880
1000
|
emit(c.file, col, mm, sp, s, false, lt, cd, scope);
|
|
881
1001
|
}
|
|
882
1002
|
flushLoose(Infinity);
|
|
1003
|
+
open.delete(f);
|
|
883
1004
|
if (groups) {
|
|
884
1005
|
for (const g of groups.values())
|
|
885
1006
|
if (g.n > 1)
|
|
@@ -1138,7 +1259,7 @@ function blendedColourHex(code) {
|
|
|
1138
1259
|
return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1139
1260
|
}
|
|
1140
1261
|
|
|
1141
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1262
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/resolver.ts
|
|
1142
1263
|
var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
|
|
1143
1264
|
var UNDER_STUD_RE = /^(stud3|stud3a|stud4.*|stud12|stud16.*|stud18a)\.dat$/i;
|
|
1144
1265
|
var norm2 = (ref) => ref.trim().replace(/\\/g, "/").toLowerCase();
|
|
@@ -1355,7 +1476,7 @@ function splitModel(text, fallbackName = "main.ldr") {
|
|
|
1355
1476
|
main = null;
|
|
1356
1477
|
};
|
|
1357
1478
|
for (const line of text.split(/\r?\n/)) {
|
|
1358
|
-
const m = /^\s*0\s+FILE\s+(
|
|
1479
|
+
const m = /^\s*0\s+FILE\s+(\S[^\r]*)/i.exec(line);
|
|
1359
1480
|
if (m) {
|
|
1360
1481
|
firstBlock();
|
|
1361
1482
|
flush();
|
|
@@ -1465,11 +1586,11 @@ function collectDeps(lib, refs) {
|
|
|
1465
1586
|
return out;
|
|
1466
1587
|
}
|
|
1467
1588
|
|
|
1468
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1589
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/compile.ts
|
|
1469
1590
|
import fs2 from "node:fs";
|
|
1470
1591
|
import path2 from "node:path";
|
|
1471
1592
|
|
|
1472
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1593
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/lod.ts
|
|
1473
1594
|
import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
|
|
1474
1595
|
await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
|
|
1475
1596
|
function reorderMesh(P, N, C, I) {
|
|
@@ -1661,7 +1782,7 @@ function lodChain(P, C, I) {
|
|
|
1661
1782
|
return out;
|
|
1662
1783
|
}
|
|
1663
1784
|
|
|
1664
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1785
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/compile.ts
|
|
1665
1786
|
class BfcState {
|
|
1666
1787
|
accum;
|
|
1667
1788
|
ccw = true;
|
|
@@ -1742,6 +1863,20 @@ var hexRgba = (hex) => {
|
|
|
1742
1863
|
return [(v >> 16) / 255, (v >> 8 & 255) / 255, (v & 255) / 255, 1];
|
|
1743
1864
|
};
|
|
1744
1865
|
var det3 = (m) => m[3] * (m[7] * m[11] - m[8] * m[10]) - m[4] * (m[6] * m[11] - m[8] * m[9]) + m[5] * (m[6] * m[10] - m[7] * m[9]);
|
|
1866
|
+
var inRangeM = (v) => {
|
|
1867
|
+
for (let i = 0;i < v.length; i++)
|
|
1868
|
+
if (!(Math.abs(v[i]) <= MAX_COORD))
|
|
1869
|
+
return false;
|
|
1870
|
+
return true;
|
|
1871
|
+
};
|
|
1872
|
+
var finiteAll = (v) => {
|
|
1873
|
+
for (let i = 0;i < v.length; i++)
|
|
1874
|
+
if (!Number.isFinite(v[i]))
|
|
1875
|
+
return false;
|
|
1876
|
+
return true;
|
|
1877
|
+
};
|
|
1878
|
+
var f32 = (p) => Math.abs(p[0]) <= MAX_COORD && Math.abs(p[1]) <= MAX_COORD && Math.abs(p[2]) <= MAX_COORD;
|
|
1879
|
+
var PART_WORK_LIMIT = 1e6;
|
|
1745
1880
|
|
|
1746
1881
|
class Compiler {
|
|
1747
1882
|
lib;
|
|
@@ -1753,6 +1888,43 @@ class Compiler {
|
|
|
1753
1888
|
this.opts = opts;
|
|
1754
1889
|
this.colors = loadColors(lib.root);
|
|
1755
1890
|
}
|
|
1891
|
+
flat = new Map;
|
|
1892
|
+
flatY(key) {
|
|
1893
|
+
const hit = this.flat.get(key);
|
|
1894
|
+
if (hit !== undefined)
|
|
1895
|
+
return hit;
|
|
1896
|
+
let budget = 1e5;
|
|
1897
|
+
const walk = (fk, M, depth) => {
|
|
1898
|
+
if (depth > 40)
|
|
1899
|
+
return true;
|
|
1900
|
+
if (--budget < 0)
|
|
1901
|
+
return false;
|
|
1902
|
+
for (const raw of this.lib.read(fk).split(/\r?\n/)) {
|
|
1903
|
+
const t = raw.trim();
|
|
1904
|
+
const c = t[0];
|
|
1905
|
+
if (c === "1") {
|
|
1906
|
+
const r = parseType1(t);
|
|
1907
|
+
if (!r || !finiteAll(r.m))
|
|
1908
|
+
continue;
|
|
1909
|
+
const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
|
|
1910
|
+
const k = this.resolve(r.name, TOP_STUD_RE.test(base));
|
|
1911
|
+
if (k && !walk(k, compose(M, r.m), depth + 1))
|
|
1912
|
+
return false;
|
|
1913
|
+
continue;
|
|
1914
|
+
}
|
|
1915
|
+
if (c !== "2" && c !== "3" && c !== "4" && c !== "5")
|
|
1916
|
+
continue;
|
|
1917
|
+
const v = t.split(/\s+/).slice(2).map(Number), n = c === "2" ? 2 : c === "3" ? 3 : 4;
|
|
1918
|
+
for (let i = 0;i < n * 3; i += 3)
|
|
1919
|
+
if (Math.abs(M[1] + M[6] * v[i] + M[7] * v[i + 1] + M[8] * v[i + 2]) > 0.000001)
|
|
1920
|
+
return false;
|
|
1921
|
+
}
|
|
1922
|
+
return true;
|
|
1923
|
+
};
|
|
1924
|
+
const r = walk(key, IDENT, 0);
|
|
1925
|
+
this.flat.set(key, r);
|
|
1926
|
+
return r;
|
|
1927
|
+
}
|
|
1756
1928
|
resolve(ref, isStud) {
|
|
1757
1929
|
const key = this.lib.resolve(ref);
|
|
1758
1930
|
if (!key)
|
|
@@ -1778,10 +1950,19 @@ class Compiler {
|
|
|
1778
1950
|
if (this.cache.has(ck))
|
|
1779
1951
|
return this.cache.get(ck);
|
|
1780
1952
|
const out = { body: { pos: [], col: [] }, under: { pos: [], col: [] }, edges: [], condLines: 0, cond: this.opts.cond ? [] : undefined, condUnder: this.opts.cond ? [] : undefined, studs: [], bbox: [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity], fullBottom: false };
|
|
1781
|
-
const colorOf = (code) => code === "16" ? [1, 1, 1, 0] : [...this.colors.get(code) || (code.startsWith("0x2") ? [parseInt(code.slice(3, 5), 16) / 255, parseInt(code.slice(5, 7), 16) / 255, parseInt(code.slice(7, 9), 16) / 255] : blendedRgb(code) ?? [1, 0, 1]), 1];
|
|
1953
|
+
const colorOf = (code) => code === "16" ? [1, 1, 1, 0] : code.charCodeAt(1) === 120 && !/^0x2[0-9a-f]{6}/i.test(code) && String(parseColor(code)) !== code ? colorOf(String(parseColor(code))) : [...this.colors.get(code) || (code.startsWith("0x2") ? [parseInt(code.slice(3, 5), 16) / 255, parseInt(code.slice(5, 7), 16) / 255, parseInt(code.slice(7, 9), 16) / 255] : blendedRgb(code) ?? [1, 0, 1]), 1];
|
|
1954
|
+
const open = new Set;
|
|
1955
|
+
let work = 0;
|
|
1956
|
+
const lim = this.opts.workLimit ?? PART_WORK_LIMIT;
|
|
1957
|
+
const step = () => {
|
|
1958
|
+
if (++work > lim)
|
|
1959
|
+
throw new ModelLimitError(`part ${key}`, lim);
|
|
1960
|
+
};
|
|
1782
1961
|
const walk = (fk, M, color, invert, target, depth, inh = null, scope0 = null, cull = true) => {
|
|
1783
|
-
if (depth > 40)
|
|
1962
|
+
if (depth > 40 || open.has(fk))
|
|
1784
1963
|
return;
|
|
1964
|
+
step();
|
|
1965
|
+
open.add(fk);
|
|
1785
1966
|
const bfc = new BfcState(cull);
|
|
1786
1967
|
let scope = scope0;
|
|
1787
1968
|
for (const raw of this.lib.read(fk).split(/\r?\n/)) {
|
|
@@ -1804,7 +1985,7 @@ class Compiler {
|
|
|
1804
1985
|
if (c === "1") {
|
|
1805
1986
|
const invertNext = bfc.takeInvert();
|
|
1806
1987
|
const r = parseType1(t);
|
|
1807
|
-
if (!r)
|
|
1988
|
+
if (!r || !finiteAll(r.m))
|
|
1808
1989
|
continue;
|
|
1809
1990
|
const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
|
|
1810
1991
|
const isTop = TOP_STUD_RE.test(base), isUnder = UNDER_STUD_RE.test(base);
|
|
@@ -1812,21 +1993,28 @@ class Compiler {
|
|
|
1812
1993
|
if (!ck2)
|
|
1813
1994
|
continue;
|
|
1814
1995
|
const childColor = r.color === "16" ? color : r.color, childInh = r.color === "16" ? inh : this.local(r.color, scope);
|
|
1815
|
-
const
|
|
1816
|
-
const
|
|
1817
|
-
if (
|
|
1996
|
+
const fx = singularFix(r.m, () => this.flatY(ck2)), rm = fx ? fx.m : r.m, subCull = bfc.cull && (!fx || fx.cull);
|
|
1997
|
+
const Mc = compose(M, rm);
|
|
1998
|
+
if (!inRangeM(Mc))
|
|
1999
|
+
continue;
|
|
2000
|
+
const inv = invert !== invertNext !== det3(rm) < 0;
|
|
2001
|
+
if (isTop && separateStuds && (!fx || fx.cull)) {
|
|
1818
2002
|
out.studs.push({ kind: ck2, color: childInh ? this.studToken(childColor, childInh) : childColor, m: Mc });
|
|
1819
2003
|
fullKind.set(out.studs.length - 1, this.lib.resolve(r.name));
|
|
1820
2004
|
growBox(out.bbox, Mc, this.compile(ck2, false).bbox);
|
|
1821
2005
|
continue;
|
|
1822
2006
|
}
|
|
1823
|
-
walk(ck2, Mc, childColor, inv, isUnder ? "under" : target, depth + 1, childInh, scope,
|
|
2007
|
+
walk(ck2, Mc, childColor, inv, isUnder ? "under" : target, depth + 1, childInh, scope, subCull);
|
|
1824
2008
|
continue;
|
|
1825
2009
|
}
|
|
1826
2010
|
const tok = t.split(/\s+/);
|
|
1827
2011
|
if (c === "2") {
|
|
1828
2012
|
const v = tok.slice(2, 8).map(Number);
|
|
1829
|
-
|
|
2013
|
+
if (v.length < 6 || !finiteAll(v))
|
|
2014
|
+
continue;
|
|
2015
|
+
const a = xf(M, v.slice(0, 3)), b = xf(M, v.slice(3, 6));
|
|
2016
|
+
if (f32(a) && f32(b))
|
|
2017
|
+
out.edges.push(...a, ...b);
|
|
1830
2018
|
continue;
|
|
1831
2019
|
}
|
|
1832
2020
|
if (c === "5") {
|
|
@@ -1834,18 +2022,26 @@ class Compiler {
|
|
|
1834
2022
|
const dst = target === "under" ? out.condUnder : out.cond;
|
|
1835
2023
|
if (dst) {
|
|
1836
2024
|
const v = t.split(/\s+/).slice(2, 14).map(Number);
|
|
1837
|
-
if (v.length === 12 && v.every(Number.isFinite))
|
|
1838
|
-
|
|
1839
|
-
|
|
2025
|
+
if (v.length === 12 && v.every(Number.isFinite)) {
|
|
2026
|
+
const q = [0, 3, 6, 9].map((i) => xf(M, v.slice(i, i + 3)));
|
|
2027
|
+
if (q.every(f32))
|
|
2028
|
+
for (const p of q)
|
|
2029
|
+
dst.push(...p);
|
|
2030
|
+
}
|
|
1840
2031
|
}
|
|
1841
2032
|
continue;
|
|
1842
2033
|
}
|
|
1843
2034
|
if (c === "3" || c === "4") {
|
|
1844
2035
|
const n = c === "3" ? 3 : 4;
|
|
1845
2036
|
const v = tok.slice(2, 2 + n * 3).map(Number);
|
|
2037
|
+
if (v.length < n * 3 || !finiteAll(v))
|
|
2038
|
+
continue;
|
|
1846
2039
|
const pts = [];
|
|
1847
2040
|
for (let i = 0;i < n; i++)
|
|
1848
2041
|
pts.push(xf(M, v.slice(i * 3, i * 3 + 3)));
|
|
2042
|
+
if (!pts.every(f32))
|
|
2043
|
+
continue;
|
|
2044
|
+
step();
|
|
1849
2045
|
for (const p of pts)
|
|
1850
2046
|
grow(out.bbox, p);
|
|
1851
2047
|
const flip = !bfc.ccw !== invert, rgba = this.rgbaAt(tok[1], color, inh, scope, colorOf), b = out[target];
|
|
@@ -1866,6 +2062,7 @@ class Compiler {
|
|
|
1866
2062
|
}
|
|
1867
2063
|
if (!bfc.certified)
|
|
1868
2064
|
out.uncertified = true;
|
|
2065
|
+
open.delete(fk);
|
|
1869
2066
|
};
|
|
1870
2067
|
const fullKind = new Map;
|
|
1871
2068
|
let culled = 0;
|
|
@@ -1966,9 +2163,11 @@ class Compiler {
|
|
|
1966
2163
|
}
|
|
1967
2164
|
texPass(key, out, separateStuds, colorOf) {
|
|
1968
2165
|
const tbody = { pos: [], col: [] }, texb = new Map;
|
|
2166
|
+
const open = new Set;
|
|
1969
2167
|
const walk = (fk, M, color, invert, target, depth, texIn, inh = null, scope0 = null, cull = true) => {
|
|
1970
|
-
if (depth > 40)
|
|
2168
|
+
if (depth > 40 || open.has(fk))
|
|
1971
2169
|
return;
|
|
2170
|
+
open.add(fk);
|
|
1972
2171
|
const bfc = new BfcState(cull);
|
|
1973
2172
|
let scope = scope0;
|
|
1974
2173
|
let stack = [];
|
|
@@ -2044,17 +2243,21 @@ class Compiler {
|
|
|
2044
2243
|
}
|
|
2045
2244
|
if (c === "1") {
|
|
2046
2245
|
const r = parseType1(t);
|
|
2047
|
-
if (!r)
|
|
2246
|
+
if (!r || !finiteAll(r.m))
|
|
2048
2247
|
continue;
|
|
2049
2248
|
const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
|
|
2050
2249
|
const isTop = TOP_STUD_RE.test(base), isUnder = UNDER_STUD_RE.test(base);
|
|
2051
2250
|
const ck2 = this.resolve(r.name, isTop);
|
|
2052
2251
|
if (!ck2)
|
|
2053
2252
|
continue;
|
|
2054
|
-
const
|
|
2055
|
-
|
|
2253
|
+
const fx = singularFix(r.m, () => this.flatY(ck2)), rm = fx ? fx.m : r.m, subCull = bfc.cull && (!fx || fx.cull);
|
|
2254
|
+
const inv = invert !== invertNext !== det3(rm) < 0;
|
|
2255
|
+
if (isTop && separateStuds && (!fx || fx.cull))
|
|
2256
|
+
continue;
|
|
2257
|
+
const Mc = compose(M, rm);
|
|
2258
|
+
if (!inRangeM(Mc))
|
|
2056
2259
|
continue;
|
|
2057
|
-
walk(ck2,
|
|
2260
|
+
walk(ck2, Mc, r.color === "16" ? color : r.color, inv, isUnder ? "under" : target, depth + 1, tex, r.color === "16" ? inh : this.local(r.color, scope), scope, subCull);
|
|
2058
2261
|
continue;
|
|
2059
2262
|
}
|
|
2060
2263
|
if (c !== "3" && c !== "4")
|
|
@@ -2062,11 +2265,17 @@ class Compiler {
|
|
|
2062
2265
|
const tok = t.split(/\s+/);
|
|
2063
2266
|
const n = c === "3" ? 3 : 4;
|
|
2064
2267
|
const v = tok.slice(2, 2 + n * 3).map(Number);
|
|
2268
|
+
if (v.length < n * 3 || !finiteAll(v))
|
|
2269
|
+
continue;
|
|
2065
2270
|
const pts = [];
|
|
2066
2271
|
for (let i = 0;i < n; i++)
|
|
2067
2272
|
pts.push(xf(M, v.slice(i * 3, i * 3 + 3)));
|
|
2273
|
+
if (!pts.every(f32))
|
|
2274
|
+
continue;
|
|
2068
2275
|
const order = windOrder(n, !bfc.ccw !== invert, bfc.cull || !!out.uncertified);
|
|
2069
2276
|
const rgba = this.rgbaAt(tok[1], color, inh, scope, colorOf);
|
|
2277
|
+
if (tex && !texmapTriangleUV(tex, pts).every((x) => Number.isFinite(Math.fround(x))))
|
|
2278
|
+
tex = null;
|
|
2070
2279
|
if (tex) {
|
|
2071
2280
|
const tk = tex.glossmap ? tex.texture + "\x00" + tex.glossmap : tex.texture;
|
|
2072
2281
|
let b = texb.get(tk);
|
|
@@ -2089,6 +2298,7 @@ class Compiler {
|
|
|
2089
2298
|
tbody.col.push(...rgba);
|
|
2090
2299
|
}
|
|
2091
2300
|
}
|
|
2301
|
+
open.delete(fk);
|
|
2092
2302
|
};
|
|
2093
2303
|
walk(key, IDENT, "16", false, "body", 0, null);
|
|
2094
2304
|
if (texb.size) {
|
|
@@ -2193,23 +2403,79 @@ function seatStuds(out, fullKind, kindBox) {
|
|
|
2193
2403
|
if (!out.studs.length)
|
|
2194
2404
|
return;
|
|
2195
2405
|
const tris = [out.body.pos, out.under.pos];
|
|
2196
|
-
const
|
|
2197
|
-
|
|
2406
|
+
const nTri = (out.body.pos.length + out.under.pos.length) / 9;
|
|
2407
|
+
let nChk = 0;
|
|
2408
|
+
for (let i = 0;i < out.studs.length; i++) {
|
|
2409
|
+
const f = fullKind.get(i);
|
|
2410
|
+
if (f && f !== out.studs[i].kind)
|
|
2411
|
+
nChk++;
|
|
2412
|
+
}
|
|
2413
|
+
let grid = null;
|
|
2414
|
+
if (nChk * 9 * nTri > 4000000) {
|
|
2415
|
+
const box = [];
|
|
2416
|
+
const sz = [];
|
|
2417
|
+
for (let t = 0;t < 2; t++) {
|
|
2418
|
+
const p = tris[t];
|
|
2198
2419
|
for (let i = 0;i < p.length; i += 9) {
|
|
2199
|
-
const
|
|
2200
|
-
const
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
continue;
|
|
2205
|
-
const wx = c[0] - ax, wy = c[1] - ay, wz = c[2] - az;
|
|
2206
|
-
if (Math.abs((wx * nx + wy * ny + wz * nz) / nl) > 0.05)
|
|
2207
|
-
continue;
|
|
2208
|
-
const uu = ux * ux + uy * uy + uz * uz, vv = vx * vx + vy * vy + vz * vz, uv = ux * vx + uy * vy + uz * vz, wu = wx * ux + wy * uy + wz * uz, wv = wx * vx + wy * vy + wz * vz;
|
|
2209
|
-
const d = uv * uv - uu * vv, s = (uv * wv - vv * wu) / d, t = (uv * wu - uu * wv) / d, e = 0.0001;
|
|
2210
|
-
if (s >= -e && t >= -e && s + t <= 1 + e)
|
|
2211
|
-
return true;
|
|
2420
|
+
const L = Math.max(Math.hypot(p[i + 3] - p[i], p[i + 4] - p[i + 1], p[i + 5] - p[i + 2]), Math.hypot(p[i + 6] - p[i], p[i + 7] - p[i + 1], p[i + 8] - p[i + 2]), Math.hypot(p[i + 6] - p[i + 3], p[i + 7] - p[i + 4], p[i + 8] - p[i + 5]));
|
|
2421
|
+
const g = 0.06 + 0.0004 * L;
|
|
2422
|
+
const b = [Math.min(p[i], p[i + 3], p[i + 6]) - g, Math.min(p[i + 1], p[i + 4], p[i + 7]) - g, Math.min(p[i + 2], p[i + 5], p[i + 8]) - g, Math.max(p[i], p[i + 3], p[i + 6]) + g, Math.max(p[i + 1], p[i + 4], p[i + 7]) + g, Math.max(p[i + 2], p[i + 5], p[i + 8]) + g, t, i];
|
|
2423
|
+
box.push(b);
|
|
2424
|
+
sz.push(Math.max(b[3] - b[0], b[4] - b[1], b[5] - b[2]));
|
|
2212
2425
|
}
|
|
2426
|
+
}
|
|
2427
|
+
sz.sort((x, y) => x - y);
|
|
2428
|
+
const h = Math.max(2 * (sz[sz.length >> 1] ?? 1), 0.5);
|
|
2429
|
+
grid = { h, cells: new Map, big: [] };
|
|
2430
|
+
const G = grid;
|
|
2431
|
+
for (const b of box) {
|
|
2432
|
+
const ref = b[6] * 1073741824 + b[7];
|
|
2433
|
+
const ax = Math.floor(b[0] / h), bx = Math.floor(b[3] / h), ay = Math.floor(b[1] / h), by = Math.floor(b[4] / h), az = Math.floor(b[2] / h), bz = Math.floor(b[5] / h);
|
|
2434
|
+
if (!((bx - ax + 1) * (by - ay + 1) * (bz - az + 1) <= 512)) {
|
|
2435
|
+
G.big.push(ref);
|
|
2436
|
+
continue;
|
|
2437
|
+
}
|
|
2438
|
+
for (let x = ax;x <= bx; x++)
|
|
2439
|
+
for (let y = ay;y <= by; y++)
|
|
2440
|
+
for (let z = az;z <= bz; z++) {
|
|
2441
|
+
const key = x + "," + y + "," + z;
|
|
2442
|
+
let l = G.cells.get(key);
|
|
2443
|
+
if (!l)
|
|
2444
|
+
G.cells.set(key, l = []);
|
|
2445
|
+
l.push(ref);
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
const hit = (p, i, c, up) => {
|
|
2450
|
+
const ax = p[i], ay = p[i + 1], az = p[i + 2], ux = p[i + 3] - ax, uy = p[i + 4] - ay, uz = p[i + 5] - az, vx = p[i + 6] - ax, vy = p[i + 7] - ay, vz = p[i + 8] - az;
|
|
2451
|
+
const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx, nl = Math.hypot(nx, ny, nz);
|
|
2452
|
+
if (nl < 0.000000001)
|
|
2453
|
+
return false;
|
|
2454
|
+
if (!out.uncertified && nx * up[0] + ny * up[1] + nz * up[2] <= 0)
|
|
2455
|
+
return false;
|
|
2456
|
+
const wx = c[0] - ax, wy = c[1] - ay, wz = c[2] - az;
|
|
2457
|
+
if (Math.abs((wx * nx + wy * ny + wz * nz) / nl) > 0.05)
|
|
2458
|
+
return false;
|
|
2459
|
+
const uu = ux * ux + uy * uy + uz * uz, vv = vx * vx + vy * vy + vz * vz, uv = ux * vx + uy * vy + uz * vz, wu = wx * ux + wy * uy + wz * uz, wv = wx * vx + wy * vy + wz * vz;
|
|
2460
|
+
const d = uv * uv - uu * vv, s = (uv * wv - vv * wu) / d, t = (uv * wu - uu * wv) / d, e = 0.0001;
|
|
2461
|
+
return s >= -e && t >= -e && s + t <= 1 + e;
|
|
2462
|
+
};
|
|
2463
|
+
const covered = (c, up) => {
|
|
2464
|
+
if (!grid) {
|
|
2465
|
+
for (const p of tris)
|
|
2466
|
+
for (let i = 0;i < p.length; i += 9)
|
|
2467
|
+
if (hit(p, i, c, up))
|
|
2468
|
+
return true;
|
|
2469
|
+
return false;
|
|
2470
|
+
}
|
|
2471
|
+
const G = grid;
|
|
2472
|
+
const at = (ref) => hit(tris[ref >= 1073741824 ? 1 : 0], ref % 1073741824, c, up);
|
|
2473
|
+
for (const r of G.big)
|
|
2474
|
+
if (at(r))
|
|
2475
|
+
return true;
|
|
2476
|
+
for (const r of G.cells.get(Math.floor(c[0] / G.h) + "," + Math.floor(c[1] / G.h) + "," + Math.floor(c[2] / G.h)) ?? [])
|
|
2477
|
+
if (at(r))
|
|
2478
|
+
return true;
|
|
2213
2479
|
return false;
|
|
2214
2480
|
};
|
|
2215
2481
|
out.studs.forEach((s, i) => {
|
|
@@ -2435,9 +2701,9 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
|
|
|
2435
2701
|
return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
|
|
2436
2702
|
}
|
|
2437
2703
|
|
|
2438
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2704
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/node/build-pack.ts
|
|
2439
2705
|
function packCompilerOpts(o) {
|
|
2440
|
-
return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures };
|
|
2706
|
+
return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures, ...o.partWorkLimit ? { workLimit: o.partWorkLimit } : {} };
|
|
2441
2707
|
}
|
|
2442
2708
|
function buildPack(o) {
|
|
2443
2709
|
const lib = new Library(o.ldrawRoot);
|
|
@@ -2508,7 +2774,7 @@ function buildPack(o) {
|
|
|
2508
2774
|
return { data: encodePack(parts, kinds, comp.opts.weld, extra, { texture, lod: o.lod !== false, reorder: !!o.reorder }), parts: parts.size, studKinds: kinds.size, missing: [...missing], ...warnings.length ? { warnings } : {} };
|
|
2509
2775
|
}
|
|
2510
2776
|
|
|
2511
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2777
|
+
// ../../../../../../../tmp/ldr-build-5tVh0D/src/cli.ts
|
|
2512
2778
|
var HELP = `ldr pack — build a parts pack for the ldr three.js renderer
|
|
2513
2779
|
|
|
2514
2780
|
Usage:
|