diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 74676c845f..369b9002c9 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -171,6 +171,8 @@ public: // This type is here to support PresetConfigSubstitutions for physical printers, however it does not belong to the Preset class, // PhysicalPrinter class is used instead. TYPE_PHYSICAL_PRINTER, + // BBS: plate config + TYPE_PLATE, // BBS: model config TYPE_MODEL, }; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index edf875bcbd..2796a18712 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -292,6 +292,13 @@ static const t_config_enum_values s_keys_map_BedType = { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(BedType) +// BBS +static const t_config_enum_values s_keys_map_FirstLayerSeq = { + { "Auto", flsAuto }, + { "Customize", flsCutomize }, +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FirstLayerSeq) + static t_config_enum_values s_keys_map_NozzleType { { "undefine", int(NozzleType::ntUndefine) }, { "hardened_steel", int(NozzleType::ntHardenedSteel) }, @@ -643,6 +650,18 @@ void PrintConfigDef::init_fff_params() def->max = 16; def->set_default_value(new ConfigOptionInts{0}); + def = this->add("first_layer_sequence_choice", coEnum); + def->category = L("Quality"); + def->label = L("First layer filament sequence"); + def->tooltip = L("test"); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("Auto"); + def->enum_values.push_back("Customize"); + def->enum_labels.push_back(L("Auto")); + def->enum_labels.push_back(L("Customize")); + def->mode = comSimple; + def->set_default_value(new ConfigOptionEnum(flsAuto)); + def = this->add("before_layer_change_gcode", coString); def->label = L("Before layer change G-code"); def->tooltip = L("This G-code is inserted at every layer change before lifting z"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 51d47db076..f4930fa989 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -201,6 +201,12 @@ enum BedType { btCount }; +// BBS +enum FirstLayerSeq { + flsAuto, + flsCutomize +}; + // BBS enum NozzleType { ntUndefine = 0, diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 53dd56fb9a..55492b08fa 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1341,7 +1341,7 @@ void Choice::set_value(const boost::any& value, bool change_event) if (m_opt_id.compare("host_type") == 0 && val != 0 && m_opt.enum_values.size() > field->GetCount()) // for case, when PrusaLink isn't used as a HostType val--; - if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "internal_solid_infill_pattern" || m_opt_id == "sparse_infill_pattern" || m_opt_id == "support_style") + if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "internal_solid_infill_pattern" || m_opt_id == "sparse_infill_pattern" || m_opt_id == "support_style" || m_opt_id == "curr_bed_type") { std::string key; const t_config_enum_values& map_names = *m_opt.enum_keys_map; @@ -1429,7 +1429,7 @@ boost::any& Choice::get_value() if (m_opt.nullable && field->GetSelection() == -1) m_value = ConfigOptionEnumsGenericNullable::nil_value(); else if (m_opt_id == "top_surface_pattern" || m_opt_id == "bottom_surface_pattern" || m_opt_id == "internal_solid_infill_pattern" || m_opt_id == "sparse_infill_pattern" || - m_opt_id == "support_style") { + m_opt_id == "support_style" || m_opt_id == "curr_bed_type") { const std::string& key = m_opt.enum_values[field->GetSelection()]; m_value = int(m_opt.enum_keys_map->at(key)); } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4c8d171378..fda7792a01 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -5097,6 +5097,11 @@ Tab* GUI_App::get_tab(Preset::Type type) return nullptr; } +Tab* GUI_App::get_plate_tab() +{ + return plate_tab; +} + Tab* GUI_App::get_model_tab(bool part) { return model_tabs_list[part ? 1 : 0]; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 819eaca2be..12e2f88378 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -471,6 +471,7 @@ public: bool load_language(wxString language, bool initial); Tab* get_tab(Preset::Type type); + Tab* get_plate_tab(); Tab* get_model_tab(bool part = false); Tab* get_layer_tab(); ConfigOptionMode get_mode(); @@ -573,6 +574,7 @@ public: std::vector tabs_list; std::vector model_tabs_list; + Tab* plate_tab; RemovableDriveManager* removable_drive_manager() { return m_removable_drive_manager.get(); } //OtherInstanceMessageHandler* other_instance_message_handler() { return m_other_instance_message_handler.get(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index aae75800d8..055bd317b6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1319,7 +1319,9 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me get_selected_item_indexes(obj_idx, vol_idx, item); //wxGetApp().plater()->PopupObjectTable(obj_idx, vol_idx, mouse_pos); - if (m_objects_model->GetItemType(item) & itLayer) + if (m_objects_model->GetItemType(item) & itPlate) + dynamic_cast(wxGetApp().get_plate_tab())->reset_model_config(); + else if (m_objects_model->GetItemType(item) & itLayer) dynamic_cast(wxGetApp().get_layer_tab())->reset_model_config(); else dynamic_cast(wxGetApp().get_model_tab(vol_idx >= 0))->reset_model_config(); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 90ea93094b..700f66676e 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -199,7 +199,9 @@ bool ObjectSettings::update_settings_list() wxDataViewItemArray items; objects_ctrl->GetSelections(items); - std::map object_configs; + std::map plate_configs; + std::map object_configs; + bool is_plate_settings = false; bool is_object_settings = false; bool is_volume_settings = false; bool is_layer_range_settings = false; @@ -207,6 +209,14 @@ bool ObjectSettings::update_settings_list() ModelObject * parent_object = nullptr; for (auto item : items) { auto type = objects_model->GetItemType(item); + if (type == itPlate) { + is_plate_settings = true; + + static ModelConfig cfg; + auto plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); + cfg.assign_config(*plate->config()); + plate_configs.emplace(plate, &cfg); + } if (type != itObject && type != itVolume && type != itLayerRoot && type != itLayer) { continue; } @@ -241,33 +251,45 @@ bool ObjectSettings::update_settings_list() } } + auto tab_plate = dynamic_cast(wxGetApp().get_plate_tab()); auto tab_object = dynamic_cast(wxGetApp().get_model_tab()); auto tab_volume = dynamic_cast(wxGetApp().get_model_tab(true)); auto tab_layer = dynamic_cast(wxGetApp().get_layer_tab()); - if (is_object_settings) { + if (is_plate_settings) { + tab_object->set_model_config({}); + tab_volume->set_model_config({}); + tab_layer->set_model_config({}); + tab_plate->set_model_config(plate_configs); + ;// m_tab_active = tab_plate; + } + else if (is_object_settings) { tab_object->set_model_config(object_configs); tab_volume->set_model_config({}); tab_layer->set_model_config({}); - m_tab_active = tab_object; + tab_plate->set_model_config({}); + //m_tab_active = tab_object; } else if (is_volume_settings) { tab_object->set_model_config({ {parent_object, &parent_object->config} }); tab_volume->set_model_config(object_configs); tab_layer->set_model_config({}); - m_tab_active = tab_volume; + tab_plate->set_model_config({}); + //m_tab_active = tab_volume; } else if (is_layer_range_settings) { tab_object->set_model_config({ {parent_object, &parent_object->config} }); tab_volume->set_model_config({}); tab_layer->set_model_config(object_configs); - m_tab_active = tab_layer; + tab_plate->set_model_config({}); + //m_tab_active = tab_layer; } else { tab_object->set_model_config({}); tab_volume->set_model_config({}); tab_layer->set_model_config({}); - m_tab_active = nullptr; + tab_plate->set_model_config({}); + //m_tab_active = nullptr; } ((ParamsPanel*) tab_object->GetParent())->set_active_tab(nullptr); return true; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 183dd6c0c8..852c0b1fbf 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1260,6 +1260,7 @@ void MainFrame::create_preset_tabs() m_param_dialog = new ParamsDialog(m_plater); add_created_tab(new TabPrint(m_param_panel), "cog"); + add_created_tab(new TabPrintPlate(m_param_panel), "cog"); add_created_tab(new TabPrintObject(m_param_panel), "cog"); add_created_tab(new TabPrintPart(m_param_panel), "cog"); add_created_tab(new TabPrintLayer(m_param_panel), "cog"); @@ -1279,6 +1280,10 @@ void MainFrame::add_created_tab(Tab* panel, const std::string& bmp_name /*= ""* { panel->create_preset_tab(); + if (panel->type() == Preset::TYPE_PLATE) { + wxGetApp().tabs_list.pop_back(); + wxGetApp().plate_tab = panel; + } // BBS: model config if (panel->type() == Preset::TYPE_MODEL) { wxGetApp().tabs_list.pop_back(); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 6352c9253a..577948f465 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -199,7 +199,7 @@ void ObjectDataViewModelNode::set_action_icon(bool enable) { m_action_enable = enable; auto undo = enable ? "lock_normal" : "dot"; - m_action_icon_name = m_type & itPlate ? "dot" : + m_action_icon_name = m_type & itPlate ? undo : m_type & itObject ? undo : m_type & (itVolume | itLayer) ? undo : /*m_type & itInstance*/ "set_separate_obj"; m_action_icon = create_scaled_bitmap(m_action_icon_name); // FIXME: pass window ptr diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 37254293c1..60b9ab0a0c 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1027,8 +1027,19 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = config.opt_int(opt_key, idx); break; case coEnum: + if (!config.has("first_layer_sequence_choice") && opt_key == "first_layer_sequence_choice") { + // reset to Auto value + ret = 0; + break; + } + if (!config.has("curr_bed_type") && opt_key == "curr_bed_type") { + // reset to global value + DynamicConfig& global_cfg = wxGetApp().preset_bundle->project_config; + ret = global_cfg.option("curr_bed_type")->getInt(); + break; + } ret = config.option(opt_key)->getInt(); - break; + break; // BBS case coEnums: ret = config.opt_int(opt_key, idx); diff --git a/src/slic3r/GUI/ParamsPanel.cpp b/src/slic3r/GUI/ParamsPanel.cpp index 3b0ef8921b..b0bb868255 100644 --- a/src/slic3r/GUI/ParamsPanel.cpp +++ b/src/slic3r/GUI/ParamsPanel.cpp @@ -390,6 +390,10 @@ void ParamsPanel::create_layout() m_left_sizer->Add( m_tab_print, 0, wxEXPAND ); } + if (m_tab_print_plate) { + m_left_sizer->Add(m_tab_print_plate, 0, wxEXPAND); + } + if (m_tab_print_object) { m_left_sizer->Add( m_tab_print_object, 0, wxEXPAND ); } @@ -480,6 +484,7 @@ void ParamsPanel::refresh_tabs() } } if (m_top_panel) { + m_tab_print_plate = wxGetApp().get_plate_tab(); m_tab_print_object = wxGetApp().get_model_tab(); m_tab_print_part = wxGetApp().get_model_tab(true); m_tab_print_layer = wxGetApp().get_layer_tab(); @@ -556,6 +561,8 @@ void ParamsPanel::set_active_tab(wxPanel* tab) cur_tab = (Tab*)m_tab_print_layer; } else if (m_tab_print_object && ((TabPrintModel*) m_tab_print_object)->has_model_config()) { cur_tab = (Tab*) m_tab_print_object; + } else if (m_tab_print_plate && ((TabPrintPlate*)m_tab_print_plate)->has_model_config()) { + cur_tab = (Tab*)m_tab_print_plate; } Show(cur_tab != nullptr); wxGetApp().sidebar().show_object_list(m_mode_region->GetValue()); @@ -576,6 +583,7 @@ void ParamsPanel::set_active_tab(wxPanel* tab) {m_tab_print_object, m_staticline_print_object}, {m_tab_print_part, m_staticline_print_part}, {m_tab_print_layer, nullptr}, + {m_tab_print_plate, nullptr}, {m_tab_filament, m_staticline_filament}, {m_tab_printer, m_staticline_printer}})) { if (!t.first) continue; @@ -639,7 +647,7 @@ void ParamsPanel::msw_rescale() ((SwitchButton* )m_mode_region)->Rescale(); if (m_mode_view) ((SwitchButton* )m_mode_view)->Rescale(); - for (auto tab : {m_tab_print, m_tab_print_object, m_tab_print_part, m_tab_print_layer, m_tab_filament, m_tab_printer}) { + for (auto tab : {m_tab_print, m_tab_print_plate, m_tab_print_object, m_tab_print_part, m_tab_print_layer, m_tab_filament, m_tab_printer}) { if (tab) dynamic_cast(tab)->msw_rescale(); } //((Button*)m_export_to_file)->Rescale(); diff --git a/src/slic3r/GUI/ParamsPanel.hpp b/src/slic3r/GUI/ParamsPanel.hpp index 7e752aa335..1a20ec7d20 100644 --- a/src/slic3r/GUI/ParamsPanel.hpp +++ b/src/slic3r/GUI/ParamsPanel.hpp @@ -90,6 +90,7 @@ class ParamsPanel : public wxPanel wxStaticLine* m_staticline_print { nullptr }; //wxBoxSizer* m_print_sizer { nullptr }; wxPanel* m_tab_print { nullptr }; + wxPanel* m_tab_print_plate { nullptr }; wxPanel* m_tab_print_object { nullptr }; wxStaticLine* m_staticline_print_object { nullptr }; wxPanel* m_tab_print_part { nullptr }; diff --git a/src/slic3r/GUI/PlateSettingsDialog.cpp b/src/slic3r/GUI/PlateSettingsDialog.cpp index 4c2edca145..e473e49921 100644 --- a/src/slic3r/GUI/PlateSettingsDialog.cpp +++ b/src/slic3r/GUI/PlateSettingsDialog.cpp @@ -5,8 +5,8 @@ namespace Slic3r { namespace GUI { wxDEFINE_EVENT(EVT_SET_BED_TYPE_CONFIRM, wxCommandEvent); -PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) -:DPIDialog(parent, id, title, pos, size, style) +PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, const wxString& title, bool only_first_layer_seq, const wxPoint& pos, const wxSize& size, long style) +:DPIDialog(parent, wxID_ANY, title, pos, size, style) { std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str(); SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); @@ -79,7 +79,7 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, wxWindowID id, const m_spiral_mode_choice->Append(_L("Enable")); m_spiral_mode_choice->Append(_L("Disable")); m_spiral_mode_choice->SetSelection(0); - wxStaticText* spiral_mode_txt = new wxStaticText(this, wxID_ANY, _L("Spiral Vase")); + wxStaticText* spiral_mode_txt = new wxStaticText(this, wxID_ANY, _L("Spiral vase")); spiral_mode_txt->SetFont(Label::Body_14); top_sizer->Add(spiral_mode_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5)); top_sizer->Add(m_spiral_mode_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5)); @@ -140,6 +140,18 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, wxWindowID id, const CenterOnParent(); wxGetApp().UpdateDlgDarkUI(this); + + if (only_first_layer_seq) { + for (auto item : top_sizer->GetChildren()) { + if (item->GetWindow()) + item->GetWindow()->Show(false); + } + first_layer_txt->Show(); + m_first_layer_print_seq_choice->Show(); + m_drag_canvas->Show(); + Layout(); + Fit(); + } } PlateSettingsDialog::~PlateSettingsDialog() diff --git a/src/slic3r/GUI/PlateSettingsDialog.hpp b/src/slic3r/GUI/PlateSettingsDialog.hpp index 6ce34f48c4..2ee3c55509 100644 --- a/src/slic3r/GUI/PlateSettingsDialog.hpp +++ b/src/slic3r/GUI/PlateSettingsDialog.hpp @@ -22,8 +22,8 @@ public: }; PlateSettingsDialog( wxWindow* parent, - wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, + bool only_first_layer_seq = false, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCLOSE_BOX | wxCAPTION diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ece8fc0c49..6ba3423ea8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -155,6 +155,7 @@ wxDEFINE_EVENT(EVT_EXPORT_FINISHED, wxCommandEvent); wxDEFINE_EVENT(EVT_IMPORT_MODEL_ID, wxCommandEvent); wxDEFINE_EVENT(EVT_DOWNLOAD_PROJECT, wxCommandEvent); wxDEFINE_EVENT(EVT_PUBLISH, wxCommandEvent); +wxDEFINE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent); // BBS: backup & restore wxDEFINE_EVENT(EVT_RESTORE_PROJECT, wxCommandEvent); wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent); @@ -2795,6 +2796,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) q->Bind(EVT_SEND_CALIBRATION_FINISHED, [q](wxCommandEvent& evt) { q->send_calibration_job_finished(evt); }); q->Bind(EVT_SEND_FINISHED, [q](wxCommandEvent &evt) { q->send_job_finished(evt); }); q->Bind(EVT_PUBLISH_FINISHED, [q](wxCommandEvent &evt) { q->publish_job_finished(evt);}); + q->Bind(EVT_OPEN_PLATESETTINGSDIALOG, [q](wxCommandEvent &evt) { q->open_platesettings_dialog(evt);}); //q->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); }); } @@ -12262,6 +12264,70 @@ void Plater::validate_current_plate(bool& model_fits, bool& validate_error) return; } +void Plater::open_platesettings_dialog(wxCommandEvent& evt) { + int plate_index = evt.GetInt(); + PlateSettingsDialog dlg(this, _L("Plate Settings"), evt.GetString() == "only_first_layer_sequence"); + PartPlate* curr_plate = p->partplate_list.get_curr_plate(); + dlg.sync_bed_type(curr_plate->get_bed_type()); + + auto curr_print_seq = curr_plate->get_print_seq(); + if (curr_print_seq != PrintSequence::ByDefault) { + dlg.sync_print_seq(int(curr_print_seq) + 1); + } + else + dlg.sync_print_seq(0); + + auto first_layer_print_seq = curr_plate->get_first_layer_print_sequence(); + if (first_layer_print_seq.empty()) + dlg.sync_first_layer_print_seq(0); + else + dlg.sync_first_layer_print_seq(1, curr_plate->get_first_layer_print_sequence()); + + dlg.sync_spiral_mode(curr_plate->get_spiral_vase_mode(), !curr_plate->has_spiral_mode_config()); + + dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent& e) { + PartPlate* curr_plate = p->partplate_list.get_curr_plate(); + BedType old_bed_type = curr_plate->get_bed_type(); + auto bt_sel = BedType(dlg.get_bed_type_choice()); + if (old_bed_type != bt_sel) { + curr_plate->set_bed_type(bt_sel); + update_project_dirty_from_presets(); + set_plater_dirty(true); + } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side") % bt_sel % plate_index; + + if (dlg.get_first_layer_print_seq_choice() != 0) + curr_plate->set_first_layer_print_sequence(dlg.get_first_layer_print_seq()); + else + curr_plate->set_first_layer_print_sequence({}); + + int ps_sel = dlg.get_print_seq_choice(); + if (ps_sel != 0) + curr_plate->set_print_seq(PrintSequence(ps_sel - 1)); + else + curr_plate->set_print_seq(PrintSequence::ByDefault); + + int spiral_sel = dlg.get_spiral_mode_choice(); + if (spiral_sel == 1) { + curr_plate->set_spiral_vase_mode(true, false); + } + else if (spiral_sel == 2) { + curr_plate->set_spiral_vase_mode(false, false); + } + else { + curr_plate->set_spiral_vase_mode(false, true); + } + + update_project_dirty_from_presets(); + set_plater_dirty(true); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select print sequence %1% for plate %2% at plate side") % ps_sel % plate_index; + auto plate_config = *(curr_plate->config()); + wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence")); + update(); + wxGetApp().obj_list()->update_selections(); + }); + dlg.ShowModal(); +} //BBS: select Plate by hover_id int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModidyPlateName) @@ -12403,64 +12469,10 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi //set the plate type ret = select_plate(plate_index); if (!ret) { - PlateSettingsDialog dlg(this, wxID_ANY, _L("Plate Settings")); - PartPlate* curr_plate = p->partplate_list.get_curr_plate(); - dlg.sync_bed_type(curr_plate->get_bed_type()); - - auto curr_print_seq = curr_plate->get_print_seq(); - if (curr_print_seq != PrintSequence::ByDefault) { - dlg.sync_print_seq(int(curr_print_seq) + 1); - } - else - dlg.sync_print_seq(0); - - auto first_layer_print_seq = curr_plate->get_first_layer_print_sequence(); - if (first_layer_print_seq.empty()) - dlg.sync_first_layer_print_seq(0); - else - dlg.sync_first_layer_print_seq(1, curr_plate->get_first_layer_print_sequence()); - - dlg.sync_spiral_mode(curr_plate->get_spiral_vase_mode(), !curr_plate->has_spiral_mode_config()); - - dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent& e) { - PartPlate *curr_plate = p->partplate_list.get_curr_plate(); - BedType old_bed_type = curr_plate->get_bed_type(); - auto bt_sel = BedType(dlg.get_bed_type_choice()); - if (old_bed_type != bt_sel) { - curr_plate->set_bed_type(bt_sel); - update_project_dirty_from_presets(); - set_plater_dirty(true); - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%bt_sel %plate_index; - - if (dlg.get_first_layer_print_seq_choice() != 0) - curr_plate->set_first_layer_print_sequence(dlg.get_first_layer_print_seq()); - else - curr_plate->set_first_layer_print_sequence({}); - - int ps_sel = dlg.get_print_seq_choice(); - if (ps_sel != 0) - curr_plate->set_print_seq(PrintSequence(ps_sel - 1)); - else - curr_plate->set_print_seq(PrintSequence::ByDefault); - - int spiral_sel = dlg.get_spiral_mode_choice(); - if (spiral_sel == 1) { - curr_plate->set_spiral_vase_mode(true, false); - }else if (spiral_sel == 2) { - curr_plate->set_spiral_vase_mode(false, false); - }else { - curr_plate->set_spiral_vase_mode(false, true); - } - - update_project_dirty_from_presets(); - set_plater_dirty(true); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select print sequence %1% for plate %2% at plate side")%ps_sel %plate_index; - auto plate_config = *(curr_plate->config()); - wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence")); - update(); - }); - dlg.ShowModal(); + wxCommandEvent evt(EVT_OPEN_PLATESETTINGSDIALOG); + evt.SetInt(plate_index); + evt.SetEventObject(this); + wxPostEvent(this, evt); this->schedule_background_process(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index e6b30559ab..a70bd2d22e 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -87,6 +87,7 @@ enum class ActionButtonType : int; //BBS: add EVT_SLICING_UPDATE declare here wxDECLARE_EVENT(EVT_SLICING_UPDATE, Slic3r::SlicingStatusEvent); wxDECLARE_EVENT(EVT_PUBLISH, wxCommandEvent); +wxDECLARE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent); wxDECLARE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent); wxDECLARE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent); wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent); @@ -373,6 +374,7 @@ public: void print_job_finished(wxCommandEvent &evt); void send_job_finished(wxCommandEvent& evt); void publish_job_finished(wxCommandEvent& evt); + void open_platesettings_dialog(wxCommandEvent& evt); void on_change_color_mode(SimpleEvent& evt); void eject_drive(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index adb961a966..a7ecec0e50 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1826,6 +1826,7 @@ void Tab::update_frequently_changed_parameters() update_wiping_button_visibility(); } } + //BBS: BBS new parameter list void TabPrint::build() { @@ -2304,6 +2305,33 @@ void TabPrintModel::update_model_config() // except those than all equal on m_config->apply_only(local_config, local_keys); m_config_manipulation.apply_null_fff_config(m_config, m_null_keys, m_object_configs); + + if (m_type == Preset::Type::TYPE_PLATE) { + // Reset m_config manually because there's no corresponding config in m_parent_tab->m_config + for (auto plate_item : m_object_configs) { + const DynamicPrintConfig& plate_config = plate_item.second->get(); + BedType plate_bed_type = (BedType)0; + PrintSequence plate_print_seq = (PrintSequence)0; + if (!plate_config.has("curr_bed_type")) { + // same as global + DynamicConfig& global_cfg = wxGetApp().preset_bundle->project_config; + if (global_cfg.has("curr_bed_type")) { + BedType global_bed_type = global_cfg.opt_enum("curr_bed_type"); + m_config->set_key_value("curr_bed_type", new ConfigOptionEnum(global_bed_type)); + } + } + if (!plate_config.has("first_layer_print_sequence")) { + // same as global + m_config->set_key_value("first_layer_sequence_choice", new ConfigOptionEnum(flsAuto)); + } + else { + replace(m_all_keys.begin(), m_all_keys.end(), std::string("first_layer_print_sequence"), std::string("first_layer_sequence_choice")); + m_config->set_key_value("first_layer_sequence_choice", new ConfigOptionEnum(flsCutomize)); + } + notify_changed(plate_item.first); + } + } + } toggle_options(); if (m_active_page) @@ -2424,6 +2452,178 @@ void TabPrintModel::update_custom_dirty() } //BBS: GUI refactor +static const std::vector plate_keys = { "curr_bed_type", "first_layer_print_sequence", "first_layer_sequence_choice", "print_sequence", "spiral_mode"}; +TabPrintPlate::TabPrintPlate(ParamsPanel* parent) : + TabPrintModel(parent, plate_keys) +{ + m_parent_tab = wxGetApp().get_tab(Preset::TYPE_PRINT); + m_type = Preset::TYPE_PLATE; + m_keys = concat(m_keys, plate_keys); +} + +void TabPrintPlate::build() +{ + m_presets = &m_prints; + load_initial_data(); + + m_config->option("curr_bed_type", true); + if (m_preset_bundle->project_config.has("curr_bed_type")) { + BedType global_bed_type = m_preset_bundle->project_config.opt_enum("curr_bed_type"); + global_bed_type = BedType(global_bed_type - 1); + m_config->set_key_value("curr_bed_type", new ConfigOptionEnum(global_bed_type)); + } + m_config->option("first_layer_sequence_choice", true); + m_config->option("first_layer_print_sequence", true); + + auto page = add_options_page(L("Plate Settings"), ""); + auto optgroup = page->new_optgroup(""); + optgroup->append_single_option_line("curr_bed_type"); + optgroup->append_single_option_line("print_sequence"); + optgroup->append_single_option_line("first_layer_sequence_choice"); + optgroup->append_single_option_line("spiral_mode"); + for (auto& line : const_cast&>(optgroup->get_lines())) { + line.undo_to_sys = true; + } + optgroup->have_sys_config = [this] { m_back_to_sys = true; return true; }; +} + +void TabPrintPlate::reset_model_config() +{ + if (m_object_configs.empty()) return; + wxGetApp().plater()->take_snapshot(std::string("Reset Options")); + for (auto plate_item : m_object_configs) { + auto rmkeys = intersect(m_keys, plate_item.second->keys()); + for (auto& k : rmkeys) { + plate_item.second->erase(k); + } + auto plate = dynamic_cast(plate_item.first); + plate->reset_bed_type(); + plate->set_print_seq(PrintSequence::ByDefault); + plate->set_first_layer_print_sequence({}); + plate->set_spiral_vase_mode(false, true); + notify_changed(plate_item.first); + } + update_model_config(); + wxGetApp().mainframe->on_config_changed(m_config); +} + +void TabPrintPlate::on_value_change(const std::string& opt_key, const boost::any& value) +{ + auto k = opt_key; + if (m_config_manipulation.is_applying()) { + return; + } + if (!has_key(k)) + return; + if (!m_object_configs.empty()) + wxGetApp().plater()->take_snapshot((boost::format("Change Option %s") % k).str()); + bool set = true; + if (m_back_to_sys) { + for (auto plate_item : m_object_configs) { + plate_item.second->erase(k); + auto plate = dynamic_cast(plate_item.first); + if (k == "curr_bed_type") + plate->reset_bed_type(); + if (k == "print_sequence") + plate->set_print_seq(PrintSequence::ByDefault); + if (k == "first_layer_sequence_choice") + plate->set_first_layer_print_sequence({}); + if (k == "spiral_mode") + plate->set_spiral_vase_mode(false, true); + } + m_all_keys.erase(std::remove(m_all_keys.begin(), m_all_keys.end(), k), m_all_keys.end()); + } + else if (set) { + for (auto plate_item : m_object_configs) { + plate_item.second->apply_only(*m_config, { k }); + auto plate = dynamic_cast(plate_item.first); + BedType bed_type; + PrintSequence print_seq; + FirstLayerSeq first_layer_seq_choice; + if (k == "curr_bed_type") { + bed_type = m_config->opt_enum("curr_bed_type"); + plate->set_bed_type(BedType(bed_type)); + } + if (k == "print_sequence") { + print_seq = m_config->opt_enum("print_sequence"); + plate->set_print_seq(print_seq); + } + if (k == "first_layer_sequence_choice") { + first_layer_seq_choice = m_config->opt_enum("first_layer_sequence_choice"); + if (first_layer_seq_choice == FirstLayerSeq::flsAuto) { + plate->set_first_layer_print_sequence({}); + } + else if (first_layer_seq_choice == FirstLayerSeq::flsCutomize) { + const DynamicPrintConfig& plate_config = plate_item.second->get(); + if (!plate_config.has("first_layer_print_sequence")) { + std::vector initial_sequence; + for (int i = 0; i < wxGetApp().filaments_cnt(); i++) { + initial_sequence.push_back(i + 1); + } + plate->set_first_layer_print_sequence(initial_sequence); + } + wxCommandEvent evt(EVT_OPEN_PLATESETTINGSDIALOG); + evt.SetInt(plate->get_index()); + evt.SetString("only_first_layer_sequence"); + evt.SetEventObject(wxGetApp().plater()); + //wxGetApp().plater()->GetEventHandler()->ProcessEvent(evt); + wxPostEvent(wxGetApp().plater(), evt); + } + } + if (k == "spiral_mode") { + plate->set_spiral_vase_mode(m_config->opt_bool("spiral_mode"), false); + } + } + m_all_keys = concat(m_all_keys, { k }); + } + if (m_back_to_sys || set) update_changed_ui(); + m_back_to_sys = false; + for (auto plate_item : m_object_configs) { + plate_item.second->touch(); + notify_changed(plate_item.first); + } + + wxGetApp().params_panel()->notify_object_config_changed(); + update(); +} + +void TabPrintPlate::notify_changed(ObjectBase* object) +{ + auto plate = dynamic_cast(object); + auto objects_list = wxGetApp().obj_list(); + wxDataViewItemArray items; + objects_list->GetSelections(items); + for (auto item : items) { + if (objects_list->GetModel()->GetItemType(item) == itPlate) { + ObjectDataViewModelNode* node = static_cast(item.GetID()); + if (node) + node->set_action_icon(!m_all_keys.empty()); + } + } +} + +void TabPrintPlate::update_custom_dirty() +{ + for (auto k : m_null_keys) + m_options_list[k] = 0; + for (auto k : m_all_keys) { + if (k == "first_layer_sequence_choice") { + if (m_config->opt_enum("first_layer_sequence_choice") != FirstLayerSeq::flsAuto) { + m_options_list[k] &= ~osInitValue; + } + } + if (k == "curr_bed_type") { + DynamicConfig& global_cfg = wxGetApp().preset_bundle->project_config; + if (global_cfg.has("curr_bed_type")) { + BedType global_bed_type = global_cfg.opt_enum("curr_bed_type"); + if (m_config->opt_enum("curr_bed_type") != global_bed_type) { + m_options_list[k] &= ~osInitValue; + } + } + } + m_options_list[k] &= ~osSystemValue; + } +} TabPrintObject::TabPrintObject(ParamsPanel* parent) : TabPrintModel(parent, concat(PrintObjectConfig().keys(), PrintRegionConfig().keys())) diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 4833ba3759..2017c7046d 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -477,7 +477,7 @@ protected: virtual void update_custom_dirty() override; protected: - std::vector const m_keys; + std::vector m_keys; PresetCollection m_prints; Tab * m_parent_tab; std::map m_object_configs; @@ -486,6 +486,22 @@ protected: bool m_back_to_sys = false; }; + +class TabPrintPlate : public TabPrintModel +{ +public: + //BBS: GUI refactor + TabPrintPlate(ParamsPanel* parent); + ~TabPrintPlate() {} + void build() override; + void reset_model_config() override; + +protected: + virtual void on_value_change(const std::string& opt_key, const boost::any& value) override; + virtual void notify_changed(ObjectBase* object) override; + virtual void update_custom_dirty() override; +}; + class TabPrintObject : public TabPrintModel { public: