mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-10 17:21:10 +00:00
fix(imex): guard IMEX zone refresh against headless CLI slicing
`check_outside` (placement check) calls `ensure_imex_zones()` to make sure
zone geometry is current before deciding if an instance is in-bounds. In
the GUI path that's fine, but the CLI / headless 3MF-load path also reaches
this through `PartPlateList::load_from_3mf_structure -> reload_all_objects
-> add_instance -> check_outside`, and CLI mode has no GUI_App initialized.
`build_imex_cache_key` and `calc_imex_zones` both dereference
`wxGetApp().preset_bundle` — without a GUI_App, `wxGetApp()` returns memory
that segfaults on member access, killing the slicer with SIGSEGV before
any G-code is produced.
Latent since 461c69c83e (Apr 9), surfaced now that upstream's main carries
the headless regression-test CI step (#13353) that exercises CLI slicing
on every PR build.
Fix: short-circuit `ensure_imex_zones()` when `m_plater` is null (already
the GUI/CLI marker used by `calc_imex_ghosts`). Also tighten the existing
`build_imex_cache_key` null check to consult `m_plater` first as defence
in depth, so the function stays safe if reached from another headless
caller.
Verified locally against the upstream regression suite — klipper /
p1s_multicolor / toolchanger_4_color all slice cleanly within the
20% baseline tolerance.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
b452a8a28f
commit
6c7bd484db
@@ -954,7 +954,11 @@ void PartPlate::calc_imex_zones()
|
||||
// adjust the scale.
|
||||
std::string PartPlate::build_imex_cache_key() const
|
||||
{
|
||||
if (!wxGetApp().preset_bundle)
|
||||
// CLI / headless slice: no GUI_App is initialized, so `wxGetApp()` returns
|
||||
// memory that segfaults on member access. `m_plater` is set only by the GUI
|
||||
// construction path; treat its absence as "no IMEX state to compute" and
|
||||
// return an empty key. Same guard pattern used by calc_imex_ghosts.
|
||||
if (!m_plater || !wxGetApp().preset_bundle)
|
||||
return "";
|
||||
const DynamicPrintConfig& printer_cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
auto* is_imex_opt = printer_cfg.option<ConfigOptionBool>("is_imex");
|
||||
@@ -1002,6 +1006,10 @@ void PartPlate::refresh_imex_icon()
|
||||
// Called before any collision check AND before rendering so both paths share the same data.
|
||||
void PartPlate::ensure_imex_zones()
|
||||
{
|
||||
// CLI / headless slice: no GUI_App, no plater, no IMEX state to track. Bail out
|
||||
// before touching `wxGetApp()` (which segfaults without a GUI_App) — placement
|
||||
// checks reach this from the headless 3MF-load path through `check_outside`.
|
||||
if (!m_plater) return;
|
||||
std::string cache_key = build_imex_cache_key();
|
||||
if (cache_key != m_imex_zones_mode_cache) {
|
||||
m_imex_zones_mode_cache = cache_key;
|
||||
|
||||
Reference in New Issue
Block a user