@ifc-lite/wasm 10.1.2 → 10.3.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
@@ -33,6 +33,23 @@ console.log(`Entities: ${refs.length}`);
33
33
  api.free(); // free the API instance
34
34
  ```
35
35
 
36
+ `api.extrusionDefinitions(bytes, ids)` returns exact authored
37
+ `IfcExtrudedAreaSolid` sources and placed product occurrences without decoding
38
+ meshes. Omit `ids` for all products, pass `new Uint32Array()` for none, or
39
+ selected product STEP IDs for a filtered view. Repeated mapping targets share a source key while each
40
+ occurrence retains its f64 `world_from_source` matrix and deterministic ordinal.
41
+ Complete sources with valid positive net profile area have
42
+ `nominal_quantities` in raw squared/cubed IFC file units; unsupported or
43
+ invalid sources have `null`.
44
+ For a complete source-profile point, apply `profile_position`, then
45
+ `position_matrix`, then `world_from_source`; the last matrix includes file-unit
46
+ conversion and maps to absolute IFC Z-up metres. An absent optional `Position`
47
+ leaves its matrix field `null`, so use identity for that step when composing
48
+ rather than expecting an identity array. Check `status` before interpreting a
49
+ null matrix; unsupported sources and bounded output are reported by `status`
50
+ and `diagnostics`. CSG operands carry
51
+ `source_modified=true` because their final body can differ.
52
+
36
53
  ## Meshes (pre-pass + job batches)
37
54
 
38
55
  Geometry runs as a single pre-pass (one scan that produces a flat job list
@@ -219,3 +236,34 @@ the versioned behavior.
219
236
  Combined fill and dashed-stroke paints can still refuse atomically when
220
237
  multiple run boundaries produce crossings outside the current fill-region
221
238
  qualifier.
239
+
240
+ ## Retained alignment station frames
241
+
242
+ `AlignmentAxisJs` evaluates one `IfcAlignment` through the canonical Rust
243
+ evaluator. Its `GlobalId` and `Name` properties use exact IFC EXPRESS names;
244
+ `expressId`, `geometricHorizontalLengthMeters` and `approximate` are derived
245
+ metadata. The caller owns the handle and must call `free()` in `finally`.
246
+
247
+ ```ts
248
+ import init, { AlignmentAxisJs } from '@ifc-lite/wasm';
249
+
250
+ await init();
251
+ const content = await (await fetch('alignment.ifc')).text();
252
+ const axis = new AlignmentAxisJs(content, 39);
253
+ try {
254
+ const sample = axis.evaluate(10);
255
+ console.log(axis.GlobalId, axis.Name, sample);
256
+ } finally {
257
+ axis.free();
258
+ }
259
+ ```
260
+
261
+ `evaluate(distanceMeters)` returns a `Float64Array` containing horizontal
262
+ distance, absolute IFC Z-up point X/Y/Z in metres, and normalized world tangent
263
+ X/Y/Z. Distance is alignment-local geometric horizontal length from the physical
264
+ start, independent of authored chainage and different from 3D arc length. No
265
+ renderer origin or axis conversion is applied. Nonfinite or out-of-range
266
+ distances and unresolved units, curves or placements fail explicitly. The
267
+ `approximate` flag identifies supported approximation paths; it must be exposed
268
+ to precision-sensitive consumers. Whole-source parsing belongs in a disposable
269
+ worker when used by the viewer, so releasing the tool also releases WASM pages.
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.1.2",
8
+ "version": "10.3.0",
9
9
  "license": "MPL-2.0",
10
10
  "repository": {
11
11
  "type": "git",
package/pkg/ifc-lite.d.ts CHANGED
@@ -132,6 +132,72 @@ export interface LandXmlPipeJs { source_id: string; source_path: string; name: s
132
132
 
133
133
 
134
134
 
135
+ export type AnalyticStatusJs = { type: "complete" } | { type: "unsupported"; reason: string };
136
+ export type AnalyticSourceContextJs =
137
+ | { kind: "direct"; representation_id: number }
138
+ | { kind: "mapped"; representation_map_path: number[] };
139
+ export interface AnalyticSourceKeyJs {
140
+ model_sha256: string; schema: string | null; length_unit_scale_bits: string;
141
+ context: AnalyticSourceContextJs; solid_id: number;
142
+ }
143
+ export type AnalyticCurveSegmentJs =
144
+ | { type: "line"; start: number[]; end: number[] }
145
+ | { type: "arc"; center: number[]; normal: number[]; x_axis: number[];
146
+ radius: number; start_angle: number; sweep_angle: number };
147
+ export interface AnalyticProfileLoopJs {
148
+ kind: "outer" | "inner"; segments: AnalyticCurveSegmentJs[];
149
+ signed_area: number; perimeter: number;
150
+ }
151
+ export interface AnalyticProfileJs {
152
+ profile_id: number; ifc_type_name: string; ProfileType: string | null;
153
+ Position: number | null; profile_position: number[] | null;
154
+ loops: AnalyticProfileLoopJs[]; status: AnalyticStatusJs;
155
+ }
156
+ export interface AnalyticExtrusionJs {
157
+ solid_id: number; SweptArea: number | null; profile: AnalyticProfileJs | null;
158
+ Position: number | null; position_matrix: number[] | null;
159
+ ExtrudedDirection: number | null; DirectionRatios: number[] | null;
160
+ axis_unit_vector: number[] | null; Depth: number | null; status: AnalyticStatusJs;
161
+ }
162
+ export interface ExtrusionNominalQuantitiesJs {
163
+ profile_area: number; projected_height: number; nominal_volume: number;
164
+ }
165
+ export interface ExtrusionDefinitionJs {
166
+ key: AnalyticSourceKeyJs; source: AnalyticExtrusionJs;
167
+ /** Squared/cubed IFC file-length units; null for unsupported or invalid sources. */
168
+ nominal_quantities: ExtrusionNominalQuantitiesJs | null;
169
+ }
170
+ export interface ExtrusionInstanceJs {
171
+ ordinal: number; source: AnalyticSourceKeyJs; product_id: number;
172
+ solid_id: number; mapping_path: number[]; source_modified: boolean;
173
+ world_from_source: number[] | null; status: AnalyticStatusJs;
174
+ }
175
+ export interface ExtrusionDefinitionsJs {
176
+ up_axis: "Z"; source_units: "ifc_file_length_units"; world_units: "m";
177
+ coordinate_space: "absolute_ifc_world"; model_sha256: string;
178
+ schema: string | null; length_unit_scale: number;
179
+ sources: ExtrusionDefinitionJs[];
180
+ instances: Record<number, ExtrusionInstanceJs[]>; diagnostics: string[];
181
+ }
182
+
183
+
184
+
185
+ export class AlignmentAxisJs {
186
+ free(): void;
187
+ [Symbol.dispose](): void;
188
+ /**
189
+ * [horizontal distance, IFC Z-up point XYZ, normalized world tangent XYZ].
190
+ * Coordinates remain f64 absolute metres; no renderer origin is applied.
191
+ */
192
+ evaluate(distance_m: number): Float64Array;
193
+ constructor(content: string, express_id: number);
194
+ readonly GlobalId: string | undefined;
195
+ readonly Name: string | undefined;
196
+ readonly approximate: boolean;
197
+ readonly expressId: number;
198
+ readonly geometricHorizontalLengthMeters: number;
199
+ }
200
+
135
201
  /**
136
202
  * The overlap solid of one clashing pair, or the reason there is none.
137
203
  */
@@ -684,8 +750,13 @@ export class IfcAPI {
684
750
  * when a filter matched nothing (#4659, the STEP twin of #4483/#4484). When
685
751
  * set, the forward `#`-reference closure is added so the subset never dangles
