MSW specific: Fixing by Windows repair algorithm of cut objects if it's needed.

Related to issues #7243
This commit is contained in:
YuSanka 2023-11-27 13:08:31 +01:00
parent ec40931389
commit 200f4073c8
4 changed files with 112 additions and 25 deletions

View File

@ -475,6 +475,30 @@ std::vector<wxBitmapBundle*> MenuFactory::get_svg_volume_bitmaps()
return volume_bmps; return volume_bmps;
} }
wxString MenuFactory::get_repaire_result_message(
const std::vector<std::string>& succes_models,
const std::vector<std::pair<std::string, std::string>>& failed_models)
{
// Show info notification
wxString msg;
wxString bullet_suf = "\n - ";
if (!succes_models.empty()) {
msg = _L_PLURAL("The following model was repaired successfully", "The following models were repaired successfully", succes_models.size()) + ":";
for (auto& model : succes_models)
msg += bullet_suf + from_u8(model);
msg += "\n\n";
}
if (!failed_models.empty()) {
msg += _L_PLURAL("Folowing model repair failed", "Folowing models repair failed", failed_models.size()) + ":\n";
for (auto& model : failed_models)
msg += bullet_suf + from_u8(model.first) + ": " + _(model.second);
}
if (msg.IsEmpty())
msg = _L("Repairing was canceled");
return msg;
}
void MenuFactory::append_menu_item_delete(wxMenu* menu) void MenuFactory::append_menu_item_delete(wxMenu* menu)
{ {
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Remove the selected object"), append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Remove the selected object"),

View File

@ -41,6 +41,9 @@ public:
static std::vector<wxBitmapBundle*> get_text_volume_bitmaps(); static std::vector<wxBitmapBundle*> get_text_volume_bitmaps();
static std::vector<wxBitmapBundle*> get_svg_volume_bitmaps(); static std::vector<wxBitmapBundle*> get_svg_volume_bitmaps();
static wxString get_repaire_result_message(const std::vector<std::string>& succes_models,
const std::vector<std::pair<std::string, std::string>>& failed_models);
MenuFactory(); MenuFactory();
~MenuFactory() = default; ~MenuFactory() = default;

View File

@ -4670,21 +4670,7 @@ void ObjectList::fix_through_winsdk()
progress_dlg.Update(100, ""); progress_dlg.Update(100, "");
// Show info notification // Show info notification
wxString msg; wxString msg = MenuFactory::get_repaire_result_message(succes_models, failed_models);
wxString bullet_suf = "\n - ";
if (!succes_models.empty()) {
msg = _L_PLURAL("The following model was repaired successfully", "The following models were repaired successfully", succes_models.size()) + ":";
for (auto& model : succes_models)
msg += bullet_suf + from_u8(model);
msg += "\n\n";
}
if (!failed_models.empty()) {
msg += _L_PLURAL("Folowing model repair failed", "Folowing models repair failed", failed_models.size()) + ":\n";
for (auto& model : failed_models)
msg += bullet_suf + from_u8(model.first) + ": " + _(model.second);
}
if (msg.IsEmpty())
msg = _L("Repairing was canceled");
plater->get_notification_manager()->push_notification(NotificationType::RepairFinished, NotificationManager::NotificationLevel::PrintInfoShortNotificationLevel, boost::nowide::narrow(msg)); plater->get_notification_manager()->push_notification(NotificationType::RepairFinished, NotificationManager::NotificationLevel::PrintInfoShortNotificationLevel, boost::nowide::narrow(msg));
} }

View File

