diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index aafc3215a..ce8f651ff 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -714,7 +714,7 @@ int GLVolumeCollection::load_wipe_tower_preview( typedef std::pair GLVolumeWithZ; typedef std::vector GLVolumesWithZList; -static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, std::function filter_func) +static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function filter_func) { GLVolumesWithZList list; list.reserve(volumes.size()); @@ -731,12 +731,9 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum if ((type == GLVolumeCollection::Transparent) && (list.size() > 1)) { - Transform3d modelview_matrix; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data())); - for (GLVolumeWithZ& volume : list) { - volume.second = volume.first->bounding_box.transformed(modelview_matrix * volume.first->world_matrix()).max(2); + volume.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2); } std::sort(list.begin(), list.end(), @@ -747,7 +744,7 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum return list; } -void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function filter_func) const +void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -778,7 +775,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool if (z_range_id != -1) glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range)); - GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func); + GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithZ& volume : to_render) { volume.first->set_render_color(); volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id); @@ -796,7 +793,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool glsafe(::glDisable(GL_BLEND)); } -void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, std::function filter_func) const +void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const { glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -808,7 +805,7 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func); + GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); for (GLVolumeWithZ& volume : to_render) { volume.first->set_render_color(); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index a1dee9e57..d9ae0ec74 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -464,8 +464,8 @@ public: int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width); // Render the volumes by OpenGL. - void render_VBOs(ERenderType type, bool disable_cullface, std::function filter_func = std::function()) const; - void render_legacy(ERenderType type, bool disable_cullface, std::function filter_func = std::function()) const; + void render_VBOs(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const; + void render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const; // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index c748efa64..7a1023e62 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -1,9 +1,21 @@ #include "libslic3r/libslic3r.h" #include "Camera.hpp" +#include "3DScene.hpp" + +#include static const float GIMBALL_LOCK_THETA_MAX = 180.0f; +// phi / theta angles to orient the camera. +static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f }; +static const float VIEW_LEFT[2] = { 90.0f, 90.0f }; +static const float VIEW_RIGHT[2] = { -90.0f, 90.0f }; +static const float VIEW_TOP[2] = { 0.0f, 0.0f }; +static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f }; +static const float VIEW_FRONT[2] = { 0.0f, 90.0f }; +static const float VIEW_REAR[2] = { 180.0f, 90.0f }; + namespace Slic3r { namespace GUI { @@ -57,6 +69,64 @@ void Camera::set_scene_box(const BoundingBoxf3& box) m_scene_box = box; } +bool Camera::select_view(const std::string& direction) +{ + const float* dir_vec = nullptr; + + if (direction == "iso") + dir_vec = VIEW_DEFAULT; + else if (direction == "left") + dir_vec = VIEW_LEFT; + else if (direction == "right") + dir_vec = VIEW_RIGHT; + else if (direction == "top") + dir_vec = VIEW_TOP; + else if (direction == "bottom") + dir_vec = VIEW_BOTTOM; + else if (direction == "front") + dir_vec = VIEW_FRONT; + else if (direction == "rear") + dir_vec = VIEW_REAR; + + if (dir_vec != nullptr) + { + phi = dir_vec[0]; + set_theta(dir_vec[1], false); + return true; + } + else + return false; +} + +void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const +{ + glsafe(::glViewport(0, 0, w, h)); + glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data())); +} + +void Camera::apply_view_matrix() const +{ + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glLoadIdentity()); + + glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch + glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw + glsafe(::glTranslated(-m_target(0), -m_target(1), -m_target(2))); + + glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data())); +} + +void Camera::apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const +{ + glsafe(::glMatrixMode(GL_PROJECTION)); + glsafe(::glLoadIdentity()); + + glsafe(::glOrtho(x_min, x_max, y_min, y_max, z_min, z_max)); + glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data())); + + glsafe(::glMatrixMode(GL_MODELVIEW)); +} + } // GUI } // Slic3r diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index d50dc6e4d..ff2d3aa31 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -26,6 +26,10 @@ private: Vec3d m_target; float m_theta; + mutable std::array m_viewport; + mutable Transform3d m_view_matrix; + mutable Transform3d m_projection_matrix; + BoundingBoxf3 m_scene_box; public: @@ -41,6 +45,22 @@ public: const BoundingBoxf3& get_scene_box() const { return m_scene_box; } void set_scene_box(const BoundingBoxf3& box); + + bool select_view(const std::string& direction); + + const std::array& get_viewport() const { return m_viewport; } + const Transform3d& get_view_matrix() const { return m_view_matrix; } + const Transform3d& get_projection_matrix() const { return m_projection_matrix; } + + Vec3d get_dir_right() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(0); } + Vec3d get_dir_up() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(1); } + Vec3d get_dir_forward() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(2); } + + Vec3d get_position() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(3); } + + void apply_viewport(int x, int y, unsigned int w, unsigned int h) const; + void apply_view_matrix() const; + void apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const; }; } // GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 76a23373d..99b9faddb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -56,15 +56,6 @@ static const float TRACKBALLSIZE = 0.8f; static const float GROUND_Z = -0.02f; -// phi / theta angles to orient the camera. -static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f }; -static const float VIEW_LEFT[2] = { 90.0f, 90.0f }; -static const float VIEW_RIGHT[2] = { -90.0f, 90.0f }; -static const float VIEW_TOP[2] = { 0.0f, 0.0f }; -static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f }; -static const float VIEW_FRONT[2] = { 0.0f, 90.0f }; -static const float VIEW_REAR[2] = { 180.0f, 90.0f }; - static const float GIZMO_RESET_BUTTON_HEIGHT = 22.0f; static const float GIZMO_RESET_BUTTON_WIDTH = 70.f; @@ -374,7 +365,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) float half_w = 0.5f * (float)cnv_size.get_width(); float half_h = 0.5f * (float)cnv_size.get_height(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom); @@ -386,7 +377,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas float half_w = 0.5f * (float)cnv_size.get_width(); float half_h = 0.5f * (float)cnv_size.get_height(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); @@ -417,7 +408,7 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas const float width = (float)m_tooltip_texture.get_width() * scale; const float height = (float)m_tooltip_texture.get_height() * scale; - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float gap = 10.0f * inv_zoom; @@ -871,7 +862,7 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const glsafe(::glLoadIdentity()); const Size& cnv_size = canvas.get_canvas_size(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float left = (-0.5f * (float)m_original_width) * inv_zoom; float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom; @@ -1140,7 +1131,7 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const glsafe(::glLoadIdentity()); const Size& cnv_size = canvas.get_canvas_size(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom; @@ -1424,11 +1415,6 @@ void GLCanvas3D::set_color_by(const std::string& value) m_color_by = value; } -float GLCanvas3D::get_camera_zoom() const -{ - return m_camera.zoom; -} - BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const { BoundingBoxf3 bb; @@ -1542,30 +1528,8 @@ void GLCanvas3D::zoom_to_selection() void GLCanvas3D::select_view(const std::string& direction) { - const float* dir_vec = nullptr; - - if (direction == "iso") - dir_vec = VIEW_DEFAULT; - else if (direction == "left") - dir_vec = VIEW_LEFT; - else if (direction == "right") - dir_vec = VIEW_RIGHT; - else if (direction == "top") - dir_vec = VIEW_TOP; - else if (direction == "bottom") - dir_vec = VIEW_BOTTOM; - else if (direction == "front") - dir_vec = VIEW_FRONT; - else if (direction == "rear") - dir_vec = VIEW_REAR; - - if (dir_vec != nullptr) - { - m_camera.phi = dir_vec[0]; - m_camera.set_theta(dir_vec[1], false); - if (m_canvas != nullptr) - m_canvas->Refresh(); - } + if (m_camera.select_view(direction) && (m_canvas != nullptr)) + m_canvas->Refresh(); } void GLCanvas3D::update_volumes_colors_by_extruder() @@ -1609,7 +1573,7 @@ void GLCanvas3D::render() m_camera.requires_zoom_to_bed = false; } - _camera_tranform(); + m_camera.apply_view_matrix(); GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam)); @@ -2661,11 +2625,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // vector from the starting position to the found intersection Vec3d inters_vec = inters - m_mouse.drag.start_position_3D; - // get the view matrix back from opengl - GLfloat matrix[16]; - glsafe(::glGetFloatv(GL_MODELVIEW_MATRIX, matrix)); - Vec3d camera_right((double)matrix[0], (double)matrix[4], (double)matrix[8]); - Vec3d camera_up((double)matrix[1], (double)matrix[5], (double)matrix[9]); + Vec3d camera_right = m_camera.get_dir_right(); + Vec3d camera_up = m_camera.get_dir_up(); // finds projection of the vector along the camera axes double projection_x = inters_vec.dot(camera_right); @@ -3103,7 +3064,7 @@ void GLCanvas3D::do_mirror() void GLCanvas3D::set_camera_zoom(float zoom) { zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f; - zoom = get_camera_zoom() / (1.0f - zoom); + zoom = m_camera.zoom / (1.0f - zoom); // Don't allow to zoom too far outside the scene. float zoom_min = _get_zoom_to_bounding_box_factor(_max_bounding_box()); @@ -3346,10 +3307,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) // ensures that this canvas is current _set_current(); - glsafe(::glViewport(0, 0, w, h)); - - glsafe(::glMatrixMode(GL_PROJECTION)); - glsafe(::glLoadIdentity()); + m_camera.apply_viewport(0, 0, w, h); const BoundingBoxf3& bbox = _max_bounding_box(); @@ -3359,7 +3317,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) { float w2 = w; float h2 = h; - float two_zoom = 2.0f * get_camera_zoom(); + float two_zoom = 2.0f * m_camera.zoom; if (two_zoom != 0.0f) { float inv_two_zoom = 1.0f / two_zoom; @@ -3369,7 +3327,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) // FIXME: calculate a tighter value for depth will improve z-fighting float depth = 5.0f * (float)bbox.max_size(); - glsafe(::glOrtho(-w2, w2, -h2, h2, -depth, depth)); + m_camera.apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth); break; } @@ -3402,8 +3360,6 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) } } - glsafe(::glMatrixMode(GL_MODELVIEW)); - m_dirty = false; } @@ -3437,16 +3393,11 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co // then calculates the vertices coordinate on this plane along the camera xy axes // we need the view matrix, we let opengl calculate it (same as done in render()) - _camera_tranform(); + m_camera.apply_view_matrix(); - // get the view matrix back from opengl - GLfloat matrix[16]; - glsafe(::glGetFloatv(GL_MODELVIEW_MATRIX, matrix)); - - // camera axes - Vec3d right((double)matrix[0], (double)matrix[4], (double)matrix[8]); - Vec3d up((double)matrix[1], (double)matrix[5], (double)matrix[9]); - Vec3d forward((double)matrix[2], (double)matrix[6], (double)matrix[10]); + Vec3d right = m_camera.get_dir_right(); + Vec3d up = m_camera.get_dir_up(); + Vec3d forward = m_camera.get_dir_forward(); Vec3d bb_min = bbox.min; Vec3d bb_max = bbox.max; @@ -3507,17 +3458,6 @@ void GLCanvas3D::_refresh_if_shown_on_screen() } } -void GLCanvas3D::_camera_tranform() const -{ - glsafe(::glMatrixMode(GL_MODELVIEW)); - glsafe(::glLoadIdentity()); - - glsafe(::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f)); // pitch - glsafe(::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f)); // yaw - Vec3d target = -m_camera.get_target(); - glsafe(::glTranslated(target(0), target(1), target(2))); -} - void GLCanvas3D::_picking_pass() const { const Vec2d& pos = m_mouse.position; @@ -3648,19 +3588,19 @@ void GLCanvas3D::_render_objects() const m_shader.start_using(); if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) { int object_id = m_layers_editing.last_object_id; - m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, [object_id](const GLVolume &volume) { + m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume &volume) { // Which volume to paint without the layer height profile shader? - return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); + return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); }); // Let LayersEditing handle rendering of the active object using the layer height profile shader. m_layers_editing.render_volumes(*this, this->m_volumes); } else { // do not cull backfaces to show broken geometry, if any - m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) { + m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); }); } - m_volumes.render_VBOs(GLVolumeCollection::Transparent, false); + m_volumes.render_VBOs(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); m_shader.stop_using(); } else @@ -3674,10 +3614,10 @@ void GLCanvas3D::_render_objects() const } // do not cull backfaces to show broken geometry, if any - m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) { - return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); - }); - m_volumes.render_legacy(GLVolumeCollection::Transparent, false); + m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) { + return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); + }); + m_volumes.render_legacy(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix()); if (m_use_clipping_planes) { @@ -3796,7 +3736,7 @@ void GLCanvas3D::_render_toolbar() const #endif // ENABLE_RETINA_GL Size cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); + float zoom = m_camera.zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation(); @@ -3859,7 +3799,7 @@ void GLCanvas3D::_render_view_toolbar() const #endif // ENABLE_RETINA_GL Size cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); + float zoom = m_camera.zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; // places the toolbar on the bottom-left corner of the 3d scene @@ -4113,14 +4053,10 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) if (m_canvas == nullptr) return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); - _camera_tranform(); - GLint viewport[4]; - glsafe(::glGetIntegerv(GL_VIEWPORT, viewport)); - GLdouble modelview_matrix[16]; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix)); - GLdouble projection_matrix[16]; - glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix)); + const std::array& viewport = m_camera.get_viewport(); + const Transform3d& modelview_matrix = m_camera.get_view_matrix(); + const Transform3d& projection_matrix = m_camera.get_projection_matrix(); GLint y = viewport[3] - (GLint)mouse_pos(1); GLfloat mouse_z; @@ -4130,7 +4066,7 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) mouse_z = *z; GLdouble out_x, out_y, out_z; - ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); + ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); return Vec3d((double)out_x, (double)out_y, (double)out_z); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9c196aa20..c53e1df8c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -483,7 +483,7 @@ public: void set_color_by(const std::string& value); - float get_camera_zoom() const; + const Camera& get_camera() const { return m_camera; } BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 scene_bounding_box() const; @@ -593,7 +593,6 @@ private: void _refresh_if_shown_on_screen(); - void _camera_tranform() const; void _picking_pass() const; void _render_background() const; void _render_bed(float theta) const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 985c6aa84..144d02476 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -612,7 +612,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -717,7 +717,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -834,7 +834,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -917,7 +917,7 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& { // NB: mouse_pos is already scaled appropriately - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = m_layout.scale * inv_zoom; @@ -1013,7 +1013,7 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const return; #endif // !ENABLE_SVG_ICONS - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = inv_zoom * m_layout.scale; @@ -1168,7 +1168,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const return; #endif // !ENABLE_SVG_ICONS - float zoom = parent.get_camera_zoom(); + float zoom = parent.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; #if ENABLE_SVG_ICONS float factor = inv_zoom * m_layout.scale; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index e21fddefa..2a5f35596 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -273,17 +273,15 @@ std::pair GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse if (m_V.size() == 0) update_mesh(); - Eigen::Matrix viewport; - glsafe(::glGetIntegerv(GL_VIEWPORT, viewport.data())); - Eigen::Matrix modelview_matrix; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data())); - Eigen::Matrix projection_matrix; - glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data())); + const Camera& camera = m_parent.get_camera(); + const std::array& viewport = camera.get_viewport(); + const Transform3d& modelview_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); Vec3d point1; Vec3d point2; - ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2)); - ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2)); + ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2)); + ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2)); igl::Hit hit; @@ -365,12 +363,10 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous // left up with selection rectangle - select points inside the rectangle: if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::ShiftUp) && m_selection_rectangle_active) { const Transform3d& instance_matrix = m_model_object->instances[m_active_instance]->get_transformation().get_matrix(); - GLint viewport[4]; - glsafe(::glGetIntegerv(GL_VIEWPORT, viewport)); - GLdouble modelview_matrix[16]; - glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix)); - GLdouble projection_matrix[16]; - glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix)); + const Camera& camera = m_parent.get_camera(); + const std::array& viewport = camera.get_viewport(); + const Transform3d& modelview_matrix = camera.get_view_matrix(); + const Transform3d& projection_matrix = camera.get_projection_matrix(); const Selection& selection = m_parent.get_selection(); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); @@ -381,7 +377,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const Transform3d& instance_matrix_no_translation = volume->get_instance_transformation().get_matrix(true); // we'll recover current look direction from the modelview matrix (in world coords)... - Vec3f direction_to_camera(modelview_matrix[2], modelview_matrix[6], modelview_matrix[10]); + Vec3f direction_to_camera = camera.get_dir_forward().cast(); // ...and transform it to model coords. direction_to_camera = (instance_matrix_no_translation.inverse().cast() * direction_to_camera).normalized().eval(); @@ -391,8 +387,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous Vec3f pos = instance_matrix.cast() * support_point.pos; pos(2) += z_offset; GLdouble out_x, out_y, out_z; - ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z); - out_y = m_canvas_height - out_y; + ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z); + out_y = m_canvas_height - out_y; if (rectangle.contains(Point(out_x, out_y))) { bool is_obscured = false; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 7f4d4d495..3935e240a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -827,7 +827,7 @@ void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selectio float cnv_w = (float)canvas.get_canvas_size().get_width(); float cnv_h = (float)canvas.get_canvas_size().get_height(); - float zoom = canvas.get_camera_zoom(); + float zoom = canvas.get_camera().zoom; float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float height = get_total_overlay_height(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 3f5f6ba4f..c568b41a8 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -971,7 +971,23 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const glsafe(::glTranslated(center(0), center(1), center(2))); if (!boost::starts_with(sidebar_field, "position")) { - Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); + Transform3d orient_matrix = Transform3d::Identity(); + if (boost::starts_with(sidebar_field, "scale")) + 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())); + } + } + glsafe(::glMultMatrixd(orient_matrix.data())); } }