From 5b15e778ef6ed9d12ec0a5105c8cf4be4d9aa01d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 29 Apr 2020 10:58:38 +0200 Subject: [PATCH 01/17] Selection rectangle is supressed when FDM custom supports gizmo is active --- src/slic3r/GUI/GLCanvas3D.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 40568f8ded..375c473f04 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3658,7 +3658,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) { - if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports) + if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports + && m_gizmos.get_current_type() != GLGizmosManager::FdmSupports) { m_rectangle_selection.start_dragging(m_mouse.position, evt.ShiftDown() ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect); m_dirty = true; From 04cfd5f832bc147e1b7bd79a16e72e65d89d8e14 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 29 Apr 2020 13:35:35 +0200 Subject: [PATCH 02/17] Fix updating of gizmos when instances are added Gizmos were in fact updated after an instance was added, but before it was selected --- src/slic3r/GUI/GUI_ObjectList.cpp | 1 + src/slic3r/GUI/Plater.cpp | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 1f2ce0221d..b2283ba4a2 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2771,6 +2771,7 @@ void ObjectList::delete_all_objects_from_list() void ObjectList::increase_object_instances(const size_t obj_idx, const size_t num) { select_item(m_objects_model->AddInstanceChild(m_objects_model->GetItemById(obj_idx), num)); + selection_changed(); } void ObjectList::decrease_object_instances(const size_t obj_idx, const size_t num) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d909442b97..e86b0580db 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4377,8 +4377,6 @@ void Plater::increase_instances(size_t num) // p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec)); } - sidebar().obj_list()->increase_object_instances(obj_idx, was_one_instance ? num + 1 : num); - if (p->get_config("autocenter") == "1") arrange(); @@ -4386,8 +4384,9 @@ void Plater::increase_instances(size_t num) p->get_selection().add_instance(obj_idx, (int)model_object->instances.size() - 1); - p->selection_changed(); + sidebar().obj_list()->increase_object_instances(obj_idx, was_one_instance ? num + 1 : num); + p->selection_changed(); this->p->schedule_background_process(); } From 377c7d30865bb0dbb3816bdcb22d77a9d4d7cad7 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 30 Apr 2020 16:44:09 +0200 Subject: [PATCH 03/17] FDM supports gizmo is aware of the clipping plane --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 41 +++++++++++++++++++- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 2 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 8094d10ad0..1d276dd3d5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -90,6 +90,20 @@ void GLGizmoFdmSupports::render_triangles(const Selection& selection) const ScopeGuard offset_fill_guard([]() { glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); } ); glsafe(::glPolygonOffset(-1.0, 1.0)); + // Take care of the clipping plane. The normal of the clipping plane is + // saved with opposite sign than we need to pass to OpenGL (FIXME) + bool clipping_plane_active = m_c->object_clipper()->get_position() != 0.; + if (clipping_plane_active) { + const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane(); + double clp_data[4]; + memcpy(clp_data, clp->get_data(), 4 * sizeof(double)); + for (int i=0; i<3; ++i) + clp_data[i] = -1. * clp_data[i]; + + glsafe(::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)clp_data)); + glsafe(::glEnable(GL_CLIP_PLANE0)); + } + int mesh_id = -1; for (const ModelVolume* mv : mo->volumes) { if (! mv->is_model_part()) @@ -113,6 +127,8 @@ void GLGizmoFdmSupports::render_triangles(const Selection& selection) const } glsafe(::glPopMatrix()); } + if (clipping_plane_active) + glsafe(::glDisable(GL_CLIP_PLANE0)); } @@ -218,6 +234,21 @@ void GLGizmoFdmSupports::update_mesh() +bool GLGizmoFdmSupports::is_mesh_point_clipped(const Vec3d& point) const +{ + if (m_c->object_clipper()->get_position() == 0.) + return false; + + auto sel_info = m_c->selection_info(); + int active_inst = m_c->selection_info()->get_active_instance(); + const ModelInstance* mi = sel_info->model_object()->instances[active_inst]; + const Transform3d& trafo = mi->get_transformation().get_matrix(); + + Vec3d transformed_point = trafo * point; + transformed_point(2) += sel_info->get_sla_shift(); + return m_c->object_clipper()->get_clipping_plane()->is_point_clipped(transformed_point); +} + bool operator<(const GLGizmoFdmSupports::NeighborData& a, const GLGizmoFdmSupports::NeighborData& b) { return a.first < b.first; @@ -230,6 +261,8 @@ bool operator<(const GLGizmoFdmSupports::NeighborData& a, const GLGizmoFdmSuppor // concludes that the event was not intended for it, it should return false. bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { + bool processed = false; + if (action == SLAGizmoEventType::MouseWheelUp || action == SLAGizmoEventType::MouseWheelDown) { if (control_down) { @@ -310,6 +343,12 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous m_clipping_plane.get(), &facet)) { + // In case this hit is clipped, skip it. + if (is_mesh_point_clipped(hit.cast())) { + processed = true; + continue; + } + // Is this hit the closest to the camera so far? double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); if (hit_squared_distance < closest_hit_squared_distance) { @@ -446,7 +485,7 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous return true; } - return false; + return processed; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index 994218f698..adf6a46060 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -59,6 +59,8 @@ private: void render_cursor_circle() const; void update_mesh(); + bool is_mesh_point_clipped(const Vec3d& point) const; + float m_clipping_plane_distance = 0.f; std::unique_ptr m_clipping_plane; From 0c84a0b696d7d3bd35cd0d58f90a98a96f153cc3 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 30 Apr 2020 15:12:59 +0200 Subject: [PATCH 04/17] Fixed SLA supports gizmo undo/redo stack broken by 4f43c6d even before 2.2.0 release --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 7 +++---- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 496568d51a..261738d444 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -66,11 +66,10 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S ModelObject* mo = m_c->selection_info()->model_object(); - if (mo != m_old_mo) { + if (mo && mo->id() != m_old_mo_id) { disable_editing_mode(); - if (mo) - reload_cache(); - m_old_mo = mo; + reload_cache(); + m_old_mo_id = mo->id(); } // If we triggered autogeneration before, check backend and fetch results if they are there diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 917d22a988..b6cad8f9ae 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -83,7 +83,7 @@ private: float m_density_stash = 0.f; // and again mutable std::vector m_editing_cache; // a support point and whether it is currently selected std::vector m_normal_cache; // to restore after discarding changes or undo/redo - const ModelObject* m_old_mo = nullptr; + ObjectID m_old_mo_id; // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. From 272de22055c72316c1c53e9a67b713d3ecbd58a2 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 5 May 2020 13:45:04 +0200 Subject: [PATCH 05/17] Undo/redo in FDM supports gizmo --- src/libslic3r/Model.hpp | 11 +++- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 61 ++++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 8 ++- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 9 --- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 6 ++ 5 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index cd2c4957da..7b56030c74 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -411,6 +411,11 @@ public: return timestamp == other.get_timestamp(); } + template void serialize(Archive &ar) + { + ar(m_data); + } + private: std::map m_data; @@ -613,7 +618,8 @@ private: } template void load(Archive &ar) { bool has_convex_hull; - ar(name, source, m_mesh, m_type, m_material_id, m_transformation, m_is_splittable, has_convex_hull); + ar(name, source, m_mesh, m_type, m_material_id, m_transformation, + m_is_splittable, has_convex_hull, m_supported_facets); cereal::load_by_value(ar, config); assert(m_mesh); if (has_convex_hull) { @@ -626,7 +632,8 @@ private: } template void save(Archive &ar) const { bool has_convex_hull = m_convex_hull.get() != nullptr; - ar(name, source, m_mesh, m_type, m_material_id, m_transformation, m_is_splittable, has_convex_hull); + ar(name, source, m_mesh, m_type, m_material_id, m_transformation, + m_is_splittable, has_convex_hull, m_supported_facets); cereal::save_by_value(ar, config); if (has_convex_hull) cereal::save_optional(ar, m_convex_hull); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 1d276dd3d5..3e2996244a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -58,10 +58,10 @@ void GLGizmoFdmSupports::set_fdm_support_data(ModelObject* model_object, const S return; if (mo && selection.is_from_single_instance() - && (mo != m_old_mo || mo->volumes.size() != m_old_volumes_size)) + && (mo->id() != m_old_mo_id || mo->volumes.size() != m_old_volumes_size)) { - update_mesh(); - m_old_mo = mo; + update_from_model_object(); + m_old_mo_id = mo->id(); m_old_volumes_size = mo->volumes.size(); } } @@ -177,14 +177,21 @@ void GLGizmoFdmSupports::render_cursor_circle() const } -void GLGizmoFdmSupports::on_render_for_picking() const +void GLGizmoFdmSupports::update_model_object() const { - + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + ++idx; + if (! mv->is_model_part()) + continue; + for (int i=0; im_supported_facets.set_facet(i, m_selected_facets[idx][i]); + } } - -void GLGizmoFdmSupports::update_mesh() +void GLGizmoFdmSupports::update_from_model_object() { wxBusyCursor wait; @@ -193,7 +200,6 @@ void GLGizmoFdmSupports::update_mesh() for (const ModelVolume* mv : mo->volumes) if (mv->is_model_part()) ++num_of_volumes; - m_selected_facets.resize(num_of_volumes); m_neighbors.resize(num_of_volumes); m_ivas.clear(); @@ -469,19 +475,16 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::RightUp) && m_button_down != Button::None) { + // Take snapshot and update ModelVolume data. + wxString action_name = shift_down + ? _L("Remove selection") + : (m_button_down == Button::Left + ? _L("Add supports") + : _L("Block supports")); + Plater::TakeSnapshot(wxGetApp().plater(), action_name); + update_model_object(); + m_button_down = Button::None; - - // Synchronize gizmo with ModelVolume data. - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - ++idx; - if (! mv->is_model_part()) - continue; - for (int i=0; im_supported_facets.set_facet(i, m_selected_facets[idx][i]); - } - return true; } @@ -666,12 +669,22 @@ void GLGizmoFdmSupports::on_set_state() return; if (m_state == On && m_old_state != On) { // the gizmo was just turned on - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned on"))); + { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned on"))); + } + if (! m_parent.get_gizmos_manager().is_serializing()) { + wxGetApp().CallAfter([]() { + wxGetApp().plater()->enter_gizmos_stack(); + }); + } } if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off // we are actually shutting down - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned off"))); - m_old_mo = nullptr; + wxGetApp().plater()->leave_gizmos_stack(); + { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned off"))); + } + m_old_mo_id = -1; m_ivas.clear(); m_neighbors.clear(); m_selected_facets.clear(); @@ -696,7 +709,7 @@ void GLGizmoFdmSupports::on_stop_dragging() void GLGizmoFdmSupports::on_load(cereal::BinaryInputArchive& ar) { - + update_from_model_object(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index adf6a46060..e2f2e96a93 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -19,7 +19,7 @@ enum class SLAGizmoEventType : unsigned char; class GLGizmoFdmSupports : public GLGizmoBase { private: - const ModelObject* m_old_mo = nullptr; + ObjectID m_old_mo_id; size_t m_old_volumes_size = 0; GLUquadricObj* m_quadric; @@ -53,11 +53,13 @@ public: private: bool on_init() override; void on_render() const override; - void on_render_for_picking() const override; + void on_render_for_picking() const override {} void render_triangles(const Selection& selection) const; void render_cursor_circle() const; - void update_mesh(); + + void update_model_object() const; + void update_from_model_object(); bool is_mesh_point_clipped(const Vec3d& point) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 685e49d367..766ffe1ef6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -371,15 +371,6 @@ void GLGizmosManager::set_sla_support_data(ModelObject* model_object) || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) return; - /*m_common_gizmos_data->update_from_backend(m_parent, model_object); - - auto* gizmo_supports = dynamic_cast(m_gizmos[SlaSupports].get()); - - - // note: sla support gizmo takes care of updating the common data. - // following lines are thus dependent - //gizmo_supports->set_sla_support_data(model_object, m_parent.get_selection()); - */ auto* gizmo_hollow = dynamic_cast(m_gizmos[Hollow].get()); auto* gizmo_supports = dynamic_cast(m_gizmos[SlaSupports].get()); gizmo_hollow->set_sla_support_data(model_object, m_parent.get_selection()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 478774718f..64f8a99b2e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -139,6 +139,11 @@ public: EType new_current = m_current; m_current = old_current; + // Update common data. They should be updated when activate_gizmo is + // called, so it can be used in on_set_state which is called from there. + if (new_current != Undefined) + m_common_gizmos_data->update(m_gizmos[new_current]->get_requirements()); + // activate_gizmo call sets m_current and calls set_state for the gizmo // it does nothing in case the gizmo is already activated // it can safely be called for Undefined gizmo @@ -167,6 +172,7 @@ public: void refresh_on_off_state(); void reset_all_states(); + bool is_serializing() const { return m_serializing; } void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); From d24a3453af263bbeb923055abe20fd4cb82fce8d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 6 May 2020 07:03:32 +0200 Subject: [PATCH 06/17] Added simple autosetting of custom supports based on facet normal angle --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 221 ++++++++++++------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp | 5 + 2 files changed, 150 insertions(+), 76 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 3e2996244a..f78297912a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -523,6 +523,46 @@ void GLGizmoFdmSupports::update_vertex_buffers(const ModelVolume* mv, } +void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool overwrite, bool block) +{ + float threshold = (M_PI/180.)*threshold_deg; + const Selection& selection = m_parent.get_selection(); + const ModelObject* mo = m_c->selection_info()->model_object(); + const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; + + int mesh_id = -1; + for (const ModelVolume* mv : mo->volumes) { + if (! mv->is_model_part()) + continue; + + ++mesh_id; + + const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true); + Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast().normalized(); + Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast().normalized(); + + float dot_limit = limit.dot(down); + + // Now calculate dot product of vert_direction and facets' normals. + int idx = -1; + for (const stl_facet& facet : mv->mesh().stl.facet_start) { + ++idx; + if (facet.normal.dot(down) > dot_limit && (overwrite || m_selected_facets[mesh_id][idx] == FacetSupportType::NONE)) + m_selected_facets[mesh_id][idx] = block + ? FacetSupportType::BLOCKER + : FacetSupportType::ENFORCER; + } + update_vertex_buffers(mv, mesh_id, true, true); + } + + Plater::TakeSnapshot(wxGetApp().plater(), block ? _L("Block supports by angle") + : _L("Add supports by angle")); + update_model_object(); + m_parent.set_as_dirty(); + m_setting_angle = false; +} + + void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_limit) { if (! m_c->selection_info()->model_object()) @@ -531,96 +571,124 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l const float approx_height = m_imgui->scaled(18.0f); y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: - const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); - const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); - const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); - const float minimal_slider_width = m_imgui->scaled(4.f); + if (! m_setting_angle) { + m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); - float caption_max = 0.f; - float total_text_max = 0.; - for (const std::string& t : {"enforce", "block", "remove"}) { - caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); - total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); - } - caption_max += m_imgui->scaled(1.f); - total_text_max += m_imgui->scaled(1.f); + // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); + const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); + const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); + const float minimal_slider_width = m_imgui->scaled(4.f); - float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); - window_width = std::max(window_width, total_text_max); - window_width = std::max(window_width, button_width); + float caption_max = 0.f; + float total_text_max = 0.; + for (const std::string& t : {"enforce", "block", "remove"}) { + caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc.at(t+"_caption")).x); + total_text_max = std::max(total_text_max, caption_max + m_imgui->calc_text_size(m_desc.at(t)).x); + } + caption_max += m_imgui->scaled(1.f); + total_text_max += m_imgui->scaled(1.f); - auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { - static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); - m_imgui->text(caption); - ImGui::PopStyleColor(); - ImGui::SameLine(caption_max); - m_imgui->text(text); - }; + float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left); + window_width = std::max(window_width, total_text_max); + window_width = std::max(window_width, button_width); - for (const std::string& t : {"enforce", "block", "remove"}) - draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); + auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) { + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Text, ORANGE); + m_imgui->text(caption); + ImGui::PopStyleColor(); + ImGui::SameLine(caption_max); + m_imgui->text(text); + }; - m_imgui->text(""); + for (const std::string& t : {"enforce", "block", "remove"}) + draw_text_with_caption(m_desc.at(t + "_caption"), m_desc.at(t)); - if (m_imgui->button(m_desc.at("remove_all"))) { - ModelObject* mo = m_c->selection_info()->model_object(); - int idx = -1; - for (ModelVolume* mv : mo->volumes) { - ++idx; - if (mv->is_model_part()) { - m_selected_facets[idx].assign(m_selected_facets[idx].size(), FacetSupportType::NONE); - mv->m_supported_facets.clear(); - update_vertex_buffers(mv, idx, true, true); - m_parent.set_as_dirty(); + m_imgui->text(""); + + if (m_imgui->button("Autoset by angle...")) { + m_setting_angle = true; + } + + ImGui::SameLine(); + + if (m_imgui->button(m_desc.at("remove_all"))) { + ModelObject* mo = m_c->selection_info()->model_object(); + int idx = -1; + for (ModelVolume* mv : mo->volumes) { + ++idx; + if (mv->is_model_part()) { + m_selected_facets[idx].assign(m_selected_facets[idx].size(), FacetSupportType::NONE); + mv->m_supported_facets.clear(); + update_vertex_buffers(mv, idx, true, true); + m_parent.set_as_dirty(); + } } } - } - const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; - m_imgui->text(m_desc.at("cursor_size")); - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - - ImGui::Separator(); - if (m_c->object_clipper()->get_position() == 0.f) - m_imgui->text(m_desc.at("clipping_of_view")); - else { - if (m_imgui->button(m_desc.at("reset_direction"))) { - wxGetApp().CallAfter([this](){ - m_c->object_clipper()->set_position(-1., false); - }); + m_imgui->text(m_desc.at("cursor_size")); + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + ImGui::SliderFloat(" ", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Alt + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); } + + ImGui::Separator(); + if (m_c->object_clipper()->get_position() == 0.f) + m_imgui->text(m_desc.at("clipping_of_view")); + else { + if (m_imgui->button(m_desc.at("reset_direction"))) { + wxGetApp().CallAfter([this](){ + m_c->object_clipper()->set_position(-1., false); + }); + } + } + + ImGui::SameLine(clipping_slider_left); + ImGui::PushItemWidth(window_width - clipping_slider_left); + float clp_dist = m_c->object_clipper()->get_position(); + if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) + m_c->object_clipper()->set_position(clp_dist, true); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(max_tooltip_width); + ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + m_imgui->end(); + if (m_setting_angle) + m_parent.set_as_dirty(); } - - ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left); - float clp_dist = m_c->object_clipper()->get_position(); - if (ImGui::SliderFloat(" ", &clp_dist, 0.f, 1.f, "%.2f")) - m_c->object_clipper()->set_position(clp_dist, true); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(max_tooltip_width); - ImGui::TextUnformatted(_L("Ctrl + Mouse wheel").ToUTF8().data()); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); + else { + std::string name = "Autoset custom supports"; + m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->text("Threshold:"); + ImGui::SameLine(); + m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f"); + m_imgui->checkbox(wxString("Overwrite already selected facets"), m_overwrite_selected); + if (m_imgui->button("Enforce")) + select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, false); + ImGui::SameLine(); + if (m_imgui->button("Block")) + select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, true); + ImGui::SameLine(); + if (m_imgui->button("Cancel")) + m_setting_angle = false; + m_imgui->end(); + if (! m_setting_angle) + m_parent.set_as_dirty(); } - - - - m_imgui->end(); } bool GLGizmoFdmSupports::on_is_activable() const @@ -680,6 +748,7 @@ void GLGizmoFdmSupports::on_set_state() } if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off // we are actually shutting down + m_setting_angle = false; wxGetApp().plater()->leave_gizmos_stack(); { Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned off"))); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index e2f2e96a93..bed6d00a0c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -61,10 +61,15 @@ private: void update_model_object() const; void update_from_model_object(); + void select_facets_by_angle(float threshold, bool overwrite, bool block); + bool m_overwrite_selected = false; + float m_angle_threshold_deg = 45.f; + bool is_mesh_point_clipped(const Vec3d& point) const; float m_clipping_plane_distance = 0.f; std::unique_ptr m_clipping_plane; + bool m_setting_angle = false; // This map holds all translated description texts, so they can be easily referenced during layout calculations // etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect. From d90cea7aad20fbcadc88aedd23d75e9c891d8a96 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 6 May 2020 08:16:44 +0200 Subject: [PATCH 07/17] FDM supports - setting by angle highlight the facets in real time (experiment) --- src/slic3r/GUI/GLCanvas3D.cpp | 10 +++++----- src/slic3r/GUI/GLCanvas3D.hpp | 16 ++++++++++++---- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 20 +++++++++++++++----- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f24891f4c0..54e184bdbd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1454,7 +1454,7 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas #if ENABLE_SLOPE_RENDERING void GLCanvas3D::Slope::render() const { - if (is_shown()) + if (m_dialog_shown) { const std::array& z_range = m_volumes.get_slope_z_range(); std::array angle_range = { Geometry::rad2deg(::acos(z_range[0])) - 90.0f, Geometry::rad2deg(::acos(z_range[1])) - 90.0f }; @@ -1502,7 +1502,7 @@ void GLCanvas3D::Slope::render() const imgui.end(); if (modified) - m_volumes.set_slope_z_range({ -::cos(Geometry::deg2rad(90.0f - angle_range[0])), -::cos(Geometry::deg2rad(90.0f - angle_range[1])) }); + set_range(angle_range); } } #endif // ENABLE_SLOPE_RENDERING @@ -1911,8 +1911,8 @@ bool GLCanvas3D::is_reload_delayed() const void GLCanvas3D::enable_layers_editing(bool enable) { #if ENABLE_SLOPE_RENDERING - if (enable && m_slope.is_shown()) - m_slope.show(false); + if (enable && m_slope.is_dialog_shown()) + m_slope.show_dialog(false); #endif // ENABLE_SLOPE_RENDERING m_layers_editing.set_enabled(enable); @@ -3123,7 +3123,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'd': { if (!is_layers_editing_enabled()) { - m_slope.show(!m_slope.is_shown()); + m_slope.show_dialog(!m_slope.is_dialog_shown()); m_dirty = true; } break; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 15aa8c4564..31b3429c24 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -414,6 +414,7 @@ private: class Slope { bool m_enabled{ false }; + bool m_dialog_shown{ false }; GLCanvas3D& m_canvas; GLVolumeCollection& m_volumes; @@ -422,9 +423,14 @@ private: void enable(bool enable) { m_enabled = enable; } bool is_enabled() const { return m_enabled; } - void show(bool show) { m_volumes.set_slope_active(m_enabled ? show : false); } - bool is_shown() const { return m_volumes.is_slope_active(); } + void use(bool use) { m_volumes.set_slope_active(m_enabled ? use : false); } + bool is_used() const { return m_volumes.is_slope_active(); } + void show_dialog(bool show) { if (show && is_used()) return; use(show); m_dialog_shown = show; } + bool is_dialog_shown() const { return m_dialog_shown; } void render() const; + void set_range(const std::array& range) const { + m_volumes.set_slope_z_range({ -::cos(Geometry::deg2rad(90.0f - range[0])), -::cos(Geometry::deg2rad(90.0f - range[1])) }); + } }; #endif // ENABLE_SLOPE_RENDERING @@ -734,8 +740,10 @@ public: void show_labels(bool show) { m_labels.show(show); } #if ENABLE_SLOPE_RENDERING - bool is_slope_shown() const { return m_slope.is_shown(); } - void show_slope(bool show) { m_slope.show(show); } + bool is_slope_shown() const { return m_slope.is_dialog_shown(); } + void use_slope(bool use) { m_slope.use(use); } + void show_slope(bool show) { m_slope.show_dialog(show); } + void set_slope_range(const std::array& range) { m_slope.set_range(range); } #endif // ENABLE_SLOPE_RENDERING private: diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index f78297912a..da6a61ba50 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -84,6 +84,9 @@ void GLGizmoFdmSupports::on_render() const void GLGizmoFdmSupports::render_triangles(const Selection& selection) const { + if (m_setting_angle) + return; + const ModelObject* mo = m_c->selection_info()->model_object(); glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); @@ -667,27 +670,34 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l } m_imgui->end(); - if (m_setting_angle) + if (m_setting_angle) { + m_parent.show_slope(false); + m_parent.set_slope_range({m_angle_threshold_deg, m_angle_threshold_deg}); + m_parent.use_slope(true); m_parent.set_as_dirty(); + } } else { std::string name = "Autoset custom supports"; m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); m_imgui->text("Threshold:"); ImGui::SameLine(); - m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f"); + if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f")) + m_parent.set_slope_range({m_angle_threshold_deg, m_angle_threshold_deg}); m_imgui->checkbox(wxString("Overwrite already selected facets"), m_overwrite_selected); if (m_imgui->button("Enforce")) - select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, false); + select_facets_by_angle(90.f - m_angle_threshold_deg, m_overwrite_selected, false); ImGui::SameLine(); if (m_imgui->button("Block")) - select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, true); + select_facets_by_angle(90.f - m_angle_threshold_deg, m_overwrite_selected, true); ImGui::SameLine(); if (m_imgui->button("Cancel")) m_setting_angle = false; m_imgui->end(); - if (! m_setting_angle) + if (! m_setting_angle) { + m_parent.use_slope(false); m_parent.set_as_dirty(); + } } } From 4ed1b49955d77d4fc0666c95d2093d0c4cddcafd Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 11 May 2020 16:57:40 +0200 Subject: [PATCH 08/17] Slope visualiser angle inverted It showed facet normal angle in the GUI, now it shows slope angle (90 deg complement). This change was made to unify it with threshold angle in Print Settings. --- src/slic3r/GUI/GLCanvas3D.cpp | 38 +++++++++++++------- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 8 ++--- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 54e184bdbd..a9f7d929af 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1465,29 +1465,41 @@ void GLCanvas3D::Slope::render() const imgui.set_next_window_pos((float)cnv_size.get_width(), (float)cnv_size.get_height(), ImGuiCond_Always, 1.0f, 1.0f); imgui.begin(_(L("Slope visualization")), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - imgui.text(_(L("Facets' normal angle range (degrees)")) + ":"); + imgui.text(_(L("Facets' slope range (degrees)")) + ":"); - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.75f, 0.0f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 1.0f, 0.0f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.85f, 0.0f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.25f, 0.0f, 1.0f)); - if (ImGui::SliderFloat("##yellow", &angle_range[0], 0.0f, 90.0f, "%.1f")) - { - modified = true; - if (angle_range[1] < angle_range[0]) - angle_range[1] = angle_range[0]; - } - ImGui::PopStyleColor(4); ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.0f, 0.0f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 0.0f, 0.0f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.0f, 0.0f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.0f, 0.0f, 1.0f)); - if (ImGui::SliderFloat("##red", &angle_range[1], 0.0f, 90.0f, "%.1f")) + + // angle_range is range of normal angle, GUI should + // show facet slope angle + float slope_bound = 90.f - angle_range[1]; + bool mod = ImGui::SliderFloat("##red", &slope_bound, 0.0f, 90.0f, "%.1f"); + angle_range[1] = 90.f - slope_bound; + if (mod) { modified = true; if (angle_range[0] > angle_range[1]) angle_range[0] = angle_range[1]; } + + ImGui::PopStyleColor(4); + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.75f, 0.0f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 1.0f, 0.0f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.85f, 0.0f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.25f, 0.0f, 1.0f)); + + slope_bound = 90.f - angle_range[0]; + mod = ImGui::SliderFloat("##yellow", &slope_bound, 0.0f, 90.0f, "%.1f"); + angle_range[0] = 90.f - slope_bound; + if (mod) + { + modified = true; + if (angle_range[1] < angle_range[0]) + angle_range[1] = angle_range[0]; + } + ImGui::PopStyleColor(4); ImGui::Separator(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index da6a61ba50..f5df156592 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -672,7 +672,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l m_imgui->end(); if (m_setting_angle) { m_parent.show_slope(false); - m_parent.set_slope_range({m_angle_threshold_deg, m_angle_threshold_deg}); + m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); m_parent.use_slope(true); m_parent.set_as_dirty(); } @@ -683,13 +683,13 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l m_imgui->text("Threshold:"); ImGui::SameLine(); if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f")) - m_parent.set_slope_range({m_angle_threshold_deg, m_angle_threshold_deg}); + m_parent.set_slope_range({90.f - m_angle_threshold_deg, 90.f - m_angle_threshold_deg}); m_imgui->checkbox(wxString("Overwrite already selected facets"), m_overwrite_selected); if (m_imgui->button("Enforce")) - select_facets_by_angle(90.f - m_angle_threshold_deg, m_overwrite_selected, false); + select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, false); ImGui::SameLine(); if (m_imgui->button("Block")) - select_facets_by_angle(90.f - m_angle_threshold_deg, m_overwrite_selected, true); + select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, true); ImGui::SameLine(); if (m_imgui->button("Cancel")) m_setting_angle = false; From 6391200390291cee040f31f5d5bedfa6b3f4aae5 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 11 May 2020 16:59:43 +0200 Subject: [PATCH 09/17] FDM supports gizmo fix: make sure that slope visualizer is off when turning off the gizmo --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index f5df156592..71142d532f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -759,6 +759,7 @@ void GLGizmoFdmSupports::on_set_state() if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off // we are actually shutting down m_setting_angle = false; + m_parent.use_slope(false); wxGetApp().plater()->leave_gizmos_stack(); { Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned off"))); From cab3bf2f208044b1945f3043ee07ff5fcfe06d2e Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 11 May 2020 16:59:51 +0200 Subject: [PATCH 10/17] FDM supports gizmo: the cursor does not stick to the cut when clipping plane is used --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 71142d532f..a75eed12c0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -270,8 +270,6 @@ bool operator<(const GLGizmoFdmSupports::NeighborData& a, const GLGizmoFdmSuppor // concludes that the event was not intended for it, it should return false. bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { - bool processed = false; - if (action == SLAGizmoEventType::MouseWheelUp || action == SLAGizmoEventType::MouseWheelDown) { if (control_down) { @@ -354,7 +352,7 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous { // In case this hit is clipped, skip it. if (is_mesh_point_clipped(hit.cast())) { - processed = true; + some_mesh_was_hit = true; continue; } @@ -491,7 +489,7 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous return true; } - return processed; + return false; } From 559f9279d97212d66d333b126e907e8f9f66e666 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 11 May 2020 22:00:26 +0200 Subject: [PATCH 11/17] Search: 1. The position of the search window is in the middle of the scene. 2. When "Search in English" is checked, then search in English names too. 3. Added score value at the end of option name -> [score_value] 4. Set focus to the Plater, when switch from some tab with focused field to the Plater and search window is shown. 5. For the mode, when settings are in non-modal dialog, neither dialog nor tabpanel doesn't receive wxEVT_KEY_UP event, when some field is selected. So, like a workaround we check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed + PreferencesDialog: fixed a control of the difference in layout modes --- src/slic3r/GUI/Field.cpp | 27 +++++++++++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.cpp | 9 +++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/MainFrame.cpp | 8 ++++++++ src/slic3r/GUI/Plater.cpp | 3 +++ src/slic3r/GUI/Preferences.cpp | 14 +++++++++++--- src/slic3r/GUI/Search.cpp | 5 +++-- 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 16d3f4123a..0b1dcc1bd1 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -79,6 +79,29 @@ void Field::PostInitialize() m_em_unit = em_unit(m_parent); BUILD(); + + // For the mode, when settings are in non-modal dialog, neither dialog nor tabpanel doesn't receive wxEVT_KEY_UP event, when some field is selected. + // So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed + if (getWindow()) + getWindow()->Bind(wxEVT_KEY_UP, [](wxKeyEvent& evt) { + if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) { + int tab_id = -1; + switch (evt.GetKeyCode()) { + case '1': { tab_id = 0; break; } + case '2': { tab_id = 1; break; } + case '3': { tab_id = 2; break; } + case '4': { tab_id = 3; break; } + default: break; + } + if (tab_id >= 0) + wxGetApp().mainframe->select_tab(tab_id); + if (tab_id > 0) + // tab panel should be focused for correct navigation between tabs + wxGetApp().tab_panel()->SetFocus(); + } + + evt.Skip(); + }); } // Values of width to alignments of fields @@ -397,7 +420,7 @@ void TextCtrl::BUILD() { bKilledFocus = false; #endif // __WXOSX__ }), temp->GetId()); - +/* // select all text using Ctrl+A temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event) { @@ -405,7 +428,7 @@ void TextCtrl::BUILD() { temp->SetSelection(-1, -1); //select all event.Skip(); })); - +*/ // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2b854ca2a1..614f5413d7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4391,7 +4391,7 @@ bool GLCanvas3D::_render_search_list(float pos_x) const bool action_taken = false; ImGuiWrapper* imgui = wxGetApp().imgui(); - const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); + const float x = /*pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + */0.5f * (float)get_canvas_size().get_width(); imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); std::string title = L("Search"); imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); @@ -7143,9 +7143,14 @@ bool GLCanvas3D::_deactivate_undo_redo_toolbar_items() return false; } +bool GLCanvas3D::is_search_pressed() const +{ + return m_main_toolbar.is_item_pressed("search"); +} + bool GLCanvas3D::_deactivate_search_toolbar_item() { - if (m_main_toolbar.is_item_pressed("search")) + if (is_search_pressed()) { m_main_toolbar.force_left_action(m_main_toolbar.get_item_id("search"), *this); return true; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index be491985b3..6a6bc4697a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -574,6 +574,7 @@ public: bool is_layers_editing_enabled() const; bool is_layers_editing_allowed() const; + bool is_search_pressed() const; void reset_layer_height_profile(); void adaptive_layer_height_profile(float quality_factor); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d05e4bd773..9d92bc78be 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -28,6 +28,7 @@ #include "RemovableDriveManager.hpp" #include "InstanceCheck.hpp" #include "I18N.hpp" +#include "GLCanvas3D.hpp" #include #include "GUI_App.hpp" @@ -1263,6 +1264,9 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/) if (tab==0) { if (m_settings_dialog->IsShown()) this->SetFocus(); + // plater should be focused for correct navigation inside search window + if (m_plater->canvas3D()->is_search_pressed()) + m_plater->SetFocus(); return; } // Show/Activate Settings Dialog @@ -1278,6 +1282,10 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/) else if (m_layout == slNew) { m_plater->Show(tab == 0); m_tabpanel->Show(tab != 0); + + // plater should be focused for correct navigation inside search window + if (tab == 0 && m_plater->canvas3D()->is_search_pressed()) + m_plater->SetFocus(); Layout(); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 96d467e000..7fd8ec09d4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5364,6 +5364,9 @@ void Plater::paste_from_clipboard() void Plater::search(bool plater_is_active) { if (plater_is_active) { + // plater should be focused for correct navigation inside search window + this->SetFocus(); + wxKeyEvent evt; #ifdef __APPLE__ evt.m_keyCode = 'f'; diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index ff42da61db..9e462d4bf1 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -190,9 +190,17 @@ void PreferencesDialog::accept() auto app_config = get_app_config(); - m_settings_layout_changed = m_values.find("old_settings_layout_mode") != m_values.end() || - m_values.find("new_settings_layout_mode") != m_values.end() || - m_values.find("dlg_settings_layout_mode") != m_values.end(); + m_settings_layout_changed = false; + for (const std::string& key : {"old_settings_layout_mode", + "new_settings_layout_mode", + "dlg_settings_layout_mode" }) + { + auto it = m_values.find(key); + if (it != m_values.end() && app_config->get(key) != it->second) { + m_settings_layout_changed = true; + break; + } + } if (m_settings_layout_changed) { // the dialog needs to be destroyed before the call to recreate_gui() diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index aef46bf559..b929b37d0a 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -262,13 +262,14 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/) append(matches, matches2); score = score2; } - if (fuzzy_match(wsearch, label_english, score2, matches2) && score2 > score) { + if (view_params.english && fuzzy_match(wsearch, label_english, score2, matches2) && score2 > score) { label = std::move(label_english); matches = std::move(matches2); score = score2; } if (score > std::numeric_limits::min()) { - label = mark_string(label, matches); + label = mark_string(label, matches); + label += L" [" + std::to_wstring(score) + L"]";// add score value std::string label_u8 = into_u8(label); std::string label_plain = label_u8; boost::erase_all(label_plain, std::string(1, char(ImGui::ColorMarkerStart))); From 1b8c7c49767d20dfd5b83a3ef7ae3e925656ad3d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 May 2020 09:46:23 +0200 Subject: [PATCH 12/17] Added missed include --- src/slic3r/GUI/Field.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 0b1dcc1bd1..59ea01314a 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #ifdef __WXOSX__ From d928d6e47e245cdb0a66a66ab8c5dc732e84ece8 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 12 May 2020 14:03:10 +0200 Subject: [PATCH 13/17] Hollowing gizmo fix: selection of single holes was recently broken --- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 5 ++++- src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index b248db1c64..8d4616da37 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -58,7 +58,10 @@ void GLGizmoHollow::set_sla_support_data(ModelObject*, const Selection&) const ModelObject* mo = m_c->selection_info()->model_object(); if (mo) { - reload_cache(); + if (m_old_mo_id != mo->id()) { + reload_cache(); + m_old_mo_id = mo->id(); + } if (m_c->hollowed_mesh() && m_c->hollowed_mesh()->get_hollowed_mesh()) m_holes_in_drilled_mesh = mo->sla_drain_holes; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index 3ee83c3454..93e577743a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -43,6 +43,8 @@ private: void hollow_mesh(bool postpone_error_messages = false); bool unsaved_changes() const; + ObjectID m_old_mo_id = -1; + // bool m_show_supports = true; float m_new_hole_radius = 2.f; // Size of a new hole. float m_new_hole_height = 6.f; From e7f32062508ecf757d13e83e78cefaeb2e3dd3eb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 May 2020 23:07:06 +0200 Subject: [PATCH 14/17] Auto scale of the toolbars in respect to the canvas size --- src/slic3r/GUI/AppConfig.cpp | 3 ++ src/slic3r/GUI/GLCanvas3D.cpp | 48 +++++++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GLToolbar.cpp | 10 +++++ src/slic3r/GUI/GLToolbar.hpp | 1 + src/slic3r/GUI/GUI_App.cpp | 22 ++++++++++- src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 + src/slic3r/GUI/MainFrame.cpp | 2 +- 9 files changed, 83 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/AppConfig.cpp b/src/slic3r/GUI/AppConfig.cpp index 291949ce91..0f603c2651 100644 --- a/src/slic3r/GUI/AppConfig.cpp +++ b/src/slic3r/GUI/AppConfig.cpp @@ -84,6 +84,9 @@ void AppConfig::set_defaults() if (get("custom_toolbar_size").empty()) set("custom_toolbar_size", "100"); + if (get("auto_toolbar_size").empty()) + set("auto_toolbar_size", "100"); + if (get("use_perspective_camera").empty()) set("use_perspective_camera", "1"); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 614f5413d7..4a62526f77 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5477,6 +5477,44 @@ void GLCanvas3D::_render_selection_center() const } #endif // ENABLE_RENDER_SELECTION_CENTER +void GLCanvas3D::_check_and_update_toolbar_icon_scale() const +{ + float scale = wxGetApp().toolbar_icon_scale(); + Size cnv_size = get_canvas_size(); + + float size = GLToolbar::Default_Icons_Size * scale; + + // Set current size for all top toolbars. It will be used for next calculations +#if ENABLE_RETINA_GL + const float sc = m_retina_helper->get_scale_factor() * scale; + m_main_toolbar.set_scale(sc); + m_undoredo_toolbar.set_scale(sc); + m_collapse_toolbar.set_scale(sc); +#else + m_main_toolbar.set_icons_size(size); + m_undoredo_toolbar.set_icons_size(size); + m_collapse_toolbar.set_icons_size(size); +#endif // ENABLE_RETINA_GL + + float top_tb_width = m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + m_collapse_toolbar.get_width(); + int items_cnt = m_main_toolbar.get_visible_items_cnt() + m_undoredo_toolbar.get_visible_items_cnt() + m_collapse_toolbar.get_visible_items_cnt(); + float noitems_width = top_tb_width - size * items_cnt; // width of separators and borders in top toolbars + + // calculate scale needed for items in all top toolbars + float new_h_scale = (cnv_size.get_width() - noitems_width) / (items_cnt * GLToolbar::Default_Icons_Size); + + items_cnt = m_gizmos.get_selectable_icons_cnt() + 3; // +3 means a place for top and view toolbars and separators in gizmos toolbar + + // calculate scale needed for items in the gizmos toolbar + float new_v_scale = cnv_size.get_height() / (items_cnt * GLGizmosManager::Default_Icons_Size); + + // set minimum scale as a auto scale for the toolbars + float new_scale = std::min(new_h_scale, new_v_scale); + if (fabs(new_scale - scale) > EPSILON) + wxGetApp().set_auto_toolbar_icon_scale(new_scale); +} + + void GLCanvas3D::_render_overlays() const { glsafe(::glDisable(GL_DEPTH_TEST)); @@ -5489,6 +5527,8 @@ void GLCanvas3D::_render_overlays() const double gui_scale = camera.get_gui_scale(); glsafe(::glScaled(gui_scale, gui_scale, 1.0)); + _check_and_update_toolbar_icon_scale(); + _render_gizmos_overlay(); _render_warning_texture(); _render_legend_texture(); @@ -5496,12 +5536,12 @@ void GLCanvas3D::_render_overlays() const // main toolbar and undoredo toolbar need to be both updated before rendering because both their sizes are needed // to correctly place them #if ENABLE_RETINA_GL - const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(true); + const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(/*true*/); m_main_toolbar.set_scale(scale); m_undoredo_toolbar.set_scale(scale); m_collapse_toolbar.set_scale(scale); #else - const float size = int(GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale(true)); + const float size = int(GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale(/*true*/)); m_main_toolbar.set_icons_size(size); m_undoredo_toolbar.set_icons_size(size); m_collapse_toolbar.set_icons_size(size); @@ -5608,7 +5648,7 @@ void GLCanvas3D::_render_main_toolbar() const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width()) * inv_zoom; + float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + m_collapse_toolbar.get_width()) * inv_zoom; m_main_toolbar.set_position(top, left); m_main_toolbar.render(*this); @@ -5623,7 +5663,7 @@ void GLCanvas3D::_render_undoredo_toolbar() const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width())) * inv_zoom; + float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + m_collapse_toolbar.get_width())) * inv_zoom; m_undoredo_toolbar.set_position(top, left); m_undoredo_toolbar.render(*this); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 6a6bc4697a..c6875165f0 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -754,6 +754,7 @@ private: #if ENABLE_RENDER_SELECTION_CENTER void _render_selection_center() const; #endif // ENABLE_RENDER_SELECTION_CENTER + void _check_and_update_toolbar_icon_scale() const; void _render_overlays() const; void _render_warning_texture() const; void _render_legend_texture() const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index e7f784773a..429853aaa4 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -627,6 +627,16 @@ float GLToolbar::get_main_size() const return size * m_layout.scale; } +int GLToolbar::get_visible_items_cnt() const +{ + int cnt = 0; + for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) + if (m_items[i]->is_visible() && !m_items[i]->is_separator()) + cnt++; + + return cnt; +} + void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas3D& parent, bool check_hover) { if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id)) diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 27b43fef63..9911bb34a5 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -319,6 +319,7 @@ public: void get_additional_tooltip(int item_id, std::string& text); void set_additional_tooltip(int item_id, const std::string& text); void set_tooltip(int item_id, const std::string& text); + int get_visible_items_cnt() const; // returns true if any item changed its state bool update_items_state(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7f3d86a9c3..9a2a51e9ce 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -580,17 +580,35 @@ float GUI_App::toolbar_icon_scale(const bool is_limited/* = false*/) const const std::string& use_val = app_config->get("use_custom_toolbar_size"); const std::string& val = app_config->get("custom_toolbar_size"); + const std::string& auto_val = app_config->get("auto_toolbar_size"); - if (val.empty() || use_val.empty() || use_val == "0") + if (val.empty() || auto_val.empty() || use_val.empty()) return icon_sc; - int int_val = atoi(val.c_str()); + int int_val = use_val == "0" ? 100 : atoi(val.c_str()); + // correct value in respect to auto_toolbar_size + int_val = std::min(atoi(auto_val.c_str()), int_val); + if (is_limited && int_val < 50) int_val = 50; return 0.01f * int_val * icon_sc; } +void GUI_App::set_auto_toolbar_icon_scale(float scale) const +{ +#ifdef __APPLE__ + const float icon_sc = 1.0f; // for Retina display will be used its own scale +#else + const float icon_sc = m_em_unit * 0.1f; +#endif // __APPLE__ + + int int_val = std::min(int(scale / icon_sc * 100), 100); + std::string val = std::to_string(int_val); + + app_config->set("auto_toolbar_size", val); +} + void GUI_App::recreate_GUI(const wxString& msg_name) { mainframe->shutdown(); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index cd59f1d803..3afadf4e0e 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -135,6 +135,7 @@ public: const wxFont& normal_font() { return m_normal_font; } int em_unit() const { return m_em_unit; } float toolbar_icon_scale(const bool is_limited = false) const; + void set_auto_toolbar_icon_scale(float scale) const; void recreate_GUI(const wxString& message); void system_info(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 64f8a99b2e..a7fb821262 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -226,6 +226,8 @@ public: void update_after_undo_redo(const UndoRedo::Snapshot& snapshot); + int get_selectable_icons_cnt() const { return get_selectable_idxs().size(); } + private: void render_background(float left, float top, float right, float bottom, float border) const; void do_render_overlay() const; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 9d92bc78be..73b78d3df2 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +//#include #include #include From 07f419f62be2a13c2e2787cfc73d213b3cf59f65 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 May 2020 23:34:08 +0200 Subject: [PATCH 15/17] Fixed a place on tool toolbar for collapse_toolbar_width in respect to its enable --- src/slic3r/GUI/GLCanvas3D.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4a62526f77..1bdc953420 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5648,7 +5648,8 @@ void GLCanvas3D::_render_main_toolbar() const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + m_collapse_toolbar.get_width()) * inv_zoom; + float collapse_toolbar_width = m_collapse_toolbar.is_enabled() ? m_collapse_toolbar.get_width() : 0.0f; + float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom; m_main_toolbar.set_position(top, left); m_main_toolbar.render(*this); @@ -5663,7 +5664,8 @@ void GLCanvas3D::_render_undoredo_toolbar() const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + m_collapse_toolbar.get_width())) * inv_zoom; + float collapse_toolbar_width = m_collapse_toolbar.is_enabled() ? m_collapse_toolbar.get_width() : 0.0f; + float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom; m_undoredo_toolbar.set_position(top, left); m_undoredo_toolbar.render(*this); } From 79101d6e54e446810afd9d21774a40f3da42a55a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 13 May 2020 12:30:09 +0200 Subject: [PATCH 16/17] Fixed toolbar items reacting when disabled --- src/slic3r/GUI/GLToolbar.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 429853aaa4..c69327cfa4 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -532,7 +532,12 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.left = true; m_mouse_capture.parent = &parent; processed = true; +#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI + if ((item_id != -2) && !m_items[item_id]->is_separator() && !m_items[item_id]->is_disabled() && + ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Left))) +#else if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Left))) +#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI { // mouse is inside an icon do_action(GLToolbarItem::Left, item_id, parent, true); @@ -549,7 +554,12 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.right = true; m_mouse_capture.parent = &parent; processed = true; +#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI + if ((item_id != -2) && !m_items[item_id]->is_separator() && !m_items[item_id]->is_disabled() && + ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Right))) +#else if ((item_id != -2) && !m_items[item_id]->is_separator() && ((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Right))) +#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI { // mouse is inside an icon do_action(GLToolbarItem::Right, item_id, parent, true); @@ -644,7 +654,11 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas if ((0 <= item_id) && (item_id < (int)m_items.size())) { GLToolbarItem* item = m_items[item_id]; +#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI + if ((item != nullptr) && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered())) +#else if ((item != nullptr) && !item->is_separator() && (!check_hover || item->is_hovered())) +#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI { if (((type == GLToolbarItem::Right) && item->is_right_toggable()) || ((type == GLToolbarItem::Left) && item->is_left_toggable())) From 54925a191e00dd0614777073d06638eea5b96c56 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 13 May 2020 12:31:48 +0200 Subject: [PATCH 17/17] Updated imgui README.md to contain reference to the commit which modify it --- src/imgui/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/imgui/README.md b/src/imgui/README.md index 00d78ed013..83f4619964 100644 --- a/src/imgui/README.md +++ b/src/imgui/README.md @@ -3,3 +3,8 @@ For more information go to https://github.com/ocornut/imgui THIS DIRECTORY CONTAINS THE imgui-1.75 58b3e02 SOURCE DISTRIBUTION. + +Customized with the following commits: +042880ba2df913916b2cc77f7bb677e07bfd2c58 +67c55c74901f1d337ef08f2090a87cfb4263bb0f +a94c952b40d36b1505fb77b87c0dd739e1034659 \ No newline at end of file