Headless pictures draw on the GPU, with the viewport's pipelines (CPU rasterizer as last tier) (#1555)

Thanks @jyviko.
This commit is contained in:
Irakli Kourtis authored and GitHub committed 2026-10-15 22:19:26 -04:00
1 parent 48322f6464
commit 1a0b33fcf3
54 files changed
+3525 -1998

No files matched your search

+9 -2
View File
@@ -18,5 +18,12 @@ A few rules follow from the layering:
- **Everything the user can do is a command** in `crates/engine`. See
[The command engine](commands.md).
- **The front end is swappable.** Nothing below `ui-egui` depends on egui. The CLI and the MCP
server run the same engine without a window, and `crates/render` has a CPU rasterizer so
headless screenshots work anywhere.
server run the same engine without a window. Headless pictures (`solidcraft-cli snapshot`, MCP
screenshots, `ui.render`, thumbnails) are drawn on the GPU with the viewport's own pipelines
(`crates/gpu`, `capture`): the engine describes the scene (`view::scene`) and the host installs
the renderer (`engine::capture`). The tiers, in order: a hardware GPU, a software adapter (Mesa
lavapipe or llvmpipe, WARP), and last `crates/render`'s CPU rasterizer, which draws no surface
analysis, highlights or legends. `SOLIDCRAFT_GPU=auto` walks all three, `hardware` and `software`
stay on their tier (an error without one), `cpu` forces the rasterizer; every picture's reply
names its `renderer` (`gpu`, `gpu-software`, `cpu`) and a CPU picture carries a warning.
`solidcraft-cli gpu` lists the adapters and the tier the policy lands on.
+1 -1
View File
@@ -186,7 +186,7 @@ A script is a list of commands:
![The bracket example, rendered by solidcraft-cli snapshot](../generated/bracket.png)
`snapshot` looks at the model from the iso view. `--view NAME` takes another standard view (`front`, `back`, `top`, `bottom`, `left`, `right`) or the name of a view saved in the design with `view.save`. `--camera JSON` takes any camera, as the MCP `screenshot` tool does (its conventions are in [the MCP page](mcp.md#camera-and-close-up-recipe)). A script that applies a view itself with `view.apply` sets the camera too. The ground grid lies on Z 0, so it cuts through a part that straddles it: `--no-grid` leaves it out of the picture, and `--no-axes` the origin's axes.
`snapshot` looks at the model from the iso view. `--view NAME` takes another standard view (`front`, `back`, `top`, `bottom`, `left`, `right`) or the name of a view saved in the design with `view.save`. `--camera JSON` takes any camera, as the MCP `screenshot` tool does (its conventions are in [the MCP page](mcp.md#camera-and-close-up-recipe)). A script that applies a view itself with `view.apply` sets the camera too. The ground grid lies on Z 0, so it cuts through a part that straddles it: `--no-grid` leaves it out of the picture, and `--no-axes` the origin's axes. The picture is drawn on the GPU with the viewport's own pipelines, so it shows what the window would (a surface analysis such as `inspect.zebra` included); a machine without a GPU uses a software one (Mesa's lavapipe on Linux, WARP on Windows), and with neither (a Mac without usable Metal, a Linux box without Mesa's Vulkan) the CPU rasterizer draws it, without surface analysis colours, and the reply's `renderer` says `cpu` with a warning. `SOLIDCRAFT_GPU=auto|hardware|software|cpu` chooses (`hardware` and `software` fail rather than fall to the CPU), and `solidcraft-cli gpu` lists the adapters and the tier a snapshot would use.
```sh
solidcraft-cli snapshot part.solidcraft --out photo.png --view Photo