From 3d8c3804fab810568adedce76836ea97e7e1c71d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 19 Jun 2019 10:46:42 +0200 Subject: [PATCH] Added 'drop to bed' button into object manipulation panel --- resources/icons/drop_to_bed.png | Bin 0 -> 528 bytes src/slic3r/GUI/3DScene.hpp | 2 + src/slic3r/GUI/GUI_ObjectManipulation.cpp | 57 +++++++++++++++++++++- src/slic3r/GUI/GUI_ObjectManipulation.hpp | 1 + 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 resources/icons/drop_to_bed.png diff --git a/resources/icons/drop_to_bed.png b/resources/icons/drop_to_bed.png new file mode 100644 index 0000000000000000000000000000000000000000..b60e1b137d9d12a1cfc177de1d51eb7c7093aa7b GIT binary patch literal 528 zcmV+r0`L8aP)pZ4MY$`uvwNR!r;okMbKJk8Mr7Sc?B_4 zw3vhk*&h#jJRY=Z9WH}5j=0iAViLGQMuMqqF{$nne8*(H`8hk~-;c&PlNg4nEF!8fo zAB{$(kqK(G+PT~9o+ZhoNVD0z(sliTyuVApvaFM$sJEMv_I2*lK8?hfruj57K`9N$uNw6@pwG@@d=4U;%B$pZI{dCsB#M&HN# z(T$${eQO-sVHtp7jYUy>bJR3V$(^0?{b#F314aL;=?9riril=m#u&2t-indexed_vertex_array.empty(); } bool indexed() const { return this->indexed_vertex_array.indexed(); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 4ccaa6847..7363b2c16 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -17,6 +17,28 @@ namespace Slic3r namespace GUI { + +// Helper function to be used by drop to bed button. Returns lowest point of this +// volume in world coordinate system. +static double get_volume_min_z(const GLVolume* volume) +{ + const Transform3f& world_matrix = volume->world_matrix().cast(); + + // need to get the ModelVolume pointer + const ModelObject* mo = wxGetApp().model_objects()->at(volume->composite_id.object_id); + const ModelVolume* mv = mo->volumes[volume->composite_id.volume_id]; + const TriangleMesh& hull = mv->get_convex_hull(); + + float min_z = std::numeric_limits::max(); + for (const stl_facet& facet : hull.stl.facet_start) { + for (int i = 0; i < 3; ++ i) + min_z = std::min(min_z, Vec3f::UnitZ().dot(world_matrix * facet.vertex[i])); + } + return min_z; +} + + + static wxBitmapComboBox* create_word_local_combo(wxWindow *parent) { wxSize size(15 * wxGetApp().em_unit(), -1); @@ -310,6 +332,33 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : }; line.append_widget(reset_rotation_button); } + else if (option_name == "Position") { + // Add drop to bed button + auto drop_to_bed_button = [=](wxWindow* parent) { + auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "drop_to_bed.png")); + btn->SetToolTip(_(L("Drop to bed"))); + m_drop_to_bed_button = btn; + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(btn, wxBU_EXACTFIT); + btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { + // ??? + GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); + Selection& selection = canvas->get_selection(); + + if (selection.is_single_volume() || selection.is_single_modifier()) { + const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); + + Vec3d diff = m_cache.position - Vec3d(0., 0., get_volume_min_z(volume)); + + change_position_value(0, diff.x()); + change_position_value(1, diff.y()); + change_position_value(2, diff.z()); + } + }); + return sizer; + }; + line.append_widget(drop_to_bed_button); + } // Add empty bmp (Its size have to be equal to PrusaLockButton) in front of "Size" option to label alignment else if (option_name == "Size") { line.near_label_widget = [this](wxWindow* parent) { @@ -534,11 +583,13 @@ void ObjectManipulation::update_reset_buttons_visibility() bool show_rotation = false; bool show_scale = false; + bool show_drop_to_bed = false; if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); Vec3d rotation; Vec3d scale; + double min_z = 0.; if (selection.is_single_full_instance()) { rotation = volume->get_instance_rotation(); @@ -547,14 +598,17 @@ void ObjectManipulation::update_reset_buttons_visibility() else { rotation = volume->get_volume_rotation(); scale = volume->get_volume_scaling_factor(); + min_z = get_volume_min_z(volume); } show_rotation = !rotation.isApprox(Vec3d::Zero()); show_scale = !scale.isApprox(Vec3d::Ones()); + show_drop_to_bed = (std::abs(min_z) > EPSILON); } - wxGetApp().CallAfter([this, show_rotation, show_scale]{ + wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed]{ m_reset_rotation_button->Show(show_rotation); m_reset_scale_button->Show(show_scale); + m_drop_to_bed_button->Show(show_drop_to_bed); }); } @@ -867,6 +921,7 @@ void ObjectManipulation::msw_rescale() m_mirror_bitmap_hidden.msw_rescale(); m_reset_scale_button->msw_rescale(); m_reset_rotation_button->msw_rescale(); + m_drop_to_bed_button->msw_rescale(); get_og()->msw_rescale(); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index cc2154514..e4e190b5b 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -56,6 +56,7 @@ class ObjectManipulation : public OG_Settings // Non-owning pointers to the reset buttons, so we can hide and show them. ScalableButton* m_reset_scale_button = nullptr; ScalableButton* m_reset_rotation_button = nullptr; + ScalableButton* m_drop_to_bed_button = nullptr; // Mirroring buttons and their current state enum MirrorButtonState {