diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 84b967e0f..92f45f023 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -575,11 +575,13 @@ void Transformation::reset() void Transformation::reset_rotation() { const Geometry::TransformationSVD svd(*this); m_matrix = get_offset_matrix() * Transform3d(svd.v * svd.s * svd.v.transpose()) * svd.mirror_matrix(); + m_rotation = Vec3d::Zero(); } void Transformation::reset_scaling_factor() { const Geometry::TransformationSVD svd(*this); m_matrix = get_offset_matrix() * Transform3d(svd.u) * Transform3d(svd.v.transpose()) * svd.mirror_matrix(); + m_scaling_factor = Vec3d::Ones(); } void Transformation::reset_skew() { @@ -589,6 +591,8 @@ void Transformation::reset_skew() { const Geometry::TransformationSVD svd(*this); m_matrix = get_offset_matrix() * Transform3d(svd.u) * scale_transform(new_scale_factor(svd.s)) * Transform3d(svd.v.transpose()) * svd.mirror_matrix(); + const Transform3d scale_tran = extract_scale(m_matrix); + m_scaling_factor = {std::abs(scale_tran(0, 0)), std::abs(scale_tran(1, 1)), std::abs(scale_tran(2, 2))}; } const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index f36266a96..67db35a6d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -219,6 +219,42 @@ bool GLGizmoBase::render_combo(const std::string &label, const std::vector &lines, size_t &selection_idx, float label_width, float item_width); - + void render_cross_mark(const Vec3f& target,bool is_single =false); public: GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 8cf5f3abb..47fc9654f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -118,7 +118,7 @@ void GLGizmoMove3D::on_update(const UpdateData& data) void GLGizmoMove3D::on_render() { - const Selection& selection = m_parent.get_selection(); + Selection& selection = m_parent.get_selection(); glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -126,6 +126,9 @@ void GLGizmoMove3D::on_render() const auto &[box, box_trafo] = selection.get_bounding_box_in_current_reference_system(); m_bounding_box = box; m_center = box_trafo.translation(); + if (m_object_manipulation) { + m_object_manipulation->cs_center = box_trafo.translation(); + } m_orient_matrix = box_trafo; float space_size = 20.f *INV_ZOOM; @@ -179,6 +182,20 @@ void GLGizmoMove3D::on_render() } } glsafe(::glPopMatrix()); + + if (!selection.is_multiple_full_object()) { + glsafe(::glPushMatrix()); + Geometry::Transformation cur_tran; + if (auto mi = m_parent.get_selection().get_selected_single_intance()) { + cur_tran = mi->get_transformation(); + } + else { + cur_tran = selection.get_first_volume()->get_instance_transformation(); + } + glsafe(::glMultMatrixd(cur_tran.get_matrix().data())); + render_cross_mark(Vec3f::Zero(), true); + glsafe(::glPopMatrix()); + } } void GLGizmoMove3D::on_render_for_picking() @@ -288,13 +305,13 @@ void GLGizmoMove3D::change_cs_by_selection() { } m_last_selected_obejct_idx = obejct_idx; m_last_selected_volume_idx = volume_idx; - if (m_parent.get_selection().is_multiple_full_instance() || m_parent.get_selection().is_single_full_instance()) { + if (m_parent.get_selection().is_multiple_full_object()) { m_object_manipulation->set_use_object_cs(false); } - else if (model_volume && model_volume->is_model_part()) { - m_object_manipulation->set_use_object_cs(false); + else if (model_volume) { + m_object_manipulation->set_use_object_cs(true); } else { - m_object_manipulation->set_use_object_cs(true); + m_object_manipulation->set_use_object_cs(false); } if (m_object_manipulation->get_use_object_cs()) { m_object_manipulation->set_coordinates_type(ECoordinatesType::Instance); diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 952b00feb..484caa0b9 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -94,7 +94,8 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection) m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.; } else {//if (is_local_coordinates()) {//for scale - m_new_position = Vec3d::Zero(); + auto tran = selection.get_first_volume()->get_instance_transformation(); + m_new_position = tran.get_matrix().inverse() * cs_center; m_new_rotation = volume->get_instance_rotation() * (180. / M_PI); m_new_size = volume->get_instance_transformation().get_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); m_new_scale = volume->get_instance_scaling_factor() * 100.; @@ -619,7 +620,7 @@ bool GizmoObjectManipulation::reset_button(ImGuiWrapper *imgui_wrapper, float ca ImGui::AlignTextToFramePadding(); unsigned int current_active_id = ImGui::GetActiveID(); ImGui::PushItemWidth(caption_max); - if (m_use_object_cs) { + if (!m_glcanvas.get_selection().is_multiple_full_instance() && m_use_object_cs) { imgui_wrapper->text(_L("Object coordinates")); } else { @@ -651,15 +652,16 @@ bool GizmoObjectManipulation::reset_button(ImGuiWrapper *imgui_wrapper, float ca ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size); imgui_wrapper->text(this->m_new_unit_string); bool is_avoid_one_update{false}; - if (bbl_checkbox(_L("Object coordinates"), m_use_object_cs)) { - if (m_use_object_cs) { - set_coordinates_type(ECoordinatesType::Instance); + if (!m_glcanvas.get_selection().is_multiple_full_object()) { + if (bbl_checkbox(_L("Object coordinates"), m_use_object_cs)) { + if (m_use_object_cs) { + set_coordinates_type(ECoordinatesType::Instance); + } else { + set_coordinates_type(ECoordinatesType::World); + } + UpdateAndShow(true); + is_avoid_one_update = true; // avoid update(current_active_id, "position", original_position } - else { - set_coordinates_type(ECoordinatesType::World); - } - UpdateAndShow(true); - is_avoid_one_update = true;//avoid update(current_active_id, "position", original_position } if (!is_avoid_one_update) { diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp index 4f327e6b1..f809b6c19 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp @@ -78,6 +78,7 @@ public: Vec3d m_buffered_rotation; Vec3d m_buffered_scale; Vec3d m_buffered_size; + Vec3d cs_center; bool m_new_enabled {true}; bool m_uniform_scale {true}; // Does the object manipulation panel work in World or Local coordinates? diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 08f11dc8d..59744ef53 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2019,42 +2019,32 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glPushMatrix()); - + Transform3d orient_matrix = Transform3d::Identity(); if (!boost::starts_with(sidebar_field, "layer")) { - const Vec3d& center = get_bounding_box().center(); - + Vec3d center = get_bounding_box().center(); + const auto &[box, box_trafo] = get_bounding_box_in_current_reference_system(); // BBS - if (is_single_full_instance()/* && !wxGetApp().obj_manipul()->get_world_coordinates()*/) { + if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) { + center = box_trafo.translation(); glsafe(::glTranslated(center(0), center(1), center(2))); - if (!boost::starts_with(sidebar_field, "position")) { - Transform3d orient_matrix = Transform3d::Identity(); - if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size")) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::starts_with(sidebar_field, "rotation")) { - if (boost::ends_with(sidebar_field, "x")) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::ends_with(sidebar_field, "y")) { - const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); - if (rotation(0) == 0.0) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else - orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ())); - } + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix(); + glsafe(::glMultMatrixd(orient_matrix.data())); + } else if (is_single_volume_or_modifier()) { + if (!wxGetApp().obj_manipul()->is_world_coordinates()) { + if (wxGetApp().obj_manipul()->is_local_coordinates()) { + orient_matrix = get_bounding_box_in_current_reference_system().second; + orient_matrix.translation() = Vec3d::Zero(); + } else { + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix(); + center = box_trafo.translation(); } - - glsafe(::glMultMatrixd(orient_matrix.data())); } - } else if (is_single_volume() || is_single_modifier()) { glsafe(::glTranslated(center(0), center(1), center(2))); - Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - if (!boost::starts_with(sidebar_field, "position")) - orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true); - glsafe(::glMultMatrixd(orient_matrix.data())); } else { glsafe(::glTranslated(center(0), center(1), center(2))); if (requires_local_axes()) { - const Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix(); glsafe(::glMultMatrixd(orient_matrix.data())); } }