okgeometry-api 1.9.0 → 1.10.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/src/Mesh.ts CHANGED
@@ -2521,6 +2521,68 @@ export class Mesh {
2521
2521
  return this.splitWithCurve(target, options as MeshCurveSplitOptions | undefined);
2522
2522
  }
2523
2523
 
2524
+ /**
2525
+ * Split this CLOSED solid by a `surface` (an open sheet or a closed shell)
2526
+ * into BOTH sides as WATERTIGHT CAPPED solids.
2527
+ *
2528
+ * Unlike {@link split} — which, for an open-surface cutter, leaves open
2529
+ * shells — this welds the portion of the surface that lies inside the solid
2530
+ * onto each side as a cap. Because the host cut and the surface trim are
2531
+ * computed from the same triangle–triangle intersection segments, the seam
2532
+ * vertices coincide and the result is watertight.
2533
+ *
2534
+ * Result semantics (classification "surface"):
2535
+ * - `outside` / `negative`: the side on the negative side of the surface
2536
+ * normal, capped by the trimmed surface patch.
2537
+ * - `inside` / `positive`: the positive side, capped by the same patch.
2538
+ *
2539
+ * If the surface does not fully cut through the solid, the produced side(s)
2540
+ * will not be closed — verify with `isClosedVolume()` on the side you keep.
2541
+ */
2542
+ splitSolidBySurface(surface: Mesh, options?: MeshBooleanOptions): MeshSplitResult {
2543
+ ensureInit();
2544
+ if (this.faceCount === 0) {
2545
+ return Mesh.createSurfaceSplitResult([], []);
2546
+ }
2547
+ if (surface.faceCount === 0) {
2548
+ return Mesh.createSurfaceSplitResult([Mesh.cloneMesh(this)], []);
2549
+ }
2550
+
2551
+ if (!options?.allowUnsafe) {
2552
+ const limits = Mesh.resolveBooleanLimits(options?.limits);
2553
+ const faceCountA = this.faceCount;
2554
+ const faceCountB = surface.faceCount;
2555
+ const maxInputFaces = Math.max(faceCountA, faceCountB);
2556
+ const combinedInputFaces = faceCountA + faceCountB;
2557
+ const faceProduct = faceCountA * faceCountB;
2558
+ if (
2559
+ maxInputFaces > limits.maxInputFacesPerMesh
2560
+ || combinedInputFaces > limits.maxCombinedInputFaces
2561
+ || faceProduct > limits.maxFaceProduct
2562
+ ) {
2563
+ throw new Error(
2564
+ `Mesh solid split by surface blocked by safety limits `
2565
+ + `(solid faces=${faceCountA}, surface faces=${faceCountB}, faceProduct=${faceProduct}). `
2566
+ + "Simplify inputs or pass allowUnsafe: true to force execution.",
2567
+ );
2568
+ }
2569
+ }
2570
+
2571
+ const token = Mesh.encodeBooleanSplitToken(this, surface, options);
2572
+ const result = wasm.mesh_solid_split_by_surface(
2573
+ this._vertexCount,
2574
+ this._buffer,
2575
+ surface._vertexCount,
2576
+ surface._buffer,
2577
+ token,
2578
+ );
2579
+ if (result.length === 0) {
2580
+ throw new Error("Mesh solid split by surface failed and returned an invalid result buffer.");
2581
+ }
2582
+ const parsed = Mesh.parseSplitResultBuffer(result);
2583
+ return Mesh.createSurfaceSplitResult(parsed.outside, parsed.inside);
2584
+ }
2585
+
2524
2586
  debugBoolean(
2525
2587
  other: Mesh,
2526
2588
  operation: MeshBooleanOperation,