Disable SLA autoslicing page

- Also set instances to unprintable for SLA instead
  of removing them from the model
This commit is contained in:
Martin Šach 2024-12-09 17:58:09 +01:00 committed by Lukas Matena
parent 29da9fcfff
commit 37f5bfc2cd
7 changed files with 163 additions and 75 deletions

View File

@ -208,7 +208,7 @@ void restore_object_instances(Model& model, const ObjectInstances &object_instan
model.objects = objects; model.objects = objects;
} }
void with_single_bed_model(Model &model, const int bed_index, const std::function<void()> &callable) { void with_single_bed_model_fff(Model &model, const int bed_index, const std::function<void()> &callable) {
const InstanceOffsets original_offssets{MultipleBedsUtils::get_instance_offsets(model)}; const InstanceOffsets original_offssets{MultipleBedsUtils::get_instance_offsets(model)};
const ObjectInstances original_objects{get_object_instances(model)}; const ObjectInstances original_objects{get_object_instances(model)};
const int original_bed{s_multiple_beds.get_active_bed()}; const int original_bed{s_multiple_beds.get_active_bed()};
@ -224,6 +224,44 @@ void with_single_bed_model(Model &model, const int bed_index, const std::functio
callable(); callable();
} }
using InstancesPrintability = std::vector<bool>;
InstancesPrintability get_instances_printability(const Model &model) {
InstancesPrintability result;
for (ModelObject* mo : model.objects) {
for (ModelInstance* mi : mo->instances) {
result.emplace_back(mi->printable);
}
}
return result;
}
void restore_instances_printability(Model& model, const InstancesPrintability &printability)
{
size_t i = 0;
for (ModelObject* mo : model.objects) {
for (ModelInstance* mi : mo->instances) {
mi->printable = printability[i++];
}
}
}
void with_single_bed_model_sla(Model &model, const int bed_index, const std::function<void()> &callable) {
const InstanceOffsets original_offssets{get_instance_offsets(model)};
const InstancesPrintability original_printability{get_instances_printability(model)};
const int original_bed{s_multiple_beds.get_active_bed()};
Slic3r::ScopeGuard guard([&]() {
restore_instance_offsets(model, original_offssets);
restore_instances_printability(model, original_printability);
s_multiple_beds.set_active_bed(original_bed);
});
s_multiple_beds.move_from_bed_to_first_bed(model, bed_index);
s_multiple_beds.set_instances_outside_outside_bed_unprintable(model, bed_index);
s_multiple_beds.set_active_bed(bed_index);
callable();
}
} }
bool MultipleBeds::is_instance_on_bed(const ObjectID id, const int bed_index) const bool MultipleBeds::is_instance_on_bed(const ObjectID id, const int bed_index) const
@ -252,6 +290,16 @@ void MultipleBeds::remove_instances_outside_outside_bed(Model& model, const int
), model.objects.end()); ), model.objects.end());
} }
void MultipleBeds::set_instances_outside_outside_bed_unprintable(Model& model, const int bed_index) const {
for (ModelObject* mo : model.objects) {
for (ModelInstance* mi : mo->instances) {
if (!this->is_instance_on_bed(mi->id(), bed_index)) {
mi->printable = false;
}
}
}
}
void MultipleBeds::move_from_bed_to_first_bed(Model& model, const int bed_index) const void MultipleBeds::move_from_bed_to_first_bed(Model& model, const int bed_index) const
{ {
if (bed_index < 0 || bed_index >= MAX_NUMBER_OF_BEDS) { if (bed_index < 0 || bed_index >= MAX_NUMBER_OF_BEDS) {

View File

@ -51,6 +51,7 @@ public:
void set_active_bed(int i); void set_active_bed(int i);
void remove_instances_outside_outside_bed(Model& model, const int bed) const; void remove_instances_outside_outside_bed(Model& model, const int bed) const;
void set_instances_outside_outside_bed_unprintable(Model& model, const int bed_index) const;
// Sets !printable to all instances outside the active bed. // Sets !printable to all instances outside the active bed.
void move_from_bed_to_first_bed(Model& model, const int bed) const; void move_from_bed_to_first_bed(Model& model, const int bed) const;
@ -113,14 +114,8 @@ ObjectInstances get_object_instances(const Model& model);
void restore_instance_offsets(Model& model, const InstanceOffsets &offsets); void restore_instance_offsets(Model& model, const InstanceOffsets &offsets);
void restore_object_instances(Model& model, const ObjectInstances &object_instances); void restore_object_instances(Model& model, const ObjectInstances &object_instances);
void with_single_bed_model_fff(Model &model, const int bed_index, const std::function<void()> &callable);
/** void with_single_bed_model_sla(Model &model, const int bed_index, const std::function<void()> &callable);
For each print apply call do:
- move all instances according to their active bed
- apply
- move all instances back to their respective beds
*/
void with_single_bed_model(Model &model, const int bed_index, const std::function<void()> &callable);
} }
} // namespace Slic3r } // namespace Slic3r

View File

@ -6575,9 +6575,9 @@ enum class PrintStatus {
std::string get_status_text(PrintStatus status) { std::string get_status_text(PrintStatus status) {
switch(status) { switch(status) {
case PrintStatus::idle: return "Idle"; case PrintStatus::idle: return _u8L("Unsliced");
case PrintStatus::running: return "Running"; case PrintStatus::running: return _u8L("Slicing...");
case PrintStatus::finished: return "Finished"; case PrintStatus::finished: return _u8L("Sliced");
} }
return {}; return {};
} }
@ -6601,7 +6601,7 @@ bool bed_selector_thumbnail(
const float side, const float side,
const float border, const float border,
const GLuint texture_id, const GLuint texture_id,
const PrintStatus status const std::optional<PrintStatus> status
) { ) {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
const ImVec2 current_position = GImGui->CurrentWindow->DC.CursorPos; const ImVec2 current_position = GImGui->CurrentWindow->DC.CursorPos;
@ -6615,7 +6615,8 @@ bool bed_selector_thumbnail(
border border
)}; )};
const std::string icon{get_status_icon(status)}; if (status) {
const std::string icon{get_status_icon(*status)};
window->DrawList->AddText( window->DrawList->AddText(
GImGui->Font, GImGui->Font,
@ -6625,6 +6626,7 @@ bool bed_selector_thumbnail(
icon.c_str(), icon.c_str(),
icon.c_str() + icon.size() icon.c_str() + icon.size()
); );
}
return clicked; return clicked;
} }
@ -6673,12 +6675,15 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
bool clicked = false; bool clicked = false;
PrintStatus print_status{PrintStatus::idle}; std::optional<PrintStatus> print_status;
if (current_printer_technology() == ptFFF) {
print_status = PrintStatus::idle;
if (wxGetApp().plater()->get_fff_prints()[i]->finished()) { if (wxGetApp().plater()->get_fff_prints()[i]->finished()) {
print_status = PrintStatus::finished; print_status = PrintStatus::finished;
} else if (m_process->fff_print() == wxGetApp().plater()->get_fff_prints()[i].get() && m_process->running()) { } else if (m_process->fff_print() == wxGetApp().plater()->get_fff_prints()[i].get() && m_process->running()) {
print_status = PrintStatus::running; print_status = PrintStatus::running;
} }
}
if (!previous_print_status[i] || print_status != previous_print_status[i]) { if (!previous_print_status[i] || print_status != previous_print_status[i]) {
extra_frame = true; extra_frame = true;
@ -6710,9 +6715,12 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
if (empty) if (empty)
ImGui::PopItemFlag(); ImGui::PopItemFlag();
const std::string status_text{get_status_text(print_status)}; if (print_status) {
if (ImGui::IsItemHovered()) const std::string status_text{get_status_text(*print_status)};
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", status_text.c_str()); ImGui::SetTooltip("%s", status_text.c_str());
}
}
}; };
ImGuiWrapper& imgui = *wxGetApp().imgui(); ImGuiWrapper& imgui = *wxGetApp().imgui();
@ -6736,7 +6744,10 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2()); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, btn_border); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, btn_border);
if (slice_all_beds_button(s_multiple_beds.is_autoslicing(), btn_size, btn_padding)) { if (
current_printer_technology() == ptFFF &&
slice_all_beds_button(s_multiple_beds.is_autoslicing(), btn_size, btn_padding)
) {
if (!s_multiple_beds.is_autoslicing()) { if (!s_multiple_beds.is_autoslicing()) {
s_multiple_beds.start_autoslice([this](int i, bool user) { this->select_bed(i, user); }); s_multiple_beds.start_autoslice([this](int i, bool user) { this->select_bed(i, user); });
wxGetApp().sidebar().switch_to_autoslicing_mode(); wxGetApp().sidebar().switch_to_autoslicing_mode();

View File

@ -94,6 +94,7 @@ void GLGizmoSlaBase::update_volumes()
const int object_idx = m_parent.get_selection().get_object_idx(); const int object_idx = m_parent.get_selection().get_object_idx();
const int instance_idx = m_parent.get_selection().get_instance_idx(); const int instance_idx = m_parent.get_selection().get_instance_idx();
const Geometry::Transformation& inst_trafo = po->model_object()->instances[instance_idx]->get_transformation(); const Geometry::Transformation& inst_trafo = po->model_object()->instances[instance_idx]->get_transformation();
const double current_elevation = po->get_current_elevation(); const double current_elevation = po->get_current_elevation();

View File

@ -563,6 +563,7 @@ struct Plater::priv
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type); void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type);
ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type); ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type);
void regenerate_thumbnails();
void bring_instance_forward() const; void bring_instance_forward() const;
@ -2162,25 +2163,64 @@ void Plater::priv::process_validation_warning(const std::vector<std::string>& wa
} }
} }
std::array<Print::ApplyStatus, MAX_NUMBER_OF_BEDS> apply_to_inactive_beds( std::vector<Print::ApplyStatus> apply_to_inactive_beds(
Model &model, Model &model,
std::vector<std::unique_ptr<Print>> &prints, std::vector<std::unique_ptr<Print>> &prints,
const DynamicPrintConfig &config const DynamicPrintConfig &config
) { ) {
std::array<Print::ApplyStatus, MAX_NUMBER_OF_BEDS> result; std::vector<Print::ApplyStatus> result(MAX_NUMBER_OF_BEDS);
for (std::size_t bed_index{0}; bed_index < prints.size(); ++bed_index) { for (std::size_t bed_index{0}; bed_index < prints.size(); ++bed_index) {
const std::unique_ptr<Print> &print{prints[bed_index]}; const std::unique_ptr<Print> &print{prints[bed_index]};
if (!print || bed_index == s_multiple_beds.get_active_bed()) { if (!print || bed_index == s_multiple_beds.get_active_bed()) {
continue; continue;
} }
using MultipleBedsUtils::with_single_bed_model; using MultipleBedsUtils::with_single_bed_model_fff;
with_single_bed_model(model, bed_index, [&](){ with_single_bed_model_fff(model, bed_index, [&](){
result[bed_index] = print->apply(model, config); result[bed_index] = print->apply(model, config);
}); });
} }
return result; return result;
} }
void Plater::priv::regenerate_thumbnails() {
const int num{s_multiple_beds.get_number_of_beds()};
if (num <= 1 || num > MAX_NUMBER_OF_BEDS) {
return;
}
ThumbnailData data;
ThumbnailsParams params;
params.parts_only = true;
params.printable_only = true;
params.show_bed = true;
params.transparent_background = true;
int w = 100, h = 100;
int curr_bound_texture = 0;
glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture));
int curr_unpack_alignment = 0;
glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment));
glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(glDeleteTextures(s_bed_selector_thumbnail_texture_ids.size(), s_bed_selector_thumbnail_texture_ids.data()));
s_bed_selector_thumbnail_changed.fill(false);
s_bed_selector_thumbnail_texture_ids.resize(num);
glsafe(glGenTextures(num, s_bed_selector_thumbnail_texture_ids.data()));
for (int i = 0; i < num; ++i) {
s_multiple_beds.set_thumbnail_bed_idx(i);
generate_thumbnail(data, w, h, params, GUI::Camera::EType::Ortho);
s_multiple_beds.set_thumbnail_bed_idx(-1);
glsafe(glBindTexture(GL_TEXTURE_2D, s_bed_selector_thumbnail_texture_ids[i]));
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGBA, GL_UNSIGNED_BYTE, data.pixels.data()));
s_bed_selector_thumbnail_changed[i] = true;
}
glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture));
glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment));
}
// Update background processing thread from the current config and Model. // Update background processing thread from the current config and Model.
// Returns a bitmask of UpdateBackgroundProcessReturnState. // Returns a bitmask of UpdateBackgroundProcessReturnState.
unsigned int Plater::priv::update_background_process(bool force_validation, bool postpone_error_messages) unsigned int Plater::priv::update_background_process(bool force_validation, bool postpone_error_messages)
@ -2236,16 +2276,29 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
Print::ApplyStatus invalidated{Print::ApplyStatus::APPLY_STATUS_INVALIDATED}; Print::ApplyStatus invalidated{Print::ApplyStatus::APPLY_STATUS_INVALIDATED};
bool was_running = background_process.running(); bool was_running = background_process.running();
using MultipleBedsUtils::with_single_bed_model; using MultipleBedsUtils::with_single_bed_model_fff;
using MultipleBedsUtils::with_single_bed_model_sla;
std::array<Print::ApplyStatus, MAX_NUMBER_OF_BEDS> apply_statuses{ std::vector<Print::ApplyStatus> apply_statuses{
apply_to_inactive_beds(q->model(), q->p->fff_prints, full_config) printer_technology == ptFFF ?
apply_to_inactive_beds(q->model(), q->p->fff_prints, full_config) :
std::vector<Print::ApplyStatus>(1)
}; };
with_single_bed_model(q->model(), s_multiple_beds.get_active_bed(), [&](){
// Apply new config to the possibly running background task. // Apply new config to the possibly running background task.
if (printer_technology == ptFFF) {
with_single_bed_model_fff(q->model(), s_multiple_beds.get_active_bed(), [&](){
invalidated = background_process.apply(q->model(), full_config); invalidated = background_process.apply(q->model(), full_config);
apply_statuses[s_multiple_beds.get_active_bed()] = invalidated; apply_statuses[s_multiple_beds.get_active_bed()] = invalidated;
}); });
} else if (printer_technology == ptSLA) {
with_single_bed_model_sla(q->model(), s_multiple_beds.get_active_bed(), [&](){
invalidated = background_process.apply(q->model(), full_config);
apply_statuses[0] = invalidated;
});
} else {
throw std::runtime_error{"Ivalid printer technology!"};
}
const bool any_status_changed{std::any_of( const bool any_status_changed{std::any_of(
apply_statuses.begin(), apply_statuses.begin(),
@ -2260,38 +2313,8 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
} }
// If current bed was invalidated, update thumbnails for all beds: // If current bed was invalidated, update thumbnails for all beds:
if (int num = s_multiple_beds.get_number_of_beds(); num > 1 && any_status_changed) { if (any_status_changed) {
ThumbnailData data; regenerate_thumbnails();
ThumbnailsParams params;
params.parts_only = true;
params.printable_only = true;
params.show_bed = true;
params.transparent_background = true;
int w = 100, h = 100;
int curr_bound_texture = 0;
glsafe(glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_bound_texture));
int curr_unpack_alignment = 0;
glsafe(glGetIntegerv(GL_UNPACK_ALIGNMENT, &curr_unpack_alignment));
glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(glDeleteTextures(s_bed_selector_thumbnail_texture_ids.size(), s_bed_selector_thumbnail_texture_ids.data()));
s_bed_selector_thumbnail_changed.fill(false);
s_bed_selector_thumbnail_texture_ids.resize(num);
glsafe(glGenTextures(num, s_bed_selector_thumbnail_texture_ids.data()));
for (int i = 0; i < num; ++i) {
s_multiple_beds.set_thumbnail_bed_idx(i);
generate_thumbnail(data, w, h, params, GUI::Camera::EType::Ortho);
s_multiple_beds.set_thumbnail_bed_idx(-1);
glsafe(glBindTexture(GL_TEXTURE_2D, s_bed_selector_thumbnail_texture_ids[i]));
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
glsafe(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
glsafe(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, static_cast<GLsizei>(w), static_cast<GLsizei>(h), 0, GL_RGBA, GL_UNSIGNED_BYTE, data.pixels.data()));
s_bed_selector_thumbnail_changed[i] = true;
}
glsafe(glBindTexture(GL_TEXTURE_2D, curr_bound_texture));
glsafe(glPixelStorei(GL_UNPACK_ALIGNMENT, curr_unpack_alignment));
} }
// Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile. // Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile.
@ -4685,6 +4708,10 @@ void Plater::object_list_changed()
p->object_list_changed(); p->object_list_changed();
} }
void Plater::regenerate_thumbnails() {
p->regenerate_thumbnails();
}
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); } 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. // To be called when providing a list of files to the GUI slic3r on command line.

