CutGizmo: Connectors mode: Implemented Rectangular selection of connectors

+ some code refactoring
This commit is contained in:
YuSanka 2022-10-03 17:18:58 +02:00
parent b4f38883a8
commit 58c7d8b188
6 changed files with 83 additions and 43 deletions

View File

@ -212,6 +212,9 @@ public:
void unregister_raycasters_for_picking() { unregister_grabbers_for_picking(); on_unregister_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: protected:
virtual bool on_init() = 0; virtual bool on_init() = 0;
virtual void on_load(cereal::BinaryInputArchive& ar) {} virtual void on_load(cereal::BinaryInputArchive& ar) {}

View File

@ -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_PLAG_COLOR = ColorRGBA::GRAY();
static const ColorRGBA SELECTED_DOWEL_COLOR = ColorRGBA::DARK_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_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 AngleResolution = 64;
const unsigned int ScaleStepsCount = 72; const unsigned int ScaleStepsCount = 72;
@ -1287,6 +1288,8 @@ void GLGizmoCut3D::on_render()
} }
render_cut_line(); render_cut_line();
m_selection_rectangle.render(m_parent);
} }
void GLGizmoCut3D::render_debug_input_window() void GLGizmoCut3D::render_debug_input_window()
@ -1622,17 +1625,7 @@ void GLGizmoCut3D::render_connectors()
m_selected.resize(connectors.size(), false); m_selected.resize(connectors.size(), false);
} }
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); ColorRGBA render_color = CONNECTOR_DEF_COLOR;
if (shader == nullptr)
return;
shader->start_using();
ScopeGuard guard([shader]() { shader->stop_using(); });
const Camera& camera = wxGetApp().plater()->get_camera();
ColorRGBA render_color;
const ModelInstance* mi = mo->instances[inst_id]; const ModelInstance* mi = mo->instances[inst_id];
const Vec3d& instance_offset = mi->get_offset(); const Vec3d& instance_offset = mi->get_offset();
@ -1656,11 +1649,11 @@ void GLGizmoCut3D::render_connectors()
pos -= height * normal; pos -= height * normal;
height *= 2; height *= 2;
} }
pos[Z] += sla_shift; pos += sla_shift * Vec3d::UnitZ();
// First decide about the color of the point. // First decide about the color of the point.
if (!m_connectors_editing) 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) 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; render_color = connector.attribs.type == CutConnectorType::Dowel ? HOVERED_DOWEL_COLOR : HOVERED_PLAG_COLOR;
else if (m_selected[i]) else if (m_selected[i])
@ -1678,22 +1671,19 @@ void GLGizmoCut3D::render_connectors()
const Transform3d volume_trafo = get_volume_transformation(mv); const Transform3d volume_trafo = get_volume_transformation(mv);
if (m_c->raycaster()->raycasters()[mesh_id]->is_valid_intersection(pos, -normal, instance_trafo * volume_trafo)) { 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; break;
} }
render_color = ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f); render_color = CONNECTOR_ERR_COLOR;
m_has_invalid_connector = true; 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<double>());
const Transform3d scale_trafo = scale_transform(Vec3f(connector.radius, connector.radius, height).cast<double>()); render_model(m_shapes[connector.attribs].model, render_color, view_model_matrix);
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();
} }
} }
@ -1992,6 +1982,29 @@ bool GLGizmoCut3D::is_selection_changed(bool alt_down, bool control_down)
return false; 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<Vec3d> 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<unsigned int> 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) 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)) if (is_dragging() || m_connector_mode == CutConnectorMode::Auto || (!m_keep_upper || !m_keep_lower))
@ -2001,21 +2014,44 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
(action == SLAGizmoEventType::LeftDown || action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::Moving) ) (action == SLAGizmoEventType::LeftDown || action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::Moving) )
return process_cut_line(action, mouse_position); return process_cut_line(action, mouse_position);
if (!m_connectors_editing)
return false;
CutConnectors& connectors = m_c->selection_info()->model_object()->cut_connectors; 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 there is no selection and no hovering, add new point
if (m_hover_id == -1 && !control_down && !alt_down) if (m_hover_id == -1 && !control_down && !alt_down)
if (!add_connector(connectors, mouse_position)) if (!add_connector(connectors, mouse_position))
unselect_all_connectors(); unselect_all_connectors();
return true; return true;
} }
if (!m_connectors_editing)
return false;
if (action == SLAGizmoEventType::LeftUp && !shift_down) if (action == SLAGizmoEventType::LeftUp && !shift_down)
return is_selection_changed(alt_down, control_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 (action == SLAGizmoEventType::RightDown && !shift_down) {
// If any point is in hover state, this should initiate its move - return control back to GLCanvas: // If any point is in hover state, this should initiate its move - return control back to GLCanvas:
if (m_hover_id < m_connectors_group_id) if (m_hover_id < m_connectors_group_id)

View File

@ -2,6 +2,7 @@
#define slic3r_GLGizmoCut_hpp_ #define slic3r_GLGizmoCut_hpp_
#include "GLGizmoBase.hpp" #include "GLGizmoBase.hpp"
#include "slic3r/GUI/GLSelectionRectangle.hpp"
#include "slic3r/GUI/GLModel.hpp" #include "slic3r/GUI/GLModel.hpp"
#include "libslic3r/TriangleMesh.hpp" #include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
@ -95,6 +96,8 @@ class GLGizmoCut3D : public GLGizmoBase
mutable std::vector<bool> m_selected; // which pins are currently selected mutable std::vector<bool> m_selected; // which pins are currently selected
int m_selected_count{ 0 }; int m_selected_count{ 0 };
GLSelectionRectangle m_selection_rectangle;
bool m_has_invalid_connector{ false }; bool m_has_invalid_connector{ false };
bool m_show_shortcuts{ false }; bool m_show_shortcuts{ false };
@ -136,6 +139,9 @@ public:
bool unproject_on_cut_plane(const Vec2d& mouse_pos, std::pair<Vec3d, Vec3d>& pos_and_normal, Vec3d& pos_world); bool unproject_on_cut_plane(const Vec2d& mouse_pos, std::pair<Vec3d, Vec3d>& 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 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(); }
/// <summary> /// <summary>
/// Drag of plane /// Drag of plane
/// </summary> /// </summary>
@ -189,6 +195,7 @@ protected:
bool delete_selected_connectors(CutConnectors&connectors); bool delete_selected_connectors(CutConnectors&connectors);
void select_connector(int idx, bool select); void select_connector(int idx, bool select);
bool is_selection_changed(bool alt_down, bool control_down); 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_register_raycasters_for_picking() override;
virtual void on_unregister_raycasters_for_picking() override; virtual void on_unregister_raycasters_for_picking() override;

View File

@ -31,7 +31,7 @@ public:
void data_changed() override; void data_changed() override;
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
void delete_selected_points(); void delete_selected_points();
bool is_selection_rectangle_dragging() const { bool is_selection_rectangle_dragging() const override {
return m_selection_rectangle.is_dragging(); return m_selection_rectangle.is_dragging();
} }

View File

@ -62,8 +62,8 @@ public:
void delete_selected_points(bool force = false); void delete_selected_points(bool force = false);
//ClippingPlane get_sla_clipping_plane() const; //ClippingPlane get_sla_clipping_plane() const;
bool is_in_editing_mode() const { return m_editing_mode; } bool is_in_editing_mode() const override { return m_editing_mode; }
bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); } bool is_selection_rectangle_dragging() const override { return m_selection_rectangle.is_dragging(); }
bool has_backend_supports() const; bool has_backend_supports() const;
void reslice_SLA_supports(bool postpone_error_messages = false) const; void reslice_SLA_supports(bool postpone_error_messages = false) const;

