Files
OrcaSlicer/src/slic3r/GUI/PrePrintChecker.hpp
SoftFever 0d31325df0 feat: Filament Track Switch (H2-series O2L-FTS) support
The Filament Track Switch (H2-series accessory, product code O2L-FTS) feeds
every AMS to both extruders through a two-track switch. Port full support
across the device layer, project config, and GUI.

Device / config:
- Model the switch-aware AMS binding (the set of extruders an AMS can feed
  and which input track A/B feeds it), switch readiness, the O2L-FTS firmware
  module, and the fun2 capability bit for checking a slice against installed
  hardware.
- Register has_filament_switcher and enable_filament_dynamic_map as project
  config that persists with the project and restores from a saved 3mf, and
  force both back to false on every project/printer/CLI load path. Live
  device sync is the only thing that sets them true.

GUI:
- Sidebar sync activates the switch from live device state, attributes each
  AMS to the extruder its input track feeds, shows a floating status icon
  (ready / not-calibrated), and surfaces a one-time tip / not-calibrated
  warning.
- Send dialog gains a non-blocking slice-vs-hardware mismatch warning and a
  blocking error when a slice needs dynamic nozzle mapping but the switch is
  missing or not set up.
- AMS load/unload guards, AMS-view routing glyph + un-calibrated banner +
  hidden external-spool road, and mapping-popup external-spool lockout.
- Filament pickers collapse the per-extruder split into a single deduplicated
  "AMS filaments" group with a smart-assign toggle when the switch is ready.
- Firmware-upgrade panel lists the O2L-FTS accessory and its version.
- Device-provided filament-change steps (ams.cfs) drive the change-step
  display when firmware sends them, including the three switch steps.
- "Load current filament" asks which extruder to feed via a
  FeedDirectionDialog when the switch is calibrated.

Inert without the accessory: every path is gated on the switch being
installed (MQTT aux bit 29, default off) or ready, both project flags default
false, and the per-extruder AMS attribution is byte-identical, so AMS state,
the send/load UI, and sliced g-code are unchanged for every printer that does
not report a Filament Track Switch.
2026-07-09 18:57:05 +08:00

195 lines
5.8 KiB
C++

