mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-13 05:28: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);
|
||||
}
|
||||
|
||||
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.
|
||||
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.
|
||||
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) {
|
||||
size_t inst_id = 0;
|
||||
const TriangleMesh& raw_mesh = mo->raw_mesh();
|
||||
int inst_id = -1;
|
||||
|
||||
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());
|
||||
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
|
||||
@ -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());
|
||||
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.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_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.
|
||||
size_t bed_idx = 0;
|
||||
for (const Sequential::ScheduledPlate& plate : m_plates) {
|
||||
Vec3d bed_offset = s_multiple_beds.get_bed_translation(bed_idx);
|
||||
// Iterate the same way as when exporting.
|
||||
int real_bed = bed_idx;
|
||||
|
||||
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 (ModelInstance* mi : mo->instances) {
|
||||
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)
|
||||
move_data_all.push_back({ object, bed_idx });
|
||||
move_data_all.push_back({ object, size_t(real_bed) });
|
||||
++bed_idx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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 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::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 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.
|
||||
class SeqArrange {
|
||||
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 apply_seq_arrange(Model& model) const;
|
||||
|
||||
@ -28,6 +28,7 @@ namespace Slic3r {
|
||||
Sequential::PrinterGeometry m_printer_geometry;
|
||||
Sequential::SolverConfiguration m_solver_configuration;
|
||||
std::vector<Sequential::ObjectToPrint> m_objects;
|
||||
int m_selected_bed = -1;
|
||||
|
||||
// This is the output, filled in by process_seq_arrange.
|
||||
std::vector<Sequential::ScheduledPlate> m_plates;
|
||||
|
@ -1342,10 +1342,10 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas *canvas, Bed3D &bed)
|
||||
return this->is_arrange_alignment_enabled();
|
||||
});
|
||||
m_arrange_settings_dialog.on_arrange_btn([]{
|
||||
wxGetApp().plater()->arrange();
|
||||
wxGetApp().plater()->arrange(false);
|
||||
});
|
||||
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 {
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
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 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_RIGHT_CLICK, &priv::on_right_click, this);
|
||||
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_CURRENT_BED, [this](SimpleEvent&) { this->q->arrange_current_bed(); });
|
||||
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(true); });
|
||||
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_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_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_ARRANGE, [this](SimpleEvent&) { this->q->arrange(); });
|
||||
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE_CURRENT_BED, [this](SimpleEvent&) { this->q->arrange_current_bed(); });
|
||||
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(true); });
|
||||
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_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{
|
||||
wxGetKeyState(WXK_SHIFT) ?
|
||||
ArrangeSelectionMode::SelectionOnly :
|
||||
ArrangeSelectionMode::Full
|
||||
};
|
||||
ArrangeSelectionMode mode;
|
||||
if (current_bed_only)
|
||||
mode = wxGetKeyState(WXK_SHIFT) ? ArrangeSelectionMode::CurrentBedSelectionOnly : ArrangeSelectionMode::CurrentBedFull;
|
||||
else
|
||||
mode = wxGetKeyState(WXK_SHIFT) ? ArrangeSelectionMode::SelectionOnly : ArrangeSelectionMode::Full;
|
||||
|
||||
const bool sequential = p->config->has("complete_objects") && p->config->opt_bool("complete_objects");
|
||||
|
||||
if (p->can_arrange()) {
|
||||
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 {
|
||||
auto& w = get_ui_job_worker();
|
||||
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)
|
||||
{
|
||||
arr2::Scene arrscene{build_scene(*this, mode)};
|
||||
@ -7731,7 +7718,7 @@ PlaterAfterLoadAutoArrange::PlaterAfterLoadAutoArrange()
|
||||
PlaterAfterLoadAutoArrange::~PlaterAfterLoadAutoArrange()
|
||||
{
|
||||
if (m_enabled)
|
||||
wxGetApp().plater()->arrange();
|
||||
wxGetApp().plater()->arrange(false);
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
@ -305,8 +305,7 @@ public:
|
||||
|
||||
void render_sliders(GLCanvas3D& canvas);
|
||||
|
||||
void arrange();
|
||||
void arrange_current_bed();
|
||||
void arrange(bool current_bed_only);
|
||||
void arrange(Worker &w, const ArrangeSelectionMode &selected);
|
||||
|
||||
void set_current_canvas_as_dirty();
|
||||
|
Loading…
x
Reference in New Issue
Block a user