X2D Support (#13388)

# Description

Adresses #13294 

- Adds the X2D printer definition, machine presets, process presets,
filament presets, BBL profile index entries, CLI config entries,
filament blacklist updates, and printer/load/calibration/cover assets.
- Updates dual-nozzle handling to use configured toolhead labels and
match Bambu X2D hotend placeholders.
- Adds X2D-specific wipe tower cooling placeholder support and 3MF
filament/nozzle change sequence metadata import/export plumbing.

# Note

I own a P2S and an X2D. That's all. I frankly have no idea if my changes
cause regression on other printers, and have no capability to test. I
know that for my X2D, which runs an AMS, .2mm nozzles, SuperTack, and in
LAN mode, this has been working without issue.

# Screenshots/Recordings/Graphs

<img width="606" height="380" alt="Dual nozzle control"
src="https://github.com/user-attachments/assets/0d1c1063-4621-4097-b97c-d739557bf18c"
/>

*Dual nozzle control*

<img width="726" height="260" alt="image"
src="https://github.com/user-attachments/assets/270355b7-ca67-4ca3-ad19-582b8f11411b"
/>

*Multi nozzle filament override*

<img width="416" height="202" alt="X2D Machine config and dual nozzle
support"
src="https://github.com/user-attachments/assets/6a5c07b2-0d20-4819-8f42-d60731313249"
/>

*X2D Machine config and dual nozzle support*

<img width="397" height="142" alt="Filament for Supports test prints"
src="https://github.com/user-attachments/assets/3c7546bd-0e27-4d56-89b7-d9ca18c976f9"
/>

*Filament for Supports has been used in over 20 hours of test prints*

<img width="210" height="263" alt="Left vs Right filament distinction"
src="https://github.com/user-attachments/assets/03322268-b669-4f14-8d77-c4d96843d219"
/>

*Left vs Right filament distinction*

<img width="557" height="327" alt="Custom filament mapping"
src="https://github.com/user-attachments/assets/c1c4396f-7359-474e-80bd-78fec22f9c82"
/>

*Custom filament mapping*

<img width="556" height="314" alt="Auto map"
src="https://github.com/user-attachments/assets/d83e3217-edce-4340-886e-043962003a30"
/>

*Auto map*

<img width="689" height="664" alt="LAN mode send print with X2D preview
and no errors"
src="https://github.com/user-attachments/assets/76009bbf-31d3-4a6c-979c-8643b487c824"
/>

*LAN mode send print with X2D preview and no errors, dual nozzle
selection*


## Tests

- 20 hours of dual-nozzle printing.
- 100% CTest tests passed
- Validated 208 changed JSON files.

<!--
> A guide for users on how to download the artifacts from this PR.
-->

[How to Download Pull Requests Artifacts for
Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
Fix #13294
This commit is contained in:
glowstab
2026-05-09 13:21:13 -05:00
committed by GitHub
parent 7bef75b2cd
commit 9956ad5b48
242 changed files with 53863 additions and 83 deletions

View File

@@ -5,9 +5,14 @@
#include "StateColor.hpp"
#include "StaticBox.hpp"
#include <vector>
#include <wx/sizer.h>
#include <wx/tglbtn.h>
wxDECLARE_EVENT(wxCUSTOMEVT_SWITCH_POS, wxCommandEvent);
wxDECLARE_EVENT(wxCUSTOMEVT_MULTISWITCH_SELECTION, wxCommandEvent);
class Button;
class SwitchButton : public wxBitmapToggleButton
{
@@ -76,6 +81,53 @@ private:
wxString m_tooltips[3];
};
class MultiSwitchButton : public StaticBox
{
public:
MultiSwitchButton(wxWindow *parent = nullptr, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize, long style = 0);
~MultiSwitchButton();
int AppendOption(const wxString &option, void *clientData = nullptr);
void SetOptions(const std::vector<wxString> &options);
void DeleteAllOptions();
unsigned int GetCount() const;
int GetSelection() const;
void SetSelection(int index);
wxString GetSelectedText() const;
wxString GetOptionText(unsigned int index) const;
void SetOptionText(unsigned int index, const wxString &text);
void *GetOptionData(unsigned int index) const;
void SetOptionData(unsigned int index, void *clientData);
void SetBackgroundColor(const StateColor &color);
void SetTextColor(const StateColor &color);
void SetButtonCornerRadius(double radius);
void SetButtonPadding(const wxSize &padding);
void Rescale();
protected:
void button_clicked(wxCommandEvent &event);
void update_button_styles();
bool send_selection_event();
private:
std::vector<Button *> btns;
wxBoxSizer *sizer = nullptr;
int sel = -1;
StateColor m_bg_color;
StateColor m_text_color;
double m_button_radius;
wxSize m_button_padding;
};
class SwitchBoard : public wxWindow
{
public: