ldr 0.25.0 → 0.26.1

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 CHANGED
@@ -93,7 +93,7 @@ Light the scene (or set `scene.environment`) as you would for any `MeshStandardM
93
93
  | `looseSteps` / `looseFile` / `looseSource` / `loosePartName` | A model's own type 2–5 geometry, per step, as synthetic parts named `<file>#<step>`. |
94
94
  | `rotStepMatrix` / `stepViewMatrix` / `fileStepViews` | ROTSTEP views, following MLCad: `REL`, `ADD`, `ABS`, `END`. A ROTSTEP ends its step. |
95
95
  | `parseTexMap` / `texmapUV` / `texmapTriangleUV` / `transformTexMap` / `resolveTexture` / `texWrapper` | `!TEXMAP` support (`PLANAR`, `CYLINDRICAL`, `SPHERICAL`). UV conventions follow LDView: v = 0 is the image's top row. |
96
- | `parseColor`, `isDirectColor`, `colorToken`, `mul`, `invert`, `IDENTITY`, `norm`, `smoothNormals`, `hash32` | Low-level helpers. |
96
+ | `parseColor`, `isDirectColor`, `namedColorCode`, `isNamedColor`, `colorToken`, `mul`, `invert`, `IDENTITY`, `norm`, `smoothNormals`, `hash32` | Low-level helpers. |
97
97
 
98
98
  `FlattenOptions`:
99
99
 
@@ -211,6 +211,7 @@ Reproduce: `cd bench && bun run setup && bun run perf` (regression gate) or `bun
211
211
  - `!TEXMAP` `START`/`NEXT`/`FALLBACK`/`END`, with `PLANAR`, `CYLINDRICAL` and `SPHERICAL` projections (orientation matches LDView), `GLOSSMAP` (alpha = gloss amount, same UVs), and model-level `!TEXMAP` around part references.
212
212
  - Colours: LDConfig `!COLOUR`, edge colours, main/edge colour inheritance (16/24), and direct colours (`0x2RRGGBB`).
213
213
  - `!COLOUR` lines in a model follow the spec's scope rule. A definition applies from its line to the end of its file and to the files that file references, and it never leaks back to the parent. It sets the instance colour and finish. Colours hard-coded inside parts (printed parts, MPD-embedded parts) always come from LDConfig, because parts are precompiled.
214
+ - Named colour codes: a `!COLOUR` CODE may be an identifier instead of a number (`0 !COLOUR My_Red CODE MyRed VALUE #FF0000 EDGE #333333`, then `1 myred ...`), which the spec allows outside strict LDraw compatibility. Identifiers are case-insensitive and follow the same scope rule. `parseColor` turns one into a stable negative code (`namedColorCode`, `isNamedColor`), and `colorToken` turns it back into the identifier. A named code with no definition in scope draws the fallback colour.
214
215
  - Blended colour codes 256-511 that LDConfig doesn't define (used by old models, e.g. 382 in Datsville) render as the spec's average of two ldraw.exe colours instead of the fallback grey.
215
216
  - Case-insensitive, backslash-normalized file lookup; `~Moved to` alias parts.
216
217
 
package/dist/cli.js CHANGED
@@ -1,20 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/cli.ts
3
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/cli.ts
4
4
  import fs4 from "node:fs";
5
5
  import zlib from "node:zlib";
6
6
 
7
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/node/build-pack.ts
7
+ // ../../../../../../../tmp/ldr-build-NA1V7v/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-sxbVKM/src/node/resolver.ts
11
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/node/resolver.ts
12
12
  import fs from "node:fs";
13
13
  import path from "node:path";
14
14
 
15
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/spec.ts
15
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/spec.ts
16
16
  var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
