mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-17 12:25:56 +08:00
CutGizmo: Connectors mode: Implemented Rectangular selection of connectors
+ some code refactoring
This commit is contained in:
parent
b4f38883a8
commit
58c7d8b188
@ -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) {}
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user