diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index 12f16679b2..0f9a75a99b 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -4955,7 +4955,7 @@ exposure_time = 5 initial_exposure_time = 35 material_type = Tough material_vendor = Made for Prusa -material_colour = #007EFD +material_colour = #79FFFF [sla_material:Prusa Super Low Odor Magenta Tough @0.025] inherits = *common 0.025* @@ -5665,7 +5665,7 @@ exposure_time = 7.5 initial_exposure_time = 35 material_type = Tough material_vendor = Made for Prusa -material_colour = #FFEEE6 +material_colour = #FF8040 [sla_material:Prusa Grey Tough @0.05] inherits = *common 0.05* @@ -5710,7 +5710,7 @@ exposure_time = 6 initial_exposure_time = 35 material_type = Tough material_vendor = Made for Prusa -material_colour = +material_colour = #79FFFF [sla_material:Prusa Super Low Odor Magenta Tough @0.05] inherits = *common 0.05* @@ -6125,7 +6125,7 @@ exposure_time = 1.8 initial_exposure_time = 25 material_type = Tough material_vendor = Made for Prusa -material_colour = +material_colour = #79FFFF [sla_material:Prusa Magenta Tough @0.025 SL1S] inherits = *0.025_sl1s* @@ -6371,7 +6371,7 @@ exposure_time = 2 initial_exposure_time = 25 material_type = Tough material_vendor = Made for Prusa -material_colour = +material_colour = #79FFFF [sla_material:Prusa Magenta Tough @0.05 SL1S] inherits = *0.05_sl1s* @@ -6617,7 +6617,7 @@ exposure_time = 2.6 initial_exposure_time = 25 material_type = Tough material_vendor = Made for Prusa -material_colour = +material_colour = #79FFFF [sla_material:Prusa Magenta Tough @0.1 SL1S] inherits = *0.1_sl1s* @@ -6657,7 +6657,7 @@ exposure_time = 2.6 initial_exposure_time = 25 material_type = Flexible material_vendor = Made for Prusa -material_colour = +material_colour = #007EFD [sla_material:Prusa Grey Tough @0.1 SL1S] inherits = *0.1_sl1s* diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index e95ae3adfa..09c80a9d9b 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -139,16 +139,16 @@ namespace ImGui const wchar_t EjectHoverButton = 0x13; const wchar_t CancelButton = 0x14; const wchar_t CancelHoverButton = 0x15; - const wchar_t VarLayerHeightMarker = 0x16; +// const wchar_t VarLayerHeightMarker = 0x16; const wchar_t RightArrowButton = 0x18; const wchar_t RightArrowHoverButton = 0x19; const wchar_t PreferencesButton = 0x1A; const wchar_t PreferencesHoverButton = 0x1B; - const wchar_t SinkingObjectMarker = 0x1C; - const wchar_t CustomSupportsMarker = 0x1D; - const wchar_t CustomSeamMarker = 0x1E; - const wchar_t MmuSegmentationMarker = 0x1F; +// const wchar_t SinkingObjectMarker = 0x1C; +// const wchar_t CustomSupportsMarker = 0x1D; +// const wchar_t CustomSeamMarker = 0x1E; +// const wchar_t MmuSegmentationMarker = 0x1F; // Do not forget use following letters only in wstring const wchar_t DocumentationButton = 0x2600; const wchar_t DocumentationHoverButton = 0x2601; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index b5d93205ad..3b6731337e 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1,3 +1,4 @@ +#include "Model.hpp" #include "libslic3r.h" #include "BuildVolume.hpp" #include "Exception.hpp" @@ -1621,9 +1622,6 @@ std::string ModelObject::get_export_filename() const TriangleMeshStats ModelObject::get_object_stl_stats() const { - if (this->volumes.size() == 1) - return this->volumes[0]->mesh().stats(); - TriangleMeshStats full_stats; full_stats.volume = 0.f; @@ -1638,7 +1636,8 @@ TriangleMeshStats ModelObject::get_object_stl_stats() const // another used satistics value if (volume->is_model_part()) { - full_stats.volume += stats.volume; + Transform3d trans = instances.empty() ? volume->get_matrix() : (volume->get_matrix() * instances[0]->get_matrix()); + full_stats.volume += stats.volume * std::fabs(trans.matrix().block(0, 0, 3, 3).determinant()); full_stats.number_of_parts += stats.number_of_parts; } } diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 2ddee6e865..85268fca15 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -2292,26 +2292,54 @@ void ConfigWizard::priv::select_default_materials_for_printer_models(Technology { PageMaterials *page_materials = technology & T_FFF ? page_filaments : page_sla_materials; const std::string &appconfig_section = page_materials->materials->appconfig_section(); - - auto select_default_materials_for_printer_page = [this, appconfig_section, printer_models](PagePrinters *page_printers, Technology technology) + + // Following block was unnecessary. Its enough to iterate printer_models once. Not for every vendor printer page. + // Filament is selected on same page for all printers of same technology. + /* + auto select_default_materials_for_printer_page = [this, appconfig_section, printer_models, technology](PagePrinters *page_printers, Technology technology) { const std::string vendor_id = page_printers->get_vendor_id(); for (auto& pair : bundles) if (pair.first == vendor_id) - for (const VendorProfile::PrinterModel *printer_model : printer_models) - for (const std::string &material : printer_model->default_materials) - appconfig_new.set(appconfig_section, material, "1"); + for (const VendorProfile::PrinterModel *printer_model : printer_models) + for (const std::string &material : printer_model->default_materials) + appconfig_new.set(appconfig_section, material, "1"); }; PagePrinters* page_printers = technology & T_FFF ? page_fff : page_msla; select_default_materials_for_printer_page(page_printers, technology); - for (const auto& printer : pages_3rdparty) + for (const auto& printer : pages_3rdparty) { page_printers = technology & T_FFF ? printer.second.first : printer.second.second; if (page_printers) select_default_materials_for_printer_page(page_printers, technology); } + */ + + // Iterate printer_models and select default materials. If none available -> msg to user. + std::vector models_without_default; + for (const VendorProfile::PrinterModel* printer_model : printer_models) { + if (printer_model->default_materials.empty()) { + models_without_default.emplace_back(printer_model); + } else { + for (const std::string& material : printer_model->default_materials) + appconfig_new.set(appconfig_section, material, "1"); + } + } + + if (!models_without_default.empty()) { + std::string printer_names = "\n\n"; + for (const VendorProfile::PrinterModel* printer_model : models_without_default) { + printer_names += printer_model->name + "\n"; + } + printer_names += "\n\n"; + std::string message = (technology & T_FFF ? + GUI::format(_L("Following printer profiles has no default filament: %1%Please select one manually."), printer_names) : + GUI::format(_L("Following printer profiles has no default material: %1%Please select one manually."), printer_names)); + MessageDialog msg(q, message, _L("Notice"), wxOK); + msg.ShowModal(); + } update_materials(technology); ((technology & T_FFF) ? page_filaments : page_sla_materials)->reload_presets(); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 6463cc1804..a38a0e0eda 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -787,7 +787,8 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v m_extrusions.ranges.width.update_from(round_to_nearest_percent(curr.width)); m_extrusions.ranges.fan_speed.update_from(curr.fan_speed); m_extrusions.ranges.temperature.update_from(curr.temperature); - m_extrusions.ranges.volumetric_rate.update_from(round_to_nearest_percent(curr.volumetric_rate())); + if (curr.extrusion_role != erCustom || is_visible(erCustom)) + m_extrusions.ranges.volumetric_rate.update_from(round_to_nearest_percent(curr.volumetric_rate())); [[fallthrough]]; } case EMoveType::Travel: diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index da377c2ad0..f6e927df06 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -65,11 +65,11 @@ static const std::map font_icons_large = { {ImGui::ErrorMarker , "notification_error" }, {ImGui::CancelButton , "notification_cancel" }, {ImGui::CancelHoverButton , "notification_cancel_hover" }, - {ImGui::SinkingObjectMarker , "move" }, - {ImGui::CustomSupportsMarker , "fdm_supports" }, - {ImGui::CustomSeamMarker , "seam" }, - {ImGui::MmuSegmentationMarker , "mmu_segmentation" }, - {ImGui::VarLayerHeightMarker , "layers" }, +// {ImGui::SinkingObjectMarker , "move" }, +// {ImGui::CustomSupportsMarker , "fdm_supports" }, +// {ImGui::CustomSeamMarker , "seam" }, +// {ImGui::MmuSegmentationMarker , "mmu_segmentation" }, +// {ImGui::VarLayerHeightMarker , "layers" }, {ImGui::DocumentationButton , "notification_documentation" }, {ImGui::DocumentationHoverButton, "notification_documentation_hover"}, {ImGui::InfoMarker , "notification_info" }, diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index f7458cab26..904a21cc67 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -1082,6 +1082,8 @@ void NotificationManager::UpdatedItemsInfoNotification::add_type(InfoItemType ty NotificationData data { get_data().type, get_data().level , get_data().duration, text }; update(data); } +// Uncomment to have different icon for every type of info, otherwise it will have standart cube with i. +/* void NotificationManager::UpdatedItemsInfoNotification::render_left_sign(ImGuiWrapper& imgui) { std::string text; @@ -1098,7 +1100,7 @@ void NotificationManager::UpdatedItemsInfoNotification::render_left_sign(ImGuiWr ImGui::SetCursorPosY(m_window_height / 2 - m_line_height); imgui.text(text.c_str()); } - +*/ //------SlicingProgressNotification void NotificationManager::SlicingProgressNotification::init() { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index f162182dcc..ee79869996 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -674,7 +674,7 @@ private: PopNotification::close(); } protected: - void render_left_sign(ImGuiWrapper& imgui) override; + //void render_left_sign(ImGuiWrapper& imgui) override; std::vector> m_types_and_counts; }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9d8fdc74cb..cea8b4fe31 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -137,6 +137,7 @@ public: ObjectInfo(wxWindow *parent); wxStaticBitmap *manifold_warning_icon; + wxStaticBitmap *info_icon; wxStaticText *info_size; wxStaticText *info_volume; wxStaticText *info_facets; @@ -144,7 +145,7 @@ public: wxStaticText *info_manifold; wxStaticText *label_volume; - wxStaticText *label_materials; +// wxStaticText *label_materials; // ysFIXME - delete after next release if anyone will not complain about this std::vector sla_hidden_items; bool showing_manifold_warning_icon; @@ -161,23 +162,33 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : auto *grid_sizer = new wxFlexGridSizer(4, 5, 15); grid_sizer->SetFlexibleDirection(wxHORIZONTAL); -// grid_sizer->AddGrowableCol(1, 1); -// grid_sizer->AddGrowableCol(3, 1); - auto init_info_label = [parent, grid_sizer](wxStaticText **info_label, wxString text_label) { - auto *text = new wxStaticText(parent, wxID_ANY, text_label+":"); + auto init_info_label = [parent, grid_sizer](wxStaticText **info_label, wxString text_label, wxSizer* sizer_with_icon=nullptr) { + auto *text = new wxStaticText(parent, wxID_ANY, text_label + ":"); text->SetFont(wxGetApp().small_font()); *info_label = new wxStaticText(parent, wxID_ANY, ""); (*info_label)->SetFont(wxGetApp().small_font()); grid_sizer->Add(text, 0); - grid_sizer->Add(*info_label, 0); + if (sizer_with_icon) { + sizer_with_icon->Insert(0, *info_label, 0); + grid_sizer->Add(sizer_with_icon, 0, wxEXPAND); + } + else + grid_sizer->Add(*info_label, 0); return text; }; init_info_label(&info_size, _L("Size")); - label_volume = init_info_label(&info_volume, _L("Volume")); + + info_icon = new wxStaticBitmap(parent, wxID_ANY, create_scaled_bitmap("info")); + info_icon->SetToolTip(_L("For a multipart object, this value isn't accurate.\n" + "It doesn't take account of intersections and negative volumes.")); + auto* volume_info_sizer = new wxBoxSizer(wxHORIZONTAL); + volume_info_sizer->Add(info_icon, 0, wxLEFT, 10); + label_volume = init_info_label(&info_volume, _L("Volume"), volume_info_sizer); + init_info_label(&info_facets, _L("Facets")); - label_materials = init_info_label(&info_materials, _L("Materials")); +// label_materials = init_info_label(&info_materials, _L("Materials")); Add(grid_sizer, 0, wxEXPAND); info_manifold = new wxStaticText(parent, wxID_ANY, ""); @@ -188,7 +199,7 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : sizer_manifold->Add(info_manifold, 0, wxLEFT, 2); Add(sizer_manifold, 0, wxEXPAND | wxTOP, 4); - sla_hidden_items = { label_volume, info_volume, label_materials, info_materials }; + sla_hidden_items = { label_volume, info_volume, /*label_materials, */info_materials }; } void ObjectInfo::show_sizer(bool show) @@ -1199,32 +1210,47 @@ void Sidebar::update_objects_list_extruder_column(size_t extruders_count) void Sidebar::show_info_sizer() { - if (!p->plater->is_single_full_object_selection() || - m_mode < comExpert || - p->plater->model().objects.empty()) { + Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); + ModelObjectPtrs objects = p->plater->model().objects; + int obj_idx = selection.get_object_idx(); + + if (m_mode < comExpert || objects.empty() || obj_idx < 0 || obj_idx > 1000 || + objects[obj_idx]->volumes.empty() || // hack to avoid crash when deleting the last object on the bed + (selection.is_single_full_object() && objects[obj_idx]->instances.size()> 1) || + !(selection.is_single_full_instance() || selection.is_single_volume())) { p->object_info->Show(false); return; } - int obj_idx = p->plater->get_selected_object_idx(); + const ModelObject* model_object = objects[obj_idx]; - const ModelObject* model_object = p->plater->model().objects[obj_idx]; - // hack to avoid crash when deleting the last object on the bed - if (model_object->volumes.empty()) - { - p->object_info->Show(false); - return; - } + int inst_idx = selection.get_instance_idx(); + assert(inst_idx >= 0); bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; double koef = imperial_units ? ObjectManipulation::mm_to_in : 1.0f; - auto size = model_object->bounding_box().size(); - p->object_info->info_size->SetLabel(wxString::Format("%.2f x %.2f x %.2f",size(0)*koef, size(1)*koef, size(2)*koef)); - p->object_info->info_materials->SetLabel(wxString::Format("%d", static_cast(model_object->materials_count()))); + ModelVolume* vol = nullptr; + Transform3d t; + if (selection.is_single_volume()) { + std::vector obj_idxs, vol_idxs; + wxGetApp().obj_list()->get_selection_indexes(obj_idxs, vol_idxs); + assert(vol_idxs.size() == 1); + vol = model_object->volumes[vol_idxs[0]]; + t = model_object->instances[inst_idx]->get_matrix() * vol->get_matrix(); + } - const auto& stats = model_object->get_object_stl_stats(); - p->object_info->info_volume->SetLabel(wxString::Format("%.2f", stats.volume*pow(koef,3))); + Vec3d size = vol ? vol->mesh().transformed_bounding_box(t).size() : model_object->instance_bounding_box(inst_idx).size(); + p->object_info->info_size->SetLabel(wxString::Format("%.2f x %.2f x %.2f", size(0)*koef, size(1)*koef, size(2)*koef)); +// p->object_info->info_materials->SetLabel(wxString::Format("%d", static_cast(model_object->materials_count()))); + + const TriangleMeshStats& stats = vol ? vol->mesh().stats() : model_object->get_object_stl_stats(); + + double volume_val = stats.volume; + if (vol) + volume_val *= std::fabs(t.matrix().block(0, 0, 3, 3).determinant()); + + p->object_info->info_volume->SetLabel(wxString::Format("%.2f", volume_val * pow(koef,3))); p->object_info->info_facets->SetLabel(format_wxstr(_L_PLURAL("%1% (%2$d shell)", "%1% (%2$d shells)", stats.number_of_parts), static_cast(model_object->facets_count()), stats.number_of_parts)); @@ -1237,6 +1263,8 @@ void Sidebar::show_info_sizer() p->object_info->manifold_warning_icon->SetToolTip(tooltip); p->object_info->show_sizer(true); + if (vol || model_object->volumes.size() == 1) + p->object_info->info_icon->Hide(); if (p->plater->printer_technology() == ptSLA) { for (auto item: p->object_info->sla_hidden_items) diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp index dd789a1da3..64f0597bef 100644 --- a/src/slic3r/GUI/UpdateDialogs.cpp +++ b/src/slic3r/GUI/UpdateDialogs.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -58,11 +57,13 @@ MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_on const std::string url_log = (boost::format(URL_CHANGELOG) % lang_code).str(); const wxString url_log_wx = from_u8(url_log); auto *link_log = new wxHyperlinkCtrl(this, wxID_ANY, _(L("Open changelog page")), url_log_wx); + link_log->Bind(wxEVT_HYPERLINK, &MsgUpdateSlic3r::on_hyperlink, this); content_sizer->Add(link_log); const std::string url_dw = (boost::format(URL_DOWNLOAD) % lang_code).str(); const wxString url_dw_wx = from_u8(url_dw); auto *link_dw = new wxHyperlinkCtrl(this, wxID_ANY, _(L("Open download page")), url_dw_wx); + link_dw->Bind(wxEVT_HYPERLINK, &MsgUpdateSlic3r::on_hyperlink, this); content_sizer->Add(link_dw); } @@ -77,12 +78,16 @@ MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_on MsgUpdateSlic3r::~MsgUpdateSlic3r() {} +void MsgUpdateSlic3r::on_hyperlink(wxHyperlinkEvent& evt) +{ + wxGetApp().open_browser_with_warning_dialog(evt.GetURL()); +} + bool MsgUpdateSlic3r::disable_version_check() const { return cbox->GetValue(); } - // MsgUpdateConfig MsgUpdateConfig::MsgUpdateConfig(const std::vector &updates, bool force_before_wizard/* = false*/) : diff --git a/src/slic3r/GUI/UpdateDialogs.hpp b/src/slic3r/GUI/UpdateDialogs.hpp index aa3a10677f..435a8ccbd8 100644 --- a/src/slic3r/GUI/UpdateDialogs.hpp +++ b/src/slic3r/GUI/UpdateDialogs.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "libslic3r/Semver.hpp" #include "MsgDialog.hpp" @@ -30,6 +31,7 @@ public: // Tells whether the user checked the "don't bother me again" checkbox bool disable_version_check() const; + void on_hyperlink(wxHyperlinkEvent& evt); private: wxCheckBox *cbox; };