mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 06:41:10 +00:00
A project saved before a printer or process option existed has no value for it. The GUI takes such keys from the project's system preset; the CLI left them at the option default, so e.g. extruder_clearance_dist_to_rod sliced as 40 instead of the P1S's 33. The CLI now resolves the project's system printer and process presets by name and copies the keys the project lacks, skipping preset bookkeeping, print-host keys, the extruder variant layout and keys the legacy handler drops. PresetBundle::resolve_system_preset finds the vendor through its manifest or preset cache, so it also works in release builds, which ship vendors as caches only.
90 lines
3.8 KiB
Bash
90 lines
3.8 KiB
Bash
#!/usr/bin/env bash
|
|
# End-to-end check that the CLI fills settings missing from a project from the project's system presets.
|
|
#
|
|
# A project saved before an option existed has no value for it. The GUI takes such keys from the
|
|
# project's system printer and process presets, not from the option defaults, and the CLI must slice
|
|
# the project with the same values. A project is exported from the shipped Bambu Lab P1S presets, one
|
|
# printer key and one process key are removed from it, one kept key is changed, and it is sliced again.
|
|
#
|
|
# usage: test_cli_project_missing_keys.sh <orca-slicer binary> <python3> <resources/profiles/BBL>
|
|
set -u
|
|
|
|
BIN="${1:-}"
|
|
PY="${2:-python3}"
|
|
PROFILES="${3:-}"
|
|
# 77 is the test's SKIP_RETURN_CODE.
|
|
[ -x "$BIN" ] || { echo "SKIP: orca-slicer binary not found: $BIN"; exit 77; }
|
|
[ -d "$PROFILES" ] || { echo "FAIL: profiles directory not found: $PROFILES"; exit 1; }
|
|
|
|
WORK="$(mktemp -d "${TMPDIR:-/tmp}/orca-cli-missing-keys.XXXXXX")"
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
"$PY" - "$WORK/cube.stl" <<'EOF'
|
|
import sys
|
|
|
|
v = [(x, y, z) for z in (0, 10) for y in (0, 10) for x in (0, 10)]
|
|
with open(sys.argv[1], "w") as f:
|
|
f.write("solid cube\n")
|
|
for a, b, c, d in ((0, 2, 3, 1), (4, 5, 7, 6), (0, 1, 5, 4), (2, 6, 7, 3), (0, 4, 6, 2), (1, 3, 7, 5)):
|
|
for tri in ((v[a], v[b], v[c]), (v[a], v[c], v[d])):
|
|
f.write("facet normal 0 0 0\nouter loop\n")
|
|
for p in tri:
|
|
f.write("vertex %g %g %g\n" % p)
|
|
f.write("endloop\nendfacet\n")
|
|
f.write("endsolid cube\n")
|
|
EOF
|
|
|
|
# slice <tag> <input> [option...]: slice into $WORK/<tag>/out.3mf with a fresh data directory.
|
|
slice() {
|
|
local out="$WORK/$1" input="$2"; shift 2
|
|
mkdir -p "$out"
|
|
timeout 300 "$BIN" --datadir "$out/datadir" "$@" --slice 0 --outputdir "$out" --export-3mf out.3mf "$input" \
|
|
> "$out/log" 2>&1 || { echo "FAIL: $1: orca-slicer exited $?"; tail -n 40 "$out/log"; exit 1; }
|
|
}
|
|
|
|
slice base "$WORK/cube.stl" \
|
|
--load-settings "$PROFILES/machine/Bambu Lab P1S 0.4 nozzle.json;$PROFILES/process/0.20mm Standard @BBL X1C.json" \
|
|
--load-filaments "$PROFILES/filament/Bambu PLA Basic @BBL P1S 0.4 nozzle.json"
|
|
|
|
# The removed keys, with their option defaults from PrintConfig.cpp, and a kept key with a new value.
|
|
"$PY" - "$WORK/base/out.3mf" "$WORK/old.3mf" <<'EOF' || exit $?
|
|
import json, sys, zipfile
|
|
|
|
src, dst = sys.argv[1], sys.argv[2]
|
|
missing = {"extruder_clearance_dist_to_rod": "40", "sparse_infill_density": "20%"}
|
|
with zipfile.ZipFile(src) as zin, zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) as zout:
|
|
for item in zin.infolist():
|
|
data = zin.read(item.filename)
|
|
if item.filename == "Metadata/project_settings.config":
|
|
config = json.loads(data)
|
|
for key, default in missing.items():
|
|
if config[key] == default:
|
|
print("SKIP: %s is %s in the system preset, the option default, so the test cannot tell them apart" % (key, default))
|
|
sys.exit(77)
|
|
expected = {key: config.pop(key) for key in missing}
|
|
expected["wall_loops"] = str(int(config["wall_loops"]) + 1)
|
|
config["wall_loops"] = expected["wall_loops"]
|
|
data = json.dumps(config, indent=4)
|
|
zout.writestr(item, data)
|
|
with open(dst + ".expected.json", "w") as f:
|
|
json.dump(expected, f)
|
|
EOF
|
|
|
|
slice project "$WORK/old.3mf"
|
|
|
|
"$PY" - "$WORK/project/out.3mf" "$WORK/old.3mf.expected.json" <<'EOF'
|
|
import json, sys, zipfile
|
|
|
|
with zipfile.ZipFile(sys.argv[1]) as z:
|
|
config = json.loads(z.read("Metadata/project_settings.config"))
|
|
with open(sys.argv[2]) as f:
|
|
expected = json.load(f)
|
|
errors = ["%s is %r, want %r" % (key, config.get(key), want) for key, want in expected.items() if config.get(key) != want]
|
|
for e in errors:
|
|
print("FAIL: " + e)
|
|
sys.exit(1 if errors else 0)
|
|
EOF
|
|
status=$?
|
|
[ "$status" -eq 0 ] || { tail -n 40 "$WORK/project/log"; exit 1; }
|
|
echo "PASS"
|