Merge branch 'lm_drop_to_bed'

This commit is contained in:
Lukas Matena 2019-07-12 13:38:18 +02:00
commit 45db42ca3b
4 changed files with 66 additions and 7 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

View file

@ -410,6 +410,8 @@ public:
BoundingBoxf3 transformed_convex_hull_bounding_box(const Transform3d &trafo) const; BoundingBoxf3 transformed_convex_hull_bounding_box(const Transform3d &trafo) const;
// caching variant // caching variant
const BoundingBoxf3& transformed_convex_hull_bounding_box() const; const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
// convex hull
const TriangleMesh* convex_hull() const { return m_convex_hull.get(); }
bool empty() const { return this->indexed_vertex_array.empty(); } bool empty() const { return this->indexed_vertex_array.empty(); }

View file

@ -17,6 +17,28 @@ namespace Slic3r
namespace GUI 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<float>();
// 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<float>::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) static wxBitmapComboBox* create_word_local_combo(wxWindow *parent)
{ {
wxSize size(15 * wxGetApp().em_unit(), -1); wxSize size(15 * wxGetApp().em_unit(), -1);
@ -185,7 +207,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
unsigned int axis_idx = (axis[0] - 'x'); // 0, 1 or 2 unsigned int axis_idx = (axis[0] - 'x'); // 0, 1 or 2
// We will add a button to toggle mirroring to each axis: // We will add a button to toggle mirroring to each axis:
auto mirror_button = [=](wxWindow* parent) { auto mirror_button = [this, mirror_btn_width, axis_idx, &label](wxWindow* parent) {
wxSize btn_size(em_unit(parent) * mirror_btn_width, em_unit(parent) * mirror_btn_width); wxSize btn_size(em_unit(parent) * mirror_btn_width, em_unit(parent) * mirror_btn_width);
auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off.png", wxEmptyString, btn_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off.png", wxEmptyString, btn_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW);
btn->SetToolTip(wxString::Format(_(L("Toggle %s axis mirroring")), label)); btn->SetToolTip(wxString::Format(_(L("Toggle %s axis mirroring")), label));
@ -195,7 +217,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn); sizer->Add(btn);
btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent &e) {
Axis axis = (Axis)(axis_idx + X); Axis axis = (Axis)(axis_idx + X);
if (m_mirror_buttons[axis_idx].second == mbHidden) if (m_mirror_buttons[axis_idx].second == mbHidden)
return; return;
@ -258,13 +280,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
return btn; return btn;
}; };
// Add reset scale button // Add reset scale button
auto reset_scale_button = [=](wxWindow* parent) { auto reset_scale_button = [this](wxWindow* parent) {
auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo"));
btn->SetToolTip(_(L("Reset scale"))); btn->SetToolTip(_(L("Reset scale")));
m_reset_scale_button = btn; m_reset_scale_button = btn;
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn, wxBU_EXACTFIT); sizer->Add(btn, wxBU_EXACTFIT);
btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
change_scale_value(0, 100.); change_scale_value(0, 100.);
change_scale_value(1, 100.); change_scale_value(1, 100.);
change_scale_value(2, 100.); change_scale_value(2, 100.);
@ -275,13 +297,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
} }
else if (option_name == "Rotation") { else if (option_name == "Rotation") {
// Add reset rotation button // Add reset rotation button
auto reset_rotation_button = [=](wxWindow* parent) { auto reset_rotation_button = [this](wxWindow* parent) {
auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); auto btn = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo"));
btn->SetToolTip(_(L("Reset rotation"))); btn->SetToolTip(_(L("Reset rotation")));
m_reset_rotation_button = btn; m_reset_rotation_button = btn;
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn, wxBU_EXACTFIT); sizer->Add(btn, wxBU_EXACTFIT);
btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent &e) { btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
Selection& selection = canvas->get_selection(); Selection& selection = canvas->get_selection();
@ -310,6 +332,34 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
}; };
line.append_widget(reset_rotation_button); 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());
const Geometry::Transformation& instance_trafo = volume->get_instance_transformation();
Vec3d diff = m_cache.position - instance_trafo.get_matrix(true).inverse() * 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 // Add empty bmp (Its size have to be equal to PrusaLockButton) in front of "Size" option to label alignment
else if (option_name == "Size") { else if (option_name == "Size") {
line.near_label_widget = [this](wxWindow* parent) { line.near_label_widget = [this](wxWindow* parent) {
@ -536,11 +586,13 @@ void ObjectManipulation::update_reset_buttons_visibility()
bool show_rotation = false; bool show_rotation = false;
bool show_scale = 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()) { 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()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
Vec3d rotation; Vec3d rotation;
Vec3d scale; Vec3d scale;
double min_z = 0.;
if (selection.is_single_full_instance()) { if (selection.is_single_full_instance()) {
rotation = volume->get_instance_rotation(); rotation = volume->get_instance_rotation();
@ -549,14 +601,17 @@ void ObjectManipulation::update_reset_buttons_visibility()
else { else {
rotation = volume->get_volume_rotation(); rotation = volume->get_volume_rotation();
scale = volume->get_volume_scaling_factor(); scale = volume->get_volume_scaling_factor();
min_z = get_volume_min_z(volume);
} }
show_rotation = !rotation.isApprox(Vec3d::Zero()); show_rotation = !rotation.isApprox(Vec3d::Zero());
show_scale = !scale.isApprox(Vec3d::Ones()); 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_rotation_button->Show(show_rotation);
m_reset_scale_button->Show(show_scale); m_reset_scale_button->Show(show_scale);
m_drop_to_bed_button->Show(show_drop_to_bed);
}); });
} }
@ -869,6 +924,7 @@ void ObjectManipulation::msw_rescale()
m_mirror_bitmap_hidden.msw_rescale(); m_mirror_bitmap_hidden.msw_rescale();
m_reset_scale_button->msw_rescale(); m_reset_scale_button->msw_rescale();
m_reset_rotation_button->msw_rescale(); m_reset_rotation_button->msw_rescale();
m_drop_to_bed_button->msw_rescale();
get_og()->msw_rescale(); get_og()->msw_rescale();
} }

View file

@ -56,6 +56,7 @@ class ObjectManipulation : public OG_Settings
// Non-owning pointers to the reset buttons, so we can hide and show them. // Non-owning pointers to the reset buttons, so we can hide and show them.
ScalableButton* m_reset_scale_button = nullptr; ScalableButton* m_reset_scale_button = nullptr;
ScalableButton* m_reset_rotation_button = nullptr; ScalableButton* m_reset_rotation_button = nullptr;
ScalableButton* m_drop_to_bed_button = nullptr;
// Mirroring buttons and their current state // Mirroring buttons and their current state
enum MirrorButtonState { enum MirrorButtonState {