mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-24 17:26:47 +00:00
Move the Design-tab scripts into scripts/CAD/ and name them by role
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.
This commit is contained in:
@@ -46,7 +46,7 @@ is new code. The negotiable surface is the 37 modified files.
|
||||
205 `TEST_CASE` blocks across 6 new test source files. This counts assertions written, not
|
||||
assertions passed — a run needs a build.
|
||||
|
||||
`scripts/kernel-test.sh` is the headless verification contract: it builds only
|
||||
`scripts/CAD/run-kernel-tests.sh` is the headless verification contract: it builds only
|
||||
`libslic3r_tests` (not the GUI app), needs no display, and exit 0 means the CAD suite
|
||||
passed. It now runs with **no exclusions** — both cases that used to be quarantined (the
|
||||
circle-line tangency solver abort and the internal-thread reference) are fixed.
|
||||
|
||||
+14
-14
@@ -3,16 +3,16 @@
|
||||
The build rig is two long-lived containers, `snaporca-gui` and `orcacad-gui`, one per fork. Each
|
||||
mounts only its fork's build volume (`snaporca_buildcache` / `orcacad_buildcache`) at
|
||||
`/OrcaSlicer/build`, its fork's `resources/`, and a shots directory — nothing else. They run the
|
||||
binary; they do not build it. Rebuild with `scripts/rig-build.sh`.
|
||||
binary; they do not build it. Rebuild with `scripts/CAD/build-gui.sh`.
|
||||
|
||||
| fork repo | project() | deps image | build volume | GUI container | binary |
|
||||
|---|---|---|---|---|---|
|
||||
| `snaporca` | `Snapmaker_Orca` | `snaporca-deps` | `snaporca_buildcache` | `snaporca-gui` | `snapmaker-orca` |
|
||||
| `orca_cad` | `OrcaSlicer` | `orcacad-deps` | `orcacad_buildcache` | `orcacad-gui` | `orca-slicer` |
|
||||
|
||||
`scripts/rig-build.sh` exists alongside `scripts/docker-iter-build.sh` for one reason: it does a
|
||||
`scripts/CAD/build-gui.sh` exists alongside `scripts/CAD/build-gui-incremental.sh` for one reason: it does a
|
||||
target-only `ninja` into the volume the GUI rig launches from, so a session can test a single
|
||||
change without a full repackage, whereas `docker-iter-build.sh` runs the full packaged build.
|
||||
change without a full repackage, whereas `build-gui-incremental.sh` runs the full packaged build.
|
||||
Both start a throwaway container from the deps image with the live repo mounted over the baked
|
||||
tree — never build inside the GUI container (Trap 1).
|
||||
|
||||
@@ -32,7 +32,7 @@ reports an unknown target, and `orca-slicer` / `OrcaSlicer` have been replaced b
|
||||
`snaporca-deps`, so even on the mainline fork the baked tree is the other fork's. A `cmake .`
|
||||
there reconfigures the shared build dir under the wrong project name.
|
||||
|
||||
**Fix.** Build only via `scripts/rig-build.sh`, which starts a throwaway container from the deps
|
||||
**Fix.** Build only via `scripts/CAD/build-gui.sh`, which starts a throwaway container from the deps
|
||||
image with the live repo mounted over the baked tree — `src`, `resources`, `cmake`, `deps_src`,
|
||||
`localization`, `CMakeLists.txt`, `version.inc` — and writes into the same volume the rig
|
||||
launches from.
|
||||
@@ -66,7 +66,7 @@ fork's root `CMakeLists.txt`, near line 948).
|
||||
**Cause.** The deps image predates that requirement. Only the mainline (`orca_cad`) fork has
|
||||
`deps_src/pybind11` and the requirement; snaporca has neither.
|
||||
|
||||
**Fix.** Mount `deps_src` over the baked tree — `scripts/rig-build.sh` does. Corollary: mounting a
|
||||
**Fix.** Mount `deps_src` over the baked tree — `scripts/CAD/build-gui.sh` does. Corollary: mounting a
|
||||
snaporca tree into an `orcacad-deps` build reproduces this error exactly.
|
||||
|
||||
---
|
||||
@@ -83,7 +83,7 @@ its own configure, while the consumer in the root `CMakeLists.txt` (`if (NOT OCC
|
||||
after the `TKFillet TKOffset` prepend (`src/libslic3r/CMakeLists.txt:599`) therefore links the
|
||||
previous list and drops `TKBool`/`TKOffset`.
|
||||
|
||||
**Fix.** Configure twice. `scripts/rig-build.sh` runs `cmake .` twice for exactly this reason; if
|
||||
**Fix.** Configure twice. `scripts/CAD/build-gui.sh` runs `cmake .` twice for exactly this reason; if
|
||||
you ever configure by hand, run it twice.
|
||||
|
||||
---
|
||||
@@ -100,7 +100,7 @@ snaporca, 319/320 in orca_cad). Every `#ifdef SLIC3R_CAD` block therefore compil
|
||||
option still reads ON.
|
||||
|
||||
**Fix.** Always mount the live `CMakeLists.txt` and `cmake/` — never inherit them from the image.
|
||||
This is why `scripts/docker-iter-build.sh`, `scripts/kernel-test.sh` and `scripts/rig-build.sh`
|
||||
This is why `scripts/CAD/build-gui-incremental.sh`, `scripts/CAD/run-kernel-tests.sh` and `scripts/CAD/build-gui.sh`
|
||||
all mount both.
|
||||
|
||||
---
|
||||
@@ -109,18 +109,18 @@ all mount both.
|
||||
|
||||
`ninja <target>` writes `/OrcaSlicer/build/src/Release/<binary>`; only `build_linux.sh`
|
||||
additionally packages to `/OrcaSlicer/build/package/bin/<binary>`. `orca_cad`'s
|
||||
`scripts/gui-session.sh` defaults `BIN` to `src/Release/orca-slicer`, but snaporca's defaults to
|
||||
`scripts/CAD/start-headless-gui.sh` defaults `BIN` to `src/Release/orca-slicer`, but snaporca's defaults to
|
||||
`package/bin/snapmaker-orca`. So after a target-only rebuild on snaporca, launching
|
||||
`gui-session.sh` with its default runs the **stale packaged** binary — the change under test is
|
||||
`start-headless-gui.sh` with its default runs the **stale packaged** binary — the change under test is
|
||||
invisible and the session hunts a phantom. Pass `BIN` explicitly:
|
||||
|
||||
docker exec -e BIN=/OrcaSlicer/build/src/Release/snapmaker-orca snaporca-gui /OrcaSlicer/scripts/gui-session.sh
|
||||
docker exec -e BIN=/OrcaSlicer/build/src/Release/snapmaker-orca snaporca-gui /OrcaSlicer/scripts/CAD/start-headless-gui.sh
|
||||
|
||||
`scripts/rig-build.sh` prints the correct line for the current fork when it finishes.
|
||||
`scripts/CAD/build-gui.sh` prints the correct line for the current fork when it finishes.
|
||||
|
||||
Note also that the GUI containers do **not** mount `scripts/`: `/OrcaSlicer/scripts` inside them
|
||||
is the baked copy, so a local edit to `gui-session.sh` has no effect until you
|
||||
`docker cp scripts/gui-session.sh <container>:/OrcaSlicer/scripts/`.
|
||||
is the baked copy, so a local edit to `start-headless-gui.sh` has no effect until you
|
||||
`docker cp scripts/CAD/start-headless-gui.sh <container>:/OrcaSlicer/scripts/`.
|
||||
|
||||
---
|
||||
|
||||
@@ -144,7 +144,7 @@ a real fault in your code gets past the version banner. Compare
|
||||
|
||||
## Trap 7 — a single-instance app plus a path-matched `pkill`
|
||||
|
||||
`gui-session.sh` used to kill by `"$BIN"`, while its own `app_pid()` matched by BASENAME. Launch
|
||||
`start-headless-gui.sh` used to kill by `"$BIN"`, while its own `app_pid()` matched by BASENAME. Launch
|
||||
with a `BIN` that differs from the running instance's path and the old process survives, keeps
|
||||
the single-instance lock, and the new one exits seconds after loading fonts — then `status`
|
||||
reports the *stale* pid as a healthy session. Fixed by killing on the basename; `status` now also
|
||||
|
||||
@@ -144,7 +144,7 @@ def main():
|
||||
text = "\n".join(lines)
|
||||
# --check: prove the checked-in header IS what this generator produces, and change nothing.
|
||||
# The header calls itself GENERATED and was hand-edited anyway; a claim like that is only
|
||||
# worth having if something enforces it, so ladder-all.sh runs this on every gate.
|
||||
# worth having if something enforces it, so run-all-checks.sh runs this on every gate.
|
||||
if "--check" in sys.argv:
|
||||
have = open(OUT, encoding="utf-8").read() if os.path.exists(OUT) else ""
|
||||
if have == text:
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# 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.
|
||||
@@ -9,8 +9,8 @@
|
||||
# Result: edit -> rebuild in seconds-to-minutes instead of a full Docker rebuild.
|
||||
#
|
||||
# Usage (run on the build host, e.g. behemoth, from anywhere):
|
||||
# scripts/docker-iter-build.sh
|
||||
# IMAGE=orcacad-deps scripts/docker-iter-build.sh
|
||||
# scripts/CAD/build-gui-incremental.sh
|
||||
# IMAGE=orcacad-deps scripts/CAD/build-gui-incremental.sh
|
||||
#
|
||||
# On success the binary is inside the persistent volume at
|
||||
# /OrcaSlicer/build/package/bin/orca-slicer (copy it out with a follow-up
|
||||
@@ -18,8 +18,8 @@
|
||||
# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# orcacad-deps, NOT snaporca-deps: see the note in kernel-test.sh — the wrong image
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
# orcacad-deps, NOT snaporca-deps: see the note in run-kernel-tests.sh — the wrong image
|
||||
# fails at CMake configure, not at link time.
|
||||
IMAGE="${IMAGE:-orcacad-deps}"
|
||||
BUILD_VOL="${BUILD_VOL:-orcacad_buildcache}"
|
||||
@@ -42,10 +42,10 @@ echo "REPO=$REPO IMAGE=$IMAGE BUILD_VOL=$BUILD_VOL"
|
||||
# ---- OOM guard (2026-08-21) -------------------------------------------------------------
|
||||
# Two of these builds ran at once on 2026-08-21, each with ninja -j$(nproc)=16: ~36 cc1plus
|
||||
# holding 42 GB of a 62 GB box -> global OOM at 21:05, a 2h28m kill storm, ssh unreachable,
|
||||
# lightdm destroyed. Neither build produced a single object. scripts/rig-build.sh grew the
|
||||
# lightdm destroyed. Neither build produced a single object. scripts/CAD/build-gui.sh grew the
|
||||
# bounds first; every script that starts a compile needs the same three, or the guard is only
|
||||
# as strong as the script you happened not to use.
|
||||
# flock — the lock path is SHARED with rig-build.sh and the other fork on purpose, so
|
||||
# flock — the lock path is SHARED with build-gui.sh and the other fork on purpose, so
|
||||
# concurrent builds serialise instead of summing.
|
||||
# -j — bounded parallelism; ~1.17 GB per cc1plus was the measured average.
|
||||
# --memory — the actual guarantee: a runaway build dies in its own cgroup instead of taking
|
||||
@@ -9,11 +9,11 @@
|
||||
# Read that file before debugging a configure or link failure this script reports.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/rig-build.sh # configure + build the fork's GUI target
|
||||
# DRY_RUN=1 scripts/rig-build.sh # print the resolved fork identity and exit, no container
|
||||
# scripts/CAD/build-gui.sh # configure + build the fork's GUI target
|
||||
# DRY_RUN=1 scripts/CAD/build-gui.sh # print the resolved fork identity and exit, no container
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
# Fork identity is DERIVED from the repo, never hardcoded, so this file is byte-identical in
|
||||
# both forks and cannot be mirrored into the wrong one. Pointing a fork at the other fork's
|
||||
@@ -53,7 +53,7 @@ LOCK=/tmp/orca-rig-build.lock
|
||||
|
||||
exec 9>"$LOCK"
|
||||
if ! flock -n 9; then
|
||||
echo "another fork's rig-build holds $LOCK — waiting (this is the OOM guard, not a hang)"
|
||||
echo "another fork's build-gui holds $LOCK — waiting (this is the OOM guard, not a hang)"
|
||||
flock 9
|
||||
fi
|
||||
|
||||
@@ -90,9 +90,9 @@ docker run --rm \
|
||||
exit \$rc
|
||||
" || rc=$?
|
||||
|
||||
# A target-only build writes src/Release/, but this fork's gui-session.sh may default BIN to the
|
||||
# A target-only build writes src/Release/, but this fork's start-headless-gui.sh may default BIN to the
|
||||
# PACKAGED path that only build_linux.sh refreshes — launching with the default would then run a
|
||||
# stale binary. Pass BIN explicitly. See docs/rig_build_traps.md.
|
||||
echo "=== launch the rig on the binary just built ==="
|
||||
echo " docker exec -e BIN=/OrcaSlicer/build/src/Release/$BIN ${PREFIX}-gui /OrcaSlicer/scripts/gui-session.sh"
|
||||
echo " docker exec -e BIN=/OrcaSlicer/build/src/Release/$BIN ${PREFIX}-gui /OrcaSlicer/scripts/CAD/start-headless-gui.sh"
|
||||
exit "$rc"
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""The OFFER ladder: prove that right-click is the pivot, and that it adapts to what was clicked.
|
||||
|
||||
The gesture ladder (scripts/gui-ladder.py) proved the TARGET — a complex closed profile, precise
|
||||
The gesture ladder (scripts/CAD/check-gui-sketching.py) proved the TARGET — a complex closed profile, precise
|
||||
in vertices, lengths, arcs and symmetry, with its voids correctly attributed. It proved it by
|
||||
arming every tool with a letter key. That leaves the goal's own MECHANISM untested: the design
|
||||
logic pivots on right-click, and the verbs offered are supposed to adapt to the element under the
|
||||
@@ -20,7 +20,7 @@ This ladder drives the menu. Nothing here is asserted from pixels:
|
||||
|
||||
Run inside the rig container, with the app launched under SNAPORCA_KEYTRACE=1:
|
||||
|
||||
docker exec snaporca-gui python3 /OrcaSlicer/scripts/offer-ladder.py [rung ...]
|
||||
docker exec snaporca-gui python3 /OrcaSlicer/scripts/CAD/check-gui-context-menu.py [rung ...]
|
||||
"""
|
||||
import importlib.util
|
||||
import math
|
||||
@@ -34,7 +34,7 @@ HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
# The gesture ladder owns the hand and the eye: the homography per sketch, the window lookup by
|
||||
# class, the synthetic click, the typed value, the socket. Importing it is the only way those
|
||||
# stay one implementation — a second copy would drift the first time a rig detail moved.
|
||||
_spec = importlib.util.spec_from_file_location("gui_ladder", os.path.join(HERE, "gui-ladder.py"))
|
||||
_spec = importlib.util.spec_from_file_location("gui_ladder", os.path.join(HERE, "check-gui-sketching.py"))
|
||||
G = importlib.util.module_from_spec(_spec)
|
||||
_spec.loader.exec_module(G)
|
||||
|
||||
@@ -617,7 +617,7 @@ def clicked(X, Y):
|
||||
def fresh_sketch(tool):
|
||||
"""Enter a sketch from a KNOWN empty state, whatever the previous rung or run left behind.
|
||||
|
||||
gui-ladder's enter_sketch dismisses the old session with keys, and a key is exactly what an
|
||||
check-gui-sketching's enter_sketch dismisses the old session with keys, and a key is exactly what an
|
||||
open value field swallows — so a session that should have been cancelled survives, the four
|
||||
calibration probes land in it on top of whatever was already there, and the run dies with
|
||||
"calibration expected 4 points, got 7". Cancelling through the socket cannot be swallowed:
|
||||
@@ -1196,7 +1196,7 @@ RUNGS = {"kinds": rung_kinds, "vocabulary": rung_vocabulary,
|
||||
|
||||
def main():
|
||||
if not os.path.exists(LOG):
|
||||
G.die(f"no {LOG} — launch the app through scripts/gui-session.sh")
|
||||
G.die(f"no {LOG} — launch the app through scripts/CAD/start-headless-gui.sh")
|
||||
if "[OFFER]" not in open(LOG, errors="replace").read()[-400000:]:
|
||||
print(f"note: no [OFFER] lines in {LOG} yet — the app must run with SNAPORCA_KEYTRACE=1")
|
||||
want = sys.argv[1:] or list(RUNGS)
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""A ladder of sketches drawn the way a person draws them: mouse gestures and typed values.
|
||||
|
||||
WHY THIS EXISTS, next to scripts/sketch-ladder.py. That ladder proves the ENGINE — it feeds
|
||||
WHY THIS EXISTS, next to scripts/CAD/check-sketch-engine.py. That ladder proves the ENGINE — it feeds
|
||||
geometry through the MCP socket's add_entities_scripted and grades what comes back. The socket
|
||||
path skips everything the goal actually rests on: gesture state, the auto-edit queue, snapping,
|
||||
inference at gesture tolerance, and the right-click offer. A ladder that only drives the socket
|
||||
@@ -11,8 +11,8 @@ here ONLY as an instrument, never as an author.
|
||||
|
||||
Runs INSIDE the headless rig container (Xvfb :10 + openbox + the app with SNAPORCA_MCP set):
|
||||
|
||||
docker cp scripts/gui-ladder.py snaporca-gui:/tmp/ && \
|
||||
docker exec snaporca-gui python3 /tmp/gui-ladder.py [rung ...]
|
||||
docker cp scripts/CAD/check-gui-sketching.py snaporca-gui:/tmp/ && \
|
||||
docker exec snaporca-gui python3 /tmp/check-gui-sketching.py [rung ...]
|
||||
|
||||
With no arguments every rung runs. Exit 0 = every property held.
|
||||
"""
|
||||
@@ -9,7 +9,7 @@ loop: build a known profile, ask the app what it thinks it has, compare against
|
||||
|
||||
RUN IT AGAINST A RUNNING APP:
|
||||
SNAPORCA_MCP=/tmp/mcp.sock <binary> # launch with the socket enabled
|
||||
python3 scripts/mcp-sketch-smoke.py [socket] # default /tmp/mcp.sock
|
||||
python3 scripts/CAD/check-mcp-sketch.py [socket] # default /tmp/mcp.sock
|
||||
|
||||
Exit 0 = every assertion held. Anything else prints the first mismatch and stops.
|
||||
"""
|
||||
@@ -20,7 +20,7 @@ agree, and that the engine's own operations preserve what they promise.
|
||||
MIRROR a real closed profile, mirrored, is still exactly one closed loop
|
||||
OFFSET a real closed profile, offset, is still closed
|
||||
|
||||
Usage: ladder-corpus.py [--sample N] [--corpus DIR]
|
||||
Usage: check-sketch-engine-corpus.py [--sample N] [--corpus DIR]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -16,7 +16,7 @@ Every rung asserts those. Area appears only as a cross-check, never as the verdi
|
||||
Entirely 2D: sketch entities only, no extrude, revolve or any solid feature.
|
||||
|
||||
SNAPORCA_MCP=/tmp/mcp.sock <binary>
|
||||
python3 scripts/sketch-ladder.py [socket]
|
||||
python3 scripts/CAD/check-sketch-engine.py [socket]
|
||||
|
||||
Exit 0 = every rung held. Otherwise the first broken property is named and the run stops.
|
||||
"""
|
||||
@@ -6,12 +6,12 @@
|
||||
# run this, read the last line, and do not push a red one. The kernel suite is the only part CI
|
||||
# can carry, and it already does.
|
||||
#
|
||||
# scripts/ladder-all.sh # kernel + engine + corpus (every 20th) + gestures + offer
|
||||
# FULL=1 scripts/ladder-all.sh # corpus over ALL 997 sheets (~25 min)
|
||||
# SKIP_GUI=1 scripts/ladder-all.sh # kernel only, for a machine with no rig
|
||||
# scripts/CAD/run-all-checks.sh # kernel + engine + corpus (every 20th) + gestures + offer
|
||||
# FULL=1 scripts/CAD/run-all-checks.sh # corpus over ALL 997 sheets (~25 min)
|
||||
# SKIP_GUI=1 scripts/CAD/run-all-checks.sh # kernel only, for a machine with no rig
|
||||
#
|
||||
# The rig container is expected to be up with the app running and SNAPORCA_MCP set; bring it up
|
||||
# with scripts/gui-session.sh inside it. The corpus lives at /corpus in that container.
|
||||
# with scripts/CAD/start-headless-gui.sh inside it. The corpus lives at /corpus in that container.
|
||||
set -uo pipefail
|
||||
cd "$(dirname "$0")/.." || exit 1
|
||||
|
||||
@@ -43,17 +43,17 @@ run_in_rig() { # copy the script in fresh, then run it ther
|
||||
# 92-row array, so the last verb was unreachable (snaporca-z8rs, snaporca-ziam).
|
||||
step "offer table matches the atlas" python3 docs/ux/mockups/gen_offer_table.py --check
|
||||
|
||||
step "kernel suite" scripts/kernel-test.sh --vol "${KVOL:-snaporca_kerneltest}"
|
||||
step "kernel suite" scripts/CAD/run-kernel-tests.sh --vol "${KVOL:-snaporca_kerneltest}"
|
||||
|
||||
if [ -z "${SKIP_GUI:-}" ]; then
|
||||
step "engine ladder (rungs 1-8, scripted geometry)" \
|
||||
run_in_rig scripts/sketch-ladder.py /tmp/sketch-ladder.py
|
||||
run_in_rig scripts/CAD/check-sketch-engine.py /tmp/check-sketch-engine.py
|
||||
step "corpus rung (real drawings, every ${STEP}th)" \
|
||||
run_in_rig scripts/ladder-corpus.py /tmp/ladder-corpus.py --corpus "$CORPUS" --step "$STEP"
|
||||
run_in_rig scripts/CAD/check-sketch-engine-corpus.py /tmp/check-sketch-engine-corpus.py --corpus "$CORPUS" --step "$STEP"
|
||||
step "corpus scale rung (the heaviest sheets)" \
|
||||
run_in_rig scripts/ladder-corpus.py /tmp/ladder-corpus.py --corpus "$CORPUS" --scale
|
||||
run_in_rig scripts/CAD/check-sketch-engine-corpus.py /tmp/check-sketch-engine-corpus.py --corpus "$CORPUS" --scale
|
||||
step "gesture ladder (mouse and keyboard)" \
|
||||
run_in_rig scripts/gui-ladder.py /tmp/gui-ladder.py
|
||||
run_in_rig scripts/CAD/check-gui-sketching.py /tmp/check-gui-sketching.py
|
||||
# The offer ladder needs TWO extra things the others do not: the app must have been launched
|
||||
# with SNAPORCA_KEYTRACE=1 (its [OFFER] lines are the whole instrument), and it reads the
|
||||
# generated offer table to predict what each selection should show — which is not in the
|
||||
@@ -61,7 +61,7 @@ if [ -z "${SKIP_GUI:-}" ]; then
|
||||
# run_in_rig puts the script, is one of the paths the ladder looks in.
|
||||
docker cp src/slic3r/GUI/CAD/DesignOffer.hpp "$C:/tmp/DesignOffer.hpp" >/dev/null
|
||||
step "offer ladder (right-click, the menu, the verbs behind it)" \
|
||||
run_in_rig scripts/offer-ladder.py /tmp/offer-ladder.py
|
||||
run_in_rig scripts/CAD/check-gui-context-menu.py /tmp/check-gui-context-menu.py
|
||||
fi
|
||||
|
||||
echo
|
||||
@@ -7,10 +7,10 @@
|
||||
# CadDocument, recompute()s it and asserts on geometry.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/kernel-test.sh # [CadDocument] tags, default volume
|
||||
# scripts/kernel-test.sh --tags '[CadDocument],[Sketch]'
|
||||
# scripts/kernel-test.sh --vol wt_mirror # private build cache (parallel workers)
|
||||
# scripts/kernel-test.sh --host tommaso@100.103.234.2 # build on a remote host
|
||||
# scripts/CAD/run-kernel-tests.sh # [CadDocument] tags, default volume
|
||||
# scripts/CAD/run-kernel-tests.sh --tags '[CadDocument],[Sketch]'
|
||||
# scripts/CAD/run-kernel-tests.sh --vol wt_mirror # private build cache (parallel workers)
|
||||
# scripts/CAD/run-kernel-tests.sh --host tommaso@100.103.234.2 # build on a remote host
|
||||
#
|
||||
# Parallel workers MUST pass a distinct --vol: two builds sharing one cache corrupt
|
||||
# each other. A new volume pays one full build; runs after that are incremental.
|
||||
@@ -22,14 +22,14 @@
|
||||
# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
# orcacad-deps, NOT snaporca-deps: this fork is mainline-based and needs Eigen 5.0.1,
|
||||
# CGAL 5.6.3, wx 3.3.2 and Python 3.12 Development.Embed, none of which snaporca-deps has.
|
||||
# With the wrong image CMake dies at configure, which is exactly why this fork went
|
||||
# M1-M8 without ever compiling (see commit 1633005bba).
|
||||
IMAGE="${IMAGE:-orcacad-deps}"
|
||||
# Must NOT default to snaporca_buildcache: that is the other fork's volume, and pointing
|
||||
# this fork at it makes the two silently trade build artefacts. docker-iter-build.sh had the
|
||||
# this fork at it makes the two silently trade build artefacts. build-gui-incremental.sh had the
|
||||
# identical defect and was fixed to orcacad_buildcache; this script was missed.
|
||||
VOL="${BUILD_VOL:-orcacad_kerneltest}"
|
||||
# No exclusions. Both cases that used to be quarantined now run: the solver SIGABRT on
|
||||
@@ -64,7 +64,7 @@ if [[ -n "$HOST" ]]; then
|
||||
"$REPO/src" "$REPO/tests" "$REPO/resources" "$REPO/cmake" "$REPO/scripts" \
|
||||
"$REPO/CMakeLists.txt" \
|
||||
"$HOST:$REMOTE/"
|
||||
exec ssh "$HOST" "cd $REMOTE && scripts/kernel-test.sh --vol '$VOL' --tags '$TAGS' --image '$IMAGE'"
|
||||
exec ssh "$HOST" "cd $REMOTE && scripts/CAD/run-kernel-tests.sh --vol '$VOL' --tags '$TAGS' --image '$IMAGE'"
|
||||
fi
|
||||
|
||||
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
|
||||
@@ -84,17 +84,17 @@ if ! docker volume inspect "$VOL" >/dev/null 2>&1; then
|
||||
docker volume create "$VOL" >/dev/null
|
||||
fi
|
||||
|
||||
# tests/ is mounted too -- unlike docker-iter-build.sh, this script exists precisely to
|
||||
# tests/ is mounted too -- unlike build-gui-incremental.sh, this script exists precisely to
|
||||
# compile tests being edited. CMakeLists.txt and cmake/ carry the SLIC3R_CAD gate; taking
|
||||
# them from the baked image instead leaves the gate off and the CAD symbols vanish.
|
||||
|
||||
# ---- OOM guard (2026-08-21) -------------------------------------------------------------
|
||||
# Two of these builds ran at once on 2026-08-21, each with ninja -j$(nproc)=16: ~36 cc1plus
|
||||
# holding 42 GB of a 62 GB box -> global OOM at 21:05, a 2h28m kill storm, ssh unreachable,
|
||||
# lightdm destroyed. Neither build produced a single object. scripts/rig-build.sh grew the
|
||||
# lightdm destroyed. Neither build produced a single object. scripts/CAD/build-gui.sh grew the
|
||||
# bounds first; every script that starts a compile needs the same three, or the guard is only
|
||||
# as strong as the script you happened not to use.
|
||||
# flock — the lock path is SHARED with rig-build.sh and the other fork on purpose, so
|
||||
# flock — the lock path is SHARED with build-gui.sh and the other fork on purpose, so
|
||||
# concurrent builds serialise instead of summing.
|
||||
# -j — bounded parallelism; ~1.17 GB per cc1plus was the measured average.
|
||||
# --memory — the actual guarantee: a runaway build dies in its own cgroup instead of taking
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Bring the headless GUI up on a VNC-served X display, ready to drive or to attach Remmina to.
|
||||
#
|
||||
# Runs INSIDE the long-lived GUI container (see the header of scripts/docker-iter-build.sh for how
|
||||
# Runs INSIDE the long-lived GUI container (see the header of scripts/CAD/build-gui-incremental.sh for how
|
||||
# that container is created). Idempotent: safe to re-run to recover a session whose app died.
|
||||
#
|
||||
# docker exec <container> /OrcaSlicer/scripts/gui-session.sh # launch + settle
|
||||
# docker exec <container> /OrcaSlicer/scripts/gui-session.sh --status # report, change nothing
|
||||
# docker exec <container> /OrcaSlicer/scripts/CAD/start-headless-gui.sh # launch + settle
|
||||
# docker exec <container> /OrcaSlicer/scripts/CAD/start-headless-gui.sh --status # report, change nothing
|
||||
#
|
||||
# WHY THIS EXISTS. Dismissing the first-run dialogs by computing the titlebar close box from
|
||||
# `xdotool getwindowgeometry --shell` and clicking it went wrong whenever the dialog had already
|
||||
@@ -2,7 +2,7 @@
|
||||
# Identical system+pinned-dependency setup to scripts/Dockerfile, but STOPS after
|
||||
# `build_linux.sh -dr` (no slicer/AppImage build). Produces an image with the pinned
|
||||
# deps baked at /OrcaSlicer/deps/build/destdir, so the slicer can be rebuilt
|
||||
# incrementally via scripts/docker-iter-build.sh without re-running the long deps build.
|
||||
# incrementally via scripts/CAD/build-gui-incremental.sh without re-running the long deps build.
|
||||
#
|
||||
# Build once (rebuild only when deps/ changes, e.g. OCCT module flags):
|
||||
# docker build -t snaporca-deps -f scripts/Dockerfile.deps .
|
||||
@@ -82,7 +82,7 @@ RUN ln -sfn /OrcaSlicer/deps/build/OrcaSlicer_dep /OrcaSlicer/deps/build/destdir
|
||||
# The rig's GUI runtime. This used to arrive for free because orcacad-deps was layered on
|
||||
# snaporca-deps; that lineage is Trap 1 in docs/rig_build_traps.md (a baked project(Snapmaker_Orca)
|
||||
# tree) and building from this Dockerfile is what removes it — along with the X stack the rig
|
||||
# needs. scripts/gui-session.sh requires Xvfb and openbox (without a window manager `xdotool
|
||||
# needs. scripts/CAD/start-headless-gui.sh requires Xvfb and openbox (without a window manager `xdotool
|
||||
# windowactivate` aborts with "windowmanager claims not to support..."), drives the UI with
|
||||
# xdotool, and captures to /shots with scrot/ImageMagick. Same set snaporca-deps carries.
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
|
||||
@@ -4005,7 +4005,7 @@ TEST_CASE("golden recipe v1 still deserialises", "[CadDocument]")
|
||||
// A failure BELOW this point means the on-disk serialization format changed: some field
|
||||
// in CadFeature::save/load was reordered, retyped, or removed. Fields may only ever be
|
||||
// APPENDED at the end of both lists. Do NOT regenerate the fixture to make this pass --
|
||||
// fix the field order instead. See scripts/kernel-test.sh and the [.regen] case.
|
||||
// fix the field order instead. See scripts/CAD/run-kernel-tests.sh and the [.regen] case.
|
||||
|
||||
// Field-by-field assertions against expected values.
|
||||
// Every field set to a distinctive non-default literal must be checked here.
|
||||
|
||||
Reference in New Issue
Block a user