Compare commits

...

4 Commits

Author SHA1 Message Date
SoftFever
d2c24fdabb Fix Linux/Wayland crash on Preview tab at startup (#13747) 2026-05-20 01:54:17 +08:00
Kappa971
5a77daf75c Fix Italian translation (#13720) 2026-05-20 00:46:22 +08:00
Ioannis Giannakas
75039f8bec Fix first layer toolhead preaheating bug with 2+ extuders and ooze prevention enabled (#13741) 2026-05-20 00:23:04 +08:00
Ian Chua
ebf9d9fd42 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
2026-05-19 23:15:44 +08:00
5 changed files with 101 additions and 32 deletions

View File

@@ -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"

View File

@@ -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, &current_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<float>& time_diffs) {
const int temperature = int(m_layer_id != 1 ? m_filament_nozzle_temp[tool_number] :
[tool_number, this, &current_layer_id](unsigned int id, const std::vector<float>& 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)

View File

@@ -11,6 +11,7 @@
#include "Downloader.hpp"
#include <boost/chrono/duration.hpp>
#include <boost/log/detail/native_typeof.hpp>
#include <libslic3r/Config.hpp>
#include <wx/event.h>
// Localization headers: include libslic3r version first so everything in this file
@@ -786,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<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";
@@ -808,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")
@@ -4844,12 +4849,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 +4862,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)

View File

@@ -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;

View File

@@ -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<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight);