lmcad script authoring skill
Purpose
Help write valid, useful lmscript programs for lmcad and verify their geometry, renders and exports.
When to use it
Use this guide when a task needs a parametric solid, a still render, a mesh export, a looped field of parts, or a keyframed APNG from lmcad.
Install
Use the latest lmcad binary from Releases and lmscript from the published npm package. Source builds need the OpenCASCADE prefix documented in the project README.
Commands
npx --yes --package=@lmctl-ai/lmctl -- lmscript model.lms build/model.dslb
lmcad --dsl build/model.dslb
lmcad --schema
lmcad --schema --json
lmcad --dsl-signatures
Inputs and outputs
- Inputs are DSL source files, JSON schemas for compilation, and optional CSV keyframes.
- Bytecode is compiled for the lmcad schema and run by the lmcad host.
- Outputs include PNG, APNG, PPM, STL and OBJ. Host methods can also export numeric volumes and bounding-box coordinates through the DSL.
Safety rules
- Use finite positive dimensions and keep image and animation sizes within host limits.
- Keep bytecode trusted: the VM intentionally has no run-time execution budget or allocation caps.
- Use unique local names. Host function names, context variables and type names are reserved by the compiler.
- There are no DSL lists; use schema collection objects with len(), at(i) and for (item in collection).
- Cast integer loop indices with float(i) before float arithmetic or float-only method calls.
Worked examples
- Primitive: scene.box(x, y, z, material()), scene.sphere(radius, material()), or scene.cylinder(radius, height, material()).
- Boolean and edge treatment: base.cut(tool), a.union(b), a.intersect(b), shape.fillet(radius), then inspect shape.volume().
- Sketch feature: chain scene.sketch().point(x,y), call close(), then scene.extrude(sketch, height, material()) or scene.revolve_y(sketch, material()).
- Camera and lighting: use scene.fit_camera(42.0, 1.2), directional_light, fill_light and ambient.
- Loops: use for (i in range(0, n)) to place repeated solids. A foreach variable is read-only and scoped to its loop.
- Animation: load keyframes with read_keyframes_csv(path), interpolate with lerp or ease, then call add_frame() and finish().
Errors and exit codes
Compiler errors exit 2 and include source locations. lmcad exits 2 for invalid arguments, 3 for bytecode load or run failures, and 4 for an application failure. A common compile-time error is passing an integer where a float is required; use an explicit conversion. A common run-time error is an invalid OCCT fillet or a render without a camera.
How to verify
- Compile using the lmcad schema.
- Run lmcad --dsl-signatures and compare it with compiler signatures for the same schema.
- Run the bytecode and inspect the JSON result and expected files.
- Use shape.volume() with scene.assert_close for numeric assertions.
- View the PNG and check dimensions, silhouette, lighting and background. Re-run and compare bytes when determinism matters.