Requested by SoftFever on PR #15238: ten of these had accumulated loose in scripts/ next to ~20 unrelated upstream ones, with names that only meant something to whoever wrote them. They now sit in scripts/CAD/, mirroring the src/libslic3r/CAD/ and src/slic3r/GUI/CAD/ split, and the verb in the name is the role: build- produces a binary, start- brings something up, run- runs a suite, check- asserts one thing against a live app. kernel-test.sh -> CAD/run-kernel-tests.sh ladder-all.sh -> CAD/run-all-checks.sh sketch-ladder.py -> CAD/check-sketch-engine.py ladder-corpus.py -> CAD/check-sketch-engine-corpus.py gui-ladder.py -> CAD/check-gui-sketching.py offer-ladder.py -> CAD/check-gui-context-menu.py mcp-sketch-smoke.py -> CAD/check-mcp-sketch.py rig-build.sh -> CAD/build-gui.sh docker-iter-build.sh -> CAD/build-gui-incremental.sh gui-session.sh -> CAD/start-headless-gui.sh "Ladder" was the worst of them: it named the shape of the test (rungs of increasing difficulty) rather than what the test proves, so nothing in the directory listing told you which one needed a GPU and which was pure kernel. Every reference rewritten -- the docs, the cross-calls between the scripts, Dockerfile.deps, and the container-side /OrcaSlicer/scripts paths. The three shell scripts resolve REPO relative to themselves and now sit one level deeper, so that walk went from /.. to /../.. . The copies these push into a container's /tmp were renamed to match, or the container would have kept the old names alive. Two runtime paths deliberately NOT renamed. /tmp/orca-rig-build.lock is a cross-fork contract -- both forks take the same lock so two concurrent builds serialise instead of OOMing the box, and renaming it on one side silently removes that guard. /tmp/gui-session.log is a runtime artefact, not a script. Added scripts/CAD/README.md: what each script proves, what it needs, and the two constraints that have each cost a session (never build inside the GUI container; a window manager is required or synthetic keys are ignored). On CI, which was the other half of the request: the kernel suite is already there and always has been. The cases are registered in tests/libslic3r/CMakeLists.txt under if (SLIC3R_CAD), which defaults ON and no workflow turns off, so they build into libslic3r_tests and run under ctest on every platform via unit_tests.yml -- like any other unit test, needing no new job. They have simply never been seen to run, because the workflows on this PR are still awaiting maintainer approval. run-kernel-tests.sh is the local loop over the same cases, and it is the only script here CI could run: the other six need an OpenGL canvas and synthetic input. Verified: scripts/CAD/run-kernel-tests.sh from its new location, all tests passed, 2562 assertions in 190 test cases.
Design-tab scripts
Everything here supports the parametric Design tab (src/libslic3r/CAD/,
src/slic3r/GUI/CAD/). Nothing here is needed to build or run OrcaSlicer — these
are the development and verification tools for that one feature.
The verb in the name is the role:
build-… |
produce a binary |
start-… |
bring something up and leave it running |
run-… |
run a suite and report pass/fail |
check-… |
one specific assertion, usually driving a live app |
Verification
| Script | What it proves | Needs |
|---|---|---|
run-kernel-tests.sh |
The CAD kernel builds and the Catch2 [CadDocument] tags pass — every case builds a document, recomputes it and asserts on real geometry. Exit 0 is the verification contract. |
Docker only. No display. |
run-all-checks.sh |
Every check below, in one command. The gate before pushing a Design-tab change. | Docker + the GUI container |
check-sketch-engine.py |
A ladder of 2D sketches of increasing complexity, judged on loop count, closure and void attribution rather than on area. | Kernel only |
check-sketch-engine-corpus.py |
The same ladder graded against a systematic sample of real drawings instead of shapes we chose. | Kernel + corpus |
check-gui-sketching.py |
The same profiles drawn the way a person draws them — synthetic mouse gestures and typed values. | Headless GUI |
check-gui-context-menu.py |
That right-click is the pivot of the design gesture, and adapts to what was clicked. | Headless GUI |
check-mcp-sketch.py |
The sketch layer driven over the MCP socket, asserting what decides whether a profile is buildable. | Headless GUI + SNAPORCA_MCP |
run-kernel-tests.sh is the only one CI can run. The rest need a live
application with an OpenGL canvas and synthetic input, which hosted runners do not
have. The kernel suite itself is already in CI by an ordinary route: the cases are
registered in tests/libslic3r/CMakeLists.txt under if (SLIC3R_CAD), so they are
part of libslic3r_tests and run under ctest on every platform like any other
unit test. This script exists for the local loop, where it is a two-minute round
trip instead of a full application build.
Build and run
| Script | Purpose |
|---|---|
build-gui.sh |
Build the GUI binary in a throwaway container, writing into the build-cache volume the long-lived GUI container reads. |
build-gui-incremental.sh |
Incremental build against the deps-baked image, for a fast edit/compile loop. |
start-headless-gui.sh |
Bring the app up on a headless X display (Xvfb + a window manager), ready to drive or attach to over VNC. |
Two constraints that are not obvious and have each cost a session:
- Never build inside the GUI container. Its baked source tree silently reconfigures the shared build directory and this fork's targets vanish.
- A window manager is required. Without one, windows are never focused, and an unfocused GTK app ignores synthetic keys — which looks exactly like a code bug.
docs/rig_build_traps.md documents these and three more, with symptoms and exact
recovery commands. Read it before debugging a configure or link failure one of
these scripts reports.