okgeometry-api 1.26.1 → 1.27.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.
Files changed (99) hide show
  1. package/dist/Arc.js +1 -1
  2. package/dist/Arc.js.map +1 -1
  3. package/dist/Brep.js +1 -1
  4. package/dist/Brep.js.map +1 -1
  5. package/dist/Circle.js +1 -1
  6. package/dist/Circle.js.map +1 -1
  7. package/dist/Line.js +1 -1
  8. package/dist/Line.js.map +1 -1
  9. package/dist/Mesh.d.ts +41 -0
  10. package/dist/Mesh.d.ts.map +1 -1
  11. package/dist/Mesh.js +235 -21
  12. package/dist/Mesh.js.map +1 -1
  13. package/dist/MeshSurface.js +1 -1
  14. package/dist/MeshSurface.js.map +1 -1
  15. package/dist/NurbsCurve.js +1 -1
  16. package/dist/NurbsCurve.js.map +1 -1
  17. package/dist/NurbsSurface.js +1 -1
  18. package/dist/NurbsSurface.js.map +1 -1
  19. package/dist/PolyCurve.js +1 -1
  20. package/dist/PolyCurve.js.map +1 -1
  21. package/dist/Polyline.js +1 -1
  22. package/dist/Polyline.js.map +1 -1
  23. package/dist/Ray.js +1 -1
  24. package/dist/Ray.js.map +1 -1
  25. package/dist/SculptSession.js +1 -1
  26. package/dist/SculptSession.js.map +1 -1
  27. package/dist/engine-threaded.d.ts +2 -0
  28. package/dist/engine-threaded.d.ts.map +1 -0
  29. package/dist/engine-threaded.js +33 -0
  30. package/dist/engine-threaded.js.map +1 -0
  31. package/dist/engine.d.ts +21 -0
  32. package/dist/engine.d.ts.map +1 -1
  33. package/dist/engine.js +42 -0
  34. package/dist/engine.js.map +1 -1
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/index.js.map +1 -1
  39. package/dist/mesh-boolean.pool.d.ts +23 -1
  40. package/dist/mesh-boolean.pool.d.ts.map +1 -1
  41. package/dist/mesh-boolean.pool.js +97 -12
  42. package/dist/mesh-boolean.pool.js.map +1 -1
  43. package/dist/mesh-boolean.protocol.d.ts +21 -1
  44. package/dist/mesh-boolean.protocol.d.ts.map +1 -1
  45. package/dist/mesh-boolean.protocol.js.map +1 -1
  46. package/dist/mesh-boolean.worker.d.ts.map +1 -1
  47. package/dist/mesh-boolean.worker.js +94 -1
  48. package/dist/mesh-boolean.worker.js.map +1 -1
  49. package/dist/wasm-active.d.ts +20 -0
  50. package/dist/wasm-active.d.ts.map +1 -0
  51. package/dist/wasm-active.js +26 -0
  52. package/dist/wasm-active.js.map +1 -0
  53. package/dist/wasm-base64-threaded.d.ts +2 -0
  54. package/dist/wasm-base64-threaded.d.ts.map +1 -0
  55. package/dist/wasm-base64-threaded.js +3 -0
  56. package/dist/wasm-base64-threaded.js.map +1 -0
  57. package/dist/wasm-base64.d.ts +1 -1
  58. package/dist/wasm-base64.d.ts.map +1 -1
  59. package/dist/wasm-base64.js +1 -1
  60. package/dist/wasm-base64.js.map +1 -1
  61. package/dist/wasm-bindings-threaded.d.ts +2664 -0
  62. package/dist/wasm-bindings-threaded.d.ts.map +1 -0
  63. package/dist/wasm-bindings-threaded.js +5008 -0
  64. package/dist/wasm-bindings-threaded.js.map +1 -0
  65. package/dist/wasm-bindings.d.ts +130 -0
  66. package/dist/wasm-bindings.d.ts.map +1 -1
  67. package/dist/wasm-bindings.js +208 -0
  68. package/dist/wasm-bindings.js.map +1 -1
  69. package/dist/workerHelpers-threaded.d.ts +2 -0
  70. package/dist/workerHelpers-threaded.d.ts.map +1 -0
  71. package/dist/workerHelpers-threaded.js +100 -0
  72. package/dist/workerHelpers-threaded.js.map +1 -0
  73. package/package.json +8 -3
  74. package/src/Arc.ts +117 -117
  75. package/src/Brep.ts +1 -1
  76. package/src/Circle.ts +166 -166
  77. package/src/Line.ts +171 -171
  78. package/src/Mesh.ts +300 -45
  79. package/src/MeshSurface.ts +1 -1
  80. package/src/NurbsCurve.ts +655 -655
  81. package/src/NurbsSurface.ts +721 -721
  82. package/src/PolyCurve.ts +203 -203
  83. package/src/Polyline.ts +316 -316
  84. package/src/Ray.ts +90 -90
  85. package/src/SculptSession.ts +377 -377
  86. package/src/engine-threaded.ts +39 -0
  87. package/src/engine.ts +46 -0
  88. package/src/index.ts +1 -1
  89. package/src/mesh-boolean.pool.ts +208 -86
  90. package/src/mesh-boolean.protocol.ts +44 -1
  91. package/src/mesh-boolean.worker.ts +170 -56
  92. package/src/wasm-active.ts +31 -0
  93. package/src/wasm-base64-threaded.ts +2 -0
  94. package/src/wasm-base64.ts +1 -1
  95. package/src/wasm-bindings-threaded.d.ts +1989 -0
  96. package/src/wasm-bindings-threaded.js +5235 -0
  97. package/src/wasm-bindings.d.ts +104 -0
  98. package/src/wasm-bindings.js +225 -0
  99. package/src/workerHelpers-threaded.js +107 -0
