From a5fd9a34e88b22cdde9883516637d1786f86efba Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 22 Mar 2019 09:47:40 +0100 Subject: [PATCH 1/4] Do not consider modifiers when centering an object after 3mf and amf import --- src/libslic3r/Model.cpp | 6 +++++- src/libslic3r/Model.hpp | 4 ++++ src/slic3r/GUI/Plater.cpp | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 68f71c308..f9db9fea0 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -997,12 +997,16 @@ Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) return hull; } +#if ENABLE_VOLUMES_CENTERING_FIXES +void ModelObject::center_around_origin(bool include_modifiers) +#else void ModelObject::center_around_origin() +#endif // ENABLE_VOLUMES_CENTERING_FIXES { // calculate the displacements needed to // center this object around the origin #if ENABLE_VOLUMES_CENTERING_FIXES - BoundingBoxf3 bb = full_raw_mesh_bounding_box(); + BoundingBoxf3 bb = include_modifiers ? full_raw_mesh_bounding_box() : raw_mesh_bounding_box(); #else BoundingBoxf3 bb; for (ModelVolume *v : this->volumes) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 1260500ee..8a48f8ee9 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -236,7 +236,11 @@ public: // This method is used by the auto arrange function. Polygon convex_hull_2d(const Transform3d &trafo_instance); +#if ENABLE_VOLUMES_CENTERING_FIXES + void center_around_origin(bool include_modifiers = true); +#else void center_around_origin(); +#endif // ENABLE_VOLUMES_CENTERING_FIXES void ensure_on_bed(); void translate_instances(const Vec3d& vector); void translate_instance(size_t instance_idx, const Vec3d& vector); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2acc2cec4..906a5009a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1617,7 +1617,11 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (type_3mf || type_any_amf) { #endif // !ENABLE_VOLUMES_CENTERING_FIXES for (ModelObject* model_object : model.objects) { +#if ENABLE_VOLUMES_CENTERING_FIXES + model_object->center_around_origin(false); +#else model_object->center_around_origin(); +#endif // ENABLE_VOLUMES_CENTERING_FIXES model_object->ensure_on_bed(); } #if !ENABLE_VOLUMES_CENTERING_FIXES From 0848617fd37e16f9404a208192d0dc8f9e18925a Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 22 Mar 2019 10:56:51 +0100 Subject: [PATCH 2/4] SLA gizmo fix: adding points to selection by Shift+click should now work again (was broken by 8466c55) --- src/slic3r/GUI/GLCanvas3D.cpp | 8 ++++---- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b08688784..1bcc53efd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3521,6 +3521,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _update_gizmos_data(); m_dirty = true; } + else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) + { + // the gizmo got the event and took some action, there is no need to do anything more + } else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) { _update_gizmos_data(); @@ -3536,10 +3540,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } - else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) - { - // the gizmo got the event and took some action, there is no need to do anything more - } else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown)) { // event was taken care of by the SlaSupports gizmo diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 619ae3b3f..c629f2172 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -328,6 +328,10 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous // left down without selection rectangle - place point on the mesh: if (action == SLAGizmoEventType::LeftDown && !m_selection_rectangle_active && !shift_down) { + // If any point is in hover state, this should initiate its move - return control back to GLCanvas: + if (m_hover_id != -1) + return false; + // If there is some selection, don't add new point and deselect everything instead. if (m_selection_empty) { try { From bbb2a6d714d0c89f00847b47b1569b0849dd4f60 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 22 Mar 2019 11:51:10 +0100 Subject: [PATCH 3/4] Fixed non-uniform scale of single volumes selection when made using the sidebar matrix fields --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index f759250b3..6c8fdcab7 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -209,8 +209,8 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_position = volume->get_volume_offset(); m_new_rotation = volume->get_volume_rotation(); m_new_scale = volume->get_volume_scaling_factor(); - m_new_size = volume->get_instance_transformation().get_matrix(true, true) * volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size(); - m_new_enabled = true; + m_new_size = volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size(); + m_new_enabled = true; } else if (wxGetApp().obj_list()->multiple_selection()) { From f5516f24c444d26c0c791f4c239eb35ba60f9f37 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 22 Mar 2019 12:11:23 +0100 Subject: [PATCH 4/4] Fix of 1.42 beta crash when deleting printer profile created by configuration assistant #1985 Fixed an issue, where deleting a profile did not correctly update profile dependences, and deleting a profile would not test dirty status of depending profiles, which would be switched thus user changes would be lost. Fixed enabling / disabling the --default FFF-- / --default SLA-- profiles when deleting the last printer profile. Little refactoring (don't compare by strings but by symbolic names). Making a copy of a profile - "Copy" suffix is added to a system profile. --- src/slic3r/GUI/Preset.cpp | 21 ++++++--- src/slic3r/GUI/Preset.hpp | 5 ++- src/slic3r/GUI/Tab.cpp | 94 ++++++++++++++++++++++++--------------- src/slic3r/GUI/Tab.hpp | 3 +- 4 files changed, 79 insertions(+), 44 deletions(-) diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 656658b0b..e63ae32f7 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -740,6 +740,8 @@ void PresetCollection::save_current_preset(const std::string &new_name) return; // Overwriting an existing preset. preset.config = std::move(m_edited_preset.config); + // The newly saved preset will be activated -> make it visible. + preset.is_visible = true; } else { // Creating a new preset. Preset &preset = *m_presets.insert(it, m_edited_preset); @@ -761,18 +763,20 @@ void PresetCollection::save_current_preset(const std::string &new_name) preset.is_default = false; preset.is_system = false; preset.is_external = false; - } + // The newly saved preset will be activated -> make it visible. + preset.is_visible = true; + } // 2) Activate the saved preset. this->select_preset_by_name(new_name, true); // 2) Store the active preset to disk. this->get_selected_preset().save(); } -void PresetCollection::delete_current_preset() +bool PresetCollection::delete_current_preset() { const Preset &selected = this->get_selected_preset(); - if (selected.is_default) - return; + if (selected.is_default) + return false; if (! selected.is_external && ! selected.is_system) { // Erase the preset file. boost::nowide::remove(selected.file.c_str()); @@ -786,6 +790,7 @@ void PresetCollection::delete_current_preset() if (new_selected_idx == m_presets.size()) for (--new_selected_idx; new_selected_idx > 0 && !m_presets[new_selected_idx].is_visible; --new_selected_idx); this->select_preset(new_selected_idx); + return true; } bool PresetCollection::load_bitmap_default(const std::string &file_name) @@ -843,7 +848,9 @@ void PresetCollection::set_default_suppressed(bool default_suppressed) { if (m_default_suppressed != default_suppressed) { m_default_suppressed = default_suppressed; - m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > m_num_default_presets && m_idx_selected > 0); + bool default_visible = ! default_suppressed || m_idx_selected < m_num_default_presets; + for (size_t i = 0; i < m_num_default_presets; ++ i) + m_presets[i].is_visible = default_visible; } } @@ -1114,7 +1121,9 @@ Preset& PresetCollection::select_preset(size_t idx) idx = first_visible_idx(); m_idx_selected = idx; m_edited_preset = m_presets[idx]; - m_presets.front().is_visible = ! m_default_suppressed || m_idx_selected == 0; + bool default_visible = ! m_default_suppressed || m_idx_selected < m_num_default_presets; + for (size_t i = 0; i < m_num_default_presets; ++i) + m_presets[i].is_visible = default_visible; return m_presets[idx]; } diff --git a/src/slic3r/GUI/Preset.hpp b/src/slic3r/GUI/Preset.hpp index 511313715..c84c37029 100644 --- a/src/slic3r/GUI/Preset.hpp +++ b/src/slic3r/GUI/Preset.hpp @@ -115,6 +115,8 @@ public: // Is this preset compatible with the currently active printer? bool is_compatible = true; + bool is_user() const { return ! this->is_default && ! this->is_system; } + // Name of the preset, usually derived form the file name. std::string name; // File name of the preset. This could be a Print / Filament / Printer preset, @@ -269,7 +271,8 @@ public: void save_current_preset(const std::string &new_name); // Delete the current preset, activate the first visible preset. - void delete_current_preset(); + // returns true if the preset was deleted successfully. + bool delete_current_preset(); // Load default bitmap to be placed at the wxBitmapComboBox of a MainFrame. bool load_bitmap_default(const std::string &file_name); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 46a6de6ab..d38e96ca2 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -385,7 +385,7 @@ void Tab::update_changed_ui() if (m_postpone_update_ui) return; - const bool deep_compare = (m_name == "printer" || m_name == "sla_material"); + const bool deep_compare = (m_type == Slic3r::Preset::TYPE_PRINTER || m_type == Slic3r::Preset::TYPE_SLA_MATERIAL); auto dirty_options = m_presets->current_dirty_options(deep_compare); auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare); if (m_type == Slic3r::Preset::TYPE_PRINTER) { @@ -2395,7 +2395,7 @@ void Tab::load_current_preset() (preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true); update(); - if (m_name == "printer") { + if (m_type == Slic3r::Preset::TYPE_PRINTER) { // For the printer profile, generate the extruder pages. if (preset.printer_technology() == ptFFF) on_preset_loaded(); @@ -2425,7 +2425,7 @@ void Tab::load_current_preset() update_tab_ui(); // update show/hide tabs - if (m_name == "printer") { + if (m_type == Slic3r::Preset::TYPE_PRINTER) { const PrinterTechnology printer_technology = m_presets->get_edited_preset().printer_technology(); if (printer_technology != static_cast(this)->m_printer_technology) { @@ -2458,7 +2458,7 @@ void Tab::load_current_preset() } else { on_presets_changed(); - if (m_type == Preset::TYPE_SLA_PRINT || m_type == Preset::TYPE_PRINT)// if (m_name == "print") + if (m_type == Preset::TYPE_SLA_PRINT || m_type == Preset::TYPE_PRINT) update_frequently_changed_parameters(); } @@ -2526,20 +2526,35 @@ void Tab::update_page_tree_visibility() } -// Called by the UI combo box when the user switches profiles. +// Called by the UI combo box when the user switches profiles, and also to delete the current profile. // Select a preset by a name.If !defined(name), then the default preset is selected. // If the current profile is modified, user is asked to save the changes. -void Tab::select_preset(std::string preset_name) +void Tab::select_preset(std::string preset_name, bool delete_current) { - // If no name is provided, select the "-- default --" preset. - if (preset_name.empty()) - preset_name = m_presets->default_preset().name; - bool current_dirty = m_presets->current_is_dirty(); + if (preset_name.empty()) { + if (delete_current) { + // Find an alternate preset to be selected after the current preset is deleted. + const std::deque &presets = this->m_presets->get_presets(); + size_t idx_current = this->m_presets->get_idx_selected(); + // Find the next visible preset. + size_t idx_new = idx_current + 1; + if (idx_new < presets.size()) + for (; idx_new < presets.size() && ! presets[idx_new].is_visible; ++ idx_new) ; + if (idx_new == presets.size()) + for (idx_new = idx_current - 1; idx_new > 0 && ! presets[idx_new].is_visible; -- idx_new); + preset_name = presets[idx_new].name; + } else { + // If no name is provided, select the "-- default --" preset. + preset_name = m_presets->default_preset().name; + } + } + assert(! delete_current || (m_presets->get_edited_preset().name != preset_name && m_presets->get_edited_preset().is_user())); + bool current_dirty = ! delete_current && m_presets->current_is_dirty(); bool print_tab = m_presets->type() == Preset::TYPE_PRINT || m_presets->type() == Preset::TYPE_SLA_PRINT; bool printer_tab = m_presets->type() == Preset::TYPE_PRINTER; bool canceled = false; m_dependent_tabs = {}; - if (current_dirty && !may_discard_current_dirty_preset()) { + if (current_dirty && ! may_discard_current_dirty_preset()) { canceled = true; } else if (print_tab) { // Before switching the print profile to a new one, verify, whether the currently active filament or SLA material @@ -2602,6 +2617,19 @@ void Tab::select_preset(std::string preset_name) } } } + + if (! canceled && delete_current) { + // Delete the file and select some other reasonable preset. + // It does not matter which preset will be made active as the preset will be re-selected from the preset_name variable. + // The 'external' presets will only be removed from the preset list, their files will not be deleted. + try { + m_presets->delete_current_preset(); + } catch (const std::exception & /* e */) { + //FIXME add some error reporting! + canceled = true; + } + } + if (canceled) { update_tab_ui(); // Trigger the on_presets_changed event so that we also restore the previous value in the plater selector, @@ -2610,17 +2638,19 @@ void Tab::select_preset(std::string preset_name) } else { if (current_dirty) m_presets->discard_current_changes(); - const bool is_selected = m_presets->select_preset_by_name(preset_name, false); + + const bool is_selected = m_presets->select_preset_by_name(preset_name, false) || delete_current; + assert(m_presets->get_edited_preset().name == preset_name || ! is_selected); // Mark the print & filament enabled if they are compatible with the currently selected preset. // The following method should not discard changes of current print or filament presets on change of a printer profile, // if they are compatible with the current printer. - if (current_dirty || print_tab || printer_tab) + if (current_dirty || delete_current || print_tab || printer_tab) m_preset_bundle->update_compatible(true); // Initialize the UI from the current preset. if (printer_tab) static_cast(this)->update_pages(); - if (!is_selected && printer_tab) + if (! is_selected && printer_tab) { /* There is a case, when : * after Config Wizard applying we try to select previously selected preset, but @@ -2631,15 +2661,10 @@ void Tab::select_preset(std::string preset_name) * to the corresponding printer_technology */ const PrinterTechnology printer_technology = m_presets->get_edited_preset().printer_technology(); - if (printer_technology == ptFFF && m_dependent_tabs.front() != Preset::Type::TYPE_PRINT || - printer_technology == ptSLA && m_dependent_tabs.front() != Preset::Type::TYPE_SLA_PRINT ) - { - m_dependent_tabs.clear(); - if (printer_technology == ptFFF) - m_dependent_tabs = { Preset::Type::TYPE_PRINT, Preset::Type::TYPE_FILAMENT }; - else - m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL }; - } + if (printer_technology == ptFFF && m_dependent_tabs.front() != Preset::Type::TYPE_PRINT) + m_dependent_tabs = { Preset::Type::TYPE_PRINT, Preset::Type::TYPE_FILAMENT }; + else if (printer_technology == ptSLA && m_dependent_tabs.front() != Preset::Type::TYPE_SLA_PRINT) + m_dependent_tabs = { Preset::Type::TYPE_SLA_PRINT, Preset::Type::TYPE_SLA_MATERIAL }; } load_current_preset(); } @@ -2771,11 +2796,14 @@ void Tab::save_preset(std::string name /*= ""*/) //! m_treectrl->OnSetFocus(); if (name.empty()) { - auto preset = m_presets->get_selected_preset(); + const Preset &preset = m_presets->get_selected_preset(); auto default_name = preset.is_default ? "Untitled" : preset.name; + if (preset.is_system) { + default_name += " - "; + default_name += _(L("Copy")).ToUTF8().data(); + } bool have_extention = boost::iends_with(default_name, ".ini"); - if (have_extention) - { + if (have_extention) { size_t len = default_name.length()-4; default_name.resize(len); } @@ -2819,7 +2847,7 @@ void Tab::save_preset(std::string name /*= ""*/) // If current profile is saved, "delete preset" button have to be enabled m_btn_delete_preset->Enable(true); - if (m_name == "printer") + if (m_type == Preset::TYPE_PRINTER) static_cast(this)->m_initial_extruders_count = static_cast(this)->m_extruders_count; update_changed_ui(); } @@ -2836,15 +2864,9 @@ void Tab::delete_preset() if (current_preset.is_default || wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) return; - // Delete the file and select some other reasonable preset. - // The 'external' presets will only be removed from the preset list, their files will not be deleted. - try{ m_presets->delete_current_preset(); } - catch (const std::exception & /* e */) - { - return; - } - // Load the newly selected preset into the UI, update selection combo boxes with their dirty flags. - load_current_preset(); + // Select will handle of the preset dependencies, of saving & closing the depending profiles, and + // finally of deleting the preset. + this->select_preset("", true); } void Tab::toggle_show_hide_incompatible() diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 15ae0443c..58950990c 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -239,7 +239,8 @@ public: void load_current_preset(); void rebuild_page_tree(); void update_page_tree_visibility(); - void select_preset(std::string preset_name = ""); + // Select a new preset, possibly delete the current one. + void select_preset(std::string preset_name = "", bool delete_current = false); bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = ""); bool may_switch_to_SLA_preset();