Add notification if some objects are ignored after arrange
This commit is contained in:
parent
3fa78b52b2
commit
c30ac4b66f
@ -8,6 +8,8 @@
|
|||||||
#include "slic3r/GUI/GUI.hpp"
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
|
||||||
|
#include "slic3r/GUI/NotificationManager.hpp"
|
||||||
|
#include "slic3r/GUI/format.hpp"
|
||||||
|
|
||||||
#include "libnest2d/common.hpp"
|
#include "libnest2d/common.hpp"
|
||||||
|
|
||||||
@ -67,6 +69,7 @@ void ArrangeJob::clear_input()
|
|||||||
m_selected.clear();
|
m_selected.clear();
|
||||||
m_unselected.clear();
|
m_unselected.clear();
|
||||||
m_unprintable.clear();
|
m_unprintable.clear();
|
||||||
|
m_unarranged.clear();
|
||||||
m_selected.reserve(count + 1 /* for optional wti */);
|
m_selected.reserve(count + 1 /* for optional wti */);
|
||||||
m_unselected.reserve(count + 1 /* for optional wti */);
|
m_unselected.reserve(count + 1 /* for optional wti */);
|
||||||
m_unprintable.reserve(cunprint /* for optional wti */);
|
m_unprintable.reserve(cunprint /* for optional wti */);
|
||||||
@ -78,7 +81,7 @@ void ArrangeJob::prepare_all() {
|
|||||||
for (ModelObject *obj: m_plater->model().objects)
|
for (ModelObject *obj: m_plater->model().objects)
|
||||||
for (ModelInstance *mi : obj->instances) {
|
for (ModelInstance *mi : obj->instances) {
|
||||||
ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
|
ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
|
||||||
cont.emplace_back(get_arrange_poly(mi, m_plater));
|
cont.emplace_back(get_arrange_poly_(mi));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto wti = get_wipe_tower_arrangepoly(*m_plater))
|
if (auto wti = get_wipe_tower_arrangepoly(*m_plater))
|
||||||
@ -110,8 +113,8 @@ void ArrangeJob::prepare_selected() {
|
|||||||
inst_sel[size_t(inst_id)] = true;
|
inst_sel[size_t(inst_id)] = true;
|
||||||
|
|
||||||
for (size_t i = 0; i < inst_sel.size(); ++i) {
|
for (size_t i = 0; i < inst_sel.size(); ++i) {
|
||||||
ArrangePolygon &&ap =
|
ModelInstance * mi = mo->instances[i];
|
||||||
get_arrange_poly(mo->instances[i], m_plater);
|
ArrangePolygon &&ap = get_arrange_poly_(mi);
|
||||||
|
|
||||||
ArrangePolygons &cont = mo->instances[i]->printable ?
|
ArrangePolygons &cont = mo->instances[i]->printable ?
|
||||||
(inst_sel[i] ? m_selected :
|
(inst_sel[i] ? m_selected :
|
||||||
@ -139,6 +142,20 @@ void ArrangeJob::prepare_selected() {
|
|||||||
for (auto &p : m_unselected) p.translation(X) -= p.bed_idx * stride;
|
for (auto &p : m_unselected) p.translation(X) -= p.bed_idx * stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi)
|
||||||
|
{
|
||||||
|
arrangement::ArrangePolygon ap = get_arrange_poly(mi, m_plater);
|
||||||
|
|
||||||
|
auto setter = ap.setter;
|
||||||
|
ap.setter = [this, setter, mi](const arrangement::ArrangePolygon &set_ap) {
|
||||||
|
setter(set_ap);
|
||||||
|
if (!set_ap.is_arranged())
|
||||||
|
m_unarranged.emplace_back(mi);
|
||||||
|
};
|
||||||
|
|
||||||
|
return ap;
|
||||||
|
}
|
||||||
|
|
||||||
void ArrangeJob::prepare()
|
void ArrangeJob::prepare()
|
||||||
{
|
{
|
||||||
wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all();
|
wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all();
|
||||||
@ -187,6 +204,16 @@ void ArrangeJob::process()
|
|||||||
: _(L("Arranging done.")));
|
: _(L("Arranging done.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string concat_strings(const std::set<std::string> &strings,
|
||||||
|
const std::string &delim = "\n")
|
||||||
|
{
|
||||||
|
return std::accumulate(
|
||||||
|
strings.begin(), strings.end(), std::string(""),
|
||||||
|
[delim](const std::string &s, const std::string &name) {
|
||||||
|
return s + name + delim;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ArrangeJob::finalize() {
|
void ArrangeJob::finalize() {
|
||||||
// Ignore the arrange result if aborted.
|
// Ignore the arrange result if aborted.
|
||||||
if (was_canceled()) return;
|
if (was_canceled()) return;
|
||||||
@ -213,6 +240,16 @@ void ArrangeJob::finalize() {
|
|||||||
m_plater->update();
|
m_plater->update();
|
||||||
wxGetApp().obj_manipul()->set_dirty();
|
wxGetApp().obj_manipul()->set_dirty();
|
||||||
|
|
||||||
|
if (!m_unarranged.empty()) {
|
||||||
|
std::set<std::string> names;
|
||||||
|
for (ModelInstance *mi : m_unarranged)
|
||||||
|
names.insert(mi->get_object()->name);
|
||||||
|
|
||||||
|
m_plater->get_notification_manager()->push_notification(GUI::format(
|
||||||
|
_L("Arrangement ignored the following objects which can't fit into a single bed:\n%s"),
|
||||||
|
concat_strings(names, "\n")));
|
||||||
|
}
|
||||||
|
|
||||||
Job::finalize();
|
Job::finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ class ArrangeJob : public PlaterJob
|
|||||||
using ArrangePolygons = arrangement::ArrangePolygons;
|
using ArrangePolygons = arrangement::ArrangePolygons;
|
||||||
|
|
||||||
ArrangePolygons m_selected, m_unselected, m_unprintable;
|
ArrangePolygons m_selected, m_unselected, m_unprintable;
|
||||||
|
std::vector<ModelInstance*> m_unarranged;
|
||||||
|
|
||||||
// clear m_selected and m_unselected, reserve space for next usage
|
// clear m_selected and m_unselected, reserve space for next usage
|
||||||
void clear_input();
|
void clear_input();
|
||||||
@ -27,6 +28,8 @@ class ArrangeJob : public PlaterJob
|
|||||||
// selected, behaves as if everything would be selected.
|
// selected, behaves as if everything would be selected.
|
||||||
void prepare_selected();
|
void prepare_selected();
|
||||||
|
|
||||||
|
ArrangePolygon get_arrange_poly_(ModelInstance *mi);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
Loading…
Reference in New Issue
Block a user