17
+ var COLOUR_ID_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
18
+ var namedCodes = new Map;
19
+ function namedColorCode(id) {
20
+ const s = id.toLowerCase();
21
+ let h = 2166136261;
22
+ for (let i = 0;i < s.length; i++) {
23
+ h ^= s.charCodeAt(i);
24
+ h = Math.imul(h, 16777619);
25
+ }
26
+ const c = -1 - (h >>> 0 & 1073741823);
27
+ if (!namedCodes.has(c))
28
+ namedCodes.set(c, s);
29
+ return c;
30
+ }
31
+ var isNamedColor = (c) => c < 0 && Number.isInteger(c);
17
32
  function parseColor(tok) {
33
+ const c0 = tok.charCodeAt(0) | 32;
34
+ if (c0 >= 97 && c0 <= 122 && COLOUR_ID_RE.test(tok))
35
+ return namedColorCode(tok);
18
36
  if (/^0x/i.test(tok))
19
37
  return parseInt(tok, 16);
20
38
  return +tok;
@@ -590,7 +608,7 @@ function looseSteps(f) {
590
608
  looseMemo.set(f, r);
591
609
  return r;
592
610
  }
593
- var colorToken = (c) => c > 16777215 ? "0x" + c.toString(16).toUpperCase() : String(c);
611
+ var colorToken = (c) => c > 16777215 ? "0x" + c.toString(16).toUpperCase() : c < 0 ? namedCodes.get(c) ?? String(c) : String(c);
594
612
  var lineOf = (c) => c.t === 0 ? "0 " + c.text : c.t === 1 ? `1 ${colorToken(c.color)} ${c.m.join(" ")} ${c.file}` : c.src ? c.src : `${c.t} ${colorToken(c.color)} ${c.p.join(" ")}`;
595
613
  var loosePartName = (file, step) => `${norm(file)}#${step}`;
596
614
  function looseFile(f, step) {
@@ -705,7 +723,7 @@ function fileStepViews(f) {
705
723
  return out;
706
724
  }
707
725
 
708
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/model.ts
726
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/model.ts
709
727
  var CALLOUT_END = 999999;
710
728
  var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
711
729
  function flatten(doc, opts = {}) {
@@ -917,14 +935,14 @@ function parseColourLine(line) {
917
935
  if (tokens.length < 2)
918
936
  return null;
919
937
  const name = tokens[0];
920
- let code = -1, hex = "#FF00FF", edge = "#333333", alpha = 255, luminance = 0;
938
+ let code = NaN, hex = "#FF00FF", edge = "#333333", alpha = 255, luminance = 0;
921
939
  let finish = { type: "default" };
922
940
  let i = 1;
923
941
  while (i < tokens.length) {
924
942
  const t = tokens[i].toUpperCase();
925
943
  const n = tokens[i + 1];
926
944
  if (t === "CODE") {
927
- code = +n;
945
+ code = n !== undefined && COLOUR_ID_RE.test(n) ? namedColorCode(n) : n !== undefined && /^\d+$/.test(n) ? +n : NaN;
928
946
  i += 2;
929
947
  } else if (t === "VALUE") {
930
948
  const h = parseHexColor(n);
@@ -979,7 +997,7 @@ function parseColourLine(line) {
979
997
  } else
980
998
  i += 1;
981
999
  }
982
- if (code < 0 || !hex)
1000
+ if (Number.isNaN(code) || !hex)
983
1001
  return null;
984
1002
  return { code, name, hex, edge, alpha: Number.isFinite(alpha) ? alpha : 255, luminance: Number.isFinite(luminance) ? luminance : 0, finish };
985
1003
  }
@@ -1088,7 +1106,7 @@ function blendedColourHex(code) {
1088
1106
  return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
1089
1107
  }
1090
1108
 
1091
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/node/resolver.ts
1109
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/node/resolver.ts
1092
1110
  var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
1093
1111
  var UNDER_STUD_RE = /^(stud3|stud3a|stud4.*|stud12|stud16.*|stud18a)\.dat$/i;
1094
1112
  var norm2 = (ref) => ref.trim().replace(/\\/g, "/").toLowerCase();
@@ -1358,11 +1376,11 @@ function collectDeps(lib, refs) {
1358
1376
  return out;
1359
1377
  }
1360
1378
 
1361
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/node/compile.ts
1379
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/node/compile.ts
1362
1380
  import fs2 from "node:fs";
1363
1381
  import path2 from "node:path";
1364
1382
 
1365
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/node/lod.ts
1383
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/node/lod.ts
1366
1384
  import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
1367
1385
  await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
1368
1386
  function reorderMesh(P, N, C, I) {
@@ -1554,7 +1572,7 @@ function lodChain(P, C, I) {
1554
1572
  return out;
1555
1573
  }
1556
1574
 
1557
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/node/compile.ts
1575
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/node/compile.ts
1558
1576
  function loadColors(root) {
1559
1577
  const map = new Map;
1560
1578
  for (const l of fs2.readFileSync(path2.join(root, "LDConfig.ldr"), "latin1").split(/\r?\n/)) {
@@ -2191,7 +2209,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
2191
2209
  return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
2192
2210
  }
2193
2211
 
2194
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/node/build-pack.ts
2212
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/node/build-pack.ts
2195
2213
  function buildPack(o) {
2196
2214
  const lib = new Library(o.ldrawRoot);
2197
2215
  const refs = new Map;
@@ -2259,7 +2277,7 @@ function buildPack(o) {
2259
2277
  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 } : {} };
2260
2278
  }
2261
2279
 
2262
- // ../../../../../../../tmp/ldr-build-sxbVKM/src/cli.ts
2280
+ // ../../../../../../../tmp/ldr-build-NA1V7v/src/cli.ts
2263
2281
  var HELP = `ldr pack — build a parts pack for the ldr three.js renderer
2264
2282
 
2265
2283
  Usage:
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { parse, parseColor, isDirectColor, mul, I as IDENTITY, norm, smoothNormals, parseTexMap, texmapUV, texmapTriangleUV, transformTexMap, resolveTexture, fileKind, looseSteps, looseSource, looseFile, loosePartName, texWrapper, invert, hash32, colorToken, rotStepMatrix, stepViewMatrix, fileStepViews } from "./spec.js";
1
+ export { parse, parseColor, isDirectColor, namedColorCode, isNamedColor, mul, I as IDENTITY, norm, smoothNormals, parseTexMap, texmapUV, texmapTriangleUV, transformTexMap, resolveTexture, fileKind, looseSteps, looseSource, looseFile, loosePartName, texWrapper, invert, hash32, colorToken, rotStepMatrix, stepViewMatrix, fileStepViews } from "./spec.js";
2
2
  export type { M as Matrix12, Doc, LFile, Cmd, RotStep, BufExchg, TexMap, TexMapCmd, TexMapMethod, TexAnno, DataBlock, PartMesh, FileKind, StepView } from "./spec.js";
3
3
  export { flatten, parseModel, sequenceSteps, stepKey, parseLDConfig, parseColourLine, colourSurface, colourMaterialKey, blendedColourHex, CALLOUT_END } from "./model.js";
4
4
  export { planStepViews, isolateMask, viewDir, instanceBoxes, MIN_VIS, REORIENT } from "./instructions.js";