package/src/Mesh.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ensureInit } from "./engine.js";
1
+ import { ensureInit, isInitialized } from "./engine.js";
2
2
  import { Point } from "./Point.js";
3
3
  import { Vec3 } from "./Vec3.js";
4
4
  import { Plane } from "./Plane.js";
@@ -17,6 +17,7 @@ import {
17
17
  configureDefaultMeshBooleanWorkerPool,
18
18
  disposeMeshBooleanWorkerPools,
19
19
  runMeshBooleanInWorkerPool,
20
+ runMeshHeavyInWorkerPool,
20
21
  } from "./mesh-boolean.pool.js";
21
22
  import { MeshBooleanExecutionError } from "./mesh-boolean.protocol.js";
22
23
  import type {
@@ -24,8 +25,7 @@ import type {
24
25
  MeshBooleanLimits,
25
26
  MeshBooleanOptions,
26
27
  } from "./mesh-boolean.protocol.js";
27
- import * as wasm from "./wasm-bindings.js";
28
- import { mesh_topology_metrics, mesh_topology_metrics_raw } from "./wasm-bindings.js";
28
+ import { wasm } from "./wasm-active.js";
29
29
 
30
30
  export { MeshBooleanExecutionError };
31
31
  export type {
@@ -362,6 +362,83 @@ export class Mesh {
362
362
  this._trustedBooleanInput = trustedBooleanInput;
363
363
  }
364
364
 
365
+ // ---- WASM-side residency (KERNEL-PERF-ARC lever 2) -----------------------
366
+ //
367
+ // Repeated queries on the same mesh (hover face groups, raycasts, render
368
+ // buffers, diagnostics) skip the per-call JS→WASM buffer copy by storing
369
+ // the buffer WASM-side once; raycasts additionally reuse a cached BVH.
370
+ // Residency is self-tuning: the FIRST hot call uses the classic buffer
371
+ // path (one-shot meshes never pay the store), the second call onward
372
+ // stores. `dispose()` releases eagerly; a FinalizationRegistry frees
373
+ // leaked ids on GC as a safety net. Buffers are immutable, so stored
374
+ // copies never need invalidation.
375
+
376
+ private _storeId: number | null = null;
377
+ private _hotCallCount = 0;
378
+
379
+ private static residencyFinalizer: FinalizationRegistry<number> | null =
380
+ typeof FinalizationRegistry !== "undefined"
381
+ ? new FinalizationRegistry<number>((id) => {
382
+ try {
383
+ if (isInitialized()) wasm.mesh_store_free(id);
384
+ } catch {
385
+ // engine torn down — nothing to free
386
+ }
387
+ })
388
+ : null;
389
+
390
+ /**
391
+ * WASM-side stored-mesh id, or 0 when this call should use the buffer
392
+ * path (first hot call, store failure, or disposed-and-cold mesh).
393
+ */
394
+ private storedId(): number {
395
+ if (this._storeId !== null) return this._storeId;
396
+ if (this._hotCallCount < 1) {
397
+ this._hotCallCount++;
398
+ return 0;
399
+ }
400
+ let id = 0;
401
+ try {
402
+ id = wasm.mesh_store(this._vertexCount, this._buffer);
403
+ } catch {
404
+ id = 0;
405
+ }
406
+ this._storeId = id;
407
+ if (id > 0) Mesh.residencyFinalizer?.register(this, id, this);
408
+ return id;
409
+ }
410
+
411
+ /**
412
+ * Release this mesh's WASM-side stored copy (idempotent). The mesh stays
413
+ * fully usable — the next repeated hot call re-stores it. Call from
414
+ * long-lived hosts (okdraw engine-bridge release paths) to return WASM
415
+ * memory promptly instead of waiting for GC.
416
+ */
417
+ dispose(): void {
418
+ if (this._storeId !== null && this._storeId > 0) {
419
+ try {
420
+ wasm.mesh_store_free(this._storeId);
421
+ } catch {
422
+ // engine torn down — nothing to free
423
+ }
424
+ Mesh.residencyFinalizer?.unregister(this);
425
+ }
426
+ this._storeId = null;
427
+ this._hotCallCount = 0;
428
+ }
429
+
430
+ /** Number of meshes currently resident WASM-side (diagnostics/tests). */
431
+ static residentMeshCount(): number {
432
+ ensureInit();
433
+ return wasm.mesh_store_count();
434
+ }
435
+
436
+ /** Approximate bytes of WASM-side resident mesh buffers (diagnostics). */
437
+ static residentMeshBytes(): number {
438
+ ensureInit();
439
+ return wasm.mesh_store_bytes();
440
+ }
441
+
365
442
  /**
366
443
  * Configure default size for the shared boolean worker pool.
367
444
  */
@@ -2198,7 +2275,10 @@ export class Mesh {
2198
2275
  if (this._edgeVertexPairs) return this._edgeVertexPairs;
2199
2276
 
2200
2277
  ensureInit();
2201
- const packed = wasm.mesh_get_edge_vertex_pairs(this._vertexCount, this._buffer);
2278
+ const sidEdges = this.storedId();
2279
+ const packed = sidEdges > 0
2280
+ ? wasm.mesh_get_edge_vertex_pairs_h(sidEdges)
2281
+ : wasm.mesh_get_edge_vertex_pairs(this._vertexCount, this._buffer);
2202
2282
  const edgeCount = Math.max(0, Math.floor(packed[0] ?? 0));
2203
2283
  const pairs: Array<[number, number]> = [];
2204
2284
  let off = 1;
@@ -3111,6 +3191,141 @@ export class Mesh {
3111
3191
  }
3112
3192
  }
3113
3193
 
3194
+ // ── Heavy async ops on the worker pool (KERNEL-PERF-ARC lever 4) ──
3195
+ //
3196
+ // Multi-second operations run off the main thread with the same
3197
+ // fallback contract as the pairwise async booleans: any worker-side
3198
+ // failure falls back to the synchronous main-thread path.
3199
+
3200
+ /** Async `Mesh.unionAll` on the worker pool. */
3201
+ static async unionAllAsync(
3202
+ meshes: Mesh[],
3203
+ options?: MeshBooleanAsyncOptions,
3204
+ ): Promise<Mesh> {
3205
+ try {
3206
+ const { buffer } = await runMeshHeavyInWorkerPool(
3207
+ "unionAll",
3208
+ meshes.map((m) => m._buffer),
3209
+ { ...options, trusted: meshes.map((m) => m._trustedBooleanInput) },
3210
+ );
3211
+ return Mesh.fromTrustedBuffer(buffer);
3212
+ } catch (error) {
3213
+ if (!shouldFallbackFromWorkerFailure(error)) throw error;
3214
+ console.warn("Mesh.unionAllAsync worker failed; falling back to main thread.", error);
3215
+ return Mesh.unionAll(meshes, {
3216
+ allowUnsafe: options?.allowUnsafe ?? true,
3217
+ limits: options?.limits,
3218
+ });
3219
+ }
3220
+ }
3221
+
3222
+ /** Async `mesh.subtractAll` on the worker pool. */
3223
+ async subtractAllAsync(
3224
+ cutters: Mesh[],
3225
+ options?: MeshBooleanAsyncOptions,
3226
+ ): Promise<Mesh> {
3227
+ try {
3228
+ const { buffer } = await runMeshHeavyInWorkerPool(
3229
+ "differenceAll",
3230
+ [this._buffer, ...cutters.map((m) => m._buffer)],
3231
+ {
3232
+ ...options,
3233
+ trusted: [this._trustedBooleanInput, ...cutters.map((m) => m._trustedBooleanInput)],
3234
+ },
3235
+ );
3236
+ return Mesh.fromTrustedBuffer(buffer);
3237
+ } catch (error) {
3238
+ if (!shouldFallbackFromWorkerFailure(error)) throw error;
3239
+ console.warn("Mesh.subtractAllAsync worker failed; falling back to main thread.", error);
3240
+ return this.subtractAll(cutters, {
3241
+ allowUnsafe: options?.allowUnsafe ?? true,
3242
+ limits: options?.limits,
3243
+ });
3244
+ }
3245
+ }
3246
+
3247
+ /** Async `mesh.makeWatertight` on the worker pool. NOTE: the async
3248
+ * variant reports the result mesh, method and effective resolution;
3249
+ * before/after diagnostics can be recomputed by the caller if needed. */
3250
+ async makeWatertightAsync(
3251
+ options: { resolution?: number; iso?: number } & MeshBooleanAsyncOptions = {},
3252
+ ): Promise<{ mesh: Mesh; method: "repair" | "remesh"; effectiveResolution: number }> {
3253
+ try {
3254
+ const { buffer, meta } = await runMeshHeavyInWorkerPool(
3255
+ "makeWatertight",
3256
+ [this._buffer],
3257
+ {
3258
+ ...options,
3259
+ trusted: [this._trustedBooleanInput],
3260
+ params: { resolution: options.resolution, iso: options.iso },
3261
+ },
3262
+ );
3263
+ return {
3264
+ mesh: Mesh.fromTrustedBuffer(buffer),
3265
+ method: (meta?.method as "repair" | "remesh") ?? "repair",
3266
+ effectiveResolution: Number(meta?.effectiveResolution ?? 0),
3267
+ };
3268
+ } catch (error) {
3269
+ if (!shouldFallbackFromWorkerFailure(error)) throw error;
3270
+ console.warn("Mesh.makeWatertightAsync worker failed; falling back to main thread.", error);
3271
+ const r = this.makeWatertight({ resolution: options.resolution, iso: options.iso });
3272
+ return { mesh: r.mesh, method: r.method, effectiveResolution: r.effectiveResolution };
3273
+ }
3274
+ }
3275
+
3276
+ /** Async `mesh.voxelRemesh` on the worker pool. */
3277
+ async voxelRemeshAsync(
3278
+ resolution = 0,
3279
+ iso = 0.5,
3280
+ options?: MeshBooleanAsyncOptions,
3281
+ ): Promise<Mesh> {
3282
+ try {
3283
+ const { buffer } = await runMeshHeavyInWorkerPool("voxelRemesh", [this._buffer], {
3284
+ ...options,
3285
+ trusted: [this._trustedBooleanInput],
3286
+ params: { resolution, iso },
3287
+ });
3288
+ return Mesh.fromTrustedBuffer(buffer);
3289
+ } catch (error) {
3290
+ if (!shouldFallbackFromWorkerFailure(error)) throw error;
3291
+ console.warn("Mesh.voxelRemeshAsync worker failed; falling back to main thread.", error);
3292
+ return this.voxelRemesh(resolution, iso);
3293
+ }
3294
+ }
3295
+
3296
+ /** Async `mesh.chamferEdges` on the worker pool. */
3297
+ async chamferEdgesAsync(
3298
+ edges: Array<{ a: Point | Vec3; b: Point | Vec3 }>,
3299
+ distance: number,
3300
+ options?: MeshBooleanAsyncOptions,
3301
+ ): Promise<Mesh> {
3302
+ const flat = new Float64Array(edges.length * 6);
3303
+ edges.forEach((edge, i) => {
3304
+ flat[i * 6] = edge.a.x;
3305
+ flat[i * 6 + 1] = edge.a.y;
3306
+ flat[i * 6 + 2] = edge.a.z;
3307
+ flat[i * 6 + 3] = edge.b.x;
3308
+ flat[i * 6 + 4] = edge.b.y;
3309
+ flat[i * 6 + 5] = edge.b.z;
3310
+ });
3311
+ try {
3312
+ const { buffer } = await runMeshHeavyInWorkerPool(
3313
+ "chamferEdges",
3314
+ [this._buffer, flat],
3315
+ {
3316
+ ...options,
3317
+ trusted: [this._trustedBooleanInput],
3318
+ params: { distance },
3319
+ },
3320
+ );
3321
+ return Mesh.fromTrustedBuffer(buffer);
3322
+ } catch (error) {
3323
+ if (!shouldFallbackFromWorkerFailure(error)) throw error;
3324
+ console.warn("Mesh.chamferEdgesAsync worker failed; falling back to main thread.", error);
3325
+ return this.chamferEdges(edges, distance);
3326
+ }
3327
+ }
3328
+
3114
3329
  // ── Intersection queries ───────────────────────────────────────
3115
3330
 
3116
3331
  /**
@@ -3459,7 +3674,10 @@ export class Mesh {
3459
3674
  getCoplanarFaceIndices(faceIndex: number): number[] {
3460
3675
  ensureInit();
3461
3676
  if (!Number.isFinite(faceIndex) || faceIndex < 0) return [];
3462
- const r = wasm.mesh_get_coplanar_face_indices(this._vertexCount, this._buffer, Math.floor(faceIndex));
3677
+ const sidCfi = this.storedId();
3678
+ const r = sidCfi > 0
3679
+ ? wasm.mesh_get_coplanar_face_indices_h(sidCfi, Math.floor(faceIndex))
3680
+ : wasm.mesh_get_coplanar_face_indices(this._vertexCount, this._buffer, Math.floor(faceIndex));
3463
3681
  const count = Math.max(0, Math.floor(r[0] ?? 0));
3464
3682
  const out: number[] = [];
3465
3683
  for (let i = 0; i < count; i++) {
@@ -3483,12 +3701,15 @@ export class Mesh {
3483
3701
  if (!Number.isFinite(faceIndex) || faceIndex < 0) {
3484
3702
  return { faceIndices: [], isPlanar: true };
3485
3703
  }
3486
- const r = wasm.mesh_get_smooth_face_group(
3487
- this._vertexCount,
3488
- this._buffer,
3489
- Math.floor(faceIndex),
3490
- maxAngleDeg,
3491
- );
3704
+ const sidSfg = this.storedId();
3705
+ const r = sidSfg > 0
3706
+ ? wasm.mesh_get_smooth_face_group_h(sidSfg, Math.floor(faceIndex), maxAngleDeg)
3707
+ : wasm.mesh_get_smooth_face_group(
3708
+ this._vertexCount,
3709
+ this._buffer,
3710
+ Math.floor(faceIndex),
3711
+ maxAngleDeg,
3712
+ );
3492
3713
  const count = Math.max(0, Math.floor(r[0] ?? 0));
3493
3714
  const isPlanar = (r[1] ?? 1) !== 0;
3494
3715
  const faceIndices: number[] = [];
@@ -3515,11 +3736,14 @@ export class Mesh {
3515
3736
  featureEdges: Float32Array;
3516
3737
  } {
3517
3738
  ensureInit();
3518
- const r: Float32Array = wasm.mesh_build_render_buffers(
3519
- this._vertexCount,
3520
- this._buffer,
3521
- creaseAngleDeg,
3522
- );
3739
+ const sidRb = this.storedId();
3740
+ const r: Float32Array = sidRb > 0
3741
+ ? wasm.mesh_build_render_buffers_h(sidRb, creaseAngleDeg)
3742
+ : wasm.mesh_build_render_buffers(
3743
+ this._vertexCount,
3744
+ this._buffer,
3745
+ creaseAngleDeg,
3746
+ );
3523
3747
  const vertexCount = Math.max(0, Math.floor(r[0] ?? 0));
3524
3748
  const posStart = 1;
3525
3749
  const norStart = posStart + vertexCount * 3;
@@ -3582,11 +3806,14 @@ export class Mesh {
3582
3806
  getCoplanarFaceGroupCentroid(faceIndex: number): Point | null {
3583
3807
  ensureInit();
3584
3808
  if (!Number.isFinite(faceIndex) || faceIndex < 0) return null;
3585
- const r = wasm.mesh_get_coplanar_face_group_centroid(
3586
- this._vertexCount,
3587
- this._buffer,
3588
- Math.floor(faceIndex),
3589
- );
3809
+ const sidCent = this.storedId();
3810
+ const r = sidCent > 0
3811
+ ? wasm.mesh_get_coplanar_face_group_centroid_h(sidCent, Math.floor(faceIndex))
3812
+ : wasm.mesh_get_coplanar_face_group_centroid(
3813
+ this._vertexCount,
3814
+ this._buffer,
3815
+ Math.floor(faceIndex),
3816
+ );
3590
3817
  if (!r || r.length < 3) return null;
3591
3818
  return new Point(r[0], r[1], r[2]);
3592
3819
  }
@@ -3600,11 +3827,14 @@ export class Mesh {
3600
3827
  getFaceBoundaryLoops(faceIndex: number): Point[][] {
3601
3828
  ensureInit();
3602
3829
  if (!Number.isFinite(faceIndex) || faceIndex < 0) return [];
3603
- const r = wasm.mesh_get_face_boundary_loops(
3604
- this._vertexCount,
3605
- this._buffer,
3606
- Math.floor(faceIndex),
3607
- );
3830
+ const sidLoops = this.storedId();
3831
+ const r = sidLoops > 0
3832
+ ? wasm.mesh_get_face_boundary_loops_h(sidLoops, Math.floor(faceIndex))
3833
+ : wasm.mesh_get_face_boundary_loops(
3834
+ this._vertexCount,
3835
+ this._buffer,
3836
+ Math.floor(faceIndex),
3837
+ );
3608
3838
  if (!r || r.length < 1) return [];
3609
3839
  const loopCount = Math.floor(r[0]);
3610
3840
  const loops: Point[][] = [];
@@ -3658,13 +3888,21 @@ export class Mesh {
3658
3888
  maxDistance = Number.POSITIVE_INFINITY,
3659
3889
  ): { point: Point; normal: Vec3; faceIndex: number; distance: number } | null {
3660
3890
  ensureInit();
3661
- const r = wasm.mesh_raycast(
3662
- this._vertexCount,
3663
- this._buffer,
3664
- origin.x, origin.y, origin.z,
3665
- direction.x, direction.y, direction.z,
3666
- maxDistance,
3667
- );
3891
+ const sidRay = this.storedId();
3892
+ const r = sidRay > 0
3893
+ ? wasm.mesh_raycast_h(
3894
+ sidRay,
3895
+ origin.x, origin.y, origin.z,
3896
+ direction.x, direction.y, direction.z,
3897
+ maxDistance,
3898
+ )
3899
+ : wasm.mesh_raycast(
3900
+ this._vertexCount,
3901
+ this._buffer,
3902
+ origin.x, origin.y, origin.z,
3903
+ direction.x, direction.y, direction.z,
3904
+ maxDistance,
3905
+ );
3668
3906
  if (!r || r.length < 8) return null;
3669
3907
  return {
3670
3908
  point: new Point(r[0], r[1], r[2]),
@@ -3683,13 +3921,21 @@ export class Mesh {
3683
3921
  maxDistance = Number.POSITIVE_INFINITY,
3684
3922
  ): Array<{ point: Point; normal: Vec3; faceIndex: number; distance: number }> {
3685
3923
  ensureInit();
3686
- const buf = wasm.mesh_raycast_all(
3687
- this._vertexCount,
3688
- this._buffer,
3689
- origin.x, origin.y, origin.z,
3690
- direction.x, direction.y, direction.z,
3691
- maxDistance,
3692
- );
3924
+ const sidRayAll = this.storedId();
3925
+ const buf = sidRayAll > 0
3926
+ ? wasm.mesh_raycast_all_h(
3927
+ sidRayAll,
3928
+ origin.x, origin.y, origin.z,
3929
+ direction.x, direction.y, direction.z,
3930
+ maxDistance,
3931
+ )
3932
+ : wasm.mesh_raycast_all(
3933
+ this._vertexCount,
3934
+ this._buffer,
3935
+ origin.x, origin.y, origin.z,
3936
+ direction.x, direction.y, direction.z,
3937
+ maxDistance,
3938
+ );
3693
3939
  const count = Math.max(0, Math.floor(buf[0] ?? 0));
3694
3940
  const hits: Array<{ point: Point; normal: Vec3; faceIndex: number; distance: number }> = [];
3695
3941
  let off = 1;
@@ -3774,8 +4020,8 @@ export class Mesh {
3774
4020
 
3775
4021
  ensureInit();
3776
4022
  const metrics = this._trustedBooleanInput
3777
- ? mesh_topology_metrics_raw(this._vertexCount, this._buffer)
3778
- : mesh_topology_metrics(this._vertexCount, this._buffer);
4023
+ ? wasm.mesh_topology_metrics_raw(this._vertexCount, this._buffer)
4024
+ : wasm.mesh_topology_metrics(this._vertexCount, this._buffer);
3779
4025
  const boundaryEdges = Math.floor(metrics[0] ?? 0);
3780
4026
  const nonManifoldEdges = Math.floor(metrics[1] ?? 0);
3781
4027
  this._topologyMetricsCache = { boundaryEdges, nonManifoldEdges };
@@ -3795,7 +4041,10 @@ export class Mesh {
3795
4041
  */
3796
4042
  diagnostics(): MeshDiagnostics {
3797
4043
  ensureInit();
3798
- const r = wasm.mesh_repair_diagnostics(this._vertexCount, this._buffer);
4044
+ const sidDiag = this.storedId();
4045
+ const r = sidDiag > 0
4046
+ ? wasm.mesh_repair_diagnostics_h(sidDiag)
4047
+ : wasm.mesh_repair_diagnostics(this._vertexCount, this._buffer);
3799
4048
  return parseMeshDiagnostics(r, 0);
3800
4049
  }
3801
4050
 
@@ -3806,7 +4055,10 @@ export class Mesh {
3806
4055
  */
3807
4056
  boundaryEdgeSegments(): Float64Array {
3808
4057
  ensureInit();
3809
- return wasm.mesh_boundary_edge_segments(this._vertexCount, this._buffer);
4058
+ const sidBes = this.storedId();
4059
+ return sidBes > 0
4060
+ ? wasm.mesh_boundary_edge_segments_h(sidBes)
4061
+ : wasm.mesh_boundary_edge_segments(this._vertexCount, this._buffer);
3810
4062
  }
3811
4063
 
3812
4064
  /**
@@ -3857,7 +4109,10 @@ export class Mesh {
3857
4109
  */
3858
4110
  featureEdgeChains(): Array<{ closed: boolean; points: Float64Array }> {
3859
4111
  ensureInit();
3860
- const r = wasm.mesh_feature_edge_chains(this._vertexCount, this._buffer);
4112
+ const sidFec = this.storedId();
4113
+ const r = sidFec > 0
4114
+ ? wasm.mesh_feature_edge_chains_h(sidFec)
4115
+ : wasm.mesh_feature_edge_chains(this._vertexCount, this._buffer);
3861
4116
  if (!r.length) {
3862
4117
  throw new Error(
3863
4118
  `Mesh.featureEdgeChains() failed: ${wasm.geometry_last_error() || "unknown error"}`,
@@ -4,7 +4,7 @@ import type { Mesh, MeshPlanarFace } from "./Mesh.js";
4
4
  import { Point } from "./Point.js";
5
5
  import type { Surface } from "./Surface.js";
6
6
  import { Vec3 } from "./Vec3.js";
7
- import * as wasm from "./wasm-bindings.js";
7
+ import { wasm } from "./wasm-active.js";
8
8
 
9
9
  /**
10
10
  * Logical planar surface extracted from a coplanar connected face group on a mesh.