@ifc-lite/wasm 10.3.0 → 10.4.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
@@ -208,6 +208,21 @@ residuals. Frames and asset identities are bound into the report; the call does
208
208
  not align a loaded model or approve scan accuracy. See the
209
209
  [registration contract](../../docs/api/wasm.md#scan-correspondence-registration).
210
210
 
211
+ `IfcAPI.segmentScanPoints` detects planes in an xyz `Float32Array` point cloud
212
+ (voxel means, PCA normals, region growing, a robust refit and coplanar
213
+ merging). It also detects cylinders, such as columns and pipes, among the
214
+ remaining voxels (seeded RANSAC, then a least-squares refit), and wide round
215
+ and polygonal columns among rings of vertical planes; a column's surface is
216
+ not also reported as planes. The JSON report is independent of point order. See the
217
+ [segmentation contract](../../docs/api/wasm.md#scan-plane-segmentation); the
218
+ typed wrapper is `@ifc-lite/geometry/scan-segmentation`.
219
+
220
+ `IfcAPI.proposeScanElements` turns that report into proposed walls, slabs,
221
+ columns and pipes in the IFC model frame, each with a confidence and its source
222
+ detections; it creates nothing. See the
223
+ [proposal contract](../../docs/api/wasm.md#scan-element-proposals); the typed
224
+ wrapper is `@ifc-lite/geometry/scan-proposals`.
225
+
211
226
  `IfcAPI.planMeshTransfer` composes registered opaque textured-mesh observations
212
227
  onto supported direct IFC tessellations using the shared atlas planner. Unknown
213
228
  samples retain existing target albedo; the IFPA response includes explicit
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.3.0",
8
+ "version": "10.4.0",
9
9
  "license": "MPL-2.0",
10
10
  "repository": {
11
11
  "type": "git",
package/pkg/ifc-lite.d.ts CHANGED
@@ -1,6 +1,55 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
 
4
+ /** Every field is optional; absent or `undefined` means the default. Unknown fields and non-finite numbers are refused. Lengths in metres; pass plane coordinates local to the slab (f32 input). */
5
+ export interface ScanOutlineOptionsJs {
6
+ /** Fixed cell edge; omit to pick it from the point density between minCellSize and maxCellSize. */
7
+ cellSize?: number;
8
+ /** Default 0.02, at least 0.001. */ minCellSize?: number;
9
+ /** Default 0.05. */ maxCellSize?: number;
10
+ /** Adaptive cells grow until the median occupied cell holds this many points. Default 6. */
11
+ targetPointsPerCell?: number;
12
+ /** Cell budget for the padded grid, from (2·pad + 1)² (81 with the defaults) up to 67108864. Default 16777216; hitting it sets diagnostics.cellCapHit. */
13
+ maxCells?: number;
14
+ /** Default 1. */ minPointsPerCell?: number;
15
+ /** A cell is occupied from this fraction of the median occupied-cell count. Default 0.25. */
16
+ noiseFraction?: number;
17
+ /** Widest gap the closing bridges, about a wall thickness; clamped to 0.5. Default 0.3. */
18
+ maxGap?: number;
19
+ /** Speckle opening radius in cells (0 disables). Default 1. */ openRadiusCells?: number;
20
+ /** Solid components below this area (m²) are dropped. Default 0.02. */ minComponentArea?: number;
21
+ /** Enclosed holes below this area (m²) are filled. Default 0.5. */ minHoleArea?: number;
22
+ /** Douglas-Peucker tolerance in cells. Default 1.5. */ simplifyToleranceCells?: number;
23
+ /** Refit edges to the points. Default true. */ snap?: boolean;
24
+ /** Evidence band beside an edge, in cells (at most 16). Default 3. */ snapDistanceCells?: number;
25
+ /** Fewest points to refit an edge. Default 8. */ minSnapPoints?: number;
26
+ /** Largest squaring move, in cells (at most 32). Default 4. */ maxVertexMoveCells?: number;
27
+ /** Square edges to the dominant direction. Default true. */ square?: boolean;
28
+ /** Default 3. */ squareAngleToleranceDeg?: number;
29
+ /** Squares edges whose ends move at most this far. Default 0.03. */ squareOffsetTolerance?: number;
30
+ }
31
+ /** world = origin + u * uAxis + v * vAxis */
32
+ export interface ScanOutlinePlaneFrameJs {
33
+ origin: [number, number, number];
34
+ uAxis: [number, number, number];
35
+ vAxis: [number, number, number];
36
+ }
37
+ export interface ScanOutlineDiagnosticsJs {
38
+ inputPoints: number; usedPoints: number; nonFinitePoints: number; outlierPoints: number;
39
+ cellSize: number; gridWidth: number; gridHeight: number;
40
+ cellCapHit: boolean; maxGapClamped: boolean; countThreshold: number;
41
+ /** f32 step at the largest input coordinate; `coordinatePrecisionDegraded` when above a tenth of a cell. Pass coordinates local to the slab. */
42
+ coordinateSpacingMetres: number; coordinatePrecisionDegraded: boolean;
43
+ occupiedCells: number; solidCells: number; componentsDropped: number; holesFilled: number;
44
+ ringCount: number; outerRingCount: number; holeRingCount: number; vertexCount: number;
45
+ simplifyReinsertions: number; snappedEdges: number;
46
+ /** Degrees in [0, 90); absent when no edge was long enough to tell. */
47
+ dominantAngleDeg?: number;
48
+ squaredEdges: number; revertedMoves: number;
49
+ }
50
+
51
+
52
+
4
53
  /** Exact browser mesh RTC frame, in IFC Z-up metres. */
5
54
  export interface RtcFrame {
6
55
  x: number;
@@ -1055,6 +1104,15 @@ export class IfcAPI {
1055
1104
  * Byte-for-byte identical output — it delegates to the legacy twin.
1056
1105
  */
1057
1106
  processGeometryBatchPartitionedFromSource(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): PartitionedBatch;
1107
+ /**
1108
+ * Propose IFC walls, slabs, columns and pipes from a scan segmentation
1109
+ * report (#6894). `report_json` is the JSON `segmentScanPoints`
1110
+ * returned; `options_json` is a camelCase `ScanProposalOptions` object
1111
+ * (`{}` for the defaults; `scanToModel` maps the report's frame into the
1112
+ * IFC model frame). Returns the UTF-8 JSON `ScanProposalReport` in the
1113
+ * model frame (Z up, metres). Pure: loads and changes nothing.
1114
+ */
1115
+ proposeScanElements(report_json: string, options_json: string): Uint8Array;
1058
1116
  /**
1059
1117
  * Fit bounded manual correspondences in source metres -> IFC world Z-up
1060
1118
  * metres, reporting held-out errors separately. Does not load or move models.
@@ -1082,12 +1140,20 @@ export class IfcAPI {
1082
1140
  * Fast entity scanning using SIMD-accelerated Rust scanner
1083
1141
  * Returns array of entity references for data model parsing
1084
1142
  * Much faster than TypeScript byte-by-byte scanning (5-10x speedup)
1143
+ *
1144
+ * The returned array also carries two own properties describing what the
1145
+ * scan refused (#7393): `oversizedIdCount` (records skipped because their
1146
+ * express id does not fit u32, #3395) and `malformedRecordCount` (0 or 1:
1147
+ * whether a record was dropped for having no terminating `;`, #3695).
1085
1148
  */
1086
1149
  scanEntitiesFast(content: string): any;
1087
1150
  /**
1088
1151
  * Fast entity scanning from raw bytes (avoids TextDecoder.decode on JS side).
1089
1152
  * Accepts Uint8Array directly — saves ~2-5s for 487MB files by skipping
1090
1153
  * JS string creation and UTF-16→UTF-8 conversion.
1154
+ *
1155
+ * Carries the same `oversizedIdCount` / `malformedRecordCount` array
1156
+ * properties as `scanEntitiesFast` (#7393).
1091
1157
  */
1092
1158
  scanEntitiesFastBytes(data: Uint8Array): any;
1093
1159
  /**
@@ -1140,6 +1206,13 @@ export class IfcAPI {
1140
1206
  * Much faster than scanning all entities (3x speedup for large files)
1141
1207
  */
1142
1208
  scanGeometryEntitiesFast(content: string): any;
1209
+ /**
1210
+ * Detect planes and cylinders (columns, pipes) in a point cloud (#6870). `positions` are xyz f32 metres
1211
+ * (at most 100,000,000 points); `options_json` is a camelCase
1212
+ * `ScanSegmentationOptions` object (`{}` for the defaults). Returns the
1213
+ * UTF-8 JSON `ScanSegmentationReport`. Pure: loads and changes nothing.
1214
+ */
1215
+ segmentScanPoints(positions: Float32Array, options_json: string): Uint8Array;
1143
1216
  /**
1144
1217
  * Enable or disable per-entity geometry fingerprinting in
1145
1218
  * `processGeometryBatch`, used by the viewer's revision-diff feature.
@@ -1810,6 +1883,50 @@ export class ProfileEntryJs {
1810
1883
  readonly transform: Float32Array;
1811
1884
  }
1812
1885
 
1886
+ /**
1887
+ * The traced outline. Owns wasm memory: call `free()`.
1888
+ */
1889
+ export class ScanOutlineJs {
1890
+ private constructor();
1891
+ free(): void;
1892
+ [Symbol.dispose](): void;
1893
+ /**
1894
+ * Every ring's plane coordinates concatenated, `[u0, v0, u1, v1, …]`.
1895
+ */
1896
+ coords(): Float64Array;
1897
+ /**
1898
+ * What the run did: cell size, cap hits, ring counts, repairs.
1899
+ */
1900
+ diagnostics(): ScanOutlineDiagnosticsJs;
1901
+ /**
1902
+ * Vertex count of each ring, in `coords()` order.
1903
+ */
1904
+ ringLengths(): Uint32Array;
1905
+ /**
1906
+ * The ring directly containing each ring (a hole's outer boundary, an
1907
+ * island's hole), or `-1` at top level.
1908
+ */
1909
+ ringParents(): Int32Array;
1910
+ /**
1911
+ * Ring index at which each shape starts; entry `s` is shape `s`'s outer
1912
+ * ring and the rings up to the next entry are its holes.
1913
+ */
1914
+ shapeOffsets(): Uint32Array;
1915
+ /**
1916
+ * Every ring mapped through the plane frame, `[x0, y0, z0, …]` in
1917
+ * `coords()` order, or `undefined` when no frame was given.
1918
+ */
1919
+ worldCoords(): Float64Array | undefined;
1920
+ /**
1921
+ * Total number of rings (outer boundaries and holes).
1922
+ */
1923
+ readonly ringCount: number;
1924
+ /**
1925
+ * Number of outer boundaries.
1926
+ */
1927
+ readonly shapeCount: number;
1928
+ }
1929
+
1813
1930
  /**
1814
1931
  * Flat result of `simplifyMeshes`: per surviving element `i`,
1815
1932
  * `vertexCounts[i]` vertices and `indexCounts[i]` indices taken in order
@@ -2348,6 +2465,14 @@ export function meshOutline2d(positions: Float32Array, indices: Uint32Array, axi
2348
2465
  */
2349
2466
  export function resolve2d(a: Contours2D): Contours2D;
2350
2467
 
2468
+ /**
2469
+ * Install (or, with `undefined`, remove) the callback invoked at most once a
2470
+ * second while geometry work is in progress inside a WASM call. It runs
2471
+ * synchronously inside that call, so it must only do something cheap such as
2472
+ * `postMessage`, and must not call back into this module.
2473
+ */
2474
+ export function setGeometryProgressCallback(callback?: Function | null): void;
2475
+
2351
2476
  /**
2352
2477
  * Split a mesh into one closed solid per zone, plus the remainder.
2353
2478
  *
@@ -2399,6 +2524,14 @@ export function resolve2d(a: Contours2D): Contours2D;
2399
2524
  */
2400
2525
  export function splitMeshByZones(positions: Float64Array, indices: Uint32Array, zones: Float64Array, footprints?: Float64Array | null, footprint_counts?: Uint32Array | null): ZoneSplitJs | undefined;
2401
2526
 
2527
+ /**
2528
+ * Trace closed outlines from slab points given in plane coordinates.
2529
+ *
2530
+ * THROWS on invalid options or plane frame (unknown field, non-finite or
2531
+ * out-of-range value). Points that are not finite are skipped and counted.
2532
+ */
2533
+ export function traceScanOutline(plane_xy: Float32Array, options?: ScanOutlineOptionsJs | null, plane_frame?: ScanOutlinePlaneFrameJs | null): ScanOutlineJs;
2534
+
2402
2535
  /**
2403
2536
  * `a ∪ b`.
2404
2537
  */
@@ -2438,6 +2571,7 @@ export interface InitOutput {
2438
2571
  readonly __wbg_partitionedbatch_free: (a: number, b: number) => void;
2439
2572
  readonly __wbg_profilecollection_free: (a: number, b: number) => void;
2440
2573
  readonly __wbg_profileentryjs_free: (a: number, b: number) => void;
2574
+ readonly __wbg_scanoutlinejs_free: (a: number, b: number) => void;
2441
2575
  readonly __wbg_simplifiedmeshes_free: (a: number, b: number) => void;
2442
2576
  readonly __wbg_spaceplatehandle_free: (a: number, b: number) => void;
2443
2577
  readonly __wbg_symboliccircle_free: (a: number, b: number) => void;
@@ -2554,6 +2688,7 @@ export interface InitOutput {
2554
2688
  readonly ifcapi_processGeometryBatchInstanced: (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, c1: number) => void;
2555
2689
  readonly ifcapi_processGeometryBatchPartitioned: (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;
2556
2690
  readonly ifcapi_processGeometryBatchPartitionedFromSource: (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) => number;
2691
+ readonly ifcapi_proposeScanElements: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2557
2692
  readonly ifcapi_registerScanCorrespondences: (a: number, b: number, c: number, d: number) => void;
2558
2693
  readonly ifcapi_resolveStyledItemsShard: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2559
2694
  readonly ifcapi_resolveStyledItemsShardFromSource: (a: number, b: number, c: number, d: number) => void;
@@ -2562,6 +2697,7 @@ export interface InitOutput {
2562
2697
  readonly ifcapi_scanEntityIndexShard: (a: number, b: number, c: number, d: number, e: number) => number;
2563
2698
  readonly ifcapi_scanEntityIndexShardFromSource: (a: number, b: number, c: number) => number;
2564
2699
  readonly ifcapi_scanGeometryEntitiesFast: (a: number, b: number, c: number) => number;
2700
+ readonly ifcapi_segmentScanPoints: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
2565
2701
  readonly ifcapi_setComputeGeometryHashes: (a: number, b: number, c: number) => void;
2566
2702
  readonly ifcapi_setEntityIndex: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
2567
2703
  readonly ifcapi_setInstantiatedTypeIds: (a: number, b: number, c: number) => void;
@@ -2650,6 +2786,15 @@ export interface InitOutput {
2650
2786
  readonly profileentryjs_outerPoints: (a: number) => number;
2651
2787
  readonly profileentryjs_transform: (a: number) => number;
2652
2788
  readonly resolve2d: (a: number) => number;
2789
+ readonly scanoutlinejs_coords: (a: number) => number;
2790
+ readonly scanoutlinejs_diagnostics: (a: number, b: number) => void;
2791
+ readonly scanoutlinejs_ringCount: (a: number) => number;
2792
+ readonly scanoutlinejs_ringLengths: (a: number) => number;
2793
+ readonly scanoutlinejs_ringParents: (a: number) => number;
2794
+ readonly scanoutlinejs_shapeCount: (a: number) => number;
2795
+ readonly scanoutlinejs_shapeOffsets: (a: number) => number;
2796
+ readonly scanoutlinejs_worldCoords: (a: number) => number;
2797
+ readonly setGeometryProgressCallback: (a: number) => void;
2653
2798
  readonly simplifiedmeshes_cavitiesDropped: (a: number, b: number) => void;
2654
2799
  readonly simplifiedmeshes_elementIds: (a: number, b: number) => void;
2655
2800
  readonly simplifiedmeshes_indexCounts: (a: number, b: number) => void;
@@ -2742,6 +2887,7 @@ export interface InitOutput {
2742
2887
  readonly symbolictext_repIdentifier: (a: number, b: number) => void;
2743
2888
  readonly symbolictext_x: (a: number) => number;
2744
2889
  readonly symbolictext_y: (a: number) => number;
2890
+ readonly traceScanOutline: (a: number, b: number, c: number, d: number, e: number) => void;
2745
2891
  readonly union2d: (a: number, b: number) => number;
2746
2892
  readonly version: (a: number) => void;
2747
2893
  readonly zonepiecejs_indices: (a: number) => number;
package/pkg/ifc-lite.js CHANGED
@@ -2779,6 +2779,39 @@ export class IfcAPI {
2779
2779
  const ret = wasm.ifcapi_processGeometryBatchPartitionedFromSource(this.__wbg_ptr, ptr0, len0, unit_scale, rtc_x, rtc_y, rtc_z, needs_shift, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, !isLikeNone(plane_angle_to_radians), isLikeNone(plane_angle_to_radians) ? 0 : plane_angle_to_radians, ptr6, len6, ptr7, len7, ptr8, len8);
2780
2780
  return PartitionedBatch.__wrap(ret);
2781
2781
  }
2782
+ /**
2783
+ * Propose IFC walls, slabs, columns and pipes from a scan segmentation
2784
+ * report (#6894). `report_json` is the JSON `segmentScanPoints`
2785
+ * returned; `options_json` is a camelCase `ScanProposalOptions` object
2786
+ * (`{}` for the defaults; `scanToModel` maps the report's frame into the
2787
+ * IFC model frame). Returns the UTF-8 JSON `ScanProposalReport` in the
2788
+ * model frame (Z up, metres). Pure: loads and changes nothing.
2789
+ * @param {string} report_json
2790
+ * @param {string} options_json
2791
+ * @returns {Uint8Array}
2792
+ */
2793
+ proposeScanElements(report_json, options_json) {
2794
+ try {
2795
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
2796
+ const ptr0 = passStringToWasm0(report_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2797
+ const len0 = WASM_VECTOR_LEN;
2798
+ const ptr1 = passStringToWasm0(options_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
2799
+ const len1 = WASM_VECTOR_LEN;
2800
+ wasm.ifcapi_proposeScanElements(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
2801
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
2802
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
2803
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
2804
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
2805
+ if (r3) {
2806
+ throw takeObject(r2);
2807
+ }
2808
+ var v3 = getArrayU8FromWasm0(r0, r1).slice();
2809
+ wasm.__wbindgen_export4(r0, r1 * 1, 1);
2810
+ return v3;
2811
+ } finally {
2812
+ wasm.__wbindgen_add_to_stack_pointer(16);
2813
+ }
2814
+ }
2782
2815
  /**
2783
2816
  * Fit bounded manual correspondences in source metres -> IFC world Z-up
2784
2817
  * metres, reporting held-out errors separately. Does not load or move models.
@@ -2866,6 +2899,11 @@ export class IfcAPI {
2866
2899
  * Fast entity scanning using SIMD-accelerated Rust scanner
2867
2900
  * Returns array of entity references for data model parsing
2868
2901
  * Much faster than TypeScript byte-by-byte scanning (5-10x speedup)
2902
+ *
2903
+ * The returned array also carries two own properties describing what the
2904
+ * scan refused (#7393): `oversizedIdCount` (records skipped because their
2905
+ * express id does not fit u32, #3395) and `malformedRecordCount` (0 or 1:
2906
+ * whether a record was dropped for having no terminating `;`, #3695).
2869
2907
  * @param {string} content
2870
2908
  * @returns {any}
2871
2909
  */
@@ -2879,6 +2917,9 @@ export class IfcAPI {
2879
2917
  * Fast entity scanning from raw bytes (avoids TextDecoder.decode on JS side).
2880
2918
  * Accepts Uint8Array directly — saves ~2-5s for 487MB files by skipping
2881
2919
  * JS string creation and UTF-16→UTF-8 conversion.
2920
+ *
2921
+ * Carries the same `oversizedIdCount` / `malformedRecordCount` array
2922
+ * properties as `scanEntitiesFast` (#7393).
2882
2923
  * @param {Uint8Array} data
2883
2924
  * @returns {any}
2884
2925
  */
@@ -2960,6 +3001,37 @@ export class IfcAPI {
2960
3001
  const ret = wasm.ifcapi_scanGeometryEntitiesFast(this.__wbg_ptr, ptr0, len0);
2961
3002
  return takeObject(ret);
2962
3003
  }
3004
+ /**
3005
+ * Detect planes and cylinders (columns, pipes) in a point cloud (#6870). `positions` are xyz f32 metres
3006
+ * (at most 100,000,000 points); `options_json` is a camelCase
3007
+ * `ScanSegmentationOptions` object (`{}` for the defaults). Returns the
3008
+ * UTF-8 JSON `ScanSegmentationReport`. Pure: loads and changes nothing.
3009
+ * @param {Float32Array} positions
3010
+ * @param {string} options_json
3011
+ * @returns {Uint8Array}
3012
+ */
3013
+ segmentScanPoints(positions, options_json) {
3014
+ try {
3015
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
3016
+ const ptr0 = passArrayF32ToWasm0(positions, wasm.__wbindgen_export);
3017
+ const len0 = WASM_VECTOR_LEN;
3018
+ const ptr1 = passStringToWasm0(options_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
3019
+ const len1 = WASM_VECTOR_LEN;
3020
+ wasm.ifcapi_segmentScanPoints(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
3021
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
3022
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
3023
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
3024
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
3025
+ if (r3) {
3026
+ throw takeObject(r2);
3027
+ }
3028
+ var v3 = getArrayU8FromWasm0(r0, r1).slice();
3029
+ wasm.__wbindgen_export4(r0, r1 * 1, 1);
3030
+ return v3;
3031
+ } finally {
3032
+ wasm.__wbindgen_add_to_stack_pointer(16);
3033
+ }
3034
+ }
2963
3035
  /**
2964
3036
  * Enable or disable per-entity geometry fingerprinting in
2965
3037
  * `processGeometryBatch`, used by the viewer's revision-diff feature.
@@ -4346,6 +4418,107 @@ export class ProfileEntryJs {
4346
4418
  }
4347
4419
  if (Symbol.dispose) ProfileEntryJs.prototype[Symbol.dispose] = ProfileEntryJs.prototype.free;
4348
4420
 
4421
+ /**
4422
+ * The traced outline. Owns wasm memory: call `free()`.
4423
+ */
4424
+ export class ScanOutlineJs {
4425
+ static __wrap(ptr) {
4426
+ const obj = Object.create(ScanOutlineJs.prototype);
4427
+ obj.__wbg_ptr = ptr;
4428
+ ScanOutlineJsFinalization.register(obj, obj.__wbg_ptr, obj);
4429
+ return obj;
4430
+ }
4431
+ __destroy_into_raw() {
4432
+ const ptr = this.__wbg_ptr;
4433
+ this.__wbg_ptr = 0;
4434
+ ScanOutlineJsFinalization.unregister(this);
4435
+ return ptr;
4436
+ }
4437
+ free() {
4438
+ const ptr = this.__destroy_into_raw();
4439
+ wasm.__wbg_scanoutlinejs_free(ptr, 0);
4440
+ }
4441
+ /**
4442
+ * Every ring's plane coordinates concatenated, `[u0, v0, u1, v1, …]`.
4443
+ * @returns {Float64Array}
4444
+ */
4445
+ coords() {
4446
+ const ret = wasm.scanoutlinejs_coords(this.__wbg_ptr);
4447
+ return takeObject(ret);
4448
+ }
4449
+ /**
4450
+ * What the run did: cell size, cap hits, ring counts, repairs.
4451
+ * @returns {ScanOutlineDiagnosticsJs}
4452
+ */
4453
+ diagnostics() {
4454
+ try {
4455
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
4456
+ wasm.scanoutlinejs_diagnostics(retptr, this.__wbg_ptr);
4457
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
4458
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
4459
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
4460
+ if (r2) {
4461
+ throw takeObject(r1);
4462
+ }
4463
+ return takeObject(r0);
4464
+ } finally {
4465
+ wasm.__wbindgen_add_to_stack_pointer(16);
4466
+ }
4467
+ }
4468
+ /**
4469
+ * Total number of rings (outer boundaries and holes).
4470
+ * @returns {number}
4471
+ */
4472
+ get ringCount() {
4473
+ const ret = wasm.scanoutlinejs_ringCount(this.__wbg_ptr);
4474
+ return ret >>> 0;
4475
+ }
4476
+ /**
4477
+ * Vertex count of each ring, in `coords()` order.
4478
+ * @returns {Uint32Array}
4479
+ */
4480
+ ringLengths() {
4481
+ const ret = wasm.scanoutlinejs_ringLengths(this.__wbg_ptr);
4482
+ return takeObject(ret);
4483
+ }
4484
+ /**
4485
+ * The ring directly containing each ring (a hole's outer boundary, an
4486
+ * island's hole), or `-1` at top level.
4487
+ * @returns {Int32Array}
4488
+ */
4489
+ ringParents() {
4490
+ const ret = wasm.scanoutlinejs_ringParents(this.__wbg_ptr);
4491
+ return takeObject(ret);
4492
+ }
4493
+ /**
4494
+ * Number of outer boundaries.
4495
+ * @returns {number}
4496
+ */
4497
+ get shapeCount() {
4498
+ const ret = wasm.scanoutlinejs_shapeCount(this.__wbg_ptr);
4499
+ return ret >>> 0;
4500
+ }
4501
+ /**
4502
+ * Ring index at which each shape starts; entry `s` is shape `s`'s outer
4503
+ * ring and the rings up to the next entry are its holes.
4504
+ * @returns {Uint32Array}
4505
+ */
4506
+ shapeOffsets() {
4507
+ const ret = wasm.scanoutlinejs_shapeOffsets(this.__wbg_ptr);
4508
+ return takeObject(ret);
4509
+ }
4510
+ /**
4511
+ * Every ring mapped through the plane frame, `[x0, y0, z0, …]` in
4512
+ * `coords()` order, or `undefined` when no frame was given.
4513
+ * @returns {Float64Array | undefined}
4514
+ */
4515
+ worldCoords() {
4516
+ const ret = wasm.scanoutlinejs_worldCoords(this.__wbg_ptr);
4517
+ return takeObject(ret);
4518
+ }
4519
+ }
4520
+ if (Symbol.dispose) ScanOutlineJs.prototype[Symbol.dispose] = ScanOutlineJs.prototype.free;
4521
+
4349
4522
  /**
4350
4523
  * Flat result of `simplifyMeshes`: per surviving element `i`,
4351
4524
  * `vertexCounts[i]` vertices and `indexCounts[i]` indices taken in order
@@ -6115,6 +6288,17 @@ export function resolve2d(a) {
6115
6288
  return Contours2D.__wrap(ret);
6116
6289
  }
6117
6290
 
6291
+ /**
6292
+ * Install (or, with `undefined`, remove) the callback invoked at most once a
6293
+ * second while geometry work is in progress inside a WASM call. It runs
6294
+ * synchronously inside that call, so it must only do something cheap such as
6295
+ * `postMessage`, and must not call back into this module.
6296
+ * @param {Function | null} [callback]
6297
+ */
6298
+ export function setGeometryProgressCallback(callback) {
6299
+ wasm.setGeometryProgressCallback(isLikeNone(callback) ? 0 : addHeapObject(callback));
6300
+ }
6301
+
6118
6302
  /**
6119
6303
  * Split a mesh into one closed solid per zone, plus the remainder.
6120
6304
  *
@@ -6185,6 +6369,34 @@ export function splitMeshByZones(positions, indices, zones, footprints, footprin
6185
6369
  return ret === 0 ? undefined : ZoneSplitJs.__wrap(ret);
6186
6370
  }
6187
6371
 
6372
+ /**
6373
+ * Trace closed outlines from slab points given in plane coordinates.
6374
+ *
6375
+ * THROWS on invalid options or plane frame (unknown field, non-finite or
6376
+ * out-of-range value). Points that are not finite are skipped and counted.
6377
+ * @param {Float32Array} plane_xy
6378
+ * @param {ScanOutlineOptionsJs | null} [options]
6379
+ * @param {ScanOutlinePlaneFrameJs | null} [plane_frame]
6380
+ * @returns {ScanOutlineJs}
6381
+ */
6382
+ export function traceScanOutline(plane_xy, options, plane_frame) {
6383
+ try {
6384
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
6385
+ const ptr0 = passArrayF32ToWasm0(plane_xy, wasm.__wbindgen_export);
6386
+ const len0 = WASM_VECTOR_LEN;
6387
+ wasm.traceScanOutline(retptr, ptr0, len0, isLikeNone(options) ? 0 : addHeapObject(options), isLikeNone(plane_frame) ? 0 : addHeapObject(plane_frame));
6388
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
6389
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
6390
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
6391
+ if (r2) {
6392
+ throw takeObject(r1);
6393
+ }
6394
+ return ScanOutlineJs.__wrap(r0);
6395
+ } finally {
6396
+ wasm.__wbindgen_add_to_stack_pointer(16);
6397
+ }
6398
+ }
6399
+
6188
6400
  /**
6189
6401
  * `a ∪ b`.
6190
6402
  * @param {Contours2D} a
@@ -6318,10 +6530,18 @@ function __wbg_get_imports() {
6318
6530
  __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
6319
6531
  throw new Error(getStringFromWasm0(arg0, arg1));
6320
6532
  },
6533
+ __wbg_call_8a2dd23819f8a60a: function() { return handleError(function (arg0, arg1) {
6534
+ const ret = getObject(arg0).call(getObject(arg1));
6535
+ return addHeapObject(ret);
6536
+ }, arguments); },
6321
6537
  __wbg_call_a6e5c5dce5018821: function() { return handleError(function (arg0, arg1, arg2) {
6322
6538
  const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
6323
6539
  return addHeapObject(ret);
6324
6540
  }, arguments); },
6541
+ __wbg_entries_015dc610cd81ede0: function(arg0) {
6542
+ const ret = Object.entries(getObject(arg0));
6543
+ return addHeapObject(ret);
6544
+ },
6325
6545
  __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {
6326
6546
  let deferred0_0;
6327
6547
  let deferred0_1;
@@ -6333,10 +6553,22 @@ function __wbg_get_imports() {
6333
6553
  wasm.__wbindgen_export4(deferred0_0, deferred0_1, 1);
6334
6554
  }
6335
6555
  },
6556
+ __wbg_from_13e323c65fc8f464: function(arg0) {
6557
+ const ret = Array.from(getObject(arg0));
6558
+ return addHeapObject(ret);
6559
+ },
6560
+ __wbg_get_507a50627bffa49b: function(arg0, arg1) {
6561
+ const ret = getObject(arg0)[arg1 >>> 0];
6562
+ return addHeapObject(ret);
6563
+ },
6336
6564
  __wbg_get_78f252d074a84d0b: function() { return handleError(function (arg0, arg1) {
6337
6565
  const ret = Reflect.get(getObject(arg0), getObject(arg1));
6338
6566
  return addHeapObject(ret);
6339
6567
  }, arguments); },
6568
+ __wbg_get_unchecked_6e0ad6d2a41b06f6: function(arg0, arg1) {
6569
+ const ret = getObject(arg0)[arg1 >>> 0];
6570
+ return addHeapObject(ret);
6571
+ },
6340
6572
  __wbg_get_with_ref_key_6412cf3094599694: function(arg0, arg1) {
6341
6573
  const ret = getObject(arg0)[getObject(arg1)];
6342
6574
  return addHeapObject(ret);
@@ -6376,6 +6608,10 @@ function __wbg_get_imports() {
6376
6608
  const ret = getObject(arg0).length;
6377
6609
  return ret;
6378
6610
  },
6611
+ __wbg_length_370319915dc99107: function(arg0) {
6612
+ const ret = getObject(arg0).length;
6613
+ return ret;
6614
+ },
6379
6615
  __wbg_new_227d7c05414eb861: function() {
6380
6616
  const ret = new Error();
6381
6617
  return addHeapObject(ret);
@@ -6416,6 +6652,10 @@ function __wbg_get_imports() {
6416
6652
  const ret = new Float64Array(getArrayF64FromWasm0(arg0, arg1));
6417
6653
  return addHeapObject(ret);
6418
6654
  },
6655
+ __wbg_new_from_slice_adc482e0820cc439: function(arg0, arg1) {
6656
+ const ret = new Int32Array(getArrayI32FromWasm0(arg0, arg1));
6657
+ return addHeapObject(ret);
6658
+ },
6419
6659
  __wbg_new_from_slice_ddf8b82c4d6af38e: function(arg0, arg1) {
6420
6660
  const ret = new Float32Array(getArrayF32FromWasm0(arg0, arg1));
6421
6661
  return addHeapObject(ret);
@@ -6491,6 +6731,9 @@ function __wbg_get_imports() {
6491
6731
  __wbg_warn_b1370d804fa3e259: function(arg0) {
6492
6732
  console.warn(getObject(arg0));
6493
6733
  },
6734
+ __wbg_warn_ef97a01ad7900eb3: function(arg0, arg1) {
6735
+ console.warn(getObject(arg0), getObject(arg1));
6736
+ },
6494
6737
  __wbindgen_cast_0000000000000001: function(arg0) {
6495
6738
  // Cast intrinsic for `F64 -> Externref`.
6496
6739
  const ret = arg0;
@@ -6565,6 +6808,9 @@ const ProfileCollectionFinalization = (typeof FinalizationRegistry === 'undefine
6565
6808
  const ProfileEntryJsFinalization = (typeof FinalizationRegistry === 'undefined')
6566
6809
  ? { register: () => {}, unregister: () => {} }
6567
6810
  : new FinalizationRegistry(ptr => wasm.__wbg_profileentryjs_free(ptr, 1));
6811
+ const ScanOutlineJsFinalization = (typeof FinalizationRegistry === 'undefined')
6812
+ ? { register: () => {}, unregister: () => {} }
6813
+ : new FinalizationRegistry(ptr => wasm.__wbg_scanoutlinejs_free(ptr, 1));
6568
6814
  const SimplifiedMeshesFinalization = (typeof FinalizationRegistry === 'undefined')
6569
6815
  ? { register: () => {}, unregister: () => {} }
6570
6816
  : new FinalizationRegistry(ptr => wasm.__wbg_simplifiedmeshes_free(ptr, 1));
@@ -6695,6 +6941,11 @@ function getArrayF64FromWasm0(ptr, len) {
6695
6941
  return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);
6696
6942
  }
6697
6943
 
6944
+ function getArrayI32FromWasm0(ptr, len) {
6945
+ ptr = ptr >>> 0;
6946
+ return getInt32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
6947
+ }
6948
+
6698
6949
  function getArrayJsValueFromWasm0(ptr, len) {
6699
6950
  ptr = ptr >>> 0;
6700
6951
  const mem = getDataViewMemory0();
@@ -6752,6 +7003,14 @@ function getFloat64ArrayMemory0() {
6752
7003
  return cachedFloat64ArrayMemory0;
6753
7004
  }
6754
7005
 
7006
+ let cachedInt32ArrayMemory0 = null;
7007
+ function getInt32ArrayMemory0() {
7008
+ if (cachedInt32ArrayMemory0 === null || cachedInt32ArrayMemory0.byteLength === 0) {
7009
+ cachedInt32ArrayMemory0 = new Int32Array(wasm.memory.buffer);
7010
+ }
7011
+ return cachedInt32ArrayMemory0;
7012
+ }
7013
+
6755
7014
  function getStringFromWasm0(ptr, len) {
6756
7015
  return decodeText(ptr >>> 0, len);
6757
7016
  }
@@ -6912,6 +7171,7 @@ function __wbg_finalize_init(instance, module) {
6912
7171
  cachedDataViewMemory0 = null;
6913
7172
  cachedFloat32ArrayMemory0 = null;
6914
7173
  cachedFloat64ArrayMemory0 = null;
7174
+ cachedInt32ArrayMemory0 = null;
6915
7175
  cachedUint32ArrayMemory0 = null;
6916
7176
  cachedUint8ArrayMemory0 = null;
6917
7177
  wasm.__wbindgen_start();
Binary file