Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ node_modules/
# JS/TS build artifacts
dist/
main/opengeometry-three/examples-dist/
main/opengeometry-three/examples-vite/.generated/
main/opengeometry/pkg/

.DS_Store
Expand Down
99 changes: 99 additions & 0 deletions AI-DOCs/opengeometry/2026-03-04-halfedge-brep-migration-handoff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Half-Edge BREP Migration Handoff

## What Changed

- Replaced the BREP core model with a half-edge-first topology schema.
- Added canonical topology entities:
- `Vertex { outgoing_halfedge }`
- `HalfEdge`
- `Edge { halfedge, twin_halfedge }`
- `Loop`
- `Face { outer_loop, inner_loops, shell_ref }`
- `Wire`
- `Shell`
- Added `BrepBuilder` for deterministic topology construction.
- Added `Brep::validate_topology() -> Result<(), BrepError>` with manifold and linkage checks.
- Reworked projection/HLR to derive visibility from half-edge adjacency.
- Migrated primitives and sweep/extrude operations to builder-based half-edge output.
- Updated wasm mutating methods to checked APIs (`Result<(), JsValue>`) for invalid topology/input states.
- Updated three integration (`shapes/sphere.ts`) to consume outline buffers from kernel instead of legacy edge endpoint fields.

## Breaking Changes

- `get_brep_serialized()` now emits the new half-edge schema.
- Removed legacy fields from serialized BREP:
- `edges[].v1`
- `edges[].v2`
- `faces[].face_indices`
- root `holes`
- root `hole_edges`
- Mutating methods such as `set_config` / `generate_geometry` now return `Result<(), JsValue>` at wasm boundaries.

## Legacy Cleanup

- Removed:
- `main/opengeometry/src/utility/geometry.rs`
- `main/opengeometry/src/primitives/cylinderOld.rs`
- Removed stale commented legacy BREP scaffolding from `main/opengeometry/src/lib.rs`.
- Replaced old extrude geometry dependency with local `Geometry` in `operations/extrude.rs`.

## Implementation Notes

- `BrepBuilder` enforces:
- canonical undirected edge mapping
- twin linking of opposite directed halfedges
- non-manifold rejection (`> 2` halfedges per edge)
- loop closure and link consistency
- Face triangulation inputs now come from `outer_loop` and `inner_loops` via `Brep::get_vertices_and_holes_by_face_id`.
- Wire primitives (`line`, `curve`, `polyline`, `arc`) are represented as `wires` and edge-backed halfedges.
- Solid primitives (`cuboid`, `cylinder`, `wedge`, `sphere`, `sweep`) assign shell topology.

## Files Added

- `main/opengeometry/src/brep/error.rs`
- `main/opengeometry/src/brep/builder.rs`
- `main/opengeometry/src/brep/loop.rs`
- `main/opengeometry/src/brep/wire.rs`
- `main/opengeometry/src/brep/shell.rs`

## Files Reworked (Core)

- `main/opengeometry/src/brep/mod.rs`
- `main/opengeometry/src/brep/vertex.rs`
- `main/opengeometry/src/brep/halfedge.rs`
- `main/opengeometry/src/brep/edge.rs`
- `main/opengeometry/src/brep/face.rs`
- `main/opengeometry/src/export/projection.rs`
- `main/opengeometry/src/operations/extrude.rs`
- `main/opengeometry/src/operations/sweep.rs`

## Files Reworked (Primitives)

- `main/opengeometry/src/primitives/line.rs`
- `main/opengeometry/src/primitives/curve.rs`
- `main/opengeometry/src/primitives/polyline.rs`
- `main/opengeometry/src/primitives/arc.rs`
- `main/opengeometry/src/primitives/rectangle.rs`
- `main/opengeometry/src/primitives/polygon.rs`
- `main/opengeometry/src/primitives/cuboid.rs`
- `main/opengeometry/src/primitives/cylinder.rs`
- `main/opengeometry/src/primitives/wedge.rs`
- `main/opengeometry/src/primitives/sphere.rs`
- `main/opengeometry/src/primitives/sweep.rs`

## Validation Run

- `cargo fmt --manifest-path main/opengeometry/Cargo.toml`
- `cargo check --manifest-path main/opengeometry/Cargo.toml`
- `cargo test --manifest-path main/opengeometry/Cargo.toml`
- `cargo test --examples --manifest-path main/opengeometry/Cargo.toml`
- `npm run build-three`

All commands above completed successfully.

## Known Caveats / Follow-ups

- Existing non-critical warnings still present in unrelated legacy code:
- `operations/windingsort.rs` (`ccw_and_flag` naming)
- `geometry/triangle.rs` (`crso` unused variable)
- Consumers that deserialize old BREP JSON must migrate to the new half-edge schema.
106 changes: 106 additions & 0 deletions AI-DOCs/opengeometry/2026-03-04-stl-export-handoff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# STL Export Handoff (Binary STL + Three.js Validation)

## What Changed