686
752
  * a reference.
687
- * `mutations_json` carries `MutablePropertyView` edits (attribute updates +
688
- * property-set synthesis); empty ⇒ none. See `export_step_json` for the shape.
753
+ * `mutations_json` carries `MutablePropertyView` edits; empty ⇒ none. It is
754
+ * either the mutation log `MutablePropertyView.exportMutations()` returns
755
+ * (an object with a `mutations` array, optionally `newEntities` and
756
+ * `georefMutations`), written with byte parity to the TypeScript
757
+ * `StepExporter` (#5941), or the older pre-serialized
758
+ * `{ attributeUpdates, propertyMutations }` shape. A log does not combine
759
+ * with `included`. See `export_step_json` for both shapes.
689
760
  * A non-empty but malformed `mutations_json` throws rather than silently
690
761
  * exporting the model with none of the caller's edits applied — mirrors
691
762
  * `exportGlb`'s and `exportMerged`'s fail-closed contract on this same API.
@@ -720,6 +791,22 @@ export class IfcAPI {
720
791
  * ```
721
792
  */
722
793
  extractProfiles(content: string, model_index: number): ProfileCollection;
794
+ /**
795
+ * Return authored swept-disk occurrences, including exact line/arc
796
+ * directrices and derived measurements, in absolute IFC Z-up metres.
797
+ * `ids` contains product STEP IDs; omit it for all products or pass an
798
+ * empty `Uint32Array` for none. Unsupported records keep their status and
799
+ * a null `directrix_metrics`; malformed representation walks report a
800
+ * diagnostic and omit that product atomically.
801
+ */
802
+ extractSweptDiskDescriptions(content: Uint8Array, ids?: Uint32Array | null): any;
803
+ /**
804
+ * `ids` is an optional product STEP-ID filter; `None` selects all and
805
+ * `Some([])` selects no products, matching the Rust and Python APIs.
806
+ * Matrices are column-major f64; profile_position and position_matrix are
807
+ * applied before world_from_source. No mesh is decoded on this path.
808
+ */
809
+ extrusionDefinitions(content: Uint8Array, ids?: Uint32Array | null): ExtrusionDefinitionsJs;
723
810
  /**
724
811
  * Sharded pre-pass: merge the shard-resolved styled-item columns with the
725
812
  * SUPPORT spans (extracted host-side from the shard classes) and run the
@@ -728,7 +815,9 @@ export class IfcAPI {
728
815
  * Span arguments are `[id, start, len]` triples; `plane_angle_to_radians`
729
816
  * comes from the meta event. `orphanColors` / `geomColors` carry exactly
730
817
  * four floats per id in `orphanIds` / `geomIds`; any other length throws
731
- * before either column is read.
818
+ * before either column is read. The payload's `styleFinishes` come from
819
+ * the geometry finishes a preceding `setPrepassGeometryFinishes` stashed
820
+ * (consumed here); without that call they are all NaN.
732
821
  */
733
822
  finalizePrepassStyles(data: Uint8Array, orphan_ids: Uint32Array, orphan_colors: Float32Array, geom_ids: Uint32Array, geom_colors: Float32Array, colour_map_spans: Uint32Array, material_def_spans: Uint32Array, rel_material_spans: Uint32Array, void_spans: Uint32Array, fills_spans: Uint32Array, aggregate_spans: Uint32Array, plane_angle_to_radians: number): any;
734
823
  /**
@@ -864,6 +953,11 @@ export class IfcAPI {
864
953
  * Does not mutate the IFC snapshot or decode the host-owned image.
865
954
  */
866
955
  planCapturedMesh(content: Uint8Array, request_json: string): Uint8Array;
956
+ /**
957
+ * Plan opt-in map similarity normalization on a completed STEP export.
958
+ * Returns entity patches, allocated IDs and atomic refusal warnings as JSON.
959
+ */
960
+ planMapConversionNormalization(content: Uint8Array): string;
867
961
  /**
868
962
  * Registered mesh observations over canonical target albedo. Host verifies
869
963
  * original GLB identity against decoded source mesh/image and freezes frames.
@@ -970,7 +1064,10 @@ export class IfcAPI {
970
1064
  * Sharded pre-pass: resolve ONE contiguous (file-ordered) slice of the
971
1065
  * styled-item span list on this worker, against the entity index installed
972
1066
  * by `setEntityIndex`. Returns raw resolved maps as flat columns:
973
- * `{ orphanIds, orphanColors (f32 rgba per id), geomIds, geomColors }`.
1067
+ * `{ orphanIds, orphanColors (f32 rgba per id), geomIds, geomColors,
1068
+ * geomFinishes }`, where `geomFinishes` is the #5582 `[metallic,
1069
+ * roughness]` pair per `geomIds` entry (NaN when unauthored), from
1070
+ * `resolve_geometry_finishes` over this slice.
974
1071
  * The host merges shard results IN SHARD ORDER with first-wins per
975
1072
  * geometry id, reproducing the serial resolver's file-order precedence,
976
1073
  * then hands the merged columns to `finalizePrepassStyles`.
@@ -1138,6 +1235,15 @@ export class IfcAPI {
1138
1235
  * Default is `false`. Pass `true` before calling `processGeometryBatch`.
1139
1236
  */
1140
1237
  setMergeLayers(enabled: boolean): void;
1238
+ /**
1239
+ * Sharded pre-pass (#5582): stash the shard-merged geometry finishes —
1240
+ * the `geomFinishes` columns `resolveStyledItemsShard` returns, merged
1241
+ * first-wins like `geomColors` — for the next `finalizePrepassStyles` /
1242
+ * `finalizePrepassStylesFromSource` call on this instance, which consumes
1243
+ * them and emits the aligned `styleFinishes`. Without this call that
1244
+ * finalize emits NaN finishes, as it always emitted colours only.
1245
+ */
1246
+ setPrepassGeometryFinishes(geom_ids: Uint32Array, geom_finishes: Float32Array): void;
1141
1247
  /**
1142
1248
  * Enable or disable the PARAMETRIC rectangular-opening fast path (the
1143
1249
  * placement-frame, ground-truth-exact analytic cut) for `processGeometryBatch`.
@@ -1193,6 +1299,22 @@ export class IfcAPI {
1193
1299
  * single JS→wasm copy directly; we wrap it in `Arc` with no second copy.
1194
1300
  */
1195
1301
  setSourceBytes(data: Uint8Array): void;
1302
+ /**
1303
+ * Install the prepass's authored metallic/roughness per style (#5582):
1304
+ * `styleFinishes` carries two floats per `styleIds` entry,
1305
+ * `[metallic, roughness]`, NaN for an unauthored field — the
1306
+ * `styleFinishes` array every prepass result carries beside `styleColors`.
1307
+ * Call it with the same `styleIds` later passed to `processGeometryBatch*`;
1308
+ * finishes set for a different style wire are ignored. Empty arrays clear
1309
+ * them. Malformed lengths never throw: a style without a complete pair
1310
+ * simply gets no finish.
1311
+ *
1312
+ * The batch stamps each returned `MeshDataJs` (`metallic` / `roughness`)
1313
+ * from these, taking each mesh's finish from the style its colour came
1314
+ * from (#5984). Occurrences that ride the instanced (IFNS) shard carry
1315
+ * theirs in the shard's per-instance finish field (v3).
1316
+ */
1317
+ setStyleFinishes(style_ids: Uint32Array, style_finishes: Float32Array): void;
1196
1318
  /**
1197
1319
  * Select the tessellation detail level applied by every subsequent
1198
1320
  * `processGeometryBatch` call (issue #976, step 4).
@@ -1492,6 +1614,10 @@ export class MeshDataJs {
1492
1614
  * `IfcMaterial` layer sliced, or `undefined` (#3199).
1493
1615
  */
1494
1616
  readonly materialId: number | undefined;
1617
+ /**
1618
+ * IFC-authored metallic/roughness (#5582). `undefined` when unauthored.
1619
+ */
1620
+ readonly metallic: number | undefined;
1495
1621
  /**
1496
1622
  * Get normals as Float32Array (copy to JS)
1497
1623
  */
@@ -1506,6 +1632,7 @@ export class MeshDataJs {
1506
1632
  * Get positions as Float32Array (copy to JS)
1507
1633
  */
1508
1634
  readonly positions: Float32Array;
1635
+ readonly roughness: number | undefined;
1509
1636
  /**
1510
1637
  * Optional SurfaceColour for the "Shading" GLB-export choice — only
1511
1638
  * present when the file authored a distinct DiffuseColour. JS sees
@@ -2296,6 +2423,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
2296
2423
 
2297
2424
  export interface InitOutput {
2298
2425
  readonly memory: WebAssembly.Memory;
2426
+ readonly __wbg_alignmentaxisjs_free: (a: number, b: number) => void;
2299
2427
  readonly __wbg_clashintersectionsolidjs_free: (a: number, b: number) => void;
2300
2428
  readonly __wbg_clashrunresult_free: (a: number, b: number) => void;
2301
2429
  readonly __wbg_clashsession_free: (a: number, b: number) => void;
@@ -2319,6 +2447,13 @@ export interface InitOutput {
2319
2447
  readonly __wbg_symbolictext_free: (a: number, b: number) => void;
2320
2448
  readonly __wbg_zonepiecejs_free: (a: number, b: number) => void;
2321
2449
  readonly __wbg_zonesplitjs_free: (a: number, b: number) => void;
2450
+ readonly alignmentaxisjs_GlobalId: (a: number, b: number) => void;
2451
+ readonly alignmentaxisjs_Name: (a: number, b: number) => void;
2452
+ readonly alignmentaxisjs_approximate: (a: number) => number;
2453
+ readonly alignmentaxisjs_evaluate: (a: number, b: number, c: number) => void;
2454
+ readonly alignmentaxisjs_expressId: (a: number) => number;
2455
+ readonly alignmentaxisjs_geometricHorizontalLengthMeters: (a: number) => number;
2456
+ readonly alignmentaxisjs_new: (a: number, b: number, c: number, d: number) => void;
2322
2457
  readonly clashIntersectionSolid: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => number;
2323
2458
  readonly clashintersectionsolidjs_degenerateReason: (a: number, b: number) => void;
2324
2459
  readonly clashintersectionsolidjs_indices: (a: number, b: number) => void;
@@ -2383,6 +2518,8 @@ export interface InitOutput {
2383
2518
  readonly ifcapi_exportStep: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
2384
2519
  readonly ifcapi_exportUsd: (a: number, b: number, c: number, d: number) => void;
2385
2520
  readonly ifcapi_extractProfiles: (a: number, b: number, c: number, d: number) => number;
2521
+ readonly ifcapi_extractSweptDiskDescriptions: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2522
+ readonly ifcapi_extrusionDefinitions: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2386
2523
  readonly ifcapi_finalizePrepassStyles: (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) => void;
2387
2524
  readonly ifcapi_finalizePrepassStylesFromSource: (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;
2388
2525
  readonly ifcapi_getMemory: (a: number) => number;
@@ -2404,6 +2541,7 @@ export interface InitOutput {
2404
2541
  readonly ifcapi_planAnnotationPlane: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2405
2542
  readonly ifcapi_planAppearance: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2406
2543
  readonly ifcapi_planCapturedMesh: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2544
+ readonly ifcapi_planMapConversionNormalization: (a: number, b: number, c: number, d: number) => void;
2407
2545
  readonly ifcapi_planMeshTransfer: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
2408
2546
  readonly ifcapi_planPageAppearance: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
2409
2547
  readonly ifcapi_planPdfFillAnnotation: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
@@ -2430,10 +2568,12 @@ export interface InitOutput {
2430
2568
  readonly ifcapi_setMappedInstancePlan: (a: number, b: number, c: number) => void;
2431
2569
  readonly ifcapi_setMaterialLayerIndex: (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) => void;
2432
2570
  readonly ifcapi_setMergeLayers: (a: number, b: number) => void;
2571
+ readonly ifcapi_setPrepassGeometryFinishes: (a: number, b: number, c: number, d: number, e: number) => void;
2433
2572
  readonly ifcapi_setRectParamFastPath: (a: number, b: number) => void;
2434
2573
  readonly ifcapi_setReferencedRepmaps: (a: number, b: number, c: number) => void;
2435
2574
  readonly ifcapi_setSkipSmallCuts: (a: number, b: number) => void;
2436
2575
  readonly ifcapi_setSourceBytes: (a: number, b: number, c: number) => void;
2576
+ readonly ifcapi_setStyleFinishes: (a: number, b: number, c: number, d: number, e: number) => void;
2437
2577
  readonly ifcapi_setTessellationQuality: (a: number, b: number, c: number, d: number) => void;
2438
2578
  readonly ifcapi_simplifyMeshes: (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;
2439
2579
  readonly ifcapi_version: (a: number, b: number) => void;
@@ -2475,9 +2615,11 @@ export interface InitOutput {
2475
2615
  readonly meshdatajs_localBounds: (a: number, b: number) => void;
2476
2616
  readonly meshdatajs_localToWorld: (a: number, b: number) => void;
2477
2617
  readonly meshdatajs_materialId: (a: number) => number;
2618
+ readonly meshdatajs_metallic: (a: number) => number;
2478
2619
  readonly meshdatajs_normals: (a: number) => number;
2479
2620
  readonly meshdatajs_origin: (a: number) => number;
2480
2621
  readonly meshdatajs_positions: (a: number) => number;
2622
+ readonly meshdatajs_roughness: (a: number) => number;
2481
2623
  readonly meshdatajs_shadingColor: (a: number, b: number) => void;
2482
2624
  readonly meshdatajs_textureHeight: (a: number) => number;
2483
2625
  readonly meshdatajs_textureId: (a: number) => number;
package/pkg/ifc-lite.js CHANGED
@@ -1,5 +1,125 @@
1
1
  /* @ts-self-types="./ifc-lite.d.ts" */
2
2
 
3
+ export class AlignmentAxisJs {
4
+ __destroy_into_raw() {
5
+ const ptr = this.__wbg_ptr;
6
+ this.__wbg_ptr = 0;
7
+ AlignmentAxisJsFinalization.unregister(this);
8
+ return ptr;
9
+ }
10
+ free() {
11
+ const ptr = this.__destroy_into_raw();
12
+ wasm.__wbg_alignmentaxisjs_free(ptr, 0);
13
+ }
14
+ /**
15
+ * @returns {string | undefined}
16
+ */
17
+ get GlobalId() {
18
+ try {
19
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
20
+ wasm.alignmentaxisjs_GlobalId(retptr, this.__wbg_ptr);
21
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
22
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
23
+ let v1;
24
+ if (r0 !== 0) {
25
+ v1 = getStringFromWasm0(r0, r1).slice();
26
+ wasm.__wbindgen_export4(r0, r1 * 1, 1);
27
+ }
28
+ return v1;
29
+ } finally {
30
+ wasm.__wbindgen_add_to_stack_pointer(16);
31
+ }
32
+ }
33
+ /**
34
+ * @returns {string | undefined}
35
+ */
36
+ get Name() {
37
+ try {
38
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
39
+ wasm.alignmentaxisjs_Name(retptr, this.__wbg_ptr);
40
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
41
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
42
+ let v1;
43
+ if (r0 !== 0) {
44
+ v1 = getStringFromWasm0(r0, r1).slice();
45
+ wasm.__wbindgen_export4(r0, r1 * 1, 1);
46
+ }
47
+ return v1;
48
+ } finally {
49
+ wasm.__wbindgen_add_to_stack_pointer(16);
50
+ }
51
+ }
52
+ /**
53
+ * @returns {boolean}
54
+ */
55
+ get approximate() {
56
+ const ret = wasm.alignmentaxisjs_approximate(this.__wbg_ptr);
57
+ return ret !== 0;
58
+ }
59
+ /**
60
+ * [horizontal distance, IFC Z-up point XYZ, normalized world tangent XYZ].
61
+ * Coordinates remain f64 absolute metres; no renderer origin is applied.
62
+ * @param {number} distance_m
63
+ * @returns {Float64Array}
64
+ */
65
+ evaluate(distance_m) {
66
+ try {
67
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
68
+ wasm.alignmentaxisjs_evaluate(retptr, this.__wbg_ptr, distance_m);
69
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
70
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
71
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
72
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
73
+ if (r3) {
74
+ throw takeObject(r2);
75
+ }
76
+ var v1 = getArrayF64FromWasm0(r0, r1).slice();
77
+ wasm.__wbindgen_export4(r0, r1 * 8, 8);
78
+ return v1;
79
+ } finally {
80
+ wasm.__wbindgen_add_to_stack_pointer(16);
81
+ }
82
+ }
83
+ /**
84
+ * @returns {number}
85
+ */
86
+ get expressId() {
87
+ const ret = wasm.alignmentaxisjs_expressId(this.__wbg_ptr);
88
+ return ret >>> 0;
89
+ }
90
+ /**
91
+ * @returns {number}
92
+ */
93
+ get geometricHorizontalLengthMeters() {
94
+ const ret = wasm.alignmentaxisjs_geometricHorizontalLengthMeters(this.__wbg_ptr);
95
+ return ret;
96
+ }
97
+ /**
98
+ * @param {string} content
99
+ * @param {number} express_id
100
+ */
101
+ constructor(content, express_id) {
102
+ try {
103
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
104
+ const ptr0 = passStringToWasm0(content, wasm.__wbindgen_export, wasm.__wbindgen_export2);
105
+ const len0 = WASM_VECTOR_LEN;
106
+ wasm.alignmentaxisjs_new(retptr, ptr0, len0, express_id);
107
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
108
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
109
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
110
+ if (r2) {
111
+ throw takeObject(r1);
112
+ }
113
+ this.__wbg_ptr = r0;
114
+ AlignmentAxisJsFinalization.register(this, this.__wbg_ptr, this);
115
+ return this;
116
+ } finally {
117
+ wasm.__wbindgen_add_to_stack_pointer(16);
118
+ }
119
+ }
120
+ }
121
+ if (Symbol.dispose) AlignmentAxisJs.prototype[Symbol.dispose] = AlignmentAxisJs.prototype.free;
122
+
3
123
  /**
4
124
  * The overlap solid of one clashing pair, or the reason there is none.
5
125
  */
@@ -1475,8 +1595,13 @@ export class IfcAPI {
1475
1595
  * when a filter matched nothing (#4659, the STEP twin of #4483/#4484). When
1476
1596
  * set, the forward `#`-reference closure is added so the subset never dangles
1477
1597
  * a reference.
1478
- * `mutations_json` carries `MutablePropertyView` edits (attribute updates +
1479
- * property-set synthesis); empty ⇒ none. See `export_step_json` for the shape.
1598
+ * `mutations_json` carries `MutablePropertyView` edits; empty ⇒ none. It is
1599
+ * either the mutation log `MutablePropertyView.exportMutations()` returns
1600
+ * (an object with a `mutations` array, optionally `newEntities` and
1601
+ * `georefMutations`), written with byte parity to the TypeScript
1602
+ * `StepExporter` (#5941), or the older pre-serialized
1603
+ * `{ attributeUpdates, propertyMutations }` shape. A log does not combine
1604
+ * with `included`. See `export_step_json` for both shapes.
1480
1605
  * A non-empty but malformed `mutations_json` throws rather than silently
1481
1606
  * exporting the model with none of the caller's edits applied — mirrors
1482
1607
  * `exportGlb`'s and `exportMerged`'s fail-closed contract on this same API.
@@ -1500,6 +1625,11 @@ export class IfcAPI {
1500
1625
  wasm.ifcapi_exportStep(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
1501
1626
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1502
1627
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1628
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1629
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
1630
+ if (r3) {
1631
+ throw takeObject(r2);
1632
+ }
1503
1633
  var v5 = getArrayU8FromWasm0(r0, r1).slice();
1504
1634
  wasm.__wbindgen_export4(r0, r1 * 1, 1);
1505
1635
  return v5;
@@ -1560,6 +1690,64 @@ export class IfcAPI {
1560
1690
  const ret = wasm.ifcapi_extractProfiles(this.__wbg_ptr, ptr0, len0, model_index);
1561
1691
  return ProfileCollection.__wrap(ret);
1562
1692
  }
1693
+ /**
1694
+ * Return authored swept-disk occurrences, including exact line/arc
1695
+ * directrices and derived measurements, in absolute IFC Z-up metres.
1696
+ * `ids` contains product STEP IDs; omit it for all products or pass an
1697
+ * empty `Uint32Array` for none. Unsupported records keep their status and
1698
+ * a null `directrix_metrics`; malformed representation walks report a
1699
+ * diagnostic and omit that product atomically.
1700
+ * @param {Uint8Array} content
1701
+ * @param {Uint32Array | null} [ids]
1702
+ * @returns {any}
1703
+ */
1704
+ extractSweptDiskDescriptions(content, ids) {
1705
+ try {
1706
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1707
+ const ptr0 = passArray8ToWasm0(content, wasm.__wbindgen_export);
1708
+ const len0 = WASM_VECTOR_LEN;
1709
+ var ptr1 = isLikeNone(ids) ? 0 : passArray32ToWasm0(ids, wasm.__wbindgen_export);
1710
+ var len1 = WASM_VECTOR_LEN;
1711
+ wasm.ifcapi_extractSweptDiskDescriptions(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
1712
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1713
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1714
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1715
+ if (r2) {
1716
+ throw takeObject(r1);
1717
+ }
1718
+ return takeObject(r0);
1719
+ } finally {
1720
+ wasm.__wbindgen_add_to_stack_pointer(16);
1721
+ }
1722
+ }
1723
+ /**
1724
+ * `ids` is an optional product STEP-ID filter; `None` selects all and
1725
+ * `Some([])` selects no products, matching the Rust and Python APIs.
1726
+ * Matrices are column-major f64; profile_position and position_matrix are
1727
+ * applied before world_from_source. No mesh is decoded on this path.
1728
+ * @param {Uint8Array} content
1729
+ * @param {Uint32Array | null} [ids]
1730
+ * @returns {ExtrusionDefinitionsJs}
1731
+ */
1732
+ extrusionDefinitions(content, ids) {
1733
+ try {
1734
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1735
+ const ptr0 = passArray8ToWasm0(content, wasm.__wbindgen_export);
1736
+ const len0 = WASM_VECTOR_LEN;
1737
+ var ptr1 = isLikeNone(ids) ? 0 : passArray32ToWasm0(ids, wasm.__wbindgen_export);
1738
+ var len1 = WASM_VECTOR_LEN;
1739
+ wasm.ifcapi_extrusionDefinitions(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
1740
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1741
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1742
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
1743
+ if (r2) {
1744
+ throw takeObject(r1);
1745
+ }
1746
+ return takeObject(r0);
1747
+ } finally {
1748
+ wasm.__wbindgen_add_to_stack_pointer(16);
1749
+ }
1750
+ }
1563
1751
  /**
1564
1752
  * Sharded pre-pass: merge the shard-resolved styled-item columns with the
1565
1753
  * SUPPORT spans (extracted host-side from the shard classes) and run the
@@ -1568,7 +1756,9 @@ export class IfcAPI {
1568
1756
  * Span arguments are `[id, start, len]` triples; `plane_angle_to_radians`
1569
1757
  * comes from the meta event. `orphanColors` / `geomColors` carry exactly
1570
1758
  * four floats per id in `orphanIds` / `geomIds`; any other length throws
1571
- * before either column is read.
1759
+ * before either column is read. The payload's `styleFinishes` come from
1760
+ * the geometry finishes a preceding `setPrepassGeometryFinishes` stashed
1761
+ * (consumed here); without that call they are all NaN.
1572
1762
  * @param {Uint8Array} data
1573
1763
  * @param {Uint32Array} orphan_ids
1574
1764
  * @param {Float32Array} orphan_colors
@@ -2073,6 +2263,38 @@ export class IfcAPI {
2073
2263
  wasm.__wbindgen_add_to_stack_pointer(16);
2074
2264
  }
2075
2265
  }
2266
+ /**
2267
+ * Plan opt-in map similarity normalization on a completed STEP export.
2268
+ * Returns entity patches, allocated IDs and atomic refusal warnings as JSON.
2269
+ * @param {Uint8Array} content
2270
+ * @returns {string}
2271
+ */
2272
+ planMapConversionNormalization(content) {
2273
+ let deferred3_0;
2274
+ let deferred3_1;
2275
+ try {
2276
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
2277
+ const ptr0 = passArray8ToWasm0(content, wasm.__wbindgen_export);
2278
+ const len0 = WASM_VECTOR_LEN;
2279
+ wasm.ifcapi_planMapConversionNormalization(retptr, this.__wbg_ptr, ptr0, len0);
2280
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
2281
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
2282
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
2283
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
2284
+ var ptr2 = r0;
2285
+ var len2 = r1;
2286
+ if (r3) {
2287
+ ptr2 = 0; len2 = 0;
2288
+ throw takeObject(r2);
2289
+ }
2290
+ deferred3_0 = ptr2;
2291
+ deferred3_1 = len2;
2292
+ return getStringFromWasm0(ptr2, len2);
2293
+ } finally {
2294
+ wasm.__wbindgen_add_to_stack_pointer(16);
2295
+ wasm.__wbindgen_export4(deferred3_0, deferred3_1, 1);
2296
+ }
2297
+ }
2076
2298
  /**
2077
2299
  * Registered mesh observations over canonical target albedo. Host verifies
2078
2300
  * original GLB identity against decoded source mesh/image and freezes frames.
@@ -2587,7 +2809,10 @@ export class IfcAPI {
2587
2809
  * Sharded pre-pass: resolve ONE contiguous (file-ordered) slice of the
2588
2810
  * styled-item span list on this worker, against the entity index installed
2589
2811
  * by `setEntityIndex`. Returns raw resolved maps as flat columns:
2590
- * `{ orphanIds, orphanColors (f32 rgba per id), geomIds, geomColors }`.
2812
+ * `{ orphanIds, orphanColors (f32 rgba per id), geomIds, geomColors,
2813
+ * geomFinishes }`, where `geomFinishes` is the #5582 `[metallic,
2814
+ * roughness]` pair per `geomIds` entry (NaN when unauthored), from
2815
+ * `resolve_geometry_finishes` over this slice.
2591
2816
  * The host merges shard results IN SHARD ORDER with first-wins per
2592
2817
  * geometry id, reproducing the serial resolver's file-order precedence,
2593
2818
  * then hands the merged columns to `finalizePrepassStyles`.
@@ -2890,6 +3115,23 @@ export class IfcAPI {
2890
3115
  setMergeLayers(enabled) {
2891
3116
  wasm.ifcapi_setMergeLayers(this.__wbg_ptr, enabled);
2892
3117
  }
3118
+ /**
3119
+ * Sharded pre-pass (#5582): stash the shard-merged geometry finishes —
3120
+ * the `geomFinishes` columns `resolveStyledItemsShard` returns, merged
3121
+ * first-wins like `geomColors` — for the next `finalizePrepassStyles` /
3122
+ * `finalizePrepassStylesFromSource` call on this instance, which consumes
3123
+ * them and emits the aligned `styleFinishes`. Without this call that
3124
+ * finalize emits NaN finishes, as it always emitted colours only.
3125
+ * @param {Uint32Array} geom_ids
3126
+ * @param {Float32Array} geom_finishes
3127
+ */
3128
+ setPrepassGeometryFinishes(geom_ids, geom_finishes) {
3129
+ const ptr0 = passArray32ToWasm0(geom_ids, wasm.__wbindgen_export);
3130
+ const len0 = WASM_VECTOR_LEN;
3131
+ const ptr1 = passArrayF32ToWasm0(geom_finishes, wasm.__wbindgen_export);
3132
+ const len1 = WASM_VECTOR_LEN;
3133
+ wasm.ifcapi_setPrepassGeometryFinishes(this.__wbg_ptr, ptr0, len0, ptr1, len1);
3134
+ }
2893
3135
  /**
2894
3136
  * Enable or disable the PARAMETRIC rectangular-opening fast path (the
2895
3137
  * placement-frame, ground-truth-exact analytic cut) for `processGeometryBatch`.
@@ -2961,6 +3203,30 @@ export class IfcAPI {
2961
3203
  const len0 = WASM_VECTOR_LEN;
2962
3204
  wasm.ifcapi_setSourceBytes(this.__wbg_ptr, ptr0, len0);
2963
3205
  }
3206
+ /**
3207
+ * Install the prepass's authored metallic/roughness per style (#5582):
3208
+ * `styleFinishes` carries two floats per `styleIds` entry,
3209
+ * `[metallic, roughness]`, NaN for an unauthored field — the
3210
+ * `styleFinishes` array every prepass result carries beside `styleColors`.
3211
+ * Call it with the same `styleIds` later passed to `processGeometryBatch*`;
3212
+ * finishes set for a different style wire are ignored. Empty arrays clear
3213
+ * them. Malformed lengths never throw: a style without a complete pair
3214
+ * simply gets no finish.
3215
+ *
3216
+ * The batch stamps each returned `MeshDataJs` (`metallic` / `roughness`)
3217
+ * from these, taking each mesh's finish from the style its colour came
3218
+ * from (#5984). Occurrences that ride the instanced (IFNS) shard carry
3219
+ * theirs in the shard's per-instance finish field (v3).
3220
+ * @param {Uint32Array} style_ids
3221
+ * @param {Float32Array} style_finishes
3222
+ */
3223
+ setStyleFinishes(style_ids, style_finishes) {
3224
+ const ptr0 = passArray32ToWasm0(style_ids, wasm.__wbindgen_export);
3225
+ const len0 = WASM_VECTOR_LEN;
3226
+ const ptr1 = passArrayF32ToWasm0(style_finishes, wasm.__wbindgen_export);
3227
+ const len1 = WASM_VECTOR_LEN;
3228
+ wasm.ifcapi_setStyleFinishes(this.__wbg_ptr, ptr0, len0, ptr1, len1);
3229
+ }
2964
3230
  /**
2965
3231
  * Select the tessellation detail level applied by every subsequent
2966
3232
  * `processGeometryBatch` call (issue #976, step 4).
@@ -3634,6 +3900,14 @@ export class MeshDataJs {
3634
3900
  const ret = wasm.meshdatajs_materialId(this.__wbg_ptr);
3635
3901
  return ret === Number.MAX_SAFE_INTEGER ? undefined : ret;
3636
3902
  }
3903
+ /**
3904
+ * IFC-authored metallic/roughness (#5582). `undefined` when unauthored.
3905
+ * @returns {number | undefined}
3906
+ */
3907
+ get metallic() {
3908
+ const ret = wasm.meshdatajs_metallic(this.__wbg_ptr);
3909
+ return ret === Number.MAX_SAFE_INTEGER ? undefined : ret;
3910
+ }
3637
3911
  /**
3638
3912
  * Get normals as Float32Array (copy to JS)
3639
3913
  * @returns {Float32Array}
@@ -3660,6 +3934,13 @@ export class MeshDataJs {
3660
3934
  const ret = wasm.meshdatajs_positions(this.__wbg_ptr);
3661
3935
  return takeObject(ret);
3662
3936
  }
3937
+ /**
3938
+ * @returns {number | undefined}
3939
+ */
3940
+ get roughness() {
3941
+ const ret = wasm.meshdatajs_roughness(this.__wbg_ptr);
3942
+ return ret === Number.MAX_SAFE_INTEGER ? undefined : ret;
3943
+ }
3663
3944
  /**
3664
3945
  * Optional SurfaceColour for the "Shading" GLB-export choice — only
3665
3946
  * present when the file authored a distinct DiffuseColour. JS sees
@@ -6239,6 +6520,9 @@ function __wbg_get_imports() {
6239
6520
  };
6240
6521
  }
6241
6522
 
6523
+ const AlignmentAxisJsFinalization = (typeof FinalizationRegistry === 'undefined')
6524
+ ? { register: () => {}, unregister: () => {} }
6525
+ : new FinalizationRegistry(ptr => wasm.__wbg_alignmentaxisjs_free(ptr, 1));
6242
6526
  const ClashIntersectionSolidJsFinalization = (typeof FinalizationRegistry === 'undefined')
6243
6527
  ? { register: () => {}, unregister: () => {} }
6244
6528
  : new FinalizationRegistry(ptr => wasm.__wbg_clashintersectionsolidjs_free(ptr, 1));
Binary file