From e12758ff9173b1d9c9b7231fb2244ec93c451a12 Mon Sep 17 00:00:00 2001 From: bherbruck Date: Mon, 12 Oct 2026 10:43:43 -0400 Subject: [PATCH] Public reference tests: analytic and FreeCAD expected values (#310) The oracle no longer uses Fusion measurements. tests/oracle// now holds the 76 recipes (our own format, with recorded measurements and tool-specific fields removed) and an expected.json per case: - 55 analytic cases: closed-form values from tools/oracle-analytic/ (stdlib Python, formulas in each case's "method"). - 21 FreeCAD cases: the same recipe built with FreeCAD's public scripting API by tools/freecad-oracle/ (an external program, not a dependency), with a reference.stl for 20. solvecraft-cli oracle compares body count, volume, area, centre of mass, bbox, face counts where the geometry fixes them, and, against reference.stl, the sampled Hausdorff distance and the principal moments (spatial.rs from #301). cargo xtask oracle reads tests/oracle, writes docs/oracle.md with the source of each value, and supports known_failure marks for tracked bugs. CI runs it on every PR; a manual workflow regenerates the FreeCAD values. step-corpus, seam normalisation and the through-all emulation, which only existed to compare with Fusion, are removed. 75/76 pass; 75-sm-bracket-holes is a known failure (#296). Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT Co-authored-by: bherbruck Co-authored-by: Claude Opus 5.5 --- .github/workflows/ci.yml | 36 +- .github/workflows/freecad-oracle.yml | 47 + AGENTS.md | 12 +- ATTRIBUTION.md | 20 + CLAUDE.md | 12 +- CONTRIBUTING.md | 16 +- README.md | 5 +- ROADMAP.md | 6 +- apps/solvecraft-cli/src/main.rs | 7 +- apps/solvecraft-cli/src/oracle.rs | 320 ++-- apps/solvecraft-cli/src/recipe.rs | 14 +- apps/solvecraft-cli/src/seams.rs | 321 ---- apps/solvecraft-cli/src/spatial.rs | 333 ++++ docs/book/src/SUMMARY.md | 2 +- docs/book/src/dev/architecture.md | 2 +- docs/book/src/dev/testing.md | 3 +- docs/book/src/introduction.md | 2 +- docs/iges-import.md | 84 - docs/oracle.md | 185 +-- docs/robustness.md | 2 +- docs/step-import.md | 85 - tests/oracle/01-box/expected.json | 25 + tests/oracle/01-box/recipe.json | 153 ++ tests/oracle/02-cylinder/expected.json | 25 + tests/oracle/02-cylinder/recipe.json | 94 ++ .../oracle/03-box-through-hole/expected.json | 25 + tests/oracle/03-box-through-hole/recipe.json | 240 +++ tests/oracle/04-revolve-vase/expected.json | 25 + tests/oracle/04-revolve-vase/recipe.json | 201 +++ tests/oracle/05-taper-extrude/expected.json | 25 + tests/oracle/05-taper-extrude/recipe.json | 154 ++ .../oracle/06-symmetric-extrude/expected.json | 25 + tests/oracle/06-symmetric-extrude/recipe.json | 155 ++ .../oracle/07-fillet-all-edges/expected.json | 25 + tests/oracle/07-fillet-all-edges/recipe.json | 379 +++++ tests/oracle/08-chamfer/expected.json | 25 + tests/oracle/08-chamfer/recipe.json | 235 +++ tests/oracle/09-shell/expected.json | 25 + tests/oracle/09-shell/recipe.json | 181 +++ .../10-rect-pattern-holes/expected.json | 25 + .../oracle/10-rect-pattern-holes/recipe.json | 248 +++ .../11-circular-pattern-flange/expected.json | 25 + .../11-circular-pattern-flange/recipe.json | 204 +++ tests/oracle/12-mirror-feature/expected.json | 25 + tests/oracle/12-mirror-feature/recipe.json | 262 +++ tests/oracle/13-combine-join/expected.json | 25 + tests/oracle/13-combine-join/recipe.json | 231 +++ tests/oracle/14-combine-cut/expected.json | 25 + tests/oracle/14-combine-cut/recipe.json | 267 ++++ .../oracle/15-combine-intersect/expected.json | 25 + tests/oracle/15-combine-intersect/recipe.json | 269 ++++ tests/oracle/16-sweep/expected.json | 25 + tests/oracle/16-sweep/recipe.json | 182 +++ tests/oracle/17-loft/expected.json | 24 + tests/oracle/17-loft/recipe.json | 211 +++ tests/oracle/17-loft/reference.stl | Bin 0 -> 311084 bytes tests/oracle/18-hole-features/expected.json | 25 + tests/oracle/18-hole-features/recipe.json | 253 +++ .../19-l-bracket-constrained/expected.json | 25 + .../19-l-bracket-constrained/recipe.json | 275 ++++ .../oracle/20-slot-constrained/expected.json | 25 + tests/oracle/20-slot-constrained/recipe.json | 225 +++ tests/oracle/21-draft/expected.json | 25 + tests/oracle/21-draft/recipe.json | 253 +++ tests/oracle/22-split-body/expected.json | 25 + tests/oracle/22-split-body/recipe.json | 125 ++ .../23-bracket-multifeature/expected.json | 24 + .../23-bracket-multifeature/recipe.json | 693 ++++++++ .../23-bracket-multifeature/reference.stl | Bin 0 -> 88484 bytes tests/oracle/24-user-parameters/expected.json | 25 + tests/oracle/24-user-parameters/recipe.json | 275 ++++ tests/oracle/25-sketch-triangle/expected.json | 25 + tests/oracle/25-sketch-triangle/recipe.json | 184 +++ tests/oracle/26-sketch-belt/expected.json | 25 + tests/oracle/26-sketch-belt/recipe.json | 296 ++++ .../oracle/27-sketch-trapezoid/expected.json | 25 + tests/oracle/27-sketch-trapezoid/recipe.json | 318 ++++ .../28-blind-pocket-fillets/expected.json | 24 + .../28-blind-pocket-fillets/recipe.json | 577 +++++++ .../28-blind-pocket-fillets/reference.stl | Bin 0 -> 215884 bytes .../expected.json | 25 + .../recipe.json | 289 ++++ .../30-fillet-after-shell/expected.json | 24 + .../oracle/30-fillet-after-shell/recipe.json | 385 +++++ .../30-fillet-after-shell/reference.stl | Bin 0 -> 196684 bytes .../31-fillet-l-all-edges/expected.json | 24 + .../oracle/31-fillet-l-all-edges/recipe.json | 524 ++++++ .../31-fillet-l-all-edges/reference.stl | Bin 0 -> 382084 bytes .../32-boss-plate-fillets/expected.json | 25 + .../oracle/32-boss-plate-fillets/recipe.json | 316 ++++ .../33-fillet-tangent-chain/expected.json | 25 + .../33-fillet-tangent-chain/recipe.json | 212 +++ .../34-chamfer-then-fillet/expected.json | 24 + .../oracle/34-chamfer-then-fillet/recipe.json | 390 +++++ .../34-chamfer-then-fillet/reference.stl | Bin 0 -> 17084 bytes .../35-fillet-curved-curved/expected.json | 24 + .../35-fillet-curved-curved/recipe.json | 193 +++ .../35-fillet-curved-curved/reference.stl | Bin 0 -> 294284 bytes .../36-corner-blend-two-radii/expected.json | 24 + .../36-corner-blend-two-radii/recipe.json | 274 ++++ .../36-corner-blend-two-radii/reference.stl | Bin 0 -> 211884 bytes .../37-pyramid-apex-blend/expected.json | 24 + .../oracle/37-pyramid-apex-blend/recipe.json | 361 +++++ .../37-pyramid-apex-blend/reference.stl | Bin 0 -> 267784 bytes .../38-coincident-cylinders/expected.json | 25 + .../38-coincident-cylinders/recipe.json | 179 +++ tests/oracle/39-tee-pipe/expected.json | 24 + tests/oracle/39-tee-pipe/recipe.json | 302 ++++ tests/oracle/39-tee-pipe/reference.stl | Bin 0 -> 120384 bytes .../oracle/40-box-sphere-torus/expected.json | 26 + tests/oracle/40-box-sphere-torus/recipe.json | 354 +++++ .../oracle/41-tube-radial-holes/expected.json | 24 + tests/oracle/41-tube-radial-holes/recipe.json | 252 +++ .../oracle/41-tube-radial-holes/reference.stl | Bin 0 -> 339484 bytes .../42-overlapping-patterns/expected.json | 24 + .../42-overlapping-patterns/recipe.json | 339 ++++ .../42-overlapping-patterns/reference.stl | Bin 0 -> 393484 bytes tests/oracle/43-cut-splits-body/expected.json | 25 + tests/oracle/43-cut-splits-body/recipe.json | 282 ++++ tests/oracle/44-shell-l-bracket/expected.json | 25 + tests/oracle/44-shell-l-bracket/recipe.json | 217 +++ .../oracle/45-shell-boss-plate/expected.json | 25 + tests/oracle/45-shell-boss-plate/recipe.json | 268 ++++ .../46-shell-two-open-faces/expected.json | 25 + .../46-shell-two-open-faces/recipe.json | 199 +++ .../47-draft-curved-pocket/expected.json | 24 + .../oracle/47-draft-curved-pocket/recipe.json | 413 +++++ .../47-draft-curved-pocket/reference.stl | Bin 0 -> 87684 bytes tests/oracle/48-pulley/expected.json | 25 + tests/oracle/48-pulley/recipe.json | 304 ++++ tests/oracle/49-helical-sweep/expected.json | 25 + tests/oracle/49-helical-sweep/recipe.json | 317 ++++ .../oracle/50-sweep-tight-bend/expected.json | 25 + tests/oracle/50-sweep-tight-bend/recipe.json | 181 +++ .../51-loft-rect-circle-offset/expected.json | 24 + .../51-loft-rect-circle-offset/recipe.json | 211 +++ .../51-loft-rect-circle-offset/reference.stl | Bin 0 -> 310084 bytes .../52-circular-pattern-fillet/expected.json | 25 + .../52-circular-pattern-fillet/recipe.json | 244 +++ tests/oracle/53-path-pattern/expected.json | 25 + tests/oracle/53-path-pattern/recipe.json | 260 +++ .../54-mirror-body-fillets/expected.json | 25 + .../oracle/54-mirror-body-fillets/recipe.json | 289 ++++ .../55-tapped-hole-cosmetic/expected.json | 25 + .../55-tapped-hole-cosmetic/recipe.json | 219 +++ .../56-holes-on-curved-face/expected.json | 24 + .../56-holes-on-curved-face/recipe.json | 169 ++ .../56-holes-on-curved-face/reference.stl | Bin 0 -> 131484 bytes .../expected.json | 25 + .../57-hole-pattern-sketch-points/recipe.json | 267 ++++ tests/oracle/58-phone-stand/expected.json | 24 + tests/oracle/58-phone-stand/recipe.json | 466 ++++++ tests/oracle/58-phone-stand/reference.stl | Bin 0 -> 13884 bytes tests/oracle/59-enclosure-base/expected.json | 24 + tests/oracle/59-enclosure-base/recipe.json | 645 ++++++++ tests/oracle/59-enclosure-base/reference.stl | Bin 0 -> 164684 bytes tests/oracle/60-pipe-flange/expected.json | 25 + tests/oracle/60-pipe-flange/recipe.json | 367 +++++ tests/oracle/61-shaft-keyway/expected.json | 24 + tests/oracle/61-shaft-keyway/recipe.json | 439 ++++++ tests/oracle/61-shaft-keyway/reference.stl | Bin 0 -> 173684 bytes tests/oracle/62-heat-sink/expected.json | 26 + tests/oracle/62-heat-sink/recipe.json | 308 ++++ tests/oracle/63-hinge-knuckle/expected.json | 24 + tests/oracle/63-hinge-knuckle/recipe.json | 420 +++++ tests/oracle/63-hinge-knuckle/reference.stl | Bin 0 -> 60284 bytes .../64-sketch-tangent-arc-chain/expected.json | 25 + .../64-sketch-tangent-arc-chain/recipe.json | 357 +++++ .../oracle/65-sketch-gear-tooth/expected.json | 24 + tests/oracle/65-sketch-gear-tooth/recipe.json | 374 +++++ .../oracle/65-sketch-gear-tooth/reference.stl | Bin 0 -> 12684 bytes tests/oracle/66-sketch-linkage/expected.json | 25 + tests/oracle/66-sketch-linkage/recipe.json | 374 +++++ tests/oracle/67-sm-base-flange/expected.json | 25 + tests/oracle/67-sm-base-flange/recipe.json | 148 ++ tests/oracle/68-sm-edge-flange/expected.json | 25 + tests/oracle/68-sm-edge-flange/recipe.json | 179 +++ tests/oracle/69-sm-tray/expected.json | 26 + tests/oracle/69-sm-tray/recipe.json | 233 +++ tests/oracle/70-sm-flange-45/expected.json | 25 + tests/oracle/70-sm-flange-45/recipe.json | 178 +++ tests/oracle/71-sm-custom-rule/expected.json | 25 + tests/oracle/71-sm-custom-rule/recipe.json | 207 +++ .../oracle/72-sm-contour-flange/expected.json | 25 + tests/oracle/72-sm-contour-flange/recipe.json | 123 ++ tests/oracle/73-sm-hem/expected.json | 25 + tests/oracle/73-sm-hem/recipe.json | 204 +++ .../oracle/74-sm-unfold-refold/expected.json | 25 + tests/oracle/74-sm-unfold-refold/recipe.json | 350 ++++ .../oracle/75-sm-bracket-holes/expected.json | 26 + tests/oracle/75-sm-bracket-holes/recipe.json | 300 ++++ .../76-sm-thickness-variant/expected.json | 25 + .../76-sm-thickness-variant/recipe.json | 187 +++ tests/oracle/README.md | 42 + tools/freecad-oracle/.gitignore | 3 + tools/freecad-oracle/README.md | 57 + tools/freecad-oracle/build.py | 1402 +++++++++++++++++ tools/freecad-oracle/emit.py | 66 + tools/freecad-oracle/run.sh | 49 + tools/oracle-analytic/README.md | 19 + tools/oracle-analytic/cases_basic.py | 560 +++++++ tools/oracle-analytic/cases_features.py | 546 +++++++ tools/oracle-analytic/cases_sheet_metal.py | 452 ++++++ xtask/src/main.rs | 235 ++- 204 files changed, 27106 insertions(+), 932 deletions(-) create mode 100644 .github/workflows/freecad-oracle.yml delete mode 100644 apps/solvecraft-cli/src/seams.rs create mode 100644 apps/solvecraft-cli/src/spatial.rs delete mode 100644 docs/iges-import.md create mode 100644 tests/oracle/01-box/expected.json create mode 100644 tests/oracle/01-box/recipe.json create mode 100644 tests/oracle/02-cylinder/expected.json create mode 100644 tests/oracle/02-cylinder/recipe.json create mode 100644 tests/oracle/03-box-through-hole/expected.json create mode 100644 tests/oracle/03-box-through-hole/recipe.json create mode 100644 tests/oracle/04-revolve-vase/expected.json create mode 100644 tests/oracle/04-revolve-vase/recipe.json create mode 100644 tests/oracle/05-taper-extrude/expected.json create mode 100644 tests/oracle/05-taper-extrude/recipe.json create mode 100644 tests/oracle/06-symmetric-extrude/expected.json create mode 100644 tests/oracle/06-symmetric-extrude/recipe.json create mode 100644 tests/oracle/07-fillet-all-edges/expected.json create mode 100644 tests/oracle/07-fillet-all-edges/recipe.json create mode 100644 tests/oracle/08-chamfer/expected.json create mode 100644 tests/oracle/08-chamfer/recipe.json create mode 100644 tests/oracle/09-shell/expected.json create mode 100644 tests/oracle/09-shell/recipe.json create mode 100644 tests/oracle/10-rect-pattern-holes/expected.json create mode 100644 tests/oracle/10-rect-pattern-holes/recipe.json create mode 100644 tests/oracle/11-circular-pattern-flange/expected.json create mode 100644 tests/oracle/11-circular-pattern-flange/recipe.json create mode 100644 tests/oracle/12-mirror-feature/expected.json create mode 100644 tests/oracle/12-mirror-feature/recipe.json create mode 100644 tests/oracle/13-combine-join/expected.json create mode 100644 tests/oracle/13-combine-join/recipe.json create mode 100644 tests/oracle/14-combine-cut/expected.json create mode 100644 tests/oracle/14-combine-cut/recipe.json create mode 100644 tests/oracle/15-combine-intersect/expected.json create mode 100644 tests/oracle/15-combine-intersect/recipe.json create mode 100644 tests/oracle/16-sweep/expected.json create mode 100644 tests/oracle/16-sweep/recipe.json create mode 100644 tests/oracle/17-loft/expected.json create mode 100644 tests/oracle/17-loft/recipe.json create mode 100644 tests/oracle/17-loft/reference.stl create mode 100644 tests/oracle/18-hole-features/expected.json create mode 100644 tests/oracle/18-hole-features/recipe.json create mode 100644 tests/oracle/19-l-bracket-constrained/expected.json create mode 100644 tests/oracle/19-l-bracket-constrained/recipe.json create mode 100644 tests/oracle/20-slot-constrained/expected.json create mode 100644 tests/oracle/20-slot-constrained/recipe.json create mode 100644 tests/oracle/21-draft/expected.json create mode 100644 tests/oracle/21-draft/recipe.json create mode 100644 tests/oracle/22-split-body/expected.json create mode 100644 tests/oracle/22-split-body/recipe.json create mode 100644 tests/oracle/23-bracket-multifeature/expected.json create mode 100644 tests/oracle/23-bracket-multifeature/recipe.json create mode 100644 tests/oracle/23-bracket-multifeature/reference.stl create mode 100644 tests/oracle/24-user-parameters/expected.json create mode 100644 tests/oracle/24-user-parameters/recipe.json create mode 100644 tests/oracle/25-sketch-triangle/expected.json create mode 100644 tests/oracle/25-sketch-triangle/recipe.json create mode 100644 tests/oracle/26-sketch-belt/expected.json create mode 100644 tests/oracle/26-sketch-belt/recipe.json create mode 100644 tests/oracle/27-sketch-trapezoid/expected.json create mode 100644 tests/oracle/27-sketch-trapezoid/recipe.json create mode 100644 tests/oracle/28-blind-pocket-fillets/expected.json create mode 100644 tests/oracle/28-blind-pocket-fillets/recipe.json create mode 100644 tests/oracle/28-blind-pocket-fillets/reference.stl create mode 100644 tests/oracle/29-two-sided-and-partial-revolve/expected.json create mode 100644 tests/oracle/29-two-sided-and-partial-revolve/recipe.json create mode 100644 tests/oracle/30-fillet-after-shell/expected.json create mode 100644 tests/oracle/30-fillet-after-shell/recipe.json create mode 100644 tests/oracle/30-fillet-after-shell/reference.stl create mode 100644 tests/oracle/31-fillet-l-all-edges/expected.json create mode 100644 tests/oracle/31-fillet-l-all-edges/recipe.json create mode 100644 tests/oracle/31-fillet-l-all-edges/reference.stl create mode 100644 tests/oracle/32-boss-plate-fillets/expected.json create mode 100644 tests/oracle/32-boss-plate-fillets/recipe.json create mode 100644 tests/oracle/33-fillet-tangent-chain/expected.json create mode 100644 tests/oracle/33-fillet-tangent-chain/recipe.json create mode 100644 tests/oracle/34-chamfer-then-fillet/expected.json create mode 100644 tests/oracle/34-chamfer-then-fillet/recipe.json create mode 100644 tests/oracle/34-chamfer-then-fillet/reference.stl create mode 100644 tests/oracle/35-fillet-curved-curved/expected.json create mode 100644 tests/oracle/35-fillet-curved-curved/recipe.json create mode 100644 tests/oracle/35-fillet-curved-curved/reference.stl create mode 100644 tests/oracle/36-corner-blend-two-radii/expected.json create mode 100644 tests/oracle/36-corner-blend-two-radii/recipe.json create mode 100644 tests/oracle/36-corner-blend-two-radii/reference.stl create mode 100644 tests/oracle/37-pyramid-apex-blend/expected.json create mode 100644 tests/oracle/37-pyramid-apex-blend/recipe.json create mode 100644 tests/oracle/37-pyramid-apex-blend/reference.stl create mode 100644 tests/oracle/38-coincident-cylinders/expected.json create mode 100644 tests/oracle/38-coincident-cylinders/recipe.json create mode 100644 tests/oracle/39-tee-pipe/expected.json create mode 100644 tests/oracle/39-tee-pipe/recipe.json create mode 100644 tests/oracle/39-tee-pipe/reference.stl create mode 100644 tests/oracle/40-box-sphere-torus/expected.json create mode 100644 tests/oracle/40-box-sphere-torus/recipe.json create mode 100644 tests/oracle/41-tube-radial-holes/expected.json create mode 100644 tests/oracle/41-tube-radial-holes/recipe.json create mode 100644 tests/oracle/41-tube-radial-holes/reference.stl create mode 100644 tests/oracle/42-overlapping-patterns/expected.json create mode 100644 tests/oracle/42-overlapping-patterns/recipe.json create mode 100644 tests/oracle/42-overlapping-patterns/reference.stl create mode 100644 tests/oracle/43-cut-splits-body/expected.json create mode 100644 tests/oracle/43-cut-splits-body/recipe.json create mode 100644 tests/oracle/44-shell-l-bracket/expected.json create mode 100644 tests/oracle/44-shell-l-bracket/recipe.json create mode 100644 tests/oracle/45-shell-boss-plate/expected.json create mode 100644 tests/oracle/45-shell-boss-plate/recipe.json create mode 100644 tests/oracle/46-shell-two-open-faces/expected.json create mode 100644 tests/oracle/46-shell-two-open-faces/recipe.json create mode 100644 tests/oracle/47-draft-curved-pocket/expected.json create mode 100644 tests/oracle/47-draft-curved-pocket/recipe.json create mode 100644 tests/oracle/47-draft-curved-pocket/reference.stl create mode 100644 tests/oracle/48-pulley/expected.json create mode 100644 tests/oracle/48-pulley/recipe.json create mode 100644 tests/oracle/49-helical-sweep/expected.json create mode 100644 tests/oracle/49-helical-sweep/recipe.json create mode 100644 tests/oracle/50-sweep-tight-bend/expected.json create mode 100644 tests/oracle/50-sweep-tight-bend/recipe.json create mode 100644 tests/oracle/51-loft-rect-circle-offset/expected.json create mode 100644 tests/oracle/51-loft-rect-circle-offset/recipe.json create mode 100644 tests/oracle/51-loft-rect-circle-offset/reference.stl create mode 100644 tests/oracle/52-circular-pattern-fillet/expected.json create mode 100644 tests/oracle/52-circular-pattern-fillet/recipe.json create mode 100644 tests/oracle/53-path-pattern/expected.json create mode 100644 tests/oracle/53-path-pattern/recipe.json create mode 100644 tests/oracle/54-mirror-body-fillets/expected.json create mode 100644 tests/oracle/54-mirror-body-fillets/recipe.json create mode 100644 tests/oracle/55-tapped-hole-cosmetic/expected.json create mode 100644 tests/oracle/55-tapped-hole-cosmetic/recipe.json create mode 100644 tests/oracle/56-holes-on-curved-face/expected.json create mode 100644 tests/oracle/56-holes-on-curved-face/recipe.json create mode 100644 tests/oracle/56-holes-on-curved-face/reference.stl create mode 100644 tests/oracle/57-hole-pattern-sketch-points/expected.json create mode 100644 tests/oracle/57-hole-pattern-sketch-points/recipe.json create mode 100644 tests/oracle/58-phone-stand/expected.json create mode 100644 tests/oracle/58-phone-stand/recipe.json create mode 100644 tests/oracle/58-phone-stand/reference.stl create mode 100644 tests/oracle/59-enclosure-base/expected.json create mode 100644 tests/oracle/59-enclosure-base/recipe.json create mode 100644 tests/oracle/59-enclosure-base/reference.stl create mode 100644 tests/oracle/60-pipe-flange/expected.json create mode 100644 tests/oracle/60-pipe-flange/recipe.json create mode 100644 tests/oracle/61-shaft-keyway/expected.json create mode 100644 tests/oracle/61-shaft-keyway/recipe.json create mode 100644 tests/oracle/61-shaft-keyway/reference.stl create mode 100644 tests/oracle/62-heat-sink/expected.json create mode 100644 tests/oracle/62-heat-sink/recipe.json create mode 100644 tests/oracle/63-hinge-knuckle/expected.json create mode 100644 tests/oracle/63-hinge-knuckle/recipe.json create mode 100644 tests/oracle/63-hinge-knuckle/reference.stl create mode 100644 tests/oracle/64-sketch-tangent-arc-chain/expected.json create mode 100644 tests/oracle/64-sketch-tangent-arc-chain/recipe.json create mode 100644 tests/oracle/65-sketch-gear-tooth/expected.json create mode 100644 tests/oracle/65-sketch-gear-tooth/recipe.json create mode 100644 tests/oracle/65-sketch-gear-tooth/reference.stl create mode 100644 tests/oracle/66-sketch-linkage/expected.json create mode 100644 tests/oracle/66-sketch-linkage/recipe.json create mode 100644 tests/oracle/67-sm-base-flange/expected.json create mode 100644 tests/oracle/67-sm-base-flange/recipe.json create mode 100644 tests/oracle/68-sm-edge-flange/expected.json create mode 100644 tests/oracle/68-sm-edge-flange/recipe.json create mode 100644 tests/oracle/69-sm-tray/expected.json create mode 100644 tests/oracle/69-sm-tray/recipe.json create mode 100644 tests/oracle/70-sm-flange-45/expected.json create mode 100644 tests/oracle/70-sm-flange-45/recipe.json create mode 100644 tests/oracle/71-sm-custom-rule/expected.json create mode 100644 tests/oracle/71-sm-custom-rule/recipe.json create mode 100644 tests/oracle/72-sm-contour-flange/expected.json create mode 100644 tests/oracle/72-sm-contour-flange/recipe.json create mode 100644 tests/oracle/73-sm-hem/expected.json create mode 100644 tests/oracle/73-sm-hem/recipe.json create mode 100644 tests/oracle/74-sm-unfold-refold/expected.json create mode 100644 tests/oracle/74-sm-unfold-refold/recipe.json create mode 100644 tests/oracle/75-sm-bracket-holes/expected.json create mode 100644 tests/oracle/75-sm-bracket-holes/recipe.json create mode 100644 tests/oracle/76-sm-thickness-variant/expected.json create mode 100644 tests/oracle/76-sm-thickness-variant/recipe.json create mode 100644 tests/oracle/README.md create mode 100644 tools/freecad-oracle/.gitignore create mode 100644 tools/freecad-oracle/README.md create mode 100644 tools/freecad-oracle/build.py create mode 100644 tools/freecad-oracle/emit.py create mode 100755 tools/freecad-oracle/run.sh create mode 100644 tools/oracle-analytic/README.md create mode 100644 tools/oracle-analytic/cases_basic.py create mode 100644 tools/oracle-analytic/cases_features.py create mode 100644 tools/oracle-analytic/cases_sheet_metal.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0fc901d..10e90df8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,9 +122,41 @@ jobs: if: always() run: sccache --show-stats + oracle: + name: Reference tests + needs: changes + if: needs.changes.outputs.native == 'true' + runs-on: ubuntu-24.04 + timeout-minutes: 60 + env: + CARGO_INCREMENTAL: "0" + RUSTC_WRAPPER: sccache + SCCACHE_GHA_ENABLED: "true" + SCCACHE_IGNORE_SERVER_IO_ERROR: "1" + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + key: oracle + - name: Set up compiler cache + uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 + with: + version: v0.16.0 + - name: Build the command line + run: cargo build -p solvecraft-cli --profile ci --locked + - name: Replay tests/oracle and compare with expected.json + run: cargo xtask oracle --cli target/ci/solvecraft-cli + - name: Upload the report + if: always() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: oracle-report + path: docs/oracle.md + # Preserve the existing check name for branch protection, including docs-only PRs. ci: - needs: [changes, checks, clippy, tests] + needs: [changes, checks, clippy, tests, oracle] if: always() runs-on: ubuntu-24.04 steps: @@ -135,12 +167,14 @@ jobs: NATIVE: ${{ needs.changes.outputs.native }} CLIPPY: ${{ needs.clippy.result }} TESTS: ${{ needs.tests.result }} + ORACLE: ${{ needs.oracle.result }} run: | test "$CHANGES" = success test "$CHECKS" = success if [ "$NATIVE" = true ]; then test "$CLIPPY" = success test "$TESTS" = success + test "$ORACLE" = success fi wasm: diff --git a/.github/workflows/freecad-oracle.yml b/.github/workflows/freecad-oracle.yml new file mode 100644 index 00000000..3e74f15e --- /dev/null +++ b/.github/workflows/freecad-oracle.yml @@ -0,0 +1,47 @@ +# Optional, run by hand: rebuild the reference cases whose expected values come from FreeCAD +# (tools/freecad-oracle/) and show what changed. FreeCAD runs as a separate program on the runner; +# it is not a dependency of SolidCraft. Nothing is committed: review the diff and the uploaded +# files, then commit them in a pull request if the change is intended. +name: FreeCAD reference values + +on: + workflow_dispatch: + inputs: + cases: + description: "Case directories (space separated); empty = every case whose source is FreeCAD" + type: string + default: "" + +permissions: + contents: read + +jobs: + regenerate: + name: Regenerate FreeCAD expected values + runs-on: ubuntu-24.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Install FreeCAD + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends freecad + freecadcmd --version || true + - name: Rebuild the cases + env: + CASES: ${{ inputs.cases }} + run: | + if [ -z "$CASES" ]; then + CASES=$(grep -l '"source": *"freecad' tests/oracle/*/expected.json | xargs -n1 dirname | tr '\n' ' ') + fi + # shellcheck disable=SC2086 + tools/freecad-oracle/run.sh --write $CASES + - name: Show the changes + run: git diff --stat && git diff -- tests/oracle/*/expected.json + - name: Upload the regenerated files + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: freecad-expected + path: | + tests/oracle/*/expected.json + tests/oracle/*/reference.stl diff --git a/AGENTS.md b/AGENTS.md index 9cd197be..a7f9951c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,8 +17,7 @@ compatibility notes. ## Start every session here 1. Read `plan/STATUS.md` (current milestone, next task), then the task in `plan/execution-plan.md` and the relevant `plan/architecture.md` section. Behaviour reference: `plan/fusion/` - (`menu-tree.json` is Fusion's toolbar dump; `oracle/*/` are parts built in Fusion with their - recipes and measurements). + (`menu-tree.json` is Fusion's toolbar dump). 2. Kernel and library decisions: `plan/adr/0001-geometry-kernel.md` (what we may depend on, what is rejected for licence reasons). 3. Follow the autonomous operation protocol (`plan/execution-plan.md` §6). Don't stop to ask @@ -49,7 +48,9 @@ People trust SolidCraft with their designs; a crash loses their work. **This out Fusion. Command ids and command names are used as identifiers only (`xtask/data/fusion-catalog.tsv` holds ids and names, nothing else). File formats come from public specifications. **Never read, copy or link GPL/LGPL/AGPL code**: OpenCASCADE, FreeCAD (incl. planegcs), SolveSpace, - CadQuery/OCP, LibreCAD, QCAD — don't even read their sources. The sketch solver and the blend + CadQuery/OCP, LibreCAD, QCAD — don't even read their sources. (`tools/freecad-oracle/` runs + FreeCAD as a separate program through its public scripting API to compute reference values; + nothing from FreeCAD is linked, vendored or shipped.) The sketch solver and the blend operations are our own. - **Assets — absolutely essential.** SolidCraft contains **no Autodesk iconography, images, fonts or artwork — ever.** Every icon is drawn in code (`crates/ui-egui/src/icons.rs`). Any @@ -123,8 +124,9 @@ before the draft is verified. `ui.render` or `solvecraft-cli snapshot`. - Headless: `solvecraft-cli run script.json --out part.step`, `solvecraft-cli eval design.solvecraft`, `solvecraft-cli snapshot script.json --out shot.png`, `solvecraft-cli commands`. -- Fusion oracle: `cargo xtask oracle` replays `plan/fusion/oracle/*/recipe.json` and compares - with Fusion's `measure.json` (writes `docs/oracle.md`). +- Reference tests: `cargo xtask oracle` replays `tests/oracle/*/recipe.json` and compares with + each case's `expected.json` (analytic or FreeCAD values; writes `docs/oracle.md`). Expected + values never come from Fusion or any other commercial CAD product. - Build with `CARGO_TARGET_DIR=/target`. Windows: `cargo xwin build --release --target x86_64-pc-windows-msvc -p solvecraft`. ## Roadmap diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 2a33880b..f4ae45e2 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -27,6 +27,26 @@ Generated-in-code assets are original and have no file to list: | docs/book/src/generated/sheet-metal.png | SolveCraft contributors | rendered by `cargo xtask book` (`solvecraft-cli snapshot docs/book/scripts/sheet-metal.json`; gitignored) | MIT OR Apache-2.0 | | crates/sketch/fonts/LiberationSans-Regular.ttf | Red Hat, Inc. (Liberation Fonts 2.x; digitized data Google) | https://github.com/liberationfonts (Debian fonts-liberation), unmodified; licence text in crates/sketch/fonts/OFL.txt; used for sketch Text outlines | SIL OFL 1.1 | | apps/solvecraft-web/fonts/BIZUDPGothic-Regular.ttf | The BIZ UDGothic Project Authors | https://github.com/googlefonts/morisawa-biz-ud-gothic (Google Fonts), unmodified; licence text in apps/solvecraft-web/fonts/OFL.txt; used for web UI Japanese font | SIL OFL 1.1 | +| tests/oracle/17-loft/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/17-loft/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/23-bracket-multifeature/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/23-bracket-multifeature/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/28-blind-pocket-fillets/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/28-blind-pocket-fillets/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/30-fillet-after-shell/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/30-fillet-after-shell/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/31-fillet-l-all-edges/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/31-fillet-l-all-edges/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/34-chamfer-then-fillet/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/34-chamfer-then-fillet/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/35-fillet-curved-curved/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/35-fillet-curved-curved/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/36-corner-blend-two-radii/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/36-corner-blend-two-radii/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/37-pyramid-apex-blend/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/37-pyramid-apex-blend/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/39-tee-pipe/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/39-tee-pipe/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/41-tube-radial-holes/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/41-tube-radial-holes/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/42-overlapping-patterns/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/42-overlapping-patterns/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/47-draft-curved-pocket/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/47-draft-curved-pocket/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/51-loft-rect-circle-offset/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/51-loft-rect-circle-offset/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/56-holes-on-curved-face/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/56-holes-on-curved-face/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/58-phone-stand/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/58-phone-stand/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/59-enclosure-base/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/59-enclosure-base/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/61-shaft-keyway/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/61-shaft-keyway/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/63-hinge-knuckle/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/63-hinge-knuckle/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | +| tests/oracle/65-sketch-gear-tooth/reference.stl | SolidCraft contributors | triangulation of our own recipe (tests/oracle/65-sketch-gear-tooth/recipe.json) built with FreeCAD as an external tool by tools/freecad-oracle | MIT OR Apache-2.0 | ## Code adapted from sibling projects diff --git a/CLAUDE.md b/CLAUDE.md index 4d5dce6c..102d885e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,8 +17,7 @@ compatibility notes. ## Start every session here 1. Read `plan/STATUS.md` (current milestone, next task), then the task in `plan/execution-plan.md` and the relevant `plan/architecture.md` section. Behaviour reference: `plan/fusion/` - (`menu-tree.json` is Fusion's toolbar dump; `oracle/*/` are parts built in Fusion with their - recipes and measurements). + (`menu-tree.json` is Fusion's toolbar dump). 2. Kernel and library decisions: `plan/adr/0001-geometry-kernel.md` (what we may depend on, what is rejected for licence reasons). 3. Follow the autonomous operation protocol (`plan/execution-plan.md` §6). Don't stop to ask @@ -49,7 +48,9 @@ People trust SolidCraft with their designs; a crash loses their work. **This out Fusion. Command ids and command names are used as identifiers only (`xtask/data/fusion-catalog.tsv` holds ids and names, nothing else). File formats come from public specifications. **Never read, copy or link GPL/LGPL/AGPL code**: OpenCASCADE, FreeCAD (incl. planegcs), SolveSpace, - CadQuery/OCP, LibreCAD, QCAD — don't even read their sources. The sketch solver and the blend + CadQuery/OCP, LibreCAD, QCAD — don't even read their sources. (`tools/freecad-oracle/` runs + FreeCAD as a separate program through its public scripting API to compute reference values; + nothing from FreeCAD is linked, vendored or shipped.) The sketch solver and the blend operations are our own. - **Assets — absolutely essential.** SolidCraft contains **no Autodesk iconography, images, fonts or artwork — ever.** Every icon is drawn in code (`crates/ui-egui/src/icons.rs`). Any @@ -100,8 +101,9 @@ before the draft is verified. `ui.render` or `solvecraft-cli snapshot`. - Headless: `solvecraft-cli run script.json --out part.step`, `solvecraft-cli eval design.solvecraft`, `solvecraft-cli snapshot script.json --out shot.png`, `solvecraft-cli commands`. -- Fusion oracle: `cargo xtask oracle` replays `plan/fusion/oracle/*/recipe.json` and compares - with Fusion's `measure.json` (writes `docs/oracle.md`). +- Reference tests: `cargo xtask oracle` replays `tests/oracle/*/recipe.json` and compares with + each case's `expected.json` (analytic or FreeCAD values; writes `docs/oracle.md`). Expected + values never come from Fusion or any other commercial CAD product. - Build with `CARGO_TARGET_DIR=/target`. Windows: `cargo xwin build --release --target x86_64-pc-windows-msvc -p solvecraft`. ## Roadmap diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8c87dcb..72595b8b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,7 +119,7 @@ the most complete description of the house style. |---|---|---| | Unit and engine tests | next to the code, or `*_tests.rs` files | `cargo xtask test` (or `cargo test --workspace --profile ci`) | | UI scenarios | `crates/ui-egui/tests/scenarios/*.json` | part of `cargo test` | -| Fusion oracle | `cargo xtask oracle` | needs the local oracle data (see below) | +| Reference tests | `cargo xtask oracle` | `tests/oracle/` (see below) | **UI scenarios** drive the real app headless: start a tool, click a plane or a sketch point, press keys, then assert on the result. @@ -150,11 +150,15 @@ in the PR. `cargo xtask test` builds the tests with it and then runs every test `cargo xtask test -- shell`. Tests run beside each other on a busy machine, so a test must not depend on wall-clock timing. -**The Fusion oracle** is a set of 76 reference parts, each built in Fusion from a recipe. -SolidCraft rebuilds the same recipe and compares volume, area and topology counts with Fusion's -measurements; [docs/oracle.md](docs/oracle.md) has the current results. The recipes and -measurements live outside the repo (`plan/`, gitignored), because they come from a Fusion -install. If you work on geometry and want to check against it, ask in an issue. +**The reference tests** are 76 parts in [`tests/oracle/`](tests/oracle/), each a `recipe.json` +in our own format with an `expected.json` beside it. SolidCraft rebuilds the recipe and compares +body count, volume, area, centre of mass and bounding box (and, where there is a `reference.stl`, +the surface itself). Expected values are either worked out in closed form +(`tools/oracle-analytic/`) or computed by building the same recipe in FreeCAD, run as a separate +program (`tools/freecad-oracle/`); each file says which. [docs/oracle.md](docs/oracle.md) has +the current results, and CI runs `cargo xtask oracle` on every pull request. A case that fails +because of a known bug names its issue in `expected.json` (`"known_failure": "#123"`); never +change an expected value to match SolidCraft's output. ## Sending a change diff --git a/README.md b/README.md index 0ea28d8f..cb585e3f 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,9 @@ developer guide and command reference; sources in [docs/book](docs/book)), and t Linux Flatpak installation needs the Freedesktop runtime from Flathub as well as the SolidCraft application feed. See [install and launch commands](https://bherbruck.github.io/solidcraft/guide/getting-started.html#linux-flatpak). -**Status: early but usable for simple parts.** The historical benchmark report records -76 of 76 reference parts matching volume, area and topology ([docs/oracle.md](docs/oracle.md)). +**Status: early but usable for simple parts.** 75 of 76 public reference parts +match their analytic or FreeCAD-computed volume, area, centre of mass and bounding box +([docs/oracle.md](docs/oracle.md)); the other is a tracked bug. These checks do not establish complete geometric or workflow equivalence. Feature coverage is tracked in [docs/parity.md](docs/parity.md) and [ROADMAP.md](ROADMAP.md). Open work and known bugs are in [GitHub issues](https://github.com/bherbruck/solidcraft/issues), diff --git a/ROADMAP.md b/ROADMAP.md index 596a0127..79231e73 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -9,7 +9,7 @@ features → parametric timeline) as an open, pure-Rust, agent-drivable applicat |---|---| | Where are we? | **M0 and M13 done; M1, M2, M5–M7, M9, M10, M14 in progress.** Sketch with solver and the full SKETCH create/modify set; extrude, revolve (two sides, symmetric, to object), fillet/chamfer (variable radius, chord length, a radius per edge, corner patches), holes, threads (cosmetic and modelled), patterns, mirror, shell (inside/outside/both), draft, loft, sweep, coil, split body and split face, delete face, construction planes, axes and points; persistent naming of faces and edges; parameters and configurations; components, joints, motion studies, exploded views; sheet metal and a plastic enclosure subset; STEP/IGES/3MF/STL/OBJ/DXF; autosave and crash recovery; desktop and browser (wasm) app, CLI, MCP server, oracle harness. | | Command parity (in scope) | **335 / 541 (62%)** in-scope commands; SOLID + SKETCH **188 / 291 (65%)** — [docs/parity.md](docs/parity.md); registry breadth does not establish workflow or geometric parity | -| Fusion oracle | **76 / 76 parts match** in the checked-in historical report — [docs/oracle.md](docs/oracle.md). The current sprint adds independent analytic and UI regressions; the local Fusion oracle corpus has not been rerun. | +| Reference tests | **75 / 76 parts match** — [docs/oracle.md](docs/oracle.md): public cases in `tests/oracle/` with analytic (55) or FreeCAD-computed (21) expected values, run by CI on every PR; 75-sm-bracket-holes fails (#296). | | Tests | Solver, profiles, kernel booleans/blends/measures, expressions, timeline, persistent naming, file formats and migrations, assemblies, sheet metal, engine end-to-end, hostile-input fuzz over every command and headless UI scenarios. `cargo xtask ci` reports the current passing counts. | | Gates | `cargo xtask ci`: fmt, clippy -D warnings, tests, asset attribution, layering, wasm32 build — green | | Time to a useful alpha (M0–M6) | ≈ **82 agent hours** remain (sum of the M1–M6 estimates below) | @@ -50,6 +50,7 @@ headline counts in-scope tabs only and lists the deferred ones separately. | M2 | Robust modelling: coplanar booleans in the kernel, holes (placed on faces and on sketch points), threads (cosmetic, then modelled), patterns, mirror, shell, draft, split, construction geometry | in progress | 16 | | M3 | General fillets and chamfers (curved edges, chains, vertex blends); saddle rolling-ball surfaces now use continuous seam sections and arc-length fitting with shared contact boundaries and bounded accuracy checks | in progress | 30 | | M4 | Files: STEP import (done: all 29 Fusion STEP files — [docs/step-import.md](docs/step-import.md)), 3MF export and 3MF/STL import as mesh bodies (done), constant-section parametric mesh reconstruction, DXF sketches, OBJ import | in progress | 6 | +| M4 | Files: STEP import (done — [docs/step-import.md](docs/step-import.md)), 3MF export and 3MF/STL import as mesh bodies (done), DXF sketches, OBJ import | in progress | 6 | | M5 | Persistent naming of faces and edges (plan/adr/0002): faces named from their history (sketch curve sides, caps, revolve sections, primitive sides, blends, pattern/mirror copies; split pieces numbered), edges by their faces; fillets/chamfers, sketches on faces, shell/draft/offset/replace faces, hole placements, joint origins and face appearances resolve by name first and warn when the entity split or vanished: done. sheet metal edges by base sketch line and flange side, shell inner faces, sweep and loft roles: done. Left: kernel-reported face history (exact through coincident surfaces) | in progress | 20 | | M6 | UI depth: selection feedback and origin (done), timeline editing (done: hover and selection highlight modifier faces, including fillets and chamfers; edit feature, history marker drag, reorder with dependency checks, suppress, rename, delete with dependents, re-resolved references; redefining selections refreshes persistent edge/face references while retaining feature identity and dimension names), right-docked dialogs (done), live previews for every feature dialog (done), keyboard-first commands with on-canvas value boxes and sketch inline dimensions (done), drag manipulators with automatic join/cut (done: extrude incl. two sides, fillet, shell, hole depth, move, pattern spacing, revolve rotator; taper handle open), dark theme (done), right-click menu with Repeat (done), measure tool (done), section analysis (done), selection filter (done), drag-solve of sketch points (done); appearance controls now preserve body/face/component targeting, named transparent looks, reuse/search and override removal; preferences | in progress | 6 | | M7 | Sweep, loft (incl. to a point), rib and web (to next / depth), emboss (planar faces and exact radial emboss/deboss of bounded orthogonal profiles on complete exterior cylinders/sleeves), thread (cosmetic, and modelled M3–M20 outside and inside: the ISO profile screwed in as a faceted cut), coil (smooth B-spline helical walls), pipe, pattern on path, patterns of bodies and components, replace face (parallel), align, remove, feature copy/paste: done. Unique eligible cylindrical targets are inferred for new Emboss features. Left: general curved-face emboss and exact (unfaceted) modelled threads | in progress | 12 | @@ -175,8 +176,7 @@ headline counts in-scope tabs only and lists the deferred ones separately. containment shortcut. Spheres are built from six pole-free patches. - Mass properties come from fine tessellation (curved faces within ~1e-4 relative); triangles that cut through curved faces (trimmed faces after booleans) are split onto the surface first. -- STEP import (our own reader, crates/kernel/src/step_in; all 29 Fusion STEP files pass - `cargo xtask step-corpus`) reads solids (B-rep with analytic and B-spline geometry), units, +- STEP import (our own reader, crates/kernel/src/step_in) reads solids (B-rep with analytic and B-spline geometry), units, product names, colours and assemblies; analytic offsets on planes, cylinders, cones, spheres and regular tori are read exactly (signed/nested distances, units and face sense). Freeform offset surfaces and pcurve-only edges are not read yet, diff --git a/apps/solvecraft-cli/src/main.rs b/apps/solvecraft-cli/src/main.rs index aff72a9b..dd62bd43 100644 --- a/apps/solvecraft-cli/src/main.rs +++ b/apps/solvecraft-cli/src/main.rs @@ -8,8 +8,7 @@ //! solvecraft-cli exec [json-params] run one command on an empty design //! solvecraft-cli commands the command registry as JSON //! solvecraft-cli recipe translate an oracle recipe to a script -//! solvecraft-cli oracle ... replay recipes and compare with measure.json -//! solvecraft-cli step-corpus ... import part.step and compare with measure.json +//! solvecraft-cli oracle ... replay recipes and compare with expected.json //! solvecraft-cli mcp [--in design|script] [--connect HOST:PORT] MCP server on stdio (docs/mcp.md) //! solvecraft-cli licences SolveCraft's licence and the third-party licences //! solvecraft-cli icon --out F.png|F.ico [--size N] the app icon (packaging; drawn, not a file) @@ -20,7 +19,7 @@ mod fuzz; mod oracle; mod recipe; -mod seams; +mod spatial; use std::process::ExitCode; @@ -42,7 +41,6 @@ const USAGE: &str = "usage: solvecraft-cli recipe solvecraft-cli oracle ... [--json] solvecraft-cli fuzz [--from N] [--count N] [--jobs J] [--timeout S] [--steps N] [--minimise] [--out DIR] [--report FILE] - solvecraft-cli step-corpus ... [--json] [--iges] solvecraft-cli mcp [--in design.solvecraft|script.json] [--connect 127.0.0.1:PORT] solvecraft-cli licences solvecraft-cli icon --out icon.png [--size 256] | --out icon.ico @@ -73,7 +71,6 @@ fn main() -> ExitCode { recipe::to_script(&v).map(|s| println!("{}", pretty(&s))) }), Some("oracle") => oracle::run(&args[1..]), - Some("step-corpus") => oracle::step_corpus(&args[1..]), Some("fuzz") => fuzz::run(&args[1..]), Some("fuzz-one") => fuzz::one(&args[1..]), Some("mcp") => cmd_mcp(&args[1..]), diff --git a/apps/solvecraft-cli/src/oracle.rs b/apps/solvecraft-cli/src/oracle.rs index 063b0ac6..2d1b1ec8 100644 --- a/apps/solvecraft-cli/src/oracle.rs +++ b/apps/solvecraft-cli/src/oracle.rs @@ -1,129 +1,149 @@ -//! Replay oracle recipes and compare with Fusion's measurements; import oracle STEP files and -//! compare them with the same measurements. +//! Reference tests: replay `tests/oracle//recipe.json` through the command engine and +//! compare the part with `expected.json` (closed-form values, or values from an independent +//! kernel; see tests/oracle/README.md), and with `reference.stl` where one exists. + +#![allow(clippy::needless_range_loop)] use serde_json::{Value, json}; +use solvecraft_engine::geom::Vec3; -use crate::{read_json, recipe, seams}; +use crate::spatial::{self, Tri}; +use crate::{read_json, recipe}; -/// Relative tolerance for volume and area (our curved-face tessellation is within ~2e-4). +/// Default relative tolerance for volume and area (our curved-face tessellation is within ~2e-4). pub const REL_TOL: f64 = 1e-3; +/// Default tolerance for centre of mass and bounding box, as a fraction of the bbox diagonal. +const ABS_FRAC: f64 = 1e-3; +/// Chord tolerance used to triangulate our part for the surface-distance check (mm). +const MESH_TOL: f64 = 0.01; +/// Relative tolerance on the principal second moments of the two triangulations. +const INERTIA_REL: f64 = 2e-3; -/// Cases compared loosely (relative tolerance on volume and area, topology not compared), and why. -const APPROXIMATE: [(&str, f64, &str); 1] = [( - "49-helical-sweep", - 5e-3, - "Fusion sweeps along a spline fitted through helix points; SolidCraft builds the true helix (a coil), so the size is compared within 0.5% and the topology not at all", -)]; +/// What SolidCraft built: totals over every body. +struct Got { + body_count: usize, + volume: f64, + area: f64, + com: [f64; 3], + bbox: ([f64; 3], [f64; 3]), + faces: u64, +} + +fn v3(v: &Value) -> Option<[f64; 3]> { + let a = v.as_array()?; + Some([a.first()?.as_f64()?, a.get(1)?.as_f64()?, a.get(2)?.as_f64()?]) +} + +fn totals(m: &Value) -> Got { + let bodies = m["bodies"].as_array().cloned().unwrap_or_default(); + let (mut volume, mut area, mut faces) = (0.0, 0.0, 0); + let mut moment = [0.0; 3]; + let mut lo = [f64::INFINITY; 3]; + let mut hi = [f64::NEG_INFINITY; 3]; + for b in &bodies { + let v = b["volume_mm3"].as_f64().unwrap_or(f64::NAN); + volume += v; + area += b["area_mm2"].as_f64().unwrap_or(f64::NAN); + faces += b["faces"].as_u64().unwrap_or(0); + let c = v3(&b["center_of_mass"]).unwrap_or([f64::NAN; 3]); + let (bl, bh) = (v3(&b["bbox"]["min"]).unwrap_or([f64::NAN; 3]), v3(&b["bbox"]["max"]).unwrap_or([f64::NAN; 3])); + for k in 0..3 { + moment[k] += v * c[k]; + lo[k] = lo[k].min(bl[k]); + hi[k] = hi[k].max(bh[k]); + } + } + let com = moment.map(|x| x / volume); + Got { body_count: bodies.len(), volume, area, com, bbox: (lo, hi), faces } +} + +struct Checks { + list: Vec, + pass: bool, +} + +impl Checks { + fn push(&mut self, what: &str, got: Value, want: Value, ok: bool) { + self.pass &= ok; + self.list.push(json!({"check": what, "got": got, "want": want, "ok": ok})); + } + fn rel(&mut self, what: &str, g: f64, w: Option, rel: f64) { + let ok = w.is_some_and(|w| g.is_finite() && (g - w).abs() <= rel * w.abs().max(1.0)); + self.push(what, json!(g), json!(w), ok); + } + fn vec(&mut self, what: &str, g: [f64; 3], w: Option<[f64; 3]>, tol: f64) { + let ok = w.is_some_and(|w| g.iter().zip(w).all(|(g, w)| g.is_finite() && (g - w).abs() <= tol)); + self.push(what, json!(g), json!(w), ok); + } +} fn check_case(dir: &str) -> Value { let name = std::path::Path::new(dir).file_name().map(|x| x.to_string_lossy().to_string()).unwrap_or_default(); - let rp = format!("{dir}/recipe.json"); - let mp = format!("{dir}/measure.json"); - let (recipe, want) = match (read_json(&rp), read_json(&mp)) { - (Ok(r), Ok(m)) => (r, m), - (Err(e), _) | (_, Err(e)) => return json!({"case": name, "pass": false, "error": e}), + let recipe = match read_json(&format!("{dir}/recipe.json")) { + Ok(r) => r, + Err(e) => return json!({"case": name, "pass": false, "error": e}), }; + let want = read_json(&format!("{dir}/expected.json")).ok(); let script = match recipe::to_script(&recipe) { Ok(s) => s, Err(e) => return json!({"case": name, "pass": false, "skipped": true, "error": e}), }; let mut s = solvecraft_engine::Session::default(); if let Err(e) = s.run_script(&script) { - return json!({"case": name, "pass": false, "error": e.to_string()}); + return json!({"case": name, "pass": false, "error": e.to_string(), "source": want.as_ref().map(|w| w["source"].clone())}); } let got = match s.execute("inspect.measure", &json!({})) { - Ok(m) => m, + Ok(m) => totals(&m), Err(e) => return json!({"case": name, "pass": false, "error": e.to_string()}), }; - let mut checks = Vec::new(); - let mut pass = true; - let mut num = |what: &str, g: Option, w: Option, rel: f64| { - let ok = match (g, w) { - (Some(g), Some(w)) => (g - w).abs() <= rel * w.abs().max(1.0), - _ => false, - }; - pass &= ok; - checks.push(json!({"check": what, "got": g, "want": w, "ok": ok})); + let got_json = json!({ + "body_count": got.body_count, "volume_mm3": got.volume, "area_mm2": got.area, + "center_of_mass": got.com, "bbox": {"min": got.bbox.0, "max": got.bbox.1}, "faces": got.faces, + }); + let Some(want) = want else { + return json!({"case": name, "pass": false, "skipped": true, "error": "no expected.json yet", "got": got_json}); }; - // Cases where Fusion's part is itself an approximation: compare size loosely, not topology. - let approx = APPROXIMATE.iter().find(|(c, _, _)| *c == name); - let tol = approx.map(|(_, t, _)| *t).unwrap_or(REL_TOL); - let within = |k: &str, rel: f64| match (got["total"][k].as_f64(), want["total"][k].as_f64()) { - (Some(g), Some(w)) => (g - w).abs() <= rel * w.abs().max(1.0), - _ => false, - }; - let size_ok = - got["body_count"] == want["body_count"] && within("volume_mm3", tol) && (FUSION_AREA_OFF.contains(&name.as_str()) || within("area_mm2", tol)); - num("body_count", got["body_count"].as_f64(), want["body_count"].as_f64(), 0.0); - num("volume_mm3", got["total"]["volume_mm3"].as_f64(), want["total"]["volume_mm3"].as_f64(), tol); - let area_off = FUSION_AREA_OFF.contains(&name.as_str()); - if !area_off { - num("area_mm2", got["total"]["area_mm2"].as_f64(), want["total"]["area_mm2"].as_f64(), tol); + let only: Option> = want["compare"].as_array().map(|a| a.iter().filter_map(|x| x.as_str().map(str::to_string)).collect()); + let wanted = |k: &str| want.get(k).is_some_and(|v| !v.is_null()) && only.as_ref().is_none_or(|o| o.iter().any(|x| x == k)); + let rel = want["tolerance"]["rel"].as_f64().unwrap_or(REL_TOL); + let diag = |b: ([f64; 3], [f64; 3])| ((b.1[0] - b.0[0]).powi(2) + (b.1[1] - b.0[1]).powi(2) + (b.1[2] - b.0[2]).powi(2)).sqrt(); + let want_bbox = v3(&want["bbox"]["min"]).zip(v3(&want["bbox"]["max"])); + let abs = want["tolerance"]["abs_mm"].as_f64().unwrap_or_else(|| ABS_FRAC * want_bbox.map(diag).unwrap_or_else(|| diag(got.bbox)).max(1.0)); + let mut c = Checks { list: Vec::new(), pass: true }; + if wanted("body_count") { + let ok = want["body_count"].as_u64() == Some(got.body_count as u64); + c.push("body_count", json!(got.body_count), want["body_count"].clone(), ok); } - let mut seam_note = None; - if approx.is_none() { - let exact = ["faces", "edges", "vertices"].iter().all(|k| got["total"][k].as_f64().is_some() && got["total"][k] == want["total"][k]); - let fusion_seams = want["bodies"] - .as_array() - .and_then(|bs| bs.iter().map(seams::normalised).try_fold((0, 0, 0), |a, n| n.map(|n| (a.0 + n.0, a.1 + n.1, a.2 + n.2)))); - match fusion_seams { - // Size matches and only the topology differs: compare with Fusion's seam splits merged. - Some((f, e, v)) if size_ok && !exact => { - let raw: Vec = ["faces", "edges", "vertices"] - .iter() - .map(|k| { - let ours: i64 = got["bodies"].as_array().into_iter().flatten().filter_map(|b| b["kernel"][k].as_i64()).sum(); - format!("{k} {ours}/{}", want["total"][k]) - }) - .collect(); - seam_note = Some(format!( - "topology compared seam-normalised: Fusion's {}/{}/{} faces/edges/vertices become {f}/{e}/{v} with closed-surface patches counted once and seam edges and vertices dropped (raw SolidCraft/Fusion: {})", - want["total"]["faces"], - want["total"]["edges"], - want["total"]["vertices"], - raw.join(", ") - )); - num("faces (seam-normalised)", got["total"]["faces"].as_f64(), Some(f as f64), 0.0); - num("edges (seam-normalised)", got["total"]["edges"].as_f64(), Some(e as f64), 0.0); - num("vertices (seam-normalised)", got["total"]["vertices"].as_f64(), Some(v as f64), 0.0); - } - _ => { - num("faces", got["total"]["faces"].as_f64(), want["total"]["faces"].as_f64(), 0.0); - num("edges", got["total"]["edges"].as_f64(), want["total"]["edges"].as_f64(), 0.0); - num("vertices", got["total"]["vertices"].as_f64(), want["total"]["vertices"].as_f64(), 0.0); - } - } + if wanted("volume_mm3") { + c.rel("volume_mm3", got.volume, want["volume_mm3"].as_f64(), rel); + } + if wanted("area_mm2") { + c.rel("area_mm2", got.area, want["area_mm2"].as_f64(), rel); + } + if wanted("center_of_mass") { + c.vec("center_of_mass", got.com, v3(&want["center_of_mass"]), abs); + } + if wanted("bbox") { + c.vec("bbox.min", got.bbox.0, want_bbox.map(|b| b.0), abs); + c.vec("bbox.max", got.bbox.1, want_bbox.map(|b| b.1), abs); + } + if wanted("faces") { + let ok = want["faces"].as_u64() == Some(got.faces); + c.push("faces", json!(got.faces), want["faces"].clone(), ok); + } + let stl = format!("{dir}/reference.stl"); + if std::path::Path::new(&stl).is_file() && only.as_ref().is_none_or(|o| o.iter().any(|x| x == "surface")) { + let tol = want["tolerance"]["surface_mm"].as_f64().unwrap_or(0.05); + reference_checks(&s, &stl, tol, &mut c); } // Our STEP export of the rebuilt part: well formed, and read back with no warnings and the // same volume. - let (ok, note) = step_export_check(&s, got["total"]["volume_mm3"].as_f64().unwrap_or(0.0)); - pass &= ok; - checks.push(json!({"check": "step_export", "got": note, "want": "valid, re-imports cleanly", "ok": ok})); - let mut out = json!({"case": name, "pass": pass, "checks": checks}); - if let Some((_, _, why)) = approx { - out["note"] = json!(why); - } - if let Some(n) = seam_note { + let (ok, note) = step_export_check(&s, got.volume); + c.push("step_export", json!(note), json!("valid, re-imports cleanly"), ok); + let mut out = json!({"case": name, "pass": c.pass, "source": want["source"], "checks": c.list, "got": got_json}); + if let Some(n) = want["note"].as_str() { out["note"] = json!(n); } - if area_off { - out["note"] = json!( - "area not compared: Fusion reports this tight sweep's horn torus face at three times its area (π²·R·r quarter-turn value; 740 mm² against 246.7 by Pappus); volume and topology are compared" - ); - } - let effective: Vec = recipe["features"] - .as_array() - .into_iter() - .flatten() - .filter(|f| f.get("fusion_effective_extent").is_some()) - .map(|f| f["name"].as_str().unwrap_or("?").to_string()) - .collect(); - if !effective.is_empty() { - out["note"] = json!(format!( - "known Fusion difference: {} replayed with the extent Fusion actually used (its through-all is sized as 1.1 × the farthest vertex, so curved tops stop it short; SolidCraft's through-all goes truly through)", - effective.join(", ") - )); - } out } @@ -163,77 +183,43 @@ fn step_export_check(s: &solvecraft_engine::Session, volume: f64) -> (bool, Stri } } -/// Cases whose Fusion area is not the geometric one: Fusion reports the horn torus face of a -/// tight sweep (tube touching its axis) at three times π²·R·r, its quarter-turn area; the -/// volumes agree. Their area is not compared. -const FUSION_AREA_OFF: &[&str] = &["50-sweep-tight-bend"]; - -/// Import a case's `part.step` (as File → Open does) and compare with Fusion's measurements: -/// body count, volume and area (relative 1e-3) and the faces read from the file. -/// Open the case's `part.step` (or `part.igs` with `iges`) and compare with measure.json. -fn check_step_case(dir: &str, iges: bool) -> Value { - let name = std::path::Path::new(dir).file_name().map(|x| x.to_string_lossy().to_string()).unwrap_or_default(); - let sp = format!("{dir}/{}", if iges { "part.igs" } else { "part.step" }); - let want = match read_json(&format!("{dir}/measure.json")) { - Ok(m) => m, - Err(e) => return json!({"case": name, "pass": false, "error": e}), - }; - let t0 = std::time::Instant::now(); - let mut s = solvecraft_engine::Session::default(); - let opened = match s.execute("doc.open", &json!({"path": sp})) { - Ok(v) => v, - Err(e) => return json!({"case": name, "pass": false, "error": e.to_string()}), - }; - let got = match s.execute("inspect.measure", &json!({})) { - Ok(m) => m, - Err(e) => return json!({"case": name, "pass": false, "error": e.to_string()}), - }; - let ms = t0.elapsed().as_secs_f64() * 1000.0; - // Faces read from the file (the kernel may split a face that wraps around a closed surface). - let file_faces = std::fs::read(&sp) - .ok() - .and_then(|b| { - let text = String::from_utf8_lossy(&b); - if iges { - solvecraft_engine::kernel::iges_import(&text).ok().map(std::sync::Arc::new) - } else { - solvecraft_engine::kernel::step_import_shared(&text).ok() +/// Our part as a triangle soup (curved faces refined onto the surface). +fn our_mesh(s: &solvecraft_engine::Session) -> Result, String> { + let mut ours: Vec = Vec::new(); + for b in &s.world_state().bodies { + let m = b.body.tessellate_with(MESH_TOL, true).map_err(|e| e.to_string())?; + let p = |i: u32| m.positions.get(i as usize).map(|v: &Vec3| [v.x, v.y, v.z]); + for t in &m.triangles { + if let (Some(a), Some(b), Some(c)) = (p(t[0]), p(t[1]), p(t[2])) { + ours.push([a, b, c]); } - }) - .map(|imp| imp.bodies.iter().map(|b| b.file_faces).sum::() as f64); - let mut checks = Vec::new(); - let mut pass = true; - let mut num = |what: &str, g: Option, w: Option, rel: f64| { - let ok = match (g, w) { - (Some(g), Some(w)) => (g - w).abs() <= rel * w.abs().max(1.0), - _ => false, - }; - pass &= ok; - checks.push(json!({"check": what, "got": g, "want": w, "ok": ok})); - }; - num("body_count", got["body_count"].as_f64(), want["body_count"].as_f64(), 0.0); - num("volume_mm3", got["total"]["volume_mm3"].as_f64(), want["total"]["volume_mm3"].as_f64(), REL_TOL); - if !FUSION_AREA_OFF.contains(&name.as_str()) { - num("area_mm2", got["total"]["area_mm2"].as_f64(), want["total"]["area_mm2"].as_f64(), REL_TOL); + } } - num("faces", file_faces, want["total"]["faces"].as_f64(), 0.0); - json!({ - "case": name, "pass": pass, "checks": checks, "ms": ms, - "bodies": opened["bodies"], "warnings": opened["warnings"], - "info": {"kernel_faces_merged": got["total"]["faces"], "edges": got["total"]["edges"], "want_edges": want["total"]["edges"], "vertices": got["total"]["vertices"], "want_vertices": want["total"]["vertices"]}, - }) + if ours.is_empty() { Err("empty mesh".into()) } else { Ok(ours) } } -pub fn step_corpus(args: &[String]) -> Result<(), String> { - let dirs: Vec<&String> = args.iter().filter(|a| !a.starts_with("--")).collect(); - if dirs.is_empty() { - return Err("step-corpus: give one or more case directories (each with part.step and measure.json)".into()); - } - let iges = args.iter().any(|a| a == "--iges"); - let results: Vec = dirs.iter().map(|d| check_step_case(d, iges)).collect(); - report(args, &results); - let failed = results.iter().filter(|r| !r["pass"].as_bool().unwrap_or(false)).count(); - if failed > 0 { Err(format!("{failed} STEP case(s) failed")) } else { Ok(()) } +/// Compare our part with the reference triangulation: the symmetric surface distance, and the +/// principal second moments of volume of both meshes (the shape's inertia, independent of how it +/// sits in space). +fn reference_checks(s: &solvecraft_engine::Session, stl: &str, tol: f64, c: &mut Checks) { + let (ours, reference) = match (our_mesh(s), spatial::read_stl(stl)) { + (Ok(o), Ok(r)) if !r.is_empty() => (o, r), + (Err(e), _) | (_, Err(e)) => return c.push("surface_distance_mm", json!(e), json!(format!("<= {tol}")), false), + _ => return c.push("surface_distance_mm", json!("empty reference.stl"), json!(format!("<= {tol}")), false), + }; + let (lo, hi) = spatial::bounds(&reference); + let size = (0..3).map(|k| hi[k] - lo[k]).fold(0.0, f64::max); + let h = spatial::hausdorff(&ours, &reference, size.max(1.0)); + let worst = h.a_to_b.max(h.b_to_a); + c.push( + "surface_distance_mm", + json!({"max": worst, "mean": h.mean, "ours_to_reference": h.a_to_b, "reference_to_ours": h.b_to_a, "worst_at": h.worst_at}), + json!(format!("<= {tol}")), + worst <= tol, + ); + let ((_, _, pa), (_, _, pb)) = (spatial::mass_properties(&ours), spatial::mass_properties(&reference)); + let ok = pa.iter().zip(pb).all(|(a, b)| (a - b).abs() <= INERTIA_REL * b.abs().max(1.0)); + c.push("principal_moments_mm5", json!(pa), json!(pb), ok); } fn report(args: &[String], results: &[Value]) { @@ -268,7 +254,7 @@ fn report(args: &[String], results: &[Value]) { pub fn run(args: &[String]) -> Result<(), String> { let dirs: Vec<&String> = args.iter().filter(|a| !a.starts_with("--")).collect(); if dirs.is_empty() { - return Err("oracle: give one or more case directories".into()); + return Err("oracle: give one or more case directories (each with recipe.json and expected.json)".into()); } let results: Vec = dirs.iter().map(|d| check_case(d)).collect(); report(args, &results); diff --git a/apps/solvecraft-cli/src/recipe.rs b/apps/solvecraft-cli/src/recipe.rs index 6669eaf6..5f7708b9 100644 --- a/apps/solvecraft-cli/src/recipe.rs +++ b/apps/solvecraft-cli/src/recipe.rs @@ -1,4 +1,4 @@ -//! Oracle recipes (`plan/fusion/oracle/*/recipe.json`) → SolveCraft command scripts. +//! Reference-test recipes (`tests/oracle/*/recipe.json`) → SolidCraft command scripts. //! //! A recipe lists features with sketch entities in sketch-local coordinates; point references //! (`l1.end`) share points. Each feature becomes one or more commands. @@ -85,14 +85,6 @@ fn sketch_cmds(f: &Value, out: &mut Vec) -> Result<(), String> { /// Extent parameters for the Extrude command. fn extent(f: &Value, p: &mut Value) { - // Where Fusion's own result differs from the geometric meaning (its through-all is sized - // from vertices), the recipe records the extent Fusion actually used: replay that. - if let Some(fx) = f.get("fusion_effective_extent").filter(|x| x.get("type").and_then(Value::as_str) == Some("distance")) { - let dir = fx.get("direction").and_then(Value::as_str).unwrap_or("positive"); - p["distance"] = fx.get("distance").cloned().unwrap_or(Value::Null); - p["direction"] = json!(if dir.starts_with("negative") { "negative" } else { "positive" }); - return; - } let e = f.get("extent").cloned().unwrap_or(Value::Null); let ty = e.get("type").and_then(Value::as_str).unwrap_or("distance"); let dist = e.get("distance").cloned().or_else(|| f.get("distance").cloned()).unwrap_or(Value::Null); @@ -545,8 +537,8 @@ fn edge_points(f: &Value) -> Value { ) } -/// Fusion names a pattern's source features with an occurrence suffix ("Hole1 (1)"); the -/// features are the recipe's own names. +/// A pattern's source features may carry an occurrence suffix ("Hole1 (1)"); the features are +/// the recipe's own names. fn feature_refs(v: Option<&Value>) -> Value { let list: Vec = v .and_then(Value::as_array) diff --git a/apps/solvecraft-cli/src/seams.rs b/apps/solvecraft-cli/src/seams.rs deleted file mode 100644 index 5911cec1..00000000 --- a/apps/solvecraft-cli/src/seams.rs +++ /dev/null @@ -1,321 +0,0 @@ -//! Seam-normalised topology of Fusion's measurements. -//! -//! Fusion splits a closed surface along seams: a full cylinder can be two half faces, and a -//! closed curve crossing a seam becomes two edges with a vertex on the seam. SolveCraft's merged -//! counts already count each closed surface patch once and ignore seam edges and vertices, so -//! the oracle normalises Fusion's side the same way from its face, edge and vertex lists: -//! - faces cut from one periodic surface (cylinder, cone, sphere, torus) and separated only by -//! seam edges count once; -//! - a seam edge lies on that surface and on no other face's surface: it is dropped; -//! - a vertex left with exactly two edges is no corner (a solid's corners have three or more): -//! the two edges join, and a curve that closes on itself keeps one vertex. - -use std::collections::HashMap; - -use serde_json::Value; - -type V3 = [f64; 3]; - -const TOL: f64 = 1e-4; - -fn v3(v: &Value) -> Option { - let a = v.as_array()?; - Some([a.first()?.as_f64()?, a.get(1)?.as_f64()?, a.get(2)?.as_f64()?]) -} -fn sub(a: V3, b: V3) -> V3 { - [a[0] - b[0], a[1] - b[1], a[2] - b[2]] -} -fn add(a: V3, b: V3) -> V3 { - [a[0] + b[0], a[1] + b[1], a[2] + b[2]] -} -fn mul(a: V3, s: f64) -> V3 { - [a[0] * s, a[1] * s, a[2] * s] -} -fn dot(a: V3, b: V3) -> f64 { - a[0] * b[0] + a[1] * b[1] + a[2] * b[2] -} -fn cross(a: V3, b: V3) -> V3 { - [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]] -} -fn len(a: V3) -> f64 { - dot(a, a).sqrt() -} -fn unit(a: V3) -> Option { - let l = len(a); - (l > 1e-12).then(|| mul(a, 1.0 / l)) -} - -#[derive(Clone, Copy, Debug, PartialEq)] -enum Surf { - Plane { p: V3, n: V3 }, - Cylinder { o: V3, a: V3, r: f64 }, - Cone { o: V3, a: V3, r: f64, tan: f64 }, - Sphere { c: V3, r: f64 }, - Torus { c: V3, a: V3, big: f64, small: f64 }, - Other, -} - -impl Surf { - fn of(f: &Value) -> Surf { - let g = |k: &str| v3(&f[k]); - let n = |k: &str| f[k].as_f64(); - let s = match f["type"].as_str().unwrap_or_default() { - "plane" => g("centroid").zip(g("plane_normal_outward").and_then(unit)).map(|(p, n)| Surf::Plane { p, n }), - "cylinder" => (|| Some(Surf::Cylinder { o: g("axis_origin")?, a: unit(g("axis")?)?, r: n("radius_mm")? }))(), - "cone" => { - (|| Some(Surf::Cone { o: g("axis_origin")?, a: unit(g("axis")?)?, r: n("radius_mm")?, tan: n("half_angle_deg")?.to_radians().tan() }))( - ) - } - "sphere" => (|| Some(Surf::Sphere { c: g("center")?, r: n("radius_mm")? }))(), - "torus" => (|| Some(Surf::Torus { c: g("center")?, a: unit(g("axis")?)?, big: n("major_radius_mm")?, small: n("minor_radius_mm")? }))(), - _ => None, - }; - s.unwrap_or(Surf::Other) - } - - fn periodic(&self) -> bool { - matches!(self, Surf::Cylinder { .. } | Surf::Cone { .. } | Surf::Sphere { .. } | Surf::Torus { .. }) - } - - /// Whether the point lies on the surface; `None` when that can't be told (free-form faces). - fn contains(&self, p: V3) -> Option { - let radial = |o: V3, a: V3| { - let d = sub(p, o); - let t = dot(d, a); - (t, len(sub(d, mul(a, t)))) - }; - Some(match *self { - Surf::Plane { p: q, n } => dot(sub(p, q), n).abs() < TOL, - Surf::Cylinder { o, a, r } => (radial(o, a).1 - r).abs() < TOL, - Surf::Cone { o, a, r, tan } => { - let (t, rho) = radial(o, a); - (rho - (r + t * tan)).abs() < TOL || (rho - (r - t * tan)).abs() < TOL - } - Surf::Sphere { c, r } => (len(sub(p, c)) - r).abs() < TOL, - Surf::Torus { c, a, big, small } => { - let (t, rho) = radial(c, a); - ((rho - big).hypot(t) - small).abs() < TOL - } - Surf::Other => return None, - }) - } - - fn same(&self, o: &Surf) -> bool { - let close = |a: f64, b: f64| (a - b).abs() < TOL; - let pt = |a: V3, b: V3| len(sub(a, b)) < TOL; - let par = |a: V3, b: V3| len(cross(a, b)) < TOL; - // Same axis line: parallel, and either origin on the other's axis. - let axis = |o1: V3, a1: V3, o2: V3, a2: V3| par(a1, a2) && len(cross(sub(o2, o1), a1)) < TOL; - match (*self, *o) { - (Surf::Cylinder { o: o1, a: a1, r: r1 }, Surf::Cylinder { o: o2, a: a2, r: r2 }) => axis(o1, a1, o2, a2) && close(r1, r2), - (Surf::Cone { o: o1, a: a1, r: r1, tan: t1 }, Surf::Cone { .. }) => { - // Same cone: the other's frame circle lies on this one, same opening angle. - let Surf::Cone { o: o2, a: a2, r: r2, tan: t2 } = *o else { return false }; - axis(o1, a1, o2, a2) && close(t1, t2) && { - let t = dot(sub(o2, o1), a1) * dot(a1, a2).signum(); - close(r2, r1 + t * t1) || close(r2, r1 - t * t1) - } - } - (Surf::Sphere { c: c1, r: r1 }, Surf::Sphere { c: c2, r: r2 }) => pt(c1, c2) && close(r1, r2), - (Surf::Torus { c: c1, a: a1, big: b1, small: s1 }, Surf::Torus { c: c2, a: a2, big: b2, small: s2 }) => { - pt(c1, c2) && par(a1, a2) && close(b1, b2) && close(s1, s2) - } - _ => false, - } - } -} - -/// Points along an edge from Fusion's edge list. -fn edge_points(e: &Value) -> Vec { - let (s, t) = (v3(&e["start"]), v3(&e["end"])); - let mut pts: Vec = s.into_iter().chain(t).collect(); - let (c, r, a) = (v3(&e["center"]), e["radius_mm"].as_f64(), v3(&e["axis"]).and_then(unit)); - match (e["type"].as_str().unwrap_or_default(), s, t) { - ("line", Some(s), Some(t)) => pts.push(mul(add(s, t), 0.5)), - ("arc", Some(s), Some(t)) => { - if let (Some(c), Some(r)) = (c, r) - && let Some(m) = unit(add(sub(s, c), sub(t, c))) - { - let long = e["length_mm"].as_f64().is_some_and(|l| l > std::f64::consts::PI * r); - pts.push(add(c, mul(m, if long { -r } else { r }))); - } - } - ("circle", Some(s), _) => { - if let (Some(c), Some(a)) = (c, a) { - let d = sub(s, c); - for th in [2.0 * std::f64::consts::FRAC_PI_3, 4.0 * std::f64::consts::FRAC_PI_3] { - pts.push(add(c, add(mul(d, th.cos()), mul(cross(a, d), th.sin())))); - } - } - } - _ => {} - } - pts -} - -fn key(p: V3) -> [i64; 3] { - p.map(|x| (x * 1e6).round() as i64) -} - -fn find(p: &mut [usize], mut i: usize) -> usize { - while let Some(&q) = p.get(i) { - if q == i { - break; - } - i = q; - } - i -} - -/// Faces, edges and vertices of one Fusion body after merging seam splits; `None` when the -/// lists are missing. -pub fn normalised(body: &Value) -> Option<(usize, usize, usize)> { - let faces = body["face_list"].as_array()?; - let edges = body["edge_list"].as_array()?; - let surfs: Vec = faces.iter().map(Surf::of).collect(); - // Group faces cut from one periodic surface. - let mut group: Vec = (0..surfs.len()).collect(); - for i in 0..surfs.len() { - for j in 0..i { - if surfs[i].periodic() && surfs[i].same(&surfs[j]) { - group[i] = group[j]; - break; - } - } - } - let size = |g: usize| group.iter().filter(|x| **x == g).count(); - // Seam edges: on a split group's surface and on no other face's surface. - let mut seams_in: HashMap = HashMap::new(); - let mut seam = vec![false; edges.len()]; - for (ei, e) in edges.iter().enumerate() { - let pts = edge_points(e); - if pts.is_empty() { - continue; - } - let on = |s: &Surf| pts.iter().map(|p| s.contains(*p)).try_fold(true, |acc, x| Some(acc && x?)); - let carriers: Vec> = surfs.iter().map(on).collect(); - if carriers.contains(&None) { - continue; - } - let groups: Vec = (0..surfs.len()).filter(|f| carriers[*f] == Some(true)).map(|f| group[f]).collect(); - if let Some(&g) = groups.first() - && groups.iter().all(|x| *x == g) - && surfs[g].periodic() - && size(g) > 1 - { - seam[ei] = true; - *seams_in.entry(g).or_insert(0) += 1; - } - } - let mut face_count = 0; - for g in 0..surfs.len() { - let k = size(g); - if k > 0 { - face_count += k.saturating_sub(seams_in.get(&g).copied().unwrap_or(0)).max(1); - } - } - // Vertex degrees over the remaining edges; a closed edge counts once at its vertex. - let mut ends: Vec<(usize, Option<[i64; 3]>, Option<[i64; 3]>)> = Vec::new(); - for (ei, e) in edges.iter().enumerate() { - if seam[ei] { - continue; - } - let (s, t) = (v3(&e["start"]).map(key), v3(&e["end"]).map(key)); - let t = if t == s { None } else { t }; - ends.push((ends.len(), s, t)); - } - // A seam between two closed curves (a closed face's seam whose surface we can't evaluate): - // an open edge whose ends each meet only a closed edge. At a real vertex three edges meet. - let closed_at = |v: &[i64; 3], ends: &[(usize, Option<[i64; 3]>, Option<[i64; 3]>)]| { - let closed = ends.iter().filter(|(_, s, t)| t.is_none() && s.as_ref() == Some(v)).count(); - let open = ends.iter().filter(|(_, s, t)| t.is_some() && (s.as_ref() == Some(v) || t.as_ref() == Some(v))).count(); - closed == 1 && open == 1 - }; - let loop_seams: Vec = - ends.iter().filter(|(_, s, t)| matches!((s, t), (Some(s), Some(t)) if closed_at(s, &ends) && closed_at(t, &ends))).map(|e| e.0).collect(); - ends.retain(|e| !loop_seams.contains(&e.0)); - for (k, e) in ends.iter_mut().enumerate() { - e.0 = k; - } - let mut deg: HashMap<[i64; 3], Vec> = HashMap::new(); - for (i, s, t) in &ends { - for v in [s, t].into_iter().flatten() { - deg.entry(*v).or_default().push(*i); - } - } - let mut ep: Vec = (0..ends.len()).collect(); - let mut merged: Vec<[i64; 3]> = Vec::new(); - for (v, es) in ° { - // Two open edges meeting: one curve split at a seam. - if let [i, j] = es[..] - && i != j - && ends.get(i).is_some_and(|e| e.2.is_some()) - && ends.get(j).is_some_and(|e| e.2.is_some()) - { - let (ri, rj) = (find(&mut ep, i), find(&mut ep, j)); - if let Some(x) = ep.get_mut(ri) { - *x = rj; - } - merged.push(*v); - } - } - let mut real: HashMap = HashMap::new(); - for (i, s, t) in &ends { - let r = find(&mut ep, *i); - let has_real = [s, t].into_iter().flatten().any(|v| !merged.contains(v)) || (s.is_none() && t.is_none()); - *real.entry(r).or_insert(false) |= has_real; - } - let closed = real.values().filter(|r| !**r).count(); - let vertices = deg.keys().filter(|v| !merged.contains(v)).count() + closed; - Some((face_count, real.len(), vertices)) -} - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::json; - - /// A cylinder (r 5, height 10) split by Fusion into two halves along two seams. - #[test] - fn split_cylinder_counts_once() { - let cyl = json!({"type": "cylinder", "axis_origin": [0, 0, 0], "axis": [0, 0, 1], "radius_mm": 5.0}); - let plane = |z: f64, n: f64| json!({"type": "plane", "centroid": [0, 0, z], "plane_normal_outward": [0, 0, n]}); - let arc = |z: f64, s: [f64; 3], t: [f64; 3]| json!({"type": "arc", "start": s, "end": t, "center": [0, 0, z], "radius_mm": 5.0, "axis": [0, 0, 1], "length_mm": 15.707963}); - let line = |x: f64| json!({"type": "line", "start": [x, 0, 0], "end": [x, 0, 10]}); - let body = json!({ - "face_list": [cyl.clone(), cyl, plane(0.0, -1.0), plane(10.0, 1.0)], - "edge_list": [line(5.0), line(-5.0), arc(0.0, [5.0, 0.0, 0.0], [-5.0, 0.0, 0.0]), arc(0.0, [-5.0, 0.0, 0.0], [5.0, 0.0, 0.0]), arc(10.0, [5.0, 0.0, 10.0], [-5.0, 0.0, 10.0]), arc(10.0, [-5.0, 0.0, 10.0], [5.0, 0.0, 10.0])], - }); - assert_eq!(normalised(&body), Some((3, 2, 2))); - } - - /// Oracle 35: a fillet (free-form face, surface unknown) between two cylinders is bounded by - /// two closed contact curves joined by its seam arc. The arc goes; the curves and circles stay. - #[test] - fn seam_between_closed_curves_on_an_unknown_surface() { - let circle = - |s: [f64; 3], c: [f64; 3], a: [f64; 3]| json!({"type": "circle", "start": s, "end": s, "center": c, "radius_mm": 1.0, "axis": a}); - let lp = |p: [f64; 3]| json!({"type": "nurbs", "start": p, "end": p}); - let (p, q) = ([0.0, -10.833333333, 10.374916332], [0.0, -10.0, 12.449899598]); - let body = json!({ - "face_list": [{"type": "nurbs"}], - "edge_list": [ - {"type": "arc", "start": p, "end": q, "center": [0.0, -13.0, 12.449899598], "radius_mm": 3.0, "axis": [1, 0, 0]}, - circle([-40.0, 0.0, 15.0], [-40.0, 0.0, 0.0], [-1.0, 0.0, 0.0]), - circle([-10.0, 0.0, 35.0], [0.0, 0.0, 35.0], [0.0, 0.0, 1.0]), - circle([40.0, 0.0, 15.0], [40.0, 0.0, 0.0], [1.0, 0.0, 0.0]), - lp(p), - lp(q), - ], - }); - assert_eq!(normalised(&body), Some((1, 5, 5))); - } - - /// A closed curve split into two edges at a seam vertex joins again (Fusion part 61's keyway). - #[test] - fn degree_two_vertices_join() { - let n = |s: [f64; 3], t: [f64; 3]| json!({"type": "nurbs", "start": s, "end": t}); - let body = json!({"face_list": [], "edge_list": [n([0.0, 0.0, 0.0], [1.0, 0.0, 0.0]), n([1.0, 0.0, 0.0], [0.0, 0.0, 0.0])]}); - assert_eq!(normalised(&body), Some((0, 1, 1))); - } -} diff --git a/apps/solvecraft-cli/src/spatial.rs b/apps/solvecraft-cli/src/spatial.rs new file mode 100644 index 00000000..95ed5ef4 --- /dev/null +++ b/apps/solvecraft-cli/src/spatial.rs @@ -0,0 +1,333 @@ +//! Geometry comparison helpers: an STL reader, bounding boxes, volume, centre of mass and principal +//! second moments of a closed triangle mesh, and a sampled symmetric Hausdorff distance between two +//! triangle meshes. + +use std::collections::HashMap; + +/// A triangle soup in mm. +pub type Tri = [[f64; 3]; 3]; + +fn sub(a: [f64; 3], b: [f64; 3]) -> [f64; 3] { + [a[0] - b[0], a[1] - b[1], a[2] - b[2]] +} +fn add(a: [f64; 3], b: [f64; 3]) -> [f64; 3] { + [a[0] + b[0], a[1] + b[1], a[2] + b[2]] +} +fn scale(a: [f64; 3], s: f64) -> [f64; 3] { + [a[0] * s, a[1] * s, a[2] * s] +} +fn dot(a: [f64; 3], b: [f64; 3]) -> f64 { + a[0] * b[0] + a[1] * b[1] + a[2] * b[2] +} +fn cross(a: [f64; 3], b: [f64; 3]) -> [f64; 3] { + [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]] +} + +/// Read a binary (or ASCII) STL file. +pub fn read_stl(path: &str) -> Result, String> { + let b = std::fs::read(path).map_err(|e| format!("{path}: {e}"))?; + if b.len() >= 84 { + let n = u32::from_le_bytes([b[80], b[81], b[82], b[83]]) as usize; + if b.len() == 84 + 50 * n { + let f = |o: usize| f64::from(f32::from_le_bytes([b[o], b[o + 1], b[o + 2], b[o + 3]])); + return Ok((0..n) + .map(|i| { + let o = 84 + 50 * i + 12; + let v = |k: usize| [f(o + 12 * k), f(o + 12 * k + 4), f(o + 12 * k + 8)]; + [v(0), v(1), v(2)] + }) + .collect()); + } + } + let text = String::from_utf8_lossy(&b); + let mut verts = Vec::new(); + for line in text.lines() { + let mut it = line.split_whitespace(); + if it.next() == Some("vertex") { + let c: Vec = it.filter_map(|x| x.parse().ok()).collect(); + if c.len() == 3 { + verts.push([c[0], c[1], c[2]]); + } + } + } + if verts.is_empty() || verts.len() % 3 != 0 { + return Err(format!("{path}: not an STL file")); + } + Ok(verts.chunks(3).map(|c| [c[0], c[1], c[2]]).collect()) +} + +/// Volume, centre of mass and the principal second moments of volume (mm^5, sorted ascending) of a +/// closed, outward-oriented triangle soup, by signed tetrahedra from the origin. +pub fn mass_properties(tris: &[Tri]) -> (f64, [f64; 3], [f64; 3]) { + let (mut v6, mut m1) = (0.0, [0.0; 3]); + let mut c = [[0.0; 3]; 3]; // ∫ x xᵀ dV + for t in tris { + let d = dot(t[0], cross(t[1], t[2])); + v6 += d; + let s = add(add(t[0], t[1]), t[2]); + m1 = add(m1, scale(s, d / 24.0)); + for (i, row) in c.iter_mut().enumerate() { + for (j, cell) in row.iter_mut().enumerate() { + let vv: f64 = t.iter().map(|p| p[i] * p[j]).sum::() + s[i] * s[j]; + *cell += d / 120.0 * vv; + } + } + } + let vol = v6 / 6.0; + if vol.abs() < 1e-12 { + return (0.0, [0.0; 3], [0.0; 3]); + } + let com = scale(m1, 1.0 / vol); + // Central covariance and inertia tensor I = tr(C)·1 − C. + let mut cc = c; + for (i, row) in cc.iter_mut().enumerate() { + for (j, cell) in row.iter_mut().enumerate() { + *cell -= vol * com[i] * com[j]; + } + } + let tr = cc[0][0] + cc[1][1] + cc[2][2]; + let mut inertia = [[0.0; 3]; 3]; + for i in 0..3 { + for j in 0..3 { + inertia[i][j] = if i == j { tr - cc[i][j] } else { -cc[i][j] }; + } + } + let mut ev = eigen_sym3(inertia); + ev.sort_by(f64::total_cmp); + (vol, com, ev) +} + +/// Eigenvalues of a symmetric 3×3 matrix (Jacobi rotations). +fn eigen_sym3(mut a: [[f64; 3]; 3]) -> [f64; 3] { + for _ in 0..50 { + let (mut p, mut q, mut big) = (0, 1, 0.0); + for (i, j) in [(0, 1), (0, 2), (1, 2)] { + if a[i][j].abs() > big { + (p, q, big) = (i, j, a[i][j].abs()); + } + } + if big <= 1e-15 * (a[0][0].abs() + a[1][1].abs() + a[2][2].abs()).max(1e-300) { + break; + } + let theta = (a[q][q] - a[p][p]) / (2.0 * a[p][q]); + let t = theta.signum() / (theta.abs() + (theta * theta + 1.0).sqrt()); + let t = if theta == 0.0 { 1.0 } else { t }; + let (cs, sn) = (1.0 / (t * t + 1.0).sqrt(), t / (t * t + 1.0).sqrt()); + let mut b = a; + for k in 0..3 { + b[k][p] = cs * a[k][p] - sn * a[k][q]; + b[k][q] = sn * a[k][p] + cs * a[k][q]; + } + let mut c2 = b; + for k in 0..3 { + c2[p][k] = cs * b[p][k] - sn * b[q][k]; + c2[q][k] = sn * b[p][k] + cs * b[q][k]; + } + a = c2; + } + [a[0][0], a[1][1], a[2][2]] +} + +/// Axis-aligned bounds of a triangle soup. +pub fn bounds(tris: &[Tri]) -> ([f64; 3], [f64; 3]) { + let (mut lo, mut hi) = ([f64::INFINITY; 3], [f64::NEG_INFINITY; 3]); + for p in tris.iter().flatten() { + for k in 0..3 { + lo[k] = lo[k].min(p[k]); + hi[k] = hi[k].max(p[k]); + } + } + (lo, hi) +} + +/// Distance from a point to a triangle (Ericson, Real-Time Collision Detection 5.1.5). +fn point_tri(p: [f64; 3], t: &Tri) -> f64 { + let (a, b, c) = (t[0], t[1], t[2]); + let (ab, ac, ap) = (sub(b, a), sub(c, a), sub(p, a)); + let (d1, d2) = (dot(ab, ap), dot(ac, ap)); + let q = if d1 <= 0.0 && d2 <= 0.0 { + a + } else { + let bp = sub(p, b); + let (d3, d4) = (dot(ab, bp), dot(ac, bp)); + if d3 >= 0.0 && d4 <= d3 { + b + } else { + let vc = d1 * d4 - d3 * d2; + if vc <= 0.0 && d1 >= 0.0 && d3 <= 0.0 { + add(a, scale(ab, d1 / (d1 - d3))) + } else { + let cp = sub(p, c); + let (d5, d6) = (dot(ab, cp), dot(ac, cp)); + if d6 >= 0.0 && d5 <= d6 { + c + } else { + let vb = d5 * d2 - d1 * d6; + if vb <= 0.0 && d2 >= 0.0 && d6 <= 0.0 { + add(a, scale(ac, d2 / (d2 - d6))) + } else { + let va = d3 * d6 - d5 * d4; + if va <= 0.0 && (d4 - d3) >= 0.0 && (d5 - d6) >= 0.0 { + add(b, scale(sub(c, b), (d4 - d3) / ((d4 - d3) + (d5 - d6)))) + } else { + let den = va + vb + vc; + if den.abs() < 1e-300 { a } else { add(a, add(scale(ab, vb / den), scale(ac, vc / den))) } + } + } + } + } + } + }; + let d = sub(p, q); + dot(d, d).sqrt() +} + +/// Uniform grid of triangles for distance queries up to `cap`. +struct Grid<'a> { + tris: &'a [Tri], + cell: f64, + cells: HashMap<(i64, i64, i64), Vec>, +} + +impl<'a> Grid<'a> { + fn new(tris: &'a [Tri], cell: f64) -> Self { + let mut cells: HashMap<(i64, i64, i64), Vec> = HashMap::new(); + let key = |x: f64| (x / cell).floor() as i64; + for (i, t) in tris.iter().enumerate() { + let (lo, hi) = bounds(std::slice::from_ref(t)); + for x in key(lo[0])..=key(hi[0]) { + for y in key(lo[1])..=key(hi[1]) { + for z in key(lo[2])..=key(hi[2]) { + cells.entry((x, y, z)).or_default().push(i as u32); + } + } + } + } + Grid { tris, cell, cells } + } + + /// Distance from `p` to the nearest triangle, or `cap` if none is that close. Searches shells + /// of cells outwards and stops once the nearest hit is closer than the unsearched shells. + fn distance(&self, p: [f64; 3], cap: f64, seen: &mut [u32], stamp: u32) -> f64 { + let rmax = (cap / self.cell).ceil() as i64; + let k = |x: f64| (x / self.cell).floor() as i64; + let (cx, cy, cz) = (k(p[0]), k(p[1]), k(p[2])); + let mut best = cap; + for r in 0..=rmax { + for x in cx - r..=cx + r { + for y in cy - r..=cy + r { + for z in cz - r..=cz + r { + // only the shell at Chebyshev distance r + if (x - cx).abs() != r && (y - cy).abs() != r && (z - cz).abs() != r { + continue; + } + let Some(list) = self.cells.get(&(x, y, z)) else { continue }; + for &i in list { + let Some(slot) = seen.get_mut(i as usize) else { continue }; + if *slot == stamp { + continue; + } + *slot = stamp; + if let Some(t) = self.tris.get(i as usize) { + best = best.min(point_tri(p, t)); + } + } + } + } + } + // Everything not yet searched is at least r·cell away from p. + if best <= r as f64 * self.cell { + break; + } + } + best + } +} + +/// At most this many sample points per side (larger meshes are sampled with an even stride). +const MAX_SAMPLES: usize = 250_000; + +/// Sample points of a triangle soup: its vertices and triangle centroids (every k-th triangle for +/// very large meshes). +fn samples(tris: &[Tri]) -> Vec<[f64; 3]> { + let stride = (tris.len() * 4).div_ceil(MAX_SAMPLES).max(1); + let mut out: Vec<[f64; 3]> = Vec::with_capacity(tris.len() * 4 / stride + 4); + for t in tris.iter().step_by(stride) { + out.extend_from_slice(t); + out.push(scale(add(add(t[0], t[1]), t[2]), 1.0 / 3.0)); + } + out +} + +/// One-sided sampled distance from `from` to `to`: (max, mean, worst sample point). Distances are +/// capped at `cap`. +fn one_sided(from: &[Tri], to: &[Tri], cap: f64) -> (f64, f64, [f64; 3]) { + let (lo, hi) = bounds(to); + let diag = dot(sub(hi, lo), sub(hi, lo)).sqrt(); + // Cells about twice the typical triangle size (so a cell holds a handful of triangles), but no + // finer than diag/400 (so big flat triangles don't fill too many cells). + let area: f64 = to.iter().map(|t| dot(cross(sub(t[1], t[0]), sub(t[2], t[0])), cross(sub(t[1], t[0]), sub(t[2], t[0]))).sqrt() / 2.0).sum(); + let typical = (area / to.len().max(1) as f64).sqrt(); + let grid = Grid::new(to, (2.0 * typical).max(diag / 400.0).max(1e-3)); + let mut seen = vec![0u32; to.len()]; + let (mut max, mut sum, mut worst, mut n) = (0.0f64, 0.0, [0.0; 3], 0usize); + for (i, p) in samples(from).into_iter().enumerate() { + let d = grid.distance(p, cap, &mut seen, i as u32 + 1); + sum += d; + n += 1; + if d > max { + max = d; + worst = p; + } + } + (max, if n > 0 { sum / n as f64 } else { 0.0 }, worst) +} + +/// Sampled symmetric Hausdorff distance between two triangle soups (distances capped at `cap`). +pub struct Hausdorff { + pub a_to_b: f64, + pub b_to_a: f64, + pub mean: f64, + /// Where the larger one-sided distance was found (mm, world). + pub worst_at: [f64; 3], +} + +pub fn hausdorff(a_mesh: &[Tri], b_mesh: &[Tri], cap: f64) -> Hausdorff { + let (a, am, ap) = one_sided(a_mesh, b_mesh, cap); + let (b, bm, bp) = one_sided(b_mesh, a_mesh, cap); + Hausdorff { a_to_b: a, b_to_a: b, mean: (am + bm) / 2.0, worst_at: if a >= b { ap } else { bp } } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn cube(s: f64, o: [f64; 3]) -> Vec { + let v = |x: f64, y: f64, z: f64| [o[0] + x * s, o[1] + y * s, o[2] + z * s]; + let q = |a: [f64; 3], b: [f64; 3], c: [f64; 3], d: [f64; 3]| vec![[a, b, c], [a, c, d]]; + let mut t = Vec::new(); + t.extend(q(v(0., 0., 0.), v(0., 1., 0.), v(1., 1., 0.), v(1., 0., 0.))); + t.extend(q(v(0., 0., 1.), v(1., 0., 1.), v(1., 1., 1.), v(0., 1., 1.))); + t.extend(q(v(0., 0., 0.), v(1., 0., 0.), v(1., 0., 1.), v(0., 0., 1.))); + t.extend(q(v(0., 1., 0.), v(0., 1., 1.), v(1., 1., 1.), v(1., 1., 0.))); + t.extend(q(v(0., 0., 0.), v(0., 0., 1.), v(0., 1., 1.), v(0., 1., 0.))); + t.extend(q(v(1., 0., 0.), v(1., 1., 0.), v(1., 1., 1.), v(1., 0., 1.))); + t + } + + #[test] + fn box_moments_and_distance() { + let c = cube(10.0, [5.0, -3.0, 2.0]); + let (v, com, pm) = mass_properties(&c); + assert!((v - 1000.0).abs() < 1e-9 && (com[0] - 10.0).abs() < 1e-9 && (com[2] - 7.0).abs() < 1e-9); + // V·(a²+b²)/12 for a cube of side 10: 1000·200/12. + for m in pm { + assert!((m - 1000.0 * 200.0 / 12.0).abs() < 1e-6, "{pm:?}"); + } + let moved = cube(10.0, [5.0, -3.0, 2.3]); + let h = hausdorff(&c, &moved, 1.0); + assert!((h.a_to_b - 0.3).abs() < 1e-9 && (h.b_to_a - 0.3).abs() < 1e-9); + let same = hausdorff(&c, &c, 1.0); + assert!(same.a_to_b < 1e-12); + } +} diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index ffe3dbe9..1f319341 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -25,7 +25,7 @@ - [Persistent naming](dev/naming.md) - [Test harnesses](dev/testing.md) - [Control protocol](dev/control-protocol.md) -- [Fusion oracle](dev/oracle.md) +- [Reference tests](dev/oracle.md) - [Command parity](dev/parity.md) - [STEP import](dev/step-import.md) diff --git a/docs/book/src/dev/architecture.md b/docs/book/src/dev/architecture.md index b2ad94c5..cd06991d 100644 --- a/docs/book/src/dev/architecture.md +++ b/docs/book/src/dev/architecture.md @@ -7,7 +7,7 @@ SolidCraft is a Cargo workspace in layers. A crate only depends on crates in low The web app, `apps/solvecraft-web`, is the desktop front end compiled to wasm with [trunk](https://trunkrs.dev). `xtask` holds the repository's own tooling: `cargo xtask ci`, -`layers`, `assets`, `oracle`, `parity`, `step-corpus` and `book`. +`layers`, `assets`, `oracle`, `parity` and `book`. A few rules follow from the layering: diff --git a/docs/book/src/dev/testing.md b/docs/book/src/dev/testing.md index 2e903b54..1d8ec605 100644 --- a/docs/book/src/dev/testing.md +++ b/docs/book/src/dev/testing.md @@ -13,8 +13,7 @@ profile and the wasm build check. | Layout tests | `crates/ui-egui/tests/ui_layout.rs`, `window_widths.rs` | panels and dialogs at every window width | | Design-file corpus | `apps/solvecraft-cli/tests/corpus` | every saved file version still opens and evaluates the same | | Kill mid-save | `apps/solvecraft-cli/tests/kill_mid_save.rs` | a save killed at any moment leaves a readable file | -| Fusion oracle | `cargo xtask oracle` → [docs/oracle.md](oracle.md) | parts rebuilt from recipes, compared with Fusion's measurements | -| STEP corpus | `cargo xtask step-corpus` → [docs/step-import.md](step-import.md) | STEP files from Fusion opened and measured | +| Reference tests | `cargo xtask oracle` → [docs/oracle.md](oracle.md) | parts rebuilt from `tests/oracle/*/recipe.json`, compared with analytic or FreeCAD expected values | ## UI scenarios diff --git a/docs/book/src/introduction.md b/docs/book/src/introduction.md index e8848264..ce6462d0 100644 --- a/docs/book/src/introduction.md +++ b/docs/book/src/introduction.md @@ -21,7 +21,7 @@ also script, test or hand to an agent. SolidCraft is early. Sketching, solid modelling, parameters, components with joints, sheet metal and a plastic-enclosure subset work; surfaces, drawings, CAM and simulation are deferred. The [roadmap](https://github.com/bherbruck/solidcraft/blob/main/ROADMAP.md) has the details, and -[command parity](dev/parity.md) and the [Fusion oracle](dev/oracle.md) measure how far along it +[command parity](dev/parity.md) and the [reference tests](dev/oracle.md) measure how far along it is. Existing `.solvecraft` designs and `solvecraft-cli` commands keep their names and behavior. diff --git a/docs/iges-import.md b/docs/iges-import.md deleted file mode 100644 index 910d81bc..00000000 --- a/docs/iges-import.md +++ /dev/null @@ -1,84 +0,0 @@ -# IGES import (Fusion corpus) - -Generated by `cargo xtask step-corpus --iges`. Each case is a reference part exported from Fusion as IGES 5.3 (kept locally in `plan/fusion/oracle/`, never committed). SolidCraft opens `part.igs` exactly as File → Open does and compares with Fusion's measurements of the part it exported: body count, volume and area (relative tolerance 1e-3) and the number of faces read from the file. How IGES is read: see [STEP import](step-import.md#iges). 50-sweep-tight-bend is written by Fusion as five loose, partly degenerate surfaces (seams running into slits, a ring given twice); Fusion cannot read it back as a solid either. - -**75 / 76 files pass.** - -| Case | Result | Bodies | Volume mm³ (got / Fusion) | Area mm² (got / Fusion) | Faces (got / Fusion) | ms | Notes | -|---|---|---|---|---|---|---|---| -| 01-box | pass | Body1 | 24000.000 / 24000.000 | 5200.000 / 5200.000 | 6 / 6 | 35 | | -| 02-cylinder | pass | Body1 | 35339.346 / 35342.917 | 6125.844 / 6126.106 | 3 / 3 | 399 | | -| 03-box-through-hole | pass | Body1 | 45738.459 / 45738.053 | 9327.794 / 9327.788 | 7 / 7 | 292 | | -| 04-revolve-vase | pass | Body1 | 112488.577 / 112499.479 | 13156.092 / 13156.615 | 5 / 5 | 1515 | | -| 05-taper-extrude | pass | Body1 | 61814.826 / 61814.826 | 9676.915 / 9676.915 | 6 / 6 | 28 | | -| 06-symmetric-extrude | pass | Body1 | 30000.000 / 30000.000 | 6200.000 / 6200.000 | 6 / 6 | 33 | | -| 07-fillet-all-edges | pass | Body1 | 23340.463 / 23340.849 | 4726.195 / 4726.265 | 26 / 26 | 1285 | | -| 08-chamfer | pass | Body1 | 23730.667 / 23730.667 | 5029.352 / 5029.352 | 10 / 10 | 64 | | -| 09-shell | pass | Body1 | 13632.000 / 13632.000 | 13992.000 / 13992.000 | 11 / 11 | 76 | | -| 10-rect-pattern-holes | pass | Body1 | 29803.844 / 29803.540 | 14652.460 / 14652.389 | 18 / 18 | 1988 | | -| 11-circular-pattern-flange | pass | Body1 | 66758.418 / 66758.844 | 19320.582 / 19320.795 | 10 / 10 | 2360 | | -| 12-mirror-feature | pass | Body1 | 21392.312 / 21392.920 | 6530.923 / 6530.973 | 10 / 10 | 753 | | -| 13-combine-join | pass | Body1 | 45569.249 / 45571.680 | 8634.154 / 8634.336 | 9 / 9 | 383 | | -| 14-combine-cut | pass | Body1 | 42932.838 / 42931.417 | 9706.788 / 9706.858 | 7 / 7 | 1401 | | -| 15-combine-intersect | pass | Body1 | 54451.677 / 54454.273 | 7382.501 / 7382.743 | 7 / 7 | 2559 | solid 'Body1': face wrapping around a closed surface kept whole: unsupported seam loop layout (8 runs) | -| 16-sweep | pass | Body1 | 2584.300 / 2584.724 | 1779.617 / 1779.698 | 5 / 5 | 1957 | | -| 17-loft | pass | Body1 | 35120.291 / 35125.498 | 6495.290 / 6495.000 | 6 / 6 | 601 | | -| 18-hole-features | pass | Body1 | 33890.962 / 33890.710 | 8568.687 / 8568.696 | 13 / 13 | 1552 | | -| 19-l-bracket-constrained | pass | Body1 | 14720.000 / 14720.000 | 5472.000 / 5472.000 | 8 / 8 | 39 | | -| 20-slot-constrained | pass | Body1 | 2965.385 / 2965.487 | 1774.641 / 1774.690 | 6 / 6 | 88 | | -| 21-draft | pass | Body1 | 54574.737 / 54574.737 | 8781.998 / 8781.998 | 6 / 6 | 38 | | -| 22-split-body | pass | Body1, Body2 | 75390.604 / 75398.224 | 12954.438 / 12955.175 | 6 / 6 | 802 | | -| 23-bracket-multifeature | pass | Body1 | 59331.547 / 59331.129 | 18290.759 / 18290.737 | 19 / 19 | 1441 | | -| 24-user-parameters | pass | Body1 | 34822.114 / 34821.903 | 8114.166 / 8114.159 | 7 / 7 | 437 | | -| 25-sketch-triangle | pass | Body1 | 4032.155 / 4032.155 | 2274.099 / 2274.099 | 5 / 5 | 51 | | -| 26-sketch-belt | pass | Body1 | 11326.049 / 11326.170 | 5637.345 / 5637.404 | 7 / 7 | 599 | | -| 27-sketch-trapezoid | pass | Body1 | 5342.307 / 5342.257 | 3066.958 / 3066.946 | 8 / 8 | 832 | | -| 28-blind-pocket-fillets | pass | Body1 | 84299.377 / 84299.249 | 16279.553 / 16279.572 | 23 / 23 | 2087 | | -| 29-two-sided-and-partial-revolve | pass | Body1 | 25731.359 / 25731.307 | 6312.589 / 6312.602 | 12 / 12 | 229 | | -| 30-fillet-after-shell | pass | Body1 | 21745.916 / 21745.876 | 14968.283 / 14968.332 | 27 / 27 | 1298 | | -| 31-fillet-l-all-edges | pass | Body1 | 14321.380 / 14321.626 | 5023.977 / 5024.045 | 38 / 38 | 2673 | | -| 32-boss-plate-fillets | pass | Body1 | 33590.273 / 33590.350 | 9929.855 / 9929.864 | 10 / 10 | 3878 | | -| 33-fillet-tangent-chain | pass | Body1 | 8236.989 / 8237.122 | 2793.535 / 2793.569 | 14 / 14 | 1687 | | -| 34-chamfer-then-fillet | pass | Body1 | 22892.359 / 22892.421 | 4753.672 / 4753.688 | 18 / 18 | 577 | | -| 35-fillet-curved-curved | pass | Body1 | 63169.296 / 63171.443 | 10269.098 / 10269.348 | 6 / 6 | 9098 | solid 'Body1': face wrapping around a closed surface kept whole: split line does not reach the rings (×2); solid 'Body1': face wrapping around a closed surface kept whole: unsupported seam loop layout (8 runs) | -| 36-corner-blend-two-radii | pass | Body1 | 57799.380 / 57800.240 | 8585.423 / 8585.524 | 18 / 18 | 3015 | | -| 37-pyramid-apex-blend | pass | Body1 | 15465.384 / 15465.575 | 3914.545 / 3914.581 | 18 / 18 | 5090 | | -| 38-coincident-cylinders | pass | Body1 | 15706.154 / 15707.963 | 3769.748 / 3769.911 | 3 / 3 | 354 | | -| 39-tee-pipe | pass | Body1 | 24095.711 / 24096.237 | 16709.770 / 16710.048 | 7 / 7 | 2800 | solid 'Body1': face wrapping around a closed surface kept whole: unsupported seam loop layout (8 runs) (×2) | -| 40-box-sphere-torus | pass | Body1 | 36287.765 / 36287.433 | 10696.188 / 10696.165 | 10 / 10 | 6187 | | -| 41-tube-radial-holes | pass | Body1 | 20243.087 / 20243.981 | 14873.680 / 14873.773 | 22 / 22 | 9763 | | -| 42-overlapping-patterns | pass | Body1 | 38488.942 / 38487.064 | 21687.167 / 21686.603 | 43 / 43 | 5322 | a solid's shell does not close; solid 'Body1': imported as an open body (the shell is not closed) | -| 43-cut-splits-body | pass | Body1, Body2 | 28000.000 / 28000.000 | 7200.000 / 7200.000 | 12 / 12 | 128 | | -| 44-shell-l-bracket | pass | Body1 | 8384.000 / 8384.000 | 8784.000 / 8784.000 | 15 / 15 | 132 | | -| 45-shell-boss-plate | pass | Body1 | 13676.813 / 13676.602 | 14156.507 / 14156.602 | 15 / 15 | 785 | | -| 46-shell-two-open-faces | pass | Body1 | 16044.000 / 16044.000 | 11398.000 / 11398.000 | 10 / 10 | 141 | | -| 47-draft-curved-pocket | pass | Body1 | 111388.066 / 111387.712 | 17700.333 / 17700.361 | 11 / 11 | 290 | | -| 48-pulley | pass | Body1 | 168508.132 / 168510.841 | 23718.191 / 23718.644 | 12 / 12 | 4041 | | -| 49-helical-sweep | pass | Body1 | 4740.421 / 4738.099 | 4768.066 / 4767.652 | 3 / 3 | 33507 | | -| 50-sweep-tight-bend | FAIL | Body1 | 1621.826 / 3758.443 | – / – | 4 / 5 | 813 | the surfaces do not close into a solid: imported as an open body; solid 'Body1': face #231: face boundary is not a closed loop; solid 'Body1': imported as an open body (the shell is not closed) | -| 51-loft-rect-circle-offset | pass | Body1 | 61129.309 / 61133.116 | 9412.484 / 9411.655 | 6 / 6 | 532 | | -| 52-circular-pattern-fillet | pass | Body1 | 47206.121 / 47206.850 | 14141.995 / 14142.171 | 21 / 21 | 5990 | | -| 53-path-pattern | pass | Body1 | 35010.576 / 35010.398 | 16463.935 / 16463.894 | 13 / 13 | 1431 | | -| 54-mirror-body-fillets | pass | Body1 | 22780.189 / 22780.089 | 6972.821 / 6972.832 | 12 / 12 | 861 | | -| 55-tapped-hole-cosmetic | pass | Body1 | 17542.374 / 17542.314 | 4761.564 / 4761.596 | 8 / 8 | 543 | | -| 56-holes-on-curved-face | pass | Body1 | 77940.974 / 77942.388 | 10592.891 / 10593.139 | 7 / 7 | 3231 | solid 'Body1': face wrapping around a closed surface kept whole: a hole crosses the split line | -| 57-hole-pattern-sketch-points | pass | Body1 | 36767.089 / 36766.712 | 11818.157 / 11818.153 | 24 / 24 | 2099 | | -| 58-phone-stand | pass | Body1 | 74559.445 / 74559.177 | 29148.741 / 29148.785 | 19 / 19 | 181 | | -| 59-enclosure-base | pass | Body1 | 34309.026 / 34309.486 | 33795.404 / 33795.610 | 39 / 39 | 2120 | solid 'Body1': 2 face(s) could not be meshed and are not shown; solid 'Body1': face wrapping around a closed surface kept whole: cannot cut a ring edge at the split line (×4) | -| 60-pipe-flange | pass | Body1 | 323660.822 / 323660.979 | 56984.283 / 56984.564 | 16 / 16 | 4410 | | -| 61-shaft-keyway | pass | Body1 | 47521.369 / 47525.946 | 9676.777 / 9677.096 | 14 / 14 | 3019 | solid 'Body1': face wrapping around a closed surface kept whole: a hole crosses the split line | -| 62-heat-sink | pass | Body1 | 43125.000 / 43125.000 | 45725.000 / 45725.000 | 66 / 66 | 278 | | -| 63-hinge-knuckle | pass | Body1 | 4783.060 / 4783.117 | 4110.247 / 4110.287 | 14 / 14 | 974 | solid 'Body1': face wrapping around a closed surface kept whole: a hole crosses the split line | -| 64-sketch-tangent-arc-chain | pass | Body1 | 4800.000 / 4800.000 | 3843.701 / 3843.712 | 9 / 9 | 113 | | -| 65-sketch-gear-tooth | pass | Body1 | 3987.829 / 3988.084 | 1945.416 / 1945.485 | 9 / 9 | 119 | | -| 66-sketch-linkage | pass | Body1 | 8045.432 / 8045.386 | 4308.169 / 4308.175 | 10 / 10 | 1662 | | -| 67-sm-base-flange | pass | Body1 | 15000.000 / 15000.000 | 12800.000 / 12800.000 | 6 / 6 | 31 | | -| 68-sm-edge-flange | pass | Body1 | 18972.511 / 18972.622 | 16057.510 / 16057.550 | 14 / 14 | 182 | | -| 69-sm-tray | pass | Body1 | 29665.924 / 29666.234 | 24979.972 / 24980.086 | 46 / 46 | 568 | | -| 70-sm-flange-45 | pass | Body1 | 18450.720 / 18450.777 | 15629.618 / 15629.637 | 14 / 14 | 112 | | -| 71-sm-custom-rule | pass | Body1 | 10053.662 / 10053.717 | 13896.235 / 13896.299 | 22 / 22 | 277 | | -| 72-sm-contour-flange | pass | Body1 | 12097.511 / 12097.622 | 10411.960 / 10412.002 | 22 / 22 | 264 | | -| 73-sm-hem | pass | Body1 | 21334.436 / 21334.723 | 17994.374 / 17994.473 | 22 / 22 | 317 | | -| 74-sm-unfold-refold | pass | Body1 | 15800.138 / 15800.304 | 13610.263 / 13610.326 | 32 / 32 | 286 | | -| 75-sm-bracket-holes | pass | Body1 | 13915.905 / 13916.012 | 12035.926 / 12035.962 | 25 / 25 | 558 | | -| 76-sm-thickness-variant | pass | Body1 | 22520.416 / 22520.575 | 16064.080 / 16064.128 | 14 / 14 | 139 | | diff --git a/docs/oracle.md b/docs/oracle.md index 30eb452e..4e8ce5f2 100644 --- a/docs/oracle.md +++ b/docs/oracle.md @@ -1,96 +1,101 @@ -# Fusion oracle +# Reference tests -Generated by `cargo xtask oracle`. Each case is a part built in Fusion (recipe and measurements kept locally in `plan/fusion/oracle/`, not committed). SolidCraft replays the recipe through its command engine and compares body count, volume and area (relative tolerance 1e-3) and face/edge/vertex counts (exact). SolidCraft counts each closed-surface patch once and ignores seam edges and vertices; when body count, volume and area pass but the raw counts differ, Fusion's counts are normalised the same way from its face, edge and vertex lists (faces cut from one cylinder, cone, sphere or torus and separated only by seams count once; an edge on that surface and no other is a seam and is dropped; a vertex left with two edges joins them) and compared exactly; the note gives both sides' raw counts. +Generated by `cargo xtask oracle`. Each case in [`tests/oracle/`](../tests/oracle/) is a part described by our own `recipe.json`. SolidCraft replays the recipe through its command engine and compares the result with `expected.json`: body count, volume and area (relative tolerance 1e-3 unless the case states another), centre of mass and bounding box (within 1e-3 of the part's size), face count where the geometry fixes it, and, where the case has a `reference.stl`, the sampled symmetric (Hausdorff) distance between the two surfaces and the principal second moments of both triangulations. Every rebuilt part is also exported as STEP, validated and read back. -**76 / 76 cases pass** (0 need features not implemented yet). +Where the expected values come from (the **Source** column): -| Case | Result | Notes | -|---|---|---| -| 01-box | pass | | -| 02-cylinder | pass | | -| 03-box-through-hole | pass | | -| 04-revolve-vase | pass | | -| 05-taper-extrude | pass | | -| 06-symmetric-extrude | pass | | -| 07-fillet-all-edges | pass | | -| 08-chamfer | pass | | -| 09-shell | pass | | -| 10-rect-pattern-holes | pass | | -| 11-circular-pattern-flange | pass | | -| 12-mirror-feature | pass | | -| 13-combine-join | pass | | -| 14-combine-cut | pass | | -| 15-combine-intersect | pass | | -| 16-sweep | pass | | -| 17-loft | pass | | -| 18-hole-features | pass | | -| 19-l-bracket-constrained | pass | | -| 20-slot-constrained | pass | | -| 21-draft | pass | | -| 22-split-body | pass | | -| 23-bracket-multifeature | pass | | -| 24-user-parameters | pass | | -| 25-sketch-triangle | pass | | -| 26-sketch-belt | pass | | -| 27-sketch-trapezoid | pass | | -| 28-blind-pocket-fillets | pass | | -| 29-two-sided-and-partial-revolve | pass | | -| 30-fillet-after-shell | pass | | -| 31-fillet-l-all-edges | pass | | -| 32-boss-plate-fillets | pass | | -| 33-fillet-tangent-chain | pass | | -| 34-chamfer-then-fillet | pass | | -| 35-fillet-curved-curved | pass | topology compared seam-normalised: Fusion's 6/6/5 faces/edges/vertices become 6/5/5 with closed-surface patches counted once and seam edges and vertices dropped (raw SolidCraft/Fusion: faces 9/6, edges 17/6, vertices 10/5) | -| 36-corner-blend-two-radii | pass | | -| 37-pyramid-apex-blend | pass | | -| 38-coincident-cylinders | pass | | -| 39-tee-pipe | pass | | -| 40-box-sphere-torus | pass | | -| 41-tube-radial-holes | pass | | -| 42-overlapping-patterns | pass | | -| 43-cut-splits-body | pass | | -| 44-shell-l-bracket | pass | | -| 45-shell-boss-plate | pass | | -| 46-shell-two-open-faces | pass | | -| 47-draft-curved-pocket | pass | | -| 48-pulley | pass | | -| 49-helical-sweep | pass | Fusion sweeps along a spline fitted through helix points; SolidCraft builds the true helix (a coil), so the size is compared within 0.5% and the topology not at all | -| 50-sweep-tight-bend | pass | area not compared: Fusion reports this tight sweep's horn torus face at three times its area (π²·R·r quarter-turn value; 740 mm² against 246.7 by Pappus); volume and topology are compared | -| 51-loft-rect-circle-offset | pass | | -| 52-circular-pattern-fillet | pass | | -| 53-path-pattern | pass | | -| 54-mirror-body-fillets | pass | | -| 55-tapped-hole-cosmetic | pass | | -| 56-holes-on-curved-face | pass | topology compared seam-normalised: Fusion's 7/10/10 faces/edges/vertices become 7/8/8 with closed-surface patches counted once and seam edges and vertices dropped (raw SolidCraft/Fusion: faces 16/7, edges 32/10, vertices 19/10) | -| 57-hole-pattern-sketch-points | pass | | -| 58-phone-stand | pass | | -| 59-enclosure-base | pass | | -| 60-pipe-flange | pass | | -| 61-shaft-keyway | pass | topology compared seam-normalised: Fusion's 14/22/18 faces/edges/vertices become 14/20/16 with closed-surface patches counted once and seam edges and vertices dropped (raw SolidCraft/Fusion: faces 24/14, edges 54/22, vertices 34/18) | -| 62-heat-sink | pass | | -| 63-hinge-knuckle | pass | known Fusion difference: Gap replayed with the extent Fusion actually used (its through-all is sized as 1.1 × the farthest vertex, so curved tops stop it short; SolidCraft's through-all goes truly through) | -| 64-sketch-tangent-arc-chain | pass | | -| 65-sketch-gear-tooth | pass | | -| 66-sketch-linkage | pass | | -| 67-sm-base-flange | pass | | -| 68-sm-edge-flange | pass | | -| 69-sm-tray | pass | | -| 70-sm-flange-45 | pass | | -| 71-sm-custom-rule | pass | | -| 72-sm-contour-flange | pass | | -| 73-sm-hem | pass | | -| 74-sm-unfold-refold | pass | | -| 75-sm-bracket-holes | pass | | -| 76-sm-thickness-variant | pass | | +- **analytic**: closed-form geometry worked out by hand (prisms, cylinders, cones, spheres, tori and Pappus' theorems, constant-radius fillets on straight edges, sheet-metal bends as annular sectors). The scripts in [`tools/oracle-analytic/`](../tools/oracle-analytic/) compute them and give the formulas. +- **freecad <version>**: the same recipe built with FreeCAD's public Python scripting API by [`tools/freecad-oracle/`](../tools/freecad-oracle/), an independent kernel run as an external program. FreeCAD is not a dependency of SolidCraft. Where the two kernels legitimately build a different shape (for example the corner patch where fillets meet), only volume and area are compared, within the tolerance the case states. -## No oracle +No expected value comes from a commercial CAD product. -| Feature | Status | Tested by | -|---|---|---| -| Boss (draft, root fillet, hole, ribs) | no oracle (licence) | post, hole and rib volumes (`boss_with_hole_fillet_and_ribs`) | -| Lip / Groove | no oracle (licence) | band offsets and groove clearance on a shelled box (`lip_and_groove_on_a_shelled_box`, `groove_takes_the_rule_clearance`) | -| Snap Fit | no oracle (licence) | arm and catch volume, hook direction (`snap_fit_arm_and_catch`) | -| Rest | no oracle (licence) | rectangle, round, hollow and drafted pads (`rest_pads`) | -| Plastic Rules (manage, assign) | no oracle (licence) | library values, Thickness-based values, rule draft as the boss default (`plastic_rules_library_edit_and_assign`) | +**75 / 76 cases pass**; sources: 55 analytic, 21 freecad. 1 known failure(s) tracked in issues; 0 case(s) without expected values yet. -Fusion builds these only with its Design Extension, which the oracle account lacks, so there is no Fusion part to compare with. They follow Autodesk's public descriptions of the features and are checked against hand-computed geometry; the plastic rule library values were read from Fusion's API. +| Case | Source | Result | Surface distance mm (max / mean) | Method | Notes | +|---|---|---|---|---|---| +| 01-box | analytic | pass | | box 40 x 30 x 20 from the origin: V = abc, A = 2(ab + bc + ca) | | +| 02-cylinder | analytic | pass | | cylinder r=15 h=50 on XY: V = pi r^2 h, A = 2 pi r^2 + 2 pi r h | | +| 03-box-through-hole | analytic | pass | | box 60x40x20 minus centred through cylinder r=6: V = abc - pi r^2 c, A = 2(ab+bc+ca) - 2 pi r^2 + 2 pi r c; hole is centred so the centroid stays at the box centre | | +| 04-revolve-vase | analytic | pass | | revolve of a line/3-point-arc profile (XZ, x = radius, z = -sketch y) 360 deg about Z. Pappus/Green: V = 2 pi * int x dA, z_c = int x z dA / int x dA, A = sum over profile edges of 2 pi int x ds (bottom disk r20, frustum r20->25, torus zone of the arc (centre (-16.000000, 33.000000), R=41.109610), frustum r15->18, top disk r18) | | +| 05-taper-extrude | analytic | pass | | square frustum: base 40 at z=0, top a1 = 40 + 2*30*tan10 at z=30 (positive taper grows outward); V = h/3 (A0 + A1 + sqrt(A0 A1)), z_c = h (A0 + 2 sqrt(A0A1) + 3 A1) / (4 (A0 + sqrt(A0A1) + A1)), sides = 4 trapezoids (a0+a1)/2 * h/cos(10) | | +| 06-symmetric-extrude | analytic | pass | | 50 (x) by 20 (z) rectangle on XZ extruded +-15 along Y: box 50x30x20 centred at origin | | +| 07-fillet-all-edges | analytic | pass | | box 40x30x20 with every edge rounded r=3 = inner box (34x24x14) grown by a ball r (Steiner): V = abc + 2r(ab+bc+ca) + pi r^2 (a+b+c) + 4/3 pi r^3, A = 2(ab+bc+ca) + 2 pi r (a+b+c) + 4 pi r^2; faces 6 planes + 12 quarter cylinders + 8 sphere octants | | +| 08-chamfer | analytic | pass | | box 40x30x20 with the 4 top edges chamfered 2: lower box 40x30x18 + top slab with section (36+2u)x(26+2u) at depth u (V, moment by exact polynomial integration); A = bottom + sides(h=18) + top 36x26 + 4 trapezoid bevels of slant 2 sqrt2 | | +| 09-shell | analytic | pass | | 50x40x30 box shelled inward 2 with the top open: box minus cavity [2,48]x[2,38]x[2,30]; A = outer bottom + outer sides + rim + cavity floor + cavity walls | | +| 10-rect-pattern-holes | analytic | pass | | plate 90x70x5 minus 12 through cylinders r=3 at (15+20i, 15+20j), i<4, j<3: V = abc - 12 pi r^2 t, A = 2(ab+bc+ca) + 12(2 pi r t - 2 pi r^2) | | +| 11-circular-pattern-flange | analytic | pass | | annulus R50/r15 h10 minus 6 through cylinders r=5 on a 40 radius: V = pi(R^2-r^2)h - 6 pi rh^2 h, A = 2 pi(R^2-r^2) + 2 pi(R+r)h + 6(2 pi rh h - 2 pi rh^2); 6-fold symmetry keeps the centroid on the axis | | +| 12-mirror-feature | analytic | pass | | block [-30,30]x[0,30]x[0,10] + two bosses r=6 h=15 at (+-15,15) on top (mirror across YZ): V = abc + 2 pi r^2 h, A = 2(ab+bc+ca) + 2 * 2 pi r h | | +| 13-combine-join | analytic | pass | | box [0,40]^2x[0,20] union cylinder r=12 at (40,20) z 0..40: V = box + half-cylinder (x>40, z<20, centroid 40 + 4r/3pi) + full cylinder z 20..40; A = bottom (1600 + pi r^2/2) + box top (1600 - pi r^2/2) + cyl top + 3 full sides + x=40 side minus 24x20 + cyl side (pi r 40 outside half + pi r 20 upper inside half) | | +| 14-combine-cut | analytic | pass | | box [-25,25]^2x[-20,0] minus sphere r=15 at the origin (lower hemisphere removed): V = abc - 2/3 pi r^3, hemisphere centroid z = -3r/8; A = 2(ab+bc+ca) - pi r^2 + 2 pi r^2 | | +| 15-combine-intersect | analytic | pass | | cube [-20,20]^3 intersect sphere R=25: sphere minus 6 disjoint caps of height h=5 (caps cannot overlap: two would need x^2+y^2 > 800 > R^2); V = 4/3 pi R^3 - 6 pi h^2 (3R-h)/3, A = 4 pi R^2 - 6 * 2 pi R h + 6 pi (R^2-20^2) | | +| 16-sweep | analytic | pass | | circle r=3 swept along line 30 (+Z) + tangent R20 quarter arc + line 30 (+X): two cylinders + quarter torus (Pappus: V = pi r^2 R theta, A = 2 pi r R theta; torus centroid at rho = (R^2 + r^2/4)/R * sin(theta/2)/(theta/2) from the bend axis along the bisector) + 2 end disks | | +| 17-loft | freecad 1.1.4 | pass | 0.013 / 0.0019 (worst at -7.9, -10.8, 31.2) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part.makeLoft | | +| 18-hole-features | analytic | pass | | plate 60x40x15 minus: counterbore (r7 x 5 deep + r4 through), countersink (90 deg cone frustum r6->r3 over 3 mm + r3 through), blind r3 hole 10 deep to the shoulder with a 118 deg cone point (height 3/tan59, centroid 1/4 up from the apex); areas: removed top/bottom disks, cylinder walls 2 pi r h, cb floor annulus, cone laterals pi r s | | +| 19-l-bracket-constrained | analytic | pass | | solved L: (0,0)-(60,0)-(60,8)-(8,8)-(8,40)-(0,40); area 60x8 + 8x32, extruded 20: V = A2 h, A = 2 A2 + perimeter*h, centroid of the two rectangles | | +| 20-slot-constrained | analytic | pass | | obround: arc centres (0,0) and (40,0), R6, tangent horizontal lines y=+-6: A2 = 2rL + pi r^2, V = A2 h, A = 2 A2 + perimeter (2L + 2 pi r) h | | +| 21-draft | analytic | pass | | 40x40x30 box, 5 deg draft hinged on the bottom (z=0), pull -Z: square frustum 40 -> 40 + 2*30*tan5; V = h/3 (A0 + A1 + sqrt(A0A1)), sides 4 trapezoids of slant h/cos5 | | +| 22-split-body | analytic | pass | | cylinder r20 z -30..30 split by the plane through the X axis tilted 30 deg (z = y tan30, stays within /z/<=11.6 inside the cylinder): 2 congruent halves (point symmetry), V total = pi r^2 h, A total = cylinder + 2 ellipses pi r (r/cos30) | | +| 23-bracket-multifeature | freecad 1.1.4 | pass | 0.007 / 0.0010 (worst at 57.3, 49.3, 25.8) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part makeFillet, Part extrude join, Part extrude cut, Part makeChamfer | | +| 24-user-parameters | analytic | pass | | width 60 x depth 40 x height 15 block from the origin with a centred d10 through hole: V = (wd - pi r^2) h, A = 2(wd - pi r^2) + 2(w+d)h + 2 pi r h | | +| 25-sketch-triangle | analytic | pass | | solved triangle (0,0), (50,0), P = t(cos60, sin60) with t = 25 + sqrt(150) from /P-(50,0)/ = 45 (the root nearest the drawn apex); V = (1/2 * 50 * Py) * 5, A = 2 A2 + perimeter*5, centroid = vertex mean | | +| 26-sketch-belt | analytic | pass | | belt: convex hull of circles R20 @ (0,0) and r10 @ (50,0) (external tangents, sin a = (R-r)/d) minus the d8 hole at (50,0), extruded 5 as one body; hull area = (R+r) sqrt(d^2-(R-r)^2) + R^2(pi+2a)/2 + r^2(pi-2a)/2; moments by Green's theorem over the line/arc boundary | | +| 27-sketch-trapezoid | analytic | pass | | solved trapezoid bottom (-30,0)-(30,0), top (-15,25)-(15,25) minus two d6 holes at (+-18, 8) (symmetric about the axis, 36 apart, 8 above l1); trapezoid centroid y = H(a+2b)/(3(a+b)); V = A2 t, A = 2 A2 + perimeter t | | +| 28-blind-pocket-fillets | freecad 1.1.4 | pass | 0.009 / 0.0015 (worst at 60.0, 15.1, 13.4) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, Part makeFillet | | +| 29-two-sided-and-partial-revolve | analytic | pass | | block [-20,20]x[-25,10]x[0,20] minus the 270 deg revolve (from +X towards +Y) of the 8x8 square r 4..12, z 12..20; the removed section is the annular sector minus the circular segment y > 10 (R^2 acos(d/R) - d sqrt(R^2-d^2), y-moment 2/3 (R^2-d^2)^1.5) that lies outside the block; sector moments (R^3-r^3)/3 (sin, 1-cos); A = box - top opening + floor - front-face notch 2 sqrt(44) x 8 + inner wall r th h + outer wall (th - pi + 2 asin(5/6)) R h + 2 end caps | | +| 30-fillet-after-shell | freecad 1.1.4 | pass | 0.008 / 0.0025 (worst at 56.3, 35.7, 3.5) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, makeThickness shell, Part makeFillet | | +| 31-fillet-l-all-edges | freecad 1.1.4 | pass | 0.009 / 0.0018 (worst at 7.9, 38.6, 18.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet | | +| 32-boss-plate-fillets | analytic | pass | | plate 60x60x8 + boss (r10, z 8..23) with R3 concave base and R2 convex top fillets taken as one solid of revolution: V, z-moment and lateral area from Pappus/Green on its (r,z) profile (quarter-circle fillet arcs); plate top loses the r13 disc | | +| 33-fillet-tangent-chain | analytic | pass | | obround (R8, centres 40 apart) x 10 minus R2 fillet spandrel R^2(1-pi/4) and 1 mm chamfer triangle swept round the whole loop (Pappus: section x path of its centroid, inset R(10-3pi)/(3(4-pi)) resp. c/3); surfaces likewise (fillet arc centroid inset R-2R/pi) | | +| 34-chamfer-then-fillet | freecad 1.1.4 | pass | 0.009 / 0.0022 (worst at 38.5, 5.6, 19.9) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeChamfer, Part makeFillet | | +| 35-fillet-curved-curved | freecad 1.1.4 | pass | 0.011 / 0.0024 (worst at -9.5, 5.3, 14.6) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part makeFillet | | +| 36-corner-blend-two-radii | freecad 1.1.4 | pass | 0.012 / 0.0026 (worst at 45.4, 39.2, 26.5) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet | | +| 37-pyramid-apex-blend | freecad 1.1.4 | pass | 0.020 / 0.0029 (worst at -0.0, 0.0, 28.4) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part.makeLoft, Part makeFillet | | +| 38-coincident-cylinders | analytic | pass | | union of r10 z0..30 and r10 z20..50 = cylinder r10 h50: V = pi r^2 h, A = 2 pi r h + 2 pi r^2 | | +| 39-tee-pipe | freecad 1.1.4 | pass | 0.008 / 0.0014 (worst at -9.7, 2.4, 40.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part extrude cut | | +| 40-box-sphere-torus | analytic | pass | | box 60x60x10 (z -10..0) + upper hemisphere r12 + spherical cap h2 below z=-10 (V = pi h^2(3R-h)/3, A = 2 pi R h) - lower half torus R22 r4 (Pappus: V = pi r^2/2 * 2 pi R, centroid -4r/3pi, A = pi r * 2 pi R); top loses disc r12 and annulus 18..26, bottom loses disc r sqrt(44) | faces: bottom, 4 sides, top split by the groove into an annulus (r 12..18) and the outer part, upper sphere, lower cap, torus | +| 41-tube-radial-holes | freecad 1.1.4 | pass | 0.010 / 0.0012 (worst at 1.9, 19.9, 24.8) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, pattern (tools transformed and re-applied) | | +| 42-overlapping-patterns | freecad 1.1.4 | pass | 0.030 / 0.0010 (worst at -20.0, -0.0, 5.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, pattern (tools transformed and re-applied), Part extrude cut, pattern (tools transformed and re-applied) | | +| 43-cut-splits-body | analytic | pass | | two boxes 35x20x20 (x 0..35 and 45..80): V = 2abc, A = 2*2(ab+bc+ca) | | +| 44-shell-l-bracket | analytic | pass | | L prism (area 736, perimeter 200) x 20 minus cavity = L shrunk by 2 (SolidCraft's intersection-join shell convention: inner faces offset by 2 and extended to meet, sharp inner corner at (6,6); area 352) from z=2 to 20. A rounded (arc) join would give V 8368.5487, A 8768.5487, 16 faces | | +| 45-shell-boss-plate | analytic | pass | | plate 60x60x10 + boss r12 h20 minus cavity (box 56x56x8 + cylinder r10 z8..28) under SolidCraft's intersection-join shell convention (offset faces extended to meet: sharp circular inner edge at r10, z8). A rounded (arc) join would give V 13620.2567, A 14104.4455, 16 faces (torus round r2) | | +| 46-shell-two-open-faces | analytic | pass | | box 50x40x30 minus cavity x3..47, y0..37, z3..30 (3 mm walls, top and front open) | | +| 47-draft-curved-pocket | freecad 1.1.4 | pass | 0.008 / 0.0019 (worst at 22.1, 21.3, 15.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, PartDesign Draft | | +| 48-pulley | analytic | pass | | revolve of the 12-segment (r,z) polygon about Z: V = 2 pi int r dA, Mz = 2 pi int r z dA, A = 2 pi int r ds (Pappus) | | +| 49-helical-sweep | analytic | pass | | true helix coil (screw motion of the axial d4 section, R20, pitch 8, 3 turns): V = turns * 2 pi R * pi a^2; lateral A = turns * 2 pi * int sqrt(r^2 + (p/2pi)^2 (dr/ds)^2) ds (periodic trapezoid, exact to round-off) + two end discs; COM z = pitch*turns/2 | | +| 50-sweep-tight-bend | analytic | pass | | tube r5 along line 20 + R5 quarter bend + line 20: V = pi r^2 L, A = 2 pi r L + 2 pi r^2 (Pappus, valid while bend radius >= r; here equal so the inner side pinches to a line); bend centroid at (R^2 + r^2/4)/R * sinc(pi/4) along the bisector | | +| 51-loft-rect-circle-offset | freecad 1.1.4 | pass | 0.025 / 0.0030 (worst at -11.7, 15.0, 0.4) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part.makeLoft | | +| 52-circular-pattern-fillet | analytic | pass | | disc r40 h8 + 6 x (boss r6 h10 with R2 concave base fillet as a solid of revolution, Pappus/Green on its (r,z) profile) at radius 28; disc top loses 6 discs r8 | | +| 53-path-pattern | analytic | pass | | plate 120x60x5 minus 7 through holes d6 at arc lengths k*17.875031 along the arc through (100,15),(60,45),(20,15) (centre (60,10/3), R 125/3), translated copies | | +| 54-mirror-body-fillets | analytic | pass | | prism h10 of the 60x40 rectangle with four R5 corner rounds and two d8 holes at (+-15,20): V = A h, area = 2A + perimeter*h | | +| 55-tapped-hole-cosmetic | analytic | pass | | plate 40x30x15 minus d6.8 cylinder 12 deep (to the shoulder) and 118 deg drill point cone (h = r/tan59, V = pi r^2 h/3, lateral pi r * r/sin59); cosmetic thread adds no geometry | | +| 56-holes-on-curved-face | freecad 1.1.4 | pass | 0.009 / 0.0018 (worst at -16.9, 18.5, 0.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, hole tool (cylinder/cone) cut | | +| 57-hole-pattern-sketch-points | analytic | pass | | plate 80x50x10 minus 6 counterbored through holes (cb d10 x 5.5, hole d5.5) at x 15/40/65, y 15/35 | | +| 58-phone-stand | freecad 1.1.4 | pass | 0.007 / 0.0010 (worst at 82.5, 11.7, 6.1) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet, Part extrude cut | | +| 59-enclosure-base | freecad 1.1.4 | pass | 0.008 / 0.0017 (worst at 90.9, 51.0, 6.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet, makeThickness shell, Part extrude join, Part extrude cut | | +| 60-pipe-flange | freecad 1.1.4 | pass | | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part revolve, Part extrude cut, pattern (tools transformed and re-applied), Part makeChamfer, Part makeFillet | No reference.stl: over 409600 bytes even at 0.02 mm deflection (11380 facets). | +| 61-shaft-keyway | freecad 1.1.4 | pass | 0.008 / 0.0019 (worst at 11.9, 3.9, 45.8) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part revolve, Part makeChamfer, Part extrude cut | | +| 62-heat-sink | analytic | pass | | base 60x50x5 + 15 fins 1.5x50x25 at x = 2 + 4k: sums of boxes; fin ends coplanar with the base ends | faces: bottom, x=0, x=60, y=0 and y=50 (each merged with the fin ends), 16 base-top strips, 15x3 fin faces | +| 63-hinge-knuckle | freecad 1.1.4 | pass | 0.008 / 0.0016 (worst at 28.0, 36.9, 4.7) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part extrude cut | | +| 64-sketch-tangent-arc-chain | analytic | pass | | solved sketch: 80x20 rectangle whose top is 4 tangent R12 arcs on 20 mm chords alternating up/down (net area 1600); prism h3: V = A h, area = 2A + perimeter*h, Green's theorem for centroid | | +| 65-sketch-gear-tooth | freecad 1.1.4 | pass | 0.008 / 0.0017 (worst at 6.5, 39.5, 8.0) | FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Sketcher-solved sketch, Part extrude | | +| 66-sketch-linkage | analytic | pass | | solved sketch: hull of circles R12 at (0,0) and R8 at (60,0) (outer tangent lines, cos a = 4/60) minus holes d12, d8 (concentric) and d4 at (30,+-4) (symmetry keeps radii equal); prism h6 | | +| 67-sm-base-flange | analytic | pass | | plate 100 x 60 x t, t = 2.5 (Steel (mm) rule), thickness along +Z: V = 100*60*t, A = 2(ab+bc+ca) | | +| 68-sm-edge-flange | analytic | pass | | extrusion along x (100) of the YZ section: base y 5..60 x t; 90 deg bend annulus R 2.5..5 about (y 5, z 5); flange y 0..2.5, z 5..20. Setback (R+t)tan45 = 5 (inside bend position, outer-face height datum: outer face of flange reaches z = 20); V = L*A_sec, A = 2 A_sec + L P_sec | trim/setback and height datum are SolidCraft's documented edge-flange conventions (sheet.rs add_flanges) | +| 69-sm-tray | analytic | pass | | tray: base 90 x 50 x 2.5 (each edge trimmed by the setback 5); four 90 deg bends R 2.5..5 along the trimmed edges (90, 50, 90, 50 long); four walls 2.5 thick, z 5..25, each running on past its bend by ext = (R+t) - (t + gap/sqrt2) = 0.732233047 at both ends; open corners. A = sum of prisms - 2 x joints | corner treatment is SolidCraft's convention (sheet.rs close_corners: panels extended until their inner corners are the rule gap = t apart; no corner fill, open corner relief below the walls) | +| 70-sm-flange-45 | analytic | pass | | as 68 with a 45 deg bend: setback (R+t)tan22.5 = 2.071068, base y 2.071068..60, bend annulus 2.5..5 over 45 deg about (y 2.071068, z 5), flat leg 15 - setback = 12.928932 turned 45 deg; extrusion along x 100 | SolidCraft convention: flange height (15) is measured along the flange's outer face from the virtual sharp at the original edge (y 0, z 0), so the outer top corner is at (y, z) = (-15 cos45, 15 sin45). | +| 71-sm-custom-rule | analytic | pass | | U channel, rule t 1.5, R 3, K 0.33 (K unused folded): base y 4.5..45.5 x 1.5; two 90 deg bend annuli R 3..4.5; flanges y 0..1.5 and 48.5..50, z 4.5..20; extrusion along x 80 | the rule edit applies to the whole sheet body (base built before it is 1.5 thick too, as the recipe's edge picks at z = 1.5 state) | +| 72-sm-contour-flange | analytic | pass | | contour flange, width 50 along +Y, XZ section: plate x 0..35 z 0..2.5; bend R 2.5..5 about (35, 5) (sketch corner = outer virtual sharp, setback R+t); wall x 37.5..40 z 5..27.5; bend R 2.5..5 about (42.5, 27.5) (sketch corner = inner virtual sharp, setback R); plate x 42.5..70 z 30..32.5 | SolidCraft convention: the sketch lines are the sheet face away from the material (material right of travel); thickness grows to the material side | +| 73-sm-hem | analytic | pass | | 68's part (height 20) plus a flat hem on the flange top edge: 180 deg bend, inner radius = hem gap 0.01, outer 2.51, about (y 2.51, z 20), folded toward +y (inside); hem leg 8 - (0.01 + 2.5) = 5.49: y 2.52..5.02, z 14.51..20; extrusion along x 100 | SolidCraft conventions: hem gap 0.01 mm (rule hem_gap), hem length measured to the outer face of the hem bend (top at z 22.51), hem folds over the flange's inner face. | +| 74-sm-unfold-refold | analytic | pass | | U channel 80x50 (t 2.5, R 2.5, base y 5..45, flanges z 5..20) with the flat-pattern slot x 35..45, y -12..10 refolded: BA = (pi/2)(R + K t) = 5.654866776, so the slot removes base y 5..10, the whole y=0 bend and the flange from z 5 to 5 + (12 - (BA - 5)) = 16.345133224; x-segments 0..35 / 35..45 / 45..80 | unfold/refold maps flat distance through the K-factor neutral layer (K 0.44) | +| 75-sm-bracket-holes | analytic | known failure (#296) | | base x 0..75, y 5..40, z 0..2.5 (trimmed 5 by each flange's setback); bend 1 (R 2.5..5 about y 5, z 5) x 0..75; flange 1 y 0..2.5, z 5..30, x 0..80; bend 2 (R 2.5..5 about x 75, z 5) y 5..40; flange 2 x 77.5..80, z 5..15, y 5..40; minus two d6 through holes at (25,20), (55,20) in the base. A = sum of prism areas - 2 x 4 joint areas (75t, 75t, 35t, 35t) + hole walls - hole discs | step 14 (solid.extrude): invalid input: sew: nonmanifold edge contact; SolidCraft convention: the second flange trims the base under the first bend, so bend 1 stops at x 75 while flange 1's panel runs to x 80 (open corner relief, no fill). | +| 76-sm-thickness-variant | analytic | pass | | final rule thickness 3 (bend radius = Thickness = 3): base y 6..60 x 3; bend annulus R 3..6 about (y 6, z 6); flange y 0..3, z 6..20; extrusion along x 100 | the rule's thickness edits regenerate the whole sheet body; only the final 3 mm state matters | + +## Not covered by a reference case + +| Feature | Tested by | +|---|---| +| Boss (draft, root fillet, hole, ribs) | post, hole and rib volumes (`boss_with_hole_fillet_and_ribs`) | +| Lip / Groove | band offsets and groove clearance on a shelled box (`lip_and_groove_on_a_shelled_box`, `groove_takes_the_rule_clearance`) | +| Snap Fit | arm and catch volume, hook direction (`snap_fit_arm_and_catch`) | +| Rest | rectangle, round, hollow and drafted pads (`rest_pads`) | +| Plastic Rules (manage, assign) | library values, Thickness-based values, rule draft as the boss default (`plastic_rules_library_edit_and_assign`) | diff --git a/docs/robustness.md b/docs/robustness.md index 0713bdbc..b5f3fa7a 100644 --- a/docs/robustness.md +++ b/docs/robustness.md @@ -1,6 +1,6 @@ # Kernel robustness -Real users hit edge cases the Fusion oracle (docs/oracle.md) never sees: faces that coincide +Real users hit edge cases the reference tests (docs/oracle.md) never see: faces that coincide by accident, tangencies, seams lying where another body cuts, walls thinner than a shell. The robustness runs build random but realistic designs and check every step. diff --git a/docs/step-import.md b/docs/step-import.md index bb373090..62032213 100644 --- a/docs/step-import.md +++ b/docs/step-import.md @@ -18,88 +18,3 @@ display on the resulting body. ## IGES IGES 5.3 files (`.igs`/`.iges`) open, insert and drop the same way: `crates/kernel/src/iges_in.rs` (written from the published specification) restates the file as STEP and the STEP reader reads it, so the feature holds STEP text. Read: manifold solid B-reps (186) with their shells, faces, loops, edge and vertex lists; trimmed (144) and bounded (143) surfaces, and bare B-spline patches, sewn into a solid by their shared edges (an open body when they do not close); lines, circular arcs, ellipses, composite curves, rational B-spline curves; planes (108, 190), cylinders, cones, spheres, tori, rational B-spline surfaces, surfaces of revolution and tabulated cylinders; transformation matrices; units; colours (314 and the predefined numbers); body names (name properties, else labels). Not read yet: ruled and offset surfaces, curves on surfaces given only in parameter space. Export (`file.export` to `.igs`) writes each body as a manifold solid B-rep on the same surfaces a STEP export uses, with its name and colour. - -## 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). SolidCraft 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 | | diff --git a/tests/oracle/01-box/expected.json b/tests/oracle/01-box/expected.json new file mode 100644 index 00000000..51353dfe --- /dev/null +++ b/tests/oracle/01-box/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box 40 x 30 x 20 from the origin: V = abc, A = 2(ab + bc + ca)", + "body_count": 1, + "volume_mm3": 24000.0, + "area_mm2": 5200.0, + "center_of_mass": [ + 20.0, + 15.0, + 10.0 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 40.0, + 30.0, + 20.0 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/01-box/recipe.json b/tests/oracle/01-box/recipe.json new file mode 100644 index 00000000..35aa4db4 --- /dev/null +++ b/tests/oracle/01-box/recipe.json @@ -0,0 +1,153 @@ +{ + "id": "01-box", + "name": "Box extrude", + "description": "40 x 30 rectangle on XY extruded 20 mm.", + "exercises": [ + "sketch", + "extrude" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + } + ] +} diff --git a/tests/oracle/02-cylinder/expected.json b/tests/oracle/02-cylinder/expected.json new file mode 100644 index 00000000..6113b075 --- /dev/null +++ b/tests/oracle/02-cylinder/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "cylinder r=15 h=50 on XY: V = pi r^2 h, A = 2 pi r^2 + 2 pi r h", + "body_count": 1, + "volume_mm3": 35342.917352885175, + "area_mm2": 6126.105674500097, + "center_of_mass": [ + 0.0, + 0.0, + 25.0 + ], + "bbox": { + "min": [ + -15.0, + -15.0, + 0.0 + ], + "max": [ + 15.0, + 15.0, + 50.0 + ] + }, + "faces": 3 +} diff --git a/tests/oracle/02-cylinder/recipe.json b/tests/oracle/02-cylinder/recipe.json new file mode 100644 index 00000000..cdec45a6 --- /dev/null +++ b/tests/oracle/02-cylinder/recipe.json @@ -0,0 +1,94 @@ +{ + "id": "02-cylinder", + "name": "Cylinder", + "description": "Circle r=15 at origin on XY extruded 50 mm.", + "exercises": [ + "sketch", + "circle", + "extrude" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 15, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 50, + "direction": "positive" + }, + "result_bodies": [ + "Cylinder" + ] + } + ] +} diff --git a/tests/oracle/03-box-through-hole/expected.json b/tests/oracle/03-box-through-hole/expected.json new file mode 100644 index 00000000..a219555b --- /dev/null +++ b/tests/oracle/03-box-through-hole/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box 60x40x20 minus centred through cylinder r=6: V = abc - pi r^2 c, A = 2(ab+bc+ca) - 2 pi r^2 + 2 pi r c; hole is centred so the centroid stays at the box centre", + "body_count": 1, + "volume_mm3": 45738.05328941535, + "area_mm2": 9327.787565803084, + "center_of_mass": [ + 30.0, + 20.0, + 10.0 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 60.0, + 40.0, + 20.0 + ] + }, + "faces": 7 +} diff --git a/tests/oracle/03-box-through-hole/recipe.json b/tests/oracle/03-box-through-hole/recipe.json new file mode 100644 index 00000000..5f91ab59 --- /dev/null +++ b/tests/oracle/03-box-through-hole/recipe.json @@ -0,0 +1,240 @@ +{ + "id": "03-box-through-hole", + "name": "Box with through hole", + "description": "60x40x20 box; d=12 circle sketched on the top face at the face centre, cut through all.", + "exercises": [ + "extrude", + "sketch_on_face", + "extrude_cut", + "through_all" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 60, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 60.0, + 0.0 + ] + }, + "end": { + "at": [ + 60, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 60.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "sketch", + "name": "Sketch2", + "plane": { + "ref": "face: top planar face of Box (z=20, normal +Z)", + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 30.0, + 20.0, + 20.0 + ] + } + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 30.0, + 20.0 + ] + }, + "radius": 6, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Cut1", + "operation": "cut", + "profiles": [ + { + "sketch": "Sketch2", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "negative" + }, + "result_bodies": [ + "Box" + ] + } + ] +} diff --git a/tests/oracle/04-revolve-vase/expected.json b/tests/oracle/04-revolve-vase/expected.json new file mode 100644 index 00000000..e3806370 --- /dev/null +++ b/tests/oracle/04-revolve-vase/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "revolve of a line/3-point-arc profile (XZ, x = radius, z = -sketch y) 360 deg about Z. Pappus/Green: V = 2 pi * int x dA, z_c = int x z dA / int x dA, A = sum over profile edges of 2 pi int x ds (bottom disk r20, frustum r20->25, torus zone of the arc (centre (-16.000000, 33.000000), R=41.109610), frustum r15->18, top disk r18)", + "body_count": 1, + "volume_mm3": 112499.47865571639, + "area_mm2": 13156.614546780698, + "center_of_mass": [ + 0.0, + 0.0, + 35.737480169007014 + ], + "bbox": { + "min": [ + -25.10960958218893, + -25.10960958218893, + 0.0 + ], + "max": [ + 25.10960958218893, + 25.10960958218893, + 80.0 + ] + }, + "faces": 5 +} diff --git a/tests/oracle/04-revolve-vase/recipe.json b/tests/oracle/04-revolve-vase/recipe.json new file mode 100644 index 00000000..e912877b --- /dev/null +++ b/tests/oracle/04-revolve-vase/recipe.json @@ -0,0 +1,201 @@ +{ + "id": "04-revolve-vase", + "name": "Revolved vase profile", + "description": "Closed profile (lines + 3-point arc) on XZ revolved 360 deg about the world Z axis.", + "exercises": [ + "sketch_xz", + "arc", + "revolve" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Profile", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 20.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + 0.0 + ] + }, + "end": { + "at": [ + 25.0, + -30.0 + ] + }, + "id": "l2" + }, + { + "type": "arc_three_point", + "start": { + "ref": "l2.end", + "at": [ + 25.0, + -30.0 + ] + }, + "mid": [ + 23.0, + -46.0 + ], + "end": { + "at": [ + 15.0, + -60.0 + ] + }, + "id": "a1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 15.0, + -60.0 + ] + }, + "end": { + "at": [ + 18.0, + -80.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 18.0, + -80.0 + ] + }, + "end": { + "at": [ + 0.0, + -80.0 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 0.0, + -80.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l5" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "Revolve1", + "operation": "new", + "profile": { + "sketch": "Profile", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "l1", + "l2", + "l3", + "l4", + "l5" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "Vase" + ] + } + ] +} diff --git a/tests/oracle/05-taper-extrude/expected.json b/tests/oracle/05-taper-extrude/expected.json new file mode 100644 index 00000000..66252988 --- /dev/null +++ b/tests/oracle/05-taper-extrude/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "square frustum: base 40 at z=0, top a1 = 40 + 2*30*tan10 at z=30 (positive taper grows outward); V = h/3 (A0 + A1 + sqrt(A0 A1)), z_c = h (A0 + 2 sqrt(A0A1) + 3 A1) / (4 (A0 + sqrt(A0A1) + A1)), sides = 4 trapezoids (a0+a1)/2 * h/cos(10)", + "body_count": 1, + "volume_mm3": 61814.82595953696, + "area_mm2": 9676.91517028238, + "center_of_mass": [ + 0.0, + 0.0, + 16.162703882981894 + ], + "bbox": { + "min": [ + -25.28980942125395, + -25.28980942125395, + 0.0 + ], + "max": [ + 25.28980942125395, + 25.28980942125395, + 30.0 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/05-taper-extrude/recipe.json b/tests/oracle/05-taper-extrude/recipe.json new file mode 100644 index 00000000..74ab9fa5 --- /dev/null +++ b/tests/oracle/05-taper-extrude/recipe.json @@ -0,0 +1,154 @@ +{ + "id": "05-taper-extrude", + "name": "Tapered extrude", + "description": "40x40 square centred on origin, extruded 30 mm with a 10 deg taper.", + "exercises": [ + "extrude", + "taper" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -20, + -20 + ] + }, + "end": { + "at": [ + 20, + -20 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + -20.0 + ] + }, + "end": { + "at": [ + 20, + 20 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 20.0, + 20.0 + ] + }, + "end": { + "at": [ + -20, + 20 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -20.0, + 20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -20.0, + -20.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive", + "taper_deg": 10 + }, + "result_bodies": [ + "Frustum" + ] + } + ] +} diff --git a/tests/oracle/06-symmetric-extrude/expected.json b/tests/oracle/06-symmetric-extrude/expected.json new file mode 100644 index 00000000..6d001169 --- /dev/null +++ b/tests/oracle/06-symmetric-extrude/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "50 (x) by 20 (z) rectangle on XZ extruded +-15 along Y: box 50x30x20 centred at origin", + "body_count": 1, + "volume_mm3": 30000.0, + "area_mm2": 6200.0, + "center_of_mass": [ + 0.0, + 0.0, + 0.0 + ], + "bbox": { + "min": [ + -25.0, + -15.0, + -10.0 + ], + "max": [ + 25.0, + 15.0, + 10.0 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/06-symmetric-extrude/recipe.json b/tests/oracle/06-symmetric-extrude/recipe.json new file mode 100644 index 00000000..98c8fb65 --- /dev/null +++ b/tests/oracle/06-symmetric-extrude/recipe.json @@ -0,0 +1,155 @@ +{ + "id": "06-symmetric-extrude", + "name": "Symmetric extrude", + "description": "50x20 rectangle centred on origin on the XZ plane, extruded symmetrically 15 mm each side (30 total).", + "exercises": [ + "sketch_xz", + "extrude", + "symmetric" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -25, + -10 + ] + }, + "end": { + "at": [ + 25, + -10 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 25.0, + -10.0 + ] + }, + "end": { + "at": [ + 25, + 10 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 25.0, + 10.0 + ] + }, + "end": { + "at": [ + -25, + 10 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -25.0, + 10.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -25.0, + -10.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 15, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Block" + ] + } + ] +} diff --git a/tests/oracle/07-fillet-all-edges/expected.json b/tests/oracle/07-fillet-all-edges/expected.json new file mode 100644 index 00000000..8e81cae1 --- /dev/null +++ b/tests/oracle/07-fillet-all-edges/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box 40x30x20 with every edge rounded r=3 = inner box (34x24x14) grown by a ball r (Steiner): V = abc + 2r(ab+bc+ca) + pi r^2 (a+b+c) + 4/3 pi r^3, A = 2(ab+bc+ca) + 2 pi r (a+b+c) + 4 pi r^2; faces 6 planes + 12 quarter cylinders + 8 sphere octants", + "body_count": 1, + "volume_mm3": 23340.84937505542, + "area_mm2": 4726.265361880023, + "center_of_mass": [ + 20.0, + 15.0, + 10.0 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 40.0, + 30.0, + 20.0 + ] + }, + "faces": 26 +} diff --git a/tests/oracle/07-fillet-all-edges/recipe.json b/tests/oracle/07-fillet-all-edges/recipe.json new file mode 100644 index 00000000..6f7295b3 --- /dev/null +++ b/tests/oracle/07-fillet-all-edges/recipe.json @@ -0,0 +1,379 @@ +{ + "id": "07-fillet-all-edges", + "name": "Box with all edges filleted", + "description": "40x30x20 box, constant-radius 3 mm fillet on all 12 edges.", + "exercises": [ + "extrude", + "fillet" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "fillet", + "name": "Fillet1", + "type": "constant_radius", + "radius": 3, + "tangent_chain": false, + "edge_selection": "all 12 edges of Box", + "edges": [ + { + "type": "line", + "start": [ + 40.0, + 30.0, + 0.0 + ], + "end": [ + 0.0, + 30.0, + 0.0 + ], + "point": [ + 20.0, + 30.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 30.0, + 0.0 + ], + "end": [ + 0.0, + 30.0, + 20.0 + ], + "point": [ + 0.0, + 30.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 30.0, + 20.0 + ], + "end": [ + 0.0, + 30.0, + 20.0 + ], + "point": [ + 20.0, + 30.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 30.0, + 0.0 + ], + "end": [ + 40.0, + 30.0, + 20.0 + ], + "point": [ + 40.0, + 30.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 0.0, + 0.0 + ], + "end": [ + 40.0, + 30.0, + 0.0 + ], + "point": [ + 40.0, + 15.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 0.0, + 20.0 + ], + "end": [ + 40.0, + 30.0, + 20.0 + ], + "point": [ + 40.0, + 15.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 0.0, + 0.0 + ], + "end": [ + 40.0, + 0.0, + 20.0 + ], + "point": [ + 40.0, + 0.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 40.0, + 0.0, + 0.0 + ], + "point": [ + 20.0, + 0.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 20.0 + ], + "end": [ + 40.0, + 0.0, + 20.0 + ], + "point": [ + 20.0, + 0.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 20.0 + ], + "point": [ + 0.0, + 0.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 30.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 0.0 + ], + "point": [ + 0.0, + 15.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 30.0, + 20.0 + ], + "end": [ + 0.0, + 0.0, + 20.0 + ], + "point": [ + 0.0, + 15.0, + 20.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/08-chamfer/expected.json b/tests/oracle/08-chamfer/expected.json new file mode 100644 index 00000000..1018eb35 --- /dev/null +++ b/tests/oracle/08-chamfer/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box 40x30x20 with the 4 top edges chamfered 2: lower box 40x30x18 + top slab with section (36+2u)x(26+2u) at depth u (V, moment by exact polynomial integration); A = bottom + sides(h=18) + top 36x26 + 4 trapezoid bevels of slant 2 sqrt2", + "body_count": 1, + "volume_mm3": 23730.666666666668, + "area_mm2": 5029.352380466497, + "center_of_mass": [ + 19.999999999999996, + 15.0, + 9.894145409596582 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 40.0, + 30.0, + 20.0 + ] + }, + "faces": 10 +} diff --git a/tests/oracle/08-chamfer/recipe.json b/tests/oracle/08-chamfer/recipe.json new file mode 100644 index 00000000..d6b0e127 --- /dev/null +++ b/tests/oracle/08-chamfer/recipe.json @@ -0,0 +1,235 @@ +{ + "id": "08-chamfer", + "name": "Box with top edges chamfered", + "description": "40x30x20 box, equal-distance 2 mm chamfer on the 4 edges of the top face.", + "exercises": [ + "extrude", + "chamfer" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "chamfer", + "name": "Chamfer1", + "type": "equal_distance", + "distance": 2, + "tangent_chain": false, + "edge_selection": "the 4 edges bounding the top face (z=20)", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 30.0, + 20.0 + ], + "end": [ + 0.0, + 0.0, + 20.0 + ], + "point": [ + 0.0, + 15.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 20.0 + ], + "end": [ + 40.0, + 0.0, + 20.0 + ], + "point": [ + 20.0, + 0.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 0.0, + 20.0 + ], + "end": [ + 40.0, + 30.0, + 20.0 + ], + "point": [ + 40.0, + 15.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 30.0, + 20.0 + ], + "end": [ + 0.0, + 30.0, + 20.0 + ], + "point": [ + 20.0, + 30.0, + 20.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/09-shell/expected.json b/tests/oracle/09-shell/expected.json new file mode 100644 index 00000000..7f18e2b4 --- /dev/null +++ b/tests/oracle/09-shell/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "50x40x30 box shelled inward 2 with the top open: box minus cavity [2,48]x[2,38]x[2,30]; A = outer bottom + outer sides + rim + cavity floor + cavity walls", + "body_count": 1, + "volume_mm3": 13632.0, + "area_mm2": 13992.0, + "center_of_mass": [ + 25.0, + 20.0, + 11.598591549295774 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 50.0, + 40.0, + 30.0 + ] + }, + "faces": 11 +} diff --git a/tests/oracle/09-shell/recipe.json b/tests/oracle/09-shell/recipe.json new file mode 100644 index 00000000..cfd46dbb --- /dev/null +++ b/tests/oracle/09-shell/recipe.json @@ -0,0 +1,181 @@ +{ + "id": "09-shell", + "name": "Shelled open box", + "description": "50x40x30 box shelled inward 2 mm with the top face removed.", + "exercises": [ + "extrude", + "shell" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 50, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 50.0, + 0.0 + ] + }, + "end": { + "at": [ + 50, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 50.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "shell", + "name": "Shell1", + "faces_removed": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 25.0, + 20.0, + 30.0 + ] + } + ], + "face_selection": "top face (z=30)", + "inside_thickness": 2, + "outside_thickness": 0, + "tangent_chain": false + } + ] +} diff --git a/tests/oracle/10-rect-pattern-holes/expected.json b/tests/oracle/10-rect-pattern-holes/expected.json new file mode 100644 index 00000000..c3a98c80 --- /dev/null +++ b/tests/oracle/10-rect-pattern-holes/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "plate 90x70x5 minus 12 through cylinders r=3 at (15+20i, 15+20j), i<4, j<3: V = abc - 12 pi r^2 t, A = 2(ab+bc+ca) + 12(2 pi r t - 2 pi r^2)", + "body_count": 1, + "volume_mm3": 29803.53996706153, + "area_mm2": 14652.38934211693, + "center_of_mass": [ + 44.99999999999998, + 34.99999999999999, + 2.4999999999999964 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 90.0, + 70.0, + 5.0 + ] + }, + "faces": 18 +} diff --git a/tests/oracle/10-rect-pattern-holes/recipe.json b/tests/oracle/10-rect-pattern-holes/recipe.json new file mode 100644 index 00000000..6eea42bc --- /dev/null +++ b/tests/oracle/10-rect-pattern-holes/recipe.json @@ -0,0 +1,248 @@ +{ + "id": "10-rect-pattern-holes", + "name": "Rectangular pattern of holes", + "description": "90x70x5 plate; d=6 hole at (15,15) cut through; feature pattern 4 along X @20 mm x 3 along Y @20 mm.", + "exercises": [ + "extrude", + "extrude_cut", + "rectangular_pattern" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 90, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 90.0, + 0.0 + ] + }, + "end": { + "at": [ + 90, + 70 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 90.0, + 70.0 + ] + }, + "end": { + "at": [ + 0, + 70 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 70.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "sketch", + "name": "HoleSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 15, + 15 + ] + }, + "radius": 3, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Hole1", + "operation": "cut", + "profiles": [ + { + "sketch": "HoleSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "rectangular_pattern", + "name": "RectPattern1", + "pattern_of": "features", + "features": [ + "Hole1" + ], + "direction1": { + "axis": [ + 1, + 0, + 0 + ], + "count": 4, + "spacing": 20 + }, + "direction2": { + "axis": [ + 0, + 1, + 0 + ], + "count": 3, + "spacing": 20 + }, + "distance_type": "spacing (distance between instances)" + } + ] +} diff --git a/tests/oracle/11-circular-pattern-flange/expected.json b/tests/oracle/11-circular-pattern-flange/expected.json new file mode 100644 index 00000000..fdad437f --- /dev/null +++ b/tests/oracle/11-circular-pattern-flange/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "annulus R50/r15 h10 minus 6 through cylinders r=5 on a 40 radius: V = pi(R^2-r^2)h - 6 pi rh^2 h, A = 2 pi(R^2-r^2) + 2 pi(R+r)h + 6(2 pi rh h - 2 pi rh^2); 6-fold symmetry keeps the centroid on the axis", + "body_count": 1, + "volume_mm3": 66758.84388878311, + "area_mm2": 19320.79481957723, + "center_of_mass": [ + 0.0, + 0.0, + 5.0 + ], + "bbox": { + "min": [ + -50.0, + -50.0, + 0.0 + ], + "max": [ + 50.0, + 50.0, + 10.0 + ] + }, + "faces": 10 +} diff --git a/tests/oracle/11-circular-pattern-flange/recipe.json b/tests/oracle/11-circular-pattern-flange/recipe.json new file mode 100644 index 00000000..cba823ae --- /dev/null +++ b/tests/oracle/11-circular-pattern-flange/recipe.json @@ -0,0 +1,204 @@ +{ + "id": "11-circular-pattern-flange", + "name": "Flange with circular hole pattern", + "description": "Annulus OD100 / ID30 extruded 10; d=10 hole at (40,0) cut through; circular pattern x6 over 360 about Z.", + "exercises": [ + "extrude", + "annulus_profile", + "extrude_cut", + "circular_pattern" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "FlangeSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 50, + "id": "c_out" + }, + { + "type": "circle", + "center": { + "ref": "c_out.center", + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 15, + "id": "c_in" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Flange", + "operation": "new", + "profiles": [ + { + "sketch": "FlangeSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c_out" + ] + }, + { + "outer": false, + "curves": [ + "c_in" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Flange" + ] + }, + { + "op": "sketch", + "name": "HoleSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 40, + 0 + ] + }, + "radius": 5, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Hole1", + "operation": "cut", + "profiles": [ + { + "sketch": "HoleSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Flange" + ] + }, + { + "op": "circular_pattern", + "name": "CircPattern1", + "pattern_of": "features", + "features": [ + "Hole1" + ], + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "count": 6, + "total_angle": 360, + "symmetric": false + } + ] +} diff --git a/tests/oracle/12-mirror-feature/expected.json b/tests/oracle/12-mirror-feature/expected.json new file mode 100644 index 00000000..6a622297 --- /dev/null +++ b/tests/oracle/12-mirror-feature/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "block [-30,30]x[0,30]x[0,10] + two bosses r=6 h=15 at (+-15,15) on top (mirror across YZ): V = abc + 2 pi r^2 h, A = 2(ab+bc+ca) + 2 * 2 pi r h", + "body_count": 1, + "volume_mm3": 21392.920065876977, + "area_mm2": 6530.973355292325, + "center_of_mass": [ + 0.0, + 14.999999999999998, + 6.98250171986157 + ], + "bbox": { + "min": [ + -30.0, + 0.0, + 0.0 + ], + "max": [ + 30.0, + 30.0, + 25.0 + ] + }, + "faces": 10 +} diff --git a/tests/oracle/12-mirror-feature/recipe.json b/tests/oracle/12-mirror-feature/recipe.json new file mode 100644 index 00000000..3046c5e7 --- /dev/null +++ b/tests/oracle/12-mirror-feature/recipe.json @@ -0,0 +1,262 @@ +{ + "id": "12-mirror-feature", + "name": "Mirror feature", + "description": "60x30x10 block centred on X; d=12 boss 15 tall joined at (15,15) on top; boss feature mirrored across YZ.", + "exercises": [ + "extrude", + "extrude_join", + "mirror" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -30, + 0 + ] + }, + "end": { + "at": [ + 30, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 30.0, + 0.0 + ] + }, + "end": { + "at": [ + 30, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 30.0, + 30.0 + ] + }, + "end": { + "at": [ + -30, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -30.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -30.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Base", + "operation": "new", + "profiles": [ + { + "sketch": "Base_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Base" + ] + }, + { + "op": "sketch", + "name": "BossSketch", + "plane": { + "ref": "face: top face of Base (z=10)", + "origin": [ + 0.0, + 0.0, + 10.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 0.0, + 15.0, + 10.0 + ] + } + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 15.0, + 15.0 + ] + }, + "radius": 6, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Boss", + "operation": "join", + "profiles": [ + { + "sketch": "BossSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 15, + "direction": "positive" + }, + "result_bodies": [ + "Base" + ] + }, + { + "op": "mirror", + "name": "Mirror1", + "mirror_of": "features", + "features": [ + "Boss" + ], + "plane": { + "ref": "YZ", + "origin": [ + 0, + 0, + 0 + ], + "normal": [ + 1, + 0, + 0 + ] + }, + "operation": "join" + } + ] +} diff --git a/tests/oracle/13-combine-join/expected.json b/tests/oracle/13-combine-join/expected.json new file mode 100644 index 00000000..553f6b1e --- /dev/null +++ b/tests/oracle/13-combine-join/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box [0,40]^2x[0,20] union cylinder r=12 at (40,20) z 0..40: V = box + half-cylinder (x>40, z<20, centroid 40 + 4r/3pi) + full cylinder z 20..40; A = bottom (1600 + pi r^2/2) + box top (1600 - pi r^2/2) + cyl top + 3 full sides + x=40 side minus 24x20 + cyl side (pi r 40 outside half + pi r 20 upper inside half)", + "body_count": 1, + "volume_mm3": 45571.68026350791, + "area_mm2": 8634.336052701581, + "center_of_mass": [ + 26.46176756194705, + 19.999999999999996, + 13.970793611305016 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 52.0, + 40.0, + 40.0 + ] + }, + "faces": 9 +} diff --git a/tests/oracle/13-combine-join/recipe.json b/tests/oracle/13-combine-join/recipe.json new file mode 100644 index 00000000..14880a7d --- /dev/null +++ b/tests/oracle/13-combine-join/recipe.json @@ -0,0 +1,231 @@ +{ + "id": "13-combine-join", + "name": "Boolean union", + "description": "Box 40x40x20 at origin + cylinder r=12 h=40 at (40,20) as separate bodies, then combine join.", + "exercises": [ + "extrude", + "combine_join" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "BoxA_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "BoxA", + "operation": "new", + "profiles": [ + { + "sketch": "BoxA_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "A" + ] + }, + { + "op": "sketch", + "name": "CylSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 40, + 20 + ] + }, + "radius": 12, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "CylB", + "operation": "new", + "profiles": [ + { + "sketch": "CylSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 40, + "direction": "positive" + }, + "result_bodies": [ + "B" + ] + }, + { + "op": "combine", + "name": "Combine1", + "operation": "join", + "target_body": "A", + "tool_bodies": [ + "B" + ], + "keep_tools": false + } + ] +} diff --git a/tests/oracle/14-combine-cut/expected.json b/tests/oracle/14-combine-cut/expected.json new file mode 100644 index 00000000..ef851168 --- /dev/null +++ b/tests/oracle/14-combine-cut/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box [-25,25]^2x[-20,0] minus sphere r=15 at the origin (lower hemisphere removed): V = abc - 2/3 pi r^3, hemisphere centroid z = -3r/8; A = 2(ab+bc+ca) - pi r^2 + 2 pi r^2", + "body_count": 1, + "volume_mm3": 42931.41652942297, + "area_mm2": 9706.858347057703, + "center_of_mass": [ + 0.0, + 0.0, + -10.720336182305564 + ], + "bbox": { + "min": [ + -25.0, + -25.0, + -20.0 + ], + "max": [ + 25.0, + 25.0, + 0.0 + ] + }, + "faces": 7 +} diff --git a/tests/oracle/14-combine-cut/recipe.json b/tests/oracle/14-combine-cut/recipe.json new file mode 100644 index 00000000..812cb4ee --- /dev/null +++ b/tests/oracle/14-combine-cut/recipe.json @@ -0,0 +1,267 @@ +{ + "id": "14-combine-cut", + "name": "Boolean subtract", + "description": "Box (-25,-25,-20)..(25,25,0) minus a sphere r=15 at origin (hemispherical dimple).", + "exercises": [ + "extrude", + "revolve", + "combine_cut" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "BoxA_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -25, + -25 + ] + }, + "end": { + "at": [ + 25, + -25 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 25.0, + -25.0 + ] + }, + "end": { + "at": [ + 25, + 25 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 25.0, + 25.0 + ] + }, + "end": { + "at": [ + -25, + 25 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -25.0, + 25.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -25.0, + -25.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "BoxA", + "operation": "new", + "profiles": [ + { + "sketch": "BoxA_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "negative" + }, + "result_bodies": [ + "A" + ] + }, + { + "op": "sketch", + "name": "SphereB_sketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "arc_three_point", + "start": { + "at": [ + 0.0, + 15.0 + ] + }, + "mid": [ + 15.0, + 0.0 + ], + "end": { + "at": [ + 0.0, + -15.0 + ] + }, + "id": "a1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 0.0, + -15.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 0.0, + 15.0 + ] + }, + "id": "l1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "SphereB", + "operation": "new", + "profile": { + "sketch": "SphereB_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "l1" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "B" + ] + }, + { + "op": "combine", + "name": "Combine1", + "operation": "cut", + "target_body": "A", + "tool_bodies": [ + "B" + ], + "keep_tools": false + } + ] +} diff --git a/tests/oracle/15-combine-intersect/expected.json b/tests/oracle/15-combine-intersect/expected.json new file mode 100644 index 00000000..d212cc37 --- /dev/null +++ b/tests/oracle/15-combine-intersect/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "cube [-20,20]^3 intersect sphere R=25: sphere minus 6 disjoint caps of height h=5 (caps cannot overlap: two would need x^2+y^2 > 800 > R^2); V = 4/3 pi R^3 - 6 pi h^2 (3R-h)/3, A = 4 pi R^2 - 6 * 2 pi R h + 6 pi (R^2-20^2)", + "body_count": 1, + "volume_mm3": 54454.27266222308, + "area_mm2": 7382.7427359360145, + "center_of_mass": [ + 0.0, + 0.0, + 0.0 + ], + "bbox": { + "min": [ + -20.0, + -20.0, + -20.0 + ], + "max": [ + 20.0, + 20.0, + 20.0 + ] + }, + "faces": 7 +} diff --git a/tests/oracle/15-combine-intersect/recipe.json b/tests/oracle/15-combine-intersect/recipe.json new file mode 100644 index 00000000..cc86a542 --- /dev/null +++ b/tests/oracle/15-combine-intersect/recipe.json @@ -0,0 +1,269 @@ +{ + "id": "15-combine-intersect", + "name": "Boolean intersect", + "description": "Cube 40 centred at origin intersected with sphere r=25 at origin.", + "exercises": [ + "extrude", + "symmetric", + "revolve", + "combine_intersect" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "CubeSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -20, + -20 + ] + }, + "end": { + "at": [ + 20, + -20 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + -20.0 + ] + }, + "end": { + "at": [ + 20, + 20 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 20.0, + 20.0 + ] + }, + "end": { + "at": [ + -20, + 20 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -20.0, + 20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -20.0, + -20.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "CubeA", + "operation": "new", + "profiles": [ + { + "sketch": "CubeSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 20, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "A" + ] + }, + { + "op": "sketch", + "name": "SphereB_sketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "arc_three_point", + "start": { + "at": [ + 0.0, + 25.0 + ] + }, + "mid": [ + 25.0, + 0.0 + ], + "end": { + "at": [ + 0.0, + -25.0 + ] + }, + "id": "a1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 0.0, + -25.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 0.0, + 25.0 + ] + }, + "id": "l1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "SphereB", + "operation": "new", + "profile": { + "sketch": "SphereB_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "l1" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "B" + ] + }, + { + "op": "combine", + "name": "Combine1", + "operation": "intersect", + "target_body": "A", + "tool_bodies": [ + "B" + ], + "keep_tools": false + } + ] +} diff --git a/tests/oracle/16-sweep/expected.json b/tests/oracle/16-sweep/expected.json new file mode 100644 index 00000000..9e39f6d8 --- /dev/null +++ b/tests/oracle/16-sweep/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "circle r=3 swept along line 30 (+Z) + tangent R20 quarter arc + line 30 (+X): two cylinders + quarter torus (Pappus: V = pi r^2 R theta, A = 2 pi r R theta; torus centroid at rho = (R^2 + r^2/4)/R * sin(theta/2)/(theta/2) from the bend axis along the bisector) + 2 end disks", + "body_count": 1, + "volume_mm3": 2584.7244290365306, + "area_mm2": 1779.6982871223033, + "center_of_mass": [ + 13.958930123810118, + 0.0, + 36.04106987618987 + ], + "bbox": { + "min": [ + -3.0, + -3.0, + 0.0 + ], + "max": [ + 50.0, + 3.0, + 53.0 + ] + }, + "faces": 5 +} diff --git a/tests/oracle/16-sweep/recipe.json b/tests/oracle/16-sweep/recipe.json new file mode 100644 index 00000000..ec534a26 --- /dev/null +++ b/tests/oracle/16-sweep/recipe.json @@ -0,0 +1,182 @@ +{ + "id": "16-sweep", + "name": "Sweep along path", + "description": "d=6 circle on XY at origin swept along a path on XZ: line up 30, tangent R20 arc, line 30 along +X.", + "exercises": [ + "sketch_xz", + "sweep", + "path_chain" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Path", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 0.0, + -30.0 + ] + }, + "id": "l1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "l1.end", + "at": [ + 0.0, + -30.0 + ] + }, + "mid": [ + 5.857864376, + -44.142135624 + ], + "end": { + "at": [ + 20.0, + -50.0 + ] + }, + "id": "a1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 20.0, + -50.0 + ] + }, + "end": { + "at": [ + 50.0, + -50.0 + ] + }, + "id": "l2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sketch", + "name": "ProfileSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 3, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sweep", + "name": "Sweep1", + "operation": "new", + "profile": { + "sketch": "ProfileSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + "path": { + "sketch": "Path", + "curves": [ + "l1", + "a1", + "l2" + ], + "chained": true + }, + "orientation": "perpendicular", + "result_bodies": [ + "Tube" + ] + } + ] +} diff --git a/tests/oracle/17-loft/expected.json b/tests/oracle/17-loft/expected.json new file mode 100644 index 00000000..790fe3b1 --- /dev/null +++ b/tests/oracle/17-loft/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part.makeLoft", + "body_count": 1, + "volume_mm3": 35125.49757633739, + "area_mm2": 6495.0000512370025, + "center_of_mass": [ + 4.902280481153527e-11, + 9.800242527565077e-16, + 15.119060422795876 + ], + "bbox": { + "min": [ + -20.0000001, + -20.0000001, + -1e-07 + ], + "max": [ + 20.0000001, + 20.0000001, + 40.000000100000015 + ] + } +} diff --git a/tests/oracle/17-loft/recipe.json b/tests/oracle/17-loft/recipe.json new file mode 100644 index 00000000..e1eba87e --- /dev/null +++ b/tests/oracle/17-loft/recipe.json @@ -0,0 +1,211 @@ +{ + "id": "17-loft", + "name": "Loft square to circle", + "description": "Loft from a 40x40 square on XY (z=0) to a d=20 circle on a plane offset 40 mm.", + "exercises": [ + "loft", + "offset_plane" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Bottom", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -20, + -20 + ] + }, + "end": { + "at": [ + 20, + -20 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + -20.0 + ] + }, + "end": { + "at": [ + 20, + 20 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 20.0, + 20.0 + ] + }, + "end": { + "at": [ + -20, + 20 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -20.0, + 20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -20.0, + -20.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "construction_plane", + "name": "Plane40", + "method": "offset", + "base": "XY", + "offset": 40 + }, + { + "op": "sketch", + "name": "Top", + "plane": { + "ref": "construction plane Plane40 (XY offset 40)", + "origin": [ + 0.0, + 0.0, + 40.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 10, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "loft", + "name": "Loft1", + "operation": "new", + "sections": [ + { + "sketch": "Bottom", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + { + "sketch": "Top", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "end_conditions": "free (none)", + "rails": [], + "solid": true, + "result_bodies": [ + "Loft" + ] + } + ] +} diff --git a/tests/oracle/17-loft/reference.stl b/tests/oracle/17-loft/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..a8a0cee32ee01ad59bfcd191634dc967854b9cab GIT binary patch literal 311084 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 z z5G(%UrdK;@udZ19@sASNl_*ZZN&a1P0_P&Lk%`)MKCY4a;bzsFEm7xE~9yMcKl-ypMN`+Wg2wR zb+uO~dzBzRTs?|X{?}sc#G??NtHUA*fxc?UkKTg~Yq2i*f_a~DF%kl)kRRo4D_4V+ zs!8|u=!FsjC6QNR@`mEl0NCjToWF6?XGcw-O}; zdWa#K@^W@)r5_L>{9J-86-px4cTQ+HQg5C)g!gK_LE?c_bj$Qrhb9l~81jw!IhePo zA|sFrC8Yd5nHuT^Xg(6#$Wq~~(R)XHc}KPTqp_amMhIVCQ$`>a&L(};3O;2U_q64G z3ZG$jC*{+!?aoKv+6+z5=Ti1)T>0@D^Nj1rOBOgQA<&}{(ezeZQ-B91*5WVo{~{r< zTCQ}%L0Tk?pP`+>3}nrvQCh1tgGZvLuZ z6st3Rq3c7}c3P8(H#GF1q8!*RZ?y`_z~Aegx-5Gb-$s>U5rI^fHcfKf+1r`M@DiOf z`-bFZ{w7)Vf0KEjzmM$cRI$<>^?l25es0-Ri3j@oAewwXTzAzHR0X{Axp@)-B|)^J z>?v573GyBMlzqO0KuK^E6y;9&Bl@k%A$-x8WHxl|NYP?e>WhVL`ojByKyNzodKq^_ z@1K+M8ho`zLLe1-AyRaI=?i*)%9Q@uZ-a!O7liP>Igy{DBwxI&t2cxA^?NdcUZ%qP z5=OM5)L8mZ?;9P&6UuI6#_F-+QK!^?(96_U(_OAE-?8p-ef`%VJmz7Nguqdd`%z@^ zDt+R|V19ejIthV3iS*|5`HqtJ=ffm@@||G5>#mGIDm*2q2I!nE`n?^&{N9}P5)YIF z`H^;T$hZ3HqQU&zd~(lmtgugtQnTF+J>UEwzM$R*P2gF}@^{g|3c*%RRR5%C7Pf@lnC~suD9>nuiS;@YtpIL+t=xe`<=+@`+ z_n`Znuf86|ZKu>USdJk6SK$N+fxZ}srmBd;3maw1(wB2=jD)~;(VvAh^eu}R-PQ*4 z<};Q{2&6)f8=CW%%!sNI$nPesVsV*sh{XAQ?0%T@3y5#VS{^V*HI$IFAGgaHH#-OM z!bfEUQsIbD^gvR1qw$DfzHfJ|!~>~hsV*kfG(5+Gc!!_j*!T6Gcq%<C>j8aR z$O|d1hLLMrFi%IZGKfGQ4MZ!-mOHJC!{(RK>RT2WTG$TK{i|%h`7_K0m_sKE|fqg=LWb!)L z)X1KdVt8LCNC<2f(e|6ufH$Y`zH8BnDChE~cdY^MS|0)}`G~e(sRq1KeF)6PjajIEg_JK{O>%CFV(Q`E0jU__~zv@4{R5$*5tW7uCuX%?3{gy&X;&#Z;_vUzcS!{CA{}5v=z~9$!9~dZ%ZcJ zmV5}zMqT7-Qw7yD%C&UCVk-T3gnFqEjk72`qZy$ZrGmdyD4=? zAwPOSKFG}u_8>&^CJBM<%DF7~>{6`rvvK_MJXtEFqDqh2m%5hU)+o&m?jOe!dhC&S zAQg@q*}URz9h+o^^G$u{vG6M;#Gg}FS!cKl_3iRX)W-dMEbX!gzOm^H34wW75KW_- zp=Qd#QnYr-Z)x_+s#LNuH7gGykT;#wuiqW}yfvH`{&Sv$Kq^_PmfNzX6kZd~U)G;5 zA&^S8G{p4MQu5yq=f$hcl@JTY6c;_-re?!K3F!z8@0HT!ayaj}Tt@uarL&m5HQv&_ zx)4pdEFLyWY56dWpKrKW;(?MNnl!?t^01yUA^g*(Wo&QL{94yK1GVjywrXfAkahZb zo)%>X>06sOW|f2(^RB!$u<#K3eE;TZG3`-`6=iO%%*e33>{UQ8FSaLMLLikDpk#gs&`lEqJ{{Rmb^vIwqW1h3*>Vb z#Yza&q{_P2t7TiTmd6A6_0@3_0;y!JbMD$hS>gKryujF15`u2}F0Us!N=TkH(>t)d z0|WT_B{BlrMYN*Oxog0=E4*JEtg4H#IrbOFfG>^@fpI?aYn#3wI($ET2$>3RWb}

Kt%Ym_$N`{6^NHztmP{dG3r>+D0&7un~fiD-JO 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 yf9HbtTwP-w`Xr3 over 3 mm + r3 through), blind r3 hole 10 deep to the shoulder with a 118 deg cone point (height 3/tan59, centroid 1/4 up from the apex); areas: removed top/bottom disks, cylinder walls 2 pi r h, cb floor annulus, cone laterals pi r s", + "body_count": 1, + "volume_mm3": 33890.710358950084, + "area_mm2": 8568.695781624992, + "center_of_mass": [ + 30.307000593669976, + 20.000000000000004, + 7.38224663372136 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 60.0, + 40.0, + 15.0 + ] + }, + "faces": 13 +} diff --git a/tests/oracle/18-hole-features/recipe.json b/tests/oracle/18-hole-features/recipe.json new file mode 100644 index 00000000..827957e4 --- /dev/null +++ b/tests/oracle/18-hole-features/recipe.json @@ -0,0 +1,253 @@ +{ + "id": "18-hole-features", + "name": "Hole features (counterbore, countersink, blind drilled)", + "description": "60x40x15 plate; on the top face: counterbore hole at (15,20) through all, countersink at (35,20) through all, simple blind hole depth 10 at (50,20) with 118 deg drill tip.", + "exercises": [ + "hole_counterbore", + "hole_countersink", + "hole_blind" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 60, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 60.0, + 0.0 + ] + }, + "end": { + "at": [ + 60, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 60.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 15, + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "hole", + "name": "CBore", + "hole_type": "counterbore", + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 30.0, + 20.0, + 15.0 + ] + }, + "position": [ + 15, + 20, + 15 + ], + "direction": "into the material (-Z)", + "diameter": 8, + "counterbore_diameter": 14, + "counterbore_depth": 5, + "extent": "through_all" + }, + { + "op": "hole", + "name": "CSink", + "hole_type": "countersink", + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 30.0, + 20.0, + 15.0 + ] + }, + "position": [ + 35, + 20, + 15 + ], + "direction": "into the material (-Z)", + "diameter": 6, + "countersink_diameter": 12, + "countersink_angle": 90, + "extent": "through_all" + }, + { + "op": "hole", + "name": "Blind", + "hole_type": "simple", + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 25.5, + 20.0, + 15.0 + ] + }, + "position": [ + 50, + 20, + 15 + ], + "direction": "into the material (-Z)", + "diameter": 6, + "depth": 10, + "tip_angle": 118, + "extent": "distance" + } + ] +} diff --git a/tests/oracle/19-l-bracket-constrained/expected.json b/tests/oracle/19-l-bracket-constrained/expected.json new file mode 100644 index 00000000..0c83c404 --- /dev/null +++ b/tests/oracle/19-l-bracket-constrained/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "solved L: (0,0)-(60,0)-(60,8)-(8,8)-(8,40)-(0,40); area 60x8 + 8x32, extruded 20: V = A2 h, A = 2 A2 + perimeter*h, centroid of the two rectangles", + "body_count": 1, + "volume_mm3": 14720.0, + "area_mm2": 5472.0, + "center_of_mass": [ + 20.956521739130434, + 10.956521739130435, + 10.0 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 60.0, + 40.0, + 20.0 + ] + }, + "faces": 8 +} diff --git a/tests/oracle/19-l-bracket-constrained/recipe.json b/tests/oracle/19-l-bracket-constrained/recipe.json new file mode 100644 index 00000000..bc483c90 --- /dev/null +++ b/tests/oracle/19-l-bracket-constrained/recipe.json @@ -0,0 +1,275 @@ +{ + "id": "19-l-bracket-constrained", + "name": "Constrained L-bracket sketch extruded", + "description": "L outline drawn roughly, fully constrained with H/V constraints + 4 dimensions + corner on origin; solved profile extruded 20 mm.", + "exercises": [ + "sketch_constraints", + "sketch_dimensions", + "extrude" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "LSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 1, + 1 + ] + }, + "end": { + "at": [ + 55, + -2 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 55.0, + -2.0 + ] + }, + "end": { + "at": [ + 57, + 9 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 57.0, + 9.0 + ] + }, + "end": { + "at": [ + 10, + 7 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 10.0, + 7.0 + ] + }, + "end": { + "at": [ + 9, + 45 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 9.0, + 45.0 + ] + }, + "end": { + "at": [ + -1, + 38 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + -1.0, + 38.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 1.0, + 1.0 + ] + }, + "id": "l6" + } + ], + "constraints": [ + { + "type": "horizontal", + "refs": [ + "l1" + ] + }, + { + "type": "horizontal", + "refs": [ + "l3" + ] + }, + { + "type": "horizontal", + "refs": [ + "l5" + ] + }, + { + "type": "vertical", + "refs": [ + "l2" + ] + }, + { + "type": "vertical", + "refs": [ + "l4" + ] + }, + { + "type": "vertical", + "refs": [ + "l6" + ] + }, + { + "type": "coincident", + "refs": [ + "l1.start", + "origin" + ] + } + ], + "dimensions": [ + { + "type": "distance", + "refs": [ + "l1.start", + "l1.end" + ], + "value": 60, + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "distance", + "refs": [ + "l2.start", + "l2.end" + ], + "value": 8, + "unit": "mm", + "orientation": "vertical" + }, + { + "type": "distance", + "refs": [ + "l6.start", + "l6.end" + ], + "value": 40, + "unit": "mm", + "orientation": "vertical" + }, + { + "type": "distance", + "refs": [ + "l5.start", + "l5.end" + ], + "value": 8, + "unit": "mm", + "orientation": "horizontal" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "LSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4", + "l5", + "l6" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "LBracket" + ] + } + ] +} diff --git a/tests/oracle/20-slot-constrained/expected.json b/tests/oracle/20-slot-constrained/expected.json new file mode 100644 index 00000000..4549733a --- /dev/null +++ b/tests/oracle/20-slot-constrained/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "obround: arc centres (0,0) and (40,0), R6, tangent horizontal lines y=+-6: A2 = 2rL + pi r^2, V = A2 h, A = 2 A2 + perimeter (2L + 2 pi r) h", + "body_count": 1, + "volume_mm3": 2965.4866776461627, + "area_mm2": 1774.6902302738526, + "center_of_mass": [ + 20.0, + 0.0, + 2.5 + ], + "bbox": { + "min": [ + -6.0, + -6.0, + 0.0 + ], + "max": [ + 46.0, + 6.0, + 5.0 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/20-slot-constrained/recipe.json b/tests/oracle/20-slot-constrained/recipe.json new file mode 100644 index 00000000..96f32828 --- /dev/null +++ b/tests/oracle/20-slot-constrained/recipe.json @@ -0,0 +1,225 @@ +{ + "id": "20-slot-constrained", + "name": "Constrained slot extruded", + "description": "Obround: two arcs + two lines drawn inexactly, solved with tangent/equal/horizontal constraints, R6 and 40 mm centre distance; extruded 5.", + "exercises": [ + "sketch_constraints", + "tangent", + "equal", + "extrude" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "SlotSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + 1, + 1 + ] + }, + "start": { + "at": [ + 1, + 7 + ] + }, + "sweep_deg": 180, + "id": "a1" + }, + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + 37, + 2 + ] + }, + "start": { + "at": [ + 37, + -3 + ] + }, + "sweep_deg": 180, + "id": "a2" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 1.0, + -5.0 + ] + }, + "end": { + "ref": "a2.start", + "at": [ + 37.0, + -3.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "a2.end", + "at": [ + 37.0, + 7.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 1.0, + 7.0 + ] + }, + "id": "l2" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "a1.center", + "origin" + ] + }, + { + "type": "tangent", + "refs": [ + "a1", + "l1" + ] + }, + { + "type": "tangent", + "refs": [ + "l1", + "a2" + ] + }, + { + "type": "tangent", + "refs": [ + "a2", + "l2" + ] + }, + { + "type": "tangent", + "refs": [ + "l2", + "a1" + ] + }, + { + "type": "equal", + "refs": [ + "a1", + "a2" + ] + }, + { + "type": "horizontal", + "refs": [ + "l1" + ] + } + ], + "dimensions": [ + { + "type": "radius", + "refs": [ + "a1" + ], + "value": 6, + "unit": "mm" + }, + { + "type": "distance", + "refs": [ + "a1.center", + "a2.center" + ], + "value": 40, + "unit": "mm", + "orientation": "horizontal" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "SlotSketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "a2", + "l1", + "l2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Slot" + ] + } + ] +} diff --git a/tests/oracle/21-draft/expected.json b/tests/oracle/21-draft/expected.json new file mode 100644 index 00000000..20016aef --- /dev/null +++ b/tests/oracle/21-draft/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "40x40x30 box, 5 deg draft hinged on the bottom (z=0), pull -Z: square frustum 40 -> 40 + 2*30*tan5; V = h/3 (A0 + A1 + sqrt(A0A1)), sides 4 trapezoids of slant h/cos5", + "body_count": 1, + "volume_mm3": 54574.73735870641, + "area_mm2": 8781.998445243411, + "center_of_mass": [ + 0.0, + 0.0, + 15.614983642248854 + ], + "bbox": { + "min": [ + -22.62465990577772, + -22.62465990577772, + 0.0 + ], + "max": [ + 22.62465990577772, + 22.62465990577772, + 30.0 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/21-draft/recipe.json b/tests/oracle/21-draft/recipe.json new file mode 100644 index 00000000..670a8163 --- /dev/null +++ b/tests/oracle/21-draft/recipe.json @@ -0,0 +1,253 @@ +{ + "id": "21-draft", + "name": "Draft side faces", + "description": "40x40x30 box (centred on origin in XY); 5 deg draft on the 4 side faces, neutral plane = bottom face.", + "exercises": [ + "extrude", + "draft" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -20, + -20 + ] + }, + "end": { + "at": [ + 20, + -20 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + -20.0 + ] + }, + "end": { + "at": [ + 20, + 20 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 20.0, + 20.0 + ] + }, + "end": { + "at": [ + -20, + 20 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -20.0, + 20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -20.0, + -20.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "draft", + "name": "Draft1", + "faces": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 1.0, + 0.0 + ], + "plane_normal_outward": [ + 0.0, + 1.0, + 0.0 + ], + "point": [ + 0.0, + 20.0, + 15.0 + ] + }, + { + "type": "plane", + "normal_at_point_on_face": [ + 1.0, + 0.0, + 0.0 + ], + "plane_normal_outward": [ + 1.0, + 0.0, + 0.0 + ], + "point": [ + 20.0, + 0.0, + 15.0 + ] + }, + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + -1.0, + 0.0 + ], + "plane_normal_outward": [ + 0.0, + -1.0, + 0.0 + ], + "point": [ + 0.0, + -20.0, + 15.0 + ] + }, + { + "type": "plane", + "normal_at_point_on_face": [ + -1.0, + 0.0, + 0.0 + ], + "plane_normal_outward": [ + -1.0, + 0.0, + 0.0 + ], + "point": [ + -20.0, + 0.0, + 15.0 + ] + } + ], + "face_selection": "the 4 vertical side faces", + "neutral_plane": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + -1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 0.0, + 0.0, + 0.0 + ] + }, + "neutral_selection": "bottom face (z=0)", + "angle": 5, + "flipped": false + } + ] +} diff --git a/tests/oracle/22-split-body/expected.json b/tests/oracle/22-split-body/expected.json new file mode 100644 index 00000000..822a52f0 --- /dev/null +++ b/tests/oracle/22-split-body/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "cylinder r20 z -30..30 split by the plane through the X axis tilted 30 deg (z = y tan30, stays within |z|<=11.6 inside the cylinder): 2 congruent halves (point symmetry), V total = pi r^2 h, A total = cylinder + 2 ellipses pi r (r/cos30)", + "body_count": 2, + "volume_mm3": 75398.22368615503, + "area_mm2": 12955.175474262087, + "center_of_mass": [ + 0.0, + 0.0, + 0.0 + ], + "bbox": { + "min": [ + -20.0, + -20.0, + -30.0 + ], + "max": [ + 20.0, + 20.0, + 30.0 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/22-split-body/recipe.json b/tests/oracle/22-split-body/recipe.json new file mode 100644 index 00000000..796d2520 --- /dev/null +++ b/tests/oracle/22-split-body/recipe.json @@ -0,0 +1,125 @@ +{ + "id": "22-split-body", + "name": "Split body by angled plane", + "description": "Cylinder r=20, z from -30 to 30 (symmetric extrude) split by a plane containing the X axis tilted 30 deg from XY.", + "exercises": [ + "extrude", + "symmetric", + "construction_plane_angle", + "split_body" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 20, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 30, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Cyl" + ] + }, + { + "op": "construction_plane", + "name": "Tilt30", + "method": "at_angle", + "axis": "world X axis", + "base_plane": "XY", + "angle": 30, + "result_origin": [ + 12.125, + 0.0, + 0.0 + ], + "result_normal": [ + 0.0, + -0.5, + 0.866025404 + ] + }, + { + "op": "split_body", + "name": "Split1", + "body": "Cyl", + "tool": "Tilt30", + "extend_tool": true, + "result_bodies": [ + "Cyl", + "Cyl (1)" + ] + } + ] +} diff --git a/tests/oracle/23-bracket-multifeature/expected.json b/tests/oracle/23-bracket-multifeature/expected.json new file mode 100644 index 00000000..25ca8076 --- /dev/null +++ b/tests/oracle/23-bracket-multifeature/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part makeFillet, Part extrude join, Part extrude cut, Part makeChamfer", + "body_count": 1, + "volume_mm3": 59331.128616959795, + "area_mm2": 18290.736978057597, + "center_of_mass": [ + 40.00000000000001, + 34.567350242237325, + 15.289013135744947 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 50.0, + 50.0 + ] + } +} diff --git a/tests/oracle/23-bracket-multifeature/recipe.json b/tests/oracle/23-bracket-multifeature/recipe.json new file mode 100644 index 00000000..a007f090 --- /dev/null +++ b/tests/oracle/23-bracket-multifeature/recipe.json @@ -0,0 +1,693 @@ +{ + "id": "23-bracket-multifeature", + "name": "Multi-feature bracket", + "description": "Base plate 80x50x8, back wall, inner fillet R5, gusset, 2 base holes, wall hole, front corner chamfers.", + "exercises": [ + "extrude", + "extrude_join", + "fillet", + "symmetric", + "offset_plane", + "extrude_cut", + "chamfer" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 50.0 + ] + }, + "end": { + "at": [ + 0, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Base", + "operation": "new", + "profiles": [ + { + "sketch": "Base_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 8, + "direction": "positive" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "sketch", + "name": "WallSketch", + "plane": { + "ref": "face: top of Base (z=8)", + "origin": [ + 0.0, + 0.0, + 8.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 40.0, + 25.0, + 8.0 + ] + } + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 42.0 + ] + }, + "end": { + "at": [ + 80.0, + 42.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 42.0 + ] + }, + "end": { + "at": [ + 80.0, + 50.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 50.0 + ] + }, + "end": { + "at": [ + 0.0, + 50.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 42.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Wall", + "operation": "join", + "profiles": [ + { + "sketch": "WallSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 42, + "direction": "positive" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "fillet", + "name": "InnerFillet", + "type": "constant_radius", + "radius": 5, + "tangent_chain": false, + "edge_selection": "the X-parallel concave edge where base top (z=8) meets wall front (y=42)", + "edges": [ + { + "type": "line", + "start": [ + 80.0, + 42.0, + 8.0 + ], + "end": [ + 0.0, + 42.0, + 8.0 + ], + "point": [ + 40.0, + 42.0, + 8.0 + ] + } + ] + }, + { + "op": "construction_plane", + "name": "MidPlane", + "method": "offset", + "base": "YZ", + "offset": 40 + }, + { + "op": "sketch", + "name": "GussetSketch", + "plane": { + "ref": "construction plane MidPlane (YZ offset 40)", + "origin": [ + 40.0, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -8.0, + 42.0 + ] + }, + "end": { + "at": [ + -35.0, + 42.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + -35.0, + 42.0 + ] + }, + "end": { + "at": [ + -8.0, + 15.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + -8.0, + 15.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -8.0, + 42.0 + ] + }, + "id": "l3" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Gusset", + "operation": "join", + "profiles": [ + { + "sketch": "GussetSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 3, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "sketch", + "name": "BaseHoles", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 20, + 20 + ] + }, + "radius": 4, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 60, + 20 + ] + }, + "radius": 4, + "id": "c2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "BaseHoles", + "operation": "cut", + "profiles": [ + { + "sketch": "BaseHoles", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + { + "sketch": "BaseHoles", + "loops": [ + { + "outer": true, + "curves": [ + "c2" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "sketch", + "name": "WallHole", + "plane": { + "ref": "face: wall front face (y=42, normal -Y)", + "origin": [ + 0.0, + 42.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + 1.0 + ], + "normal": [ + 0.0, + -1.0, + 0.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + -1.0, + 0.0 + ], + "plane_normal_outward": [ + 0.0, + -1.0, + 0.0 + ], + "point": [ + 61.5, + 42.0, + 31.5 + ] + } + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 20.0, + 30.0 + ] + }, + "radius": 5, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 60.0, + 30.0 + ] + }, + "radius": 5, + "id": "c2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "WallHoles", + "operation": "cut", + "profiles": [ + { + "sketch": "WallHole", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + { + "sketch": "WallHole", + "loops": [ + { + "outer": true, + "curves": [ + "c2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 8, + "direction": "negative" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "chamfer", + "name": "FrontChamfer", + "type": "equal_distance", + "distance": 3, + "tangent_chain": false, + "edge_selection": "the 2 vertical edges at the front corners of the base (y=0, z 0..8)", + "edges": [ + { + "type": "line", + "start": [ + 80.0, + 0.0, + 0.0 + ], + "end": [ + 80.0, + 0.0, + 8.0 + ], + "point": [ + 80.0, + 0.0, + 4.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 8.0 + ], + "point": [ + 0.0, + 0.0, + 4.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/23-bracket-multifeature/reference.stl b/tests/oracle/23-bracket-multifeature/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..86036751bdfab089b572d3a2091380e7d77031d8 GIT binary patch literal 88484 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 Q79*?k;l>HgBa0gU4`u}GjsO4v literal 0 HcmV?d00001 diff --git a/tests/oracle/24-user-parameters/expected.json b/tests/oracle/24-user-parameters/expected.json new file mode 100644 index 00000000..e9ffa040 --- /dev/null +++ b/tests/oracle/24-user-parameters/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "width 60 x depth 40 x height 15 block from the origin with a centred d10 through hole: V = (wd - pi r^2) h, A = 2(wd - pi r^2) + 2(w+d)h + 2 pi r h", + "body_count": 1, + "volume_mm3": 34821.90275490383, + "area_mm2": 8114.15926535898, + "center_of_mass": [ + 30.0, + 20.0, + 7.5 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 60.0, + 40.0, + 15.0 + ] + }, + "faces": 7 +} diff --git a/tests/oracle/24-user-parameters/recipe.json b/tests/oracle/24-user-parameters/recipe.json new file mode 100644 index 00000000..9d926442 --- /dev/null +++ b/tests/oracle/24-user-parameters/recipe.json @@ -0,0 +1,275 @@ +{ + "id": "24-user-parameters", + "name": "Parametric block driven by user parameters", + "description": "Rectangle sized by params width x depth (corner at origin), centred hole d=hole_d, extruded height.", + "exercises": [ + "user_parameters", + "sketch_constraints", + "dimension_expressions", + "extrude", + "recompute" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [ + { + "name": "width", + "expression": "60 mm", + "unit": "mm" + }, + { + "name": "depth", + "expression": "40 mm", + "unit": "mm" + }, + { + "name": "height", + "expression": "15 mm", + "unit": "mm" + }, + { + "name": "hole_d", + "expression": "10 mm", + "unit": "mm" + } + ], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 50, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 50.0, + 0.0 + ] + }, + "end": { + "at": [ + 50, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 50.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + }, + { + "type": "circle", + "center": { + "at": [ + 25, + 15 + ] + }, + "radius": 4, + "id": "c1" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "l1.start", + "origin" + ] + }, + { + "type": "horizontal", + "refs": [ + "l1" + ] + }, + { + "type": "vertical", + "refs": [ + "l2" + ] + }, + { + "type": "horizontal", + "refs": [ + "l3" + ] + }, + { + "type": "vertical", + "refs": [ + "l4" + ] + } + ], + "dimensions": [ + { + "type": "distance", + "refs": [ + "l1.start", + "l1.end" + ], + "value": "width", + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "distance", + "refs": [ + "l2.start", + "l2.end" + ], + "value": "depth", + "unit": "mm", + "orientation": "vertical" + }, + { + "type": "diameter", + "refs": [ + "c1" + ], + "value": "hole_d", + "unit": "mm" + }, + { + "type": "distance", + "refs": [ + "origin", + "c1.center" + ], + "value": "width / 2", + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "distance", + "refs": [ + "origin", + "c1.center" + ], + "value": "depth / 2", + "unit": "mm", + "orientation": "vertical" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + }, + { + "outer": false, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": "height", + "direction": "positive" + }, + "result_bodies": [ + "Block" + ] + } + ] +} diff --git a/tests/oracle/25-sketch-triangle/expected.json b/tests/oracle/25-sketch-triangle/expected.json new file mode 100644 index 00000000..21fa6181 --- /dev/null +++ b/tests/oracle/25-sketch-triangle/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "solved triangle (0,0), (50,0), P = t(cos60, sin60) with t = 25 + sqrt(150) from |P-(50,0)| = 45 (the root nearest the drawn apex); V = (1/2 * 50 * Py) * 5, A = 2 A2 + perimeter*5, centroid = vertex mean", + "body_count": 1, + "volume_mm3": 4032.1546015511467, + "area_mm2": 2274.0990841900384, + "center_of_mass": [ + 22.87457478565265, + 10.752412270803058, + 2.5 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 50.0, + 32.257236812409175, + 5.0 + ] + }, + "faces": 5 +} diff --git a/tests/oracle/25-sketch-triangle/recipe.json b/tests/oracle/25-sketch-triangle/recipe.json new file mode 100644 index 00000000..65516990 --- /dev/null +++ b/tests/oracle/25-sketch-triangle/recipe.json @@ -0,0 +1,184 @@ +{ + "id": "25-sketch-triangle", + "name": "Sketch solver: triangle with lengths and angle", + "description": "Triangle drawn roughly; l1 horizontal from origin, |l1|=50, |l2|=45, angle(l1,l3)=60 deg. Solved sketch extruded 5 mm.", + "exercises": [ + "sketch_only", + "sketch_constraints", + "angle_dim" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Triangle", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 2, + 1 + ] + }, + "end": { + "at": [ + 45, + 3 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 45.0, + 3.0 + ] + }, + "end": { + "at": [ + 22, + 35 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 22.0, + 35.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 2.0, + 1.0 + ] + }, + "id": "l3" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "l1.start", + "origin" + ] + }, + { + "type": "horizontal", + "refs": [ + "l1" + ] + } + ], + "dimensions": [ + { + "type": "distance", + "refs": [ + "l1.start", + "l1.end" + ], + "value": 50, + "unit": "mm", + "orientation": "aligned" + }, + { + "type": "distance", + "refs": [ + "l2.start", + "l2.end" + ], + "value": 45, + "unit": "mm", + "orientation": "aligned" + }, + { + "type": "angle", + "refs": [ + "l1", + "l3" + ], + "value": 60, + "unit": "deg", + "text_at": [ + 8, + 4 + ] + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Triangle", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Triangle" + ] + } + ] +} diff --git a/tests/oracle/26-sketch-belt/expected.json b/tests/oracle/26-sketch-belt/expected.json new file mode 100644 index 00000000..5c6bb50f --- /dev/null +++ b/tests/oracle/26-sketch-belt/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "belt: convex hull of circles R20 @ (0,0) and r10 @ (50,0) (external tangents, sin a = (R-r)/d) minus the d8 hole at (50,0), extruded 5 as one body; hull area = (R+r) sqrt(d^2-(R-r)^2) + R^2(pi+2a)/2 + r^2(pi-2a)/2; moments by Green's theorem over the line/arc boundary", + "body_count": 1, + "volume_mm3": 11326.169514235082, + "area_mm2": 5637.404150511762, + "center_of_mass": [ + 15.321857347287981, + 0.0, + 2.5 + ], + "bbox": { + "min": [ + -20.0, + -20.0, + 0.0 + ], + "max": [ + 60.0, + 20.0, + 5.0 + ] + }, + "faces": 7 +} diff --git a/tests/oracle/26-sketch-belt/recipe.json b/tests/oracle/26-sketch-belt/recipe.json new file mode 100644 index 00000000..74083f47 --- /dev/null +++ b/tests/oracle/26-sketch-belt/recipe.json @@ -0,0 +1,296 @@ +{ + "id": "26-sketch-belt", + "name": "Sketch solver: tangent lines between circles", + "description": "Circles d40 at origin and d20 at 50 mm (horizontal), concentric d8 hole, two lines tangent to both. All profiles extruded 5 mm.", + "exercises": [ + "sketch_only", + "sketch_constraints", + "tangent", + "concentric", + "point_on_curve" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Belt", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 2, + -1 + ] + }, + "radius": 18, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 45, + 3 + ] + }, + "radius": 12, + "id": "c2" + }, + { + "type": "circle", + "center": { + "at": [ + 46, + 2 + ] + }, + "radius": 5, + "id": "c3" + }, + { + "type": "line", + "start": { + "at": [ + 3, + 19 + ] + }, + "end": { + "at": [ + 47, + 13 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "at": [ + 1, + -22 + ] + }, + "end": { + "at": [ + 44, + -8 + ] + }, + "id": "l2" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "c1.center", + "origin" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "c1.center", + "c2.center" + ] + }, + { + "type": "concentric", + "refs": [ + "c3", + "c2" + ] + }, + { + "type": "coincident", + "refs": [ + "l1.start", + "c1" + ] + }, + { + "type": "coincident", + "refs": [ + "l1.end", + "c2" + ] + }, + { + "type": "tangent", + "refs": [ + "l1", + "c1" + ] + }, + { + "type": "tangent", + "refs": [ + "l1", + "c2" + ] + }, + { + "type": "coincident", + "refs": [ + "l2.start", + "c1" + ] + }, + { + "type": "coincident", + "refs": [ + "l2.end", + "c2" + ] + }, + { + "type": "tangent", + "refs": [ + "l2", + "c1" + ] + }, + { + "type": "tangent", + "refs": [ + "l2", + "c2" + ] + } + ], + "dimensions": [ + { + "type": "diameter", + "refs": [ + "c1" + ], + "value": 40, + "unit": "mm" + }, + { + "type": "diameter", + "refs": [ + "c2" + ], + "value": 20, + "unit": "mm" + }, + { + "type": "diameter", + "refs": [ + "c3" + ], + "value": 8, + "unit": "mm" + }, + { + "type": "distance", + "refs": [ + "c1.center", + "c2.center" + ], + "value": 50, + "unit": "mm", + "orientation": "horizontal" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Belt", + "loops": [ + { + "outer": false, + "curves": [ + "c3" + ] + }, + { + "outer": true, + "curves": [ + "c2", + "c2" + ] + } + ] + }, + { + "sketch": "Belt", + "loops": [ + { + "outer": true, + "curves": [ + "c1", + "c1" + ] + } + ] + }, + { + "sketch": "Belt", + "loops": [ + { + "outer": true, + "curves": [ + "c1", + "c2", + "l1", + "l2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Belt" + ] + } + ] +} diff --git a/tests/oracle/27-sketch-trapezoid/expected.json b/tests/oracle/27-sketch-trapezoid/expected.json new file mode 100644 index 00000000..f3eb4f01 --- /dev/null +++ b/tests/oracle/27-sketch-trapezoid/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "solved trapezoid bottom (-30,0)-(30,0), top (-15,25)-(15,25) minus two d6 holes at (+-18, 8) (symmetric about the axis, 36 apart, 8 above l1); trapezoid centroid y = H(a+2b)/(3(a+b)); V = A2 t, A = 2 A2 + perimeter t", + "body_count": 1, + "volume_mm3": 5342.256661176918, + "area_mm2": 3066.94581842842, + "center_of_mass": [ + 0.0, + 11.275769231975591, + 2.5 + ], + "bbox": { + "min": [ + -30.0, + 0.0, + 0.0 + ], + "max": [ + 30.0, + 25.0, + 5.0 + ] + }, + "faces": 8 +} diff --git a/tests/oracle/27-sketch-trapezoid/recipe.json b/tests/oracle/27-sketch-trapezoid/recipe.json new file mode 100644 index 00000000..742500b2 --- /dev/null +++ b/tests/oracle/27-sketch-trapezoid/recipe.json @@ -0,0 +1,318 @@ +{ + "id": "27-sketch-trapezoid", + "name": "Sketch solver: parallel/perpendicular/midpoint/symmetry", + "description": "Trapezoid: bottom horizontal 60 centred on origin (midpoint), construction axis perpendicular, top parallel 30 with its midpoint on the axis end (height 25); two d6 holes symmetric about the axis.", + "exercises": [ + "sketch_only", + "sketch_constraints", + "parallel", + "perpendicular", + "midpoint", + "symmetric", + "offset_dim", + "construction_geometry" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Trapezoid", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -27, + 2 + ] + }, + "end": { + "at": [ + 31, + -1 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 31.0, + -1.0 + ] + }, + "end": { + "at": [ + 18, + 23 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 18.0, + 23.0 + ] + }, + "end": { + "at": [ + -13, + 27 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -13.0, + 27.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -27.0, + 2.0 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "at": [ + 1, + 1 + ] + }, + "end": { + "at": [ + 2, + 22 + ] + }, + "id": "l0", + "construction": true + }, + { + "type": "circle", + "center": { + "at": [ + -14, + 9 + ] + }, + "radius": 2.5, + "id": "h1" + }, + { + "type": "circle", + "center": { + "at": [ + 16, + 7 + ] + }, + "radius": 3.5, + "id": "h2" + } + ], + "constraints": [ + { + "type": "horizontal", + "refs": [ + "l1" + ] + }, + { + "type": "midpoint", + "refs": [ + "origin", + "l1" + ] + }, + { + "type": "perpendicular", + "refs": [ + "l0", + "l1" + ] + }, + { + "type": "coincident", + "refs": [ + "l0.start", + "origin" + ] + }, + { + "type": "parallel", + "refs": [ + "l3", + "l1" + ] + }, + { + "type": "midpoint", + "refs": [ + "l0.end", + "l3" + ] + }, + { + "type": "symmetric", + "refs": [ + "h1", + "h2", + "l0" + ] + } + ], + "dimensions": [ + { + "type": "distance", + "refs": [ + "l1.start", + "l1.end" + ], + "value": 60, + "unit": "mm", + "orientation": "aligned" + }, + { + "type": "distance", + "refs": [ + "l0.start", + "l0.end" + ], + "value": 25, + "unit": "mm", + "orientation": "aligned" + }, + { + "type": "distance", + "refs": [ + "l3.start", + "l3.end" + ], + "value": 30, + "unit": "mm", + "orientation": "aligned" + }, + { + "type": "diameter", + "refs": [ + "h1" + ], + "value": 6, + "unit": "mm" + }, + { + "type": "offset", + "refs": [ + "l1", + "h1.center" + ], + "value": 8, + "unit": "mm" + }, + { + "type": "distance", + "refs": [ + "h1.center", + "h2.center" + ], + "value": 36, + "unit": "mm", + "orientation": "horizontal" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Trapezoid", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + }, + { + "outer": false, + "curves": [ + "h1" + ] + }, + { + "outer": false, + "curves": [ + "h2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Trapezoid" + ] + } + ] +} diff --git a/tests/oracle/28-blind-pocket-fillets/expected.json b/tests/oracle/28-blind-pocket-fillets/expected.json new file mode 100644 index 00000000..4d7c7fa3 --- /dev/null +++ b/tests/oracle/28-blind-pocket-fillets/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, Part makeFillet", + "body_count": 1, + "volume_mm3": 84299.24852854047, + "area_mm2": 16279.571562823978, + "center_of_mass": [ + 39.99999999999999, + 29.999999999999996, + 9.161827142086619 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 60.0, + 20.0 + ] + } +} diff --git a/tests/oracle/28-blind-pocket-fillets/recipe.json b/tests/oracle/28-blind-pocket-fillets/recipe.json new file mode 100644 index 00000000..4fb5720a --- /dev/null +++ b/tests/oracle/28-blind-pocket-fillets/recipe.json @@ -0,0 +1,577 @@ +{ + "id": "28-blind-pocket-fillets", + "name": "Blind pocket with filleted corners", + "description": "80x60x20 block; 50x30 rectangle on top face cut 8 mm deep (blind); 4 vertical pocket corner edges filleted R5, then pocket floor edges R2.", + "exercises": [ + "extrude_cut", + "blind", + "fillet", + "concave_fillet" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Block_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Block", + "operation": "new", + "profiles": [ + { + "sketch": "Block_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Block" + ] + }, + { + "op": "sketch", + "name": "PocketSketch", + "plane": { + "ref": "face: top of Block (z=20)", + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 40.0, + 30.0, + 20.0 + ] + } + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 15.0, + 15.0 + ] + }, + "end": { + "at": [ + 65.0, + 15.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 65.0, + 15.0 + ] + }, + "end": { + "at": [ + 65.0, + 45.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 65.0, + 45.0 + ] + }, + "end": { + "at": [ + 15.0, + 45.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 15.0, + 45.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 15.0, + 15.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Pocket", + "operation": "cut", + "profiles": [ + { + "sketch": "PocketSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 8, + "direction": "negative" + }, + "result_bodies": [ + "Block" + ] + }, + { + "op": "fillet", + "name": "CornerFillet", + "type": "constant_radius", + "radius": 5, + "tangent_chain": false, + "edge_selection": "the 4 vertical pocket corner edges (z 12..20)", + "edges": [ + { + "type": "line", + "start": [ + 65.0, + 15.0, + 20.0 + ], + "end": [ + 65.0, + 15.0, + 12.0 + ], + "point": [ + 65.0, + 15.0, + 16.0 + ] + }, + { + "type": "line", + "start": [ + 15.0, + 15.0, + 20.0 + ], + "end": [ + 15.0, + 15.0, + 12.0 + ], + "point": [ + 15.0, + 15.0, + 16.0 + ] + }, + { + "type": "line", + "start": [ + 65.0, + 45.0, + 20.0 + ], + "end": [ + 65.0, + 45.0, + 12.0 + ], + "point": [ + 65.0, + 45.0, + 16.0 + ] + }, + { + "type": "line", + "start": [ + 15.0, + 45.0, + 20.0 + ], + "end": [ + 15.0, + 45.0, + 12.0 + ], + "point": [ + 15.0, + 45.0, + 16.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "FloorFillet", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "all edges of the pocket floor (z=12) - 4 lines + 4 arcs", + "edges": [ + { + "type": "arc", + "start": [ + 20.0, + 45.0, + 12.0 + ], + "end": [ + 15.0, + 40.0, + 12.0 + ], + "center": [ + 20.0, + 40.0, + 12.0 + ], + "axis": [ + 0.0, + -0.0, + 1.0 + ], + "point": [ + 16.464466094, + 43.535533906, + 12.0 + ] + }, + { + "type": "line", + "start": [ + 15.0, + 20.0, + 12.0 + ], + "end": [ + 15.0, + 40.0, + 12.0 + ], + "point": [ + 15.0, + 30.0, + 12.0 + ] + }, + { + "type": "arc", + "start": [ + 15.0, + 20.0, + 12.0 + ], + "end": [ + 20.0, + 15.0, + 12.0 + ], + "center": [ + 20.0, + 20.0, + 12.0 + ], + "axis": [ + 0.0, + -0.0, + 1.0 + ], + "point": [ + 16.464466094, + 16.464466094, + 12.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 15.0, + 12.0 + ], + "end": [ + 20.0, + 15.0, + 12.0 + ], + "point": [ + 40.0, + 15.0, + 12.0 + ] + }, + { + "type": "arc", + "start": [ + 60.0, + 15.0, + 12.0 + ], + "end": [ + 65.0, + 20.0, + 12.0 + ], + "center": [ + 60.0, + 20.0, + 12.0 + ], + "axis": [ + -0.0, + 0.0, + 1.0 + ], + "point": [ + 63.535533906, + 16.464466094, + 12.0 + ] + }, + { + "type": "line", + "start": [ + 65.0, + 40.0, + 12.0 + ], + "end": [ + 65.0, + 20.0, + 12.0 + ], + "point": [ + 65.0, + 30.0, + 12.0 + ] + }, + { + "type": "arc", + "start": [ + 65.0, + 40.0, + 12.0 + ], + "end": [ + 60.0, + 45.0, + 12.0 + ], + "center": [ + 60.0, + 40.0, + 12.0 + ], + "axis": [ + 0.0, + -0.0, + 1.0 + ], + "point": [ + 63.535533906, + 43.535533906, + 12.0 + ] + }, + { + "type": "line", + "start": [ + 20.0, + 45.0, + 12.0 + ], + "end": [ + 60.0, + 45.0, + 12.0 + ], + "point": [ + 40.0, + 45.0, + 12.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/28-blind-pocket-fillets/reference.stl b/tests/oracle/28-blind-pocket-fillets/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..a38e3f7d1c061331db042624c7163951d8ddf3ea GIT binary patch literal 215884 zcmb@vdAv^5`~SZpna7MN5+b4~gnO@L-6=AZp~;j}WNL8ChhsR$a2)fPc{oTBA*BiD zAWDfsgOnjjDvgQ~`n|4oyFdH2H|O2=kDtfm^uFKsy`KBpd#!c7uC@1C`&upUY1_0$ z%m3g0lkck{>e9ay6Z?=DRVvXcm4Lqt{DnWucd>ttNI{7!5RSa`y?kE1Qh6(mjJRYY zeq8zA_~!(B&9H^GSJk+^cQ+LiK&e^h=h@*);so1Z!nYBmm1=wYjk@v| zL!Ax(SQ*y;oM7vv&avBi^}(4Y;E&JBFU7|V(n|f3&{?nfbg;AGA1fnp++GD|*{4SJ zy<~&WiV3#oe=lcs=<~^X@23Nt4gXjf*8iMfUs^W9cKV^;B^!KJekneyAgxs4-Y@GZ zhZ3C)|5zD;SR zN(%?!+YIY}POt~wo@l*q2VXj?0}t=g|NhqNGJ=oGv{L^~{I9d}t@BxBgwAS6s~l!Y zyN>RxZkjgUR_j01U58I6SpR#u^8Y5nHr5|6Y$k7P>ueMsmTn(vGQ!#5FKd!Wl*V%kPYz->G5(_;>+R}aveUM;Cwvxz1a9~B1oeJp(COvVncL9RKT_Q|Jh4$ z`V#wIZ2UKYUP81|qCBD}VndWtR7Y(1_7a?e#=aLD|4jsGv^i8-lvHep;)}+L4c}gZ ziv+Rn#m0XVL0Tz^HlpuhLn4=Gy4djTCAf$d`(AAPHxZi(432uZD`(AAPHxZXZBPID>KL0m?5y1bQtq}6B$SWgE>%W`A zjvOaG@=A>Mt&(W-AL@wjGOYg@K+4Jn!_4+ZB~iotOOWWXFwySY+U_zNJhBWDzHPDb zbK4}7_;Hf6;U6n8>VM9#SqXjYg$)m1vf-ZdZyz&b=xS%fKUQMY|D0iG z_U>y7Z*66$=`(t%S_`d{+Cpr(dPjtTTQhWF|_)LO?Z(GjF zx51?nqyBL-aD28QXC#!=mH$g(wBW1BHs$Un?mGO>V#6o+xIw}{k`Pi)axG%RKUQLN z$6dqiysq~+8~$eiDG{{Zb!bH){9l5^Edx@}x_4iyE8hm6Ns#bui;Zv43%8&*iVgo* ziBbP^h8=q}6+RNZWWzrzK5mfkX}NOW2A4{V`o|615RVnFlC$zlB}Ol{9|c9QuCDyg zV#6o+xIw}{k`R@kJg1>RV#7aHV)Xl?qiv6cjhqetGk}!mpogoVi$eIn1c|g~)1ah6 z%Rk=+pGlDLZ42Ss;8KZE|F{{}|188b=(^}Tw3SMU2FsW+b{*Lfe5@eh(_$m`FU9y{ zT!|y`e>|q zPaeE?_DeA>HvBOz|H30={$2=w#LB<$c$dEy!hdGL_x)UoKMUcHSos$o@ACITT=^LZ zm*USt_)moR$qkp{&qDZPT>gbe$o#z!SAGJ;rTDWD{uq~k;Sn-_FN8nl z9Km$Ff#d$L4=mas<=a6XGjfvno1*>Ff#V`5RJias<=a6VmgC*$R$e zI(s74hhu$->HkH#z9CIvoETDpK71X`|Lz|Z)e(Z}?1}0%2S!ENgkU;*;=_)E zqN1KcFr7VdVN_C76j}(TvnOUQ9UPS?AOzFd6TROU5|v0J1k>3Q1GgqeC7KDrboRu8 ztf5hfm_jg}J#lQ^u&8LE5KIS&HZzAuV^8}t5Wjr_6!lP_Nin&5j)=yd_GdtUeL8!h zM5&Z${Fy$}*%QfqQljza?M!D+Jo-*bH1=FQ!!n&c(V;+UH1?D{!!n&c(V#_YH1^Cp z!!n&c@!H7LXzU4ghGjZ?V#eCkXzY1(hGjZ?V#U7HXzb~7hGjZ?;^QAvqoRK(VVTaJ zIDIZPD*7h`)7cYBjYR(u70a+p|1Uy%Tr7qQ5g%p5juaa|`2EmVpBN!$6(7k2X`hL! zXpE36kB^p^_REKDNbSZ)WK3sINDIbCeN1OhNH2+xESb)pke(PHy)vCWA-z35LS{O9 zLOd!y3THZdLcBIU(q}q*LX;tXH^FrFgs4yao`dP^2~oKCn33u12~p1Yn33u12~p?x zNRR343HFu$H~)~B5g%o;z3gpBT#An}na-Y&*cTsVGMzmk@ijimWIB67Vt9O%$#nLF zj1%IcOs2CZWGoUNWip*TA>*C+D3j^z2^mwxN104#PsEfiHp*oBe-WanaUJy4^?woa zTTJa@TFj%`7#GyUU@0Nv1m^8F`)i}*mn)4Xh%rs7|C z{ONzro(PUu`AB$veEW@=H(gpy#mC|itN&SST$u=tarsC}%}MB-`P!w`RD3KR(%ZD(hLkISFM2Il88otMQSPf{$mlxwJNlkHzWY$464?)Nj4AYCaNM8^y=syF350 z*tjwgydUHvxs^^?@wHKWEWRJ~KZ^~h^c9HU9V8z~sS%$J$SQg;wl<27#dnbYXR-12 zr-QROV+X&vJvhD0_@NxOG*tqA5p;>p;h^>wC?`0DLcd7mzYxYF& zzLt-K6)%T|XO-L*TN}m4;`>_vv)H&Y5xf)TBVn|3WJFf0WwEtU!DI1AFaB9o1(lFe zGPas3_Bloz0FfVd7KDiScu`9Evu9$XQ`uqW!Ssuf+BHk+kvkIYU#Sb-IxAV(BsOHt zRnXq!Af6k4G4f80Ai<^hY?WF*dAPYaVvF}2&MISPqAmRIJa_I~DtJ~x^i0{}H9Z_8 zxRgI{DA#dKrD3M-4Mp_hzcuyBR_tSIZ=LIGu)QGh*ULlA-^Fj#6K0eM5M0Wi{}da& z>L!^JbN`MUTA!o`ruVUB(igh*VzNR@>Pps*alN6|K|H$P@5qxOf=h9&EA?X8p=Qnt znchj%?h3Du?SIXD*9KgQ>kYLF;^6X3Zx~vT2`n(WY#a)+9(R*0*FHmg9MjidrB4mIngv| z@p~lNbG3eFR$n`B>O!|tPF9*p?aHb-u4$#N0#Ufh?~%7d1efA=!icQlAoJy!x4o}l zNz(oQ?PFglHs7@x*Dha^QZIvO2g0HSnc(9x4G&v3*!+1%XIM)Ho@AR3Zg5B zmS{mHxD?yN8tQ`sOyo>{z4E;zJ>k*5_O&nOy1L@}VS7qNKhHGQ zP1U6*BOmNNsQ3KT&ptVSp<9zEEB~a;Wql&IzfxB}*xlUr{K?3o5W%Im_b4^@TyOKw z;0@kt^pYwCu-3WaeAkz_1^En>ng!xL5Sbx@kIS@DKTIBEuCM)&zPV0GeQHl%dwk<8 z*B)G>+!rt|0df5HhxClPL4w2L0NubN)FGfCSWeQo2Vb6k6H8!)ZZ9uSjv zR?}~wJ(%FuWLl}FOP@6#f00`kPgckO4t`FXCZE3O}=mAV(iG!WH81lKgvNH=~w>kF(r51n~z45C^df}OrfSjF`kAaGeQ07o`^vsquFbhMgKaKE zIS>Ow1ef9-ig8K5XUr|zE9+~~g3UhaXP@6V$F(`Pf3VF9fjA0c@1P*TrT7eSKUnTb zbL`n1`u$@E^|&|s+Z}o5xw_(d3)WRd5O0C_JVbCQK0~GMn%vUN+^{Fov0rJUdknHY z-dO0?1IW?urw83sQWs6>Z!c_|;ryIy zlzWU)AA?u`;y}e9!KJu|Ds^~Cd(-IQkZ0M{R!oDRc1W zX8Qd;t98AZ{q6m~&vN~W`&h7-ybj_P5S9A|2`fIaZ# z9M`Y7j|F?luOPmvQeNlzCP;88K0~ESKH1J38GY6>b90)k2L{?Q)#kbO;2LFnO63Rf zU%09*aw45uYrquh_NwjIPS5bZ()mtrqaYI{EquB*8)Z|Af5yvKF9=LEz|I*=(Fa>$*Xi5jCa#-A7~%%GR^rQ z_g(JOG2#ahZ9@c~JJU*SFi)5vpGEbVFAwU(V*~6n*UfhQiu+iwmwW&s^Yf@~A0oIE zdx28NT0LqG=Paemp_hF3`anA^$6VL1xG%9i+z*2IJ4Y$qC`53tWLl~DD|?w*rFZFX zzHRD#wq=lgN=H6jBNQLJ;Gx^hGTjsT`?k5R zw{w4GTB$)G)<0EHj|&szD@-d@|NAbccB38odR+Om>Pa@e%oL|^TnoV~U*5fk`Lg2s zIuQ!T1eanD#+VvJ!%FY#MtIJ^1efC0RI1GGhGxOXpL&B&!n3>~_Wi;0TuJ-LV2N4HOOy`6i0u(z*;*B*t}Zi3gg89B(7 zuRqg81MW+#7)oW`QQh<#lnBewjTB%jLI-5VwpVB)+Hu$() zhe|#2;S=Vgmdo@DxOYDL^&orOThpA1a{aK+E7bu+(fgO_Rw05*anHx|_HFIVhr1T& z?zoR)8{9T*PpR{H?lad_sG-+N|GHUD(4ElRpI z#i=OQ54R@XMXp!PT)TU#*J8D2+KeA+6IRS~J&}85uwPXL@i>U4A%aWs8Dd;AJEv*+ z(CEmHi5*PoF)8-k)r;JFg7Rjbc&)rM$R4cJrx<--DAzI4qg(d?A#cqIA#VUOt<)~q zDDdFu$cG^td|Xxx%v#pyXd-oUm^XUeH!d|Ks*8!WrFL6X{Ayxlr+iTukz+BXlY93 z8DWndoacH8w=-XpQpq54f>;qbwPHV5|&v43xy=^_sIKK6O2 z4~QwPI_oYWf=jVtV0A*VoTj~ZuP2)L>1!$WkNgXq)^d%q&ntBT#J&1n@0}3ArMNXQ z|1scE^F#4Z^f){n-2KfEyRPeG*Auz-aV_9p4aA_5pXgqAI>-d~N~V>{TztQI_`R9B zFrHt1vSf%I(|EemM7~<~d1R&-Va=(w6LbQe8Zf~%&9qWmV52K+3Dq(KID`{H4yVv<(zAhtdo6qJt zA7pcuV9WwA!KGMTG3S-*A#-8I*ZO;S z?b_T!ZGqO4oS(CAvpuC=0Z|6TWGDj@?DI@3RW_rp*_`Wsz3f1B^S~!VZP${|x#-NA z$R4azIS@NREDjOuMNBL8%ryt~8%HX60}*i^zG0*tQGbDpIIM}>{z~-#kq$y)6cgMA zOe53Ku2nks4_A58f=qDxGmUxY{STPCm+aDW@SM7E$)Wc3^^=`{uupKk;SLhSsEl2@ zG$JSy>?=$wwH=zc2b$OznpnE?P`hfubQf{BMp-MBDsg=YGrot?2j;dkxpJl0cTD464PKiEUTfh|w_lxVe=0f8c`bV|)3}42+{WC$u7DYc z8Izaa9bq3?mF`9W++SIVuo`#h{ifkxdCf6Ar)GkCKGRA)2pjETqgcoWAD6XKso4|m zGv#})(K!%5+6^CSf4yO3?dTYgndDl3DQcXq&IaBA0egJ$~mfdtlil=e6vQL9fj{wuNa9qATK1mFq_dTZI~Tf zWQy}B_O76R%m>j0M3WG~rMPXBYB{pDS)HDu2jN+G(T9fHd}@Y^IIM}Rm3Y1j;ujDd zLIl?j(->c^Q|9$$hrF{>I+(@}rrNVummyC)SnYxeHylLE7Y=!!ga|IhtqFx&^|`)% z>MSn>eqO%kNPBgMc}^MFx7i-XyCANfKFjM9B3M_L#;P!=Xj`c0P0NyWhuSH2%kgwK z%3v>Ib%kDKM$DA<%XEE2oK?3Cx8IDK>LLznBDW@CHQ~twh>U?zuWpFoUdc4FEF#xZ^0l)Y{!@RLNlZ?&Ii6hP z@+wItBhf_3vBdg_duQZ9s$Beo1{cYO0~bQPjiuzTa6VJ zV>l2ufk+DxT#EG=TA9_sMqDd9ZSiHP7_(}f(kbk#DwINdLU*-ncz~a z;D|VdqvooV-MSn6yx8L5wp;GWP8ry@*&d$Bfan3@-VnjM!n9J~9`j84tgrM;%>1wo zJ}#fFQlCI~*FtyGpu0(Lrr6q_J?BPC?5V8aN_AOLLLcq)L`3@4%2H$O?zszGeC0kC zZ1e5=2I=WfZ;VKEW`av`KUV6q4g+<;XaR2+vWqdnrPyzjs`a5Usikf){Slove>>7{ zUNzc9XFq#ZI1BBaAclkZHbijGU>fUQSKfu$%Gb2a@aC*F!bXNoamv7Iz-<#F{sJMh zWK6KGFpZJrhZW4Mt9t5NF=Nu-q}Vmj%y5yD+kjPDsc|5>fv6KAxD-bTrB)XFO#k)J zo8G5Ax|_KhM%rCx=Q!PE4G!w=Fc9+}eAD|jL~tpN5{T!&tkgxCKI7GgULE^tl>KGN zJg0E1YHUxbF(8r~KjSo!32tYmm3s8qre@ZuT&5*vs=r^HVjsP8oEt5%wzKBPh=m~P zh6wglrlD8mYnpTGXX$2$oFxjR*!^dwx>(EF&aH_zUqDO&F)&1M8!)ZZuzfd}`(~%R z7GxXT{!HUZQOALLl~=&)2mk0=cZ@x>b-wdK_7$!-Jmsu7K-aygy4OEMa4D{Jr3#$5 z)5zb*y)SD}d$YNgl~BPTlDWqk~4 z;%jf$F_rpk(NDo^J5@-rTZc?`e$KwlG~QPOu`Y3oQwAp3=b1)c!{iG(&$&YS&GZhY zvw~hVn&rkrR*9f8tjJf%l$(~R-@#le6MR;Dwuqdtk&^a`P6^rI<1&pkEc^E9gZqE-CU)s= z{%AMKUh~Q`^oDRBDfSQ5uOM)Xn^uHa#KH8+g!ExRx<}PicD}R?mbv70vn}ZqZZ;h6Wq>h4}JH^>&(U`v-LfgMea5o z>m)`@bw0@c81%v8Al|!owjLBBxD>ahQm3KRo4VB2Z$qi?Ts_kE?=sWHTCN|~W2Ihg z*-u{_)7twEcPv{n#@Ons<~oIARbzFm$=j^~qCQ_gTBgY01E2 zX*Q+Kd>5TrKbXezk{_bpca$=;xojm;@Q>A=7HJ_Kh@M5SS-!HlOOmHbaL(KLqsB3=7 z^M~GUR*&U-L%V z>;9eQ#ta;BxaTYNB#60JAh^FWjrM@o-UhFof?56F?ig+5Pu}5Vf8=_@6R)Fn&EH=X zG_^3#IdADmTWrHv7i;-yS?BQ#AgzYEeeN~pR0B4}X(t`%j$Yl$td-sJplQUdmi`GDF`EW%$0>NZWMc6sIMu225k_ zZf$X+-&(Cd#@sd&T#9WgbvtaVJdvRXhitHRu{}JQSl(NIe(PATKx@2byLGfZS9!J@ zk+H4>wPZ{A7xZgAHhQab_6ZPNiX#KYB_L{b-{@tA2rk8OMX4qq-)WxcQQrKB=)C;x zQFe8|F)p5S8?b6)%{GWJASQ$eF2#LJsl|WhF$-#?=_#1iFS>rDol!K_+qs8xz2WIO zh_kn+>D3{EeT8YfCDdW5Zus%{-Ya;fU+Cf}d)N0fUF77N4qo{W1@`D>or>%Jm>Fe) zqX9<=^xcAcbcM%?>&HR_AD3yRDvWLHU1e^GTm#)rs5sVM$UV<#J1aG-E5<%Q71Ij~ zUx+k??lQrpg3+MTOzWLWXdn3vcV0|vxOJTE_MGe()5x+t%t6A&)S?$6_k?Wlak*FG z+0yB%rtXr6`2nktw%?Uzo9#_?y32|hRMAc#dV^SqcSf1uQmpxS-x*pZBMlj4$e2X> zkmwa_6x)Ljf_NRoWGEaHtaeOeO;OJ3rslZgx;|DReKBLCoxXUy8(Fe`uxexPGZ43c zh=d3(#cGF{hVwghyWeZ*0q7+!4H#ulOq=dT8QjN${i@{3-*n}hTkB02moUMlSm!ZQ z4PpR@S3?AsVqbw$m#$%|WmYk{v7TZ5jL}y9SU+XtieIueRJnEX6nYt zdNP#Zvl@v0Ri?Vg$+{BMk~cs^-=3`B4-s67?J4yvlzIh}IuDe3SLc^ zT|rO8?5>Ad-mfvkD=Uy>hC%LYdGzA%lprG+b$dB;YDH61zT(gT!9Kw>R?y9_VWNe~ zm=r|LpXwn$_4i|3bmkgm)kbzP5QRaU2@zb1+aJ#vx}DO^7I)VVVm(9SZ%5fOYo@ur z%YBJ!8d)qs6kXC?-w`6XA2Y2~p^i)SXCHmq&v(-%+WK!rTA=>>bc_v^Vnzm^lGdSiaa~YdU}Ez z`>cdJEQ76gF-zb6(dA+2B%a5Az1ca~gBkT>TM6h--jkkVRe4`IE9Iba?{`^db(e{VkQ=Jbo!M3qBYWYcB z_5+=tGr>O3G**kuz$l}0`^fJYWqiG6tbMr595<5TQ3j7b zurA}xB0Ayjirx%7LuP_il+{(K=Rx$1R`h0t2tF>;N)3MZdeiRkz2+*cbdr@+^2A^6 z2U!hRQ8E7k;vo>_LIjs$1;-lUw=0?c4T_pJh-%aKjJ7)mrn#uby30KuS#CgV1CcXC zaDQc5sk8I8>&nX-=|rq&$bHKgTeR(T=Y#Bb+%_1658bNoKGs6Z+9)Qt6t^t0c)-T} zOB(5kA%cCL?P31BZZG}ivK3x&Jj)oeGtCyidX|fW+-j`aO6926OBY|h!jp9}OmHdI ze5GXVuB_pG9Fg<2`QvTUb3$gW)tJWE2fF(>boXt%d0+YC zG@Cwhq|UyjB9P0p>;8JWGPtRdv zF>Le-*(T=oJyBU^Wa`Rt?8CKYQY9$h@f%AaIXVNd0n#u_gWhd~St z5$y9!E42|3XAUCHJ%~7MJ{WC>4IAg8GuJ3bB8)P=&Ta1gaG$P%nFc1fZJ5T}PKX9I zBct^nhz3Q=jek=1(39ckUFMCke+`}Hw1n%2Y0Ls-mNAc9 zbGNC4wNbJzN}kNiofoSpt1I4|1ThN4VXR4Ig1v}orLJFft=U?puvvk*)bhi|*!9^B#u z$Ht=6kGbCP6eqEu-uQBJPgcEDZ;)>L&6?%nAZsEkpHeT?YUu4LH$EaOotRj=f1KU* zvFsY#$Z{0LDx}*yuTK5+h^)V2f=h8k#kd`3_2t^;-r3MuaVb7SrMf>{$n@{i+N5Ll z_5O|HZPCAny2#1x%!=w0lR^ZSVg<+3C}`p*(8T)C#BFA*t(R+*Q&HB(peEXp#W3?z z(X7H8y~J5*E%90=_(-@vhsVx?=O)8znPA^$8mp;5Oa&pzzy$X`rZM(;^MbAj-F+Uq z+okImd+n-;Zq&zq#~zG(oB>^Ri??=oMGyyH8!*F;VMk#i`B7eHK#$jJn^8q?T&`K4>kZg}lm z@YZ;Tm ztqPfse>tb`MZ`H_(`@qou`c3pjj}#swFroEzn;^#ga|Iht%>}iNu71W(+AxOp_QMG zwco9s;rcH3%3$9u3Zlvt2rk7njhQ&)KG1j(UI?5>=D^XD4Qt!xXZmwCzyob4M ziJH<{;)6`^k&sId9xI;vCcKsj_TZq`N@SJ@Ezy|?F2(k6<>&F{PMhgE1FMi)V^#6n z117m~32P#2WsE2eVo``--)0))tKYBD7491C$qI(RDkfGe9BdD^&6xUmOg^k<7?*pjl|RYE#r=wV57xJ%^gd8! zLIi79P<`b1Vkc~aOR+t?OLY8seyumo_Uby*sSkTF*Bj>5QttFV`f{CHWx)h11Jlqe_~7gCLCHWP8E)h)d+~Gj zN3Ln5IwGolfT;F4qS_sIO|Yv*4tJvru2GIe=vRmzw<3NVNBkJ_c)ES|(a|n`u%`y& zhj^@bu6V7CFr;3@&)MghMh2RS7xdu=3YrAW(KErN*fzYj!t46!uKjcp)-5$#GS;?g zKG}`>*o!za;2jeXKX>V;$Akzj#gRxU$$}u+5F`_VWI>Sk-{iiQYnN*sYX^J$sS6}O zVD_MPnc$iZ)^6AR=k=>w9x|ITW?+Jqn(Zm|G>A1Ij)Vw4F4M>}@yi)~u=y{#8`c_B zJUG_MpX7w&o*(SHLqQa5@r!OBBDfT{Ci1Wp{#ZZWWr@zhjADcJ81)^W;Nm&gC@U() zq98s7@j{5;Qmn3+D}r8)hF%?mUgbZES+Y;2IfY{-3hLEAOKW-UuG{21s>+;k_LVg= zoDZ@`v8Q2V*|moEU7c+%Iy3S3xCwZ(e1?n8Oe1pczFOy9GST@t6MWpDpC1QNcln9>=Uc z6MS4gTdbfvo7;>Ve5?5otEprqmCUEe9X)G1Yd&VlKy(1{Z-`)xVj6G#etBH4d*^*U zA0vQH*QDEoq2t^LfTIEX3i306xE92FA%goW)9CG^cjyi`tKE9~2p9*H<3nq5Puvnx);4-f{&!sk5IP-&@9m_CRpu)dUYN|PY|MsOmHc-hg=q;r|4=Q7`+5* zqXzF!x7%--;>K_saX1nwb$rwmo%emC-wY9~QB30rWX6xWN!=!95?WAlOvqb+@(h4$ zI@p5K5OMM&;v^#CFu|p`$KY9C{x9{)#-HfTSkKTqGu_IcWDevW&h@5Lc@Ur7^NAiC zBDfzjjaiv|FYAW&)AUr#3D^A~-KKpw(M4yD2Hf+Za3H#X7#AYAMw!Mu=bu;UZGX@5 znqYiYT(tB_>PlFU%cGXT~^_F&xIf#?mQZ-`(|Wg1WJM(xm#LE#QS;nrU@ z&UWoF-i-jbow>&#$1n1u3`L%lDOdp^nUf?Bfb@3muY66&nF(SSi0`nVOk*zf z$QgYGdKJN3>eV?X+EXbhE`IRUvUfq-6Tj7)pgxk>sNTMD_SQUDQw{ZDl?bX&uCcrH zs)pa_7cfUJu|uv>JcF5 zPv^rbq*H~)+dm3Tb)zL#AJ#FvD+6L6h+H9peS&GMbw0XIzxHNtQxy9G$SwksCtAiO z+{1&Tj3vmD-T~Rtx8WHw6I@DmC64XAE#nf|sX%rtklhNH;8LXBwHm zK$HaWaL5Mx3e)iOR~qXQ(@X0T81L@;X`J1@d6J7b+?v4_{I^}Yes64BJp(hNOt6Zw z9^OqkCX3b!NWt_NK=txH!md&ixHf zo$q;GuirP-MNTHT)mTxH6A(nk{;9eRsy8x%O_y?pJ9-fTQW zW`cE>eIECmAnq*wqBk={@EC<@JhQ}ECF87Q{T18bGhte(-7Fh-wY7lR%qdvuwu7zAkcdjRvFI*cOv?vl{(O z3p}A`f@_*-%p(81O-~un(fok*qRXlx)AS=rPDNP|WGl;Gsg4KX&)D^O@ zNj5gg#3p$SCEJi_3HvEA~6q;Oq%5#d?fq8HuTS zOr)!xjyRZ9Zi21bb)t)$+y<&O<>8E<% z57(Pa%-1r(n#k&kmE<6r{dm1e2oZc-rm^1Vg|+(88@B7uv8L#wQ4{Qeoas&zSqE8N zQM(}Q_1krUsX>Ajm1#T?hX0L*ABqpUsEOz)KFI#a8jL3sASB*OtYv~ru|4ESfnGfW zy=n}-lKoyJr@GvEu}`pfA#x_{)o)*2%alRHk!%j~_O0AUvHEap!au5P)%#jjG@DVo zOmN!-+am%S@4`lrkPR-y_LRD1+aNvUx#I{-RAYr><->Z0b=P}87C0NJjd@Ncif)-?clDg= z;vmOFjD29^$Hs4Z=MmMI;CRLM@cioQa$bocXWU9BCiu8aW3K3uihhHc(F-@uvR{|& z=b{?7Gpj51^sc&5&tBEme1cU-J$g;Ei)IdX3dgF(>WXn9h*S`HkOhhf)<>psclX>Y zdgbR$%`nXBOYTI;6-pFJFP+-p4fF&V04D&UI@IEm@%01|OIG2Jbsx-&wzsKG@_zbe8=;Wv@ZG zujQT*jLsE6yal2hc5!8bOVvxAV`Znx*lx6v0ZKAKNfs!{03~nrinm#+^`ybisfBUPU;i?RMn_Cu0g zHRLXp)qrCOviyUn1>*e>!KFA7VMTn^t@>-kj|qq$l4C;ND3-faZUb(A>>2i2ZR}Z7 zLrYeb;rk|9`IEe*-1E5>usQ+z{K|g6ve&Qd3@p2zN^j@>I_vyAD|`RO`mXGcEBoZi z9=S|#&u1EXHEp~eGx%Ba*DFc7N&Q*2_!s?LtmUg^4aR&eh)Ez`4G~<56&x!}p`t6G zqQjx0!?3f;fMUr`McIpjDk?eE#0Mp>n&fAc%sk?Q?2k<28Ck()I{lM9It8ncWX+O1 zla~8I?yszNcm@EX2#AFtf=jVhA~W}bvHI3rtKCdB+u+{E_HYL|=4)@*{&!t;p44%Y zZ8c)Di_RPqSsyXGw5F6-@9kWktaM_6qchXU+5byXZ_tTrJjoit#JJp3Ftb0!#dD@H zcZah|xWZZSnQ*UEYR#FBy6jDZj6`SIwO97#lzUEYXVzfs&ULnIiMJAKncz}vPbt}#T=pmL zjFp+P_qptWE$YL%5>%hN@5<2mZf<8@!FnIrZAx}2kb6$nUDji)xdU;eaywHOYl@g) zHDDTRYp-3aS6^M+ltdhq{15Vuo!q6e?sEHMT?UBlAS7}!!R^d6-f-Lhxp#Y&y@Hy}i>m|*Q< z8Z*_1AGaWWq+z9#tc#N8_j2#dYQS*?&v(~7sy}Yu*Sv;UD?4Y)p0aW$%r(jyjQyRl z*S74rE&FXV!EMehi*@?2u?aSYAg2=(d|aln_WZjH{rzvHjAUq%d`|Mlz4##e9oGVO z$U{bzLCCBknOm4(e`Ff@GOn7bzuftS-hx@n`>^We_Q%G!c+U018mv@n5OqKt4-s67 zHD9S#1#Z^Wp}QxbyZfJ*Yh%zyu!&>%yT5 zH-GxMH!MW38ZeC=@^0Si6@dbYmaq+038tZmi2gDPkP!eAayKuLU*1GwUBOcvD32(R zs1FlditS-6nsTGpqV))KYx$wxjfWT50o`KJ;F@6zZLg~F@uy^+j(v~pVl%gRU#uK% zhCO*xfZ&)Bq;D!#-rJgYnAw7-&TJ!=k2-!_$@ZV|?J%$KfUcd!I4E8pZao z>IDi{3<{SFP3(Woe7nMnsVMsd)0lD3Jx4!U;C^#AvOvkcXRvzH%peOEGH$XnfVN6$S!*mu4A=j-h)bDF~#moULmjlB!cML|@& zKc`s{BKWvWOBVBLdJnYZb*!^|?Tfiqc1joZVU^%|Qz~*MzxECeFe^g@m*QGSj;%_m zdS#=>%*$9=vwqAh`{1nu-I#%+0ml`rFR7TSH-ShD5nQ88W3TvLbM#@=(TE;zD=85ts2=b1(p59GLe6`AWKZ6?x;qHj^^FNG z#eEF5i##vqk?%z^O-Yt1$zdS=5$NF*i4X^oOQsJ9$qvH=`$~XT^===i%T?H*pTd0Y zg)gx~<xKuDk^-JF4_5MEDj6oKtt;ZJFLSM!7 zm35HS6`6D{DfI~`H50*7tkjEO<5}2P9J0Y`!1l1m$e;Oj1X^+qTJlP<`L_SReVqER z5;2YE)CrUI_h%ZJ&R82IJJ-pM7xL7Am6{bCStCGPd$y6O9U@o_n8rM3yHWayT(wOW z)*7%4))l7l)>ghWUEqaddNRf(lJi5}V3a2l+?Tjl;@#Knm35AO&zNFZW%13=b8Y^v zF&|`~;99`j%OFaE*o##bOt5z`jhy7g2I%VFv@r!S`&#m?S$6rRK`yFs{jj1UiwB5u zAZ`c|T#8i!Ico|`(0AW`gE@{BTit%1ZgccYahk|#7gV?jAS!`48zQ(A*EGh|$UnCg zS>+^elw@0!oJ67w?DMR_$Wj1eIEYmtf=lrkD)su!*Xa}E?#4RKBqOV}WUfQ*&)JJu zgR%AlME>!2yER@+a4GhAtV#X-K5e19#bj;NmvgM_-!1pfT%+8Y7}Iqcs1@?Pw807p z$>$^)LZn}DUkcQMYKUDI#=n65AVUQAN~ZBf?s=;VL9dozzV^KrrrPlzk984;&z*G) zdsJO0>wR1~$uwA+q@Vg>f&E}n%xh%~=a1WDhq?Io&-`1~I}9R%**+#%SAz8Q!#?o- z$UDe9eK;eDI};^KF#^F&|{_3i{w~5O;&9 z9wN9D+rw(Za?k4S9V?j1m~od~>kqrv#-nkm}N&y9PG56^@?>&DGg#1 zh$lh>*ALTpa<^`vUYL^KY{Dv}KYGrv%@(FQEnzj_wo&Q~h!haJLIf)j)5wmW(OqAM z+-j1EO)>~dW*+fc_TZq`zKFbSpMa1|Y)o(|wukxins0m4s-N^TG_c=?!37DgKeI**y!%9A2v54Mlr#qSWz+m0b)Fe-|*f9 z6I_b>F`gPA2TO0{Vv#&7lFvyp2Z%?puLS)=@;OOfC&}r=1efCW$6Dtf^Xs>cwbVuN zWMadhX?AOwaW3Mp?y??Z1q6sB5G6wdw;Iz}rFUV4*JI^hp6ms|Hn?q=Mhi~Z?#+6? zx2b@9OZoqVwy*B%?hRPgSdWo&;OSD{w}%r=SInz1A$smd0NFV`b|mD#>Q&176vRg% zB6wV;k9R5RjlH+Kxfaim!#4cm%6{(soGRg+hD+B`K6D+d^L$Ns;`M9}eRH`d%}(f5 zo%-`_wZ~%$#~Q`7Qb$4D1md$0!D`2}Qtc28`XL&WLNt*5^kfeRxr1cIVa-PiuDMO; zNuTL5G)d+Qc|Tb02f1gk&cn|^{4jQ=egW~E2`$bwZhH*yHDc zm=ChA1pVX4=(AqQC)*hlBKXR=4lzQ8joq-(C`9mana1Uqx_bw7w-0o;_ib~n>?AMuQCy?k{unJytgMSxt#3M^J(%FOVOmxKR?r%` zSR`|cWM`7M)1~in@8dJXlRM;jDFQ;)8Zg2Am}%_2obOoV&6YQNl5c5Si|ID0=Xe(f zIpVO|VKwfnha#O$RQ6sjSGA7{xU1)u5t7prU_6MVa8^vbth?)wQTM0(x~9 z^lEI5g|>grn3jaK%h#(vUfbk7*r1zPhm}rDuonf@r~igcUJDR=Lj;!!+Iw=;Sua1l zwj+G7Y}@&^&OZZOtYx2Pdw4n+X{$?CE^Jb;rbu>`lU;7)&WnA5wF@)VAo7Bcz37# zxWA#dKUGjSo7T*{ht&y_AAlxSjrj-n{Gfl#-}#;A&1~-0`!K<^%e9V72)zpGaj+pP zAei9eGL8LfPa1t^#mc4z<~cu0oozcG80O*!*C?wU_NW43K~xG6T#7vyD@>tRbD>w? zK(9{YS$KN&m|n521of&mvam@uHp#>$83ZMFkoY;*Xwc6kAE4v~l$?M}a4EKj$O-ky z1NG?z^||_qxmI?rm-{F_cWxWpO`y#sXNKg?Pxr|3KM>*4D^FRPQmdEx!|i_8qTV5=&blmg4cB0d*6Ar(RZImPb}AG zzJ2hs*s-`*@--=yw^dy|w$xdd5lHqulic}okHbBKRRT|ILEHdBc1vS|OR-{Le}nvU zy*s;JrDgOg*#qQlPr1iot>xBKsu_qHAVjH|VAWAC1}0h7uneAO&wH`H%l(yW8uM!XbLbHuI)n)B z`AkE1KmOD!v%8@g93uF*+_K2f6se|H4=ZNgz+BOd`)1qkD#f&&+kkZi`>TOi3?eH; za4A+Lya9Tun6C2GdAGkB+u-(Rd&t}}Ccpk|*Fr6OpY6>1oV|VA7^fwy2CPb$j{@-p zh{_>?b%klzK)$om$a^NrAldySN0cZ7s{zxPg9K6N3Iyv4(`b*o-}he6=%SAzMzIY( zE?*yZ^emf8Z#+`mY(wqtpF7veZuN3+!1Wfa-MR%!>iqkwm5EERA>kZnDEFqFDL}sd) zV2@&Z@Y=O6dgrFKFuSq#V{GMx_QcSbUa>|6wX!)>bQe^#BUF@$U@2D7lWSh|u9@D# zYzf(5FJgOGd%piu?@svO{qVul)92eiej4mz6#G2W$Q-$}lpdS98+*ldH?m)t>_#H@ z2HeA0QDvlGN_QK%TXzf*T#CI5JB=rw@(w(9i)n&6$b=R1Y@6}1e#Py~XNa{?Lr!_$ zg3uv?`xw*6Y}D-!uTRT;Isx-)hpWu72l}SEXu#JLJga|X9}_6U%a}1?f=hAF$2u8! z)LM9yWT5$X(R21`>@zA}%ib0AD9Jx3dFZ6?O8z;?-z0sPdmq!#T@bf`ki1b$aIa(< zYdMiKN^(a@-(`aPF4K5pqx{PBPa?#9=}*&`P#Ci8yQz z5eHhb6!Znq(&^$&fDNUG`e; z`KVnG3qiabBDlXYt<;_G?)9)2q*;L(tYZh~*^+r;Ey%4IY{3dU_Iis!%n1=(ifaKg zqu;OcQZHOia4D`sJX`AehgS`LJ_vpu89B#(xNoG>E52IxW@P^^(a-x4y}dDddzE^# z?DmA14{|>a_V$mbEsY%ds-Bw-XM%e>(|8M_!GuVw^%3{fnF-lJN%Ahcr_SUnh=V1w zyc^#7)Lq94S!QMXm&WYYm5R#LFZE&fey_Gntt8rEZLT42`lMLLg#LiZ!{4Zxkt{Z?E z0C{(bu0sgFR0f__40k%FR4(-0Vd%RH(c3eR&bN~`$A01Z;cJ4|c3kcKGq0!1upzqw zNltBvAKd%cACWNNFlF(=Ffmtz0N6R*4*yisVuW@y2^MdsTX2U1+W;@0Fd#N2kL znO?aEa+u~Jf=luBVGZQ;E#A-#%k^43-|cV|>-23*eb@)NA0w+gh-W~o4-tIsOk=l# z5?NkO_{VVg`PCifS=mQe#wC1Qz9y{x%uMpyZY*UEVV11NQw!~yr(^BGZ4hkPLTj@k zInd@y(dJA9OL3cjurbL?gN=@sFxUEv;skv@pMS0K0)_a5vT3cZ>Iy^?t~w!wPE_Ao-8I?LO? z>T}%>PlQ+AH{T|iSbK0A@HOEXz_eN3Xb>qOf?JbmyeqSFpcl)yq3oyb&FWXvvPx1lJqW zcshtHztDY!n=$!i$vi7Nwn}v7zRR_MXW`Rlc`HDOM=`@5T0-~YJ!VQ=y29Of^~8!*8&8tjP`S3T@yf{>X8Cb$&)4Fb-r zagl$H9@J0b-hc@?EB{O~?AW8J&YSVxUE=acGOlBK=sJSOlFu|qR9!4^C+Icg7>FYe|U+l;(yE;mY;-1L0fT!mm z=75lA;Y{$kGmZPfakagN(SrNYf@ha5v@QRN^#*R6U<UzpCzkw1w8j*f=lt) z;%%p!s(Z=U_gdXIZ%$pn|;{)U~* za8})~a8_K3&k)z~)uWO9SmpEr?pRiCS!n0>iM3#`M!C)Feer1IH4w7nEfbIs0CK`*_JlvcIGq0DkSXZ zJq7!E%Tog;xXrm`v9f>7p2%R>kS7yNa4EKj8LZPEL@GZwNFT?QH#)M=wmLJ~^>)6d z;Fa(1aed_J-AQh|%S5mgx8T5T*GD2C3SxxJgtWQe&KdUmqcPja)-&x`!%i1tSH5)D z0$XuutgiUV`T8&}>9R8N#E#gNGr^^Twc9LVW#mN=^4y0BF2%K=RP}NLBJYkY;hxDb z!KH%NmwEW@hTS^cd4rY2an5j zb=&m=BI|Khl4X+#wil%D`Dt0hPX9D<_s&f4Suu?}uj88<{$@(*Iia(X7W7*!!=^nO zJ6qJ%%JU6|{N2>uZLh{#=Bu6UW(5U_s%NC$baM$?q6^$ zIiCE<=NqH3H{s)-<@-y7e89grk#Gefexz7Q`EQEhOkAA5B=}Bsb_AE=x2yc}VuPR1 zajD>XIG+g;Tq?LaAv=Og1?Qsz1np$SxwW}Q{PONPh~QFuO+kWpu;zWRf;(;aOp4)1 z#-*~i!33A$TK6r;buhuD_&HPd1efCRT#yhYke)3uoNIxvDSKjh^K>g35~hPh%r9cT z#>eIB%bwsfWIB5y=CR^MjhxcOuP=Lo&m^dcJ|q4v$GluQ!^#k6;2-FT^JZ6q8pL*C zYq_DK`z$qGdG}53bG)?tZ;Fu~zOrxS%SuU2Pdi%SKL{=*^_KfLQKCjTYyV%+MzEAz z+kX*!P1#?E_+7bsZg$rBnqu{LB^#nqWp`C^gect01!JH2Nd8qwU5OVp99q>8O#ixv1J-=iqfP!KFkWTW*Ni&Ys{> ze6~SCdUef%v9priUVc^Vvna#zp0UqCLV9)jnafM@*=A30sqD{+ZSWape^xOcyw%lc zunnXIV?G}|tILUaDc_s3CxYjmT`yr9d`&^xw<21Sh-;AJiFeAG#IGs4vzm6aPgMLn zM)-8@-x8zZ#h3ee%MJaa@!18YEAQ?b70> zD(x#am~J>UDJn{F`IR%lHkc0Dxb>AGQPB`NR?7{8qvGrGxmCj<2`-g>COIlzeEC_i4Q@d`!>|qU)VOc^UK>1;&%~7>POvgCoju{#Ld?dM zVy*adJQ|38#C1M)O>x_7L+ZyLe~69Paiy-VJjxJ%jz<=@m%R-pM5E#{DoFELNpFac zucR-<$5hhC;$tnpy!g53Qam~b&&0o`|3&zvf;HkZK^uHcL3`N|d>wp!e);fq@R=|j zBt$LaV-c=}>}`n3#K&-4N|Yf!Mh)5!eT|P;L^Y!JZ$lJ0K2GFPd`&?cOmHba!|Vwz#n+cT!PmrRh<7ulj>vi~S$Us*+SDudPpVTm z$$xeFTxwMEmc*VjjJ%|L3Hbk4jZ~WtOdVk^BG=^MMt!0?ABg8HNsRh=QAA7R8H5n| zKzt73rz;TgQp0SYsGniw!SsupI+Yz}Y9p`O)uvB$m9 z+-+eZepbP=y*Oga=H-)zn{h{*dPymLqw&mNTq<~0JyN!8ejY?aTn7_eYC~$@sGq5D z`}IXK^CG+0N61vzy?noDJhvg!LE^3wH)ftiHpI;7B?1JO>YCLr>Syw7KJV{Mz3L{J zuaMd3bi+Q;f$8ygjuWH)+h<&Fk1Y6mQ*RKG3n@&*Yd2Vjb6?2Zyt3?2vl_Mg?$Ex` zcs>~}#r1}q9LqB|zX+lcT964Y#kGL9Qa-;ev*)F(juSTbi^j8_a=itwyv|#NGD{%K zO$B7R`QW;K(Ri*fwimQ9@e(1KznI`sY!9;lEq>or{O3dyMHY`&>-CAgGb{cMUt-jM z?~ZG_ZGtliTfrh(`aBDfUWbGdgi-1*5E(YwAXgX@T+>V|wR6eIO@FuTZgwF%%>A|dMECp@f2T4r>c9EG?O*Hplbdoq z*xk&!0uk>e!QOLm@P^Hc&h<9a&`YX6+cz42^PXFf&k%E7Am)Qu79#k#Ok=GU5fj{MOe6EKUbDGbuWn{N zdSbUOeWUSrc)6EwEnrm`h&CW(*Ec5kYMDk}&Z4a|Pj2sPe$Ikk&FUXLG%=PN~ z=4qFRe?kP8;vTBhhV7Lz3nJIcF|>KjrTwDu3{Bjc!8Sh%qR^%6FidbMK100c)jLO~ zyzjgeZ!h2QPv2-fqXXAMu&(|;zRm+oiehWSO;BQwU)S@i%A<&Xn{2`@+pZzXOi!2|YW-T8fd}pO_jk3omN+^gkAkHJR5ffaB{S9xb zT~>K6FYB%qgSUru2^GGbll&y?F^aOR^D55?5Or(>m*SdMlyi-~)<4DRTrCkF)w@NC zi~GW5E>?aLYkVvR(Gx@goX*7rmpaljQUomt&lrnVpT1r{C`M=Q_rZ>;iGmMsO*P8|0a&Qbxc15@%Gwuil*%CVY8u z*vG7X)vIb5{XPgY8wnF!ik}c8fOA4$t@YKOVYe(3T#A1m){!N@@D#|{XjdWWxuXcM+ZsqNcEiix$or#td* zvOd+Ll=b>KczX=S?M!efjslE#&kFqkyrc}ggMv01Pkr~QR1%w+!GEQA!g6oHAtePB>Pj_SYay0ggHad^^ z$k-vxPsP6v`#*lTq6>`@ zDQA3Z%tM5KC3%SO$IAM%8`ArNXofv;cEVT68k?b)#^_VC4Av$gf61HI;lg+J0DA^U z7qS$9m73!CHI7`Gf|c!nc=l<9=FJylp=%5G^`ijFLSLd&ZpQ(ZX>nI>SqLzr3nfTQWd<@TjGQV2@!MIcpHL z(TLhAcvtHZ94V^Yj*uDt_}6l5!mqA2)Q@iHqAfyvtnWTrbR6x?TF1U*jgMl(^64Gm ziQmIZS`7{pzFZdUl}sy2P{l)f+MvN&7?dG6EK2y!+vX=>&qr>N3WxL+AcE0zGQp*| z7I50l@iU&v*bO)wy8%n?4;8*$zuX4=go@Jf)EQ4x5KbGx?awsUCw5$r{uKKY%{`-C za*h)Jbo1?x2oe5u$n5!^E(_8NMHki9XF~Ym!x{yZT0hb+{`rL#iX8E$)1t+(95K>M z*ki0-a=vY>zGVOBS~g_A2)Pk1d^zGdJ~(c$R;^vEz7<3qvdS~T?aVZ4H!{hyqh58b zIimL03ZcTc&x@a(V?|LOg7AP)Z3LI%n#MlJpD*hIXRLR?7nYe>qeV!wXql6k+uz#e zwU1xcYlGN`H+m+x6xSPi=e8^K&?9}d=6J6iQXx{jxE3k%Eph#DtYA!?LA0|GT#6$N zy}{wd`uKg_wEcL;VH;f2Y)?^&lnv5v80r*|dY$eKz)Wh$uSVw-X^m`1b;^ zO62`?T>4=UM=~LNT4L3h;09TZ4}*GYJMdL4_lOuV#rMRXQ<pc@d%*8%PCfH+`#=BbOp6RFX-fW&(T;egl-9Pf}1_}}Wb^5Fl zTT1s#p9R9)^=l`5T4L3hh(2%h+kbY~RwEPi^3P*L#rAPBYB?UQG1%aXH~M}MKfZ4z zxD+b}zF!TztCx)Iq1AvV7LAG)-HXRc-(^3xdg9L@ii3F9MsO*9LY(b1`Y$~$y^D4O zU+&ljm*U^2C<)M#NN7oaXvx?m;lh`nn*Eg(1HFOzk>_@yY}$V4?%OX%3Ev(?j&p8J zoU!is$ny&bQ>mHYHegy&78E(HFUASodGJMe&Cw`v^hS&vWw7^gyRhW1$)tmo{Bb5~ctJU`v)B}oE)sEQ+RtcuDzxMkRo&^r?uK08Bh6!Kp z1dc9i4Awkw!ZQ}cH;6$dxD?w{lxu?(y+p|(+6nArWr9ob@59+OI|~?{VmfK(@vU#& z?pUD>N|b#q_pcFqV@2l{i5Y$E4^Q(Mm%={P)Jky{f}@COWZ*xuLvJ+rQ*9TNI!CD} z;X6;56^`2<8OA|01aZ_xaH}zmbCG+^@f606-1gX!J1;U+_;yIMhjUFU%A(xcJz>~W z-N8n1DXv4z#C<-;QxP`Iee`UDV}fR>bQ9wWYa9w+sRb;YVBwPs(_55Cn|%Ymqk`7By& z$`L1{mgCVHwMFJ!(>H+Vi>PISOR+ut^0(XR#oZ0GrO3%~Y;?Hr<)`K-V(r3=B8Vy= zrq~EB#ma}T=T|Fw!rs21hNJ&zdSjIE?HT3zVeP^$>?;*LeL=+72rk8~sVF%QMR@XJ zmuUianX(No#lCr6-K3t2yx9hi!0c zvOVlxhWb>1`W%7!>^~bO-g?WM`HQ2-sy^FtZuhK23^qnYO@10GeEBlCMwv!$usN^M zFQuba5VJC!*TssjzfY7S0QPWJBAm1VqBn?5<*WpkV&y}g?GYRGkSVRSzUV)4{t+pB zC--vwuo5ZCPasBv=wKtb6t^bcwhu&jV&GRp;a4?!gbLrzd-gG|1$?co`Eqy5V^Q){ z-M@bc5sM%C_P&J(|Bfowm1)kGyRU#S_tD!4pZZu;snm{=M%!GiwHxRSI(-)>Dms#6 zZ@~3q?F|NkCU>(Eg z6~rA79WnF61S=8KI45q-c|FI3HkiS}tW3>lar6Cn8G{^mOe@M85Pv4Okx|P8$0O5N z9jZ6hcTKFMy@zZhhdv4yzMRYK;jDHzuL#7qAZpkMF2&J>*^Ch3d4}D~^{{(+(&16U zx8Iq)guO>mlJ8~l>_5C-W+`BT+nMzdU%c*T@!SHDh8~9rF2(i~rC@`-`fQv!T^REQ zp2#TCJ~>{F$k@ZV-Z1m?{$70ri19Xpql;-psp~qbzf(|X1#AT0m)i-mebB4k&?_^q z^WTY>ukGwTsflZpbqraDR$cP+->hi2kqKcOR#`Or)SIn`6^C^U=SQu)Q@( zi)mzTNlEq0M81sii1UP#p~9E(gkzg&MKNZjdTxO*&%9@X+nH(PV*N9hF*>fDHhN{0 z>Yf%Wden8v5ddo z27lkChv6LFo%njr1h+YR5BAZ+Mk(0nXS2cgWg6`fAv|3WAFUA|GaaGAm(hX!nClI> zsS3~A9faMoW`2gmqah*$XZ@Ocs?Alt{#~Z5sFmLRX;%_nyzg|$! zJ&hKdvnER2Fe)OR?rF${$dM6$S930%d6XDoPYunjqDOeTnU1 zWVyDI{_FWdS|l<8-FY`$__9s2QnP|9%9S;h^!*^ryirWB8ZeE_Mqlnuk3AJB``Y4L zM+sjB0d6(cV0^zCv^)LI$w;**dS@oM6#Fs0o(H~Xj6I@hHy*Zhlv@`sJh#Tk-kJN? z>zm_6&vRok`r2(E@_?v@-kAw*HKuW<1x0ONe2vPMae_TZFxNEJA!iw)Cmbm!XH4E} z6(L4zE}1KgYm_w@85coJ0#P3`CQNWCR&cC`>%7ymEZ(dmF)}ID&C<);FoTvrJ8`6Z*k<<06Ic zG+M4vR&8Xo-kPcp1d-K7a4BwotZy${-J>Ia$w=g~C{!j?_%fdGFXtLTKC%zeXlvXFzPV5nPJ35+|&V+@l-2>TBufYu)>zM6Yr#nX{WC z*c!FxM(xozf@oqRxD-F3qC9w+UyqM{t=(5bjuO5s9=wy$+KVRi>YE<1rijeU%>?T%dkog%^z55H0EF4sGQs^W z(^&DV&ENfHhgLE#4io$&Ok>?^WEI2p#39!K{4qCPq!%13duR3x)?j4p1+fssF{}e% zf=jVi;{5Y_tMxNDL;BI3>RO5HQNnlTJ;%H?YJa@5T0aM(3uZ={;8N@{in4c0J3Vef z0qp>0e$w+rh?T>KbFfH>fdB$htTS}T7Dt!5`Si6`;j>aV)7Cao^x7) z@T?yvwS;xWswFp46=Ps%Q|&6&8g#6Oy@=J4+^$D=iBYk}AVVlsBPF~Oy{rZL{_T-TU>yoNT_MsO)^C!BA9{-fp92HN4{SOrlj zPAptLMvfV{ez=#w?9zg_jWWqW+6$aH$pp6z)9}QZy1pxSMQt)xy?oy&T3o*2Rccme z?jT4NSm&9>X@Ym$ddJ6sT5agnuZ^O_y+UK;HvrZsrg3iHZ7fka)*W>SN z>(SR%`zT(l+BH`8=iCOY+E{fDA_&AWti@r1ORd*2hboAIZ`rCu;;qs8o{WqPO?4#=TzGXjv}TNr5%XAAP(4Ua6B@N(<6Gl ztN)t!m^vDBsr{#fi~MiAXN++F!99_pWdHnK{UwOOHiFxLX{hVCx95i3qR z$I5Vev$h41VERybBZ>`SdN!BYo>c^*9z97Rkk%G6w~jWget z)Gp#1a?!#rv0>swIg;VgOOZgAcsJh6O=V`LsIj)C@m;Ob+JaJX7J@yTX=EwLU(8s$ zC`dboe(sw=Ym_w@XXNH9X6y#>3~ydca4Bw0WV&?^(#1gU>Df=JMhf4V z_v}kt(|A8$Hb`#=!aO~j3HC9j(c}Dl&vT{6a(N=c?&jg*aWC&FW84O;c3A0j{GR6x zh&7mfWr9m_tRQOtZfN|mv642=6QwqKoFM8(CCfPH*k;ARnR*~{Y^tQS#|idKuu3qE zxuU7{jN2#5YUeOV|8@BUu_0`{j1MOGPFVd}G|2FHs%YmCQA}_YF^v;%L2LxE*+y_Y zGL7BKXHV*%9W14}u|nutpBNE5Vyt}UU^qC|@~kh>hU;a;@X*dC^yTu&cZ_A9Ja#=f#RoUyha9&U(c0nQ0PB60%!?Amo_Y0(HHwu_QO16-K(7Ykj*VcoV_H$hcZ<-Ut-7mr zMhxaz5GkJb7$;9Y;dr!0ZPQ*6`Wp}hYy_8LdsqSSVFl0Oodwl7_#)i-Ntp1R&B2<; zT8a7d-rds`j2X<#!%Xm)fky_|=jE*6iG&R^A2JhMitXW-U;fA_|9wgANyPxQS`L@^ zZ2d$zX5iRnMOBm}5S2g#RI(CWiWMB^{4{>Y_w>1bZLbQhwaafQUL9A#%Jo zUY;w#@o0^~dMlgiH9>r4Be)cM4A#S4Yoniy+xstqOR>M<%fyN`o-GZA$}>iuzaA}O ze)OL6!=Ax9uPE=XTI0$3!B90HzJ4&lrC9S(yV0GDoZl7D4*u5C(P6ktY+E#0_O;x< z#*T7{@-xlzK+V2Zjp<}e*jYdujoz6FZfB+yCF`_$#!P7Y^so(Tx}G2^9Z#0p&iY~1 z_IpsDJW!wiL49)Fj29j6c@>V^nQ6p%2}4iLQa~$=l}_Dq#faLy$I16WR%%voMR{G^ z&_{y!&_=L+FpZVu1#{^!pD&R;XPIIV!go3_*C?wtzHGmfOJ53N5&BvtxD@*s#_jO- z8SwTbc>AZd<3-n{<7IrXA9F2WR)6MQeayWgS{&w5oz7U%@uzXJk75;NJ;q4?$Vt8C zwH)$$I}==Q*1Bp08ws$n&}M^6u|2$>2anU|t+}D@$GWAdjwta?iSbfJ*~6`x__WD5 zJrTqe8^NVm^RWW^W*fb6>|QkmF*wc{Df%t+MlDA$+f$TdZ+~d4)Qf4Omqe+jZYPR8 zHz&%G3@aQfA7)=cctHHU)Jm|wGL13AqnCO@`}~>1JsRg!zmJsz(_In5cY-~8rPUKv5D^(? zVKc#{xTY}^H>#W-IC{Q3?S=_1#qESO6PrHvB!uLXXCnQuZM3M~*n6fP_gAcTh>y~f z(>v8^B3C*w!Fgo4PsA7cuRr#D0vqN@%1rQmSt~ILZ#Xf1MJc#@pS*wfb@peQgAnVztA#|aEY!5rpmsS``51fUE=(%sTqCk(IP#KnpLxEhtNAS!Jff1 zGPxEjVDw&JSX+Zt78@?ciM1`0rTVb0SheH|h{hmB+6XSit%+TY=s(J!|EP=k+RoQw z#Lt_?%f6Otl+_OB(Ld>-AL{H;uVZc0lFO0eX8UA0zG5}7D)kW%7eJi05nPJ<6-7A# z^|=`~Usa)S-ET*T+_#hEX=$uPY!6>K+c}KL;38TxtaQq|IZ2xdvh1C?ez6n$K0DP5qNc)^hEZ)9(j|* zTYsixc;c^reqq#W{YZWBprwUiuVfmlqx-itewdp_JGwDSZQ8~qRy>+4`&zD1)i)E!v2 zRH1pa=zulC<|(eMaIAdzF4{j#A6)KRH5#+X7J{P78XrwN&eEH~MzYNYmtuQ36>*6> zz4zQkaurhKsBjUTaq2YpwcI~qWO;0aM|+-2u5@C8OR=J29of+lo`#taT#Ee|?@IMT2RsZma2N!IMz6s%5Y5*LSD@Drpmu$QpEVQwO8 zc4K^_oLaJtVEtek-x)v*0P&fPU?pN&QCj}9OTSm>4>bkzoFijn#OyW6vaeRnI3Z#|@nj+huBzH2g3o*BmaXjRc|H|~0hgD_9XV}eVuJ*)~_GQcSP@~XNQIfQQI zND{-8=~6|xovkVwv%kLaTk8T^6!OVT7@8=0Etn+7aNK{e+To4WAGBClm6{P^Q zBx|;IgTn z+efp@)l^Kd8t`wz{0E3zAk6b1ncyd38kwf{4KKdI@v%Y=iI1w4!_(UBejsB8S!kE1ez%B#P68 zCd<()D-QPzic$;2mmntE2rk7vk)kv?a7gcR@unJy{`@$;C-!=Kq8tHm|H09PvzPZD z(p!LV+X(h>rZGp~{Ip&z??tr_=AGFF-nm!Z^EhR2Ja z3Qm$^IM!gRQg?g!T(8&mk=hIDlZdZ_y_Qaty)*w>tNJ{AS26w`c}q3(elWo{*tVin zc=TL<*yfRHu8m@X@5?miYY%Dq&9T$fomjV2dRUZ*J~dH}$XGwPXTVCppESMrxasOL z8^NWxU%?ud*iVe@gPy79(bwiqbcwtjrpdmR+kkZ*nTKOOG5$CBnR*>-qnO}Q-2RI4 zJoiO?@JFZBFX2~*+_7S$?)6=+U9J(V(t{^n$#YR1ZX?($nZ`GO37zyT-6yKE@lD^e zAX+r|X`<{ox!$b5d`Y8ZeN^tR)dbA&GQs@^_bX6p5CcF=vJre=rtxj*uT;;$XIa!% zP*G)LgeX{VvK*1I)^aa_FGYVGN}q5hNUkYjg0-FX80*Mj<47hpxD?w%3qlj0{BT4a zS~oy_S}jS8`gw*_QC2&vCeF;#+gRtipqhESBJgFR^oP@BoO5h5jd!)Iy^Xc;7gP_F zfeBU#rm<#Xd^uy;x;JVl))W=~HbKl`#vsR|HKGpI*`cR_=w~Ci6nhLZLFe)4 zjygNk{x*V3vG*Wz3;K^Y-6pED(0`OJ7cEZyK1ueq+|JxfVD~`Ten!yAAJrOrklXOx zByr;D45^8%c2-SH0g-;Wxb_`dor)<#`#iCwYk6ggVrNM#MiE+G&ah`~03 zOR-8IPf?HgdaH(MGMB~3Ph!NJ+>>SR%x%uTfZa8xX6W~uuT%%1uVsRjnrW=8IXOfB z6-2y^;8tT=QMM$vG5${j;@fXhWPGsab4}yh5;U^S*Q}!0am%T#EG(bM&y0 z1RH-~_LT`flha~P`5iVU!G^igi3z?h>oHav&KYh*wArNYEfb)=8JQ$r@18BkB^(p1 zs5mPHM3=Uk)Jr&Ng9$FhdW;#x91i39tSf2`tU@YX!zBjhNRd4!D;&2!zIeUuFmlbg zqAo+v$pp7E)0nS?x7UNW55o$GVXI?A^{rlSXFulF#LDI7J3S%Oe|MPKNPbxvB}DNl zvXA0=v({C$Sw;2XTbikb@tuJQ)+^RAjx8O>K?c%S>?FFpXXD;XRFdzwc9jLr$mC&oCcVb*5A} z)+p9Wv^j_=AckR0Dif@BOk=gksZWd*%MYvT5$8{rxWto#(`B4<%vTR>T(&#?_>wYC)_uXz+A#vsQXw+(im6%@v;#G`7J`BsACk!j>^ zyI;~++479)!3=N0-30Nx@HE-0u~M^wW7XtuC5?|k1lkC$QKr%3G|q4Q-F~lH8DHqx z2Dc{DcvmZVK(F=HCiMYUQ@#5pR{T76iqv-2d8@Yf2hkA3a~r{>xL-kDgNAAP!5;Ia z`h5E`MwI_zitKB-)vW4+o>@l^EqiAsxD-Dj<{)1WHgertulB(SE(g0NiRu?-%drnD zHOD;0qae=SU9a{>rYR;kwwcC`-0XFX9lcMe`O(*Qc$6si#-zx;mRpTA7^6NAjy@;U zV>W_IvB%)cMB55R&MJG=-Dq>R!L7;mklCnch<*?8(Gc;mxNMC0QTIj^dp_4R^eX0g zdai4wW!|VVm7~PcHdAHq%snUTJn~=VdyyWrrKDU<#RQ);%{11xqyMO%(SI<(_vKy! z-z=fjo1xTOF#9@gG5XrFsj{!-R$~RnchTq(Mva-1)iRg`V1iqdX}qyO6DL;Qt#(8f zs4tJY#NeSbrS7smS~YQgo#w`y`g_$vP=@*;F7dxoGo&)GN?4WQ_PLhEuGw4EEm%3g z1lwTSijvQ?(O|DS&Srz}%e11DTKPy%xSy`ZVcpWPw(+9y`l)gZ$8pE1joH@~kFZKF zT|HqVxD=}d-kq0J)F*t`SoY^3EwNX>@l-hi;8wHt=jTC;&xGJo?3KvkF)`ZcS)#WZ zaI>Z3_|YVBZ`^$ETPnRZt~r?`K1ec80XN?u7lCM1s<(O{BLF7YGpr+k4Qm@3zdqci zzK$)bT`lGk!ST~&)N%`QJ7IOgZtO)4*`q30m%#)_D%03w@?Cu+YuFyOYP^-;2xc1j z;h@yLJM2~8hEnevnjofbohJKQZUc^a?B*!8LVr_amii-BI{h9ND~^twDpizqkQH1} z3Kw6YKLO#f5v-_8BPZZkmtN(AfogTkpC1T`5e@oJmAx|)Y#Zlu?u*pR6$??DLVcKE z#bH`eZh?4MG(_qZ6RcfKW1Lu}uTlTXYIOzHUzy|R?AhnY5gA7+t2WO6sM^;Ey}Vjo z*V9UHDOL&W+s^*3@v879H3!-wPjsR<@+w94&fGTE_ISTt1*5=wd)5D4u5KZ?6t_Qm z=juWF_gm|#kytsfH#J%$ob*N%N0&7|#?%PX7l8<~5nPJv4Y|TL#u+!>DXWeiSHzKa zF-g?jyFf-1N73=$l0@pOg&7gm>Uykk_m^7gdoNmA2#zkMktGefyJq@iHD*VYdTCse zXwfKD_O)E2tjAbe3r$=HP22%Z+>+)J@!!pqD#~$Z)x=GR+6IW)YKXx+ja}l#*cmcv zIUbqD9Q~(LIROZTMCiqF%$52=0B8}ZIda4_+Zs}7aNxYaoU-q@EqTK$- zLtj49c=4>Kx)!}N6Wq>BV??&Hit%9L7Ig*I6vgjO6o+0+ml4G=!L6w%lU7wR@=e&H z-ay_cCO96MMvnMHzvv~h&QYWBEj;{syqMA_MfQW-{?-;;*yWY}OWb-b>n_JU z&OZn72Z-#cR)X)#G{$gH(T-5jYEaRfH)F*70n?<4vf5cyG`U|Ry>;Ho>UF#cuf85F z%8i^R`&uUWPKxs9*1CGd8bMMSm|$J8D#I`k9YL7t!vvRNdssDDG2WP5w4mA%v*8bJ zCy4_8ER6N+}BOAHZomjW@ZGj|FrqLWZzT((s)mD^L5JNz$vJqU0H6LpY zpwyiTZBkRA)Ki`(h?Y~Q%bt^4jXg$D&Qw0(2|abrVXi3(${j6M|K^QajumTsd|&B= zXAcN7*9#L|ifdX?(odc99IbT1kz^yd6xTXV^SGMFGwQQ~j=Wf9!8SO~`3W&**cxNh z-JV|+9|ov-FZL}^|Qyq`hhD>k-TjM+kM2o65)y6g(T#D@> z-%`vVBQP;p4Z(bE;r>bDY4=pwJ9DdX&w#n2rk@*2%O|N{V*Z>7_86uyPK1pnu+EF2NcvCb;KhMa4eIw>IdNK@7JM zd|#%q8?bw*adK-{bvDKfUB5~a&6dxXV+L+D?n@Nq7Z5?4yQ&?K&58*w#eR&H9Df8F zgYUT2tys@+v_Ya!5@$$dV3n{cL)FKD#`m|~YLt!OQrwzYL5Cja7iErWo?UadeY|Le z^*-hbY_1>fS1=ZZwl9XZUxv0H!c4=dz9~}MSq->taGJ-XcRa=Kye&rn-*t!k8XL9+uAvdK_2tNcCZY@5?lHVRuM0R!%GH zh^QCmsPiOAl)b!I_6AR0CW*J>)8uHf(BDY{D>&r8V>Q*<1VdZ2$Dv1;w-DTCFs&#n za>W}POP6spsvMxQ4Zd%u2VNT|_jZHLEB-y@DYoL5>}Y_JZpJ*>rnieC2QSEG@A z@8k1HV)WaKq>8dWGL5evFPa+D`=qE@FsncNvP=9OHOKpPkaWeW49)YlGnVF}Ct{UFo_0p>ob%QA$yS0(u|DE`ux&P@NxMbrMT}&M3`r0ttIUvNAND@(6S01` zT{a^Cgn3#T6I_a81z&3~gc}9_&ZEx2jN+qhNn+bC3uM%CU2z@aG^pjHjUxN2sbAR$ zj#Q@2l>?)Vw8PcZ@yHItHaO;)#!goBAG69Oso!80IlOU__-1^n9A$9*aKD0Yuh%;o zC-a4?{bpvJ(i+S=SzUE<5QSyJ0s=dHSnta!%c7W33-Xvqg* ziDE_gOsPJsL{=@CJ+QbD{Lwr$yN%#dY!AN!+WtPYeG|0(!_-)D;JxW`WXbx$3XX4m z>M*0xXC2ke=s5$Elf=s1^JVYM^}`yBJlh}=x^`3#Aa4{CT#DNUI}U$*+gQ3QMKw=k zd$Bq}%zkI4^hEYCn_q!=Z+D8i*G6zDt~b2ne3zo{dgYX-4<+r06R$5$m%SR-g7ufb zEW2H=S}Q^wkJ(oySgBdTv62Hs2N26_1mBlwoMd+Ais$5%A06gus>M5_MZN*krBbuj zvgYGWSTEwqQ}%7g+ZgpR!P?GxjNMMKaRoM7+iY+twuhDd_hOANBab=K8U&~bHx-qraim%mZaN4x{Fvio3zrRRP8w@L| zty<+0f9;ziM|~Wr9P{WuR$td!=1x|pqd$M^WW2b4bcXEDSw-28F;l(jx*h>yuZ>_| zVjB5g!-g9N4pvf|MQ%_NXD5jp4;RQ7SS!&RJj-ds)Jay?BhD*dOAy8X@hStyHrqo)fj9(Wzl~sBVH&I3CV!}VDi>F? zVQtjpKV!tx{4?bEiZzi{0yzgVi0n3kBb8~aNU8q7leOk9$3lEzVH+I5Okl zJXfSqf6`BmMObH92i)0LP6!8wtW^O*8Mp{j%3?E=Kh$bP9CEm ztK*YWo?E&83N|xMF~Ox+AF-YqDq5x1E{B=TiU}^o>WZ~d9l99KWtw^$y;_C$lEloc z3uLdxt;YI@H(?MB+?pC|Be)cMCAJU7?$v+2)<&I*wNY`y;>A0iX36+q59fNrC?jsK z{@c|yYN(CiSYaAoNA@Tn;e`^$K*9M3w?3SUK~3;~m2l*xLy{ zZ~?^ceFGgwFcZfF-- zIPK`9j=}sn6C8I;V^`yZIeLptwbbqCIscv-C)(7TC3{ZRUG^C4iJLe_|8-+6xi*Rk zZfB;k`>aD(qhYo{^((AG%Gn@E6sxvS#s|lW)!RRA-_@v{D^T5rwFXRZDXwXpo!P&e z(P_d9#||68rMT7=Wlik{#--hz)L*fNrSLSDIPk$d*$;A!vT7s8R-FdMk)55?O_)n% zf=jXHV@wTAoOS0@^(izla8`o2`TK0CqO6bHHpoD;@PK}Bc~f-?qV{`tyhy7tTgExZ zyfw~eg4hqjR0bxv6x+i(GOWJ2Ua*dO6*KNka4CLTMVYp(rSVaCJ@qX5s4fp(Vq~oa zvR7k;IqC#_NgfV^&Wr7d~GvFtVIl z%|>u3t~Y$MT=%CZ>Gc}Nb7*@r>|@#2W|r(fSm9X56eX=~Wlx`6*MrT|>zLpkhkFV1 z2DdADI&8ZXT<;qz(Y{HHI2dm3N@(h2T2ad4sZ#J%FKkc6_vI(Vs{4-y8Am(6ZId_j(s?aSox5Ry?+*ccAf>Y%`04w6%`-NlD!(YrnSvmf7nIOH{!LU7Zf3MVU(RedhqTc}4I3RHs;=hL3W ziG4?B%RY)@n`z`cJDjGM9-l|8g1K!bxD?w)3*KL-kNYuDea~itm5A-Z6RS2dW=^Xl zdxN|iTq1kl1+xF(`eC)h3R4hkQt-V5Jq{CGirWTj=zr^>pSpI}5rf(A>P6zjolUc) z@3L1~{Yt;zL$7`PuERX_jR`KrzX^LS!@3(^zO&V_3#(qfHrT`Y3Gpo)Pj%*2E=Lk(GuQ?{J3k@TOw9e*sCM>_<9)2TYw%W*C_QSCj6se^ zwujyz@CEW;HBe_@EzXI5aH>_)RN0@i`mieD^lT9OK`gZq?BPr+%HjMqJvFWz4K9Kn z=K;>a+Ol!B?4!8DBJj0C% zzAyV2G6G$0Y}5|Vs%FD1vU8_P9Ex5jy`BBo>botjG&ZJ(W>wu-C&L7n;+j^Jl}DQx zwJx7=EVU6_irWd_ec}rlZ5`Fryjb-z?e|1c_T)U-8*m%25+VC{LLsABlWOX4%q}s( zrC9ke69+A64K1kvEg9SdSp;*t}J)9*#8=1u^!ilqRE=W8SJI&1SYSZtwWYu{hdFaBMS;^`f)e7+{T1IGl+_I*3T zCHkycDE*3k%<5N@L0knf-9~UJt_95Swmqpg?f=vfhc9zh1^Vm=6S|2Y#}isK)vcijE-hz}1ru3-$<8Yh$fvt+J}T8?0A z46Xt(Efa!EaZMx7#N)U1XAQ?W%O3jrK#Zkoe@Khj*gNU;c94kyK%9QY2 z`l7;N4)e?xw!!!1--qn@uJ=9ah0QVsncx^?d-xg^^S-CVpw+U+VWMh4tT=q!+(+Hi z$uv$Tz51?Ewd7k;cbDQ6jE-j)NTudBU?sxpoh$DeEla(n?t)S?!KK(MK`e9_-;a72 z+zDT{OJd)|_Qq*423ZZ>J?)ZfKl=7=g{Q2uGuY_2dZA+_=FgenNM((|UNYGDeDK5I ztu`B6itS;p2sSpYTIiT*v%xCC_OR3YgK9?np1qD~h^W3%F41D=A{m1mkJgCF*PxnF z`p8~K>#wZ@mtuQpA1K3~=MNp`*-rVE#*3Gg<~fZ%PAB^-$0NRFybdrPUs~_Tk=9mw zjjvJHFD#TT$WO&jik$(Z2Qw6SOBLm3=lC~wPUg}N1%x@8AwHJ;94o4PkSb%4{n#2G4S)T>GiBEDU~@K{ z3HElT@m{+&i?Jo^cE>P$*}fZ}D1HxEC>4%>IoAk$H%>9W-+Rkp>J=0G>>Mk2R|7F- z-z~=j8^NX69@b^#t8Of+KGjhTGo#nXxJ2QOY0|IQGdKz`i=3yrQ3Y8bAK?rhCb*rM z#+U71s~f+SJ0IK)-z=Hn`&wf#_+oX#{pY#hA23(M1eaPe$s4t<4_hE=ONAFTcFZ$^ z=inOv6I|*}LoZ=w#lQ+7`0n1@>m6zE#CBLGqhDPleV5ySe-qY=E*zrILRzC79ip@q zx8g+9l6kT>V9(%KQIyt;hUjfUnE5i8;8GlEn9YEf9LT@j@pNVnZO80HaiZWN=_TC$ z{Dc_weUjBU&|}WO2rk9HPf><%U!{l4+T-{J-*?+zi5ESt&X;k{Pr|W+HC`Y(fY@Xs zxD-bkR5b5Meemtcj@;-u*#_4F+f$UB-<{FN1R64GM;%TO*?TOMQOoyb&&RhV5K{vT z#}|lmCb$&W8{Rp01sb3J9OW3Yu&p+^=4Xa@RKmDC}+{;X`jz= z`~ojYU4_}cJd5SM*kkw!(K{E)r*EjyUd~`muNo)16q_#*u$+E$CCmvH-A+r0kzb9(RDsgCJ3f=h9|;WQ8U?vY!Q9R=XKvE}1MC+7kg=lpBg zr!j9ZXpP=zR;rAT>F*?nN6QwZyDE4#Jdp`5W%a~?PqP|jR&;Spwb@`FV|(!S6Tj%Y zU3DG5;mcj;KN3V@qs6j4m|)w;hNz#{uN{nV%s_iE!L4a+kFP*1_#whE-$rmLwx=i` zJX)*gZ9Ux424C)aRZ0+-#x0WV!8L8I-De4`Rp;6wanSn(|2W8ISar=_6)X%^SlnN(_ao1j=DC2y^?8UpeY}&zg@Yy{91dgf4sP~cadxl zZUd$2^>`>TNNUu{Zo8wRT?!lBe;i|t#`YwA6wyHm(|76+u8GxTcm4q&!Ujp!2$4HCb$$op`v{2 zUavpioY&#Rcer{j&>QSYlkLH6z`lS4G|SfOBR1xByl*48HJOI*Ms3g^T1KjO?QTd)RBGe5duv1~zZ8*2*|OpVm*{P9!pSws{Q{8Vfk8Rc*y+xw04 zI)v+2&l+))wpuqSK~h!RF2|Cb$&;CS)+n z`jMw#=i>6o7 zWbJbOSli>s+(`ZHhd%{hKQhf%eHH9zF)&lhQ z57V10LPRmar93~zNg}k0Nt_u|M86jhj$`lRwMQG{#PY-5_TZ=DJ7Jg5n~yy87hZ2- zeivneYnST~d00@p9}QU>Y<{g}f=jVI?2zu!+@oLK)x?}PU}EC)Sn;IP5*f8@56Xbw zQ95sUa2wcIt;dP5H)+zZn700oWvHuczo$1b*Q7GRrL1)o{;GvXzp{hPqsk8Cxw6x+j0oZ>Rf|6^WZ)g?-m z%_wPJyK&Dx_^~9e!t#o%9&_sgYV_Pc00}djFo!(Y-Ija{3LvB+9-c6Mg9FuxU|9d z@?X21X4c3dZ~1Iw{#5)Vd~Mn&F!F14`lS$QgYV_Pc00{H-r@7>X0%}DPsLBd*QSk{ zpB+{o{4rG8;CuP6-A?nQn;k`cHZp%IeiFVmZFC%USIu3lzqG;k@?X21=DAK=lIvvr zj?ABmpM$Nj%Wd2nABz$e!XnnJQc4l`cX@l?O zzjiy#bC;{v^x4S#srX6w+O)CyPDw4IMQdq;@8!RCJAZH`J97-FmGL_=e=2?wzW#3; zd|$pci8UX;r*+HGR6Z43cPts_>^P?;p2Y3+Uz^09?De(EZ`GFs|HXgpcJ@3s#(8~n zP{!}b+y>v*{#2RU;QR8m`BdNJXsUhq@q6;A{MOyh$3aQX#YPSJJN*Ct-$Wk^;ipYv zNQ>6m&O0Tg4gQP&+U@MzBGDPKw|d4e&z#^=d~MoD+1*L|=4JtDgYV_Pb~~$$j&qLO zQ7yy9vTi-KnD$vE!GG~zqo!{~JLfEaFN4V32H%&j&8N!T2H%&jO#-T*wI6j?H+v|y zUNJ4w`Fd~1xGev8jdwV^R@8!RCJ7*(fn%DFH`>FUz_}U~AF@AgJf;Xc0UjA#h)6DDbjo|-& zDt;2aHVJe5=2Hf~m;c)BG_#F+mFT~pil2n9P2yLK-=Z=Uj_>8ac00`zT)c|<-%rI) z!q+BI8soQrLcB`N_wrx6o#q*b{{AELr{X8!Ytu%-?mZ0;<|oXk<$L+B-A?mFPk*nL z`BU+e@U>|p5aYK#x4bkU;Ni@ zjNhV#|2-;m8+>2BHlHeU8+>2BHVIP|%s4c?gss0G8zsDNjc$zPeAgynYL%%DCc%I4 zU%N3fixmF%TC(Bt+u-}!pUTu+-@7y4%YW_0$Sgwm-_J9DDt;2aHh)LvHu%1LZ4!7t z*L`0N*!stRjTYXo5pIm-eAgy%xo>ZMcE-01{)_+GjgeWH@P98M8!o>MzOVhMGPl9^ zak2&3`u3zy;r%+~##qjGZ4%~a%=c}H|Kh)PV`Mf;_`gPx4VT{r-`Da@333*>4e6*MFJ(2Hz<}+vZAM@XdaQVyl|Kk5Q z-&F>o`Tn={+07^M*|R;BNw~Ze|HV#NZM!lkE@j?>ZDc~Agpcq(ub=SI=D!!j*Jks7 zclfKN110b;W%2xd@O9g~_U4N6UY8YlF7?E}t;IKRlQ_^6=X1(Z-oG$0IL&(}Zx*Nw z8!o>M)3VhD+eZE?%=nl#LXJnNd@t{{TjonK`izoK>&;*C@2B!UI}>~-yno~xC2h>c zSt)!k?==(~c~Rz!43###`)mLGRQx1fg71`>4Zg2i?f|yhxH4>ze5!$WFR1*Nwm*d7 zN!)U`oA-m{FGQ!<9oS2jFdLa-7enivckLb<&TXHNp$+Hy2gKDqHphL*&g0i ztQj_3ej9GNgNF&WttkJt;g)OYz4vv?RkKzb=F^y-Xp;Pwd|PAX?{Hydp7*+}Ft0Ih z;3Zss!h2sP_)gf>h&nQDn7@bbb+BQAv|+C0^In$~-gSM!XgQN8j+W%VF!5fvOV*Wl z{Z)nym*0k4u7PBNZ6o^yJkYeU2Oi1y@?Lw_bxpXMByD)tGyMCh+;Zg^6MU!4Z18m;dsn`&e05<~j-Qby?wEGm$~K{Dk+uOz@o)r6N?vwDANg#P_;) zb)2+e&W3ug%L?zz=v-)_Nvwx9@?V%p9+52T$~!ZfVZ-IO;g+-dOt5X_HTahe%wFJ0 zy!Um>`ADmcnNrggm#M#8N>L`t-=Sc(FH=JH3f8~)2`_E-5>0WJb2AdP++!5aYh?K2 z-oW~G$ltHv9Nt*PacV}QQSE+9$A<}N&ioJRW%Mj=XNBkfYyaqDLk6+`-oFW7DgVr0 zA3Rm@xo?6)OT-&ns|TomCZ#!-9;+w3eUaO_`n>2L2v7khp(I2&IW^_#5>}>-s#r1|<7OQl}DiHBF z8Hfok#kGL7gQse#Dae*y5t-7>lM396ymiI(X8q->cjQ;gZi_MEk!#Y-)>~|$_o>*P z)yBNt`PE_|2H`wmCb$&a!k02@!tE^4-+%3|X|?U+ z;G!U^4f!|WD`jn`gHLuj(wjsYmywIr%)(Z|tUH(nj=LKR1h-PR(CiuQgD~i^j zx7vI~v~jI}c}Llesm{lPy|v3V>Yq_I{c3Ep&(tH&qm7!6T3QHh8>W$Mp-N44HZmL! zLG7A3&(|b)+kJUCy7PR5M@Zr6JzB;`(8G ziqh*v9qC zU+*-?sEC})cEVT6>OHq2wmT-i9BDMcsk-ZsE$ex(*O#~j`3Z62RP=VoW)QXDS4{AI znO2lSbvvt826VAeBg4>2^tPuLKn))+x zjE+U^npuZ8xAV3Kw*k|NGWcLM^)QG)v>+4QHcaE)`C<;WG4h2KL9Q?}yWi`|-n!!Y zVH&>sOAa*%#CJA=>y2qexpwr|;3bJYjAA(Tt@oNV=kT<;8DnREn_FA9(5YX8(?OWo zlkCKW)&Hgyr3}titA#Vx+TLjCFi#B4`Kqq$IXUk9D=y3!T>I^0_116UM&%N57J^%i zX%Hi_syUFcr!DgPn7Mtn->EBomw!3eAx;`sH##Z}9cZ+N?=r!D#Wdz|Km>uPW+S+M zm{ycV?{rXe9Sk)DPQu)BGSzvgq}NNh{jFY73q(#3AKM5n#U83C>yQKTFJyKsj5as( zumhIA{OWHGQp+z32~m+(5&ht)b3&ALNc?kl|JdMU9LB_hy0@J zjs-uM*4FqQXH*T|k>>oPQr(RACAYI|E&sLOW2PQC7W{KcTVrDAzX@L{tG}&_o}~W# zU6`>Bry`nXD89N-k$#6&j(f|x8^sYHX10@hNnQ`< zC*k(T8&~I5jwZ{y8wrRHCb$&Wo1(OA{I%-9Ik`U|KGwCJ>1;LK8z1~6*7#VA6LmiY zvGjqJ;8OneMP@`T{k^rCv~rjc8n!`g_Za=)g}Smo=k~X@`D+m4Kxj6COR-O5eS6h1 zYQ4Yv89%{G%*>PrcX+*oJ;v%KGmxvV35Y}+!KL^Kp(V&Z^8#6D%uG{eUaEp$dfS6* zl(JveZ=!^nfYA3c6da|SQ1BfM|!ZfDgs{%gM< z$9<&-_gdyKE@wjcN?D`e#ffC~MYfT~9(R;#o+>waOIZ9B%e8=v4(As-${KBq@rXet_}Q7pYO3k$)!kx* zQ8g$){i5GY=jAYO3|f4bd>XS$APf+lFhXX6pPgy!06izvY)$(bBao+Pc=378{u8`@ z#Xe^BlDlVx`b_I@4m_;xT|3mc{98-MFlD;)Z~?C}uu53td}`6d z>U0p(f3*@^%D*bmRE9r~-f>hyuA(W(I%H-wI{vJVRBHANenRXSJ#@$M&+Lzl^EQG# zhH3PJXEy}*zE<66fm{~(FQz%ua@WcD>V&mKh5gt5==$HS4Z-I?oJO7^JK-y3jZNdy z7&RixU}G<`2%2YkRT|}0IF2Ze8+=a$(G|p_-d2J=gK4ZbZX2tf+W)!H0y(zW2DdZQ ziZbk%6i2P=!A5T=gPCJu>^QG}a71yvDM~wJr7*Koe1gmrOmHb~C(In5NpbveE!enX zv%&Sl_7LZ-?yAKe_cOknR>To_b(*vKp*nIz#-8C{*J*l5>6cg4_DcpBI^K$yV6S8v zU%J#aYV)s#7&&l`V&@4noe>{-6^`40V;vxhT{oiE79wGxCGA53r?FpbsG z6%MI~1`Rg)Lg6OjB#)AaDDx{0M=jSIRvUuY3!)8FlnMT|Oe;!rcu9SDNn3b{ncF8R z#Oqh=G5mzswT0Y1YmpVGgN@)){QIy|ujhi`r%^?raBa0uA7StLklGpFaox_JNBOV) z5qze@g5aefvLL^Yo$!^iM)Qg`kJKuEeqsFarlq6nfvL{C30_ZRAG3O5db?Ql3&h|a zob6RK+=Ga6Y;pimC`|npbjzde#+zbc*S6iwNKMBVQ@{vU(IsUF!-N*yI zVuDL?P2+pX&zIF^gZmjb@kW37mwtZ3LI%*u)o>(n0FkoUM$)(M7eHW9B)N z@H@Gi36piYy*x7M(9I zdA)?&-`eK8j_!3tg7{~>mEcnRn=q2;H7@w&yllosalsEj?8t=hm9j?K<_1}{Y(YH@$AI$xN7q|`S8=rO|BJhO(EuSKA-I#X%N(S* zyA&u6#VtS-3BfH$DH5Pi+$nZ;7Hy$Ov9=J3TiQZtDX#x}cgZ*R?*IM0*Y#e_)z0V4 zIXlmDKeIE>JmYy(YNjZX&h{wwqLh4k>)qfhMe`NvZY+O+8`+3pe`FdJf!;k*e>>g7 zxC?7PdTW-b*2lJXwqvKY|NY^S+6+V>*2tLPR@@)-YV1(e*R!qh7pm5ocjE-;m8_Ks zwm$ZGoWTNd9>f6`!L3*^%oVS`p4T@D7`vfxW{rszt!!0eW#I8gM&s7Lp2Z-{d;6H+ zF<@Fz?nEW3M^p7M2A&F2s|Cyvy(ZhX%XaLvL_IoDT?-=jNhiUr_(>~@=$E9n9@o{# z?jpDqKXu%~cV@Y|`e@P`)Rov2BI%kKbYVr%Cw@) z+E-kCJGz!}2$gge9a$pk1>1hkzRik(vohZoSAPZZ+C{KRFpXLk6CZhkdz3Xkzz5Bm zYUfYbUdtZr^uZrNR08qbMQ|(b4}FX^)F!pM8?T_EKZMT}8)jCr-kn)}cr>w}2BIa1 zjxK_qDATBD{baMJ2dbWYgNi3+rJgq)+Y;HvoR+u>^-=zNm*2>Y+B-~eD}D-!QYuro z(5rV6<+rHGak}tI;g_+3*WLk55WXBKf2SzX>vG*f)7?vyUH=D>+{&qAy?TC7pS|j0 zWW?I5?wu)K{#DVM`>=1b#^5cr*9Y|oh~8D41ludqSP|}@q;478)$l(Zrv98`wisB; z_9*r)rg57`+7@c21XP1Y6)5xemL^T@sK!?5w8T5Dd#J{<2F6F+`N9ON533SZAY1lO z`+@ilH8Yvu&t)33zS<2vx$>kjwnE#@Dj|#4*%5%XgvVb|hSqB6Q9zi{fC(N0rm>ch z@3OjaOebR)RtIS(M518e$uFH^kcmGVO0xbC04wq)?XlI zcC?k6pAV}9s&f4hubu^=VpWX^Zp9jd_4cDV)fNQR%+EaRL=+nBZ3YZ51Wf zcfnH$ePo5#GQl3q{VB@ReL1xF32hA(Ykgbd;zY$V6|HwQj^Qb1*UWhS@L4wP!l-se zLeX#s!G6cIqKy4zpBgiuov{be;J*`dMUuyk2CP?XF~}YV5eed|i{MdX8oTZZr`7V8 zTN=Bt*2jJD=dy)j)wy@PXAZK}U!anXS!-$ELfb#sC-}K3%De9Ip2i@|n`oF|Utt>A zpTj~zCr#KQXPLELs;m?ZnwI~Re~}Pt@tP^%vb%JA)XE`=glPR@@&dS9c=PcV(MM0ZPjuBT6wT@Z21dNu9;EpNprexj^)$ho^#+Vde@qKtPD z+=|B^d%|l@t5q+xG^S&(==)uBMEIME*4&4!lAjw^Cfd$aeNn=wkCoKT%NK~+NfoWP zB33xoG1zXqnd(&#Z?KZe1V1096~!M~QWaWa-uW`I%~BEhzJm3(%__mqO;OB>b!O!{ zvud4Lu`VgX_7C<6rjh%I>SbmXGqZvj6YMKY<4&XsqCSbmZU+4P%G%lD$6dCcv(G#IeDUj{$?>Gr=#r@%}2nwgi`5T2$4bi;s zr77m^WvJqORIYWOCeSZ>uOPC+jh0GHb7UvV-uO=OkEBnZ_&wHSYdGt-C(Z z60>&Vh|{+Eu;MU{O6jPhHyFfx7r{!zG*;+eWzyD%w=jxhfAH|VIC1Gg1#6bUO3glx zH!l$1fJj{BB-rnm#@j@fwd!j<)c6{4@b2V!BHw5`4zg17_`^y-mF0~f)g#x%~Q zqSBjL@y)FEX4Z!5?r-}C|8jnYs0V-=UQ1B@tC5Rf%XfOzd(;Vg2EwfT#eHxq?hny9 z?@zU3P`AdsS0;7em7>wn6m>?8^G{i&2_i+c`>cIadr6Pab@N^sCd^7baWBlu1a&c2 zPr(0^>FIfv)Tv!JzkH2oz=YW<`E%KWvF-zHUj}WD!@j}OU9n+(cclzC6q@NW>Qf=snsvg;jkaSrj{(~lX0HXxY9VJdBOh{W_03a+ z-|X^MtmSB#QlGmU{FH%e6o?Kkf?KiXBNu093w6h|9L5T))^Z;_{@kCUq-nq3^E}(H@+9gGo_@Jh zR9$E5E^94oKAu&F{hpH9f0g@O1S<~H*j+*`%bL(Dv!10{TXb$NTd!DGn8rH8qjXy5 zp^c2fxFN4o)#)PZjtbVh8ha6Iu%avm(FsIz>}@l_tyuH1&aiv2nzeX&qbcIxr5E$W z^Vb!ucQt;Ztif0v1o669d1I7|;8r~TiZarh)sr5z?#w!OW+lXPeQf_=Uvc`!;#yff zRl1Fp6I}$i;^&4u{rgol&x5K)NPIp|xf7GcprW=%u@^b($s|3gr2V;r{nCl|A6?+$AZHF&I2W`kF&6{YRBL z73(8%?mB%LI^%y3+=?v*GXT`MGi%+Mb?&$ivodA*L_2aiqiCworFBlVZmgTtDVg9_ z{0&h-0Cf%Lp#q;-eUAzLCT!D+Qej+xw&gz$>T={)i(Z~0){HA}#agxuR&DHzf>;CM zNjWFMt=KAYa_7N%^=0QEV}Q9w|8lN~IAnV*d$7|7XC~Q1dKba1*kW+bYgY?(C{*+~ zR5b41LQx)b2J>_lk29;QqFk;!-?M1r23Z4jIsIFGEh;|_vDU~~?VJjiq|W!W1M#_w z;8v{1i07!0`ViGs&3mvuqRMUdHnx`V7&w(-DC)4bLUq+qZi42F{0$L5R@Tt|cv8ve zk-D)*zduR%Z3?lXGpmGCOZqQXw0R@z8pDul(EaP_V%nez)=Cj8HS4jW`~zY+h>ypd z1p7AA$W~txr}n&9)aZmbxOU8ZQDc-HIe83NwK0NAsAahaH7(70mQ1h@GL7B7S{1bliPen1YUfvP|2#5;y@iI!L4{~;2(M(t-(0esEku7Q$L?3{`jZ76**aVS&vZ<8AN*!e%Og) zf=7*MR571_P7S$O$q>kZ81QkHC=+ArE^Dw;cMmN%r`80q1sM=ba4Xh)MR^>%Qysi6 zz{muzJ@amk$THscbM|?s*TzlTsSW^f7k6zj!L9fkqWdtH6PF)*VnK{|5!{O7ilUsURa%?>d2Qn(vMgTbpDHr7D{sAX@))o_;!eHV zrL_Sddf?0t6Wod|2KNu1FQ;{HU)flOlNL;HE4DYhe>_M~1D_T!!jQ?KM9mXttJ@yM zPnVw|>LE8+qL%FUnK9Nyuop3norcessDU8TxCr(~rjZHQr?Ps{cqx6@yBpm*UOd=n zM`zYu)?>s$5J@0*xCkBtrjdCzy|t%ki&63h-dKV+e=QO!*ec38$O?{o0YDT2annVx z1~ZMC9H=3j1+|1tWiV?~pO|B72`d9D26nKvo(ugF^@>gPVS-yZ)yJ$&ZPutZX8=r? zmDr1Kwr2p`AMQU#E#wjC!>pjp1b;67CRE0|t!Wj?mNgFbE9n{WZHzeaqMQ{CI0B?p z6g1z}CX7|Jf0qOqh2AuB5FAUG#);F!YFg=96^$RDaK4kGfP$+jy}kH1@Z4U)s49>f?IL4gAcYJ zsrFT}8pkka`0V3+QRa4eYtF#-%JB+2?jZX84}x2V^VvE6EkshEeEf`{4!Cop8+=}f@ zQOX{gqfR}U-Z%o=U6^aWc)8y84~{;Lr>>lWwKs&dA9E3G`Aj3Dv3p*1ch+-q0`@s; z{t+);D|S5RG2qC6itk_KRgZ%h<07~fMUpYG*@9&P2#bm4wn&;1%;7`J;TKmdct@GuK6`08|!5YOhG!aC95VN3gOtAGajs2+U z_tYh6f(;E>NDEfY5P7~YZ><_|G+^z*Dkq4qLDX~+tRGBcouN!?HE`pC=*>xapYt->_(7PGbY%UQd~ z>=Uf6ic&CB6Ya}=MT}cGKdAMO5}OVMTQeD+y`M-p7!48C+Wdi;{=E<@a`F>p4TkN4s0`vYPLngit#~wXM&zQ|_V726U&H$^GaZLE4_U6M5OeVE`@{M4~>_odsj~dfhr+!;gd%n%z=w*bda|=%r5090z zw1j=$sU z9$*M$2rP&H`QF&|CnYDyf2^n;S4dgoKFw$fHoC)?W zr$+_ zvBls{@0^*`;a{wj-(k$T4<3K+5A_);mC;US^D_n`*Pv#$siMz#+oN~{`KjYHM>aoA zuT;hu=pxvQn1&{T_!Gq6E`t4$X?ShHck1Bil14}D*M4;&PW+nMjvuU|tgg5%ZGMva z&mZ}WBG@-zf=AOi<_7v0f<9`w`ruaFAL{Q`|5{ylFAYvkHrI}wpCd-6vsILR+o_`d zHNIB2fLP}uxE0$N>H%~etIk-TB(p&o{yaNRq`Memt)8>4aDULmUR^?QbXR|hxsQ2g z-`qfZw#0KEp5frmuzICD3-;%fi?Djm1h-{E zSj*9XZ47w;pNKSw&P=c^F^yT@&jq#5b`~|tAX|h9{#^DO^s%O{x?tIHISV-xx!Nue z;e%~IXHVtPRFoh89|U_a(@=(W8$79N43gQfUXnNMVsY#nJ36zrv(MwaGl(1@%-c4Z z;89~5XG})4)`oS+ZWP15LD-^jQD#?=70-Dzog>(GLR;;N{W*+Ym;o@sQ9tD#0&@n? z3PdjuzqtthT&9t&fcSCfLJ8v);z!)1N#gG%<*XSQYm_s7Ooze^hr*fa^SH(o(J_my za6D>E!=n%l;t>sUBN{Y+JW~ufA7Z_wvZu1HVBY|`8xP%G3*9|>cA=R4yqvW+!DGOq z2`zzL&D&Abh=E;oS~XR)t7zLU+ZcaCtRX|;4ng4>K;a@HriZJYVOvV zqTbzbSDrvlQPPyTB5b6sC9Eq>Ey)Ptdl3J*2yVs7hgvVUnyFR7k670JDtx~9xw38T zZ23-W_uOfw)&wyU{=o#d;%|sP($~{A%REyUuOL=_ z>m;}p+c8d=rpl;gsQ;Of0nuRBXVb(85n{cuurl!2Ae&0bsAUAv!A0;GFpZha$pUKd zpUY%z?9t!-ut3~K_KsO)k1fV&B{_!qseWUY${-iPPnVw|-p@}JP^+PjKo`NE%QW_c zw>9;g8J10&w^WW=yjc8sC)mpP0Jyd@^gd*TE0+i&ztqb4=l(k|MM;X3v29-iUgoDU~ zh{FV12GhvPD3n91vpJ731X)NM8^ww(*UDMSz-qu_1KkBt5kyxP!MegURyjB4(a?`E z%ti3$vMnfzdgh{9@pc9y0QdX*@0__;ZqsEazQJQ}^sD76FUzrAHMw#HzWEvHL z&_^ZoQQFl9e=bKN%=(^nRqwagtxTum-g#oqZ{@6a9M&k8wmJ*_Cp)4aW`u3#F~5Ks5e zTD^NDM`8~$WY`3;YHnF8p0g#gh2re%%g)+Q4;5o2W&lj^IJ3^<)*cY|K};&|B)Ap# zhaJV#X|>9=G8!|HGci5GG*Ktq_H*`B9!*$DnzUL@5S?5Es|3@yt+`f4t$FISMy!kA z&t>buo)@%zcdmbBacFy~Of$vzo6A`<0JaR)d}v9l5cODvMY0@nqo!n>FRE3yRg{&J z^%yG?Eko3uAZoh^)?lXbt?ndwZvNTT%Cju}WPvD!nWb5CnH7g=WOAf><7ry0qkMoF z02ADbzb#hiZzp-KqYqQzm|(Tz{uCu>Wnb;kn_Kd4)DZgh@HlZgD$trUuq`?D>gus- z+O{UR#Rc`2{tJo`ZK?!Y^F)pxtVEbug4hS5Au_g@VEteknNB0`s!cyAMj6D~?yKTN z6qLa{!Na4*u>_eMAX(XE`nQeT)~OMmf5sDrQXZs*gt#+kU@qtv%0zLyJ-P1UOD9MQFcJtJe^=2)UA<3QX2vC>6wD~?1s zwRO0?*7DLj`3!l;T|S#A3Wk-n;yLRsj}2DUKy(IC7}1#t9s{OP^%NDFZvFj2c0=Ys zsl;jG@7%V3u!Zwez@G4v7izXlggBn6ia4Wur z6K9wP^wvVo-;k{^XP6%xCPGIAT5|?g1MW{zJ_qs3&o|^&XbBUnD@>#6(D-uN(U%#F zCdgazyBH%DzX-D4=-Ibf=Wz;qs-ISC^9NZOd)rK~Z!?V(>*(VU`pD<%gFlz!ilXE{ zc1m5Ecuzh>ZdA|k>Egn>U~2}z@q_Ict2jqbsnbCe!<>N$wmzn@meJs{S}OB3c@?|J zOz`KjZ(>h)TvzREza&`>Rfoc#ju(9&1zO6$YQRrgQGBU-XxX9@WeFF-t$3WU`hh-h zDS*uFB3M_rKSh}~Skp=rNNw!EF7lmkqr|mpK~_BHXuwfIQC@?1nm@I%5WC1s@E9;{ zYx}p*_SMk#UH((WH{*h>_d!-19)DO#UPa3@{Jui~7r}PSG)~dgidD;G-YVx~_civ+EOCEXu(g)K+RmDf zRc8qCRnwZMoqwfPK6%*B}7k){3|9{+nL7d`8WNw!l%y2-pE_(v0b z^M!ncozX|p(IWCgSt~}dUa^iLs)6_&#A6r1&xdK8yDJ!^)vNSShGPGN``{Oc^wkuS;ww_<<9Y1#e5w5qpu$oLZBp4&M_ zi{im$teFhkt8-rR#lqp*x3#v)*0<2yW%Pp*#PKG1~8&=g2S@!L9h_Zq)sVAELcz zx?R>ojTHV?>|Oi~@pf1JbFFv6U$PY9;JvC5B5(P!RvcudW~)RsT@dp@tZ)%*OH89) zMx}kKUlv{VK|Vw6UDGi`wmph{f=3f;WR>@+7c%Rzri)%qMM3ks_L?W}LrNI9<076mfdagfK~Ip*!5)D^nK$pzTqWrAC=f}?gqiQd}1iznr; zhr`t0x{VV{rUqDZAJ!-y8%3!PVk3wU7r|=BG}Zvdbke%#zbvys8G2k8FIEU!OIRhG z%5Z2*H|^Ntqp}b7&zayp_}gM8gFbfVyDZHLO-%6TGL0%wY4T~Qp8hHKAU7&>=wxxb zXOK1bVc%vAR+JDB=|J3b5!{M(1#vJ}2CeAx%hH2AdhUaDh5N(3$QS3SD;j(&=OH?m z?1eS5H$hfB=TT#wN4SaK8OG0;>Kz9o^jS(GXSu3jX^I<*4Ev}(=)wQvwWjL~s zw!V)Q*|r5)?*{A>P8A(f=dOAY#1R+4t@ugfq&Ivpf8~9$1AK5-s_Ej~=^!g|vd?pW zu#&vrd7fu|qsL>_dDE+TVoyhVCc{e2{)l-=p6@*0f-tj?nBX}I)5r>&cr&zMod7F0 zii!32=8NWg%UY|>JgZTZ-XQLPFf+-S;8xrpW|q+1v(Vi;(A`|oqebeHWvsam`!?$_ z_M_5!w4CubrCDhz_o_(I{9T|GomoZMVlWp4acAL8`4-Wc2_9#ru~Xf3san703ONW_ z7Qwq`h{5Y^YiE1qvBBCah`JyKx(N0arZH!LihkTtUlzj3M9c5zh?^trSj(fvT8W$G z5Y-MMs)gQZAb~saHELwbZ<; zPs=s%s4p{46d8)zKFD6gG!za*br4Hk1p6b?$Pj}1EQR{yg8EeKF-3IF6lBe0*e6(( z6s2pOKI+5aF;@O=^**!2@!>(%n-{AOKWXd&g!WNif-oZv6Z}M(R+P0lyxPCfXJvon z8nlXy5c)XVuGnInc9koqSE~#nhl}7={1i}OrI$do0SN0u)%&$ zGZ1Fg2qw4{>ln_&O?VMH@>VhZ1EK*F96z`}jPkAk=gVxWuQR;=LIH~6iQ_9lL( zH22RtM}~`x{{~obko(}iQN_Gc1MPCvBQiJiiV0Rbr(SggajDu7ImJbAEA9_#;cK6$ z)&KIz>Bx=h-Dj#8x2dc(TVnlSoyR%)OXt*xY-{Cm?9ns9O2o9HyhR_i&_`ESAN;u- zR}`h=%F=4|f!bEA^&2)@tiMy%daq@B<;Z}X2@rEZ0mi z6Ku!aAMSi97orZ{U0II9?kf}gx$OVAdmwJS_EX^=vKVf>jhR0}%+yO+GXReIM+c1% zeT-6=otZhp--D=Kq=!s{IRg`H;Y=$^=Y!R>h!KaSS(_?Nr6}$pK<8h;%N3Td@Ws zXX3N9>Yw=*NQvC2fP&M-XD7>AZ!8?IoDoNWxDUdt8^r{-Vyje?>PN?^0fmNJN*z{g zrnrB$tTiuTt>ylZ-8MN|Em)(U3`QOR6WogX#u-KQ@wDJ@OWT=X%i#VHoddtrvfo%Q zS0n%GE9@10c<*n``dB|Wiel9n#PjRxWgi#8tyt}lA%r-1CE$qMk2v^OwivN2CeWJ6 z@EGv;;}kZm{WYxJto0Ikah5o;*!DrTeEv;1)wnfWtC_Eal*o-LTxx{qU);8Kw(!W+ z!^Pg1lAo-7;GKzD_uneWGEW;h2)2Bt@s0y+Z#jR4+=W^ed9RKV-R_pQW*PizS@ZG! zF`>UUF*;VZKsFT<{G^#iJ_D5c+M=DZIh1-#?uo)%%2sODV5d@#+E`O-`go7r50Bbh zAyQvv7%Iiver8%Tc6X~&q1kk zLaFydshQwbtl)~W|6n>#&+P@QOs7^+bHstx_AGJv?FT2Shm@_cJmccZXy30sy?#@o~d)O5dY%xq@Ua~GgD;T>|c1CtW`svZ4a9Z1= z*o$~Haq{Kc0PPlt%`Srdk!fT{cX+2(jo2)I!airdI#a~Kp98Jv%(}~ZjHq_ls`j#5>5^mVbLY6=*-&X)T!N?Gmu7BMzO2z=$&>&qp0g4;)u(KiAnmiH_3~d-vtoi< z@i)Y(Ga}BTZ>Gscww1D?Gd~|5 zP2^uaEucMnkRU5!SHIta7!iFqz_NC>e5bXS1JV6qf^6?1xD`JIoUVZ;&Po+;?OIm+ zVyftdJQ*{qn7=z~C9*}JCGpUbThNkWJ!gs~=K`(w57rf@maKeu(^GQRN!_fMF}oWw zmk$S8@8?YLC!rF;<=;HT%3RRROh6{s@0eDUoR@y{j0ItOEfefrOe1soNiNUj2kEWo z%tWrkvqj<40akQoe?*>s$DAJHRu;=^nc!C3AI`C~j?!L7m(a@<5BH4eH(dNP&(BiP zL4m_Xgz&RwdLsjd z8#64G1(CPZC(C#->6pLuM$ewgkpWK^#C{MVE`nQel)$|*FY0Pld(M#)v8&I0u&!`_ zhz8BmXr30|$Qy{~zlKZ}1s(-ha|VtE>|J=H2N49~M;F09!8Eizaf}xFB8%LJswy)( zjTB|_*nZB>ik~6YGFFe)PW})i54Z?c1E#U24BZnSD0T5eV1h-<%hYjCtqvgyqMrOlq2KT{Z!~H4BvzQRg zf6&)*8gip{7?I+qBV{b5X07GXRFrO$LbNRdzm~OJ1gkdFiqfQBQLS~>ner}bq%0^D zBPukoRg?+t+pNXsiN0F{Qdb7S>Hu)EA9_=HEWu>U|)NgfNZMq zm*PaR!GYG>HpdT+D~M_!ri0k&B3NsgR+KN*!CJxgZDa>T=O#ao66M#FvZ6Cb9JUzD z+d+&1vDQWKI5UmRnv?0ZGY99$pOBZ4Yu6-EeVpx4>|IWex(1>@h>b3STk(^|T=c*k z^}%}~7h?b8{k&L_I=3Bb`MEitRr?Zq)w31HTJM@5Yw2W-_cq{0&iY5lY<~O5GDmop^DAn7q>8n)R`7vr3=>|N1+sU*=dj2k&Yx zx=s;Uz7DYFC9Jz_V>th@?vDC7hyyNyM~!Jk$ueq)cH_9eyoG#*EPY0axfyN$V4vXM zgjoiNeIPEn2=*?fG3$$HpiPPCE5F39%sSsVF=lOPD-QBgaQ^boprXI!9wUoFMVa7M ztggsChr(rs!o7sTr5+V6&c>Co=83FbPKBHDJfk+eQmotnAKc@aBt|K=*RlsYeXt&g zGa!z;2yVswVW&Dei*|MUSa}DT1KbC<;%|#HqciHM2g`gW(;@%rQT7=k_Ems2vt%z~ zwZjO4H~=EEi{MtQ61eB*MlUV;zs52*@|GT#7$fp7C}qV#RyZC_?C^qk`?RrKi#W&x zj{(z|Wvow9dv+Nsvm*nd{{6|~zd+k|*^ZsITYX)U`W5QXw{;QRipK`|yZcec>#dOA zLlbA5pC*=X39#Y^|60~D+)I{eoR%2zlb#hdoqk$5LY$uAXL&7qu+wXQ_7BrazAvoT z!5$hNXJCSLg=r`QzST5*t3*_-V}id4)7T|jGgJ$@ znn6B-4+dl%C4z^Rw4xe&u+wW>g6In(HFBev;8y$;P*E;jW$k(A$ua?1NG&gii*uv> zt$7K15o;HA6hYhq5$htj75hBqCDA_hw`X6-L5MiLmrWI@DQCSw@~E+Pp{_xcPc8oZ z3pv9@a4WVkMM)oiL@jZGJI6}%F1jWw zVnq6;WvqES>xxrLLQemqrb%ii|3DtVrZJO6wtZ!+_`w8!66yi;d!&v`=r7GmY)r7< zF|8=~`#w@5SNE6gT?9W-rg8T`&?8U%@(1;0Sl|7+)l9K@a)9+F%(DSjJLEwASJaa` z^K0Kf*mq`v=L}3E8h}Wf>9xwnXMYF`#Z1#IC(@^T*N1jIbR!dypioXf#F><3? zchGVqXtD%i)Wh$`iv5wLtfOB1kau3>Xg5-$b49tI8tc3C{y2#AN<`}AFVfx_PFW``{@Su;&Gmq=3U45`Va(|eG7wfBS z81sN^EJ6)QOQQvGviy+Yf{DD1d%AFKx4AI4)^ygG1O1-TcoHuHm6 z(d9uIE7r1QuxjH*ow#^a1+m^ma4WWBR9tM`Nz0wOfXs;O1f%6x@!y{%EstVfar(#Q zR-Lp~X$nZqMQ|$~8=RHt+gS^XeW|+%ZpGt-ea=eNwP^?2%8}R^9lT_sDAuR66$e?V zS;3)KAku-T>mqmzn8rPEQ0fH_+sS88>WkMViR_tdrDhH0vB6IDvg4{)Ti3b?bF`cy zb`G?afz^O%WUDVfu5M1KE89a$m|$ID8YkBGG}5|^sv@>3j=(Qxf}b1HIDd{luA`3;u0Hs4dHiu^bo5en&ImtQ3%OD1gjg{*+O|Zt zCH_r{a&Od9^#TahMX((+jeXAMWjs-t@A%A{<-!Ke5UZ}1v0@a*4^}%=h=nFD|D=gb za4XhIMfvK1zvtub>pn9#iiuv+XNqDC%2;c!+#l9`YWLIL?D6S~kW(}|&1j)V`dRZ5 zwpXW?#5L@%weOQl&x741CRl5m|2WFh-PV7$!ap0MkE?rq`UO`X{JE^)xLX!|Z0ns% zui@&0TXBEzbNFC}sW0_z@Y-r`$B0oKY(Hn8=idY$gkG(KUX6lYh3$_P5A*t4b078z z)-mKE*Xy7@8~R?)fv9$%PMjEu_d&DT0_zozKXkW#2laap8C?XA8qdVUkF(BN$H z2khz_fnlQ7m6Dc!u;n{#HvvSgf!XAE7s0LgDd4`M_@-LLpC0PrE`nR}GlYMX^4BIN zY0`_`z8+U1L_V#w6+ig-uo7Vh3q)xUW@RHLxD|V_q8#&{RMX_DB(ET|CN6l2n1+?@ z_+ehbio-gF-vMG02(z*g6Rbo`ql)04%ha|%7O?J|e2_O*6fb1^Ir}!#@DC8nL72+G z1giwo$Vh=+HGy75La)AEH9>r6QOeSG{Is%E>Jq?XPNYR*aeudYK&Mt*3XKA?5WH8jIq4-M9miX z=cy^pwYim2>D{rm#00mBt~bsi%-k>3FF_xua-$b;^}#B^{h=!Gs4iNK9J_V1A`th% z*5~xvaUg!qwp;J+BDfXzhclzFcE2AV>bqd=?S366Mtp926nhuWGu8iPs*AXONY9_c9+ZeJ~vzPa%H_!Ua`_-7>_`&^Q zUeY(j)1&%PpLv4|6B|~{5F1DOTM>t8tU%tVt@Rm`T7HFHjB^t(EiyNdx;)4@*ajfAW{Mq5&%$>ljWo zg18hKBsaJS9%rUei}m++s_`hdJd2f7?t?9cX+`<=^a}Oh)GV?rvR*1qpDKz>^tWcn ztWm6dxY^;%3bhA_5-x(Zi)ozI59^`EJx$byLreCInI?+<;BQ4W)(@s(SL1r9GoB?{ z>ca#p5z|=9Na(HpT)eBSW%G` z2BH}Vvsw=m+=^`s=W))aRrju*W$lLlQ)9X~eb(RdD7Is#f4l=R6htKUCYaz>{1mYN zv8IxzcVV9|3r>17!T!PhDau9YZb|5FTj=hC@NvR3#Lt=mu;Ms%H}isKTFdR<>HE!0 z4kFmXnZ{ZM{G-jKUvw}06KgrTa436egu&<{E^<)MQ|(bPf@;spYO&!CR^d> zS4PH&T#rgw(SUy~`#~s;_>dPME zt=ZC-JsRVmX@3va0&`vQWy1;!_ra~Q?Ve~6<{5s}Puw4>HQcdGpM^boCfLHAUYi?4 zs-4U91Q)@r_%~s75FXX=%n`jOto?ClxcI%4?NRJq+#jOBHv`oQ-M8rGZBP%6Oc7~@ zl(u3NTcy(y>%z|uzxZ1>Z=7O+Te0Qiq~81d+V!N(`cmwY<6TauIAXPAmBqM6cr)^sik6x8nY=&H%5S+vk}+4qkia;v{iLma;UFzdL&~ z)&Rz2QXl6TrJI#Pj`xfcU)?KhMI81!er}5L;`bV!w)5Bc(!rycVE zaes);;fl8V=zZPPtBPr3#EfSpExqFJ&c1?52q20ayRVyj!c1^0e$vRZ+?Wchf_wEk zSkq^MTk*(ZHzRAXwxsGT{W^AE|4W)EUUu-aw4JSwy#TW%5IrcaPUw;aM%bf;`J{_IPj~+&6X_@N^?H?$ukn2!7H`V<&F!IyKXR z!}?CFr1r!f*~Ph~EU)En!gh?T7Z8;}>~Rs?ioF0gjUV_$J)O_c$HG5~51b?-FP60Y zgIlqUVV`sVFY18&hCanba4Y^z7{M_GwKZD|-?v!B+4fbWXx7BfQU)GP=Lj}AR6r|y zI7~P9&zay+V;VC{^igiR;hX2`gFp8~%}7hB%^Q}n&VW9CI~1nxb@joc#{DTuX^i>6 zFXHuj7{OomM2qxq{45{j@n;%#l{=eSH>8!m5N~(4w@nl6|0`u_3ELIh8}57ou@{87 zAH@W#1k>0P-WBSZS$n3n=fwo857UY=5k!_cGkxaiekS&on~r(_=7}>@$)nhgO3<5s zQ~NJitWU)na+o$rlH`Nv2LEDXM$VtbHhy=S%#^vAI#A6Vz!j| z&{WZ}M=8q(`T4NrBYt$vsm?hTpufbkVuF7Y(~8m}>oBz}`Y`YRV1hrFJq>SO{WqvT z;+OA+N8R~-vdFZ(q~(L$ihTvjFkpi^bN*s|rHkNJ{M@jQgLRUqA?tkWu+ETePPF(T z)V3?O*Ro@xE!#Eolc6Ob)(>Cjo9`mnSC~d##($}`3Y$CV_p#H!eXzYUjT*loCT#7X zzj6_5`Ap+P&S#ZPs@3Rly2N+0bd?L5S_=M>oa^|Fb16k7Dma1~zPW*^vNi-G>RbUA9o zExmhMdlO9X=Q53)iBe#+@$sx?$xWnt}et+7Sm7rSz5x@$27DZ#D8PGdJ`AHqsBDW z$Z!kaXZ5n`Bd}7`r}|WpySP2(OmN>g)d(y3tYomYw!{RF4b#X9gO%I~N@J~Zj=d8r z>h>*ZMK!h(rg3Y}pI%R|yoG(|;U7$_YZ@o!-!jhv)D`S2$nombz|&%6MQfFl32w#x zp-$22&FY=4S@l9#Rr`9xWU-~V{dD<>@;G5F{A`#SF`$Sq8)kh>ux0#lYl>wh<{pxw zj71-nw`bLhyZYcK%Kbr0V2PQpcJi%*C2}A9O}IbA4~$?(PgZ;1pukk|*=|3}Yk6$A zKSlW~ew=#spPzh5@TiSMa4YT`nwT-K>e+tIXPy`-V#JD9AN{NmB0e*tvDJ$yqGwL~m-Babjz@t- zgGJ#Z;|7*qH5IHRPU&ftL#>6y@J;+4I)2xdB_eARiQR+pNPv@0} zdsF^4i6gZmjL+5ls!62$7bmg)N);=M-E7Z&B;d3EcONPL-Xs#+h8b%vgjs#0d{%-; z`Fptc{C8EX>{hcqe=GhbP9lXiiI7YqjMU*IIRiPpDDX_X*CvRARPA&oUv)#!p&A1R-eAWBrIZ0#YKeWd(t z_93==j5mJdM-zD**f4{ntpQa*RMH|1}W2>L77 z$hX~NeXErJk{~>JDp_kl=I==P+ez@}I*F7|GKrs}3L0-#Hn;jn`K$!-^N5Pp3WC{3 z%HJl@b9ovgU3^!INck^L;;R!CtoL@aJ@>)i#7U&|Z4wV3Cdzk%`&)gad{%-;`Fpt6 zm!pF9?qjy+Z^fVMBvNRTNa=%HC5V*Ib@%Z$e2Yw#X@vEyQd%X5m^S6DS*H1{QvNpk zNFn%hokYqfnS}3rm`uXV()n2lV%FRcYmQ?6`;@;;qDI~PavP$W^S?L={iJJ9C&P;v?~S_lY1!OwW6(PJgzO~i zZ=1dZ!t5t6`d|X*Pyesge{W*E$!Bd*m8)=sF=yfj->!=J)m9Hznbd9zBThCf82jR?cs=41_QCuwDwkoC$7q z{;wEsN_Cjpr6Y`j1#`-yxIewenk}lcL$~^PI&kgwuAePO2?GyW)1h?X+j`LB4!;SMB zrCuISx9OD_Z}Q1vZpF_{QN9ClZJpHXqJ9Yz+=`z9Dgxb^XpBs(Aj`gN`&tN}l{g7jBR7 zHhpdGlA1n$@x^!}Z~cxk0QW92!DGWTe)*X3#G{OmHji4|{isV~m_{v&eapbBl+AmKOgQ7HP1i{`7?_wjCVFB__;BS75a9V zzkQSBYmBpG4JXBTTU55QSo2S_$K1?AW z-TqtDi7R8g$>*bZ1o;~(O6Ir2j26**^$V~oCirui#yQBjAsbE!=5*f4EYt{-iPqe1ckPQ`cn4$usmk)OkJZem1^}JYLdZF<@BPJ-==9wotr7jT~ZB|G_>dTp%{an|zL* zf34F>(vKQqB>m_w8^ErZ;8y$%k+)Q|uaR~{Y8iA7)xQVEc$3fF@l)XbkXbXkxiR(d zIp1-d9(a{I#@np4oqsj2fNdpat}9y%s^fzww)dPbWVDmuR&1fzKR+-5g^odmby=Z4wf!r?{;Ze0jI+sL!-bNE4L`^G8$CQknt0b&P;?msvQ zZdJQkjQ318^F*ELQCq(qY~261iL8bC)Z>T5c(2CVwUBuHonyWa#HOcBeJbH6!%i!hZ71J zt7F#p=_C?AQSJ}xa3EqLU+S^ToCJ?1)5z0b<1zLhmcGo$Jzx2AwD(eBJ8voPvn0lg9j5oRFGCxtaW84b>V$j7{ z`7^3CGr_IcreRk`Go#Y=W%}PE3ToBU#dwo*w%K<1Dc}xJ+02-EW|>|CKF9=rcczj3 z=^bkHo3mNI#~aI&S~1>ME$kb0*ml{bQLhg~y}6rZTg;G|;P1{f*21+fjm;Oma_Wsl zbyq#icSqXQVc5o;R&ox+!9=fIm*^z86?*}0&T7@kD4VH(j9;2YD^)hen|x-JZHfC+ zlo?w)7>$0fDUEn1!L9h);(RUoIGw71G;NprU_0jiP)&E^Amc%y({cv<{CzMpJXcr=xvYkX7V%<+f%1Z4Iny@~cFpOsKc|Ws5HnS;Z};MtjHSwzH5{PPaYE%*%Zt4vWl7D zRy*yevqUJS~w&VffI-|om>%g+sUia^Lxr{oQ&C=>i^ zna1s0u#$|If6?cmCZO0K?M*)a!4|{c5O3QzYa4+hQ_BS|f?M(LL;b6;g2vItU;B??|LuyU~R*@zfDbe)snR{W%qUoxP#@h@)lY*RD8I`X$@Z}MHgJkI=^a84M+ zToC`c2p)f?QDf`OmqvWcwX!(gosXo6@eV|FV{;vbe=U0#vJFA}*?g^Rg^F2Ba4YsS zoF2&3*wBlG$ObqCA@Do)t9JDZ_6hbh>y~J5 z^4UJNW2SLO)gQf$!gWu`T2O|u(5vJ-_4vE9uh>Mv|3Ppoe$t9kp?Z*USRT>8-0IQ3 z9~$jVJ_W%R;~ev|AYLKM`x|6=Gr_I+H(}1OG>y^fiz&WN$oL(tM|mf|FJbL-e03tq znpv8;W9(hH^L|Mhqe8POKJ(r_Cb$**ChoKd>1IS#OKp4{QqnVLQnWYo&>(9!l)Y%; zh-mMyedg`Arna9f)ZJMBm0~FO8#xH}N2Zb4f4YZp>cb=10=E0vu4r%ao%d|{PHTS+ zV#C`ga4YT)w}$p?Yb1pYl}T}Fw1qdKy~#Bi+4|V$v9{Est&wK*P&svmli*gY z7&sMwqkxgPr?0*hdetH@+MAq*%*w#ykJAG;3m6Oc_0?y)2p$8b5u;M~FkVI^$|0zR zxbsM~H~DT^wqvIyUQE@)_zQQ-UOMh1xD`KXM76P9jhh3Kw6}V3 zyFLT^Hfs#-83pnA_r>KGE`n8pY1CH#qO37s{3Crid@$+DXm9cfH}*%T53T@lVd5iw zf{Wl*+@GSKO7VS+wo55D;v_wA;ZLe?EGp=wF+=`z9)=Tar$}JhY`PL#Y+%IF4xA4;v)()sI zhpj$lW*#dMqVqlMqn7LD>*6A~6{`~R3|@6Hygfh2{I&9{Z^uM?*L)FVWmB+kvnt^P zD2R(7_SJ9_Y_CkC-s`xoMq^m}PshU4z00G$$@jRkcQK8O_*K=70vTG!Q#e<&Ze6rD zxxyb?rPC6NJ#SzXYu`iG9E{3%M6mj>DnUh`H89?`=^?MW2>x8AG3I&F7)|Om)XiwH zcwLk?Ia}SKC8SE&dId4GRzrQCi{LR}T2Zo(>1503B6+da*?X;?eQRR5N?2i?%A2vsO_3LGhh2ao`HUq46?p+C6qw*v{B5y1h(2O{7xb*~S|-@%xj)q39pBc- zejtZ2`dTATL42!Chk~tm&M`b+foSj8Bf+2I`LR*$j2q9g8B?%&&IJ1%)5x+K(9Zbz zmwmDs*215yjP@qqMaO!@7K1!85c@9elRqFDFu|k7G}f;!wKR-1r)6!d&@;iG%NB|o z5n84;4s?yz-_Gx$@N-_lVc8xCr(xrm=T7VT+6y7UG+Qvj7d6 zMtW;KC}HJd#I%XDW@KjWG3z5d3dE9LA-**(f?Kh=V!rF^U`!qJT8aZxYiCk6*er`CAvoV!%B=uh1yiYhOBFdY5;*foUX}r;cXqs)W2F< zQEVCf6mX^*#F}Gc_2n*tt&(ZHf1C@GSHzn`*^%qKD=xzO_G$?$=W5p62un-M40YBO z+;5=emlumKIrI^^wM^(I!!5$hr)3(a$`WMH^py7vnrj;sBuKz za`nNjxIg6IO{#1RnjS4HVrBb_YSG@eQFaA>R#DbttiypQ92YHpE`rB^Y1~n@Losr% zyRPTLEv`4(M|r0plfztxVdZ2!#w~mxqQ1SZ7jhA-s7zxHxA`~uEzT&Kce0K+9qCOz z!^?`pG|s+)xIf1}&&dR97t_d+4R2vof0fA?zbZ_<^dQQcFgw_qWw27S&tqj9#C{Mr zzi|@mcT6KET!tDgx~`RJv8$h@cC7ho6&TC~xL{27n)R@MO;**VX zO1&YvSu3o&f2240G$8+SejGfL759gEBJxrF z^ZstmK=JGXut%2E_<+|{0ePLi-*zh8w;)P}C&~HPOJ#yvu^yum!d;JXdC~8(2X;n_m5cT!-y6<- z@F(F+Tu!eMjr*Mgp$ts0t}u-iuPeEYyBqzjx`W5pMtPI#4zj1R24nRcME(u_@+X`> zXM$U?f-6d)%j4vt0f&6)prYkQM|hLZdGQ#qjbSJ5jArC2P}Z3AqLIgMcBI#DQ-~F7 zIa;=fkM!Qz5%MW=UOlZDe}gE4$jJnc8q>)4Iatj&gF8SgVn6Cup=fXNt)cv^_!*+s z%f^~UmB07MU>Cuj$~4~9KupIShh1C*doa_uJM)a65u0Y9Jh0ZIHM|w&E!((^b;f|7 zC~GiguOR%CfwBX3WtiYrtog{Go0h}4wX21Ej{`j9~U(Wr+^^^@BJ8T6JBd zx9}9Zwg_u2Yd)&bf;iKDzi!@T$^+~myO>7B#i5Oi zfBs5m9O}76&AKDXd%170HTPjJVhx72fH?Rl9rg~K1h-<%$L><`@YU0fU)r@%~56c(u!PZX@&p+Lm&OXmHzSYF{ zGVyhGX`tr7g^!Wmvyg;=|0T%`BkMIlzKWy@gI#ySIt(IB3b za}wN&tr9D#ov{b`aJ@W$ozaLxSfT%PGbwwp(+5prAc&t`1h-;~QIw(oUtwn+-_y~) z|6^ZcE1_zMEr~=DqIMA(Yip^c6jAyVMO9_r6V$%fu9OCqQfjHS^*J*rO6{SwmRgFU zR9m8iey?+;`MJ(%U$5WuSDu>pxzA^2?(3d2%RNxho>0-fP|;wF89ZM4wgPTvR#(i! ztywLvx1Mb_#F^^QU(?0iH*}U8Ry(J{^#d`!)oinai{MhMuE={{D_(wCBhXBSGL-6( zF7h%Va2q(4;cXC)YU|tyOmHcFLyWbc3YI#20cEK1dAg`ELu(1^ic?Fzh-s}-78vS0 z_WMkFceLoyFwhAA9Acz`RiDQCWjcE|s4b-;TM`g+6O5wg^M~lv5>e{D1 zS%aOr+Z4pkIY;F>?0{f`OR?r-g#4+W+B#vA%!b#NNFFWn?(}A#cY5tlATCedBulvn zF2!$X7}vA2<)9yaH3uMHM&X_rA}`k@`yEFHs1JzRr+ziZx(F`CaRuwO9h$3W&1$Ph zh@8b<&k*C{g6zo2ZNU17*+CHRHm|J);)7)Qth=no*mJilM>ZM~Dwn$mZUd%KS6yReqbc3Zi}+&6 z3`rLw0(6EZ)W}{#u68SQ$j1EljbNM$JMrhr-s?_Ch zRdHa=uze5H#DSm?dt}KG;A530iVP3=XJk2kQGoh2zLm<#_lkqySi&^cgrRPap>meO z-JhQ>RwQao{b&{wd2NU-&)m(PF{F0DEM~io?+d zYb;9|tA$1WlqXySm*Qv#KS$=Mk9x&OYbT)ZVXi{MfmiI8vUenmA5cQ0>-UQK(LA@c4f=Ne^u z_^z#ecwIYBYPa{(M7~^| zH;Q$a)fF?s^CHaUZ}+n^6*94Ec&fjH>Z$~^U0 zxmcOtH(?r?FaGpb%QIW5IP57}b~Q~zRt&MnqO6>(`It}q!(SCy-cprqIUt(42-Xj#4a0xUeHriDU2ev>B(PnE z$h*CcqXGA0teAkP1Hu~nFu}c#X~S4hDM-zS4<;q!R>W=T!f%`QbM{BB1)Qjw7^EIA zDy+W7Nj>j@8Dh!RKsyfduVn?tO2hi{%4f$q*#kR-D$U9eIk)}oIZO6brzZXaBKxa# z@(gn0GQp)-!41RfU}5Ep`-JDg&npbi5P5fcvr4c%)K%6fIRGm9cekYQl|QG6yiB+3 z6RfV7b;io;$f|GeZDhQ)c37#k7RiClCV1!=WFZ#GmUFZH5YfT&jNTDo|nM35ahxkg!okp~h)ClEOlEXx*d8Hn>-^J=|jwxk9EN|HWL5 z)z>23)5Xqq`t}IcUDjjlHUu&E*e~XnE`nQ)X`I!Emiz!MnP(=oy75h#X!g6-683qg zmRP=F`H1Bo0qxVp7d3D;+b$<+lRtkqm1Is}fGW=0stz02uQ)nH@z583jz z%LbQXdxjC7dq76~5oE`~{h8?^??yImHC7^w$etXKckTzt`G}lMa4GIFxN~yAGI_I1 zG5HzVoC)qRY!8_{y=o}4fv*~Vh*c5=vAt|J@#R3=O}@@ z$w5>EkyG1Au;MU{EH_`*R)?CGRexDoBNnBLkN4KIV=YGm?qi0r0z}ysWz}XE!F`Eo zWFy&BRV_VMN%>-b3ESZ3vftpYt;KugaooHZja?RLBhp3QoviGs+?v=~1HyNCYx$9j zU=L;*C#0LaE6cB1ZF*t8fH6BttA-%D;M^S( z{9LAy!}NrYx`Oy|6!GKk!ZhKLI^wWKIpaqOD9ZAZ7sA30DDBnp31s{TS=h1>!G_#pu003q>2A`7ac`vZcXeX+gMdyK))J` ze)W3&bn$xqAiM8!ALBQ~4XaSNNGMzy6z=rmbP*8|Xh$`E6IMRMxVrkPeA;5X+=tBE zNipeSdYHdG*T=fz)RIFW5S{ehl7{` zBF;r{DSksl9QmSJT)2&Tf;~lml|x4!1L_1a1ZbQ4Pd8WGP^ROL0HON!B)% z)!X@ssv?L6(Glt5vzU5z#9?LNw!uD25FVqbTI?dY4VcC~akm!B?YMvNWvtO(#_pZG zn@PFHID5(CxJ7c+s2bAWMR4tMtz$m}YMTginY{RS5n2d zTl769tn;iAhH(MJ^8X;X6l;uOtPBY=uQi?Q$;HYj+u#_*_ONHWK@0OjwW)TdbSC`0 zQ$^lgLQG@S2fbPfy_$q|&b}*BglD&oINZ*xG01p2tg@OvxSpzsyG*OUl_rLy2isp0 ztOl$x$hHWgDTs?Mf^~&y~$$k z2=97!bmscu$Y2;VK-2}1f3q;@h=gf)N z&%gwi;(Eglp-%T?&qx1Le?03L_Gjs25qMC06#I(PqpS=bRwfTCiw6^2>gl*7vAt60 zKR!5oehKy6;4Z2Pa&iPuP7z}k)wkn0*C?wtvZ|yPQFR7%P<1hT&IGp&(>O&38!KTW zV5`#xKbNC~VQl`OoSHDFmb!|)Q3b1}iIc&>_K1wtnWF?^Er@`*wNy_R!Jf)AzCWM} zmO8u%W%w*6O+-fo*`o~B6{fLo3A#HRx*G-E?SnBxt#)%7 z=WS-EioCl4S$Da|U>^X89U!dRXqn)+%QQ~j&u?b7U6yIzy1)cSXQr`UoBA?tg37XQ zc3`63rWBEPw=C0!(Hj@t%5mwOLp=*!-hbD-_H(DrR>)5NIM0DA<$J%be-H*|;0m*u+! z$$Hou)u?frkg0z5i9=RS)?=Jw0ny^MAlckSum&@Y9r3p!WeePFZSAwHg^^|69qX(( zOdCe0MsLW&`5v3sF=k+bOYz$p#wW1R=%<^u!ZE>W$M!J$f&4*M9-$-GJBA$^og@yG z4zsch`O>d`P&OnNuO9w&1AU?swico3&S#JLF852mp@;hCWh z#axvS5Nk(68MJOmHdgV}{Y;XhDf>9A+w3u!;^&6?u2$ za$Rv9V*UL0!ZNk__8E<~zdMhr)_K^J| z_l~>_W!R3qwX^dli)-t(GO*8cYhpGE@xur4V=mTfZwyKiy$05|M*!Sv99J;DYFJFI z3Vu-~VmDQrW2xfcNv+iEcTT152VxY6WiEnCaa_T?Xw9cmz2>EU#QM4LP7_|2w3e_9 zwrv=ej#zqPX$cdoD@-GIyU#ZHXi%)2gWXh-A!(w|Ie&XZ#=gz51oMd?5%$13|da07gpj;^_SqyL1z>epvyWBR0@oP5bc0u?fIy1p-z%;(k?>?04I^UE1 zv2);VxioRNTs_-AxQBBs;B+QRTa=sNQe20K&M2MS<(>?2*nV6Vtr{?C8w(!y1fn35d0WmP_llO(wV$D>(8%HhDuv8IR4A(8MRRQpM#8e!@D# z$)4)e#04uFn0Kmp>^pewK(F#{muDYj-^8BOBL(FTEA;KzOmHc-hxx>Jg3Ru?EB+YH z6*1ARMG8)qTN!j)N3cEQzuI?Hs`JBD%%zTDvsWexzi6$ytiev*og92f&f4>?${AME zL2#+V{S!s}qP&sieq^$GJamv6iTpk-W0ORc2U;0e4cMMxi~>;sIk1jEOPF9?VH&3a zbBd_)$@Nqg_AM=Vm?G|ZhuGsp_HEXAd=-6;ydo27s8FnJGr_*iH1=%6#{HyvD%)j) zpUaU5XT#53lb?KZP#(qz;6!e!IF8vtD>E9$5AMgfYYRjX5IHV_dmq!NtK#S7wRWfE zCafZ}4Sp{BCPqu|+>{Z>lM;liLqqN)iT{n$%D`&CHH}pOWE`4@%tJmdf=h8b;l$z4 zn{p{K54An)w86T<_ONr=JHOgIB3${LLSmSkGUTS+vR&o*CkD119_2OU1E6pa#46MHXyf{^uAJw%ZCu=(^ zIFuTMFNjPR!8OV>vJUl~EQd_$DXlZrY=hf|X`FC-kWWs`Szva?XesG>iZIsu+9yC+ zojFQiuJ2(!`Te5><|{6ORhwz-N&O+n{PVYio`Sgfgl(|4GYvmKa99ppGE_~(PN$BG z62;A4q4u{Ld#Y1+pMHB-MuGUNv6J9Z93^n}70R##$}kMd5IrDC+&Q4Ngms1O8OAB- z?iT27Gw5!UjVa=VZNc`}Hv1jxF?K+V-zR(4TrVY}v)|}carBUm=iJV$j~F3?hzGIF zMQ|zZW61bE?=srEm%4)N_^Xd339k+f?6D~OinF(eBR@(n5EGFpoe3_*wSb*xmmbPR zD;lYVSm(@mmMo?!9iv#USjVsm0Al9yMrsRom@>ij!!)u}Hn<^QsT82Xu>QdW*EG|Z zRU7rQ{1ysV8ath?VIKe16RmLUsZND6+nkaaCC|&v@Y>@Msp3Sg_H*`mrtw8z^fj5- zySV(TTT=McM=4_BBRyJTpJ45>?jL+j?&?)s=ErS^$0#+hc3N2V zzywh=SC3@4zdFYypCU{80Ax$={!>Q>!KDI&6U6XBd3XNQSUXdOPK{TIE`m#S`YTS< z8JI^j?z}FYUP8I#kXJTILJ!Pz0xoWEx#>K zH0q$rA#yUoeTixKM+s9V*WWJ3Vn4%G-&AqcH_#p-vrlkqV*hS&Qw|8-E}Oat_D7}> z2l0H%j@t%5mwONLS#D}8i_EDctsE&8iy;oysB6bTZhvQ+hxD5)dqJt^K&hGFQmo)O z&5?aT_V*d2&f=zxg%c9RcmARFR}pIzw+(gCrnQ7s!l?{KrC|+T#9uC-<%Il$xda9s4%S2vklf2wug1K zcAv`I*&oVuMCWafQ^cs(0_=Fst;RZ!?{g6Ep8QY_aS>dKdnNWQ%{wD~kiBII_8P3p zN)l<0wMVh9I6W$I{u!A$v9lU?)k$zEZcW^`4c+Yk-F*eR`-V&was5K)9 ziHBs>7FXr>*oEY^K1BqKt!IB5uunKubPEW-mRIEh7r~{trjdaL9&357<+Vo-r3k;# z+RxeN*`8tSFZtM9S^hI~9%h}lypbZ-j`OoeGOX0>kJy0?VtcvI%#U3Jk5QP0pEvh2 zZ=_zb_l2{KE?bku7hcw_6s;q8RD;uJE&a^pAgo(Mncz}v4?9euy9&B{37Mwy*Gv$( zm-N_&eVg?dv3A}i*|Tt%I*#bvB{xa5>{H+Vf@Brt9)r0I5K}6I`QA<1`0y zmjob(NiOo2n2AZ^y=A&zaUXN`tKFlI$etk1y9h4DwE%_d_`M9jT}8c$Rm(yN$s*&X z)^`52tVD(}1;m|ORn#;W!KGNoa0()8gS=X0ue^<2NR?Wp;0sb~3G0eeOCEx#45HkJ zPJ&CZ@?pIeJ^dH-_+IGkqh3o9+a7EGU|(_i$1V`BfUvSBF~Ozy4Y9^@bFFOubeJlR zT}ZdeC5Wk;^az0aE2{+B97Lc+eCi~)6l)C5f4p@B4%4`;pz{pb zD=1cV#!WP1@5PCt&GgOB+|I0zxFx333^@$MJIDdS1eaoU#Tl#*r^=Y*_f-s5+?n8B z$@Xy1um4W@bZt)+f_zJdUriKe7i$$|eRQg5H4tUjVfW`*C&8sy!Er)i-X=NzbVqx| zz3BZ!@$OGruh<6L#_1YldOM5!Z9hVQx*vy&bFHPJM;lR7`LwwufE!w>+}N zr}t!E?2StNJXsv=5@e5-SU*_ju|KioN|}4|s5G%g&jf21)959zv1H{vImKmzpUZIt zr-Z(0E|)B;Enh&a&AO5-qB_>KV=ebrjtuDSAZmS5TUvXBnc!0FkND-|FPnw3_nTH8 zNG7-+vpw{y&7pE>y&xHl6<#Lzx$OTqD^qQtTs%2hmATe2Y?>J>GMDHP07w17Dpqt` zmG@n1R2?WcfGCGC0~6fCnKq19k(X-R*NxOI?6PXn% zSRa`-jEwHPrKfo*W$nLe?wc(3yc=wf0JzmSCL$jIh~GdIauHmLH5eIzyywWnFRqj( zc2iY8kSulIQlpvPHhmADzB8wT?CinUWwb%pt-l8y%EsepN}Mqy-`}JS!>xI zb~HA5N2+mSWFYndFu|qxZ7~9XjdV-jT{gI9uszJfUCffc{%@=0*njoxX}qX|wIb_| z5!MfmqR3hYqA`fUE`m$3+F?JO|87~PYb{k3ad7e2BvB$c#QsXkNohE|Ui&9>{_&OLnV*ch?=bY5?7b1Fnm z#$CLAxQCYs?)gk(ZF}}qnFMV=`(;wA{#WC~&SDMic?SNqtofL~8Z%M0PZ_GZVmB2N zT+>Wro_hW!IU7nn0Xv;Utwb@XMFabbg%#DQ)Qgd~tsL^VRYm43US&8+3%Rf z8D0>tgSY`7WP&}IX~U?!bdp?EXq|ioE7i5yC5t|L>e+Kk-20rp{i4@O+2zzx84IOm zf=jW28%B|h70vTs7cwj0d+@97u(3;zGB}>IK4J&m-LhuFjl$+}i~yKuk(PwrLe_m} zts|Jm*(K6lCiuDB$FLri(_a>^nWz?E%ur}YtXQ3)#|*5A++#3n@UXwE3F2jp8JOUn z!8BHWHujO*`^BhB=vPc|k6{`&vQOM3yRPz6q1c`9Qo$sVzEgV?dl9!LzMVnL08!FK zus<@5IhnMzvUcxW`53E~Umr^n@mF+oX5D2y#_V9ed2-ajvvM|O=$YX5ceeRq*!Ueb z_PA_tDYl2KLyg~&d!UJppouScNft$~X%%ICYtIN!diKQc{4U5ytbs)yQN+pGqx+BjX)G*f`o6o3ohUQmjOV@#YH~ zWch;S)m%i*3(bjYY zcwPHzg8h!$2K&fB^sIBj9Ooj~gPFz*%Nu1(57#Zt|_6txix(F`CZ;08!C6i=bM4V3$ar&G~ z5|JVG>=7CJHtULEq-^RV6;$*TGEH4vA1gL?)zO*jhg%aPGUP|G@}yWfQpW5`6h|6| z*dt5s`Oe;MWtpq`93E?VuI05%a4EKj z+X|9>%vZaQR_*=L!hZWOS`50bRWv;!T3mmSH`0p|wI1sKj`M2sc9}n{$xt)it?3|G zYn}A+;?>QI#nM%~8s4qg2KFb>bE8Do8Lb$|vpxE_S+{?Nn(}8yhYj{^wukez+e^t> zP==aNpZ#euV!=lJEY=mK5kHD7lA}s?Rj*;+(g)wf3qMnj6WLQaG8o3S!i(fZ5DNFJ zF~OxcN??U|;7mE~VQW=-WF-f|y2AF5%cAQNS*2?MW!?%ecz0E@^tG-ZCCRkCOD%!9E za`hntUjY}vrPv-$C~WH`k4>K>H()nawGm08&4NICUXtXW(0{#7BvuP_`bIuE4s3e$#>^uZAMdwM(d z6!$L0uZ$C?%Y@qVC0q;6U;g}05Uq@edtC&VVtZJ-+kkBBV@jwi*g3#9 zxD>xF<{5k|%coP@$Y{QABVXFpV3CkhNtmvbU7N4v0Ve6U6|p zV0%o>{n*)et(;L-?kFp76cb#E+Xm{B8zFB(6SJ_2{PDU(v9n@5JAUx5WgWvjL-Kd# zlVXXgm`ZAOXlk_RvPgR^d$7}MKl=M6(^Dr&jl`-Y6V}M``Dijq9REx|314>wtC;6N zv|jEcSc#nUdw8qA@m3d*wT^A@n>gu!vqfaD74NG%@Y=xlW5mOj+H2V#onHI>xgydZ z#4PMvVuDL?Enroq?>Kp&P^jvRT}Vgc;>Dfs^tgn*h_wqj&-#s%PYZ^s{J4vb2`q{RPRb#@dB*6Cmz`h;|WNiu)Mm+mT(v%Ccc)*kBu6 ziu)VpOX^marJoE^b+B)#>XR5zEnE8s`vliCZg%jmE<1t9z%C0W*jJdwE{oAahD^nu}X%wdb!>md;b;N;5T7)#Yu~0;c{{J-s&1+)Q*f;(Y}X{YTRn9kA`vRlW^G? zL}%5!yevA9GD31I_Ic^3jzp_By9;+eA?vt7O*9 z1iw4$qhUmYI1HjR<}#SzQmn2}(Wk4;LZ3gf_Zl$4^~Uy)dnc-*`SfCxI`QVZR;d%B z#gW&wURgT$Tsfn}OM~KGeN+Z^ zC;V|MMwEF^dldVM(?4nys3>QG*ybX*6t@lLebRHxdxQI`EiQsfaXTSK?dU1nH9(GP ztc+G0j6LR+8`$6HtkkUF*a`SmPx)*8#%i~V;5J|y85eK7E~`PQ|AbPPDwZHB&e2NE zipp(+9Vy7E))<-67C{*{4aXdErd9@41E#Sag`8^Lm+ZB*gbCIarjds}zM=eWb4Rrr zG3u3Jv0~i?9i#Zyvf3F&I}XO*aknB+aG89 zkO9id1Z8D`nl&atT*f-5bt5qMCH_rV;YEHFD^H4*BZUd>$4tY|i(T<7?c!@%H_Lr; zHbJz-$rtP1PmUj~c2H4h;)69>6Pe&rtd;oXTYmJ6zh1|*?xJI&TDt_%twn%6_saHg z-g$?|3~v68dg;QsR%S-DsP(s2AMUSCEjjs4Su?BsP&ET5@0qZ4_qo8n;_-%@Pv7}0R7_H*`m z{!JJywd^T7K(G2huWpo&7kgLgu@CzM>lotT`%lebZF)=Vw$1nPJy`3Cj)SaM-2R3U z4B`<8D-JTjt;RIwMTdIH`?FtF0a&ANb|yv~$N5^X&7C5+A3OVQv*BJc6GXC$;8I)* z$S{8FhUq`AlS+3HT#D-uz5QmmtXQj#5?Jl45FRIPPSNp$>xY#HI|o2SfT-;vxDn~yc`o;1efABG>i#Pi-S~vVte>vS@W5Bdv<5_40$G);8JWGcQ1EqEDu%8ksn~!%Zf{J;>6!N*0Pqc#^C#- zdt=!P#3wF-dpOgG=fyuVXAaIMt=+hvp_kmj9aUERV4Y`O!CQgw0rA8|a4GI%$OL`q zi09?f!KQV;8r$Ib!S;|<1sMvgOa)e!0w&hP#EW{Hbi`pAyO84Z%W4;!tG!qguJTQc z7#pSigMG#6AKRky%bg%1Tm+Zm*2JysC%-paA8GL~f=hAB8b)SVfGm_zPQ8cqsNcNf z#Ef5cG+>2e<-_cGs{nZ{y_}lvBDkHIHjD?j-(bUqT=^+xQrQOg7^X2!oKQl3dT6Pv zi(M~OQsc$27D4v7gf)t_68kJciejg^d6!$UY5JEl zoX+ZN=oJ&(!<}@GfBZwhqb4dA7p=I8e_N>_>LNTL}p-LM*3%QqHxb(dsdBm zA8QxR4}$m{#0M^dOL5OPjGZ}m%@OyO%Pm-mV;kHv*q&j0ab&moUXuV-4C{l(*T#tV ze$>5$e+U0QtQ(}odr3;#9n%|x+Xk0nd)Pa8r<`mAKmP%KUiMC` znAbkUo~Pzt%l?nNID`H)3wFtt<1hos1lI!7I3ER%x(Sc^5hKg7^|A7UyG*S)8TKx& zH|*7%Y3$QzI^Mit=cjTK+>evYBT1kv)+ytO>s8Ex~Yl1%Nof%ANxc{-}P(& z(bGjZOGOF))%r<>5$kitbM}0o3c(Bu+pvh|rJ_XG3k~eK8tf5Xx7d7nM@uyoYxGQT z4|jU)+%FcJRY0t85nRgoo1PuqZMKC+g~6jP)QS=Ne$yVs-o^H?E9}j6rq7b$_F7Sa zk#WN76CIB`<=)}9 z;T9gN=Jbvh-xSh*z`c*X0JqDBPB%}3_})cu&tMws zI4_>@_+1E8x0gC?IG@Wtc;Vh!^WCT3YA*WK^3pM4DR$OaJ(1s??O}BZ{?Q8lVPGwF zZ~Zv2@@K8o+|KL;$ZkAno;m)t{3>^LWcb3w7_oh>ZV$G>wy}H1YpeMuYWInY;F@L{ z_gc=`WyWt^B{yLvHG39L16|Ty%WuN{7#;=UZ4g^r1eanj!1sAYWfuMFd)q%UvSUQ_ zA?+Vriu)K=U%i#t2gFc#6cb#Ee-q|QwkS_bd?nQtvpAh!jTYYz*6qPP#!}ShD*Ev2 zBy<1HifRVdyqMrtbJ8hmm8UXn%y!vuJ~v7ni`KR=>nxMZDX_8KWrJId?P0!sz&x`f z+T2?6D*QNFELf%6oZFvi!)P1S&8$|=OD@LOU9Uf4#Vr4N_V*z7EADT|FIumgIUmFV z7s0y1v|&tbHqBG)%a-OJ_#R{%tUgR53vG*Oo>UO`T|}3yv0~M59nYCYR{2>A%#!O) z+oyi(MaGD>Kj~h=?eA>!?sFEH@2x#8Ct#kM2`dB)5ypk`p6VSmeL@z)OBudKfNyuU_? z_x9!eclq8b&u{YzsOv6*eZ@)NUf0_U{Ug6>j!FnbfsXCNlJ2<|aVV}IhyXg4>^I_{XPxJY$Nsw&(P( z2gQmz|I>b6=SYmGzE*n_dl#-A*z0HZjVvQ`(07^OzRNunHio|CS?L{NuT3z)&t)3> zsc|E_bu+tlx@PRu7*VQ+_9*@xTqBru4lH2q*;3AaD<;^U^R1>g?rToI7h}(!Gr|7B z_At-TsIPezgyrW<@N=2QXldpYPrjed$>sP;9UmMm&J_r;ziX`?{@f>`gr{`gfB*8k zKAvjH>*NxQUfsm=Qc+@T58W56{R~q)6EB~W!eztRm)PEsnW1Jt_F1_MGuv!~d!>`U zJxZ9f4ty@#po#YCZDX%NjX<*sdPy>R2@~8lOk<^?ZUJ)ydWn@Oz4Z`$f6UaqoqGw>7?8R5b=9Lq!w$N3 zxkkC2u#;m{70(YxlI*V{Caiw-yk|s->9cel8pg%-CC$>y*UAPi8(gDo536LC`*?~a zt&`uOC$bIao3OofQPO+3N?NNDiw5W%B+^tyyZX33T5!wCkJXIDX%J1P(OmHc- z4K2a#+?{btw>8i3=$j1Pwm>r@I8 zT*}!?!rrgqd4l%Hhf(-jWunEI@%ooL-<{hd^4IS?a(<#cXUPQDf|LGz*cwmMefq6J z7DtPF>-8_^H+25;MvJfP-1-oC$s|zoB8g5B}9@gKZ<1Mb9ML#)=b3t@v5`Zy!6?=*^Sb#?!66|MRW%yEDO0LO!yh(YB3t z8S7f{v-ICS_L+LGFSQLT7r}qM6~Bol_(}g|gP-eTpVM&KcsgRJ{Z^N5oNLAZ;yp>X zNB3LZBJ|&x5!T-rGyIFt&t-z2gb~@iNZZECOK@kg{apR5kv+8yYb93yof)B5W&ch1 z*t;p1;3pxTFYBUhjHwjP&-$>Uwqfle(0^w}SbyWIXhWDyJiZke&i}$h`BP);er3&m z{+A6Odli`pw*6l=eC*X?{ahb=R@G@^@~uGotyXUc3+I1XHpO}qAA2rT|D73OWpBm` z*1rh-TqgKQh|Z%c>0iFAOE^F4MpJFWn$gjJXGU0mV+{9k0h`z`H!__6g^Bm}jkfEm z%eQSn{M&|pcP7|2GML>sCoN^j9WgYVpQZoyvDXkhrL~QDqr`u{m5)6e#RNa;zijYx zeeAKX)5epub@p53D;6Ej|1!2mhTR_4J}LcoW`y-OZbbMOp`XhHKMDKDjwjhRZdzXx z_H*^Krq4>ZZCGOz{dZ=B^|xU(Y3*$j>k&WrUzjitq}lCZt&;zj4Ile!n+dl4Up9Q~ z(UN|yk3HMsv@sj8!)n1Yh*4Y$J5TK2VV!;b{}GuH`hA}hnzo{Z^*f&bZ;ag|pa1_% X*sx-g^*`(HfB!F!;8J;ibLsyBZ-|R! literal 0 HcmV?d00001 diff --git a/tests/oracle/29-two-sided-and-partial-revolve/expected.json b/tests/oracle/29-two-sided-and-partial-revolve/expected.json new file mode 100644 index 00000000..845ec645 --- /dev/null +++ b/tests/oracle/29-two-sided-and-partial-revolve/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "block [-20,20]x[-25,10]x[0,20] minus the 270 deg revolve (from +X towards +Y) of the 8x8 square r 4..12, z 12..20; the removed section is the annular sector minus the circular segment y > 10 (R^2 acos(d/R) - d sqrt(R^2-d^2), y-moment 2/3 (R^2-d^2)^1.5) that lies outside the block; sector moments (R^3-r^3)/3 (sin, 1-cos); A = box - top opening + floor - front-face notch 2 sqrt(44) x 8 + inner wall r th h + outer wall (th - pi + 2 asin(5/6)) R h + 2 end caps", + "body_count": 1, + "volume_mm3": 25731.30662164881, + "area_mm2": 6312.602171854095, + "center_of_mass": [ + 0.17244881492337513, + -8.273218841749548, + 9.4709883773001 + ], + "bbox": { + "min": [ + -20.0, + -25.0, + 0.0 + ], + "max": [ + 20.0, + 10.0, + 20.0 + ] + }, + "faces": 12 +} diff --git a/tests/oracle/29-two-sided-and-partial-revolve/recipe.json b/tests/oracle/29-two-sided-and-partial-revolve/recipe.json new file mode 100644 index 00000000..9fcbeb0e --- /dev/null +++ b/tests/oracle/29-two-sided-and-partial-revolve/recipe.json @@ -0,0 +1,289 @@ +{ + "id": "29-two-sided-and-partial-revolve", + "name": "Two-sided extrude + partial revolve cut", + "description": "Rectangle 40x20 on XZ extruded two sides (+10 along normal, 25 opposite); then a 270 deg revolve cut of an 8x8 square about the world Z axis.", + "exercises": [ + "extrude_two_sides", + "revolve_partial", + "revolve_cut" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Sketch1", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -20.0, + 0.0 + ] + }, + "end": { + "at": [ + 20.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + 0.0 + ] + }, + "end": { + "at": [ + 20.0, + -20.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 20.0, + -20.0 + ] + }, + "end": { + "at": [ + -20.0, + -20.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -20.0, + -20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -20.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Sketch1", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "two_sides", + "side1": 10, + "side2_opposite": 25 + }, + "result_bodies": [ + "Block" + ] + }, + { + "op": "sketch", + "name": "RevolveSketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 4.0, + -12.0 + ] + }, + "end": { + "at": [ + 12.0, + -12.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 12.0, + -12.0 + ] + }, + "end": { + "at": [ + 12.0, + -20.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 12.0, + -20.0 + ] + }, + "end": { + "at": [ + 4.0, + -20.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 4.0, + -20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 4.0, + -12.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "RevolveCut", + "operation": "cut", + "profile": { + "sketch": "RevolveSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 270, + "result_bodies": [ + "Block" + ] + } + ] +} diff --git a/tests/oracle/30-fillet-after-shell/expected.json b/tests/oracle/30-fillet-after-shell/expected.json new file mode 100644 index 00000000..3717aa55 --- /dev/null +++ b/tests/oracle/30-fillet-after-shell/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, makeThickness shell, Part makeFillet", + "body_count": 1, + "volume_mm3": 21745.87649398271, + "area_mm2": 14968.331952825032, + "center_of_mass": [ + 30.000000000000004, + 20.000000000000007, + 11.575289961678543 + ], + "bbox": { + "min": [ + -8.881784197001252e-16, + -8.881784197001252e-16, + 0.0 + ], + "max": [ + 60.0, + 40.0, + 30.0 + ] + } +} diff --git a/tests/oracle/30-fillet-after-shell/recipe.json b/tests/oracle/30-fillet-after-shell/recipe.json new file mode 100644 index 00000000..3db40eae --- /dev/null +++ b/tests/oracle/30-fillet-after-shell/recipe.json @@ -0,0 +1,385 @@ +{ + "id": "30-fillet-after-shell", + "name": "Fillets after shell", + "description": "60x40x30 box shelled 3 mm (top open); outer vertical edges R6, inner vertical edges R3, then the inner floor loop R1 (tangent chain).", + "exercises": [ + "shell", + "fillet", + "fillet_after_shell", + "tangent_chain" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 60, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 60.0, + 0.0 + ] + }, + "end": { + "at": [ + 60, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 60.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "shell", + "name": "Shell1", + "faces_removed": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 30.0, + 20.0, + 30.0 + ] + } + ], + "face_selection": "top face (z=30)", + "inside_thickness": 3, + "outside_thickness": 0, + "tangent_chain": false + }, + { + "op": "fillet", + "name": "OuterFillet", + "type": "constant_radius", + "radius": 6, + "tangent_chain": false, + "edge_selection": "the 4 outer vertical edges (x in {0,60}, y in {0,40})", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 40.0, + 0.0 + ], + "end": [ + 0.0, + 40.0, + 30.0 + ], + "point": [ + 0.0, + 40.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 40.0, + 0.0 + ], + "end": [ + 60.0, + 40.0, + 30.0 + ], + "point": [ + 60.0, + 40.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 0.0, + 0.0 + ], + "end": [ + 60.0, + 0.0, + 30.0 + ], + "point": [ + 60.0, + 0.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + 0.0, + 0.0, + 15.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "InnerFillet", + "type": "constant_radius", + "radius": 3, + "tangent_chain": false, + "edge_selection": "the 4 inner vertical edges (x in {3,57}, y in {3,37}, z 3..30)", + "edges": [ + { + "type": "line", + "start": [ + 57.0, + 37.0, + 3.0 + ], + "end": [ + 57.0, + 37.0, + 30.0 + ], + "point": [ + 57.0, + 37.0, + 16.5 + ] + }, + { + "type": "line", + "start": [ + 3.0, + 37.0, + 3.0 + ], + "end": [ + 3.0, + 37.0, + 30.0 + ], + "point": [ + 3.0, + 37.0, + 16.5 + ] + }, + { + "type": "line", + "start": [ + 57.0, + 3.0, + 3.0 + ], + "end": [ + 57.0, + 3.0, + 30.0 + ], + "point": [ + 57.0, + 3.0, + 16.5 + ] + }, + { + "type": "line", + "start": [ + 3.0, + 3.0, + 3.0 + ], + "end": [ + 3.0, + 3.0, + 30.0 + ], + "point": [ + 3.0, + 3.0, + 16.5 + ] + } + ] + }, + { + "op": "fillet", + "name": "FloorFillet", + "type": "constant_radius", + "radius": 1, + "tangent_chain": true, + "edge_selection": "one edge of the inner floor (z=3) + tangent chain = whole floor boundary loop", + "edges": [ + { + "type": "arc", + "start": [ + 3.0, + 6.0, + 3.0 + ], + "end": [ + 6.0, + 3.0, + 3.0 + ], + "center": [ + 6.0, + 6.0, + 3.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 3.878679656, + 3.878679656, + 3.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/30-fillet-after-shell/reference.stl b/tests/oracle/30-fillet-after-shell/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..8ed767be49e3b2044226d1ccb51e6dda88a5d921 GIT binary patch literal 196684 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 Ip|XSEe<*}Gf&c&j literal 0 HcmV?d00001 diff --git a/tests/oracle/31-fillet-l-all-edges/expected.json b/tests/oracle/31-fillet-l-all-edges/expected.json new file mode 100644 index 00000000..6e912683 --- /dev/null +++ b/tests/oracle/31-fillet-l-all-edges/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet", + "body_count": 1, + "volume_mm3": 14321.625800678561, + "area_mm2": 5024.044667641301, + "center_of_mass": [ + 20.90086014062925, + 10.902918183990028, + 10.000000000000005 + ], + "bbox": { + "min": [ + -4.440892098500626e-16, + -4.440892098500626e-16, + -4.440892098500626e-16 + ], + "max": [ + 60.0, + 40.0, + 20.0 + ] + } +} diff --git a/tests/oracle/31-fillet-l-all-edges/recipe.json b/tests/oracle/31-fillet-l-all-edges/recipe.json new file mode 100644 index 00000000..1a713730 --- /dev/null +++ b/tests/oracle/31-fillet-l-all-edges/recipe.json @@ -0,0 +1,524 @@ +{ + "id": "31-fillet-l-all-edges", + "name": "All-edge fillet on an L block", + "description": "L profile (60x40, 8 thick legs) extruded 20; every edge filleted R2 - mixed convex/concave corners.", + "exercises": [ + "fillet", + "concave_edge", + "mixed_corner" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "LSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 60, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 60.0, + 0.0 + ] + }, + "end": { + "at": [ + 60, + 8 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 60.0, + 8.0 + ] + }, + "end": { + "at": [ + 8, + 8 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 8.0, + 8.0 + ] + }, + "end": { + "at": [ + 8, + 40 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 8.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l6" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "LSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4", + "l5", + "l6" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "L" + ] + }, + { + "op": "fillet", + "name": "Fillet1", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "all 18 edges of L", + "edges": [ + { + "type": "line", + "start": [ + 8.0, + 40.0, + 0.0 + ], + "end": [ + 0.0, + 40.0, + 0.0 + ], + "point": [ + 4.0, + 40.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 40.0, + 0.0 + ], + "end": [ + 0.0, + 40.0, + 20.0 + ], + "point": [ + 0.0, + 40.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 8.0, + 40.0, + 20.0 + ], + "end": [ + 0.0, + 40.0, + 20.0 + ], + "point": [ + 4.0, + 40.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 8.0, + 40.0, + 0.0 + ], + "end": [ + 8.0, + 40.0, + 20.0 + ], + "point": [ + 8.0, + 40.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 8.0, + 8.0, + 0.0 + ], + "end": [ + 8.0, + 40.0, + 0.0 + ], + "point": [ + 8.0, + 24.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 8.0, + 8.0, + 20.0 + ], + "end": [ + 8.0, + 40.0, + 20.0 + ], + "point": [ + 8.0, + 24.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 8.0, + 8.0, + 0.0 + ], + "end": [ + 8.0, + 8.0, + 20.0 + ], + "point": [ + 8.0, + 8.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 8.0, + 0.0 + ], + "end": [ + 8.0, + 8.0, + 0.0 + ], + "point": [ + 34.0, + 8.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 8.0, + 20.0 + ], + "end": [ + 8.0, + 8.0, + 20.0 + ], + "point": [ + 34.0, + 8.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 8.0, + 0.0 + ], + "end": [ + 60.0, + 8.0, + 20.0 + ], + "point": [ + 60.0, + 8.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 0.0, + 0.0 + ], + "end": [ + 60.0, + 8.0, + 0.0 + ], + "point": [ + 60.0, + 4.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 0.0, + 20.0 + ], + "end": [ + 60.0, + 8.0, + 20.0 + ], + "point": [ + 60.0, + 4.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 60.0, + 0.0, + 0.0 + ], + "end": [ + 60.0, + 0.0, + 20.0 + ], + "point": [ + 60.0, + 0.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 60.0, + 0.0, + 0.0 + ], + "point": [ + 30.0, + 0.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 20.0 + ], + "end": [ + 60.0, + 0.0, + 20.0 + ], + "point": [ + 30.0, + 0.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 20.0 + ], + "point": [ + 0.0, + 0.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 40.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 0.0 + ], + "point": [ + 0.0, + 20.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 40.0, + 20.0 + ], + "end": [ + 0.0, + 0.0, + 20.0 + ], + "point": [ + 0.0, + 20.0, + 20.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/31-fillet-l-all-edges/reference.stl b/tests/oracle/31-fillet-l-all-edges/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..711138d2e24a83898229689b13ddefdcfc9b5ff3 GIT binary patch literal 382084 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

+U@9$7?guBjj3d5xz&krfPTj($Xim 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

jM9y(eS2KJ})XFOE9jFYt*y6Mcs(EsUG3l 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 literal 0 HcmV?d00001 diff --git a/tests/oracle/32-boss-plate-fillets/expected.json b/tests/oracle/32-boss-plate-fillets/expected.json new file mode 100644 index 00000000..b0cbfaed --- /dev/null +++ b/tests/oracle/32-boss-plate-fillets/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "plate 60x60x8 + boss (r10, z 8..23) with R3 concave base and R2 convex top fillets taken as one solid of revolution: V, z-moment and lateral area from Pappus/Green on its (r,z) profile (quarter-circle fillet arcs); plate top loses the r13 disc", + "body_count": 1, + "volume_mm3": 33590.34963015678, + "area_mm2": 9929.863617615047, + "center_of_mass": [ + 0.0, + 0.0, + 5.602823546473236 + ], + "bbox": { + "min": [ + -30.0, + -30.0, + 0.0 + ], + "max": [ + 30.0, + 30.0, + 23.0 + ] + }, + "faces": 10 +} diff --git a/tests/oracle/32-boss-plate-fillets/recipe.json b/tests/oracle/32-boss-plate-fillets/recipe.json new file mode 100644 index 00000000..7cf4ec86 --- /dev/null +++ b/tests/oracle/32-boss-plate-fillets/recipe.json @@ -0,0 +1,316 @@ +{ + "id": "32-boss-plate-fillets", + "name": "Boss on plate: base and top fillets", + "description": "60x60x8 plate centred on origin; d20 boss 15 tall joined on top; base circle edge R3 (concave), top circle edge R2 (convex).", + "exercises": [ + "extrude_join", + "fillet", + "cylinder_plane_edge" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -30, + -30 + ] + }, + "end": { + "at": [ + 30, + -30 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 30.0, + -30.0 + ] + }, + "end": { + "at": [ + 30, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 30.0, + 30.0 + ] + }, + "end": { + "at": [ + -30, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -30.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -30.0, + -30.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 8, + "direction": "positive" + }, + "result_bodies": [ + "Part" + ] + }, + { + "op": "sketch", + "name": "BossSketch", + "plane": { + "ref": "face: top of plate (z=8)", + "origin": [ + 0.0, + 0.0, + 8.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 0.0, + 0.0, + 8.0 + ] + } + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 10, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Boss", + "operation": "join", + "profiles": [ + { + "sketch": "BossSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 15, + "direction": "positive" + }, + "result_bodies": [ + "Part" + ] + }, + { + "op": "fillet", + "name": "BaseFillet", + "type": "constant_radius", + "radius": 3, + "tangent_chain": false, + "edge_selection": "circular edge r=10 at z=8 (boss meets plate)", + "edges": [ + { + "type": "circle", + "start": [ + -10.0, + -0.0, + 8.0 + ], + "end": [ + -10.0, + -0.0, + 8.0 + ], + "center": [ + 0.0, + 0.0, + 8.0 + ], + "axis": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 10.0, + 0.0, + 8.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "TopFillet", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "circular edge r=10 at z=23 (boss top)", + "edges": [ + { + "type": "circle", + "start": [ + -10.0, + -0.0, + 23.0 + ], + "end": [ + -10.0, + -0.0, + 23.0 + ], + "center": [ + 0.0, + 0.0, + 23.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 10.0, + 0.0, + 23.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/33-fillet-tangent-chain/expected.json b/tests/oracle/33-fillet-tangent-chain/expected.json new file mode 100644 index 00000000..45dff156 --- /dev/null +++ b/tests/oracle/33-fillet-tangent-chain/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "obround (R8, centres 40 apart) x 10 minus R2 fillet spandrel R^2(1-pi/4) and 1 mm chamfer triangle swept round the whole loop (Pappus: section x path of its centroid, inset R(10-3pi)/(3(4-pi)) resp. c/3); surfaces likewise (fillet arc centroid inset R-2R/pi)", + "body_count": 1, + "volume_mm3": 8237.12239193832, + "area_mm2": 2793.569488148386, + "center_of_mass": [ + 20.0, + 0.0, + 4.975827363940953 + ], + "bbox": { + "min": [ + -8.0, + -8.0, + 0.0 + ], + "max": [ + 48.0, + 8.0, + 10.0 + ] + }, + "faces": 14 +} diff --git a/tests/oracle/33-fillet-tangent-chain/recipe.json b/tests/oracle/33-fillet-tangent-chain/recipe.json new file mode 100644 index 00000000..96ea9118 --- /dev/null +++ b/tests/oracle/33-fillet-tangent-chain/recipe.json @@ -0,0 +1,212 @@ +{ + "id": "33-fillet-tangent-chain", + "name": "Fillet chain across tangent faces", + "description": "Obround (centres 0 and 40, R8) extruded 10; one top edge filleted R2 with tangent chain (whole top loop), then one bottom edge chamfered 1 with tangent chain.", + "exercises": [ + "fillet", + "tangent_chain", + "chamfer" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "SlotSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + 0, + 0 + ] + }, + "start": { + "at": [ + 0, + 8 + ] + }, + "sweep_deg": 180, + "id": "a1" + }, + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + 40, + 0 + ] + }, + "start": { + "at": [ + 40, + -8 + ] + }, + "sweep_deg": 180, + "id": "a2" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + -0.0, + -8.0 + ] + }, + "end": { + "ref": "a2.start", + "at": [ + 40.0, + -8.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "a2.end", + "at": [ + 40.0, + 8.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 0.0, + 8.0 + ] + }, + "id": "l2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "SlotSketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "a2", + "l1", + "l2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Slot" + ] + }, + { + "op": "fillet", + "name": "TopFillet", + "type": "constant_radius", + "radius": 2, + "tangent_chain": true, + "edge_selection": "top straight edge at y=-8, z=10, plus tangent chain", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + -8.0, + 10.0 + ], + "end": [ + 40.0, + -8.0, + 10.0 + ], + "point": [ + 20.0, + -8.0, + 10.0 + ] + } + ] + }, + { + "op": "chamfer", + "name": "BottomChamfer", + "type": "equal_distance", + "distance": 1, + "tangent_chain": true, + "edge_selection": "bottom straight edge at y=-8, z=0, plus tangent chain", + "edges": [ + { + "type": "line", + "start": [ + -0.0, + -8.0, + 0.0 + ], + "end": [ + 40.0, + -8.0, + 0.0 + ], + "point": [ + 20.0, + -8.0, + 0.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/34-chamfer-then-fillet/expected.json b/tests/oracle/34-chamfer-then-fillet/expected.json new file mode 100644 index 00000000..7ed149fc --- /dev/null +++ b/tests/oracle/34-chamfer-then-fillet/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeChamfer, Part makeFillet", + "body_count": 1, + "volume_mm3": 22892.42132988775, + "area_mm2": 4753.688476928938, + "center_of_mass": [ + 20.000000000000004, + 15.000000000000012, + 9.95512677479753 + ], + "bbox": { + "min": [ + -1.3322676295501878e-15, + -8.881784197001252e-16, + 0.0 + ], + "max": [ + 40.0, + 30.0, + 20.0 + ] + } +} diff --git a/tests/oracle/34-chamfer-then-fillet/recipe.json b/tests/oracle/34-chamfer-then-fillet/recipe.json new file mode 100644 index 00000000..bfcd0aab --- /dev/null +++ b/tests/oracle/34-chamfer-then-fillet/recipe.json @@ -0,0 +1,390 @@ +{ + "id": "34-chamfer-then-fillet", + "name": "Chamfer then fillet", + "description": "40x30x20 box; 4 vertical edges chamfered 5; then all 8 edges of the (now octagonal) top face filleted R2.", + "exercises": [ + "chamfer", + "fillet", + "chamfer_fillet_interaction" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "chamfer", + "name": "Chamfer1", + "type": "equal_distance", + "distance": 5, + "tangent_chain": false, + "edge_selection": "the 4 vertical edges", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 30.0, + 0.0 + ], + "end": [ + 0.0, + 30.0, + 20.0 + ], + "point": [ + 0.0, + 30.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 30.0, + 0.0 + ], + "end": [ + 40.0, + 30.0, + 20.0 + ], + "point": [ + 40.0, + 30.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 0.0, + 0.0 + ], + "end": [ + 40.0, + 0.0, + 20.0 + ], + "point": [ + 40.0, + 0.0, + 10.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 20.0 + ], + "point": [ + 0.0, + 0.0, + 10.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "Fillet1", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "all 8 edges of the top face (z=20)", + "edges": [ + { + "type": "line", + "start": [ + 5.0, + 0.0, + 20.0 + ], + "end": [ + 0.0, + 5.0, + 20.0 + ], + "point": [ + 2.5, + 2.5, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 5.0, + 0.0, + 20.0 + ], + "end": [ + 35.0, + 0.0, + 20.0 + ], + "point": [ + 20.0, + 0.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 5.0, + 20.0 + ], + "end": [ + 35.0, + 0.0, + 20.0 + ], + "point": [ + 37.5, + 2.5, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 40.0, + 5.0, + 20.0 + ], + "end": [ + 40.0, + 25.0, + 20.0 + ], + "point": [ + 40.0, + 15.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 35.0, + 30.0, + 20.0 + ], + "end": [ + 40.0, + 25.0, + 20.0 + ], + "point": [ + 37.5, + 27.5, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 35.0, + 30.0, + 20.0 + ], + "end": [ + 5.0, + 30.0, + 20.0 + ], + "point": [ + 20.0, + 30.0, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 25.0, + 20.0 + ], + "end": [ + 5.0, + 30.0, + 20.0 + ], + "point": [ + 2.5, + 27.5, + 20.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 25.0, + 20.0 + ], + "end": [ + 0.0, + 5.0, + 20.0 + ], + "point": [ + 0.0, + 15.0, + 20.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/34-chamfer-then-fillet/reference.stl b/tests/oracle/34-chamfer-then-fillet/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..f338108e485fc174bd41bffc37cfd1f0d98461c7 GIT binary patch literal 17084 zcmb`Od3aQ1vc@Y;j3hlOtCBzxMg*fHCGO3TML`w?**6I&4vJhAP$59VIsyX% ziV%$uB;XhZBC_>J=p%s;m@5>7$eq(2*%SGch>$MH99;|sr| z`;Byxl~~{(R`LP(k;To3*j&tU{ zztlplrAIur*7Yx1;V&#d>+A5`Vz-8LHJH0XT_jK`T%+XBXy@Cl5FO}B>b3U!e{rErZ#3r9FKmo8TDM~IO8!Af6TkCGvT(4ket)Qm8d+Xo9VE_tY!)*Ppde zT^O^>{dL5;U7;=#s1&YIUA8+^FXvf>TIIq?e%3W~SE!2wDuru| z?!7$pQaH5P1ZLgdJ>J$?wTUZP^+U&pPFDC15+z@3 z@y~qfsCv0t*U$uJy&4;D>#W+usbJo=W)J5mdXNRZ3Cz0d^E$T9 zs!dE!*;_KcI!EC<>x=8y{O{h+voSDn+DH6z_%;8`Uz$K&Bv2_#gnz7Y0X&g+yT21; zBA<3&>&Uy}iZIJ`8TqU)(IUBx4+(TxiECDAYAw#$fJ9Vm5b$ z1lB{EC}Gdtj>IbVKH_ymPka>Wnl583cO;R?T_J(>kS6-qggYFGUF?0t>xiECDAYAw z#?9Q3#3b$t39N@S(ZwH{IT9ZBKH_ymPka>Wnl9sixFd-J+!Yd74{4&&dx{kz3b{XPzL{EGa>Y6U&2JT2AmAgU$>mf~) zui_ku>FhGZ>xiECDAYAw#`WBh#Czh%fWUf46V;n`AtbShy^nYu(Gwqqx~9v>E=0PP%%6eMx-OP3F17skU}Cct;@`%fuKa>P(KcP!|catC#lPt6pGV za(~oK=Gm>Ow)hcoHF!tizpt1W#KgAHAPaSoFuS^L&)tgHmz-r^f?D~rQf=*O@Qy;% zh>3bk^kV{bkw7J)k_mSx4kxE)sfAikK9Fi_SA%yHBG0jAD&bf&XGPS71qr;05Pi%w z9Ii2pYhWixU~Qs%S|+Nt>@rFxnirN%XH#r(Fye#oD#FK5?&=Qi%EMiuE)r%}mon=r z4reR74AiQ8J;l~O2(KbUN!%5ObAh`;T_jM6=mQm}*0akP9(7?kkd|U=AB0yCzHs{L zss#2v%egDmMZ)YVIQ4?HdFqAG8Fm?{758DXt$h$)MTpqE>K<5|`+_9f9bnIoSj+1dx; z9fe5!G|zhIr+J~%Q=V0*i-g(LY_74`^*)%jC@sm>KFF*ws!j{*MRqbbv6I1fkig3e zQAZ{e6Agp_-PB2mw)R0LapiXvzF77?C)mm0J4oQ=g(xw$!gm`J;(ah{|0j)Y?So8W z!&3u%TV3yi?;wGf7ouMh7G_>$Uow_`3BEITWMf-9Cv)zyxAF~j-4f~|fl5Suxkhi- zEnyZ;XS0UuN8B;3C#U?Qyw*1o{e9Q_h=a+M9Gtba3GJ5LCqF{*mpG!+H6DsZz*Fh( zOASqgpB14ayA~m;?uEte413piAJNs{cWcNM$0c-@XzABT$oIovHU2F(k|p2Oy~}H) z<)0(}hVdOF^lPbi!_;ou;=0^)--GK+Pt7uZ?Wuaca8&K6QyQ3EbF-YrmqDo_zpv2a z3IV?DH=3xD@0I!Y?b|3fOZ4hUn>8AqYY_4t&dnJ7n7K`0*4fn+>YvL?1CMN$D`(^3 z^+R9gPi}vV|3u*if%T9k`r_=U(Ag8sw`}TYZbhiu_m!>cwH7-9)1Q$Vb*uA3d!9?o zXt&PXyfCY*c6`L#Ik6tnM9;kZL+F`$oxBYWjxhFG)P3Z( zY3eU4b_PmL%F~QDckB*z%;*zb7_~d&&WSY9%e#4&ubblSxN3m0pQG;8*eo^hma;&i zUurzK>2zq(|IP{iBkBf#n=sNup>wx7Lpv?@&X4P1+!;{!?)Q|co>3Oa$d;!|Ge>)z z#Saz+KiXj4GH|0un&|JTY0i!F3cYDJ1&n(M>L!n9re+;43uLX3r(}D^COg|VZVtZm zxp|Yp%LLMVRcn*sRCZqLZT?wXyV}ELH+^4*fVzpD~qFUeQ;qznkf6=U}we9 z0`H5HVvGwU>UP}oy!B^qdEneEdBS@gKNang;si4$nKw(k+#yXgb;(F)!RxPiw`Nrt zcTvNqjPOyp#4u z2k(GJ3ysS*X1$g1if`#B<$=}Tzs@zf@@D{sjqDU0v(3EFifU@xjgX0K=~xcjO-kzsQu*4PozyV2+W%QMs>%DSIPtVYh`lECq-5?+8O*^irfIi zC&*k~5Wpu5Ch_o@97iUnvwCeN5@r@Uj!ir3Zri-GuCEbKXPjPm%lPrjE&l4Ihu!JC zlZkRB8b%Q^o%K9Nn&^Lg`?ekQ?elfzS&Op>b^npO$-nUWBkrs%X5s@Tx$WHYJ4Bl3(d;>)?%8v!_B@?&-l6W%;l=)<%}3qo{4^6BR;wriJ4Bi< zMYpaBaagY%7@=_9p>D;5wf--@`p%usJ(+lviN#R_c8D}l#NWmD7r%F>b2<|owFvAGX`&mC9t=0?9E&V;trv4t4_jGfG^A2_G|61km9z5<& z=XaS{&V&<1V24N(m1Q<`c4jtIEl<=}IPXyR^YlW0(Mu=X>Fh93!bJNh0y{*S=-#xZ z&OK>O)qiKlD4chw`|sqH{xK;h-Raz#iB?QhL=o5_(nN=DZ0;PqvAIegR%PMr!+K_o zb4>im#H&x31ZK6r=UxBgbtm0<{>tGrXVT#`71JkZ;q1eDCee+FE=&yI>5K$s4IH(? z|9y*7?sT4>*UHJsYo(^~ti{=fv`H*uVg(cZ8=3@Wt=P*?;isQ+r}MDZZJZIU+o1sdDVy066=}7S|&Ku`X~ak zhBq$ocRq8wR1RB*VfZ~I4v+&ggI{RGW)hGfxM4D*sCI0lorFQDV z53O_5trxuZ?8Ri}3+pPLlj|ZlAnZpGaw;X9PJs9CYmsOl=ZhcFK_uH z@3p(9CE9uq$4>Be#?#;RC!dPwtLyK}b{+pSM<$+7XYHTue&U=?q|Cr>u9^&XD8c#|bM z`_d2Au%i!p+ww+_1lB{EpBs$!sLJ%hV9dt8>UefjTkqkhi??OIp6`xRho(&N-ohI_ z5?BvuqV#des(1e8U~}GtN5mxCdJjikypa=KICrah@lT7rBYC4o0_!2oM7P%Jx^bn! z0Xg@paZ{3Qy@#VN-uj7}r>3c=XBK+b@J5dW)pdKG@mUyA=E1@0nXCeD6>s!NU_GRX#w;1B-tYXH_om@hmg<*k z>pdK4vqqOgqg9jF-wEFOc&R~P7Cr?ey8XZy_4A(Rz4!1uKffr|)>}2!Gl?$;j#ImQ z(}R!lwv7a4;qy;^3J^b0{eEnx;H8fTS!cJW+Ip+TEPN_UR6TXPT0gpjcQHEvB(NUR zM6D_(tHcSXx5Q0~wW^P#+Ip)-U3|LCe`*&^R1J7P@3FI|L0~~t2VRnDZq=_IjX8x?&fp%PBRFsXVP8H z)O;R;-m01BkxM+*GoL5$V9wpMwOh@$jr%KpQXz{!nH$-*h4|on1FHv5H6$?WyGP^g z$nGrDznp8xevSn0%dpPR;aeurW*`1}vI_|2RyFvo%Asw#q@xOLh?RXC2#*4Zu8zk6~-C1hP<*rh> zDOE_+BGWA->O2qJLCR}S>sC+?8vq)RfKS&2&{*6 zxU1wpq^YyKZR7rmx({4Pup`^HFxMimL!`qsj`H-pk0&SYuc)h9dhE!yEzGqD>=5a2 zjjFnx)B@g}aeqbK#=SgtWZM?zD<aio+w$vEG)3c0sXWV76UM(Uwi;1041ZE9A@3AA>w$$jv^S127RUhuJSg#h5 zdo2R9&h!7T7}>VDMD7bbZ>h~RAMUT1<-6*!BipugHI|8(C;~e~TJkBkGf(Ken&}+b zs!d&df-T6k2<*_LMLpDvlDK&PZT~ND~zu8)8Yc;#rF` z6?JiA<*qpUEslGl2&{)RZ!CNVm$;2*EzVTb#f_C{7H3Peh$65=0>wcE@*ciPJotaYCXlZmj$?oU{MV@p=@2 z^^oS94Bx@ea_l-@U*UvAUEEmN<#V<~b9MkoV24Qar&#$8eltfZZ^Ae&Q5SbyqNh1~ z1V>k%=SW~Zr1?_BcW}9d|Apr{PD`ZC8hbc.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "MainSketch", + "plane": { + "ref": "YZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 15, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Main", + "operation": "new", + "profiles": [ + { + "sketch": "MainSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 40, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Tee" + ] + }, + { + "op": "sketch", + "name": "BranchSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 10, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Branch", + "operation": "join", + "profiles": [ + { + "sketch": "BranchSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 35, + "direction": "positive" + }, + "result_bodies": [ + "Tee" + ] + }, + { + "op": "fillet", + "name": "SaddleFillet", + "type": "constant_radius", + "radius": 3, + "tangent_chain": false, + "edge_selection": "edge(s) whose both adjacent faces are cylinders (the branch/main intersection curve)", + "edges": [ + { + "type": "nurbs", + "start": [ + 0.0, + -10.0, + 11.180339887 + ], + "end": [ + 0.0, + -10.0, + 11.180339887 + ], + "point": [ + 0.0, + 10.0, + 11.180339887 + ] + } + ] + } + ] +} diff --git a/tests/oracle/35-fillet-curved-curved/reference.stl b/tests/oracle/35-fillet-curved-curved/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..132d80b948ed2c793365beb30f72ef69403bb5c0 GIT binary patch literal 294284 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�%uynw(FoCV* zGZR4*NXfukWK(=M*zhEXwb7qSi<)IH$EN;l&4W@ZSM&2MjeOa_yHjX`@0zppdfseF zPJca2K7Pu8xIs->t2qnkkK8^2fhDO_x~6_)&iN~(@wYy3&&8MhXtbP$zw9j#SQ7X7 zq{-yflk22w!)}1JW2-9vdb5w&bEy6Q-(B-$`b1K>_W}8@xC`JGOq9EMu{}>0QqLXz zG#)IONVHczAY?`tz%7`-)@pX8IKaIhhe(EL5FA_v$i3-WD6cl{p8 z#Mo7G8^Zp5XGpGL0E~Ixn7Oa+MBhEg6$mVezn47rhV+}~Nr|Hqtl8zlx~x~oqQfxwdZ4PYCB z$iBii7e_WbB1s*D-JI^1<+^1z9-U)SOP zc(7MHGni_xf{o2RVUm*r`;;|}`uYtM2rP;3QGDtMsz!BS;8hzqnqtqkbecfF49^t^ zEQy~7;Nk*d9^c5Zp>{%)V5_hsUa9*YC9i&&!ytY?$MMk(nS5*=T@uls*zu|k++%k;6qUy9J=euHg77UcbfGP2rP-ux9=z;$w~DfyfjYmAhrri z;-_CU`XK2sV>s6{1?CU5Xa0Y$(2ScM*uWG!_G#%kdN?MXg=}ubj`z7luhEXY=cQxK zh!@{E;MKkp;1*1H&val5$DE|<=+2zTY@SBwcnb(NjtAU=33o3W)_>9oI@zErCsHjt zl4mv+u+uXha0@2(pR#1iz)Q4MSvn_l>n$cXj+?_>ezR_QOhab&Tc(|lbz>=YZP@0c zm9+i+9!!i~(>|qSP+e4A4Etr^dyFQ!u@E~1CHAK|19pv{R3-FC4@ZWDsX4$fehMwvv^aGCw zpD%g3i#$$nfZO$h0n5TVuq6I#VsCwNV1_UdP;qCC|M~P0Tw9{^vV#`*kF3 zKG%l=qd36hj*0R=R_vYDE!tP=!29uOxe2-LXaX}{w*%aQ2^?>Hte$luxgRZI#LhUt ze#QjW&3}2_xI~V5^0V8GJs^Lw8SA;bik?~8o9(@9&fa!BKwY2rWq3sR%|Iu=k`_Om zAyKh|*`H0AUb70?`AmO-z>@e$Y-9ONg8SUS=#dT7)3#z$`RzNe1(uswe+{z3ii)SfQU`?+3(V7>T@xL4Vh-awtl%s>wC0k`W7~9 z*58M8ajR55x{rs(l4lnh0(rrs9gRCCio2V!`WtT29_KV!J7K8~SzT-h9duFw%fbYf z#7~sFzJVOq@qtH*7qlxfVg@CrX=XrAR=d}fW%j;EU6*xXUZ)M&3iSn={6zCqi(52< z+}-I27Qe%VD8WRMuLbLK_9T5!tszc7Jw(oAyMob=CV*QofpzmQah?VwW|RfYw`wbl zm3Ip>_O9?TZBdgdj2l10G_zW2IlVsIot6mYwZ@E2eL)K>Qy3<4Usy7ai~R4N$=s^Q zY!gy**aVzLw*%aQ3G64nBHkgIJn^&#I1vSSL@^=yBVWdulGbp*CZw-pgqpzBh;W{BH}mVrmCZV|NkUf{7|UWA+?Y(=W1S7v1a>KR8=v z0o@k7B(J!vm&Z5Ib}NSnIgWnltGD4$gu;tW6B8bkK6$0XCkm=#Vcr$bz_*vy4`%r$T??YCzb z!=uhu%Kq_#S1;XQ(4)cG1BTIY%3q+JhJ@GT|q)J>1woyTv;8kx$DywGJQ`_<5u`;*wlvD(bD>I3~{rOERa zOGC-C2X1h_w*M}V* zp@rI-FAZ)_8i4&Ee>fI>li(Ii%vI~No$n9P%jY$78G$!kV3DpX9B|~jEl>+4uxI(x z*}@6PC@-*|az*etCUC^?-ybKI5{IF|Q1;#h`sLJRN&0u`unApQ{B~VtruB%LH|xkA zY|>_T_CKUgVm0}}KZ6o2<_Z2K!9o?q1kM8fYrFS2qE+n$(ZKI4LUDx&T#xxt#o61) z$9{fr{=S=#QJBEi@^k1n`9ee46UMr%BRCH#+;o{K*-vXn4QJR-{1n;*KWMet6>8d* z3m(J-9yh+$xrZ0@sqlmomiq{9!Gt)v`sJSR{EQDQd$p0^7EEAk`8WF5NEm7843eiU zX&qLN+4yXyp7X}B>=U}|M9em7={$r2iD}istj1dk{tuq3`idTSV5Sl|LVnd1qTg$XgPBKb}*yWvhyyL-IgK}=xX{3N#0#?bFc z5R6^5R;X7wm$cXt+mkfsdM10aL&YMEkJEJtnwg?4ea)c74t^(q!D;d^NSie-J57s< z2QW;;)#$L-n~u}ihyk4Vt?LYZTL#0dL2C(?g^8^ApY&YOIl9qYb2e4I=ho1;Q2@9p zHwl)730z(IlXG%Y@GWQpUMKT~Jg+^Z#imb@X+?*;fBZ4@OazQdafX70-qTh5C z+ngcOk$I!JRhMUlz?5`f(7Iqva0@0p@BE?P^pDWvi#2b3>5ZJ>0q z?Az5dbhI*$(Fm423xiclE)bKwKk2B^m+2+LfeaHSZR)Te?Jv-jyPA2?UN0I! z@A=K)ziX=rmL(8K5??iGZv`QTg2C~C=s`?iYx!O>EgMMd5C{RKmk8F52^-7DZ2Cx7?fpjeirNV}ux|eD^L{2N%#$E?xjkT6SclGl zFSKRY2kNjXjq8{>ZZcmD9$(H}Z@Dj=pSe$aO0G=2YJ1j7W*G=9G5`XD&) z$OpzJr%(K#1@lkPb*~Er ztFX2FJLhu(eF*&^-7W`~K+(6WA2c)nIUV4X&M+Z9akg35K#NcU^Uf?2@_bX+ zXF6chO*;5?e`ZxyOW%iGr_Yl#UzeuF8Nrr*;V?1$0y(wr7k%M+liqIAhhYL&3_j!a zqb`K}js&x`!{l7ZSDLc$4mIL8)?orm;@=GpSV5ivg@RAZ2-c2?%+GIVpPu*Vm(Q9L z_Ry5SWUNZ{je z2pM50WGyD}sPpe?mk*K#6CxmLfIbYa`HNc);%L(?u&KotI! zWPZ(C>bdPY)w!R`F8=qC*7Lhcf4myXp4z^p(T8qPtJ|74fHjHDpkHtxG;wq$coZ># zCGqb#Lp@-JZwS1EY$0|rfuE23zPoe}Xj&WspWY1;{DBGV8y;83U18IhFnH)VgkXCy zf%As{n%K_YVh%I|hr=!e%fbZiAODrw(}FB5YX)>=4X&aisyX}F1Wnmpy68{pHRxVAB^n@WR0e0McLk*@G@R`9V!76O6N~OHsB=t>f z!f$1l0BgrOVrm}KI%AF5W2*>mRj_)!7lb(yqEf zv}2-0@^jkc#63DERrB5XXrUvVT|{BUrhY;#!3545mFljR1DH&X0LPVGNS?`4>Y4DA zc9QxFR^h6|&*fZY1M;kBST?^G!S-SuSQ3vbzRo8>0vO%KfM9zufk#B8s%yDg8q~-S z9?lMfS+=+6zz8#@(x=S)_XWBr#FQNx!x)Zf{w1z!o6`lzJ@y+S`Y~jRwc*fE(s))fm2b8R@{1_#CohUB2!r47L>b2pNTmn+-3~ z=aUTC`d-o8A7#=HDe8JlSoX&Y&e@-!$Ge#@B_dMLfpzm!JZ!Z|%a|}IndAdl7S@3! z@wtpA3Rw}C1lso=5gfbk-d&>`i&V^DbqZ^I|01;<@|PxtYTnzux~?NMBpzlg)`qKT zcj)A~TI>lVF-%}d{Eck#f8>~9B8+Ta2L|stMTeiS%XZ|8#FR#tsq5*wEaY1P*KyzS z0Lj0d0tX%)_6{&%osx+2giYQ-VAUHCa|@957xIl zGG}xg%yKdp`hf{-tx8p#O-YaZ2sqZGkq{-A5T76KOInic3nL)2xDntUVgkn-Use3= z0qK3a9k{is6l(jMzzg&l{G!utcVGIqf0*&P-yz^%zai zRWS$WZVVG1hmTXajTXDuuM;OCFMl9E&!s_L%^YHX=N#2L@SV%h^&bFlsc(%?-p7)`4X;tCVu^JB@#pJYU3GPJrhhu|J!0$a;xye4Fj z`3DkU);l9%bn_CA(3ic8*qgR7EN`AntJfQ_$$Z5;uO(YskiNFj(D;PCP#G|R{lr)H zFL*7b#Q|KI?IF~w)PRHZ)8zW>SWk)Vn@~vyzcpj~;~CfC_u-zjdohFker_=A#ZGE+ z&XSGS0fq^;f}OPOF>6*)8qNumnqukoMLtuM*%Vye4$$C-4cJb@FoB4#JWBrzv10qR zTXG_gPL_f%2Se-rO##coIXg$AxzslTz;LSv;2vTE z_mAJU+0%zini&foId%fkC|XTx&l8i&Xy-)Zj zKjPZ1CAVVJ;ZK7r#3XqyRm*y;V`!2XOqnj zQ{Z;~H-i0v2`q`9(P(c9##+e`WcXDYG3qG2W%8R&xSGLEJUvOfHvCC@(LOBu?os+l z`a{puXx6G3ZLbSowbH<`eQSbSFd^2GYZaEz!8;L#TN)CN(^qL1sG*i2{RJIZH{Ub5 zRUdS0+d#m4A8M>Xl{T~fPqY3?tKVJX zy`c-dcb`IvcJ8LmKXh0Rw@wTb-}~*MbAol*-2XJ|O9&^voazFt+e{`{7ACMHK5G!7 z3wbBogX>it!5?8o`|11T+Dv8Mo$YSAn?BE~%TA5cc(9w}Pm+JCBSdUZ7Ia`jd`1nh z{Yh4tb%K`eiNbRb6F3(5uL+A9vUz$JxH~C=M8xc-nZ`Qo(&?@Y6S#kT7AL0;OpHhe z*Yvj%wigpvl1g2cv#d32woJ zm)RCNga6)LP^DS>vE1-DIls3ToLn)1;1*0IHeO3N7#XrPYcwA0T<19PI^PTOj3yA= zf{CcEYpC^1Bj&7~#EGD1JIIbtJ>bTF8whT}1g;n=mAUaPvc;e`s7zXt$yICUjt~QO zSEmzOyKX&=GSg@24(SYA%dL9#n4G%a9sIkt7W#n+F|KyreoQVJ_W-SPF+%KOLiC4u zo6n>sqZ{}ossx{7V(A)w_se#Db}v`6+HhFKYhpIEC+zTgD&ZDP;QsL)x&9s1D~BgR zgDhU#<$YBivrO5dyOFFoHned0Po`m3XF zCqT(oBbd*ss%GXGuop_4U=_BOzbzT}Q12R^2)kDr0Ui^q154t+=nr*MM+UcrscQ`Z zYsUnZ#8-bNnyZawH-pya0^v)=ohm+S%kEXgvOfXOsxEBPV=~0B-`^iswSA|J}x=rLuf zrY45f-L3vLp$DXISWj>Z)`6|%R&~3q_G{N2O16{`tQ`|rw@Ou8K3F~bSyT83KHwAo zy{h%SpS0`dL{_KqkE#N_Pc&p%GV_l5P_<&o4|?sP#;Vi>)786bTf)*~4uD%Qv0+SY zRgdzI)ZmHcX>j{&fAuf#rm&@hFYJ%{Q`NV@dzzDJ{o`xTx9h3>zgfZAHEp0*x|#Ca<_R@T zOl5ac43)rw*Yv+3$!vQAQ)S7%w{+%jja3dVKPvZ!HUz~Z4sZ)5vK{o5Wc?aCYmJ6z zAKOy>Xpu9ho>1`7F;q^GYC7jjnxF&g=BNDci&UG&IYayo3Z=_+l^0W9(yoD`Rag@L z?!1bs=Pq)A`6mFdc5D@vq*6(_qtwo&zWj{4K=A#ht+;=BPuCg^US`;$m#u>lEH5Os zAG4HF$u&H15sUl09o|JKv9w14=Is$IJ0zeIy<_4QBJ>zxhq^y*kDwMLU}@=_hXc}t zJbIq!Fz2lrQM=xmN*m_g$IBn~=GE=7w%=^wsz)P~Qq5ac4@js-RHfDHg&#BMvuak2 zRlNifF;6N>s{?N1ggWeQM%aR_g3ZgO=+J}42mo`ElWaF{R$Gzi>;*nH!k4b9a*VvlvEd5|63JZI2?hX79`Yd?)9^W5HqeO z!c{}jK+ihTmx(8FQMG=mQo+*Fdv{_#0llZs;}mp4&^ojMl{A{wDJ8-`2ZGW4j>owc z+n|e1Uc$B|tE`bCb z1scs)yLrO!U>6kmkB_Pz_FrpAmDA7TsuBHoSX%o2#K^^hw~ZtEt8W16xu>SoZ|zC^ zu4xPp3E1E0H;dow6P_Qahdw@Pj$nBq0hQ*kK0L&ast@M}PAn8FA1=V}Uk>JjD!vxK z2H(XCBH3Nb#;r_=ZaR-9{dSaV{{4e!a_<)2L!UW@gh|mmam%L%_|0t=VM*yzfz-tv z(Bt+x4yHgt-FG9cEJ;wqAT-KmooWn10+yDZTwYX@5SMo7_?ERCEH5NrY3UPg4TlL^ z>9=LW?7FIExId$vq|H|)tSR4*-|B2H-R~>nS~+agng+xPYaW;)%jVq>Oo2p)O^%Xh zY%b2*-k%bCVg?Aq=sQw#61yRo0tu;l1L^m1T0HFvvoXJ19bw?!wuw< zY;2^b-vnHEra$jdP)8D~Yq7b+T5#6wmBJHkZIty8t7;Aj^(=Z|!D^xTdn-a}sb}H=EH9In@lRx6BW^ynE60Pri5d)fC#KjBP z6AHDD*b|R^eyF?uCJv@RB6g5Qy1(%pjy=Oh)H4T5;^5(nX8wDcgDH@(u=pw7>zS51rqAs9%bW9+TGw#Wb=`#@sYT)P_#RF8`t}544={MsVJTK z2Z!acHyge7YfP>`4n(UenQ<@$5;w0s72gNm!}I5`(+MS~JV^!Og_^f?=3ojW61Kk- z-4EZwn;jYP{8l{@*eejV?KV<%bs+&qGwr*<%}B^nZ{*s`gM(TQW8a7^_uasag|WPt z^j^HP>oU&wW6xmacdbt@6bB$PmysMyfdp(>`c*3*50YW-hn|HwbFd_kfVMT7tX=iU zw46ZXdttb$9*}@a?7QKaLR^tK`Y|(DH8Yr`IY{-l?Z(H`2K_PyKV@wZ?t7S`o%tP+ z!xu@;y#pAlA@Oixa9B{9@Q@|wTL*0ms*VGZEsYR zzHL8&*JZL(lj#RsNZ08t(U9}oR3i!!JI9uY+~iZZ!7BDPl6GgT$dj+$s6ykD9MpmY z9GkT7HfcawK4^hlw{7R379=X9mX~J#CgG4Q))Vg+HXwU?wm?@uZ{uJJBw+pM(@yn$ z$ey4ksKJfq+}Zh`#2d}e;ne+;c%k_>vDo1Ze&RZTPkHfE9R1)J9=;}#+8C7SLF@}# zA*cD{Ri%OioR#P~vbOHz?~>MNqsv6qd<6+OZs^^ND=o>syDd@eAV<}Rf&?rr{X*U+ z53(wy6$;8r;9z+n0k0vQcW-SMQ1wsTX6J6mvb~#hY07GxKxS~R zsy32RuWi78C$dwM7q?^!&+C5WEGlwmf; zs0#_GL?bNu=Y{^SOwfrRoN9bP!p+TD@>{$bpKxV!`@AbnNHhAJm(wEp#3AUr_jj2{ z!%k^&gjqa4&byLS(f$w~wRZv~uI+Ik6}mM=Zh;rLKNG4*&)(+ZVN*xb_dps6s6;)> z2lYw$AXj7(a+8}k(_AVlw+BzujaLy+iAGquH6=4r8=<3oS+UP8qNWb0u3ukU- z{c8D`X2fA#L$rO;E)J$Z0@|j}R1df*d^z=nJDt`J!E0i_v4OOs?`m947{*Wf=qior zy9Bpf%tme7w%3GjU(2Jhu^7QC3JIu0PdY_q2}L;-kokg6s$K#K*s}B;5WndJ=gjZi z?FpS!Z4L=&o8CX4yj!^OxR|qX=!#%@Apv_Rwb9#)tn_t5dj?G75>Ho@*2Evgp68PI zd37pCg?A6*t3xOM(&iR(dGeQEJ(Q;P=C*b%C*3m_u!{qI3lt!r67|A+1Q72@G{)fB zKsBNu0hQ?9pn?}E%yC2Z&8Mo`91?I=qA}!qt>~)ej;bt6R?SzCfTLNXS=F==d3uz7 z>rQu#D|W0Qt#bGSe@u$!>v>g^oVxG8lbt8>>R!^&)0LrQXh!l2Ya`b`?{Y8&60o%Nq?5Tjaad6o4Kcl|ss|)s3F*7;JG3Ns_Bo@x8tPJU z*43o@G23ya4~eQ0(owtEhXj7HLl?ewXQUt4CDw(e`B9=eo$GvYTquLZZj?%2KELd+>|h?3vO0<()_)TWeH)2FJk^NMyb= zlWyj3$GZ3Iy@P)|Hei6@C-%($B(|-ou)?yr=xye=9*fJ3}zQ(R@ZQhc6od1LK8QECX z9*}@7OCxt1%9GW1K5^k+z0kfx^`)ZIX?R-kXq64vvh+FO;pNDS1N2=;3%yaq8CR*V z*G#;GzCjh*fJ!u~wzU%J&(UXD8q%lrKzShnmFS(H_C-RyJJ-2CLxWLdiHEc=Y!r5C zJDM*%-c)+sZvg)NkJ0=%>&DVV=lUa?wFvPoy`?Ci&ojVF}1mL-KGy- z%d1OB-!|=ZNZ88avf7X|A^0yp(y4+L|K-rh{Q zav>U@x%sP&0oKoj*h%zFY@b6BEITCB_1H5XkuN){qqV)Ys#$dLZ#AWtdspG7Ri^L> z^egb=HEZy*TkOrMTh2BogJ)TxB8Pii#6)Xp-jx-&cAtqnB;b5Z&tHAHAb4*+#LX0Y zs_M}t)>Aqf*8_WW9>c>D(%6#qYaz<&2v_@3X9QCqp{~aY|5jwko$BaXjYq0dWyaQ$ z;-9DEo|mVnN=TpW+tY^RO*2J}ratC&AGem)#4W(Sc!TKeqkjR3OuNHuix#BmO4K?0UmqiMf2PuQ?Z z;@*ykQuW=<+dQQSzjeiPE{#$3V~u9XgTIBxdAZ#8UFtT61Z+)>=1}?@VbQ8wZpG;? z2&O!|;|1lPJ+RqX`Mtl|vU6 z&{K!NXMhB(AANI6XfSDaswTSe=UkN!7ZX-ZN;g}N`M;<0aDAkn{?iWRx}_x&*UnM( zT}Y_CrE7P(kk<5B`h3@BsScWC2M9&&c3_B9Us&T{XL<9)YLK(3xSFJ z{jT+;t%bv}PME;MRhxd3wM_%k`s{1Y`;|R{R}>QJ_9&u6^K-Ac#6o*jFM$M9qR(c8 zH6|VL9WGewh@ciEU}@>;1UGAv?)Z}X{D%jED>5Y1KEv5SYZ6lRC0DZEL*o-=ZQ8_>z^KYBlRF>+qIG+y1L`<>&EdT=X*PQ zx9C+2YE|GP*;jMGJI%-PkbqZ&zN>iiIU#w-BJR&4G4v@=qjg9?CHmGnuTw(k&K2CO zmFlYt30PWs5Au~K$=aO51!lRRqX%82g&F>M$lpo)h*=G#O7jEo_&+E8@-=g-_RgeP z$!@OIu2!nAnM0z@5;rONRUp1}mPJ3VY_3bT*dOCIxV1nq1rq9>NIaX6@Ome?4EK7f z5d{fYTKY!0v+YSApW|GhXF22?;v}uk4ad3r>9^b8+Dr3)?}KMArQZDZ83`y?e}tI!-yx`X3y^& z)Pe+5qJCmg5NS8>E|;_99S2M0*Qu`bSH&K<*~{rFdm2sZ8hrc1S=a8pR3dM&=#9$ZZ>Tje{kDgt}D1$u8vP`zzdo=hr!y0tslFo+&B_ zCg&FCb8QEdM^6jr7rqnze^zo|M5ASn*fB(+G8bSj09{L5BoFT+4s|lBue2#mtyPh;_ zsur~zJ%`s-XdtcqnU2bxPW|QEHBJABCJP^Va~(bwaq!!4kWhbFZc*)iiC$wg%LLGB4Ts;3}w0uN#9G!wqSD_r%o0zD&q=P;+4)DMld z-J?1~4+-^Y^+m_GayJX3P{USNRp;~}0iRIOXrgVix%nr0qAZ6y9DKqB66z->H7J`) z;d>zm`&%5;f&^5e9@(2C+^+I{5z5}j!KW)A0iO||Cu^Ripq-EJ259I@x@lybjxqLc zDIa&tiN9a93hMM|3H_V??^WBbs@aiTBOy5M8S=Z|&A_ahha!5($^-pAW3Hio56Lf*$GaM1xBbWj%(P>J3J zxHlGQ#_Zv77rse%nziK5b2$V&nDs1awte$&GnaNe6Wy0hQ=G z0VBtvD*bb~-HXh%Fqg+>D}MHik$AzG`M=mGem4S@>vfj%ZL!M-T90-)>TdUaUZ8;dlXFTEp@2u8BT}VJBx)Y9yMk~9~H(DPY=nJ*ZrknCt_ixAL z5@++-HYWV*iMtdVeu2LsvEEN^xxK9p>Oul4X*7!tcSn04Ss?R-6kn*7np%Nx$Q{HZ z!)Eb4$CcxMv&mCzY)AA6JO3MHV#zpg7!SKK^2w`))uS|>$ZQ6ZL8l=Y^41egznvQK~J^gbx;=)P>G(1ujqx?f4}{yzEEp8{}7vnKE!Qv z5_zW2(n?3|zvKLn%cl28EbNA!=_7(Y|XsFz8Sx+go(c)8W z^e^dxHeX59L0w2dCF;Y`v9Xknk*MPdzHAKWwW{9Qg5$@S@eZ$ID1J@B#hgd4!GJQX8LseBs^= zi$Pi!PaV{S1XQATU+G-+kb)o^Jzl zwdmOydu_7eLw|<7q2v6@zHG+VmlqOjwPEvnX+0e2-n@8W0=oO?losaN zQ=u7t@Y$C4x9%#hPe!69UD4Re=C!b&FVunrTQ%7_RcfO_Rx)Q&oQTQ|G1I|ZmW^uQ zlz;8{mRmc^>#UJrD>GZ6*X@Y*g<6nct3O+BOKr4n-IeRIe+o)3SfPcvcFcK#7FfWGr4W%|-j(6rJUZ0Ady#2=q<~p6R3vr7b`9lpt zWWUEqWEDIL95*-_4f9^9g}Ejl9faydJMoz{I{reOq`p-{>SI0M-rpBmhXnJ+n8#FF zsx{~51x|@eLCJ1+v@q8a)2Ce5>rVU#`dqu3U>+ay{2tWx^Mxsp==S#3AEh24^ZHgE z$qyLuIt4iwhqZyZ&b0^$_*~+|Uu)TcR}<0uvhv=%OQG-IZJP^oEsVG=@lFeMLo)V}iz6KQPu=A;1kJk@hu)b?Z z88_TkywSs+_wN(NMwDnAQRiOv6-ebN=&0^>8>kBjs6@X-cXP48#(9Q$2pfY2t*4KC zMH@R?`Uc-_Y-SLRGsD}{X+ooG6VbV@f)?sR0xHq-iKBN5%jkUNpFe`lB?c|iM}5Tm zQMGxq`Q6zJC+g=hdTyyCQ>cC`9_37|uYh;M1z(?@2TQJ zvs!%X_+D)N5cPAuMiaL#PlzoUg))MX4(dVzD$y?-je90Af3)h!L2UgnXic|XB6f1H z;Lrclm#u@Me(j<=;rTa&3tq#}3x^OL)P)38lGj?o*4hqNqS-oV(8{Z^NnAnSO_p?` zKU>d5{TfVbo?Rp~kBde2wq0~k7ZOm3?us5+5au%!U+Bx$bA#5_dCw_es zv``lkP>Dvidw7x6`&-kmk_NYdx%%2Y7kBvI!84<${9=RFnlKOc@3BXGp!F@Cibby( z=W%vm3iI?u<|~$#>d6>HZhWNABFB5@LS0BeC5?u*9$_BrYSNT>`Ub7+V2$*xEx|k9 z&R{zhiTR49Hr8M1NM;^!M83HOwf(UARW|&1XQBWK@RFqswRBoQapO-V6MBt)g_OC>3G`*d6x=o(0PP( zr9SV;$&1*Y(~trQI#)@|yDTl${=bHh6L0Tvu9CkF<~s1rQabo`Ca%0z-faVd?#~I^ zpMTvsn(dtpDUhIZuEc!EQXB8_NRrX)ICuE{Wi8C*?q@C8-5-MMS}b5O06@^l1Ywa0 z|Lk(UFa;8H?U0xcS!$z>)i_ejWpfwy1o^;R6D!q`)~@J)r*~h-;w6CS*lGe18!YFx zRBfV#xu*5Eldd*xjH?cnBP@WRD;i-jne2U$EM8(rfdpMOCFXUOmP*_-iQN4>p7V=v z(!pHttMzJvdah&(^MzmtR*7Hjj-}s<&*V9)1{{m~NC7%iY)d0h z@GH=2f_kom#mGM0UdZBC1}#WXFGgZMWNAILQ>Kv{y)3v%?~1fA7yO#FnxK9tIYIr= z@OSlC9L}Hx3F?hW%!e$s(fw^QnHF*=aHI1mADC<9HYW*HbVo(kmhfsK<>(q^*yc;54Fx4(7W4(m~p=<2*5^kyJII^ebUtb2;|P+FaIxgwo#>8_y>tk%f6k z7}6j{2XplZt1I0-XDY4_S3-wVFM161n{E1Yy_x z4my}?QX4zTIn`ZkM$=NJVWrC{|Ae`8nhsx%=rpY zSZy$I+5Sj)abblP=GtgeP3r%2mFO}ijYVtODxnZ&bd6#@@3X#5^y`P50tsd9Qiz_u zzmWl+KZWRzHaeKgcd4m_^S6tSC(PEbwF*IfUA8)tANd3H>!6$h31zKSh=qr{6B_j* zo6aQb*K;{#$BYWn;NXLzcV{`0%6tihK#O}4_wDAS`KpdOs0#_T4H`)$6Q9;4XDsAM zszEFB@;5Ou{$(vLJ6?@7e;$vUVD3B^xT2twe8#G97#23-F$FG+X_)C{9U}DlOw5Ymm!tT zCA+4%kkp?+?<969!Cunq}jSELXNE}4;9`MpTQy)inN>+{7eVxxF7De^_Ees`x3Y;3SGlAxKO z->bi%@A)4B5NPQwMWRieDjq%daM#j_If0r78rCy$Uq;N-l@@(C<0r z6i6t$RE208P#}DLJeW)}f2D=FvfrnQqvu&lzV1=Hnqd2L=8qomv(WFIWi3c3yKTjW zChn9lDm{)Iy%muQbLD&-A&OV5B*(sTB$e&-6(S^mk1#8KEE(v~rwz>Yu3cwQ$h470 ze3v7sfMAgcHoxELQ%N5+khLJ8#2FMD8>3bWt(GK^i;*X_FxTF9O-0wQwo+y-Ig-j^ z915XCSjZP=Ig)BffrJt-QHcD7$-?cAiNrP5Ob2sCTh|b0KeCq|Y?dRbELNis)DIQd zdb_}^pFWBsr$9o9`zS=AO;_RAfhpwEm{nSs>-50KTGrS~p|sG34l+xaNpZ%8uPcXPQG z=88`lL}t?G!yQW_sVv&25G>ZmJf?dC}6&)#cDW)Ov)YbUe}!Jy)(3+uzVgD!CrwrjLcoDUe`$C}U52?&QXOPNMzl?A=_L zYt@G$G}y*LYHTG(QUQ@-63w-#G=(GOC zroV3>mkJVW_h=l0H*TbH+?9#sz{)%=%(ecbFD7+trQ=Pz>F<9iHD~u&PSKs}mZ2T> z_dnzmNU(jgaW1J`eKWW7dORtxsIP;$%75&G{d?Dz$}Q~9s|j|mh{j$?@;o{AYS4lN z+y5J9Q5G>^Gxb&H(fYefa;d^cOvOh`YDp6kS%?)ly%VA{hln@=%g#?S07)!-s zKJ?B$F-z#DzoRH?J+j?|U(c-~ai`@-D!ZGh*tmG8h-*DGmTb@MqJz4SU{NAtsaWi4 zG4%lYFOJsV8I`r>eaOLST`NhCYs!&SZ1hXao>xZZ%c4lg&Yn7`3keqOGL}lYi%h}? zcOul4(Q`6=y^zPBt;td^mo_k0<@(R@ z^j3Gov=}*(3T%iI5JGR=i1{e%T$t-fcriXO>AbiMr|8c!D5YW%XXdy2?iE<<)u06l zT5D|F8&tW~5p6l_ND2b8v@lmuh=yOz9{bb}IoFAlxG z!uFh_Hp+2PgI33o>bw}0F6I`?yHwe`EVbb_tUvlZ=%cXLzK0I#LV}K1gAzTBOYal0 zz4Jf2$LP-#$=B-U4@?^U@mi$I((-Y9Yo(qIhFxzuseOs9}S$|U4M>DwtgYjj-O}OSlmt{sdPn??<$sF z-349~P?q&_q0RtTE!2gCx*mJ!9m~zsAD#OkU4I@#Y(g z%Gx{$?Y%W#IGNIdUi8doI0JLeez!(9c3> zbN_=D>Oz8gO6)9vQmT@-$;hJmq5Ny#2Km5TkGDDT%e8K#&h=kyuzTmsAB~+S$3+d+ zW1l?vY_Gcn!-YU@mo>!N{m>z+CF60VLo~5$=A~yHrTP z9Tp^@k}*H4IV9j!_$3BlfYb!c1??HK(;sRAmPEZvH8RuX{SDhQm5vuuk;4fgPlgkykatehJnb(#HI(J?QLgAfP?|5jEw`L~*YdooxLSXwoqtbPBX3tP5q0_G~aJ)jL(r~kDc z>@I*@DrKC@zm;`Y{;e*R;(z={E@-=K0+t<)uCfWJ3u!e0cUZI@hFvk-S(Z(}Ti%mrm|ziD(6!C9r-s@Dw}}1|7*=zB>q2i zA+5Hd)KKwpjJrnViu`xqM~;-UxddJ-cn#GylwAK|Lv7p0$o`eV1{__`o-seWy3mHY zB*r?a38jb2*GlnsQX@h=7Lv5O(-6VtflxO@^7eAHUV>$Z9`dE&t<2i;-_.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 50, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 50.0, + 0.0 + ] + }, + "end": { + "at": [ + 50, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 50.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "fillet", + "name": "VerticalFillet", + "type": "constant_radius", + "radius": 8, + "tangent_chain": false, + "edge_selection": "the 4 vertical edges", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 40.0, + 0.0 + ], + "end": [ + 0.0, + 40.0, + 30.0 + ], + "point": [ + 0.0, + 40.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 50.0, + 40.0, + 0.0 + ], + "end": [ + 50.0, + 40.0, + 30.0 + ], + "point": [ + 50.0, + 40.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 50.0, + 0.0, + 0.0 + ], + "end": [ + 50.0, + 0.0, + 30.0 + ], + "point": [ + 50.0, + 0.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + 0.0, + 0.0, + 15.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "TopFillet", + "type": "constant_radius", + "radius": 4, + "tangent_chain": true, + "edge_selection": "one edge of the top face + tangent chain (whole top loop)", + "edges": [ + { + "type": "arc", + "start": [ + 8.0, + 0.0, + 30.0 + ], + "end": [ + 0.0, + 8.0, + 30.0 + ], + "center": [ + 8.0, + 8.0, + 30.0 + ], + "axis": [ + -0.0, + -0.0, + -1.0 + ], + "point": [ + 2.343145751, + 2.343145751, + 30.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/36-corner-blend-two-radii/reference.stl b/tests/oracle/36-corner-blend-two-radii/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..9d2b147c03bead08c841791eb663a5229e369fb0 GIT binary patch literal 211884 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.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -20, + -20 + ] + }, + "end": { + "at": [ + 20, + -20 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 20.0, + -20.0 + ] + }, + "end": { + "at": [ + 20, + 20 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 20.0, + 20.0 + ] + }, + "end": { + "at": [ + -20, + 20 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -20.0, + 20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -20.0, + -20.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "construction_plane", + "name": "Apex30", + "method": "offset", + "base": "XY", + "offset": 30 + }, + { + "op": "sketch", + "name": "Apex", + "plane": { + "ref": "construction plane Apex30 (XY offset 30)", + "origin": [ + 0.0, + 0.0, + 30.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "point", + "at": [ + 0, + 0 + ], + "fixed": false, + "id": "p1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "loft", + "name": "Loft1", + "operation": "new", + "sections": [ + { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + { + "sketch": "Apex", + "point": "p1", + "world": [ + 0, + 0, + 30 + ] + } + ], + "end_conditions": "free", + "solid": true, + "result_bodies": [ + "Pyramid" + ] + }, + { + "op": "fillet", + "name": "Fillet1", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "all 8 edges of the pyramid", + "edges": [ + { + "type": "line", + "start": [ + -20.0, + 20.0, + 0.0 + ], + "end": [ + -20.0, + -20.0, + 0.0 + ], + "point": [ + -20.0, + 0.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 20.0, + 20.0, + 0.0 + ], + "end": [ + -20.0, + 20.0, + 0.0 + ], + "point": [ + 0.0, + 20.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + 20.0, + -20.0, + 0.0 + ], + "end": [ + 20.0, + 20.0, + 0.0 + ], + "point": [ + 20.0, + 0.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + -20.0, + -20.0, + 0.0 + ], + "end": [ + 20.0, + -20.0, + 0.0 + ], + "point": [ + 0.0, + -20.0, + 0.0 + ] + }, + { + "type": "line", + "start": [ + -20.0, + -20.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + -10.0, + -10.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + -20.0, + 20.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + -10.0, + 10.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 20.0, + -20.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + 10.0, + -10.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 20.0, + 20.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + 10.0, + 10.0, + 15.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/37-pyramid-apex-blend/reference.stl b/tests/oracle/37-pyramid-apex-blend/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..bf2740d4de9fdf5df821ec99935ab1a4567f612a GIT binary patch literal 267784 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 kg^e#|Y)+gvzU%3a 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⋘ra_h*M9(oB{I#EAW*>rt}YoSgS(C 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 literal 0 HcmV?d00001 diff --git a/tests/oracle/38-coincident-cylinders/expected.json b/tests/oracle/38-coincident-cylinders/expected.json new file mode 100644 index 00000000..bdddcc63 --- /dev/null +++ b/tests/oracle/38-coincident-cylinders/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "union of r10 z0..30 and r10 z20..50 = cylinder r10 h50: V = pi r^2 h, A = 2 pi r h + 2 pi r^2", + "body_count": 1, + "volume_mm3": 15707.963267948966, + "area_mm2": 3769.9111843077517, + "center_of_mass": [ + 0.0, + 0.0, + 25.0 + ], + "bbox": { + "min": [ + -10.0, + -10.0, + 0.0 + ], + "max": [ + 10.0, + 10.0, + 50.0 + ] + }, + "faces": 3 +} diff --git a/tests/oracle/38-coincident-cylinders/recipe.json b/tests/oracle/38-coincident-cylinders/recipe.json new file mode 100644 index 00000000..659e104b --- /dev/null +++ b/tests/oracle/38-coincident-cylinders/recipe.json @@ -0,0 +1,179 @@ +{ + "id": "38-coincident-cylinders", + "name": "Union of coaxial equal cylinders", + "description": "Cylinder r10 z 0..30 and cylinder r10 z 20..50 (coincident cylindrical faces), combine join.", + "exercises": [ + "combine_join", + "coincident_faces", + "offset_plane" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "S1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 10, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "CylA", + "operation": "new", + "profiles": [ + { + "sketch": "S1", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "A" + ] + }, + { + "op": "construction_plane", + "name": "Z20", + "method": "offset", + "base": "XY", + "offset": 20 + }, + { + "op": "sketch", + "name": "S2", + "plane": { + "ref": "construction plane Z20", + "origin": [ + 0.0, + 0.0, + 20.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 10, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "CylB", + "operation": "new", + "profiles": [ + { + "sketch": "S2", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "B" + ] + }, + { + "op": "combine", + "name": "Combine1", + "operation": "join", + "target_body": "A", + "tool_bodies": [ + "B" + ], + "keep_tools": false + } + ] +} diff --git a/tests/oracle/39-tee-pipe/expected.json b/tests/oracle/39-tee-pipe/expected.json new file mode 100644 index 00000000..7ebd702c --- /dev/null +++ b/tests/oracle/39-tee-pipe/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part extrude cut", + "body_count": 1, + "volume_mm3": 24097.79380441197, + "area_mm2": 16710.06166887699, + "center_of_mass": [ + 4.75919240426363e-06, + -3.866233490238524e-07, + 4.436155001585041 + ], + "bbox": { + "min": [ + -40.0000001, + -15.0000001, + -15.0000001 + ], + "max": [ + 40.0000001, + 15.0000001, + 40.0000001 + ] + } +} diff --git a/tests/oracle/39-tee-pipe/recipe.json b/tests/oracle/39-tee-pipe/recipe.json new file mode 100644 index 00000000..ed664457 --- /dev/null +++ b/tests/oracle/39-tee-pipe/recipe.json @@ -0,0 +1,302 @@ +{ + "id": "39-tee-pipe", + "name": "Tee pipe (cylinder through cylinder)", + "description": "Main pipe OD30/ID24 along X (x -40..40); branch OD20/ID14 along +Z to z=40; outer join then bores cut.", + "exercises": [ + "sketch_yz", + "symmetric", + "extrude_join", + "extrude_cut", + "cylinder_cylinder" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "MainOuter", + "plane": { + "ref": "YZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 15, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "MainOuter", + "operation": "new", + "profiles": [ + { + "sketch": "MainOuter", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 40, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Tee" + ] + }, + { + "op": "sketch", + "name": "BranchOuter", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 10, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "BranchOuter", + "operation": "join", + "profiles": [ + { + "sketch": "BranchOuter", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 40, + "direction": "positive" + }, + "result_bodies": [ + "Tee" + ] + }, + { + "op": "sketch", + "name": "MainBore", + "plane": { + "ref": "YZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 12, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "MainBore", + "operation": "cut", + "profiles": [ + { + "sketch": "MainBore", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 40, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Tee" + ] + }, + { + "op": "sketch", + "name": "BranchBore", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 7, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "BranchBore", + "operation": "cut", + "profiles": [ + { + "sketch": "BranchBore", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 40, + "direction": "positive" + }, + "result_bodies": [ + "Tee" + ] + } + ] +} diff --git a/tests/oracle/39-tee-pipe/reference.stl b/tests/oracle/39-tee-pipe/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..d86e1765e536bdd2e92d97263545221f85042f8e GIT binary patch literal 120384 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.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Box_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -30, + -30 + ] + }, + "end": { + "at": [ + 30, + -30 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 30.0, + -30.0 + ] + }, + "end": { + "at": [ + 30, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 30.0, + 30.0 + ] + }, + "end": { + "at": [ + -30, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -30.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -30.0, + -30.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Box", + "operation": "new", + "profiles": [ + { + "sketch": "Box_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "negative" + }, + "result_bodies": [ + "A" + ] + }, + { + "op": "sketch", + "name": "Sphere_sketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "arc_three_point", + "start": { + "at": [ + 0.0, + 12.0 + ] + }, + "mid": [ + 12.0, + 0.0 + ], + "end": { + "at": [ + 0.0, + -12.0 + ] + }, + "id": "a1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 0.0, + -12.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 0.0, + 12.0 + ] + }, + "id": "l1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "Sphere", + "operation": "new", + "profile": { + "sketch": "Sphere_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "l1" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "S" + ] + }, + { + "op": "combine", + "name": "JoinSphere", + "operation": "join", + "target_body": "A", + "tool_bodies": [ + "S" + ], + "keep_tools": false + }, + { + "op": "sketch", + "name": "TorusSketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 22.0, + 0.0 + ] + }, + "radius": 4, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "Torus", + "operation": "new", + "profile": { + "sketch": "TorusSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "T" + ] + }, + { + "op": "combine", + "name": "CutTorus", + "operation": "cut", + "target_body": "A", + "tool_bodies": [ + "T" + ], + "keep_tools": false + } + ] +} diff --git a/tests/oracle/41-tube-radial-holes/expected.json b/tests/oracle/41-tube-radial-holes/expected.json new file mode 100644 index 00000000..605c5af0 --- /dev/null +++ b/tests/oracle/41-tube-radial-holes/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, pattern (tools transformed and re-applied)", + "body_count": 1, + "volume_mm3": 20243.55643647215, + "area_mm2": 14873.859284949844, + "center_of_mass": [ + -9.45514125510865e-05, + -0.00016121064416442976, + 29.9999903705421 + ], + "bbox": { + "min": [ + -20.0000001, + -20.000000101011352, + -1e-07 + ], + "max": [ + 20.0000001, + 20.000000101011356, + 60.0000001 + ] + } +} diff --git a/tests/oracle/41-tube-radial-holes/recipe.json b/tests/oracle/41-tube-radial-holes/recipe.json new file mode 100644 index 00000000..026e5d07 --- /dev/null +++ b/tests/oracle/41-tube-radial-holes/recipe.json @@ -0,0 +1,252 @@ +{ + "id": "41-tube-radial-holes", + "name": "Many small holes in a curved wall", + "description": "Tube OD40/ID34 length 60; three d4 radial holes along Y (z=15,30,45) cut symmetric through both walls; circular pattern x3 over 120 deg -> 18 holes.", + "exercises": [ + "annulus_profile", + "sketch_xz", + "symmetric", + "extrude_cut", + "circular_pattern", + "holes_in_cylinder" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "TubeSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 20, + "id": "c_out" + }, + { + "type": "circle", + "center": { + "ref": "c_out.center", + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 17, + "id": "c_in" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Tube", + "operation": "new", + "profiles": [ + { + "sketch": "TubeSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c_out" + ] + }, + { + "outer": false, + "curves": [ + "c_in" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 60, + "direction": "positive" + }, + "result_bodies": [ + "Tube" + ] + }, + { + "op": "sketch", + "name": "HoleSketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0.0, + -15.0 + ] + }, + "radius": 2, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 0.0, + -30.0 + ] + }, + "radius": 2, + "id": "c2" + }, + { + "type": "circle", + "center": { + "at": [ + 0.0, + -45.0 + ] + }, + "radius": 2, + "id": "c3" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Holes", + "operation": "cut", + "profiles": [ + { + "sketch": "HoleSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + { + "sketch": "HoleSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c2" + ] + } + ] + }, + { + "sketch": "HoleSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c3" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 25, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Tube" + ] + }, + { + "op": "circular_pattern", + "name": "HolePattern", + "pattern_of": "features", + "features": [ + "Holes" + ], + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "count": 3, + "total_angle": 120, + "symmetric": false + } + ] +} diff --git a/tests/oracle/41-tube-radial-holes/reference.stl b/tests/oracle/41-tube-radial-holes/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..a1213132c0a3c34b5e9cb7ee5eb6462605901928 GIT binary patch literal 339484 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

&nwjqKlC4s$CwrDllCC^K_>VW@;p3c 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.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -50, + -50 + ] + }, + "end": { + "at": [ + 50, + -50 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 50.0, + -50.0 + ] + }, + "end": { + "at": [ + 50, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 50.0, + 50.0 + ] + }, + "end": { + "at": [ + -50, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -50.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -50.0, + -50.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "sketch", + "name": "HoleA", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + -30, + -30 + ] + }, + "radius": 5, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "HoleA", + "operation": "cut", + "profiles": [ + { + "sketch": "HoleA", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "rectangular_pattern", + "name": "GridPattern", + "pattern_of": "features", + "features": [ + "HoleA (1)" + ], + "direction1": { + "axis": [ + 1, + 0, + 0 + ], + "count": 5, + "spacing": 15 + }, + "distance_type": "spacing (distance between instances)", + "direction2": { + "axis": [ + 0, + 1, + 0 + ], + "count": 5, + "spacing": 15 + } + }, + { + "op": "sketch", + "name": "HoleB", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 25, + 0 + ] + }, + "radius": 5, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "HoleB", + "operation": "cut", + "profiles": [ + { + "sketch": "HoleB", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "circular_pattern", + "name": "RingPattern", + "pattern_of": "features", + "features": [ + "HoleB (1)" + ], + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "count": 8, + "total_angle": 360, + "symmetric": false + } + ] +} diff --git a/tests/oracle/42-overlapping-patterns/reference.stl b/tests/oracle/42-overlapping-patterns/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..12002cb1827095bf36488ac90a8ca25d13914de5 GIT binary patch literal 393484 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 TLp7{j=0l^JkY_oAw;=u>X$9WB literal 0 HcmV?d00001 diff --git a/tests/oracle/43-cut-splits-body/expected.json b/tests/oracle/43-cut-splits-body/expected.json new file mode 100644 index 00000000..5b108371 --- /dev/null +++ b/tests/oracle/43-cut-splits-body/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "two boxes 35x20x20 (x 0..35 and 45..80): V = 2abc, A = 2*2(ab+bc+ca)", + "body_count": 2, + "volume_mm3": 28000, + "area_mm2": 7200, + "center_of_mass": [ + 40.0, + 10.0, + 10.0 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 20.0, + 20.0 + ] + }, + "faces": 12 +} diff --git a/tests/oracle/43-cut-splits-body/recipe.json b/tests/oracle/43-cut-splits-body/recipe.json new file mode 100644 index 00000000..97c01258 --- /dev/null +++ b/tests/oracle/43-cut-splits-body/recipe.json @@ -0,0 +1,282 @@ +{ + "id": "43-cut-splits-body", + "name": "Cut that splits a body in two", + "description": "80x20x20 box; rectangle x 35..45 (wider than the box in Y) cut through all -> two separate bodies.", + "exercises": [ + "extrude_cut", + "through_all", + "multi_body_result" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 20 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 20.0 + ] + }, + "end": { + "at": [ + 0, + 20 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 20.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Bar" + ] + }, + { + "op": "sketch", + "name": "CutSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 35, + -5 + ] + }, + "end": { + "at": [ + 45, + -5 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 45.0, + -5.0 + ] + }, + "end": { + "at": [ + 45, + 25 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 45.0, + 25.0 + ] + }, + "end": { + "at": [ + 35, + 25 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 35.0, + 25.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 35.0, + -5.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Cut1", + "operation": "cut", + "profiles": [ + { + "sketch": "CutSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Bar", + "Bar (1)" + ] + } + ] +} diff --git a/tests/oracle/44-shell-l-bracket/expected.json b/tests/oracle/44-shell-l-bracket/expected.json new file mode 100644 index 00000000..f09ec972 --- /dev/null +++ b/tests/oracle/44-shell-l-bracket/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "L prism (area 736, perimeter 200) x 20 minus cavity = L shrunk by 2 (SolidCraft's intersection-join shell convention: inner faces offset by 2 and extended to meet, sharp inner corner at (6,6); area 352) from z=2 to 20. A rounded (arc) join would give V 8368.5487, A 8768.5487, 16 faces", + "body_count": 1, + "volume_mm3": 8384.000000000004, + "area_mm2": 8784.000000000004, + "center_of_mass": [ + 21.26717557251906, + 11.267175572519093, + 9.244274809160306 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 60.0, + 40.0, + 20.0 + ] + }, + "faces": 15 +} diff --git a/tests/oracle/44-shell-l-bracket/recipe.json b/tests/oracle/44-shell-l-bracket/recipe.json new file mode 100644 index 00000000..ab32a6a2 --- /dev/null +++ b/tests/oracle/44-shell-l-bracket/recipe.json @@ -0,0 +1,217 @@ +{ + "id": "44-shell-l-bracket", + "name": "Shelled L block", + "description": "L profile extruded 20, shelled 2 mm inward with the top face (z=20) removed - non-convex shell.", + "exercises": [ + "shell", + "non_convex" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "LSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 60, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 60.0, + 0.0 + ] + }, + "end": { + "at": [ + 60, + 8 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 60.0, + 8.0 + ] + }, + "end": { + "at": [ + 8, + 8 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 8.0, + 8.0 + ] + }, + "end": { + "at": [ + 8, + 40 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 8.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l6" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "LSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4", + "l5", + "l6" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "L" + ] + }, + { + "op": "shell", + "name": "Shell1", + "faces_removed": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 30.0, + 4.0, + 20.0 + ] + } + ], + "face_selection": "top face (z=20)", + "inside_thickness": 2, + "outside_thickness": 0, + "tangent_chain": false + } + ] +} diff --git a/tests/oracle/45-shell-boss-plate/expected.json b/tests/oracle/45-shell-boss-plate/expected.json new file mode 100644 index 00000000..37c5dbee --- /dev/null +++ b/tests/oracle/45-shell-boss-plate/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "plate 60x60x10 + boss r12 h20 minus cavity (box 56x56x8 + cylinder r10 z8..28) under SolidCraft's intersection-join shell convention (offset faces extended to meet: sharp circular inner edge at r10, z8). A rounded (arc) join would give V 13620.2567, A 14104.4455, 16 faces (torus round r2)", + "body_count": 1, + "volume_mm3": 13676.601535159018, + "area_mm2": 14156.601535159018, + "center_of_mass": [ + 0.0, + 0.0, + 10.785311024697076 + ], + "bbox": { + "min": [ + -30.0, + -30.0, + 0.0 + ], + "max": [ + 30.0, + 30.0, + 30.0 + ] + }, + "faces": 15 +} diff --git a/tests/oracle/45-shell-boss-plate/recipe.json b/tests/oracle/45-shell-boss-plate/recipe.json new file mode 100644 index 00000000..86509f25 --- /dev/null +++ b/tests/oracle/45-shell-boss-plate/recipe.json @@ -0,0 +1,268 @@ +{ + "id": "45-shell-boss-plate", + "name": "Shelled boss-on-plate", + "description": "60x60x10 plate + d24 boss 20 tall, shelled 2 mm with the bottom face removed (hollow from below).", + "exercises": [ + "extrude_join", + "shell", + "non_convex" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -30, + -30 + ] + }, + "end": { + "at": [ + 30, + -30 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 30.0, + -30.0 + ] + }, + "end": { + "at": [ + 30, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 30.0, + 30.0 + ] + }, + "end": { + "at": [ + -30, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -30.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -30.0, + -30.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Part" + ] + }, + { + "op": "sketch", + "name": "BossSketch", + "plane": { + "ref": "face: top of plate (z=10)", + "origin": [ + 0.0, + 0.0, + 10.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 0.0, + 0.0, + 10.0 + ] + } + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0.0, + 0.0 + ] + }, + "radius": 12, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Boss", + "operation": "join", + "profiles": [ + { + "sketch": "BossSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "positive" + }, + "result_bodies": [ + "Part" + ] + }, + { + "op": "shell", + "name": "Shell1", + "faces_removed": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + -1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 0.0, + 0.0, + 0.0 + ] + } + ], + "face_selection": "bottom face (z=0)", + "inside_thickness": 2, + "outside_thickness": 0, + "tangent_chain": false + } + ] +} diff --git a/tests/oracle/46-shell-two-open-faces/expected.json b/tests/oracle/46-shell-two-open-faces/expected.json new file mode 100644 index 00000000..e34e75b0 --- /dev/null +++ b/tests/oracle/46-shell-two-open-faces/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "box 50x40x30 minus cavity x3..47, y0..37, z3..30 (3 mm walls, top and front open)", + "body_count": 1, + "volume_mm3": 16044, + "area_mm2": 11398, + "center_of_mass": [ + 25.0, + 24.1095736724009, + 10.890426327599103 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 50.0, + 40.0, + 30.0 + ] + }, + "faces": 10 +} diff --git a/tests/oracle/46-shell-two-open-faces/recipe.json b/tests/oracle/46-shell-two-open-faces/recipe.json new file mode 100644 index 00000000..f10dbda4 --- /dev/null +++ b/tests/oracle/46-shell-two-open-faces/recipe.json @@ -0,0 +1,199 @@ +{ + "id": "46-shell-two-open-faces", + "name": "Shell with two open faces", + "description": "50x40x30 box shelled 3 mm with top (z=30) and front (y=0) faces removed.", + "exercises": [ + "shell", + "multi_face_shell" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Extrude1_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 50, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 50.0, + 0.0 + ] + }, + "end": { + "at": [ + 50, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 50.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Extrude1_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "Box" + ] + }, + { + "op": "shell", + "name": "Shell1", + "faces_removed": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 25.0, + 20.0, + 30.0 + ] + }, + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + -1.0, + 0.0 + ], + "plane_normal_outward": [ + 0.0, + -1.0, + 0.0 + ], + "point": [ + 25.0, + 0.0, + 15.0 + ] + } + ], + "face_selection": "top face (z=30) and front face (y=0)", + "inside_thickness": 3, + "outside_thickness": 0, + "tangent_chain": false + } + ] +} diff --git a/tests/oracle/47-draft-curved-pocket/expected.json b/tests/oracle/47-draft-curved-pocket/expected.json new file mode 100644 index 00000000..17698d26 --- /dev/null +++ b/tests/oracle/47-draft-curved-pocket/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude cut, PartDesign Draft", + "body_count": 1, + "volume_mm3": 111387.71155072484, + "area_mm2": 17700.360856055668, + "center_of_mass": [ + 40.00000000000002, + 30.000000000000004, + 11.912254219746519 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 60.0, + 25.0 + ] + } +} diff --git a/tests/oracle/47-draft-curved-pocket/recipe.json b/tests/oracle/47-draft-curved-pocket/recipe.json new file mode 100644 index 00000000..b3dc02dc --- /dev/null +++ b/tests/oracle/47-draft-curved-pocket/recipe.json @@ -0,0 +1,413 @@ +{ + "id": "47-draft-curved-pocket", + "name": "Draft on an obround pocket", + "description": "80x60x25 block; obround pocket (centres (25,30),(55,30), R10) cut 10 deep from the top; 5 deg draft on the 4 pocket walls (2 planes + 2 half-cylinders), neutral plane = top face.", + "exercises": [ + "extrude_cut", + "draft", + "draft_curved" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Block_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Block", + "operation": "new", + "profiles": [ + { + "sketch": "Block_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 25, + "direction": "positive" + }, + "result_bodies": [ + "Block" + ] + }, + { + "op": "sketch", + "name": "PocketSketch", + "plane": { + "ref": "face: top of block (z=25)", + "origin": [ + 0.0, + 0.0, + 25.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 40.0, + 30.0, + 25.0 + ] + } + }, + "entities": [ + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + 25.0, + 30.0 + ] + }, + "start": { + "at": [ + 25.0, + 40.0 + ] + }, + "sweep_deg": 180, + "id": "a1" + }, + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + 55.0, + 30.0 + ] + }, + "start": { + "at": [ + 55.0, + 20.0 + ] + }, + "sweep_deg": 180, + "id": "a2" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 25.0, + 20.0 + ] + }, + "end": { + "ref": "a2.start", + "at": [ + 55.0, + 20.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "a2.end", + "at": [ + 55.0, + 40.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 25.0, + 40.0 + ] + }, + "id": "l2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Pocket", + "operation": "cut", + "profiles": [ + { + "sketch": "PocketSketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "a2", + "l1", + "l2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "negative" + }, + "result_bodies": [ + "Block" + ] + }, + { + "op": "draft", + "name": "Draft1", + "faces": [ + { + "type": "cylinder", + "normal_at_point_on_face": [ + 1.0, + -0.0, + 0.0 + ], + "axis_origin": [ + 25.0, + 30.0, + 25.0 + ], + "axis": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 15.0, + 30.0, + 20.0 + ] + }, + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 1.0, + 0.0 + ], + "plane_normal_outward": [ + 0.0, + 1.0, + 0.0 + ], + "point": [ + 40.0, + 20.0, + 20.0 + ] + }, + { + "type": "cylinder", + "normal_at_point_on_face": [ + -1.0, + 0.0, + 0.0 + ], + "axis_origin": [ + 55.0, + 30.0, + 25.0 + ], + "axis": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 65.0, + 30.0, + 20.0 + ] + }, + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + -1.0, + 0.0 + ], + "plane_normal_outward": [ + 0.0, + -1.0, + 0.0 + ], + "point": [ + 40.0, + 40.0, + 20.0 + ] + } + ], + "face_selection": "the 4 pocket wall faces", + "neutral_plane": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 40.0, + 50.0, + 25.0 + ] + }, + "neutral_selection": "top face (z=25)", + "angle": 5, + "flipped": false, + "tangent_chain": false + } + ] +} diff --git a/tests/oracle/47-draft-curved-pocket/reference.stl b/tests/oracle/47-draft-curved-pocket/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..e33f8d8a998f2f1be0458908000412d4d6c01672 GIT binary patch literal 87684 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 Chk2s_ literal 0 HcmV?d00001 diff --git a/tests/oracle/48-pulley/expected.json b/tests/oracle/48-pulley/expected.json new file mode 100644 index 00000000..d3f2ffd5 --- /dev/null +++ b/tests/oracle/48-pulley/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "revolve of the 12-segment (r,z) polygon about Z: V = 2 pi int r dA, Mz = 2 pi int r z dA, A = 2 pi int r ds (Pappus)", + "body_count": 1, + "volume_mm3": 168510.84114835176, + "area_mm2": 23718.644332702832, + "center_of_mass": [ + 0.0, + 0.0, + 19.999999999999996 + ], + "bbox": { + "min": [ + -40.0, + -40.0, + 0.0 + ], + "max": [ + 40.0, + 40.0, + 40.0 + ] + }, + "faces": 12 +} diff --git a/tests/oracle/48-pulley/recipe.json b/tests/oracle/48-pulley/recipe.json new file mode 100644 index 00000000..6c5241e2 --- /dev/null +++ b/tests/oracle/48-pulley/recipe.json @@ -0,0 +1,304 @@ +{ + "id": "48-pulley", + "name": "Grooved pulley", + "description": "Revolved profile with a d10 bore and two trapezoidal V-grooves, about Z.", + "exercises": [ + "revolve", + "sketch_xz" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Profile", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 5.0, + 0.0 + ] + }, + "end": { + "at": [ + 40.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40.0, + -3.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + -3.0 + ] + }, + "end": { + "at": [ + 33.0, + -8.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 33.0, + -8.0 + ] + }, + "end": { + "at": [ + 33.0, + -12.0 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 33.0, + -12.0 + ] + }, + "end": { + "at": [ + 40.0, + -17.0 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + 40.0, + -17.0 + ] + }, + "end": { + "at": [ + 40.0, + -23.0 + ] + }, + "id": "l6" + }, + { + "type": "line", + "start": { + "ref": "l6.end", + "at": [ + 40.0, + -23.0 + ] + }, + "end": { + "at": [ + 33.0, + -28.0 + ] + }, + "id": "l7" + }, + { + "type": "line", + "start": { + "ref": "l7.end", + "at": [ + 33.0, + -28.0 + ] + }, + "end": { + "at": [ + 33.0, + -32.0 + ] + }, + "id": "l8" + }, + { + "type": "line", + "start": { + "ref": "l8.end", + "at": [ + 33.0, + -32.0 + ] + }, + "end": { + "at": [ + 40.0, + -37.0 + ] + }, + "id": "l9" + }, + { + "type": "line", + "start": { + "ref": "l9.end", + "at": [ + 40.0, + -37.0 + ] + }, + "end": { + "at": [ + 40.0, + -40.0 + ] + }, + "id": "l10" + }, + { + "type": "line", + "start": { + "ref": "l10.end", + "at": [ + 40.0, + -40.0 + ] + }, + "end": { + "at": [ + 5.0, + -40.0 + ] + }, + "id": "l11" + }, + { + "type": "line", + "start": { + "ref": "l11.end", + "at": [ + 5.0, + -40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 5.0, + 0.0 + ] + }, + "id": "l12" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "Revolve1", + "operation": "new", + "profile": { + "sketch": "Profile", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l10", + "l11", + "l12", + "l2", + "l3", + "l4", + "l5", + "l6", + "l7", + "l8", + "l9" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "Pulley" + ] + } + ] +} diff --git a/tests/oracle/49-helical-sweep/expected.json b/tests/oracle/49-helical-sweep/expected.json new file mode 100644 index 00000000..f7f54c8b --- /dev/null +++ b/tests/oracle/49-helical-sweep/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "true helix coil (screw motion of the axial d4 section, R20, pitch 8, 3 turns): V = turns * 2 pi R * pi a^2; lateral A = turns * 2 pi * int sqrt(r^2 + (p/2pi)^2 (dr/ds)^2) ds (periodic trapezoid, exact to round-off) + two end discs; COM z = pitch*turns/2", + "body_count": 1, + "volume_mm3": 4737.410112522892, + "area_mm2": 4767.351236008563, + "center_of_mass": [ + 0.0, + 0.0, + 12.0 + ], + "bbox": { + "min": [ + -22.0, + -22.0, + -2.0 + ], + "max": [ + 22.0, + 22.0, + 26.0 + ] + }, + "faces": 3 +} diff --git a/tests/oracle/49-helical-sweep/recipe.json b/tests/oracle/49-helical-sweep/recipe.json new file mode 100644 index 00000000..132cb867 --- /dev/null +++ b/tests/oracle/49-helical-sweep/recipe.json @@ -0,0 +1,317 @@ +{ + "id": "49-helical-sweep", + "name": "Helical sweep (spline helix)", + "description": "d4 circle swept along a 3-turn helix (R20, pitch 8) given as a fitted 3D spline through 12 points per turn; replayed as the true helix.", + "exercises": [ + "sweep", + "spline_3d", + "helix" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Helix", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "fitted_spline", + "fit_points": [ + [ + 20.0, + 0.0, + 0.0 + ], + [ + 17.320508076, + 10.0, + 0.666666667 + ], + [ + 10.0, + 17.320508076, + 1.333333333 + ], + [ + 0.0, + 20.0, + 2.0 + ], + [ + -10.0, + 17.320508076, + 2.666666667 + ], + [ + -17.320508076, + 10.0, + 3.333333333 + ], + [ + -20.0, + 0.0, + 4.0 + ], + [ + -17.320508076, + -10.0, + 4.666666667 + ], + [ + -10.0, + -17.320508076, + 5.333333333 + ], + [ + -0.0, + -20.0, + 6.0 + ], + [ + 10.0, + -17.320508076, + 6.666666667 + ], + [ + 17.320508076, + -10.0, + 7.333333333 + ], + [ + 20.0, + -0.0, + 8.0 + ], + [ + 17.320508076, + 10.0, + 8.666666667 + ], + [ + 10.0, + 17.320508076, + 9.333333333 + ], + [ + 0.0, + 20.0, + 10.0 + ], + [ + -10.0, + 17.320508076, + 10.666666667 + ], + [ + -17.320508076, + 10.0, + 11.333333333 + ], + [ + -20.0, + 0.0, + 12.0 + ], + [ + -17.320508076, + -10.0, + 12.666666667 + ], + [ + -10.0, + -17.320508076, + 13.333333333 + ], + [ + -0.0, + -20.0, + 14.0 + ], + [ + 10.0, + -17.320508076, + 14.666666667 + ], + [ + 17.320508076, + -10.0, + 15.333333333 + ], + [ + 20.0, + -0.0, + 16.0 + ], + [ + 17.320508076, + 10.0, + 16.666666667 + ], + [ + 10.0, + 17.320508076, + 17.333333333 + ], + [ + 0.0, + 20.0, + 18.0 + ], + [ + -10.0, + 17.320508076, + 18.666666667 + ], + [ + -17.320508076, + 10.0, + 19.333333333 + ], + [ + -20.0, + 0.0, + 20.0 + ], + [ + -17.320508076, + -10.0, + 20.666666667 + ], + [ + -10.0, + -17.320508076, + 21.333333333 + ], + [ + -0.0, + -20.0, + 22.0 + ], + [ + 10.0, + -17.320508076, + 22.666666667 + ], + [ + 17.320508076, + -10.0, + 23.333333333 + ], + [ + 20.0, + -0.0, + 24.0 + ] + ], + "id": "h1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sketch", + "name": "ProfileSketch", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 20.0, + 0.0 + ] + }, + "radius": 2, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sweep", + "name": "Sweep1", + "operation": "new", + "profile": { + "sketch": "ProfileSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + "path": { + "sketch": "Helix", + "curves": [ + "h1" + ], + "chained": false + }, + "orientation": "perpendicular", + "result_bodies": [ + "Spring" + ] + } + ] +} diff --git a/tests/oracle/50-sweep-tight-bend/expected.json b/tests/oracle/50-sweep-tight-bend/expected.json new file mode 100644 index 00000000..49896543 --- /dev/null +++ b/tests/oracle/50-sweep-tight-bend/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "tube r5 along line 20 + R5 quarter bend + line 20: V = pi r^2 L, A = 2 pi r L + 2 pi r^2 (Pappus, valid while bend radius >= r; here equal so the inner side pinches to a line); bend centroid at (R^2 + r^2/4)/R * sinc(pi/4) along the bisector", + "body_count": 1, + "volume_mm3": 3758.4429286578784, + "area_mm2": 1660.4568041426407, + "center_of_mass": [ + 6.436662063480004, + 0.0, + 18.563337936519996 + ], + "bbox": { + "min": [ + -5.0, + -5.0, + 0.0 + ], + "max": [ + 25.0, + 5.0, + 30.0 + ] + }, + "faces": 5 +} diff --git a/tests/oracle/50-sweep-tight-bend/recipe.json b/tests/oracle/50-sweep-tight-bend/recipe.json new file mode 100644 index 00000000..deae0ec9 --- /dev/null +++ b/tests/oracle/50-sweep-tight-bend/recipe.json @@ -0,0 +1,181 @@ +{ + "id": "50-sweep-tight-bend", + "name": "Sweep with a bend radius equal to the profile radius", + "description": "d10 circle on XY swept along: line up 20, R5 arc 90 deg, line 20 along +X - the inner side of the bend collapses to a line (self-touching).", + "exercises": [ + "sweep", + "degenerate" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Path", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 0.0, + -20.0 + ] + }, + "id": "l1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "l1.end", + "at": [ + 0.0, + -20.0 + ] + }, + "mid": [ + 1.464466094, + -23.535533906 + ], + "end": { + "at": [ + 5.0, + -25.0 + ] + }, + "id": "a1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 5.0, + -25.0 + ] + }, + "end": { + "at": [ + 25.0, + -25.0 + ] + }, + "id": "l2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sketch", + "name": "ProfileSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 5, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sweep", + "name": "Sweep1", + "operation": "new", + "profile": { + "sketch": "ProfileSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + "path": { + "sketch": "Path", + "curves": [ + "l1", + "a1", + "l2" + ], + "chained": true + }, + "orientation": "perpendicular", + "result_bodies": [ + "Bend" + ] + } + ] +} diff --git a/tests/oracle/51-loft-rect-circle-offset/expected.json b/tests/oracle/51-loft-rect-circle-offset/expected.json new file mode 100644 index 00000000..b5360ba0 --- /dev/null +++ b/tests/oracle/51-loft-rect-circle-offset/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part.makeLoft", + "body_count": 1, + "volume_mm3": 61133.11623557925, + "area_mm2": 9411.65454371453, + "center_of_mass": [ + 4.254944428543755, + 2.1274722141148166, + 21.274722141148143 + ], + "bbox": { + "min": [ + -30.0000001, + -15.0000001, + -1e-07 + ], + "max": [ + 30.0000001, + 20.0000001, + 50.00000010000001 + ] + } +} diff --git a/tests/oracle/51-loft-rect-circle-offset/recipe.json b/tests/oracle/51-loft-rect-circle-offset/recipe.json new file mode 100644 index 00000000..ee46b802 --- /dev/null +++ b/tests/oracle/51-loft-rect-circle-offset/recipe.json @@ -0,0 +1,211 @@ +{ + "id": "51-loft-rect-circle-offset", + "name": "Skewed loft rectangle to circle", + "description": "Loft from a 60x30 rectangle (XY, centred) to a d30 circle centred (10,5) on a plane 50 mm up.", + "exercises": [ + "loft", + "offset_plane", + "skewed" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Bottom", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + -30, + -15 + ] + }, + "end": { + "at": [ + 30, + -15 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 30.0, + -15.0 + ] + }, + "end": { + "at": [ + 30, + 15 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 30.0, + 15.0 + ] + }, + "end": { + "at": [ + -30, + 15 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + -30.0, + 15.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + -30.0, + -15.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "construction_plane", + "name": "Plane50", + "method": "offset", + "base": "XY", + "offset": 50 + }, + { + "op": "sketch", + "name": "Top", + "plane": { + "ref": "construction plane Plane50", + "origin": [ + 0.0, + 0.0, + 50.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 10, + 5 + ] + }, + "radius": 15, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "loft", + "name": "Loft1", + "operation": "new", + "sections": [ + { + "sketch": "Bottom", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + { + "sketch": "Top", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "end_conditions": "free", + "solid": true, + "result_bodies": [ + "Loft" + ] + } + ] +} diff --git a/tests/oracle/51-loft-rect-circle-offset/reference.stl b/tests/oracle/51-loft-rect-circle-offset/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..09dbb6dc6b81d891583ca828a022b3d2c0c51e33 GIT binary patch literal 310084 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%0DC6%EJm^C% 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 JMnXE3`UB*lh~EGJ literal 0 HcmV?d00001 diff --git a/tests/oracle/52-circular-pattern-fillet/expected.json b/tests/oracle/52-circular-pattern-fillet/expected.json new file mode 100644 index 00000000..d994f0ff --- /dev/null +++ b/tests/oracle/52-circular-pattern-fillet/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "disc r40 h8 + 6 x (boss r6 h10 with R2 concave base fillet as a solid of revolution, Pappus/Green on its (r,z) profile) at radius 28; disc top loses 6 discs r8", + "body_count": 1, + "volume_mm3": 47206.85017171979, + "area_mm2": 14142.17116758171, + "center_of_mass": [ + 3.8532318867475695e-17, + 5.394524641446597e-16, + 5.313317447963345 + ], + "bbox": { + "min": [ + -40.0, + -40.0, + 0.0 + ], + "max": [ + 40.0, + 40.0, + 18.0 + ] + }, + "faces": 21 +} diff --git a/tests/oracle/52-circular-pattern-fillet/recipe.json b/tests/oracle/52-circular-pattern-fillet/recipe.json new file mode 100644 index 00000000..ae62a9e5 --- /dev/null +++ b/tests/oracle/52-circular-pattern-fillet/recipe.json @@ -0,0 +1,244 @@ +{ + "id": "52-circular-pattern-fillet", + "name": "Circular pattern of boss + fillet", + "description": "Disc r40 h8; d12 boss 10 tall at (28,0) joined; boss base edge filleted R2; boss and fillet features circular-patterned x6 about Z.", + "exercises": [ + "extrude_join", + "fillet", + "circular_pattern", + "pattern_of_fillet" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Disc", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 40, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Disc", + "operation": "new", + "profiles": [ + { + "sketch": "Disc", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 8, + "direction": "positive" + }, + "result_bodies": [ + "Hub" + ] + }, + { + "op": "sketch", + "name": "BossSketch", + "plane": { + "ref": "face: top of disc (z=8)", + "origin": [ + 0.0, + 0.0, + 8.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 0.0, + 0.0, + 8.0 + ] + } + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 28.0, + 0.0 + ] + }, + "radius": 6, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Boss", + "operation": "join", + "profiles": [ + { + "sketch": "BossSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Hub" + ] + }, + { + "op": "fillet", + "name": "BossFillet", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "boss base circle r=6 at z=8", + "edges": [ + { + "type": "circle", + "start": [ + 22.0, + -0.0, + 8.0 + ], + "end": [ + 22.0, + -0.0, + 8.0 + ], + "center": [ + 28.0, + 0.0, + 8.0 + ], + "axis": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 34.0, + 0.0, + 8.0 + ] + } + ] + }, + { + "op": "circular_pattern", + "name": "BossPattern", + "pattern_of": "features", + "features": [ + "Boss", + "BossFillet" + ], + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "count": 6, + "total_angle": 360, + "symmetric": false + } + ] +} diff --git a/tests/oracle/53-path-pattern/expected.json b/tests/oracle/53-path-pattern/expected.json new file mode 100644 index 00000000..7fbc40dd --- /dev/null +++ b/tests/oracle/53-path-pattern/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "plate 120x60x5 minus 7 through holes d6 at arc lengths k*17.875031 along the arc through (100,15),(60,45),(20,15) (centre (60,10/3), R 125/3), translated copies", + "body_count": 1, + "volume_mm3": 35010.3983141192, + "area_mm2": 16463.89378290154, + "center_of_mass": [ + 60.00000001136545, + 29.96522867057171, + 2.5 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 120.0, + 60.0, + 5.0 + ] + }, + "faces": 13 +} diff --git a/tests/oracle/53-path-pattern/recipe.json b/tests/oracle/53-path-pattern/recipe.json new file mode 100644 index 00000000..85fabaef --- /dev/null +++ b/tests/oracle/53-path-pattern/recipe.json @@ -0,0 +1,260 @@ +{ + "id": "53-path-pattern", + "name": "Pattern along a path", + "description": "120x60x5 plate; d6 hole at (100,15) cut through; patterned 7x along a 3-point arc (100,15)-(60,45)-(20,15), evenly over the arc length.", + "exercises": [ + "path_pattern", + "extrude_cut" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 120, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 120.0, + 0.0 + ] + }, + "end": { + "at": [ + 120, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 120.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "sketch", + "name": "PathSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "arc_three_point", + "start": { + "at": [ + 100, + 15 + ] + }, + "mid": [ + 60, + 45 + ], + "end": { + "at": [ + 20, + 15 + ] + }, + "id": "a1" + }, + { + "type": "circle", + "center": { + "ref": "a1.start", + "at": [ + 100.0, + 15.0 + ] + }, + "radius": 3, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Hole1", + "operation": "cut", + "profiles": [ + { + "sketch": "PathSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "path_pattern", + "name": "PathPattern1", + "pattern_of": "features", + "features": [ + "Hole1" + ], + "path": { + "sketch": "PathSketch", + "curves": [ + "a1" + ] + }, + "count": 7, + "spacing": 17.875031, + "distance_type": "spacing (arc-length distance between consecutive instances), starting at the hole and running along the arc toward (20,15)", + "semantics": "instance k = feature translated by path(k*spacing) - path(0); path(0) is the path's start point, so the feature must sit at the path start", + "orientation": "identical (not rotated along the path)" + } + ] +} diff --git a/tests/oracle/54-mirror-body-fillets/expected.json b/tests/oracle/54-mirror-body-fillets/expected.json new file mode 100644 index 00000000..f867f11b --- /dev/null +++ b/tests/oracle/54-mirror-body-fillets/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "prism h10 of the 60x40 rectangle with four R5 corner rounds and two d8 holes at (+-15,20): V = A h, area = 2A + perimeter*h", + "body_count": 1, + "volume_mm3": 22780.08851424851, + "area_mm2": 6972.831792783061, + "center_of_mass": [ + -1.4178560266764932e-15, + 20.00000000000026, + 5.0 + ], + "bbox": { + "min": [ + -30.0, + 0.0, + 0.0 + ], + "max": [ + 30.0, + 40.0, + 10.0 + ] + }, + "faces": 12 +} diff --git a/tests/oracle/54-mirror-body-fillets/recipe.json b/tests/oracle/54-mirror-body-fillets/recipe.json new file mode 100644 index 00000000..e76e188a --- /dev/null +++ b/tests/oracle/54-mirror-body-fillets/recipe.json @@ -0,0 +1,289 @@ +{ + "id": "54-mirror-body-fillets", + "name": "Mirror a filleted body", + "description": "Half bracket x 0..30, y 0..40, h10 with the two x=30 vertical edges R5 and a d8 hole at (15,20); body mirrored across YZ and combined into one body.", + "exercises": [ + "fillet", + "mirror_body", + "mirror_combine" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Half_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 30, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 30.0, + 0.0 + ] + }, + "end": { + "at": [ + 30, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 30.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Half", + "operation": "new", + "profiles": [ + { + "sketch": "Half_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "fillet", + "name": "Fillet1", + "type": "constant_radius", + "radius": 5, + "tangent_chain": false, + "edge_selection": "the 2 vertical edges at x=30", + "edges": [ + { + "type": "line", + "start": [ + 30.0, + 40.0, + 0.0 + ], + "end": [ + 30.0, + 40.0, + 10.0 + ], + "point": [ + 30.0, + 40.0, + 5.0 + ] + }, + { + "type": "line", + "start": [ + 30.0, + 0.0, + 0.0 + ], + "end": [ + 30.0, + 0.0, + 10.0 + ], + "point": [ + 30.0, + 0.0, + 5.0 + ] + } + ] + }, + { + "op": "sketch", + "name": "HoleSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 15, + 20 + ] + }, + "radius": 4, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Hole1", + "operation": "cut", + "profiles": [ + { + "sketch": "HoleSketch", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Bracket" + ] + }, + { + "op": "mirror", + "name": "Mirror1", + "mirror_of": "bodies", + "bodies": [ + "Bracket" + ], + "plane": { + "ref": "YZ", + "origin": [ + 0, + 0, + 0 + ], + "normal": [ + 1, + 0, + 0 + ] + }, + "combine": true + } + ] +} diff --git a/tests/oracle/55-tapped-hole-cosmetic/expected.json b/tests/oracle/55-tapped-hole-cosmetic/expected.json new file mode 100644 index 00000000..6e71ad05 --- /dev/null +++ b/tests/oracle/55-tapped-hole-cosmetic/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "plate 40x30x15 minus d6.8 cylinder 12 deep (to the shoulder) and 118 deg drill point cone (h = r/tan59, V = pi r^2 h/3, lateral pi r * r/sin59); cosmetic thread adds no geometry", + "body_count": 1, + "volume_mm3": 17539.467413298902, + "area_mm2": 4762.405554138465, + "center_of_mass": [ + 20.0, + 15.0, + 7.469794810863136 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 40.0, + 30.0, + 15.0 + ] + }, + "faces": 8 +} diff --git a/tests/oracle/55-tapped-hole-cosmetic/recipe.json b/tests/oracle/55-tapped-hole-cosmetic/recipe.json new file mode 100644 index 00000000..2f2f0e2e --- /dev/null +++ b/tests/oracle/55-tapped-hole-cosmetic/recipe.json @@ -0,0 +1,219 @@ +{ + "id": "55-tapped-hole-cosmetic", + "name": "Tapped hole with cosmetic thread", + "description": "40x30x15 plate; d6.8 simple hole 12 deep (118 deg tip) at (20,15); cosmetic ISO M8x1.25 6H thread on the hole wall, full length.", + "exercises": [ + "hole_blind", + "thread_cosmetic" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 15, + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "hole", + "name": "TapDrill", + "hole_type": "simple", + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 20.0, + 15.0, + 15.0 + ] + }, + "position": [ + 20, + 15, + 15 + ], + "direction": "into the material (-Z)", + "diameter": 6.8, + "depth": 12, + "tip_angle": 118, + "extent": "distance" + }, + { + "op": "thread", + "name": "Thread1", + "face": { + "type": "cylinder", + "normal_at_point_on_face": [ + -0.0, + 1.0, + 0.0 + ], + "axis_origin": [ + 20.0, + 15.0, + 9.0 + ], + "axis": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 20.0, + 11.61025, + 9.0 + ] + }, + "modeled": false, + "full_length": true, + "internal": true, + "thread_type": "ISO Metric profile", + "designation": "M8x1.25", + "class": "6H" + } + ] +} diff --git a/tests/oracle/56-holes-on-curved-face/expected.json b/tests/oracle/56-holes-on-curved-face/expected.json new file mode 100644 index 00000000..bd34f5b0 --- /dev/null +++ b/tests/oracle/56-holes-on-curved-face/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, hole tool (cylinder/cone) cut", + "body_count": 1, + "volume_mm3": 77942.84309053734, + "area_mm2": 10593.056836186597, + "center_of_mass": [ + -0.07534872185918355, + -0.07534952345333637, + 19.999998003198982 + ], + "bbox": { + "min": [ + -25.0000001, + -25.0000001, + -1e-07 + ], + "max": [ + 25.0000001, + 25.00000011239331, + 40.0000001 + ] + } +} diff --git a/tests/oracle/56-holes-on-curved-face/recipe.json b/tests/oracle/56-holes-on-curved-face/recipe.json new file mode 100644 index 00000000..6a7b5219 --- /dev/null +++ b/tests/oracle/56-holes-on-curved-face/recipe.json @@ -0,0 +1,169 @@ +{ + "id": "56-holes-on-curved-face", + "name": "Holes on a cylindrical face", + "description": "Cylinder r25 h40 (axis Z); two d6 radial blind holes 10 deep placed on the curved face at (25,0,20) and (0,25,20).", + "exercises": [ + "hole_on_curved_face", + "hole_blind" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "S1", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 0, + 0 + ] + }, + "radius": 25, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Cyl", + "operation": "new", + "profiles": [ + { + "sketch": "S1", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 40, + "direction": "positive" + }, + "result_bodies": [ + "Cyl" + ] + }, + { + "op": "hole", + "name": "Hole1", + "hole_type": "simple", + "face": { + "type": "cylinder", + "normal_at_point_on_face": [ + 0.0, + 1.0, + 0.0 + ], + "axis_origin": [ + 0.0, + 0.0, + 0.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 0.0, + 25.0, + 20.0 + ] + }, + "position": [ + 25, + 0, + 20 + ], + "direction": "along the inward surface normal (radial, toward the axis)", + "diameter": 6, + "depth": 10, + "tip_angle": 118, + "extent": "distance" + }, + { + "op": "hole", + "name": "Hole2", + "hole_type": "simple", + "face": { + "type": "cylinder", + "normal_at_point_on_face": [ + 0.992773892, + 0.12, + 0.0 + ], + "axis_origin": [ + 0.0, + 0.0, + 0.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 24.819347292, + 3.0, + 20.0 + ] + }, + "position": [ + 0, + 25, + 20 + ], + "direction": "along the inward surface normal (radial, toward the axis)", + "diameter": 6, + "depth": 10, + "tip_angle": 118, + "extent": "distance" + } + ] +} diff --git a/tests/oracle/56-holes-on-curved-face/reference.stl b/tests/oracle/56-holes-on-curved-face/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..53d276c5858c3acd39ac6570e59f036cdffeee30 GIT binary patch literal 131484 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.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Plate_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 50.0 + ] + }, + "end": { + "at": [ + 0, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Plate", + "operation": "new", + "profiles": [ + { + "sketch": "Plate_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Plate" + ] + }, + { + "op": "sketch", + "name": "HolePoints", + "plane": { + "ref": "face: top of plate (z=10)", + "origin": [ + 0.0, + 0.0, + 10.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ], + "face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 40.0, + 25.0, + 10.0 + ] + } + }, + "entities": [ + { + "type": "point", + "at": [ + 15.0, + 15.0 + ], + "fixed": false, + "id": "p1" + }, + { + "type": "point", + "at": [ + 40.0, + 15.0 + ], + "fixed": false, + "id": "p2" + }, + { + "type": "point", + "at": [ + 65.0, + 15.0 + ], + "fixed": false, + "id": "p3" + }, + { + "type": "point", + "at": [ + 15.0, + 35.0 + ], + "fixed": false, + "id": "p4" + }, + { + "type": "point", + "at": [ + 40.0, + 35.0 + ], + "fixed": false, + "id": "p5" + }, + { + "type": "point", + "at": [ + 65.0, + 35.0 + ], + "fixed": false, + "id": "p6" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "hole", + "name": "CBores", + "hole_type": "counterbore", + "positions_from": "sketch HolePoints points p1..p6", + "direction": "into the material (-Z)", + "diameter": 5.5, + "counterbore_diameter": 10, + "counterbore_depth": 5.5, + "extent": "through_all" + } + ] +} diff --git a/tests/oracle/58-phone-stand/expected.json b/tests/oracle/58-phone-stand/expected.json new file mode 100644 index 00000000..26ebf93c --- /dev/null +++ b/tests/oracle/58-phone-stand/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet, Part extrude cut", + "body_count": 1, + "volume_mm3": 74559.17735612375, + "area_mm2": 29148.784986945895, + "center_of_mass": [ + 30.24137598608169, + -1.2447738706242872e-15, + 23.750201033013706 + ], + "bbox": { + "min": [ + -14.035643557, + -35.0, + 0.0 + ], + "max": [ + 90.0, + 35.0, + 87.567700833 + ] + } +} diff --git a/tests/oracle/58-phone-stand/recipe.json b/tests/oracle/58-phone-stand/recipe.json new file mode 100644 index 00000000..f0b3f8f9 --- /dev/null +++ b/tests/oracle/58-phone-stand/recipe.json @@ -0,0 +1,466 @@ +{ + "id": "58-phone-stand", + "name": "Phone stand", + "description": "Side profile on XZ (base, front lip, 65 deg back rest) extruded symmetric 35 each side; root fillets R3 and R2; cable slot cut through the base.", + "exercises": [ + "sketch_xz", + "symmetric", + "fillet", + "extrude_cut", + "realistic" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "SideProfile", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 90.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 90.0, + 0.0 + ] + }, + "end": { + "at": [ + 90.0, + -18.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 90.0, + -18.0 + ] + }, + "end": { + "at": [ + 84.0, + -18.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 84.0, + -18.0 + ] + }, + "end": { + "at": [ + 84.0, + -6.0 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 84.0, + -6.0 + ] + }, + "end": { + "at": [ + 30.0, + -6.0 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + 30.0, + -6.0 + ] + }, + "end": { + "at": [ + -8.035643557, + -87.567700833 + ] + }, + "id": "l6" + }, + { + "type": "line", + "start": { + "ref": "l6.end", + "at": [ + -8.035643557, + -87.567700833 + ] + }, + "end": { + "at": [ + -14.035643557, + -87.567700833 + ] + }, + "id": "l7" + }, + { + "type": "line", + "start": { + "ref": "l7.end", + "at": [ + -14.035643557, + -87.567700833 + ] + }, + "end": { + "at": [ + 24.0, + -6.0 + ] + }, + "id": "l8" + }, + { + "type": "line", + "start": { + "ref": "l8.end", + "at": [ + 24.0, + -6.0 + ] + }, + "end": { + "at": [ + 0.0, + -6.0 + ] + }, + "id": "l9" + }, + { + "type": "line", + "start": { + "ref": "l9.end", + "at": [ + 0.0, + -6.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l10" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Body", + "operation": "new", + "profiles": [ + { + "sketch": "SideProfile", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l10", + "l2", + "l3", + "l4", + "l5", + "l6", + "l7", + "l8", + "l9" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 35, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Stand" + ] + }, + { + "op": "fillet", + "name": "RestFillet", + "type": "constant_radius", + "radius": 3, + "tangent_chain": false, + "edge_selection": "the two Y-parallel edges where the back rest meets the base (x=30,z=6 concave; x=24,z=6 concave)", + "edges": [ + { + "type": "line", + "start": [ + 30.0, + -35.0, + 6.0 + ], + "end": [ + 30.0, + 35.0, + 6.0 + ], + "point": [ + 30.0, + 0.0, + 6.0 + ] + }, + { + "type": "line", + "start": [ + 24.0, + -35.0, + 6.0 + ], + "end": [ + 24.0, + 35.0, + 6.0 + ], + "point": [ + 24.0, + 0.0, + 6.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "LipFillet", + "type": "constant_radius", + "radius": 2, + "tangent_chain": false, + "edge_selection": "the Y-parallel concave edge at the lip root (x=84, z=6)", + "edges": [ + { + "type": "line", + "start": [ + 84.0, + -35.0, + 6.0 + ], + "end": [ + 84.0, + 35.0, + 6.0 + ], + "point": [ + 84.0, + 0.0, + 6.0 + ] + } + ] + }, + { + "op": "sketch", + "name": "SlotSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 45, + -10 + ] + }, + "end": { + "at": [ + 70, + -10 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 70.0, + -10.0 + ] + }, + "end": { + "at": [ + 70, + 10 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 70.0, + 10.0 + ] + }, + "end": { + "at": [ + 45, + 10 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 45.0, + 10.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 45.0, + -10.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "CableSlot", + "operation": "cut", + "profiles": [ + { + "sketch": "SlotSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Stand" + ] + } + ] +} diff --git a/tests/oracle/58-phone-stand/reference.stl b/tests/oracle/58-phone-stand/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..8d07ecf9b276a12e632d023f22bc2cdd700a1faf GIT binary patch literal 13884 zcmb`Of3Q_m6~}kInf%dX0!2bc6H!TE{4t8D6z`n384??w890UGIEFf6KFvY1&_u3b zGB%c4ls{rH6Osf49Aui*=X)0jeKw@X1d(XvC_jY3R8&NKoxS!t=YH0G=f3w(cN8~g zuh06feeXH@?DO5nwh2=vp4|3-`{U5TpK^th~yRsUrih3b=_Rn)cWy_QYvz*OZRX9@L4#(mr68ER`g&6hC&a|A) z<8zJmckU44nQK2x&m6p5+QZK~p>@uN*lv9~oDb9>!KgpAuMqnALC5q#Fly6lk?5R! zWFG{hhL3(yG%mXRh&~8L9eqJ0HZL922f?VhZIPI_VL%@QqpmtW65ID5(g(q)rVVlA zUq1D7eGrWL*F}-I@A}X7K`?6V)A1MVy#GKdzh9;7H)qtUkCtV*o2vtV`avWzES^{V z&3o>3T_NhR;mbVF7^~6x{hg9)`|aJ#`u+s7G2fimEzqd|NdB@%E0C zbT5rcJ`NI$`t;x@B-4ps*-=;3-3xX}&!WfQNJ;l13JnsBn)~`v$+UIg8&RVmo_TAx z^t`ZfYs#pb?^`0r55Hh*T~#EgN80Hp{({3M?U7tZwr@^J_tGe;BEhKlPk&4@O*pVA zR#gy}|MeZ|S$fkeDWh6fE|%kCk9#E&F8@79P>*yLET1@zPp^1aa=mo$-%`@OG%C3U z2}W%`=26MCclG)-3gpE2!{3*l{l~tTGHUAei{$tpcXdZ1!(vq=s7KmrT)J_u!kBW*RNE&5P$J=?P;W!^KkJuJts*}kSug9P%VuP9N|)IX-=DwN8Ts^+;Qdbyx3~T%Y${Df5mTwLp%a@U^Zw4HDENZ8iQr^?>AB zbU}6xM_%4hg~%=bNDTS&zLa!hqITW6R??Q} zx%azWWos&~wJZ_;md^mS>(O4dNAI8bY>52AirI-?Yrg(Uwbx)jM0Rdf%Ia8DBp~ z+1aNbLiDW0^4UX0W57dgiOx&Depa*d)tx&>3$b|FI72YX&R6|t$e8RnsG+$$W=^Tl zYFxN%oK*GZ&e4g^eZGF?v~yxVgy>m~#}~AT#+b^`L}yE1KiAq>v>!q$v{kK{cd=*; z|7}yEv!$<}o$V~z4anBGvtMSXRv!tr=*A(d!eAD-K+#(xid~aT{LcZ`K*Mw)Wz|^HKL>A+=`j0 zd{>>_CnfA5LD#5MLuw~M?LxyrLn_g{KKNx;V{xTT#<6hm(1bnes`=pJ(P7K3^WKEy zCBaP2oqg&>qS1E8K?!rIJLrQONvE)skV;4}lXIudxLhH?zNn|KtMJg%9A@zNsbr84j8dP$haG_!1|mBU3H5P(aQ<19`upDO z0*D5CNT|Q>%`Sit>>;84zBju7La>K~`upDO0tmq#66)`JvkM>udq}9i@69fN5bPnL z{=PT6079^bg!=p5>;eeE9un&Bd$S851baxRzwe7(fZ{i24+-_#z1am24SgE*!TBe_ zvnQTo`FX`$yrR^5_huJBG?~yd zdCe<+Vjx^^yTbF!ROGImwz-ApkFKw)cuJKg*327=LG>M^ znspq~F2)i57CxnfMoA{URzhfqk3>Gg@b|hXIuoHg`veWnB_xR=BEzCr1nYE+;hE)EGjOGLX=L;M~3GghN@cijIN+I(FHd+5*bEzNA98HoxAafC=P zlXLIyyhTQS=rv#JU@kg3e6Q2FIp@Y5lOyhV;92&N;Cr2gMgMn&#MQ1cvA~|=wldUCW%J1{iuXd^sM?Ns==Wn zq3vpP)jE$)MB_)3MkVZ_m!<7$bk&w@Jxz#dgU?CWL&Cn3TB0GI9tmnYx95iAM5AfR z*AwQV%f7~A8PgNyqGzS;YIM~e{dlERHU6gS z684a=@1&M!hzm%9+Rl||h^I%F%W6#e6RadyHU z688UTDbWxYkOZ}zE76dhG47aIjks#9t^I0i!*DFD6Fbw`+nlZXVmquT`N>z4;aDvy Ywi%acCGqbuFDqe%WJ-ymlA7NC0R97KasU7T literal 0 HcmV?d00001 diff --git a/tests/oracle/59-enclosure-base/expected.json b/tests/oracle/59-enclosure-base/expected.json new file mode 100644 index 00000000..c9223709 --- /dev/null +++ b/tests/oracle/59-enclosure-base/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part makeFillet, makeThickness shell, Part extrude join, Part extrude cut", + "body_count": 1, + "volume_mm3": 34309.48619533657, + "area_mm2": 33795.610175573434, + "center_of_mass": [ + 50.0, + 29.999999999999954, + 10.205570681943714 + ], + "bbox": { + "min": [ + -8.881784197001252e-16, + -8.881784197001252e-16, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 30.0 + ] + } +} diff --git a/tests/oracle/59-enclosure-base/recipe.json b/tests/oracle/59-enclosure-base/recipe.json new file mode 100644 index 00000000..9b9a44b0 --- /dev/null +++ b/tests/oracle/59-enclosure-base/recipe.json @@ -0,0 +1,645 @@ +{ + "id": "59-enclosure-base", + "name": "Enclosure base with bosses and ribs", + "description": "100x60x30 box, vertical edges R6, shelled 2 (top open); 4 d8 screw bosses to z=26 with d3 holes 20 deep; a 2 mm rib along Y 10 tall.", + "exercises": [ + "fillet", + "shell", + "extrude_join", + "extrude_cut", + "realistic" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Box_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Box", + "operation": "new", + "profiles": [ + { + "sketch": "Box_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 30, + "direction": "positive" + }, + "result_bodies": [ + "Enclosure" + ] + }, + { + "op": "fillet", + "name": "CornerFillet", + "type": "constant_radius", + "radius": 6, + "tangent_chain": false, + "edge_selection": "the 4 outer vertical edges", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 60.0, + 0.0 + ], + "end": [ + 0.0, + 60.0, + 30.0 + ], + "point": [ + 0.0, + 60.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 100.0, + 60.0, + 0.0 + ], + "end": [ + 100.0, + 60.0, + 30.0 + ], + "point": [ + 100.0, + 60.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 100.0, + 0.0, + 0.0 + ], + "end": [ + 100.0, + 0.0, + 30.0 + ], + "point": [ + 100.0, + 0.0, + 15.0 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 0.0 + ], + "end": [ + 0.0, + 0.0, + 30.0 + ], + "point": [ + 0.0, + 0.0, + 15.0 + ] + } + ] + }, + { + "op": "shell", + "name": "Shell1", + "faces_removed": [ + { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + 1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + 50.0, + 30.0, + 30.0 + ] + } + ], + "face_selection": "top face (z=30)", + "inside_thickness": 2, + "outside_thickness": 0, + "tangent_chain": false + }, + { + "op": "construction_plane", + "name": "Floor2", + "method": "offset", + "base": "XY", + "offset": 2 + }, + { + "op": "sketch", + "name": "Bosses", + "plane": { + "ref": "construction plane Floor2 (inner floor, z=2)", + "origin": [ + 0.0, + 0.0, + 2.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 8, + 8 + ] + }, + "radius": 4, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 92, + 8 + ] + }, + "radius": 4, + "id": "c2" + }, + { + "type": "circle", + "center": { + "at": [ + 8, + 52 + ] + }, + "radius": 4, + "id": "c3" + }, + { + "type": "circle", + "center": { + "at": [ + 92, + 52 + ] + }, + "radius": 4, + "id": "c4" + }, + { + "type": "line", + "start": { + "at": [ + 49, + 2 + ] + }, + "end": { + "at": [ + 51, + 2 + ] + }, + "id": "r1" + }, + { + "type": "line", + "start": { + "ref": "r1.end", + "at": [ + 51.0, + 2.0 + ] + }, + "end": { + "at": [ + 51, + 58 + ] + }, + "id": "r2" + }, + { + "type": "line", + "start": { + "ref": "r2.end", + "at": [ + 51.0, + 58.0 + ] + }, + "end": { + "at": [ + 49, + 58 + ] + }, + "id": "r3" + }, + { + "type": "line", + "start": { + "ref": "r3.end", + "at": [ + 49.0, + 58.0 + ] + }, + "end": { + "ref": "r1.start", + "at": [ + 49.0, + 2.0 + ] + }, + "id": "r4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Bosses", + "operation": "join", + "profiles": [ + { + "sketch": "Bosses", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + { + "sketch": "Bosses", + "loops": [ + { + "outer": true, + "curves": [ + "c2" + ] + } + ] + }, + { + "sketch": "Bosses", + "loops": [ + { + "outer": true, + "curves": [ + "c3" + ] + } + ] + }, + { + "sketch": "Bosses", + "loops": [ + { + "outer": true, + "curves": [ + "c4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 24, + "direction": "positive" + }, + "result_bodies": [ + "Enclosure" + ] + }, + { + "op": "extrude", + "name": "Rib", + "operation": "join", + "profiles": [ + { + "sketch": "Bosses", + "loops": [ + { + "outer": true, + "curves": [ + "r1", + "r2", + "r3", + "r4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 10, + "direction": "positive" + }, + "result_bodies": [ + "Enclosure" + ] + }, + { + "op": "construction_plane", + "name": "BossTop", + "method": "offset", + "base": "XY", + "offset": 26 + }, + { + "op": "sketch", + "name": "ScrewHoles", + "plane": { + "ref": "construction plane BossTop (z=26)", + "origin": [ + 0.0, + 0.0, + 26.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 8, + 8 + ] + }, + "radius": 1.5, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 92, + 8 + ] + }, + "radius": 1.5, + "id": "c2" + }, + { + "type": "circle", + "center": { + "at": [ + 8, + 52 + ] + }, + "radius": 1.5, + "id": "c3" + }, + { + "type": "circle", + "center": { + "at": [ + 92, + 52 + ] + }, + "radius": 1.5, + "id": "c4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "ScrewHoles", + "operation": "cut", + "profiles": [ + { + "sketch": "ScrewHoles", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + { + "sketch": "ScrewHoles", + "loops": [ + { + "outer": true, + "curves": [ + "c3" + ] + } + ] + }, + { + "sketch": "ScrewHoles", + "loops": [ + { + "outer": true, + "curves": [ + "c2" + ] + } + ] + }, + { + "sketch": "ScrewHoles", + "loops": [ + { + "outer": true, + "curves": [ + "c4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 20, + "direction": "negative" + }, + "result_bodies": [ + "Enclosure" + ] + } + ] +} diff --git a/tests/oracle/59-enclosure-base/reference.stl b/tests/oracle/59-enclosure-base/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..3091cc3f3144cb59666c39c60df9c4918f34d0fd GIT binary patch literal 164684 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 literal 0 HcmV?d00001 diff --git a/tests/oracle/60-pipe-flange/expected.json b/tests/oracle/60-pipe-flange/expected.json new file mode 100644 index 00000000..745d26fe --- /dev/null +++ b/tests/oracle/60-pipe-flange/expected.json @@ -0,0 +1,25 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part revolve, Part extrude cut, pattern (tools transformed and re-applied), Part makeChamfer, Part makeFillet", + "body_count": 1, + "volume_mm3": 323660.9792237058, + "area_mm2": 56984.564025960535, + "center_of_mass": [ + 8.992072670155864e-17, + -3.0983486149956997e-15, + 14.841104660417978 + ], + "bbox": { + "min": [ + -75.0, + -75.0, + 0.0 + ], + "max": [ + 75.0, + 75.0, + 50.0 + ] + }, + "note": "No reference.stl: over 409600 bytes even at 0.02 mm deflection (11380 facets)." +} diff --git a/tests/oracle/60-pipe-flange/recipe.json b/tests/oracle/60-pipe-flange/recipe.json new file mode 100644 index 00000000..3a27b3e8 --- /dev/null +++ b/tests/oracle/60-pipe-flange/recipe.json @@ -0,0 +1,367 @@ +{ + "id": "60-pipe-flange", + "name": "Weld-neck pipe flange", + "description": "Revolved flange (bore d50, flange OD150 x16, tapered neck to z=50); 8 x d14 bolt holes on PCD120; bore top edge chamfer 2; neck root fillet R4.", + "exercises": [ + "revolve", + "extrude_cut", + "circular_pattern", + "chamfer", + "fillet", + "realistic" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Profile", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 25.0, + 0.0 + ] + }, + "end": { + "at": [ + 75.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 75.0, + 0.0 + ] + }, + "end": { + "at": [ + 75.0, + -16.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 75.0, + -16.0 + ] + }, + "end": { + "at": [ + 40.0, + -16.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 40.0, + -16.0 + ] + }, + "end": { + "at": [ + 37.0, + -50.0 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 37.0, + -50.0 + ] + }, + "end": { + "at": [ + 25.0, + -50.0 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + 25.0, + -50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 25.0, + 0.0 + ] + }, + "id": "l6" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "Revolve1", + "operation": "new", + "profile": { + "sketch": "Profile", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4", + "l5", + "l6" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "Flange" + ] + }, + { + "op": "sketch", + "name": "BoltHole", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 60, + 0 + ] + }, + "radius": 7, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "BoltHole", + "operation": "cut", + "profiles": [ + { + "sketch": "BoltHole", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Flange" + ] + }, + { + "op": "circular_pattern", + "name": "BoltPattern", + "pattern_of": "features", + "features": [ + "BoltHole (1)" + ], + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "count": 8, + "total_angle": 360, + "symmetric": false + }, + { + "op": "chamfer", + "name": "BoreChamfer", + "type": "equal_distance", + "distance": 2, + "tangent_chain": false, + "edge_selection": "bore circle r=25 at z=50 (top of neck)", + "edges": [ + { + "type": "circle", + "start": [ + 25.0, + 0.0, + 50.0 + ], + "end": [ + 25.0, + 0.0, + 50.0 + ], + "center": [ + 0.0, + 0.0, + 50.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + -25.0, + 0.0, + 50.0 + ] + } + ] + }, + { + "op": "fillet", + "name": "NeckFillet", + "type": "constant_radius", + "radius": 4, + "tangent_chain": false, + "edge_selection": "circle r=40 at z=16 (neck meets flange face, concave)", + "edges": [ + { + "type": "circle", + "start": [ + 40.0, + 0.0, + 16.0 + ], + "end": [ + 40.0, + 0.0, + 16.0 + ], + "center": [ + 0.0, + 0.0, + 16.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + -40.0, + 0.0, + 16.0 + ] + } + ] + } + ] +} diff --git a/tests/oracle/61-shaft-keyway/expected.json b/tests/oracle/61-shaft-keyway/expected.json new file mode 100644 index 00000000..1fd8d545 --- /dev/null +++ b/tests/oracle/61-shaft-keyway/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part revolve, Part makeChamfer, Part extrude cut", + "body_count": 1, + "volume_mm3": 47526.16490034648, + "area_mm2": 9677.092709919276, + "center_of_mass": [ + -0.15632153741345178, + 2.2099613089702305e-12, + 60.00000055531035 + ], + "bbox": { + "min": [ + -12.5000001, + -12.5000001, + 0.0 + ], + "max": [ + 12.5000001, + 12.5000001, + 120.0 + ] + } +} diff --git a/tests/oracle/61-shaft-keyway/recipe.json b/tests/oracle/61-shaft-keyway/recipe.json new file mode 100644 index 00000000..264a97dc --- /dev/null +++ b/tests/oracle/61-shaft-keyway/recipe.json @@ -0,0 +1,439 @@ +{ + "id": "61-shaft-keyway", + "name": "Stepped shaft with keyway and chamfers", + "description": "Revolved stepped shaft (d20 x30, d25 x60, d20 x30 along Z); end edges chamfered 1; 8 mm wide R4-ended keyway 4 deep on the d25 section (z 45..75), cut from a tangent plane at x=12.5.", + "exercises": [ + "revolve", + "chamfer", + "offset_plane", + "extrude_cut", + "keyway", + "realistic" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Profile", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 10.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 10.0, + 0.0 + ] + }, + "end": { + "at": [ + 10.0, + -30.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 10.0, + -30.0 + ] + }, + "end": { + "at": [ + 12.5, + -30.0 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 12.5, + -30.0 + ] + }, + "end": { + "at": [ + 12.5, + -90.0 + ] + }, + "id": "l4" + }, + { + "type": "line", + "start": { + "ref": "l4.end", + "at": [ + 12.5, + -90.0 + ] + }, + "end": { + "at": [ + 10.0, + -90.0 + ] + }, + "id": "l5" + }, + { + "type": "line", + "start": { + "ref": "l5.end", + "at": [ + 10.0, + -90.0 + ] + }, + "end": { + "at": [ + 10.0, + -120.0 + ] + }, + "id": "l6" + }, + { + "type": "line", + "start": { + "ref": "l6.end", + "at": [ + 10.0, + -120.0 + ] + }, + "end": { + "at": [ + 0.0, + -120.0 + ] + }, + "id": "l7" + }, + { + "type": "line", + "start": { + "ref": "l7.end", + "at": [ + 0.0, + -120.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l8" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "revolve", + "name": "Revolve1", + "operation": "new", + "profile": { + "sketch": "Profile", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4", + "l5", + "l6", + "l7", + "l8" + ] + } + ] + }, + "axis": { + "ref": "world Z axis", + "origin": [ + 0, + 0, + 0 + ], + "dir": [ + 0, + 0, + 1 + ] + }, + "angle": 360, + "result_bodies": [ + "Shaft" + ] + }, + { + "op": "chamfer", + "name": "EndChamfers", + "type": "equal_distance", + "distance": 1, + "tangent_chain": false, + "edge_selection": "end circles r=10 at z=0 and z=120", + "edges": [ + { + "type": "circle", + "start": [ + 10.0, + 0.0, + 0.0 + ], + "end": [ + 10.0, + 0.0, + 0.0 + ], + "center": [ + 0.0, + 0.0, + 0.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + -10.0, + 0.0, + 0.0 + ] + }, + { + "type": "circle", + "start": [ + 10.0, + 0.0, + 120.0 + ], + "end": [ + 10.0, + 0.0, + 120.0 + ], + "center": [ + 0.0, + 0.0, + 120.0 + ], + "axis": [ + 0.0, + 0.0, + 1.0 + ], + "point": [ + -10.0, + 0.0, + 120.0 + ] + } + ] + }, + { + "op": "construction_plane", + "name": "Tangent", + "method": "offset", + "base": "YZ", + "offset": 12.5 + }, + { + "op": "sketch", + "name": "KeywaySketch", + "plane": { + "ref": "construction plane Tangent (YZ offset 12.5)", + "origin": [ + 12.5, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + -45.0, + 0.0 + ] + }, + "start": { + "at": [ + -45.0, + 4.0 + ] + }, + "sweep_deg": 180, + "id": "a1" + }, + { + "type": "arc_center_start_sweep", + "center": { + "at": [ + -75.0, + 0.0 + ] + }, + "start": { + "at": [ + -75.0, + -4.0 + ] + }, + "sweep_deg": 180, + "id": "a2" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + -45.0, + -4.0 + ] + }, + "end": { + "ref": "a2.start", + "at": [ + -75.0, + -4.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "a2.end", + "at": [ + -75.0, + 4.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + -45.0, + 4.0 + ] + }, + "id": "l2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Keyway", + "operation": "cut", + "profiles": [ + { + "sketch": "KeywaySketch", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "a2", + "l1", + "l2" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 4, + "direction": "negative" + }, + "result_bodies": [ + "Shaft" + ] + } + ] +} diff --git a/tests/oracle/61-shaft-keyway/reference.stl b/tests/oracle/61-shaft-keyway/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..d570ac2691f1b8521f9508f51de709630ca383d0 GIT binary patch literal 173684 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.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 60, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 60.0, + 0.0 + ] + }, + "end": { + "at": [ + 60, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 60.0, + 50.0 + ] + }, + "end": { + "at": [ + 0, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Base", + "operation": "new", + "profiles": [ + { + "sketch": "Base_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 5, + "direction": "positive" + }, + "result_bodies": [ + "HeatSink" + ] + }, + { + "op": "construction_plane", + "name": "BaseTop", + "method": "offset", + "base": "XY", + "offset": 5 + }, + { + "op": "sketch", + "name": "Fin", + "plane": { + "ref": "construction plane BaseTop (z=5)", + "origin": [ + 0.0, + 0.0, + 5.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 2, + 0 + ] + }, + "end": { + "at": [ + 3.5, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 3.5, + 0.0 + ] + }, + "end": { + "at": [ + 3.5, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 3.5, + 50.0 + ] + }, + "end": { + "at": [ + 2, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 2.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 2.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Fin", + "operation": "join", + "profiles": [ + { + "sketch": "Fin", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 25, + "direction": "positive" + }, + "result_bodies": [ + "HeatSink" + ] + }, + { + "op": "rectangular_pattern", + "name": "FinPattern", + "pattern_of": "features", + "features": [ + "Fin (1)" + ], + "direction1": { + "axis": [ + 1, + 0, + 0 + ], + "count": 15, + "spacing": 4 + }, + "distance_type": "spacing (distance between instances)" + } + ] +} diff --git a/tests/oracle/63-hinge-knuckle/expected.json b/tests/oracle/63-hinge-knuckle/expected.json new file mode 100644 index 00000000..f9b9e70e --- /dev/null +++ b/tests/oracle/63-hinge-knuckle/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Part extrude, Part extrude join, Part extrude cut", + "body_count": 1, + "volume_mm3": 4436.251164993785, + "area_mm2": 3740.579063328514, + "center_of_mass": [ + 19.99999999999998, + 18.446306909750707, + 2.0056940715466656 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 40.0, + 37.0, + 8.0 + ] + } +} diff --git a/tests/oracle/63-hinge-knuckle/recipe.json b/tests/oracle/63-hinge-knuckle/recipe.json new file mode 100644 index 00000000..16081559 --- /dev/null +++ b/tests/oracle/63-hinge-knuckle/recipe.json @@ -0,0 +1,420 @@ +{ + "id": "63-hinge-knuckle", + "name": "Hinge leaf with knuckles", + "description": "40x30x3 leaf; knuckle cylinder r4 along X at (y=33, z=4); d4 pin hole; gap x 12..28 (y 29..40) cut through all from z=0, which removes the knuckle between x=12 and 28.", + "exercises": [ + "sketch_yz", + "extrude_join", + "extrude_cut", + "symmetric", + "realistic" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Leaf_sketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 40, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40, + 30 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + 30.0 + ] + }, + "end": { + "at": [ + 0, + 30 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 30.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Leaf", + "operation": "new", + "profiles": [ + { + "sketch": "Leaf_sketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 3, + "direction": "positive" + }, + "result_bodies": [ + "Hinge" + ] + }, + { + "op": "sketch", + "name": "Knuckle", + "plane": { + "ref": "YZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + -4.0, + 33.0 + ] + }, + "radius": 4, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Knuckle", + "operation": "join", + "profiles": [ + { + "sketch": "Knuckle", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 40, + "direction": "positive" + }, + "result_bodies": [ + "Hinge" + ] + }, + { + "op": "sketch", + "name": "Pin", + "plane": { + "ref": "YZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 0.0, + 0.0, + -1.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 1.0, + 0.0, + 0.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + -4.0, + 33.0 + ] + }, + "radius": 2, + "id": "c1" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "PinHole", + "operation": "cut", + "profiles": [ + { + "sketch": "Pin", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + } + ], + "extent": { + "type": "symmetric", + "distance": 100, + "is_full_length": false, + "meaning": "distance on each side" + }, + "result_bodies": [ + "Hinge" + ] + }, + { + "op": "sketch", + "name": "Gap", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 12, + 29 + ] + }, + "end": { + "at": [ + 28, + 29 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 28.0, + 29.0 + ] + }, + "end": { + "at": [ + 28, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 28.0, + 40.0 + ] + }, + "end": { + "at": [ + 12, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 12.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 12.0, + 29.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Gap", + "operation": "cut", + "profiles": [ + { + "sketch": "Gap", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Hinge" + ] + } + ] +} diff --git a/tests/oracle/63-hinge-knuckle/reference.stl b/tests/oracle/63-hinge-knuckle/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..d0858f213ee9e0f92e795aa942ab698ce05684bd GIT binary patch literal 60284 zcmb`Qcf1tU`TvKGAX2VM&?qBl#9olFqjGoVSU?4h6?^PmBPtdYxf(Q<7)xS}v48DK zEXa<^T?D%ZHHl(pj19qxqKK5=bI#tK&*wS!&VBL6@4gaUch37MXJ=>UoOwRyjM-`L zQJanV|Mrg_k9Q7Q{+g=wSNL~m@Vfpgj_a>{!X9Cw{<=o!*1vjk74yZE2c50W2KP3d zKYP!;e*cT!X6tcpy4RXGW&Ksm+^&zbBG^(f@u%HaGq->KQ7gKbSaeb^GwGDi9l^9F zwn};!^Z7ll)y=o}G3M&o?)AmH^fmw4{RQ{BnBZ)gE+#lzrZw^K1>Mbnj~;j4IS=l` zV&a-ftD477|FRXWiNh*A%%SCdYW&){k9cdO!T_Ahq*5M!4XVrV*I*2&0n_uhik>XP@Fjv-0IF_`k65=OmmjB zkI8FyGiUw$q&vb9pm)+vtFDAI(iu-EzwOz~xPc=JR92MuMeK7IDzTHgYmdjev#l%J1bv0*Hmpg)K zO?;g7G`-fj+_mCfD9)UTJ)dnbM?ZJ1qlYYLFsFa|XZO0;2is*@6Z2o`Y_5B_cFj0* z-7e{?8lC z{6R;#*Tp{AF4LM=bDK{2XMVt}4rbHl+PTa9R!nd!?n6zi{cTTk!5XK!csZxyJec5C zlbajNcE|12M&?_e&@um>a~_bE*9OWqk)`^Di1iwSPUJ)((&uI*|5 zyWLoq$L?D-m|Y*=!oB|bU;WIbpRMa&7ZaQ<)5Qe$0@Io}?~@?^b-wMZCCQ<0*6ta& z7m5jP#eJxWXLs#s79O~p%aD7aICCbr)rztG%!Svi)<$1lx@nN#Uw!z+;^eK5YIjSV zla7jswSN9FDIHe3Ph`57V7uIhnz;3=9�}oug~K-q-y8#%1L|{@(d*U-QtObKUD= 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 Xu;io3o{1QT*IwJRqV|6MN$mdvX-}a6 literal 0 HcmV?d00001 diff --git a/tests/oracle/64-sketch-tangent-arc-chain/expected.json b/tests/oracle/64-sketch-tangent-arc-chain/expected.json new file mode 100644 index 00000000..a3de8d2e --- /dev/null +++ b/tests/oracle/64-sketch-tangent-arc-chain/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "solved sketch: 80x20 rectangle whose top is 4 tangent R12 arcs on 20 mm chords alternating up/down (net area 1600); prism h3: V = A h, area = 2A + perimeter*h, Green's theorem for centroid", + "body_count": 1, + "volume_mm3": 4799.999999999989, + "area_mm2": 3843.711905601287, + "center_of_mass": [ + 38.11191357516195, + -9.585748181923725, + 1.5 + ], + "bbox": { + "min": [ + 0.0, + -20.0, + 0.0 + ], + "max": [ + 80.0, + 5.3667504192892, + 3.0 + ] + }, + "faces": 9 +} diff --git a/tests/oracle/64-sketch-tangent-arc-chain/recipe.json b/tests/oracle/64-sketch-tangent-arc-chain/recipe.json new file mode 100644 index 00000000..776d4b2f --- /dev/null +++ b/tests/oracle/64-sketch-tangent-arc-chain/recipe.json @@ -0,0 +1,357 @@ +{ + "id": "64-sketch-tangent-arc-chain", + "name": "Sketch solver: tangent arc chain", + "description": "Four alternating 3-point arcs (wave) closed by three lines; equal/tangent/horizontal-points constraints, R12, chord 20, line 20; solved then extruded 3.", + "exercises": [ + "sketch_only", + "sketch_constraints", + "tangent", + "equal", + "arc_chain" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Wave", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "arc_three_point", + "start": { + "at": [ + 20, + 0.5 + ] + }, + "mid": [ + 10, + 5.5 + ], + "end": { + "at": [ + 0.5, + -0.5 + ] + }, + "id": "a1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "a1.start", + "at": [ + 20.0, + 0.5 + ] + }, + "mid": [ + 30, + -4.5 + ], + "end": { + "at": [ + 40, + 0.5 + ] + }, + "id": "a2" + }, + { + "type": "arc_three_point", + "start": { + "at": [ + 60, + -0.5 + ] + }, + "mid": [ + 50, + 5 + ], + "end": { + "at": [ + 40.5, + 0.5 + ] + }, + "id": "a3" + }, + { + "type": "arc_three_point", + "start": { + "ref": "a3.start", + "at": [ + 60.0, + -0.5 + ] + }, + "mid": [ + 70, + -5 + ], + "end": { + "at": [ + 79, + 0.5 + ] + }, + "id": "a4" + }, + { + "type": "line", + "start": { + "ref": "a4.end", + "at": [ + 79.0, + 0.5 + ] + }, + "end": { + "at": [ + 80, + -19 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + -19.0 + ] + }, + "end": { + "at": [ + 1, + -21 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 1.0, + -21.0 + ] + }, + "end": { + "ref": "a1.end", + "at": [ + 0.5, + -0.5 + ] + }, + "id": "l3" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "a1.end", + "origin" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "a1.start", + "a1.end" + ] + }, + { + "type": "coincident", + "refs": [ + "a3.end", + "a2.end" + ] + }, + { + "type": "equal", + "refs": [ + "a1", + "a2" + ] + }, + { + "type": "tangent", + "refs": [ + "a1", + "a2" + ] + }, + { + "type": "equal", + "refs": [ + "a2", + "a3" + ] + }, + { + "type": "tangent", + "refs": [ + "a2", + "a3" + ] + }, + { + "type": "equal", + "refs": [ + "a3", + "a4" + ] + }, + { + "type": "tangent", + "refs": [ + "a3", + "a4" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "a2.start", + "a2.end" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "a3.start", + "a3.end" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "a4.start", + "a4.end" + ] + }, + { + "type": "vertical", + "refs": [ + "l1" + ] + }, + { + "type": "horizontal", + "refs": [ + "l2" + ] + }, + { + "type": "vertical", + "refs": [ + "l3" + ] + } + ], + "dimensions": [ + { + "type": "radius", + "refs": [ + "a1" + ], + "value": 12, + "unit": "mm" + }, + { + "type": "distance", + "refs": [ + "a1.end", + "a1.start" + ], + "value": 20, + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "distance", + "refs": [ + "l1.start", + "l1.end" + ], + "value": 20, + "unit": "mm", + "orientation": "vertical" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Wave", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "a2", + "a3", + "a4", + "l1", + "l2", + "l3" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 3, + "direction": "positive" + }, + "result_bodies": [ + "Wave" + ] + } + ] +} diff --git a/tests/oracle/65-sketch-gear-tooth/expected.json b/tests/oracle/65-sketch-gear-tooth/expected.json new file mode 100644 index 00000000..20fec2a6 --- /dev/null +++ b/tests/oracle/65-sketch-gear-tooth/expected.json @@ -0,0 +1,24 @@ +{ + "source": "freecad 1.1.4", + "method": "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: Sketcher-solved sketch, Part extrude", + "body_count": 1, + "volume_mm3": 3988.0844756019715, + "area_mm2": 1945.485055624576, + "center_of_mass": [ + -4.250889726760085e-15, + 29.27488680616214, + 4.0 + ], + "bbox": { + "min": [ + -10.352761804100844, + 0.0, + 0.0 + ], + "max": [ + 10.35276180410083, + 50.0, + 8.0 + ] + } +} diff --git a/tests/oracle/65-sketch-gear-tooth/recipe.json b/tests/oracle/65-sketch-gear-tooth/recipe.json new file mode 100644 index 00000000..1d662ccc --- /dev/null +++ b/tests/oracle/65-sketch-gear-tooth/recipe.json @@ -0,0 +1,374 @@ +{ + "id": "65-sketch-gear-tooth", + "name": "Sketch solver: gear-tooth sector", + "description": "30 deg sector with one tooth: root arcs R40 and tip arc R50 centred on the origin, R15 flank arcs, symmetric about a vertical construction line; fully constrained; extruded 8.", + "exercises": [ + "sketch_only", + "sketch_constraints", + "symmetric", + "angle_dim", + "arcs" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Tooth", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "ref": "origin", + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 0, + 58 + ] + }, + "id": "l0", + "construction": true + }, + { + "type": "line", + "start": { + "ref": "origin", + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 9.193, + 36.8712 + ] + }, + "id": "s1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "s1.end", + "at": [ + 9.193, + 36.8712 + ] + }, + "mid": [ + 6.7619, + 37.3935 + ], + "end": { + "at": [ + 4.3017, + 37.7557 + ] + }, + "id": "r1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "r1.end", + "at": [ + 4.3017, + 37.7557 + ] + }, + "mid": [ + 4.4596, + 42.995 + ], + "end": { + "at": [ + 2.6794, + 47.9252 + ] + }, + "id": "f1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "f1.end", + "at": [ + 2.6794, + 47.9252 + ] + }, + "mid": [ + 0.0, + 48.0 + ], + "end": { + "at": [ + -2.6794, + 47.9252 + ] + }, + "id": "t1" + }, + { + "type": "arc_three_point", + "start": { + "ref": "t1.end", + "at": [ + -2.6794, + 47.9252 + ] + }, + "mid": [ + -4.4596, + 42.995 + ], + "end": { + "at": [ + -4.3017, + 37.7557 + ] + }, + "id": "f2" + }, + { + "type": "arc_three_point", + "start": { + "ref": "f2.end", + "at": [ + -4.3017, + 37.7557 + ] + }, + "mid": [ + -6.7619, + 37.3935 + ], + "end": { + "at": [ + -9.193, + 36.8712 + ] + }, + "id": "r2" + }, + { + "type": "line", + "start": { + "ref": "r2.end", + "at": [ + -9.193, + 36.8712 + ] + }, + "end": { + "ref": "origin", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "s2" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "r1.center", + "origin" + ] + }, + { + "type": "coincident", + "refs": [ + "t1.center", + "origin" + ] + }, + { + "type": "coincident", + "refs": [ + "r2.center", + "origin" + ] + }, + { + "type": "vertical", + "refs": [ + "l0" + ] + }, + { + "type": "equal", + "refs": [ + "f1", + "f2" + ] + }, + { + "type": "symmetric", + "refs": [ + "r1.end", + "f2.end", + "l0" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "f1.end", + "t1.end" + ] + }, + { + "type": "horizontal_points", + "refs": [ + "s1.end", + "r2.end" + ] + } + ], + "dimensions": [ + { + "type": "distance", + "refs": [ + "l0.start", + "l0.end" + ], + "value": 60, + "unit": "mm", + "orientation": "vertical" + }, + { + "type": "radius", + "refs": [ + "r1" + ], + "value": 40, + "unit": "mm" + }, + { + "type": "radius", + "refs": [ + "t1" + ], + "value": 50, + "unit": "mm" + }, + { + "type": "radius", + "refs": [ + "f1" + ], + "value": 15, + "unit": "mm" + }, + { + "type": "angle", + "refs": [ + "l0", + "s1" + ], + "value": 15, + "unit": "deg", + "text_at": [ + 2, + 20 + ] + }, + { + "type": "distance", + "refs": [ + "r1.end", + "f2.end" + ], + "value": 8.4, + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "distance", + "refs": [ + "f1.end", + "t1.end" + ], + "value": 5, + "unit": "mm", + "orientation": "horizontal" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Tooth", + "loops": [ + { + "outer": true, + "curves": [ + "f1", + "f2", + "r1", + "r2", + "s1", + "s2", + "t1" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 8, + "direction": "positive" + }, + "result_bodies": [ + "Tooth" + ] + } + ] +} diff --git a/tests/oracle/65-sketch-gear-tooth/reference.stl b/tests/oracle/65-sketch-gear-tooth/reference.stl new file mode 100644 index 0000000000000000000000000000000000000000..9b724321cccb6929e241d61fb61f5a7c3dcd9451 GIT binary patch literal 12684 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 S{6L~X?UaBYNC=MP+.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Link", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "arc_three_point", + "start": { + "at": [ + 2, + 11 + ] + }, + "mid": [ + -13, + 1 + ], + "end": { + "at": [ + 1, + -12 + ] + }, + "id": "a1" + }, + { + "type": "arc_three_point", + "start": { + "at": [ + 58, + -7 + ] + }, + "mid": [ + 69, + 1 + ], + "end": { + "at": [ + 59, + 8 + ] + }, + "id": "a2" + }, + { + "type": "line", + "start": { + "ref": "a2.end", + "at": [ + 59.0, + 8.0 + ] + }, + "end": { + "ref": "a1.start", + "at": [ + 2.0, + 11.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "a1.end", + "at": [ + 1.0, + -12.0 + ] + }, + "end": { + "ref": "a2.start", + "at": [ + 58.0, + -7.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "a1.center", + "at": [ + -1.246268657, + -0.380597015 + ] + }, + "end": { + "ref": "a2.center", + "at": [ + 61.079617834, + 0.328025478 + ] + }, + "id": "lc", + "construction": true + }, + { + "type": "circle", + "center": { + "ref": "a1.center", + "at": [ + -1.246268657, + -0.380597015 + ] + }, + "radius": 5, + "id": "h1" + }, + { + "type": "circle", + "center": { + "ref": "a2.center", + "at": [ + 61.079617834, + 0.328025478 + ] + }, + "radius": 3.5, + "id": "h2" + }, + { + "type": "circle", + "center": { + "at": [ + 28, + 4 + ] + }, + "radius": 2.5, + "id": "h3" + }, + { + "type": "circle", + "center": { + "at": [ + 31, + -5 + ] + }, + "radius": 1.5, + "id": "h4" + } + ], + "constraints": [ + { + "type": "coincident", + "refs": [ + "a1.center", + "origin" + ] + }, + { + "type": "horizontal", + "refs": [ + "lc" + ] + }, + { + "type": "tangent", + "refs": [ + "l1", + "a1" + ] + }, + { + "type": "tangent", + "refs": [ + "l1", + "a2" + ] + }, + { + "type": "tangent", + "refs": [ + "l2", + "a1" + ] + }, + { + "type": "tangent", + "refs": [ + "l2", + "a2" + ] + }, + { + "type": "symmetric", + "refs": [ + "h3", + "h4", + "lc" + ] + } + ], + "dimensions": [ + { + "type": "distance", + "refs": [ + "a1.center", + "a2.center" + ], + "value": 60, + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "radius", + "refs": [ + "a1" + ], + "value": 12, + "unit": "mm" + }, + { + "type": "radius", + "refs": [ + "a2" + ], + "value": 8, + "unit": "mm" + }, + { + "type": "diameter", + "refs": [ + "h1" + ], + "value": 12, + "unit": "mm" + }, + { + "type": "diameter", + "refs": [ + "h2" + ], + "value": 8, + "unit": "mm" + }, + { + "type": "diameter", + "refs": [ + "h3" + ], + "value": 4, + "unit": "mm" + }, + { + "type": "distance", + "refs": [ + "a1.center", + "h3.center" + ], + "value": 30, + "unit": "mm", + "orientation": "horizontal" + }, + { + "type": "offset", + "refs": [ + "lc", + "h3.center" + ], + "value": 4, + "unit": "mm" + } + ] + }, + { + "op": "extrude", + "name": "Extrude1", + "operation": "new", + "profiles": [ + { + "sketch": "Link", + "loops": [ + { + "outer": true, + "curves": [ + "a1", + "a2", + "l1", + "l2" + ] + }, + { + "outer": false, + "curves": [ + "h1" + ] + }, + { + "outer": false, + "curves": [ + "h2" + ] + }, + { + "outer": false, + "curves": [ + "h3" + ] + }, + { + "outer": false, + "curves": [ + "h4" + ] + } + ] + } + ], + "extent": { + "type": "distance", + "distance": 6, + "direction": "positive" + }, + "result_bodies": [ + "Link" + ] + } + ] +} diff --git a/tests/oracle/67-sm-base-flange/expected.json b/tests/oracle/67-sm-base-flange/expected.json new file mode 100644 index 00000000..85705908 --- /dev/null +++ b/tests/oracle/67-sm-base-flange/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "plate 100 x 60 x t, t = 2.5 (Steel (mm) rule), thickness along +Z: V = 100*60*t, A = 2(ab+bc+ca)", + "body_count": 1, + "volume_mm3": 15000.0, + "area_mm2": 12800.0, + "center_of_mass": [ + 50.0, + 30.0, + 1.25 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 2.5 + ] + }, + "faces": 6 +} diff --git a/tests/oracle/67-sm-base-flange/recipe.json b/tests/oracle/67-sm-base-flange/recipe.json new file mode 100644 index 00000000..0c15b251 --- /dev/null +++ b/tests/oracle/67-sm-base-flange/recipe.json @@ -0,0 +1,148 @@ +{ + "id": "67-sm-base-flange", + "name": "Sheet metal: base flange", + "description": "100x60 rectangle -> base flange (Steel (mm) rule, 2.5 mm).", + "exercises": [ + "sheet_metal", + "base_flange", + "flat_pattern", + "dxf" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + } + ] +} diff --git a/tests/oracle/68-sm-edge-flange/expected.json b/tests/oracle/68-sm-edge-flange/expected.json new file mode 100644 index 00000000..265c5203 --- /dev/null +++ b/tests/oracle/68-sm-edge-flange/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "extrusion along x (100) of the YZ section: base y 5..60 x t; 90 deg bend annulus R 2.5..5 about (y 5, z 5); flange y 0..2.5, z 5..20. Setback (R+t)tan45 = 5 (inside bend position, outer-face height datum: outer face of flange reaches z = 20); V = L*A_sec, A = 2 A_sec + L P_sec", + "body_count": 1, + "volume_mm3": 18972.621556370217, + "area_mm2": 16057.549676223574, + "center_of_mass": [ + 50.0, + 23.996671893539865, + 3.572504424184866 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 20.0 + ] + }, + "note": "trim/setback and height datum are SolidCraft's documented edge-flange conventions (sheet.rs add_flanges)" +} diff --git a/tests/oracle/68-sm-edge-flange/recipe.json b/tests/oracle/68-sm-edge-flange/recipe.json new file mode 100644 index 00000000..d1bedbcc --- /dev/null +++ b/tests/oracle/68-sm-edge-flange/recipe.json @@ -0,0 +1,179 @@ +{ + "id": "68-sm-edge-flange", + "name": "Sheet metal: one edge flange", + "description": "100x60 base + 20 mm edge flange on the y=0 top edge.", + "exercises": [ + "sheet_metal", + "edge_flange", + "bend", + "flat_pattern" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 100.0, + 0.0, + 2.5 + ], + "point": [ + 50.0, + 0.0, + 2.5 + ] + } + ], + "edge_selection": "top edge at y=0", + "height": 20, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + } + ] +} diff --git a/tests/oracle/69-sm-tray/expected.json b/tests/oracle/69-sm-tray/expected.json new file mode 100644 index 00000000..2deb505d --- /dev/null +++ b/tests/oracle/69-sm-tray/expected.json @@ -0,0 +1,26 @@ +{ + "source": "analytic", + "method": "tray: base 90 x 50 x 2.5 (each edge trimmed by the setback 5); four 90 deg bends R 2.5..5 along the trimmed edges (90, 50, 90, 50 long); four walls 2.5 thick, z 5..25, each running on past its bend by ext = (R+t) - (t + gap/sqrt2) = 0.732233047 at both ends; open corners. A = sum of prisms - 2 x joints", + "body_count": 1, + "volume_mm3": 29666.23357665006, + "area_mm2": 24980.085907711007, + "center_of_mass": [ + 49.99999999999999, + 29.999999999999996, + 8.051722040173603 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 25.0 + ] + }, + "faces": 46, + "note": "corner treatment is SolidCraft's convention (sheet.rs close_corners: panels extended until their inner corners are the rule gap = t apart; no corner fill, open corner relief below the walls)" +} diff --git a/tests/oracle/69-sm-tray/recipe.json b/tests/oracle/69-sm-tray/recipe.json new file mode 100644 index 00000000..b6403884 --- /dev/null +++ b/tests/oracle/69-sm-tray/recipe.json @@ -0,0 +1,233 @@ +{ + "id": "69-sm-tray", + "name": "Sheet metal: tray (4 flanges, corner reliefs)", + "description": "100x60 base + 25 mm edge flanges on all 4 top edges in one command (2-bend corners).", + "exercises": [ + "sheet_metal", + "edge_flange", + "corner_relief", + "flat_pattern" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 100.0, + 60.0, + 2.5 + ], + "end": [ + 0.0, + 60.0, + 2.5 + ], + "point": [ + 50.0, + 60.0, + 2.5 + ] + }, + { + "type": "line", + "start": [ + 100.0, + 0.0, + 2.5 + ], + "end": [ + 100.0, + 60.0, + 2.5 + ], + "point": [ + 100.0, + 30.0, + 2.5 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 100.0, + 0.0, + 2.5 + ], + "point": [ + 50.0, + 0.0, + 2.5 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 60.0, + 2.5 + ], + "end": [ + 0.0, + 0.0, + 2.5 + ], + "point": [ + 0.0, + 30.0, + 2.5 + ] + } + ], + "edge_selection": "all 4 top edges of the base", + "height": 25, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + } + ] +} diff --git a/tests/oracle/70-sm-flange-45/expected.json b/tests/oracle/70-sm-flange-45/expected.json new file mode 100644 index 00000000..c609b50f --- /dev/null +++ b/tests/oracle/70-sm-flange-45/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "as 68 with a 45 deg bend: setback (R+t)tan22.5 = 2.071068, base y 2.071068..60, bend annulus 2.5..5 over 45 deg about (y 2.071068, z 5), flat leg 15 - setback = 12.928932 turned 45 deg; extrusion along x 100", + "body_count": 1, + "volume_mm3": 18450.776872252372, + "area_mm2": 15629.637035246944, + "center_of_mass": [ + 50.0, + 23.482458906299712, + 2.253104112858446 + ], + "bbox": { + "min": [ + 0.0, + -10.606601717798213, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 12.37436867076458 + ] + }, + "note": "SolidCraft convention: flange height (15) is measured along the flange's outer face from the virtual sharp at the original edge (y 0, z 0), so the outer top corner is at (y, z) = (-15 cos45, 15 sin45)." +} diff --git a/tests/oracle/70-sm-flange-45/recipe.json b/tests/oracle/70-sm-flange-45/recipe.json new file mode 100644 index 00000000..db966280 --- /dev/null +++ b/tests/oracle/70-sm-flange-45/recipe.json @@ -0,0 +1,178 @@ +{ + "id": "70-sm-flange-45", + "name": "Sheet metal: 45 deg flange", + "description": "100x60 base + 15 mm edge flange on y=0 edge, flange angle parameter set to 45 deg.", + "exercises": [ + "sheet_metal", + "edge_flange", + "flange_angle" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 100.0, + 0.0, + 2.5 + ], + "point": [ + 50.0, + 0.0, + 2.5 + ] + } + ], + "edge_selection": "top edge at y=0", + "height": 15, + "angle": 45, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + } + ] +} diff --git a/tests/oracle/71-sm-custom-rule/expected.json b/tests/oracle/71-sm-custom-rule/expected.json new file mode 100644 index 00000000..ab349155 --- /dev/null +++ b/tests/oracle/71-sm-custom-rule/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "U channel, rule t 1.5, R 3, K 0.33 (K unused folded): base y 4.5..45.5 x 1.5; two 90 deg bend annuli R 3..4.5; flanges y 0..1.5 and 48.5..50, z 4.5..20; extrusion along x 80", + "body_count": 1, + "volume_mm3": 10053.716694115408, + "area_mm2": 13896.29850950676, + "center_of_mass": [ + 40.0, + 24.999999999999996, + 5.19228129375018 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 50.0, + 20.0 + ] + }, + "note": "the rule edit applies to the whole sheet body (base built before it is 1.5 thick too, as the recipe's edge picks at z = 1.5 state)" +} diff --git a/tests/oracle/71-sm-custom-rule/recipe.json b/tests/oracle/71-sm-custom-rule/recipe.json new file mode 100644 index 00000000..86f9d071 --- /dev/null +++ b/tests/oracle/71-sm-custom-rule/recipe.json @@ -0,0 +1,207 @@ +{ + "id": "71-sm-custom-rule", + "name": "Sheet metal: custom rule (t=1.5, K=0.33, R=3)", + "description": "Rule edited to thickness 1.5, K 0.33, bend radius 3 mm; 80x50 base + 20 mm flanges on both long edges (U channel).", + "exercises": [ + "sheet_metal", + "rule", + "k_factor", + "bend_radius", + "flat_pattern" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 50.0 + ] + }, + "end": { + "at": [ + 0, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sheet_metal_rule_edit", + "rule": "Steel (mm)", + "set": { + "thickness": "1.5 mm", + "kFactor": "0.33", + "bendRadius": "3 mm" + } + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 80.0, + 50.0, + 1.5 + ], + "end": [ + 0.0, + 50.0, + 1.5 + ], + "point": [ + 40.0, + 50.0, + 1.5 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 1.5 + ], + "end": [ + 80.0, + 0.0, + 1.5 + ], + "point": [ + 40.0, + 0.0, + 1.5 + ] + } + ], + "edge_selection": "both long top edges (y=0 and y=50)", + "height": 20, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + } + ] +} diff --git a/tests/oracle/72-sm-contour-flange/expected.json b/tests/oracle/72-sm-contour-flange/expected.json new file mode 100644 index 00000000..c450d469 --- /dev/null +++ b/tests/oracle/72-sm-contour-flange/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "contour flange, width 50 along +Y, XZ section: plate x 0..35 z 0..2.5; bend R 2.5..5 about (35, 5) (sketch corner = outer virtual sharp, setback R+t); wall x 37.5..40 z 5..27.5; bend R 2.5..5 about (42.5, 27.5) (sketch corner = inner virtual sharp, setback R); plate x 42.5..70 z 30..32.5", + "body_count": 1, + "volume_mm3": 12097.621556370217, + "area_mm2": 10412.00210735098, + "center_of_mass": [ + 36.037689993681276, + 25.0, + 15.087581425863405 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 70.0, + 50.0, + 32.5 + ] + }, + "note": "SolidCraft convention: the sketch lines are the sheet face away from the material (material right of travel); thickness grows to the material side" +} diff --git a/tests/oracle/72-sm-contour-flange/recipe.json b/tests/oracle/72-sm-contour-flange/recipe.json new file mode 100644 index 00000000..b5a4c8bd --- /dev/null +++ b/tests/oracle/72-sm-contour-flange/recipe.json @@ -0,0 +1,123 @@ +{ + "id": "72-sm-contour-flange", + "name": "Sheet metal: contour flange", + "description": "Open Z-shaped sketch on XZ (40 / 30 / 30) -> contour flange, width 50 (typed).", + "exercises": [ + "sheet_metal", + "contour_flange", + "bends" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Contour", + "plane": { + "ref": "XZ", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 0.0, + -1.0 + ], + "normal": [ + 0.0, + 1.0, + 0.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0.0, + 0.0 + ] + }, + "end": { + "at": [ + 40.0, + 0.0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 40.0, + 0.0 + ] + }, + "end": { + "at": [ + 40.0, + -30.0 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 40.0, + -30.0 + ] + }, + "end": { + "at": [ + 70.0, + -30.0 + ] + }, + "id": "l3" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "contour", + "name": "ContourFlange", + "profile_curves": [ + "l1", + "l2", + "l3" + ], + "profile_sketch": "Contour", + "distance": 50, + "orientation": "Side 1 (default)", + "direction": "One Side (default): width along the XZ sketch normal (+Y)", + "bend_radius": "rule (2.50 mm = Thickness)", + "rule": "Steel (mm)" + } + ] +} diff --git a/tests/oracle/73-sm-hem/expected.json b/tests/oracle/73-sm-hem/expected.json new file mode 100644 index 00000000..fa334ffb --- /dev/null +++ b/tests/oracle/73-sm-hem/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "68's part (height 20) plus a flat hem on the flange top edge: 180 deg bend, inner radius = hem gap 0.01, outer 2.51, about (y 2.51, z 20), folded toward +y (inside); hem leg 8 - (0.01 + 2.5) = 5.49: y 2.52..5.02, z 14.51..20; extrusion along x 100", + "body_count": 1, + "volume_mm3": 21334.723242251002, + "area_mm2": 17994.473058645817, + "center_of_mass": [ + 50.0, + 21.698805014882137, + 5.264118547850942 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 22.51 + ] + }, + "note": "SolidCraft conventions: hem gap 0.01 mm (rule hem_gap), hem length measured to the outer face of the hem bend (top at z 22.51), hem folds over the flange's inner face." +} diff --git a/tests/oracle/73-sm-hem/recipe.json b/tests/oracle/73-sm-hem/recipe.json new file mode 100644 index 00000000..7ef6b6c3 --- /dev/null +++ b/tests/oracle/73-sm-hem/recipe.json @@ -0,0 +1,204 @@ +{ + "id": "73-sm-hem", + "name": "Sheet metal: flat hem", + "description": "100x60 base + 20 mm edge flange on y=0; flat hem (length 8) on the flange's outer top edge via HemFeatures.", + "exercises": [ + "sheet_metal", + "edge_flange", + "hem" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 100.0, + 0.0, + 2.5 + ], + "point": [ + 50.0, + 0.0, + 2.5 + ] + } + ], + "edge_selection": "top edge at y=0", + "height": 20, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + }, + { + "op": "sm_hem", + "type": "flat", + "edge": { + "type": "line", + "start": [ + 100.0, + -0.0, + 20.0 + ], + "end": [ + 0.0, + -0.0, + 20.0 + ], + "point": [ + 50.0, + -0.0, + 20.0 + ] + }, + "edge_selection": "straight edge at the top of the flange (z max); outer (min y) tried first", + "length": 8, + "flipped": false, + "bend_position": "StartEdge" + } + ] +} diff --git a/tests/oracle/74-sm-unfold-refold/expected.json b/tests/oracle/74-sm-unfold-refold/expected.json new file mode 100644 index 00000000..3b86e80d --- /dev/null +++ b/tests/oracle/74-sm-unfold-refold/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "U channel 80x50 (t 2.5, R 2.5, base y 5..45, flanges z 5..20) with the flat-pattern slot x 35..45, y -12..10 refolded: BA = (pi/2)(R + K t) = 5.654866776, so the slot removes base y 5..10, the whole y=0 bend and the flange from z 5 to 5 + (12 - (BA - 5)) = 16.345133224; x-segments 0..35 / 35..45 / 45..80", + "body_count": 1, + "volume_mm3": 15800.304003966867, + "area_mm2": 13610.326162673397, + "center_of_mass": [ + 40.0, + 25.774257210144707, + 5.531072022389276 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 50.0, + 20.0 + ] + }, + "note": "unfold/refold maps flat distance through the K-factor neutral layer (K 0.44)" +} diff --git a/tests/oracle/74-sm-unfold-refold/recipe.json b/tests/oracle/74-sm-unfold-refold/recipe.json new file mode 100644 index 00000000..c5dfa488 --- /dev/null +++ b/tests/oracle/74-sm-unfold-refold/recipe.json @@ -0,0 +1,350 @@ +{ + "id": "74-sm-unfold-refold", + "name": "Sheet metal: unfold, cut across bend, refold", + "description": "80x50 base + 20 mm flanges on both long edges; unfold all bends (stationary = base); 10x22 slot (x 35..45, y -12..10) cut across the y=0 bend while flat; refold.", + "exercises": [ + "sheet_metal", + "unfold", + "refold", + "cut_across_bend" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 50 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 50.0 + ] + }, + "end": { + "at": [ + 0, + 50 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 50.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 80.0, + 50.0, + 2.5 + ], + "end": [ + 0.0, + 50.0, + 2.5 + ], + "point": [ + 40.0, + 50.0, + 2.5 + ] + }, + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 80.0, + 0.0, + 2.5 + ], + "point": [ + 40.0, + 0.0, + 2.5 + ] + } + ], + "edge_selection": "both long top edges", + "height": 20, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + }, + { + "op": "sm_unfold", + "stationary_face": { + "type": "plane", + "normal_at_point_on_face": [ + 0.0, + 0.0, + -1.0 + ], + "plane_normal_outward": [ + 0.0, + 0.0, + -1.0 + ], + "point": [ + 40.0, + 25.0, + 0.0 + ] + }, + "all_bends": true + }, + { + "op": "sketch", + "name": "SlotSketch", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 35, + -12 + ] + }, + "end": { + "at": [ + 45, + -12 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 45.0, + -12.0 + ] + }, + "end": { + "at": [ + 45, + 10 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 45.0, + 10.0 + ] + }, + "end": { + "at": [ + 35, + 10 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 35.0, + 10.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 35.0, + -12.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Slot", + "operation": "cut", + "profiles": [ + { + "sketch": "SlotSketch", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Body1" + ] + }, + { + "op": "sm_refold", + "unfold": "Unfold1" + } + ] +} diff --git a/tests/oracle/75-sm-bracket-holes/expected.json b/tests/oracle/75-sm-bracket-holes/expected.json new file mode 100644 index 00000000..352f1946 --- /dev/null +++ b/tests/oracle/75-sm-bracket-holes/expected.json @@ -0,0 +1,26 @@ +{ + "source": "analytic", + "method": "base x 0..75, y 5..40, z 0..2.5 (trimmed 5 by each flange's setback); bend 1 (R 2.5..5 about y 5, z 5) x 0..75; flange 1 y 0..2.5, z 5..30, x 0..80; bend 2 (R 2.5..5 about x 75, z 5) y 5..40; flange 2 x 77.5..80, z 5..15, y 5..40; minus two d6 through holes at (25,20), (55,20) in the base. A = sum of prism areas - 2 x 4 joint areas (75t, 75t, 35t, 35t) + hole walls - hole discs", + "body_count": 1, + "volume_mm3": 13916.012042595696, + "area_mm2": 12035.962275939059, + "center_of_mass": [ + 42.447144354989774, + 13.304901335083745, + 7.787102510037218 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 80.0, + 40.0, + 30.0 + ] + }, + "note": "SolidCraft convention: the second flange trims the base under the first bend, so bend 1 stops at x 75 while flange 1's panel runs to x 80 (open corner relief, no fill).", + "known_failure": "#296" +} diff --git a/tests/oracle/75-sm-bracket-holes/recipe.json b/tests/oracle/75-sm-bracket-holes/recipe.json new file mode 100644 index 00000000..7ca403cc --- /dev/null +++ b/tests/oracle/75-sm-bracket-holes/recipe.json @@ -0,0 +1,300 @@ +{ + "id": "75-sm-bracket-holes", + "name": "Sheet metal: bracket with holes for DXF", + "description": "80x40 base, 30 mm flange on y=0 edge and 15 mm flange on x=80 edge; two d6 holes in the base.", + "exercises": [ + "sheet_metal", + "edge_flange", + "holes", + "dxf", + "bend_lines" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 80, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 80.0, + 0.0 + ] + }, + "end": { + "at": [ + 80, + 40 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 80.0, + 40.0 + ] + }, + "end": { + "at": [ + 0, + 40 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 40.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 80.0, + 0.0, + 2.5 + ], + "point": [ + 40.0, + 0.0, + 2.5 + ] + } + ], + "edge_selection": "top edge at y=0", + "height": 30, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 80.0, + 5.0, + 2.5 + ], + "end": [ + 80.0, + 40.0, + 2.5 + ], + "point": [ + 80.0, + 22.5, + 2.5 + ] + } + ], + "edge_selection": "top edge at x=80 of the base", + "height": 15, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + }, + { + "op": "sketch", + "name": "Holes", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "circle", + "center": { + "at": [ + 25, + 20 + ] + }, + "radius": 3, + "id": "c1" + }, + { + "type": "circle", + "center": { + "at": [ + 55, + 20 + ] + }, + "radius": 3, + "id": "c2" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "extrude", + "name": "Holes", + "operation": "cut", + "profiles": [ + { + "sketch": "Holes", + "loops": [ + { + "outer": true, + "curves": [ + "c1" + ] + } + ] + }, + { + "sketch": "Holes", + "loops": [ + { + "outer": true, + "curves": [ + "c2" + ] + } + ] + } + ], + "extent": { + "type": "through_all", + "direction": "positive" + }, + "result_bodies": [ + "Body1" + ] + } + ] +} diff --git a/tests/oracle/76-sm-thickness-variant/expected.json b/tests/oracle/76-sm-thickness-variant/expected.json new file mode 100644 index 00000000..779c94f0 --- /dev/null +++ b/tests/oracle/76-sm-thickness-variant/expected.json @@ -0,0 +1,25 @@ +{ + "source": "analytic", + "method": "final rule thickness 3 (bend radius = Thickness = 3): base y 6..60 x 3; bend annulus R 3..6 about (y 6, z 6); flange y 0..3, z 6..20; extrusion along x 100", + "body_count": 1, + "volume_mm3": 22520.575041173113, + "area_mm2": 16064.12819493887, + "center_of_mass": [ + 50.0, + 24.30326264966137, + 3.788688791962308 + ], + "bbox": { + "min": [ + 0.0, + 0.0, + 0.0 + ], + "max": [ + 100.0, + 60.0, + 20.0 + ] + }, + "note": "the rule's thickness edits regenerate the whole sheet body; only the final 3 mm state matters" +} diff --git a/tests/oracle/76-sm-thickness-variant/recipe.json b/tests/oracle/76-sm-thickness-variant/recipe.json new file mode 100644 index 00000000..8e431c8c --- /dev/null +++ b/tests/oracle/76-sm-thickness-variant/recipe.json @@ -0,0 +1,187 @@ +{ + "id": "76-sm-thickness-variant", + "name": "Sheet metal: thickness change", + "description": "100x60 base + 20 mm flange; rule thickness 2.5 mm, then changed to 1 mm and then to 3 mm after the build (the final state is 3 mm).", + "exercises": [ + "sheet_metal", + "rule", + "thickness", + "recompute" + ], + "units": { + "length": "mm", + "angle": "deg", + "area": "mm2", + "volume": "mm3" + }, + "conventions": { + "world": "right-handed; Z up. XY/XZ/YZ are the origin planes.", + "sketch_frame": "sketch-local 2D coords; world = plane.origin + x*plane.x_dir + y*plane.y_dir (origin in mm). Profile 'loops' list sketch entity ids.", + "point_refs": "'.start' / '.end' / '.center' reuse (share) that existing sketch point; 'at' is its position when referenced.", + "extrude_direction": "positive = along sketch plane normal unless stated", + "selections": "selected faces/edges carry 'point': a world-space point on the face / the edge's parametric midpoint; pick the nearest face/edge to it." + }, + "parameters": [], + "features": [ + { + "op": "sketch", + "name": "Base", + "plane": { + "ref": "XY", + "origin": [ + 0.0, + 0.0, + 0.0 + ], + "x_dir": [ + 1.0, + 0.0, + 0.0 + ], + "y_dir": [ + 0.0, + 1.0, + 0.0 + ], + "normal": [ + 0.0, + 0.0, + 1.0 + ] + }, + "entities": [ + { + "type": "line", + "start": { + "at": [ + 0, + 0 + ] + }, + "end": { + "at": [ + 100, + 0 + ] + }, + "id": "l1" + }, + { + "type": "line", + "start": { + "ref": "l1.end", + "at": [ + 100.0, + 0.0 + ] + }, + "end": { + "at": [ + 100, + 60 + ] + }, + "id": "l2" + }, + { + "type": "line", + "start": { + "ref": "l2.end", + "at": [ + 100.0, + 60.0 + ] + }, + "end": { + "at": [ + 0, + 60 + ] + }, + "id": "l3" + }, + { + "type": "line", + "start": { + "ref": "l3.end", + "at": [ + 0.0, + 60.0 + ] + }, + "end": { + "ref": "l1.start", + "at": [ + 0.0, + 0.0 + ] + }, + "id": "l4" + } + ], + "constraints": [], + "dimensions": [] + }, + { + "op": "sm_flange", + "type": "base", + "name": "BaseFlange", + "profile": { + "sketch": "Base", + "loops": [ + { + "outer": true, + "curves": [ + "l1", + "l2", + "l3", + "l4" + ] + } + ] + }, + "orientation": "Side 1 (default): thickness grows along the sketch normal (+Z)", + "operation": "new body", + "rule": "Steel (mm)" + }, + { + "op": "sm_flange", + "type": "edge", + "edges": [ + { + "type": "line", + "start": [ + 0.0, + 0.0, + 2.5 + ], + "end": [ + 100.0, + 0.0, + 2.5 + ], + "point": [ + 50.0, + 0.0, + 2.5 + ] + } + ], + "edge_selection": "top edge at y=0", + "height": 20, + "angle": 90, + "height_datum": "Outer Faces (default)", + "bend_position": "Inside (default)", + "bend_radius": "rule (default)", + "flip": false + }, + { + "op": "sheet_metal_rule_edit", + "rule": "Steel (mm)", + "sequence": [ + "thickness 1 mm", + "thickness 3 mm" + ] + } + ] +} diff --git a/tests/oracle/README.md b/tests/oracle/README.md new file mode 100644 index 00000000..001e0688 --- /dev/null +++ b/tests/oracle/README.md @@ -0,0 +1,42 @@ +# Reference tests (the oracle) + +Each directory is one case: + +- `recipe.json`: the part, written in SolidCraft's recipe format (sketches in sketch-local + coordinates, features with their parameters, faces and edges picked by a world-space point). + `cargo xtask oracle` replays it through SolidCraft's command engine. +- `expected.json`: what the part must measure, and where those numbers come from. +- `reference.stl` (optional): a fine triangulation of the expected part, used to check the + shape itself (surface distance), not only its totals. + +Run every case with `cargo xtask oracle`; it writes `docs/oracle.md`. + +## expected.json + +```json +{ + "source": "analytic", + "method": "box 40 x 30 x 20: V = abc, A = 2(ab + bc + ca)", + "body_count": 1, + "volume_mm3": 24000.0, + "area_mm2": 5200.0, + "center_of_mass": [20.0, 15.0, 10.0], + "bbox": { "min": [0.0, 0.0, 0.0], "max": [40.0, 30.0, 20.0] }, + "faces": 6 +} +``` + +| Field | Meaning | +|---|---| +| `source` | `"analytic"` (closed-form geometry, worked out by hand; `method` gives the formulas) or `"freecad "` (built from the same recipe by `tools/freecad-oracle/`). | +| `method` | How the numbers were obtained: formulas for analytic cases, the construction for FreeCAD ones. | +| `body_count` | Number of solid bodies. | +| `volume_mm3`, `area_mm2` | Totals over all bodies. | +| `center_of_mass` | Volume-weighted centroid of all bodies (uniform density). | +| `bbox` | Axis-aligned bounding box of all bodies. | +| `faces` | Optional. Only where the geometry fixes the count: a face is a maximal smooth patch of one surface (a full cylinder side is one face; coplanar neighbours are one face). | +| `compare` | Optional. Restricts the comparison to these keys (for example `["volume_mm3", "area_mm2"]` where kernels legitimately build different corner patches); `note` says why. | +| `tolerance` | Optional overrides: `rel` (volume, area; default 1e-3), `abs_mm` (centre of mass and bbox, default 1e-3 × the bbox diagonal), `surface_mm` (STL surface distance). | +| `note` | Optional remarks. | + +No value here was measured in, or exported from, any commercial CAD product. diff --git a/tools/freecad-oracle/.gitignore b/tools/freecad-oracle/.gitignore new file mode 100644 index 00000000..036ce378 --- /dev/null +++ b/tools/freecad-oracle/.gitignore @@ -0,0 +1,3 @@ +squashfs-root/ +*.AppImage +__pycache__/ diff --git a/tools/freecad-oracle/README.md b/tools/freecad-oracle/README.md new file mode 100644 index 00000000..cec7e3ef --- /dev/null +++ b/tools/freecad-oracle/README.md @@ -0,0 +1,57 @@ +# FreeCAD oracle + +Reference values for some of the cases in [`tests/oracle/`](../../tests/oracle/) are computed by +building the case's own `recipe.json` a second time, in a different kernel: FreeCAD +(OpenCASCADE). Those cases have `"source": "freecad "` in their `expected.json`. +The cases with closed-form answers are worked out by hand instead (`"source": "analytic"`, +see [`tools/oracle-analytic/`](../oracle-analytic/)). + +## FreeCAD is an external tool, not a dependency + +FreeCAD is run as a separate program (`freecadcmd`) that executes `build.py` through FreeCAD's +public Python scripting API (Part, PartDesign, Sketcher, MeshPart). SolidCraft does not use, +link, vendor or ship any code, library or binary from FreeCAD or OpenCASCADE, and nothing in +this directory is part of the build. FreeCAD's LGPL licence therefore does not apply to +SolidCraft's code. The scripts here are our own; they were written against FreeCAD's public +API documentation only, never its sources. + +Only values for our own recipes are produced: the numbers in `expected.json` (body count, +volume, area, centre of mass, bounding box) and the triangulated surface in `reference.stl`. + +## Files + +- `build.py`: runs inside FreeCAD. Reads a case's `recipe.json` and builds the part with + FreeCAD's modelling operations, following the meaning SolidCraft gives the recipe + (`apps/solvecraft-cli/src/recipe.rs`): sketches (solved by FreeCAD's sketcher when the recipe + constrains them, otherwise at their recorded coordinates), extrude (distance, symmetric, two + sides, through all, taper), revolve, sweep, loft, holes (simple, drilled tip, counterbore, + countersink), rectangular/circular/path patterns and mirror (each source feature's tool moved + and its operation applied again), combine, shell, draft, fillet and chamfer (edges picked + nearest the recipe's point, tangent chains followed), split body and construction planes. + It then measures the result. +- `emit.py`: prints a result or writes it as `expected.json` / `reference.stl`. +- `run.sh`: the entry point. + +## Running it + +```sh +tools/freecad-oracle/run.sh tests/oracle/17-loft tests/oracle/42-overlapping-patterns # print +tools/freecad-oracle/run.sh --write tests/oracle/17-loft # write +``` + +Without `--write` each case prints one line. With `--write` it writes `/expected.json` +(`source`, `method`, `body_count`, `volume_mm3`, `area_mm2`, `center_of_mass`, `bbox` from +`optimalBoundingBox()`) and `/reference.stl` (binary, linear deflection 0.005 to 0.02 mm, +at most about 400 KB; when that is not possible the STL is skipped and `note` says so). It never +overwrites an `expected.json` whose source is `analytic`. Per-case comparison settings +(`compare`, `tolerance`, `note`) live in `CASE_META` in `build.py`. + +`freecadcmd` is found through `$FREECADCMD`, then `freecadcmd` on `PATH`, then an AppImage +extracted in this directory (`squashfs-root/`, ignored by git). Locally: install FreeCAD 1.x from your distribution or extract the +AppImage (`./FreeCAD_*.AppImage --appimage-extract`) and point `FREECADCMD` at +`squashfs-root/usr/bin/freecadcmd`. In CI (Debian/Ubuntu): `apt install freecad`, then run the +script; it needs no display. + +The values were produced with FreeCAD 1.1.4. A different FreeCAD version may differ in the last +digits; regenerate only when a recipe changes, and check the new values against SolidCraft +(`solvecraft-cli oracle`) before committing them. diff --git a/tools/freecad-oracle/build.py b/tools/freecad-oracle/build.py new file mode 100644 index 00000000..eef0f5b9 --- /dev/null +++ b/tools/freecad-oracle/build.py @@ -0,0 +1,1402 @@ +# FreeCAD oracle builder for SolidCraft reference cases (tests/oracle//recipe.json). +# +# Run under FreeCAD's interpreter (freecadcmd); see run.sh. FreeCAD is used only as an external +# program through its public Python scripting API (Part, PartDesign, Sketcher, Mesh/MeshPart). +# +# Inputs (environment): +# ORACLE_CASE case directory (contains recipe.json) +# ORACLE_OUT path of a JSON file to write the measured result to +# ORACLE_STL optional: path of a binary STL to write (reference.stl) +# +# The recipe format and its meaning are SolidCraft's (apps/solvecraft-cli/src/recipe.rs and the +# engine in crates/); this file re-implements that meaning with FreeCAD's modelling operations. + +import json +import math +import os +import re +import sys +import traceback + +import FreeCAD as App +import Part +from FreeCAD import Vector as V + +TOL = 1e-7 +BIG = 1000.0 + +# Per-case additions to expected.json: "compare", "tolerance", "note", "method_extra". +# (Empty: every case written so far is built by the generic mapping and agrees with SolidCraft +# within the default tolerances, so no comparison is relaxed.) +CASE_META = {} + + +def vec(a): + return V(float(a[0]), float(a[1]), float(a[2]) if len(a) > 2 else 0.0) + + +class RecipeError(Exception): + pass + + +# -------------------------------------------------------------------------------------------- +# Expressions (user parameters) +# -------------------------------------------------------------------------------------------- + +class Exprs: + def __init__(self, params): + self.vals = {} + for p in params or []: + self.vals[p["name"]] = self.eval(p.get("expression", p.get("value"))) + + def eval(self, v, kind="length"): + if v is None: + return None + if isinstance(v, (int, float)): + return float(v) + s = str(v).strip() + s = re.sub(r"(?<=[0-9.\s)])\s*(mm|deg|°)\b", "", s) + s = s.replace("°", "") + names = dict(self.vals) + names.update({"pi": math.pi, "sqrt": math.sqrt, "sin": math.sin, "cos": math.cos, "tan": math.tan}) + return float(eval(s, {"__builtins__": {}}, names)) + + +# -------------------------------------------------------------------------------------------- +# Sketches +# -------------------------------------------------------------------------------------------- + +class Plane: + def __init__(self, origin, xd, yd, normal=None): + self.o = vec(origin) + self.x = vec(xd).normalize() + self.y = vec(yd).normalize() + n = self.x.cross(self.y) + self.n = n.normalize() + if normal is not None: + given = vec(normal) + if given.Length > 0 and given.normalize().dot(self.n) < 0.999: + raise RecipeError("sketch plane normal disagrees with x_dir x y_dir") + + def w(self, p): + return self.o + self.x * float(p[0]) + self.y * float(p[1]) + + def placement(self): + m = App.Matrix(self.x.x, self.y.x, self.n.x, self.o.x, + self.x.y, self.y.y, self.n.y, self.o.y, + self.x.z, self.y.z, self.n.z, self.o.z, + 0, 0, 0, 1) + return App.Placement(m) + + +def circumcenter(a, b, c): + """2D circumcentre of three points (tuples).""" + ax, ay = a + bx, by = b + cx, cy = c + d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) + if abs(d) < 1e-14: + raise RecipeError("collinear 3-point arc") + ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d + uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d + return (ux, uy) + + +def ccw3(a, b, c): + return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0 + + +class Sketch: + """A solved sketch: world-space edges per entity id and named points.""" + + def __init__(self, f, ex): + pl = f["plane"] + self.name = f.get("name") + self.plane = Plane(pl.get("origin", [0, 0, 0]), pl["x_dir"], pl["y_dir"], pl.get("normal")) + self.ents = {e["id"]: e for e in f.get("entities", [])} + self.order = [e["id"] for e in f.get("entities", [])] + self.edges = {} # id -> Part.Edge (world) + self.pts = {"origin": (0.0, 0.0)} # "id.start" etc -> local 2D + self.ex = ex + if f.get("constraints") or f.get("dimensions"): + self.solved = True + self._solve_with_sketcher(f) + else: + self.solved = False + self._direct() + + # -- direct (unconstrained): coordinates as recorded, shared points reused ----------------- + def _p(self, spec): + if spec is None: + return None + if isinstance(spec, list): + return (float(spec[0]), float(spec[1])) + r = spec.get("ref") + if r and r in self.pts: + return self.pts[r] + at = spec.get("at") + return (float(at[0]), float(at[1])) + + def _direct(self): + P = self.plane + for i in self.order: + e = self.ents[i] + t = e["type"] + if t == "line": + a, b = self._p(e["start"]), self._p(e["end"]) + self.pts[i + ".start"], self.pts[i + ".end"] = a, b + self.edges[i] = Part.LineSegment(P.w(a), P.w(b)).toShape() + elif t == "circle": + c = self._p(e["center"]) + r = self.ex.eval(e["radius"]) + self.pts[i + ".center"] = c + self.edges[i] = Part.Circle(P.w(c), P.n, r).toShape() + elif t in ("arc_three_point", "arc") and e.get("center") is None: + a, b = self._p(e["start"]), self._p(e["end"]) + m = self._p(e.get("mid") or e.get("through")) + self.pts[i + ".start"], self.pts[i + ".end"] = a, b + self.pts[i + ".center"] = circumcenter(a, m, b) + self.edges[i] = Part.Arc(P.w(a), P.w(m), P.w(b)).toShape() + elif t in ("arc_center_start_sweep", "arc"): + c, a = self._p(e["center"]), self._p(e["start"]) + r = math.hypot(a[0] - c[0], a[1] - c[1]) + a0 = math.atan2(a[1] - c[1], a[0] - c[0]) + if t == "arc": + b = self._p(e["end"]) + a1 = math.atan2(b[1] - c[1], b[0] - c[0]) + sw = (a1 - a0) % (2 * math.pi) + else: + sw = math.radians(self.ex.eval(e.get("sweep_deg", e.get("sweep")))) + b = (c[0] + r * math.cos(a0 + sw), c[1] + r * math.sin(a0 + sw)) + m = (c[0] + r * math.cos(a0 + sw / 2), c[1] + r * math.sin(a0 + sw / 2)) + self.pts[i + ".start"], self.pts[i + ".end"], self.pts[i + ".center"] = a, b, c + self.edges[i] = Part.Arc(P.w(a), P.w(m), P.w(b)).toShape() + elif t == "point": + self.pts[i] = self.pts[i + ".start"] = self._p(e.get("at") if isinstance(e.get("at"), list) else e) + elif t == "fitted_spline": + fp = e.get("fit_points", []) + if fp and len(fp[0]) == 3: + self.edges[i] = ("helix3d", [vec(p) for p in fp]) + else: + pts = [P.w(p) for p in fp] + bs = Part.BSplineCurve() + bs.interpolate(pts) + self.edges[i] = bs.toShape() + else: + raise RecipeError("sketch entity type %s not supported" % t) + + # -- constrained: FreeCAD's sketch solver --------------------------------------------------- + def _solve_with_sketcher(self, f): + import Sketcher + doc = App.newDocument("sk") + sk = doc.addObject("Sketcher::SketchObject", "S") + gid = {} # entity id -> geo index + pos = {} # "id.start" -> (geo, posid) + pos["origin"] = (-1, 1) + coinc = [] # (refname_a, refname_b) + swapped = {} + + def at(spec): + if isinstance(spec, list): + return (float(spec[0]), float(spec[1])) + a = spec.get("at") + return (float(a[0]), float(a[1])) + + def V2(p): + return V(p[0], p[1], 0) + + for i in self.order: + e = self.ents[i] + t = e["type"] + cons = bool(e.get("construction", False)) + if t == "line": + g = Part.LineSegment(V2(at(e["start"])), V2(at(e["end"]))) + k = sk.addGeometry(g, cons) + pos[i + ".start"], pos[i + ".end"] = (k, 1), (k, 2) + for nm in ("start", "end"): + if isinstance(e[nm], dict) and e[nm].get("ref"): + coinc.append((i + "." + nm, e[nm]["ref"])) + elif t == "circle": + g = Part.Circle(V2(at(e["center"])), V(0, 0, 1), self.ex.eval(e["radius"])) + k = sk.addGeometry(g, cons) + pos[i + ".center"] = (k, 3) + if isinstance(e["center"], dict) and e["center"].get("ref"): + coinc.append((i + ".center", e["center"]["ref"])) + elif t in ("arc_three_point", "arc_center_start_sweep", "arc"): + if t == "arc_center_start_sweep" or (t == "arc" and e.get("center") is not None): + c, a = at(e["center"]), at(e["start"]) + r = math.hypot(a[0] - c[0], a[1] - c[1]) + a0 = math.atan2(a[1] - c[1], a[0] - c[0]) + if t == "arc": + b = at(e["end"]) + sw = (math.atan2(b[1] - c[1], b[0] - c[0]) - a0) % (2 * math.pi) + else: + sw = math.radians(self.ex.eval(e.get("sweep_deg", e.get("sweep")))) + ccw = sw > 0 + s0, s1 = (a0, a0 + sw) if ccw else (a0 + sw, a0) + else: + a, b = at(e["start"]), at(e["end"]) + m = at(e.get("mid") if isinstance(e.get("mid"), list) else (e.get("mid") or e.get("through"))) + c = circumcenter(a, m, b) + r = math.hypot(a[0] - c[0], a[1] - c[1]) + ccw = ccw3(a, m, b) + aa = math.atan2(a[1] - c[1], a[0] - c[0]) + bb = math.atan2(b[1] - c[1], b[0] - c[0]) + if ccw: + s0, s1 = aa, aa + (bb - aa) % (2 * math.pi) + else: + s0, s1 = bb, bb + (aa - bb) % (2 * math.pi) + g = Part.ArcOfCircle(Part.Circle(V2(c), V(0, 0, 1), r), s0, s1) + k = sk.addGeometry(g, cons) + swapped[i] = not ccw + pos[i + ".start"] = (k, 1) if ccw else (k, 2) + pos[i + ".end"] = (k, 2) if ccw else (k, 1) + pos[i + ".center"] = (k, 3) + for nm in ("start", "end", "center"): + if isinstance(e.get(nm), dict) and e[nm].get("ref"): + coinc.append((i + "." + nm, e[nm]["ref"])) + elif t == "point": + p = e["at"] if isinstance(e.get("at"), list) else at(e) + k = sk.addGeometry(Part.Point(V2(p)), cons) + pos[i] = pos[i + ".start"] = (k, 1) + else: + raise RecipeError("constrained sketch entity type %s not supported" % t) + gid[i] = k + + # union-find of points known to coincide + parent = {} + + def find(x): + parent.setdefault(x, x) + while parent[x] != x: + x = parent[x] + return x + + def union(a, b): + parent[find(a)] = find(b) + + def key(r): + return pos[r] if r in pos else None + + explicit = [] + for c in f.get("constraints", []): + if c["type"].lower() == "coincident": + a, b = c["refs"] + if a in pos and b in pos: + explicit.append((a, b)) + for a, b in coinc + explicit: + union(key(a), key(b)) + + cons_list = [] + drop_coinc = set() + + def geo_of(r): + if r in gid: + return gid[r] + return pos[r][0] + + def ispt(r): + return r in pos and r not in gid + + def ptof(r): + # a circle/arc named where a point is wanted: its centre + if r in pos: + return pos[r] + if r + ".center" in pos: + return pos[r + ".center"] + raise RecipeError("unknown point " + r) + + def ends(eid): + out = [] + for nm in ("start", "end"): + if eid + "." + nm in pos: + out.append(eid + "." + nm) + return out + + for c in f.get("constraints", []): + t = c["type"].lower() + r = c.get("refs", []) + if t in ("horizontal", "vertical") and len(r) == 1: + cons_list.append(Sketcher.Constraint("Horizontal" if t == "horizontal" else "Vertical", gid[r[0]])) + elif t in ("horizontal", "vertical", "horizontal_points", "vertical_points"): + mode = "Horizontal" if t.startswith("horizontal") else "Vertical" + (g1, p1), (g2, p2) = ptof(r[0]), ptof(r[1]) + cons_list.append(Sketcher.Constraint(mode, g1, p1, g2, p2)) + elif t in ("coincident", "point_on_curve"): + a, b = r + if ispt(a) and ispt(b): + coinc.append((a, b)) + else: + if not ispt(a): + a, b = b, a + g, p = ptof(a) + cons_list.append(Sketcher.Constraint("PointOnObject", g, p, gid[b])) + elif t == "midpoint": + a, b = r + if not ispt(a): + a, b = b, a + g, p = ptof(a) + cons_list.append(Sketcher.Constraint("Symmetric", gid[b], 1, gid[b], 2, g, p)) + elif t in ("symmetric", "symmetry"): + a, b, ln = r + if ispt(a) and ispt(b): + (g1, p1), (g2, p2) = ptof(a), ptof(b) + cons_list.append(Sketcher.Constraint("Symmetric", g1, p1, g2, p2, gid[ln])) + elif self.ents[a]["type"] == "line" and self.ents[b]["type"] == "line": + # two lines: their end points mirror + for nm in ("start", "end"): + (g1, p1), (g2, p2) = pos[a + "." + nm], pos[b + "." + nm] + cons_list.append(Sketcher.Constraint("Symmetric", g1, p1, g2, p2, gid[ln])) + else: + # two circles/arcs: mirrored centres and equal radii + (g1, p1), (g2, p2) = ptof(a), ptof(b) + cons_list.append(Sketcher.Constraint("Symmetric", g1, p1, g2, p2, gid[ln])) + cons_list.append(Sketcher.Constraint("Equal", gid[a], gid[b])) + elif t == "tangent": + a, b = r + pair = None + for pa in ends(a): + for pb in ends(b): + if find(pos[pa]) == find(pos[pb]): + pair = (pa, pb) + if pair: + (g1, p1), (g2, p2) = pos[pair[0]], pos[pair[1]] + cons_list.append(Sketcher.Constraint("Tangent", g1, p1, g2, p2)) + drop_coinc.add(frozenset(pair)) + else: + cons_list.append(Sketcher.Constraint("Tangent", gid[a], gid[b])) + elif t == "equal": + cons_list.append(Sketcher.Constraint("Equal", gid[r[0]], gid[r[1]])) + elif t == "parallel": + cons_list.append(Sketcher.Constraint("Parallel", gid[r[0]], gid[r[1]])) + elif t == "perpendicular": + cons_list.append(Sketcher.Constraint("Perpendicular", gid[r[0]], gid[r[1]])) + elif t == "concentric": + coinc.append((r[0] + ".center", r[1] + ".center")) + elif t == "collinear": + cons_list.append(Sketcher.Constraint("Parallel", gid[r[0]], gid[r[1]])) + cons_list.append(Sketcher.Constraint("PointOnObject", gid[r[1]], 1, gid[r[0]])) + elif t == "fix": + cons_list.append(Sketcher.Constraint("Block", gid[r[0]])) + else: + raise RecipeError("constraint %s not supported" % t) + + def cur(gp): + g, p = gp + if g == -1: + return (0.0, 0.0) + v = sk.getPoint(g, p) + return (v.x, v.y) + + for d in f.get("dimensions", []): + t = d["type"].lower() + r = d.get("refs", d.get("entities")) + val = self.ex.eval(d["value"]) + ori = d.get("orientation", "aligned") + if t in ("distance", "length"): + if len(r) == 1: + r = [r[0] + ".start", r[0] + ".end"] + A, B = ptof(r[0]), ptof(r[1]) + pa, pb = cur(A), cur(B) + if ori == "horizontal": + if pb[0] < pa[0]: + A, B = B, A + cons_list.append(Sketcher.Constraint("DistanceX", A[0], A[1], B[0], B[1], val)) + elif ori == "vertical": + if pb[1] < pa[1]: + A, B = B, A + cons_list.append(Sketcher.Constraint("DistanceY", A[0], A[1], B[0], B[1], val)) + else: + cons_list.append(Sketcher.Constraint("Distance", A[0], A[1], B[0], B[1], val)) + elif t == "offset": + a, b = r + if not ispt(a) and a + ".center" not in pos or a in gid and self.ents[a]["type"] == "line": + a, b = b, a + g, p = ptof(a) + cons_list.append(Sketcher.Constraint("Distance", g, p, gid[b], val)) + elif t == "radius": + cons_list.append(Sketcher.Constraint("Radius", gid[r[0]], val)) + elif t == "diameter": + cons_list.append(Sketcher.Constraint("Diameter", gid[r[0]], val)) + elif t == "angle": + g1, g2 = gid[r[0]], gid[r[1]] + d1 = sk.Geometry[g1].EndPoint - sk.Geometry[g1].StartPoint + d2 = sk.Geometry[g2].EndPoint - sk.Geometry[g2].StartPoint + curang = math.atan2(d1.x * d2.y - d1.y * d2.x, d1.x * d2.x + d1.y * d2.y) + v = math.radians(val) + cands = [v, -v, math.pi - v, -(math.pi - v)] + best = min(cands, key=lambda q: abs(math.remainder(q - curang, 2 * math.pi))) + cons_list.append(Sketcher.Constraint("Angle", g1, g2, best)) + else: + raise RecipeError("dimension %s not supported" % t) + + seen = set() + for a, b in coinc: + if frozenset((a, b)) in drop_coinc: + continue + A, B = key(a), key(b) + if A is None or B is None: + raise RecipeError("unknown point ref %s / %s" % (a, b)) + k = frozenset((A, B)) + if k in seen or A == B: + continue + seen.add(k) + cons_list.insert(0, Sketcher.Constraint("Coincident", A[0], A[1], B[0], B[1])) + sk.addConstraint(cons_list) + rc = sk.solve() + doc.recompute() + if rc != 0: + raise RecipeError("sketch %s: FreeCAD sketch solver failed (%d)" % (self.name, rc)) + P = self.plane + M = P.placement().toMatrix() + for i in self.order: + g = sk.Geometry[gid[i]] + e = self.ents[i] + if e["type"] == "point": + p = g.X, g.Y + self.pts[i] = self.pts[i + ".start"] = (p[0], p[1]) + continue + sh = g.toShape() + sh.transformShape(M) + self.edges[i] = sh + for nm in ("start", "end", "center"): + if i + "." + nm in pos: + v = sk.getPoint(*pos[i + "." + nm]) + self.pts[i + "." + nm] = (v.x, v.y) + App.closeDocument(doc.Name) + + # -- profiles -------------------------------------------------------------------------------- + def loop_wire(self, ids): + edges = [] + for i in ids: + e = self.edges.get(i) + if e is None: + raise RecipeError("unknown curve %s in sketch %s" % (i, self.name)) + edges.append(e.copy()) + w = Part.Wire(Part.__sortEdges__(edges)) + if not w.isClosed(): + # fix tiny gaps (recorded coordinates rounded) + w = Part.Wire(Part.__sortEdges__(edges)) + w.fixWire(None, 1e-5) + if not w.isClosed(): + raise RecipeError("loop %s of sketch %s is not closed" % (ids, self.name)) + return w + + def regions(self): + """The sketch's minimal regions (faces of the arrangement of its curves), each with the + set of curve ids its outer boundary runs along.""" + if getattr(self, "_regions", None) is not None: + return self._regions + import BOPTools.SplitAPI as SA + ids = [i for i in self.order if i in self.edges and not isinstance(self.edges[i], tuple) + and not self.ents[i].get("construction")] + edges = [self.edges[i] for i in ids] + c = self.plane.o + big = Part.Plane(c, self.plane.n).toShape(-1e4, 1e4, -1e4, 1e4) + frag = SA.booleanFragments([big] + edges, "Standard", 1e-7) + out = [] + for fc in frag.Faces: + ow = fc.OuterWire + if any(v.Point.distanceToPoint(c) > 5e3 for v in ow.Vertexes): + continue # the unbounded outside + used = set() + for e in ow.Edges: + m = e.valueAt((e.FirstParameter + e.LastParameter) / 2) + for i, x in zip(ids, edges): + if x.distToShape(Part.Vertex(m))[0] < 1e-6: + used.add(i) + out.append((fc, used)) + self._regions = out + return out + + def profile_face(self, prof): + try: + return self._profile_face_loops(prof) + except Exception: + pass + # Loops that are not closed chains of whole curves (e.g. pieces of circles between + # tangent lines): the region whose outer boundary runs along exactly these curves. + want = set(c for lp in prof.get("loops", []) if lp.get("outer", True) for c in lp["curves"]) + hits = [fc for fc, used in self.regions() if used == want] + if len(hits) != 1: + raise RecipeError("profile %s of sketch %s matches %d regions" % (sorted(want), self.name, len(hits))) + return [hits[0]] + + def _profile_face_loops(self, prof): + outer, inner = None, [] + for lp in prof.get("loops", []): + if len(set(lp["curves"])) != len(lp["curves"]): + raise RecipeError("curve repeated in a loop") + if len(lp["curves"]) > 1 and any(self.edges[c].isClosed() for c in lp["curves"]): + raise RecipeError("a full circle in a multi-curve loop") + f = Part.Face(self.loop_wire(lp["curves"])) + if lp.get("outer", True): + outer = f if outer is None else outer.fuse(f) + else: + inner.append(f) + for h in inner: + outer = outer.cut(h) + faces = outer.Faces + return faces + + +# -------------------------------------------------------------------------------------------- +# The model +# -------------------------------------------------------------------------------------------- + +def xform(shape, m): + """Rigid motion or reflection of a shape (exact; no conversion to B-splines).""" + if m.determinant() < 0: + # reflection: m = mirror about a plane; recover it (n from the eigenvector of -1) + import numpy + a = numpy.array([[m.A11, m.A12, m.A13], [m.A21, m.A22, m.A23], [m.A31, m.A32, m.A33]]) + w, vv = numpy.linalg.eig(a) + k = int(numpy.argmin(w.real)) + n = V(*[float(x) for x in vv[:, k].real]).normalize() + t = V(m.A14, m.A24, m.A34) + o = n * (t.dot(n) / 2) + return shape.mirror(o, n) + s = shape.copy() + s.transformShape(m) + return s + + +def solids_of(s): + return list(s.Solids) if s is not None else [] + + +def compound(shapes): + sol = [] + for s in shapes: + sol += solids_of(s) + return Part.makeCompound(sol) + + +def refine(s): + try: + # removeSplitter() can damage the shape it is called on: work on a deep copy + r = s.copy().removeSplitter() + if r.isValid() and s.isValid() and abs(r.Volume - s.Volume) < 1e-6 * max(1.0, abs(s.Volume)): + return r + except Exception: + pass + return s + + +def as_solid_shape(s): + sol = s.Solids + if len(sol) == 1: + return sol[0] + return Part.makeCompound(sol) + + +def nearest(items, p, key=None): + vp = Part.Vertex(p) + best, bd = None, None + for it in items: + d = (key(it) if key else it).distToShape(vp)[0] + if bd is None or d < bd - 1e-9: + best, bd = it, d + return best, bd + + +def edge_tangent_at(e, v): + """Unit tangent of edge e at vertex point v, oriented along the edge.""" + u = e.FirstParameter if (e.Vertexes[0].Point - v).Length < (e.Vertexes[-1].Point - v).Length else e.LastParameter + t = e.tangentAt(u) + return t.normalize() if t.Length > 0 else t + + +def tangent_chain(shape, seeds): + """Grow edge selection along G1-continuous neighbours.""" + edges = list(shape.Edges) + sel = [e for e in seeds] + changed = True + while changed: + changed = False + for e in edges: + if any(e.isSame(s) for s in sel): + continue + for s in sel: + for va in e.Vertexes: + for vb in s.Vertexes: + if va.isSame(vb): + ta = edge_tangent_at(e, va.Point) + tb = edge_tangent_at(s, vb.Point) + if abs(abs(ta.dot(tb)) - 1) < 1e-6: + sel.append(e) + changed = True + break + if changed: + break + if changed: + break + return sel + + +class Model: + def __init__(self, recipe): + self.r = recipe + self.ex = Exprs(recipe.get("parameters")) + self.sketches = {} + self.planes = { + "XY": (V(0, 0, 0), V(0, 0, 1)), + "XZ": (V(0, 0, 0), V(0, 1, 0)), + "YZ": (V(0, 0, 0), V(1, 0, 0)), + } + self.bodies = {} # name -> shape + self.order = [] + self.feats = {} # feature name -> replay record (for patterns / mirror) + self.notes = [] + + # ---- bodies -------------------------------------------------------------------------------- + def set_body(self, name, shape): + if name not in self.bodies: + self.order.append(name) + self.bodies[name] = shape + + def all_shape(self): + return compound([self.bodies[n] for n in self.order if self.bodies.get(n) is not None]) + + def size(self): + s = self.all_shape() + if not s.Solids: + return 100.0 + return s.BoundBox.DiagonalLength + + def targets(self, f, tool=None): + names = [n for n in f.get("result_bodies", []) if n in self.bodies] + if names: + return names[:1] if f.get("operation") == "join" else names + if tool is not None: + hit = [n for n in self.order if self.bodies[n] is not None and self.bodies[n].common(tool).Volume > 1e-9] + if hit: + return hit + return list(self.order) + + def apply(self, op, tools, targets, new_name=None): + tool = tools[0] + for t in tools[1:]: + tool = tool.fuse(t) + if op == "new": + self.set_body(new_name or "Body%d" % (len(self.order) + 1), as_solid_shape(refine(tool))) + return + if op == "join": + if not targets: + self.set_body(new_name or "Body%d" % (len(self.order) + 1), tool) + return + n0 = targets[0] + s = self.bodies[n0] + for n in targets[1:]: + s = s.fuse(self.bodies.pop(n)) + self.order.remove(n) + self.bodies[n0] = as_solid_shape(refine(s.fuse(tool))) + return + for n in targets: + s = self.bodies[n] + if op == "cut": + r = s.cut(tool) + elif op == "intersect": + r = s.common(tool) + else: + raise RecipeError("operation " + op) + self.bodies[n] = as_solid_shape(refine(r)) + + # ---- selections ------------------------------------------------------------------------------ + def pick_edges(self, shape, f, transform=None): + out = [] + + def tp(v): + return transform.multiply(v) if transform is not None else v + + for e in f.get("edges", []): + p = vec(e.get("point") or e.get("mid")) + if transform is not None: + p = transform.multiply(p) + best, d = nearest(shape.Edges, p) + # ties (the point sits on a vertex shared with other edges, e.g. a cylinder seam): + # prefer the edge that also passes through the recipe's start/end and is the same kind + vp = Part.Vertex(p) + cands = [x for x in shape.Edges if x.distToShape(vp)[0] <= d + 1e-6] + if len(cands) > 1: + kind = {"line": "Line", "circle": "Circle", "arc": "Circle"}.get(e.get("type")) + + def score(x): + sc = 0.0 + for k in ("start", "end", "center"): + if k in e and k != "center": + sc += x.distToShape(Part.Vertex(tp(vec(e[k]))))[0] + if kind and x.Curve.__class__.__name__ != kind: + sc += 1e6 + return sc + + best = min(cands, key=score) + if d > 1e-3 * max(1.0, self.size()) + 1e-3: + self.notes.append("edge pick at %s is %.3g mm from the nearest edge" % (p, d)) + sel = [best] + # The recipe's edge runs start..end; if FreeCAD split it, take the G1 neighbours that + # complete it. + if "start" in e and "end" in e: + a, b = tp(vec(e["start"])), tp(vec(e["end"])) + closed = (a - b).Length < 1e-6 + + def spans(es): + w = es + vs = [] + for x in w: + vs += [v.Point for v in x.Vertexes] + if closed: + # a closed run: a closed edge, or every vertex used twice + if len(es) == 1 and es[0].isClosed(): + return True + return all(sum(1 for q in vs if (q - v).Length < 1e-6) % 2 == 0 for v in vs) + ok_a = any((q - a).Length < 1e-4 for q in vs) + ok_b = any((q - b).Length < 1e-4 for q in vs) + return ok_a and ok_b + + if not spans(sel) and e.get("type") in ("line", "arc", "circle", "nurbs"): + sel = tangent_chain(shape, sel) + if f.get("tangent_chain"): + sel = tangent_chain(shape, sel) + for s in sel: + if not any(s.isSame(o) for o in out): + out.append(s) + return out + + def pick_face(self, shape, p): + best, d = nearest(shape.Faces, vec(p)) + return best + + def body_with(self, p): + best, d = None, None + for n in self.order: + s = self.bodies[n] + if s is None: + continue + dd = s.distToShape(Part.Vertex(p))[0] + if d is None or dd < d: + best, d = n, dd + return best + + # ---- features -------------------------------------------------------------------------------- + def profiles(self, f): + profs = f.get("profiles") + if profs is None and f.get("profile") is not None: + profs = [f["profile"]] + faces = [] + sk = None + for p in profs or []: + sk = self.sketches[p["sketch"]] + faces += sk.profile_face(p) + if not faces: + raise RecipeError("feature %s: no profiles" % f.get("name")) + return faces, sk + + def extrude_tools(self, f): + faces, sk = self.profiles(f) + n = sk.plane.n + e = f.get("extent", {}) + ty = e.get("type", "distance") + d = self.ex.eval(e.get("distance", f.get("distance"))) + direction = e.get("direction", "positive") + if ty == "symmetric": + if e.get("is_full_length"): + d = d / 2 + lo, hi = -d, d + elif ty == "two_sides": + lo, hi = -self.ex.eval(e.get("side2_opposite", e.get("side2"))), self.ex.eval(e.get("side1")) + elif ty == "through_all": + L = 4 * self.size() + BIG + lo, hi = (0, L) if direction == "positive" else (-L, 0) + if direction in ("both", "symmetric"): + lo, hi = -L, L + else: + lo, hi = (0, d) if direction == "positive" else (-d, 0) + if direction == "symmetric": + lo, hi = -d, d + taper = e.get("taper_deg") + tools = [] + for fc in faces: + if taper: + if lo != 0: + raise RecipeError("taper only from the sketch plane") + tools.append(self.tapered(fc, n, hi, math.radians(self.ex.eval(taper)))) + continue + g = fc.copy() + g.translate(n * lo) + tools.append(g.extrude(n * (hi - lo))) + return tools + + def tapered(self, face, n, length, ang): + d = length * math.tan(ang) + bottom = face.OuterWire + off = Part.Face(bottom).makeOffset2D(d, 2, False, False, False) + top = off.OuterWire.copy() + top.translate(n * length) + solid = Part.makeLoft([bottom, top], True, True) + for h in face.Wires[1:]: + hoff = Part.Face(h).makeOffset2D(-d, 2, False, False, False).OuterWire.copy() + hoff.translate(n * length) + solid = solid.cut(Part.makeLoft([h, hoff], True, True)) + return solid + + def revolve_tools(self, f): + faces, sk = self.profiles(f) + a = f.get("axis") + if isinstance(a, dict) and a.get("dir") is not None: + o, d = vec(a.get("origin", [0, 0, 0])), vec(a["dir"]) + else: + ln = a.get("line", a.get("ref")) if isinstance(a, dict) else a + ed = sk.edges[ln] + o, d = ed.Vertexes[0].Point, ed.Vertexes[-1].Point - ed.Vertexes[0].Point + ang = self.ex.eval(f.get("angle", 360)) + return [fc.revolve(o, d, ang) for fc in faces] + + def sweep_tools(self, f): + faces, sk = self.profiles(f) + path = f["path"] + psk = self.sketches[path["sketch"]] + ents = [psk.edges[c] for c in path["curves"]] + if isinstance(ents[0], tuple) and ents[0][0] == "helix3d": + return [self.helix_sweep(faces, ents[0][1])] + pw = Part.Wire(Part.__sortEdges__([e.copy() for e in ents])) + tools = [] + for fc in faces: + outer = pw.makePipeShell([fc.OuterWire], True, True) + for h in fc.Wires[1:]: + outer = outer.cut(pw.makePipeShell([h], True, True)) + tools.append(outer) + return tools + + def helix_sweep(self, faces, pts): + # The fitted 3D spline of the recipe is read as the helix it samples (as SolidCraft does). + n = len(pts) + # least squares circle in xy + sx = sy = sxx = syy = sxy = sxz = syz = sz = 0.0 + A = [[0.0] * 3 for _ in range(3)] + bvec = [0.0] * 3 + for p in pts: + row = [p.x, p.y, 1.0] + rhs = -(p.x * p.x + p.y * p.y) + for i in range(3): + for j in range(3): + A[i][j] += row[i] * row[j] + bvec[i] += row[i] * rhs + import numpy + D, E, F = numpy.linalg.solve(numpy.array(A), numpy.array(bvec)) + cx, cy = -D / 2, -E / 2 + rm = sum(math.hypot(p.x - cx, p.y - cy) for p in pts) / n + tot = 0.0 + prev = math.atan2(pts[0].y - cy, pts[0].x - cx) + start = prev + for p in pts[1:]: + a = math.atan2(p.y - cy, p.x - cx) + d = math.remainder(a - prev, 2 * math.pi) + tot += d + prev = a + turns = abs(tot) / (2 * math.pi) + rise = pts[-1].z - pts[0].z + pitch = abs(rise) / turns + lefthand = (tot < 0) != (rise < 0) + h = Part.makeHelix(pitch, abs(rise), rm, 0, lefthand) + h.rotate(V(0, 0, 0), V(0, 0, 1), math.degrees(start)) + h.translate(V(cx, cy, pts[0].z)) + if rise < 0: + raise RecipeError("downward helix not supported") + hw = Part.Wire(h.Edges) + tools = [] + for fc in faces: + tools.append(hw.makePipeShell([fc.OuterWire], True, True)) + return tools[0] + + def loft_tools(self, f): + secs = [] + for s in f["sections"]: + sk = self.sketches[s["sketch"]] + if s.get("point") is not None: + if s.get("world"): + secs.append(Part.Vertex(vec(s["world"]))) + else: + secs.append(Part.Vertex(sk.plane.w(sk.pts[s["point"]]))) + continue + loops = s.get("loops", []) + w = sk.loop_wire(loops[0]["curves"]) + secs.append(w) + ruled = bool(f.get("ruled", False)) + return [Part.makeLoft(secs, True, ruled, False)] + + def hole_tools(self, f, p, d): + r = self.ex.eval(f["diameter"]) / 2 + size = self.size() + top = max(size * 0.01, 0.1) + through = f.get("extent") == "through_all" or f.get("depth") is None + depth = 4 * size + BIG if through else self.ex.eval(f["depth"]) + ty = f.get("hole_type", "simple") + tip = f.get("tip_angle") + tools = [] + start = p - d * top + + def cyl(rad, dep): + return Part.makeCylinder(rad, dep + top, start, d) + + if ty == "counterbore": + rc = self.ex.eval(f["counterbore_diameter"]) / 2 + dc = self.ex.eval(f["counterbore_depth"]) + tools.append(cyl(rc, dc)) + tools.append(cyl(r, depth)) + elif ty == "countersink": + rc = self.ex.eval(f["countersink_diameter"]) / 2 + half = math.radians(self.ex.eval(f["countersink_angle"])) / 2 + r_top = rc + top * math.tan(half) + ln = (r_top - r * 0.9) / math.tan(half) + tools.append(Part.makeCone(r_top, r * 0.9, ln, start, d)) + tools.append(cyl(r, depth)) + elif tip is not None and not through and ty in ("simple", "drilled"): + half = math.radians(self.ex.eval(tip)) / 2 + tl = r / math.tan(half) + # does the drill exit exactly at the shoulder (a through hole as drilled)? + sh = self.all_shape() + eps = size * 1e-6 + q = lambda h: p + d * h + exits = sh.isInside(q(depth - eps), 1e-9, True) and not sh.isInside(q(depth + eps), 1e-9, True) + tools.append(cyl(r, depth)) + if not exits: + tools.append(Part.makeCone(r, 0, tl, p + d * depth, d)) + else: + tools.append(cyl(r, depth)) + t = tools[0] + for x in tools[1:]: + t = t.fuse(x) + return [refine(t)] + + def on_surface(self, p, d): + sh = self.all_shape() + L = 4 * self.size() + BIG + line = Part.LineSegment(p - d * L, p + d * L).toShape() + sec = sh.section(line) + ts = [(v.Point - p).dot(d) for v in sec.Vertexes] + if not ts: + return p + if any(abs(t) < 1e-6 for t in ts): + return p + if sh.isInside(p, 1e-9, False): + neg = [t for t in ts if t < 0] + return p + d * max(neg) if neg else p + pos = [t for t in ts if t > 0] + return p + d * min(pos) if pos else p + + def hole(self, f): + spots = [] + n = None + fc = f.get("face") + if fc is not None: + nn = fc.get("plane_normal_outward") or fc.get("normal_at_point_on_face") + if nn: + n = vec(nn) * -1 + if f.get("positions_from"): + w = f["positions_from"].split() + sk = self.sketches[w[w.index("sketch") + 1]] + rng = w[w.index("points") + 1] + if ".." in rng: + a, b = rng.split("..") + pre = re.match(r"\D*", a).group(0) + ids = ["%s%d" % (pre, k) for k in range(int(a[len(pre):]), int(b[len(pre):]) + 1)] + else: + ids = rng.split(",") + spots = [sk.plane.w(sk.pts[i]) for i in ids] + n = sk.plane.n * -1 + else: + spots = [vec(f["position"])] + if fc is not None and fc.get("type") == "cylinder": + o, ax, p = vec(fc["axis_origin"]), vec(fc["axis"]).normalize(), spots[0] + dd = p - o + rr = dd - ax * dd.dot(ax) + if rr.Length > 1e-9: + n = rr.normalize() * -1 + if n is None: + raise RecipeError("hole direction unknown") + n = n.normalize() + tools = [] + for p in spots: + p = self.on_surface(p, n) + tools += self.hole_tools(f, p, n) + return tools + + def fillet(self, f, transform=None): + pts = [] + for e in f.get("edges", []): + p = vec(e.get("point") or e.get("mid")) + pts.append(transform.multiply(p) if transform else p) + name = self.body_with(pts[0]) + s = self.bodies[name] + edges = self.pick_edges(s, f, transform) + if f["op"] == "fillet": + r = self.ex.eval(f["radius"]) + out = s.makeFillet(r, edges) + else: + out = s.makeChamfer(self.ex.eval(f["distance"]), edges) + if not out.isValid(): + out.fix(1e-7, 1e-7, 1e-7) + self.bodies[name] = as_solid_shape(out) + + def shell(self, f): + pts = [vec(x["point"]) for x in f.get("faces_removed", [])] + name = self.body_with(pts[0]) + s = self.bodies[name] + solid = s.Solids[0] + faces = [self.pick_face(solid, p) for p in pts] + t = self.ex.eval(f.get("inside_thickness")) + out = solid.makeThickness(faces, -t, 1e-6, False, False, 0, 2) + self.bodies[name] = as_solid_shape(out) + + def draft(self, f): + pts = [vec(x["point"]) for x in f["faces"]] + np_ = f["neutral_plane"] + nrm = vec(np_.get("plane_normal_outward") or np_.get("normal_at_point_on_face") or [0, 0, 1]).normalize() + origin = vec(np_.get("point") or np_.get("centroid") or [0, 0, 0]) + ang = float(f["angle"]) * (-1 if f.get("flipped") else 1) + name = self.body_with(pts[0]) + s = self.bodies[name] + out = self._draft_partdesign(s, pts, origin, nrm, ang) + self.bodies[name] = as_solid_shape(out) + + def _draft_partdesign(self, s, pts, origin, pull, ang): + # SolidCraft: faces lean in (toward the material) by `ang` going along `pull`, pivoting on + # their line in the neutral plane. FreeCAD's PartDesign Draft does the same tilt; which + # of its two senses matches is checked on the result below. + doc = App.newDocument("dr") + base = doc.addObject("Part::Feature", "Base") + base.Shape = s + faces = [self.pick_face(s, p) for p in pts] + names = [] + for fc in faces: + for i, g in enumerate(s.Faces): + if g.isSame(fc): + names.append("Face%d" % (i + 1)) + nface = None + for i, g in enumerate(s.Faces): + if g.Surface.__class__.__name__ == "Plane" and abs(abs(g.normalAt(0, 0).dot(pull)) - 1) < 1e-9 and abs((g.Vertexes[0].Point - origin).dot(pull)) < 1e-9: + nface = "Face%d" % (i + 1) + break + if nface is None: + # a datum plane would do; the recipes use body faces + raise RecipeError("neutral face not found") + body = doc.addObject("PartDesign::Body", "Body") + body.BaseFeature = base + results = [] + for rev in (False, True): + dr = body.newObject("PartDesign::Draft", "Draft%d" % rev) + dr.Base = (body.BaseFeature, names) + dr.NeutralPlane = (body.BaseFeature, [nface]) + dr.Angle = abs(ang) + dr.Reversed = rev + doc.recompute() + sh = dr.Shape.copy() + results.append(sh) + body.removeObject(dr) + doc.removeObject(dr.Name) + # expected: a point a little toward the material from the face at height h > 0 along pull + # ends up outside; pick the variant that does this. + fc0 = faces[0] + u0, u1, v0, v1 = fc0.ParameterRange + c = fc0.valueAt((u0 + u1) / 2, (v0 + v1) / 2) + nf = fc0.normalAt((u0 + u1) / 2, (v0 + v1) / 2) + h = (c - origin).dot(pull) + t = math.tan(math.radians(ang)) + delta = -h * t / 2 # half the expected displacement along the outward normal + q = c + nf * delta + pick = None + for sh in results: + inside = sh.isInside(q, 1e-9, True) + if inside == (delta > 0): + pick = sh + App.closeDocument(doc.Name) + if pick is None: + raise RecipeError("draft: no FreeCAD variant matches the recipe's sense") + return pick + + def split(self, f): + name = f["body"] + tool = f["tool"] + o, n = self.planes[tool] + s = self.bodies[name] + L = 4 * self.size() + BIG + pl = Part.Plane(o, n) + face = pl.toShape(-L, L, -L, L) + import BOPTools.SplitAPI as SA + res = SA.slice(s, [face], "Split") + sols = res.Solids + names = f.get("result_bodies") or [name] + self.bodies.pop(name) + self.order.remove(name) + for i, so in enumerate(sols): + self.set_body(names[i] if i < len(names) else "%s (%d)" % (name, i), so) + + def construction_plane(self, f): + if f.get("method") == "offset": + o, n = self.planes[f["base"]] if isinstance(f["base"], str) else (vec(f["base"]["origin"]), vec(f["base"]["normal"])) + self.planes[f["name"]] = (o + n * self.ex.eval(f["offset"]), n) + else: + self.planes[f["name"]] = (vec(f.get("result_origin", [0, 0, 0])), vec(f["result_normal"]).normalize()) + + def transforms_for(self, f): + op = f["op"] + mats = [] + if op == "rectangular_pattern": + d1 = f["direction1"] + d2 = f.get("direction2") + a1 = vec(d1["axis"]).normalize() + c1, s1 = int(d1["count"]), self.ex.eval(d1["spacing"]) + c2, s2, a2 = 1, 0.0, V(0, 0, 0) + if d2: + a2, c2, s2 = vec(d2["axis"]).normalize(), int(d2["count"]), self.ex.eval(d2["spacing"]) + for j in range(c2): + for i in range(c1): + if i == 0 and j == 0: + continue + m = App.Matrix() + m.move(a1 * (i * s1) + a2 * (j * s2)) + mats.append(m) + elif op == "circular_pattern": + ax = f["axis"] + o, dr = vec(ax.get("origin", [0, 0, 0])), vec(ax["dir"]).normalize() + n = int(f["count"]) + tot = self.ex.eval(f.get("total_angle", 360)) + full = abs(abs(tot) - 360) < 1e-9 + step = tot / n if full else (tot / (n - 1) if n > 1 else 0) + for i in range(1, n): + pl = App.Placement(V(0, 0, 0), App.Rotation(dr, step * i), o) + mats.append(pl.toMatrix()) + elif op == "path_pattern": + path = f["path"] + psk = self.sketches[path["sketch"]] + edges = [psk.edges[c] for c in path["curves"]] + n = int(f["count"]) + sp = self.ex.eval(f["spacing"]) if f.get("spacing") is not None else self.ex.eval(f["distance"]) / (n - 1) + # path(0) is the start of the first curve as drawn; the curves are chained from there + first = edges[0] + p0 = first.valueAt(first.FirstParameter) + if len(edges) > 1: + nxt = edges[1] + ends = [v.Point for v in nxt.Vertexes] + if min((first.valueAt(first.FirstParameter) - q).Length for q in ends) < min((first.valueAt(first.LastParameter) - q).Length for q in ends): + p0 = first.valueAt(first.LastParameter) + for k in range(1, n): + s_ = k * sp + cur, acc, pk = p0, 0.0, None + for e in edges: + fwd = (e.valueAt(e.FirstParameter) - cur).Length < 1e-6 + if acc + e.Length >= s_ - 1e-9 or e is edges[-1]: + ll = min(max(s_ - acc, 0.0), e.Length) + u = e.getParameterByLength(ll if fwd else e.Length - ll) + pk = e.valueAt(u) + break + acc += e.Length + cur = e.valueAt(e.LastParameter if fwd else e.FirstParameter) + m = App.Matrix() + m.move(pk - p0) + mats.append(m) + elif op == "mirror": + pl = f["plane"] + if pl.get("ref") in ("XY", "XZ", "YZ"): + o, n = self.planes[pl["ref"]] + else: + o, n = vec(pl.get("origin", [0, 0, 0])), vec(pl["normal"]) + n = n.normalize() + m = App.Matrix(1 - 2 * n.x * n.x, -2 * n.x * n.y, -2 * n.x * n.z, 0, + -2 * n.y * n.x, 1 - 2 * n.y * n.y, -2 * n.y * n.z, 0, + -2 * n.z * n.x, -2 * n.z * n.y, 1 - 2 * n.z * n.z, 0, + 0, 0, 0, 1) + t = o - m.multiply(o) + m.move(t) + mats.append(m) + return mats + + def replay(self, f, mats): + names = [] + for x in f.get("features", []): + x = re.sub(r" \(\d+\)$", "", x.strip()) + names.append(x) + for m in mats: + for nm in names: + rec = self.feats[nm] + if rec["kind"] == "tool": + tools = [] + for t in rec["tools"]: + tools.append(xform(t, m)) + op = rec["op"] + if op == "new": + op = "join" + tg = [n for n in rec["targets"] if n in self.bodies] or self.targets({"operation": op}) + self.apply(op, tools, tg) + elif rec["kind"] == "edges": + self.fillet(rec["f"], transform=m) + + def mirror(self, f): + mats = self.transforms_for(f) + if f.get("mirror_of") == "bodies": + for b in f["bodies"]: + s = self.bodies[b] + ms = xform(s, mats[0]) + if f.get("combine"): + self.bodies[b] = as_solid_shape(refine(s.fuse(ms))) + else: + self.set_body(b + " (mirror)", ms) + return + self.replay(f, mats) + + def combine(self, f): + tgt = f.get("target_body") or f.get("target") + tools = [self.bodies[t] for t in (f.get("tool_bodies") or f.get("tools"))] + op = f.get("operation", "join") + self.apply(op, tools, [tgt]) + if not f.get("keep_tools"): + for t in (f.get("tool_bodies") or f.get("tools")): + self.bodies.pop(t, None) + self.order.remove(t) + + def run(self): + for f in self.r["features"]: + if os.environ.get("ORACLE_DEBUG"): + print("..", f["op"], f.get("name"), [(n, round(self.bodies[n].Volume, 4), len(self.bodies[n].Solids)) for n in self.order]) + op = f["op"] + name = f.get("name") + if op == "sketch": + self.sketches[name] = Sketch(f, self.ex) + elif op in ("extrude", "revolve", "sweep", "loft", "hole"): + if op == "extrude": + tools = self.extrude_tools(f) + elif op == "revolve": + tools = self.revolve_tools(f) + elif op == "sweep": + tools = self.sweep_tools(f) + elif op == "loft": + tools = self.loft_tools(f) + else: + tools = self.hole(f) + o = "cut" if op == "hole" else f.get("operation", "new") + if o == "new": + rb = f.get("result_bodies") or [name] + self.apply("new", tools, [], rb[0]) + tg = [rb[0]] + else: + tg = self.targets(f, tools[0] if o != "join" else None) + self.apply(o, tools, tg) + self.feats[name] = {"kind": "tool", "op": o, "tools": tools, "targets": tg} + elif op in ("fillet", "chamfer"): + self.fillet(f) + self.feats[name] = {"kind": "edges", "f": f} + elif op == "shell": + self.shell(f) + elif op == "draft": + self.draft(f) + elif op == "construction_plane": + self.construction_plane(f) + elif op == "split_body": + self.split(f) + elif op == "combine": + self.combine(f) + elif op in ("rectangular_pattern", "circular_pattern", "path_pattern"): + if f.get("pattern_of") == "bodies": + raise RecipeError("body patterns not supported") + self.replay(f, self.transforms_for(f)) + elif op == "mirror": + self.mirror(f) + elif op == "thread": + pass # cosmetic thread: no geometry + else: + raise RecipeError("feature op %s not supported" % op) + + +def measure(shape): + sol = shape.Solids + vol = sum(s.Volume for s in sol) + area = sum(s.Area for s in sol) + com = V(0, 0, 0) + for s in sol: + com += s.CenterOfMass * s.Volume + com = com * (1.0 / vol) if vol else com + bb = shape.optimalBoundingBox() + return { + "body_count": len(sol), + "volume_mm3": vol, + "area_mm2": area, + "center_of_mass": [com.x, com.y, com.z], + "bbox": {"min": [bb.XMin, bb.YMin, bb.ZMin], "max": [bb.XMax, bb.YMax, bb.ZMax]}, + "valid": all(s.isValid() for s in sol), + "faces": len(shape.Faces), + } + + +def write_stl(shape, path, limit=400 * 1024): + import MeshPart + for lin in (0.005, 0.01, 0.015, 0.02): + m = MeshPart.meshFromShape(Shape=shape, LinearDeflection=lin, AngularDeflection=0.2, Relative=False) + size = 84 + 50 * m.CountFacets + if size <= limit: + m.write(path) + return {"stl_deflection_mm": lin, "stl_bytes": size, "stl_facets": m.CountFacets} + return {"stl_skipped": "over %d bytes even at 0.02 mm deflection (%d facets)" % (limit, m.CountFacets)} + + +def main(): + case = os.environ["ORACLE_CASE"] + out = os.environ["ORACLE_OUT"] + stl = os.environ.get("ORACLE_STL") or None + res = {"case": os.path.basename(case.rstrip("/"))} + try: + recipe = json.load(open(os.path.join(case, "recipe.json"))) + m = Model(recipe) + m.run() + shape = m.all_shape() + res.update(measure(shape)) + res["version"] = ".".join(App.Version()[:3]) + res["notes"] = m.notes + res["method"] = construction_note(recipe) + meta = CASE_META.get(recipe.get("id"), {}) + for k in ("compare", "tolerance", "note", "method_extra"): + if k in meta: + res[k] = meta[k] + if stl: + res.update(write_stl(shape, stl)) + except Exception as e: + res["error"] = "%s: %s" % (type(e).__name__, e) + res["trace"] = traceback.format_exc() + with open(out, "w") as fh: + json.dump(res, fh, indent=1) + + +def construction_note(recipe): + ops = [] + for f in recipe["features"]: + op = f["op"] + if op in ("sketch", "construction_plane"): + if op == "sketch" and (f.get("constraints") or f.get("dimensions")): + ops.append("Sketcher-solved sketch") + continue + word = { + "extrude": "Part extrude", + "revolve": "Part revolve", + "loft": "Part.makeLoft", + "sweep": "makePipeShell sweep", + "hole": "hole tool (cylinder/cone) cut", + "fillet": "Part makeFillet", + "chamfer": "Part makeChamfer", + "shell": "makeThickness shell", + "draft": "PartDesign Draft", + "rectangular_pattern": "pattern (tools transformed and re-applied)", + "circular_pattern": "pattern (tools transformed and re-applied)", + "path_pattern": "pattern (tools transformed and re-applied)", + "mirror": "mirror", + "combine": "boolean combine", + "split_body": "split by plane", + }.get(op, op) + if op == "extrude" and f.get("operation") in ("cut", "join", "intersect"): + word += " " + f["operation"] + if not ops or ops[-1] != word: + ops.append(word) + return "FreeCAD (OpenCASCADE) build of recipe.json by tools/freecad-oracle/build.py: " + ", ".join(ops) + + +if not os.environ.get("ORACLE_NO_MAIN"): + main() diff --git a/tools/freecad-oracle/emit.py b/tools/freecad-oracle/emit.py new file mode 100644 index 00000000..6472d9f6 --- /dev/null +++ b/tools/freecad-oracle/emit.py @@ -0,0 +1,66 @@ +# Print a build result, or write it as the case's expected.json (+ reference.stl). +# Run by run.sh under FreeCAD's interpreter (plain Python; no FreeCAD API used here). +import json +import os +import shutil +import sys + +case = os.environ["CASE"] +res = json.load(open(os.environ["OUT"])) +name = res["case"] +write = os.environ.get("WRITE") == "1" +stl = os.environ.get("STL") or "" + +def emit(): + if "error" in res: + print("%s: ERROR %s" % (name, res["error"])) + if os.environ.get("ORACLE_VERBOSE"): + print(res.get("trace", "")) + else: + c = res["center_of_mass"] + print("%s: bodies %d V %.6f A %.6f com [%.4f, %.4f, %.4f] bbox %s..%s%s%s" % ( + name, res["body_count"], res["volume_mm3"], res["area_mm2"], c[0], c[1], c[2], + [round(x, 4) for x in res["bbox"]["min"]], [round(x, 4) for x in res["bbox"]["max"]], + "" if res.get("valid", True) else " (INVALID SHAPE)", + (" notes: " + "; ".join(res["notes"])) if res.get("notes") else "")) + if write: + path = os.path.join(case, "expected.json") + if os.path.exists(path): + old = json.load(open(path)) + if str(old.get("source", "")).startswith("analytic"): + print("%s: expected.json is analytic; not overwritten" % name) + return 0 + if not res.get("valid", True): + print("%s: FreeCAD shape is invalid; not written" % name) + return 1 + method = res["method"] + if res.get("method_extra"): + method += "; " + res["method_extra"] + exp = { + "source": "freecad %s" % res["version"], + "method": method, + "body_count": res["body_count"], + "volume_mm3": res["volume_mm3"], + "area_mm2": res["area_mm2"], + "center_of_mass": res["center_of_mass"], + "bbox": res["bbox"], + } + for k in ("compare", "tolerance", "note"): + if k in res: + exp[k] = res[k] + if res.get("stl_skipped"): + exp["note"] = (exp.get("note", "") + " " if exp.get("note") else "") + "No reference.stl: " + res["stl_skipped"] + "." + with open(path, "w") as fh: + json.dump(exp, fh, indent=2) + fh.write("\n") + ref = os.path.join(case, "reference.stl") + if stl and os.path.exists(stl): + shutil.copyfile(stl, ref) + print("%s: wrote expected.json, reference.stl (%d bytes, deflection %s mm)" % (name, os.path.getsize(ref), res.get("stl_deflection_mm"))) + else: + print("%s: wrote expected.json (no STL)" % name) + return 0 + + +emit() +sys.stdout.flush() diff --git a/tools/freecad-oracle/run.sh b/tools/freecad-oracle/run.sh new file mode 100755 index 00000000..13525c29 --- /dev/null +++ b/tools/freecad-oracle/run.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Build reference cases with FreeCAD (as an external program) and print or write the results. +# +# tools/freecad-oracle/run.sh [--write] ... +# +# Without --write: prints one line per case. With --write: writes /expected.json and +# /reference.stl (refuses to overwrite an expected.json whose source is "analytic"). +# freecadcmd is found via $FREECADCMD, then `freecadcmd` on PATH, then the local AppImage. +set -euo pipefail + +here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +write=0 +cases=() +for a in "$@"; do + case "$a" in + --write) write=1 ;; + -h|--help) sed -n '2,9p' "$0"; exit 0 ;; + *) cases+=("$a") ;; + esac +done +[ ${#cases[@]} -gt 0 ] || { echo "usage: $0 [--write] ..." >&2; exit 2; } + +fc="${FREECADCMD:-}" +if [ -z "$fc" ]; then + if command -v freecadcmd >/dev/null 2>&1; then fc="$(command -v freecadcmd)" + elif command -v FreeCADCmd >/dev/null 2>&1; then fc="$(command -v FreeCADCmd)" + else fc="$here/squashfs-root/usr/bin/freecadcmd" # an AppImage extracted here (gitignored) + fi +fi +[ -x "$fc" ] || { echo "freecadcmd not found (set FREECADCMD)" >&2; exit 2; } + +tmp="$(mktemp -d)" +trap 'rm -rf "$tmp"' EXIT +status=0 +for c in "${cases[@]}"; do + c="${c%/}" + name="$(basename "$c")" + out="$tmp/$name.json" + stl="" + [ $write = 1 ] && stl="$tmp/$name.stl" + ORACLE_CASE="$c" ORACLE_OUT="$out" ORACLE_STL="$stl" \ + "$fc" -c "exec(open('$here/build.py').read())" "$tmp/$name.log" 2>&1 || true + if [ ! -s "$out" ]; then + echo "$name: FreeCAD produced no result"; tail -5 "$tmp/$name.log"; status=1; continue + fi + WRITE=$write CASE="$c" OUT="$out" STL="$stl" "$fc" -c "exec(open('$here/emit.py').read())" &1 \ + | grep -v '^FreeCAD\|^(c) \|^$' || status=1 +done +exit $status diff --git a/tools/oracle-analytic/README.md b/tools/oracle-analytic/README.md new file mode 100644 index 00000000..af99ffd9 --- /dev/null +++ b/tools/oracle-analytic/README.md @@ -0,0 +1,19 @@ +# Analytic reference values + +Closed-form expected values for the cases in [`tests/oracle/`](../../tests/oracle/) whose shape +has one: prisms, cylinders, cones and frustums, spheres and caps, tori and solids of revolution +(Pappus), constant-radius fillets on straight edges, shells, patterns of these, and folded sheet +metal (flats plus bends as annular sectors). Each script is plain Python 3 (standard library only) +with one function per case. Running a script from the repository root rewrites the +`expected.json` of its cases with `"source": "analytic"` and a `method` string giving the formulas: + +```sh +python3 tools/oracle-analytic/cases_basic.py # 01-29: boxes, holes, revolves, sketches +python3 tools/oracle-analytic/cases_features.py # 32-66: fillets, shells, sweeps, patterns +python3 tools/oracle-analytic/cases_sheet_metal.py # 67-76: sheet metal +``` + +Where a value depends on a SolidCraft convention rather than on geometry alone (a shell's sharp +inner corner, a sheet-metal corner relief, where a flange height is measured), `method` or +`note` says which convention is used. Never change a value to match SolidCraft's output: if they +disagree, find out which one is wrong. diff --git a/tools/oracle-analytic/cases_basic.py b/tools/oracle-analytic/cases_basic.py new file mode 100644 index 00000000..aefb6a5f --- /dev/null +++ b/tools/oracle-analytic/cases_basic.py @@ -0,0 +1,560 @@ +#!/usr/bin/env python3 +"""Closed-form expected values for the basic oracle cases. + +Run from the worktree root: python3 tools/oracle-analytic/cases_basic.py [case ...] +Writes tests/oracle//expected.json with "source": "analytic". + +Every value is derived from first principles (prisms, cylinders, cones/frustums, spheres and +caps, tori via Pappus, Green's theorem over line/arc profiles) and composed by adding or +subtracting mass properties. Nothing here is measured from a CAD kernel. +Stdlib only. +""" +import json +import math +import os +import sys + +PI = math.pi +ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "tests", "oracle") + + +# ---------------------------------------------------------------------------------------------- +# Mass-property composition +# ---------------------------------------------------------------------------------------------- +class MP: + """Volume and first moments; add pieces with sign +1 (material) or -1 (removed).""" + + def __init__(self): + self.v = 0.0 + self.m = [0.0, 0.0, 0.0] + + def add(self, v, c, sign=1.0): + self.v += sign * v + for i in range(3): + self.m[i] += sign * v * c[i] + return self + + def com(self): + return [self.m[i] / self.v for i in range(3)] + + +def box_mp(lo, hi): + v = (hi[0] - lo[0]) * (hi[1] - lo[1]) * (hi[2] - lo[2]) + return v, [(lo[i] + hi[i]) / 2 for i in range(3)] + + +def box_area(a, b, c): + return 2 * (a * b + b * c + c * a) + + +def frustum_v(h, r1, r2): + """Circular frustum, radii r1 (z=0) and r2 (z=h).""" + return PI * h / 3 * (r1 * r1 + r1 * r2 + r2 * r2) + + +def frustum_zc(h, r1, r2): + """Centroid height of a circular frustum above the r1 end.""" + return h * (r1 * r1 + 2 * r1 * r2 + 3 * r2 * r2) / (4 * (r1 * r1 + r1 * r2 + r2 * r2)) + + +def frustum_lat(h, r1, r2): + return PI * (r1 + r2) * math.hypot(h, r1 - r2) + + +def sq_frustum(h, a0, a1): + """Square frustum, side a0 at z=0, a1 at z=h: (V, z-centroid).""" + A0, A1 = a0 * a0, a1 * a1 + s = math.sqrt(A0 * A1) + v = h / 3 * (A0 + A1 + s) + zc = h * (A0 + 2 * s + 3 * A1) / (4 * (A0 + s + A1)) + return v, zc + + +def cap_v(R, h): + return PI * h * h * (3 * R - h) / 3 + + +# ---------------------------------------------------------------------------------------------- +# 2D region integrals by Green's theorem (lines exact; arcs by 48-point Gauss-Legendre, which +# integrates these low-degree trigonometric polynomials to machine precision). +# ---------------------------------------------------------------------------------------------- +def _gauss_legendre(n): + xs, ws = [], [] + for i in range(1, n + 1): + x = math.cos(PI * (i - 0.25) / (n + 0.5)) + for _ in range(100): + p0, p1 = 1.0, x + for k in range(2, n + 1): + p0, p1 = p1, ((2 * k - 1) * x * p1 - (k - 1) * p0) / k + dp = n * (x * p1 - p0) / (x * x - 1) + dx = p1 / dp + x -= dx + if abs(dx) < 1e-16: + break + xs.append(x) + ws.append(2 / ((1 - x * x) * dp * dp)) + return xs, ws + + +GL = _gauss_legendre(48) + + +def seg_eval(seg, t): + """Point and derivative on a segment at t in [0, 1].""" + if seg[0] == "line": + (x0, y0), (x1, y1) = seg[1], seg[2] + return x0 + (x1 - x0) * t, y0 + (y1 - y0) * t, x1 - x0, y1 - y0 + _, (cx, cy), r, a0, a1 = seg + a = a0 + (a1 - a0) * t + da = a1 - a0 + return cx + r * math.cos(a), cy + r * math.sin(a), -r * math.sin(a) * da, r * math.cos(a) * da + + +def seg_int(seg, f): + """Integral over t of f(x, y, dx/dt, dy/dt).""" + s = 0.0 + for x, w in zip(*GL): + t = (x + 1) / 2 + s += w / 2 * f(*seg_eval(seg, t)) + return s + + +def region(segs): + """Area A, moments Sx = int x dA, Sy = int y dA, Sxy = int x*y dA of a CCW-bounded region.""" + A = sum(seg_int(s, lambda x, y, dx, dy: x * dy) for s in segs) + Sx = sum(seg_int(s, lambda x, y, dx, dy: x * x / 2 * dy) for s in segs) + Sy = sum(seg_int(s, lambda x, y, dx, dy: x * y * dy) for s in segs) + Sxy = sum(seg_int(s, lambda x, y, dx, dy: x * x * y / 2 * dy) for s in segs) + return A, Sx, Sy, Sxy + + +def seg_len(seg): + return seg_int(seg, lambda x, y, dx, dy: math.hypot(dx, dy)) + + +def seg_rev_area(seg): + """Area swept by a profile segment (x = radius) turned 360 deg about the y axis.""" + return seg_int(seg, lambda x, y, dx, dy: 2 * PI * x * math.hypot(dx, dy)) + + +def arc3(p0, pm, p1): + """Circle through three points, as an arc segment from p0 through pm to p1.""" + (ax, ay), (bx, by), (cx, cy) = p0, pm, p1 + d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) + ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d + uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d + r = math.hypot(ax - ux, ay - uy) + t0 = math.atan2(ay - uy, ax - ux) + tm = math.atan2(by - uy, bx - ux) + t1 = math.atan2(cy - uy, cx - ux) + # choose the sweep direction that passes through the mid point + ccw = (t1 - t0) % (2 * PI) + if (tm - t0) % (2 * PI) < ccw: + a1 = t0 + ccw + else: + a1 = t0 - ((t0 - t1) % (2 * PI)) + return ("arc", (ux, uy), r, t0, a1) + + +def circle_seg(c, r): + return ("arc", c, r, 0.0, 2 * PI) + + +# ---------------------------------------------------------------------------------------------- +# Output +# ---------------------------------------------------------------------------------------------- +def result(method, bodies, V, A, com, lo, hi, faces=None, note=None, **extra): + d = { + "source": "analytic", + "method": method, + "body_count": bodies, + "volume_mm3": V, + "area_mm2": A, + "center_of_mass": [c + 0.0 for c in com], + "bbox": {"min": [float(x) + 0.0 for x in lo], "max": [float(x) + 0.0 for x in hi]}, + } + if faces is not None: + d["faces"] = faces + if note: + d["note"] = note + d.update(extra) + return d + + +# ---------------------------------------------------------------------------------------------- +# Cases +# ---------------------------------------------------------------------------------------------- +def c01_box(): + a, b, c = 40.0, 30.0, 20.0 + return result("box 40 x 30 x 20 from the origin: V = abc, A = 2(ab + bc + ca)", 1, a * b * c, box_area(a, b, c), + [a / 2, b / 2, c / 2], [0, 0, 0], [a, b, c], 6) + + +def c02_cylinder(): + r, h = 15.0, 50.0 + return result("cylinder r=15 h=50 on XY: V = pi r^2 h, A = 2 pi r^2 + 2 pi r h", 1, PI * r * r * h, + 2 * PI * r * r + 2 * PI * r * h, [0, 0, h / 2], [-r, -r, 0], [r, r, h], 3) + + +def c03_box_through_hole(): + a, b, c, r = 60.0, 40.0, 20.0, 6.0 + V = a * b * c - PI * r * r * c + A = box_area(a, b, c) - 2 * PI * r * r + 2 * PI * r * c + return result("box 60x40x20 minus centred through cylinder r=6: V = abc - pi r^2 c, A = 2(ab+bc+ca) - 2 pi r^2 + 2 pi r c; " + "hole is centred so the centroid stays at the box centre", 1, V, A, [30, 20, 10], [0, 0, 0], [a, b, c], 7) + + +def _vase_profile(): + # sketch on XZ with y_dir = -Z: world (x, z) = (sx, -sy) + w = lambda p: (p[0], -p[1]) + P = [w(p) for p in [(0, 0), (20, 0), (25, -30)]] + arc = arc3(w((25, -30)), w((23, -46)), w((15, -60))) + Q = [w(p) for p in [(15, -60), (18, -80), (0, -80)]] + segs = [("line", P[0], P[1]), ("line", P[1], P[2]), arc, ("line", Q[0], Q[1]), ("line", Q[1], Q[2]), ("line", Q[2], P[0])] + return segs, arc + + +def c04_revolve_vase(): + segs, arc = _vase_profile() + A2, Sx, Sy, Sxy = region(segs) + V = 2 * PI * Sx + zc = Sxy / Sx + area = sum(seg_rev_area(s) for s in segs) + # largest radius: the line/arc endpoints, or the arc's x-extreme if it lies within the sweep + _, (cx, cz), r, a0, a1 = arc + rmax = max(25.0, 20.0, 15.0, 18.0) + lo_a, hi_a = min(a0, a1), max(a0, a1) + for k in range(-2, 3): + if lo_a <= 2 * PI * k <= hi_a: + rmax = max(rmax, cx + r) + method = ("revolve of a line/3-point-arc profile (XZ, x = radius, z = -sketch y) 360 deg about Z. Pappus/Green: " + "V = 2 pi * int x dA, z_c = int x z dA / int x dA, A = sum over profile edges of 2 pi int x ds " + "(bottom disk r20, frustum r20->25, torus zone of the arc (centre (%.6f, %.6f), R=%.6f), frustum r15->18, top disk r18)" + % (cx, cz, r)) + return result(method, 1, V, area, [0, 0, zc], [-rmax, -rmax, 0], [rmax, rmax, 80], 5) + + +def c05_taper_extrude(): + h, a0, t = 30.0, 40.0, math.radians(10) + a1 = a0 + 2 * h * math.tan(t) # positive taper offsets the CCW outer loop outward (recipe.rs -> extrude_tapered) + V, zc = sq_frustum(h, a0, a1) + side = (a0 + a1) / 2 * h / math.cos(t) + A = a0 * a0 + a1 * a1 + 4 * side + return result("square frustum: base 40 at z=0, top a1 = 40 + 2*30*tan10 at z=30 (positive taper grows outward); " + "V = h/3 (A0 + A1 + sqrt(A0 A1)), z_c = h (A0 + 2 sqrt(A0A1) + 3 A1) / (4 (A0 + sqrt(A0A1) + A1)), " + "sides = 4 trapezoids (a0+a1)/2 * h/cos(10)", 1, V, A, [0, 0, zc], [-a1 / 2, -a1 / 2, 0], [a1 / 2, a1 / 2, h], 6) + + +def c06_symmetric_extrude(): + a, b, c = 50.0, 30.0, 20.0 + return result("50 (x) by 20 (z) rectangle on XZ extruded +-15 along Y: box 50x30x20 centred at origin", 1, a * b * c, + box_area(a, b, c), [0, 0, 0], [-25, -15, -10], [25, 15, 10], 6) + + +def c07_fillet_all_edges(): + r = 3.0 + a, b, c = 40 - 2 * r, 30 - 2 * r, 20 - 2 * r # inner box swept by a ball of radius r + V = a * b * c + 2 * r * (a * b + b * c + c * a) + PI * r * r * (a + b + c) + 4 / 3 * PI * r ** 3 + A = 2 * (a * b + b * c + c * a) + 2 * PI * r * (a + b + c) + 4 * PI * r * r + return result("box 40x30x20 with every edge rounded r=3 = inner box (34x24x14) grown by a ball r (Steiner): " + "V = abc + 2r(ab+bc+ca) + pi r^2 (a+b+c) + 4/3 pi r^3, A = 2(ab+bc+ca) + 2 pi r (a+b+c) + 4 pi r^2; " + "faces 6 planes + 12 quarter cylinders + 8 sphere octants", 1, V, A, [20, 15, 10], [0, 0, 0], [40, 30, 20], 26) + + +def c08_chamfer(): + d = 2.0 + mp = MP().add(*box_mp([0, 0, 0], [40, 30, 18])) + # top slab z in [18, 20]: at depth u below the top the section is (36+2u) x (26+2u) + # V = int_0^2 (36+2u)(26+2u) du ; z-moment = int (20-u)(...) du (polynomial, exact) + f = lambda u: (36 + 2 * u) * (26 + 2 * u) + # integrate quadratic exactly (Simpson) + Vs = d / 6 * (f(0) + 4 * f(1) + f(2)) + g = lambda u: (20 - u) * f(u) # cubic: Simpson is exact + Ms = d / 6 * (g(0) + 4 * g(1) + g(2)) + mp.add(Vs, [20, 15, Ms / Vs]) + s = d * math.sqrt(2) + A = 40 * 30 + 2 * (40 + 30) * 18 + 36 * 26 + 2 * (40 + 36) / 2 * s + 2 * (30 + 26) / 2 * s + return result("box 40x30x20 with the 4 top edges chamfered 2: lower box 40x30x18 + top slab with section (36+2u)x(26+2u) at depth u " + "(V, moment by exact polynomial integration); A = bottom + sides(h=18) + top 36x26 + 4 trapezoid bevels of slant 2 sqrt2", + 1, mp.v, A, mp.com(), [0, 0, 0], [40, 30, 20], 10) + + +def c09_shell(): + t = 2.0 + mp = MP().add(*box_mp([0, 0, 0], [50, 40, 30])).add(*box_mp([t, t, t], [50 - t, 40 - t, 30]), -1) + ia, ib, ih = 50 - 2 * t, 40 - 2 * t, 30 - t + A = 50 * 40 + 2 * (50 + 40) * 30 + (50 * 40 - ia * ib) + ia * ib + 2 * (ia + ib) * ih + return result("50x40x30 box shelled inward 2 with the top open: box minus cavity [2,48]x[2,38]x[2,30]; " + "A = outer bottom + outer sides + rim + cavity floor + cavity walls", 1, mp.v, A, mp.com(), [0, 0, 0], [50, 40, 30], 11) + + +def c10_rect_pattern_holes(): + r, t = 3.0, 5.0 + n = 12 + mp = MP().add(*box_mp([0, 0, 0], [90, 70, t])) + for i in range(4): + for j in range(3): + mp.add(PI * r * r * t, [15 + 20 * i, 15 + 20 * j, t / 2], -1) + A = box_area(90, 70, t) + n * (2 * PI * r * t - 2 * PI * r * r) + return result("plate 90x70x5 minus 12 through cylinders r=3 at (15+20i, 15+20j), i<4, j<3: V = abc - 12 pi r^2 t, " + "A = 2(ab+bc+ca) + 12(2 pi r t - 2 pi r^2)", 1, mp.v, A, mp.com(), [0, 0, 0], [90, 70, t], 18) + + +def c11_circular_pattern_flange(): + R, ri, rh, h = 50.0, 15.0, 5.0, 10.0 + V = PI * (R * R - ri * ri) * h - 6 * PI * rh * rh * h + A = 2 * PI * (R * R - ri * ri) + 2 * PI * (R + ri) * h + 6 * (2 * PI * rh * h - 2 * PI * rh * rh) + return result("annulus R50/r15 h10 minus 6 through cylinders r=5 on a 40 radius: V = pi(R^2-r^2)h - 6 pi rh^2 h, " + "A = 2 pi(R^2-r^2) + 2 pi(R+r)h + 6(2 pi rh h - 2 pi rh^2); 6-fold symmetry keeps the centroid on the axis", + 1, V, A, [0, 0, h / 2], [-R, -R, 0], [R, R, h], 10) + + +def c12_mirror_feature(): + r, hb = 6.0, 15.0 + mp = MP().add(*box_mp([-30, 0, 0], [30, 30, 10])) + for x in (15, -15): + mp.add(PI * r * r * hb, [x, 15, 10 + hb / 2]) + A = box_area(60, 30, 10) + 2 * (2 * PI * r * hb) + return result("block [-30,30]x[0,30]x[0,10] + two bosses r=6 h=15 at (+-15,15) on top (mirror across YZ): " + "V = abc + 2 pi r^2 h, A = 2(ab+bc+ca) + 2 * 2 pi r h", 1, mp.v, A, mp.com(), [-30, 0, 0], [30, 30, 25], 10) + + +def c13_combine_join(): + r = 12.0 + mp = MP().add(*box_mp([0, 0, 0], [40, 40, 20])) + mp.add(PI * r * r / 2 * 20, [40 + 4 * r / (3 * PI), 20, 10]) # half cylinder x>40, z 0..20 + mp.add(PI * r * r * 20, [40, 20, 30]) # full cylinder z 20..40 + A = (1600 + PI * r * r / 2) + (1600 - PI * r * r / 2) + PI * r * r + 3 * 800 + (800 - 2 * r * 20) + PI * r * 40 + PI * r * 20 + return result("box [0,40]^2x[0,20] union cylinder r=12 at (40,20) z 0..40: V = box + half-cylinder (x>40, z<20, centroid " + "40 + 4r/3pi) + full cylinder z 20..40; A = bottom (1600 + pi r^2/2) + box top (1600 - pi r^2/2) + cyl top + " + "3 full sides + x=40 side minus 24x20 + cyl side (pi r 40 outside half + pi r 20 upper inside half)", + 1, mp.v, A, mp.com(), [0, 0, 0], [52, 40, 40], 9) + + +def c14_combine_cut(): + r = 15.0 + mp = MP().add(*box_mp([-25, -25, -20], [25, 25, 0])) + mp.add(2 / 3 * PI * r ** 3, [0, 0, -3 * r / 8], -1) + A = box_area(50, 50, 20) - PI * r * r + 2 * PI * r * r + return result("box [-25,25]^2x[-20,0] minus sphere r=15 at the origin (lower hemisphere removed): V = abc - 2/3 pi r^3, " + "hemisphere centroid z = -3r/8; A = 2(ab+bc+ca) - pi r^2 + 2 pi r^2", 1, mp.v, A, mp.com(), + [-25, -25, -20], [25, 25, 0], 7) + + +def c15_combine_intersect(): + R, a = 25.0, 20.0 + h = R - a + rc = math.sqrt(R * R - a * a) + V = 4 / 3 * PI * R ** 3 - 6 * cap_v(R, h) + A = 4 * PI * R * R - 6 * 2 * PI * R * h + 6 * PI * rc * rc + return result("cube [-20,20]^3 intersect sphere R=25: sphere minus 6 disjoint caps of height h=5 (caps cannot overlap: " + "two would need x^2+y^2 > 800 > R^2); V = 4/3 pi R^3 - 6 pi h^2 (3R-h)/3, A = 4 pi R^2 - 6 * 2 pi R h + 6 pi (R^2-20^2)", + 1, V, A, [0, 0, 0], [-a, -a, -a], [a, a, a], 7) + + +def c16_sweep(): + r, R, L1, L2 = 3.0, 20.0, 30.0, 30.0 + th = PI / 2 + ar = PI * r * r + mp = MP() + mp.add(ar * L1, [0, 0, L1 / 2]) # vertical leg z 0..30 along the Z axis + # quarter torus: bend centre C=(20, 30) in XZ, from direction (-1,0) to (0,1) about C + Vt = ar * R * th + c_eff = (R * R + r * r / 4) / R # int rho^2 dA / int rho dA over the section disk + rho = c_eff * math.sin(th / 2) / (th / 2) # sector centroid distance from the bend axis + bis = (-math.sqrt(0.5), math.sqrt(0.5)) + mp.add(Vt, [20 + rho * bis[0], 0, 30 + rho * bis[1]]) + mp.add(ar * L2, [20 + L2 / 2, 0, 50]) + A = 2 * PI * r * (L1 + R * th + L2) + 2 * ar + return result("circle r=3 swept along line 30 (+Z) + tangent R20 quarter arc + line 30 (+X): two cylinders + quarter torus " + "(Pappus: V = pi r^2 R theta, A = 2 pi r R theta; torus centroid at rho = (R^2 + r^2/4)/R * sin(theta/2)/(theta/2) " + "from the bend axis along the bisector) + 2 end disks", 1, mp.v, A, mp.com(), [-r, -r, 0], [50, r, 50 + r], 5) + + +def c18_hole_features(): + T = 15.0 + mp = MP().add(*box_mp([0, 0, 0], [60, 40, T])) + A = box_area(60, 40, T) + # counterbore at (15,20): r=7 depth 5, then r=4 through + mp.add(PI * 49 * 5, [15, 20, T - 2.5], -1) + mp.add(PI * 16 * 10, [15, 20, 5], -1) + A += -PI * 49 + 2 * PI * 7 * 5 + PI * (49 - 16) + 2 * PI * 4 * 10 - PI * 16 + # countersink at (35,20): 90 deg cone r=6 at the top to r=3 at depth 3, then r=3 through + hc = (6 - 3) / math.tan(math.radians(45)) + mp.add(frustum_v(hc, 3, 6), [35, 20, T - hc + frustum_zc(hc, 3, 6)], -1) + mp.add(PI * 9 * (T - hc), [35, 20, (T - hc) / 2], -1) + A += -PI * 36 + frustum_lat(hc, 3, 6) + 2 * PI * 3 * (T - hc) - PI * 9 + # blind drilled hole at (50,20): r=3 to depth 10 (shoulder), 118 deg point below + tip = 3 / math.tan(math.radians(59)) + zs = T - 10 + mp.add(PI * 9 * 10, [50, 20, zs + 5], -1) + mp.add(PI * 9 * tip / 3, [50, 20, zs - tip / 4], -1) + A += -PI * 9 + 2 * PI * 3 * 10 + PI * 3 * math.hypot(3, tip) + return result("plate 60x40x15 minus: counterbore (r7 x 5 deep + r4 through), countersink (90 deg cone frustum r6->r3 over 3 mm " + "+ r3 through), blind r3 hole 10 deep to the shoulder with a 118 deg cone point (height 3/tan59, centroid 1/4 up " + "from the apex); areas: removed top/bottom disks, cylinder walls 2 pi r h, cb floor annulus, cone laterals pi r s", + 1, mp.v, A, mp.com(), [0, 0, 0], [60, 40, T], 13) + + +def c19_l_bracket(): + # solved: l1 (0,0)-(60,0), l2 up 8, l3 left to x=8 (l5 is 8 long and l6 is vertical at x=0), l4 up to y=40, l5 to (0,40) + h = 20.0 + mp = MP().add(*box_mp([0, 0, 0], [60, 8, h])).add(*box_mp([0, 8, 0], [8, 40, h])) + a2 = 60 * 8 + 8 * 32 + A = 2 * a2 + (60 + 8 + 52 + 32 + 8 + 40) * h + return result("solved L: (0,0)-(60,0)-(60,8)-(8,8)-(8,40)-(0,40); area 60x8 + 8x32, extruded 20: V = A2 h, " + "A = 2 A2 + perimeter*h, centroid of the two rectangles", 1, mp.v, A, mp.com(), [0, 0, 0], [60, 40, h], 8) + + +def c20_slot(): + r, L, h = 6.0, 40.0, 5.0 + a2 = 2 * r * L + PI * r * r + per = 2 * L + 2 * PI * r + return result("obround: arc centres (0,0) and (40,0), R6, tangent horizontal lines y=+-6: A2 = 2rL + pi r^2, " + "V = A2 h, A = 2 A2 + perimeter (2L + 2 pi r) h", 1, a2 * h, 2 * a2 + per * h, [L / 2, 0, h / 2], + [-r, -r, 0], [L + r, r, h], 6) + + +def c21_draft(): + h, a0, t = 30.0, 40.0, math.radians(5) + a1 = a0 + 2 * h * math.tan(t) # pull = -Z (bottom normal); faces lean in along the pull, so the top widens + V, zc = sq_frustum(h, a0, a1) + A = a0 * a0 + a1 * a1 + 4 * (a0 + a1) / 2 * h / math.cos(t) + return result("40x40x30 box, 5 deg draft hinged on the bottom (z=0), pull -Z: square frustum 40 -> 40 + 2*30*tan5; " + "V = h/3 (A0 + A1 + sqrt(A0A1)), sides 4 trapezoids of slant h/cos5", 1, V, A, [0, 0, zc], + [-a1 / 2, -a1 / 2, 0], [a1 / 2, a1 / 2, h], 6) + + +def c22_split_body(): + r, h = 20.0, 60.0 + t = math.radians(30) + V = PI * r * r * h + A = 2 * PI * r * r + 2 * PI * r * h + 2 * PI * r * (r / math.cos(t)) + return result("cylinder r20 z -30..30 split by the plane through the X axis tilted 30 deg (z = y tan30, stays within |z|<=11.6 " + "inside the cylinder): 2 congruent halves (point symmetry), V total = pi r^2 h, A total = cylinder + 2 ellipses " + "pi r (r/cos30)", 2, V, A, [0, 0, 0], [-r, -r, -h / 2], [r, r, h / 2], 6) + + +def c24_user_parameters(): + w, d, h, rh = 60.0, 40.0, 15.0, 5.0 + V = (w * d - PI * rh * rh) * h + A = 2 * (w * d - PI * rh * rh) + 2 * (w + d) * h + 2 * PI * rh * h + return result("width 60 x depth 40 x height 15 block from the origin with a centred d10 through hole: V = (wd - pi r^2) h, " + "A = 2(wd - pi r^2) + 2(w+d)h + 2 pi r h", 1, V, A, [w / 2, d / 2, h / 2], [0, 0, 0], [w, d, h], 7) + + +def c25_sketch_triangle(): + # P = t (cos60, sin60), |P - (50,0)| = 45 -> t^2 - 50 t + 475 = 0; the drawn apex (|P| ~ 41) picks t = 25 + sqrt(150) + tt = 25 + math.sqrt(150) + P = (tt * 0.5, tt * math.sqrt(3) / 2) + h = 5.0 + a2 = 0.5 * 50 * P[1] + per = 50 + 45 + tt + return result("solved triangle (0,0), (50,0), P = t(cos60, sin60) with t = 25 + sqrt(150) from |P-(50,0)| = 45 " + "(the root nearest the drawn apex); V = (1/2 * 50 * Py) * 5, A = 2 A2 + perimeter*5, centroid = vertex mean", + 1, a2 * h, 2 * a2 + per * h, [(50 + P[0]) / 3, P[1] / 3, h / 2], [0, 0, 0], [50, P[1], h], 5) + + +def c26_sketch_belt(): + R, r, d, rh, h = 20.0, 10.0, 50.0, 4.0, 5.0 + al = math.asin((R - r) / d) + nt = (math.sin(al), math.cos(al)) + nb = (math.sin(al), -math.cos(al)) + b1, b2 = (R * nb[0], R * nb[1]), (d + r * nb[0], r * nb[1]) + t2, t1 = (d + r * nt[0], r * nt[1]), (R * nt[0], R * nt[1]) + segs = [("line", b1, b2), ("arc", (d, 0), r, -(PI / 2 - al), PI / 2 - al), ("line", t2, t1), + ("arc", (0, 0), R, PI / 2 - al, 3 * PI / 2 + al)] + A2, Sx, Sy, _ = region(segs) + per_out = sum(seg_len(s) for s in segs) + A2n = A2 - PI * rh * rh + Sxn = Sx - PI * rh * rh * d + V = A2n * h + A = 2 * A2n + (per_out + 2 * PI * rh) * h + return result("belt: convex hull of circles R20 @ (0,0) and r10 @ (50,0) (external tangents, sin a = (R-r)/d) minus the " + "d8 hole at (50,0), extruded 5 as one body; hull area = (R+r) sqrt(d^2-(R-r)^2) + R^2(pi+2a)/2 + r^2(pi-2a)/2; " + "moments by Green's theorem over the line/arc boundary", 1, V, A, [Sxn / A2n, 0, h / 2], + [-R, -R, 0], [d + r, R, h], 7) + + +def c27_sketch_trapezoid(): + a, b, H, rh, t = 60.0, 30.0, 25.0, 3.0, 5.0 + At = (a + b) / 2 * H + yt = H * (a + 2 * b) / (3 * (a + b)) + A2 = At - 2 * PI * rh * rh + yc = (At * yt - 2 * PI * rh * rh * 8) / A2 + per = a + b + 2 * math.hypot((a - b) / 2, H) + 2 * 2 * PI * rh + return result("solved trapezoid bottom (-30,0)-(30,0), top (-15,25)-(15,25) minus two d6 holes at (+-18, 8) " + "(symmetric about the axis, 36 apart, 8 above l1); trapezoid centroid y = H(a+2b)/(3(a+b)); " + "V = A2 t, A = 2 A2 + perimeter t", 1, A2 * t, 2 * A2 + per * t, [0, yc, t / 2], [-30, 0, 0], [30, H, t], 8) + + +def c29_two_sided_partial_revolve(): + # block: x -20..20, z 0..20 (XZ sketch, y_dir = -Z), extruded +10 along +Y and 25 along -Y + mp = MP().add(*box_mp([-20, -25, 0], [20, 10, 20])) + ri, ro, z0, z1 = 4.0, 12.0, 12.0, 20.0 + th = 1.5 * PI # sweeps from +X towards the sketch normal (+Y): theta in [0, 270 deg] + # removed cross-section S = annular sector theta in [0, th] minus the part above y = 10 (outside the block) + Asec = th / 2 * (ro * ro - ri * ri) + Mx_sec = (ro ** 3 - ri ** 3) / 3 * math.sin(th) + My_sec = (ro ** 3 - ri ** 3) / 3 * (1 - math.cos(th)) + dy = 10.0 + seg_a = ro * ro * math.acos(dy / ro) - dy * math.sqrt(ro * ro - dy * dy) + seg_my = 2 / 3 * (ro * ro - dy * dy) ** 1.5 + S = Asec - seg_a + Mx, My = Mx_sec, My_sec - seg_my + hz = z1 - z0 + mp.add(S * hz, [Mx / S, My / S, (z0 + z1) / 2], -1) + half_w = math.sqrt(ro * ro - dy * dy) + phi = math.asin(dy / ro) + outer_ang = th - (PI - 2 * phi) + A = box_area(40, 35, 20) - S + S - 2 * half_w * hz + ri * th * hz + ro * outer_ang * hz + 2 * (ro - ri) * hz + return result("block [-20,20]x[-25,10]x[0,20] minus the 270 deg revolve (from +X towards +Y) of the 8x8 square r 4..12, z 12..20; " + "the removed section is the annular sector minus the circular segment y > 10 (R^2 acos(d/R) - d sqrt(R^2-d^2), " + "y-moment 2/3 (R^2-d^2)^1.5) that lies outside the block; sector moments (R^3-r^3)/3 (sin, 1-cos); " + "A = box - top opening + floor - front-face notch 2 sqrt(44) x 8 + inner wall r th h + outer wall (th - pi + 2 asin(5/6)) R h + 2 end caps", + 1, mp.v, A, mp.com(), [-20, -25, 0], [20, 10, 20], 12) + + +CASES = { + "01-box": c01_box, + "02-cylinder": c02_cylinder, + "03-box-through-hole": c03_box_through_hole, + "04-revolve-vase": c04_revolve_vase, + "05-taper-extrude": c05_taper_extrude, + "06-symmetric-extrude": c06_symmetric_extrude, + "07-fillet-all-edges": c07_fillet_all_edges, + "08-chamfer": c08_chamfer, + "09-shell": c09_shell, + "10-rect-pattern-holes": c10_rect_pattern_holes, + "11-circular-pattern-flange": c11_circular_pattern_flange, + "12-mirror-feature": c12_mirror_feature, + "13-combine-join": c13_combine_join, + "14-combine-cut": c14_combine_cut, + "15-combine-intersect": c15_combine_intersect, + "16-sweep": c16_sweep, + "18-hole-features": c18_hole_features, + "19-l-bracket-constrained": c19_l_bracket, + "20-slot-constrained": c20_slot, + "21-draft": c21_draft, + "22-split-body": c22_split_body, + "24-user-parameters": c24_user_parameters, + "25-sketch-triangle": c25_sketch_triangle, + "26-sketch-belt": c26_sketch_belt, + "27-sketch-trapezoid": c27_sketch_trapezoid, + "29-two-sided-and-partial-revolve": c29_two_sided_partial_revolve, +} + + +def main(argv): + names = argv[1:] or list(CASES) + for n in names: + d = CASES[n]() + path = os.path.join(ROOT, n, "expected.json") + with open(path, "w") as f: + json.dump(d, f, indent=2) + f.write("\n") + print(f"{n}: V={d['volume_mm3']!r} A={d['area_mm2']!r} com={d['center_of_mass']}") + + +if __name__ == "__main__": + main(sys.argv) diff --git a/tools/oracle-analytic/cases_features.py b/tools/oracle-analytic/cases_features.py new file mode 100644 index 00000000..0270408c --- /dev/null +++ b/tools/oracle-analytic/cases_features.py @@ -0,0 +1,546 @@ +#!/usr/bin/env python3 +"""Closed-form expected values for the feature cases of tests/oracle (analytic oracle). + +Standalone, Python 3 stdlib only. Run from the worktree root: + + python3 tools/oracle-analytic/cases_features.py + +Every number is derived from the recipe's dimensions with elementary geometry: +prisms, cylinders, cones, spheres, tori, solids of revolution (Pappus / Green's theorem on +the (r, z) profile), constant fillets as swept spandrels, tubes, screw sweeps. Planar +regions bounded by lines and circular arcs are integrated exactly with Green's theorem +(Gauss-Legendre on each segment, exact to round-off for lines and short arc pieces). +""" + +import json +import math +import os + +PI = math.pi +ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..") +OUT = os.path.join(ROOT, "tests", "oracle") + +# -------------------------------------------------------------------------------------- +# Planar regions (lines + circular arcs), Green's theorem. +# -------------------------------------------------------------------------------------- + + +def _gauss_legendre(n): + xs, ws = [], [] + for i in range(1, n + 1): + x = math.cos(PI * (i - 0.25) / (n + 0.5)) + for _ in range(100): + p0, p1 = 1.0, x + for k in range(2, n + 1): + p0, p1 = p1, ((2 * k - 1) * x * p1 - (k - 1) * p0) / k + dp = n * (x * p1 - p0) / (x * x - 1) + dx = p1 / dp + x -= dx + if abs(dx) < 1e-16: + break + xs.append(x) + ws.append(2 / ((1 - x * x) * dp * dp)) + return xs, ws + + +GL_X, GL_W = _gauss_legendre(24) + + +def L(p, q): + """Line segment p -> q.""" + return ("L", tuple(p), tuple(q)) + + +def A(c, r, a0, a1): + """Arc about centre c, radius r, from angle a0 to a1 (radians; a1 < a0 is clockwise).""" + return ("A", tuple(c), r, a0, a1) + + +def _pieces(seg): + """Parametric pieces (point(t), derivative(t)) over t in [0, 1].""" + if seg[0] == "L": + (x0, y0), (x1, y1) = seg[1], seg[2] + yield (lambda t: (x0 + (x1 - x0) * t, y0 + (y1 - y0) * t), lambda t: (x1 - x0, y1 - y0)) + else: + (cx, cy), r, a0, a1 = seg[1], seg[2], seg[3], seg[4] + n = max(1, int(math.ceil(abs(a1 - a0) / (PI / 36)))) + for k in range(n): + b0 = a0 + (a1 - a0) * k / n + b1 = a0 + (a1 - a0) * (k + 1) / n + db = b1 - b0 + yield ( + (lambda b0, db: lambda t: (cx + r * math.cos(b0 + db * t), cy + r * math.sin(b0 + db * t)))(b0, db), + (lambda b0, db: lambda t: (-r * db * math.sin(b0 + db * t), r * db * math.cos(b0 + db * t)))(b0, db), + ) + + +def region(loops): + """Integrals of a region whose boundary loops are CCW (outer) / CW (holes). + + Returns dict: A, Sx = int x dA, Sy = int y dA, Sxy = int x y dA, P = perimeter, + Px = int x ds over the boundary. + """ + acc = dict(A=0.0, Sx=0.0, Sy=0.0, Sxy=0.0, P=0.0, Px=0.0) + for loop in loops: + for seg in loop: + for pt, dpt in _pieces(seg): + for xg, wg in zip(GL_X, GL_W): + t = 0.5 * (xg + 1) + w = 0.5 * wg + x, y = pt(t) + dx, dy = dpt(t) + ds = math.hypot(dx, dy) + acc["A"] += w * x * dy + acc["Sx"] += w * x * x / 2 * dy + acc["Sy"] += w * x * y * dy + acc["Sxy"] += w * x * x * y / 2 * dy + acc["P"] += w * ds + acc["Px"] += w * x * ds + return acc + + +def poly(pts): + return [L(pts[i], pts[(i + 1) % len(pts)]) for i in range(len(pts))] + + +def reverse(loop): + out = [] + for seg in reversed(loop): + out.append(L(seg[2], seg[1]) if seg[0] == "L" else A(seg[1], seg[2], seg[4], seg[3])) + return out + + +def circle_loop(c, r, ccw=True): + return [A(c, r, 0.0, 2 * PI if ccw else -2 * PI)] + + +# -------------------------------------------------------------------------------------- +# Mass properties: (V, [Mx, My, Mz]) with composition. +# -------------------------------------------------------------------------------------- + + +class MP: + def __init__(self, v=0.0, m=(0.0, 0.0, 0.0)): + self.v = v + self.m = list(m) + + @staticmethod + def at(v, c): + return MP(v, [v * c[0], v * c[1], v * c[2]]) + + def __add__(self, o): + return MP(self.v + o.v, [a + b for a, b in zip(self.m, o.m)]) + + def __sub__(self, o): + return MP(self.v - o.v, [a - b for a, b in zip(self.m, o.m)]) + + def com(self): + return [x / self.v for x in self.m] + + +def box(x0, y0, z0, x1, y1, z1): + v = (x1 - x0) * (y1 - y0) * (z1 - z0) + return MP.at(v, [(x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2]) + + +def cyl(cx, cy, r, z0, z1): + return MP.at(PI * r * r * (z1 - z0), [cx, cy, (z0 + z1) / 2]) + + +def extrude(reg, z0, h): + """Prism of a planar region (sketch x, y = world x, y) from z0 to z0 + h.""" + return MP(reg["A"] * h, [reg["Sx"] * h, reg["Sy"] * h, reg["A"] * h * (z0 + h / 2)]) + + +def extrude_area(reg, h): + return 2 * reg["A"] + reg["P"] * h + + +def revolve(reg, cx=0.0, cy=0.0): + """Full revolution about the vertical axis through (cx, cy) of an (r, z) region (r >= 0).""" + v = 2 * PI * reg["Sx"] + return MP(v, [v * cx, v * cy, 2 * PI * reg["Sxy"]]) + + +def revolve_area(reg): + """Area of the surface swept by the whole boundary (segments on the axis add nothing).""" + return 2 * PI * reg["Px"] + + +# Spandrel of a fillet radius R: the square corner R x R minus the quarter disc. +def spandrel_area(R): + return R * R * (1 - PI / 4) + + +def spandrel_offset(R): + """Distance of the spandrel's centroid from each of the two corner faces.""" + return R * (10 - 3 * PI) / (3 * (4 - PI)) + + +# -------------------------------------------------------------------------------------- +# Output +# -------------------------------------------------------------------------------------- + + +def write(case, method, bodies, mp, area, bbox, faces=None, **extra): + d = { + "source": "analytic", + "method": method, + "body_count": bodies, + "volume_mm3": mp.v, + "area_mm2": area, + "center_of_mass": mp.com(), + "bbox": {"min": list(map(float, bbox[0])), "max": list(map(float, bbox[1]))}, + } + if faces is not None: + d["faces"] = faces + d.update(extra) + path = os.path.join(OUT, case, "expected.json") + with open(path, "w") as f: + json.dump(d, f, indent=2) + f.write("\n") + print(f"{case}: V={mp.v:.6f} A={area:.6f} com={[round(x, 6) for x in mp.com()]}") + + +# -------------------------------------------------------------------------------------- +# Cases +# -------------------------------------------------------------------------------------- + + +def c32(): + # Plate 60x60x8 centred; boss r10 z 8..23 with R3 concave base fillet and R2 convex top fillet. + # The boss with both fillets is one solid of revolution: its (r, z) profile. + prof = region([[ + L((0, 8), (13, 8)), + A((13, 11), 3, -PI / 2, -PI), # concave base fillet, (13,8) -> (10,11) + L((10, 11), (10, 21)), + A((8, 21), 2, 0.0, PI / 2), # convex top fillet, (10,21) -> (8,23) + L((8, 23), (0, 23)), + L((0, 23), (0, 8)), + ]]) + mp = box(-30, -30, 0, 30, 30, 8) + revolve(prof) + # Revolved boundary minus its bottom disc (r 0..13 at z=8, internal); plate top loses that disc. + area = (3600 + 4 * 60 * 8 + 3600 - PI * 13 ** 2) + (revolve_area(prof) - PI * 13 ** 2) + write("32-boss-plate-fillets", + "plate 60x60x8 + boss (r10, z 8..23) with R3 concave base and R2 convex top fillets taken as one " + "solid of revolution: V, z-moment and lateral area from Pappus/Green on its (r,z) profile " + "(quarter-circle fillet arcs); plate top loses the r13 disc", + 1, mp, area, [(-30, -30, 0), (30, 30, 23)], faces=10) + + +def c33(): + # Obround R8 (centres x=0, x=40), height 10. Top loop R2 fillet, bottom loop 1 mm chamfer. + R, Lst, H = 8.0, 40.0, 10.0 + rf, ch = 2.0, 1.0 + base = MP.at((2 * R * Lst + PI * R * R) * H, [Lst / 2, 0, H / 2]) + + def path_len(inset): # perimeter of the obround inset by `inset` + return 2 * Lst + 2 * PI * (R - inset) + + # Removed fillet spandrel: area R^2(1-pi/4), centroid inset d from the wall and d below the top. + d = spandrel_offset(rf) + fil = MP.at(spandrel_area(rf) * path_len(d), [Lst / 2, 0, H - d]) + # Removed chamfer triangle: area c^2/2, centroid inset c/3, height c/3. + cha = MP.at(ch * ch / 2 * path_len(ch / 3), [Lst / 2, 0, ch / 3]) + mp = base - fil - cha + top = 2 * (R - rf) * Lst + PI * (R - rf) ** 2 + bot = 2 * (R - ch) * Lst + PI * (R - ch) ** 2 + wall = (H - rf - ch) * path_len(0) + # fillet surface: quarter arc length pi*rf/2, its centroid inset rf - 2rf/pi from the wall + fsurf = PI * rf / 2 * path_len(rf - 2 * rf / PI) + csurf = math.sqrt(2) * ch * path_len(ch / 2) + area = top + bot + wall + fsurf + csurf + write("33-fillet-tangent-chain", + "obround (R8, centres 40 apart) x 10 minus R2 fillet spandrel R^2(1-pi/4) and 1 mm chamfer " + "triangle swept round the whole loop (Pappus: section x path of its centroid, inset " + "R(10-3pi)/(3(4-pi)) resp. c/3); surfaces likewise (fillet arc centroid inset R-2R/pi)", + 1, mp, area, [(-8, -8, 0), (48, 8, 10)], faces=14) + + +def c38(): + mp = cyl(0, 0, 10, 0, 50) + area = 2 * PI * 10 * 50 + 2 * PI * 100 + write("38-coincident-cylinders", + "union of r10 z0..30 and r10 z20..50 = cylinder r10 h50: V = pi r^2 h, A = 2 pi r h + 2 pi r^2", + 1, mp, area, [(-10, -10, 0), (10, 10, 50)], faces=3) + + +def c40(): + r_s, R_t, r_t = 12.0, 22.0, 4.0 + b = box(-30, -30, -10, 30, 30, 0) + hemi = MP.at(2 / 3 * PI * r_s ** 3, [0, 0, 3 * r_s / 8]) + # The sphere (r12) also pokes 2 mm out of the box bottom (z=-10): a spherical cap h=2. + h = r_s - 10.0 + cap = MP.at(PI * h * h * (3 * r_s - h) / 3, [0, 0, -3 * (2 * r_s - h) ** 2 / (4 * (3 * r_s - h))]) + # Torus centred on the box top: only its lower half lies in material. + half_torus = MP.at(PI * r_t ** 2 / 2 * 2 * PI * R_t, [0, 0, -4 * r_t / (3 * PI)]) + mp = b + hemi + cap - half_torus + area = (3600 - PI * (r_s ** 2 - 10.0 ** 2) + 4 * 60 * 10 # bottom (minus cap footprint) + sides + + 3600 - PI * r_s ** 2 - PI * ((R_t + r_t) ** 2 - (R_t - r_t) ** 2) # top + + 2 * PI * r_s ** 2 # upper hemisphere + + 2 * PI * r_s * h # cap below the box + + 2 * PI * R_t * PI * r_t) # half torus (semicircle r_t about R_t) + write("40-box-sphere-torus", + "box 60x60x10 (z -10..0) + upper hemisphere r12 + spherical cap h2 below z=-10 (V = pi h^2(3R-h)/3, " + "A = 2 pi R h) - lower half torus R22 r4 (Pappus: V = pi r^2/2 * 2 pi R, centroid -4r/3pi, " + "A = pi r * 2 pi R); top loses disc r12 and annulus 18..26, bottom loses disc r sqrt(44)", + 1, mp, area, [(-30, -30, -12), (30, 30, 12)], faces=10, + note="faces: bottom, 4 sides, top split by the groove into an annulus (r 12..18) and the outer part, " + "upper sphere, lower cap, torus") + + +def c43(): + mp = box(0, 0, 0, 35, 20, 20) + box(45, 0, 0, 80, 20, 20) + area = 2 * 2 * (35 * 20 + 20 * 20 + 35 * 20) + write("43-cut-splits-body", + "two boxes 35x20x20 (x 0..35 and 45..80): V = 2abc, A = 2*2(ab+bc+ca)", + 2, mp, area, [(0, 0, 0), (80, 20, 20)], faces=12) + + +def c44(): + # L (x 0..60, y 0..8 and x 0..8, y 0..40) x 20; shell 2 inward, top open. + # SolidCraft's shell convention (intersection join): the inner walls are the outer faces + # offset by 2 and extended until they meet, so the cavity is the L shrunk by 2 with a sharp + # corner at (6,6) opposite the reflex edge. Floor at z=2, open at z=20. + Lpts = [(0, 0), (60, 0), (60, 8), (8, 8), (8, 40), (0, 40)] + outer = region([poly(Lpts)]) + cav = region([poly([(2, 2), (58, 2), (58, 6), (6, 6), (6, 38), (2, 38)])]) + mp = extrude(outer, 0, 20) - extrude(cav, 2, 18) + area = (outer["A"] + outer["P"] * 20 # bottom + outer walls + + (outer["A"] - cav["A"]) # top rim + + cav["A"] + cav["P"] * 18) # cavity floor + inner walls + # Rounded (constant-distance, arc) join instead: cavity gains (4-pi) x 18. + rv, ra = mp.v - (4 - PI) * 18, area - (4 - PI) * 18 + write("44-shell-l-bracket", + "L prism (area 736, perimeter 200) x 20 minus cavity = L shrunk by 2 (SolidCraft's intersection-join " + "shell convention: inner faces offset by 2 and extended to meet, sharp inner corner at (6,6); area 352) " + f"from z=2 to 20. A rounded (arc) join would give V {rv:.4f}, A {ra:.4f}, 16 faces", + 1, mp, area, [(0, 0, 0), (60, 40, 20)], faces=15) + + +def c45(): + # Plate 60x60x10 centred + boss r12 z 10..30; shell 2 inward, bottom open. + # Intersection-join convention: cavity = box 56x56 z 0..8 + cylinder r10 z 8..28 (the offset + # cylinder r10 extended down to meet the offset plate top z=8, sharp circular inner edge). + solid = box(-30, -30, 0, 30, 30, 10) + cyl(0, 0, 12, 10, 30) + cav = box(-28, -28, 0, 28, 28, 8) + cyl(0, 0, 10, 8, 28) + mp = solid - cav + area = (3600 - 56 * 56 # bottom rim + + 4 * 60 * 10 # plate sides + + 3600 - PI * 144 # plate top + + 2 * PI * 12 * 20 + PI * 144 # boss side + top + + 4 * 56 * 8 # cavity side walls + + 56 * 56 - PI * 100 # cavity ceiling z=8 (outside r10) + + 2 * PI * 10 * 20 # inner cylinder r10 z8..28 + + PI * 100) # inner top disc z=28 + # Rounded (arc) join: the ring r10..12, z8..10 outside the r2 torus about (12,10) is also hollow. + ring = region([[L((10, 8), (12, 8)), A((12, 10), 2, -PI / 2, -PI), L((10, 10), (10, 8))]]) + rv = mp.v - revolve(ring).v + ra = (area - 2 * PI * 10 * 2 - PI * (144 - 100) + 2 * PI * PI * (12 - 4 / PI)) + write("45-shell-boss-plate", + "plate 60x60x10 + boss r12 h20 minus cavity (box 56x56x8 + cylinder r10 z8..28) under SolidCraft's " + "intersection-join shell convention (offset faces extended to meet: sharp circular inner edge at r10, " + f"z8). A rounded (arc) join would give V {rv:.4f}, A {ra:.4f}, 16 faces (torus round r2)", + 1, mp, area, [(-30, -30, 0), (30, 30, 30)], faces=15) + + +def c46(): + mp = box(0, 0, 0, 50, 40, 30) - box(3, 0, 3, 47, 37, 30) + area = (50 * 40 + 50 * 30 + 2 * 40 * 30 # bottom, back, two sides + + (50 * 40 - 44 * 37) + (50 * 30 - 44 * 27) # top rim, front rim + + 44 * 37 + 44 * 27 + 2 * 37 * 27) # floor, back inner, side inners + write("46-shell-two-open-faces", + "box 50x40x30 minus cavity x3..47, y0..37, z3..30 (3 mm walls, top and front open)", + 1, mp, area, [(0, 0, 0), (50, 40, 30)], faces=10) + + +def c48(): + # Sketch on XZ with y_dir = -Z: profile (r, z) = (sx, -sy). + pts = [(5, 0), (40, 0), (40, 3), (33, 8), (33, 12), (40, 17), (40, 23), (33, 28), (33, 32), + (40, 37), (40, 40), (5, 40)] + reg = region([poly(pts)]) + mp = revolve(reg) + area = revolve_area(reg) + write("48-pulley", + "revolve of the 12-segment (r,z) polygon about Z: V = 2 pi int r dA, Mz = 2 pi int r z dA, " + "A = 2 pi int r ds (Pappus)", + 1, mp, area, [(-40, -40, 0), (40, 40, 40)], faces=12) + + +def c49(): + # Coil: the circle r=2 centred at radius 20 in the meridian plane, screw-swept 3 turns, pitch 8. + Rh, a, p, n = 20.0, 2.0, 8.0, 3.0 + c = p / (2 * PI) + v = n * 2 * PI * Rh * PI * a * a # screw motion: only rotation sweeps volume + # lateral area: n * 2pi * closed-integral sqrt(r^2 + c^2 (dr/ds)^2) ds, r = R + a cos t, dr/ds = -sin t + N = 4096 + s = 0.0 + for k in range(N): + t = 2 * PI * k / N + s += math.sqrt((Rh + a * math.cos(t)) ** 2 + c * c * math.sin(t) ** 2) * a + lat = n * 2 * PI * s * 2 * PI / N + area = lat + 2 * PI * a * a + mp = MP.at(v, [0.0, 0.0, c * n * PI]) # full turns: x,y centroid on the axis; z = c * mean angle + write("49-helical-sweep", + "true helix coil (screw motion of the axial d4 section, R20, pitch 8, 3 turns): " + "V = turns * 2 pi R * pi a^2; lateral A = turns * 2 pi * int sqrt(r^2 + (p/2pi)^2 (dr/ds)^2) ds " + "(periodic trapezoid, exact to round-off) + two end discs; COM z = pitch*turns/2", + 1, mp, area, [(-22, -22, -2), (22, 22, 26)], faces=3) + + +def c50(): + r, Rb = 5.0, 5.0 + l1 = cyl(0, 0, r, 0, 20) + # quarter torus: bend centre (5,0,20), axis Y, from (0,0,20) to (5,0,25). + vb = PI * r * r * (PI / 2 * Rb) + rad_mean = (Rb * Rb + r * r / 4) / Rb # int rho^2 dA / int rho dA + off = rad_mean * (math.sin(PI / 4) / (PI / 4)) / math.sqrt(2) + bend = MP.at(vb, [5 - off, 0, 20 + off]) + l2 = MP.at(PI * r * r * 20, [15, 0, 25]) + mp = l1 + bend + l2 + Lp = 20 + PI / 2 * Rb + 20 + area = 2 * PI * r * Lp + 2 * PI * r * r + write("50-sweep-tight-bend", + "tube r5 along line 20 + R5 quarter bend + line 20: V = pi r^2 L, A = 2 pi r L + 2 pi r^2 " + "(Pappus, valid while bend radius >= r; here equal so the inner side pinches to a line); " + "bend centroid at (R^2 + r^2/4)/R * sinc(pi/4) along the bisector", + 1, mp, area, [(-5, -5, 0), (25, 5, 30)], faces=5) + + +def c52(): + disc = cyl(0, 0, 40, 0, 8) + prof = region([[ + L((0, 8), (8, 8)), + A((8, 10), 2, -PI / 2, -PI), # concave fillet R2 at the boss base + L((6, 10), (6, 18)), L((6, 18), (0, 18)), L((0, 18), (0, 8)), + ]]) + mp = disc + for k in range(6): + th = 2 * PI * k / 6 + mp = mp + revolve(prof, 28 * math.cos(th), 28 * math.sin(th)) + area = (PI * 1600 + 2 * PI * 40 * 8 + PI * 1600 + + 6 * (revolve_area(prof) - 2 * PI * 64)) # boss lateral without its base disc r8; disc top loses it too + write("52-circular-pattern-fillet", + "disc r40 h8 + 6 x (boss r6 h10 with R2 concave base fillet as a solid of revolution, Pappus/Green " + "on its (r,z) profile) at radius 28; disc top loses 6 discs r8", + 1, mp, area, [(-40, -40, 0), (40, 40, 18)], faces=21) + + +def c53(): + cx, cy = 60.0, 10.0 / 3.0 + R = 45.0 - cy + th0 = math.atan2(15 - cy, 100 - cx) + sp = 17.875031 + mp = box(0, 0, 0, 120, 60, 5) + for k in range(7): + th = th0 + k * sp / R + mp = mp - cyl(cx + R * math.cos(th), cy + R * math.sin(th), 3, 0, 5) + area = 2 * (7200 - 7 * PI * 9) + 2 * (120 + 60) * 5 + 7 * 2 * PI * 3 * 5 + write("53-path-pattern", + "plate 120x60x5 minus 7 through holes d6 at arc lengths k*17.875031 along the arc through " + "(100,15),(60,45),(20,15) (centre (60,10/3), R 125/3), translated copies", + 1, mp, area, [(0, 0, 0), (120, 60, 5)], faces=13) + + +def c54(): + # Mirrored + joined: x -30..30, y 0..40, h10, four R5 vertical corner rounds, holes d8 at (+-15,20). + r = 5.0 + outer = [ + L((-25, 0), (25, 0)), A((25, 5), r, -PI / 2, 0), L((30, 5), (30, 35)), A((25, 35), r, 0, PI / 2), + L((25, 40), (-25, 40)), A((-25, 35), r, PI / 2, PI), L((-30, 35), (-30, 5)), A((-25, 5), r, PI, 1.5 * PI), + ] + reg = region([outer, circle_loop((15, 20), 4, False), circle_loop((-15, 20), 4, False)]) + mp = extrude(reg, 0, 10) + area = extrude_area(reg, 10) + write("54-mirror-body-fillets", + "prism h10 of the 60x40 rectangle with four R5 corner rounds and two d8 holes at (+-15,20): " + "V = A h, area = 2A + perimeter*h", + 1, mp, area, [(-30, 0, 0), (30, 40, 10)], faces=12) + + +def c55(): + r, d, half = 3.4, 12.0, math.radians(59) + tip = r / math.tan(half) + mp = (box(0, 0, 0, 40, 30, 15) - cyl(20, 15, r, 15 - d, 15) + - MP.at(PI * r * r * tip / 3, [20, 15, 15 - d - tip / 4])) + area = (2 * 1200 + 2 * (40 * 15 + 30 * 15) - PI * r * r + + 2 * PI * r * d + PI * r * (r / math.sin(half))) + write("55-tapped-hole-cosmetic", + "plate 40x30x15 minus d6.8 cylinder 12 deep (to the shoulder) and 118 deg drill point cone " + "(h = r/tan59, V = pi r^2 h/3, lateral pi r * r/sin59); cosmetic thread adds no geometry", + 1, mp, area, [(0, 0, 0), (40, 30, 15)], faces=8) + + +def c57(): + r, rc, dc, T = 2.75, 5.0, 5.5, 10.0 + mp = box(0, 0, 0, 80, 50, T) + for x in (15, 40, 65): + for y in (15, 35): + mp = mp - cyl(x, y, rc, T - dc, T) - cyl(x, y, r, 0, T - dc) + area = (2 * 4000 + 2 * (80 + 50) * T + + 6 * (-PI * rc * rc - PI * r * r + 2 * PI * rc * dc + PI * (rc * rc - r * r) + 2 * PI * r * (T - dc))) + write("57-hole-pattern-sketch-points", + "plate 80x50x10 minus 6 counterbored through holes (cb d10 x 5.5, hole d5.5) at x 15/40/65, y 15/35", + 1, mp, area, [(0, 0, 0), (80, 50, 10)], faces=24) + + +def c62(): + mp = box(0, 0, 0, 60, 50, 5) + for k in range(15): + x0 = 2 + 4 * k + mp = mp + box(x0, 0, 5, x0 + 1.5, 50, 30) + area = (3000 + 2 * (60 * 5 + 50 * 5) + 3000 - 15 * 1.5 * 50 + + 15 * (2 * 50 * 25 + 2 * 1.5 * 25 + 1.5 * 50)) + write("62-heat-sink", + "base 60x50x5 + 15 fins 1.5x50x25 at x = 2 + 4k: sums of boxes; fin ends coplanar with the base ends", + 1, mp, area, [(0, 0, 0), (60, 50, 30)], faces=66, + note="faces: bottom, x=0, x=60, y=0 and y=50 (each merged with the fin ends), 16 base-top strips, 15x3 fin faces") + + +def c64(): + # Solved sketch: four R12 arcs on chord 20 (sagitta 12 - sqrt 44) alternating up/down from + # (0,0) to (80,0) tangent in a chain, closed by (80,0)-(80,-20)-(0,-20)-(0,0). + R = 12.0 + h = math.sqrt(R * R - 100) # centre distance from the chord + al = math.atan2(h, 10) # half-angle complement + loop = [ + A((10, -h), R, PI - al, al), # a1: (0,0) -> (20,0), bulging up (cw) + A((30, h), R, PI + al, 2 * PI - al), # a2: (20,0) -> (40,0), bulging down (ccw) + A((50, -h), R, PI - al, al), # a3 + A((70, h), R, PI + al, 2 * PI - al), # a4 + L((80, 0), (80, -20)), L((80, -20), (0, -20)), L((0, -20), (0, 0)), + ] + reg = region([reverse(loop)]) # traced clockwise above; reverse to CCW + mp = extrude(reg, 0, 3) + area = extrude_area(reg, 3) + write("64-sketch-tangent-arc-chain", + "solved sketch: 80x20 rectangle whose top is 4 tangent R12 arcs on 20 mm chords alternating " + "up/down (net area 1600); prism h3: V = A h, area = 2A + perimeter*h, Green's theorem for centroid", + 1, mp, area, [(0, -20, 0), (80, R - h, 3)], faces=9) + + +def c66(): + r1, r2, dctr = 12.0, 8.0, 60.0 + al = math.acos((r1 - r2) / dctr) # direction of the outer tangent normals: +-al + outer = [ + A((0, 0), r1, al, 2 * PI - al), + L((r1 * math.cos(al), -r1 * math.sin(al)), (dctr + r2 * math.cos(al), -r2 * math.sin(al))), + A((dctr, 0), r2, -al, al), + L((dctr + r2 * math.cos(al), r2 * math.sin(al)), (r1 * math.cos(al), r1 * math.sin(al))), + ] + holes = [circle_loop((0, 0), 6, False), circle_loop((60, 0), 4, False), + circle_loop((30, 4), 2, False), circle_loop((30, -4), 2, False)] + reg = region([outer] + holes) + mp = extrude(reg, 0, 6) + area = extrude_area(reg, 6) + write("66-sketch-linkage", + "solved sketch: hull of circles R12 at (0,0) and R8 at (60,0) (outer tangent lines, cos a = 4/60) " + "minus holes d12, d8 (concentric) and d4 at (30,+-4) (symmetry keeps radii equal); prism h6", + 1, mp, area, [(-12, -12, 0), (68, 12, 6)], faces=10) + + +CASES = [c32, c33, c38, c40, c43, c44, c45, c46, c48, c49, c50, c52, c53, c54, c55, c57, c62, c64, c66] + +if __name__ == "__main__": + for fn in CASES: + fn() diff --git a/tools/oracle-analytic/cases_sheet_metal.py b/tools/oracle-analytic/cases_sheet_metal.py new file mode 100644 index 00000000..c61a8240 --- /dev/null +++ b/tools/oracle-analytic/cases_sheet_metal.py @@ -0,0 +1,452 @@ +#!/usr/bin/env python3 +"""Closed-form expected values for the sheet-metal oracle cases (67..76). + +Run from the worktree root: python3 tools/oracle-analytic/cases_sheet_metal.py +It (re)writes tests/oracle//expected.json with "source": "analytic". + +Folded sheet metal is built here from first principles as flat plates (prisms of thickness t) +and bends (annular-sector prisms: inner radius R, outer R + t, angle theta), joined face to +face. The conventions that place them are SolidCraft's documented sheet-metal semantics +(crates/doc/src/sheet.rs module docs, docs/book/src/guide/sheet-metal.md): + + * Steel (mm) rule: t = 2.5, R = Thickness, K = 0.44, corner gap = Thickness. + * Edge flange, height datum "outer faces", bend position "inside": the virtual sharp (where + the outer faces would meet) lies on the picked edge's outer corner; the parent panel is + trimmed back by the setback (R + t) tan(theta/2); the flange's outer face measures + `height` from the virtual sharp (along the flange for a non-90 deg angle); the flat leg + past the bend is height - (R + t) tan(theta/2). + * Several flanges in one command meeting at a 90 deg corner: each bend stops at the trimmed + base corner; each panel runs on past its bend by (R + t) - (t + gap/sqrt 2) so the gap + between the panels' inner corners is the rule gap (corner open, no corner fill). + * A later flange on an adjacent edge trims the base under the earlier bend; that bend stops + at the trimmed base corner and the earlier panel runs on alone (an open corner relief). + * Flat hem: 180 deg bend with inner radius hem_gap = 0.01 mm toward the face it starts from + (inside), length measured from the outer face of the hem bend, leg = L - (gap + t). + * Contour flange: the sketch lines are the sheet face on the side away from the material + (material right of travel); a corner that bends toward the material has the sketch + corner as the outer virtual sharp (setback (R+t)tan), the other as inner (setback R tan). + * Unfold/refold: bend zone of flat width BA = theta (R + K t); a point s into the zone maps + to angle s / (R + K t) on the bend; past the zone, flat distance maps 1:1 to the panel. +""" +import json +import math +import os + +ROOT = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..")) +OUT = os.path.join(ROOT, "tests", "oracle") + +PI = math.pi +STEEL = dict(t=2.5, R=2.5, K=0.44, gap=2.5, hem_gap=0.01) + + +# ---------------------------------------------------------------- 2D section pieces +class Poly: + def __init__(self, pts): + self.pts = pts + + def props(self): + a = cx = cy = per = 0.0 + n = len(self.pts) + for i in range(n): + x0, y0 = self.pts[i] + x1, y1 = self.pts[(i + 1) % n] + c = x0 * y1 - x1 * y0 + a += c + cx += (x0 + x1) * c + cy += (y0 + y1) * c + per += math.hypot(x1 - x0, y1 - y0) + a *= 0.5 + return abs(a), (cx / (6 * a), cy / (6 * a)), per + + def box(self): + xs = [p[0] for p in self.pts] + ys = [p[1] for p in self.pts] + return (min(xs), min(ys)), (max(xs), max(ys)) + + +def Rect(u0, u1, v0, v1): + return Poly([(u0, v0), (u1, v0), (u1, v1), (u0, v1)]) + + +class Sector: + """Annular sector: centre c, radii r0 < r1, angles a0 < a1 (radians, CCW).""" + + def __init__(self, c, r0, r1, a0, a1): + self.c, self.r0, self.r1, self.a0, self.a1 = c, r0, r1, a0, a1 + + def props(self): + d = self.a1 - self.a0 + r0, r1 = self.r0, self.r1 + a = d / 2 * (r1 * r1 - r0 * r0) + rho = (2.0 / 3.0) * (r1 ** 3 - r0 ** 3) / (r1 * r1 - r0 * r0) * math.sin(d / 2) / (d / 2) + m = (self.a0 + self.a1) / 2 + cen = (self.c[0] + rho * math.cos(m), self.c[1] + rho * math.sin(m)) + per = d * (r0 + r1) + 2 * (r1 - r0) + return a, cen, per + + def box(self): + pts = [] + for r in (self.r0, self.r1): + for ang in (self.a0, self.a1): + pts.append((r * math.cos(ang), r * math.sin(ang))) + k = math.ceil(self.a0 / (PI / 2) - 1e-12) + while k * PI / 2 <= self.a1 + 1e-12: + ang = k * PI / 2 + pts.append((self.r1 * math.cos(ang), self.r1 * math.sin(ang))) + k += 1 + xs = [p[0] + self.c[0] for p in pts] + ys = [p[1] + self.c[1] for p in pts] + return (min(xs), min(ys)), (max(xs), max(ys)) + + +class Section: + """Union of pieces meeting face to face; `joints` = total length of shared interfaces.""" + + def __init__(self, pieces, joints): + self.pieces, self.joints = pieces, joints + + def props(self): + A = Su = Sv = P = 0.0 + for p in self.pieces: + a, (cu, cv), per = p.props() + A += a + Su += a * cu + Sv += a * cv + P += per + return A, (Su / A, Sv / A), P - 2 * self.joints + + def box(self): + bs = [p.box() for p in self.pieces] + return (min(b[0][0] for b in bs), min(b[0][1] for b in bs)), (max(b[1][0] for b in bs), max(b[1][1] for b in bs)) + + +def extrusion(segments, to_world): + """A solid swept along one axis w: segments = [(w0, w1, Section)], contiguous, with each + section nested in its neighbours (so a step's cap area is the area difference). + to_world(u, v, w) -> (x, y, z). Returns (V, A, com, bbox).""" + V = A = 0.0 + S = [0.0, 0.0, 0.0] + lo = [1e300] * 3 + hi = [-1e300] * 3 + areas = [] + for w0, w1, sec in segments: + a, (cu, cv), per = sec.props() + L = w1 - w0 + V += a * L + A += per * L + c = to_world(cu, cv, (w0 + w1) / 2) + for i in range(3): + S[i] += a * L * c[i] + (u0, v0), (u1, v1) = sec.box() + for u in (u0, u1): + for v in (v0, v1): + for w in (w0, w1): + p = to_world(u, v, w) + for i in range(3): + lo[i] = min(lo[i], p[i]) + hi[i] = max(hi[i], p[i]) + areas.append(a) + A += areas[0] + areas[-1] + for i in range(len(areas) - 1): + A += abs(areas[i] - areas[i + 1]) + return V, A, [s / V for s in S], (lo, hi) + + +# ---------------------------------------------------------------- 3D prisms (corner cases) +def prism(sec_piece, w0, w1, to_world): + a, (cu, cv), per = sec_piece.props() + L = w1 - w0 + c = to_world(cu, cv, (w0 + w1) / 2) + (u0, v0), (u1, v1) = sec_piece.box() + pts = [to_world(u, v, w) for u in (u0, u1) for v in (v0, v1) for w in (w0, w1)] + lo = [min(p[i] for p in pts) for i in range(3)] + hi = [max(p[i] for p in pts) for i in range(3)] + return dict(V=a * L, A=2 * a + per * L, c=c, lo=lo, hi=hi) + + +def assemble(prisms, contacts, extra_V=0.0, extra_A=0.0, extra_S=(0.0, 0.0, 0.0)): + V = sum(p["V"] for p in prisms) + extra_V + A = sum(p["A"] for p in prisms) - 2 * sum(contacts) + extra_A + com = [(sum(p["V"] * p["c"][i] for p in prisms) + extra_S[i]) / V for i in range(3)] + lo = [min(p["lo"][i] for p in prisms) for i in range(3)] + hi = [max(p["hi"][i] for p in prisms) for i in range(3)] + return V, A, com, (lo, hi) + + +# ---------------------------------------------------------------- shared shapes +def yz(u, v, w): # section in (y, z), swept along x + return (w, u, v) + + +def xz(u, v, w): # section in (x, z), swept along y + return (u, w, v) + + +def edge_flange_section(width_y, height, theta, rv, base_far=None): + """Base plate y in [0, width_y] with an edge flange on its y = 0 top edge (bend up, toward + -y), as YZ section pieces. Returns (pieces, joints, info).""" + t, R = rv["t"], rv["R"] + sb = (R + t) * math.tan(theta / 2) + leg = height - sb + zc = t + R + base = Rect(sb, width_y, 0.0, t) + bend = Sector((sb, zc), R, R + t, -PI / 2 - theta, -PI / 2) + # Panel: flat (s along -y from the bend line, z in [0, t]) turned by theta about the axis. + c, s = math.cos(theta), math.sin(theta) + + def place(sv, z): + uu, ww = sv, z - zc # uu outward (-y) from the axis, ww from the axis + ru, rw = uu * c - ww * s, uu * s + ww * c + return (sb - ru, zc + rw) + + panel = Poly([place(0, 0), place(0, t), place(leg, t), place(leg, 0)]) + return [base, bend, panel], 2 * t, dict(setback=sb, leg=leg) + + +# Cases SolidCraft fails today, with the issue that tracks each (cargo xtask oracle reports them +# as known failures and fails once they pass, so the mark is removed with the fix). +KNOWN_FAILURES = {"75-sm-bracket-holes": "#296"} + + +def write(case, d): + if case in KNOWN_FAILURES: + d["known_failure"] = KNOWN_FAILURES[case] + path = os.path.join(OUT, case, "expected.json") + with open(path, "w") as f: + json.dump(d, f, indent=2) + f.write("\n") + + +def clean(v): + """Drop float noise (e.g. 1e-15 from cos(pi/2)) on bbox coordinates.""" + r = round(v, 9) + return r if abs(v - r) < 1e-12 else v + + +def record(V, A, com, bb, method, faces=None, note=None, body_count=1): + bb = ([clean(v) + 0.0 for v in bb[0]], [clean(v) + 0.0 for v in bb[1]]) + d = { + "source": "analytic", + "method": method, + "body_count": body_count, + "volume_mm3": V, + "area_mm2": A, + "center_of_mass": com, + "bbox": {"min": bb[0], "max": bb[1]}, + } + if faces is not None: + d["faces"] = faces + if note: + d["note"] = note + return d + + +# ---------------------------------------------------------------- cases +def c67(): + t = STEEL["t"] + sec = Section([Rect(0, 60, 0, t)], 0) + V, A, com, bb = extrusion([(0, 100, sec)], yz) + return record(V, A, com, bb, "plate 100 x 60 x t, t = 2.5 (Steel (mm) rule), thickness along +Z: V = 100*60*t, A = 2(ab+bc+ca)", faces=6) + + +def single_flange(width_x, width_y, height, theta, rv, method_extra): + pieces, joints, info = edge_flange_section(width_y, height, theta, rv) + V, A, com, bb = extrusion([(0, width_x, Section(pieces, joints))], yz) + return V, A, com, bb, info + + +def c68(): + rv = STEEL + V, A, com, bb, info = single_flange(100, 60, 20, PI / 2, rv, "") + m = ("extrusion along x (100) of the YZ section: base y 5..60 x t; 90 deg bend annulus R 2.5..5 about (y 5, z 5); " + "flange y 0..2.5, z 5..20. Setback (R+t)tan45 = 5 (inside bend position, outer-face height datum: " + "outer face of flange reaches z = 20); V = L*A_sec, A = 2 A_sec + L P_sec") + return record(V, A, com, bb, m, faces=None, + note="trim/setback and height datum are SolidCraft's documented edge-flange conventions (sheet.rs add_flanges)") + + +def c70(): + rv = STEEL + th = PI / 4 + V, A, com, bb, info = single_flange(100, 60, 15, th, rv, "") + m = ("as 68 with a 45 deg bend: setback (R+t)tan22.5 = %.6f, base y %.6f..60, bend annulus 2.5..5 over 45 deg about " + "(y %.6f, z 5), flat leg 15 - setback = %.6f turned 45 deg; extrusion along x 100" % (info["setback"], info["setback"], info["setback"], info["leg"])) + return record(V, A, com, bb, m, faces=None, + note="SolidCraft convention: flange height (15) is measured along the flange's outer face from the virtual sharp at the original edge (y 0, z 0), so the outer top corner is at (y, z) = (-15 cos45, 15 sin45).") + + +def u_channel(rv, wx, wy, h): + t, R = rv["t"], rv["R"] + sb = R + t + zc = t + R + leg = h - sb + pieces = [ + Rect(sb, wy - sb, 0, t), + Sector((sb, zc), R, R + t, -PI, -PI / 2), + Rect(0, t, zc, zc + leg), + Sector((wy - sb, zc), R, R + t, -PI / 2, 0), + Rect(wy - t, wy, zc, zc + leg), + ] + return pieces, sb, leg + + +def c71(): + rv = dict(t=1.5, R=3.0, K=0.33, gap=1.5) + pieces, sb, leg = u_channel(rv, 80, 50, 20) + V, A, com, bb = extrusion([(0, 80, Section(pieces, 4 * rv["t"]))], yz) + m = ("U channel, rule t 1.5, R 3, K 0.33 (K unused folded): base y 4.5..45.5 x 1.5; two 90 deg bend annuli R 3..4.5; " + "flanges y 0..1.5 and 48.5..50, z 4.5..20; extrusion along x 80") + return record(V, A, com, bb, m, faces=None, + note="the rule edit applies to the whole sheet body (base built before it is 1.5 thick too, as the recipe's edge picks at z = 1.5 state)") + + +def c72(): + rv = STEEL + t, R = rv["t"], rv["R"] + # Sketch lines (world XZ): (0,0)->(40,0)->(40,30)->(70,30), material right of travel (+z, then -x, then +z). + pieces = [ + Rect(0, 40 - (R + t), 0, t), # x 0..35 + Sector((40 - (R + t), R + t), R, R + t, -PI / 2, 0), # centre (35, 5) + Rect(40 - t, 40, R + t, 30 - R), # x 37.5..40, z 5..27.5 + Sector((40 + R, 30 - R), R, R + t, PI / 2, PI), # centre (42.5, 27.5) + Rect(40 + R, 70, 30, 30 + t), # x 42.5..70, z 30..32.5 + ] + V, A, com, bb = extrusion([(0, 50, Section(pieces, 4 * t))], xz) + m = ("contour flange, width 50 along +Y, XZ section: plate x 0..35 z 0..2.5; bend R 2.5..5 about (35, 5) (sketch corner = " + "outer virtual sharp, setback R+t); wall x 37.5..40 z 5..27.5; bend R 2.5..5 about (42.5, 27.5) (sketch corner = inner " + "virtual sharp, setback R); plate x 42.5..70 z 30..32.5") + return record(V, A, com, bb, m, faces=None, + note="SolidCraft convention: the sketch lines are the sheet face away from the material (material right of travel); thickness grows to the material side") + + +def c73(): + rv = STEEL + t, R, g = rv["t"], rv["R"], rv["hem_gap"] + pieces, joints, info = edge_flange_section(60, 20, PI / 2, rv) + L = 8.0 + leg = L - (g + t) + hem_bend = Sector((t + g, 20.0), g, g + t, 0.0, PI) + hem_panel = Rect(t + 2 * g, 2 * t + 2 * g, 20.0 - leg, 20.0) + sec = Section(pieces + [hem_bend, hem_panel], joints + 2 * t) + V, A, com, bb = extrusion([(0, 100, sec)], yz) + m = ("68's part (height 20) plus a flat hem on the flange top edge: 180 deg bend, inner radius = hem gap 0.01, outer 2.51, " + "about (y 2.51, z 20), folded toward +y (inside); hem leg 8 - (0.01 + 2.5) = 5.49: y 2.52..5.02, z 14.51..20; " + "extrusion along x 100") + return record(V, A, com, bb, m, faces=None, + note="SolidCraft conventions: hem gap 0.01 mm (rule hem_gap), hem length measured to the outer face of the hem bend (top at z 22.51), hem folds over the flange's inner face.") + + +def c74(): + rv = STEEL + t, R, K = rv["t"], rv["R"], rv["K"] + sb = R + t + zc = t + R + leg = 20 - sb + BA = PI / 2 * (R + K * t) + # Flat: base y 5..45; y=0 side bend zone y (5-BA)..5, panel y (5-BA-15)..(5-BA). + # Slot y -12..10: base strip 5..10, whole bend, panel up to 12 - (BA - 5) from the bend. + cut_panel = -(-12 - (sb - BA)) # flat distance past the bend zone + zcut = zc + cut_panel + full = Section([ + Rect(sb, 50 - sb, 0, t), + Sector((sb, zc), R, R + t, -PI, -PI / 2), + Rect(0, t, zc, zc + leg), + Sector((50 - sb, zc), R, R + t, -PI / 2, 0), + Rect(50 - t, 50, zc, zc + leg), + ], 4 * t) + cut = Section([ + Rect(10, 50 - sb, 0, t), + Sector((50 - sb, zc), R, R + t, -PI / 2, 0), + Rect(50 - t, 50, zc, zc + leg), + Rect(0, t, zcut, zc + leg), + ], 2 * t) + V, A, com, bb = extrusion([(0, 35, full), (35, 45, cut), (45, 80, full)], yz) + m = ("U channel 80x50 (t 2.5, R 2.5, base y 5..45, flanges z 5..20) with the flat-pattern slot x 35..45, y -12..10 refolded: " + "BA = (pi/2)(R + K t) = %.9f, so the slot removes base y 5..10, the whole y=0 bend and the flange from z 5 to " + "5 + (12 - (BA - 5)) = %.9f; x-segments 0..35 / 35..45 / 45..80" % (BA, zcut)) + return record(V, A, com, bb, m, faces=None, + note="unfold/refold maps flat distance through the K-factor neutral layer (K 0.44)") + + +def c75(): + rv = STEEL + t, R = rv["t"], rv["R"] + sb = R + t + zc = t + R + leg1, leg2 = 30 - sb, 15 - sb + P = [] + P.append(prism(Rect(sb, 40, 0, t), 0, 80 - sb, yz)) # base x 0..75, y 5..40 + P.append(prism(Sector((sb, zc), R, R + t, -PI, -PI / 2), 0, 80 - sb, yz)) # bend 1, x 0..75 + P.append(prism(Rect(0, t, zc, zc + leg1), 0, 80, yz)) # flange 1, x 0..80 + P.append(prism(Sector((80 - sb, zc), R, R + t, -PI / 2, 0), sb, 40, xz)) # bend 2, y 5..40 + P.append(prism(Rect(80 - t, 80, zc, zc + leg2), sb, 40, xz)) # flange 2, y 5..40 + contacts = [(80 - sb) * t, (80 - sb) * t, (40 - sb) * t, (40 - sb) * t] + r, n = 3.0, 2 + dV = -n * PI * r * r * t + dA = n * (2 * PI * r * t - 2 * PI * r * r) + dS = (-PI * r * r * t * (25 + 55), -n * PI * r * r * t * 20, -n * PI * r * r * t * t / 2) + V, A, com, bb = assemble(P, contacts, dV, dA, dS) + m = ("base x 0..75, y 5..40, z 0..2.5 (trimmed 5 by each flange's setback); bend 1 (R 2.5..5 about y 5, z 5) x 0..75; " + "flange 1 y 0..2.5, z 5..30, x 0..80; bend 2 (R 2.5..5 about x 75, z 5) y 5..40; flange 2 x 77.5..80, z 5..15, " + "y 5..40; minus two d6 through holes at (25,20), (55,20) in the base. A = sum of prism areas - 2 x 4 joint " + "areas (75t, 75t, 35t, 35t) + hole walls - hole discs") + return record(V, A, com, bb, m, faces=None, + note="SolidCraft convention: the second flange trims the base under the first bend, so bend 1 stops at x 75 while flange 1's panel runs to x 80 (open corner relief, no fill).") + + +def c69(): + rv = STEEL + t, R, gap = rv["t"], rv["R"], rv["gap"] + sb = R + t + zc = t + R + leg = 25 - sb + ext = sb - (t + gap / math.sqrt(2)) + X, Y = 100.0, 60.0 + P = [prism(Rect(sb, Y - sb, 0, t), sb, X - sb, yz)] # base x 5..95, y 5..55 + # y = 0 and y = 60 flanges (swept along x) + P.append(prism(Sector((sb, zc), R, R + t, -PI, -PI / 2), sb, X - sb, yz)) + P.append(prism(Rect(0, t, zc, zc + leg), sb - ext, X - sb + ext, yz)) + P.append(prism(Sector((Y - sb, zc), R, R + t, -PI / 2, 0), sb, X - sb, yz)) + P.append(prism(Rect(Y - t, Y, zc, zc + leg), sb - ext, X - sb + ext, yz)) + # x = 0 and x = 100 flanges (swept along y) + P.append(prism(Sector((sb, zc), R, R + t, -PI, -PI / 2), sb, Y - sb, xz)) + P.append(prism(Rect(0, t, zc, zc + leg), sb - ext, Y - sb + ext, xz)) + P.append(prism(Sector((X - sb, zc), R, R + t, -PI / 2, 0), sb, Y - sb, xz)) + P.append(prism(Rect(X - t, X, zc, zc + leg), sb - ext, Y - sb + ext, xz)) + lx, ly = X - 2 * sb, Y - 2 * sb + contacts = [lx * t] * 4 + [ly * t] * 4 + V, A, com, bb = assemble(P, contacts) + m = ("tray: base 90 x 50 x 2.5 (each edge trimmed by the setback 5); four 90 deg bends R 2.5..5 along the trimmed edges " + "(90, 50, 90, 50 long); four walls 2.5 thick, z 5..25, each running on past its bend by " + "ext = (R+t) - (t + gap/sqrt2) = %.9f at both ends; open corners. A = sum of prisms - 2 x joints" % ext) + return record(V, A, com, bb, m, faces=46, + note="corner treatment is SolidCraft's convention (sheet.rs close_corners: panels extended until their inner corners are the rule gap = t apart; no corner fill, open corner relief below the walls)") + + +def c76(): + rv = dict(t=3.0, R=3.0, K=0.44, gap=3.0) + V, A, com, bb, info = single_flange(100, 60, 20, PI / 2, rv, "") + m = ("final rule thickness 3 (bend radius = Thickness = 3): base y 6..60 x 3; bend annulus R 3..6 about (y 6, z 6); " + "flange y 0..3, z 6..20; extrusion along x 100") + return record(V, A, com, bb, m, faces=None, + note="the rule's thickness edits regenerate the whole sheet body; only the final 3 mm state matters") + + +CASES = { + "67-sm-base-flange": c67, + "68-sm-edge-flange": c68, + "69-sm-tray": c69, + "70-sm-flange-45": c70, + "71-sm-custom-rule": c71, + "72-sm-contour-flange": c72, + "73-sm-hem": c73, + "74-sm-unfold-refold": c74, + "75-sm-bracket-holes": c75, + "76-sm-thickness-variant": c76, +} + +if __name__ == "__main__": + for case, fn in CASES.items(): + d = fn() + write(case, d) + print(case, d["volume_mm3"], d["area_mm2"], [round(c, 6) for c in d["center_of_mass"]]) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c3f488ec..358728e8 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -22,12 +22,10 @@ commands: parity [--refresh] recompute Fusion command parity in docs/parity.md (--refresh rebuilds xtask/data/fusion-catalog.tsv from plan/fusion/menu-tree.json) - oracle replay plan/fusion/oracle/*/recipe.json and compare with measure.json; - writes docs/oracle.md - step-corpus [--iges] [DIR] - import every DIR/*/part.step (default plan/fusion/oracle) and compare - with measure.json; writes docs/step-import.md (--iges: part.igs, - docs/iges-import.md) + oracle [--cli BIN] + replay the reference tests (tests/oracle/*/recipe.json), compare with each + case's expected.json and write docs/oracle.md (--cli: a solvecraft-cli + already built, instead of cargo run --release) book [--no-build] generate docs/book's command reference and screenshots, then mdbook build into target/book @@ -49,8 +47,7 @@ fn main() -> ExitCode { Some("layers") => cmd_layers(), Some("assets") => assets::run(&root()), Some("parity") => parity::run(&root(), rest.contains(&"--refresh")), - Some("oracle") => cmd_oracle(), - Some("step-corpus") => cmd_step_corpus(rest.iter().find(|a| !a.starts_with("--")).copied(), rest.contains(&"--iges")), + Some("oracle") => cmd_oracle(rest.iter().position(|a| *a == "--cli").and_then(|i| rest.get(i + 1)).copied()), Some("book") => book::run(&root(), !rest.contains(&"--no-build")), Some("licences") => licences::run(&root(), rest.contains(&"--check")), Some("test") => { @@ -134,7 +131,8 @@ fn cmd_layers() -> Result<(), String> { } } -/// Features with no Fusion part to compare with, and the tests that check them analytically. +/// Features with no reference case yet, and the tests that check them against hand-computed +/// geometry. const NO_ORACLE: [(&str, &str); 5] = [ ("Boss (draft, root fillet, hole, ribs)", "post, hole and rib volumes (`boss_with_hole_fillet_and_ribs`)"), ("Lip / Groove", "band offsets and groove clearance on a shelled box (`lip_and_groove_on_a_shelled_box`, `groove_takes_the_rule_clearance`)"), @@ -146,41 +144,76 @@ const NO_ORACLE: [(&str, &str); 5] = [ ), ]; -/// Run the CLI's oracle replay over every case directory and write docs/oracle.md. -fn cmd_oracle() -> Result<(), String> { - let dir = root().join("plan/fusion/oracle"); +/// Replay every reference case in tests/oracle, compare with its expected.json and write +/// docs/oracle.md. Fails when a case fails, unless its expected.json names the issue that +/// tracks it (`known_failure`); a known failure that passes fails too, so the mark is removed. +fn cmd_oracle(cli: Option<&str>) -> Result<(), String> { + let dir = root().join("tests/oracle"); let mut cases: Vec = std::fs::read_dir(&dir) - .map_err(|e| format!("{}: {e} (the oracle data is local, in plan/fusion/oracle)", dir.display()))? + .map_err(|e| format!("{}: {e}", dir.display()))? .flatten() .map(|e| e.path()) - .filter(|p| p.join("recipe.json").is_file() && p.join("measure.json").is_file()) + .filter(|p| p.join("recipe.json").is_file()) .collect(); cases.sort(); if cases.is_empty() { - return Err("no oracle cases with recipe.json and measure.json".into()); + return Err(format!("no cases with recipe.json in {}", dir.display())); } - let mut cmd = cargo(); - cmd.args(["run", "-q", "--release", "-p", "solvecraft-cli", "--", "oracle", "--json"]); + let mut cmd = match cli { + Some(bin) => { + let mut c = Command::new(bin); + c.current_dir(root()); + c + } + None => { + let mut c = cargo(); + c.args(["run", "-q", "--release", "-p", "solvecraft-cli", "--"]); + c + } + }; + cmd.args(["oracle", "--json"]); for c in &cases { - cmd.arg(c); + cmd.arg(c.strip_prefix(root()).unwrap_or(c)); } let out = cmd.output().map_err(|e| format!("solvecraft-cli: {e}"))?; let results: serde_json::Value = serde_json::from_slice(&out.stdout).map_err(|e| format!("oracle JSON: {e}\n{}", String::from_utf8_lossy(&out.stderr)))?; let list = results.as_array().cloned().unwrap_or_default(); - let pass = list.iter().filter(|r| r["pass"].as_bool().unwrap_or(false)).count(); - let skipped = list.iter().filter(|r| r["skipped"].as_bool().unwrap_or(false)).count(); - let mut md = format!( - "# Fusion oracle\n\nGenerated by `cargo xtask oracle`. Each case is a part built in Fusion (recipe and measurements kept locally in `plan/fusion/oracle/`, not committed). SolidCraft replays the recipe through its command engine and compares body count, volume and area (relative tolerance 1e-3) and face/edge/vertex counts (exact). SolidCraft counts each closed-surface patch once and ignores seam edges and vertices; when body count, volume and area pass but the raw counts differ, Fusion's counts are normalised the same way from its face, edge and vertex lists (faces cut from one cylinder, cone, sphere or torus and separated only by seams count once; an edge on that surface and no other is a seam and is dropped; a vertex left with two edges joins them) and compared exactly; the note gives both sides' raw counts.\n\n**{pass} / {} cases pass** ({skipped} need features not implemented yet).\n\n| Case | Result | Notes |\n|---|---|---|\n", - list.len() - ); + let expected = |case: &str| -> serde_json::Value { + std::fs::read_to_string(dir.join(case).join("expected.json")).ok().and_then(|t| serde_json::from_str(&t).ok()).unwrap_or_default() + }; + let (mut pass, mut missing, mut known, mut failed, mut fixed) = (0, 0, 0, Vec::new(), Vec::new()); + let mut sources: std::collections::BTreeMap = std::collections::BTreeMap::new(); + let mut rows = String::new(); for r in &list { - let status = if r["pass"].as_bool().unwrap_or(false) { - "pass" - } else if r["skipped"].as_bool().unwrap_or(false) { - "not yet" - } else { - "FAIL" + let case = r["case"].as_str().unwrap_or(""); + let want = expected(case); + let source = want["source"].as_str().unwrap_or("none yet").to_string(); + let source_kind = source.split_whitespace().next().unwrap_or("").to_string(); + *sources.entry(if want.is_null() { "none yet".into() } else { source_kind }).or_default() += 1; + let ok = r["pass"].as_bool().unwrap_or(false); + let issue = want["known_failure"].as_str().map(str::to_string); + let status = match (ok, want.is_null(), &issue) { + (_, true, _) => { + missing += 1; + "no expected values yet".to_string() + } + (true, _, Some(i)) => { + fixed.push(format!("{case} ({i})")); + format!("pass (marked known failure {i}: remove the mark)") + } + (true, _, None) => { + pass += 1; + "pass".to_string() + } + (false, _, Some(i)) => { + known += 1; + format!("known failure ({i})") + } + (false, _, None) => { + failed.push(case.to_string()); + "**FAIL**".to_string() + } }; let mut notes: Vec = r["checks"] .as_array() @@ -189,21 +222,43 @@ fn cmd_oracle() -> Result<(), String> { .filter(|c| !c["ok"].as_bool().unwrap_or(false)) .map(|c| format!("{}: got {} want {}", c["check"].as_str().unwrap_or(""), c["got"], c["want"])) .collect(); - if let Some(e) = r["error"].as_str() { - notes.push(e.replace('|', "/")); + if let Some(e) = r["error"].as_str().filter(|_| !want.is_null()) { + notes.push(e.to_string()); } - if let Some(n) = r["note"].as_str() { - notes.push(n.replace('|', "/")); + if let Some(n) = want["note"].as_str() { + notes.push(n.to_string()); } - md += &format!("| {} | {status} | {} |\n", r["case"].as_str().unwrap_or(""), notes.join("; ")); + let how = want["method"].as_str().unwrap_or(""); + let surface = r["checks"] + .as_array() + .and_then(|cs| cs.iter().find(|c| c["check"] == "surface_distance_mm")) + .and_then(|c| Some((c["got"]["max"].as_f64()?, c["got"]["mean"].as_f64()?, c["got"]["worst_at"].as_array()?.clone()))) + .map(|(max, mean, at)| { + let at: Vec = at.iter().filter_map(|x| x.as_f64()).map(|x| format!("{x:.1}")).collect(); + format!("{max:.3} / {mean:.4} (worst at {})", at.join(", ")) + }) + .unwrap_or_default(); + rows += &format!("| {case} | {source} | {status} | {surface} | {} | {} |\n", how.replace('|', "/"), notes.join("; ").replace('|', "/")); } - md += "\n## No oracle\n\n| Feature | Status | Tested by |\n|---|---|---|\n"; + let counts: Vec = sources.iter().map(|(k, v)| format!("{v} {k}")).collect(); + let mut md = format!( + "# Reference tests\n\nGenerated by `cargo xtask oracle`. Each case in [`tests/oracle/`](../tests/oracle/) is a part described by our own `recipe.json`. SolidCraft replays the recipe through its command engine and compares the result with `expected.json`: body count, volume and area (relative tolerance 1e-3 unless the case states another), centre of mass and bounding box (within 1e-3 of the part's size), face count where the geometry fixes it, and, where the case has a `reference.stl`, the sampled symmetric (Hausdorff) distance between the two surfaces and the principal second moments of both triangulations. Every rebuilt part is also exported as STEP, validated and read back.\n\nWhere the expected values come from (the **Source** column):\n\n- **analytic**: closed-form geometry worked out by hand (prisms, cylinders, cones, spheres, tori and Pappus' theorems, constant-radius fillets on straight edges, sheet-metal bends as annular sectors). The scripts in [`tools/oracle-analytic/`](../tools/oracle-analytic/) compute them and give the formulas.\n- **freecad <version>**: the same recipe built with FreeCAD's public Python scripting API by [`tools/freecad-oracle/`](../tools/freecad-oracle/), an independent kernel run as an external program. FreeCAD is not a dependency of SolidCraft. Where the two kernels legitimately build a different shape (for example the corner patch where fillets meet), only volume and area are compared, within the tolerance the case states.\n\nNo expected value comes from a commercial CAD product.\n\n**{pass} / {} cases pass**; sources: {}. {known} known failure(s) tracked in issues; {missing} case(s) without expected values yet.\n\n| Case | Source | Result | Surface distance mm (max / mean) | Method | Notes |\n|---|---|---|---|---|---|\n", + list.len(), + counts.join(", ") + ); + md += &rows; + md += "\n## Not covered by a reference case\n\n| Feature | Tested by |\n|---|---|\n"; for (feature, test) in NO_ORACLE { - md += &format!("| {feature} | no oracle (licence) | {test} |\n"); + md += &format!("| {feature} | {test} |\n"); } - md += "\nFusion builds these only with its Design Extension, which the oracle account lacks, so there is no Fusion part to compare with. They follow Autodesk's public descriptions of the features and are checked against hand-computed geometry; the plastic rule library values were read from Fusion's API.\n"; std::fs::write(root().join("docs/oracle.md"), md).map_err(|e| format!("docs/oracle.md: {e}"))?; - println!("oracle: {pass}/{} cases pass ({skipped} not yet supported) → docs/oracle.md", list.len()); + println!("oracle: {pass}/{} cases pass, {known} known failures, {missing} without expected values → docs/oracle.md", list.len()); + if !failed.is_empty() { + return Err(format!("{} case(s) failed: {}", failed.len(), failed.join(", "))); + } + if !fixed.is_empty() { + return Err(format!("now passing, remove `known_failure` from expected.json: {}", fixed.join(", "))); + } Ok(()) } @@ -231,108 +286,6 @@ fn wasm_check() -> Result<(Command, usize), String> { Ok((c, set.len())) } -/// Import every oracle STEP file (exported by Fusion) and compare with Fusion's measurements; -/// write docs/step-import.md. -fn cmd_step_corpus(dir: Option<&str>, iges: bool) -> Result<(), String> { - let dir = dir.map(PathBuf::from).unwrap_or_else(|| root().join("plan/fusion/oracle")); - let file = if iges { "part.igs" } else { "part.step" }; - let mut cases: Vec = std::fs::read_dir(&dir) - .map_err(|e| format!("{}: {e} (the oracle data is local, in plan/fusion/oracle)", dir.display()))? - .flatten() - .map(|e| e.path()) - .filter(|p| p.join(file).is_file() && p.join("measure.json").is_file()) - .collect(); - cases.sort(); - if cases.is_empty() { - return Err(format!("no cases with {file} and measure.json in {}", dir.display())); - } - let mut cmd = cargo(); - cmd.args(["run", "-q", "--release", "-p", "solvecraft-cli", "--", "step-corpus", "--json"]); - if iges { - cmd.arg("--iges"); - } - for c in &cases { - cmd.arg(c); - } - let out = cmd.output().map_err(|e| format!("solvecraft-cli: {e}"))?; - let results: serde_json::Value = - serde_json::from_slice(&out.stdout).map_err(|e| format!("step-corpus JSON: {e}\n{}", String::from_utf8_lossy(&out.stderr)))?; - let list = results.as_array().cloned().unwrap_or_default(); - let pass = list.iter().filter(|r| r["pass"].as_bool().unwrap_or(false)).count(); - let check = - |r: &serde_json::Value, name: &str| r["checks"].as_array().and_then(|c| c.iter().find(|c| c["check"] == name).cloned()).unwrap_or_default(); - let num = |v: &serde_json::Value| v.as_f64().map(|x| format!("{x:.3}")).unwrap_or_else(|| "–".into()); - let mut md = if iges { - format!( - "# IGES import (Fusion corpus)\n\nGenerated by `cargo xtask step-corpus --iges`. Each case is a reference part exported from Fusion as IGES 5.3 \ -(kept locally in `plan/fusion/oracle/`, never committed). SolidCraft opens `part.igs` exactly as File → Open does and compares with Fusion's \ -measurements of the part it exported: body count, volume and area (relative tolerance 1e-3) and the number of faces read from the file. \ -How IGES is read: see [STEP import](step-import.md#iges). 50-sweep-tight-bend is written by Fusion as five loose, partly degenerate surfaces \ -(seams running into slits, a ring given twice); Fusion cannot read it back as a solid either.\n\n**{pass} / {} files pass.**\n\n\ -| Case | Result | Bodies | Volume mm³ (got / Fusion) | Area mm² (got / Fusion) | Faces (got / Fusion) | ms | Notes |\n|---|---|---|---|---|---|---|---|\n", - list.len() - ) - } else { - format!( - "# STEP import\n\n\ -SolidCraft 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.\n\n\ -- **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.\n\ -- **Insert** into the current design: File → Insert STEP… or SOLID → INSERT (`file.insert_step {{path}}`).\n\ -- **Drag and drop** a STEP file on the window: inserted when the design has features, opened otherwise.\n\n\ -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.\n\n\ -## IGES\n\n\ -IGES 5.3 files (`.igs`/`.iges`) open, insert and drop the same way: `crates/kernel/src/iges_in.rs` (written from the \ -published specification) restates the file as STEP and the STEP reader reads it, so the feature holds STEP text. Read: \ -manifold solid B-reps (186) with their shells, faces, loops, edge and vertex lists; trimmed (144) and bounded (143) \ -surfaces, and bare B-spline patches, sewn into a solid by their shared edges (an open body when they do not close); \ -lines, circular arcs, ellipses, composite curves, rational B-spline curves; planes (108, 190), cylinders, cones, \ -spheres, tori, rational B-spline surfaces, surfaces of revolution and tabulated cylinders; transformation matrices; \ -units; colours (314 and the predefined numbers); body names (name properties, else labels). Not read yet: ruled and \ -offset surfaces, curves on surfaces given only in parameter space. Export (`file.export` to `.igs`) writes each body as \ -a manifold solid B-rep on the same surfaces a STEP export uses, with its name and colour.\n\n\ -## Fusion corpus\n\nGenerated by `cargo xtask step-corpus`. Each case is a part exported from Fusion as STEP (AP214; kept locally in `plan/fusion/oracle/`, never committed). SolidCraft 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.\n\n**{pass} / {} files pass.**\n\n| Case | Result | Bodies | Volume mm³ (got / Fusion) | Area mm² (got / Fusion) | Faces (got / Fusion) | ms | Notes |\n|---|---|---|---|---|---|---|---|\n", - list.len() - ) - }; - for r in &list { - let status = if r["pass"].as_bool().unwrap_or(false) { "pass" } else { "FAIL" }; - let (v, a, f) = (check(r, "volume_mm3"), check(r, "area_mm2"), check(r, "faces")); - let bodies: Vec = r["bodies"].as_array().into_iter().flatten().filter_map(|b| b.as_str().map(str::to_string)).collect(); - let mut notes: Vec = r["warnings"].as_array().into_iter().flatten().filter_map(|w| w.as_str().map(|w| w.replace('|', "/"))).collect(); - if let Some(e) = r["error"].as_str() { - notes.push(e.replace('|', "/")); - } - md += &format!( - "| {} | {status} | {} | {} / {} | {} / {} | {} / {} | {:.0} | {} |\n", - r["case"].as_str().unwrap_or(""), - bodies.join(", "), - num(&v["got"]), - num(&v["want"]), - num(&a["got"]), - num(&a["want"]), - f["got"].as_f64().map(|x| format!("{x}")).unwrap_or_else(|| "–".into()), - f["want"].as_f64().map(|x| format!("{x}")).unwrap_or_else(|| "–".into()), - r["ms"].as_f64().unwrap_or(0.0), - notes.join("; ") - ); - } - let out_md = if iges { "docs/iges-import.md" } else { "docs/step-import.md" }; - std::fs::write(root().join(out_md), md).map_err(|e| format!("{out_md}: {e}"))?; - println!("step-corpus: {pass}/{} files pass → {out_md}", list.len()); - if pass == list.len() { Ok(()) } else { Err(format!("{} file(s) failed", list.len() - pass)) } -} - /// The quick gates first, so they fail fast; the wasm check (and doc tests) run while the test /// binaries do, which leaves cargo's build lock free. fn cmd_ci() -> Result<(), String> {

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%0D6ByG{RO*&Z6{U)U?>WG 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%0Ad9Y%vVNmONg_q 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