From 58c7d8b1881127cafd971fa14dcf2fcc9ef9c5eb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 3 Oct 2022 17:18:58 +0200 Subject: [PATCH] CutGizmo: Connectors mode: Implemented Rectangular selection of connectors + some code refactoring --- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 5 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 86 ++++++++++++++------ src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 7 ++ src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 22 ++--- 6 files changed, 83 insertions(+), 43 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 09766bbac9..43624964a8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -210,7 +210,10 @@ public: #if ENABLE_RAYCAST_PICKING void register_raycasters_for_picking() { register_grabbers_for_picking(); on_register_raycasters_for_picking(); } void unregister_raycasters_for_picking() { unregister_grabbers_for_picking(); on_unregister_raycasters_for_picking(); } -#endif // ENABLE_RAYCAST_PICKING +#endif // ENABLE_RAYCAST_PICKING + + virtual bool is_in_editing_mode() const { return false; } + virtual bool is_selection_rectangle_dragging() const { return false; } protected: virtual bool on_init() = 0; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 71a9c5dcf7..775cd32ccd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -28,6 +28,7 @@ static const ColorRGBA HOVERED_DOWEL_COLOR = ColorRGBA(0.0f, 0.5f, 0.5f, 1.0f); static const ColorRGBA SELECTED_PLAG_COLOR = ColorRGBA::GRAY(); static const ColorRGBA SELECTED_DOWEL_COLOR = ColorRGBA::DARK_GRAY(); static const ColorRGBA CONNECTOR_DEF_COLOR = ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); +static const ColorRGBA CONNECTOR_ERR_COLOR = ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f); const unsigned int AngleResolution = 64; const unsigned int ScaleStepsCount = 72; @@ -1287,6 +1288,8 @@ void GLGizmoCut3D::on_render() } render_cut_line(); + + m_selection_rectangle.render(m_parent); } void GLGizmoCut3D::render_debug_input_window() @@ -1622,17 +1625,7 @@ void GLGizmoCut3D::render_connectors() m_selected.resize(connectors.size(), false); } - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); - if (shader == nullptr) - return; - - shader->start_using(); - - ScopeGuard guard([shader]() { shader->stop_using(); }); - - const Camera& camera = wxGetApp().plater()->get_camera(); - - ColorRGBA render_color; + ColorRGBA render_color = CONNECTOR_DEF_COLOR; const ModelInstance* mi = mo->instances[inst_id]; const Vec3d& instance_offset = mi->get_offset(); @@ -1656,11 +1649,11 @@ void GLGizmoCut3D::render_connectors() pos -= height * normal; height *= 2; } - pos[Z] += sla_shift; + pos += sla_shift * Vec3d::UnitZ(); // First decide about the color of the point. if (!m_connectors_editing) - render_color = CONNECTOR_DEF_COLOR; + render_color = CONNECTOR_ERR_COLOR; else if (size_t(m_hover_id - m_connectors_group_id) == i) render_color = connector.attribs.type == CutConnectorType::Dowel ? HOVERED_DOWEL_COLOR : HOVERED_PLAG_COLOR; else if (m_selected[i]) @@ -1678,22 +1671,19 @@ void GLGizmoCut3D::render_connectors() const Transform3d volume_trafo = get_volume_transformation(mv); if (m_c->raycaster()->raycasters()[mesh_id]->is_valid_intersection(pos, -normal, instance_trafo * volume_trafo)) { - render_color = m_connectors_editing ? ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f) : /*ColorRGBA(0.5f, 0.5f, 0.5f, 1.f)*/ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f); + render_color = m_connectors_editing ? ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f) : CONNECTOR_ERR_COLOR; break; } - render_color = ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f); + render_color = CONNECTOR_ERR_COLOR; m_has_invalid_connector = true; } } - m_shapes[connector.attribs].model.set_color(render_color); + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d view_model_matrix = camera.get_view_matrix() * translation_transform(pos) * m_rotation_m * + scale_transform(Vec3f(connector.radius, connector.radius, height).cast()); - const Transform3d scale_trafo = scale_transform(Vec3f(connector.radius, connector.radius, height).cast()); - const Transform3d view_model_matrix = camera.get_view_matrix() * translation_transform(pos) * m_rotation_m * scale_trafo; - shader->set_uniform("view_model_matrix", view_model_matrix); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - - m_shapes[connector.attribs].model.render(); + render_model(m_shapes[connector.attribs].model, render_color, view_model_matrix); } } @@ -1992,6 +1982,29 @@ bool GLGizmoCut3D::is_selection_changed(bool alt_down, bool control_down) return false; } +void GLGizmoCut3D::process_selection_rectangle(CutConnectors &connectors) +{ + GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state(); + + ModelObject* mo = m_c->selection_info()->model_object(); + int active_inst = m_c->selection_info()->get_active_instance(); + + // First collect positions of all the points in world coordinates. + Transformation trafo = mo->instances[active_inst]->get_transformation(); + trafo.set_offset(trafo.get_offset() + double(m_c->selection_info()->get_sla_shift()) * Vec3d::UnitZ()); + + std::vector points; + for (const CutConnector&connector : connectors) + points.push_back(connector.pos + trafo.get_offset()); + + // Now ask the rectangle which of the points are inside. + std::vector points_idxs = m_selection_rectangle.contains(points); + m_selection_rectangle.stop_dragging(); + + for (size_t idx : points_idxs) + select_connector(int(idx), rectangle_status == GLSelectionRectangle::EState::Select); +} + bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { if (is_dragging() || m_connector_mode == CutConnectorMode::Auto || (!m_keep_upper || !m_keep_lower)) @@ -2001,20 +2014,43 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi (action == SLAGizmoEventType::LeftDown || action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::Moving) ) return process_cut_line(action, mouse_position); + if (!m_connectors_editing) + return false; + CutConnectors& connectors = m_c->selection_info()->model_object()->cut_connectors; - if (action == SLAGizmoEventType::LeftDown && !shift_down) { + if (action == SLAGizmoEventType::LeftDown) { + if (shift_down || alt_down) { + // left down with shift - show the selection rectangle: + if (m_hover_id == -1) + m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect); + } + else // If there is no selection and no hovering, add new point if (m_hover_id == -1 && !control_down && !alt_down) if (!add_connector(connectors, mouse_position)) unselect_all_connectors(); return true; } - if (!m_connectors_editing) - return false; if (action == SLAGizmoEventType::LeftUp && !shift_down) return is_selection_changed(alt_down, control_down); + + // left up with selection rectangle - select points inside the rectangle: + if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::ShiftUp || action == SLAGizmoEventType::AltUp) && m_selection_rectangle.is_dragging()) { + // Is this a selection or deselection rectangle? + process_selection_rectangle(connectors); + return true; + } + + // dragging the selection rectangle: + if (action == SLAGizmoEventType::Dragging) { + if (m_selection_rectangle.is_dragging()) { + m_selection_rectangle.dragging(mouse_position); + return true; + } + return false; + } if (action == SLAGizmoEventType::RightDown && !shift_down) { // If any point is in hover state, this should initiate its move - return control back to GLCanvas: diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 4335da35ae..355c9230e4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -2,6 +2,7 @@ #define slic3r_GLGizmoCut_hpp_ #include "GLGizmoBase.hpp" +#include "slic3r/GUI/GLSelectionRectangle.hpp" #include "slic3r/GUI/GLModel.hpp" #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Model.hpp" @@ -95,6 +96,8 @@ class GLGizmoCut3D : public GLGizmoBase mutable std::vector m_selected; // which pins are currently selected int m_selected_count{ 0 }; + GLSelectionRectangle m_selection_rectangle; + bool m_has_invalid_connector{ false }; bool m_show_shortcuts{ false }; @@ -136,6 +139,9 @@ public: bool unproject_on_cut_plane(const Vec2d& mouse_pos, std::pair& pos_and_normal, Vec3d& pos_world); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); + bool is_in_editing_mode() const override { return m_connectors_editing; } + bool is_selection_rectangle_dragging() const override { return m_selection_rectangle.is_dragging(); } + /// /// Drag of plane /// @@ -189,6 +195,7 @@ protected: bool delete_selected_connectors(CutConnectors&connectors); void select_connector(int idx, bool select); bool is_selection_changed(bool alt_down, bool control_down); + void process_selection_rectangle(CutConnectors &connectors); virtual void on_register_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index aa8cdda043..0fdc3b2db7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -31,7 +31,7 @@ public: void data_changed() override; bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); void delete_selected_points(); - bool is_selection_rectangle_dragging() const { + bool is_selection_rectangle_dragging() const override { return m_selection_rectangle.is_dragging(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index ed48b6e5e2..136276803e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -62,8 +62,8 @@ public: void delete_selected_points(bool force = false); //ClippingPlane get_sla_clipping_plane() const; - bool is_in_editing_mode() const { return m_editing_mode; } - bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); } + bool is_in_editing_mode() const override { return m_editing_mode; } + bool is_selection_rectangle_dragging() const override { return m_selection_rectangle.is_dragging(); } bool has_backend_supports() const; void reslice_SLA_supports(bool postpone_error_messages = false) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 3946e54e13..add1eb94c8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -610,20 +610,11 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) if (evt.GetEventType() == wxEVT_KEY_UP) { - if (m_current == SlaSupports || m_current == Hollow) + if (m_current == SlaSupports || m_current == Hollow || m_current == Cut) { - bool is_editing = true; - bool is_rectangle_dragging = false; - - if (m_current == SlaSupports) { - GLGizmoSlaSupports* gizmo = dynamic_cast(get_current()); - is_editing = gizmo->is_in_editing_mode(); - is_rectangle_dragging = gizmo->is_selection_rectangle_dragging(); - } - else { - GLGizmoHollow* gizmo = dynamic_cast(get_current()); - is_rectangle_dragging = gizmo->is_selection_rectangle_dragging(); - } + GLGizmoBase* gizmo = get_current(); + const bool is_editing = m_current == Hollow ? true : gizmo->is_in_editing_mode(); + const bool is_rectangle_dragging = gizmo->is_selection_rectangle_dragging(); if (keyCode == WXK_SHIFT) { @@ -645,7 +636,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) else if (evt.GetEventType() == wxEVT_KEY_DOWN) { if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) - && dynamic_cast(get_current())->is_in_editing_mode()) + && get_current()->is_in_editing_mode()) { // m_parent.set_cursor(GLCanvas3D::Cross); processed = true; @@ -662,6 +653,9 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) { case WXK_NUMPAD_UP: case WXK_UP: { do_move(1.0); break; } case WXK_NUMPAD_DOWN: case WXK_DOWN: { do_move(-1.0); break; } + case WXK_SHIFT : case WXK_ALT: { + processed = get_current()->is_in_editing_mode(); + } default: { break; } } } else if (m_current == Simplify && keyCode == WXK_ESCAPE) {