From ff68a2859d6eff9ea40f74498017dcf1e6776ccd Mon Sep 17 00:00:00 2001 From: Ian Bassi Date: Tue, 19 May 2026 09:42:44 -0300 Subject: [PATCH 1/5] Ignore Jerk values Warning if using JD (#13575) * Ignore Jerk values if using JD * add flavor check --- src/libslic3r/Print.cpp | 63 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1853e249b8..f2e59c3b67 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1754,46 +1754,47 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* }; std::string warning_key; + const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; + const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0; + // check jerk - if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 || - m_default_object_config.inner_wall_jerk == 1) { - warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces"); - if (m_default_object_config.outer_wall_jerk == 1) - warning_key = "outer_wall_jerk"; - else if (m_default_object_config.inner_wall_jerk == 1) - warning_key = "inner_wall_jerk"; - else - warning_key = "default_jerk"; + if (!ignore_jerk_validation) { + if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 || + m_default_object_config.inner_wall_jerk == 1) { + warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces"); + if (m_default_object_config.outer_wall_jerk == 1) + warning_key = "outer_wall_jerk"; + else if (m_default_object_config.inner_wall_jerk == 1) + warning_key = "inner_wall_jerk"; + else + warning_key = "default_jerk"; - warning->opt_key = warning_key; - } + warning->opt_key = warning_key; + } - if (warning_key.empty() && m_default_object_config.default_jerk > 0) { - std::vector jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", - "top_surface_jerk", "initial_layer_jerk", "travel_jerk"}; - const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]); - warning_key.clear(); - if (m_default_object_config.default_jerk > 0) - warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk); - if (!warning_key.empty()) { - warning->string = L( - "The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\nOrca will " - "automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the " - "maximum jerk setting in your printer's configuration to get higher speeds."); - warning->opt_key = warning_key; - } + if (warning_key.empty() && m_default_object_config.default_jerk > 0) { + std::vector jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", + "top_surface_jerk", "initial_layer_jerk", "travel_jerk"}; + const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]); + warning_key.clear(); + warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk); + if (!warning_key.empty()) { + warning->string = L( + "The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n" + "Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n" + "You can adjust the maximum jerk setting in your printer's configuration to get higher speeds."); + warning->opt_key = warning_key; + } + } } // Check junction deviation - const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; // Orca: Only marlin FW supports max junction deviation. Dont display warning if firmware is not supporting it. const bool support_max_junction_deviation = ( m_config.gcode_flavor == gcfMarlinFirmware); if (warning_key.empty() && m_default_object_config.default_junction_deviation.value > max_junction_deviation && support_max_junction_deviation) { - warning->string = L( "Junction deviation setting exceeds the printer's maximum value " - "(machine_max_junction_deviation).\nOrca will " - "automatically cap the junction deviation to ensure it doesn't surpass the printer's " - "capabilities.\nYou can adjust the " - "machine_max_junction_deviation value in your printer's configuration to get higher limits."); + warning->string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n" + "Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n" + "You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits."); warning->opt_key = warning_key; } From ebf9d9fd42d9654d6f8e4480fb47aa0a6f7d2865 Mon Sep 17 00:00:00 2001 From: Ian Chua Date: Tue, 19 May 2026 23:15:44 +0800 Subject: [PATCH 2/5] feat: add UI feedback on http error and some logs (#13738) * feat: add UI feedback on http error and some logs * spelling fix * show error dialog only once per session * show errors with plater notification when on developer mode * remove return * remove irrelevant logs --- src/slic3r/GUI/GUI_App.cpp | 41 ++++++++++++++++++++++++++++++--- src/slic3r/GUI/GUI_App.hpp | 2 +- src/slic3r/GUI/ImGuiWrapper.hpp | 3 ++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b5204e1d49..9f2ce1c8f5 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -11,6 +11,7 @@ #include "Downloader.hpp" #include #include +#include #include // Localization headers: include libslic3r version first so everything in this file @@ -4844,12 +4845,12 @@ void GUI_App::on_http_error(wxCommandEvent &evt) BOOST_LOG_TRIVIAL(warning) << "logout: http error 401."; this->request_user_logout(provider); - if (!m_show_http_errpr_msgdlg) { + if (!m_show_http_error_msgdlg) { MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK); - m_show_http_errpr_msgdlg = true; + m_show_http_error_msgdlg = true; auto modal_result = msg_dlg.ShowModal(); if (modal_result == wxOK || modal_result == wxCLOSE) { - m_show_http_errpr_msgdlg = false; + m_show_http_error_msgdlg = false; return; } } @@ -4857,6 +4858,40 @@ void GUI_App::on_http_error(wxCommandEvent &evt) } return; } + + // No need to show dialog for 410: 410 means resource has been deleted from the server. + if (status == 410) { + BOOST_LOG_TRIVIAL(info) << "Http error 410."; + return; + } + + static bool m_is_error_shown = false; + // Show general error notification for Orca Cloud API failures (not Bambu) + if (provider == ORCA_CLOUD_PROVIDER && status >= 400 && code != HttpErrorVersionLimited) { + wxString msg; + if (!error.empty()) { + msg = wxString::Format(_L("API error (HTTP %u): %s"), status, wxString::FromUTF8(error)); + } else { + msg = wxString::Format(_L("API error (HTTP %u)"), status); + } + + if (app_config->get_bool("developer_mode")) { + // Use notification manager if ImGui is ready; fall back to wxMessageBox on Linux + // where ImGui may not be initialized until the user switches to the Prepare tab. + if (wxGetApp().plater() != nullptr && wxGetApp().imgui()->display_initialized()) { + wxGetApp() + .plater() + ->get_notification_manager() + ->push_notification(NotificationType::PlaterError, NotificationManager::NotificationLevel::WarningNotificationLevel, + msg.ToUTF8().data()); + } + } + + if (!m_is_error_shown) { + m_is_error_shown = true; + wxMessageBox(msg, _L("Orca Cloud API Error"), wxOK | wxICON_ERROR, wxGetApp().mainframe); + } + } } void GUI_App::enable_user_preset_folder(bool enable) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index fac853e65c..3212c719f5 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -324,7 +324,7 @@ private: bool m_is_dark_mode{ false }; bool m_adding_script_handler { false }; bool m_side_popup_status{false}; - bool m_show_http_errpr_msgdlg{false}; + bool m_show_http_error_msgdlg{false}; bool m_show_error_msgdlg{false}; wxString m_info_dialog_content; HttpServer m_http_server; diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 8855a38405..af92140379 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -373,12 +373,13 @@ public: //BBS static int TOOLBAR_WINDOW_FLAGS; + bool display_initialized() const; + private: void init_font(bool compress); void init_input(); void init_style(); void render_draw_data(ImDrawData *draw_data); - bool display_initialized() const; void destroy_font(); std::vector load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight); From 75039f8becdb886bc3c57321ed1cd597e91199ae Mon Sep 17 00:00:00 2001 From: Ioannis Giannakas <59056762+igiannakas@users.noreply.github.com> Date: Tue, 19 May 2026 17:23:04 +0100 Subject: [PATCH 3/5] Fix first layer toolhead preaheating bug with 2+ extuders and ooze prevention enabled (#13741) --- src/libslic3r/GCode/GCodeProcessor.cpp | 31 +++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 1ca9c3ffc4..598ae5bcd2 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1230,8 +1230,15 @@ void GCodeProcessor::run_post_process() } }; + // Orca: track the current layer during the post-processing pass so that preheat M104s emitted + // for tool changes on the first layer use the correct first-layer temperature. The member + // m_layer_id is populated during the analysis pass and ends at the total layer count, so it + // cannot be used here — it would always select the "other layers" temperature for multi-layer + // prints. + unsigned int current_layer_id = 0; + // add lines M104 to exported gcode - auto process_line_T = [this, &export_line](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { + auto process_line_T = [this, &export_line, ¤t_layer_id](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { const std::string cmd = GCodeReader::GCodeLine::extract_cmd(gcode_line); int tool_number = -1; @@ -1257,8 +1264,13 @@ void GCodeProcessor::run_post_process() export_line.insert_lines( backtrace, cmd, // line inserter - [tool_number, this](unsigned int id, const std::vector& time_diffs) { - const int temperature = int(m_layer_id != 1 ? m_filament_nozzle_temp[tool_number] : + [tool_number, this, ¤t_layer_id](unsigned int id, const std::vector& time_diffs) { + // Orca: use the locally-tracked layer index (current_layer_id) rather than + // the stale m_layer_id from the analysis pass. current_layer_id == 0 means + // we haven't reached the first ;LAYER_CHANGE marker yet (e.g. tool change + // inside start gcode); == 1 means we are inside the first printed layer. + // Both cases should use the first-layer nozzle temperature. + const int temperature = int(current_layer_id > 1 ? m_filament_nozzle_temp[tool_number] : m_filament_nozzle_temp_first_layer[tool_number]); // Orca: M104.1 for XL printers, I can't find the documentation for this so I copied the C++ comments from // Prusa-Firmware-Buddy here @@ -1351,6 +1363,19 @@ void GCodeProcessor::run_post_process() if (eol) { ++line_id; const unsigned int internal_g1_lines_counter = export_line.update(gcode_line, line_id, g1_lines_counter); + // Orca: track the current layer for preheat temperature selection. + // The line is ";" + reserved_tag(Layer_Change) + EOL; match it independent of + // BBL vs. compatible flavor (which differ in the tag text). + if (gcode_line.size() > 1 && gcode_line.front() == ';') { + std::string_view tag_line(gcode_line); + // strip trailing CR/LF + while (!tag_line.empty() && (tag_line.back() == '\n' || tag_line.back() == '\r')) + tag_line.remove_suffix(1); + // strip leading ';' + tag_line.remove_prefix(1); + if (tag_line == reserved_tag(ETags::Layer_Change)) + ++current_layer_id; + } // replace placeholder lines bool processed = process_placeholders(gcode_line); if (processed) From 5a77daf75c6c5bfc91477abdc038df20baa2214c Mon Sep 17 00:00:00 2001 From: Kappa971 <62349018+Kappa971@users.noreply.github.com> Date: Tue, 19 May 2026 18:46:22 +0200 Subject: [PATCH 4/5] Fix Italian translation (#13720) --- localization/i18n/it/OrcaSlicer_it.po | 32 +++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index 91f171c11d..c1d7ce992a 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -17664,9 +17664,10 @@ msgid "" "Apply scarf joints only to smooth perimeters where traditional seams do not " "conceal the seams at sharp corners effectively." msgstr "" -"Applica le cuciture a sciarpa solo sui perimetri lisci, dove le cuciture " -"tradizionali non riescono a nascondere efficacemente quelle in " -"corrispondenza degli angoli vivi." +"Applica le cuciture a sciarpa solo sui perimetri lisci e curvi, dove le " +"cuciture tradizionali risulterebbero molto evidenti. Gli angoli netti " +"continueranno a utilizzare le cuciture normali per mantenere la precisione " +"dimensionale." msgid "Conditional angle threshold" msgstr "Soglia angolo condizionale" @@ -17734,45 +17735,48 @@ msgstr "" "cucitura a sciarpa." msgid "Scarf start height" -msgstr "Altezza iniziale sciarpa" +msgstr "Altezza iniziale cucitura a sciarpa" msgid "" "Start height of the scarf.\n" "This amount can be specified in millimeters or as a percentage of the " "current layer height. The default value for this parameter is 0." msgstr "" -"Altezza iniziale della sciarpa.\n" -"Questa quantità può essere specificata in millimetri o come percentuale " +"Altezza iniziale della cucitura a sciarpa.\n" +"Questo valore può essere specificato in millimetri o come percentuale " "dell'altezza dello strato corrente. Il valore predefinito per questo " "parametro è 0." msgid "Scarf around entire wall" -msgstr "Sciarpa attorno all'intera parete" +msgstr "Cucitura a sciarpa su intera parete" msgid "The scarf extends to the entire length of the wall." -msgstr "La sciarpa si estende per tutta la lunghezza della parete." +msgstr "" +"La cucitura a sciarpa si estende lungo tutto il perimetro della parete." msgid "Scarf length" -msgstr "Lunghezza sciarpa" +msgstr "Lunghezza cucitura a sciarpa" msgid "" "Length of the scarf. Setting this parameter to zero effectively disables the " "scarf." msgstr "" -"Lunghezza della sciarpa. Impostando questo parametro su zero, la sciarpa " -"viene effettivamente disabilitata." +"Lunghezza della cucitura a sciarpa. Impostando questo parametro su zero, la " +"cucitura a sciarpa viene disabilitata." msgid "Scarf steps" -msgstr "Incrementi sciarpa" +msgstr "Incrementi cucitura a sciarpa" msgid "Minimum number of segments of each scarf." -msgstr "Numero minimo di segmenti di ogni sciarpa." +msgstr "" +"Numero minimo di segmenti utilizzati per la creazione della sfumatura della " +"cucitura a sciarpa." msgid "Scarf joint for inner walls" msgstr "Cucitura a sciarpa per pareti interne" msgid "Use scarf joint for inner walls as well." -msgstr "Utilizzare la cucitura a sciarpa anche per le pareti interne." +msgstr "Utilizza la cucitura a sciarpa anche per le pareti interne." msgid "Role base wipe speed" msgstr "Velocità di spurgo basata su ruolo" From d2c24fdabb26c5cb06696cd21f2f2ab514c832b9 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 20 May 2026 01:54:17 +0800 Subject: [PATCH 5/5] Fix Linux/Wayland crash on Preview tab at startup (#13747) --- src/slic3r/GUI/GUI_App.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 9f2ce1c8f5..0339805304 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -787,9 +787,20 @@ void GUI_App::post_init() mainframe->select_tab(size_t(MainFrame::tp3DEditor)); plater_->select_view_3D("3D"); //BBS init the opengl resource here -//#ifdef __linux__ - if (plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen()&&plater_->canvas3D()->make_current_for_postinit()) { -//#endif + if (!plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen() || + !plater_->canvas3D()->make_current_for_postinit()) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": glcontext not ready, postpone init"; + plater_->canvas3D()->enable_render(true); + plater_->canvas3D()->set_as_dirty(); +#ifdef __linux__ + // Wayland/EGL may not have committed the GL surface yet; ask the + // idle loop to retry post_init when the canvas is actually mapped. + // Without this, GL function pointers stay null and the first + // Preview focus crashes in Camera::apply_viewport. + m_post_initialized = false; + return; +#endif + } else { Size canvas_size = plater_->canvas3D()->get_canvas_size(); wxGetApp().imgui()->set_display_size(static_cast(canvas_size.get_width()), static_cast(canvas_size.get_height())); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl"; @@ -809,14 +820,7 @@ void GUI_App::post_init() plater_->canvas3D()->render(false); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test"; } -//#ifdef __linux__ } - else { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "Found glcontext not ready, postpone the init"; - plater_->canvas3D()->enable_render(true); - plater_->canvas3D()->set_as_dirty(); - } -//#endif if (is_editor()) mainframe->select_tab(size_t(0)); if (app_config->get("default_page") == "1")