#ifndef slic3r_GUI_PRE_PRINT_CHECK_hpp_
#define slic3r_GUI_PRE_PRINT_CHECK_hpp_
#include <wx/wx.h>
#include "Widgets/Label.hpp"
namespace Slic3r { namespace GUI {
enum prePrintInfoLevel {
Normal,
Warning,
Error
};
enum prePrintInfoType {
Printer,
Filament
};
struct prePrintInfo
{
prePrintInfoLevel level;
prePrintInfoType type;
wxString msg;
wxString tips;
wxString wiki_url;
int index;
public:
bool operator==(const prePrintInfo& other) const {
return level == other.level && type == other.type &&
msg == other.msg && tips == other.tips &&
wiki_url == other.wiki_url && index == other.index;
}
};
enum PrintDialogStatus : unsigned int {
PrintStatusErrorBegin,//->start error<-
// Errors for printer, Block Print
PrintStatusPrinterErrorBegin,
PrintStatusInit,
PrintStatusNoUserLogin,
PrintStatusInvalidPrinter,
PrintStatusConnectingServer,
PrintStatusReadingTimeout,
PrintStatusReading,
PrintStatusConnecting,
PrintStatusReconnecting,
PrintStatusInUpgrading,
PrintStatusModeNotFDM,
PrintStatusInSystemPrinting,
PrintStatusInPrinting,
PrintStatusNozzleMatchInvalid,
PrintStatusNozzleDataInvalid,
PrintStatusNozzleDiameterMismatch,
PrintStatusNozzleTypeMismatch,
PrintStatusRefreshingMachineList,
PrintStatusSending,
PrintStatusLanModeNoSdcard,
PrintStatusNoSdcard,
PrintStatusLanModeSDcardNotAvailable,
PrintStatusNeedForceUpgrading,
PrintStatusNeedConsistencyUpgrading,
PrintStatusNotSupportedPrintAll,
PrintStatusBlankPlate,
PrintStatusUnsupportedPrinter,
PrintStatusRackNozzleMappingWaiting,
PrintStatusRackNozzleMappingError,
PrintStatusFilaSwitcherError,
PrintStatusPrinterErrorEnd,
// Errors for filament, Block Print
PrintStatusFilamentErrorBegin,
PrintStatusAmsOnSettingup,
PrintStatusAmsMappingInvalid,
PrintStatusAmsMappingU0Invalid,
PrintStatusAmsMappingMixInvalid,
PrintStatusTPUUnsupportAutoCali,
PrintStatusHasFilamentInBlackListError,
PrintStatusColorQuantityExceed,
PrintStatusFilamentErrorEnd,
PrintStatusErrorEnd,//->end error<-
PrintStatusWarningBegin,//->start warning<-
// Warnings for printer
PrintStatusPrinterWarningBegin,
PrintStatusTimelapseNoSdcard,
PrintStatusTimelapseWarning,
PrintStatusMixAmsAndVtSlotWarning,
PrintStatusToolHeadCoolingFanWarning,
PrintStatusRackNozzleMappingWarning,
PrintStatusFilaSwitcherSlicingNotMatch,
PrintStatusPrinterWarningEnd,
// Warnings for filament
PrintStatusFilamentWarningBegin,
PrintStatusWarningKvalueNotUsed,
PrintStatusHasFilamentInBlackListWarning,
PrintStatusFilamentWarningHighChamberTemp,
PrintStatusFilamentWarningHighChamberTempCloseDoor,
PrintStatusFilamentWarningHighChamberTempSoft,
PrintStatusFilamentWarningUnknownHighChamberTempSoft,
PrintStatusWarningExtFilamentNotMatch,
PrintStatusFilamentWarningEnd,
PrintStatusWarningEnd,//->end error<-
/*success*/
// printer
PrintStatusReadingFinished,
PrintStatusSendingCanceled,
PrintStatusReadyToGo,
// filament
PrintStatusAmsMappingSuccess,
/*Other, SendToPrinterDialog*/
PrintStatusNotOnTheSameLAN,
PrintStatusNotSupportedSendToSDCard,
PrintStatusPublicInitFailed,
PrintStatusPublicUploadFiled,
};
class PrePrintChecker
{
public:
std::vector<prePrintInfo> printerList;
std::vector<prePrintInfo> filamentList;
public:
void clear();
/*auto merge*/
void add(PrintDialogStatus state, wxString msg, wxString tip, const wxString& wiki_url);
static ::std::string get_print_status_info(PrintDialogStatus status);
wxString get_pre_state_msg(PrintDialogStatus status);
static bool is_error(PrintDialogStatus status) { return (PrintStatusErrorBegin < status) && (PrintStatusErrorEnd > status); };
static bool is_error_printer(PrintDialogStatus status) { return (PrintStatusPrinterErrorBegin < status) && (PrintStatusPrinterErrorEnd > status); };
static bool is_error_filament(PrintDialogStatus status) { return (PrintStatusFilamentErrorBegin < status) && (PrintStatusFilamentErrorEnd > status); };
static bool is_warning(PrintDialogStatus status) { return (PrintStatusWarningBegin < status) && (PrintStatusWarningEnd > status); };
static bool is_warning_printer(PrintDialogStatus status) { return (PrintStatusPrinterWarningBegin < status) && (PrintStatusPrinterWarningEnd > status); };
static bool is_warning_filament(PrintDialogStatus status) { return (PrintStatusFilamentWarningBegin < status) && (PrintStatusFilamentWarningEnd > status); };
};
//class PrePrintMsgBoard : public wxWindow
//{
//public:
// PrePrintMsgBoard(wxWindow * parent,
// wxWindowID winid = wxID_ANY,
// const wxPoint & pos = wxDefaultPosition,
// const wxSize & size = wxDefaultSize,
// long style = wxTAB_TRAVERSAL | wxNO_BORDER,
// const wxString &name = wxASCII_STR(wxPanelNameStr)
// );
//
//public:
// // Operations
// void addError(const wxString &msg, const wxString &tips = wxEmptyString) { Add(msg, tips, true); };
// void addWarning(const wxString &msg, const wxString &tips = wxEmptyString) { Add(msg, tips, false); };
// void clear() { m_sizer->Clear(); };
//
// // Const Access
// bool isEmpty() const { return m_sizer->IsEmpty(); }
//
//private:
// void add(const wxString &msg, const wxString &tips, bool is_error);
//
//private:
// wxBoxSizer *m_sizer{nullptr};
//};
class PrinterMsgPanel : public wxPanel
{
public:
PrinterMsgPanel(wxWindow *parent);
public:
bool UpdateInfos(const std::vector<prePrintInfo>& infos);
private:
wxBoxSizer* m_sizer = nullptr;
std::vector<prePrintInfo> m_infos;
};
}} // namespace Slic3r::GUI
#endif