ENH: merge all error when multi obj have empty layer
Change-Id: Iff091babff67050fe512a3cffe6cb2af0e91efa5 STUDIO-2540 (cherry picked from commit e23781245e3a6ae9bffcff869aa8991eb0298243) Change-Id: Ia90ffa1244ef8a89c8d3007ca65b68439b09249b
This commit is contained in:
parent
81319b6a9e
commit
35d6b072d3
|
@ -2,6 +2,7 @@
|
||||||
#define _libslic3r_Exception_h_
|
#define _libslic3r_Exception_h_
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
@ -35,6 +36,16 @@ public:
|
||||||
private:
|
private:
|
||||||
size_t objectId_ = 0;
|
size_t objectId_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SlicingErrors : public Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Exception::Exception;
|
||||||
|
SlicingErrors(const std::vector<SlicingError> &errors) : Exception("Errors"), errors_(errors) {}
|
||||||
|
|
||||||
|
std::vector<SlicingError> errors_;
|
||||||
|
};
|
||||||
|
|
||||||
#undef SLIC3R_DERIVE_EXCEPTION
|
#undef SLIC3R_DERIVE_EXCEPTION
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -808,7 +808,7 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
||||||
// first layer may result in skirt/brim in the air and maybe other issues.
|
// first layer may result in skirt/brim in the air and maybe other issues.
|
||||||
if (layers_to_print.size() == 1u) {
|
if (layers_to_print.size() == 1u) {
|
||||||
if (!has_extrusions)
|
if (!has_extrusions)
|
||||||
throw Slic3r::SlicingError(_(L("One object has empty initial layer and can't be printed. Please Cut the bottom or enable supports.")), object.id().id);
|
throw Slic3r::SlicingError(_(L("The following object(s) have empty initial layer and can't be printed. Please Cut the bottom or enable supports.")), object.id().id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case there are extrusions on this layer, check there is a layer to lay it on.
|
// In case there are extrusions on this layer, check there is a layer to lay it on.
|
||||||
|
@ -863,8 +863,16 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
|
||||||
|
|
||||||
std::vector<std::vector<LayerToPrint>> per_object(print.objects().size(), std::vector<LayerToPrint>());
|
std::vector<std::vector<LayerToPrint>> per_object(print.objects().size(), std::vector<LayerToPrint>());
|
||||||
std::vector<OrderingItem> ordering;
|
std::vector<OrderingItem> ordering;
|
||||||
|
|
||||||
|
std::vector<Slic3r::SlicingError> errors;
|
||||||
|
|
||||||
for (size_t i = 0; i < print.objects().size(); ++i) {
|
for (size_t i = 0; i < print.objects().size(); ++i) {
|
||||||
per_object[i] = collect_layers_to_print(*print.objects()[i]);
|
try {
|
||||||
|
per_object[i] = collect_layers_to_print(*print.objects()[i]);
|
||||||
|
} catch (const Slic3r::SlicingError &e) {
|
||||||
|
errors.push_back(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
OrderingItem ordering_item;
|
OrderingItem ordering_item;
|
||||||
ordering_item.object_idx = i;
|
ordering_item.object_idx = i;
|
||||||
ordering.reserve(ordering.size() + per_object[i].size());
|
ordering.reserve(ordering.size() + per_object[i].size());
|
||||||
|
@ -876,6 +884,8 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!errors.empty()) { throw Slic3r::SlicingErrors(errors); }
|
||||||
|
|
||||||
std::sort(ordering.begin(), ordering.end(), [](const OrderingItem& oi1, const OrderingItem& oi2) { return oi1.print_z < oi2.print_z; });
|
std::sort(ordering.begin(), ordering.end(), [](const OrderingItem& oi1, const OrderingItem& oi2) { return oi1.print_z < oi2.print_z; });
|
||||||
|
|
||||||
std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print;
|
std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print;
|
||||||
|
|
|
@ -46,9 +46,10 @@ bool SlicingProcessCompletedEvent::critical_error() const
|
||||||
} catch (const Slic3r::SlicingError &) {
|
} catch (const Slic3r::SlicingError &) {
|
||||||
// Exception derived from SlicingError is non-critical.
|
// Exception derived from SlicingError is non-critical.
|
||||||
return false;
|
return false;
|
||||||
} catch (...) {
|
} catch (const Slic3r::SlicingErrors &) {
|
||||||
}
|
return false;
|
||||||
return true;
|
} catch (...) {}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SlicingProcessCompletedEvent::invalidate_plater() const
|
bool SlicingProcessCompletedEvent::invalidate_plater() const
|
||||||
|
@ -69,7 +70,7 @@ bool SlicingProcessCompletedEvent::invalidate_plater() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string, size_t> SlicingProcessCompletedEvent::format_error_message() const
|
std::pair<std::string, std::vector<size_t>> SlicingProcessCompletedEvent::format_error_message() const
|
||||||
{
|
{
|
||||||
std::string error;
|
std::string error;
|
||||||
size_t monospace = 0;
|
size_t monospace = 0;
|
||||||
|
@ -88,12 +89,20 @@ std::pair<std::string, size_t> SlicingProcessCompletedEvent::format_error_messag
|
||||||
} catch (SlicingError &ex) {
|
} catch (SlicingError &ex) {
|
||||||
error = ex.what();
|
error = ex.what();
|
||||||
monospace = ex.objectId();
|
monospace = ex.objectId();
|
||||||
|
} catch (SlicingErrors &exs) {
|
||||||
|
std::vector<size_t> ids;
|
||||||
|
for (auto &ex : exs.errors_) {
|
||||||
|
error = ex.what();
|
||||||
|
monospace = ex.objectId();
|
||||||
|
ids.push_back(monospace);
|
||||||
|
}
|
||||||
|
return std::make_pair(std::move(error), ids);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
error = ex.what();
|
error = ex.what();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
error = "Unknown C++ exception.";
|
error = "Unknown C++ exception.";
|
||||||
}
|
}
|
||||||
return std::make_pair(std::move(error), monospace);
|
return std::make_pair(std::move(error), std::vector<size_t>{monospace});
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundSlicingProcess::BackgroundSlicingProcess()
|
BackgroundSlicingProcess::BackgroundSlicingProcess()
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
void rethrow_exception() const { assert(this->error()); assert(m_exception); std::rethrow_exception(m_exception); }
|
void rethrow_exception() const { assert(this->error()); assert(m_exception); std::rethrow_exception(m_exception); }
|
||||||
// Produce a human readable message to be displayed by a notification or a message box.
|
// Produce a human readable message to be displayed by a notification or a message box.
|
||||||
// 2nd parameter defines whether the output should be displayed with a monospace font.
|
// 2nd parameter defines whether the output should be displayed with a monospace font.
|
||||||
std::pair<std::string, size_t> format_error_message() const;
|
std::pair<std::string, std::vector<size_t>> format_error_message() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StatusType m_status;
|
StatusType m_status;
|
||||||
|
|
|
@ -8945,7 +8945,7 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||||
break;
|
break;
|
||||||
case SLICING_ERROR:
|
case SLICING_ERROR:
|
||||||
if (state)
|
if (state)
|
||||||
notification_manager.push_slicing_error_notification(text, conflictObj);
|
notification_manager.push_slicing_error_notification(text, {conflictObj});
|
||||||
else
|
else
|
||||||
notification_manager.close_slicing_error_notification(text);
|
notification_manager.close_slicing_error_notification(text);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1630,19 +1630,33 @@ void NotificationManager::push_validate_error_notification(StringObjectException
|
||||||
set_slicing_progress_hidden();
|
set_slicing_progress_hidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::push_slicing_error_notification(const std::string &text, ModelObject const *obj)
|
void NotificationManager::push_slicing_error_notification(const std::string &text, std::vector<ModelObject const *> objs)
|
||||||
{
|
{
|
||||||
auto callback = obj ? [id = obj->id()](wxEvtHandler *) {
|
std::vector<ObjectID> ids;
|
||||||
|
for (auto optr : objs) { ids.push_back(optr->id()); }
|
||||||
|
auto callback = !objs.empty() ? [ids](wxEvtHandler *) {
|
||||||
auto & objects = wxGetApp().model().objects;
|
auto & objects = wxGetApp().model().objects;
|
||||||
auto iter = std::find_if(objects.begin(), objects.end(), [id](auto o) { return o->id() == id; });
|
std::vector<ObjectVolumeID> ovs;
|
||||||
if (iter != objects.end()) {
|
for (auto id : ids) {
|
||||||
wxGetApp().obj_list()->select_items({{*iter, nullptr}});
|
auto iter = std::find_if(objects.begin(), objects.end(), [id](auto o) { return o->id() == id; });
|
||||||
|
if (iter != objects.end()) { ovs.push_back({*iter, nullptr}); }
|
||||||
|
}
|
||||||
|
if (!ovs.empty()) {
|
||||||
|
wxGetApp().obj_list()->select_items(ovs);
|
||||||
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
|
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} : std::function<bool(wxEvtHandler *)>();
|
} : std::function<bool(wxEvtHandler *)>();
|
||||||
auto link = callback ? _u8L("Jump to") : "";
|
auto link = callback ? _u8L("Jump to") : "";
|
||||||
if (obj) link += std::string(" [") + obj->name + "]";
|
if (!objs.empty()) {
|
||||||
|
link += " [";
|
||||||
|
for (auto obj : objs) { link += obj->name + ", "; }
|
||||||
|
if (!objs.empty()) {
|
||||||
|
link.pop_back();
|
||||||
|
link.pop_back();
|
||||||
|
}
|
||||||
|
link += "] ";
|
||||||
|
}
|
||||||
set_all_slicing_errors_gray(false);
|
set_all_slicing_errors_gray(false);
|
||||||
push_notification_data({ NotificationType::SlicingError, NotificationLevel::ErrorNotificationLevel, 0, _u8L("Error:") + "\n" + text, link, callback }, 0);
|
push_notification_data({ NotificationType::SlicingError, NotificationLevel::ErrorNotificationLevel, 0, _u8L("Error:") + "\n" + text, link, callback }, 0);
|
||||||
set_slicing_progress_hidden();
|
set_slicing_progress_hidden();
|
||||||
|
|
|
@ -192,7 +192,7 @@ public:
|
||||||
void upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host);
|
void upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host);
|
||||||
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
|
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
|
||||||
// Creates Slicing Error notification with a custom text and no fade out.
|
// Creates Slicing Error notification with a custom text and no fade out.
|
||||||
void push_slicing_error_notification(const std::string &text, ModelObject const *obj);
|
void push_slicing_error_notification(const std::string &text, std::vector<ModelObject const *> objs);
|
||||||
// Creates Slicing Warning notification with a custom text and no fade out.
|
// Creates Slicing Warning notification with a custom text and no fade out.
|
||||||
void push_slicing_warning_notification(const std::string &text, bool gray, ModelObject const *obj, ObjectID oid, int warning_step, int warning_msg_id);
|
void push_slicing_warning_notification(const std::string &text, bool gray, ModelObject const *obj, ObjectID oid, int warning_step, int warning_msg_id);
|
||||||
// marks slicing errors as gray
|
// marks slicing errors as gray
|
||||||
|
|
|
@ -5878,21 +5878,24 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
|
||||||
// This bool stops showing export finished notification even when process_completed_with_error is false
|
// This bool stops showing export finished notification even when process_completed_with_error is false
|
||||||
bool has_error = false;
|
bool has_error = false;
|
||||||
if (evt.error()) {
|
if (evt.error()) {
|
||||||
std::pair<std::string, size_t> message = evt.format_error_message();
|
auto message = evt.format_error_message();
|
||||||
if (evt.critical_error()) {
|
if (evt.critical_error()) {
|
||||||
if (q->m_tracking_popup_menu) {
|
if (q->m_tracking_popup_menu) {
|
||||||
// We don't want to pop-up a message box when tracking a pop-up menu.
|
// We don't want to pop-up a message box when tracking a pop-up menu.
|
||||||
// We postpone the error message instead.
|
// We postpone the error message instead.
|
||||||
q->m_tracking_popup_menu_error_message = message.first;
|
q->m_tracking_popup_menu_error_message = message.first;
|
||||||
} else {
|
} else {
|
||||||
show_error(q, message.first, message.second != 0);
|
show_error(q, message.first, message.second.size() != 0 && message.second[0] != 0);
|
||||||
notification_manager->set_slicing_progress_hidden();
|
notification_manager->set_slicing_progress_hidden();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ModelObject const *model_object = nullptr;
|
std::vector<const ModelObject *> ptrs;
|
||||||
const PrintObject *print_object = this->background_process.m_fff_print->get_object(ObjectID(message.second));
|
for (auto oid : message.second)
|
||||||
if (print_object) model_object = print_object->model_object();
|
{
|
||||||
notification_manager->push_slicing_error_notification(message.first, model_object);
|
const PrintObject *print_object = this->background_process.m_fff_print->get_object(ObjectID(oid));
|
||||||
|
if (print_object) { ptrs.push_back(print_object->model_object()); }
|
||||||
|
}
|
||||||
|
notification_manager->push_slicing_error_notification(message.first, ptrs);
|
||||||
}
|
}
|
||||||
if (evt.invalidate_plater())
|
if (evt.invalidate_plater())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue