diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 5dbe8574b3..315965a65d 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1114,6 +1114,13 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* if (layer_height > min_nozzle_diameter) return {L("Layer height cannot exceed nozzle diameter"), object, "layer_height"}; + for (auto range : object->m_model_object->layer_config_ranges) { + double range_layer_height = range.second.opt_float("layer_height"); + if (range_layer_height > object->m_slicing_params.max_layer_height || + range_layer_height < object->m_slicing_params.min_layer_height) + return { L("Layer height cannot exceed nozzle diameter"), nullptr, "layer_height" }; + } + // Validate extrusion widths. std::string err_msg; if (!validate_extrusion_width(object->config(), "line_width", layer_height, err_msg)) diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 79a9143eac..45e0dd932c 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -168,6 +168,8 @@ static bool layer_height_ranges_equal(const t_layer_config_ranges &lr1, const t_ auto it2 = lr2.begin(); for (const auto &kvp1 : lr1) { const auto &kvp2 = *it2 ++; + if (!kvp2.second.has("layer_height") || !kvp1.second.has("layer_height")) + return false; if (std::abs(kvp1.first.first - kvp2.first.first ) > EPSILON || std::abs(kvp1.first.second - kvp2.first.second) > EPSILON || (check_layer_height && std::abs(kvp1.second.option("layer_height")->getFloat() - kvp2.second.option("layer_height")->getFloat()) > EPSILON)) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e83c91a6ef..22808f1b42 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -702,58 +702,58 @@ PRINT_CONFIG_CLASS_DEFINE( PRINT_CONFIG_CLASS_DEFINE( PrintRegionConfig, - ((ConfigOptionInt, bottom_shell_layers)) - ((ConfigOptionFloat, bottom_shell_thickness)) - ((ConfigOptionFloat, bridge_angle)) - ((ConfigOptionFloat, bridge_flow)) - ((ConfigOptionFloat, bridge_speed)) - ((ConfigOptionBool, ensure_vertical_shell_thickness)) - ((ConfigOptionEnum, top_surface_pattern)) - ((ConfigOptionEnum, bottom_surface_pattern)) - ((ConfigOptionFloat, outer_wall_line_width)) - ((ConfigOptionFloat, outer_wall_speed)) - ((ConfigOptionFloat, infill_direction)) - ((ConfigOptionPercent, sparse_infill_density)) - ((ConfigOptionEnum, sparse_infill_pattern)) - ((ConfigOptionEnum, fuzzy_skin)) - ((ConfigOptionFloat, fuzzy_skin_thickness)) - ((ConfigOptionFloat, fuzzy_skin_point_distance)) - ((ConfigOptionFloat, gap_infill_speed)) - ((ConfigOptionInt, sparse_infill_filament)) - ((ConfigOptionFloat, sparse_infill_line_width)) - ((ConfigOptionPercent, infill_wall_overlap)) - ((ConfigOptionFloat, sparse_infill_speed)) + ((ConfigOptionInt, bottom_shell_layers)) + ((ConfigOptionFloat, bottom_shell_thickness)) + ((ConfigOptionFloat, bridge_angle)) + ((ConfigOptionFloat, bridge_flow)) + ((ConfigOptionFloat, bridge_speed)) + ((ConfigOptionBool, ensure_vertical_shell_thickness)) + ((ConfigOptionEnum, top_surface_pattern)) + ((ConfigOptionEnum, bottom_surface_pattern)) + ((ConfigOptionFloat, outer_wall_line_width)) + ((ConfigOptionFloat, outer_wall_speed)) + ((ConfigOptionFloat, infill_direction)) + ((ConfigOptionPercent, sparse_infill_density)) + ((ConfigOptionEnum, sparse_infill_pattern)) + ((ConfigOptionEnum, fuzzy_skin)) + ((ConfigOptionFloat, fuzzy_skin_thickness)) + ((ConfigOptionFloat, fuzzy_skin_point_distance)) + ((ConfigOptionFloat, gap_infill_speed)) + ((ConfigOptionInt, sparse_infill_filament)) + ((ConfigOptionFloat, sparse_infill_line_width)) + ((ConfigOptionPercent, infill_wall_overlap)) + ((ConfigOptionFloat, sparse_infill_speed)) //BBS - ((ConfigOptionBool, infill_combination)) + ((ConfigOptionBool, infill_combination)) // Ironing options - ((ConfigOptionEnum, ironing_type)) - ((ConfigOptionPercent, ironing_flow)) - ((ConfigOptionFloat, ironing_spacing)) - ((ConfigOptionFloat, ironing_speed)) + ((ConfigOptionEnum, ironing_type)) + ((ConfigOptionPercent, ironing_flow)) + ((ConfigOptionFloat, ironing_spacing)) + ((ConfigOptionFloat, ironing_speed)) // Detect bridging perimeters - ((ConfigOptionBool, detect_overhang_wall)) - ((ConfigOptionInt, wall_filament)) - ((ConfigOptionFloat, inner_wall_line_width)) - ((ConfigOptionFloat, inner_wall_speed)) + ((ConfigOptionBool, detect_overhang_wall)) + ((ConfigOptionInt, wall_filament)) + ((ConfigOptionFloat, inner_wall_line_width)) + ((ConfigOptionFloat, inner_wall_speed)) // Total number of perimeters. - ((ConfigOptionInt, wall_loops)) - ((ConfigOptionFloat, minimum_sparse_infill_area)) - ((ConfigOptionInt, solid_infill_filament)) - ((ConfigOptionFloat, internal_solid_infill_line_width)) - ((ConfigOptionFloat, internal_solid_infill_speed)) + ((ConfigOptionInt, wall_loops)) + ((ConfigOptionFloat, minimum_sparse_infill_area)) + ((ConfigOptionInt, solid_infill_filament)) + ((ConfigOptionFloat, internal_solid_infill_line_width)) + ((ConfigOptionFloat, internal_solid_infill_speed)) // Detect thin walls. - ((ConfigOptionBool, detect_thin_wall)) - ((ConfigOptionFloat, top_surface_line_width)) - ((ConfigOptionInt, top_shell_layers)) - ((ConfigOptionFloat, top_shell_thickness)) - ((ConfigOptionFloat, top_surface_speed)) + ((ConfigOptionBool, detect_thin_wall)) + ((ConfigOptionFloat, top_surface_line_width)) + ((ConfigOptionInt, top_shell_layers)) + ((ConfigOptionFloat, top_shell_thickness)) + ((ConfigOptionFloat, top_surface_speed)) //BBS - ((ConfigOptionBool, enable_overhang_speed)) - ((ConfigOptionFloat, overhang_1_4_speed)) - ((ConfigOptionFloat, overhang_2_4_speed)) - ((ConfigOptionFloat, overhang_3_4_speed)) - ((ConfigOptionFloat, overhang_4_4_speed)) - ((ConfigOptionBool, only_one_wall_top)) + ((ConfigOptionBool, enable_overhang_speed)) + ((ConfigOptionFloat, overhang_1_4_speed)) + ((ConfigOptionFloat, overhang_2_4_speed)) + ((ConfigOptionFloat, overhang_3_4_speed)) + ((ConfigOptionFloat, overhang_4_4_speed)) + ((ConfigOptionBool, only_one_wall_top)) ) PRINT_CONFIG_CLASS_DEFINE( diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f33eb3df15..46d1a87da3 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -195,6 +195,8 @@ set(SLIC3R_GUI_SOURCES GUI/GUI_Factories.hpp GUI/GUI_ObjectList.cpp GUI/GUI_ObjectList.hpp + GUI/GUI_ObjectLayers.cpp + GUI/GUI_ObjectLayers.hpp GUI/GUI_AuxiliaryList.cpp GUI/GUI_AuxiliaryList.hpp GUI/GUI_ObjectSettings.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 71014054b2..c31ca9bc69 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4760,6 +4760,7 @@ void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool foc void GLCanvas3D::handle_layers_data_focus_event(const t_layer_height_range range, const EditorType type) { std::string field = "layer_" + std::to_string(type) + "_" + std::to_string(range.first) + "_" + std::to_string(range.second); + m_gizmos.reset_all_states(); handle_sidebar_focus_event(field, true); } @@ -8063,8 +8064,7 @@ void GLCanvas3D::_render_sla_slices() void GLCanvas3D::_render_selection_sidebar_hints() const { - //BBS do not render sidebar hints - //m_selection.render_sidebar_hints(m_sidebar_field, m_gizmos.get_uniform_scaling()); + m_selection.render_sidebar_hints(m_sidebar_field, m_gizmos.get_uniform_scaling()); } void GLCanvas3D::_update_volumes_hover_state() diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 316e07038a..bbeca86a3d 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -4908,6 +4908,11 @@ Tab* GUI_App::get_model_tab(bool part) return model_tabs_list[part ? 1 : 0]; } +Tab* GUI_App::get_layer_tab() +{ + return model_tabs_list[2]; +} + ConfigOptionMode GUI_App::get_mode() { if (!app_config->has("user_mode")) @@ -5604,6 +5609,11 @@ ObjectList* GUI_App::obj_list() return sidebar().obj_list(); } +ObjectLayers* GUI_App::obj_layers() +{ + return sidebar().obj_layers(); +} + Plater* GUI_App::plater() { return plater_; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 51b85bd0b0..62803cb003 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -66,6 +66,7 @@ class MainFrame; class Sidebar; class ObjectSettings; class ObjectList; +class ObjectLayers; class Plater; class ParamsPanel; class NotificationManager; @@ -455,6 +456,7 @@ public: Tab* get_tab(Preset::Type type); Tab* get_model_tab(bool part = false); + Tab* get_layer_tab(); ConfigOptionMode get_mode(); void save_mode(const /*ConfigOptionMode*/int mode) ; void update_mode(); @@ -502,6 +504,7 @@ public: Sidebar& sidebar(); ObjectSettings* obj_settings(); ObjectList* obj_list(); + ObjectLayers* obj_layers(); Plater* plater(); const Plater* plater() const; ParamsPanel* params_panel(); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 288fd9ada3..a54a84c270 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -18,6 +18,7 @@ #include #include "slic3r/Utils/FixModelByWin10.hpp" +#include "ParamsPanel.hpp" namespace Slic3r { @@ -200,7 +201,7 @@ std::map> SettingsFactory::get_all_v } -SettingsFactory::Bundle SettingsFactory::get_bundle(const DynamicPrintConfig* config, bool is_object_settings) +SettingsFactory::Bundle SettingsFactory::get_bundle(const DynamicPrintConfig* config, bool is_object_settings, bool is_layer_settings/* = false*/) { auto opt_keys = config->keys(); if (opt_keys.empty()) @@ -208,6 +209,8 @@ SettingsFactory::Bundle SettingsFactory::get_bundle(const DynamicPrintConfig* co // update options list according to print technology auto full_current_opts = get_options(!is_object_settings); + if (is_layer_settings) + full_current_opts.push_back("layer_height"); for (int i = opt_keys.size() - 1; i >= 0; --i) if (find(full_current_opts.begin(), full_current_opts.end(), opt_keys[i]) == full_current_opts.end()) opt_keys.erase(opt_keys.begin() + i); @@ -506,6 +509,15 @@ void MenuFactory::append_menu_items_add_volume(wxMenu* menu) append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second, []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); } + + append_menu_item_layers_editing(menu); +} + +wxMenuItem* MenuFactory::append_menu_item_layers_editing(wxMenu* menu) +{ + return append_menu_item(menu, wxID_ANY, _L("Height range Modifier"), "", + [](wxCommandEvent&) { obj_list()->layers_editing(); wxGetApp().params_panel()->switch_to_object(); }, "", menu, + []() { return obj_list()->is_instance_or_object_selected(); }, m_parent); } wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_) @@ -549,7 +561,7 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_) if (printer_technology() == ptFFF || (menu->GetMenuItems().size() > 0 && !menu->GetMenuItems().back()->IsSeparator())) - menu->SetFirstSeparator(); + ;// menu->SetFirstSeparator(); // detect itemm for adding of the setting ObjectList* object_list = obj_list(); @@ -573,7 +585,7 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_) // BBS remvoe freq setting popupmenu // create_freq_settings_popupmenu(menu, is_object_settings, item); - menu->SetSecondSeparator(); + //menu->SetSecondSeparator(); // Add full settings list auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name); diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp index 8e2814b572..3d99a072bd 100644 --- a/src/slic3r/GUI/GUI_Factories.hpp +++ b/src/slic3r/GUI/GUI_Factories.hpp @@ -37,7 +37,7 @@ struct SettingsFactory static std::map> PART_CATEGORY_SETTINGS; static wxBitmap get_category_bitmap(const std::string& category_name, bool menu_bmp = true); - static Bundle get_bundle(const DynamicPrintConfig* config, bool is_object_settings); + static Bundle get_bundle(const DynamicPrintConfig* config, bool is_object_settings, bool is_layer_settings = false); static std::vector get_options(bool is_part); //BBS: add api to get options for catogary static std::vector get_visible_options(const std::string& category, const bool is_part); @@ -115,6 +115,7 @@ private: wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type); void append_menu_items_add_volume(wxMenu* menu); + wxMenuItem* append_menu_item_layers_editing(wxMenu* menu); wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu); diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index a1e4f09c2c..4dc2a2e77b 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -22,24 +22,15 @@ namespace GUI ObjectLayers::ObjectLayers(wxWindow* parent) : OG_Settings(parent, true) { - m_grid_sizer = new wxFlexGridSizer(3, 5, wxGetApp().em_unit()); // "Min Z", "Max Z", "Layer height" & buttons sizer + m_grid_sizer = new wxFlexGridSizer(3, 0, wxGetApp().em_unit()); // "Min Z", "Max Z", "Layer height" & buttons sizer m_grid_sizer->SetFlexibleDirection(wxHORIZONTAL); - // Legend for object layers - for (const std::string col : { L("From height"), L("To height"), L("Layer height") }) { - auto temp = new wxStaticText(m_parent, wxID_ANY, _(col), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); - temp->SetFont(wxGetApp().bold_font()); - - m_grid_sizer->Add(temp); - } - m_og->activate(); m_og->sizer->Clear(true); - m_og->sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX ? 0 : 5); + m_og->sizer->Add(m_grid_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, wxOSX ? 0 : 5); - m_bmp_delete = ScalableBitmap(parent, "remove_copies"/*"cross"*/); - m_bmp_add = ScalableBitmap(parent, "add_copies"); + m_bmp_delete = ScalableBitmap(parent, "delete_filament"/*"cross"*/); + m_bmp_add = ScalableBitmap(parent, "add_filament"); } void ObjectLayers::select_editor(LayerRangeEditor* editor, const bool is_last_edited_range) @@ -80,6 +71,12 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus m_selection_type = type; }; + // Add text + auto head_text = new wxStaticText(m_parent, wxID_ANY, _L("Height Range"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + head_text->SetBackgroundStyle(wxBG_STYLE_PAINT); + head_text->SetFont(wxGetApp().normal_font()); + m_grid_sizer->Add(head_text, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit()); + // Add control for the "Min Z" auto editor = new LayerRangeEditor(this, double_to_string(range.first), etMinZ, set_focus_data, @@ -103,7 +100,15 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus }); select_editor(editor, is_last_edited_range); - m_grid_sizer->Add(editor); + + auto sizer1 = new wxBoxSizer(wxHORIZONTAL); + sizer1->Add(editor); + auto middle_text = new wxStaticText(m_parent, wxID_ANY, _L("to"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + middle_text->SetBackgroundStyle(wxBG_STYLE_PAINT); + middle_text->SetFont(wxGetApp().normal_font()); + sizer1->Add(middle_text, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit()); + + m_grid_sizer->Add(sizer1); // Add control for the "Max Z" @@ -127,29 +132,38 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus }); select_editor(editor, is_last_edited_range); - m_grid_sizer->Add(editor); + auto sizer2 = new wxBoxSizer(wxHORIZONTAL); + sizer2->Add(editor); + auto unit_text = new wxStaticText(m_parent, wxID_ANY, _L("mm"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + unit_text->SetBackgroundStyle(wxBG_STYLE_PAINT); + unit_text->SetFont(wxGetApp().normal_font()); + sizer2->Add(unit_text, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit()); + + m_grid_sizer->Add(sizer2); + + // BBS // Add control for the "Layer height" - editor = new LayerRangeEditor(this, double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), etLayerHeight, set_focus_data, - [range](coordf_t layer_height, bool, bool) - { - return wxGetApp().obj_list()->edit_layer_range(range, layer_height); - }); + //editor = new LayerRangeEditor(this, double_to_string(m_object->layer_config_ranges[range].option("layer_height")->getFloat()), etLayerHeight, set_focus_data, + // [range](coordf_t layer_height, bool, bool) + //{ + // return wxGetApp().obj_list()->edit_layer_range(range, layer_height); + //}); - select_editor(editor, is_last_edited_range); + //select_editor(editor, is_last_edited_range); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(editor); + //auto sizer = new wxBoxSizer(wxHORIZONTAL); + //sizer->Add(editor); - auto temp = new wxStaticText(m_parent, wxID_ANY, _L("mm")); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); - temp->SetFont(wxGetApp().normal_font()); - sizer->Add(temp, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit()); + //auto temp = new wxStaticText(m_parent, wxID_ANY, _L("mm")); + //temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + //temp->SetFont(wxGetApp().normal_font()); + //sizer->Add(temp, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit()); - m_grid_sizer->Add(sizer); + //m_grid_sizer->Add(sizer); - return sizer; + return sizer2; } void ObjectLayers::create_layers_list() @@ -157,9 +171,11 @@ void ObjectLayers::create_layers_list() for (const auto &layer : m_object->layer_config_ranges) { const t_layer_height_range& range = layer.first; auto del_btn = new PlusMinusButton(m_parent, m_bmp_delete, range); + del_btn->SetBackgroundColour(m_parent->GetBackgroundColour()); del_btn->SetToolTip(_L("Remove height range")); auto add_btn = new PlusMinusButton(m_parent, m_bmp_add, range); + add_btn->SetBackgroundColour(m_parent->GetBackgroundColour()); wxString tooltip = wxGetApp().obj_list()->can_add_new_range_after_current(range); add_btn->SetToolTip(tooltip.IsEmpty() ? _L("Add height range") : tooltip); add_btn->Enable(tooltip.IsEmpty()); @@ -195,18 +211,8 @@ void ObjectLayers::update_layers_list() m_object = objects_ctrl->object(obj_idx); if (!m_object || m_object->layer_config_ranges.empty()) return; - // Delete all controls from options group except of the legends - - const int cols = m_grid_sizer->GetEffectiveColsCount(); - const int rows = m_grid_sizer->GetEffectiveRowsCount(); - for (int idx = cols*rows-1; idx >= cols; idx--) { - wxSizerItem* t = m_grid_sizer->GetItem(idx); - if (t->IsSizer()) - t->GetSizer()->Clear(true); - else - t->DeleteWindows(); - m_grid_sizer->Remove(idx); - } + // Delete all controls from options group + m_grid_sizer->Clear(true); // Add new control according to the selected item diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 76d968cdfc..d15a60afed 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -946,15 +946,13 @@ void ObjectList::selection_changed() const ItemType type = m_objects_model->GetItemType(item); // to correct visual hints for layers editing on the Scene if (type & (itLayer|itLayerRoot)) { - //BBS remove obj_layers - // wxGetApp().obj_layers()->reset_selection(); + wxGetApp().obj_layers()->reset_selection(); if (type & itLayerRoot) wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); else { - //BBS remove obj_layers - //wxGetApp().obj_layers()->set_selectable_range(m_objects_model->GetLayerRangeByItem(item)); - //wxGetApp().obj_layers()->update_scene_from_editor_selection(); + wxGetApp().obj_layers()->set_selectable_range(m_objects_model->GetLayerRangeByItem(item)); + wxGetApp().obj_layers()->update_scene_from_editor_selection(); } } } @@ -1221,7 +1219,10 @@ 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); - dynamic_cast(wxGetApp().get_model_tab(vol_idx >= 0))->reset_model_config(); + 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(); } else if (col_num == colName) { @@ -2865,8 +2866,7 @@ void ObjectList::layers_editing() return; // to correct visual hints for layers editing on the Scene, reset previous selection - //BBS remove obj_layers - //wxGetApp().obj_layers()->reset_selection(); + wxGetApp().obj_layers()->reset_selection(); wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); // select LayerRoor item and expand @@ -3268,7 +3268,14 @@ void ObjectList::part_selection_changed() m_config = &(*m_objects)[obj_idx]->config; disable_ss_manipulation = (*m_objects)[obj_idx]->is_cut(); } - // BBS: remove height range logics + else if (type & (itLayerRoot | itLayer)) { + og_name = type & itLayerRoot ? _L("Height ranges") : _L("Settings for height range"); + update_and_show_layers = true; + update_and_show_settings = true; + + if (type & itLayer) + m_config = &get_item_config(item); + } } } } @@ -3300,8 +3307,7 @@ void ObjectList::part_selection_changed() if (printer_technology() == ptSLA) update_and_show_layers = false; else if (update_and_show_layers) { - //BBS remove obj layers - //wxGetApp().obj_layers()->get_og()->set_name(" "); + ;//wxGetApp().obj_layers()->get_og()->set_name(" " + og_name + " "); } update_min_height(); @@ -3313,8 +3319,7 @@ void ObjectList::part_selection_changed() // BBS //wxGetApp().obj_manipul() ->UpdateAndShow(update_and_show_manipulations); wxGetApp().obj_settings()->UpdateAndShow(update_and_show_settings); - //BBS - //wxGetApp().obj_layers() ->UpdateAndShow(update_and_show_layers); + wxGetApp().obj_layers() ->UpdateAndShow(update_and_show_layers); wxGetApp().plater()->show_object_info(); panel.Layout(); @@ -3330,13 +3335,33 @@ wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const D return ret; const bool is_object_settings = m_objects_model->GetItemType(parent_item) == itObject; + const bool is_volume_settings = m_objects_model->GetItemType(parent_item) == itVolume; + const bool is_layer_settings = m_objects_model->GetItemType(parent_item) == itLayer; if (!is_object_settings) { ModelVolumeType volume_type = m_objects_model->GetVolumeType(parent_item); if (volume_type == ModelVolumeType::NEGATIVE_VOLUME || volume_type == ModelVolumeType::SUPPORT_BLOCKER || volume_type == ModelVolumeType::SUPPORT_ENFORCER) return ret; } - SettingsFactory::Bundle cat_options = SettingsFactory::get_bundle(config, is_object_settings); + SettingsFactory::Bundle cat_options = SettingsFactory::get_bundle(config, is_object_settings, is_layer_settings); + if (is_layer_settings) { + auto tab_object = dynamic_cast(wxGetApp().get_model_tab()); + auto object_cfg = tab_object->get_config(); + if (config->opt_float("layer_height") == object_cfg->opt_float("layer_height")) { + SettingsFactory::Bundle new_cat_options; + for (auto cat_opt : cat_options) { + std::vector temp; + for (auto value : cat_opt.second) { + if (value != "layer_height") + temp.push_back(value); + } + if (!temp.empty()) + new_cat_options[cat_opt.first] = temp; + } + cat_options = new_cat_options; + } + } + if (cat_options.empty()) { #if NEW_OBJECT_SETTING ObjectDataViewModelNode *node = static_cast(parent_item.GetID()); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index d6662b8b4d..f11085543e 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -26,7 +26,9 @@ namespace GUI OG_Settings::OG_Settings(wxWindow* parent, const bool staticbox) : m_parent(parent) { - wxString title = staticbox ? " " : ""; // temporary workaround - #ys_FIXME + //BBS + wxString title = ""; + //wxString title = staticbox ? " " : ""; // temporary workaround - #ys_FIXME m_og = std::make_shared(parent, title); } @@ -106,13 +108,14 @@ bool ObjectSettings::update_settings_list() auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line auto btn = new ScalableButton(parent, wxID_ANY, m_bmp_delete); + btn->SetBackgroundColour(parent->GetBackgroundColour()); btn->SetToolTip(_(L("Remove parameter"))); btn->SetBitmapFocus(m_bmp_delete_focus.bmp()); btn->SetBitmapHover(m_bmp_delete_focus.bmp()); btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { - wxGetApp().plater()->take_snapshot(from_u8(boost::format(("Delete Option %s") % opt_key).str())); + wxGetApp().plater()->take_snapshot(from_u8((boost::format("Delete Option %s") % opt_key).str()).ToStdString()); config->erase(opt_key); wxGetApp().obj_list()->changed_object(); wxTheApp->CallAfter([this]() { @@ -159,7 +162,7 @@ bool ObjectSettings::update_settings_list() for (auto& opt : cat.second) optgroup->get_field(opt)->m_on_change = [optgroup](const std::string& opt_id, const boost::any& value) { // first of all take a snapshot and then change value in configuration - wxGetApp().plater()->take_snapshot(from_u8((boost::format("Change Option %s")% opt_id).str())); + wxGetApp().plater()->take_snapshot(from_u8((boost::format("Change Option %s")% opt_id).str()).ToStdString()); optgroup->on_change_OG(opt_id, value); }; @@ -183,7 +186,6 @@ bool ObjectSettings::update_settings_list() } #else - bool ObjectSettings::update_settings_list() { if (!wxGetApp().is_editor()) @@ -198,51 +200,74 @@ bool ObjectSettings::update_settings_list() objects_ctrl->GetSelections(items); std::map object_configs; - bool is_object_settings = true; - bool is_volume_settings = true; + bool is_object_settings = false; + bool is_volume_settings = false; + bool is_layer_range_settings = false; + bool is_layer_root = false; ModelObject * parent_object = nullptr; for (auto item : items) { auto type = objects_model->GetItemType(item); - if (type != itObject && type != itVolume) { + if (type != itObject && type != itVolume && type != itLayerRoot && type != itLayer) { continue; } const int obj_idx = objects_model->GetObjectIdByItem(item); assert(obj_idx >= 0); auto object = wxGetApp().model().objects[obj_idx]; if (type == itObject) { - if (!is_object_settings) - return false; - is_volume_settings = false; + is_object_settings = true; object_configs.emplace(object, &object->config); - } else { - if (!is_volume_settings) - return false; + } + else if(type == itVolume){ + is_volume_settings = true; if (parent_object && parent_object != object) return false; parent_object = object; - is_object_settings = false; const int vol_idx = objects_model->GetVolumeIdByItem(item); assert(vol_idx >= 0); auto volume = object->volumes[vol_idx]; object_configs.emplace(volume, &volume->config); } + else if(type == itLayer){ + is_layer_range_settings = true; + if (parent_object && parent_object != object) + return false; + parent_object = object; + + t_layer_height_range height_range = objects_model->GetLayerRangeByItem(item); + object_configs.emplace( (ObjectBase*)(&object->layer_config_ranges.at(height_range)), &object->layer_config_ranges.at(height_range) ); + } + else if (type == itLayerRoot) { + is_layer_root = true; + } } 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_volume_settings == is_object_settings) { - tab_object->set_model_config({}); - tab_volume->set_model_config({}); - m_tab_active = nullptr; - } else if (is_volume_settings) { - tab_object->set_model_config({{parent_object, &parent_object->config}}); - tab_volume->set_model_config(object_configs); - m_tab_active = tab_volume; - } else if (is_object_settings) { + 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; + } + 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; + } + 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; + } + else { + tab_object->set_model_config({}); + tab_volume->set_model_config({}); + tab_layer->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 8b0cbc3c42..cd3a3b6f36 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1093,6 +1093,7 @@ void MainFrame::create_preset_tabs() add_created_tab(new TabPrint(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"); add_created_tab(new TabFilament(m_param_dialog->panel()), "spool"); /* BBS work around to avoid appearance bug */ //add_created_tab(new TabSLAPrint(m_param_panel)); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 936de904c3..aead8232d8 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -1207,7 +1207,7 @@ void ObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent) node->set_action_icon(false); ItemChanged(parent); #else - if volume has a "settings"item, than delete it before volume deleting + // if volume has a "settings"item, than delete it before volume deleting if (node->GetChildCount() > 0 && node->GetNthChild(0)->GetType() == itSettings) { auto settings_node = node->GetNthChild(0); auto settings_item = wxDataViewItem(settings_node); @@ -2208,8 +2208,10 @@ void ObjectDataViewModel::Rescale() break; case itLayerRoot: node->m_bmp = create_scaled_bitmap(LayerRootIcon); + break; case itLayer: node->m_bmp = create_scaled_bitmap(LayerIcon); + break; case itInfo: node->m_bmp = m_info_bmps.at(node->m_info_item_type); break; diff --git a/src/slic3r/GUI/ParamsPanel.cpp b/src/slic3r/GUI/ParamsPanel.cpp index 6148823ff7..b4c72137ad 100644 --- a/src/slic3r/GUI/ParamsPanel.cpp +++ b/src/slic3r/GUI/ParamsPanel.cpp @@ -404,6 +404,10 @@ void ParamsPanel::create_layout() m_left_sizer->Add( m_tab_print_part, 0, wxEXPAND ); } + if (m_tab_print_layer) { + m_left_sizer->Add(m_tab_print_layer, 0, wxEXPAND); + } + if (m_tab_filament) { if (m_staticline_filament) m_left_sizer->Add(m_staticline_filament, 0, wxEXPAND); @@ -488,6 +492,7 @@ void ParamsPanel::refresh_tabs() if (m_top_panel) { 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(); } return; } @@ -557,6 +562,8 @@ void ParamsPanel::set_active_tab(wxPanel* tab) cur_tab = (Tab*) m_tab_print; } else if (m_tab_print_part && ((TabPrintModel*) m_tab_print_part)->has_model_config()) { cur_tab = (Tab*) m_tab_print_part; + } else if (m_tab_print_layer && ((TabPrintModel*)m_tab_print_layer)->has_model_config()) { + 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; } @@ -578,6 +585,7 @@ void ParamsPanel::set_active_tab(wxPanel* tab) {m_tab_print, m_staticline_print}, {m_tab_print_object, m_staticline_print_object}, {m_tab_print_part, m_staticline_print_part}, + {m_tab_print_layer, nullptr}, {m_tab_filament, m_staticline_filament}, {m_tab_printer, m_staticline_printer}})) { if (!t.first) continue; @@ -641,7 +649,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_filament, m_tab_printer}) { + for (auto tab : {m_tab_print, 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 c39f7cfbc9..7e752aa335 100644 --- a/src/slic3r/GUI/ParamsPanel.hpp +++ b/src/slic3r/GUI/ParamsPanel.hpp @@ -93,6 +93,7 @@ class ParamsPanel : public wxPanel wxPanel* m_tab_print_object { nullptr }; wxStaticLine* m_staticline_print_object { nullptr }; wxPanel* m_tab_print_part { nullptr }; + wxPanel* m_tab_print_layer { nullptr }; wxStaticLine* m_staticline_print_part { nullptr }; wxStaticLine* m_staticline_filament { nullptr }; //wxBoxSizer* m_filament_sizer { nullptr }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8d60fa64ad..0035201787 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -325,6 +325,7 @@ struct Sidebar::priv ObjectList *m_object_list{ nullptr }; ObjectSettings *object_settings{ nullptr }; + ObjectLayers *object_layers{ nullptr }; wxButton *btn_export_gcode; wxButton *btn_reslice; @@ -924,6 +925,10 @@ Sidebar::Sidebar(Plater *parent) #endif } + p->object_layers = new ObjectLayers(p->scrolled); + p->object_layers->Hide(); + p->sizer_params->Add(p->object_layers->get_sizer(), 0, wxEXPAND | wxTOP, 0); + auto *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(p->scrolled, 1, wxEXPAND); SetSizer(sizer); @@ -1458,6 +1463,11 @@ ObjectSettings* Sidebar::obj_settings() return p->object_settings; } +ObjectLayers* Sidebar::obj_layers() +{ + return p->object_layers; +} + wxPanel* Sidebar::scrolled_panel() { return p->scrolled; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 130b20f174..d735a550f6 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -63,6 +63,7 @@ namespace GUI { class MainFrame; class ConfigOptionsGroup; class ObjectSettings; +class ObjectLayers; class ObjectList; class GLCanvas3D; class Mouse3DController; @@ -128,6 +129,7 @@ public: ObjectList* obj_list(); ObjectSettings* obj_settings(); + ObjectLayers* obj_layers(); wxPanel* scrolled_panel(); wxPanel* print_panel(); wxPanel* filament_panel(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index dea947993a..d91db4725d 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2350,7 +2350,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co ::glBegin(GL_QUADS); if ((camera_on_top && type == 1) || (!camera_on_top && type == 2)) - ::glColor4f(1.0f, 0.38f, 0.0f, 1.0f); + ::glColor4f(0.0f, 174.0f / 255.0f, 66.0f / 255.0f, 1.0f); else ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); ::glVertex3f(min_x, min_y, z1); @@ -2361,7 +2361,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co ::glBegin(GL_QUADS); if ((camera_on_top && type == 2) || (!camera_on_top && type == 1)) - ::glColor4f(1.0f, 0.38f, 0.0f, 1.0f); + ::glColor4f(0.0f, 174.0f / 255.0f, 66.0f / 255.0f, 1.0f); else ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); ::glVertex3f(min_x, min_y, z2); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index ea5a7d8232..c4f2e87c99 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2283,8 +2283,9 @@ void TabPrintModel::reset_model_config() wxGetApp().plater()->take_snapshot(std::string("Reset Options")); for (auto config : m_object_configs) { auto rmkeys = intersect(m_keys, config.second->keys()); - for (auto & k : rmkeys) + for (auto& k : rmkeys) { config.second->erase(k); + } notify_changed(config.first); } update_model_config(); @@ -2405,6 +2406,44 @@ void TabPrintPart::notify_changed(ObjectBase * object) wxGetApp().obj_list()->object_config_options_changed({vol->get_object(), vol}); } +static std::string layer_height = "layer_height"; +TabPrintLayer::TabPrintLayer(ParamsPanel* parent) : + TabPrintModel(parent, concat({ layer_height }, PrintRegionConfig().keys())) +{ + m_parent_tab = wxGetApp().get_model_tab(); +} + +void TabPrintLayer::notify_changed(ObjectBase * object) +{ + for (auto config : m_object_configs) { + if (!config.second->has(layer_height)) { + auto option = m_parent_tab->get_config()->option(layer_height); + config.second->set_key_value(layer_height, option->clone()); + } + auto objects_list = wxGetApp().obj_list(); + wxDataViewItemArray items; + objects_list->GetSelections(items); + for (auto item : items) + objects_list->add_settings_item(item, &config.second->get()); + } +} + +void TabPrintLayer::update_custom_dirty() +{ + for (auto k : m_null_keys) m_options_list[k] = 0; + for (auto k : m_all_keys) m_options_list[k] &= ~osSystemValue; + + auto option = m_parent_tab->get_config()->option(layer_height); + for (auto config : m_object_configs) { + if (!config.second->has(layer_height)) { + config.second->set_key_value(layer_height, option->clone()); + m_options_list[layer_height] = osInitValue | osSystemValue; + } + else if (config.second->opt_float(layer_height) == option->getFloat()) + m_options_list[layer_height] = osInitValue | osSystemValue; + } +} + bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode) { std::vector tags; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index b495d3f9b6..4a2224b6a9 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -461,7 +461,7 @@ public: void update_model_config(); - void reset_model_config(); + virtual void reset_model_config(); bool has_key(std::string const &key); @@ -506,6 +506,17 @@ protected: virtual void notify_changed(ObjectBase * object) override; }; +class TabPrintLayer : public TabPrintModel +{ +public: + //BBS: GUI refactor + TabPrintLayer(ParamsPanel* parent); + ~TabPrintLayer() {} +protected: + virtual void notify_changed(ObjectBase* object) override; + virtual void update_custom_dirty() override; +}; + class TabFilament : public Tab { private: