mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 20:32:01 +08:00
Multiple beds in SLA
This commit is contained in:
parent
324763a90e
commit
08eb318780
@ -22,6 +22,8 @@
|
|||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
|
#include "libslic3r/MultipleBeds.hpp"
|
||||||
|
|
||||||
// #define SLAPRINT_DO_BENCHMARK
|
// #define SLAPRINT_DO_BENCHMARK
|
||||||
|
|
||||||
#ifdef SLAPRINT_DO_BENCHMARK
|
#ifdef SLAPRINT_DO_BENCHMARK
|
||||||
@ -298,6 +300,16 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con
|
|||||||
if (! material_diff.empty())
|
if (! material_diff.empty())
|
||||||
update_apply_status(this->invalidate_state_by_config_options(material_diff, invalidate_all_model_objects));
|
update_apply_status(this->invalidate_state_by_config_options(material_diff, invalidate_all_model_objects));
|
||||||
|
|
||||||
|
// Multiple beds hack: We currently use one SLAPrint for all beds. It must be invalidated
|
||||||
|
// when beds are switched. If not done explicitly, supports from previously sliced object
|
||||||
|
// might end up with wrong offset.
|
||||||
|
static int last_bed_idx = s_multiple_beds.get_active_bed();
|
||||||
|
int current_bed = s_multiple_beds.get_active_bed();
|
||||||
|
if (current_bed != last_bed_idx) {
|
||||||
|
invalidate_all_model_objects = true;
|
||||||
|
last_bed_idx = current_bed;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply variables to placeholder parser. The placeholder parser is currently used
|
// Apply variables to placeholder parser. The placeholder parser is currently used
|
||||||
// only to generate the output file name.
|
// only to generate the output file name.
|
||||||
if (! placeholder_parser_diff.empty()) {
|
if (! placeholder_parser_diff.empty()) {
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "libslic3r/ClipperUtils.hpp"
|
#include "libslic3r/ClipperUtils.hpp"
|
||||||
#include "libslic3r/Tesselate.hpp"
|
#include "libslic3r/Tesselate.hpp"
|
||||||
#include "libslic3r/PrintConfig.hpp"
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
|
#include "libslic3r/MultipleBeds.hpp"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -656,6 +657,7 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||||||
std::shared_ptr<const indexed_triangle_set> preview_mesh_ptr = print_object->get_mesh_to_print();
|
std::shared_ptr<const indexed_triangle_set> preview_mesh_ptr = print_object->get_mesh_to_print();
|
||||||
if (preview_mesh_ptr != nullptr)
|
if (preview_mesh_ptr != nullptr)
|
||||||
backend_mesh = TriangleMesh(*preview_mesh_ptr);
|
backend_mesh = TriangleMesh(*preview_mesh_ptr);
|
||||||
|
backend_mesh.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()).cast<float>());
|
||||||
if (!backend_mesh.empty()) {
|
if (!backend_mesh.empty()) {
|
||||||
backend_mesh.transform(mesh_trafo_inv);
|
backend_mesh.transform(mesh_trafo_inv);
|
||||||
TriangleMesh convex_hull = backend_mesh.convex_hull_3d();
|
TriangleMesh convex_hull = backend_mesh.convex_hull_3d();
|
||||||
@ -670,6 +672,7 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||||||
// Get the support mesh.
|
// Get the support mesh.
|
||||||
if (milestone == SLAPrintObjectStep::slaposSupportTree) {
|
if (milestone == SLAPrintObjectStep::slaposSupportTree) {
|
||||||
TriangleMesh supports_mesh = print_object->support_mesh();
|
TriangleMesh supports_mesh = print_object->support_mesh();
|
||||||
|
supports_mesh.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()).cast<float>());
|
||||||
if (!supports_mesh.empty()) {
|
if (!supports_mesh.empty()) {
|
||||||
supports_mesh.transform(mesh_trafo_inv);
|
supports_mesh.transform(mesh_trafo_inv);
|
||||||
TriangleMesh convex_hull = supports_mesh.convex_hull_3d();
|
TriangleMesh convex_hull = supports_mesh.convex_hull_3d();
|
||||||
@ -683,6 +686,7 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||||||
// Get the pad mesh.
|
// Get the pad mesh.
|
||||||
if (milestone == SLAPrintObjectStep::slaposPad) {
|
if (milestone == SLAPrintObjectStep::slaposPad) {
|
||||||
TriangleMesh pad_mesh = print_object->pad_mesh();
|
TriangleMesh pad_mesh = print_object->pad_mesh();
|
||||||
|
pad_mesh.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()).cast<float>());
|
||||||
if (!pad_mesh.empty()) {
|
if (!pad_mesh.empty()) {
|
||||||
pad_mesh.transform(mesh_trafo_inv);
|
pad_mesh.transform(mesh_trafo_inv);
|
||||||
TriangleMesh convex_hull = pad_mesh.convex_hull_3d();
|
TriangleMesh convex_hull = pad_mesh.convex_hull_3d();
|
||||||
|
@ -109,10 +109,22 @@ void GLCanvas3D::select_bed(int i, bool triggered_by_user)
|
|||||||
int old_bed = s_multiple_beds.get_active_bed();
|
int old_bed = s_multiple_beds.get_active_bed();
|
||||||
if ((i == old_bed && !s_multiple_beds.is_autoslicing()) || i == -1)
|
if ((i == old_bed && !s_multiple_beds.is_autoslicing()) || i == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (current_printer_technology() == ptSLA) {
|
||||||
|
// Close SlaSupports or Hollow gizmos before switching beds. They rely on having access to SLAPrintObject to work.
|
||||||
|
if (GLGizmosManager::EType cur_giz = get_gizmos_manager().get_current_type();
|
||||||
|
cur_giz == GLGizmosManager::EType::SlaSupports || cur_giz == GLGizmosManager::EType::Hollow) {
|
||||||
|
if (! get_gizmos_manager().open_gizmo(get_gizmos_manager().get_current_type()))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
wxGetApp().plater()->canvas3D()->m_process->stop();
|
wxGetApp().plater()->canvas3D()->m_process->stop();
|
||||||
m_sequential_print_clearance.m_evaluating = true;
|
m_sequential_print_clearance.m_evaluating = true;
|
||||||
reset_sequential_print_clearance();
|
reset_sequential_print_clearance();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The stop call above schedules some events that would be processed after the switch.
|
// The stop call above schedules some events that would be processed after the switch.
|
||||||
// Among else, on_process_completed would be called, which would stop slicing of
|
// Among else, on_process_completed would be called, which would stop slicing of
|
||||||
// the new bed. We need to stop the process, pump all the events out of the queue
|
// the new bed. We need to stop the process, pump all the events out of the queue
|
||||||
@ -6085,6 +6097,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
|||||||
m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances());
|
m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances());
|
||||||
m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify);
|
m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify);
|
||||||
|
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
auto trafo = camera.get_view_matrix();
|
||||||
|
if (current_printer_technology() == ptSLA && wxGetApp().plater()->is_preview_shown()) {
|
||||||
|
trafo.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()));
|
||||||
|
}
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
||||||
if (shader != nullptr) {
|
if (shader != nullptr) {
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
@ -6096,8 +6114,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
|||||||
{
|
{
|
||||||
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
||||||
int object_id = m_layers_editing.last_object_id;
|
int object_id = m_layers_editing.last_object_id;
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
|
||||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix(), [object_id](const GLVolume& volume) {
|
m_volumes.render(type, false, trafo, camera.get_projection_matrix(), [object_id](const GLVolume& volume) {
|
||||||
// Which volume to paint without the layer height profile shader?
|
// Which volume to paint without the layer height profile shader?
|
||||||
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
||||||
});
|
});
|
||||||
@ -6107,7 +6125,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
|||||||
else {
|
else {
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), [this](const GLVolume& volume) {
|
m_volumes.render(type, m_picking_enabled, trafo, camera.get_projection_matrix(), [this](const GLVolume& volume) {
|
||||||
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -6129,7 +6147,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
|
|||||||
case GLVolumeCollection::ERenderType::Transparent:
|
case GLVolumeCollection::ERenderType::Transparent:
|
||||||
{
|
{
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix());
|
m_volumes.render(type, false, trafo, camera.get_projection_matrix());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6382,6 +6400,7 @@ void Slic3r::GUI::GLCanvas3D::_render_bed_selector()
|
|||||||
height = win_size.y;
|
height = win_size.y;
|
||||||
wxGetApp().imgui()->set_requires_extra_frame();
|
wxGetApp().imgui()->set_requires_extra_frame();
|
||||||
}
|
}
|
||||||
|
m_bed_selector_current_height = height;
|
||||||
|
|
||||||
float max_width = win_x_pos;
|
float max_width = win_x_pos;
|
||||||
if (is_legend_shown())
|
if (is_legend_shown())
|
||||||
@ -6739,7 +6758,7 @@ void GLCanvas3D::_render_camera_target_validation_box()
|
|||||||
}
|
}
|
||||||
#endif // ENABLE_SHOW_CAMERA_TARGET
|
#endif // ENABLE_SHOW_CAMERA_TARGET
|
||||||
|
|
||||||
static void render_sla_layer_legend(const SLAPrint& print, int layer_idx, int cnv_width)
|
static void render_sla_layer_legend(const SLAPrint& print, int layer_idx, int cnv_width, float bed_sel_height)
|
||||||
{
|
{
|
||||||
const std::vector<double>& areas = print.print_statistics().layers_areas;
|
const std::vector<double>& areas = print.print_statistics().layers_areas;
|
||||||
const std::vector<double>& times = print.print_statistics().layers_times_running_total;
|
const std::vector<double>& times = print.print_statistics().layers_times_running_total;
|
||||||
@ -6750,7 +6769,7 @@ static void render_sla_layer_legend(const SLAPrint& print, int layer_idx, int cn
|
|||||||
const double time_until_layer = times[layer_idx];
|
const double time_until_layer = times[layer_idx];
|
||||||
|
|
||||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
ImGuiPureWrap::set_next_window_pos(float(cnv_width) - imgui.get_style_scaling() * 5.f, 5.f, ImGuiCond_Always, 1.0f, 0.0f);
|
ImGuiPureWrap::set_next_window_pos(float(cnv_width) - imgui.get_style_scaling() * 5.f, 5.f + bed_sel_height, ImGuiCond_Always, 1.0f, 0.0f);
|
||||||
ImGui::SetNextWindowBgAlpha(0.6f);
|
ImGui::SetNextWindowBgAlpha(0.6f);
|
||||||
|
|
||||||
ImGuiPureWrap::begin(_u8L("Layer statistics"), ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoFocusOnAppearing);
|
ImGuiPureWrap::begin(_u8L("Layer statistics"), ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoFocusOnAppearing);
|
||||||
@ -6786,7 +6805,7 @@ void GLCanvas3D::_render_sla_slices()
|
|||||||
double slider_width = 0.;
|
double slider_width = 0.;
|
||||||
if (const Preview* preview = dynamic_cast<Preview*>(m_canvas->GetParent()))
|
if (const Preview* preview = dynamic_cast<Preview*>(m_canvas->GetParent()))
|
||||||
slider_width = preview->get_layers_slider_width();
|
slider_width = preview->get_layers_slider_width();
|
||||||
render_sla_layer_legend(*print, m_layer_slider_index, get_canvas_size().get_width() - slider_width);
|
render_sla_layer_legend(*print, m_layer_slider_index, get_canvas_size().get_width() - slider_width, m_bed_selector_current_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
double clip_min_z = -m_clipping_planes[0].get_data()[3];
|
double clip_min_z = -m_clipping_planes[0].get_data()[3];
|
||||||
@ -6887,6 +6906,7 @@ void GLCanvas3D::_render_sla_slices()
|
|||||||
for (const SLAPrintObject::Instance& inst : obj->instances()) {
|
for (const SLAPrintObject::Instance& inst : obj->instances()) {
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
Transform3d view_model_matrix = camera.get_view_matrix() *
|
Transform3d view_model_matrix = camera.get_view_matrix() *
|
||||||
|
Geometry::translation_transform(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed())) *
|
||||||
Geometry::translation_transform({ unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0.0 }) *
|
Geometry::translation_transform({ unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0.0 }) *
|
||||||
Geometry::rotation_transform(inst.rotation * Vec3d::UnitZ());
|
Geometry::rotation_transform(inst.rotation * Vec3d::UnitZ());
|
||||||
if (obj->is_left_handed())
|
if (obj->is_left_handed())
|
||||||
|
@ -512,6 +512,7 @@ private:
|
|||||||
// see request_extra_frame()
|
// see request_extra_frame()
|
||||||
bool m_extra_frame_requested;
|
bool m_extra_frame_requested;
|
||||||
bool m_event_handlers_bound{ false };
|
bool m_event_handlers_bound{ false };
|
||||||
|
float m_bed_selector_current_height = 0.f;
|
||||||
|
|
||||||
GLVolumeCollection m_volumes;
|
GLVolumeCollection m_volumes;
|
||||||
#if SLIC3R_OPENGL_ES
|
#if SLIC3R_OPENGL_ES
|
||||||
|
@ -81,6 +81,12 @@ void GLGizmoHollow::data_changed(bool is_serializing)
|
|||||||
|
|
||||||
void GLGizmoHollow::on_render()
|
void GLGizmoHollow::on_render()
|
||||||
{
|
{
|
||||||
|
if (! selected_print_object_exists(m_parent, wxEmptyString)) {
|
||||||
|
wxGetApp().CallAfter([this]() {
|
||||||
|
// Close current gizmo.
|
||||||
|
m_parent.get_gizmos_manager().open_gizmo(m_parent.get_gizmos_manager().get_current_type());
|
||||||
|
});
|
||||||
|
}
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info();
|
const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info();
|
||||||
|
|
||||||
@ -137,7 +143,7 @@ void GLGizmoHollow::render_points(const Selection& selection)
|
|||||||
if (!inst)
|
if (!inst)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double shift_z = m_c->selection_info()->print_object()->get_current_elevation();
|
double shift_z = m_c->selection_info()->print_object() ? m_c->selection_info()->print_object()->get_current_elevation() : 0.;
|
||||||
Transform3d trafo(inst->get_transformation().get_matrix());
|
Transform3d trafo(inst->get_transformation().get_matrix());
|
||||||
trafo.translation()(2) += shift_z;
|
trafo.translation()(2) += shift_z;
|
||||||
const Geometry::Transformation transformation{trafo};
|
const Geometry::Transformation transformation{trafo};
|
||||||
@ -849,6 +855,14 @@ void GLGizmoHollow::on_set_state()
|
|||||||
if (m_state == m_old_state)
|
if (m_state == m_old_state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (m_state == On) {
|
||||||
|
// Make sure that current object is on current bed. Refuse to turn on otherwise.
|
||||||
|
if (! selected_print_object_exists(m_parent, _L("Selected object has to be on the active bed."))) {
|
||||||
|
m_state = Off;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_state == Off && m_old_state != Off) {
|
if (m_state == Off && m_old_state != Off) {
|
||||||
// the gizmo was just turned Off
|
// the gizmo was just turned Off
|
||||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
|
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE));
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
|
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
|
||||||
|
#include "slic3r/GUI/MsgDialog.hpp"
|
||||||
|
#include "slic3r/GUI/MainFrame.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/MultipleBeds.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
@ -21,6 +25,22 @@ GLGizmoSlaBase::GLGizmoSlaBase(GLCanvas3D& parent, const std::string& icon_filen
|
|||||||
, m_min_sla_print_object_step((int)min_step)
|
, m_min_sla_print_object_step((int)min_step)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/*static*/ bool GLGizmoSlaBase::selected_print_object_exists(const GLCanvas3D& canvas, const wxString& text)
|
||||||
|
{
|
||||||
|
if (const Selection& sel = canvas.get_selection(); !sel.is_single_full_instance() || !sel.get_model()->objects[sel.get_object_idx()]
|
||||||
|
|| ! canvas.sla_print()->get_print_object_by_model_object_id(sel.get_model()->objects[sel.get_object_idx()]->id()))
|
||||||
|
{
|
||||||
|
if (! text.IsEmpty())
|
||||||
|
wxGetApp().CallAfter([text]() {
|
||||||
|
MessageDialog dlg(GUI::wxGetApp().mainframe, text,
|
||||||
|
_L("Bed selection mismatch"), wxICON_INFORMATION | wxOK);
|
||||||
|
dlg.ShowModal();
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoSlaBase::reslice_until_step(SLAPrintObjectStep step, bool postpone_error_messages)
|
void GLGizmoSlaBase::reslice_until_step(SLAPrintObjectStep step, bool postpone_error_messages)
|
||||||
{
|
{
|
||||||
wxGetApp().CallAfter([this, step, postpone_error_messages]() {
|
wxGetApp().CallAfter([this, step, postpone_error_messages]() {
|
||||||
@ -94,12 +114,14 @@ void GLGizmoSlaBase::update_volumes()
|
|||||||
const Transform3d po_trafo_inverse = po->trafo().inverse();
|
const Transform3d po_trafo_inverse = po->trafo().inverse();
|
||||||
|
|
||||||
// main mesh
|
// main mesh
|
||||||
|
backend_mesh.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()).cast<float>());
|
||||||
backend_mesh.transform(po_trafo_inverse);
|
backend_mesh.transform(po_trafo_inverse);
|
||||||
add_volume(backend_mesh, 0, true);
|
add_volume(backend_mesh, 0, true);
|
||||||
|
|
||||||
// supports mesh
|
// supports mesh
|
||||||
TriangleMesh supports_mesh = po->support_mesh();
|
TriangleMesh supports_mesh = po->support_mesh();
|
||||||
if (!supports_mesh.empty()) {
|
if (!supports_mesh.empty()) {
|
||||||
|
supports_mesh.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()).cast<float>());
|
||||||
supports_mesh.transform(po_trafo_inverse);
|
supports_mesh.transform(po_trafo_inverse);
|
||||||
add_volume(supports_mesh, -int(slaposSupportTree));
|
add_volume(supports_mesh, -int(slaposSupportTree));
|
||||||
}
|
}
|
||||||
@ -107,6 +129,7 @@ void GLGizmoSlaBase::update_volumes()
|
|||||||
// pad mesh
|
// pad mesh
|
||||||
TriangleMesh pad_mesh = po->pad_mesh();
|
TriangleMesh pad_mesh = po->pad_mesh();
|
||||||
if (!pad_mesh.empty()) {
|
if (!pad_mesh.empty()) {
|
||||||
|
pad_mesh.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()).cast<float>());
|
||||||
pad_mesh.transform(po_trafo_inverse);
|
pad_mesh.transform(po_trafo_inverse);
|
||||||
add_volume(pad_mesh, -int(slaposPad));
|
add_volume(pad_mesh, -int(slaposPad));
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ protected:
|
|||||||
|
|
||||||
const GLVolumeCollection &volumes() const { return m_volumes; }
|
const GLVolumeCollection &volumes() const { return m_volumes; }
|
||||||
|
|
||||||
|
static bool selected_print_object_exists(const GLCanvas3D& canvas, const wxString& text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLVolumeCollection m_volumes;
|
GLVolumeCollection m_volumes;
|
||||||
bool m_input_enabled{ false };
|
bool m_input_enabled{ false };
|
||||||
|
@ -103,6 +103,13 @@ void GLGizmoSlaSupports::data_changed(bool is_serializing)
|
|||||||
|
|
||||||
void GLGizmoSlaSupports::on_render()
|
void GLGizmoSlaSupports::on_render()
|
||||||
{
|
{
|
||||||
|
if (! selected_print_object_exists(m_parent, wxEmptyString)) {
|
||||||
|
wxGetApp().CallAfter([this]() {
|
||||||
|
// Close current gizmo.
|
||||||
|
m_parent.get_gizmos_manager().open_gizmo(m_parent.get_gizmos_manager().get_current_type());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (m_state == On) {
|
if (m_state == On) {
|
||||||
// This gizmo is showing the object elevated. Tell the common
|
// This gizmo is showing the object elevated. Tell the common
|
||||||
// SelectionInfo object to lie about the actual shift.
|
// SelectionInfo object to lie about the actual shift.
|
||||||
@ -843,6 +850,13 @@ bool GLGizmoSlaSupports::ask_about_changes(std::function<void()> on_yes, std::fu
|
|||||||
void GLGizmoSlaSupports::on_set_state()
|
void GLGizmoSlaSupports::on_set_state()
|
||||||
{
|
{
|
||||||
if (m_state == On) { // the gizmo was just turned on
|
if (m_state == On) { // the gizmo was just turned on
|
||||||
|
|
||||||
|
// Make sure that current object is on current bed. Refuse to turn on otherwise.
|
||||||
|
if (! selected_print_object_exists(m_parent, _L("Selected object has to be on the active bed."))) {
|
||||||
|
m_state = Off;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set default head diameter from config.
|
// Set default head diameter from config.
|
||||||
const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
|
const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
|
||||||
m_new_point_head_diameter = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
|
m_new_point_head_diameter = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
|
||||||
|
@ -2129,12 +2129,12 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
|||||||
|
|
||||||
int active_bed = s_multiple_beds.get_active_bed();
|
int active_bed = s_multiple_beds.get_active_bed();
|
||||||
background_process.set_temp_output_path(active_bed);
|
background_process.set_temp_output_path(active_bed);
|
||||||
background_process.set_fff_print(fff_prints[active_bed].get());
|
background_process.set_fff_print(&q->active_fff_print());
|
||||||
background_process.set_sla_print(sla_prints[active_bed].get());
|
background_process.set_sla_print(&q->active_sla_print());
|
||||||
background_process.set_gcode_result(&gcode_results[active_bed]);
|
background_process.set_gcode_result(&gcode_results[active_bed]);
|
||||||
background_process.select_technology(this->printer_technology);
|
background_process.select_technology(this->printer_technology);
|
||||||
|
|
||||||
if (s_beds_just_switched) {
|
if (s_beds_just_switched && printer_technology == ptFFF) {
|
||||||
PrintBase::SlicingStatus status(q->active_fff_print(), -1);
|
PrintBase::SlicingStatus status(q->active_fff_print(), -1);
|
||||||
SlicingStatusEvent evt(EVT_SLICING_UPDATE, 0, status);
|
SlicingStatusEvent evt(EVT_SLICING_UPDATE, 0, status);
|
||||||
on_slicing_update(evt);
|
on_slicing_update(evt);
|
||||||
@ -3077,10 +3077,10 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
|||||||
warning_steps.clear();
|
warning_steps.clear();
|
||||||
if (flags == PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS) {
|
if (flags == PrintBase::SlicingStatus::UPDATE_PRINT_STEP_WARNINGS) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < int(psCount)) { warning_steps.push_back(i); ++i; }
|
while (i < int(printer_technology == ptFFF ? psCount : slapsCount)) { warning_steps.push_back(i); ++i; }
|
||||||
} else {
|
} else {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < int(posCount)) { warning_steps.push_back(i); ++i; }
|
while (i < int(printer_technology == ptFFF ? posCount : slaposCount)) { warning_steps.push_back(i); ++i; }
|
||||||
for (const PrintObject* po : wxGetApp().plater()->active_fff_print().objects())
|
for (const PrintObject* po : wxGetApp().plater()->active_fff_print().objects())
|
||||||
object_ids.push_back(po->id());
|
object_ids.push_back(po->id());
|
||||||
}
|
}
|
||||||
@ -5652,7 +5652,7 @@ void Plater::export_gcode(bool prefer_removable)
|
|||||||
start_dir,
|
start_dir,
|
||||||
from_path(default_output_file.filename()),
|
from_path(default_output_file.filename()),
|
||||||
printer_technology() == ptFFF ? GUI::file_wildcards(FT_GCODE, ext) :
|
printer_technology() == ptFFF ? GUI::file_wildcards(FT_GCODE, ext) :
|
||||||
GUI::sla_wildcards(p->sla_prints.front()->printer_config().sla_archive_format.value.c_str(), ext),
|
GUI::sla_wildcards(active_sla_print().printer_config().sla_archive_format.value.c_str(), ext),
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||||
);
|
);
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
if (dlg.ShowModal() == wxID_OK) {
|
||||||
@ -5769,7 +5769,7 @@ void Plater::export_stl_obj(bool extended, bool selection_only)
|
|||||||
auto mesh_to_export_sla = [&, this](const ModelObject& mo, int instance_id) {
|
auto mesh_to_export_sla = [&, this](const ModelObject& mo, int instance_id) {
|
||||||
TriangleMesh mesh;
|
TriangleMesh mesh;
|
||||||
|
|
||||||
const SLAPrintObject *object; // LUKAS = this->p->sla_print.get_print_object_by_model_object_id(mo.id());
|
const SLAPrintObject *object = this->active_sla_print().get_print_object_by_model_object_id(mo.id());
|
||||||
|
|
||||||
if (!object || !object->get_mesh_to_print() || object->get_mesh_to_print()->empty()) {
|
if (!object || !object->get_mesh_to_print() || object->get_mesh_to_print()->empty()) {
|
||||||
if (!extended)
|
if (!extended)
|
||||||
@ -7330,7 +7330,11 @@ wxMenu* Plater::multi_selection_menu() { return p->menus.multi_selection_menu()
|
|||||||
|
|
||||||
|
|
||||||
Print& Plater::active_fff_print() { return *p->fff_prints[s_multiple_beds.get_active_bed()]; }
|
Print& Plater::active_fff_print() { return *p->fff_prints[s_multiple_beds.get_active_bed()]; }
|
||||||
SLAPrint& Plater::active_sla_print() { return *p->sla_prints[s_multiple_beds.get_active_bed()]; }
|
//SLAPrint& Plater::active_sla_print() { return *p->sla_prints[s_multiple_beds.get_active_bed()]; }
|
||||||
|
|
||||||
|
// For now, only use the first SLAPrint for all the beds - it means reslicing
|
||||||
|
// everything when a bed is changed.
|
||||||
|
SLAPrint& Plater::active_sla_print() { return *p->sla_prints.front(); }
|
||||||
|
|
||||||
|
|
||||||
SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() :
|
SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() :
|
||||||
|
Loading…
x
Reference in New Issue
Block a user