Files
OneCAD/docs/step-import.md
bherbruckandClaude Opus 5.5 0a1b6f0fff STEP export: pieces of a plane or extruded cylinder written as one face
Fusion round trip WARNs on face counts:
- 48: the pulley's annular end faces arrived as 240° and 120° sectors.
- 54: the side faces and holes of a body glued to its mirror image came
  in halves.

Changes:
- Planes merge: PLANE faces and flat B-spline sheets, as well as revolved
  planes. A plane keeps several loops (an annulus, a face with holes), no
  seam. Flat B-spline sheets are written as PLANE.
- Pieces of an extruded cylinder (B-spline sheets) merge when their edges
  are circles square to the axis. The merged face is written as a
  CYLINDRICAL_SURFACE, with its parameter seam on the face's seam edge.
- A full turn's loop is built explicitly: ring, seam, other ring (or the
  apex on the axis), seam back. Before, it depended on edge order, and
  after 81c85b5 the pulley's last pieces no longer merged.
- The read-back check moved to the whole file. If the merged file reads
  with warnings and the unmerged one does not, the unmerged one is
  written.

Results: 48 has 12 faces (Fusion 12), 54 has 12 (Fusion 12). Oracle
results are unchanged (73 PASS) and the STEP corpus passes 76/76. New
test: a plate with a hole glued to its mirror exports 8 faces, all
planes and cylinders, and round-trips.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
2026-10-08 13:16:39 +00:00

