mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-04 22:31:02 +00:00
The CLI filled only the keys a project lacked from its system preset. The GUI builds a project preset differently: the project's values go over the default preset, without the print-host keys, and every key the project does not list in different_settings_to_system is refreshed to its base system preset's current value. After a profile update the two sliced the same project differently. That step now lives in Preset::load_external_config, which takes plain configs and gets the base preset from a callback, so the collection lookup stays in PresetCollection. PresetBundle::project_different_keys builds the kept-key set from a project's escaped entry, adding the preset bookkeeping keys, and is used by both the GUI and the CLI. PresetCollection::load_external_preset calls the shared step with no change in behaviour. The CLI now builds the project's printer and process configs with the same step, passing the system preset from resolve_system_preset. That drops the hand-kept skip list for print-host and variant-layout keys and the legacy-key check: the shared step already excludes print-host keys and maps per-variant values onto the base preset's variant layout. The --uptodate path and a printer or process given on the command line are left as they were. Because the GUI's kept-key set always holds the bookkeeping keys, the refresh runs for every project that names a system preset, so the CLI now loads that preset's vendor on every such run.
97 lines
4.4 KiB
Bash
97 lines
4.4 KiB
Bash
#!/usr/bin/env bash
|
|
# End-to-end check that the CLI loads a project's printer and process settings as the GUI does.
|
|
#
|
|
# The GUI takes every key a project does not list as changed from the project's current system preset:
|
|
# keys saved before an option existed, and keys holding an older system value. Keys the project lists
|
|
# in different_settings_to_system keep the project's value. A project is exported from the shipped
|
|
# Bambu Lab P1S presets; one printer key and one process key are removed, one printer key and one
|
|
# process key are changed without being listed, one key is changed and listed, 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; stale keys changed without being
|
|
# listed as different, which must come back with the system value; and a listed key the project keeps.
|
|
"$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}
|
|
for key in ("top_shell_layers", "extruder_clearance_height_to_rod"):
|
|
expected[key] = config[key]
|
|
config[key] = str(int(float(config[key])) + 1)
|
|
expected["wall_loops"] = str(int(config["wall_loops"]) + 1)
|
|
config["wall_loops"] = expected["wall_loops"]
|
|
different = config["different_settings_to_system"]
|
|
different[0] = ";".join([k for k in different[0].split(";") if k] + ["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"
|