Rename snaporca/SnapOrca to orca_cad so the OrcaSlicer PR carries no Snapmaker naming

This commit is contained in:
Tommaso Bianchi
2026-09-10 10:58:46 +02:00
parent 498e92ee35
commit 31a15cc5e5
44 changed files with 229 additions and 229 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ The verb in the name is the role:
| `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` |
| `check-mcp-sketch.py` | The sketch layer driven over the MCP socket, asserting what decides whether a profile is buildable. | Headless GUI + `ORCA_CAD_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
+3 -3
View File
@@ -19,7 +19,7 @@
set -euo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# orcacad-deps, NOT snaporca-deps: see the note in run-kernel-tests.sh — the wrong image
# orcacad-deps, NOT snapmaker-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}"
@@ -32,11 +32,11 @@ echo "REPO=$REPO IMAGE=$IMAGE BUILD_VOL=$BUILD_VOL"
# the build fails with "class GLCanvas3D has no member named set_design_sketch_tool".
#
# build_linux.sh must be mounted for the same reason, and here the stale copy is guaranteed
# wrong rather than merely risky: orcacad-deps is layered on snaporca-deps, so the baked script
# wrong rather than merely risky: orcacad-deps is layered on snapmaker-deps, so the baked script
# is the OTHER fork's and builds `--target Snapmaker_Orca`. This fork's target is `OrcaSlicer`,
# so without this mount configure succeeds and then ninja dies on "unknown target".
# scripts/ likewise: build_linux.sh's packaging step sources scripts/appimage_lib_policy.sh,
# which the baked snaporca tree does not have, so a fully successful link still exited
# which the baked Snapmaker tree does not have, so a fully successful link still exited
# non-zero with "missing AppImage helper" and the binary check never ran.
# ---- OOM guard (2026-08-21) -------------------------------------------------------------
+2 -2
View File
@@ -2,7 +2,7 @@
# Rebuild the GUI binary the design rig launches — in a THROWAWAY container, writing into the
# same build-cache volume the rig's long-lived GUI container reads from.
#
# NEVER build inside the GUI container (snaporca-gui / orcacad-gui). Its baked /OrcaSlicer tree
# NEVER build inside the GUI container (snapmaker-gui / orcacad-gui). Its baked /OrcaSlicer tree
# is the Jun-13 Snapmaker-derived source, so a `cmake .` in there silently reconfigures the
# shared build dir as project(Snapmaker_Orca) and this fork's targets vanish. That is Trap 1 of
# five; all of them, with symptoms and exact recovery commands, are in docs/rig_build_traps.md.
@@ -21,7 +21,7 @@ REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# the wrong volume the two forks silently trade build artefacts.
PROJECT="$(sed -n 's/^project(\([A-Za-z_0-9]*\)).*/\1/p' "$REPO/CMakeLists.txt" | head -1)"
case "$PROJECT" in
Snapmaker_Orca) PREFIX=snaporca; BIN=snapmaker-orca ;;
Snapmaker_Orca) PREFIX=snapmaker; BIN=snapmaker-orca ;;
OrcaSlicer) PREFIX=orcacad; BIN=orca-slicer ;;
*) echo "FATAL: unrecognised project($PROJECT) in $REPO/CMakeLists.txt" >&2; exit 2 ;;
esac
+4 -4
View File
@@ -14,7 +14,7 @@ again. A user cannot be told to click the field first; when they do not, they ge
number and report "the label value is not editable". So this ladder types IMMEDIATELY after the
field opens, exactly as a person does, and fails if the prefill is what gets committed.
WHAT IT GRADES. The app emits one line per event under SNAPORCA_UXTRACE=1:
WHAT IT GRADES. The app emits one line per event under ORCA_CAD_UXTRACE=1:
[UX] open title=Length prefill=154.76
[UX] commit title=Length typed=80 value=80.0000
@@ -29,7 +29,7 @@ that matters — a field that is on screen but deaf commits its prefill, and eve
scripts/CAD/check-gui-click-edit.py --display :10 --bin build/src/Release/orca-slicer
With --attach it drives an already-running app instead of launching one; the app must have been
started with SNAPORCA_UXTRACE=1 and its stderr redirected to --trace.
started with ORCA_CAD_UXTRACE=1 and its stderr redirected to --trace.
Exit 0 = every field took what was typed.
"""
import argparse, json, os, re, shutil, signal, socket, subprocess, sys, tempfile, time
@@ -175,7 +175,7 @@ def launch():
# the process was alive, `xdotool search` on the rig display found nothing, and the window
# was sitting on the user's own screen. Silent, and it drives a stray app at someone's face.
env.pop("WAYLAND_DISPLAY", None)
env.update(DISPLAY=DISP, GDK_BACKEND="x11", SNAPORCA_UXTRACE="1",
env.update(DISPLAY=DISP, GDK_BACKEND="x11", ORCA_CAD_UXTRACE="1",
LIBGL_ALWAYS_SOFTWARE="1", GALLIUM_DRIVER="llvmpipe",
# The rig's Xvfb has no input-method daemon, and a dead ibus context makes a
# GtkEntry drop every character while the app looks fine. It cannot affect the
@@ -186,7 +186,7 @@ def launch():
# the Design panel at all. Without it "the field never opened" is indistinguishable
# from "we never got into sketch mode", and the first run of this ladder reported
# seven product failures that were really one driver racing a still-loading app.
SNAPORCA_KEYTRACE="1", SNAPORCA_MCP=A.sock,
ORCA_CAD_KEYTRACE="1", ORCA_CAD_MCP=A.sock,
SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt",
WEBKIT_DISABLE_DMABUF_RENDERER="1", WEBKIT_DISABLE_COMPOSITING_MODE="1")
if os.path.exists(A.sock):
+10 -10
View File
@@ -11,16 +11,16 @@ action and no shortcut, so a key-driven ladder cannot reach them at all.
This ladder drives the menu. Nothing here is asserted from pixels:
WHAT WAS CLICKED -> the offer's own [OFFER] trace, emitted by show_offer_menu from the same
loop that builds the rows (SNAPORCA_KEYTRACE). It cannot drift from what
loop that builds the rows (ORCA_CAD_KEYTRACE). It cannot drift from what
the user is shown, which a hand-written expectation list would.
WHAT IS OFFERED -> the same trace, compared against DesignOffer.hpp parsed independently.
"The menu shows exactly the verbs the table says apply here" is a
property; a copied list of row names is a transcription.
WHAT IT PRODUCED -> the MCP socket, read-only, exactly as in the gesture ladder.
Run inside the rig container, with the app launched under SNAPORCA_KEYTRACE=1:
Run inside the rig container, with the app launched under ORCA_CAD_KEYTRACE=1:
docker exec snaporca-gui python3 /OrcaSlicer/scripts/CAD/check-gui-context-menu.py [rung ...]
docker exec orcacad-gui python3 /OrcaSlicer/scripts/CAD/check-gui-context-menu.py [rung ...]
"""
import importlib.util
import math
@@ -38,13 +38,13 @@ _spec = importlib.util.spec_from_file_location("gui_ladder", os.path.join(HERE,
G = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(G)
LOG = os.environ.get("SNAPORCA_GUI_LOG", "/tmp/gui-session.log")
LOG = os.environ.get("ORCA_CAD_GUI_LOG", "/tmp/gui-session.log")
# The rig container's /OrcaSlicer is the image's own baked source tree, not this checkout, so the
# generated header is not where a repo-relative path expects it. Look in both places and say which
# one was read — a ladder that silently graded against the WRONG table would be worse than one
# that refuses to start.
HEADER_CANDIDATES = [os.environ.get("SNAPORCA_OFFER_HPP", ""),
HEADER_CANDIDATES = [os.environ.get("ORCA_CAD_OFFER_HPP", ""),
os.path.join(HERE, "..", "src", "slic3r", "GUI", "CAD", "DesignOffer.hpp"),
os.path.join(HERE, "DesignOffer.hpp")]
@@ -61,12 +61,12 @@ def load_table():
"""Every verb in DesignOffer.hpp, as dicts. The independent half of the comparison.
Parsed from the generated header rather than from tool_atlas.json on purpose: the header is
what the binary was compiled from, and the two have been out of step before (snaporca-ziam,
what the binary was compiled from, and the two have been out of step before (ziam,
where regenerating the header silently dropped the Constrain row).
"""
path = next((p for p in HEADER_CANDIDATES if p and os.path.exists(p)), None)
if path is None:
raise SystemExit("no DesignOffer.hpp found; set SNAPORCA_OFFER_HPP or copy it beside "
raise SystemExit("no DesignOffer.hpp found; set ORCA_CAD_OFFER_HPP or copy it beside "
"this script (tried: " + ", ".join(filter(None, HEADER_CANDIDATES)) + ")")
print(f"offer table: {os.path.realpath(path)}")
src = open(path).read()
@@ -301,7 +301,7 @@ def rung_kinds():
# Empty space first: nothing is selected, so the sketch vocabulary's no-selection row set.
# Right-click has two jobs on a draw tool, and which one it does depends on whether an
# anchor is down. Both are asserted here: the version that consumed EVERY right-click made
# the offer unreachable from any armed tool (snaporca-ghcz), which is the goal's own
# the offer unreachable from any armed tool (ghcz), which is the goal's own
# mechanism failing silently.
hi = y1 - (y1 - y0) * 0.12
o = open_offer(cx, hi)
@@ -766,7 +766,7 @@ def rung_curves():
f"and it takes a typed radius exactly: {got:.9f} (asked 30.0)")
# The DoF of ONE CIRCLE is three. Asserted here because it is where the lie showed:
# after a delete the solver was never re-run, so this reported the DoF of the
# geometry that had just been erased. snaporca-ua9g.
# geometry that had just been erased. ua9g.
G.check("VERTEX", G.describe()["dof"] == 2,
f"and the sketch reports the DoF of what is actually in it: {G.describe()['dof']}")
@@ -1198,7 +1198,7 @@ def main():
if not os.path.exists(LOG):
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")
print(f"note: no [OFFER] lines in {LOG} yet — the app must run with ORCA_CAD_KEYTRACE=1")
want = sys.argv[1:] or list(RUNGS)
# TWICE. From a cold launch the app shows the Home page over the Design tab, and the first
# click only selects the tab — the second is what brings the viewport forward. A ladder that
+6 -6
View File
@@ -9,16 +9,16 @@ cannot say the Design tab meets its goal. This one draws with synthetic clicks a
values into the in-canvas field, then reads the result back through the socket, which is used
here ONLY as an instrument, never as an author.
Runs INSIDE the headless rig container (Xvfb :10 + openbox + the app with SNAPORCA_MCP set):
Runs INSIDE the headless rig container (Xvfb :10 + openbox + the app with ORCA_CAD_MCP set):
docker cp scripts/CAD/check-gui-sketching.py snaporca-gui:/tmp/ && \
docker exec snaporca-gui python3 /tmp/check-gui-sketching.py [rung ...]
docker cp scripts/CAD/check-gui-sketching.py orcacad-gui:/tmp/ && \
docker exec orcacad-gui python3 /tmp/check-gui-sketching.py [rung ...]
With no arguments every rung runs. Exit 0 = every property held.
"""
import json, math, os, re, socket, subprocess, sys, time
SOCK = os.environ.get("SNAPORCA_MCP", "/tmp/mcp.sock")
SOCK = os.environ.get("ORCA_CAD_MCP", "/tmp/mcp.sock")
DISP = os.environ.get("DISPLAY", ":10")
_n = 0
_fail = 0
@@ -225,7 +225,7 @@ def leave_sketch():
# "no sketch opened after plane click + Shift+S"; the unshifted Construction checkbox reported
# "0 construction axis". Both name the wrong subsystem. Canvas coordinates are immune because
# clickmm() derives them from the live canvas geometry — only the chrome constants need this.
CHROME_DY = int(os.environ.get("SNAPORCA_CHROME_DY", "26"))
CHROME_DY = int(os.environ.get("ORCA_CAD_CHROME_DY", "26"))
DESIGN_TAB = (128, 29 + CHROME_DY)
@@ -1873,7 +1873,7 @@ def rung_scale():
f"every cut-out is exactly {side:.6f} squared")
# Now the part that matters: draw ONE more entity by hand, on top of all that.
#
# No Escape here, deliberately: this rung is the regression test for snaporca-j7gc, where a
# No Escape here, deliberately: this rung is the regression test for j7gc, where a
# bulk sketch_add made while a creation tool is armed was read as a drawn gesture, opened that
# tool's value field and swallowed the next key and click until one Escape dismissed it. The
# gesture below has to land on the FIRST try. Fixed by resyncing m_autoedit_seen in
+1 -1
View File
@@ -8,7 +8,7 @@ cost a GUI session and a human. The socket verbs make each one a call, and this
loop: build a known profile, ask the app what it thinks it has, compare against arithmetic.
RUN IT AGAINST A RUNNING APP:
SNAPORCA_MCP=/tmp/mcp.sock <binary> # launch with the socket enabled
ORCA_CAD_MCP=/tmp/mcp.sock <binary> # launch with the socket enabled
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.
+2 -2
View File
@@ -35,7 +35,7 @@ import sys
import tempfile
import time
SOCK = os.environ.get("SNAPORCA_MCP", "/tmp/mcp.sock")
SOCK = os.environ.get("ORCA_CAD_MCP", "/tmp/mcp.sock")
TOL = 1e-6 # exact-comparison tolerance (all inputs are lines)
WELD = 0.05 # endpoint-coincidence tolerance, in PDF units
@@ -295,7 +295,7 @@ def grade(pdf, name, report):
# same rule the engine now uses (DesignSketchTool::region_loops). A vertex is exactly
# where two loops touch in a real drawing, and a ray cast from a point lying ON the
# polygon under test answers by rounding: that alone accounted for every one of the 6
# sheets where the two attributions used to disagree. snaporca-5hvl.
# sheets where the two attributions used to disagree. 5hvl.
probes = [interior_point(r) for r in rings]
mine_parent = {}
for i, r in enumerate(rings):
+1 -1
View File
@@ -15,7 +15,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>
ORCA_CAD_MCP=/tmp/mcp.sock <binary>
python3 scripts/CAD/check-sketch-engine.py [socket]
Exit 0 = every rung held. Otherwise the first broken property is named and the run stops.
+5 -5
View File
@@ -10,7 +10,7 @@
# 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
# The rig container is expected to be up with the app running and ORCA_CAD_MCP set; bring it up
# with scripts/CAD/start-headless-gui.sh inside it. The corpus lives at /corpus in that container.
set -uo pipefail
# ../.. -- this script lives in scripts/CAD/, so one level up is scripts/, not the repo
@@ -19,7 +19,7 @@ set -uo pipefail
# scripts/scripts/ and reporting instant failures that were all the same typo.
cd "$(dirname "${BASH_SOURCE[0]}")/../.." || exit 1
# orcacad-gui, NOT snaporca-gui: that is the other fork's rig, and defaulting to it makes
# orcacad-gui, NOT snapmaker-gui: that is the other fork's rig, and defaulting to it makes
# this gate verify the wrong fork's binary while reporting green. run-kernel-tests.sh
# carries the same warning about the build volume, where the defect was found first.
C="${C:-orcacad-gui}"
@@ -53,13 +53,13 @@ run_in_rig() { # copy the script in fresh, then run it ther
# FIRST, and it needs no rig: the offer table the menu is compiled from must be what the atlas
# says. The header calls itself GENERATED and had been hand-edited anyway — which cost four rows
# that existed only in the header, one row wired to the wrong action, and a count of 91 for a
# 92-row array, so the last verb was unreachable (snaporca-z8rs, snaporca-ziam).
# 92-row array, so the last verb was unreachable (z8rs, ziam).
# docs/CAD/, not docs/: SoftFever moved the design docs into the CAD subfolder
# (bbd1989e1e) and this line kept the old path, so the rung failed on a missing file
# rather than on anything about the table. The other fork still has docs/ux/.
step "offer table matches the atlas" python3 docs/CAD/ux/mockups/gen_offer_table.py --check
step "kernel suite" scripts/CAD/run-kernel-tests.sh --vol "${KVOL:-snaporca_kerneltest}"
step "kernel suite" scripts/CAD/run-kernel-tests.sh --vol "${KVOL:-orcacad_kerneltest}"
if [ -z "${SKIP_GUI:-}" ]; then
step "engine ladder (rungs 1-8, scripted geometry)" \
@@ -71,7 +71,7 @@ if [ -z "${SKIP_GUI:-}" ]; then
step "gesture ladder (mouse and keyboard)" \
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
# with ORCA_CAD_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
# container's own baked source tree, so it is copied in beside the script — /tmp, where
# run_in_rig puts the script, is one of the paths the ladder looks in.
+5 -5
View File
@@ -23,18 +23,18 @@
set -euo pipefail
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.
# orcacad-deps, NOT snapmaker-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 snapmaker-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
# Must NOT default to snapmaker_buildcache: that is the other fork's volume, and pointing
# 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
# circle-line tangency is fixed (snaporca-tkz), and the internal-thread case turned out to have
# correct geometry and a wrong reference in the test (snaporca-kzy). A green run here now means
# circle-line tangency is fixed (tkz), and the internal-thread case turned out to have
# correct geometry and a wrong reference in the test (kzy). A green run here now means
# the whole CAD suite passed, not "everything except the two we gave up on".
#
# ...and that claim was still not true, because the default tag was [CadDocument] alone while
+2 -2
View File
@@ -36,8 +36,8 @@ export LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe
# them comes up looking perfectly healthy: the window is there, status says app up, and every
# ladder then dies on "Connection refused" — which reads as a dead app rather than a rig that was
# started without its instrument. The script that launches the rig is where they belong.
export SNAPORCA_MCP="${SNAPORCA_MCP:-/tmp/mcp.sock}"
export SNAPORCA_KEYTRACE="${SNAPORCA_KEYTRACE:-1}"
export ORCA_CAD_MCP="${ORCA_CAD_MCP:-/tmp/mcp.sock}"
export ORCA_CAD_KEYTRACE="${ORCA_CAD_KEYTRACE:-1}"
export LD_LIBRARY_PATH="$LIBPY:$LIBPY2:${LD_LIBRARY_PATH:-}"
mkdir -p /root/.config # startup dies in boost::filesystem::create_directory without this
+5 -5
View File
@@ -1,13 +1,13 @@
# Deps-only base image for fast iteration on SnapOrca.
# Deps-only base image for fast iteration on Orca.
# 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/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 .
# docker build -t snapmaker-deps -f scripts/Dockerfile.deps .
FROM docker.io/ubuntu:24.04
LABEL maintainer="SnapOrca CAD iteration base"
LABEL maintainer="Orca CAD iteration base"
# Disable interactive package configuration
RUN apt-get update && \
@@ -80,11 +80,11 @@ RUN ./build_linux.sh -dr -j 12
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)
# snapmaker-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/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.
# xdotool, and captures to /shots with scrot/ImageMagick. Same set snapmaker-deps carries.
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
imagemagick \
openbox \
+2 -2
View File
@@ -9,8 +9,8 @@
#
# The consequence was that scripts/CAD/run-kernel-tests.sh failed at CMake CONFIGURE time,
# before a single source file compiled, so THIS FORK'S KERNEL SUITE COULD NOT RUN AT ALL.
# Every kernel change ported here was parity-checked against snaporca and never independently
# tested (snaporca-w80c). The Snapmaker fork does not hit this: its base requires neither
# Every kernel change ported here was parity-checked against Snapmaker and never independently
# tested (w80c). The Snapmaker fork does not hit this: its base requires neither
# assimp nor OpenCV.
#
# WHY A LAYER AND NOT A FULL DEPS REBUILD. Rebuilding every dependency takes hours and would