mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 05:56:02 +08:00
Disable SLA autoslicing page
- Also set instances to unprintable for SLA instead of removing them from the model
This commit is contained in:
parent
29da9fcfff
commit
37f5bfc2cd
@ -208,7 +208,7 @@ void restore_object_instances(Model& model, const ObjectInstances &object_instan
|
||||
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 ObjectInstances original_objects{get_object_instances(model)};
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
@ -252,6 +290,16 @@ void MultipleBeds::remove_instances_outside_outside_bed(Model& model, const int
|
||||
), 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
|
||||
{
|
||||
if (bed_index < 0 || bed_index >= MAX_NUMBER_OF_BEDS) {
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
void set_active_bed(int i);
|
||||
|
||||
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.
|
||||
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_object_instances(Model& model, const ObjectInstances &object_instances);
|
||||
|
||||
|
||||
/**
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -6575,9 +6575,9 @@ enum class PrintStatus {
|
||||
|
||||
std::string get_status_text(PrintStatus status) {
|
||||
switch(status) {
|
||||
case PrintStatus::idle: return "Idle";
|
||||
case PrintStatus::running: return "Running";
|
||||
case PrintStatus::finished: return "Finished";
|
||||
case PrintStatus::idle: return _u8L("Unsliced");
|
||||
case PrintStatus::running: return _u8L("Slicing...");
|
||||
case PrintStatus::finished: return _u8L("Sliced");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -6601,7 +6601,7 @@ bool bed_selector_thumbnail(
|
||||
const float side,
|
||||
const float border,
|
||||
const GLuint texture_id,
|
||||
const PrintStatus status
|
||||
const std::optional<PrintStatus> status
|
||||
) {
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
const ImVec2 current_position = GImGui->CurrentWindow->DC.CursorPos;
|
||||
@ -6615,7 +6615,8 @@ bool bed_selector_thumbnail(
|
||||
border
|
||||
)};
|
||||
|
||||
const std::string icon{get_status_icon(status)};
|
||||
if (status) {
|
||||
const std::string icon{get_status_icon(*status)};
|
||||
|
||||
window->DrawList->AddText(
|
||||
GImGui->Font,
|
||||
@ -6625,6 +6626,7 @@ bool bed_selector_thumbnail(
|
||||
icon.c_str(),
|
||||
icon.c_str() + icon.size()
|
||||
);
|
||||
}
|
||||
|
||||
return clicked;
|
||||
}
|
||||
@ -6673,12 +6675,15 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
|
||||
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()) {
|
||||
print_status = PrintStatus::finished;
|
||||
} else if (m_process->fff_print() == wxGetApp().plater()->get_fff_prints()[i].get() && m_process->running()) {
|
||||
print_status = PrintStatus::running;
|
||||
}
|
||||
}
|
||||
|
||||
if (!previous_print_status[i] || print_status != previous_print_status[i]) {
|
||||
extra_frame = true;
|
||||
@ -6710,9 +6715,12 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
if (empty)
|
||||
ImGui::PopItemFlag();
|
||||
|
||||
const std::string status_text{get_status_text(print_status)};
|
||||
if (ImGui::IsItemHovered())
|
||||
if (print_status) {
|
||||
const std::string status_text{get_status_text(*print_status)};
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", status_text.c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
@ -6736,7 +6744,10 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
|
||||
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()) {
|
||||
s_multiple_beds.start_autoslice([this](int i, bool user) { this->select_bed(i, user); });
|
||||
wxGetApp().sidebar().switch_to_autoslicing_mode();
|
||||
|
@ -94,6 +94,7 @@ void GLGizmoSlaBase::update_volumes()
|
||||
|
||||
const int object_idx = m_parent.get_selection().get_object_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 double current_elevation = po->get_current_elevation();
|
||||
|
||||
|
@ -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);
|
||||
ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type);
|
||||
void regenerate_thumbnails();
|
||||
|
||||
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,
|
||||
std::vector<std::unique_ptr<Print>> &prints,
|
||||
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) {
|
||||
const std::unique_ptr<Print> &print{prints[bed_index]};
|
||||
if (!print || bed_index == s_multiple_beds.get_active_bed()) {
|
||||
continue;
|
||||
}
|
||||
using MultipleBedsUtils::with_single_bed_model;
|
||||
with_single_bed_model(model, bed_index, [&](){
|
||||
using MultipleBedsUtils::with_single_bed_model_fff;
|
||||
with_single_bed_model_fff(model, bed_index, [&](){
|
||||
result[bed_index] = print->apply(model, config);
|
||||
});
|
||||
}
|
||||
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.
|
||||
// Returns a bitmask of UpdateBackgroundProcessReturnState.
|
||||
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};
|
||||
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{
|
||||
apply_to_inactive_beds(q->model(), q->p->fff_prints, full_config)
|
||||
std::vector<Print::ApplyStatus> apply_statuses{
|
||||
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.
|
||||
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);
|
||||
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(
|
||||
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 (int num = s_multiple_beds.get_number_of_beds(); num > 1 && any_status_changed) {
|
||||
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));
|
||||
if (any_status_changed) {
|
||||
regenerate_thumbnails();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
// To be called when providing a list of files to the GUI slic3r on command line.
|
||||
|
@ -122,6 +122,7 @@ public:
|
||||
void reload_print();
|
||||
void object_list_changed();
|
||||
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);
|
||||
// To be called when providing a list of files to the GUI slic3r on command line.
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/wupdlock.h> // IWYU pragma: keep
|
||||
#include "libslic3r/MultipleBeds.hpp"
|
||||
#include "wx/generic/stattextg.h"
|
||||
#ifdef _WIN32
|
||||
#include <wx/richtooltip.h>
|
||||
@ -758,6 +759,10 @@ void Sidebar::on_select_preset(wxCommandEvent& evt)
|
||||
* and for SLA presets they should be deleted
|
||||
*/
|
||||
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__
|
||||
|
Loading…
x
Reference in New Issue
Block a user