Context
OCCTSwiftScripts has the harness (Sources/Script/main.swift), the runtime (occtkit run), and 10 verbs covering composition, validation, drawing export, feature recognition, and reconstruction. What's missing is a library of worked examples — concrete parametric CAD patterns that show the full toolchain in use, end-to-end.
A recipes folder serves three purposes:
- Onboarding. New users (and LLMs driving OCCTMCP) can copy a recipe and tweak parameters instead of starting from a blank
main.swift.
- Coverage. Building the recipes surfaces latent ergonomic gaps in OCCTSwift — naming inconsistencies, missing convenience inits, awkward API combinations. Each gap becomes a follow-up issue against OCCTSwift.
- Distribution narrative. Turns OCCTSwiftScripts from "harness" into "harness + cookbook" — closer to what users expect from CadQuery / OpenSCAD ecosystems.
Proposed structure
recipes/
├── README.md # Index + screenshots
├── 01-spur-gear/
│ ├── main.swift # ~30–60 lines, runnable with `occtkit run`
│ ├── README.md # Algorithm explanation, parameters, gotchas
│ ├── output.png # Rendered preview
│ └── output.brep # Reference output (for CI smoke test)
├── 02-mounting-bracket/
│ ├── ...
└── ...
Each recipe is self-contained — no shared utility files, no cross-recipe imports. Copy-paste-friendly. Trade some duplication for radically simpler "open one folder, read three files, understand the recipe."
Recipes to seed (10)
Pick a spread that hits the most-used OCCTSwift surface areas. Suggested set, ordered roughly by complexity:
- Spur gear — involute tooth profile, parametric module / tooth count / pressure angle / face width. Exercises: 2D wire construction (involute curves via
Curve2D), Wire.polygon for closure, Shape.extrude, circular pattern.
- Mounting bracket — L-bracket with 4 mounting holes, fillet on the inside corner, optional rib stiffener. Exercises: box, drilled holes, fillets, sweep for rib.
- Sheet-metal enclosure — base plate + 4 walls + lid via
compose-sheet-metal verb (used as a script preamble), with cuts via reconstruct. Exercises: SheetMetal.Builder, FeatureReconstructor cuts.
- Lattice cube — 3D-printable lattice (octet truss or BCC unit cell), parametric cell size and strut diameter. Exercises: linear pattern, sweep along polyline, boolean union of many bodies.
- M8×40 bolt — hex head + threaded shank, ISO-standard thread profile. Exercises: hexagonal wire, revolve, helical sweep for threads, chamfer on thread start.
- Helical compression spring — parametric coil count / wire diameter / outside diameter / pitch. Exercises:
Wire.helix, sweep with section.
- Finger-jointed lid box — laser-cut-style box with finger joints on all four corners. Exercises: 2D profile boolean ops, extrude, mirror.
- Fan blade — single airfoil-section blade, parametric chord / twist / span. Exercises: lofted surface from multiple section profiles, surface-of-revolution for hub.
- Planetary gear set — sun + 3 planets + ring, parametric ratios. Exercises: composition of recipe 1, transforms, assembly via
Document / XCAF.
- Pipe flange — ANSI-style flange with bolt circle, raised face, gasket groove. Exercises: revolve, drilled bolt pattern, chamfer / fillet, threaded center bore.
(The list is a starting set — the exact recipes can be debated / swapped in the PR. The goal is breadth × ten.)
Per-recipe contract
Each recipe ships:
main.swift (~30–60 lines):
- Top-of-file comment block:
// Inputs: ..., // Outputs: ..., // Notes: ...
- All parameters as named
let constants at the top — no magic numbers buried in code
- Single
try ctx.add(shape, id:, color:, name:) per top-level body
- Final
try ctx.emit(description: "...") describing what was built
- Runnable with
occtkit run recipes/<name>/main.swift --format brep,manifest from repo root
- No deps beyond OCCTSwift + ScriptHarness
README.md:
- Title + one-line description
- Parameters table: name, default, description, valid range
- Algorithm explanation (3–8 sentences)
- "OCCTSwift APIs used" — small bulleted list, useful for users searching by API
- Gotchas / edge cases
- Embedded
output.png
output.png:
- Rendered preview, isometric or three-view
- 800×600 px, dark or neutral background (consistent across recipes)
- Generated by OCCTSwiftViewport's
OffscreenRenderer — see Scripts/render-recipe.sh (new) which calls the existing renderer
- Optional: regenerate via
make recipe-render NAME=<name>; missing PNG doesn't fail CI (Viewport may not be available in all environments)
output.brep:
- Reference output committed for diff-ability
- CI compares
recipe → emit BREP against the committed output.brep via byte-equal or BREP-equivalence check (volume + bounding box + face count tolerance comparison if exact byte match is too brittle)
Tooling
Scaffolder:
Creates recipes/NN-widget/ with skeleton main.swift + README.md + a placeholder for output.png. Auto-numbers NN.
CI:
- Each recipe runs via
swift run occtkit run recipes/<name>/main.swift --format brep,manifest
- Asserts: emitted manifest is valid JSON; emitted BREP is non-empty; bounding box volume > 0
- Optional reference comparison if
output.brep exists
- Recipe failures don't block unrelated PRs by default (separate CI job, allowed to fail) — promote to required after the seed batch settles
Renderer:
make recipes-render walks recipes/ and regenerates each output.png
- Skips silently if Viewport / OffscreenRenderer not available
- Don't commit auto-rendered PNGs from CI; treat them as locally-generated artifacts that get committed by the recipe author
Acceptance
Out of scope
- Recipe tutorials / video walk-throughs (recipes themselves are the tutorial)
- Animated preview GIFs (single PNG per recipe is enough for v1)
- Auto-publication to a recipe gallery website (could be a future GitHub Pages job, separate issue)
- Recipe-as-NPM-package or recipe-registry semantics — keep them as plain folders for now
Related
Context
OCCTSwiftScripts has the harness (
Sources/Script/main.swift), the runtime (occtkit run), and 10 verbs covering composition, validation, drawing export, feature recognition, and reconstruction. What's missing is a library of worked examples — concrete parametric CAD patterns that show the full toolchain in use, end-to-end.A recipes folder serves three purposes:
main.swift.Proposed structure
Each recipe is self-contained — no shared utility files, no cross-recipe imports. Copy-paste-friendly. Trade some duplication for radically simpler "open one folder, read three files, understand the recipe."
Recipes to seed (10)
Pick a spread that hits the most-used OCCTSwift surface areas. Suggested set, ordered roughly by complexity:
Curve2D),Wire.polygonfor closure,Shape.extrude, circular pattern.compose-sheet-metalverb (used as a script preamble), with cuts viareconstruct. Exercises: SheetMetal.Builder, FeatureReconstructor cuts.Wire.helix, sweep with section.Document/ XCAF.(The list is a starting set — the exact recipes can be debated / swapped in the PR. The goal is breadth × ten.)
Per-recipe contract
Each recipe ships:
main.swift(~30–60 lines):// Inputs: ...,// Outputs: ...,// Notes: ...letconstants at the top — no magic numbers buried in codetry ctx.add(shape, id:, color:, name:)per top-level bodytry ctx.emit(description: "...")describing what was builtocctkit run recipes/<name>/main.swift --format brep,manifestfrom repo rootREADME.md:output.pngoutput.png:OffscreenRenderer— seeScripts/render-recipe.sh(new) which calls the existing renderermake recipe-render NAME=<name>; missing PNG doesn't fail CI (Viewport may not be available in all environments)output.brep:recipe → emit BREPagainst the committedoutput.brepvia byte-equal or BREP-equivalence check (volume + bounding box + face count tolerance comparison if exact byte match is too brittle)Tooling
Scaffolder:
Creates
recipes/NN-widget/with skeletonmain.swift+README.md+ a placeholder foroutput.png. Auto-numbersNN.CI:
swift run occtkit run recipes/<name>/main.swift --format brep,manifestoutput.brepexistsRenderer:
make recipes-renderwalksrecipes/and regenerates eachoutput.pngAcceptance
recipes/directory with the 10 seed recipesmain.swift,README.md,output.png,output.brepocctkit runand emits non-empty BREPrecipes/README.mdindexing all recipes with thumbnails + one-line descriptionsmake recipe NAME=...scaffolderrecipes/from a new "Examples" sectionOut of scope
Related
list_recipes/load_recipetool pair, letting LLMs browse and start from a recipe rather than write from scratch. File a follow-up issue in OCCTMCP if this lands well.OffscreenRenderer(issue Add introspection JSON verbs: metrics, query-topology, measure-distance (+ JSON output for graph-validate, feature-recognize) #18) is the renderer dependency foroutput.png.