ENH: some tip logic optimize

1. Only check printablily if have explicit filament map
2. Refine some sentences

jira:STUDIO-9753,STUDIO-9727

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I2fc3aa2276dc6f514c50ac2fcaf9509f41e778f3
This commit is contained in:
xun.zhang 2025-01-13 10:20:31 +08:00 committed by lane.wei
parent 80b5e4f4d6
commit 73f92d27da
9 changed files with 68 additions and 54 deletions

View File

@ -2434,7 +2434,7 @@ std::vector<std::set<int>> Print::get_physical_unprintable_filaments(const std::
tpu_filaments.insert(f);
}
if (tpu_filaments.size() > 1) {
throw Slic3r::RuntimeError(std::string("Only supports up to one TPU filament."));
throw Slic3r::RuntimeError(_u8L("Only supports up to one TPU filament."));
}
int extruder_num = m_config.nozzle_diameter.size();

View File

@ -53,18 +53,17 @@ FilamentGroupPopup::FilamentGroupPopup(wxWindow *parent) : PopupWindow(parent, w
const wxString AutoForMatchLabel = _L("Convenient Mode");
const wxString ManualLabel = _L("Manual Mode");
const wxString AutoForFlushDetail = _L("Disregrad the filaments in AMS. Optimize filament usage "
"by calculating the best arrangement for the left and right "
"nozzles. Arrange the filaments on the printer based on "
"the slicing results.");
const wxString AutoForMatchDetail = _L("Based on the current filaments in the AMS, arrange the "
"filaments to the left and right nozzles.");
const wxString ManualDetail = _L("Mannully arrange the filaments for the left and right nozzles.");
const wxString AutoForFlushDetail = _L("Calculate the best filament arrangement "
"to minimize usage. Need to manually arrange filaments on the printer "
"based on slicing results.");
const wxString AutoForMatchDetail = _L("Use AMS filaments to automatically assign filament "
"to the left or right nozzle.");
const wxString ManualDetail = _L("Manually assign filament to the left or right nozzle.");
const wxString AutoForFlushDesp = _L("(Arrange after slicing)");
const wxString AutoForFlushDesp = ""; //_L("(Post-slicing arrangement)");
const wxString ManualDesp = "";
const wxString AutoForMatchDesp = _L("(Arrange before slicing)");
const wxString MachineSyncTip = _L("(Please sync printer)");
const wxString AutoForMatchDesp = "";// _L("(Pre-slicing arrangement)");
wxBoxSizer *top_sizer = new wxBoxSizer(wxVERTICAL);
const int horizontal_margin = FromDIP(16);
@ -147,7 +146,7 @@ FilamentGroupPopup::FilamentGroupPopup(wxWindow *parent) : PopupWindow(parent, w
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
auto* wiki_sizer = new wxBoxSizer(wxHORIZONTAL);
wiki_link = new wxStaticText(this, wxID_ANY, _L("More info on wiki"));
wiki_link = new wxStaticText(this, wxID_ANY, _L("Learn more"));
wiki_link->SetBackgroundColour(BackGroundColor);
wiki_link->SetForegroundColour(GreenColor);
wiki_link->SetFont(Label::Body_12.Underlined());
@ -191,8 +190,8 @@ void FilamentGroupPopup::DrawRoundedCorner(int radius)
void FilamentGroupPopup::Init()
{
const wxString AutoForMatchDesp = _L("(Arrange before slicing)");
const wxString MachineSyncTip = _L("(Please sync printer)");
const wxString AutoForMatchDesp = "";// _L("(Pre-slicing arrangement)");
const wxString MachineSyncTip = _L("(Sync with printer)");
radio_btns[ButtonType::btForMatch]->Enable(m_connected);
if (m_connected) {

View File

@ -115,7 +115,7 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent,
bool machine_synced,
bool show_default,
bool with_checkbox)
: wxDialog(parent, wxID_ANY, _L("Filament arrangement method"), wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE), m_filament_color(filament_color), m_filament_map(filament_map)
: wxDialog(parent, wxID_ANY, _L("Filament arrangement"), wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE), m_filament_color(filament_color), m_filament_map(filament_map)
{
SetBackgroundColour(*wxWHITE);

View File

@ -273,12 +273,12 @@ void GUI::FilamentMapBtnPanel::Show()
FilamentMapAutoPanel::FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode, bool machine_synced) : wxPanel(parent)
{
static const wxString AutoForFlushDetail = _L("Disregrad the filaments in AMS. Optimize filament usage "
"by calculating the best arrangement for the left and right "
"nozzles. Arrange the filaments on the printer based on "
"the slicing results.");
static const wxString AutoForMatchDetail = _L("Based on the current filaments in the AMS, arrange the "
"filaments to the left and right nozzles.");
const wxString AutoForFlushDetail = _L("Calculate the best filament arrangement "
"to minimize usage. Need to manually arrange filaments on the printer "
"based on slicing results.");
const wxString AutoForMatchDetail = _L("Use AMS filaments to automatically assign filament "
"to the left or right nozzle.");
auto sizer = new wxBoxSizer(wxHORIZONTAL);
m_flush_panel = new FilamentMapBtnPanel(this, _L("Filament-Saving Mode"), AutoForFlushDetail, "flush_mode_panel_icon");
m_match_panel = new FilamentMapBtnPanel(this, _L("Convenient Mode"), AutoForMatchDetail, "match_mode_panel_icon");

View File

@ -125,10 +125,18 @@ float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleF
#undef Convex
#endif
std::string object_limited_text = _u8L("An object is laid on the left/right extruder only area.\n"
"Please make sure the filaments used by this object on this area are not mapped to the other extruders.");
std::string object_clashed_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
std::string& get_object_limited_text() {
static std::string object_limited_text = _u8L("An object is laid on the left/right nozzle only area.\n"
"Please make sure the filaments used by this object on this area are not mapped to the other nozzles.");
return object_limited_text;
}
std::string& get_object_clashed_text() {
static std::string object_clashed_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
return object_clashed_text;
}
wxString filament_printable_error_msg;
@ -1451,7 +1459,7 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state(ObjectFil
ModelInstanceEPrintVolumeState state;
m_volumes.check_outside_state(m_bed.build_volume(), &state, object_results);
construct_error_string(*object_results, object_clashed_text);
construct_error_string(*object_results, get_object_clashed_text());
return state;
}
@ -2947,7 +2955,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
const bool objectLimited = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Limited);
construct_error_string(object_results, object_clashed_text);
construct_error_string(object_results, get_object_clashed_text());
_set_warning_notification(EWarning::ObjectClashed, partlyOut || !object_results.filaments.empty());
_set_warning_notification(EWarning::ObjectLimited, objectLimited);
@ -9950,6 +9958,7 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
SLICING_LIMIT_ERROR,
SLICING_HEIGHT_OUTSIDE
};
const static std::vector<std::string> extruder_name_list= {_u8L("left nozzle"), _u8L("right nozzle")}; // in ui, we treat extruder as nozzle
std::string text;
ErrorType error = ErrorType::PLATER_WARNING;
const ModelObject* conflictObj=nullptr;
@ -9975,11 +9984,11 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
case EWarning::ToolHeightOutside: text = _u8L("A G-code path goes beyond the max print height."); error = ErrorType::SLICING_ERROR; break;
case EWarning::ToolpathOutside: text = _u8L("A G-code path goes beyond the boundary of plate."); error = ErrorType::SLICING_ERROR; break;
case EWarning::TPUPrintableError: {
int master_extruder_id = 0; // main extruder is left or right
int master_extruder_id = 1; // main extruder is left or right
if (m_config->has("master_extruder_id"))
master_extruder_id = m_config->opt_int("master_extruder_id"); // base 1
std::string extruder_name = master_extruder_id == 1 ? "Left extruder" : "Right extruder";
text = (boost::format(_u8L("Multiple TPU filaments are not allowed to print at the same time, and the TPU filament must be placed in the virtual slot of %s.")) %extruder_name).str();
std::string extruder_name = extruder_name_list[master_extruder_id-1];
text = (boost::format(_u8L("Only the %s with external filament spool can print TPU")) %extruder_name).str();
error = ErrorType::SLICING_ERROR;
break;
}
@ -10023,7 +10032,7 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
}
}
}
std::string extruder_name = extruder_id == 1 ? "Left extruder" : "Right extruder";
std::string extruder_name = extruder_name_list[extruder_id-1];
if (error_iter->second.size() == 1) {
text += (boost::format(_u8L("Filament %d is placed in the %s, but the generated G-code path exceeds the printable range of the %s.")) %filaments %extruder_name %extruder_name).str();
}
@ -10080,7 +10089,7 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
}
}
}
std::string extruder_name = extruder_id == 1 ? "Left extruder" : "Right extruder";
std::string extruder_name = extruder_name_list[extruder_id-1];
if (error_iter->second.size() == 1) {
text += (boost::format(_u8L("Filament %d is placed in the %s, but the generated G-code path exceeds the printable height of the %s.")) % filaments % extruder_name % extruder_name).str();
} else {
@ -10099,11 +10108,11 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
case EWarning::SlaSupportsOutside: text = ("SLA supports outside the print area were detected."); error = ErrorType::PLATER_ERROR; break;
case EWarning::SomethingNotShown: text = _u8L("Only the object being edited is visible."); break;
case EWarning::ObjectClashed:
text = object_clashed_text;
text = get_object_clashed_text();
error = ErrorType::PLATER_ERROR;
break;
case EWarning::ObjectLimited:
text = object_limited_text;
text = get_object_limited_text();
break;
case EWarning::FilamentUnPrintableOnFirstLayer: {
std::string warning;

View File

@ -1372,7 +1372,7 @@ void MenuFactory::create_filament_action_menu(bool init, int active_filament_men
[]() { return true; }, m_parent);
}
const int item_id = menu->FindItem(_L("Change to"));
const int item_id = menu->FindItem(_L("Delete then replace with"));
if (item_id != wxNOT_FOUND)
menu->Destroy(item_id);
@ -1390,7 +1390,7 @@ void MenuFactory::create_filament_action_menu(bool init, int active_filament_men
[i](wxCommandEvent&) { plater()->sidebar().change_filament(-2, i); }, *icons[i], menu,
[]() { return true; }, m_parent);
}
append_submenu(menu, sub_menu, wxID_ANY, _L("Change to"), "", "",
append_submenu(menu, sub_menu, wxID_ANY, _L("Delete then replace with"), "", "",
[filaments_cnt]() { return filaments_cnt > 1; }, m_parent, 1);
if (init) {

View File

@ -1314,6 +1314,13 @@ std::vector<int> PartPlate::get_used_filaments()
bool PartPlate::check_filament_printable(const DynamicPrintConfig &config, wxString& error_message)
{
error_message.clear();
FilamentMapMode mode = config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode")->value;
bool has_valid_result = this->is_slice_result_valid();
// only check printablity if we have explicit map result
if (!has_valid_result && mode != fmmManual)
return true;
std::vector<int> used_filaments = get_extruders(true); // 1 base
if (!used_filaments.empty()) {
for (auto filament_idx : used_filaments) {
@ -1326,7 +1333,7 @@ bool PartPlate::check_filament_printable(const DynamicPrintConfig &config, wxStr
auto iter = std::find(filament_types.begin(), filament_types.end(), filament_type);
if (iter != filament_types.end()) {
wxString extruder_name = extruder_idx == 0 ? _L("left") : _L("right");
error_message = wxString::Format(_L("Filament %s cannot be placed in the %s extruder for printing."), filament_type, extruder_name);
error_message = wxString::Format(_L("The %s nozzle can not print %s."), extruder_name, filament_type);
return false;
}
}

View File

@ -5421,19 +5421,16 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
if (printer_preset.get_current_printer_type(preset_bundle) != machine_type || !is_approx((float) preset_nozzle_diameter, machine_nozzle_diameter)) {
Preset *machine_preset = get_printer_preset(obj);
if (machine_preset != nullptr) {
std::string printer_model = machine_preset->config.option<ConfigOptionString>("printer_model")->value;
bool sync_printer_info = false;
if (!wxGetApp().app_config->has("sync_after_load_file_show_flag")) {
wxString tips = from_u8((boost::format(L("The printer you are currently bound to is %s,\nThe printer preset for your current file is %s,\n")) %
machine_preset->name % printer_preset.name)
.str());
if (obj->is_multi_extruders())
tips += L("Do you want to sync printer presets, ams and nozzle information immediately?");
else
tips += L("Do you want to sync printer presets immediately?");
wxString tips = from_u8((boost::format(_u8L("Connected printer is %s. It must match the project preset for printing.\n")) % printer_model).str());
tips += _L("Do you want to sync the printer information and automatically switch the preset?");
TipsDialog dlg(wxGetApp().mainframe, _L("Tips"), tips, "sync_after_load_file_show_flag", wxYES_NO);
if (dlg.ShowModal() == wxID_YES) { sync_printer_info = true; }
} else {
}
else {
sync_printer_info = wxGetApp().app_config->get("sync_after_load_file_show_flag") == "true";
}
if (sync_printer_info) {
@ -15405,8 +15402,9 @@ int Plater::select_sliced_plate(int plate_index)
return ret;
}
extern std::string object_limited_text;
extern std::string object_clashed_text;
extern std::string& get_object_limited_text();
extern std::string& get_object_clashed_text();
void Plater::validate_current_plate(bool& model_fits, bool& validate_error)
{
ObjectFilamentResults object_results;
@ -15451,17 +15449,17 @@ void Plater::validate_current_plate(bool& model_fits, bool& validate_error)
}
if (!model_fits) {
p->notification_manager->push_plater_error_notification(object_clashed_text);
p->notification_manager->push_plater_error_notification(get_object_clashed_text());
}
else {
p->notification_manager->close_plater_error_notification(object_clashed_text);
p->notification_manager->close_plater_error_notification(get_object_clashed_text());
}
if (state == ModelInstancePVS_Limited) {
p->notification_manager->push_plater_warning_notification(object_limited_text);
p->notification_manager->push_plater_warning_notification(get_object_limited_text());
}
else {
p->notification_manager->close_plater_warning_notification(object_limited_text);
p->notification_manager->close_plater_warning_notification(get_object_limited_text());
}
}

View File

@ -1243,8 +1243,9 @@ wxWindow* PreferencesDialog::create_general_page()
#endif
auto title_filament_group = create_item_title(_L("Filament Arrange"), page, _L("Filament Arrange"));
auto item_ignore_ext_filament = create_item_checkbox(_L("Ignore ext filament when auto grouping"), page, _L("Ignore ext filament when auto grouping"), 50, "ignore_ext_filament_when_group");
auto item_pop_up_filament_map_dialog = create_item_checkbox(_L("Pop up to select filament map mode"), page, _L("Pop up to select filament map mode"), 50, "pop_up_filament_map_dialog");
//temporarily disable it
//auto item_ignore_ext_filament = create_item_checkbox(_L("Ignore ext filament when auto grouping"), page, _L("Ignore ext filament when auto grouping"), 50, "ignore_ext_filament_when_group");
auto item_pop_up_filament_map_dialog = create_item_checkbox(_L("Pop up to select filament arrangement mode"), page, _L("Pop up to select filament arrangement mode"), 50, "pop_up_filament_map_dialog");
auto title_user_experience = create_item_title(_L("User Experience"), page, _L("User Experience"));
auto item_priv_policy = create_item_checkbox(_L("Join Customer Experience Improvement Program."), page, "", 50, "privacyuse");
@ -1317,7 +1318,7 @@ wxWindow* PreferencesDialog::create_general_page()
#endif
sizer_page->Add(title_filament_group, 0, wxTOP | wxEXPAND, FromDIP(20));
sizer_page->Add(item_ignore_ext_filament, 0, wxEXPAND, FromDIP(3));
//sizer_page->Add(item_ignore_ext_filament, 0, wxEXPAND, FromDIP(3));
sizer_page->Add(item_pop_up_filament_map_dialog, 0, wxEXPAND, FromDIP(3));
sizer_page->Add(title_user_experience, 0, wxTOP | wxEXPAND, FromDIP(20));