@ -12,8 +12,10 @@
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/GUI_ObjectManipulation.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp"
#include "slic3r/GUI/GUI_Factories.hpp"
#include "slic3r/GUI/format.hpp" #include "slic3r/GUI/format.hpp"
#include "slic3r/Utils/UndoRedo.hpp" #include "slic3r/Utils/UndoRedo.hpp"
#include "slic3r/Utils/FixModelByWin10.hpp"
#include "libslic3r/AppConfig.hpp" #include "libslic3r/AppConfig.hpp"
#include "libslic3r/TriangleMeshSlicer.hpp" #include "libslic3r/TriangleMeshSlicer.hpp"
@ -3259,6 +3261,8 @@ void update_object_cut_id(CutObjectBase& cut_id, ModelObjectCutAttributes attrib
static void check_objects_after_cut(const ModelObjectPtrs& objects) static void check_objects_after_cut(const ModelObjectPtrs& objects)
{ {
std::vector<std::string> err_objects_names; std::vector<std::string> err_objects_names;
std::vector<int> err_objects_idxs;
int obj_idx{ 0 };
for (const ModelObject* object : objects) { for (const ModelObject* object : objects) {
std::vector<std::string> connectors_names; std::vector<std::string> connectors_names;
connectors_names.reserve(object->volumes.size()); connectors_names.reserve(object->volumes.size());
@ -3269,17 +3273,87 @@ static void check_objects_after_cut(const ModelObjectPtrs& objects)
sort_remove_duplicates(connectors_names); sort_remove_duplicates(connectors_names);
if (connectors_count != connectors_names.size()) if (connectors_count != connectors_names.size())
err_objects_names.push_back(object->name); err_objects_names.push_back(object->name);
}
if (err_objects_names.empty())
return;
wxString names = from_u8(err_objects_names[0]); // check manifol/repairs
for (size_t i = 1; i < err_objects_names.size(); i++) auto stats = object->get_object_stl_stats();
names += ", " + from_u8(err_objects_names[i]); if (!stats.manifold() || stats.repaired())
WarningDialog(wxGetApp().plater(), format_wxstr("Objects(%1%) have duplicated connectors. " err_objects_idxs.push_back(obj_idx);
"Some connectors may be missing in slicing result.\n" obj_idx++;
"Please report to PrusaSlicer team in which scenario this issue happened.\n" }
"Thank you.", names)).ShowModal();
auto plater = wxGetApp().plater();
if (!err_objects_names.empty()) {
wxString names = from_u8(err_objects_names[0]);
for (size_t i = 1; i < err_objects_names.size(); i++)
names += ", " + from_u8(err_objects_names[i]);
WarningDialog(plater, format_wxstr("Objects(%1%) have duplicated connectors. "
"Some connectors may be missing in slicing result.\n"
"Please report to PrusaSlicer team in which scenario this issue happened.\n"
"Thank you.", names)).ShowModal();
}
if (is_windows10() && !err_objects_idxs.empty()) {
auto dlg = WarningDialog(plater, _L("Cut is performed and open eages or auto-repaired errors are detected in result objects.\n"
"You can fix them by Windows repair algorithm.\n\n"
"Do you want to fix cut objects?"),
_L("Detected errors in cut objects"), wxYES_NO);
if (dlg.ShowModal() == wxID_YES) {
// model_name
std::vector<std::string> succes_models;
// model_name failing reason
std::vector<std::pair<std::string, std::string>> failed_models;
std::vector<std::string> model_names;
for (int obj_idx : err_objects_idxs)
model_names.push_back(objects[obj_idx]->name);
auto fix_and_update_progress = [plater, model_names, &objects](const int obj_idx, int model_idx,
wxProgressDialog& progress_dlg,
std::vector<std::string>& succes_models,
std::vector<std::pair<std::string, std::string>>& failed_models) -> bool
{
const std::string& model_name = model_names[model_idx];
wxString msg = _L("Repairing model");
if (model_names.size() == 1)
msg += ": " + from_u8(model_name) + "\n";
else {
msg += ":\n";
for (int i = 0; i < int(model_names.size()); ++i)
msg += (i == model_idx ? " > " : " ") + from_u8(model_names[i]) + "\n";
msg += "\n";
}
std::string res;
if (!fix_model_by_win10_sdk_gui(*objects[obj_idx], -1, progress_dlg, msg, res))
return false;
if (res.empty())
succes_models.push_back(model_name);
else
failed_models.push_back({ model_name, res });
return true;
};
// Open a progress dialog.
wxProgressDialog progress_dlg(_L("Fixing by Windows repair algorithm"), "", 100, find_toplevel_parent(plater),
wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
int model_idx{ 0 };
for (int obj_idx : err_objects_idxs) {
if (!fix_and_update_progress(obj_idx, model_idx, progress_dlg, succes_models, failed_models))
break;
model_idx++;
}
// Close the progress dialog
progress_dlg.Update(100, "");
// Show info dialog
wxString msg = MenuFactory::get_repaire_result_message(succes_models, failed_models);
InfoDialog(plater, _L("Repairing result"), msg).ShowModal();
}
}
} }
void synchronize_model_after_cut(Model& model, const CutObjectBase& cut_id) void synchronize_model_after_cut(Model& model, const CutObjectBase& cut_id)