- Added binary STL export support in the Rust core:
- `main/opengeometry/src/export/stl.rs`
- best-effort and strict policies
- single-BREP and multi-BREP export APIs
- native file output helpers (`cfg(not(target_arch = "wasm32"))`)
- Wired STL export through `scenegraph`:
- `exportBrepToStl(...)`
- `exportSceneToStl(...)`
- `exportCurrentSceneToStl(...)`
- wasm return payload includes bytes + report metadata (`OGStlExportResult`)
- Hardened incoming serialized BREP handling:
- `addBrepEntityToScene(...)` now validates topology before storing.
- Fixed stale half-edge usage in native sandbox:
- `main/opengeometry/sandbox-native/src/main.rs` now resolves endpoints via `get_edge_endpoints(...)`.
- Added Three.js validation examples:
- Legacy page: `main/opengeometry-three/examples/stl-export.html`
- Vite page: `main/opengeometry-three/examples-vite/operations/stl-export.html`
- Vite script: `main/opengeometry-three/examples-vite/src/pages/operations-stl-export.ts`
- Vite specs index updated to include STL export card.
- Vite STL page now includes a shape dropdown (`Cuboid`, `Cylinder`, `Sphere`, `Wedge`) with per-shape parameter groups and shape-specific STL filenames (`opengeometry-<shape>.stl`).
- Vite STL controls were consolidated into a single panel to prevent control container overlap.
- Exposed STL-related wasm types from package entry:
- `main/opengeometry-three/index.ts` now re-exports `OGSceneManager` and `OGStlExportResult`.

## API Summary

- Rust core:
- `export_brep_to_stl_bytes(&Brep, &StlExportConfig) -> Result<(Vec<u8>, StlExportReport), StlExportError>`
- `export_breps_to_stl_bytes(...) -> Result<(Vec<u8>, StlExportReport), StlExportError>`
- `export_brep_to_stl_file(...)` and `export_breps_to_stl_file(...)` for native file output
- Wasm scenegraph:
- `OGSceneManager.exportBrepToStl(brep_serialized, config_json?)`
- `OGSceneManager.exportSceneToStl(scene_id, config_json?)`
- `OGSceneManager.exportCurrentSceneToStl(config_json?)`
- return type: `OGStlExportResult` with:
- `bytes: Uint8Array`
- `reportJson: string`

## Config Defaults

- Binary STL only.
- Default policy is best-effort.
- Units are preserved as-is (`scale: 1.0` by default).
- Topology validation is enabled by default (`validate_topology: true`).

## How To Test Locally

### Rust quality gates

```bash
cargo fmt --manifest-path main/opengeometry/Cargo.toml
cargo check --manifest-path main/opengeometry/Cargo.toml
cargo test --manifest-path main/opengeometry/Cargo.toml
cargo test --examples --manifest-path main/opengeometry/Cargo.toml
cargo check --target wasm32-unknown-unknown --manifest-path main/opengeometry/Cargo.toml
```

### Native sandbox check

```bash
cargo check --offline --manifest-path main/opengeometry/sandbox-native/Cargo.toml
```

Note: online `cargo check` for `sandbox-native` may fail in restricted environments that cannot reach `index.crates.io`.

### Regenerate wasm package and build examples

```bash
npm run build-core
npm --prefix main/opengeometry-three run build-example-three
```

### Run examples

- Legacy page (static host):
- `main/opengeometry-three/examples/stl-export.html`
- Vite built page:
- `main/opengeometry-three/examples-dist/operations/stl-export.html`
- Use the Shape dropdown and export button to verify shape-specific downloads (`opengeometry-cuboid.stl`, `opengeometry-cylinder.stl`, etc.).

## STL Validation Notes

- Binary STL writer uses `stl_io::write_stl` (spec-compliant binary structure).
- Unit tests cover:
- expected binary size (`84 + 50 * triangle_count`)
- triangle count consistency with STL header
- custom header injection
- best-effort skip behavior and strict failure behavior

## Backward Compatibility

- Existing primitive generation, projection, and PDF APIs remain intact.
- STL functionality is additive.
- One behavior hardening change:
- serialized BREPs added through scene manager are now topology-validated before insertion.

## Known Caveats / Follow-ups

- Existing non-critical warnings remain:
- `operations/windingsort.rs` (`ccw_and_flag` naming)
- `geometry/triangle.rs` (`crso` unused variable)
- `sandbox-native` still has pre-existing `unused_must_use` warnings in some call sites (not introduced by STL work).
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="operations/offset">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="operations/sweep-path-profile">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="operations/wall-from-offsets">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="primitives/arc">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="primitives/curve">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="primitives/line">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="primitives/polyline">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="primitives/rectangle">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="shapes/cuboid">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="shapes/cylinder">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="shapes/opening">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="shapes/polygon-suite">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="shapes/polygon">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenGeometry Example</title>
</head>
<body data-example-slug="shapes/sphere">
<div id="app"></div>
<script type="module" src="../../src/example-page.ts"></script>
</body>
</html>
Loading
Loading