mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-04 00:50:40 +08:00
Multiple beds: Fixed behaviour with empty beds and non-printable instances
This commit is contained in:
parent
4f7366045e
commit
1a608da2ae
@ -1661,7 +1661,7 @@ unsigned int ModelObject::update_instances_print_volume_state(const BuildVolume
|
||||
if (inside_outside == INSIDE)
|
||||
++num_printable;
|
||||
if (bed_idx != -1)
|
||||
s_multiple_beds.set_instance_bed(model_instance->id(), bed_idx);
|
||||
s_multiple_beds.set_instance_bed(model_instance->id(), model_instance->printable, bed_idx);
|
||||
}
|
||||
return num_printable;
|
||||
}
|
||||
|
@ -115,12 +115,16 @@ Vec3d MultipleBeds::get_bed_translation(int id) const
|
||||
void MultipleBeds::clear_inst_map()
|
||||
{
|
||||
m_inst_to_bed.clear();
|
||||
m_occupied_beds_cache.fill(false);
|
||||
}
|
||||
|
||||
void MultipleBeds::set_instance_bed(ObjectID id, int bed_idx)
|
||||
void MultipleBeds::set_instance_bed(ObjectID id, bool printable, int bed_idx)
|
||||
{
|
||||
assert(bed_idx < get_max_beds());
|
||||
m_inst_to_bed[id] = bed_idx;
|
||||
|
||||
if (printable)
|
||||
m_occupied_beds_cache[bed_idx] = true;
|
||||
}
|
||||
|
||||
void MultipleBeds::inst_map_updated()
|
||||
@ -298,6 +302,11 @@ Vec2d MultipleBeds::bed_gap() const
|
||||
return Vec2d::Ones() * gap;
|
||||
}
|
||||
|
||||
bool MultipleBeds::is_bed_occupied(int i) const
|
||||
{
|
||||
return m_occupied_beds_cache[i];
|
||||
}
|
||||
|
||||
|
||||
Vec2crd MultipleBeds::get_bed_gap() const {
|
||||
return scaled(Vec2d{bed_gap() / 2.0});
|
||||
|
@ -32,9 +32,10 @@ public:
|
||||
Vec3d get_bed_translation(int id) const;
|
||||
|
||||
void clear_inst_map();
|
||||
void set_instance_bed(ObjectID id, int bed_idx);
|
||||
void set_instance_bed(ObjectID id, bool printable, int bed_idx);
|
||||
void inst_map_updated();
|
||||
const std::map<ObjectID, int> &get_inst_map() const { return m_inst_to_bed; }
|
||||
bool is_bed_occupied(int bed_idx) const;
|
||||
|
||||
int get_number_of_beds() const { return m_number_of_beds; }
|
||||
bool should_show_next_bed() const { return m_show_next_bed; }
|
||||
@ -78,6 +79,7 @@ private:
|
||||
bool m_show_next_bed = false;
|
||||
std::map<ObjectID, int> m_inst_to_bed;
|
||||
std::map<PrintBase*, size_t> m_printbase_to_texture;
|
||||
std::array<int, MAX_NUMBER_OF_BEDS> m_occupied_beds_cache;
|
||||
int m_last_hovered_bed = -1;
|
||||
BoundingBoxf m_build_volume_bb;
|
||||
bool m_legacy_layout = false;
|
||||
|
@ -139,6 +139,7 @@ void GLCanvas3D::select_bed(int i, bool triggered_by_user)
|
||||
wxGetApp().plater()->get_camera().translate_world(s_multiple_beds.get_bed_translation(i) - s_multiple_beds.get_bed_translation(old_bed));
|
||||
}
|
||||
wxGetApp().plater()->schedule_background_process();
|
||||
wxGetApp().plater()->object_list_changed(); // Updates Slice Now / Export buttons.
|
||||
if (s_multiple_beds.is_autoslicing() && triggered_by_user)
|
||||
s_multiple_beds.stop_autoslice(false);
|
||||
});
|
||||
@ -6314,7 +6315,7 @@ void GLCanvas3D::_render_overlays()
|
||||
void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
{
|
||||
static float btn_side = 80.f;
|
||||
static float btn_border = 4.f;
|
||||
static float btn_border = 2.f;
|
||||
static bool hide_title = true;
|
||||
|
||||
ImVec2 btn_size = ImVec2(btn_side, btn_side);
|
||||
@ -6325,27 +6326,38 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
//ImGui::Text("%d", i);
|
||||
//ImGui::SameLine();
|
||||
|
||||
bool empty = ! s_multiple_beds.is_bed_occupied(i);
|
||||
bool inactive = i != s_multiple_beds.get_active_bed() || s_multiple_beds.is_autoslicing();
|
||||
if (inactive)
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0., 0., 0., .5));
|
||||
if (bool clicked = (i >= int(s_th_tex_id.size()))
|
||||
? ImGui::Button(std::to_string(i).c_str(), btn_size)
|
||||
: ImGui::ImageButton((void*)(int64_t)s_th_tex_id[i], btn_size, ImVec2(0, 1), ImVec2(1, 0));
|
||||
clicked)
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGuiPureWrap::COL_GREY_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, inactive ? ImGuiPureWrap::COL_GREY_DARK : ImGuiPureWrap::COL_BUTTON_ACTIVE);
|
||||
|
||||
if (empty)
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
|
||||
bool clicked = false;
|
||||
ImVec2 btn_padding = ImVec2(btn_border, btn_border);
|
||||
if (i >= int(s_th_tex_id.size()) || empty)
|
||||
clicked = ImGui::Button(empty ? "empty" : std::to_string(i + 1).c_str(), btn_size + btn_padding);
|
||||
else
|
||||
clicked = ImGui::ImageButton((void*)(int64_t)s_th_tex_id[i], btn_size - btn_padding, ImVec2(0, 1), ImVec2(1, 0), btn_border);
|
||||
|
||||
if (clicked && ! empty)
|
||||
select_bed(i, true);
|
||||
|
||||
if (inactive)
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleColor(2);
|
||||
if (empty)
|
||||
ImGui::PopItemFlag();
|
||||
|
||||
std::string status_text;
|
||||
if (wxGetApp().plater()->get_fff_prints()[i]->finished())
|
||||
status_text = "Finished";
|
||||
else if (m_process->fff_print() == wxGetApp().plater()->get_fff_prints()[i].get() && m_process->running())
|
||||
status_text = "Running";
|
||||
else
|
||||
status_text = "Idle";
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip(status_text.c_str());
|
||||
//std::string status_text;
|
||||
//if (wxGetApp().plater()->get_fff_prints()[i]->finished())
|
||||
// status_text = "Finished";
|
||||
//else if (m_process->fff_print() == wxGetApp().plater()->get_fff_prints()[i].get() && m_process->running())
|
||||
// status_text = "Running";
|
||||
//else
|
||||
// status_text = "Idle";
|
||||
//if (ImGui::IsItemHovered())
|
||||
// ImGui::SetTooltip(status_text.c_str());
|
||||
};
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
@ -6365,9 +6377,8 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
#endif
|
||||
ImGui::Begin("Bed selector", 0, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(btn_border, btn_border));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
|
||||
|
||||
// Disable for now.
|
||||
//if (imgui.image_button(ImGui::SliceAllBtnIcon, "Slice All")) {
|
||||
@ -6386,7 +6397,7 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(4);
|
||||
ImGui::PopStyleVar(3);
|
||||
|
||||
#if use_scrolling
|
||||
bool extra_frame{ false };
|
||||
|
@ -1874,7 +1874,7 @@ void Plater::priv::object_list_changed()
|
||||
// XXX: is this right?
|
||||
const bool model_fits = view3D->get_canvas3d()->check_volumes_outside_state() == ModelInstancePVS_Inside;
|
||||
|
||||
sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits);
|
||||
sidebar->enable_buttons(s_multiple_beds.is_bed_occupied(s_multiple_beds.get_active_bed()) && !model.objects.empty() && !export_in_progress && model_fits);
|
||||
}
|
||||
|
||||
void Plater::priv::select_all()
|
||||
@ -2979,13 +2979,17 @@ void Plater::priv::set_current_panel(wxPanel* panel)
|
||||
// FIXME: it may be better to have a single function making this check and let it be called wherever needed
|
||||
bool export_in_progress = this->background_process.is_export_scheduled();
|
||||
bool model_fits = view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside;
|
||||
if (!model.objects.empty() && !export_in_progress && model_fits) {
|
||||
if (s_multiple_beds.is_bed_occupied(s_multiple_beds.get_active_bed()) && !model.objects.empty() && !export_in_progress && model_fits) {
|
||||
preview->get_canvas3d()->init_gcode_viewer();
|
||||
preview->load_gcode_shells();
|
||||
q->reslice();
|
||||
}
|
||||
// keeps current gcode preview, if any
|
||||
preview->reload_print();
|
||||
|
||||
if (! s_multiple_beds.is_bed_occupied(s_multiple_beds.get_active_bed()))
|
||||
preview->get_canvas3d()->reset_gcode_toolpaths();
|
||||
|
||||
}
|
||||
|
||||
preview->set_as_dirty();
|
||||
@ -4564,6 +4568,11 @@ void Plater::reload_print()
|
||||
p->preview->reload_print();
|
||||
}
|
||||
|
||||
void Plater::object_list_changed()
|
||||
{
|
||||
p->object_list_changed();
|
||||
}
|
||||
|
||||
std::vector<size_t> Plater::load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool imperial_units /*= false*/) { return p->load_files(input_files, load_model, load_config, imperial_units); }
|
||||
|
||||
// To be called when providing a list of files to the GUI slic3r on command line.
|
||||
@ -5535,8 +5544,9 @@ void Plater::apply_cut_object_to_model(size_t obj_idx, const ModelObjectPtrs& ne
|
||||
size_t last_id = p->model.objects.size() - 1;
|
||||
for (size_t i = 0; i < new_objects.size(); ++i) {
|
||||
selection.add_object((unsigned int)(last_id - i), i == 0);
|
||||
const ObjectID instance_id{p->model.objects[last_id - i]->instances.front()->id().id};
|
||||
s_multiple_beds.set_instance_bed(instance_id, s_multiple_beds.get_active_bed());
|
||||
const ModelInstance* mi = p->model.objects[last_id - i]->instances.front();
|
||||
const ObjectID instance_id{mi->id().id};
|
||||
s_multiple_beds.set_instance_bed(instance_id, mi->printable, s_multiple_beds.get_active_bed());
|
||||
}
|
||||
|
||||
UIThreadWorker w;
|
||||
|
@ -117,6 +117,7 @@ public:
|
||||
void convert_gcode_to_ascii();
|
||||
void convert_gcode_to_binary();
|
||||
void reload_print();
|
||||
void object_list_changed();
|
||||
|
||||
std::vector<size_t> load_files(const std::vector<boost::filesystem::path>& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false);
|
||||
// To be called when providing a list of files to the GUI slic3r on command line.
|
||||
|
Loading…
x
Reference in New Issue
Block a user