From 3a19b81cefd9438eb4ac128a976914e03cf0c684 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 13 Jun 2018 15:44:04 +0200 Subject: Scale gizmo rendering --- xs/src/slic3r/GUI/GLCanvas3D.cpp | 76 ++++++++++++++++++++++--------------- xs/src/slic3r/GUI/GLCanvas3D.hpp | 8 ++-- xs/src/slic3r/GUI/GLGizmo.cpp | 81 ++++++++++++++++++++++++++++++++++------ xs/src/slic3r/GUI/GLGizmo.hpp | 19 +++++++--- 4 files changed, 132 insertions(+), 52 deletions(-) (limited to 'xs') diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index e3db3af10..9dbfeaff3 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1125,17 +1125,6 @@ void GLCanvas3D::Gizmos::set_enabled(bool enable) m_enabled = enable; } -void GLCanvas3D::Gizmos::select(EType type) -{ - if (m_gizmos.find(type) != m_gizmos.end()) - m_current = type; -} - -void GLCanvas3D::Gizmos::reset_selection() -{ - m_current = Undefined; -} - void GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse_pos) { if (!m_enabled) @@ -1180,7 +1169,18 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Poi // we currently use circular icons for gizmo, so we check the radius if (length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size) - it->second->set_state((it->second->get_state() == GLGizmoBase::On) ? GLGizmoBase::Off : GLGizmoBase::On); + { + if ((it->second->get_state() == GLGizmoBase::On)) + { + it->second->set_state(GLGizmoBase::Off); + m_current = Undefined; + } + else + { + it->second->set_state(GLGizmoBase::On); + m_current = it->first; + } + } else it->second->set_state(GLGizmoBase::Off); @@ -1190,15 +1190,23 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Poi void GLCanvas3D::Gizmos::reset_all_states() { + if (!m_enabled) + return; + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if (it->second != nullptr) it->second->set_state(GLGizmoBase::Off); } + + m_current = Undefined; } bool GLCanvas3D::Gizmos::contains_mouse() const { + if (!m_enabled) + return false; + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) { if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::Hover)) @@ -1208,7 +1216,7 @@ bool GLCanvas3D::Gizmos::contains_mouse() const return false; } -void GLCanvas3D::Gizmos::render(const GLCanvas3D& canvas) const +void GLCanvas3D::Gizmos::render(const GLCanvas3D& canvas, const BoundingBoxf3& box) const { if (!m_enabled) return; @@ -1219,9 +1227,10 @@ void GLCanvas3D::Gizmos::render(const GLCanvas3D& canvas) const ::glLoadIdentity(); _render_overlay(canvas); - _render_current_gizmo(); ::glPopMatrix(); + + _render_current_gizmo(box); } void GLCanvas3D::Gizmos::_reset() @@ -1256,13 +1265,13 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas) const } } -void GLCanvas3D::Gizmos::_render_current_gizmo() const +void GLCanvas3D::Gizmos::_render_current_gizmo(const BoundingBoxf3& box) const { GizmosMap::const_iterator it = m_gizmos.find(m_current); if (it == m_gizmos.end()) return; - it->second->render(); + it->second->render(box); } float GLCanvas3D::Gizmos::_get_total_overlay_height() const @@ -2603,14 +2612,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (m_picking_enabled) _on_select(volume_idx); - // The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate pos x, y, - // an converts the screen space coordinate to unscaled object space. - Pointf3 pos3d = (volume_idx == -1) ? Pointf3(DBL_MAX, DBL_MAX) : _mouse_to_3d(pos); - if (volume_idx != -1) { if (evt.LeftDown() && m_moving_enabled) { + // The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate pos x, y, + // an converts the screen space coordinate to unscaled object space. + Pointf3 pos3d = (volume_idx == -1) ? Pointf3(DBL_MAX, DBL_MAX) : _mouse_to_3d(pos); + // Only accept the initial position, if it is inside the volume bounding box. BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box(); volume_bbox.offset(1.0); @@ -2895,6 +2904,17 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box() const return bb; } +BoundingBoxf3 GLCanvas3D::_selected_volumes_bounding_box() const +{ + BoundingBoxf3 bb; + for (const GLVolume* volume : m_volumes.volumes) + { + if ((volume != nullptr) && volume->selected) + bb.merge(volume->transformed_bounding_box()); + } + return bb; +} + void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox) { // Calculate the zoom factor needed to adjust viewport to bounding box. @@ -3150,7 +3170,6 @@ void GLCanvas3D::_render_axes(bool depth_test) const void GLCanvas3D::_render_objects() const { if (m_volumes.empty()) - return; ::glEnable(GL_LIGHTING); @@ -3343,7 +3362,7 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const void GLCanvas3D::_render_gizmo() const { - m_gizmos.render(*this); + m_gizmos.render(*this, _selected_volumes_bounding_box()); } float GLCanvas3D::_get_layers_editing_cursor_z_relative() const @@ -4079,15 +4098,12 @@ void GLCanvas3D::_on_move(const std::vector& volume_idxs) void GLCanvas3D::_on_select(int volume_idx) { int id = -1; - if (volume_idx < (int)m_volumes.volumes.size()) + if ((volume_idx != -1) && (volume_idx < (int)m_volumes.volumes.size())) { - if (volume_idx != -1) - { - if (m_select_by == "volume") - id = m_volumes.volumes[volume_idx]->volume_idx(); - else if (m_select_by == "object") - id = m_volumes.volumes[volume_idx]->object_idx(); - } + if (m_select_by == "volume") + id = m_volumes.volumes[volume_idx]->volume_idx(); + else if (m_select_by == "object") + id = m_volumes.volumes[volume_idx]->object_idx(); } m_on_select_object_callback.call(id); } diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 738df637c..291b07553 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -350,22 +350,19 @@ public: bool is_enabled() const; void set_enabled(bool enable); - void select(EType type); - void reset_selection(); - void update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse_pos); void update_on_off_state(const GLCanvas3D& canvas, const Pointf& mouse_pos); void reset_all_states(); bool contains_mouse() const; - void render(const GLCanvas3D& canvas) const; + void render(const GLCanvas3D& canvas, const BoundingBoxf3& box) const; private: void _reset(); void _render_overlay(const GLCanvas3D& canvas) const; - void _render_current_gizmo() const; + void _render_current_gizmo(const BoundingBoxf3& box) const; float _get_total_overlay_height() const; }; @@ -557,6 +554,7 @@ private: void _resize(unsigned int w, unsigned int h); BoundingBoxf3 _max_bounding_box() const; + BoundingBoxf3 _selected_volumes_bounding_box() const; void _zoom_to_bounding_box(const BoundingBoxf3& bbox); float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const; diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index b4237e162..75f39aad9 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -1,6 +1,9 @@ #include "GLGizmo.hpp" #include "../../libslic3r/Utils.hpp" +#include "../../libslic3r/BoundingBox.hpp" + +#include #include @@ -16,6 +19,11 @@ GLGizmoBase::~GLGizmoBase() { } +bool GLGizmoBase::init() +{ + return on_init(); +} + GLGizmoBase::EState GLGizmoBase::get_state() const { return m_state; @@ -36,9 +44,9 @@ int GLGizmoBase::get_textures_size() const return m_textures[Off].get_width(); } -bool GLGizmoBase::init() +void GLGizmoBase::render(const BoundingBoxf3& box) const { - return on_init(); + on_render(box); } GLGizmoRotate::GLGizmoRotate() @@ -49,11 +57,6 @@ GLGizmoRotate::GLGizmoRotate() { } -void GLGizmoRotate::render() const -{ - std::cout << "GLGizmoRotate::render()" << std::endl; -} - bool GLGizmoRotate::on_init() { std::string path = resources_dir() + "/icons/overlay/"; @@ -73,6 +76,14 @@ bool GLGizmoRotate::on_init() return true; } +void GLGizmoRotate::on_render(const BoundingBoxf3& box) const +{ + std::cout << "GLGizmoRotate::render()" << std::endl; +} + +const float GLGizmoScale::Offset = 5.0f; +const float GLGizmoScale::SquareHalfSize = 2.0f; + GLGizmoScale::GLGizmoScale() : GLGizmoBase() , m_scale_x(1.0f) @@ -81,11 +92,6 @@ GLGizmoScale::GLGizmoScale() { } -void GLGizmoScale::render() const -{ - std::cout << "GLGizmoScale::render()" << std::endl; -} - bool GLGizmoScale::on_init() { std::string path = resources_dir() + "/icons/overlay/"; @@ -105,5 +111,56 @@ bool GLGizmoScale::on_init() return true; } +void GLGizmoScale::on_render(const BoundingBoxf3& box) const +{ + ::glDisable(GL_LIGHTING); + ::glDisable(GL_DEPTH_TEST); + + const Pointf3& size = box.size(); + const Pointf3& center = box.center(); + + Pointf3 half_scaled_size = 0.5 * Pointf3((coordf_t)m_scale_x * size.x, (coordf_t)m_scale_y * size.y, (coordf_t)m_scale_z * size.z); + coordf_t min_x = center.x - half_scaled_size.x - (coordf_t)Offset; + coordf_t max_x = center.x + half_scaled_size.x + (coordf_t)Offset; + coordf_t min_y = center.y - half_scaled_size.y - (coordf_t)Offset; + coordf_t max_y = center.y + half_scaled_size.y + (coordf_t)Offset; + + ::glLineWidth(2.0f); + ::glBegin(GL_LINE_LOOP); + // draw outline + ::glColor3f(1.0f, 1.0f, 1.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f); + ::glEnd(); + + // draw grabbers + ::glColor3f(1.0f, 0.38f, 0.0f); + ::glDisable(GL_CULL_FACE); + _render_square(Pointf3(min_x, min_y, 0.0)); + _render_square(Pointf3(max_x, min_y, 0.0)); + _render_square(Pointf3(max_x, max_y, 0.0)); + _render_square(Pointf3(min_x, max_y, 0.0)); + ::glEnable(GL_CULL_FACE); +} + +void GLGizmoScale::_render_square(const Pointf3& center) const +{ + float min_x = (float)center.x - SquareHalfSize; + float max_x = (float)center.x + SquareHalfSize; + float min_y = (float)center.y - SquareHalfSize; + float max_y = (float)center.y + SquareHalfSize; + + ::glBegin(GL_TRIANGLES); + ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f); + ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f); + ::glEnd(); +} + } // namespace GUI } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp index 3ca8e3213..a626305c1 100644 --- a/xs/src/slic3r/GUI/GLGizmo.hpp +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -4,6 +4,10 @@ #include "../../slic3r/GUI/GLTexture.hpp" namespace Slic3r { + +class BoundingBoxf3; +class Pointf3; + namespace GUI { class GLGizmoBase @@ -35,10 +39,11 @@ public: unsigned int get_textures_id() const; int get_textures_size() const; - virtual void render() const = 0; + void render(const BoundingBoxf3& box) const; protected: virtual bool on_init() = 0; + virtual void on_render(const BoundingBoxf3& box) const = 0; }; class GLGizmoRotate : public GLGizmoBase @@ -50,14 +55,16 @@ class GLGizmoRotate : public GLGizmoBase public: GLGizmoRotate(); - void render() const; - protected: virtual bool on_init(); + virtual void on_render(const BoundingBoxf3& box) const; }; class GLGizmoScale : public GLGizmoBase { + static const float Offset; + static const float SquareHalfSize; + float m_scale_x; float m_scale_y; float m_scale_z; @@ -65,10 +72,12 @@ class GLGizmoScale : public GLGizmoBase public: GLGizmoScale(); - void render() const; - protected: virtual bool on_init(); + virtual void on_render(const BoundingBoxf3& box) const; + +private: + void _render_square(const Pointf3& center) const; }; } // namespace GUI -- cgit v1.2.3