From fd4054be7eb73507156f853792e719263cd61b88 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Sat, 9 Feb 2019 07:19:01 +0100 Subject: [PATCH 1/4] First steps on the rectangular selection for the SLA gizmo --- src/slic3r/GUI/GLCanvas3D.cpp | 16 +++-- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GLGizmo.cpp | 124 ++++++++++++++++++++++++++++------ src/slic3r/GUI/GLGizmo.hpp | 9 ++- 4 files changed, 125 insertions(+), 26 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 76c0337d17..7a0ca3e8ff 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3430,14 +3430,14 @@ void GLCanvas3D::Gizmos::set_sla_support_data(ModelObject* model_object, const G reinterpret_cast(it->second)->set_sla_support_data(model_object, selection); } -void GLCanvas3D::Gizmos::clicked_on_object(const Vec2d& mouse_position) +void GLCanvas3D::Gizmos::mouse_event(int action, const Vec2d& mouse_position, bool shift_down) { if (!m_enabled) return; GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); if (it != m_gizmos.end()) - reinterpret_cast(it->second)->clicked_on_object(mouse_position); + reinterpret_cast(it->second)->mouse_event(action, mouse_position, shift_down); } void GLCanvas3D::Gizmos::delete_current_grabber(bool delete_all) @@ -5396,6 +5396,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _update_gizmos_data(); m_dirty = true; } + else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown()) // inform the gizmo about the event (rectangular selection init) + { + m_gizmos.mouse_event(1, Vec2d(pos(0), pos(1)), evt.ShiftDown()); + } else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) { _update_gizmos_data(); @@ -5579,6 +5583,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } + else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown()) + { + m_gizmos.mouse_event(3, Vec2d(pos(0), pos(1)), evt.ShiftDown()); + } else if (evt.Dragging() && !gizmos_overlay_contains_mouse) { m_mouse.dragging = true; @@ -5643,12 +5651,12 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } - else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_hover_volume_id != -1) + else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports/* && m_hover_volume_id != -1*/) { int id = m_selection.get_object_idx(); if ((id != -1) && (m_model != nullptr)) { - m_gizmos.clicked_on_object(Vec2d(pos(0), pos(1))); + m_gizmos.mouse_event(2, Vec2d(pos(0), pos(1)), evt.ShiftDown()); } } else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() && !is_layers_editing_enabled()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9f341083be..6fd4584a6f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -789,7 +789,7 @@ private: void set_flattening_data(const ModelObject* model_object); void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); - void clicked_on_object(const Vec2d& mouse_position); + void mouse_event(int action, const Vec2d& mouse_position, bool shift_down); void delete_current_grabber(bool delete_all = false); void render_current_gizmo(const Selection& selection) const; diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index f9191b69b6..f752e7d943 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1816,13 +1816,49 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const ::glEnable(GL_DEPTH_TEST); render_points(selection, false); + render_selection_rectangle(); #if !ENABLE_IMGUI render_tooltip_texture(); #endif // not ENABLE_IMGUI + ::glDisable(GL_BLEND); } +void GLGizmoSlaSupports::render_selection_rectangle() const +{ + if (!m_selection_rectangle_active) + return; + + ::glLineWidth(1.5f); + float render_color[3] = {1.f, 0.f, 0.f}; + ::glColor3fv(render_color); + + ::glPushAttrib(GL_TRANSFORM_BIT); // remember current MatrixMode + + ::glMatrixMode(GL_MODELVIEW); // cache modelview matrix and set to identity + ::glPushMatrix(); + ::glLoadIdentity(); + + ::glMatrixMode(GL_PROJECTION); // cache projection matrix and set to identity + ::glPushMatrix(); + ::glLoadIdentity(); + + ::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f); // set projection matrix so that world coords = window coords + + // render the selection rectangle (window coordinates): + ::glBegin(GL_LINE_LOOP); + ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); + ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); + ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); + ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); + ::glEnd(); + + ::glPopMatrix(); // restore former projection matrix + ::glMatrixMode(GL_MODELVIEW); + ::glPopMatrix(); // restore former modelview matrix + ::glPopAttrib(); // restore former MatrixMode +} void GLGizmoSlaSupports::on_render_for_picking(const GLCanvas3D::Selection& selection) const { @@ -1984,34 +2020,82 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) return bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2)); } -void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position) +void GLGizmoSlaSupports::mouse_event(int action, const Vec2d& mouse_position, bool shift_down) { if (!m_editing_mode) return; - int instance_id = m_parent.get_selection().get_instance_idx(); - if (m_old_instance_id != instance_id) - { - bool something_selected = (m_old_instance_id != -1); - m_old_instance_id = instance_id; - if (something_selected) + // left down - show the selection rectangle: + if (action == 1 && shift_down) { + m_selection_rectangle_active = true; + m_selection_rectangle_start_corner = mouse_position; + m_selection_rectangle_end_corner = mouse_position; + m_canvas_width = m_parent.get_canvas_size().get_width(); + m_canvas_height = m_parent.get_canvas_size().get_height(); + } + + // dragging the selection rectangle: + if (action == 3 && m_selection_rectangle_active) { + m_selection_rectangle_end_corner = mouse_position; + m_parent.render(); + } + + // mouse up without selection rectangle - place point on the mesh: + if (action == 2 && !m_selection_rectangle_active) { + int instance_id = m_parent.get_selection().get_instance_idx(); + if (m_old_instance_id != instance_id) + { + bool something_selected = (m_old_instance_id != -1); + m_old_instance_id = instance_id; + if (something_selected) + return; + } + if (instance_id == -1) return; + + Vec3f new_pos; + try { + new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new point in that case + } + catch (...) { return; } + + m_editing_mode_cache.emplace_back(new_pos, m_new_point_head_diameter, false); } - if (instance_id == -1) - return; - Vec3f new_pos; - try { - new_pos = unproject_on_mesh(mouse_position); // this can throw - we don't want to create a new point in that case + // left up with selection rectangle - select points inside the rectangle: + if (action == 2 && m_selection_rectangle_active) { + const Transform3d& instance_matrix = m_model_object->instances[m_active_instance]->get_transformation().get_matrix(); + GLint viewport[4]; + ::glGetIntegerv(GL_VIEWPORT, viewport); + GLdouble modelview_matrix[16]; + ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix); + GLdouble projection_matrix[16]; + ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix); + + const GLCanvas3D::Selection& selection = m_parent.get_selection(); + const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); + double z_offset = volume->get_sla_shift_z(); + + // bounding box created from the rectangle corners - will take care of order of the corners + BoundingBox rectangle(Points{Point(m_selection_rectangle_start_corner.cast()), Point(m_selection_rectangle_end_corner.cast())}); + + for (sla::SupportPoint& support_point : m_editing_mode_cache) { + Vec3f pos = instance_matrix.cast() * support_point.pos; + pos(2) += z_offset; + GLdouble out_x, out_y, out_z; + ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); + out_y = m_canvas_height - out_y; + + /*GLfloat depth_comp; + ::glReadPixels( out_x, out_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth_comp); + if (depth_comp > out_z + EPSILON) // the point is obscured by something else + continue;*/ + + if (rectangle.contains(Point(out_x, out_y))) + support_point.head_front_radius = 1.f; + } + m_selection_rectangle_active = false; } - catch (...) { return; } - - m_editing_mode_cache.emplace_back(new_pos, m_new_point_head_diameter, false); - - // This should trigger the support generation - // wxGetApp().plater()->reslice(); - - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } void GLGizmoSlaSupports::delete_current_point(bool delete_all) diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index f5ddbd76fb..96dafafdfd 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -464,7 +464,7 @@ public: explicit GLGizmoSlaSupports(GLCanvas3D& parent); virtual ~GLGizmoSlaSupports(); void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); - void clicked_on_object(const Vec2d& mouse_position); + void mouse_event(int action, const Vec2d& mouse_position, bool shift_down); void delete_current_point(bool delete_all); private: @@ -473,6 +473,7 @@ private: virtual void on_render(const GLCanvas3D::Selection& selection) const; virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const; + void render_selection_rectangle() const; void render_points(const GLCanvas3D::Selection& selection, bool picking = false) const; bool is_mesh_update_necessary() const; void update_mesh(); @@ -488,6 +489,12 @@ private: float m_new_point_head_diameter = 0.4f; std::vector m_editing_mode_cache; + bool m_selection_rectangle_active = false; + Vec2d m_selection_rectangle_start_corner; + Vec2d m_selection_rectangle_end_corner; + int m_canvas_width; + int m_canvas_height; + protected: void on_set_state() override; From 0453caf266abe7400de07905653f2f1ff14ec704 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 11 Feb 2019 08:21:37 +0100 Subject: [PATCH 2/4] SLA gizmo - shift-up and ctrl+a event passing --- src/slic3r/GUI/GLCanvas3D.cpp | 22 +++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 3 ++- src/slic3r/GUI/GLGizmo.cpp | 18 +++++++++++++++--- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7a0ca3e8ff..92078a8b9d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5114,6 +5114,7 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_SIZE, &GLCanvas3D::on_size, this); m_canvas->Bind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); m_canvas->Bind(wxEVT_CHAR, &GLCanvas3D::on_char, this); + m_canvas->Bind(wxEVT_KEY_UP, &GLCanvas3D::on_key_up, this); m_canvas->Bind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); m_canvas->Bind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); m_canvas->Bind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); @@ -5139,6 +5140,7 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_SIZE, &GLCanvas3D::on_size, this); m_canvas->Unbind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); m_canvas->Unbind(wxEVT_CHAR, &GLCanvas3D::on_char, this); + m_canvas->Unbind(wxEVT_KEY_UP, &GLCanvas3D::on_key_up, this); m_canvas->Unbind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); m_canvas->Unbind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); m_canvas->Unbind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); @@ -5182,7 +5184,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) switch (keyCode) { case 'a': case 'A': - case WXK_CONTROL_A: post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); break; + case WXK_CONTROL_A: + if (m_gizmos.get_current_type() == Gizmos::SlaSupports) // Sla gizmo selects all support points + m_gizmos.mouse_event(5); + else + post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); + break; #ifdef __APPLE__ case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. #else /* __APPLE__ */ @@ -5240,6 +5247,18 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } } +void GLCanvas3D::on_key_up(wxKeyEvent& evt) +{ + // see include/wx/defs.h enum wxKeyCode + int keyCode = evt.GetKeyCode(); + + // shift has been just released - SLA gizmo might want to close rectangular selection: + if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT) { + m_gizmos.mouse_event(2); + m_dirty = true; + } +} + void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) { // Ignore the wheel events if the middle button is pressed. @@ -5586,6 +5605,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown()) { m_gizmos.mouse_event(3, Vec2d(pos(0), pos(1)), evt.ShiftDown()); + m_dirty = true; } else if (evt.Dragging() && !gizmos_overlay_contains_mouse) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 6fd4584a6f..db630988ce 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -789,7 +789,7 @@ private: void set_flattening_data(const ModelObject* model_object); void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); - void mouse_event(int action, const Vec2d& mouse_position, bool shift_down); + void mouse_event(int action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); void delete_current_grabber(bool delete_all = false); void render_current_gizmo(const Selection& selection) const; @@ -1050,6 +1050,7 @@ public: void on_size(wxSizeEvent& evt); void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); + void on_key_up(wxKeyEvent& evt); void on_mouse_wheel(wxMouseEvent& evt); void on_timer(wxTimerEvent& evt); void on_mouse(wxMouseEvent& evt); diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index f752e7d943..e58eb8500e 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1847,12 +1847,17 @@ void GLGizmoSlaSupports::render_selection_rectangle() const ::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f); // set projection matrix so that world coords = window coords // render the selection rectangle (window coordinates): + ::glPushAttrib(GL_ENABLE_BIT); + ::glLineStipple(4, 0xAAAA); + ::glEnable(GL_LINE_STIPPLE); + ::glBegin(GL_LINE_LOOP); ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); ::glEnd(); + ::glPopAttrib(); ::glPopMatrix(); // restore former projection matrix ::glMatrixMode(GL_MODELVIEW); @@ -2035,10 +2040,8 @@ void GLGizmoSlaSupports::mouse_event(int action, const Vec2d& mouse_position, bo } // dragging the selection rectangle: - if (action == 3 && m_selection_rectangle_active) { + if (action == 3 && m_selection_rectangle_active) m_selection_rectangle_end_corner = mouse_position; - m_parent.render(); - } // mouse up without selection rectangle - place point on the mesh: if (action == 2 && !m_selection_rectangle_active) { @@ -2096,6 +2099,15 @@ void GLGizmoSlaSupports::mouse_event(int action, const Vec2d& mouse_position, bo } m_selection_rectangle_active = false; } + + if (action == 4) { + // shift has been released + } + + if (action == 5) { + // ctrl+A : select all + std::cout << "select all..." << std::endl; + } } void GLGizmoSlaSupports::delete_current_point(bool delete_all) From ac8f9ab3dce8da344a6e18acb623b5f0db3eb197 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 11 Feb 2019 16:29:03 +0100 Subject: [PATCH 3/4] SLA gizmo improvements - point can be selected - selection can be deleted, head diameter changed - dragging of objects is not allowed with the gizmo being on - added a modal dialog when automatic support generator is triggered --- src/libslic3r/SLA/SLAAutoSupports.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 80 ++++----- src/slic3r/GUI/GLCanvas3D.hpp | 13 +- src/slic3r/GUI/GLGizmo.cpp | 231 ++++++++++++++++---------- src/slic3r/GUI/GLGizmo.hpp | 9 +- 5 files changed, 195 insertions(+), 140 deletions(-) diff --git a/src/libslic3r/SLA/SLAAutoSupports.cpp b/src/libslic3r/SLA/SLAAutoSupports.cpp index c87f985dac..49b59d60aa 100644 --- a/src/libslic3r/SLA/SLAAutoSupports.cpp +++ b/src/libslic3r/SLA/SLAAutoSupports.cpp @@ -253,7 +253,7 @@ void SLAAutoSupports::uniformly_cover(const ExPolygon& island, Structure& struct } for (const Vec3d& p : island_new_points) { - m_output.emplace_back(float(p(0)), float(p(1)), structure.height, 0.4f, is_new_island); + m_output.emplace_back(float(p(0)), float(p(1)), structure.height, 0.2f, is_new_island); structure.supports_force += m_config.support_force; } } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 92078a8b9d..2cf7f5f67b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3430,24 +3430,18 @@ void GLCanvas3D::Gizmos::set_sla_support_data(ModelObject* model_object, const G reinterpret_cast(it->second)->set_sla_support_data(model_object, selection); } -void GLCanvas3D::Gizmos::mouse_event(int action, const Vec2d& mouse_position, bool shift_down) + +// Returns true if the gizmo used the event to do something, false otherwise. +bool GLCanvas3D::Gizmos::mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down) { if (!m_enabled) - return; + return false; GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); if (it != m_gizmos.end()) - reinterpret_cast(it->second)->mouse_event(action, mouse_position, shift_down); -} + return reinterpret_cast(it->second)->mouse_event(action, mouse_position, shift_down); -void GLCanvas3D::Gizmos::delete_current_grabber(bool delete_all) -{ - if (!m_enabled) - return; - - GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->delete_current_point(delete_all); + return false; } void GLCanvas3D::Gizmos::render_current_gizmo(const GLCanvas3D::Selection& selection) const @@ -5185,8 +5179,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'a': case 'A': case WXK_CONTROL_A: - if (m_gizmos.get_current_type() == Gizmos::SlaSupports) // Sla gizmo selects all support points - m_gizmos.mouse_event(5); + if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::SelectAll)) // Sla gizmo selects all support points + m_dirty = true; else post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); break; @@ -5210,7 +5204,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #else /* __APPLE__ */ case WXK_DELETE: #endif /* __APPLE__ */ - post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; + if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::Delete)) + m_dirty = true; + else + post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); + break; + case '0': { select_view("iso"); break; } case '1': { select_view("top"); break; } case '2': { select_view("bottom"); break; } @@ -5252,11 +5251,9 @@ void GLCanvas3D::on_key_up(wxKeyEvent& evt) // see include/wx/defs.h enum wxKeyCode int keyCode = evt.GetKeyCode(); - // shift has been just released - SLA gizmo might want to close rectangular selection: - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT) { - m_gizmos.mouse_event(2); + // shift has been just released - SLA gizmo might want to close rectangular selection. + if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) m_dirty = true; - } } void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) @@ -5399,25 +5396,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } -#if !ENABLE_IMGUI - else if ((m_gizmos.get_current_type() == Gizmos::SlaSupports) && gizmo_reset_rect_contains(*this, pos(0), pos(1))) - { - if (evt.LeftDown()) - { - m_gizmos.delete_current_grabber(true); - m_dirty = true; - } - } -#endif // not ENABLE_IMGUI else if (!m_selection.is_empty() && gizmos_overlay_contains_mouse) { m_gizmos.update_on_off_state(*this, m_mouse.position, m_selection); _update_gizmos_data(); m_dirty = true; } - else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown()) // inform the gizmo about the event (rectangular selection init) + else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) { - m_gizmos.mouse_event(1, 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()) { @@ -5434,10 +5421,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } - else if ((selected_object_idx != -1) && m_gizmos.grabber_contains_mouse() && evt.RightDown()) { + /*else if ((selected_object_idx != -1) && m_gizmos.grabber_contains_mouse() && evt.RightDown()) { if (m_gizmos.get_current_type() == Gizmos::SlaSupports) m_gizmos.delete_current_grabber(); - } + }*/ else if (view_toolbar_contains_mouse != -1) { if (m_view_toolbar != nullptr) @@ -5542,7 +5529,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } } - else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.move_volume_idx != -1)) + else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) + && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != Gizmos::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) { #if ENABLE_MOVE_MIN_THRESHOLD if (!m_mouse.drag.move_requires_threshold) @@ -5602,9 +5590,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } - else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown()) + else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) { - m_gizmos.mouse_event(3, Vec2d(pos(0), pos(1)), evt.ShiftDown()); + // the gizmo got the event and took some action, no need to do anything more here m_dirty = true; } else if (evt.Dragging() && !gizmos_overlay_contains_mouse) @@ -5662,6 +5650,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _stop_timer(); m_layers_editing.accept_changes(*this); } + else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports && !m_gizmos.is_dragging() + && !m_mouse.dragging && m_gizmos.mouse_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown())) + { + // the gizmo got the event and took some action, no need to do anything more + } else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) { m_regenerate_volumes = false; @@ -5671,16 +5664,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } - else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports/* && m_hover_volume_id != -1*/) + else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() + && !is_layers_editing_enabled() && m_gizmos.get_current_type() != Gizmos::SlaSupports) { - int id = m_selection.get_object_idx(); + // SLA gizmo cannot be deselected by clicking in canvas area to avoid inadvertent unselection and losing manual changes - if ((id != -1) && (m_model != nullptr)) { - m_gizmos.mouse_event(2, Vec2d(pos(0), pos(1)), evt.ShiftDown()); - } - } - else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() && !is_layers_editing_enabled()) - { // deselect and propagate event through callback if (!evt.ShiftDown() && m_picking_enabled && !m_toolbar_action_running && !m_mouse.ignore_up_event) { @@ -5713,10 +5701,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) do_rotate(); break; } - case Gizmos::SlaSupports: - // End of mouse dragging, update the SLAPrint/SLAPrintObjects with the new support points. - post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); - break; default: break; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index db630988ce..ff69f1ef88 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -132,6 +132,17 @@ wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); +// this describes events being passed from GLCanvas3D to SlaSupport gizmo +enum class SLAGizmoEventType { + LeftDown = 1, + LeftUp, + Dragging, + Delete, + SelectAll, + ShiftUp +}; + + class GLCanvas3D { struct GCodePreviewVolumeIndex @@ -789,7 +800,7 @@ private: void set_flattening_data(const ModelObject* model_object); void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); - void mouse_event(int action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); + bool mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); void delete_current_grabber(bool delete_all = false); void render_current_gizmo(const Selection& selection) const; diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index e58eb8500e..6f387ceb31 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1795,8 +1795,9 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const G if (po->model_object()->id() == model_object->id()) { const Eigen::MatrixXd& points = po->get_support_points(); for (unsigned int i=0; itrafo().inverse().cast() * Vec3f(points(i,0), points(i,1), points(i,2)), - points(i, 3), points(i, 4)); + m_editing_mode_cache.push_back(std::make_pair(sla::SupportPoint(po->trafo().inverse().cast() * Vec3f(points(i,0), points(i,1), points(i,2)), + points(i, 3), points(i, 4)), + false)); break; } } @@ -1895,7 +1896,8 @@ void GLGizmoSlaSupports::render_points(const GLCanvas3D::Selection& selection, b float render_color[3]; for (int i = 0; i < (int)m_editing_mode_cache.size(); ++i) { - const Vec3f& point_pos = m_editing_mode_cache[i].pos; + const Vec3f& point_pos = m_editing_mode_cache[i].first.pos; + const bool point_selected = m_editing_mode_cache[i].second; // first precalculate the grabber position in world coordinates, so that the grabber // is not scaled with the object (as it would be if rendered with current gl matrix). Eigen::Matrix glmatrix; @@ -1919,11 +1921,11 @@ void GLGizmoSlaSupports::render_points(const GLCanvas3D::Selection& selection, b render_color[2] = picking_color_component(i); } else { // normal rendering - bool supports_new_island = m_lock_unique_islands && m_editing_mode_cache[i].is_new_island; + bool supports_new_island = m_lock_unique_islands && m_editing_mode_cache[i].first.is_new_island; if (m_editing_mode) { - render_color[0] = supports_new_island ? 0.f : 1.f; - render_color[1] = 0.f; - render_color[2] = supports_new_island ? 1.f : 0.f; + render_color[0] = point_selected ? 0.f : (supports_new_island ? 0.f : 1.f); + render_color[1] = point_selected ? 1.f : 0.f; + render_color[2] = point_selected ? 0.f : (supports_new_island ? 1.f : 0.f); } else for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f; @@ -1934,7 +1936,7 @@ void GLGizmoSlaSupports::render_points(const GLCanvas3D::Selection& selection, b ::glPushMatrix(); ::glLoadIdentity(); ::glTranslated(grabber_world_position(0), grabber_world_position(1), grabber_world_position(2) + z_shift); - ::gluSphere(m_quadric, m_editing_mode_cache[i].head_front_radius, 64, 36); + ::gluSphere(m_quadric, m_editing_mode_cache[i].first.head_front_radius, 64, 36); ::glPopMatrix(); } @@ -1982,7 +1984,9 @@ void GLGizmoSlaSupports::update_mesh() m_AABB.init(m_V, m_F); // we'll now reload support points (selection might have changed): - m_editing_mode_cache = m_model_object->sla_support_points; + m_editing_mode_cache.clear(); + for (const sla::SupportPoint& point : m_model_object->sla_support_points) + m_editing_mode_cache.push_back(std::make_pair(point, false)); } Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) @@ -2025,48 +2029,74 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos) return bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2)); } -void GLGizmoSlaSupports::mouse_event(int action, const Vec2d& mouse_position, bool shift_down) +// Following function is called from GLCanvas3D to inform the gizmo about a mouse/keyboard event. +// The gizmo has an opportunity to react - if it does, it should return true so that the Canvas3D is +// aware that the event was reacted to and stops trying to make different sense of it. If the gizmo +// concludes that the event was not intended for it, it should return false. +bool GLGizmoSlaSupports::mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down) { if (!m_editing_mode) - return; + return false; // left down - show the selection rectangle: - if (action == 1 && shift_down) { - m_selection_rectangle_active = true; - m_selection_rectangle_start_corner = mouse_position; - m_selection_rectangle_end_corner = mouse_position; - m_canvas_width = m_parent.get_canvas_size().get_width(); - m_canvas_height = m_parent.get_canvas_size().get_height(); + if (action == SLAGizmoEventType::LeftDown && shift_down) { + if (m_hover_id == -1) { + m_selection_rectangle_active = true; + m_selection_rectangle_start_corner = mouse_position; + m_selection_rectangle_end_corner = mouse_position; + m_canvas_width = m_parent.get_canvas_size().get_width(); + m_canvas_height = m_parent.get_canvas_size().get_height(); + } + else + m_editing_mode_cache[m_hover_id].second = true; + + return true; } // dragging the selection rectangle: - if (action == 3 && m_selection_rectangle_active) + if (action == SLAGizmoEventType::Dragging && m_selection_rectangle_active) { m_selection_rectangle_end_corner = mouse_position; + return true; + } // mouse up without selection rectangle - place point on the mesh: - if (action == 2 && !m_selection_rectangle_active) { + if (action == SLAGizmoEventType::LeftUp && !m_selection_rectangle_active && !shift_down) { + if (m_ignore_up_event) { + m_ignore_up_event = false; + return false; + } + int instance_id = m_parent.get_selection().get_instance_idx(); if (m_old_instance_id != instance_id) { bool something_selected = (m_old_instance_id != -1); m_old_instance_id = instance_id; if (something_selected) - return; + return false; } if (instance_id == -1) - return; + return false; + + // Regardless of whether the user clicked the object or not, we will unselect all points: + for (unsigned int i=0; iinstances[m_active_instance]->get_transformation().get_matrix(); GLint viewport[4]; ::glGetIntegerv(GL_VIEWPORT, viewport); @@ -2082,68 +2112,61 @@ void GLGizmoSlaSupports::mouse_event(int action, const Vec2d& mouse_position, bo // bounding box created from the rectangle corners - will take care of order of the corners BoundingBox rectangle(Points{Point(m_selection_rectangle_start_corner.cast()), Point(m_selection_rectangle_end_corner.cast())}); - for (sla::SupportPoint& support_point : m_editing_mode_cache) { + for (std::pair& point_and_selection : m_editing_mode_cache) { + const sla::SupportPoint& support_point = point_and_selection.first; Vec3f pos = instance_matrix.cast() * support_point.pos; pos(2) += z_offset; GLdouble out_x, out_y, out_z; ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); out_y = m_canvas_height - out_y; - /*GLfloat depth_comp; - ::glReadPixels( out_x, out_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth_comp); - if (depth_comp > out_z + EPSILON) // the point is obscured by something else - continue;*/ - if (rectangle.contains(Point(out_x, out_y))) - support_point.head_front_radius = 1.f; + point_and_selection.second = true; } m_selection_rectangle_active = false; + return true; } - if (action == 4) { - // shift has been released + if (action == SLAGizmoEventType::Delete) { + // delete key pressed + delete_selected_points(); + return true; } - if (action == 5) { - // ctrl+A : select all - std::cout << "select all..." << std::endl; + if (action == SLAGizmoEventType::SelectAll) { + for (auto& point_and_selection : m_editing_mode_cache) + point_and_selection.second = true; + return true; } + + return false; } -void GLGizmoSlaSupports::delete_current_point(bool delete_all) +void GLGizmoSlaSupports::delete_selected_points() { - if (!m_editing_mode && !delete_all) + if (!m_editing_mode) return; - if (delete_all) { - m_editing_mode_cache.clear(); - - // This should trigger the support generation - // wxGetApp().plater()->reslice(); + for (unsigned int idx=0; idxreslice(); } - else - if (m_hover_id != -1) { - if (!m_editing_mode_cache[m_hover_id].is_new_island || !m_lock_unique_islands) { - m_editing_mode_cache.erase(m_editing_mode_cache.begin() + m_hover_id); - m_hover_id = -1; - // This should trigger the support generation - // wxGetApp().plater()->reslice(); - } - } //m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } void GLGizmoSlaSupports::on_update(const UpdateData& data, const GLCanvas3D::Selection& selection) { - if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_editing_mode_cache[m_hover_id].is_new_island || !m_lock_unique_islands)) { + if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_editing_mode_cache[m_hover_id].first.is_new_island || !m_lock_unique_islands)) { Vec3f new_pos; try { new_pos = unproject_on_mesh(Vec2d((*data.mouse_pos)(0), (*data.mouse_pos)(1))); } catch (...) { return; } - m_editing_mode_cache[m_hover_id].pos = new_pos; - m_editing_mode_cache[m_hover_id].is_new_island = false; + m_editing_mode_cache[m_hover_id].first.pos = new_pos; + m_editing_mode_cache[m_hover_id].first.is_new_island = false; // Do not update immediately, wait until the mouse is released. // m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } @@ -2193,29 +2216,13 @@ RENDER_AGAIN: ImGui::PushItemWidth(100.0f); - /*bool force_refresh = m_editing_mode; - if (m_imgui->radio_button(_(L("Automatic")), !m_editing_mode)) - m_editing_mode = false; - ImGui::SameLine(); - if (m_imgui->radio_button(_(L("Manual")), m_editing_mode)) - m_editing_mode = true; - force_refresh = force_refresh != m_editing_mode; - - if (force_refresh) { // mode has just changed! - if (m_editing_mode) - m_editing_mode_cache = m_model_object->sla_support_points; - else - m_model_object->sla_support_points = m_editing_mode_cache; - } - */ - bool force_refresh = false; - bool remove_all_points = false; + bool remove_selected = false; bool old_editing_state = m_editing_mode; if (m_editing_mode) { m_imgui->text(_(L("Left mouse click - add point"))); - m_imgui->text(_(L("Right mouse click - remove point"))); + m_imgui->text(_(L("Shift + Left (+ drag) - select point(s)"))); m_imgui->text(" "); // vertical gap std::vector options = {"0.2", "0.4", "0.6", "0.8", "1.0"}; @@ -2223,28 +2230,38 @@ RENDER_AGAIN: ss << std::setprecision(1) << m_new_point_head_diameter; wxString str = ss.str(); m_imgui->combo(_(L("Head diameter")), options, str); - force_refresh |= std::abs(atof(str) - m_new_point_head_diameter) > 0.001; - m_new_point_head_diameter = atof(str); + float current_number = atof(str); + if (std::abs(current_number - m_new_point_head_diameter) > 0.001) { + force_refresh = true; + m_new_point_head_diameter = current_number; + for (auto& point_and_selection : m_editing_mode_cache) + if (point_and_selection.second) + point_and_selection.first.head_front_radius = current_number / 2.f; + } bool changed = m_lock_unique_islands; m_imgui->checkbox(_(L("Lock supports under new islands")), m_lock_unique_islands); force_refresh |= changed != m_lock_unique_islands; - remove_all_points = m_imgui->button(_(L("Remove all points")) + (m_model_object == nullptr ? "" : " (" + std::to_string(m_editing_mode_cache.size())+")")); + remove_selected = m_imgui->button(_(L("Remove selected points"))); m_imgui->text(" "); // vertical gap bool apply_changes = m_imgui->button(_(L("Apply changes"))); if (apply_changes) { - m_model_object->sla_support_points = m_editing_mode_cache; + m_model_object->sla_support_points.clear(); + for (const std::pair& point_and_selection : m_editing_mode_cache) + m_model_object->sla_support_points.push_back(point_and_selection.first); m_editing_mode = false; force_refresh = true; m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } ImGui::SameLine(); - bool discard_changes = m_imgui->button(_(L("Cancel"))); + bool discard_changes = m_imgui->button(_(L("Discard changes"))); if (discard_changes) { - m_editing_mode_cache = m_model_object->sla_support_points; + m_editing_mode_cache.clear(); + for (const sla::SupportPoint& point : m_model_object->sla_support_points) + m_editing_mode_cache.push_back(std::make_pair(point, false)); m_editing_mode = false; force_refresh = true; } @@ -2258,16 +2275,45 @@ RENDER_AGAIN: m_imgui->text(""); bool generate =m_imgui->button(_(L("Auto-generate points"))); - force_refresh |= generate; + if (generate) { - m_model_object->sla_support_points.clear(); - m_editing_mode_cache.clear(); - wxGetApp().plater()->reslice(); + ImGui::OpenPopup(_(L("Warning"))); + m_show_modal = true; + force_refresh = true; } + + if (m_show_modal) { + if (ImGui::BeginPopupModal(_(L("Warning")), &m_show_modal/*, ImGuiWindowFlags_NoDecoration*/)) + { + m_imgui->text(_(L("This will erase all your manual changes."))); + + if (m_imgui->button(_(L("Continue")))) + { + ImGui::CloseCurrentPopup(); + m_show_modal = false; + + m_model_object->sla_support_points.clear(); + m_editing_mode_cache.clear(); + wxGetApp().plater()->reslice(); + } + ImGui::SameLine(); + if (m_imgui->button(_(L("Cancel")))) { + ImGui::CloseCurrentPopup(); + m_show_modal = false; + } + ImGui::EndPopup(); + } + + if (!m_show_modal) + force_refresh = true; + } + ImGui::SameLine(); bool editing_clicked = m_imgui->button("Editing"); if (editing_clicked) { - m_editing_mode_cache = m_model_object->sla_support_points; + m_editing_mode_cache.clear(); + for (const sla::SupportPoint& point : m_model_object->sla_support_points) + m_editing_mode_cache.push_back(std::make_pair(point, false)); m_editing_mode = true; } } @@ -2280,10 +2326,10 @@ RENDER_AGAIN: } - if (remove_all_points) { + if (remove_selected) { force_refresh = false; m_parent.reload_scene(true); - delete_current_point(true); + delete_selected_points(); if (first_run) { first_run = false; goto RENDER_AGAIN; @@ -2324,9 +2370,20 @@ void GLGizmoSlaSupports::on_set_state() if (m_state == Off) { m_parent.toggle_model_objects_visibility(true); m_editing_mode = false; + if (m_show_modal) { + m_show_modal = false; + on_render_input_window(0,0,m_parent.get_selection()); // this is necessary to allow ImGui to terminate the modal dialog correctly + } } } +void GLGizmoSlaSupports::on_start_dragging(const GLCanvas3D::Selection& selection) +{ + if (m_hover_id != -1) + for (unsigned int i=0;i m_editing_mode_cache; + std::vector> m_editing_mode_cache; // a support point and whether it is currently selected bool m_selection_rectangle_active = false; Vec2d m_selection_rectangle_start_corner; Vec2d m_selection_rectangle_end_corner; + bool m_ignore_up_event = false; + bool m_show_modal = false; int m_canvas_width; int m_canvas_height; protected: void on_set_state() override; + void on_start_dragging(const GLCanvas3D::Selection& selection) override; #if ENABLE_IMGUI virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) override; From d1529296c6e9ae56b4fb12a69c346416b0ec07c1 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 11 Feb 2019 17:06:39 +0100 Subject: [PATCH 4/4] Added a wxMessageDialog as an alternative to the ImGui modal, in case it turns out not good enough --- src/slic3r/GUI/GLGizmo.cpp | 24 ++++++++++++++++++++---- src/slic3r/GUI/GLGizmo.hpp | 5 +++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 6f387ceb31..85551d23cb 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -2274,18 +2274,32 @@ RENDER_AGAIN: m_imgui->text(""); - bool generate =m_imgui->button(_(L("Auto-generate points"))); + bool generate = m_imgui->button(_(L("Auto-generate points"))); if (generate) { +#if SLAGIZMO_IMGUI_MODAL ImGui::OpenPopup(_(L("Warning"))); m_show_modal = true; force_refresh = true; +#else + wxMessageDialog dlg(GUI::wxGetApp().plater(), _(L( + "Autogeneration will erase all currently assigned points.\n\n" + "Are you sure you want to do it?\n" + )), _(L("Warning")), wxICON_WARNING | wxYES | wxNO); + if (dlg.ShowModal() == wxID_YES) { + m_model_object->sla_support_points.clear(); + m_editing_mode_cache.clear(); + wxGetApp().plater()->reslice(); + } +#endif } - +#if SLAGIZMO_IMGUI_MODAL if (m_show_modal) { if (ImGui::BeginPopupModal(_(L("Warning")), &m_show_modal/*, ImGuiWindowFlags_NoDecoration*/)) { - m_imgui->text(_(L("This will erase all your manual changes."))); + m_imgui->text(_(L("Autogeneration will erase all currently assigned points."))); + m_imgui->text(""); + m_imgui->text(_(L("Are you sure you want to do it?"))); if (m_imgui->button(_(L("Continue")))) { @@ -2307,7 +2321,7 @@ RENDER_AGAIN: if (!m_show_modal) force_refresh = true; } - +#endif ImGui::SameLine(); bool editing_clicked = m_imgui->button("Editing"); if (editing_clicked) { @@ -2370,10 +2384,12 @@ void GLGizmoSlaSupports::on_set_state() if (m_state == Off) { m_parent.toggle_model_objects_visibility(true); m_editing_mode = false; +#if SLAGIZMO_IMGUI_MODAL if (m_show_modal) { m_show_modal = false; on_render_input_window(0,0,m_parent.get_selection()); // this is necessary to allow ImGui to terminate the modal dialog correctly } +#endif } } diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index 15c3779f54..b80916db72 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -437,6 +437,9 @@ protected: } }; + + +#define SLAGIZMO_IMGUI_MODAL 1 class GLGizmoSlaSupports : public GLGizmoBase { private: @@ -493,7 +496,9 @@ private: Vec2d m_selection_rectangle_start_corner; Vec2d m_selection_rectangle_end_corner; bool m_ignore_up_event = false; +#if SLAGIZMO_IMGUI_MODAL bool m_show_modal = false; +#endif int m_canvas_width; int m_canvas_height;