mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 05:15:59 +08:00
Seq arrange now handles selected-bed-only arrange
This commit is contained in:
parent
0ac100cd2c
commit
ad29cd395b
@ -115,7 +115,7 @@ static Sequential::SolverConfiguration get_solver_config(const Sequential::Print
|
|||||||
return Sequential::SolverConfiguration(printer_geometry);
|
return Sequential::SolverConfiguration(printer_geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model& model, const Sequential::PrinterGeometry& printer_geometry)
|
static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model& model, const Sequential::PrinterGeometry& printer_geometry, int selected_bed)
|
||||||
{
|
{
|
||||||
// First extract the heights of interest.
|
// First extract the heights of interest.
|
||||||
std::vector<double> heights;
|
std::vector<double> heights;
|
||||||
@ -126,9 +126,16 @@ static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model&
|
|||||||
// Now collect all objects and projections of convex hull above respective heights.
|
// Now collect all objects and projections of convex hull above respective heights.
|
||||||
std::vector<std::pair<Sequential::ObjectToPrint, std::vector<Sequential::ObjectToPrint>>> objects; // first = object id, the vector = ids of its instances
|
std::vector<std::pair<Sequential::ObjectToPrint, std::vector<Sequential::ObjectToPrint>>> objects; // first = object id, the vector = ids of its instances
|
||||||
for (const ModelObject* mo : model.objects) {
|
for (const ModelObject* mo : model.objects) {
|
||||||
size_t inst_id = 0;
|
|
||||||
const TriangleMesh& raw_mesh = mo->raw_mesh();
|
const TriangleMesh& raw_mesh = mo->raw_mesh();
|
||||||
|
int inst_id = -1;
|
||||||
|
|
||||||
for (const ModelInstance* mi : mo->instances) {
|
for (const ModelInstance* mi : mo->instances) {
|
||||||
|
++inst_id;
|
||||||
|
if (selected_bed != -1) {
|
||||||
|
auto it = s_multiple_beds.get_inst_map().find(mi->id());
|
||||||
|
if (it == s_multiple_beds.get_inst_map().end() || it->second != selected_bed)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
coord_t height = scaled(mo->instance_bounding_box(inst_id).size().z());
|
coord_t height = scaled(mo->instance_bounding_box(inst_id).size().z());
|
||||||
Sequential::ObjectToPrint* new_object =
|
Sequential::ObjectToPrint* new_object =
|
||||||
(inst_id == 0 ? &objects.emplace_back(std::make_pair(Sequential::ObjectToPrint{int(mo->id().id), inst_id + 1 < mo->instances.size(), height, {}}, std::vector<Sequential::ObjectToPrint>())).first
|
(inst_id == 0 ? &objects.emplace_back(std::make_pair(Sequential::ObjectToPrint{int(mo->id().id), inst_id + 1 < mo->instances.size(), height, {}}, std::vector<Sequential::ObjectToPrint>())).first
|
||||||
@ -140,7 +147,6 @@ static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model&
|
|||||||
Polygon pgn = its_convex_hull_2d_above(raw_mesh.its, mi->get_matrix_no_offset().cast<float>(), height - mi->get_offset().z());
|
Polygon pgn = its_convex_hull_2d_above(raw_mesh.its, mi->get_matrix_no_offset().cast<float>(), height - mi->get_offset().z());
|
||||||
new_object->pgns_at_height.emplace_back(std::make_pair(scaled(height), pgn));
|
new_object->pgns_at_height.emplace_back(std::make_pair(scaled(height), pgn));
|
||||||
}
|
}
|
||||||
++inst_id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,21 +167,21 @@ static std::vector<Sequential::ObjectToPrint> get_objects_to_print(const Model&
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void arrange_model_sequential(Model& model, const ConfigBase& config)
|
void arrange_model_sequential(Model& model, const ConfigBase& config, bool current_bed_only)
|
||||||
{
|
{
|
||||||
SeqArrange seq_arrange(model, config);
|
SeqArrange seq_arrange(model, config, current_bed_only);
|
||||||
seq_arrange.process_seq_arrange([](int) {});
|
seq_arrange.process_seq_arrange([](int) {});
|
||||||
seq_arrange.apply_seq_arrange(model);
|
seq_arrange.apply_seq_arrange(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SeqArrange::SeqArrange(const Model& model, const ConfigBase& config)
|
SeqArrange::SeqArrange(const Model& model, const ConfigBase& config, bool current_bed_only)
|
||||||
{
|
{
|
||||||
|
m_selected_bed = current_bed_only ? s_multiple_beds.get_active_bed() : -1;
|
||||||
m_printer_geometry = get_printer_geometry(config);
|
m_printer_geometry = get_printer_geometry(config);
|
||||||
m_solver_configuration = get_solver_config(m_printer_geometry);
|
m_solver_configuration = get_solver_config(m_printer_geometry);
|
||||||
m_objects = get_objects_to_print(model, m_printer_geometry);
|
m_objects = get_objects_to_print(model, m_printer_geometry, m_selected_bed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -206,8 +212,16 @@ void SeqArrange::apply_seq_arrange(Model& model) const
|
|||||||
// Save the move data from this file to move_data_all.
|
// Save the move data from this file to move_data_all.
|
||||||
size_t bed_idx = 0;
|
size_t bed_idx = 0;
|
||||||
for (const Sequential::ScheduledPlate& plate : m_plates) {
|
for (const Sequential::ScheduledPlate& plate : m_plates) {
|
||||||
Vec3d bed_offset = s_multiple_beds.get_bed_translation(bed_idx);
|
int real_bed = bed_idx;
|
||||||
// Iterate the same way as when exporting.
|
|
||||||
|
if (m_selected_bed != -1) {
|
||||||
|
if (bed_idx == 0)
|
||||||
|
real_bed = m_selected_bed;
|
||||||
|
else
|
||||||
|
real_bed += s_multiple_beds.get_number_of_beds() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3d bed_offset = s_multiple_beds.get_bed_translation(real_bed);
|
||||||
for (ModelObject* mo : model.objects) {
|
for (ModelObject* mo : model.objects) {
|
||||||
for (ModelInstance* mi : mo->instances) {
|
for (ModelInstance* mi : mo->instances) {
|
||||||
const ObjectID& oid = (mi == mo->instances.front() ? mo->id() : mi->id());
|
const ObjectID& oid = (mi == mo->instances.front() ? mo->id() : mi->id());
|
||||||
@ -218,10 +232,12 @@ void SeqArrange::apply_seq_arrange(Model& model) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const Sequential::ScheduledObject& object : plate.scheduled_objects)
|
for (const Sequential::ScheduledObject& object : plate.scheduled_objects)
|
||||||
move_data_all.push_back({ object, bed_idx });
|
move_data_all.push_back({ object, size_t(real_bed) });
|
||||||
++bed_idx;
|
++bed_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Now reorder the objects in the model so they are in the same order as requested.
|
// Now reorder the objects in the model so they are in the same order as requested.
|
||||||
auto comp = [&move_data_all](ModelObject* mo1, ModelObject* mo2) {
|
auto comp = [&move_data_all](ModelObject* mo1, ModelObject* mo2) {
|
||||||
auto it1 = std::find_if(move_data_all.begin(), move_data_all.end(), [&mo1](const auto& md) { return md.scheduled_object.id == mo1->id().id; });
|
auto it1 = std::find_if(move_data_all.begin(), move_data_all.end(), [&mo1](const auto& md) { return md.scheduled_object.id == mo1->id().id; });
|
||||||
@ -241,7 +257,7 @@ bool check_seq_printability(const Model& model, const ConfigBase& config)
|
|||||||
{
|
{
|
||||||
Sequential::PrinterGeometry printer_geometry = get_printer_geometry(config);
|
Sequential::PrinterGeometry printer_geometry = get_printer_geometry(config);
|
||||||
Sequential::SolverConfiguration solver_config = get_solver_config(printer_geometry);
|
Sequential::SolverConfiguration solver_config = get_solver_config(printer_geometry);
|
||||||
std::vector<Sequential::ObjectToPrint> objects = get_objects_to_print(model, printer_geometry);
|
std::vector<Sequential::ObjectToPrint> objects = get_objects_to_print(model, printer_geometry, -1);
|
||||||
|
|
||||||
if (printer_geometry.extruder_slices.empty()) {
|
if (printer_geometry.extruder_slices.empty()) {
|
||||||
// If there are no data for extruder (such as extruder_clearance_radius set to 0),
|
// If there are no data for extruder (such as extruder_clearance_radius set to 0),
|
||||||
|
@ -19,7 +19,7 @@ namespace Slic3r {
|
|||||||
// into a separate thread without copying the Model or sharing it with UI thread.
|
// into a separate thread without copying the Model or sharing it with UI thread.
|
||||||
class SeqArrange {
|
class SeqArrange {
|
||||||
public:
|
public:
|
||||||
explicit SeqArrange(const Model& model, const ConfigBase& config);
|
explicit SeqArrange(const Model& model, const ConfigBase& config, bool current_bed_only);
|
||||||
void process_seq_arrange(std::function<void(int)> progress_fn);
|
void process_seq_arrange(std::function<void(int)> progress_fn);
|
||||||
void apply_seq_arrange(Model& model) const;
|
void apply_seq_arrange(Model& model) const;
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ namespace Slic3r {
|
|||||||
Sequential::PrinterGeometry m_printer_geometry;
|
Sequential::PrinterGeometry m_printer_geometry;
|
||||||
Sequential::SolverConfiguration m_solver_configuration;
|
Sequential::SolverConfiguration m_solver_configuration;
|
||||||
std::vector<Sequential::ObjectToPrint> m_objects;
|
std::vector<Sequential::ObjectToPrint> m_objects;
|
||||||
|
int m_selected_bed = -1;
|
||||||
|
|
||||||
// This is the output, filled in by process_seq_arrange.
|
// This is the output, filled in by process_seq_arrange.
|
||||||
std::vector<Sequential::ScheduledPlate> m_plates;
|
std::vector<Sequential::ScheduledPlate> m_plates;
|
||||||
|
@ -1342,10 +1342,10 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas *canvas, Bed3D &bed)
|
|||||||
return this->is_arrange_alignment_enabled();
|
return this->is_arrange_alignment_enabled();
|
||||||
});
|
});
|
||||||
m_arrange_settings_dialog.on_arrange_btn([]{
|
m_arrange_settings_dialog.on_arrange_btn([]{
|
||||||
wxGetApp().plater()->arrange();
|
wxGetApp().plater()->arrange(false);
|
||||||
});
|
});
|
||||||
m_arrange_settings_dialog.on_arrange_bed_btn([]{
|
m_arrange_settings_dialog.on_arrange_bed_btn([]{
|
||||||
wxGetApp().plater()->arrange_current_bed();
|
wxGetApp().plater()->arrange(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
SeqArrangeJob::SeqArrangeJob(const Model& model, const DynamicPrintConfig& config)
|
SeqArrangeJob::SeqArrangeJob(const Model& model, const DynamicPrintConfig& config, bool current_bed_only)
|
||||||
{
|
{
|
||||||
m_seq_arrange.reset(new SeqArrange(model, config));
|
m_seq_arrange.reset(new SeqArrange(model, config, current_bed_only));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ namespace GUI {
|
|||||||
class SeqArrangeJob : public Job
|
class SeqArrangeJob : public Job
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SeqArrangeJob(const Model& model, const DynamicPrintConfig& config);
|
explicit SeqArrangeJob(const Model& model, const DynamicPrintConfig& config, bool current_bed_only);
|
||||||
virtual void process(Ctl &ctl) override;
|
virtual void process(Ctl &ctl) override;
|
||||||
virtual void finalize(bool /*canceled*/, std::exception_ptr&) override;
|
virtual void finalize(bool /*canceled*/, std::exception_ptr&) override;
|
||||||
|
|
||||||
|
@ -715,8 +715,8 @@ void Plater::priv::init()
|
|||||||
view3D_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this);
|
view3D_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this);
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this);
|
view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this);
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [this](SimpleEvent&) { q->remove_selected(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [this](SimpleEvent&) { q->remove_selected(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { this->q->arrange(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { this->q->arrange(false); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE_CURRENT_BED, [this](SimpleEvent&) { this->q->arrange_current_bed(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE_CURRENT_BED, [this](SimpleEvent&) { this->q->arrange(true); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_SELECT_ALL, [this](SimpleEvent&) { this->q->select_all(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_SELECT_ALL, [this](SimpleEvent&) { this->q->select_all(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); });
|
view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); });
|
||||||
view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event<int>& evt)
|
view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event<int>& evt)
|
||||||
@ -747,8 +747,8 @@ void Plater::priv::init()
|
|||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [this](SimpleEvent&) { q->remove_selected(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [this](SimpleEvent&) { q->remove_selected(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { delete_all_objects_from_model(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { delete_all_objects_from_model(); });
|
||||||
// view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [q](SimpleEvent&) { q->reset_with_confirm(); });
|
// view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [q](SimpleEvent&) { q->reset_with_confirm(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { this->q->arrange(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { this->q->arrange(false); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE_CURRENT_BED, [this](SimpleEvent&) { this->q->arrange_current_bed(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE_CURRENT_BED, [this](SimpleEvent&) { this->q->arrange(true); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [this](SimpleEvent&) { q->copy_selection_to_clipboard(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [this](SimpleEvent&) { q->copy_selection_to_clipboard(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [this](SimpleEvent&) { q->paste_from_clipboard(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [this](SimpleEvent&) { q->paste_from_clipboard(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [this](SimpleEvent&) { q->increase_instances(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [this](SimpleEvent&) { q->increase_instances(); });
|
||||||
@ -7111,19 +7111,19 @@ static std::string concat_strings(const std::set<std::string> &strings,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::arrange()
|
void Plater::arrange(bool current_bed_only)
|
||||||
{
|
{
|
||||||
const auto mode{
|
ArrangeSelectionMode mode;
|
||||||
wxGetKeyState(WXK_SHIFT) ?
|
if (current_bed_only)
|
||||||
ArrangeSelectionMode::SelectionOnly :
|
mode = wxGetKeyState(WXK_SHIFT) ? ArrangeSelectionMode::CurrentBedSelectionOnly : ArrangeSelectionMode::CurrentBedFull;
|
||||||
ArrangeSelectionMode::Full
|
else
|
||||||
};
|
mode = wxGetKeyState(WXK_SHIFT) ? ArrangeSelectionMode::SelectionOnly : ArrangeSelectionMode::Full;
|
||||||
|
|
||||||
const bool sequential = p->config->has("complete_objects") && p->config->opt_bool("complete_objects");
|
const bool sequential = p->config->has("complete_objects") && p->config->opt_bool("complete_objects");
|
||||||
|
|
||||||
if (p->can_arrange()) {
|
if (p->can_arrange()) {
|
||||||
if (sequential)
|
if (sequential)
|
||||||
replace_job(this->get_ui_job_worker(), std::make_unique<SeqArrangeJob>(this->model(), *p->config));
|
replace_job(this->get_ui_job_worker(), std::make_unique<SeqArrangeJob>(this->model(), *p->config, current_bed_only));
|
||||||
else {
|
else {
|
||||||
auto& w = get_ui_job_worker();
|
auto& w = get_ui_job_worker();
|
||||||
arrange(w, mode);
|
arrange(w, mode);
|
||||||
@ -7131,19 +7131,6 @@ void Plater::arrange()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::arrange_current_bed()
|
|
||||||
{
|
|
||||||
const auto mode{
|
|
||||||
wxGetKeyState(WXK_SHIFT) ?
|
|
||||||
ArrangeSelectionMode::CurrentBedSelectionOnly :
|
|
||||||
ArrangeSelectionMode::CurrentBedFull
|
|
||||||
};
|
|
||||||
if (p->can_arrange()) {
|
|
||||||
auto &w = get_ui_job_worker();
|
|
||||||
arrange(w, mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Plater::arrange(Worker &w, const ArrangeSelectionMode &mode)
|
void Plater::arrange(Worker &w, const ArrangeSelectionMode &mode)
|
||||||
{
|
{
|
||||||
arr2::Scene arrscene{build_scene(*this, mode)};
|
arr2::Scene arrscene{build_scene(*this, mode)};
|
||||||
@ -7731,7 +7718,7 @@ PlaterAfterLoadAutoArrange::PlaterAfterLoadAutoArrange()
|
|||||||
PlaterAfterLoadAutoArrange::~PlaterAfterLoadAutoArrange()
|
PlaterAfterLoadAutoArrange::~PlaterAfterLoadAutoArrange()
|
||||||
{
|
{
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
wxGetApp().plater()->arrange();
|
wxGetApp().plater()->arrange(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace Slic3r::GUI
|
}} // namespace Slic3r::GUI
|
||||||
|
@ -305,8 +305,7 @@ public:
|
|||||||
|
|
||||||
void render_sliders(GLCanvas3D& canvas);
|
void render_sliders(GLCanvas3D& canvas);
|
||||||
|
|
||||||
void arrange();
|
void arrange(bool current_bed_only);
|
||||||
void arrange_current_bed();
|
|
||||||
void arrange(Worker &w, const ArrangeSelectionMode &selected);
|
void arrange(Worker &w, const ArrangeSelectionMode &selected);
|
||||||
|
|
||||||
void set_current_canvas_as_dirty();
|
void set_current_canvas_as_dirty();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user