Add arrange support for unprintable items

This commit is contained in:
tamasmeszaros 2020-03-09 14:05:54 +01:00
parent cbd80685c2
commit c489663126

View file

@ -1509,6 +1509,7 @@ struct Plater::priv
ret.poly.contour = std::move(p); ret.poly.contour = std::move(p);
ret.translation = scaled(m_pos); ret.translation = scaled(m_pos);
ret.rotation = m_rotation; ret.rotation = m_rotation;
ret.priority++;
return ret; return ret;
} }
} wipetower; } wipetower;
@ -1572,18 +1573,23 @@ struct Plater::priv
// the current bed width. // the current bed width.
static const constexpr double LOGICAL_BED_GAP = 1. / 5.; static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
ArrangePolygons m_selected, m_unselected; ArrangePolygons m_selected, m_unselected, m_unprintable;
// 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() {
const Model &model = plater().model; const Model &model = plater().model;
size_t count = 0; // To know how much space to reserve size_t count = 0, cunprint = 0; // To know how much space to reserve
for (auto obj : model.objects) count += obj->instances.size(); for (auto obj : model.objects)
for (auto mi : obj->instances)
mi->printable ? count++ : cunprint++;
m_selected.clear(); m_selected.clear();
m_unselected.clear(); m_unselected.clear();
m_unprintable.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 */);
} }
// Stride between logical beds // Stride between logical beds
@ -1612,8 +1618,10 @@ struct Plater::priv
clear_input(); clear_input();
for (ModelObject *obj: plater().model.objects) for (ModelObject *obj: plater().model.objects)
for (ModelInstance *mi : obj->instances) for (ModelInstance *mi : obj->instances) {
m_selected.emplace_back(get_arrange_poly(mi)); ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
cont.emplace_back(get_arrange_poly(mi));
}
auto& wti = plater().updated_wipe_tower(); auto& wti = plater().updated_wipe_tower();
if (wti) m_selected.emplace_back(get_arrange_poly(&wti)); if (wti) m_selected.emplace_back(get_arrange_poly(&wti));
@ -1648,9 +1656,12 @@ struct Plater::priv
for (size_t i = 0; i < inst_sel.size(); ++i) { for (size_t i = 0; i < inst_sel.size(); ++i) {
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]); ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]);
inst_sel[i] ? ArrangePolygons &cont = mo->instances[i]->printable ?
m_selected.emplace_back(std::move(ap)) : (inst_sel[i] ? m_selected :
m_unselected.emplace_back(std::move(ap)); m_unselected) :
m_unprintable;
cont.emplace_back(std::move(ap));
} }
} }
@ -1682,16 +1693,35 @@ struct Plater::priv
public: public:
using PlaterJob::PlaterJob; using PlaterJob::PlaterJob;
int status_range() const override { return int(m_selected.size()); } int status_range() const override
{
return int(m_selected.size() + m_unprintable.size());
}
void process() override; void process() override;
void finalize() override { void finalize() override {
// Ignore the arrange result if aborted. // Ignore the arrange result if aborted.
if (was_canceled()) return; if (was_canceled()) return;
// Unprintable items go to the last virtual bed
int beds = 0;
// Apply the arrange result to all selected objects // Apply the arrange result to all selected objects
for (ArrangePolygon &ap : m_selected) ap.apply(); for (ArrangePolygon &ap : m_selected) {
beds = std::max(ap.bed_idx, beds);
ap.apply();
}
// Get the virtual beds from the unselected items
for (ArrangePolygon &ap : m_unselected)
beds = std::max(ap.bed_idx, beds);
// Move the unprintable items to the last virtual bed.
for (ArrangePolygon &ap : m_unprintable) {
ap.bed_idx += beds + 1;
ap.apply();
}
plater().update(); plater().update();
} }
@ -2838,16 +2868,21 @@ void Plater::priv::ArrangeJob::process() {
} }
coord_t min_d = scaled(dist); coord_t min_d = scaled(dist);
auto count = unsigned(m_selected.size()); auto count = unsigned(m_selected.size() + m_unprintable.size());
arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint(); arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint();
auto stopfn = [this]() { return was_canceled(); };
try { try {
arrangement::arrange(m_selected, m_unselected, min_d, bedshape, arrangement::arrange(m_selected, m_unselected, min_d, bedshape,
[this, count](unsigned st) { [this, count](unsigned st) {
if (st > 0) // will not finalize after last one st += m_unprintable.size();
update_status(int(count - st), arrangestr); if (st > 0) update_status(int(count - st), arrangestr);
}, }, stopfn);
[this]() { return was_canceled(); }); arrangement::arrange(m_unprintable, {}, min_d, bedshape,
[this, count](unsigned st) {
if (st > 0) update_status(int(count - st), arrangestr);
}, stopfn);
} catch (std::exception & /*e*/) { } catch (std::exception & /*e*/) {
GUI::show_error(plater().q, GUI::show_error(plater().q,
_(L("Could not arrange model objects! " _(L("Could not arrange model objects! "