Skip to content

feat(brep): make the BRep builder public - #36

Open
Basnederveen wants to merge 1 commit into
OpenGeometry-io:mainfrom
Bas-Automation-Services:feat/public-brep-builder
Open

Basnederveen wants to merge 1 commit into
OpenGeometry-io:mainfrom
Bas-Automation-Services:feat/public-brep-builder

Conversation

@Basnederveen

Copy link
Copy Markdown

What

The kernel builds every primitive and boolean result face by face with brep::Builder, but the builder is crate-private. A crate that depends on OpenGeometry and needs a solid the primitives don't cover (for example a part made of planar faces and cylinder sectors, laid out by its own rules) can't build one, except by writing BRep JSON by hand and reading it back with BrepEnvelope::from_json. That path skips the checks the builder does as it goes (an edge used by a third loop, a missing edge) and gives no face ids back.

This makes the builder usable from outside the crate, with the smallest surface that can describe a face:

  • brep::Builder: new, vertex, edge, face, face_with_holes, finish_solid, plus two new methods:
    • brep(): read access to the body under construction (e.g. to look up an edge's curve);
    • set_face_sense(face, Orientation): a face whose material normal opposes its surface normal (the inside of a tube), without reaching into the topology.
  • face and face_with_holes return the new face's id instead of (), so set_face_sense can use it. The 14 internal call sites that used the call as a tail expression now end in ?; Ok(()).
  • brep::{Use, boundary, plane_boundary, uv_line}: the loop edge uses.
  • Types those signatures need, made public: brep::Orientation, brep::PcurveGeometry (with IntersectionSide, which one of its variants holds) and math::Interval::new. PcurveGeometry and Orientation are already part of the BRep JSON schema.

edge_geometry, face_loop, finish_wire, WireUse, dimensions and padded_uv_bounds stay crate-private. Nothing changes for the TypeScript API.

Tests

  • New tests/public_brep_builder.rs, using only the public API:
    • a 2 x 3 x 4 box built face by face: face ids 0 to 5, finish_solid and validate pass, 12 edges and 24 half-edges, volume 24, a point inside classifies as Inside and one outside as Outside, STEP export writes 6 faces;
    • set_face_sense on the top face's id turns its face_normal_at from +z to -z, and an unknown id is a MissingReference;
    • a face that uses an edge a third time is rejected with InvalidTopology.
  • cargo fmt --check and cargo clippy --all-targets -D warnings: clean.
  • cargo test --all-targets with CI=true (Windows x86_64, no golden file for this target): 788 pass, 0 fail, 1 ignored (main without this change: 785 pass, 0 fail, the same 1 ignored; the 3 new tests are the difference).
  • npm run check:source, check:duplicates, check:cycles: clean. check:api reads the built dist/ and was not run (this change has no TypeScript or WASM surface).

Files

  • main/opengeometry/src/brep/builder/{brep_builder,boundary,mod}.rs, src/brep/mod.rs, src/brep/pcurve.rs, src/brep/topology/{mod,orientation}.rs, src/math/interval.rs: visibility, the face id return, brep() and set_face_sense
  • 10 files under src/primitives/ and src/operations/modifying/boolean/handlers/cylinder_cylinder/: tail calls of face now return Ok(())
  • main/opengeometry/tests/public_brep_builder.rs (new)

🤖 Generated with Claude Code

A crate that depends on OpenGeometry and needs a solid the primitives
don't cover can only build one by writing BRep JSON by hand. The builder
the kernel uses for every primitive and boolean result is crate-private.

- brep::{Builder, Use, boundary, plane_boundary, uv_line} are public:
  Builder::{new, vertex, edge, face, face_with_holes, finish_solid}
- face() and face_with_holes() return the new face id
- Builder::brep() gives read access while building
- Builder::set_face_sense() sets a face's sense by id
- the types those signatures need are public: brep::Orientation,
  brep::PcurveGeometry (and IntersectionSide), math::Interval::new
- the 14 internal tail calls of face() now end in `?; Ok(())`

tests/public_brep_builder.rs builds a box through the public API only:
valid, volume 24, inside/outside classification, STEP export; a face
sense set by id flips face_normal_at; an edge used by a third loop is
rejected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VFZvqx1RmXzPtbL9VXP4H7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant