@ifc-lite/wasm 2.7.0 → 2.8.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/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "IFC-Lite Contributors"
6
6
  ],
7
7
  "description": "WebAssembly bindings for IFC-Lite",
8
- "version": "2.7.0",
8
+ "version": "2.8.1",
9
9
  "license": "MPL-2.0",
10
10
  "repository": {
11
11
  "type": "git",
package/pkg/ifc-lite.d.ts CHANGED
@@ -82,13 +82,6 @@ export class GridAxisJs {
82
82
  export class IfcAPI {
83
83
  free(): void;
84
84
  [Symbol.dispose](): void;
85
- /**
86
- * Fast pre-pass: scans for geometry entities ONLY (skips style/void/material resolution).
87
- * Returns job list + unit scale + RTC offset in ~1-2s instead of ~6s.
88
- * Geometry workers can start immediately with default colors + no void subtraction.
89
- * A parallel style worker can run buildPrePassOnce for correct colors later.
90
- */
91
- buildPrePassFast(data: Uint8Array): any;
92
85
  /**
93
86
  * Run the pre-pass ONCE and return serialized results for worker distribution.
94
87
  * Takes raw bytes (&[u8]) to avoid TextDecoder overhead.
@@ -98,16 +91,15 @@ export class IfcAPI {
98
91
  * Process geometry for a subset of pre-scanned entities.
99
92
  * Takes raw bytes and pre-pass data from buildPrePassOnce.
100
93
  */
101
- processGeometryBatch(data: Uint8Array, jobs_flat: Uint32Array, unit_scale: number, rtc_x: number, rtc_y: number, rtc_z: number, needs_shift: boolean, void_keys: Uint32Array, void_counts: Uint32Array, void_values: Uint32Array, style_ids: Uint32Array, style_colors: Uint8Array): MeshCollection;
94
+ processGeometryBatch(data: Uint8Array, jobs_flat: Uint32Array, unit_scale: number, rtc_x: number, rtc_y: number, rtc_z: number, needs_shift: boolean, void_keys: Uint32Array, void_counts: Uint32Array, void_values: Uint32Array, style_ids: Uint32Array, style_colors: Uint8Array, plane_angle_to_radians?: number | null, material_element_ids?: Uint32Array | null, material_color_counts?: Uint32Array | null, material_colors_rgba?: Uint8Array | null): MeshCollection;
102
95
  /**
103
96
  * Streaming pre-pass: emits geometry jobs in chunks via a JS callback
104
97
  * instead of waiting for the full file scan to complete.
105
98
  *
106
99
  * Single linear walk over the file:
107
100
  * 1. Builds the entity index incrementally from the same scan that
108
- * collects geometry jobs (the old `build_pre_pass_fast` did two
109
- * full-file scans — one for entities, one for the index — which
110
- * doubled wall-clock).
101
+ * collects geometry jobs (a separate index scan would double
102
+ * wall-clock).
111
103
  * 2. As soon as `IFCPROJECT` has been seen, the unit scale and the
112
104
  * first ~50 geometry jobs have been collected, resolves
113
105
  * `unitScale` + `rtcOffset` and emits a `meta` callback so the
@@ -125,7 +117,7 @@ export class IfcAPI {
125
117
  * `{ type: "jobs", jobs: Uint32Array }` // [id, start, end] triples
126
118
  * `{ type: "complete", totalJobs }`
127
119
  */
128
- buildPrePassStreaming(data: Uint8Array, on_event: Function, chunk_size: number): any;
120
+ buildPrePassStreaming(data: Uint8Array, on_event: Function, chunk_size: number, disabled_type_names: string[] | null | undefined, skip_type_geometry: boolean): any;
129
121
  /**
130
122
  * Parse the file and return structured per-axis data (tag + endpoints) in
131
123
  * the renderer's Y-up world space (RTC-subtracted, metres). Use this when
@@ -259,19 +251,6 @@ export class IfcAPI {
259
251
  * Create and initialize the IFC API
260
252
  */
261
253
  constructor();
262
- /**
263
- * Parse IFC file with streaming events
264
- * Calls the callback function for each parse event
265
- *
266
- * Example:
267
- * ```javascript
268
- * const api = new IfcAPI();
269
- * await api.parseStreaming(ifcData, (event) => {
270
- * console.log('Event:', event);
271
- * });
272
- * ```
273
- */
274
- parseStreaming(content: string, callback: Function): Promise<any>;
275
254
  /**
276
255
  * Fast entity scanning using SIMD-accelerated Rust scanner
277
256
  * Returns array of entity references for data model parsing
@@ -291,22 +270,6 @@ export class IfcAPI {
291
270
  * Much faster than scanning all entities (3x speedup for large files)
292
271
  */
293
272
  scanGeometryEntitiesFast(content: string): any;
294
- /**
295
- * Fast scan that only returns metadata-relevant entity refs.
296
- * This drastically reduces transfer size for huge-file metadata hydration.
297
- */
298
- scanRelevantEntitiesFastBytes(data: Uint8Array): any;
299
- /**
300
- * Parse IFC file (traditional - waits for completion)
301
- *
302
- * Example:
303
- * ```javascript
304
- * const api = new IfcAPI();
305
- * const result = await api.parse(ifcData);
306
- * console.log('Entities:', result.entityCount);
307
- * ```
308
- */
309
- parse(content: string): Promise<any>;
310
273
  /**
311
274
  * Parse IFC file and extract symbolic representations (Plan,
312
275
  * Annotation, FootPrint, Axis). These are 2D curves used for
@@ -343,14 +306,19 @@ export class MeshCollection {
343
306
  */
344
307
  hasRtcOffset(): boolean;
345
308
  /**
346
- * Convert local coordinates to world coordinates
347
- * Use this to convert mesh positions back to original IFC coordinates
309
+ * Get mesh at index (clones — non-destructive). Prefer `takeMesh` on the
310
+ * hot streaming path; this stays for callers that read meshes more than once.
348
311
  */
349
- localToWorld(x: number, y: number, z: number): Float64Array;
312
+ get(index: number): MeshDataJs | undefined;
350
313
  /**
351
- * Get mesh at index
314
+ * #1097 perf: MOVE the mesh at `index` out of the collection (the Vec
315
+ * buffers are `std::mem::take`-n, leaving an empty stub). The streaming
316
+ * worker reads each mesh exactly once, so moving avoids the full vertex-
317
+ * data clone `get` pays — one fewer copy of positions/normals/indices/uvs/
318
+ * texture per mesh (the JS getters still do the single Rust→JS copy). Calling
319
+ * it twice for the same index yields the second call an empty mesh.
352
320
  */
353
- get(index: number): MeshDataJs | undefined;
321
+ takeMesh(index: number): MeshDataJs | undefined;
354
322
  /**
355
323
  * Get RTC offset X (for converting local coords back to world coords)
356
324
  * Add this to local X coordinates to get world X coordinates
@@ -455,6 +423,12 @@ export class MeshDataJs {
455
423
  * Get color as [r, g, b, a] array
456
424
  */
457
425
  readonly color: Float32Array;
426
+ /**
427
+ * Per-element local-frame origin (Float64Array[3], WebGL Y-up, metres):
428
+ * world position of vertex i = `origin + positions[3i..3i+3]`. Returns
429
+ * [0,0,0] when positions are absolute (legacy / local frame off).
430
+ */
431
+ readonly origin: Float64Array;
458
432
  /**
459
433
  * Get indices as Uint32Array (copy to JS)
460
434
  */
@@ -876,25 +850,21 @@ export interface InitOutput {
876
850
  readonly gridaxisjs_gridId: (a: number) => number;
877
851
  readonly gridaxisjs_start: (a: number) => number;
878
852
  readonly gridaxisjs_tag: (a: number, b: number) => void;
879
- readonly ifcapi_buildPrePassFast: (a: number, b: number, c: number) => number;
880
853
  readonly ifcapi_buildPrePassOnce: (a: number, b: number, c: number) => number;
881
- readonly ifcapi_buildPrePassStreaming: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
854
+ readonly ifcapi_buildPrePassStreaming: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
882
855
  readonly ifcapi_clearPrePassCache: (a: number) => void;
883
856
  readonly ifcapi_extractProfiles: (a: number, b: number, c: number, d: number) => number;
884
857
  readonly ifcapi_getMemory: (a: number) => number;
885
858
  readonly ifcapi_is_ready: (a: number) => number;
886
859
  readonly ifcapi_new: () => number;
887
- readonly ifcapi_parse: (a: number, b: number, c: number) => number;
888
860
  readonly ifcapi_parseAlignmentLines: (a: number, b: number, c: number) => number;
889
861
  readonly ifcapi_parseGridAxes: (a: number, b: number, c: number) => number;
890
862
  readonly ifcapi_parseGridLines: (a: number, b: number, c: number) => number;
891
- readonly ifcapi_parseStreaming: (a: number, b: number, c: number, d: number) => number;
892
863
  readonly ifcapi_parseSymbolicRepresentations: (a: number, b: number, c: number) => number;
893
- readonly ifcapi_processGeometryBatch: (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) => number;
864
+ readonly ifcapi_processGeometryBatch: (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, b1: number) => number;
894
865
  readonly ifcapi_scanEntitiesFast: (a: number, b: number, c: number) => number;
895
866
  readonly ifcapi_scanEntitiesFastBytes: (a: number, b: number, c: number) => number;
896
867
  readonly ifcapi_scanGeometryEntitiesFast: (a: number, b: number, c: number) => number;
897
- readonly ifcapi_scanRelevantEntitiesFastBytes: (a: number, b: number, c: number) => number;
898
868
  readonly ifcapi_setComputeGeometryHashes: (a: number, b: number, c: number) => void;
899
869
  readonly ifcapi_setEntityIndex: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
900
870
  readonly ifcapi_setMergeLayers: (a: number, b: number) => void;
@@ -908,10 +878,10 @@ export interface InitOutput {
908
878
  readonly meshcollection_get: (a: number, b: number) => number;
909
879
  readonly meshcollection_hasRtcOffset: (a: number) => number;
910
880
  readonly meshcollection_length: (a: number) => number;
911
- readonly meshcollection_localToWorld: (a: number, b: number, c: number, d: number, e: number) => void;
912
881
  readonly meshcollection_rtcOffsetX: (a: number) => number;
913
882
  readonly meshcollection_rtcOffsetY: (a: number) => number;
914
883
  readonly meshcollection_rtcOffsetZ: (a: number) => number;
884
+ readonly meshcollection_takeMesh: (a: number, b: number) => number;
915
885
  readonly meshcollection_totalTriangles: (a: number) => number;
916
886
  readonly meshcollection_totalVertices: (a: number) => number;
917
887
  readonly meshdatajs_color: (a: number, b: number) => void;
@@ -921,6 +891,7 @@ export interface InitOutput {
921
891
  readonly meshdatajs_ifcType: (a: number, b: number) => void;
922
892
  readonly meshdatajs_indices: (a: number) => number;
923
893
  readonly meshdatajs_normals: (a: number) => number;
894
+ readonly meshdatajs_origin: (a: number) => number;
924
895
  readonly meshdatajs_positions: (a: number) => number;
925
896
  readonly meshdatajs_shadingColor: (a: number, b: number) => void;
926
897
  readonly meshdatajs_textureHeight: (a: number) => number;
@@ -937,7 +908,6 @@ export interface InitOutput {
937
908
  readonly meshoutlinejs_contourCount: (a: number) => number;
938
909
  readonly profilecollection_get: (a: number, b: number) => number;
939
910
  readonly profilecollection_length: (a: number) => number;
940
- readonly profileentryjs_expressId: (a: number) => number;
941
911
  readonly profileentryjs_extrusionDepth: (a: number) => number;
942
912
  readonly profileentryjs_extrusionDir: (a: number) => number;
943
913
  readonly profileentryjs_holeCounts: (a: number) => number;
@@ -1013,6 +983,7 @@ export interface InitOutput {
1013
983
  readonly init: () => void;
1014
984
  readonly symbolicpolyline_pointCount: (a: number) => number;
1015
985
  readonly get_memory: () => number;
986
+ readonly profileentryjs_expressId: (a: number) => number;
1016
987
  readonly symbolicfillarea_expressId: (a: number) => number;
1017
988
  readonly symbolicpolyline_worldY: (a: number) => number;
1018
989
  readonly symbolictext_colorB: (a: number) => number;
package/pkg/ifc-lite.js CHANGED
@@ -15,10 +15,6 @@ function addBorrowedObject(obj) {
15
15
  return stack_pointer;
16
16
  }
17
17
 
18
- const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
19
- ? { register: () => {}, unregister: () => {} }
20
- : new FinalizationRegistry(state => state.dtor(state.a, state.b));
21
-
22
18
  function dropObject(idx) {
23
19
  if (idx < 132) return;
24
20
  heap[idx] = heap_next;
@@ -122,34 +118,6 @@ function isLikeNone(x) {
122
118
  return x === undefined || x === null;
123
119
  }
124
120
 
125
- function makeMutClosure(arg0, arg1, dtor, f) {
126
- const state = { a: arg0, b: arg1, cnt: 1, dtor };
127
- const real = (...args) => {
128
-
129
- // First up with a closure we increment the internal reference
130
- // count. This ensures that the Rust closure environment won't
131
- // be deallocated while we're invoking it.
132
- state.cnt++;
133
- const a = state.a;
134
- state.a = 0;
135
- try {
136
- return f(a, state.b, ...args);
137
- } finally {
138
- state.a = a;
139
- real._wbg_cb_unref();
140
- }
141
- };
142
- real._wbg_cb_unref = () => {
143
- if (--state.cnt === 0) {
144
- state.dtor(state.a, state.b);
145
- state.a = 0;
146
- CLOSURE_DTORS.unregister(state);
147
- }
148
- };
149
- CLOSURE_DTORS.register(real, state, state);
150
- return real;
151
- }
152
-
153
121
  function passArray32ToWasm0(arg, malloc) {
154
122
  const ptr = malloc(arg.length * 4, 4) >>> 0;
155
123
  getUint32ArrayMemory0().set(arg, ptr / 4);
@@ -178,6 +146,16 @@ function passArrayF64ToWasm0(arg, malloc) {
178
146
  return ptr;
179
147
  }
180
148
 
149
+ function passArrayJsValueToWasm0(array, malloc) {
150
+ const ptr = malloc(array.length * 4, 4) >>> 0;
151
+ const mem = getDataViewMemory0();
152
+ for (let i = 0; i < array.length; i++) {
153
+ mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true);
154
+ }
155
+ WASM_VECTOR_LEN = array.length;
156
+ return ptr;
157
+ }
158
+
181
159
  function passStringToWasm0(arg, malloc, realloc) {
182
160
  if (realloc === undefined) {
183
161
  const buf = cachedTextEncoder.encode(arg);
@@ -252,14 +230,6 @@ if (!('encodeInto' in cachedTextEncoder)) {
252
230
 
253
231
  let WASM_VECTOR_LEN = 0;
254
232
 
255
- function __wasm_bindgen_func_elem_722(arg0, arg1, arg2) {
256
- wasm.__wasm_bindgen_func_elem_722(arg0, arg1, addHeapObject(arg2));
257
- }
258
-
259
- function __wasm_bindgen_func_elem_756(arg0, arg1, arg2, arg3) {
260
- wasm.__wasm_bindgen_func_elem_756(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
261
- }
262
-
263
233
  const ClashRunResultFinalization = (typeof FinalizationRegistry === 'undefined')
264
234
  ? { register: () => {}, unregister: () => {} }
265
235
  : new FinalizationRegistry(ptr => wasm.__wbg_clashrunresult_free(ptr >>> 0, 1));
@@ -654,20 +624,6 @@ export class IfcAPI {
654
624
  const ptr = this.__destroy_into_raw();
655
625
  wasm.__wbg_ifcapi_free(ptr, 0);
656
626
  }
657
- /**
658
- * Fast pre-pass: scans for geometry entities ONLY (skips style/void/material resolution).
659
- * Returns job list + unit scale + RTC offset in ~1-2s instead of ~6s.
660
- * Geometry workers can start immediately with default colors + no void subtraction.
661
- * A parallel style worker can run buildPrePassOnce for correct colors later.
662
- * @param {Uint8Array} data
663
- * @returns {any}
664
- */
665
- buildPrePassFast(data) {
666
- const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);
667
- const len0 = WASM_VECTOR_LEN;
668
- const ret = wasm.ifcapi_buildPrePassFast(this.__wbg_ptr, ptr0, len0);
669
- return takeObject(ret);
670
- }
671
627
  /**
672
628
  * Run the pre-pass ONCE and return serialized results for worker distribution.
673
629
  * Takes raw bytes (&[u8]) to avoid TextDecoder overhead.
@@ -695,9 +651,13 @@ export class IfcAPI {
695
651
  * @param {Uint32Array} void_values
696
652
  * @param {Uint32Array} style_ids
697
653
  * @param {Uint8Array} style_colors
654
+ * @param {number | null} [plane_angle_to_radians]
655
+ * @param {Uint32Array | null} [material_element_ids]
656
+ * @param {Uint32Array | null} [material_color_counts]
657
+ * @param {Uint8Array | null} [material_colors_rgba]
698
658
  * @returns {MeshCollection}
699
659
  */
700
- processGeometryBatch(data, jobs_flat, unit_scale, rtc_x, rtc_y, rtc_z, needs_shift, void_keys, void_counts, void_values, style_ids, style_colors) {
660
+ processGeometryBatch(data, jobs_flat, unit_scale, rtc_x, rtc_y, rtc_z, needs_shift, void_keys, void_counts, void_values, style_ids, style_colors, plane_angle_to_radians, material_element_ids, material_color_counts, material_colors_rgba) {
701
661
  const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);
702
662
  const len0 = WASM_VECTOR_LEN;
703
663
  const ptr1 = passArray32ToWasm0(jobs_flat, wasm.__wbindgen_export);
@@ -712,7 +672,13 @@ export class IfcAPI {
712
672
  const len5 = WASM_VECTOR_LEN;
713
673
  const ptr6 = passArray8ToWasm0(style_colors, wasm.__wbindgen_export);
714
674
  const len6 = WASM_VECTOR_LEN;
715
- const ret = wasm.ifcapi_processGeometryBatch(this.__wbg_ptr, ptr0, len0, ptr1, len1, unit_scale, rtc_x, rtc_y, rtc_z, needs_shift, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, ptr6, len6);
675
+ var ptr7 = isLikeNone(material_element_ids) ? 0 : passArray32ToWasm0(material_element_ids, wasm.__wbindgen_export);
676
+ var len7 = WASM_VECTOR_LEN;
677
+ var ptr8 = isLikeNone(material_color_counts) ? 0 : passArray32ToWasm0(material_color_counts, wasm.__wbindgen_export);
678
+ var len8 = WASM_VECTOR_LEN;
679
+ var ptr9 = isLikeNone(material_colors_rgba) ? 0 : passArray8ToWasm0(material_colors_rgba, wasm.__wbindgen_export);
680
+ var len9 = WASM_VECTOR_LEN;
681
+ const ret = wasm.ifcapi_processGeometryBatch(this.__wbg_ptr, ptr0, len0, ptr1, len1, unit_scale, rtc_x, rtc_y, rtc_z, needs_shift, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, ptr6, len6, !isLikeNone(plane_angle_to_radians), isLikeNone(plane_angle_to_radians) ? 0 : plane_angle_to_radians, ptr7, len7, ptr8, len8, ptr9, len9);
716
682
  return MeshCollection.__wrap(ret);
717
683
  }
718
684
  /**
@@ -721,9 +687,8 @@ export class IfcAPI {
721
687
  *
722
688
  * Single linear walk over the file:
723
689
  * 1. Builds the entity index incrementally from the same scan that
724
- * collects geometry jobs (the old `build_pre_pass_fast` did two
725
- * full-file scans — one for entities, one for the index — which
726
- * doubled wall-clock).
690
+ * collects geometry jobs (a separate index scan would double
691
+ * wall-clock).
727
692
  * 2. As soon as `IFCPROJECT` has been seen, the unit scale and the
728
693
  * first ~50 geometry jobs have been collected, resolves
729
694
  * `unitScale` + `rtcOffset` and emits a `meta` callback so the
@@ -743,14 +708,18 @@ export class IfcAPI {
743
708
  * @param {Uint8Array} data
744
709
  * @param {Function} on_event
745
710
  * @param {number} chunk_size
711
+ * @param {string[] | null | undefined} disabled_type_names
712
+ * @param {boolean} skip_type_geometry
746
713
  * @returns {any}
747
714
  */
748
- buildPrePassStreaming(data, on_event, chunk_size) {
715
+ buildPrePassStreaming(data, on_event, chunk_size, disabled_type_names, skip_type_geometry) {
749
716
  try {
750
717
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
751
718
  const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);
752
719
  const len0 = WASM_VECTOR_LEN;
753
- wasm.ifcapi_buildPrePassStreaming(retptr, this.__wbg_ptr, ptr0, len0, addBorrowedObject(on_event), chunk_size);
720
+ var ptr1 = isLikeNone(disabled_type_names) ? 0 : passArrayJsValueToWasm0(disabled_type_names, wasm.__wbindgen_export);
721
+ var len1 = WASM_VECTOR_LEN;
722
+ wasm.ifcapi_buildPrePassStreaming(retptr, this.__wbg_ptr, ptr0, len0, addBorrowedObject(on_event), chunk_size, ptr1, len1, skip_type_geometry);
754
723
  var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
755
724
  var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
756
725
  var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
@@ -996,27 +965,6 @@ export class IfcAPI {
996
965
  const ret = wasm.ifcapi_is_ready(this.__wbg_ptr);
997
966
  return ret !== 0;
998
967
  }
999
- /**
1000
- * Parse IFC file with streaming events
1001
- * Calls the callback function for each parse event
1002
- *
1003
- * Example:
1004
- * ```javascript
1005
- * const api = new IfcAPI();
1006
- * await api.parseStreaming(ifcData, (event) => {
1007
- * console.log('Event:', event);
1008
- * });
1009
- * ```
1010
- * @param {string} content
1011
- * @param {Function} callback
1012
- * @returns {Promise<any>}
1013
- */
1014
- parseStreaming(content, callback) {
1015
- const ptr0 = passStringToWasm0(content, wasm.__wbindgen_export, wasm.__wbindgen_export2);
1016
- const len0 = WASM_VECTOR_LEN;
1017
- const ret = wasm.ifcapi_parseStreaming(this.__wbg_ptr, ptr0, len0, addHeapObject(callback));
1018
- return takeObject(ret);
1019
- }
1020
968
  /**
1021
969
  * Fast entity scanning using SIMD-accelerated Rust scanner
1022
970
  * Returns array of entity references for data model parsing
@@ -1057,36 +1005,6 @@ export class IfcAPI {
1057
1005
  const ret = wasm.ifcapi_scanGeometryEntitiesFast(this.__wbg_ptr, ptr0, len0);
1058
1006
  return takeObject(ret);
1059
1007
  }
1060
- /**
1061
- * Fast scan that only returns metadata-relevant entity refs.
1062
- * This drastically reduces transfer size for huge-file metadata hydration.
1063
- * @param {Uint8Array} data
1064
- * @returns {any}
1065
- */
1066
- scanRelevantEntitiesFastBytes(data) {
1067
- const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);
1068
- const len0 = WASM_VECTOR_LEN;
1069
- const ret = wasm.ifcapi_scanRelevantEntitiesFastBytes(this.__wbg_ptr, ptr0, len0);
1070
- return takeObject(ret);
1071
- }
1072
- /**
1073
- * Parse IFC file (traditional - waits for completion)
1074
- *
1075
- * Example:
1076
- * ```javascript
1077
- * const api = new IfcAPI();
1078
- * const result = await api.parse(ifcData);
1079
- * console.log('Entities:', result.entityCount);
1080
- * ```
1081
- * @param {string} content
1082
- * @returns {Promise<any>}
1083
- */
1084
- parse(content) {
1085
- const ptr0 = passStringToWasm0(content, wasm.__wbindgen_export, wasm.__wbindgen_export2);
1086
- const len0 = WASM_VECTOR_LEN;
1087
- const ret = wasm.ifcapi_parse(this.__wbg_ptr, ptr0, len0);
1088
- return takeObject(ret);
1089
- }
1090
1008
  /**
1091
1009
  * Parse IFC file and extract symbolic representations (Plan,
1092
1010
  * Annotation, FootPrint, Axis). These are 2D curves used for
@@ -1168,27 +1086,6 @@ export class MeshCollection {
1168
1086
  const ret = wasm.meshcollection_hasRtcOffset(this.__wbg_ptr);
1169
1087
  return ret !== 0;
1170
1088
  }
1171
- /**
1172
- * Convert local coordinates to world coordinates
1173
- * Use this to convert mesh positions back to original IFC coordinates
1174
- * @param {number} x
1175
- * @param {number} y
1176
- * @param {number} z
1177
- * @returns {Float64Array}
1178
- */
1179
- localToWorld(x, y, z) {
1180
- try {
1181
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1182
- wasm.meshcollection_localToWorld(retptr, this.__wbg_ptr, x, y, z);
1183
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1184
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1185
- var v1 = getArrayF64FromWasm0(r0, r1).slice();
1186
- wasm.__wbindgen_export4(r0, r1 * 8, 8);
1187
- return v1;
1188
- } finally {
1189
- wasm.__wbindgen_add_to_stack_pointer(16);
1190
- }
1191
- }
1192
1089
  /**
1193
1090
  * Get total vertex count across all meshes
1194
1091
  * @returns {number}
@@ -1251,7 +1148,8 @@ export class MeshCollection {
1251
1148
  return takeObject(ret);
1252
1149
  }
1253
1150
  /**
1254
- * Get mesh at index
1151
+ * Get mesh at index (clones — non-destructive). Prefer `takeMesh` on the
1152
+ * hot streaming path; this stays for callers that read meshes more than once.
1255
1153
  * @param {number} index
1256
1154
  * @returns {MeshDataJs | undefined}
1257
1155
  */
@@ -1267,6 +1165,20 @@ export class MeshCollection {
1267
1165
  const ret = wasm.meshcollection_length(this.__wbg_ptr);
1268
1166
  return ret >>> 0;
1269
1167
  }
1168
+ /**
1169
+ * #1097 perf: MOVE the mesh at `index` out of the collection (the Vec
1170
+ * buffers are `std::mem::take`-n, leaving an empty stub). The streaming
1171
+ * worker reads each mesh exactly once, so moving avoids the full vertex-
1172
+ * data clone `get` pays — one fewer copy of positions/normals/indices/uvs/
1173
+ * texture per mesh (the JS getters still do the single Rust→JS copy). Calling
1174
+ * it twice for the same index yields the second call an empty mesh.
1175
+ * @param {number} index
1176
+ * @returns {MeshDataJs | undefined}
1177
+ */
1178
+ takeMesh(index) {
1179
+ const ret = wasm.meshcollection_takeMesh(this.__wbg_ptr, index);
1180
+ return ret === 0 ? undefined : MeshDataJs.__wrap(ret);
1181
+ }
1270
1182
  }
1271
1183
  if (Symbol.dispose) MeshCollection.prototype[Symbol.dispose] = MeshCollection.prototype.free;
1272
1184
 
@@ -1419,6 +1331,16 @@ export class MeshDataJs {
1419
1331
  wasm.__wbindgen_add_to_stack_pointer(16);
1420
1332
  }
1421
1333
  }
1334
+ /**
1335
+ * Per-element local-frame origin (Float64Array[3], WebGL Y-up, metres):
1336
+ * world position of vertex i = `origin + positions[3i..3i+3]`. Returns
1337
+ * [0,0,0] when positions are absolute (legacy / local frame off).
1338
+ * @returns {Float64Array}
1339
+ */
1340
+ get origin() {
1341
+ const ret = wasm.meshdatajs_origin(this.__wbg_ptr);
1342
+ return takeObject(ret);
1343
+ }
1422
1344
  /**
1423
1345
  * Get indices as Uint32Array (copy to JS)
1424
1346
  * @returns {Uint32Array}
@@ -1600,7 +1522,7 @@ export class ProfileEntryJs {
1600
1522
  * @returns {number}
1601
1523
  */
1602
1524
  get expressId() {
1603
- const ret = wasm.profileentryjs_expressId(this.__wbg_ptr);
1525
+ const ret = wasm.meshdatajs_textureWidth(this.__wbg_ptr);
1604
1526
  return ret >>> 0;
1605
1527
  }
1606
1528
  /**
@@ -2123,7 +2045,7 @@ export class SymbolicFillArea {
2123
2045
  * @returns {number}
2124
2046
  */
2125
2047
  get expressId() {
2126
- const ret = wasm.profileentryjs_expressId(this.__wbg_ptr);
2048
+ const ret = wasm.meshdatajs_textureWidth(this.__wbg_ptr);
2127
2049
  return ret >>> 0;
2128
2050
  }
2129
2051
  /**
@@ -2531,7 +2453,7 @@ export class SymbolicText {
2531
2453
  * @returns {number}
2532
2454
  */
2533
2455
  get expressId() {
2534
- const ret = wasm.profileentryjs_expressId(this.__wbg_ptr);
2456
+ const ret = wasm.meshdatajs_textureWidth(this.__wbg_ptr);
2535
2457
  return ret >>> 0;
2536
2458
  }
2537
2459
  /**
@@ -2817,32 +2739,25 @@ function __wbg_get_imports() {
2817
2739
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
2818
2740
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
2819
2741
  };
2820
- imports.wbg.__wbg___wbindgen_is_function_8d400b8b1af978cd = function(arg0) {
2821
- const ret = typeof(getObject(arg0)) === 'function';
2822
- return ret;
2823
- };
2824
- imports.wbg.__wbg___wbindgen_is_undefined_f6b95eab589e0269 = function(arg0) {
2825
- const ret = getObject(arg0) === undefined;
2826
- return ret;
2827
- };
2828
2742
  imports.wbg.__wbg___wbindgen_memory_a342e963fbcabd68 = function() {
2829
2743
  const ret = wasm.memory;
2830
2744
  return addHeapObject(ret);
2831
2745
  };
2746
+ imports.wbg.__wbg___wbindgen_string_get_a2a31e16edf96e42 = function(arg0, arg1) {
2747
+ const obj = getObject(arg1);
2748
+ const ret = typeof(obj) === 'string' ? obj : undefined;
2749
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2750
+ var len1 = WASM_VECTOR_LEN;
2751
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
2752
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
2753
+ };
2832
2754
  imports.wbg.__wbg___wbindgen_throw_dd24417ed36fc46e = function(arg0, arg1) {
2833
2755
  throw new Error(getStringFromWasm0(arg0, arg1));
2834
2756
  };
2835
- imports.wbg.__wbg__wbg_cb_unref_87dfb5aaa0cbcea7 = function(arg0) {
2836
- getObject(arg0)._wbg_cb_unref();
2837
- };
2838
2757
  imports.wbg.__wbg_call_3020136f7a2d6e44 = function() { return handleError(function (arg0, arg1, arg2) {
2839
2758
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
2840
2759
  return addHeapObject(ret);
2841
2760
  }, arguments) };
2842
- imports.wbg.__wbg_call_abb4ff46ce38be40 = function() { return handleError(function (arg0, arg1) {
2843
- const ret = getObject(arg0).call(getObject(arg1));
2844
- return addHeapObject(ret);
2845
- }, arguments) };
2846
2761
  imports.wbg.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
2847
2762
  let deferred0_0;
2848
2763
  let deferred0_1;
@@ -2869,24 +2784,6 @@ function __wbg_get_imports() {
2869
2784
  const ret = new Error();
2870
2785
  return addHeapObject(ret);
2871
2786
  };
2872
- imports.wbg.__wbg_new_ff12d2b041fb48f1 = function(arg0, arg1) {
2873
- try {
2874
- var state0 = {a: arg0, b: arg1};
2875
- var cb0 = (arg0, arg1) => {
2876
- const a = state0.a;
2877
- state0.a = 0;
2878
- try {
2879
- return __wasm_bindgen_func_elem_756(a, state0.b, arg0, arg1);
2880
- } finally {
2881
- state0.a = a;
2882
- }
2883
- };
2884
- const ret = new Promise(cb0);
2885
- return addHeapObject(ret);
2886
- } finally {
2887
- state0.a = state0.b = 0;
2888
- }
2889
- };
2890
2787
  imports.wbg.__wbg_new_from_slice_41e2764a343e3cb1 = function(arg0, arg1) {
2891
2788
  const ret = new Float32Array(getArrayF32FromWasm0(arg0, arg1));
2892
2789
  return addHeapObject(ret);
@@ -2895,6 +2792,10 @@ function __wbg_get_imports() {
2895
2792
  const ret = new BigUint64Array(getArrayU64FromWasm0(arg0, arg1));
2896
2793
  return addHeapObject(ret);
2897
2794
  };
2795
+ imports.wbg.__wbg_new_from_slice_9a48ef80d2a51f94 = function(arg0, arg1) {
2796
+ const ret = new Float64Array(getArrayF64FromWasm0(arg0, arg1));
2797
+ return addHeapObject(ret);
2798
+ };
2898
2799
  imports.wbg.__wbg_new_from_slice_db0691b69e9d3891 = function(arg0, arg1) {
2899
2800
  const ret = new Uint32Array(getArrayU32FromWasm0(arg0, arg1));
2900
2801
  return addHeapObject(ret);
@@ -2903,10 +2804,6 @@ function __wbg_get_imports() {
2903
2804
  const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));
2904
2805
  return addHeapObject(ret);
2905
2806
  };
2906
- imports.wbg.__wbg_new_no_args_cb138f77cf6151ee = function(arg0, arg1) {
2907
- const ret = new Function(getStringFromWasm0(arg0, arg1));
2908
- return addHeapObject(ret);
2909
- };
2910
2807
  imports.wbg.__wbg_new_with_length_202b3db94ba5fc86 = function(arg0) {
2911
2808
  const ret = new Uint32Array(arg0 >>> 0);
2912
2809
  return addHeapObject(ret);
@@ -2915,21 +2812,6 @@ function __wbg_get_imports() {
2915
2812
  const ret = new Float64Array(arg0 >>> 0);
2916
2813
  return addHeapObject(ret);
2917
2814
  };
2918
- imports.wbg.__wbg_new_with_length_aa5eaf41d35235e5 = function(arg0) {
2919
- const ret = new Uint8Array(arg0 >>> 0);
2920
- return addHeapObject(ret);
2921
- };
2922
- imports.wbg.__wbg_queueMicrotask_9b549dfce8865860 = function(arg0) {
2923
- const ret = getObject(arg0).queueMicrotask;
2924
- return addHeapObject(ret);
2925
- };
2926
- imports.wbg.__wbg_queueMicrotask_fca69f5bfad613a5 = function(arg0) {
2927
- queueMicrotask(getObject(arg0));
2928
- };
2929
- imports.wbg.__wbg_resolve_fd5bfbaa4ce36e1e = function(arg0) {
2930
- const ret = Promise.resolve(getObject(arg0));
2931
- return addHeapObject(ret);
2932
- };
2933
2815
  imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {
2934
2816
  getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
2935
2817
  };
@@ -2943,9 +2825,6 @@ function __wbg_get_imports() {
2943
2825
  imports.wbg.__wbg_set_index_021489b2916af13e = function(arg0, arg1, arg2) {
2944
2826
  getObject(arg0)[arg1 >>> 0] = arg2;
2945
2827
  };
2946
- imports.wbg.__wbg_set_index_04c4b93e64d08a52 = function(arg0, arg1, arg2) {
2947
- getObject(arg0)[arg1 >>> 0] = arg2;
2948
- };
2949
2828
  imports.wbg.__wbg_set_index_42abe35f117e614e = function(arg0, arg1, arg2) {
2950
2829
  getObject(arg0)[arg1 >>> 0] = arg2 >>> 0;
2951
2830
  };
@@ -2956,26 +2835,6 @@ function __wbg_get_imports() {
2956
2835
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
2957
2836
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
2958
2837
  };
2959
- imports.wbg.__wbg_static_accessor_GLOBAL_769e6b65d6557335 = function() {
2960
- const ret = typeof global === 'undefined' ? null : global;
2961
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
2962
- };
2963
- imports.wbg.__wbg_static_accessor_GLOBAL_THIS_60cf02db4de8e1c1 = function() {
2964
- const ret = typeof globalThis === 'undefined' ? null : globalThis;
2965
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
2966
- };
2967
- imports.wbg.__wbg_static_accessor_SELF_08f5a74c69739274 = function() {
2968
- const ret = typeof self === 'undefined' ? null : self;
2969
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
2970
- };
2971
- imports.wbg.__wbg_static_accessor_WINDOW_a8924b26aa92d024 = function() {
2972
- const ret = typeof window === 'undefined' ? null : window;
2973
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
2974
- };
2975
- imports.wbg.__wbg_then_4f95312d68691235 = function(arg0, arg1) {
2976
- const ret = getObject(arg0).then(getObject(arg1));
2977
- return addHeapObject(ret);
2978
- };
2979
2838
  imports.wbg.__wbg_warn_6e567d0d926ff881 = function(arg0) {
2980
2839
  console.warn(getObject(arg0));
2981
2840
  };
@@ -2994,11 +2853,6 @@ function __wbg_get_imports() {
2994
2853
  const ret = arg0;
2995
2854
  return addHeapObject(ret);
2996
2855
  };
2997
- imports.wbg.__wbindgen_cast_efaa74e24e38a7b5 = function(arg0, arg1) {
2998
- // Cast intrinsic for `Closure(Closure { dtor_idx: 65, function: Function { arguments: [Externref], shim_idx: 66, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
2999
- const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_721, __wasm_bindgen_func_elem_722);
3000
- return addHeapObject(ret);
3001
- };
3002
2856
  imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
3003
2857
  const ret = getObject(arg0);
3004
2858
  return addHeapObject(ret);
Binary file