diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 2d5a9eac7..f2bb9b3d1 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -1025,6 +1025,21 @@ static int construct_assemble_list(std::vector &assemble_ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to read a valid mesh from obj file %1%, plate index %2%, object index %3%, error %4%") % assemble_object.path % (index + 1) % (obj_index + 1) % message; return CLI_DATA_FILE_ERROR; } + if (obj_info.lost_material_name != "") { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to read a valid mesh from obj file %1%, plate index %2%, object index %3%, mtl lost material: %4% ,please check mtl file") % + assemble_object.path % (index + 1) % (obj_index + 1) % obj_info.lost_material_name; + return CLI_DATA_FILE_ERROR; + } + if (obj_info.face_colors.size() > 0) { + auto temp0 = obj_info.face_colors.size(); + auto temp1 = mesh.facets_count(); + bool some_face_no_color = temp0 < temp1; + if (some_face_no_color) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": failed to read a valid mesh from obj file %1%, plate index %2%, object index %3%, error:some_face_no_color,please check mtl file and obj file.") % + assemble_object.path % (index + 1) % (obj_index + 1); + return CLI_DATA_FILE_ERROR; + } + } object_name.erase(object_name.end() - 4, object_name.end()); object_1_name = object_name + "_1"; //process colors diff --git a/src/libslic3r/Format/OBJ.cpp b/src/libslic3r/Format/OBJ.cpp index 634d29d84..7f8d72751 100644 --- a/src/libslic3r/Format/OBJ.cpp +++ b/src/libslic3r/Format/OBJ.cpp @@ -180,6 +180,11 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s } obj_info.face_colors.emplace_back(face_color); } + else { + if (obj_info.lost_material_name.empty()) { + obj_info.lost_material_name = mtl_name; + } + } }; auto set_face_color_by_mtl = [&data, &set_face_color](int face_index) { if (data.usemtls.size() == 1) { diff --git a/src/libslic3r/Format/OBJ.hpp b/src/libslic3r/Format/OBJ.hpp index 1dfcb2bde..48335f823 100644 --- a/src/libslic3r/Format/OBJ.hpp +++ b/src/libslic3r/Format/OBJ.hpp @@ -13,6 +13,7 @@ struct ObjInfo { std::vector vertex_colors; std::vector face_colors; bool is_single_mtl{false}; + std::string lost_material_name{""}; std::vector> uvs; std::string obj_dircetory; std::map pngs; @@ -36,6 +37,7 @@ struct ObjDialogInOut std::string ml_region; std::string ml_name; std::string ml_id; + std::string lost_material_name{""}; }; typedef std::function ObjImportColorFn; extern bool load_obj(const char *path, TriangleMesh *mesh, ObjInfo &vertex_colors, std::string &message); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index c7805568c..9af7e9548 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -279,6 +279,7 @@ Model Model::read_from_file(const std::string& if (result){ ObjDialogInOut in_out; in_out.model = &model; + in_out.lost_material_name = obj_info.lost_material_name; if (obj_info.vertex_colors.size() > 0) { if (objFn) { // 1.result is ok and pop up a dialog in_out.input_colors = std::move(obj_info.vertex_colors); @@ -3762,7 +3763,9 @@ bool Model::obj_import_face_color_deal(const std::vector &face_fi auto face_count = volume->mesh().its.indices.size(); volume->mmu_segmentation_facets.reset(); volume->mmu_segmentation_facets.reserve(face_count); - if (volume->mesh().its.indices.size() != face_filament_ids.size()) { return false; } + if (volume->mesh().its.indices.size() != face_filament_ids.size()) { + return false; + } for (size_t i = 0; i < volume->mesh().its.indices.size(); i++) { auto face = volume->mesh().its.indices[i]; auto filament_id = face_filament_ids[i]; diff --git a/src/slic3r/GUI/ObjColorDialog.cpp b/src/slic3r/GUI/ObjColorDialog.cpp index e8fa9fbe2..02f75b9dc 100644 --- a/src/slic3r/GUI/ObjColorDialog.cpp +++ b/src/slic3r/GUI/ObjColorDialog.cpp @@ -46,29 +46,29 @@ const StateColor ok_btn_bg(std::pair(wxColour(27, 136, 68), Stat const StateColor ok_btn_disable_bg(std::pair(wxColour(205, 201, 201), StateColor::Pressed), std::pair(wxColour(205, 201, 201), StateColor::Hovered), std::pair(wxColour(205, 201, 201), StateColor::Normal)); -wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags) +wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags,bool exist_error) { auto btn_sizer = new wxBoxSizer(wxHORIZONTAL); - btn_sizer->AddSpacer(FromDIP(25)); - wxStaticText *tips = new wxStaticText(this, wxID_ANY, _L("Open Wiki for more information >")); - /* wxFont font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false); - font.SetUnderlined(true); - tips->SetFont(font);*/ - auto font = tips->GetFont(); - font.SetUnderlined(true); - tips->SetFont(font); - tips->SetForegroundColour(wxColour(0,174,100)); - tips->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { - bool is_zh = wxGetApp().app_config->get("language") == "zh_CN"; - if (is_zh) { - wxLaunchDefaultBrowser("https://wiki.bambulab.com/zh/software/bambu-studio/import_obj"); - } - else { - wxLaunchDefaultBrowser("https://wiki.bambulab.com/en/software/bambu-studio/import_obj"); - } - }); - btn_sizer->Add(tips, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); - + if (!exist_error) { + btn_sizer->AddSpacer(FromDIP(25)); + wxStaticText *tips = new wxStaticText(this, wxID_ANY, _L("Open Wiki for more information >")); + /* wxFont font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false); + font.SetUnderlined(true); + tips->SetFont(font);*/ + auto font = tips->GetFont(); + font.SetUnderlined(true); + tips->SetFont(font); + tips->SetForegroundColour(wxColour(0, 174, 100)); + tips->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { + bool is_zh = wxGetApp().app_config->get("language") == "zh_CN"; + if (is_zh) { + wxLaunchDefaultBrowser("https://wiki.bambulab.com/zh/software/bambu-studio/import_obj"); + } else { + wxLaunchDefaultBrowser("https://wiki.bambulab.com/en/software/bambu-studio/import_obj"); + } + }); + btn_sizer->Add(tips, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + } btn_sizer->AddStretchSpacer(); StateColor ok_btn_bd( @@ -171,19 +171,47 @@ ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, this->SetBackgroundColour(*wxWHITE); this->SetMinSize(wxSize(MIN_OBJCOLOR_DIALOG_WIDTH, -1)); - m_panel_ObjColor = new ObjColorPanel(this, in_out, extruder_colours); - m_panel_ObjColor->set_layout_callback([this]() { update_layout(); - }); m_main_sizer = new wxBoxSizer(wxVERTICAL); m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0); // set min sizer width according to extruders count auto sizer_width = (int) (2.8 * OBJCOLOR_ITEM_WIDTH()); sizer_width = sizer_width > MIN_OBJCOLOR_DIALOG_WIDTH ? sizer_width : MIN_OBJCOLOR_DIALOG_WIDTH; m_main_sizer->SetMinSize(wxSize(sizer_width, -1)); - m_main_sizer->Add(m_panel_ObjColor, 1, wxEXPAND | wxALL, 0); + bool some_face_no_color = false; + if (!in_out.deal_vertex_color) { + auto temp0 = in_out.input_colors.size(); + auto temp1 = in_out.model->objects[0]->volumes[0]->mesh_ptr()->facets_count(); + some_face_no_color = temp0 < temp1; + } + bool ok = in_out.lost_material_name.empty() && !some_face_no_color; + if (ok) { + m_panel_ObjColor = new ObjColorPanel(this, in_out, extruder_colours); + m_panel_ObjColor->set_layout_callback([this]() { update_layout(); }); + m_main_sizer->Add(m_panel_ObjColor, 1, wxEXPAND | wxALL, 0); + } + else { + wxBoxSizer * error_mtl_sizer = new wxBoxSizer(wxVERTICAL); - m_buttons_sizer = create_btn_sizer(wxOK | wxCANCEL); - { + wxStaticText *error_mtl_title = new wxStaticText(this, wxID_ANY, _L("Some faces not define color.")); + if (!in_out.lost_material_name.empty()) { + error_mtl_title->SetLabel(_L("mtl file exist error,could not find the material:") + " " + in_out.lost_material_name + "."); + } + error_mtl_title->SetFont(Label::Head_12); + error_mtl_sizer->Add(error_mtl_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5)); + + wxStaticText *tip_title = new wxStaticText(this, wxID_ANY, _L("Please check obj or mtl file.")); + tip_title->SetFont(Label::Head_12); + error_mtl_sizer->Add(tip_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5)); + + m_main_sizer->Add(error_mtl_sizer, 1, wxEXPAND | wxLEFT, FromDIP(25)); + } + + m_buttons_sizer = create_btn_sizer(wxOK | wxCANCEL, !ok); + if (!ok) { + m_button_list[wxCANCEL]->Hide(); + m_button_list[wxOK]->Enable(true); + m_button_list[wxOK]->SetBackgroundColor(ok_btn_bg); + } else { m_button_list[wxOK]->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) { if (m_panel_ObjColor->is_ok() == m_button_list[wxOK]->IsEnabled()) { return; } m_button_list[wxOK]->Enable(m_panel_ObjColor->is_ok()); @@ -196,6 +224,10 @@ ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, if (this->FindWindowById(wxID_OK, this)) { this->FindWindowById(wxID_OK, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {// if OK button is clicked.. + if (!m_panel_ObjColor) { + EndModal(wxCANCEL); + return; + } m_panel_ObjColor->send_new_filament_to_ui(); EndModal(wxID_OK); }, wxID_OK); @@ -203,6 +235,7 @@ ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, if (this->FindWindowById(wxID_CANCEL, this)) { update_ui(static_cast(this->FindWindowById(wxID_CANCEL, this))); this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + if (!m_panel_ObjColor) { return; } m_panel_ObjColor->cancel_paint_color(); EndModal(wxCANCEL); }); @@ -210,6 +243,7 @@ ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); }); wxGetApp().UpdateDlgDarkUI(this); + CenterOnParent(); } // This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers) diff --git a/src/slic3r/GUI/ObjColorDialog.hpp b/src/slic3r/GUI/ObjColorDialog.hpp index 56fb836aa..1da537d26 100644 --- a/src/slic3r/GUI/ObjColorDialog.hpp +++ b/src/slic3r/GUI/ObjColorDialog.hpp @@ -106,7 +106,7 @@ class ObjColorDialog : public Slic3r::GUI::DPIDialog { public: ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector &extruder_colours); - wxBoxSizer* create_btn_sizer(long flags); + wxBoxSizer *create_btn_sizer(long flags, bool exist_error); void on_dpi_changed(const wxRect &suggested_rect) override; void update_layout(); private: diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0495bbe6b..bedffb62a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5072,7 +5072,6 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (!boost::iends_with(path.string(), ".obj")) { return; } const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); ObjColorDialog color_dlg(nullptr, in_out, extruder_colours); - color_dlg.CenterOnScreen(); if (color_dlg.ShowModal() != wxID_OK) { in_out.filament_ids.clear(); }