Skip to content
Closed
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
46 changes: 46 additions & 0 deletions AI-DOCs/2026-03-11-pipe-network-layout-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Pipe Network Layout Example Handoff

## What changed

- Added a new operations example: `operations/pipe-network-layout.html`.
- Example builds a multi-branch pipe layout using sweep path + profile primitives (4 pipe types).
- Added an on-page legend describing each pipe type and profile dimensions.
- Added scene walls built with `Cuboid` to mimic room boundaries.
- Added UI toggles for outlines, fat outlines, outline width, wall visibility, and FPS stats visibility.
- Added Three.js FPS monitoring using `stats.module.js`.
- Added config logging in the console on each state update, including pipe metadata.
- Registered the new example in `examples-vite/index.html` and updated the operations item count.

## Why it changed

To provide a richer, architecture-consistent example similar to HVAC / MEP layouts:
- sweep + profile usage,
- multiple pipe classes with visual legend,
- wall context geometry,
- quick outline controls,
- and runtime perf visibility.

## How to test locally

1. Ensure the OpenGeometry wasm package is available at `main/opengeometry/pkg/opengeometry_bg.wasm`.
2. Start examples dev server:
- `npm --prefix main/opengeometry-three run dev-example-three`
3. Open:
- `http://localhost:5173/operations/pipe-network-layout.html`
4. Validate:
- outlines toggle applies to walls + sweeps,
- 4 pipe types render with distinct colors,
- legend entries match rendered pipe colors/profiles,
- console prints `[OpenGeometry] Pipe network config ...`,
- FPS panel appears and can be toggled.

## Backward-compatibility notes

- No existing APIs changed.
- Existing examples were not behaviorally modified.
- Only example catalog index was updated to add one new operation card.

## Known caveats and follow-ups

- Example build depends on generated wasm artifacts in `main/opengeometry/pkg/`; without them, Vite build fails on wasm URL resolution.
- If desired later, extract shared example helpers to reduce repeated boilerplate across example HTML pages.
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>
Loading
Loading