Merge branch 'main' into pr/tommasobbianchi/15238

This commit is contained in:
SoftFever
2026-09-08 14:28:31 +08:00
4759 changed files with 44361 additions and 18139 deletions
+50 -40
View File
@@ -1343,7 +1343,7 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title
if (index >= 0) label_flow->SetMinSize({FromDIP(80), -1});
auto combo_flow = new ComboBox(this, wxID_ANY, wxString(""), wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY);
combo_flow->GetDropDown().SetUseContentWidth(true);
combo_flow->Bind(wxEVT_COMBOBOX, [this, index, combo_flow](wxCommandEvent &evt) {
combo_flow->Bind(wxEVT_COMBOBOX, [index, combo_flow](wxCommandEvent &evt) {
auto printer_tab = dynamic_cast<TabPrinter *>(wxGetApp().get_tab(Preset::TYPE_PRINTER));
NozzleVolumeType volume_type = NozzleVolumeType(intptr_t(combo_flow->GetClientData(evt.GetInt())));
printer_tab->set_extruder_volume_type(index, volume_type);
@@ -1403,7 +1403,7 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title
btn_up = new ScalableButton(this, wxID_ANY, "page_up", "", {FromDIP(14), FromDIP(14)}, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 14);
btn_up->SetBackgroundColour(*wxWHITE);
btn_up->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, index](auto &evt) {
btn_up->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) {
if (page_cur > 0)
--page_cur;
update_ams();
@@ -1411,7 +1411,7 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title
btn_up->Hide();
btn_down = new ScalableButton(this, wxID_ANY, "page_down", "", {FromDIP(14), FromDIP(14)}, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 14);
btn_down->SetBackgroundColour(*wxWHITE);
btn_down->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, index](auto &evt) {
btn_down->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) {
if (page_cur + 1 < page_num)
++page_cur;
update_ams();
@@ -2028,7 +2028,7 @@ bool Sidebar::priv::sync_extruder_list(bool &only_external_material, bool is_man
if (!this->plater)
return false;
this->plater->update_objects_position_when_select_preset([&obj, machine_preset]() {
this->plater->update_objects_position_when_select_preset([machine_preset]() {
Tab *printer_tab = GUI::wxGetApp().get_tab(Preset::Type::TYPE_PRINTER);
printer_tab->select_preset(machine_preset->name);
});
@@ -2173,7 +2173,7 @@ bool Sidebar::priv::sync_extruder_list(bool &only_external_material, bool is_man
void Sidebar::priv::update_sync_status(const MachineObject *obj)
{
StateColor not_synced_colour(std::pair<wxColour, int>(wxColour("#009688"), StateColor::Normal));
auto clear_all_sync_status = [this, &not_synced_colour]() {
auto clear_all_sync_status = [this]() {
panel_printer_preset->ShowBadge(false);
panel_printer_bed->ShowBadge(false);
panel_nozzle_dia->ShowBadge(false); // ORCA add support for nozzle sync
@@ -2477,7 +2477,7 @@ Sidebar::Sidebar(Plater *parent)
p->m_printer_icon = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "printer");
p->m_text_printer_settings = new Label(p->m_panel_printer_title, _L("Printer"), LB_PROPAGATE_MOUSE_EVENT | wxST_ELLIPSIZE_END);
p->m_printer_icon->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
p->m_printer_icon->Bind(wxEVT_BUTTON, [](wxCommandEvent& e) {
//auto wizard_t = new ConfigWizard(wxGetApp().mainframe);
//wizard_t->run(ConfigWizard::RR_USER, ConfigWizard::SP_CUSTOM);
});
@@ -2498,7 +2498,7 @@ Sidebar::Sidebar(Plater *parent)
});
p->m_printer_setting = new ScalableButton(p->m_panel_printer_title, wxID_ANY, "settings");
p->m_printer_setting->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
p->m_printer_setting->Bind(wxEVT_BUTTON, [](wxCommandEvent &e) {
// p->editing_filament = -1;
// wxGetApp().params_dialog()->Popup();
// wxGetApp().get_tab(Preset::TYPE_FILAMENT)->restore_last_select_item();
@@ -2613,8 +2613,8 @@ Sidebar::Sidebar(Plater *parent)
p->image_printer->SetBackgroundColour(bg_color);
p->combo_printer->SetBackgroundColour(bg_color); // paints margins instead combo background
};
p->combo_printer->Bind(wxEVT_SET_FOCUS, [this, printer_focus_bg](auto& e) {printer_focus_bg(true ); e.Skip();});
p->combo_printer->Bind(wxEVT_KILL_FOCUS, [this, printer_focus_bg](auto& e) {printer_focus_bg(false); e.Skip();});
p->combo_printer->Bind(wxEVT_SET_FOCUS, [printer_focus_bg](auto& e) {printer_focus_bg(true ); e.Skip();});
p->combo_printer->Bind(wxEVT_KILL_FOCUS, [printer_focus_bg](auto& e) {printer_focus_bg(false); e.Skip();});
/* ORCA This part moved to titlebar
p->btn_connect_printer = new ScalableButton(p->panel_printer_preset, wxID_ANY, "monitor_signal_strong");
@@ -2691,8 +2691,8 @@ Sidebar::Sidebar(Plater *parent)
p->label_nozzle_type->SetBackgroundColour(bg_color);
p->combo_nozzle_dia->SetBackgroundColour(bg_color); // paints margins instead combo background
};
p->combo_nozzle_dia->Bind(wxEVT_SET_FOCUS, [this, nozzle_focus_bg](auto& e) {nozzle_focus_bg(true ); e.Skip();});
p->combo_nozzle_dia->Bind(wxEVT_KILL_FOCUS, [this, nozzle_focus_bg](auto& e) {nozzle_focus_bg(false); e.Skip();});
p->combo_nozzle_dia->Bind(wxEVT_SET_FOCUS, [nozzle_focus_bg](auto& e) {nozzle_focus_bg(true ); e.Skip();});
p->combo_nozzle_dia->Bind(wxEVT_KILL_FOCUS, [nozzle_focus_bg](auto& e) {nozzle_focus_bg(false); e.Skip();});
p->label_nozzle_type = new Label(p->panel_nozzle_dia, "Brass", LB_PROPAGATE_MOUSE_EVENT | wxST_ELLIPSIZE_END | wxALIGN_CENTRE_HORIZONTAL);
p->label_nozzle_type->SetFont(Label::Body_10);
@@ -2766,8 +2766,8 @@ Sidebar::Sidebar(Plater *parent)
p->image_printer_bed->SetBackgroundColour(bg_color);
p->combo_printer_bed->SetBackgroundColour(bg_color); // paints margins instead combo background
};
p->combo_printer_bed->Bind(wxEVT_SET_FOCUS, [this, bed_focus_bg](auto& e) {bed_focus_bg(true ); e.Skip();});
p->combo_printer_bed->Bind(wxEVT_KILL_FOCUS, [this, bed_focus_bg](auto& e) {bed_focus_bg(false); e.Skip();});
p->combo_printer_bed->Bind(wxEVT_SET_FOCUS, [bed_focus_bg](auto& e) {bed_focus_bg(true ); e.Skip();});
p->combo_printer_bed->Bind(wxEVT_KILL_FOCUS, [bed_focus_bg](auto& e) {bed_focus_bg(false); e.Skip();});
// highlight border on hover
auto printer_bed_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
@@ -2981,7 +2981,7 @@ Sidebar::Sidebar(Plater *parent)
ScalableButton* add_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "add_filament");
add_btn->SetToolTip(_L("Add one filament"));
add_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent& e){
add_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e){
add_filament();
update_filaments_counter();
});
@@ -2991,7 +2991,7 @@ Sidebar::Sidebar(Plater *parent)
ScalableButton* del_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "delete_filament");
del_btn->SetToolTip(_L("Remove last filament"));
del_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) {
del_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
delete_filament();
update_filaments_counter();
});
@@ -3005,7 +3005,7 @@ Sidebar::Sidebar(Plater *parent)
ams_btn = new ScalableButton(p->m_panel_filament_title, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition,
wxBU_EXACTFIT | wxNO_BORDER, false, 16); // ORCA match icon size with other icons as 16x16
ams_btn->SetToolTip(_L("Synchronize filament list from AMS"));
ams_btn->Bind(wxEVT_BUTTON, [this, scrolled_sizer](wxCommandEvent &e) {
ams_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
sync_ams_list();
});
@@ -3685,7 +3685,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
extruder.combo_flow->SetSelection(select);
};
auto update_extruder_diameter = [&diameters, &diameter, &nozzle_diameter](int extruder_index,ExtruderGroup & extruder) {
auto update_extruder_diameter = [&diameters, &nozzle_diameter](int extruder_index,ExtruderGroup & extruder) {
extruder.combo_diameter->Clear();
int select = -1;
// ORCA get the actual nozzle diameter from printer config
@@ -3991,16 +3991,16 @@ void Sidebar::update_mixed_filament_list()
p->m_panel_mixed_warning->Show(false);
// Show/dismiss 3D canvas notification for broken mixed filaments
if (has_mixed && !broken_set.empty()) {
auto* notify = wxGetApp().plater()->get_notification_manager();
if (notify)
auto* notify = plater->get_notification_manager();
GLCanvas3D* view3d_canvas = plater->get_view3D_canvas3D();
if(view3d_canvas && view3d_canvas->is_initialized() && notify){
if (has_mixed && !broken_set.empty()) {
notify->push_notification(NotificationType::BBLMixedFilamentBroken,
NotificationManager::NotificationLevel::ErrorNotificationLevel,
_u8L("Mixed filament has invalid or mismatched components. Please re-edit affected entries."));
} else {
auto* notify = wxGetApp().plater()->get_notification_manager();
if (notify)
} else {
notify->close_notification_of_type(NotificationType::BBLMixedFilamentBroken);
}
}
if (has_mixed) {
@@ -7500,7 +7500,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// Keep tracking the current sidebar size, by storing it using `best_size`, which will be stored
// in the config and re-applied when the app is opened again.
this->sidebar->Bind(wxEVT_IDLE, [&sidebar, this](wxIdleEvent& e) {
this->sidebar->Bind(wxEVT_IDLE, [&sidebar](wxIdleEvent& e) {
if (sidebar.IsShown() && sidebar.IsDocked() && sidebar.rect.GetWidth() > 0) {
sidebar.BestSize(sidebar.rect.GetWidth(), sidebar.best_size.GetHeight());
}
@@ -7799,8 +7799,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
wxGetApp().removable_drive_manager()->init(this->q);
#ifdef _WIN32
//Trigger enumeration of removable media on Win32 notification.
this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
this->q->Bind(EVT_VOLUME_ATTACHED, [](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
this->q->Bind(EVT_VOLUME_DETACHED, [](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
#endif /* _WIN32 */
}
@@ -8281,7 +8281,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
bool dlg_cont = true;
bool is_user_cancel = false;
bool translate_old = false;
int current_width = 0, current_depth = 0, current_height = 0, project_filament_count = 1;
int current_width = 0, current_depth = 0, project_filament_count = 1;
double current_height = 0;
if (input_files.empty())
return std::vector<size_t>();
@@ -8360,7 +8361,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
const float LOAD_MODEL_RATIO = 0.9;
for (size_t i = 0; i < input_files.size(); ++i) {
int file_percent = 0;
#ifdef _WIN32
auto path = input_files[i];
@@ -8409,7 +8409,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
q->skip_thumbnail_invalid = true;
model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, en_3mf_file_type, strategy, &plate_data, &project_presets,
&file_version,
[this, &dlg, real_filename, &progress_percent, &file_percent, stage_percent, INPUT_FILES_RATIO, total_files, i,
[&dlg, real_filename, &progress_percent, stage_percent, INPUT_FILES_RATIO, total_files, i,
&is_user_cancel](int import_stage, int current, int total, bool &cancel) {
bool cont = true;
float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)stage_percent[import_stage] + (float)current * (float)(stage_percent[import_stage + 1] - stage_percent[import_stage]) /(float) total) / (float)total_files;
@@ -8830,6 +8830,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
if (wipe_tower_y_opt)
file_wipe_tower_y = *wipe_tower_y_opt;
if (auto* agent = wxGetApp().getAgent()) {
if (auto* ids = config.opt<ConfigOptionStrings>("filament_ids"))
for (std::string& id : ids->values)
id = agent->to_orca_filament_id(id);
}
preset_bundle->load_config_model(filename.string(), std::move(config), file_version);
ConfigOption* bed_type_opt = preset_bundle->project_config.option("curr_bed_type");
@@ -8992,7 +8997,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
Semver file_version;
//ObjImportColorFn obj_color_fun=nullptr;
auto obj_color_fun = [this, &path](ObjDialogInOut &in_out) {
auto obj_color_fun = [&path](ObjDialogInOut &in_out) {
if (!boost::iends_with(path.string(), ".obj")) { return; }
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
@@ -9009,7 +9014,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
if (angle <= 0) angle = 0.5;
bool split_compound = wxGetApp().app_config->get_bool("is_split_compound");
model = Slic3r::Model:: read_from_step(path.string(), strategy,
[this, &dlg, real_filename, &progress_percent, &file_percent, step_percent, INPUT_FILES_RATIO, total_files, i](int load_stage, int current, int total, bool &cancel)
[&dlg, real_filename, &progress_percent, step_percent, INPUT_FILES_RATIO, total_files, i](int load_stage, int current, int total, bool &cancel)
{
bool cont = true;
float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)step_percent[load_stage] + (float)current * (float)(step_percent[load_stage + 1] - step_percent[load_stage]) / (float)total) / (float)total_files;
@@ -9023,7 +9028,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
if (!isUtf8StepFile) {
const auto no_warn = wxGetApp().app_config->get_bool("step_not_utf8_no_warn");
if (!no_warn) {
MessageDialog dlg(nullptr, _L("Component name(s) inside step file not in UTF8 format!") + "\n\n" + _L("Because of unsupported text encoding, garbage characters may appear!"),
MessageDialog dlg(nullptr, _L("Component name(s) inside step file not in UTF-8 format!") + "\n\n" + _L("Because of unsupported text encoding, garbage characters may appear!"),
wxString(SLIC3R_APP_FULL_NAME " - ") + _L("Attention!"), wxOK | wxICON_INFORMATION);
dlg.show_dsa_button(_L("Remember my choice."));
dlg.ShowModal();
@@ -9033,7 +9038,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
}
},
[this, &path, &is_user_cancel, &linear, &angle, &split_compound](Slic3r::Step& file, double& linear_value, double& angle_value, bool& is_split)-> int {
[&is_user_cancel, &linear, &angle, &split_compound](Slic3r::Step& file, double& linear_value, double& angle_value, bool& is_split)-> int {
if (wxGetApp().app_config->get_bool("enable_step_mesh_setting")) {
StepMeshDialog mesh_dlg(nullptr, file, linear, angle);
if (mesh_dlg.ShowModal() == wxID_OK) {
@@ -9054,7 +9059,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}else {
model = Slic3r::Model:: read_from_file(
path.string(), nullptr, nullptr, strategy, &plate_data, &project_presets, &is_xxx, &file_version, nullptr,
[this, &dlg, real_filename, &progress_percent, &file_percent, INPUT_FILES_RATIO, total_files, i, &designer_model_id, &designer_country_code](int current, int total, bool &cancel, std::string &mode_id, std::string &code)
[&dlg, real_filename, &progress_percent, INPUT_FILES_RATIO, total_files, i, &designer_model_id, &designer_country_code](int current, int total, bool &cancel, std::string &mode_id, std::string &code)
{
designer_model_id = mode_id;
designer_country_code = code;
@@ -9136,7 +9141,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
else if (model.looks_like_saved_in_meters()) {
// BBS do not handle look like in meters
MessageDialog dlg(q,
format_wxstr(_L("The object from file %s is too small, and may be in meters or inches.\n Do you want to scale to millimeters\?"),
format_wxstr(_L("The object from file %s is too small, and may be in meters or inches.\nDo you want to scale to millimeters\?"),
from_path(filename)),
_L("Object too small"), wxICON_QUESTION | wxYES_NO);
int answer = dlg.ShowModal();
@@ -9144,7 +9149,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
} else if (model.looks_like_imperial_units()) {
// BBS do not handle look like in meters
MessageDialog dlg(q,
format_wxstr(_L("The object from file %s is too small, and may be in meters or inches.\n Do you want to scale to millimeters\?"),
format_wxstr(_L("The object from file %s is too small, and may be in meters or inches.\nDo you want to scale to millimeters\?"),
from_path(filename)),
_L("Object too small"), wxICON_QUESTION | wxYES_NO);
int answer = dlg.ShowModal();
@@ -11325,7 +11330,7 @@ void Plater::priv::reload_from_disk()
// load one file at a time
for (size_t i = 0; i < input_paths.size(); ++i) {
const auto& path = input_paths[i].string();
auto obj_color_fun = [this, &path](ObjDialogInOut &in_out) {
auto obj_color_fun = [&path](ObjDialogInOut &in_out) {
if (!boost::iends_with(path, ".obj")) { return; }
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
ObjColorDialog color_dlg(nullptr, in_out, extruder_colours, Sidebar::should_show_SEMM_buttons());
@@ -15309,7 +15314,7 @@ void Plater::import_model_id(wxString download_info)
p->project.reset();
/* prepare project and profile */
boost::thread import_thread = Slic3r::create_thread([&percent, &cont, &cancel, &retry_count, max_retries, &msg, &target_path, &download_ok, download_url, &filename] {
boost::thread import_thread = Slic3r::create_thread([&percent, &cont, &retry_count, &msg, &target_path, &download_ok, download_url, &filename] {
// Orca: NetworkAgent is not needed and only prevents this from running
// NetworkAgent* m_agent = Slic3r::GUI::wxGetApp().getAgent();
@@ -15416,7 +15421,7 @@ void Plater::import_model_id(wxString download_info)
msg = wxString::Format(_L("Project downloaded %d%%"), percent);
}
})
.on_error([&msg, &cont, &retry_count, max_retries](std::string body, std::string error, unsigned http_status) {
.on_error([&msg, &cont, &retry_count](std::string body, std::string error, unsigned http_status) {
(void)body;
BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%",
body,
@@ -16316,6 +16321,7 @@ void Plater::calib_retraction(const Calib_Params& params)
obj->config.set_key_value("wall_sequence", new ConfigOptionEnum<WallSequence>(WallSequence::InnerOuter));
obj->config.set_key_value("overhang_reverse", new ConfigOptionBool(false));
obj->config.set_key_value("precise_z_height", new ConfigOptionBool(false));
obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
changed_objects({ 0 });
@@ -18718,6 +18724,8 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
nozzle_diameter_str = nozzle_diameter_option->serialize();
std::string printer_model_id = preset_bundle.printers.get_edited_preset().get_printer_type(&preset_bundle);
// The printer reads slice_info.config and knows only its own catalog ids.
auto* id_agent = preset_bundle.is_bbl_vendor() ? wxGetApp().getAgent() : nullptr;
for (int i = 0; i < plate_data_list.size(); i++) {
PlateData *plate_data = plate_data_list[i];
@@ -18727,6 +18735,8 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
std::string display_filament_type;
it->type = cfg.get_filament_type(display_filament_type, it->id);
it->filament_id = filament_id_opt ? filament_id_opt->get_at(it->id) : "";
if (id_agent)
it->filament_id = id_agent->from_orca_filament_id(it->filament_id);
it->color = filament_color ? filament_color->get_at(it->id) : "#FFFFFF";
// save filament info used in curr plate
int index = p->partplate_list.get_curr_plate_index();
@@ -21683,7 +21693,7 @@ void Plater::show_object_info()
auto mesh_errors = p->sidebar->obj_list()->get_mesh_errors_info(&info_manifold, &non_manifold_edges);
if (non_manifold_edges > 0) {
info_manifold += into_u8("\n" + _L("Tips:") + "\n" + _L("Use \"Fix Model\" to repair the mesh."));
info_manifold += "\n" + _L("Tips:") + "\n" + _L("Use \"Fix Model\" to repair the mesh.");
}
info_manifold = "<Error>" + info_manifold + "</Error>";