@ifc-lite/wasm 10.4.0 → 10.6.0

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
@@ -10,6 +10,16 @@ Pre-built WebAssembly bindings for the IFClite Rust core, covering STEP parsing
10
10
  npm install @ifc-lite/wasm
11
11
  ```
12
12
 
13
+ The package includes generated private JavaScript helpers under `pkg/snippets/`
14
+ when the WASM bindings import them. Keep these files beside the generated glue;
15
+ copying only `ifc-lite.js` and the `.wasm` file can leave an incomplete runtime.
16
+ The canonical build and prebuilt fetch generate npm ignore metadata so
17
+ wasm-pack's broad Git ignore does not exclude these helpers from publication.
18
+ `pnpm build:wasm:fetch` validates the static helper dependency closure and runtime
19
+ exports before installation, preserving committed types and an existing runtime
20
+ if validation fails. Validation parses code without evaluating the generated JavaScript.
21
+ Dynamic imports remain lazy and are outside this static dependency check.
22
+
13
23
  ## Direct WASM use
14
24
 
15
25
  The text-based entity scanner (`scanEntitiesFast`) takes the raw IFC text
@@ -282,3 +292,23 @@ distances and unresolved units, curves or placements fail explicitly. The
282
292
  `approximate` flag identifies supported approximation paths; it must be exposed
283
293
  to precision-sensitive consumers. Whole-source parsing belongs in a disposable
284
294
  worker when used by the viewer, so releasing the tool also releases WASM pages.
295
+
296
+ ## Rust diff bindings
297
+
298
+ After initializing `@ifc-lite/wasm/diff`, `DiffModel` owns fingerprint columns for repeated synchronous comparisons. Its constructor accepts a string dictionary, five string indices per entity (key, IFC class, data hash, geometry hash, container), presence flags, six bounding-box coordinates per entity, volumes, component offsets, and component key/value indices. Column dictionary strings must be well-formed Unicode; the internal TypeScript column adapter explicitly rejects lone surrogates rather than replacing them. Arbitrary UTF-16 entity-key transport remains a requirement for the public facade cutover in #8042; the public TypeScript comparison API continues to accept those keys. An absent optional string uses `0xffffffff`; flag bits 0, 1, and 2 represent a bounding box, volume, and components. Call `.free()` in `finally` for each model.
299
+
300
+ `DiffModel.compare` returns row indices instead of JavaScript references. Keep the original fingerprint arrays and restore those references on the JavaScript side; opaque references never cross into WASM. The model can be reused for more comparisons before freeing it.
301
+
302
+ `diffStableHash` accepts UTF-16 code units, including unpaired surrogates. `diffBuildDataFingerprint` and `diffBuildComponentFingerprints` accept IFC adapter projections directly.
303
+
304
+ In staging PR #8081 these two raw typed boundaries require well-formed UTF-16: they reject unpaired surrogates before conversion to Rust strings, including every typed name, material/classification string, property/quantity object key, and recursively nested value. Literal U+FFFD, valid surrogate pairs, and scalar-only hashes retain the TypeScript semantics. Only known record fields are read; ignored extras (including assigned-type `globalId`) are not validated or hashed. Property-value objects are content, so all their keys and values are validated. The boundary decoder mirrors the Rust input schema and must be kept in sync when that schema changes. This is an explicit staging limitation, consistent with the column and lineage guards, rather than arbitrary UTF-16 support: the public `@ifc-lite/diff` index still uses TypeScript and continues to accept arbitrary UTF-16. The separate final facade must retain lossless `JsString` transport (#8042).
305
+
306
+ `diffCreateSidecar`, `diffValidateSidecar`, and `diffSerializeSidecar` handle the small JSON sidecar documents; date validation uses the host's `Date.parse`. Sidecar serialization includes the trailing newline.
307
+
308
+ `diffLineageConflicts(entries)` returns ordered conflict diagnostics, and `diffKeyAliasesFromLineage(entries)` returns head/base pairs in insertion order for constructing a JavaScript `Map`. `diffRekeyByLineage(keys, entries, deleted, policy)` migrates external keys using `copy-to-all`, `largest-share`, or `orphan-on-split`. These helpers accept lineage objects directly, preserving non-finite share values and the existing TypeScript policy behavior. Deleted keys have no `relation` field in their result. Invalid-share policy changes are tracked separately in #8084. In this staging payload, every raw lineage string (base/head keys, reason, relation, rekey keys, deleted keys, and policy) must be well-formed UTF-16. The bindings reject unpaired surrogates before serde or wasm-bindgen can replace them; literal U+FFFD and valid surrogate pairs remain accepted. This limited scalar domain is temporary: the full lossless `JsString` engine/facade followup removes the rejection before public cutover.
309
+
310
+ These bindings are the staged backend for issue #8042. The public `@ifc-lite/diff` facade has not switched to them yet; existing consumers keep their current initialization contract until integration and performance qualification complete.
311
+
312
+ The Rust diff engine is a separate `@ifc-lite/wasm/diff` payload, built from `rust/diff-wasm` by `scripts/build-wasm.sh`. Its `DiffModel`, canonical fingerprint, sidecar and lineage bindings are loaded by explicit diff initialization; they are excluded from both geometry bundles. The committed `pkg-diff/ifc-lite-diff.d.ts` supports wasm-free typechecking.
313
+
314
+ The real IFC parity runner (`node scripts/diff-real-fixture-parity.mjs`) reports executed/total pairs. Missing fixtures are skipped with a `pnpm fixtures` hint; zero executed pairs exits with status 2 (incomplete), rather than claiming parity.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "IFC-Lite Contributors"
6
6
  ],
7
7
  "description": "WebAssembly bindings for IFC-Lite",
8
- "version": "10.4.0",
8
+ "version": "10.6.0",
9
9
  "license": "MPL-2.0",
10
10
  "repository": {
11
11
  "type": "git",
@@ -14,7 +14,15 @@
14
14
  "files": [
15
15
  "pkg/ifc-lite_bg.wasm",
16
16
  "pkg/ifc-lite.js",
17
- "pkg/ifc-lite.d.ts"
17
+ "pkg/ifc-lite.d.ts",
18
+ "pkg/snippets/**",
19
+ "retained.js",
20
+ "retained.d.ts",
21
+ "pkg-retained/ifc-lite.d.ts",
22
+ "pkg-diff/ifc-lite-diff.js",
23
+ "pkg-diff/ifc-lite-diff_bg.wasm",
24
+ "pkg-diff/ifc-lite-diff.d.ts",
25
+ "pkg-diff/snippets/**"
18
26
  ],
19
27
  "main": "./pkg/ifc-lite.js",
20
28
  "module": "./pkg/ifc-lite.js",
@@ -25,7 +33,18 @@
25
33
  "import": "./pkg/ifc-lite.js",
26
34
  "default": "./pkg/ifc-lite.js"
27
35
  },
28
- "./ifc-lite_bg.wasm": "./pkg/ifc-lite_bg.wasm"
36
+ "./ifc-lite_bg.wasm": "./pkg/ifc-lite_bg.wasm",
37
+ "./retained": {
38
+ "types": "./retained.d.ts",
39
+ "import": "./retained.js",
40
+ "default": "./retained.js"
41
+ },
42
+ "./diff": {
43
+ "types": "./pkg-diff/ifc-lite-diff.d.ts",
44
+ "import": "./pkg-diff/ifc-lite-diff.js",
45
+ "default": "./pkg-diff/ifc-lite-diff.js"
46
+ },
47
+ "./diff_bg.wasm": "./pkg-diff/ifc-lite-diff_bg.wasm"
29
48
  },
30
49
  "sideEffects": false,
31
50
  "keywords": [
@@ -43,6 +62,6 @@
43
62
  "bugs": "https://github.com/LTplus-AG/ifc-lite/issues",
44
63
  "scripts": {
45
64
  "build": "node ../../scripts/run-build-wasm.mjs",
46
- "test": "node --test test/*.test.mjs"
65
+ "test": "node --experimental-strip-types --test test/*.test.mjs"
47
66
  }
48
67
  }
package/pkg/ifc-lite.d.ts CHANGED
@@ -60,6 +60,21 @@ export interface RtcFrame {
60
60
 
61
61
 
62
62
 
63
+ export interface LandXmlTerrainOptionsJs {
64
+ /** `YYYY-MM-DD`, the required `LandXML@date`; the caller owns the clock. */
65
+ date: string;
66
+ /** `HH:MM:SS`, the required `LandXML@time`. */
67
+ time: string;
68
+ /** Default `'metre'`. US survey feet write elevations in international feet (LandXML 1.2 has no US-survey-foot elevation unit); both are declared. */
69
+ linearUnit?: 'metre' | 'internationalFoot' | 'usSurveyFoot';
70
+ /** Decimal places in the written unit, 0 to 9. Default 6. */
71
+ decimals?: number;
72
+ /** `Surface@name` per product; a blank name keeps the IFC name. */
73
+ surfaceNames?: { productId: number; name: string }[];
74
+ }
75
+
76
+
77
+
63
78
  export interface LandXmlTinDocumentJs {
64
79
  format: "landxml";
65
80
  schema: "LandXML-1.0" | "LandXML-1.1" | "LandXML-1.2";
@@ -159,7 +174,8 @@ export interface LandXmlCrossSectionSurfaceJs { source_id: string; parent_cross_
159
174
  export interface LandXmlRoadwayJs { source_id: string; ordinal: number; name: string; alignment_refs: string[]; alignment_source_ids: string[]; surface_refs: string[]; surface_source_ids: string[]; grade_model_refs: string[]; }
160
175
  export interface LandXmlCapabilityDiagnosticJs { code: string; source_id?: string; source_path: string; message: string; }
161
176
  export interface LandXmlPreservedOnlyExtensionJs { source_id: string; parent_source_id?: string; local_name: string; source_path: string; kind: "corridor" | "string_line"; }
162
- export interface LandXmlPipeUnitsJs { linear_unit: string; elevation_unit: string; diameter_unit: string; width_unit: string; height_unit: string; flow_unit?: string; linear_scale_to_meters: number; elevation_scale_to_meters: number; diameter_scale_to_meters: number; width_scale_to_meters: number; height_scale_to_meters: number; }
177
+ /** `assumed` is true only when these units came from `LandXmlParseOptionsJs.assumedLinearUnit` because the source declares no root LandXML/Units element, never from a declared one (#5175, #7693). */
178
+ export interface LandXmlPipeUnitsJs { linear_unit: string; elevation_unit: string; diameter_unit: string; width_unit: string; height_unit: string; flow_unit?: string; linear_scale_to_meters: number; elevation_scale_to_meters: number; diameter_scale_to_meters: number; width_scale_to_meters: number; height_scale_to_meters: number; assumed: boolean; }
163
179
  export interface LandXmlPipeNetworkDocumentJs {
164
180
  schema: "LandXML-1.0" | "LandXML-1.1" | "LandXML-1.2"; version: string;
165
181
  capability_diagnostics: LandXmlCapabilityDiagnosticJs[];
@@ -670,8 +686,16 @@ export class IfcAPI {
670
686
  * out-of-range index copied into the BIN chunk. (The viewer always passes
671
687
  * fully-backed, normal-covered, whole-triangle, in-range arrays, so this only
672
688
  * fires on a caller bug.)
689
+ *
690
+ * `world_matrix` is the frame the meshes were baked in (#7734): 16 finite
691
+ * numbers, a column-major 4x4 in IFC Z-up metres with `world = M * baked`
692
+ * (the viewer builds it from `CoordinateInfo`). The GLB root carries it, so
693
+ * a georeferenced model exports where the from-bytes `exportGlb` puts it
694
+ * instead of in the render frame. Omit it (`undefined`) for an unshifted
695
+ * model; a matrix that is not 16 finite numbers throws
696
+ * `MALFORMED_MESH_INPUT`.
673
697
  */
674
- exportGlbFromMeshes(positions: Float32Array, normals: Float32Array, indices: Uint32Array, vertex_counts: Uint32Array, index_counts: Uint32Array, colors: Float32Array, origins: Float64Array, express_ids: Uint32Array, include_metadata: boolean, lit?: boolean | null, emissive?: boolean | null): Uint8Array;
698
+ exportGlbFromMeshes(positions: Float32Array, normals: Float32Array, indices: Uint32Array, vertex_counts: Uint32Array, index_counts: Uint32Array, colors: Float32Array, origins: Float64Array, express_ids: Uint32Array, include_metadata: boolean, lit?: boolean | null, emissive?: boolean | null, world_matrix?: Float64Array | null): Uint8Array;
675
699
  /**
676
700
  * Export the `IfcSpace` volumes in `content` as Honeybee **HBJSON** UTF-8 bytes.
677
701
  *
@@ -752,6 +776,17 @@ export class IfcAPI {
752
776
  * document the 1.4.1 schema rejects, or one with meshes or faces missing.
753
777
  */
754
778
  exportKmzFromMeshes(positions: Float32Array, normals: Float32Array, indices: Uint32Array, vertex_counts: Uint32Array, index_counts: Uint32Array, colors: Float32Array, origins: Float64Array, latitude: number, longitude: number, altitude: number, x_axis_abscissa: number | null | undefined, x_axis_ordinate: number | null | undefined, name: string, altitude_mode?: string | null): Uint8Array;
779
+ /**
780
+ * Export the terrain products `product_ids` (express ids) of `content` as
781
+ * one LandXML 1.2 document, one `<Surface>` each.
782
+ *
783
+ * Returns JSON `{ xml, crsName, surfaces: [{ productId, globalId, name,
784
+ * points, faces }] }`. A selection that is not an authored triangulated
785
+ * terrain, or whose georeferencing is missing or ambiguous, throws an
786
+ * `Error` whose message starts with `TERRAIN_REFUSED:` and names the
787
+ * reason.
788
+ */
789
+ exportLandXmlTerrain(content: Uint8Array, product_ids: Uint32Array, options: LandXmlTerrainOptionsJs): string;
755
790
  /**
756
791
  * Merge several IFC models into one STEP/IFC UTF-8 byte buffer (`Uint8Array`).
757
792
  * `concatenated` is every model's
@@ -776,6 +811,10 @@ export class IfcAPI {
776
811
  * for GLB in `export_glb`). A non-empty `Uint32Array` is the ordinary allowlist.
777
812
  * Instanced type-library shapes are skipped regardless of the filter.
778
813
  *
814
+ * Fails CLOSED like `exportGlb`: when no mesh is written this throws an
815
+ * `Error` whose message starts with `NO_RENDER_GEOMETRY`, instead of
816
+ * returning a header-only OBJ (#7695).
817
+ *
779
818
  * ```javascript
