okgeometry-api 1.37.0 → 1.38.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.
@@ -1 +1 @@
1
- {"version":3,"file":"wasm-base64.js","sourceRoot":"","sources":["../src/wasm-base64.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,sow2GAAsow2G,CAAC"}
1
+ {"version":3,"file":"wasm-base64.js","sourceRoot":"","sources":["../src/wasm-base64.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,8hq3GAA8hq3G,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okgeometry-api",
3
- "version": "1.37.0",
3
+ "version": "1.38.0",
4
4
  "description": "Geometry engine API for AEC applications - NURBS, meshes, booleans, intersections. Powered by Rust/WASM.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/Mesh.ts CHANGED
@@ -3260,6 +3260,63 @@ export class Mesh {
3260
3260
  * If the surface does not fully cut through the solid, the produced side(s)
3261
3261
  * will not be closed — verify with `isClosedVolume()` on the side you keep.
3262
3262
  */
3263
+ /**
3264
+ * Async `splitSolidBySurface` on the worker pool — off the UI thread, with
3265
+ * the sync safety limits lifted (worker jobs default `allowUnsafe`). Used for
3266
+ * the capped solid − surface split on high-poly imported scans, which would
3267
+ * otherwise freeze the main thread for tens of seconds. Falls back to the
3268
+ * synchronous path only on a worker INFRASTRUCTURE failure.
3269
+ */
3270
+ async splitSolidBySurfaceAsync(
3271
+ surface: Mesh,
3272
+ options?: MeshBooleanAsyncOptions,
3273
+ ): Promise<MeshSplitResult> {
3274
+ try {
3275
+ const { buffer, meta } = await runMeshHeavyInWorkerPool(
3276
+ "solidSplitBySurface",
3277
+ [this._buffer, surface._buffer],
3278
+ {
3279
+ ...options,
3280
+ trusted: [this._trustedBooleanInput, surface._trustedBooleanInput],
3281
+ allowUnsafe: options?.allowUnsafe ?? true,
3282
+ },
3283
+ );
3284
+ const packed = new Float64Array(buffer);
3285
+ const readSide = (off: number): { side: Mesh[]; next: number } => {
3286
+ const count = Math.max(0, Math.round(packed[off] ?? 0));
3287
+ let cursor = off + 1;
3288
+ const side: Mesh[] = [];
3289
+ for (let i = 0; i < count; i++) {
3290
+ const len = Math.max(0, Math.round(packed[cursor] ?? 0));
3291
+ cursor += 1;
3292
+ side.push(Mesh.fromTrustedBuffer(packed.slice(cursor, cursor + len)));
3293
+ cursor += len;
3294
+ }
3295
+ return { side, next: cursor };
3296
+ };
3297
+ const outside = readSide(0);
3298
+ const inside = readSide(outside.next);
3299
+ const classification =
3300
+ (meta?.classification as "volume" | "surface" | undefined) ?? "surface";
3301
+ return {
3302
+ outside: outside.side,
3303
+ inside: inside.side,
3304
+ all: [...outside.side, ...inside.side],
3305
+ classification,
3306
+ };
3307
+ } catch (error) {
3308
+ if (!shouldFallbackFromWorkerFailure(error)) throw error;
3309
+ console.warn(
3310
+ "Mesh.splitSolidBySurfaceAsync worker failed; falling back to main thread.",
3311
+ error,
3312
+ );
3313
+ return this.splitSolidBySurface(surface, {
3314
+ ...options,
3315
+ allowUnsafe: options?.allowUnsafe ?? true,
3316
+ });
3317
+ }
3318
+ }
3319
+
3263
3320
  splitSolidBySurface(surface: Mesh, options?: MeshBooleanOptions): MeshSplitResult {
3264
3321
  ensureInit();
3265
3322
  if (this.faceCount === 0) {
@@ -154,6 +154,7 @@ export type MeshHeavyOperation =
154
154
  | "filletEdges"
155
155
  | "brepBoolean"
156
156
  | "split"
157
+ | "solidSplitBySurface"
157
158
  | "diagnostics"
158
159
  | "repair"
159
160
  | "importStl";
@@ -208,6 +208,29 @@ function runHeavyOperation(message: {
208
208
  meta: { classification: r.classification ?? "volume" },
209
209
  };
210
210
  }
211
+ case "solidSplitBySurface": {
212
+ const [solid, surface] = meshes();
213
+ const r = solid.splitSolidBySurface(surface, options);
214
+ // Same two-side packing as "split".
215
+ const packSide = (side: Mesh[]): number =>
216
+ side.reduce((n, m) => n + 1 + m.rawBuffer.length, 1);
217
+ const total = packSide(r.outside) + packSide(r.inside);
218
+ const out = new Float64Array(total);
219
+ let off = 0;
220
+ for (const side of [r.outside, r.inside]) {
221
+ out[off++] = side.length;
222
+ for (const m of side) {
223
+ const raw = m.rawBuffer;
224
+ out[off++] = raw.length;
225
+ out.set(raw, off);
226
+ off += raw.length;
227
+ }
228
+ }
229
+ return {
230
+ buffer: out.buffer as ArrayBuffer,
231
+ meta: { classification: r.classification ?? "surface" },
232
+ };
233
+ }
211
234
  case "importStl": {
212
235
  // buffers[0] carries the RAW STL FILE BYTES, length-prefixed and padded
213
236
  // into an f64-aligned payload: [byteLength] then the bytes from offset 8