95 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STEP import
SolveCraft reads STEP (ISO 10303-21; AP203, AP214 and AP242 geometry) with its own reader in `crates/kernel/src/step_in` (written from the public standards; no third-party STEP code). A STEP file becomes an **Import** base feature on the timeline: it holds the file's B-rep (the STEP text is kept in the design, so the design reopens without the file) and later features — fillets, holes, cuts sketched on its faces, shells — build on its bodies.
- **Open**: File → Open (`doc.open`) accepts `.step`/`.stp` in any case and starts a new design; `solvecraft part.step`; `solvecraft-cli eval part.step`, `solvecraft-cli run script.json --in part.step`; the MCP `open` tool.
- **Insert** into the current design: File → Insert STEP… or SOLID → INSERT (`FusionImportCommandFromToolbar {path}`).
- **Drag and drop** a STEP file on the window: inserted when the design has features, opened otherwise.
Read: manifold solid breps (with voids), faceted breps, shell-based surface models; planes, cylinders, cones, spheres, tori, B-spline and rational B-spline surfaces (with knots, Bézier, uniform, quasi-uniform), surfaces of revolution and linear extrusion, trimmed surfaces; lines, circles, ellipses, B-spline curves, polylines, trimmed/surface/seam curves; length and angle units (SI prefixes, conversion-based units such as inches); product names (body names come from the solid's name, else the product's); surface colours; assemblies (next-assembly-usage occurrences placed by item-defined transformations, and mapped items) — the product tree is kept in the feature for the components milestone. Files are untrusted: sizes, entity counts and nesting are capped and every kernel call is guarded. What cannot be read becomes a warning on the feature (a face left out gives an open body); not read yet: offset surfaces, pcurve-only edges.
## Fusion corpus
Generated by `cargo xtask step-corpus`. Each case is a part exported from Fusion as STEP (AP214; kept locally in `plan/fusion/oracle/`, never committed). SolveCraft opens `part.step` exactly as File → Open does (an Import base feature) and compares with Fusion's own measurements: body count, volume and area (relative tolerance 1e-3) and the number of faces read from the file.
**76 / 76 files pass.**
| Case | Result | Bodies | Volume mm³ (got / Fusion) | Area mm² (got / Fusion) | Faces (got / Fusion) | ms | Notes |
|---|---|---|---|---|---|---|---|
| 01-box | pass | Box | 24000.000 / 24000.000 | 5200.000 / 5200.000 | 6 / 6 | 3 | |
| 02-cylinder | pass | Cylinder | 35339.429 / 35342.917 | 6125.845 / 6126.106 | 3 / 3 | 87 | |
| 03-box-through-hole | pass | Box | 45738.283 / 45738.053 | 9327.809 / 9327.788 | 7 / 7 | 62 | |
| 04-revolve-vase | pass | Vase | 112488.847 / 112499.479 | 13156.093 / 13156.615 | 5 / 5 | 511 | |
| 05-taper-extrude | pass | Frustum | 61814.826 / 61814.826 | 9676.915 / 9676.915 | 6 / 6 | 2 | |
| 06-symmetric-extrude | pass | Block | 30000.000 / 30000.000 | 6200.000 / 6200.000 | 6 / 6 | 1 | |
| 07-fillet-all-edges | pass | Box | 23340.621 / 23340.849 | 4726.220 / 4726.265 | 26 / 26 | 532 | |
| 08-chamfer | pass | Box | 23730.667 / 23730.667 | 5029.352 / 5029.352 | 10 / 10 | 3 | |
| 09-shell | pass | Box | 13632.000 / 13632.000 | 13992.000 / 13992.000 | 11 / 11 | 2 | |
| 10-rect-pattern-holes | pass | Plate | 29803.713 / 29803.540 | 14652.481 / 14652.389 | 18 / 18 | 252 | |
| 11-circular-pattern-flange | pass | Flange | 66758.144 / 66758.844 | 19320.617 / 19320.795 | 10 / 10 | 168 | |
| 12-mirror-feature | pass | Base | 21392.575 / 21392.920 | 6530.944 / 6530.973 | 10 / 10 | 80 | |
| 13-combine-join | pass | A | 45570.295 / 45571.680 | 8634.196 / 8634.336 | 9 / 9 | 43 | |
| 14-combine-cut | pass | A | 42933.034 / 42931.417 | 9706.783 / 9706.858 | 7 / 7 | 402 | |
| 15-combine-intersect | pass | A | 54452.172 / 54454.273 | 7382.532 / 7382.743 | 7 / 7 | 1022 | |
| 16-sweep | pass | Tube | 2584.428 / 2584.724 | 1779.638 / 1779.698 | 5 / 5 | 612 | |
| 17-loft | pass | Loft | 35121.595 / 35125.498 | 6495.373 / 6495.000 | 6 / 6 | 191 | |
| 18-hole-features | pass | Plate | 33890.908 / 33890.710 | 8568.695 / 8568.696 | 13 / 13 | 184 | |
| 19-l-bracket-constrained | pass | LBracket | 14720.000 / 14720.000 | 5472.000 / 5472.000 | 8 / 8 | 2 | |
| 20-slot-constrained | pass | Slot | 2965.428 / 2965.487 | 1774.644 / 1774.690 | 6 / 6 | 15 | |
| 21-draft | pass | Box | 54574.737 / 54574.737 | 8781.998 / 8781.998 | 6 / 6 | 1 | |
| 22-split-body | pass | Cyl, Cyl (1) | 75390.813 / 75398.224 | 12954.440 / 12955.175 | 6 / 6 | 109 | |
| 23-bracket-multifeature | pass | Bracket | 59331.477 / 59331.129 | 18290.767 / 18290.737 | 19 / 19 | 117 | |
| 24-user-parameters | pass | Block | 34822.022 / 34821.903 | 8114.175 / 8114.159 | 7 / 7 | 58 | |
| 25-sketch-triangle | pass | Triangle | 4032.155 / 4032.155 | 2274.099 / 2274.099 | 5 / 5 | 1 | |
| 26-sketch-belt | pass | Belt | 11326.042 / 11326.170 | 5637.347 / 5637.404 | 7 / 7 | 42 | |
| 27-sketch-trapezoid | pass | Trapezoid | 5342.286 / 5342.257 | 3066.961 / 3066.946 | 8 / 8 | 53 | |
| 28-blind-pocket-fillets | pass | Block | 84299.345 / 84299.249 | 16279.560 / 16279.572 | 23 / 23 | 320 | |
| 29-two-sided-and-partial-revolve | pass | Block | 25731.356 / 25731.307 | 6312.589 / 6312.602 | 12 / 12 | 26 | |
| 30-fillet-after-shell | pass | Box | 21745.915 / 21745.876 | 14968.284 / 14968.332 | 27 / 27 | 464 | |
| 31-fillet-l-all-edges | pass | L | 14321.483 / 14321.626 | 5024.004 / 5024.045 | 38 / 38 | 747 | |
| 32-boss-plate-fillets | pass | Part | 33590.273 / 33590.350 | 9929.854 / 9929.864 | 10 / 10 | 1214 | |
| 33-fillet-tangent-chain | pass | Slot | 8237.037 / 8237.122 | 2793.541 / 2793.569 | 14 / 14 | 555 | |
| 34-chamfer-then-fillet | pass | Box | 22892.383 / 22892.421 | 4753.677 / 4753.688 | 18 / 18 | 54 | |
| 35-fillet-curved-curved | pass | Tee | 63169.685 / 63171.443 | 10269.168 / 10269.348 | 6 / 6 | 904 | |
| 36-corner-blend-two-radii | pass | Box | 57799.504 / 57800.240 | 8585.437 / 8585.524 | 18 / 18 | 519 | |
| 37-pyramid-apex-blend | pass | Pyramid | 15465.376 / 15465.575 | 3914.529 / 3914.581 | 18 / 18 | 312 | |
| 38-coincident-cylinders | pass | A | 15706.406 / 15707.963 | 3769.760 / 3769.911 | 3 / 3 | 67 | |
| 39-tee-pipe | pass | Tee | 24095.763 / 24096.237 | 16709.772 / 16710.048 | 7 / 7 | 182 | |
| 40-box-sphere-torus | pass | A | 36287.558 / 36287.433 | 10696.143 / 10696.165 | 10 / 10 | 2393 | |
| 41-tube-radial-holes | pass | Tube | 20243.046 / 20243.981 | 14873.689 / 14873.773 | 22 / 22 | 1409 | |
| 42-overlapping-patterns | pass | Plate | 38488.411 / 38487.064 | 21687.215 / 21686.603 | 43 / 43 | 533 | solid 'Plate': imported as an open body (the shell is not closed) |
| 43-cut-splits-body | pass | Bar, Bar (1) | 28000.000 / 28000.000 | 7200.000 / 7200.000 | 12 / 12 | 5 | |
| 44-shell-l-bracket | pass | L | 8384.000 / 8384.000 | 8784.000 / 8784.000 | 15 / 15 | 3 | |
| 45-shell-boss-plate | pass | Part | 13676.354 / 13676.602 | 14156.531 / 14156.602 | 15 / 15 | 69 | |
| 46-shell-two-open-faces | pass | Box | 16044.000 / 16044.000 | 11398.000 / 11398.000 | 10 / 10 | 3 | |
| 47-draft-curved-pocket | pass | Block | 111387.998 / 111387.712 | 17700.336 / 17700.361 | 11 / 11 | 27 | |
| 48-pulley | pass | Pulley | 168508.160 / 168510.841 | 23718.215 / 23718.644 | 12 / 12 | 321 | |
| 49-helical-sweep | pass | Spring | 4733.931 / 4738.099 | 4765.903 / 4767.652 | 3 / 3 | 10552 | solid 'Spring': face wrapping around a closed surface kept whole: split line does not reach the rings |
| 50-sweep-tight-bend | pass | Bend | 3758.025 / 3758.443 | – / – | 5 / 5 | 405 | |
| 51-loft-rect-circle-offset | pass | Loft | 61129.957 / 61133.116 | 9412.473 / 9411.655 | 6 / 6 | 251 | |
| 52-circular-pattern-fillet | pass | Hub | 47206.182 / 47206.850 | 14141.988 / 14142.171 | 21 / 21 | 820 | |
| 53-path-pattern | pass | Plate | 35010.499 / 35010.398 | 16463.947 / 16463.894 | 13 / 13 | 130 | |
| 54-mirror-body-fillets | pass | Bracket | 22780.113 / 22780.089 | 6972.831 / 6972.832 | 12 / 12 | 98 | |
| 55-tapped-hole-cosmetic | pass | Plate | 17542.360 / 17542.314 | 4761.590 / 4761.596 | 8 / 8 | 84 | |
| 56-holes-on-curved-face | pass | Cyl | 77941.171 / 77942.388 | 10592.951 / 10593.139 | 7 / 7 | 378 | |
| 57-hole-pattern-sketch-points | pass | Plate | 36767.029 / 36766.712 | 11818.165 / 11818.153 | 24 / 24 | 197 | |
| 58-phone-stand | pass | Stand | 74559.442 / 74559.177 | 29148.741 / 29148.785 | 19 / 19 | 24 | |
| 59-enclosure-base | pass | Enclosure | 34309.038 / 34309.486 | 33795.405 / 33795.610 | 39 / 39 | 286 | |
| 60-pipe-flange | pass | Flange | 323661.027 / 323660.979 | 56984.270 / 56984.564 | 16 / 16 | 993 | |
| 61-shaft-keyway | pass | Shaft | 47521.504 / 47525.946 | 9676.781 / 9677.096 | 14 / 14 | 182 | |
| 62-heat-sink | pass | HeatSink | 43125.000 / 43125.000 | 45725.000 / 45725.000 | 66 / 66 | 8 | |
| 63-hinge-knuckle | pass | Hinge | 4783.029 / 4783.117 | 4110.255 / 4110.287 | 14 / 14 | 118 | |
| 64-sketch-tangent-arc-chain | pass | Wave | 4800.000 / 4800.000 | 3843.701 / 3843.712 | 9 / 9 | 10 | |
| 65-sketch-gear-tooth | pass | Tooth | 3987.831 / 3988.084 | 1945.416 / 1945.485 | 9 / 9 | 8 | |
| 66-sketch-linkage | pass | Link | 8045.410 / 8045.386 | 4308.172 / 4308.175 | 10 / 10 | 129 | |
| 67-sm-base-flange | pass | Body1 | 15000.000 / 15000.000 | 12800.000 / 12800.000 | 6 / 6 | 2 | |
| 68-sm-edge-flange | pass | Body1 | 18972.476 / 18972.622 | 16057.518 / 16057.550 | 14 / 14 | 26 | |
| 69-sm-tray | pass | Body1 | 29665.828 / 29666.234 | 24979.993 / 24980.086 | 46 / 46 | 66 | |
| 70-sm-flange-45 | pass | Body1 | 18450.704 / 18450.777 | 15629.621 / 15629.637 | 14 / 14 | 14 | |
| 71-sm-custom-rule | pass | Body1 | 10053.579 / 10053.717 | 13896.249 / 13896.299 | 22 / 22 | 38 | |
| 72-sm-contour-flange | pass | Body1 | 12097.478 / 12097.622 | 10411.968 / 10412.002 | 22 / 22 | 36 | |
| 73-sm-hem | pass | Body1 | 21334.478 / 21334.723 | 17994.397 / 17994.473 | 22 / 22 | 60 | |
| 74-sm-unfold-refold | pass | Body1 | 15800.086 / 15800.304 | 13610.275 / 13610.326 | 32 / 32 | 84 | |
| 75-sm-bracket-holes | pass | Body1 | 13915.866 / 13916.012 | 12035.934 / 12035.962 | 25 / 25 | 100 | |
| 76-sm-thickness-variant | pass | Body1 | 22520.368 / 22520.575 | 16064.089 / 16064.128 | 14 / 14 | 31 | |