Problem
SolidRepr in crates/vcad-kernel/src/lib.rs:82 is BRep | Mesh | Empty. Several code paths drop a BRep solid down to Mesh, after which any feature that needs topology (face IDs, surface kind, edges, normals) silently no-ops on that part:
crates/vcad-kernel/src/lib.rs:219 — BooleanResult::Mesh(m) => Solid { repr: SolidRepr::Mesh(m), ... } is the explicit boolean fallback path.
crates/vcad-kernel/src/lib.rs:130, 232, 336, 614, 720 — every other transform / shell / mesh-input path that hits a Mesh representation propagates it forward.
Solid::as_brep() returns None for any of these, which is what the new DFM crate hits and why my v1 has the "DFM skipped on mesh-only solids" branch.
The downstream blast radius is large:
- DFM (
vcad-kernel-dfm): Solid.runDfm returns an empty report for any part that's been booleaned. The whole agent loop is silently a no-op on assemblies with cuts.
- STEP export (
StepExportError::NotBRep at crates/vcad-kernel/src/lib.rs:42): explicitly errors on mesh-only solids. Users hit this whenever they export a part that uses a difference op.
- Direct BRep ray tracing (
vcad-kernel-raytrace): needs BRepSolid to build a BVH; mesh-only parts fall back to the standard rasterizer or render incorrectly.
- Provenance, fillets, shells, drafting projections: all topology-aware, all silently degraded.
Why now
This is the upstream cause of half the caveats in the v1 DFM PR (#TBD on claude/dfm-tools-integration-HcsqQ) and the "BRep lost after boolean operations" wording that's repeated through several error messages. Fixing it once unlocks DFM, STEP export, raytrace, and any future BRep-aware feature on the most common kind of part (a primitive with a hole or pocket).
Proposed approach
Make vcad-kernel-booleans always produce a BooleanResult::BRep. The mesh fallback exists because some boolean cases used to fail or produce non-manifold output; with the current sewing pipeline the cases that fall through should be small enough to either:
- Fix the missing topology directly in the boolean kernel (preferred — preserves provenance and the rest of the kernel's BRep-first design), or
- Re-tessellate the mesh result and reconstruct topology via face-grouping by coplanarity (a stopgap; loses the benefit but at least keeps
as_brep() non-None).
Acceptance criteria
BooleanResult no longer has a Mesh variant.
cargo test --workspace passes including the boolean test suite.
- A part =
cube.difference(cylinder) returns Some(brep) from as_brep().
- DFM run on a cube-with-hole part produces a non-empty report (e.g., flags the hole's small radius as a CNC issue).
- STEP export on the same part succeeds.
References
crates/vcad-kernel/src/lib.rs:82, 130, 219-222, 232, 336, 614, 720 — every site SolidRepr::Mesh is constructed
crates/vcad-kernel/src/lib.rs:42-50 — StepExportError::NotBRep
crates/vcad-kernel-wasm/src/lib.rs — Solid.runDfm mesh-only short-circuit added in the v1 DFM PR
crates/vcad-kernel-booleans/ — the boolean pipeline that needs to commit to BRep output
Problem
SolidReprincrates/vcad-kernel/src/lib.rs:82isBRep | Mesh | Empty. Several code paths drop aBRepsolid down toMesh, after which any feature that needs topology (face IDs, surface kind, edges, normals) silently no-ops on that part:crates/vcad-kernel/src/lib.rs:219—BooleanResult::Mesh(m) => Solid { repr: SolidRepr::Mesh(m), ... }is the explicit boolean fallback path.crates/vcad-kernel/src/lib.rs:130, 232, 336, 614, 720— every other transform / shell / mesh-input path that hits aMeshrepresentation propagates it forward.Solid::as_brep()returnsNonefor any of these, which is what the new DFM crate hits and why my v1 has the "DFM skipped on mesh-only solids" branch.The downstream blast radius is large:
vcad-kernel-dfm):Solid.runDfmreturns an empty report for any part that's been booleaned. The whole agent loop is silently a no-op on assemblies with cuts.StepExportError::NotBRepatcrates/vcad-kernel/src/lib.rs:42): explicitly errors on mesh-only solids. Users hit this whenever they export a part that uses a difference op.vcad-kernel-raytrace): needsBRepSolidto build a BVH; mesh-only parts fall back to the standard rasterizer or render incorrectly.Why now
This is the upstream cause of half the caveats in the v1 DFM PR (#TBD on
claude/dfm-tools-integration-HcsqQ) and the "BRep lost after boolean operations" wording that's repeated through several error messages. Fixing it once unlocks DFM, STEP export, raytrace, and any future BRep-aware feature on the most common kind of part (a primitive with a hole or pocket).Proposed approach
Make
vcad-kernel-booleansalways produce aBooleanResult::BRep. The mesh fallback exists because some boolean cases used to fail or produce non-manifold output; with the current sewing pipeline the cases that fall through should be small enough to either:as_brep()non-None).Acceptance criteria
BooleanResultno longer has aMeshvariant.cargo test --workspacepasses including the boolean test suite.cube.difference(cylinder)returnsSome(brep)fromas_brep().References
crates/vcad-kernel/src/lib.rs:82, 130, 219-222, 232, 336, 614, 720— every siteSolidRepr::Meshis constructedcrates/vcad-kernel/src/lib.rs:42-50—StepExportError::NotBRepcrates/vcad-kernel-wasm/src/lib.rs—Solid.runDfmmesh-only short-circuit added in the v1 DFM PRcrates/vcad-kernel-booleans/— the boolean pipeline that needs to commit to BRep output