View File

@ -122,6 +122,7 @@ public:
void reload_print(); void reload_print();
void object_list_changed(); void object_list_changed();
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type); void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type);
void regenerate_thumbnails();
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); 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. // To be called when providing a list of files to the GUI slic3r on command line.

View File

@ -32,6 +32,7 @@
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/statbmp.h> #include <wx/statbmp.h>
#include <wx/wupdlock.h> // IWYU pragma: keep #include <wx/wupdlock.h> // IWYU pragma: keep
#include "libslic3r/MultipleBeds.hpp"
#include "wx/generic/stattextg.h" #include "wx/generic/stattextg.h"
#ifdef _WIN32 #ifdef _WIN32
#include <wx/richtooltip.h> #include <wx/richtooltip.h>
@ -758,6 +759,10 @@ void Sidebar::on_select_preset(wxCommandEvent& evt)
* and for SLA presets they should be deleted * and for SLA presets they should be deleted
*/ */
m_object_list->update_object_list_by_printer_technology(); m_object_list->update_object_list_by_printer_technology();
s_multiple_beds.stop_autoslice(false);
this->switch_from_autoslicing_mode();
this->m_plater->regenerate_thumbnails();
this->m_plater->update();
} }
#ifdef __WXMSW__ #ifdef __WXMSW__