polystrata-3d 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +91 -2
- package/dist/brep3d.d.ts +85 -0
- package/dist/brep3d.d.ts.map +1 -0
- package/dist/index.cjs +420 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +420 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/wasm-bytes.d.ts +2 -0
- package/dist/wasm-bytes.d.ts.map +1 -0
- package/dist/wasm-kernel.d.ts +37 -0
- package/dist/wasm-kernel.d.ts.map +1 -0
- package/package.json +74 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,92 @@
|
|
|
1
|
-
#
|
|
1
|
+
# polystrata-3d
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**[Interactive 3D Planar B-Rep Lab](https://polystrata3d.ptrbyr.com)** • **[Live 3D Benchmark Suite](https://polystrata3d.ptrbyr.com/benchmark)** • **[npm](https://www.npmjs.com/package/polystrata-3d)** • **[crates.io](https://crates.io/crates/polystrata-3d)** • **[docs.rs](https://docs.rs/polystrata-3d)**
|
|
4
|
+
|
|
5
|
+
`polystrata-3d` is a high-performance, topologically robust **3D Planar Boundary-Representation (B-Rep) Boolean & Healing kernel** implemented in Rust and compiled to WebAssembly.
|
|
6
|
+
|
|
7
|
+
Unlike triangle-mesh CSG libraries (`manifold-3d`, `three-bvh-csg`), `polystrata-3d` operates directly on **exact planar polygon faces with interior holes** in IEEE-754 `f64` precision, unifying coplanar regions, resolving 3D T-junctions conformally, and stripping non-manifold dangling fins to guarantee closed, watertight 2-manifold (`∂₁ · ∂₂ = 0`) output.
|
|
8
|
+
|
|
9
|
+
- **Zero dependencies**, self-contained dual ESM + CommonJS build (including embedded WASM) and native Rust crate ([`polystrata-3d` on crates.io](https://crates.io/crates/polystrata-3d)).
|
|
10
|
+
- **Faster than `manifold-3d` (v3.5.4 C++/WASM) on 7 of 10 3D CAD, bicylinder, and glancing workloads** (`1.04×–2.17×` faster), while emitting **3×–4× fewer polygonal faces** and **10⁸× lower volume error** (`~10⁻¹³` vs. `~10⁻⁵`).
|
|
11
|
+
- **100% watertight 2-manifold pass rate (`24/24`)** across the 3D adversarial glancing & degeneracy stress suite (`manifold-3d`: `23/24` with 1 crash on non-manifold input; `three-bvh-csg`: `3/24`; `@jscad/modeling`: `4/24`).
|
|
12
|
+
- Looking for 2D polygon clipping? See [**`polystrata`**](https://github.com/pboyer/polystrata).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
**JavaScript / TypeScript ([npm](https://www.npmjs.com/package/polystrata-3d)):**
|
|
19
|
+
```bash
|
|
20
|
+
npm install polystrata-3d
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Rust ([crates.io](https://crates.io/crates/polystrata-3d) / [docs.rs](https://docs.rs/polystrata-3d)):**
|
|
24
|
+
```bash
|
|
25
|
+
cargo add polystrata-3d
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Quick Start (TypeScript / JavaScript)
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import {
|
|
34
|
+
union,
|
|
35
|
+
intersect,
|
|
36
|
+
difference,
|
|
37
|
+
xor,
|
|
38
|
+
heal,
|
|
39
|
+
createBox,
|
|
40
|
+
extrudePolygon,
|
|
41
|
+
transformSolid,
|
|
42
|
+
initPolystrata3D,
|
|
43
|
+
} from "polystrata-3d";
|
|
44
|
+
|
|
45
|
+
// Optional on Node.js / Bun / Deno / Web Workers; recommended once at startup on browser main threads:
|
|
46
|
+
await initPolystrata3D();
|
|
47
|
+
|
|
48
|
+
const boxA = createBox([-5, -5, -5], [5, 5, 5]);
|
|
49
|
+
const boxB = createBox([0, 0, 0], [8, 8, 8]);
|
|
50
|
+
|
|
51
|
+
const diff = difference(boxA, boxB);
|
|
52
|
+
console.log(diff.solid.faces); // Exact unified planar faces ({ outer, holes, normal })
|
|
53
|
+
console.log(diff.triangles); // Ready-to-render 3D surface triangles
|
|
54
|
+
console.log(diff.totalVolume); // 875.0
|
|
55
|
+
console.log(diff.unmatchedHalfEdgeCount); // 0 (watertight 2-manifold)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Quick Start (Rust)
|
|
59
|
+
|
|
60
|
+
```rust
|
|
61
|
+
use polystrata_3d::{union, intersect, difference, xor, heal, KernelOptions, Point3D, Face3D, Solid3D};
|
|
62
|
+
|
|
63
|
+
let opts = KernelOptions::default();
|
|
64
|
+
let res = difference(&solid_a, &solid_b, opts);
|
|
65
|
+
assert_eq!(res.unmatched_half_edge_count, 0);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Benchmarks vs. `manifold-3d`, `three-bvh-csg`, and `@jscad/modeling`
|
|
71
|
+
|
|
72
|
+
Run the 3D benchmark suite locally with `npm run bench`:
|
|
73
|
+
|
|
74
|
+
| 3D Workload | Input Faces | `polystrata-3d` (Planar B-Rep) | `manifold-3d` v3.5.4 (C++/WASM) | `three-bvh-csg` v0.0.18 | `@jscad/modeling` v2.13.0 |
|
|
75
|
+
| :--- | ---: | ---: | ---: | ---: | ---: |
|
|
76
|
+
| **Multi-Hole Flange & Tilted Pillar** | 14 + 6 | **5,063 op/s** (`22F/92T`, PASS) | 4,882 op/s (`92F/92T`, PASS) | 1,672 op/s (NON-MANIFOLD) | 4,952 op/s (NON-MANIFOLD) |
|
|
77
|
+
| **Coplanar Overlapping Hexahedra** | 6 + 6 | **25,779 op/s** (`6F/12T`, PASS) | 16,360 op/s (`28F/28T`, PASS) | 4,305 op/s (NON-MANIFOLD) | 40,097 op/s (`6F/12T`, PASS) |
|
|
78
|
+
| **8-Tooth Star Gear & Hex Cutter** | 18 + 8 | **3,574 op/s** (`39F/136T`, PASS) | 3,315 op/s (`156F/156T`, PASS) | 1,303 op/s (NON-MANIFOLD) | 3,353 op/s (NON-MANIFOLD) |
|
|
79
|
+
| **Steinmetz Bicylinder (Tangent)** | 18 + 18 | **3,250 op/s** (`68F/184T`, PASS) | 2,440 op/s (`184F/184T`, PASS) | 1,250 op/s (NON-MANIFOLD) | 1,717 op/s (`68F/184T`, PASS) |
|
|
80
|
+
| **UV-Spheres 3.5° Glancing Lens** | 144 + 144 | **2,124 op/s** (`288F/552T`, PASS) | 5,141 op/s (`576F/576T`, PASS) | 2,996 op/s (NON-MANIFOLD) | 696 op/s (NON-MANIFOLD) |
|
|
81
|
+
| **Torus Saddle Cut by 2° Cylinder** | 160 + 18 | **1,219 op/s** (`157F/494T`, PASS) | 1,972 op/s (`558F/558T`, PASS) | 850 op/s (NON-MANIFOLD) | 413 op/s (NON-MANIFOLD) |
|
|
82
|
+
| **Nearly Parallel Cylinders (1.75°)** | 18 + 18 | **3,440 op/s** (`50F/180T`, PASS) | 1,583 op/s (`222F/222T`, PASS) | 922 op/s (NON-MANIFOLD) | 1,669 op/s (NON-MANIFOLD) |
|
|
83
|
+
| **Pointed Cone Grazing Box (0.8°)** | 6 + 17 | **10,857 op/s** (`23F/50T`, PASS) | 16,375 op/s (`50F/50T`, PASS) | 5,155 op/s (NON-MANIFOLD) | 12,695 op/s (NON-MANIFOLD) |
|
|
84
|
+
| **Intermeshing Comb Teeth (1.1°)** | 14 + 14 | **4,588 op/s** (`36F/132T`, PASS) | 3,243 op/s (`134F/134T`, PASS) | 1,357 op/s (NON-MANIFOLD) | 3,154 op/s (NON-MANIFOLD) |
|
|
85
|
+
| **Box with Non-Manifold Dangling Fin** | 7 + 6 | **16,569 op/s** (`12F/36T`, PASS) | **CRASH** (`NotManifold`) | 7,240 op/s (NON-MANIFOLD) | 17,623 op/s (NON-MANIFOLD) |
|
|
86
|
+
| **24-Scenario 3D Stress Suite (72 ops)** | — | **1,737 op/s — 24/24 (100%) 2-Manifold** | 1,950 op/s — 23/24 (95.8%) (1 crash) | 1,015 op/s — 3/24 (12.5%) | 942 op/s — 4/24 (16.7%) |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
[MIT](./LICENSE)
|
package/dist/brep3d.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 3D Planar B-Rep Boolean & Self-Intersection Healing Engine for `polystrata-3d`.
|
|
3
|
+
*
|
|
4
|
+
* Implements the 4-Stage Coupled 3D Stratified Tolerance Complex:
|
|
5
|
+
* - Canonical carrier plane clustering (`π_c`) & 1D plane-plane intersection chord injection
|
|
6
|
+
* - Coupled 3D 0-stratum & 1-stratum fixpoint consolidation with regularized 3×3 quadric projection
|
|
7
|
+
* - Combinatorial 2-stratum (`∂₂`) & radial CoFace 3-stratum (`∂₃`) volume cell extraction
|
|
8
|
+
* - Van Oosterom–Strackee 3D solid-angle winding classification, coplanar face unification,
|
|
9
|
+
* and conformal 3D T-junction subdivision for watertight 2-manifold (`∂₁ · ∂₂ = 0`) output
|
|
10
|
+
*/
|
|
11
|
+
import type { BooleanOp, BRepResult3D, Face3D, KernelOptions, Point3D, Solid3D, Triangle3D, TuplePoint3D, WasmBRep3DResult, WindingRule } from "./types.js";
|
|
12
|
+
export type { BooleanOp, BRepResult3D, Face3D, KernelOptions, Point3D, Solid3D, Triangle3D, TuplePoint3D, WasmBRep3DResult, WindingRule, };
|
|
13
|
+
/**
|
|
14
|
+
* Compute the Newell outward unit normal of a 3D polygon ring.
|
|
15
|
+
*/
|
|
16
|
+
export declare function computeLoopNormal3D(loop: readonly (Point3D | TuplePoint3D)[]): Point3D;
|
|
17
|
+
/** Alias for {@link computeLoopNormal3D}. */
|
|
18
|
+
export declare const computeLoopNormal: typeof computeLoopNormal3D;
|
|
19
|
+
/**
|
|
20
|
+
* Construct an axis-aligned 3D box `[min[0], max[0]] × [min[1], max[1]] × [min[2], max[2]]`
|
|
21
|
+
* with 6 outward-oriented planar faces.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createBox3D(min: TuplePoint3D | Point3D, max: TuplePoint3D | Point3D): Solid3D;
|
|
24
|
+
/** Alias for {@link createBox3D}. */
|
|
25
|
+
export declare const createBox: typeof createBox3D;
|
|
26
|
+
/**
|
|
27
|
+
* Construct a 3D prism by extruding a 2D polygon (with optional interior holes)
|
|
28
|
+
* along `[zMin, zMax]`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extrudePolygon3D(outer2D: readonly (readonly [number, number])[], holes2D?: readonly (readonly (readonly [number, number])[])[], zMin?: number, zMax?: number): Solid3D;
|
|
31
|
+
/** Alias for {@link extrudePolygon3D}. */
|
|
32
|
+
export declare const extrudePolygon: typeof extrudePolygon3D;
|
|
33
|
+
/**
|
|
34
|
+
* Apply an affine or rigid 3D transformation `(p) => Point3D` to every vertex of a `Solid3D`
|
|
35
|
+
* and recompute outward unit normals.
|
|
36
|
+
*/
|
|
37
|
+
export declare function transformSolid3D(solid: Solid3D, transformPt: (p: Point3D) => Point3D): Solid3D;
|
|
38
|
+
/** Alias for {@link transformSolid3D}. */
|
|
39
|
+
export declare const transformSolid: typeof transformSolid3D;
|
|
40
|
+
/**
|
|
41
|
+
* Compute the 3D Boolean union (`A ∪ B`) of two planar B-Rep solids.
|
|
42
|
+
*/
|
|
43
|
+
export declare function union3D(a: Solid3D, b: Solid3D, options?: KernelOptions): BRepResult3D;
|
|
44
|
+
/** Alias for {@link union3D}. */
|
|
45
|
+
export declare const union: typeof union3D;
|
|
46
|
+
/**
|
|
47
|
+
* Compute the 3D Boolean intersection (`A ∩ B`) of two planar B-Rep solids.
|
|
48
|
+
*/
|
|
49
|
+
export declare function intersect3D(a: Solid3D, b: Solid3D, options?: KernelOptions): BRepResult3D;
|
|
50
|
+
/** Alias for {@link intersect3D}. */
|
|
51
|
+
export declare const intersect: typeof intersect3D;
|
|
52
|
+
/**
|
|
53
|
+
* Compute the 3D Boolean difference (`A \ B`) of two planar B-Rep solids.
|
|
54
|
+
*/
|
|
55
|
+
export declare function difference3D(a: Solid3D, b: Solid3D, options?: KernelOptions): BRepResult3D;
|
|
56
|
+
/** Alias for {@link difference3D}. */
|
|
57
|
+
export declare const difference: typeof difference3D;
|
|
58
|
+
/**
|
|
59
|
+
* Compute the 3D Boolean symmetric difference (`A ⊕ B`) of two planar B-Rep solids.
|
|
60
|
+
*/
|
|
61
|
+
export declare function xor3D(a: Solid3D, b: Solid3D, options?: KernelOptions): BRepResult3D;
|
|
62
|
+
/** Alias for {@link xor3D}. */
|
|
63
|
+
export declare const xor: typeof xor3D;
|
|
64
|
+
/**
|
|
65
|
+
* Heal a single 3D planar face soup or self-intersecting polyhedron into a closed 2-manifold B-Rep.
|
|
66
|
+
*/
|
|
67
|
+
export declare function heal3D(solid: Solid3D, options?: KernelOptions): BRepResult3D;
|
|
68
|
+
/** Alias for {@link heal3D}. */
|
|
69
|
+
export declare const heal: typeof heal3D;
|
|
70
|
+
/**
|
|
71
|
+
* Dispatch a 3D Boolean operation by {@link BooleanOp}.
|
|
72
|
+
*/
|
|
73
|
+
export declare function clip3D(op: BooleanOp, a: Solid3D, b: Solid3D, options?: KernelOptions): BRepResult3D;
|
|
74
|
+
/** Alias for {@link clip3D}. */
|
|
75
|
+
export declare const clip: typeof clip3D;
|
|
76
|
+
/**
|
|
77
|
+
* Pre-load two {@link Solid3D} bodies into WASM linear memory for repeated or benchmarked
|
|
78
|
+
* 3D Boolean execution, returning flat TypedArray views of the output B-Rep and triangle mesh.
|
|
79
|
+
*/
|
|
80
|
+
export declare function prepareBooleanTask3D(a: Solid3D, b: Solid3D, options?: KernelOptions): {
|
|
81
|
+
run: (op: BooleanOp) => WasmBRep3DResult;
|
|
82
|
+
};
|
|
83
|
+
/** Alias for {@link prepareBooleanTask3D}. */
|
|
84
|
+
export declare const prepareBooleanTask: typeof prepareBooleanTask3D;
|
|
85
|
+
//# sourceMappingURL=brep3d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brep3d.d.ts","sourceRoot":"","sources":["../src/brep3d.ts"],"names":[],"mappings":"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"}
|