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.
@@ -1,5 +1,7 @@
1
1
  import { type FlattenOptions, type LDrawColor } from "../model.js";
2
2
  import { type Doc, type PartMesh, type Instance } from "../spec.js";
3
+ /** Most subfile placements + triangles one `mesh` may expand to (a few lines can nest subfiles that each place the next twice). */
4
+ export declare const MESH_WORK_LIMIT = 1000000;
3
5
  export declare class Library {
4
6
  root: string;
5
7
  unofficialRoot?: string | undefined;
@@ -43,6 +45,14 @@ export declare class Library {
43
45
  /** Texture PNG bytes for a !TEXMAP name: an MPD `!DATA` block in `doc` first, then the LDraw search path with a
44
46
  * `textures/` prefix (parts/, p/, models/, official then unofficial), then without it. Case-insensitive. */
45
47
  texture(name: string, doc?: Doc): Uint8Array | null;
48
+ /** Files being expanded by `emit` (a reference back to one is a cycle, which LDraw doesn't allow: ignored) and `emit`'s work so far. */
49
+ private open;
50
+ private work;
51
+ /** subfile walks + triangles one `mesh` may take before it throws `ModelLimitError` */
52
+ workLimit: number;
53
+ /** Every point of file `fname` of `doc` (type 2-5 lines, through its subfiles) has y = 0 (see `singularFix`). Past a work budget
54
+ * (subfiles nested exponentially) the answer is no, so the placement is drawn without culling. */
55
+ private flatY;
46
56
  private emit;
47
57
  /** Flatten a model into part instances (see `flatten` in the browser entry for the rules; `models/` library files are walked
48
58
  * as submodels). 24 handled at render (edge color). Alias parts resolve to canonical names. MPD files and synthetic parts
package/dist/spec.d.ts CHANGED
@@ -101,6 +101,9 @@ export declare function namedColorCode(id: string): number;
101
101
  export declare const isNamedColor: (c: number) => boolean;
102
102
  /** Parse LDraw color token: decimal code, direct color 0x2RRGGBB (and related 0xN…… forms), or a `!COLOUR` identifier (see `namedColorCode`). */
103
103
  export declare function parseColor(tok: string): number;
104
+ /** Largest coordinate / matrix entry the library places or draws: an LDraw line or a placement beyond it is out of range and ignored
105
+ * (1e15 LDU is 400 million km; products of two such values stay finite in float32, so bounding boxes and GPU data stay finite). */
106
+ export declare const MAX_COORD = 1000000000000000;
104
107
  /** Parse the tail of `0 !TEXMAP START|NEXT <method> <params> <png> [GLOSSMAP <png>]`. Returns null when malformed. */
105
108
  export declare function parseTexMap(tail: string, next?: boolean): TexMap | null;
106
109
  /** `geometryText`: keep type 2-5 lines as their source text (`src`) with empty `p` instead of parsing their numbers (for tools that
@@ -223,6 +226,19 @@ export declare function looseSource(f: LFile, step: number): string;
223
226
  export declare function hash32(s: string): string;
224
227
  /** Inverse of an affine LDraw matrix, or null when singular. */
225
228
  export declare function invert(m: M): M | null;
229
+ /**
230
+ * BFC "Degenerate Matrices" (ldraw.org article 415): a subfile placed with a singular (determinant 0) matrix can't be culled.
231
+ * Returns null for a regular matrix. For a singular one: when the subfile lies in its own XZ plane (`flatY`: every point has y = 0),
232
+ * the Y column doesn't move any point, so the matrix is repaired the way LDView / L3P / LDGLite do (L3Input heritage, LDView
233
+ * `LDLModelLine::tryToFixPlanarMatrix`): an all-zero row gets 1 in its Y column (one row at a time), else an all-zero Y column gets 1s
234
+ * one row at a time; the repaired matrix (same points, determinant != 0) decides the winding and culling stays on. Otherwise culling
235
+ * is off for the subfile (`cull: false`). "Singular" = |det| at most 1e-9 of the product of the row lengths (the library's own
236
+ * near-singular references, e.g. 55297's discs at ~1e-6, keep their determinant's sign as before).
237
+ */
238
+ export declare function singularFix(m: M, flatY: () => boolean): {
239
+ m: M;
240
+ cull: boolean;
241
+ } | null;
226
242
  /**
227
243
  * Synthetic part for a part reference wrapped by a model-level `!TEXMAP` (the map is defined in the model, not in the part file).
228
244
  * `map` must already be in the part's own coordinates. The wrapper is a certified file that applies the map to the part, so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ldr",
3
- "version": "0.33.1",
3
+ "version": "0.33.3",
4
4
  "description": "High-performance LEGO (LDraw) rendering for three.js: instanced parts packs, hidden stud/tube culling, low-detail studs, indexed edges, build steps.",
5
5
  "license": "MIT",
6
6
  "author": "Evan Bacon",
@@ -50,6 +50,7 @@
50
50
  ],
51
51
  "scripts": {
52
52
  "build": "rm -rf dist && bun scripts/gen-worker.ts && bun scripts/build.ts && tsc -p tsconfig.build.json && bun scripts/postbuild.ts && node scripts/check-dist.mjs",
53
+ "fuzz": "bun fuzz/fuzz.ts",
53
54
  "test": "bun test",
54
55
  "prepublishOnly": "bun run build && bun test"
55
56
  },