Summary
A geometrically-valid-looking shape built from sweep + fuseAll verifies fine (positive volume, sensible bounds, validSolid where checked) but exportSTEP returns Result.Err("Failed to read exported STEP file"). So a shape that all in-memory checks accept cannot round-trip to STEP — the primary interchange format.
Repro
A miniature spiral-staircase model (one of the brepjs-agent benchmark parts, #1124):
- Central column:
cylinder
- Treads: annular-sector profile drawn with
threePointsArcTo (outer + inner arcs), sketchOnPlane('XY').extrude(...) → ValidSolid, arranged helically (~20 of them)
- Balusters: vertical
cylinder rods at each tread's outer-mid radius
- Handrail:
sketchCircle(...).wire swept along a helical path via sweep(railProfile, railPath, { frenet: true })
- Everything combined with
fuseAll([...])
The resulting shape:
- ✅
measureVolume > 0, getBounds sane, renders correctly in the viewer
- ❌
exportSTEP(shape) → Err("Failed to read exported STEP file") (the writer's read-back validation rejects it)
Suspected cause
The fused result is almost certainly a Compound containing a sub-shape that STEPControl_Writer (or the read-back step that validates the write) won't accept — likely a degenerate/near-degenerate face from the frenet sweep along the tight helix, or a non-manifold seam where the swept rail meets the balusters. The in-memory volume/bounds checks don't catch this because they don't exercise STEP's stricter topology/geometry validation.
Ask
- Investigate whether the offending sub-shape comes from the sweep, the fuseAll, or the STEP writer itself.
- Consider running a validity/heal pass (or surfacing the specific invalid sub-shape) before/at export, and
- At minimum, surface a more actionable error than "Failed to read exported STEP file" — e.g. which sub-shape index/type failed, so callers can locate and heal it.
I can attach the full .brep.ts repro on request (it lives in gitignored benchmark scratch). Surfaced by the brepjs-agent work (#1124).
Summary
A geometrically-valid-looking shape built from
sweep+fuseAllverifies fine (positive volume, sensible bounds,validSolidwhere checked) butexportSTEPreturnsResult.Err("Failed to read exported STEP file"). So a shape that all in-memory checks accept cannot round-trip to STEP — the primary interchange format.Repro
A miniature spiral-staircase model (one of the brepjs-agent benchmark parts, #1124):
cylinderthreePointsArcTo(outer + inner arcs),sketchOnPlane('XY').extrude(...)→ValidSolid, arranged helically (~20 of them)cylinderrods at each tread's outer-mid radiussketchCircle(...).wireswept along a helical path viasweep(railProfile, railPath, { frenet: true })fuseAll([...])The resulting shape:
measureVolume> 0,getBoundssane, renders correctly in the viewerexportSTEP(shape)→Err("Failed to read exported STEP file")(the writer's read-back validation rejects it)Suspected cause
The fused result is almost certainly a
Compoundcontaining a sub-shape thatSTEPControl_Writer(or the read-back step that validates the write) won't accept — likely a degenerate/near-degenerate face from the frenet sweep along the tight helix, or a non-manifold seam where the swept rail meets the balusters. The in-memory volume/bounds checks don't catch this because they don't exercise STEP's stricter topology/geometry validation.Ask
I can attach the full
.brep.tsrepro on request (it lives in gitignored benchmark scratch). Surfaced by the brepjs-agent work (#1124).