diff --git a/src/libslic3r/MultipleBeds.cpp b/src/libslic3r/MultipleBeds.cpp index d889a4b85a..0b314daa17 100644 --- a/src/libslic3r/MultipleBeds.cpp +++ b/src/libslic3r/MultipleBeds.cpp @@ -8,6 +8,8 @@ namespace Slic3r { MultipleBeds s_multiple_beds; +bool s_reload_preview_after_switching_beds = false; + Vec3d MultipleBeds::get_bed_translation(int id) const diff --git a/src/libslic3r/MultipleBeds.hpp b/src/libslic3r/MultipleBeds.hpp index 4c747fe6f2..e2d5b54da2 100644 --- a/src/libslic3r/MultipleBeds.hpp +++ b/src/libslic3r/MultipleBeds.hpp @@ -12,6 +12,7 @@ namespace Slic3r { class Model; class BuildVolume; +extern bool s_reload_preview_after_switching_beds; class MultipleBeds { public: diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 26f067cd6c..f3585b6d1d 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -26,6 +26,8 @@ #include #include +#include + static const float GROUND_Z = -0.02f; static const Slic3r::ColorRGBA DEFAULT_MODEL_COLOR = Slic3r::ColorRGBA::DARK_GRAY(); static const Slic3r::ColorRGBA PICKING_MODEL_COLOR = Slic3r::ColorRGBA::BLACK(); @@ -106,11 +108,24 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_texture) { - for (size_t i = 0; i < s_multiple_beds.get_number_of_beds() + int(s_multiple_beds.should_show_next_bed()); ++i) { + bool is_preview = wxGetApp().plater()->is_preview_shown(); + int bed_to_highlight = -1; + + static std::vector beds_to_render; + beds_to_render.clear(); + if (is_preview) + beds_to_render.push_back(s_multiple_beds.get_active_bed()); + else { + beds_to_render.resize(s_multiple_beds.get_number_of_beds() + int(s_multiple_beds.should_show_next_bed())); + std::iota(beds_to_render.begin(), beds_to_render.end(), 0); + if (s_multiple_beds.get_number_of_beds() != 1) + bed_to_highlight = s_multiple_beds.get_active_bed(); + } + + for (int i : beds_to_render) { Transform3d mat = view_matrix; mat.translate(s_multiple_beds.get_bed_translation(i)); - bool is_active = (i == s_multiple_beds.get_active_bed() && s_multiple_beds.get_number_of_beds() != 1); - render_internal(canvas, mat, projection_matrix, bottom, scale_factor, show_texture, false, is_active); + render_internal(canvas, mat, projection_matrix, bottom, scale_factor, show_texture, false, i == bed_to_highlight); } } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 9ff84ef17c..679d43ad34 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -31,6 +31,8 @@ #include "GUI_ObjectManipulation.hpp" #include "MsgDialog.hpp" +#include "libslic3r/MultipleBeds.hpp" + #if ENABLE_ACTUAL_SPEED_DEBUG #define IMGUI_DEFINE_MATH_OPERATORS #endif // ENABLE_ACTUAL_SPEED_DEBUG @@ -86,7 +88,10 @@ void GCodeViewer::COG::render() const double inv_zoom = camera.get_inv_zoom(); model_matrix = model_matrix * Geometry::scale_transform(inv_zoom); } - const Transform3d& view_matrix = camera.get_view_matrix(); + + Transform3d view_matrix = camera.get_view_matrix(); + view_matrix.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed())); + shader->set_uniform("view_model_matrix", view_matrix * model_matrix); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose(); @@ -233,7 +238,10 @@ void GCodeViewer::SequentialView::Marker::render() shader->start_using(); shader->set_uniform("emission_factor", 0.0f); const Camera& camera = wxGetApp().plater()->get_camera(); - const Transform3d& view_matrix = camera.get_view_matrix(); + + Transform3d view_matrix = camera.get_view_matrix(); + view_matrix.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed())); + float scale_factor = m_scale_factor; if (m_fixed_screen_size) scale_factor *= 10.0f * camera.get_inv_zoom(); @@ -1706,7 +1714,12 @@ void GCodeViewer::load_wipetower_shell(const Print& print) void GCodeViewer::render_toolpaths() { const Camera& camera = wxGetApp().plater()->get_camera(); - const libvgcode::Mat4x4 converted_view_matrix = libvgcode::convert(static_cast(camera.get_view_matrix().matrix().cast())); + + Transform3d tr = camera.get_view_matrix(); + tr.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed())); + Matrix4f m = tr.matrix().cast(); + + const libvgcode::Mat4x4 converted_view_matrix = libvgcode::convert(m); const libvgcode::Mat4x4 converted_projetion_matrix = libvgcode::convert(static_cast(camera.get_projection_matrix().matrix().cast())); #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS m_viewer.set_cog_marker_scale_factor(m_cog_marker_fixed_screen_size ? 10.0f * m_cog_marker_size * camera.get_inv_zoom() : m_cog_marker_size); @@ -1896,7 +1909,11 @@ void GCodeViewer::render_shells() shader->start_using(); shader->set_uniform("emission_factor", 0.1f); const Camera& camera = wxGetApp().plater()->get_camera(); - m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, camera.get_view_matrix(), camera.get_projection_matrix()); + + Transform3d tr = camera.get_view_matrix(); + tr.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed())); + + m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, tr, camera.get_projection_matrix()); shader->set_uniform("emission_factor", 0.0f); shader->stop_using(); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ddca7796da..e045ab5957 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1840,8 +1840,16 @@ void GLCanvas3D::render() bool inactive = i != s_multiple_beds.get_active_bed(); if (inactive) ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0., 0., 0., .5)); - if (ImGui::Button((std::string("Bed number ") + std::to_string(i + 1)).c_str())) + if (ImGui::Button((std::string("Bed number ") + std::to_string(i + 1)).c_str())) { + int old_bed = s_multiple_beds.get_active_bed(); s_multiple_beds.set_active_bed(i); + if (wxGetApp().plater()->is_preview_shown()) { + s_reload_preview_after_switching_beds = true; + wxPostEvent(wxGetApp().plater(), SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); + camera.translate_world(s_multiple_beds.get_bed_translation(i) - s_multiple_beds.get_bed_translation(old_bed)); + } + wxGetApp().plater()->sidebar().update_sliced_info_sizer(); + } if (inactive) ImGui::PopStyleColor(); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 16fb2beba0..7acec8ccd9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2841,8 +2841,12 @@ void Plater::priv::set_current_panel(wxPanel* panel) bool force_render = (current_panel != nullptr); #endif // __WXMAC__ - if (current_panel == panel) - return; + if (current_panel == panel) { + if (! s_reload_preview_after_switching_beds) + return; + else + s_reload_preview_after_switching_beds = false; + } wxPanel* old_panel = current_panel; current_panel = panel;