From ed271d66e67ac71ba4cbe681bcfb2a6ae1c4630b Mon Sep 17 00:00:00 2001 From: Enrico Turri <enricoturri@seznam.cz> Date: Thu, 15 Nov 2018 11:38:40 +0100 Subject: [PATCH 1/4] Fixed object picking when gizmos are rendered on top --- src/slic3r/GUI/GLCanvas3D.cpp | 20 ++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c7a1bad5b..da6a9839c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1103,6 +1103,9 @@ GLCanvas3D::Mouse::Drag::Drag() GLCanvas3D::Mouse::Mouse() : dragging(false) , position(DBL_MAX, DBL_MAX) +#if ENABLE_GIZMOS_ON_TOP + , scene_position(DBL_MAX, DBL_MAX, DBL_MAX) +#endif // ENABLE_GIZMOS_ON_TOP #if ENABLE_GIZMOS_RESET , ignore_up_event(false) #endif // ENABLE_GIZMOS_RESET @@ -3601,6 +3604,13 @@ void GLCanvas3D::render() _render_bed(theta); } +#if ENABLE_GIZMOS_ON_TOP + // we need to set the mouse's scene position here because the depth buffer + // could be invalidated by the following gizmo render methods + // this position is used later into on_mouse() to drag the objects + m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<int>()); +#endif // ENABLE_GIZMOS_ON_TOP + _render_current_gizmo(); _render_cutting_plane(); #if ENABLE_SHOW_CAMERA_TARGET @@ -4176,19 +4186,29 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { if (evt.LeftDown() && m_moving_enabled && (m_mouse.drag.move_volume_idx == -1)) { +#if !ENABLE_GIZMOS_ON_TOP // The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate pos x, y, // an converts the screen space coordinate to unscaled object space. Vec3d pos3d = _mouse_to_3d(pos); +#endif // !ENABLE_GIZMOS_ON_TOP // Only accept the initial position, if it is inside the volume bounding box. BoundingBoxf3 volume_bbox = m_volumes.volumes[m_hover_volume_id]->transformed_bounding_box(); volume_bbox.offset(1.0); +#if ENABLE_GIZMOS_ON_TOP + if (volume_bbox.contains(m_mouse.scene_position)) +#else if (volume_bbox.contains(pos3d)) +#endif // ENABLE_GIZMOS_ON_TOP { // The dragging operation is initiated. m_mouse.drag.move_volume_idx = m_hover_volume_id; m_selection.start_dragging(); +#if ENABLE_GIZMOS_ON_TOP + m_mouse.drag.start_position_3D = m_mouse.scene_position; +#else m_mouse.drag.start_position_3D = pos3d; +#endif // ENABLE_GIZMOS_ON_TOP } } else if (evt.RightDown()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index fd4fa1953..be48b1ac2 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -337,6 +337,9 @@ class GLCanvas3D bool dragging; Vec2d position; +#if ENABLE_GIZMOS_ON_TOP + Vec3d scene_position; +#endif // ENABLE_GIZMOS_ON_TOP Drag drag; #if ENABLE_GIZMOS_RESET bool ignore_up_event; From e83e755e8b9aab7c021ae8a368424154e9e5da17 Mon Sep 17 00:00:00 2001 From: Enrico Turri <enricoturri@seznam.cz> Date: Thu, 15 Nov 2018 12:21:09 +0100 Subject: [PATCH 2/4] Fixed crash when dismissing file dialog for quick slice menu command --- src/slic3r/GUI/MainFrame.cpp | 26 +++++++++++++------------- src/slic3r/GUI/MainFrame.hpp | 1 + 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index df4cba60b..b67d19af2 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -233,25 +233,25 @@ void MainFrame::init_menubar() append_menu_item(fileMenu, wxID_ANY, _(L("&Export Config Bundle…")), _(L("Export all presets to file")), [this](wxCommandEvent&) { export_configbundle(); }, "lorry_go.png"); fileMenu->AppendSeparator(); - wxMenuItem* repeat = nullptr; - append_menu_item(fileMenu, wxID_ANY, _(L("Q&uick Slice…\tCtrl+U")), _(L("Slice a file into a G-code")), - [this, repeat](wxCommandEvent&) { - wxTheApp->CallAfter([this, repeat]() { + m_menu_item_repeat = nullptr; + append_menu_item(fileMenu, wxID_ANY, _(L("Q&uick Slice…\tCtrl+U")), _(L("Slice a file into a G-code")), + [this](wxCommandEvent&) { + wxTheApp->CallAfter([this]() { quick_slice(); - repeat->Enable(is_last_input_file()); - }); }, "cog_go.png"); - append_menu_item(fileMenu, wxID_ANY, _(L("Quick Slice and Save &As…\tCtrl+Alt+U")), _(L("Slice a file into a G-code, save as")), - [this, repeat](wxCommandEvent&) { - wxTheApp->CallAfter([this, repeat]() { + m_menu_item_repeat->Enable(is_last_input_file()); + }); }, "cog_go.png"); + append_menu_item(fileMenu, wxID_ANY, _(L("Quick Slice and Save &As…\tCtrl+Alt+U")), _(L("Slice a file into a G-code, save as")), + [this](wxCommandEvent&) { + wxTheApp->CallAfter([this]() { quick_slice(qsSaveAs); - repeat->Enable(is_last_input_file()); - }); }, "cog_go.png"); - repeat = append_menu_item(fileMenu, wxID_ANY, _(L("&Repeat Last Quick Slice\tCtrl+Shift+U")), _(L("Repeat last quick slice")), + m_menu_item_repeat->Enable(is_last_input_file()); + }); }, "cog_go.png"); + m_menu_item_repeat = append_menu_item(fileMenu, wxID_ANY, _(L("&Repeat Last Quick Slice\tCtrl+Shift+U")), _(L("Repeat last quick slice")), [this](wxCommandEvent&) { wxTheApp->CallAfter([this]() { quick_slice(qsReslice); }); }, "cog_go.png"); - repeat->Enable(0); + m_menu_item_repeat->Enable(false); fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _(L("Slice to SV&G…\tCtrl+G")), _(L("Slice file to a multi-layer SVG")), [this](wxCommandEvent&) { quick_slice(qsSaveAs | qsExportSVG); }, "shape_handles.png"); diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index e00216cbc..b6cd7916a 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -55,6 +55,7 @@ class MainFrame : public wxFrame std::map<std::string, Tab*> m_options_tabs; + wxMenuItem* m_menu_item_repeat { nullptr }; wxMenuItem* m_menu_item_reslice_now { nullptr }; wxMenu* m_plater_menu { nullptr }; wxMenu* m_viewMenu{ nullptr }; From ede21eec7afedef4b1f8c61230d7655c8e3cd0ac Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 15 Nov 2018 11:15:24 +0100 Subject: [PATCH 3/4] Rotation/Scale from modification pane for SingleObject, SingleVolume & SingleInstance Note: - doesn't work for group selection - scaling work only with percent mode --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 75 +++++++++++++++++------ src/slic3r/GUI/GUI_ObjectManipulation.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 16 ++--- 3 files changed, 67 insertions(+), 28 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 73c004514..fb1fbbbe6 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -23,11 +23,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : m_og->set_process_enter(); // We need to update new values only after press ENTER m_og->m_on_change = [this](t_config_option_key opt_key, boost::any value) { + std::vector<std::string> axes{ "_x", "_y", "_z" }; + if (opt_key == "scale_unit") { const wxString& selection = boost::any_cast<wxString>(value); - std::vector<std::string> axes{ "x", "y", "z" }; for (auto axis : axes) { - std::string key = "scale_" + axis; + std::string key = "scale" + axis; m_og->set_side_text(key, selection); } @@ -39,13 +40,17 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : std::string param; std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param)); - if (param == "position") { - Vec3d displacement; - displacement(0) = boost::any_cast<double>(m_og->get_value("position_x")); - displacement(1) = boost::any_cast<double>(m_og->get_value("position_y")); - displacement(2) = boost::any_cast<double>(m_og->get_value("position_z")); - change_position_value(displacement); - } + size_t i = 0; + Vec3d new_value; + for (auto axis : axes) + new_value(i++) = boost::any_cast<double>(m_og->get_value(param+axis)); + + if (param == "position") + change_position_value(new_value); + else if (param == "rotation") + change_rotation_value(new_value); + else if (param == "scale") + change_scale_value(new_value); }; ConfigOptionDef def; @@ -132,7 +137,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : m_og->append_line(add_og_to_object_settings(L("Rotation"), "°")); m_og->append_line(add_og_to_object_settings(L("Scale"), "mm")); - + /* Unused parameter at this time def.label = L("Place on bed"); def.type = coBool; def.tooltip = L("Automatic placing of models on printing bed in Y axis"); @@ -140,6 +145,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : def.sidetext = ""; def.default_value = new ConfigOptionBool{ false }; m_og->append_single_option_line(Option(def, "place_on_bed")); + */ } void ObjectManipulation::Show(const bool show) @@ -241,6 +247,8 @@ void ObjectManipulation::update_settings_value(const GLCanvas3D::Selection& sele } else reset_settings_value(); + + m_og->get_field("scale_unit")->disable();// temporary decision } void ObjectManipulation::reset_settings_value() @@ -317,9 +325,9 @@ void ObjectManipulation::update_scale_values() m_og->set_value("scale_z", double_to_string(instance->get_scaling_factor(Z) * 100, 2)); } else { - m_og->set_value("scale_x", double_to_string(instance->get_scaling_factor(X) * size(0) + 0.5, 2)); - m_og->set_value("scale_y", double_to_string(instance->get_scaling_factor(Y) * size(1) + 0.5, 2)); - m_og->set_value("scale_z", double_to_string(instance->get_scaling_factor(Z) * size(2) + 0.5, 2)); + m_og->set_value("scale_x", double_to_string(size(0), 2)); + m_og->set_value("scale_y", double_to_string(size(1), 2)); + m_og->set_value("scale_z", double_to_string(size(2), 2)); } } @@ -347,8 +355,10 @@ void ObjectManipulation::update_scale_value(const Vec3d& scaling_factor) // to be able to update the values as size // we need to store somewhere the original size // or have it passed as parameter - if (!m_is_percent_scale) + if (!m_is_percent_scale) { + m_is_percent_scale = true; m_og->set_value("scale_unit", _("%")); + } auto scale = scaling_factor * 100.0; m_og->set_value("scale_x", double_to_string(scale(0), 2)); @@ -399,11 +409,40 @@ void ObjectManipulation::change_position_value(const Vec3d& position) cache_position = position; } - - -void ObjectManipulation::print_cashe_value(const std::string& label, const Vec3d& value) +void ObjectManipulation::change_rotation_value(const Vec3d& rotation) { - std::cout << label << " => " << " X:" << value(0) << " Y:" << value(1) << " Z:" << value(2) << std::endl; + Vec3d rad_rotation; + for (size_t i = 0; i < 3; ++i) + rad_rotation(i) = Geometry::deg2rad(rotation(i)); + auto canvas = _3DScene::get_canvas(wxGetApp().canvas3D()); + canvas->get_selection().start_dragging(); + canvas->get_selection().rotate(rad_rotation); + canvas->_on_rotate(); +} + +void ObjectManipulation::change_scale_value(const Vec3d& scale) +{ + Vec3d scaling_factor; + if (m_is_percent_scale) + scaling_factor = scale*0.01; + else { + int selection = ol_selection(); + ModelObjectPtrs& objects = *wxGetApp().model_objects(); + + auto size = objects[selection]->instance_bounding_box(0).size(); + for (size_t i = 0; i < 3; ++i) + scaling_factor(i) = scale(i) / size(i); + } + + auto canvas = _3DScene::get_canvas(wxGetApp().canvas3D()); + canvas->get_selection().start_dragging(); + canvas->get_selection().scale(scaling_factor); + canvas->_on_scale(); +} + +void ObjectManipulation::print_cashe_value(const std::string& label, const Vec3d& v) +{ + std::cout << label << " => " << " X:" << v(0) << " Y:" << v(1) << " Z:" << v(2) << std::endl; } } //namespace GUI diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 2f016f46f..6ab76a83b 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -18,8 +18,6 @@ class ObjectManipulation : public OG_Settings bool m_is_uniform_scale = false; // It indicates if scale is uniform Vec3d cache_position { 0., 0., 0. }; - Vec3d cache_rotation { 0., 0., 0. }; - Vec3d cache_scale { 0., 0., 0. }; public: ObjectManipulation(wxWindow* parent); @@ -55,6 +53,8 @@ public: // change values void change_position_value(const Vec3d& position); + void change_rotation_value(const Vec3d& rotation); + void change_scale_value(const Vec3d& scale); private: diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cd045d1a5..3840b248c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -449,8 +449,7 @@ void Sidebar::priv::show_preset_comboboxes() { const bool showSLA = plater->printer_technology() == ptSLA; - wxWindowUpdateLocker noUpdates_scrolled(scrolled); -// scrolled->Freeze(); + wxWindowUpdateLocker noUpdates_scrolled(scrolled->GetParent()); for (size_t i = 0; i < 4; ++i) { if (sizer_presets->IsShown(i) == showSLA) @@ -465,8 +464,8 @@ void Sidebar::priv::show_preset_comboboxes() if (frequently_changed_parameters->IsShown() == showSLA) frequently_changed_parameters->Show(!showSLA); - scrolled->Layout(); -// scrolled->Thaw(); + scrolled->GetParent()->Layout(); + scrolled->Refresh(); } @@ -710,7 +709,7 @@ void Sidebar::show_info_sizer() const ModelInstance* model_instance = !model_object->instances.empty() ? model_object->instances.front() : nullptr; - auto size = model_object->instance_bounding_box(0).size(); + auto size = model_object->bounding_box().size(); p->object_info->info_size->SetLabel(wxString::Format("%.2f x %.2f x %.2f",size(0), size(1), size(2))); p->object_info->info_materials->SetLabel(wxString::Format("%d", static_cast<int>(model_object->materials_count()))); @@ -776,6 +775,7 @@ void Sidebar::show_sliced_info_sizer(const bool show) } Layout(); + p->scrolled->Refresh(); } void Sidebar::show_buttons(const bool show) @@ -2370,7 +2370,7 @@ void Plater::on_extruders_change(int num_extruders) { auto& choices = sidebar().combos_filament(); - wxWindowUpdateLocker noUpdates_scrolled_panel(sidebar().scrolled_panel()); + wxWindowUpdateLocker noUpdates_scrolled_panel(&sidebar()/*.scrolled_panel()*/); // sidebar().scrolled_panel()->Freeze(); int i = choices.size(); @@ -2388,8 +2388,8 @@ void Plater::on_extruders_change(int num_extruders) // remove unused choices if any sidebar().remove_unused_filament_combos(num_extruders); - sidebar().scrolled_panel()->Layout(); -// sidebar().scrolled_panel()->Thaw(); + sidebar().Layout(); + sidebar().scrolled_panel()->Refresh(); } void Plater::on_config_change(const DynamicPrintConfig &config) From 410568c9d958dfd4d75a31da6614475439343ab8 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 15 Nov 2018 12:25:08 +0100 Subject: [PATCH 4/4] Temporary workaround for the correct behavior of the Scrolled sidebar panel --- src/slic3r/GUI/GUI_App.cpp | 10 ++++++++++ src/slic3r/GUI/GUI_ObjectList.cpp | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 66ac7a979..c201d4018 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -115,6 +115,16 @@ bool GUI_App::OnInit() update_mode(); SetTopWindow(mainframe); + CallAfter([this]() { + // temporary workaround for the correct behavior of the Scrolled sidebar panel + auto& panel = sidebar(); + if (panel.obj_list()->GetMinHeight() > 200) { + wxWindowUpdateLocker noUpdates_sidebar(&panel); + panel.obj_list()->SetMinSize(wxSize(-1, 200)); + panel.Layout(); + } + }); + // This makes CallAfter() work Bind(wxEVT_IDLE, [this](wxIdleEvent& event) { diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a616307ba..01815cfd6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -83,7 +83,10 @@ ObjectList::~ObjectList() void ObjectList::create_objects_ctrl() { - SetMinSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + // temporary workaround for the correct behavior of the Scrolled sidebar panel: + // 1. set a height of the list to some big value + // 2. change it to the normal min value (200) after first whole App updating/layouting + SetMinSize(wxSize(-1, 1500)); // #ys_FIXME m_sizer = new wxBoxSizer(wxVERTICAL); m_sizer->Add(this, 1, wxGROW | wxLEFT, 20);