mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 17:45:58 +08:00
Cut: Bug fixing and Improvements
* CutGizmo: Fixed a label scale * Fixed deselection of selected connectors, when moving the camera * Implemented update of the settings for selected connectors * Connector selection: Ctrl shortcut is changed to Shift to compatibility of the selection/deselection with rectangle selection
This commit is contained in:
parent
58c7d8b188
commit
74a32e3261
@ -222,11 +222,13 @@ private:
|
|||||||
enum class CutConnectorType : int {
|
enum class CutConnectorType : int {
|
||||||
Plug
|
Plug
|
||||||
, Dowel
|
, Dowel
|
||||||
|
, Undef
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class CutConnectorStyle : int {
|
enum class CutConnectorStyle : int {
|
||||||
Prizm
|
Prizm
|
||||||
, Frustum
|
, Frustum
|
||||||
|
, Undef
|
||||||
//,Claw
|
//,Claw
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,6 +237,7 @@ enum class CutConnectorShape : int {
|
|||||||
, Square
|
, Square
|
||||||
, Hexagon
|
, Hexagon
|
||||||
, Circle
|
, Circle
|
||||||
|
, Undef
|
||||||
//,D-shape
|
//,D-shape
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ const unsigned int ScaleLongEvery = 2;
|
|||||||
const float ScaleLongTooth = 0.1f; // in percent of radius
|
const float ScaleLongTooth = 0.1f; // in percent of radius
|
||||||
const unsigned int SnapRegionsCount = 8;
|
const unsigned int SnapRegionsCount = 8;
|
||||||
|
|
||||||
|
const float UndefFloat = -999.f;
|
||||||
|
const std::string UndefLabel = " ";
|
||||||
|
|
||||||
using namespace Geometry;
|
using namespace Geometry;
|
||||||
|
|
||||||
// Generates mesh for a line
|
// Generates mesh for a line
|
||||||
@ -274,8 +277,8 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||||||
static bool pending_right_up = false;
|
static bool pending_right_up = false;
|
||||||
if (mouse_event.LeftDown()) {
|
if (mouse_event.LeftDown()) {
|
||||||
bool grabber_contains_mouse = (get_hover_id() != -1);
|
bool grabber_contains_mouse = (get_hover_id() != -1);
|
||||||
bool control_down = mouse_event.CmdDown();
|
const bool shift_down = mouse_event.ShiftDown();
|
||||||
if ((!control_down || grabber_contains_mouse) &&
|
if ((!shift_down || grabber_contains_mouse) &&
|
||||||
gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), false))
|
gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), false))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -285,14 +288,14 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||||||
// don't allow dragging objects with the Sla gizmo on
|
// don't allow dragging objects with the Sla gizmo on
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (!control_down &&
|
if (!control_down &&
|
||||||
gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), false)) {
|
gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), false)) {
|
||||||
// the gizmo got the event and took some action, no need to do
|
// the gizmo got the event and took some action, no need to do
|
||||||
// anything more here
|
// anything more here
|
||||||
m_parent.set_as_dirty();
|
m_parent.set_as_dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (control_down && (mouse_event.LeftIsDown() || mouse_event.RightIsDown())) {
|
if (control_down && (mouse_event.LeftIsDown() || mouse_event.RightIsDown())) {
|
||||||
// CTRL has been pressed while already dragging -> stop current action
|
// CTRL has been pressed while already dragging -> stop current action
|
||||||
if (mouse_event.LeftIsDown())
|
if (mouse_event.LeftIsDown())
|
||||||
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), true);
|
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), true);
|
||||||
@ -427,7 +430,7 @@ bool GLGizmoCut3D::render_combo(const std::string& label, const std::vector<std:
|
|||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y + style.FramePadding.y));
|
ImGui::SetCursorScreenPos(ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y + style.FramePadding.y));
|
||||||
ImGui::Text("%s", lines[selection_out].c_str());
|
ImGui::Text("%s", selection_out < lines.size() ? lines[selection_out].c_str() : UndefLabel.c_str());
|
||||||
ImGui::SetCursorScreenPos(backup_pos);
|
ImGui::SetCursorScreenPos(backup_pos);
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
@ -457,41 +460,47 @@ bool GLGizmoCut3D::render_double_input(const std::string& label, double& value_i
|
|||||||
m_imgui->text(m_imperial_units ? _L("in") : _L("mm"));
|
m_imgui->text(m_imperial_units ? _L("in") : _L("mm"));
|
||||||
|
|
||||||
value_in = value * (m_imperial_units ? ObjectManipulation::in_to_mm : 1.0);
|
value_in = value * (m_imperial_units ? ObjectManipulation::in_to_mm : 1.0);
|
||||||
return old_val != value;
|
return !is_approx(old_val, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoCut3D::render_slider_double_input(const std::string& label, double& value_in, int& tolerance_in)
|
bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in)
|
||||||
{
|
{
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
m_imgui->text(label);
|
m_imgui->text(label);
|
||||||
ImGui::SameLine(m_label_width);
|
ImGui::SameLine(m_label_width);
|
||||||
ImGui::PushItemWidth(m_control_width * 0.85f);
|
ImGui::PushItemWidth(m_control_width * 0.85f);
|
||||||
|
|
||||||
float value = (float)value_in;
|
float value = value_in;
|
||||||
if (m_imperial_units)
|
if (m_imperial_units)
|
||||||
value *= float(ObjectManipulation::mm_to_in);
|
value *= float(ObjectManipulation::mm_to_in);
|
||||||
float old_val = value;
|
float old_val = value;
|
||||||
|
|
||||||
|
constexpr float UndefMinVal = -0.1f;
|
||||||
|
|
||||||
const BoundingBoxf3 bbox = bounding_box();
|
const BoundingBoxf3 bbox = bounding_box();
|
||||||
float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0);
|
float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0);
|
||||||
float min_size = 1.f;
|
float min_size = value_in < 0.f ? UndefMinVal : 2.f;
|
||||||
if (m_imperial_units) {
|
if (m_imperial_units) {
|
||||||
mean_size *= float(ObjectManipulation::mm_to_in);
|
mean_size *= float(ObjectManipulation::mm_to_in);
|
||||||
min_size *= float(ObjectManipulation::mm_to_in);
|
min_size *= float(ObjectManipulation::mm_to_in);
|
||||||
}
|
}
|
||||||
std::string format = m_imperial_units ? "%.4f " + _u8L("in") : "%.2f " + _u8L("mm");
|
std::string format = value_in < 0.f ? UndefLabel :
|
||||||
|
m_imperial_units ? "%.4f " + _u8L("in") : "%.2f " + _u8L("mm");
|
||||||
|
|
||||||
m_imgui->slider_float(("##" + label).c_str(), &value, min_size, mean_size, format.c_str());
|
m_imgui->slider_float(("##" + label).c_str(), &value, min_size, mean_size, format.c_str());
|
||||||
value_in = (double)(value) * (m_imperial_units ? ObjectManipulation::in_to_mm : 1.0);
|
value_in = value * float(m_imperial_units ? ObjectManipulation::in_to_mm : 1.0);
|
||||||
|
|
||||||
ImGui::SameLine(m_label_width + m_control_width + 3);
|
ImGui::SameLine(m_label_width + m_control_width + 3);
|
||||||
ImGui::PushItemWidth(m_control_width * 0.3f);
|
ImGui::PushItemWidth(m_control_width * 0.3f);
|
||||||
|
|
||||||
float old_tolerance, tolerance = old_tolerance = (float)tolerance_in;
|
float old_tolerance, tolerance = old_tolerance = tolerance_in * 100.f;
|
||||||
m_imgui->slider_float(("##tolerance_" + label).c_str(), &tolerance, 1.f, 20.f, "%.f %%", 1.f, true, _L("Tolerance"));
|
std::string format_t = tolerance_in < 0.f ? UndefLabel : "%.f %%";
|
||||||
tolerance_in = (int)tolerance;
|
float min_tolerance = tolerance_in < 0.f ? UndefMinVal : 0.f;
|
||||||
|
|
||||||
return old_val != value || old_tolerance != tolerance;
|
m_imgui->slider_float(("##tolerance_" + label).c_str(), &tolerance, min_tolerance, 20.f, format_t.c_str(), 1.f, true, _L("Tolerance"));
|
||||||
|
tolerance_in = tolerance * 0.01f;
|
||||||
|
|
||||||
|
return !is_approx(old_val, value) || !is_approx(old_tolerance, tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::render_move_center_input(int axis)
|
void GLGizmoCut3D::render_move_center_input(int axis)
|
||||||
@ -774,11 +783,12 @@ bool GLGizmoCut3D::on_init()
|
|||||||
// initiate info shortcuts
|
// initiate info shortcuts
|
||||||
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
||||||
const wxString alt = GUI::shortkey_alt_prefix();
|
const wxString alt = GUI::shortkey_alt_prefix();
|
||||||
|
const wxString shift = "Shift+";
|
||||||
|
|
||||||
m_shortcuts.push_back(std::make_pair(_L("Left click"), _L("Add connector")));
|
m_shortcuts.push_back(std::make_pair(_L("Left click"), _L("Add connector")));
|
||||||
m_shortcuts.push_back(std::make_pair(_L("Right click"), _L("Remove connector")));
|
m_shortcuts.push_back(std::make_pair(_L("Right click"), _L("Remove connector")));
|
||||||
m_shortcuts.push_back(std::make_pair(_L("Drag"), _L("Move connector")));
|
m_shortcuts.push_back(std::make_pair(_L("Drag"), _L("Move connector")));
|
||||||
m_shortcuts.push_back(std::make_pair(ctrl + _L("Left click"), _L("Add connector to selection")));
|
m_shortcuts.push_back(std::make_pair(shift + _L("Left click"), _L("Add connector to selection")));
|
||||||
m_shortcuts.push_back(std::make_pair(alt + _L("Left click"), _L("Remove connector from selection")));
|
m_shortcuts.push_back(std::make_pair(alt + _L("Left click"), _L("Remove connector from selection")));
|
||||||
m_shortcuts.push_back(std::make_pair(ctrl + "A", _L("Select all connectors")));
|
m_shortcuts.push_back(std::make_pair(ctrl + "A", _L("Select all connectors")));
|
||||||
|
|
||||||
@ -1214,7 +1224,7 @@ bool GLGizmoCut3D::update_bb()
|
|||||||
on_unregister_raycasters_for_picking();
|
on_unregister_raycasters_for_picking();
|
||||||
|
|
||||||
if (CommonGizmosDataObjects::SelectionInfo* selection = m_c->selection_info()) {
|
if (CommonGizmosDataObjects::SelectionInfo* selection = m_c->selection_info()) {
|
||||||
m_selected.clear();
|
clear_selection();
|
||||||
m_selected.resize(selection->model_object()->cut_connectors.size(), false);
|
m_selected.resize(selection->model_object()->cut_connectors.size(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1235,6 +1245,8 @@ void GLGizmoCut3D::init_picking_models()
|
|||||||
m_sphere.model.init_from(its);
|
m_sphere.model.init_from(its);
|
||||||
m_sphere.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
m_sphere.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
||||||
}
|
}
|
||||||
|
if (m_shapes.empty())
|
||||||
|
init_connector_shapes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::init_rendering_items()
|
void GLGizmoCut3D::init_rendering_items()
|
||||||
@ -1335,6 +1347,7 @@ void GLGizmoCut3D::unselect_all_connectors()
|
|||||||
{
|
{
|
||||||
std::fill(m_selected.begin(), m_selected.end(), false);
|
std::fill(m_selected.begin(), m_selected.end(), false);
|
||||||
m_selected_count = 0;
|
m_selected_count = 0;
|
||||||
|
validate_connector_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::select_all_connectors()
|
void GLGizmoCut3D::select_all_connectors()
|
||||||
@ -1361,6 +1374,8 @@ void GLGizmoCut3D::apply_selected_connectors(std::function<void(size_t idx)> app
|
|||||||
for (size_t idx = 0; idx < m_selected.size(); idx++)
|
for (size_t idx = 0; idx < m_selected.size(); idx++)
|
||||||
if (m_selected[idx])
|
if (m_selected[idx])
|
||||||
apply_fn(idx);
|
apply_fn(idx);
|
||||||
|
|
||||||
|
update_raycasters_for_picking_transform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
||||||
@ -1400,14 +1415,18 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
|||||||
|
|
||||||
if (render_slider_double_input(_u8L("Depth ratio"), m_connector_depth_ratio, m_connector_depth_ratio_tolerance))
|
if (render_slider_double_input(_u8L("Depth ratio"), m_connector_depth_ratio, m_connector_depth_ratio_tolerance))
|
||||||
apply_selected_connectors([this, &connectors](size_t idx) {
|
apply_selected_connectors([this, &connectors](size_t idx) {
|
||||||
connectors[idx].height = float(m_connector_depth_ratio);
|
if (m_connector_depth_ratio > 0)
|
||||||
connectors[idx].height_tolerance = 0.01f * float(m_connector_depth_ratio_tolerance);
|
connectors[idx].height = m_connector_depth_ratio;
|
||||||
|
if (m_connector_depth_ratio_tolerance >= 0)
|
||||||
|
connectors[idx].height_tolerance = m_connector_depth_ratio_tolerance;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (render_slider_double_input(_u8L("Size"), m_connector_size, m_connector_size_tolerance))
|
if (render_slider_double_input(_u8L("Size"), m_connector_size, m_connector_size_tolerance))
|
||||||
apply_selected_connectors([this, &connectors](size_t idx) {
|
apply_selected_connectors([this, &connectors](size_t idx) {
|
||||||
connectors[idx].radius = float(m_connector_size * 0.5);
|
if (m_connector_size > 0)
|
||||||
connectors[idx].radius_tolerance = 0.01f * float(m_connector_size_tolerance);
|
connectors[idx].radius = 0.5f * m_connector_size;
|
||||||
|
if (m_connector_size_tolerance >= 0)
|
||||||
|
connectors[idx].radius_tolerance = m_connector_size_tolerance;
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
@ -1529,25 +1548,83 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
|||||||
m_imgui->disabled_end();
|
m_imgui->disabled_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoCut3D::validate_connector_settings()
|
||||||
|
{
|
||||||
|
if (m_connector_depth_ratio < 0.f)
|
||||||
|
m_connector_depth_ratio = 3.f;
|
||||||
|
if (m_connector_depth_ratio_tolerance < 0.f)
|
||||||
|
m_connector_depth_ratio_tolerance = 0.1f;
|
||||||
|
if (m_connector_size < 0.f)
|
||||||
|
m_connector_size = 2.5f;
|
||||||
|
if (m_connector_size_tolerance < 0.f)
|
||||||
|
m_connector_size_tolerance = 0.f;
|
||||||
|
|
||||||
|
if (m_connector_type == CutConnectorType::Undef)
|
||||||
|
m_connector_type = CutConnectorType::Plug;
|
||||||
|
if (m_connector_style == size_t(CutConnectorStyle::Undef))
|
||||||
|
m_connector_style = size_t(CutConnectorStyle::Prizm);
|
||||||
|
if (m_connector_shape_id == size_t(CutConnectorShape::Undef))
|
||||||
|
m_connector_shape_id = size_t(CutConnectorShape::Circle);
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors)
|
void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors)
|
||||||
{
|
{
|
||||||
m_imperial_units = wxGetApp().app_config->get("use_inches") == "1";
|
m_imperial_units = wxGetApp().app_config->get("use_inches") == "1";
|
||||||
m_label_width = m_imgui->get_style_scaling() * 100.0f;
|
m_label_width = m_imgui->get_font_size() * 6.f;
|
||||||
m_control_width = m_imgui->get_style_scaling() * 150.0f;
|
m_control_width = m_imgui->get_font_size() * 9.f;
|
||||||
|
|
||||||
if (m_selected_count == 1)
|
if (m_connectors_editing && m_selected_count > 0) {
|
||||||
|
float depth_ratio { UndefFloat };
|
||||||
|
float depth_ratio_tolerance { UndefFloat };
|
||||||
|
float radius { UndefFloat };
|
||||||
|
float radius_tolerance { UndefFloat };
|
||||||
|
CutConnectorType type { CutConnectorType::Undef };
|
||||||
|
CutConnectorStyle style { CutConnectorStyle::Undef };
|
||||||
|
CutConnectorShape shape { CutConnectorShape::Undef };
|
||||||
|
|
||||||
|
bool is_init = false;
|
||||||
for (size_t idx = 0; idx < m_selected.size(); idx++)
|
for (size_t idx = 0; idx < m_selected.size(); idx++)
|
||||||
if (m_selected[idx]) {
|
if (m_selected[idx]) {
|
||||||
auto&connector = connectors[idx];
|
const CutConnector& connector = connectors[idx];
|
||||||
m_connector_depth_ratio = connector.height;
|
if (!is_init) {
|
||||||
m_connector_depth_ratio_tolerance = 100 * connector.height_tolerance;
|
depth_ratio = connector.height;
|
||||||
m_connector_size = 2. * connector.radius;
|
depth_ratio_tolerance = connector.height_tolerance;
|
||||||
m_connector_size_tolerance = 100 * connector.radius_tolerance;
|
radius = connector.radius;
|
||||||
m_connector_type = connector.attribs.type;
|
radius_tolerance = connector.radius_tolerance;
|
||||||
m_connector_style = size_t(connector.attribs.style);
|
type = connector.attribs.type;
|
||||||
m_connector_shape_id = size_t(connector.attribs.shape);
|
style = connector.attribs.style;
|
||||||
|
shape = connector.attribs.shape;
|
||||||
|
|
||||||
|
if (m_selected_count == 1)
|
||||||
break;
|
break;
|
||||||
|
is_init = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!is_approx(depth_ratio, connector.height))
|
||||||
|
depth_ratio = UndefFloat;
|
||||||
|
if (!is_approx(depth_ratio_tolerance, connector.height_tolerance))
|
||||||
|
depth_ratio_tolerance = UndefFloat;
|
||||||
|
if (!is_approx(radius,connector.radius))
|
||||||
|
radius = UndefFloat;
|
||||||
|
if (!is_approx(radius_tolerance, connector.radius_tolerance))
|
||||||
|
radius_tolerance = UndefFloat;
|
||||||
|
|
||||||
|
if (type != connector.attribs.type)
|
||||||
|
type = CutConnectorType::Undef;
|
||||||
|
if (style != connector.attribs.style)
|
||||||
|
style = CutConnectorStyle::Undef;
|
||||||
|
if (shape != connector.attribs.shape)
|
||||||
|
shape = CutConnectorShape::Undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_connector_depth_ratio = depth_ratio;
|
||||||
|
m_connector_depth_ratio_tolerance = depth_ratio_tolerance;
|
||||||
|
m_connector_size = 2.f * radius;
|
||||||
|
m_connector_size_tolerance = radius_tolerance;
|
||||||
|
m_connector_type = type;
|
||||||
|
m_connector_style = size_t(style);
|
||||||
|
m_connector_shape_id = size_t(shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,7 +1698,7 @@ void GLGizmoCut3D::render_connectors()
|
|||||||
const CutConnectors& connectors = mo->cut_connectors;
|
const CutConnectors& connectors = mo->cut_connectors;
|
||||||
if (connectors.size() != m_selected.size()) {
|
if (connectors.size() != m_selected.size()) {
|
||||||
// #ysFIXME
|
// #ysFIXME
|
||||||
m_selected.clear();
|
clear_selection();
|
||||||
m_selected.resize(connectors.size(), false);
|
m_selected.resize(connectors.size(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1699,7 +1776,7 @@ bool GLGizmoCut3D::can_perform_cut() const
|
|||||||
void GLGizmoCut3D::apply_connectors_in_model(ModelObject* mo, const bool has_connectors, bool &create_dowels_as_separate_object)
|
void GLGizmoCut3D::apply_connectors_in_model(ModelObject* mo, const bool has_connectors, bool &create_dowels_as_separate_object)
|
||||||
{
|
{
|
||||||
if (has_connectors && m_connector_mode == CutConnectorMode::Manual) {
|
if (has_connectors && m_connector_mode == CutConnectorMode::Manual) {
|
||||||
m_selected.clear();
|
clear_selection();
|
||||||
|
|
||||||
for (CutConnector&connector : mo->cut_connectors) {
|
for (CutConnector&connector : mo->cut_connectors) {
|
||||||
connector.rotation_m = m_rotation_m;
|
connector.rotation_m = m_rotation_m;
|
||||||
@ -1810,21 +1887,34 @@ bool GLGizmoCut3D::unproject_on_cut_plane(const Vec2d& mouse_position, std::pair
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoCut3D::clear_selection()
|
||||||
|
{
|
||||||
|
m_selected.clear();
|
||||||
|
m_selected_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::reset_connectors()
|
void GLGizmoCut3D::reset_connectors()
|
||||||
{
|
{
|
||||||
m_c->selection_info()->model_object()->cut_connectors.clear();
|
m_c->selection_info()->model_object()->cut_connectors.clear();
|
||||||
update_model_object();
|
update_model_object();
|
||||||
m_selected.clear();
|
clear_selection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoCut3D::init_connector_shapes()
|
||||||
|
{
|
||||||
|
for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug})
|
||||||
|
for (const CutConnectorStyle& style : {CutConnectorStyle::Frustum, CutConnectorStyle::Prizm})
|
||||||
|
for (const CutConnectorShape& shape : {CutConnectorShape::Circle, CutConnectorShape::Hexagon, CutConnectorShape::Square, CutConnectorShape::Triangle}) {
|
||||||
|
const CutConnectorAttributes attribs = { type, style, shape };
|
||||||
|
const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
|
||||||
|
m_shapes[attribs].model.init_from(its);
|
||||||
|
m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::update_connector_shape()
|
void GLGizmoCut3D::update_connector_shape()
|
||||||
{
|
{
|
||||||
CutConnectorAttributes attribs = { m_connector_type, CutConnectorStyle(m_connector_style), CutConnectorShape(m_connector_shape_id) };
|
CutConnectorAttributes attribs = { m_connector_type, CutConnectorStyle(m_connector_style), CutConnectorShape(m_connector_shape_id) };
|
||||||
if (m_shapes.find(attribs) == m_shapes.end()) {
|
|
||||||
const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
|
|
||||||
m_shapes[attribs].model.init_from(its);
|
|
||||||
m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));;
|
|
||||||
}
|
|
||||||
|
|
||||||
const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
|
const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
|
||||||
m_connector_mesh.clear();
|
m_connector_mesh.clear();
|
||||||
@ -1913,15 +2003,16 @@ bool GLGizmoCut3D::add_connector(CutConnectors& connectors, const Vec2d& mouse_p
|
|||||||
if (m_connectors_editing) {
|
if (m_connectors_editing) {
|
||||||
|
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"), UndoRedo::SnapshotType::GizmoAction);
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add connector"), UndoRedo::SnapshotType::GizmoAction);
|
||||||
|
unselect_all_connectors();
|
||||||
|
|
||||||
connectors.emplace_back(hit, m_rotation_m,
|
connectors.emplace_back(hit, m_rotation_m,
|
||||||
float(m_connector_size) * 0.5f, float(m_connector_depth_ratio),
|
m_connector_size * 0.5f, m_connector_depth_ratio,
|
||||||
float(m_connector_size_tolerance) * 0.01f, float(m_connector_depth_ratio_tolerance) * 0.01f,
|
m_connector_size_tolerance, m_connector_depth_ratio_tolerance,
|
||||||
CutConnectorAttributes( CutConnectorType(m_connector_type),
|
CutConnectorAttributes( CutConnectorType(m_connector_type),
|
||||||
CutConnectorStyle(m_connector_style),
|
CutConnectorStyle(m_connector_style),
|
||||||
CutConnectorShape(m_connector_shape_id)));
|
CutConnectorShape(m_connector_shape_id)));
|
||||||
unselect_all_connectors();
|
|
||||||
m_selected.push_back(true);
|
m_selected.push_back(true);
|
||||||
|
m_selected_count = 1;
|
||||||
assert(m_selected.size() == connectors.size());
|
assert(m_selected.size() == connectors.size());
|
||||||
update_model_object();
|
update_model_object();
|
||||||
m_parent.set_as_dirty();
|
m_parent.set_as_dirty();
|
||||||
@ -1951,6 +2042,7 @@ bool GLGizmoCut3D::delete_selected_connectors(CutConnectors& connectors)
|
|||||||
// remove selections
|
// remove selections
|
||||||
m_selected.erase(std::remove_if(m_selected.begin(), m_selected.end(), [](const auto& selected) {
|
m_selected.erase(std::remove_if(m_selected.begin(), m_selected.end(), [](const auto& selected) {
|
||||||
return selected; }), m_selected.end());
|
return selected; }), m_selected.end());
|
||||||
|
m_selected_count = 0;
|
||||||
|
|
||||||
assert(m_selected.size() == connectors.size());
|
assert(m_selected.size() == connectors.size());
|
||||||
update_model_object();
|
update_model_object();
|
||||||
@ -1967,13 +2059,13 @@ void GLGizmoCut3D::select_connector(int idx, bool select)
|
|||||||
--m_selected_count;
|
--m_selected_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoCut3D::is_selection_changed(bool alt_down, bool control_down)
|
bool GLGizmoCut3D::is_selection_changed(bool alt_down, bool shift_down)
|
||||||
{
|
{
|
||||||
if (m_hover_id >= m_connectors_group_id) {
|
if (m_hover_id >= m_connectors_group_id) {
|
||||||
if (alt_down)
|
if (alt_down)
|
||||||
select_connector(m_hover_id - m_connectors_group_id, false);
|
select_connector(m_hover_id - m_connectors_group_id, false);
|
||||||
else {
|
else {
|
||||||
if (!control_down)
|
if (!shift_down)
|
||||||
unselect_all_connectors();
|
unselect_all_connectors();
|
||||||
select_connector(m_hover_id - m_connectors_group_id, true);
|
select_connector(m_hover_id - m_connectors_group_id, true);
|
||||||
}
|
}
|
||||||
@ -2027,14 +2119,17 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
|
|||||||
}
|
}
|
||||||
else
|
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 && !shift_down && !alt_down)
|
||||||
if (!add_connector(connectors, mouse_position))
|
if (!add_connector(connectors, mouse_position))
|
||||||
unselect_all_connectors();
|
m_ldown_mouse_position = mouse_position;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == SLAGizmoEventType::LeftUp && !shift_down)
|
if (action == SLAGizmoEventType::LeftUp) {
|
||||||
return is_selection_changed(alt_down, control_down);
|
if ((m_ldown_mouse_position - mouse_position).norm() < 5.)
|
||||||
|
unselect_all_connectors();
|
||||||
|
return is_selection_changed(alt_down, shift_down);
|
||||||
|
}
|
||||||
|
|
||||||
// left up with selection rectangle - select points inside the rectangle:
|
// 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()) {
|
if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::ShiftUp || action == SLAGizmoEventType::AltUp) && m_selection_rectangle.is_dragging()) {
|
||||||
|
@ -55,6 +55,8 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||||||
Vec3d m_line_beg{ Vec3d::Zero() };
|
Vec3d m_line_beg{ Vec3d::Zero() };
|
||||||
Vec3d m_line_end{ Vec3d::Zero() };
|
Vec3d m_line_end{ Vec3d::Zero() };
|
||||||
|
|
||||||
|
Vec2d m_ldown_mouse_position{ Vec2d::Zero() };
|
||||||
|
|
||||||
GLModel m_plane;
|
GLModel m_plane;
|
||||||
GLModel m_grabber_connection;
|
GLModel m_grabber_connection;
|
||||||
GLModel m_cut_line;
|
GLModel m_cut_line;
|
||||||
@ -82,11 +84,11 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||||||
bool m_hide_cut_plane{ false };
|
bool m_hide_cut_plane{ false };
|
||||||
bool m_connectors_editing{ false };
|
bool m_connectors_editing{ false };
|
||||||
|
|
||||||
double m_connector_depth_ratio{ 3.0 };
|
float m_connector_depth_ratio{ 3.f };
|
||||||
double m_connector_size{ 2.5 };
|
float m_connector_size{ 2.5f };
|
||||||
|
|
||||||
int m_connector_depth_ratio_tolerance{ 10 };
|
float m_connector_depth_ratio_tolerance{ 0.1f };
|
||||||
int m_connector_size_tolerance{ 0 };
|
float m_connector_size_tolerance{ 0.f };
|
||||||
|
|
||||||
float m_label_width{ 150.0 };
|
float m_label_width{ 150.0 };
|
||||||
float m_control_width{ 200.0 };
|
float m_control_width{ 200.0 };
|
||||||
@ -194,7 +196,7 @@ protected:
|
|||||||
bool add_connector(CutConnectors&connectors, const Vec2d&mouse_position);
|
bool add_connector(CutConnectors&connectors, const Vec2d&mouse_position);
|
||||||
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 shift_down);
|
||||||
void process_selection_rectangle(CutConnectors &connectors);
|
void process_selection_rectangle(CutConnectors &connectors);
|
||||||
|
|
||||||
virtual void on_register_raycasters_for_picking() override;
|
virtual void on_register_raycasters_for_picking() override;
|
||||||
@ -214,7 +216,7 @@ private:
|
|||||||
void set_center(const Vec3d& center);
|
void set_center(const Vec3d& center);
|
||||||
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
||||||
bool render_double_input(const std::string& label, double& value_in);
|
bool render_double_input(const std::string& label, double& value_in);
|
||||||
bool render_slider_double_input(const std::string& label, double& value_in, int& tolerance_in);
|
bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in);
|
||||||
void render_move_center_input(int axis);
|
void render_move_center_input(int axis);
|
||||||
void render_connect_mode_radio_button(CutConnectorMode mode);
|
void render_connect_mode_radio_button(CutConnectorMode mode);
|
||||||
bool render_reset_button(const std::string& label_id, const std::string& tooltip) const;
|
bool render_reset_button(const std::string& label_id, const std::string& tooltip) const;
|
||||||
@ -240,8 +242,11 @@ private:
|
|||||||
void init_picking_models();
|
void init_picking_models();
|
||||||
void init_rendering_items();
|
void init_rendering_items();
|
||||||
void render_clipper_cut();
|
void render_clipper_cut();
|
||||||
|
void clear_selection();
|
||||||
void reset_connectors();
|
void reset_connectors();
|
||||||
|
void init_connector_shapes();
|
||||||
void update_connector_shape();
|
void update_connector_shape();
|
||||||
|
void validate_connector_settings();
|
||||||
void update_model_object();
|
void update_model_object();
|
||||||
bool process_cut_line(SLAGizmoEventType action, const Vec2d& mouse_position);
|
bool process_cut_line(SLAGizmoEventType action, const Vec2d& mouse_position);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user