780
819
  * const obj = api.exportObj(ifcContent, true, new Uint32Array(), undefined);
781
820
  * ```
@@ -815,6 +854,10 @@ export class IfcAPI {
815
854
  * Export **OpenUSD** (`.usda` ASCII): a real Z-up USD stage — spatial hierarchy of
816
855
  * `Xform` prims, `UsdGeomMesh` geometry, `UsdPreviewSurface` materials, IFC
817
856
  * metadata as custom attributes. Whole-model (geometry-backed).
857
+ *
858
+ * Fails CLOSED like `exportGlb`: a model with no render geometry throws an
859
+ * `Error` whose message starts with `NO_RENDER_GEOMETRY`, instead of
860
+ * returning a stage with nothing to look at (#7695).
818
861
  */
819
862
  exportUsd(content: Uint8Array): Uint8Array;
820
863
  /**
@@ -2503,6 +2546,14 @@ export function setGeometryProgressCallback(callback?: Function | null): void;
2503
2546
  * meaningless volumes with a plausible `sumErrorRel`, so the closure proof
2504
2547
  * above is the caller's responsibility and not a formality.
2505
2548
  *
2549
+ * Returns `undefined` when a zone parameter is non-finite, or a mesh vertex
2550
+ * or zone corner lies past ±2^128, the exact kernel's coordinate bound
2551
+ * (#7677): such a split is refused rather than answered wrongly.
2552
+ *
2553
+ * Returns `undefined` if an intersection, zone union or remainder exhausts
2554
+ * the exact kernel's work budget. Completed pieces are not returned as a
2555
+ * successful partial split, and a failed empty piece is not treated as disjoint.
2556
+ *
2506
2557
  * Returns `undefined` when the mesh encloses no volume (no triangles survive
2507
2558
  * the filter above, or the shell is degenerate): there is nothing to split,
2508
2559
  * and a result for it would report `pieceCount` 1, `sumErrorRel` 0 and
@@ -2513,7 +2564,7 @@ export function setGeometryProgressCallback(callback?: Function | null): void;
2513
2564
  * const split = splitMeshByZones(positions, indices, new Float64Array([
2514
2565
  * 0, 0, 0, 10, 10, 10, 0,
2515
2566
  * ]));
2516
- * if (!split) return; // the mesh encloses no volume
2567
+ * if (!split) return; // no usable complete split
2517
2568
  * for (let i = 0; i < split.pieceCount; i++) {
2518
2569
  * const piece = split.piece(i);
2519
2570
  * // piece.zoneIndex, piece.positions, piece.indices, piece.volume
@@ -2640,13 +2691,14 @@ export interface InitOutput {
2640
2691
  readonly ifcapi_exportCsv: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
2641
2692
  readonly ifcapi_exportDfjson: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2642
2693
  readonly ifcapi_exportGlb: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number) => void;
2643
- readonly ifcapi_exportGlbFromMeshes: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number) => void;
2694
+ readonly ifcapi_exportGlbFromMeshes: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number) => void;
2644
2695
  readonly ifcapi_exportHbjson: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2645
2696
  readonly ifcapi_exportHbjsonWithStats: (a: number, b: number, c: number, d: number, e: number) => number;
2646
2697
  readonly ifcapi_exportIfcx: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2647
2698
  readonly ifcapi_exportJson: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
2648
2699
  readonly ifcapi_exportJsonld: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
2649
2700
  readonly ifcapi_exportKmzFromMeshes: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number) => void;
2701
+ readonly ifcapi_exportLandXmlTerrain: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
2650
2702
  readonly ifcapi_exportMerged: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
2651
2703
  readonly ifcapi_exportObj: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
2652
2704
  readonly ifcapi_exportStep: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
package/pkg/ifc-lite.js CHANGED
@@ -1235,6 +1235,14 @@ export class IfcAPI {
1235
1235
  * out-of-range index copied into the BIN chunk. (The viewer always passes
1236
1236
  * fully-backed, normal-covered, whole-triangle, in-range arrays, so this only
1237
1237
  * fires on a caller bug.)
1238
+ *
1239
+ * `world_matrix` is the frame the meshes were baked in (#7734): 16 finite
1240
+ * numbers, a column-major 4x4 in IFC Z-up metres with `world = M * baked`
1241
+ * (the viewer builds it from `CoordinateInfo`). The GLB root carries it, so
1242
+ * a georeferenced model exports where the from-bytes `exportGlb` puts it
1243
+ * instead of in the render frame. Omit it (`undefined`) for an unshifted
1244
+ * model; a matrix that is not 16 finite numbers throws
1245
+ * `MALFORMED_MESH_INPUT`.
1238
1246
  * @param {Float32Array} positions
1239
1247
  * @param {Float32Array} normals
1240
1248
  * @param {Uint32Array} indices
@@ -1246,9 +1254,10 @@ export class IfcAPI {
1246
1254
  * @param {boolean} include_metadata
1247
1255
  * @param {boolean | null} [lit]
1248
1256
  * @param {boolean | null} [emissive]
1257
+ * @param {Float64Array | null} [world_matrix]
1249
1258
  * @returns {Uint8Array}
1250
1259
  */
1251
- exportGlbFromMeshes(positions, normals, indices, vertex_counts, index_counts, colors, origins, express_ids, include_metadata, lit, emissive) {
1260
+ exportGlbFromMeshes(positions, normals, indices, vertex_counts, index_counts, colors, origins, express_ids, include_metadata, lit, emissive, world_matrix) {
1252
1261
  try {
1253
1262
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1254
1263
  const ptr0 = passArrayF32ToWasm0(positions, wasm.__wbindgen_export);
@@ -1267,7 +1276,9 @@ export class IfcAPI {
1267
1276
  const len6 = WASM_VECTOR_LEN;
1268
1277
  const ptr7 = passArray32ToWasm0(express_ids, wasm.__wbindgen_export);
1269
1278
  const len7 = WASM_VECTOR_LEN;
1270
- wasm.ifcapi_exportGlbFromMeshes(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, ptr6, len6, ptr7, len7, include_metadata, isLikeNone(lit) ? 0xFFFFFF : lit ? 1 : 0, isLikeNone(emissive) ? 0xFFFFFF : emissive ? 1 : 0);
1279
+ var ptr8 = isLikeNone(world_matrix) ? 0 : passArrayF64ToWasm0(world_matrix, wasm.__wbindgen_export);
1280
+ var len8 = WASM_VECTOR_LEN;
1281
+ wasm.ifcapi_exportGlbFromMeshes(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, ptr6, len6, ptr7, len7, include_metadata, isLikeNone(lit) ? 0xFFFFFF : lit ? 1 : 0, isLikeNone(emissive) ? 0xFFFFFF : emissive ? 1 : 0, ptr8, len8);
1271
1282
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1272
1283
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1273
1284
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -1275,9 +1286,9 @@ export class IfcAPI {
1275
1286
  if (r3) {
1276
1287
  throw takeObject(r2);
1277
1288
  }
1278
- var v9 = getArrayU8FromWasm0(r0, r1).slice();
1289
+ var v10 = getArrayU8FromWasm0(r0, r1).slice();
1279
1290
  wasm.__wbindgen_export4(r0, r1 * 1, 1);
1280
- return v9;
1291
+ return v10;
1281
1292
  } finally {
1282
1293
  wasm.__wbindgen_add_to_stack_pointer(16);
1283
1294
  }
@@ -1503,6 +1514,48 @@ export class IfcAPI {
1503
1514
  wasm.__wbindgen_add_to_stack_pointer(16);
1504
1515
  }
1505
1516
  }
1517
+ /**
1518
+ * Export the terrain products `product_ids` (express ids) of `content` as
1519
+ * one LandXML 1.2 document, one `<Surface>` each.
1520
+ *
1521
+ * Returns JSON `{ xml, crsName, surfaces: [{ productId, globalId, name,
1522
+ * points, faces }] }`. A selection that is not an authored triangulated
1523
+ * terrain, or whose georeferencing is missing or ambiguous, throws an
1524
+ * `Error` whose message starts with `TERRAIN_REFUSED:` and names the
1525
+ * reason.
1526
+ * @param {Uint8Array} content
1527
+ * @param {Uint32Array} product_ids
1528
+ * @param {LandXmlTerrainOptionsJs} options
1529
+ * @returns {string}
1530
+ */
1531
+ exportLandXmlTerrain(content, product_ids, options) {
1532
+ let deferred4_0;
1533
+ let deferred4_1;
1534
+ try {
1535
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1536
+ const ptr0 = passArray8ToWasm0(content, wasm.__wbindgen_export);
1537
+ const len0 = WASM_VECTOR_LEN;
1538
+ const ptr1 = passArray32ToWasm0(product_ids, wasm.__wbindgen_export);
1539
+ const len1 = WASM_VECTOR_LEN;
1540
+ wasm.ifcapi_exportLandXmlTerrain(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(options));
1541
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1542
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1543
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1544
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1545
+ var ptr3 = r0;
1546
+ var len3 = r1;
1547
+ if (r3) {
1548
+ ptr3 = 0; len3 = 0;
1549
+ throw takeObject(r2);
1550
+ }
1551
+ deferred4_0 = ptr3;
1552
+ deferred4_1 = len3;
1553
+ return getStringFromWasm0(ptr3, len3);
1554
+ } finally {
1555
+ wasm.__wbindgen_add_to_stack_pointer(16);
1556
+ wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1);
1557
+ }
1558
+ }
1506
1559
  /**
1507
1560
  * Merge several IFC models into one STEP/IFC UTF-8 byte buffer (`Uint8Array`).
1508
1561
  * `concatenated` is every model's
@@ -1525,6 +1578,11 @@ export class IfcAPI {
1525
1578
  wasm.ifcapi_exportMerged(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2);
1526
1579
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1527
1580
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1581
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1582
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1583
+ if (r3) {
1584
+ throw takeObject(r2);
1585
+ }
1528
1586
  var v4 = getArrayU8FromWasm0(r0, r1).slice();
1529
1587
  wasm.__wbindgen_export4(r0, r1 * 1, 1);
1530
1588
  return v4;
@@ -1549,6 +1607,10 @@ export class IfcAPI {
1549
1607
  * for GLB in `export_glb`). A non-empty `Uint32Array` is the ordinary allowlist.
1550
1608
  * Instanced type-library shapes are skipped regardless of the filter.
1551
1609
  *
1610
+ * Fails CLOSED like `exportGlb`: when no mesh is written this throws an
1611
+ * `Error` whose message starts with `NO_RENDER_GEOMETRY`, instead of
1612
+ * returning a header-only OBJ (#7695).
1613
+ *
1552
1614
  * ```javascript
