From a270c476cfe5a2c06de799e9736baa3902cc8844 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 24 Oct 2023 11:56:17 +0800 Subject: [PATCH] ENH: [STUDIO-4898] export as STLs Change-Id: I001a7d026ca369fc7ff14f079eec10feaf012eb0 Jira: STUDIO-4898 --- src/slic3r/GUI/GUI_Factories.cpp | 10 +++++++- src/slic3r/GUI/MainFrame.cpp | 5 +++- src/slic3r/GUI/Plater.cpp | 43 +++++++++++++++++++++++++++++--- src/slic3r/GUI/Plater.hpp | 2 +- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 12529936b..0f2991365 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -687,7 +687,7 @@ wxMenuItem* MenuFactory::append_menu_item_fix_through_netfabb(wxMenu* menu) void MenuFactory::append_menu_item_export_stl(wxMenu* menu, bool is_mulity_menu) { - append_menu_item(menu, wxID_ANY, _L("Export as STL") + dots, "", + append_menu_item(menu, wxID_ANY, _L("Export as one STL") + dots, "", [](wxCommandEvent&) { plater()->export_stl(false, true); }, "", nullptr, [is_mulity_menu]() { const Selection& selection = plater()->canvas3D()->get_selection(); @@ -696,6 +696,14 @@ void MenuFactory::append_menu_item_export_stl(wxMenu* menu, bool is_mulity_menu) else return selection.is_single_full_instance() || selection.is_single_full_object(); }, m_parent); + if (!is_mulity_menu) + return; + append_menu_item(menu, wxID_ANY, _L("Export as STLs") + dots, "", + [](wxCommandEvent&) { plater()->export_stl(false, true, true); }, "", nullptr, + []() { + const Selection& selection = plater()->canvas3D()->get_selection(); + return selection.is_multiple_full_instance() || selection.is_multiple_full_object(); + }, m_parent); } void MenuFactory::append_menu_item_reload_from_disk(wxMenu* menu) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 16713a72b..cf1599d35 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2312,9 +2312,12 @@ void MainFrame::init_menubar_as_editor() wxMenu* export_menu = new wxMenu(); // BBS export as STL - append_menu_item(export_menu, wxID_ANY, _L("Export all objects as STL") + dots, _L("Export all objects as STL"), + append_menu_item(export_menu, wxID_ANY, _L("Export all objects as one STL") + dots, _L("Export all objects as one STL"), [this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "menu_export_stl", nullptr, [this](){return can_export_model(); }, this); + append_menu_item(export_menu, wxID_ANY, _L("Export all objects as STLs") + dots, _L("Export all objects as STLs"), + [this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(false, false, true); }, "menu_export_stl", nullptr, + [this](){return can_export_model(); }, this); append_menu_item(export_menu, wxID_ANY, _L("Export Generic 3MF") + dots/* + "\tCtrl+G"*/, _L("Export 3mf file without using some 3mf-extensions"), [this](wxCommandEvent&) { if (m_plater) m_plater->export_core_3mf(); }, "menu_export_sliced_file", nullptr, [this](){return can_export_model(); }, this); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4a64b9a4b..ba2d3092c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -10480,11 +10480,20 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st // BBS export with/without boolean, however, stil merge mesh #define EXPORT_WITH_BOOLEAN 0 -void Plater::export_stl(bool extended, bool selection_only) +void Plater::export_stl(bool extended, bool selection_only, bool multi_stls) { if (p->model.objects.empty()) { return; } - wxString path = p->get_export_file(FT_STL); + wxString path; + if (multi_stls) { + wxDirDialog dlg(this, _L("Choose a directory"), from_u8(wxGetApp().app_config->get_last_dir()), + wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + if (dlg.ShowModal() == wxID_OK) { + path = dlg.GetPath() + "/"; + } + } else { + path = p->get_export_file(FT_STL); + } if (path.empty()) { return; } const std::string path_u8 = into_u8(path); @@ -10607,6 +10616,14 @@ void Plater::export_stl(bool extended, bool selection_only) else mesh_to_export = mesh_to_export_sla; + auto get_save_file = [](std::string const & dir, std::string const & name) { + auto path = dir + name + ".stl"; + int n = 1; + while (boost::filesystem::exists(path)) + path = dir + name + "(" + std::to_string(n++) + ").stl"; + return path; + }; + TriangleMesh mesh; if (selection_only) { if (selection.is_single_full_object()) { @@ -10622,18 +10639,36 @@ void Plater::export_stl(bool extended, bool selection_only) if (model_object->instances.size() == 1) mesh.translate(-model_object->origin_translation.cast()); } - else if (selection.is_multiple_full_object()) { + else if (selection.is_multiple_full_object() && !multi_stls) { const std::set>& instances_idxs = p->get_selection().get_selected_object_instances(); for (const std::pair& i : instances_idxs) { ModelObject* object = p->model.objects[i.first]; mesh.merge(mesh_to_export(*object, i.second)); } } + else if (selection.is_multiple_full_object() && multi_stls) { + const std::set> &instances_idxs = p->get_selection().get_selected_object_instances(); + for (const std::pair &i : instances_idxs) { + ModelObject *object = p->model.objects[i.first]; + auto mesh = mesh_to_export(*object, i.second); + mesh.translate(-object->origin_translation.cast()); + + Slic3r::store_stl(get_save_file(path_u8, object->name).c_str(), &mesh, true); + } + return; + } } - else { + else if (!multi_stls) { for (const ModelObject* o : p->model.objects) { mesh.merge(mesh_to_export(*o, -1)); } + } else { + for (const ModelObject* o : p->model.objects) { + auto mesh = mesh_to_export(*o, -1); + mesh.translate(-o->origin_translation.cast()); + Slic3r::store_stl(get_save_file(path_u8, o->name).c_str(), &mesh, true); + } + return; } Slic3r::store_stl(path_u8.c_str(), &mesh, true); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 23acb23e8..5cd025faf 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -338,7 +338,7 @@ public: void send_gcode_finish(wxString name); void export_core_3mf(); static TriangleMesh combine_mesh_fff(const ModelObject& mo, int instance_id, std::function notify_func = {}); - void export_stl(bool extended = false, bool selection_only = false); + void export_stl(bool extended = false, bool selection_only = false, bool multi_stls = false); //BBS: remove amf //void export_amf(); //BBS add extra param for exporting 3mf silence