From 90136d3ad363d844302c040b5ff6d1a0790838dc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 23 Oct 2024 10:23:00 +0200 Subject: [PATCH] Camera + shading Zoom to bed command set to zoom to active bed Added camera rotation pivot which is updated whenever the active bed changes SPE-2506 - Follow up of a2873759aba1eb13a31591d9e852be0f1e21786b - Fixed camera position after zoom to bed --- src/slic3r/GUI/Camera.cpp | 13 ++++++++----- src/slic3r/GUI/Camera.hpp | 4 ++++ src/slic3r/GUI/GLCanvas3D.cpp | 28 +++++++++++++++++++++------- src/slic3r/GUI/GLCanvas3D.hpp | 1 + 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 62ce8ea3ac..385d2966a7 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -60,7 +60,10 @@ void Camera::set_target(const Vec3d& target) const Vec3d new_displacement = new_target - m_target; if (!new_displacement.isApprox(Vec3d::Zero())) { m_target = new_target; - m_view_matrix.translate(-new_displacement); + Transform3d inv_view_matrix = m_view_matrix.inverse(); + inv_view_matrix.translation() = m_target - m_distance * get_dir_forward(); + m_view_matrix = inv_view_matrix.inverse(); + m_rotation_pivot = m_target; } } @@ -347,11 +350,11 @@ void Camera::rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad, b } } - const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target; + const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_rotation_pivot; const auto rot_z = Eigen::AngleAxisd(delta_azimut_rad, Vec3d::UnitZ()); m_view_rotation *= rot_z * Eigen::AngleAxisd(delta_zenit_rad, rot_z.inverse() * get_dir_right()); m_view_rotation.normalize(); - m_view_matrix.fromPositionOrientationScale(m_view_rotation * (- m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.)); + m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_rotation_pivot) + translation, m_view_rotation, Vec3d(1., 1., 1.)); } // Virtual trackball, rotate around an axis, where the eucledian norm of the axis gives the rotation angle in radians. @@ -359,11 +362,11 @@ void Camera::rotate_local_around_target(const Vec3d& rotation_rad) { const double angle = rotation_rad.norm(); if (std::abs(angle) > EPSILON) { - const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target; + const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_rotation_pivot; const Vec3d axis = m_view_rotation.conjugate() * rotation_rad.normalized(); m_view_rotation *= Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)); m_view_rotation.normalize(); - m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.)); + m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_rotation_pivot) + translation, m_view_rotation, Vec3d(1., 1., 1.)); update_zenit(); } } diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 10d6d68b70..3117c6f3bb 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -36,6 +36,7 @@ private: EType m_type{ EType::Perspective }; bool m_update_config_on_type_change_enabled{ false }; Vec3d m_target{ Vec3d::Zero() }; + Vec3d m_rotation_pivot{ Vec3d::Zero() }; float m_zenit{ 45.0f }; double m_zoom{ 1.0 }; // Distance between camera position and camera target measured along the camera Z axis @@ -66,6 +67,9 @@ public: const Vec3d& get_target() const { return m_target; } void set_target(const Vec3d& target); + const Vec3d& get_rotation_pivot() const { return m_rotation_pivot; } + void set_rotation_pivot(const Vec3d& pivot) { m_rotation_pivot = pivot; } + double get_distance() const { return (get_position() - m_target).norm(); } double get_gui_scale() const { return m_gui_scale; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 79189cc094..e4bb744ddc 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1746,8 +1746,10 @@ void GLCanvas3D::enable_layers_editing(bool enable) void GLCanvas3D::zoom_to_bed() { BoundingBoxf3 box = m_bed.build_volume().bounding_volume(); + box.translate(s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed())); box.min.z() = 0.0; box.max.z() = 0.0; + _zoom_to_box(box); } @@ -1839,6 +1841,14 @@ void GLCanvas3D::render() camera.apply_projection(_max_bounding_box(true, true)); + const int curr_active_bed_id = s_multiple_beds.get_active_bed(); + if (m_last_active_bed_id != curr_active_bed_id) { + const Vec3d bed_offset = s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()); + const Vec2d bed_center = m_bed.build_volume().bed_center() + Vec2d(bed_offset.x(), bed_offset.y()); + camera.set_rotation_pivot({ bed_center.x(), bed_center.y(), 0.0f }); + m_last_active_bed_id = curr_active_bed_id; + } + wxGetApp().imgui()->new_frame(); if (m_picking_enabled) { @@ -5923,18 +5933,22 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) m_layers_editing.select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1); if (const BuildVolume &build_volume = m_bed.build_volume(); build_volume.valid()) { - switch (build_volume.type()) { + const Vec3d bed_offset = s_multiple_beds.get_bed_translation(s_multiple_beds.get_active_bed()); + switch (build_volume.type()) { case BuildVolume::Type::Rectangle: { const BoundingBox3Base bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon); - m_volumes.set_print_volume({ 0, // circle - { float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) }, - { 0.0f, float(build_volume.max_print_height()) } }); + m_volumes.set_print_volume({ 0, // rectangle + { float(bed_bb.min.x() + bed_offset.x()), float(bed_bb.min.y() + bed_offset.y()), + float(bed_bb.max.x() + bed_offset.x()), float(bed_bb.max.y() + bed_offset.y()) }, + { float(0.0 + bed_offset.z()), float(build_volume.max_print_height() + bed_offset.z()) } }); break; } case BuildVolume::Type::Circle: { - m_volumes.set_print_volume({ 1, // rectangle - { unscaled(build_volume.circle().center.x()), unscaled(build_volume.circle().center.y()), unscaled(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f }, - { 0.0f, float(build_volume.max_print_height() + BuildVolume::SceneEpsilon) } }); + m_volumes.set_print_volume({ 1, // circle + { unscaled(build_volume.circle().center.x() + bed_offset.x()), + unscaled(build_volume.circle().center.y() + bed_offset.y()), + unscaled(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f }, + { float(0.0 + bed_offset.z()), float(build_volume.max_print_height() + bed_offset.z() + BuildVolume::SceneEpsilon) } }); break; } default: diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index bae830f9e2..715997437e 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -486,6 +486,7 @@ private: wxGLContext* m_context; SceneRaycaster m_scene_raycaster; Bed3D &m_bed; + int m_last_active_bed_id{ -1 }; #if ENABLE_RETINA_GL std::unique_ptr m_retina_helper; #endif