1553
1615
  * const obj = api.exportObj(ifcContent, true, new Uint32Array(), undefined);
1554
1616
  * ```
@@ -1570,6 +1632,11 @@ export class IfcAPI {
1570
1632
  wasm.ifcapi_exportObj(retptr, this.__wbg_ptr, ptr0, len0, include_normals, ptr1, len1, ptr2, len2);
1571
1633
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1572
1634
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1635
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1636
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1637
+ if (r3) {
1638
+ throw takeObject(r2);
1639
+ }
1573
1640
  var v4 = getArrayU8FromWasm0(r0, r1).slice();
1574
1641
  wasm.__wbindgen_export4(r0, r1 * 1, 1);
1575
1642
  return v4;
@@ -1641,6 +1708,10 @@ export class IfcAPI {
1641
1708
  * Export **OpenUSD** (`.usda` ASCII): a real Z-up USD stage — spatial hierarchy of
1642
1709
  * `Xform` prims, `UsdGeomMesh` geometry, `UsdPreviewSurface` materials, IFC
1643
1710
  * metadata as custom attributes. Whole-model (geometry-backed).
1711
+ *
1712
+ * Fails CLOSED like `exportGlb`: a model with no render geometry throws an
1713
+ * `Error` whose message starts with `NO_RENDER_GEOMETRY`, instead of
1714
+ * returning a stage with nothing to look at (#7695).
1644
1715
  * @param {Uint8Array} content
1645
1716
  * @returns {Uint8Array}
1646
1717
  */
@@ -1652,6 +1723,11 @@ export class IfcAPI {
1652
1723
  wasm.ifcapi_exportUsd(retptr, this.__wbg_ptr, ptr0, len0);
1653
1724
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1654
1725
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1726
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1727
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1728
+ if (r3) {
1729
+ throw takeObject(r2);
1730
+ }
1655
1731
  var v2 = getArrayU8FromWasm0(r0, r1).slice();
1656
1732
  wasm.__wbindgen_export4(r0, r1 * 1, 1);
1657
1733
  return v2;
@@ -6329,6 +6405,14 @@ export function setGeometryProgressCallback(callback) {
6329
6405
  * meaningless volumes with a plausible `sumErrorRel`, so the closure proof
6330
6406
  * above is the caller's responsibility and not a formality.
6331
6407
  *
6408
+ * Returns `undefined` when a zone parameter is non-finite, or a mesh vertex
6409
+ * or zone corner lies past ±2^128, the exact kernel's coordinate bound
6410
+ * (#7677): such a split is refused rather than answered wrongly.
6411
+ *
6412
+ * Returns `undefined` if an intersection, zone union or remainder exhausts
6413
+ * the exact kernel's work budget. Completed pieces are not returned as a
6414
+ * successful partial split, and a failed empty piece is not treated as disjoint.
6415
+ *
6332
6416
  * Returns `undefined` when the mesh encloses no volume (no triangles survive
6333
6417
  * the filter above, or the shell is degenerate): there is nothing to split,
6334
6418
  * and a result for it would report `pieceCount` 1, `sumErrorRel` 0 and
@@ -6339,7 +6423,7 @@ export function setGeometryProgressCallback(callback) {
6339
6423
  * const split = splitMeshByZones(positions, indices, new Float64Array([
6340
6424
  * 0, 0, 0, 10, 10, 10, 0,
6341
6425
  * ]));
6342
- * if (!split) return; // the mesh encloses no volume
6426
+ * if (!split) return; // no usable complete split
6343
6427
  * for (let i = 0; i < split.pieceCount; i++) {
6344
6428
  * const piece = split.piece(i);
6345
6429
  * // piece.zoneIndex, piece.positions, piece.indices, piece.volume
Binary file
@@ -0,0 +1,109 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ export class DiffModel {
5
+ free(): void;
6
+ [Symbol.dispose](): void;
7
+ /**
8
+ * Compare this base model with a head model, returning row-index records.
9
+ * No JS reference is serialized, cloned, or retained inside WASM.
10
+ */
11
+ compare(head: DiffModel, options: any): any;
12
+ /**
13
+ * Create an owned model from columnar buffers. Call free() when finished;
14
+ * a model may participate in any number of comparisons before that.
15
+ */
16
+ constructor(strings: any, fields: Uint32Array, flags: Uint8Array, boxes: Float64Array, volumes: Float64Array, component_offsets: Uint32Array, component_pairs: Uint32Array);
17
+ readonly entityCount: number;
18
+ }
19
+
20
+ /**
21
+ * Component hashes share the canonical Rust attribute projection.
22
+ */
23
+ export function diffBuildComponentFingerprints(input: any): any;
24
+
25
+ /**
26
+ * Hash adapter data directly in Rust without a JSON text round trip.
27
+ */
28
+ export function diffBuildDataFingerprint(input: any): string;
29
+
30
+ /**
31
+ * Normalize, deduplicate and validate an identity or lineage sidecar.
32
+ */
33
+ export function diffCreateSidecar(text: string, lineage: boolean): string;
34
+
35
+ /**
36
+ * Return head/base pairs in JavaScript Map insertion order.
37
+ */
38
+ export function diffKeyAliasesFromLineage(value: any): any;
39
+
40
+ /**
41
+ * Return ordered conflict diagnostics for caller-supplied lineage entries.
42
+ */
43
+ export function diffLineageConflicts(value: any): string[];
44
+
45
+ /**
46
+ * Migrate keys using Rust policies, preserving the absence of orphan relations.
47
+ */
48
+ export function diffRekeyByLineage(keys: string[], value: any, deleted: string[], policy: string): any;
49
+
50
+ /**
51
+ * Emit JSON.stringify-compatible pretty bytes and the trailing newline.
52
+ */
53
+ export function diffSerializeSidecar(text: string): string;
54
+
55
+ /**
56
+ * Raw code units preserve JS strings that cannot be represented as Rust UTF-8.
57
+ */
58
+ export function diffStableHash(units: Uint16Array): string;
59
+
60
+ /**
61
+ * Host decoding preserves lone UTF-16 units even inside conflict diagnostics.
62
+ */
63
+ export function diffValidateSidecar(text: string, lineage: boolean): string[];
64
+
65
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
66
+
67
+ export interface InitOutput {
68
+ readonly memory: WebAssembly.Memory;
69
+ readonly __wbg_diffmodel_free: (a: number, b: number) => void;
70
+ readonly diffBuildComponentFingerprints: (a: number, b: number) => void;
71
+ readonly diffBuildDataFingerprint: (a: number, b: number) => void;
72
+ readonly diffCreateSidecar: (a: number, b: number, c: number) => void;
73
+ readonly diffKeyAliasesFromLineage: (a: number, b: number) => void;
74
+ readonly diffLineageConflicts: (a: number, b: number) => void;
75
+ readonly diffRekeyByLineage: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
76
+ readonly diffSerializeSidecar: (a: number, b: number) => void;
77
+ readonly diffStableHash: (a: number, b: number, c: number) => void;
78
+ readonly diffValidateSidecar: (a: number, b: number, c: number) => void;
79
+ readonly diffmodel_compare: (a: number, b: number, c: number, d: number) => void;
80
+ readonly diffmodel_entityCount: (a: number) => number;
81
+ readonly diffmodel_new: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number) => void;
82
+ readonly __wbindgen_export: (a: number, b: number) => number;
83
+ readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
84
+ readonly __wbindgen_export3: (a: number) => void;
85
+ readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
86
+ readonly __wbindgen_export4: (a: number, b: number, c: number) => void;
87
+ }
88
+
89
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
90
+
91
+ /**
92
+ * Instantiates the given `module`, which can either be bytes or
93
+ * a precompiled `WebAssembly.Module`.
94
+ *
95
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
96
+ *
97
+ * @returns {InitOutput}
98
+ */
99
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
100
+
101
+ /**
102
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
103
+ * for everything else, calls `WebAssembly.instantiate` directly.
104
+ *
105
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
106
+ *
107
+ * @returns {Promise<InitOutput>}
108
+ */
109
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;