From 07d455a12566f0c37fe6d58c8c5eb7a5382ba7b2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 11 Jul 2022 09:11:06 +0200 Subject: [PATCH] Cut WIP: some UI improvements + partially reverted https://github.com/prusa3d/PrusaSlicer/commit/63890b5f8d352d3ef1228fa00b0d3932717f933d --- src/slic3r/GUI/GLCanvas3D.cpp | 10 ++- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GUI_ObjectList.cpp | 5 ++ src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 4 ++ src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 84 ++++++++++++++++++------- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 6 +- 7 files changed, 84 insertions(+), 28 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3a5c89beaa..cbf1a61d4e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1382,6 +1382,8 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) && (mv == nullptr || m_model->objects[vol->composite_id.object_id]->volumes[vol->composite_id.volume_id] == mv)) { vol->is_active = visible; + if (!vol->is_modifier) + vol->color.a(1.f); if (instance_idx == -1) { vol->force_native_color = false; @@ -1390,9 +1392,13 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject const GLGizmosManager& gm = get_gizmos_manager(); auto gizmo_type = gm.get_current_type(); if ( (gizmo_type == GLGizmosManager::FdmSupports - || gizmo_type == GLGizmosManager::Seam) - && ! vol->is_modifier) + || gizmo_type == GLGizmosManager::Seam + || gizmo_type == GLGizmosManager::Cut) + && ! vol->is_modifier) { vol->force_neutral_color = true; + if (gizmo_type == GLGizmosManager::Cut) + vol->color.a(0.95f); + } else if (gizmo_type == GLGizmosManager::MmuSegmentation) vol->is_active = false; else diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a5b2acb32d..b761deaa67 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -855,6 +855,7 @@ public: Linef3 mouse_ray(const Point& mouse_pos); bool is_mouse_dragging() const { return m_mouse.dragging; } + void set_mouse_as_dragging() { m_mouse.dragging = true; } double get_size_proportional_to_max_bed_size(double factor) const; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2c1ee7a6c2..3b5af8cd93 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -11,6 +11,7 @@ #include "GalleryDialog.hpp" #include "MainFrame.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "Gizmos/GLGizmoCut.hpp" #include "OptionsGroup.hpp" #include "Tab.hpp" @@ -2579,6 +2580,10 @@ void ObjectList::part_selection_changed() GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager(); if (gizmos_mgr.get_current_type() != gizmo_type) gizmos_mgr.open_gizmo(gizmo_type); + if (info_type == InfoItemType::Cut) { + GLGizmoCut3D* cut = dynamic_cast(gizmos_mgr.get_current()); + cut->set_connectors_editing(); + } break; } case InfoItemType::Sinking: { break; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 6ddb804d4e..ced04197db 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -318,6 +318,9 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) { on_start_dragging(); + // prevent change of hover_id during dragging + m_parent.set_mouse_as_dragging(); + // Let the plater know that the dragging started m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED)); m_parent.set_as_dirty(); @@ -327,6 +330,7 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) { // when mouse cursor leave window than finish actual dragging operation bool is_leaving = mouse_event.Leaving(); if (mouse_event.Dragging()) { + m_parent.set_mouse_as_dragging(); Point mouse_coord(mouse_event.GetX(), mouse_event.GetY()); auto ray = m_parent.mouse_ray(mouse_coord); UpdateData data(ray, mouse_coord); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 972598b737..8cf7ab42f3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -302,6 +302,30 @@ bool GLGizmoCut3D::render_double_input(const std::string& label, double& value_i return old_val != value; } +bool GLGizmoCut3D::render_slicer_double_input(const std::string& label, double& value_in) +{ + ImGui::AlignTextToFramePadding(); + m_imgui->text(label); + ImGui::SameLine(m_label_width); + ImGui::PushItemWidth(m_control_width); + + float value = (float)value_in; + if (m_imperial_units) + value *= ObjectManipulation::mm_to_in; + float old_val = value; + + const BoundingBoxf3 bbox = bounding_box(); + const float mean_size = float((bbox.size().x() + bbox.size().y() + bbox.size().z()) / 9.0); + + m_imgui->slider_float(("##" + label).c_str(), &value, 1.0f, mean_size); + + ImGui::SameLine(); + m_imgui->text(m_imperial_units ? _L("in") : _L("mm")); + + value_in = (double)(value * (m_imperial_units ? ObjectManipulation::in_to_mm : 1.0)); + return old_val != value; +} + void GLGizmoCut3D::render_move_center_input(int axis) { ImGui::AlignTextToFramePadding(); @@ -511,23 +535,26 @@ void GLGizmoCut3D::render_cut_center_graber() const Transform3d view_matrix = camera.get_view_matrix() * graber.matrix * Geometry::assemble_transform(center, angles); - Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), size * Vec3d::Ones()); - - shader->set_uniform("view_model_matrix", view_model_matrix); - shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); - m_sphere.render(); - const BoundingBoxf3 tbb = transformed_bounding_box(); - if (tbb.max.z() >= 0.0) { - view_model_matrix = view_matrix * Geometry::assemble_transform(offset, Vec3d::Zero(), scale); + + if (tbb.min.z() <= 0.0) { + Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(-offset, PI * Vec3d::UnitX(), scale); shader->set_uniform("view_model_matrix", view_model_matrix); shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); m_cone.render(); } - if (tbb.min.z() <= 0.0) { - view_model_matrix = view_matrix * Geometry::assemble_transform(-offset, PI * Vec3d::UnitX(), scale); + { + Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), size * Vec3d::Ones()); + + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); + m_sphere.render(); + } + + if (tbb.max.z() >= 0.0) { + Transform3d view_model_matrix = view_matrix * Geometry::assemble_transform(offset, Vec3d::Zero(), scale); shader->set_uniform("view_model_matrix", view_model_matrix); shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); @@ -892,7 +919,7 @@ void GLGizmoCut3D::on_render() render_cut_center_graber(); render_cut_plane(); if (m_hover_id < m_group_id && m_mode == size_t(CutMode::cutPlanar) && !cut_line_processing()) - m_rotation_gizmo.render(); + m_rotation_gizmo.render(); } render_cut_line(); @@ -950,13 +977,25 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) double top = (tbb.min.z() <= 0.0 ? tbb.max.z() : tbb.size().z()) * koef; double bottom = (tbb.max.z() <= 0.0 ? tbb.size().z() : (tbb.min.z() * (-1))) * koef; + Vec3d tbb_sz = tbb.size(); + wxString size = "X: " + double_to_string(tbb_sz.x() * koef, 2) + unit_str + + ", Y: " + double_to_string(tbb_sz.y() * koef, 2) + unit_str + + ", Z: " + double_to_string(tbb_sz.z() * koef, 2) + unit_str; + + ImGui::AlignTextToFramePadding(); + m_imgui->text(_L("Build size")); + ImGui::SameLine(m_label_width); + m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, size); + //static float v = 0.; // TODO: connect to cutting plane position m_imgui->text(_L("Cut position: ")); render_move_center_input(Z); //m_imgui->input_double(unit_str, v); //v = std::clamp(v, 0.f, float(bottom+top)); if (m_imgui->button("Reset cutting plane")) { - // TODO: reset both position and rotation + set_center(bounding_box().center()); + m_rotation_gizmo.set_rotation(Vec3d::Zero()); + update_clipper(); } ////// @@ -1015,7 +1054,7 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) ImGui::SameLine(); m_imgui->disabled_begin(!m_keep_upper); m_imgui->disabled_begin(is_approx(m_rotation_gizmo.get_rotation().x(), 0.) && is_approx(m_rotation_gizmo.get_rotation().y(), 0.)); - m_imgui->checkbox(_L("Place on cut") + "##upper", m_rotate_upper); + m_imgui->checkbox(_L("Place on cut") + "##upper", m_rotate_upper); // #ysTODO implement place on cut instead of Flip? m_imgui->disabled_end(); m_imgui->disabled_end(); @@ -1029,7 +1068,7 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) m_imgui->disabled_end(); ImGui::SameLine(); m_imgui->disabled_begin(!m_keep_lower); - m_imgui->checkbox(_L("Place on cut") + "##lower", m_rotate_lower); + m_imgui->checkbox(_L("Place on cut") + "##lower", m_rotate_lower); // #ysTODO implement place on cut instead of Flip? m_imgui->disabled_end(); } @@ -1064,17 +1103,19 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) if (render_combo(_u8L("Shape"), m_connector_shapes, m_connector_shape_id)) update_connector_shape(); - if (render_double_input(_u8L("Depth ratio"), m_connector_depth_ratio)) + if (render_slicer_double_input(_u8L("Depth ratio"), m_connector_depth_ratio)) for (auto& connector : connectors) connector.height = float(m_connector_depth_ratio); - if (render_double_input(_u8L("Size"), m_connector_size)) + if (render_slicer_double_input(_u8L("Size"), m_connector_size)) for (auto& connector : connectors) connector.radius = float(m_connector_size * 0.5); m_imgui->disabled_end(); - if (m_imgui->button(_L("Confirm connectors"))) + if (m_imgui->button(_L("Confirm connectors"))) { + m_clp_normal = m_c->object_clipper()->get_clipping_plane()->get_normal(); m_connectors_editing = false; + } } ImGui::Separator(); @@ -1111,7 +1152,7 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) } } -// get volume transformation regarding to the "border". Border is related from the siae of connectors +// get volume transformation regarding to the "border". Border is related from the size of connectors Transform3d GLGizmoCut3D::get_volume_transformation(const ModelVolume* volume) const { bool is_prizm_dowel = m_connector_type == CutConnectorType::Dowel && m_connector_style == size_t(CutConnectorStyle::Prizm); @@ -1141,10 +1182,7 @@ void GLGizmoCut3D::render_connectors(bool picking) if (picking && ! m_connectors_editing) return; - const bool depth_test = m_connectors_editing; - if (! depth_test) - ::glDisable(GL_DEPTH_TEST); - Slic3r::ScopeGuard guard_depth_test([&](){ if (! depth_test) ::glEnable(GL_DEPTH_TEST); }); + ::glEnable(GL_DEPTH_TEST); if (cut_line_processing() || m_connector_mode == CutConnectorMode::Auto || !m_c->selection_info()) return; @@ -1225,7 +1263,7 @@ void GLGizmoCut3D::render_connectors(bool picking) 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); + 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); break; } render_color = ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index dfaef3fb23..76ec2f7ba4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -124,6 +124,7 @@ public: void put_connetors_on_cut_plane(const Vec3d& cp_normal, double cp_offset); void update_clipper(); void update_clipper_on_render(); + void set_connectors_editing() { m_connectors_editing = true; } BoundingBoxf3 bounding_box() const; BoundingBoxf3 transformed_bounding_box(bool revert_move = false) const; @@ -153,6 +154,7 @@ private: void set_center(const Vec3d& center); bool render_combo(const std::string& label, const std::vector& lines, size_t& selection_idx); bool render_double_input(const std::string& label, double& value_in); + bool render_slicer_double_input(const std::string& label, double& value_in); void render_move_center_input(int axis); void render_rotation_input(int axis); void render_connect_mode_radio_button(CutConnectorMode mode); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 9e2f9e08b7..d82fbd587d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -301,13 +301,13 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection) coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); if (coordinates_type == ECoordinatesType::World) { m_bounding_box = selection.get_bounding_box(); - m_center = m_bounding_box.center(); + m_center = m_has_forced_center ? m_forced_center : m_bounding_box.center(); } else if (coordinates_type == ECoordinatesType::Local && selection.is_single_volume_or_modifier()) { const GLVolume& v = *selection.get_first_volume(); m_bounding_box = v.transformed_convex_hull_bounding_box( v.get_instance_transformation().get_scaling_factor_matrix() * v.get_volume_transformation().get_scaling_factor_matrix()); - m_center = v.world_matrix() * m_bounding_box.center(); + m_center = v.world_matrix() * (m_has_forced_center ? m_forced_center : m_bounding_box.center()); } else { m_bounding_box.reset(); @@ -318,7 +318,7 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection) } const Geometry::Transformation inst_trafo = selection.get_first_volume()->get_instance_transformation(); m_bounding_box = m_bounding_box.transformed(inst_trafo.get_scaling_factor_matrix()); - m_center = inst_trafo.get_matrix_no_scaling_factor() * m_bounding_box.center(); + m_center = inst_trafo.get_matrix_no_scaling_factor() * (m_has_forced_center ? m_forced_center : m_bounding_box.center()); } m_radius = Offset + m_bounding_box.radius();