View File

@ -610,20 +610,11 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
if (evt.GetEventType() == wxEVT_KEY_UP) 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; GLGizmoBase* gizmo = get_current();
bool is_rectangle_dragging = false; const bool is_editing = m_current == Hollow ? true : gizmo->is_in_editing_mode();
const bool is_rectangle_dragging = gizmo->is_selection_rectangle_dragging();
if (m_current == SlaSupports) {
GLGizmoSlaSupports* gizmo = dynamic_cast<GLGizmoSlaSupports*>(get_current());
is_editing = gizmo->is_in_editing_mode();
is_rectangle_dragging = gizmo->is_selection_rectangle_dragging();
}
else {
GLGizmoHollow* gizmo = dynamic_cast<GLGizmoHollow*>(get_current());
is_rectangle_dragging = gizmo->is_selection_rectangle_dragging();
}
if (keyCode == WXK_SHIFT) if (keyCode == WXK_SHIFT)
{ {
@ -645,7 +636,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
else if (evt.GetEventType() == wxEVT_KEY_DOWN) else if (evt.GetEventType() == wxEVT_KEY_DOWN)
{ {
if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)) if ((m_current == SlaSupports) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT))
&& dynamic_cast<GLGizmoSlaSupports*>(get_current())->is_in_editing_mode()) && get_current()->is_in_editing_mode())
{ {
// m_parent.set_cursor(GLCanvas3D::Cross); // m_parent.set_cursor(GLCanvas3D::Cross);
processed = true; 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_UP: case WXK_UP: { do_move(1.0); break; }
case WXK_NUMPAD_DOWN: case WXK_DOWN: { 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; } default: { break; }
} }
} else if (m_current == Simplify && keyCode == WXK_ESCAPE) { } else if (m_current == Simplify && keyCode == WXK_ESCAPE) {