diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index c9fef0a40..0c1ff112f 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1475,6 +1475,16 @@ bool PhysicalPrinter::has_empty_config() const config.opt_string("printhost_password").empty(); } +// temporary workaround for compatibility with older Slicer +static void update_preset_name_option(const std::set& preset_names, DynamicPrintConfig& config) +{ + std::string name; + for (auto el : preset_names) + name += el + ";"; + name.pop_back(); + config.set_key_value("preset_name", new ConfigOptionString(name)); +} + void PhysicalPrinter::update_preset_names_in_config() { if (!preset_names.empty()) { @@ -1484,13 +1494,7 @@ void PhysicalPrinter::update_preset_names_in_config() values.push_back(preset); // temporary workaround for compatibility with older Slicer - { - std::string name; - for (auto el : preset_names) - name += el + ";"; - name.pop_back(); - config.set_key_value("preset_name", new ConfigOptionString(name)); - } + update_preset_name_option(preset_names, config); } } @@ -1519,9 +1523,12 @@ void PhysicalPrinter::update_from_config(const DynamicPrintConfig& new_config) if (values.empty()) preset_names.clear(); - else + else { for (const std::string& val : values) preset_names.emplace(val); + // temporary workaround for compatibility with older Slicer + update_preset_name_option(preset_names, config); + } } void PhysicalPrinter::reset_presets() diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index c646fe3f1..6cc09c7ba 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -161,6 +161,8 @@ void GLModel::render() const GLShaderProgram* shader = wxGetApp().get_current_shader(); if (shader != nullptr) shader->set_uniform("uniform_color", data.color); + else + glsafe(::glColor4fv(data.color.data())); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id)); glsafe(::glDrawElements(mode, static_cast(data.indices_count), GL_UNSIGNED_INT, (const void*)0)); diff --git a/src/slic3r/GUI/GalleryDialog.cpp b/src/slic3r/GUI/GalleryDialog.cpp index 6bdbedcb3..50c828b0f 100644 --- a/src/slic3r/GUI/GalleryDialog.cpp +++ b/src/slic3r/GUI/GalleryDialog.cpp @@ -97,6 +97,7 @@ GalleryDialog::GalleryDialog(wxWindow* parent, bool modify_gallery/* = false*/) ok_btn->SetLabel(_L("Add to bed")); ok_btn->SetToolTip(_L("Add selected shape(s) to the bed")); } + static_cast(FindWindowById(wxID_CLOSE, this))->Bind(wxEVT_BUTTON, [this](wxCommandEvent&){ this->EndModal(wxID_CLOSE); }); auto add_btn = [this, buttons]( size_t pos, int& ID, wxString title, wxString tooltip, void (GalleryDialog::* method)(wxEvent&), diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 854a1c804..92c03cb75 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -61,11 +61,7 @@ void GLGizmoBase::Grabber::render(float size, const std::array& render float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size)); - GLShaderProgram* shader = picking ? nullptr : wxGetApp().get_current_shader(); - if (shader != nullptr) - const_cast(&cube)->set_color(-1, render_color); - else - glsafe(::glColor4fv(render_color.data())); // picking + const_cast(&cube)->set_color(-1, render_color); glsafe(::glPushMatrix()); glsafe(::glTranslated(center.x(), center.y(), center.z())); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 081c22240..2fa16bc03 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -118,8 +118,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes; size_t cache_size = drain_holes.size(); - for (size_t i = 0; i < cache_size; ++i) - { + for (size_t i = 0; i < cache_size; ++i) { const sla::DrainHole& drain_hole = drain_holes[i]; const bool& point_selected = m_selected[i]; @@ -129,13 +128,13 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons // First decide about the color of the point. if (picking) { std::array color = picking_color_component(i); - render_color = color; } else { if (size_t(m_hover_id) == i) { render_color = {0.f, 1.f, 1.f, 1.f}; - } else if (m_c->hollowed_mesh() && + } + else if (m_c->hollowed_mesh() && i < m_c->hollowed_mesh()->get_drainholes().size() && m_c->hollowed_mesh()->get_drainholes()[i].failed) { render_color = {1.f, 0.f, 0.f, .5f}; @@ -149,10 +148,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons } } - if (shader && ! picking) - const_cast(&m_vbo_cylinder)->set_color(-1 , render_color); - else // picking - glsafe(::glColor4fv(render_color.data())); + const_cast(&m_vbo_cylinder)->set_color(-1, render_color); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index e2eac0e3a..7a9e69fac 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -205,12 +205,11 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box if (shader == nullptr) return; - if (! picking) { + const_cast(&m_vbo_cone)->set_color(-1, color); + if (!picking) { shader->start_using(); shader->set_uniform("emission_factor", 0.1); - const_cast(&m_vbo_cone)->set_color(-1, color); - } else - glsafe(::glColor4fv(color.data())); + } glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z())); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 75bbe0d73..8b12bdc3d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -336,13 +336,11 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick if (shader == nullptr) return; - if (! picking) { + const_cast(&m_cone)->set_color(-1, color); + if (!picking) { shader->start_using(); shader->set_uniform("emission_factor", 0.1); - const_cast(&m_cone)->set_color(-1, color); } - else - glsafe(::glColor4fv(color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z())); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 6575b8d36..20306f182 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -137,8 +137,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glMultMatrixd(instance_matrix.data())); std::array render_color; - for (size_t i = 0; i < cache_size; ++i) - { + for (size_t i = 0; i < cache_size; ++i) { const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i]; const bool& point_selected = m_editing_mode ? m_editing_cache[i].selected : false; @@ -149,7 +148,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (picking) render_color = picking_color_component(i); else { - if ((size_t(m_hover_id) == i && m_editing_mode)) // ignore hover state unless editing mode is active + if (size_t(m_hover_id) == i && m_editing_mode) // ignore hover state unless editing mode is active render_color = { 0.f, 1.f, 1.f, 1.f }; else { // neigher hover nor picking bool supports_new_island = m_lock_unique_islands && support_point.is_new_island; @@ -166,14 +165,11 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color = { 0.5f, 0.5f, 0.5f, 1.f }; } } - if (shader && ! picking) { - const_cast(&m_cone)->set_color(-1, render_color); - const_cast(&m_sphere)->set_color(-1, render_color); - shader->set_uniform("emission_factor", 0.5); - } - else // picking - glsafe(::glColor4fv(render_color.data())); + const_cast(&m_cone)->set_color(-1, render_color); + const_cast(&m_sphere)->set_color(-1, render_color); + if (shader && !picking) + shader->set_uniform("emission_factor", 0.5); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. glsafe(::glPushMatrix()); @@ -226,10 +222,9 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) render_color[1] = 0.7f; render_color[2] = 0.7f; render_color[3] = 0.7f; - if (shader) { - const_cast(&m_cylinder)->set_color(-1, render_color); + const_cast(&m_cylinder)->set_color(-1, render_color); + if (shader) shader->set_uniform("emission_factor", 0.5); - } for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) { if (is_mesh_point_clipped(drain_hole.pos.cast())) continue; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6631e4df7..c81a49569 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1397,7 +1397,7 @@ void MainFrame::init_menubar_as_editor() } windowMenu->AppendSeparator(); - append_menu_item(windowMenu, wxID_ANY, _L("Modify Shapes Gallery") + "\tCtrl+G", _L("Open the dialog to modify shapes gallery"), + append_menu_item(windowMenu, wxID_ANY, _L("Modify Shapes Gallery"), _L("Open the dialog to modify shapes gallery"), [this](wxCommandEvent&) { GalleryDialog dlg(this, true); if (dlg.ShowModal() == wxID_OK) { diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index e5626c90f..92e54ec9c 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -7,7 +7,6 @@ #include #include -class wxRadioBox; class wxColourPickerCtrl; namespace Slic3r { diff --git a/src/slic3r/GUI/PresetComboBoxes.hpp b/src/slic3r/GUI/PresetComboBoxes.hpp index 6e974676d..f6a6eb3e8 100644 --- a/src/slic3r/GUI/PresetComboBoxes.hpp +++ b/src/slic3r/GUI/PresetComboBoxes.hpp @@ -16,7 +16,6 @@ class ScalableButton; class wxBoxSizer; class wxComboBox; class wxStaticBitmap; -class wxRadioBox; namespace Slic3r { diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp index 8fe10c882..460b30126 100644 --- a/src/slic3r/GUI/SavePresetDialog.cpp +++ b/src/slic3r/GUI/SavePresetDialog.cpp @@ -286,17 +286,21 @@ void SavePresetDialog::add_info_for_edit_ph_printer(wxBoxSizer* sizer) m_label = new wxStaticText(this, wxID_ANY, msg_text); m_label->SetFont(wxGetApp().bold_font()); - wxString choices[] = {"","",""}; - - m_action_radio_box = new wxRadioBox(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, - WXSIZEOF(choices), choices, 3, wxRA_SPECIFY_ROWS); - m_action_radio_box->SetSelection(0); - m_action_radio_box->Bind(wxEVT_RADIOBOX, [this](wxCommandEvent& e) { - m_action = (ActionType)e.GetSelection(); }); m_action = ChangePreset; - m_radio_sizer = new wxBoxSizer(wxHORIZONTAL); - m_radio_sizer->Add(m_action_radio_box, 1, wxEXPAND | wxTOP, 2*BORDER_W); + + wxStaticBox* action_stb = new wxStaticBox(this, wxID_ANY, ""); + if (!wxOSX) action_stb->SetBackgroundStyle(wxBG_STYLE_PAINT); + action_stb->SetFont(wxGetApp().bold_font()); + + wxStaticBoxSizer* stb_sizer = new wxStaticBoxSizer(action_stb, wxVERTICAL); + for (int id = 0; id < 3; id++) { + wxRadioButton* btn = new wxRadioButton(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, id == 0 ? wxRB_GROUP : 0); + btn->SetValue(id == int(ChangePreset)); + btn->Bind(wxEVT_RADIOBUTTON, [this, id](wxCommandEvent&) { m_action = (ActionType)id; }); + stb_sizer->Add(btn, 0, wxEXPAND | wxTOP, 5); + } + m_radio_sizer->Add(stb_sizer, 1, wxEXPAND | wxTOP, 2*BORDER_W); sizer->Add(m_label, 0, wxEXPAND | wxLEFT | wxTOP, 3*BORDER_W); sizer->Add(m_radio_sizer, 1, wxEXPAND | wxLEFT, 3*BORDER_W); @@ -313,16 +317,21 @@ void SavePresetDialog::update_info_for_edit_ph_printer(const std::string& preset return; } - wxString msg_text = from_u8((boost::format(_u8L("What would you like to do with \"%1%\" preset after saving?")) % preset_name).str()); - m_action_radio_box->SetLabel(msg_text); + if (wxSizerItem* sizer_item = m_radio_sizer->GetItem(size_t(0))) { + if (wxStaticBoxSizer* stb_sizer = static_cast(sizer_item->GetSizer())) { + wxString msg_text = format_wxstr(_L("What would you like to do with \"%1%\" preset after saving?"), preset_name); + stb_sizer->GetStaticBox()->SetLabel(msg_text); - wxString choices[] = { from_u8((boost::format(_u8L("Change \"%1%\" to \"%2%\" for this physical printer \"%3%\"")) % m_old_preset_name % preset_name % m_ph_printer_name).str()), - from_u8((boost::format(_u8L("Add \"%1%\" as a next preset for the the physical printer \"%2%\"")) % preset_name % m_ph_printer_name).str()), - from_u8((boost::format(_u8L("Just switch to \"%1%\" preset")) % preset_name).str()) }; + wxString choices[] = { format_wxstr(_L("Change \"%1%\" to \"%2%\" for this physical printer \"%3%\""), m_old_preset_name, preset_name, m_ph_printer_name), + format_wxstr(_L("Add \"%1%\" as a next preset for the the physical printer \"%2%\""), preset_name, m_ph_printer_name), + format_wxstr(_L("Just switch to \"%1%\" preset"), preset_name) }; - int n = 0; - for(const wxString& label: choices) - m_action_radio_box->SetString(n++, label); + size_t n = 0; + for (const wxString& label : choices) + stb_sizer->GetItem(n++)->GetWindow()->SetLabel(label); + } + Refresh(); + } } void SavePresetDialog::layout() diff --git a/src/slic3r/GUI/SavePresetDialog.hpp b/src/slic3r/GUI/SavePresetDialog.hpp index 2b0c71a6b..cc1ea1f24 100644 --- a/src/slic3r/GUI/SavePresetDialog.hpp +++ b/src/slic3r/GUI/SavePresetDialog.hpp @@ -10,7 +10,6 @@ class wxString; class wxStaticText; class wxComboBox; -class wxRadioBox; class wxStaticBitmap; namespace Slic3r { @@ -64,7 +63,6 @@ class SavePresetDialog : public DPIDialog wxBoxSizer* m_presets_sizer {nullptr}; wxStaticText* m_label {nullptr}; - wxRadioBox* m_action_radio_box {nullptr}; wxBoxSizer* m_radio_sizer {nullptr}; ActionType m_action {UndefAction}; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 05df2925f..f2e879605 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -658,20 +658,21 @@ void Selection::translate(const Vec3d& displacement, bool local) EMode translation_type = m_mode; for (unsigned int i : m_list) { - if (m_mode == Volume || (*m_volumes)[i]->is_wipe_tower) { + GLVolume& v = *(*m_volumes)[i]; + if (m_mode == Volume || v.is_wipe_tower) { if (local) - (*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement); + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement); else { const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement; - (*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); } } else if (m_mode == Instance) { if (is_from_fully_selected_instance(i)) - (*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement); + v.set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement); else { const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement; - (*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); translation_type = Volume; } } @@ -811,6 +812,7 @@ void Selection::flattening_rotate(const Vec3d& normal) return; for (unsigned int i : m_list) { + GLVolume& v = *(*m_volumes)[i]; // Normal transformed from the object coordinate space to the world coordinate space. const auto &voldata = m_cache.volumes_data[i]; Vec3d tnormal = (Geometry::assemble_transform( @@ -818,7 +820,7 @@ void Selection::flattening_rotate(const Vec3d& normal) voldata.get_instance_scaling_factor().cwiseInverse(), voldata.get_instance_mirror()) * normal).normalized(); // Additional rotation to align tnormal with the down vector in the world coordinate space. auto extra_rotation = Eigen::Quaterniond().setFromTwoVectors(tnormal, - Vec3d::UnitZ()); - (*m_volumes)[i]->set_instance_rotation(Geometry::extract_euler_angles(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix())); + v.set_instance_rotation(Geometry::extract_euler_angles(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix())); } #if !DISABLE_INSTANCES_SYNCH @@ -836,8 +838,21 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type if (!m_valid) return; +#if ENABLE_ALLOW_NEGATIVE_Z + bool is_any_volume_sinking = false; +#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA + bool is_sla = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; +#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA +#endif // ENABLE_ALLOW_NEGATIVE_Z + for (unsigned int i : m_list) { GLVolume &volume = *(*m_volumes)[i]; +#if ENABLE_ALLOW_NEGATIVE_Z +#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA + if (!is_sla) +#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA + is_any_volume_sinking |= !volume.is_modifier && std::find(m_cache.sinking_volumes.begin(), m_cache.sinking_volumes.end(), i) != m_cache.sinking_volumes.end(); +#endif // ENABLE_ALLOW_NEGATIVE_Z if (is_single_full_instance()) { if (transformation_type.relative()) { Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); @@ -893,10 +908,10 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH -#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA - if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) +#if ENABLE_ALLOW_NEGATIVE_Z + if (!is_any_volume_sinking) ensure_on_bed(); -#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA +#endif // ENABLE_ALLOW_NEGATIVE_Z this->set_bounding_boxes_dirty(); } @@ -952,10 +967,11 @@ void Selection::mirror(Axis axis) bool single_full_instance = is_single_full_instance(); for (unsigned int i : m_list) { + GLVolume& v = *(*m_volumes)[i]; if (single_full_instance) - (*m_volumes)[i]->set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis)); + v.set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis)); else if (m_mode == Volume) - (*m_volumes)[i]->set_volume_mirror(axis, -(*m_volumes)[i]->get_volume_mirror(axis)); + v.set_volume_mirror(axis, -(*m_volumes)[i]->get_volume_mirror(axis)); } #if !DISABLE_INSTANCES_SYNCH @@ -974,9 +990,9 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) return; for (unsigned int i : m_list) { - GLVolume* v = (*m_volumes)[i]; - if (v->object_idx() == (int)object_idx) - v->set_instance_offset(v->get_instance_offset() + displacement); + GLVolume& v = *(*m_volumes)[i]; + if (v.object_idx() == (int)object_idx) + v.set_instance_offset(v.get_instance_offset() + displacement); } std::set done; // prevent processing volumes twice @@ -998,11 +1014,11 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) if (done.find(j) != done.end()) continue; - GLVolume* v = (*m_volumes)[j]; - if (v->object_idx() != object_idx) + GLVolume& v = *(*m_volumes)[j]; + if (v.object_idx() != object_idx) continue; - v->set_instance_offset(v->get_instance_offset() + displacement); + v.set_instance_offset(v.get_instance_offset() + displacement); done.insert(j); } } @@ -1016,9 +1032,9 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co return; for (unsigned int i : m_list) { - GLVolume* v = (*m_volumes)[i]; - if (v->object_idx() == (int)object_idx && v->instance_idx() == (int)instance_idx) - v->set_instance_offset(v->get_instance_offset() + displacement); + GLVolume& v = *(*m_volumes)[i]; + if (v.object_idx() == (int)object_idx && v.instance_idx() == (int)instance_idx) + v.set_instance_offset(v.get_instance_offset() + displacement); } std::set done; // prevent processing volumes twice @@ -1040,11 +1056,11 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co if (done.find(j) != done.end()) continue; - GLVolume* v = (*m_volumes)[j]; - if (v->object_idx() != object_idx || v->instance_idx() != (int)instance_idx) + GLVolume& v = *(*m_volumes)[j]; + if (v.object_idx() != object_idx || v.instance_idx() != (int)instance_idx) continue; - v->set_instance_offset(v->get_instance_offset() + displacement); + v.set_instance_offset(v.get_instance_offset() + displacement); done.insert(j); } } @@ -1641,10 +1657,16 @@ void Selection::update_type() void Selection::set_caches() { m_cache.volumes_data.clear(); - for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) - { - const GLVolume* v = (*m_volumes)[i]; - m_cache.volumes_data.emplace(i, VolumeCache(v->get_volume_transformation(), v->get_instance_transformation())); +#if ENABLE_ALLOW_NEGATIVE_Z + m_cache.sinking_volumes.clear(); +#endif // ENABLE_ALLOW_NEGATIVE_Z + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { + const GLVolume& v = *(*m_volumes)[i]; + m_cache.volumes_data.emplace(i, VolumeCache(v.get_volume_transformation(), v.get_instance_transformation())); +#if ENABLE_ALLOW_NEGATIVE_Z + if (v.is_sinking()) + m_cache.sinking_volumes.push_back(i); +#endif // ENABLE_ALLOW_NEGATIVE_Z } m_cache.dragging_center = get_bounding_box().center(); } diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index ae82f9ca7..c6409f9f2 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -186,6 +186,10 @@ private: // to a set of indices of ModelVolume instances in ModelObject::instances // Here the index means a position inside the respective std::vector, not ObjectID. ObjectIdxsToInstanceIdxsMap content; +#if ENABLE_ALLOW_NEGATIVE_Z + // List of ids of the volumes which are sinking when starting dragging + std::vector sinking_volumes; +#endif // ENABLE_ALLOW_NEGATIVE_Z }; // Volumes owned by GLCanvas3D.