mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-10 17:21:10 +00:00
Leave the AFC lane sync out of the IMEX work
MoonrakerPrinterAgent filled physical_extruder_map from AFC's per-lane extruder_index whenever the printer's filaments were synced. IMEX does not need it: printers carry their map in the printer profile, and IMEX reads it from there. The sync also wrote device state into the edited printer preset, so a sync could mark the preset modified or replace a hand-tuned map. The two Moonraker agent files go back to upstream's version. The sync can return separately, writing the map somewhere other than the printer preset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d09850c528
commit
45932dd956
@@ -119,9 +119,7 @@ static std::vector<std::string> s_project_options {
|
||||
// project_config's default [0] to clobber the preset's authored value
|
||||
// (e.g. AFC-shaped [0,1,1,1,1]) during full_fff_config() merge, and the
|
||||
// clobbered value then rode into saved 3mfs and back into the edited
|
||||
// preset on reload. MoonrakerPrinterAgent's runtime set_key_value still
|
||||
// works — it creates the option on project_config on demand without
|
||||
// needing it pre-initialized here.
|
||||
// preset on reload.
|
||||
// Per-filament nozzle-volume choice; project-level like filament_map so the per-filament
|
||||
// slot resolution survives preset switches.
|
||||
"filament_volume_map",
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <ios>
|
||||
#include <functional>
|
||||
#include <exception>
|
||||
#include <libslic3r/Config.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
@@ -51,7 +50,6 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <wx/app.h>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -572,79 +570,6 @@ bool MoonrakerPrinterAgent::fetch_filament_info(std::string dev_id, FilamentSync
|
||||
<< (max_lane_index + 1) << " lanes";
|
||||
int ams_count = (max_lane_index + 4) / 4;
|
||||
build_ams_payload(ams_count, max_lane_index, trays);
|
||||
|
||||
// If every tray reported extruder_index, auto-populate physical_extruder_map on an
|
||||
// IMEX printer so IMEX PA and temperature emission use the correct physical extruder
|
||||
// qualifier. AFC publishes extruder_index=0 for all AFC lanes (they share one carriage)
|
||||
// and extruder_index=N for independent direct-drive tools on separate carriages.
|
||||
// The write itself is gated below, on the GUI thread, where the preset can be read.
|
||||
bool all_have_extruder_index = std::all_of(trays.begin(), trays.end(),
|
||||
[](const AmsTrayData& t) { return t.extruder_index >= 0; });
|
||||
if (all_have_extruder_index) {
|
||||
std::vector<int> pem(max_lane_index + 1, 0);
|
||||
for (const auto& tray : trays)
|
||||
if (tray.slot_index >= 0 && tray.slot_index <= max_lane_index)
|
||||
pem[tray.slot_index] = tray.extruder_index;
|
||||
// Record which device this map came from. The write below targets whichever
|
||||
// printer preset is being edited when the callback runs, and nothing else here
|
||||
// establishes the two are the same machine: two IMEX printers of different models
|
||||
// with the same logical extruder count would both pass every check below.
|
||||
const std::string src_dev_id = device_info.dev_id;
|
||||
wxTheApp->CallAfter([pem, src_dev_id]() {
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
if (!bundle) return;
|
||||
auto& preset = bundle->printers.get_edited_preset();
|
||||
auto& config = preset.config;
|
||||
|
||||
// Pair device to preset at callback time, on the predicate update_sync_status()
|
||||
// uses. Matching against an identity captured when the device was selected would
|
||||
// instead ask whether the edited preset had changed since then, and would reject
|
||||
// the user who selects a machine and only then switches to its matching preset.
|
||||
auto* dev_manager = GUI::wxGetApp().getDeviceManager();
|
||||
MachineObject* obj = dev_manager ? dev_manager->get_selected_machine() : nullptr;
|
||||
if (!obj || obj->get_dev_id() != src_dev_id) return;
|
||||
|
||||
const std::string preset_model = preset.get_printer_type(bundle);
|
||||
if (preset_model != obj->get_show_printer_type()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent: skipping physical_extruder_map sync, the device is a "
|
||||
<< obj->get_show_printer_type() << " but the edited printer preset is a "
|
||||
<< preset_model;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only IMEX profiles read physical_extruder_map as logical -> physical extruder.
|
||||
// Elsewhere in the tree the key carries the BBL extruder-id reading, or is unused
|
||||
// entirely (a single-nozzle Klipper machine), so writing the device's lane data
|
||||
// there would silently mutate an unrelated setting -- and dirty the preset with
|
||||
// no user action -- for every AFC user who is not running IMEX.
|
||||
const auto* is_imex = config.option<ConfigOptionBool>("is_imex");
|
||||
if (!is_imex || !is_imex->value) return;
|
||||
|
||||
// The map has one entry per LOGICAL extruder, i.e. the nozzle_diameter index
|
||||
// space (see effective_physical_extruder_map() in IMEXHelpers.cpp). The device
|
||||
// reports one entry per lane, which is the same index space only when the counts
|
||||
// match; when they differ the lane -> logical extruder correspondence is not
|
||||
// knowable here, and a wrong-length map is discarded by PrintApply anyway, so
|
||||
// leave whatever the profile authored alone rather than writing a map that
|
||||
// nothing will honour.
|
||||
const auto* nozzles = config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
if (!nozzles || nozzles->values.size() != pem.size()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent: skipping physical_extruder_map sync, device reports "
|
||||
<< pem.size() << " lanes but the printer profile has "
|
||||
<< (nozzles ? nozzles->values.size() : 0) << " logical extruders";
|
||||
return;
|
||||
}
|
||||
|
||||
// Write only on a real change: an unconditional set_key_value() marks the printer
|
||||
// preset dirty on every device poll, so the user sees unsaved changes they never made.
|
||||
const auto* current = config.option<ConfigOptionInts>("physical_extruder_map");
|
||||
if (current && current->values == pem) return;
|
||||
|
||||
config.set_key_value("physical_extruder_map", new ConfigOptionInts(pem));
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent: auto-populated physical_extruder_map from AFC extruder_index";
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -888,10 +813,6 @@ bool MoonrakerPrinterAgent::fetch_moonraker_filament_data(std::vector<AmsTrayDat
|
||||
tray.tray_type = safe_json_string(lane_obj, "material");
|
||||
tray.bed_temp = safe_json_int(lane_obj, "bed_temp");
|
||||
tray.nozzle_temp = safe_json_int(lane_obj, "nozzle_temp");
|
||||
// extruder_index: 0 is a valid value (AFC lanes on E0), so check contains()
|
||||
// rather than relying on safe_json_int's 0-for-missing fallback.
|
||||
if (lane_obj.contains("extruder_index") && lane_obj["extruder_index"].is_number())
|
||||
tray.extruder_index = lane_obj["extruder_index"].get<int>();
|
||||
tray.has_filament = !tray.tray_type.empty();
|
||||
auto* bundle = GUI::wxGetApp().preset_bundle;
|
||||
tray.tray_info_idx = bundle
|
||||
|
||||
@@ -88,7 +88,6 @@ protected:
|
||||
// Tray data for AMS payload building
|
||||
struct AmsTrayData {
|
||||
int slot_index = 0; // 0-based slot index
|
||||
int extruder_index = -1; // Physical extruder index from AFC extruder_index field (-1 = not provided)
|
||||
bool has_filament = false;
|
||||
std::string tray_type; // Material type (e.g., "PLA", "ASA")
|
||||
std::string tray_color; // Raw color (#RRGGBB, 0xRRGGBB, or RRGGBBAA)
|
||||
|
||||
Reference in New Issue
Block a user