From d23824af97fec6f40e25167aed73b8f53aa948a2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 20 Mar 2019 13:51:25 +0100 Subject: [PATCH 01/61] GLCanvas3D::Gizmos as a standalone class (GLGizmosManager) --- src/slic3r/CMakeLists.txt | 3 + src/slic3r/GUI/GLCanvas3D.cpp | 985 +------------------ src/slic3r/GUI/GLCanvas3D.hpp | 161 +-- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 1 - src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmos.hpp | 15 + src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 865 ++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 160 +++ 11 files changed, 1078 insertions(+), 1116 deletions(-) create mode 100644 src/slic3r/GUI/Gizmos/GLGizmosManager.cpp create mode 100644 src/slic3r/GUI/Gizmos/GLGizmosManager.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index ef60ab3fa9..9d25318136 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -30,6 +30,9 @@ set(SLIC3R_GUI_SOURCES GUI/GLCanvas3DManager.cpp GUI/Selection.hpp GUI/Selection.cpp + GUI/Gizmos/GLGizmos.hpp + GUI/Gizmos/GLGizmosManager.cpp + GUI/Gizmos/GLGizmosManager.hpp GUI/Gizmos/GLGizmoBase.cpp GUI/Gizmos/GLGizmoBase.hpp GUI/Gizmos/GLGizmoMove.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7fb1ad25ed..06a36866d1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -124,62 +124,6 @@ void Size::set_scale_factor(int scale_factor) m_scale_factor = scale_factor; } -Rect::Rect() - : m_left(0.0f) - , m_top(0.0f) - , m_right(0.0f) - , m_bottom(0.0f) -{ -} - -Rect::Rect(float left, float top, float right, float bottom) - : m_left(left) - , m_top(top) - , m_right(right) - , m_bottom(bottom) -{ -} - -float Rect::get_left() const -{ - return m_left; -} - -void Rect::set_left(float left) -{ - m_left = left; -} - -float Rect::get_top() const -{ - return m_top; -} - -void Rect::set_top(float top) -{ - m_top = top; -} - -float Rect::get_right() const -{ - return m_right; -} - -void Rect::set_right(float right) -{ - m_right = right; -} - -float Rect::get_bottom() const -{ - return m_bottom; -} - -void Rect::set_bottom(float bottom) -{ - m_bottom = bottom; -} - #if !ENABLE_TEXTURES_FROM_SVG GLCanvas3D::Shader::Shader() : m_shader(nullptr) @@ -734,881 +678,6 @@ GLCanvas3D::Mouse::Mouse() { } -#if ENABLE_SVG_ICONS -const float GLCanvas3D::Gizmos::Default_Icons_Size = 64; -#endif // ENABLE_SVG_ICONS - -GLCanvas3D::Gizmos::Gizmos() - : m_enabled(false) -#if ENABLE_SVG_ICONS - , m_icons_texture_dirty(true) -#endif // ENABLE_SVG_ICONS - , m_current(Undefined) -#if ENABLE_SVG_ICONS - , m_overlay_icons_size(Default_Icons_Size) - , m_overlay_scale(1.0f) - , m_overlay_border(5.0f) - , m_overlay_gap_y(5.0f) -{ -} -#else -{ - set_overlay_scale(1.0); -} -#endif // ENABLE_SVG_ICONS - -GLCanvas3D::Gizmos::~Gizmos() -{ - reset(); -} - -bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) -{ -#if !ENABLE_SVG_ICONS - m_icons_texture.metadata.filename = "gizmos.png"; - m_icons_texture.metadata.icon_size = 64; - - if (!m_icons_texture.metadata.filename.empty()) - { - if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false)) - { - reset(); - return false; - } - } -#endif // !ENABLE_SVG_ICONS - - m_background_texture.metadata.filename = "toolbar_background.png"; - m_background_texture.metadata.left = 16; - m_background_texture.metadata.top = 16; - m_background_texture.metadata.right = 16; - m_background_texture.metadata.bottom = 16; - - if (!m_background_texture.metadata.filename.empty()) - { - if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false)) - { - reset(); - return false; - } - } - -#if ENABLE_SVG_ICONS - GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "move.svg", 0); -#else - GLGizmoBase* gizmo = new GLGizmoMove3D(parent, 0); -#endif // ENABLE_SVG_ICONS - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) - return false; - - m_gizmos.insert(GizmosMap::value_type(Move, gizmo)); - -#if ENABLE_SVG_ICONS - gizmo = new GLGizmoScale3D(parent, "scale.svg", 1); -#else - gizmo = new GLGizmoScale3D(parent, 1); -#endif // ENABLE_SVG_ICONS - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) - return false; - - m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); - -#if ENABLE_SVG_ICONS - gizmo = new GLGizmoRotate3D(parent, "rotate.svg", 2); -#else - gizmo = new GLGizmoRotate3D(parent, 2); -#endif // ENABLE_SVG_ICONS - if (gizmo == nullptr) - { - reset(); - return false; - } - - if (!gizmo->init()) - { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); - -#if ENABLE_SVG_ICONS - gizmo = new GLGizmoFlatten(parent, "place.svg", 3); -#else - gizmo = new GLGizmoFlatten(parent, 3); -#endif // ENABLE_SVG_ICONS - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); - -#if ENABLE_SVG_ICONS - gizmo = new GLGizmoCut(parent, "cut.svg", 4); -#else - gizmo = new GLGizmoCut(parent, 4); -#endif // ENABLE_SVG_ICONS - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); - -#if ENABLE_SVG_ICONS - gizmo = new GLGizmoSlaSupports(parent, "sla_supports.svg", 5); -#else - gizmo = new GLGizmoSlaSupports(parent, 5); -#endif // ENABLE_SVG_ICONS - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo)); - - return true; -} - -bool GLCanvas3D::Gizmos::is_enabled() const -{ - return m_enabled; -} - -void GLCanvas3D::Gizmos::set_enabled(bool enable) -{ - m_enabled = enable; -} - -#if ENABLE_SVG_ICONS -void GLCanvas3D::Gizmos::set_overlay_icon_size(float size) -{ - if (m_overlay_icons_size != size) - { - m_overlay_icons_size = size; - m_icons_texture_dirty = true; - } -} -#endif // ENABLE_SVG_ICONS - -void GLCanvas3D::Gizmos::set_overlay_scale(float scale) -{ -#if ENABLE_SVG_ICONS - if (m_overlay_scale != scale) - { - m_overlay_scale = scale; - m_icons_texture_dirty = true; - } -#else - m_overlay_icons_scale = scale; - m_overlay_border = 5.0f * scale; - m_overlay_gap_y = 5.0f * scale; -#endif // ENABLE_SVG_ICONS -} - -std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) -{ - std::string name = ""; - - if (!m_enabled) - return name; - - float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = get_total_overlay_height(); -#if ENABLE_SVG_ICONS - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS - - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - -#if ENABLE_SVG_ICONS - bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#else - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#endif // ENABLE_SVG_ICONS - if (inside) - name = it->second->get_name(); - - if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On)) - it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); - -#if ENABLE_SVG_ICONS - top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS - } - - return name; -} - -void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) -{ - if (!m_enabled) - return; - - float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = get_total_overlay_height(); - -#if ENABLE_SVG_ICONS - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS - - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - -#if ENABLE_SVG_ICONS - bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#else - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#endif // ENABLE_SVG_ICONS - if (it->second->is_activable(selection) && inside) - { - if ((it->second->get_state() == GLGizmoBase::On)) - { - it->second->set_state(GLGizmoBase::Hover); - m_current = Undefined; - } - else if ((it->second->get_state() == GLGizmoBase::Hover)) - { - it->second->set_state(GLGizmoBase::On); - m_current = it->first; - } - } - else - it->second->set_state(GLGizmoBase::Off); - -#if ENABLE_SVG_ICONS - top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS - } - - GizmosMap::iterator it = m_gizmos.find(m_current); - if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) - it->second->set_state(GLGizmoBase::On); -} - -void GLCanvas3D::Gizmos::update_on_off_state(const Selection& selection) -{ - GizmosMap::iterator it = m_gizmos.find(m_current); - if ((it != m_gizmos.end()) && (it->second != nullptr)) - { - if (!it->second->is_activable(selection)) - { - it->second->set_state(GLGizmoBase::Off); - m_current = Undefined; - } - } -} - -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); - it->second->set_hover_id(-1); - } - } - - m_current = Undefined; -} - -void GLCanvas3D::Gizmos::set_hover_id(int id) -{ - if (!m_enabled) - return; - - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On)) - it->second->set_hover_id(id); - } -} - -void GLCanvas3D::Gizmos::enable_grabber(EType type, unsigned int id, bool enable) -{ - if (!m_enabled) - return; - - GizmosMap::const_iterator it = m_gizmos.find(type); - if (it != m_gizmos.end()) - { - if (enable) - it->second->enable_grabber(id); - else - it->second->disable_grabber(id); - } -} - -bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const -{ - if (!m_enabled) - return false; - - float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = get_total_overlay_height(); - -#if ENABLE_SVG_ICONS - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS - - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - -#if ENABLE_SVG_ICONS - if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) -#else - if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) -#endif // ENABLE_SVG_ICONS - return true; - -#if ENABLE_SVG_ICONS - top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS - } - - return false; -} - -bool GLCanvas3D::Gizmos::grabber_contains_mouse() const -{ - if (!m_enabled) - return false; - - GLGizmoBase* curr = get_current(); - return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; -} - -void GLCanvas3D::Gizmos::update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos) -{ - if (!m_enabled) - return; - - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection); -} - -GLCanvas3D::Gizmos::EType GLCanvas3D::Gizmos::get_current_type() const -{ - return m_current; -} - -bool GLCanvas3D::Gizmos::is_running() const -{ - if (!m_enabled) - return false; - - GLGizmoBase* curr = get_current(); - return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; -} - -bool GLCanvas3D::Gizmos::handle_shortcut(int key, const Selection& selection) -{ - if (!m_enabled || selection.is_empty()) - return false; - - EType old_current = m_current; - bool handled = false; - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - - int it_key = it->second->get_shortcut_key(); - - if (it->second->is_activable(selection) && ((it_key == key - 64) || (it_key == key - 96))) - { - if ((it->second->get_state() == GLGizmoBase::On)) - { - it->second->set_state(GLGizmoBase::Off); - m_current = Undefined; - handled = true; - } - else if ((it->second->get_state() == GLGizmoBase::Off)) - { - it->second->set_state(GLGizmoBase::On); - m_current = it->first; - handled = true; - } - } - } - - if (handled && (old_current != Undefined) && (old_current != m_current)) - { - GizmosMap::const_iterator it = m_gizmos.find(old_current); - if (it != m_gizmos.end()) - it->second->set_state(GLGizmoBase::Off); - } - - return handled; -} - -bool GLCanvas3D::Gizmos::is_dragging() const -{ - if (!m_enabled) - return false; - - GLGizmoBase* curr = get_current(); - return (curr != nullptr) ? curr->is_dragging() : false; -} - -void GLCanvas3D::Gizmos::start_dragging(const Selection& selection) -{ - if (!m_enabled) - return; - - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->start_dragging(selection); -} - -void GLCanvas3D::Gizmos::stop_dragging() -{ - if (!m_enabled) - return; - - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->stop_dragging(); -} - -Vec3d GLCanvas3D::Gizmos::get_displacement() const -{ - if (!m_enabled) - return Vec3d::Zero(); - - GizmosMap::const_iterator it = m_gizmos.find(Move); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_displacement() : Vec3d::Zero(); -} - -Vec3d GLCanvas3D::Gizmos::get_scale() const -{ - if (!m_enabled) - return Vec3d::Ones(); - - GizmosMap::const_iterator it = m_gizmos.find(Scale); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale() : Vec3d::Ones(); -} - -void GLCanvas3D::Gizmos::set_scale(const Vec3d& scale) -{ - if (!m_enabled) - return; - - GizmosMap::const_iterator it = m_gizmos.find(Scale); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_scale(scale); -} - -Vec3d GLCanvas3D::Gizmos::get_rotation() const -{ - if (!m_enabled) - return Vec3d::Zero(); - - GizmosMap::const_iterator it = m_gizmos.find(Rotate); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_rotation() : Vec3d::Zero(); -} - -void GLCanvas3D::Gizmos::set_rotation(const Vec3d& rotation) -{ - if (!m_enabled) - return; - - GizmosMap::const_iterator it = m_gizmos.find(Rotate); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_rotation(rotation); -} - -Vec3d GLCanvas3D::Gizmos::get_flattening_normal() const -{ - if (!m_enabled) - return Vec3d::Zero(); - - GizmosMap::const_iterator it = m_gizmos.find(Flatten); - return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_flattening_normal() : Vec3d::Zero(); -} - -void GLCanvas3D::Gizmos::set_flattening_data(const ModelObject* model_object) -{ - if (!m_enabled) - return; - - GizmosMap::const_iterator it = m_gizmos.find(Flatten); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_flattening_data(model_object); -} - -void GLCanvas3D::Gizmos::set_sla_support_data(ModelObject* model_object, const Selection& selection) -{ - if (!m_enabled) - return; - - GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); - if (it != m_gizmos.end()) - reinterpret_cast(it->second)->set_sla_support_data(model_object, selection); -} - - -// Returns true if the gizmo used the event to do something, false otherwise. -bool GLCanvas3D::Gizmos::mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down) -{ - if (!m_enabled) - return false; - - GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); - if (it != m_gizmos.end()) - return reinterpret_cast(it->second)->mouse_event(action, mouse_position, shift_down); - - return false; -} - -void GLCanvas3D::Gizmos::render_current_gizmo(const Selection& selection) const -{ - if (!m_enabled) - return; - - do_render_current_gizmo(selection); -} - -void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const Selection& selection) const -{ - if (!m_enabled) - return; - - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->render_for_picking(selection); -} - -void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas, const Selection& selection) const -{ - if (!m_enabled) - return; - -#if ENABLE_SVG_ICONS - if (m_icons_texture_dirty) - generate_icons_texture(); -#endif // ENABLE_SVG_ICONS - - ::glDisable(GL_DEPTH_TEST); - - ::glPushMatrix(); - ::glLoadIdentity(); - - do_render_overlay(canvas, selection); - - ::glPopMatrix(); -} - - -void GLCanvas3D::Gizmos::reset() -{ - for (GizmosMap::value_type& gizmo : m_gizmos) - { - delete gizmo.second; - gizmo.second = nullptr; - } - - m_gizmos.clear(); -} - -void GLCanvas3D::Gizmos::do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const -{ - if (m_gizmos.empty()) - return; - - 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 inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - - float height = get_total_overlay_height(); - float width = get_total_overlay_width(); -#if ENABLE_SVG_ICONS - float scaled_border = m_overlay_border * m_overlay_scale * inv_zoom; -#else - float scaled_border = m_overlay_border * inv_zoom; -#endif // ENABLE_SVG_ICONS - - float top_x = (-0.5f * cnv_w) * inv_zoom; - float top_y = (0.5f * height) * inv_zoom; - - float left = top_x; - float top = top_y; - float right = left + width * inv_zoom; - float bottom = top - height * inv_zoom; - - // renders background - unsigned int bg_tex_id = m_background_texture.texture.get_id(); - float bg_tex_width = (float)m_background_texture.texture.get_width(); - float bg_tex_height = (float)m_background_texture.texture.get_height(); - if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0)) - { - float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f; - float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f; - - float bg_uv_left = 0.0f; - float bg_uv_right = 1.0f; - float bg_uv_top = 1.0f; - float bg_uv_bottom = 0.0f; - - float bg_left = left; - float bg_right = right; - float bg_top = top; - float bg_bottom = bottom; - float bg_width = right - left; - float bg_height = top - bottom; - float bg_min_size = std::min(bg_width, bg_height); - - float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width; - float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width; - float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height; - float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height; - - float bg_i_left = bg_left + scaled_border; - float bg_i_right = bg_right - scaled_border; - float bg_i_top = bg_top - scaled_border; - float bg_i_bottom = bg_bottom + scaled_border; - - bg_uv_left = bg_uv_i_left; - bg_i_left = bg_left; - - if ((m_overlay_border > 0) && (bg_uv_top != bg_uv_i_top)) - { - if (bg_uv_left != bg_uv_i_left) - GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } }); - - GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } }); - - if (bg_uv_right != bg_uv_i_right) - GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } }); - } - - if ((m_overlay_border > 0) && (bg_uv_left != bg_uv_i_left)) - GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } }); - - GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } }); - - if ((m_overlay_border > 0) && (bg_uv_right != bg_uv_i_right)) - GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } }); - - if ((m_overlay_border > 0) && (bg_uv_bottom != bg_uv_i_bottom)) - { - if (bg_uv_left != bg_uv_i_left) - GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } }); - - GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } }); - - if (bg_uv_right != bg_uv_i_right) - GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } }); - } - } - -#if ENABLE_SVG_ICONS - top_x += scaled_border; - top_y -= scaled_border; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale * inv_zoom; - - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - unsigned int icons_texture_id = m_icons_texture.get_id(); - unsigned int tex_width = m_icons_texture.get_width(); - unsigned int tex_height = m_icons_texture.get_height(); - float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f; - float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f; -#else - top_x += m_overlay_border * inv_zoom; - top_y -= m_overlay_border * inv_zoom; - float scaled_gap_y = m_overlay_gap_y * inv_zoom; - - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale * inv_zoom; - unsigned int icons_texture_id = m_icons_texture.texture.get_id(); - unsigned int texture_size = m_icons_texture.texture.get_width(); - float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f; -#endif // ENABLE_SVG_ICONS - -#if ENABLE_SVG_ICONS - if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0)) - return; -#endif // ENABLE_SVG_ICONS - - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - - unsigned int sprite_id = it->second->get_sprite_id(); - GLGizmoBase::EState state = it->second->get_state(); - -#if ENABLE_SVG_ICONS - float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width; - float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height; - float v_top = sprite_id * v_icon_size; - float u_left = state * u_icon_size; - float v_bottom = v_top + v_icon_size; - float u_right = u_left + u_icon_size; -#else - float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size; - float v_top = sprite_id * uv_icon_size; - float u_left = state * uv_icon_size; - float v_bottom = v_top + uv_icon_size; - float u_right = u_left + uv_icon_size; -#endif // ENABLE_SVG_ICONS - - GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); - if (it->second->get_state() == GLGizmoBase::On) { - float toolbar_top = (float)cnv_h - canvas.m_view_toolbar.get_height(); -#if ENABLE_SVG_ICONS - it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); -#else - it->second->render_input_window(2.0f * m_overlay_border + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); -#endif // ENABLE_SVG_ICONS - } -#if ENABLE_SVG_ICONS - top_y -= scaled_stride_y; -#else - top_y -= (scaled_icons_size + scaled_gap_y); -#endif // ENABLE_SVG_ICONS - } -} - -void GLCanvas3D::Gizmos::do_render_current_gizmo(const Selection& selection) const -{ - GLGizmoBase* curr = get_current(); - if (curr != nullptr) - curr->render(selection); -} - -float GLCanvas3D::Gizmos::get_total_overlay_height() const -{ -#if ENABLE_SVG_ICONS - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float height = 2.0f * scaled_border; -#else - float height = 2.0f * m_overlay_border; - - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS - - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - -#if ENABLE_SVG_ICONS - height += scaled_stride_y; -#else - height += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS - } - -#if ENABLE_SVG_ICONS - return height - scaled_gap_y; -#else - return height - m_overlay_gap_y; -#endif // ENABLE_SVG_ICONS -} - -float GLCanvas3D::Gizmos::get_total_overlay_width() const -{ -#if ENABLE_SVG_ICONS - return (2.0f * m_overlay_border + m_overlay_icons_size) * m_overlay_scale; -#else - return (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale + 2.0f * m_overlay_border; -#endif // ENABLE_SVG_ICONS -} - -GLGizmoBase* GLCanvas3D::Gizmos::get_current() const -{ - GizmosMap::const_iterator it = m_gizmos.find(m_current); - return (it != m_gizmos.end()) ? it->second : nullptr; -} - -#if ENABLE_SVG_ICONS -bool GLCanvas3D::Gizmos::generate_icons_texture() const -{ - std::string path = resources_dir() + "/icons/"; - std::vector filenames; - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if (it->second != nullptr) - { - const std::string& icon_filename = it->second->get_icon_filename(); - if (!icon_filename.empty()) - filenames.push_back(path + icon_filename); - } - } - - std::vector> states; - states.push_back(std::make_pair(1, false)); - states.push_back(std::make_pair(0, false)); - states.push_back(std::make_pair(0, true)); - - bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_overlay_icons_size * m_overlay_scale)); - if (res) - m_icons_texture_dirty = false; - - return res; -} -#endif // ENABLE_SVG_ICONS - const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 120, 120, 120 };//{ 9, 91, 134 }; const unsigned char GLCanvas3D::WarningTexture::Opacity = 255; @@ -3100,7 +2169,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'a': case 'A': case WXK_CONTROL_A: - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::SelectAll)) // Sla gizmo selects all support points + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::SelectAll)) // Sla gizmo selects all support points m_dirty = true; else post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); @@ -3120,14 +2189,14 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) { // key ESC case WXK_ESCAPE: { - if (m_gizmos.get_current_type() != Gizmos::SlaSupports || !m_gizmos.mouse_event(SLAGizmoEventType::DiscardChanges)) + if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports || !m_gizmos.mouse_event(SLAGizmoEventType::DiscardChanges)) m_gizmos.reset_all_states(); m_dirty = true; break; } case WXK_RETURN: { - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::ApplyChanges)) + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::ApplyChanges)) m_dirty = true; break; } @@ -3137,8 +2206,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #else /* __APPLE__ */ case WXK_DELETE: #endif /* __APPLE__ */ - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::Delete)) - m_dirty = true; + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::Delete)) + m_dirty = true; else post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; @@ -3155,7 +2224,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; } case 'A': case 'a': { - if (m_gizmos.get_current_type() == Gizmos::SlaSupports) { + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports) { if (m_gizmos.mouse_event(SLAGizmoEventType::AutomaticGeneration)) m_dirty = true; } @@ -3173,7 +2242,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; } case 'M': case 'm': { - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::ManualEditing)) { + if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::ManualEditing)) { m_dirty = true; break; } @@ -3207,7 +2276,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) // Enable switching between 3D and Preview with Tab // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux post_event(SimpleEvent(EVT_GLCANVAS_TAB)); - } else if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) { + } else if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) { // shift has been just released - SLA gizmo might want to close rectangular selection. m_dirty = true; } @@ -3409,7 +2478,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.position = Vec2d(-1.0, -1.0); m_dirty = true; } - else if (evt.LeftDClick() && (m_gizmos.get_current_type() != Gizmos::Undefined)) + else if (evt.LeftDClick() && (m_gizmos.get_current_type() != GLGizmosManager::Undefined)) { m_mouse.ignore_up_event = true; } @@ -3443,7 +2512,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _update_gizmos_data(); m_dirty = true; } - else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) + else if (evt.LeftDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) { // the gizmo got the event and took some action, there is no need to do anything more } @@ -3453,7 +2522,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.start_dragging(); m_gizmos.start_dragging(m_selection); - if (m_gizmos.get_current_type() == Gizmos::Flatten) { + if (m_gizmos.get_current_type() == GLGizmosManager::Flatten) { // Rotate the object so the normal points downward: m_selection.flattening_rotate(m_gizmos.get_flattening_normal()); do_flatten(); @@ -3462,7 +2531,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } - else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::RightDown)) + else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.mouse_event(SLAGizmoEventType::RightDown)) { // event was taken care of by the SlaSupports gizmo } @@ -3526,7 +2595,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) - && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != Gizmos::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) + && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) { if (!m_mouse.drag.move_requires_threshold) { @@ -3589,21 +2658,21 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) switch (m_gizmos.get_current_type()) { - case Gizmos::Move: + case GLGizmosManager::Move: { // Apply new temporary offset m_selection.translate(m_gizmos.get_displacement()); wxGetApp().obj_manipul()->update_settings_value(m_selection); break; } - case Gizmos::Scale: + case GLGizmosManager::Scale: { // Apply new temporary scale factors m_selection.scale(m_gizmos.get_scale(), evt.AltDown()); wxGetApp().obj_manipul()->update_settings_value(m_selection); break; } - case Gizmos::Rotate: + case GLGizmosManager::Rotate: { // Apply new temporary rotations TransformationType transformation_type(TransformationType::World_Relative_Joint); @@ -3619,7 +2688,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } - else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) + else if (evt.Dragging() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && evt.ShiftDown() && m_gizmos.mouse_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) { // the gizmo got the event and took some action, no need to do anything more here m_dirty = true; @@ -3671,12 +2740,12 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _stop_timer(); m_layers_editing.accept_changes(*this); } - else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports && !m_gizmos.is_dragging() - && !m_mouse.dragging && m_gizmos.mouse_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown())) + else if (evt.LeftUp() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && !m_gizmos.is_dragging() + && !m_mouse.dragging && m_gizmos.mouse_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown())) { // the gizmo got the event and took some action, no need to do anything more } - else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging && m_gizmos.get_current_type() != Gizmos::SlaSupports) + else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports) { m_regenerate_volumes = false; do_move(); @@ -3686,7 +2755,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() - && !is_layers_editing_enabled() && (m_gizmos.get_current_type() != Gizmos::SlaSupports || !m_gizmos.mouse_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown()))) + && !is_layers_editing_enabled() && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports || !m_gizmos.mouse_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown()))) { // SLA gizmo cannot be deselected by clicking in canvas area to avoid inadvertent unselection and losing manual changes // that's why the mouse_event function was called so that the gizmo can refuse the deselection in manual editing mode @@ -3707,18 +2776,18 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { switch (m_gizmos.get_current_type()) { - case Gizmos::Move: + case GLGizmosManager::Move: { m_regenerate_volumes = false; do_move(); break; } - case Gizmos::Scale: + case GLGizmosManager::Scale: { do_scale(); break; } - case Gizmos::Rotate: + case GLGizmosManager::Rotate: { do_rotate(); break; @@ -3746,7 +2815,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // if right clicking on volume, propagate event through callback (shows context menu) if (m_volumes.volumes[m_hover_volume_id]->hover && !m_volumes.volumes[m_hover_volume_id]->is_wipe_tower // no context menu for the wipe tower - && m_gizmos.get_current_type() != Gizmos::SlaSupports) // disable context menu when the gizmo is open + && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports) // disable context menu when the gizmo is open { // forces the selection of the volume m_selection.add(m_hover_volume_id); @@ -5058,11 +4127,11 @@ void GLCanvas3D::_update_gizmos_data() return; bool enable_move_z = !m_selection.is_wipe_tower(); - m_gizmos.enable_grabber(Gizmos::Move, 2, enable_move_z); + m_gizmos.enable_grabber(GLGizmosManager::Move, 2, enable_move_z); bool enable_scale_xyz = m_selection.is_single_full_instance() || m_selection.is_single_volume() || m_selection.is_single_modifier(); for (int i = 0; i < 6; ++i) { - m_gizmos.enable_grabber(Gizmos::Scale, i, enable_scale_xyz); + m_gizmos.enable_grabber(GLGizmosManager::Scale, i, enable_scale_xyz); } if (m_selection.is_single_full_instance()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 4cbabc4384..bc9932e75d 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -10,6 +10,7 @@ #include "3DBed.hpp" #include "Camera.hpp" #include "Selection.hpp" +#include "Gizmos/GLGizmosManager.hpp" #include @@ -64,33 +65,6 @@ public: void set_scale_factor(int height); }; -class Rect -{ - float m_left; - float m_top; - float m_right; - float m_bottom; - -public: - Rect(); - Rect(float left, float top, float right, float bottom); - - float get_left() const; - void set_left(float left); - - float get_top() const; - void set_top(float top); - - float get_right() const; - void set_right(float right); - - float get_bottom() const; - void set_bottom(float bottom); - - float get_width() const { return m_right - m_left; } - float get_height() const { return m_top - m_bottom; } -}; - wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent); using Vec2dEvent = Event; @@ -117,22 +91,6 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); -// this describes events being passed from GLCanvas3D to SlaSupport gizmo -enum class SLAGizmoEventType { - LeftDown = 1, - LeftUp, - RightDown, - Dragging, - Delete, - SelectAll, - ShiftUp, - ApplyChanges, - DiscardChanges, - AutomaticGeneration, - ManualEditing -}; - - class GLCanvas3D { struct GCodePreviewVolumeIndex @@ -357,119 +315,6 @@ public: }; private: - class Gizmos - { - public: -#if ENABLE_SVG_ICONS - static const float Default_Icons_Size; -#endif // ENABLE_SVG_ICONS - - enum EType : unsigned char - { - Undefined, - Move, - Scale, - Rotate, - Flatten, - Cut, - SlaSupports, - Num_Types - }; - - private: - bool m_enabled; - typedef std::map GizmosMap; - GizmosMap m_gizmos; -#if ENABLE_SVG_ICONS - mutable GLTexture m_icons_texture; - mutable bool m_icons_texture_dirty; -#else - ItemsIconsTexture m_icons_texture; -#endif // ENABLE_SVG_ICONS - BackgroundTexture m_background_texture; - EType m_current; - -#if ENABLE_SVG_ICONS - float m_overlay_icons_size; - float m_overlay_scale; -#else - float m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS - float m_overlay_border; - float m_overlay_gap_y; - - public: - Gizmos(); - ~Gizmos(); - - bool init(GLCanvas3D& parent); - - bool is_enabled() const; - void set_enabled(bool enable); - -#if ENABLE_SVG_ICONS - void set_overlay_icon_size(float size); -#endif // ENABLE_SVG_ICONS - void set_overlay_scale(float scale); - - std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); - void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); - void update_on_off_state(const Selection& selection); - void reset_all_states(); - - void set_hover_id(int id); - void enable_grabber(EType type, unsigned int id, bool enable); - - bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; - bool grabber_contains_mouse() const; - void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr); - Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; - EType get_current_type() const; - - bool is_running() const; - bool handle_shortcut(int key, const Selection& selection); - - bool is_dragging() const; - void start_dragging(const Selection& selection); - void stop_dragging(); - - Vec3d get_displacement() const; - - Vec3d get_scale() const; - void set_scale(const Vec3d& scale); - - Vec3d get_rotation() const; - void set_rotation(const Vec3d& rotation); - - Vec3d get_flattening_normal() const; - - void set_flattening_data(const ModelObject* model_object); - - void set_sla_support_data(ModelObject* model_object, const Selection& selection); - bool mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); - void delete_current_grabber(bool delete_all = false); - - void render_current_gizmo(const Selection& selection) const; - void render_current_gizmo_for_picking_pass(const Selection& selection) const; - - void render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; - - private: - void reset(); - - void do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; - void do_render_current_gizmo(const Selection& selection) const; - - float get_total_overlay_height() const; - float get_total_overlay_width() const; - - GLGizmoBase* get_current() const; - -#if ENABLE_SVG_ICONS - bool generate_icons_texture() const; -#endif // ENABLE_SVG_ICONS - }; - struct SlaCap { struct Triangles @@ -557,7 +402,7 @@ private: LayersEditing m_layers_editing; Shader m_shader; Mouse m_mouse; - mutable Gizmos m_gizmos; + mutable GLGizmosManager m_gizmos; mutable GLToolbar m_toolbar; ClippingPlane m_clipping_planes[2]; bool m_use_clipping_planes; @@ -715,6 +560,8 @@ public: void update_ui_from_settings(); + float get_view_toolbar_height() const { return m_view_toolbar.get_height(); } + private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 1e12674ec8..ee22b994f6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -1,4 +1,5 @@ #include "GLGizmoBase.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index b70c1f8df1..461f655702 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -3,7 +3,6 @@ #include "libslic3r/Point.hpp" -#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/Selection.hpp" diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index e228706c05..30cc1527fe 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -1,5 +1,6 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoCut.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index cd7e3b9858..8ac2405ec4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -1,5 +1,6 @@ // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. #include "GLGizmoSlaSupports.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" #include diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index c27ff0b6d7..8edfbe2cb3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -2,6 +2,7 @@ #define slic3r_GLGizmoSlaSupports_hpp_ #include "GLGizmoBase.hpp" +#include "GLGizmos.hpp" // There is an L function in igl that would be overridden by our localization macro - let's undefine it... #undef L diff --git a/src/slic3r/GUI/Gizmos/GLGizmos.hpp b/src/slic3r/GUI/Gizmos/GLGizmos.hpp index 8c5e25669d..c45b7648db 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmos.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmos.hpp @@ -1,6 +1,21 @@ #ifndef slic3r_GLGizmos_hpp_ #define slic3r_GLGizmos_hpp_ +// this describes events being passed from GLCanvas3D to SlaSupport gizmo +enum class SLAGizmoEventType { + LeftDown = 1, + LeftUp, + RightDown, + Dragging, + Delete, + SelectAll, + ShiftUp, + ApplyChanges, + DiscardChanges, + AutomaticGeneration, + ManualEditing +}; + #include "slic3r/GUI/Gizmos/GLGizmoMove.hpp" #include "slic3r/GUI/Gizmos/GLGizmoScale.hpp" #include "slic3r/GUI/Gizmos/GLGizmoRotate.hpp" diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp new file mode 100644 index 0000000000..0a7cacd30e --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -0,0 +1,865 @@ +#include "libslic3r/libslic3r.h" +#include "GLGizmosManager.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/3DScene.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +#if ENABLE_SVG_ICONS + const float GLGizmosManager::Default_Icons_Size = 64; +#endif // ENABLE_SVG_ICONS + +GLGizmosManager::GLGizmosManager() + : m_enabled(false) +#if ENABLE_SVG_ICONS + , m_icons_texture_dirty(true) +#endif // ENABLE_SVG_ICONS + , m_current(Undefined) +#if ENABLE_SVG_ICONS + , m_overlay_icons_size(Default_Icons_Size) + , m_overlay_scale(1.0f) + , m_overlay_border(5.0f) + , m_overlay_gap_y(5.0f) +{ +} +#else +{ + set_overlay_scale(1.0); +} +#endif // ENABLE_SVG_ICONS + +GLGizmosManager::~GLGizmosManager() +{ + reset(); +} + +bool GLGizmosManager::init(GLCanvas3D& parent) +{ +#if !ENABLE_SVG_ICONS + m_icons_texture.metadata.filename = "gizmos.png"; + m_icons_texture.metadata.icon_size = 64; + + if (!m_icons_texture.metadata.filename.empty()) + { + if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false)) + { + reset(); + return false; + } + } +#endif // !ENABLE_SVG_ICONS + + m_background_texture.metadata.filename = "toolbar_background.png"; + m_background_texture.metadata.left = 16; + m_background_texture.metadata.top = 16; + m_background_texture.metadata.right = 16; + m_background_texture.metadata.bottom = 16; + + if (!m_background_texture.metadata.filename.empty()) + { + if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false)) + { + reset(); + return false; + } + } + +#if ENABLE_SVG_ICONS + GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "move.svg", 0); +#else + GLGizmoBase* gizmo = new GLGizmoMove3D(parent, 0); +#endif // ENABLE_SVG_ICONS + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) + return false; + + m_gizmos.insert(GizmosMap::value_type(Move, gizmo)); + +#if ENABLE_SVG_ICONS + gizmo = new GLGizmoScale3D(parent, "scale.svg", 1); +#else + gizmo = new GLGizmoScale3D(parent, 1); +#endif // ENABLE_SVG_ICONS + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) + return false; + + m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); + +#if ENABLE_SVG_ICONS + gizmo = new GLGizmoRotate3D(parent, "rotate.svg", 2); +#else + gizmo = new GLGizmoRotate3D(parent, 2); +#endif // ENABLE_SVG_ICONS + if (gizmo == nullptr) + { + reset(); + return false; + } + + if (!gizmo->init()) + { + reset(); + return false; + } + + m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); + +#if ENABLE_SVG_ICONS + gizmo = new GLGizmoFlatten(parent, "place.svg", 3); +#else + gizmo = new GLGizmoFlatten(parent, 3); +#endif // ENABLE_SVG_ICONS + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) { + reset(); + return false; + } + + m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); + +#if ENABLE_SVG_ICONS + gizmo = new GLGizmoCut(parent, "cut.svg", 4); +#else + gizmo = new GLGizmoCut(parent, 4); +#endif // ENABLE_SVG_ICONS + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) { + reset(); + return false; + } + + m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); + +#if ENABLE_SVG_ICONS + gizmo = new GLGizmoSlaSupports(parent, "sla_supports.svg", 5); +#else + gizmo = new GLGizmoSlaSupports(parent, 5); +#endif // ENABLE_SVG_ICONS + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) { + reset(); + return false; + } + + m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo)); + + return true; +} + +#if ENABLE_SVG_ICONS +void GLGizmosManager::set_overlay_icon_size(float size) +{ + if (m_overlay_icons_size != size) + { + m_overlay_icons_size = size; + m_icons_texture_dirty = true; + } +} +#endif // ENABLE_SVG_ICONS + +void GLGizmosManager::set_overlay_scale(float scale) +{ +#if ENABLE_SVG_ICONS + if (m_overlay_scale != scale) + { + m_overlay_scale = scale; + m_icons_texture_dirty = true; + } +#else + m_overlay_icons_scale = scale; + m_overlay_border = 5.0f * scale; + m_overlay_gap_y = 5.0f * scale; +#endif // ENABLE_SVG_ICONS +} + +std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) +{ + std::string name = ""; + + if (!m_enabled) + return name; + + float cnv_h = (float)canvas.get_canvas_size().get_height(); + float height = get_total_overlay_height(); +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; + float scaled_border = m_overlay_border * m_overlay_scale; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + float top_y = 0.5f * (cnv_h - height) + scaled_border; +#else + float top_y = 0.5f * (cnv_h - height) + m_overlay_border; + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; +#endif // ENABLE_SVG_ICONS + + for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + +#if ENABLE_SVG_ICONS + bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +#else + bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +#endif // ENABLE_SVG_ICONS + if (inside) + name = it->second->get_name(); + + if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On)) + it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); + +#if ENABLE_SVG_ICONS + top_y += scaled_stride_y; +#else + top_y += (scaled_icons_size + m_overlay_gap_y); +#endif // ENABLE_SVG_ICONS + } + + return name; +} + +void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) +{ + if (!m_enabled) + return; + + float cnv_h = (float)canvas.get_canvas_size().get_height(); + float height = get_total_overlay_height(); + +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; + float scaled_border = m_overlay_border * m_overlay_scale; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + float top_y = 0.5f * (cnv_h - height) + scaled_border; +#else + float top_y = 0.5f * (cnv_h - height) + m_overlay_border; + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; +#endif // ENABLE_SVG_ICONS + + for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + +#if ENABLE_SVG_ICONS + bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +#else + bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +#endif // ENABLE_SVG_ICONS + if (it->second->is_activable(selection) && inside) + { + if ((it->second->get_state() == GLGizmoBase::On)) + { + it->second->set_state(GLGizmoBase::Hover); + m_current = Undefined; + } + else if ((it->second->get_state() == GLGizmoBase::Hover)) + { + it->second->set_state(GLGizmoBase::On); + m_current = it->first; + } + } + else + it->second->set_state(GLGizmoBase::Off); + +#if ENABLE_SVG_ICONS + top_y += scaled_stride_y; +#else + top_y += (scaled_icons_size + m_overlay_gap_y); +#endif // ENABLE_SVG_ICONS + } + + GizmosMap::iterator it = m_gizmos.find(m_current); + if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) + it->second->set_state(GLGizmoBase::On); +} + +void GLGizmosManager::update_on_off_state(const Selection& selection) +{ + GizmosMap::iterator it = m_gizmos.find(m_current); + if ((it != m_gizmos.end()) && (it->second != nullptr)) + { + if (!it->second->is_activable(selection)) + { + it->second->set_state(GLGizmoBase::Off); + m_current = Undefined; + } + } +} + +void GLGizmosManager::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); + it->second->set_hover_id(-1); + } + } + + m_current = Undefined; +} + +void GLGizmosManager::set_hover_id(int id) +{ + if (!m_enabled) + return; + + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On)) + it->second->set_hover_id(id); + } +} + +void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(type); + if (it != m_gizmos.end()) + { + if (enable) + it->second->enable_grabber(id); + else + it->second->disable_grabber(id); + } +} + +bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const +{ + if (!m_enabled) + return false; + + float cnv_h = (float)canvas.get_canvas_size().get_height(); + float height = get_total_overlay_height(); + +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; + float scaled_border = m_overlay_border * m_overlay_scale; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + float top_y = 0.5f * (cnv_h - height) + scaled_border; +#else + float top_y = 0.5f * (cnv_h - height) + m_overlay_border; + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; +#endif // ENABLE_SVG_ICONS + + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + +#if ENABLE_SVG_ICONS + if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) +#else + if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) +#endif // ENABLE_SVG_ICONS + return true; + +#if ENABLE_SVG_ICONS + top_y += scaled_stride_y; +#else + top_y += (scaled_icons_size + m_overlay_gap_y); +#endif // ENABLE_SVG_ICONS + } + + return false; +} + +bool GLGizmosManager::grabber_contains_mouse() const +{ + if (!m_enabled) + return false; + + GLGizmoBase* curr = get_current(); + return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; +} + +void GLGizmosManager::update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos) +{ + if (!m_enabled) + return; + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection); +} + +bool GLGizmosManager::is_running() const +{ + if (!m_enabled) + return false; + + GLGizmoBase* curr = get_current(); + return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; +} + +bool GLGizmosManager::handle_shortcut(int key, const Selection& selection) +{ + if (!m_enabled || selection.is_empty()) + return false; + + EType old_current = m_current; + bool handled = false; + for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + + int it_key = it->second->get_shortcut_key(); + + if (it->second->is_activable(selection) && ((it_key == key - 64) || (it_key == key - 96))) + { + if ((it->second->get_state() == GLGizmoBase::On)) + { + it->second->set_state(GLGizmoBase::Off); + m_current = Undefined; + handled = true; + } + else if ((it->second->get_state() == GLGizmoBase::Off)) + { + it->second->set_state(GLGizmoBase::On); + m_current = it->first; + handled = true; + } + } + } + + if (handled && (old_current != Undefined) && (old_current != m_current)) + { + GizmosMap::const_iterator it = m_gizmos.find(old_current); + if (it != m_gizmos.end()) + it->second->set_state(GLGizmoBase::Off); + } + + return handled; +} + +bool GLGizmosManager::is_dragging() const +{ + if (!m_enabled) + return false; + + GLGizmoBase* curr = get_current(); + return (curr != nullptr) ? curr->is_dragging() : false; +} + +void GLGizmosManager::start_dragging(const Selection& selection) +{ + if (!m_enabled) + return; + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + curr->start_dragging(selection); +} + +void GLGizmosManager::stop_dragging() +{ + if (!m_enabled) + return; + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + curr->stop_dragging(); +} + +Vec3d GLGizmosManager::get_displacement() const +{ + if (!m_enabled) + return Vec3d::Zero(); + + GizmosMap::const_iterator it = m_gizmos.find(Move); + return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_displacement() : Vec3d::Zero(); +} + +Vec3d GLGizmosManager::get_scale() const +{ + if (!m_enabled) + return Vec3d::Ones(); + + GizmosMap::const_iterator it = m_gizmos.find(Scale); + return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale() : Vec3d::Ones(); +} + +void GLGizmosManager::set_scale(const Vec3d& scale) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(Scale); + if (it != m_gizmos.end()) + reinterpret_cast(it->second)->set_scale(scale); +} + +Vec3d GLGizmosManager::get_rotation() const +{ + if (!m_enabled) + return Vec3d::Zero(); + + GizmosMap::const_iterator it = m_gizmos.find(Rotate); + return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_rotation() : Vec3d::Zero(); +} + +void GLGizmosManager::set_rotation(const Vec3d& rotation) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(Rotate); + if (it != m_gizmos.end()) + reinterpret_cast(it->second)->set_rotation(rotation); +} + +Vec3d GLGizmosManager::get_flattening_normal() const +{ + if (!m_enabled) + return Vec3d::Zero(); + + GizmosMap::const_iterator it = m_gizmos.find(Flatten); + return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_flattening_normal() : Vec3d::Zero(); +} + +void GLGizmosManager::set_flattening_data(const ModelObject* model_object) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(Flatten); + if (it != m_gizmos.end()) + reinterpret_cast(it->second)->set_flattening_data(model_object); +} + +void GLGizmosManager::set_sla_support_data(ModelObject* model_object, const Selection& selection) +{ + if (!m_enabled) + return; + + GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); + if (it != m_gizmos.end()) + reinterpret_cast(it->second)->set_sla_support_data(model_object, selection); +} + +// Returns true if the gizmo used the event to do something, false otherwise. +bool GLGizmosManager::mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down) +{ + if (!m_enabled) + return false; + + GizmosMap::const_iterator it = m_gizmos.find(SlaSupports); + if (it != m_gizmos.end()) + return reinterpret_cast(it->second)->mouse_event(action, mouse_position, shift_down); + + return false; +} + +void GLGizmosManager::render_current_gizmo(const Selection& selection) const +{ + if (!m_enabled) + return; + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + curr->render(selection); +} + +void GLGizmosManager::render_current_gizmo_for_picking_pass(const Selection& selection) const +{ + if (!m_enabled) + return; + + GLGizmoBase* curr = get_current(); + if (curr != nullptr) + curr->render_for_picking(selection); +} + +void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& selection) const +{ + if (!m_enabled) + return; + +#if ENABLE_SVG_ICONS + if (m_icons_texture_dirty) + generate_icons_texture(); +#endif // ENABLE_SVG_ICONS + + glsafe(::glDisable(GL_DEPTH_TEST)); + + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); + + do_render_overlay(canvas, selection); + + glsafe(::glPopMatrix()); +} + +void GLGizmosManager::reset() +{ + for (GizmosMap::value_type& gizmo : m_gizmos) + { + delete gizmo.second; + gizmo.second = nullptr; + } + + m_gizmos.clear(); +} + +void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const +{ + if (m_gizmos.empty()) + return; + + 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 inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + float height = get_total_overlay_height(); + float width = get_total_overlay_width(); +#if ENABLE_SVG_ICONS + float scaled_border = m_overlay_border * m_overlay_scale * inv_zoom; +#else + float scaled_border = m_overlay_border * inv_zoom; +#endif // ENABLE_SVG_ICONS + + float top_x = (-0.5f * cnv_w) * inv_zoom; + float top_y = (0.5f * height) * inv_zoom; + + float left = top_x; + float top = top_y; + float right = left + width * inv_zoom; + float bottom = top - height * inv_zoom; + + // renders background + unsigned int bg_tex_id = m_background_texture.texture.get_id(); + float bg_tex_width = (float)m_background_texture.texture.get_width(); + float bg_tex_height = (float)m_background_texture.texture.get_height(); + if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0)) + { + float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f; + float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f; + + float bg_uv_left = 0.0f; + float bg_uv_right = 1.0f; + float bg_uv_top = 1.0f; + float bg_uv_bottom = 0.0f; + + float bg_left = left; + float bg_right = right; + float bg_top = top; + float bg_bottom = bottom; + float bg_width = right - left; + float bg_height = top - bottom; + float bg_min_size = std::min(bg_width, bg_height); + + float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width; + float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width; + float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height; + float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height; + + float bg_i_left = bg_left + scaled_border; + float bg_i_right = bg_right - scaled_border; + float bg_i_top = bg_top - scaled_border; + float bg_i_bottom = bg_bottom + scaled_border; + + bg_uv_left = bg_uv_i_left; + bg_i_left = bg_left; + + if ((m_overlay_border > 0) && (bg_uv_top != bg_uv_i_top)) + { + if (bg_uv_left != bg_uv_i_left) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } }); + + if (bg_uv_right != bg_uv_i_right) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } }); + } + + if ((m_overlay_border > 0) && (bg_uv_left != bg_uv_i_left)) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } }); + + if ((m_overlay_border > 0) && (bg_uv_right != bg_uv_i_right)) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } }); + + if ((m_overlay_border > 0) && (bg_uv_bottom != bg_uv_i_bottom)) + { + if (bg_uv_left != bg_uv_i_left) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } }); + + if (bg_uv_right != bg_uv_i_right) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } }); + } + } + +#if ENABLE_SVG_ICONS + top_x += scaled_border; + top_y -= scaled_border; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale * inv_zoom; + + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + unsigned int icons_texture_id = m_icons_texture.get_id(); + unsigned int tex_width = m_icons_texture.get_width(); + unsigned int tex_height = m_icons_texture.get_height(); + float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f; + float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f; +#else + top_x += m_overlay_border * inv_zoom; + top_y -= m_overlay_border * inv_zoom; + float scaled_gap_y = m_overlay_gap_y * inv_zoom; + + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale * inv_zoom; + unsigned int icons_texture_id = m_icons_texture.texture.get_id(); + unsigned int texture_size = m_icons_texture.texture.get_width(); + float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f; +#endif // ENABLE_SVG_ICONS + +#if ENABLE_SVG_ICONS + if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0)) + return; +#endif // ENABLE_SVG_ICONS + + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + + unsigned int sprite_id = it->second->get_sprite_id(); + GLGizmoBase::EState state = it->second->get_state(); + +#if ENABLE_SVG_ICONS + float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width; + float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height; + float v_top = sprite_id * v_icon_size; + float u_left = state * u_icon_size; + float v_bottom = v_top + v_icon_size; + float u_right = u_left + u_icon_size; +#else + float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size; + float v_top = sprite_id * uv_icon_size; + float u_left = state * uv_icon_size; + float v_bottom = v_top + uv_icon_size; + float u_right = u_left + uv_icon_size; +#endif // ENABLE_SVG_ICONS + + GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); + if (it->second->get_state() == GLGizmoBase::On) { + float toolbar_top = (float)cnv_h - canvas.get_view_toolbar_height(); +#if ENABLE_SVG_ICONS + it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); +#else + it->second->render_input_window(2.0f * m_overlay_border + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection); +#endif // ENABLE_SVG_ICONS + } +#if ENABLE_SVG_ICONS + top_y -= scaled_stride_y; +#else + top_y -= (scaled_icons_size + scaled_gap_y); +#endif // ENABLE_SVG_ICONS + } +} + +float GLGizmosManager::get_total_overlay_height() const +{ +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; + float scaled_border = m_overlay_border * m_overlay_scale; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + float height = 2.0f * scaled_border; +#else + float height = 2.0f * m_overlay_border; + + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; +#endif // ENABLE_SVG_ICONS + + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + +#if ENABLE_SVG_ICONS + height += scaled_stride_y; +#else + height += (scaled_icons_size + m_overlay_gap_y); +#endif // ENABLE_SVG_ICONS + } + +#if ENABLE_SVG_ICONS + return height - scaled_gap_y; +#else + return height - m_overlay_gap_y; +#endif // ENABLE_SVG_ICONS +} + +float GLGizmosManager::get_total_overlay_width() const +{ +#if ENABLE_SVG_ICONS + return (2.0f * m_overlay_border + m_overlay_icons_size) * m_overlay_scale; +#else + return (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale + 2.0f * m_overlay_border; +#endif // ENABLE_SVG_ICONS +} + +GLGizmoBase* GLGizmosManager::get_current() const +{ + GizmosMap::const_iterator it = m_gizmos.find(m_current); + return (it != m_gizmos.end()) ? it->second : nullptr; +} + +#if ENABLE_SVG_ICONS +bool GLGizmosManager::generate_icons_texture() const +{ + std::string path = resources_dir() + "/icons/"; + std::vector filenames; + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if (it->second != nullptr) + { + const std::string& icon_filename = it->second->get_icon_filename(); + if (!icon_filename.empty()) + filenames.push_back(path + icon_filename); + } + } + + std::vector> states; + states.push_back(std::make_pair(1, false)); + states.push_back(std::make_pair(0, false)); + states.push_back(std::make_pair(0, true)); + + bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_overlay_icons_size * m_overlay_scale)); + if (res) + m_icons_texture_dirty = false; + + return res; +} +#endif // ENABLE_SVG_ICONS + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp new file mode 100644 index 0000000000..0dcb9c774d --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -0,0 +1,160 @@ +#ifndef slic3r_GUI_GLGizmosManager_hpp_ +#define slic3r_GUI_GLGizmosManager_hpp_ + +#include "slic3r/GUI/GLTexture.hpp" +#include "slic3r/GUI/GLToolbar.hpp" +#include "slic3r/GUI/Gizmos/GLGizmos.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +class Selection; +class GLGizmoBase; +class GLCanvas3D; + +class Rect +{ + float m_left; + float m_top; + float m_right; + float m_bottom; + +public: + Rect() : m_left(0.0f) , m_top(0.0f) , m_right(0.0f) , m_bottom(0.0f) {} + + Rect::Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {} + + float get_left() const { return m_left; } + void set_left(float left) { m_left = left; } + + float get_top() const { return m_top; } + void set_top(float top) { m_top = top; } + + float get_right() const { return m_right; } + void set_right(float right) { m_right = right; } + + float get_bottom() const { return m_bottom; } + void set_bottom(float bottom) { m_bottom = bottom; } + + float get_width() const { return m_right - m_left; } + float get_height() const { return m_top - m_bottom; } +}; + +class GLGizmosManager +{ +public: +#if ENABLE_SVG_ICONS + static const float Default_Icons_Size; +#endif // ENABLE_SVG_ICONS + + enum EType : unsigned char + { + Undefined, + Move, + Scale, + Rotate, + Flatten, + Cut, + SlaSupports, + Num_Types + }; + +private: + bool m_enabled; + typedef std::map GizmosMap; + GizmosMap m_gizmos; +#if ENABLE_SVG_ICONS + mutable GLTexture m_icons_texture; + mutable bool m_icons_texture_dirty; +#else + ItemsIconsTexture m_icons_texture; +#endif // ENABLE_SVG_ICONS + BackgroundTexture m_background_texture; + EType m_current; + +#if ENABLE_SVG_ICONS + float m_overlay_icons_size; + float m_overlay_scale; +#else + float m_overlay_icons_scale; +#endif // ENABLE_SVG_ICONS + float m_overlay_border; + float m_overlay_gap_y; + +public: + GLGizmosManager(); + ~GLGizmosManager(); + + bool init(GLCanvas3D& parent); + + bool is_enabled() const { return m_enabled; } + void set_enabled(bool enable) { m_enabled = enable; } + +#if ENABLE_SVG_ICONS + void set_overlay_icon_size(float size); +#endif // ENABLE_SVG_ICONS + void set_overlay_scale(float scale); + + std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); + void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); + void update_on_off_state(const Selection& selection); + void reset_all_states(); + + void set_hover_id(int id); + void enable_grabber(EType type, unsigned int id, bool enable); + + bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; + bool grabber_contains_mouse() const; + void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr); + Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; + EType get_current_type() const { return m_current; } + + bool is_running() const; + bool handle_shortcut(int key, const Selection& selection); + + bool is_dragging() const; + void start_dragging(const Selection& selection); + void stop_dragging(); + + Vec3d get_displacement() const; + + Vec3d get_scale() const; + void set_scale(const Vec3d& scale); + + Vec3d get_rotation() const; + void set_rotation(const Vec3d& rotation); + + Vec3d get_flattening_normal() const; + + void set_flattening_data(const ModelObject* model_object); + + void set_sla_support_data(ModelObject* model_object, const Selection& selection); + bool mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false); + void delete_current_grabber(bool delete_all = false); + + void render_current_gizmo(const Selection& selection) const; + void render_current_gizmo_for_picking_pass(const Selection& selection) const; + + void render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; + +private: + void reset(); + + void do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; + + float get_total_overlay_height() const; + float get_total_overlay_width() const; + + GLGizmoBase* get_current() const; + +#if ENABLE_SVG_ICONS + bool generate_icons_texture() const; +#endif // ENABLE_SVG_ICONS +}; + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GUI_GLGizmosManager_hpp_ From 9a2d7c881b517521f1d92d3c218e278b51e9f637 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 20 Mar 2019 14:14:21 +0100 Subject: [PATCH 02/61] Fixed typo --- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 0dcb9c774d..355ef12479 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -24,7 +24,7 @@ class Rect public: Rect() : m_left(0.0f) , m_top(0.0f) , m_right(0.0f) , m_bottom(0.0f) {} - Rect::Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {} + Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {} float get_left() const { return m_left; } void set_left(float left) { m_left = left; } From 83b24eee5b79bf4c323ce152f7fdc2d1a0b257c0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 20 Mar 2019 14:36:36 +0100 Subject: [PATCH 03/61] Added missing include --- src/slic3r/GUI/GLToolbar.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 07d1fcb92f..c7b018cfd8 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -7,6 +7,7 @@ #include "GLTexture.hpp" #include "Event.hpp" +#include "libslic3r/Point.hpp" class wxEvtHandler; From 024efd963ad599503e9ac8826e29176b182d3ddc Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 21 Mar 2019 11:02:10 +0100 Subject: [PATCH 04/61] Renamed private methods of Selection --- src/slic3r/GUI/3DScene.cpp | 1 + src/slic3r/GUI/Selection.cpp | 247 ++++++++++++++++++----------------- src/slic3r/GUI/Selection.hpp | 48 +++---- 3 files changed, 149 insertions(+), 147 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 419f1baae7..361d16bfe1 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -41,6 +41,7 @@ void glAssertRecentCallImpl() switch (err) { case GL_INVALID_ENUM: sErr = "Invalid Enum"; break; case GL_INVALID_VALUE: sErr = "Invalid Value"; break; + // be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin and the corresponding execution of glEnd case GL_INVALID_OPERATION: sErr = "Invalid Operation"; break; case GL_STACK_OVERFLOW: sErr = "Stack Overflow"; break; case GL_STACK_UNDERFLOW: sErr = "Stack Underflow"; break; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index e5d221a5f0..6967719768 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -6,6 +6,7 @@ #include "GUI_ObjectManipulation.hpp" #include "GUI_ObjectList.hpp" #include "Gizmos/GLGizmoBase.hpp" +#include "slic3r/GUI/3DScene.hpp" #include @@ -74,7 +75,7 @@ Selection::~Selection() void Selection::set_volumes(GLVolumePtrs* volumes) { m_volumes = volumes; - _update_valid(); + update_valid(); } bool Selection::init(bool useVBOs) @@ -94,7 +95,7 @@ bool Selection::init(bool useVBOs) void Selection::set_model(Model* model) { m_model = model; - _update_valid(); + update_valid(); } void Selection::add(unsigned int volume_idx, bool as_single_selection) @@ -128,18 +129,18 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection) case Volume: { if (volume->volume_idx() >= 0 && (is_empty() || (volume->instance_idx() == get_instance_idx()))) - _add_volume(volume_idx); + do_add_volume(volume_idx); break; } case Instance: { - _add_instance(volume->object_idx(), volume->instance_idx()); + do_add_instance(volume->object_idx(), volume->instance_idx()); break; } } - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -154,17 +155,17 @@ void Selection::remove(unsigned int volume_idx) { case Volume: { - _remove_volume(volume_idx); + do_remove_volume(volume_idx); break; } case Instance: { - _remove_instance(volume->object_idx(), volume->instance_idx()); + do_remove_instance(volume->object_idx(), volume->instance_idx()); break; } } - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -179,9 +180,9 @@ void Selection::add_object(unsigned int object_idx, bool as_single_selection) m_mode = Instance; - _add_object(object_idx); + do_add_object(object_idx); - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -190,9 +191,9 @@ void Selection::remove_object(unsigned int object_idx) if (!m_valid) return; - _remove_object(object_idx); + do_remove_object(object_idx); - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -207,9 +208,9 @@ void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx, m_mode = Instance; - _add_instance(object_idx, instance_idx); + do_add_instance(object_idx, instance_idx); - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -218,9 +219,9 @@ void Selection::remove_instance(unsigned int object_idx, unsigned int instance_i if (!m_valid) return; - _remove_instance(object_idx, instance_idx); + do_remove_instance(object_idx, instance_idx); - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -241,11 +242,11 @@ void Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, int if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx)) { if ((instance_idx != -1) && (v->instance_idx() == instance_idx)) - _add_volume(i); + do_add_volume(i); } } - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -258,10 +259,10 @@ void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx) { GLVolume* v = (*m_volumes)[i]; if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx)) - _remove_volume(i); + do_remove_volume(i); } - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -276,10 +277,10 @@ void Selection::add_all() for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { if (!(*m_volumes)[i]->is_wipe_tower) - _add_volume(i); + do_add_volume(i); } - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -295,7 +296,7 @@ void Selection::clear() m_list.clear(); - _update_type(); + update_type(); m_bounding_box_dirty = true; // resets the cache in the sidebar @@ -335,11 +336,11 @@ void Selection::volumes_changed(const std::vector &map_volume_old_to_new const GLVolume* volume = (*m_volumes)[i]; for (const std::pair &model_instance : model_instances) if (volume->object_idx() == model_instance.first && volume->instance_idx() == model_instance.second) - this->_add_volume(i); + do_add_volume(i); } } - _update_type(); + update_type(); m_bounding_box_dirty = true; } @@ -420,7 +421,7 @@ const GLVolume* Selection::get_volume(unsigned int volume_idx) const const BoundingBoxf3& Selection::get_bounding_box() const { if (m_bounding_box_dirty) - _calc_bounding_box(); + calc_bounding_box(); return m_bounding_box; } @@ -430,7 +431,7 @@ void Selection::start_dragging() if (!m_valid) return; - _set_caches(); + set_caches(); } void Selection::translate(const Vec3d& displacement, bool local) @@ -456,9 +457,9 @@ void Selection::translate(const Vec3d& displacement, bool local) #if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) - _synchronize_unselected_instances(SYNC_ROTATION_NONE); + synchronize_unselected_instances(SYNC_ROTATION_NONE); else if (m_mode == Volume) - _synchronize_unselected_volumes(); + synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; @@ -587,9 +588,9 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ #if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) - _synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL); + synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL); else if (m_mode == Volume) - _synchronize_unselected_volumes(); + synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; @@ -630,7 +631,7 @@ void Selection::flattening_rotate(const Vec3d& normal) // we want to synchronize z-rotation as well, otherwise the flattening behaves funny // when applied on one of several identical instances if (m_mode == Instance) - _synchronize_unselected_instances(SYNC_ROTATION_FULL); + synchronize_unselected_instances(SYNC_ROTATION_FULL); #endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; @@ -677,12 +678,12 @@ void Selection::scale(const Vec3d& scale, bool local) #if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) - _synchronize_unselected_instances(SYNC_ROTATION_NONE); + synchronize_unselected_instances(SYNC_ROTATION_NONE); else if (m_mode == Volume) - _synchronize_unselected_volumes(); + synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH - _ensure_on_bed(); + ensure_on_bed(); m_bounding_box_dirty = true; } @@ -704,9 +705,9 @@ void Selection::mirror(Axis axis) #if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) - _synchronize_unselected_instances(SYNC_ROTATION_NONE); + synchronize_unselected_instances(SYNC_ROTATION_NONE); else if (m_mode == Volume) - _synchronize_unselected_volumes(); + synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH m_bounding_box_dirty = true; @@ -924,8 +925,8 @@ void Selection::render(float scale_factor) const m_scale_factor = scale_factor; // render cumulative bounding box of selected volumes - _render_selected_volumes(); - _render_synchronized_volumes(); + render_selected_volumes(); + render_synchronized_volumes(); } #if ENABLE_RENDER_SELECTION_CENTER @@ -936,17 +937,17 @@ void Selection::render_center() const const Vec3d& center = get_bounding_box().center(); - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST))); - ::glEnable(GL_LIGHTING); + glsafe(::glEnable(GL_LIGHTING)); - ::glColor3f(1.0f, 1.0f, 1.0f); - ::glPushMatrix(); - ::glTranslated(center(0), center(1), center(2)); - ::gluSphere(m_quadric, 0.75, 32, 32); - ::glPopMatrix(); + glsafe(::glColor3f(1.0f, 1.0f, 1.0f)); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(center(0), center(1), center(2))); + glsafe(::gluSphere(m_quadric, 0.75, 32, 32)); + glsafe(::glPopMatrix()); - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); } #endif // ENABLE_RENDER_SELECTION_CENTER @@ -955,55 +956,55 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const if (sidebar_field.empty()) return; - ::glClear(GL_DEPTH_BUFFER_BIT); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_DEPTH_TEST)); - ::glEnable(GL_LIGHTING); + glsafe(::glEnable(GL_LIGHTING)); - ::glPushMatrix(); + glsafe(::glPushMatrix()); const Vec3d& center = get_bounding_box().center(); if (is_single_full_instance()) { - ::glTranslated(center(0), center(1), center(2)); + 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); - ::glMultMatrixd(orient_matrix.data()); + glsafe(::glMultMatrixd(orient_matrix.data())); } } else if (is_single_volume() || is_single_modifier()) { - ::glTranslated(center(0), center(1), center(2)); + 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); - ::glMultMatrixd(orient_matrix.data()); + glsafe(::glMultMatrixd(orient_matrix.data())); } else { - ::glTranslated(center(0), center(1), center(2)); + glsafe(::glTranslated(center(0), center(1), center(2))); if (requires_local_axes()) { Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - ::glMultMatrixd(orient_matrix.data()); + glsafe(::glMultMatrixd(orient_matrix.data())); } } if (boost::starts_with(sidebar_field, "position")) - _render_sidebar_position_hints(sidebar_field); + render_sidebar_position_hints(sidebar_field); else if (boost::starts_with(sidebar_field, "rotation")) - _render_sidebar_rotation_hints(sidebar_field); + render_sidebar_rotation_hints(sidebar_field); else if (boost::starts_with(sidebar_field, "scale")) - _render_sidebar_scale_hints(sidebar_field); + render_sidebar_scale_hints(sidebar_field); else if (boost::starts_with(sidebar_field, "size")) - _render_sidebar_size_hints(sidebar_field); + render_sidebar_size_hints(sidebar_field); - ::glPopMatrix(); + glsafe(::glPopMatrix()); - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); } bool Selection::requires_local_axes() const @@ -1011,12 +1012,12 @@ bool Selection::requires_local_axes() const return (m_mode == Volume) && is_from_single_instance(); } -void Selection::_update_valid() +void Selection::update_valid() { m_valid = (m_volumes != nullptr) && (m_model != nullptr); } -void Selection::_update_type() +void Selection::update_type() { m_cache.content.clear(); m_type = Mixed; @@ -1244,7 +1245,7 @@ void Selection::_update_type() #endif // ENABLE_SELECTION_DEBUG_OUTPUT } -void Selection::_set_caches() +void Selection::set_caches() { m_cache.volumes_data.clear(); for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) @@ -1255,33 +1256,33 @@ void Selection::_set_caches() m_cache.dragging_center = get_bounding_box().center(); } -void Selection::_add_volume(unsigned int volume_idx) +void Selection::do_add_volume(unsigned int volume_idx) { m_list.insert(volume_idx); (*m_volumes)[volume_idx]->selected = true; } -void Selection::_add_instance(unsigned int object_idx, unsigned int instance_idx) +void Selection::do_add_instance(unsigned int object_idx, unsigned int instance_idx) { for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { GLVolume* v = (*m_volumes)[i]; if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) - _add_volume(i); + do_add_volume(i); } } -void Selection::_add_object(unsigned int object_idx) +void Selection::do_add_object(unsigned int object_idx) { for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { GLVolume* v = (*m_volumes)[i]; if (v->object_idx() == object_idx) - _add_volume(i); + do_add_volume(i); } } -void Selection::_remove_volume(unsigned int volume_idx) +void Selection::do_remove_volume(unsigned int volume_idx) { IndicesList::iterator v_it = m_list.find(volume_idx); if (v_it == m_list.end()) @@ -1292,27 +1293,27 @@ void Selection::_remove_volume(unsigned int volume_idx) (*m_volumes)[volume_idx]->selected = false; } -void Selection::_remove_instance(unsigned int object_idx, unsigned int instance_idx) +void Selection::do_remove_instance(unsigned int object_idx, unsigned int instance_idx) { for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { GLVolume* v = (*m_volumes)[i]; if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) - _remove_volume(i); + do_remove_volume(i); } } -void Selection::_remove_object(unsigned int object_idx) +void Selection::do_remove_object(unsigned int object_idx) { for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { GLVolume* v = (*m_volumes)[i]; if (v->object_idx() == object_idx) - _remove_volume(i); + do_remove_volume(i); } } -void Selection::_calc_bounding_box() const +void Selection::calc_bounding_box() const { m_bounding_box = BoundingBoxf3(); if (m_valid) @@ -1325,13 +1326,13 @@ void Selection::_calc_bounding_box() const m_bounding_box_dirty = false; } -void Selection::_render_selected_volumes() const +void Selection::render_selected_volumes() const { float color[3] = { 1.0f, 1.0f, 1.0f }; - _render_bounding_box(get_bounding_box(), color); + render_bounding_box(get_bounding_box(), color); } -void Selection::_render_synchronized_volumes() const +void Selection::render_synchronized_volumes() const { if (m_mode == Instance) return; @@ -1353,12 +1354,12 @@ void Selection::_render_synchronized_volumes() const if ((v->object_idx() != object_idx) || (v->volume_idx() != volume_idx)) continue; - _render_bounding_box(v->transformed_convex_hull_bounding_box(), color); + render_bounding_box(v->transformed_convex_hull_bounding_box(), color); } } } -void Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) const +void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) const { if (color == nullptr) return; @@ -1367,10 +1368,10 @@ void Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) con Vec3f b_max = box.max.cast(); Vec3f size = 0.2f * box.size().cast(); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_DEPTH_TEST)); - ::glColor3fv(color); - ::glLineWidth(2.0f * m_scale_factor); + glsafe(::glColor3fv(color)); + glsafe(::glLineWidth(2.0f * m_scale_factor)); ::glBegin(GL_LINES); @@ -1406,102 +1407,102 @@ void Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) con ::glVertex3f(b_min(0), b_max(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1) - size(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1), b_max(2) - size(2)); - ::glEnd(); + glsafe(::glEnd()); } -void Selection::_render_sidebar_position_hints(const std::string& sidebar_field) const +void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const { if (boost::ends_with(sidebar_field, "x")) { - ::glRotated(-90.0, 0.0, 0.0, 1.0); - _render_sidebar_position_hint(X); + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + render_sidebar_position_hint(X); } else if (boost::ends_with(sidebar_field, "y")) - _render_sidebar_position_hint(Y); + render_sidebar_position_hint(Y); else if (boost::ends_with(sidebar_field, "z")) { - ::glRotated(90.0, 1.0, 0.0, 0.0); - _render_sidebar_position_hint(Z); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + render_sidebar_position_hint(Z); } } -void Selection::_render_sidebar_rotation_hints(const std::string& sidebar_field) const +void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const { if (boost::ends_with(sidebar_field, "x")) { - ::glRotated(90.0, 0.0, 1.0, 0.0); - _render_sidebar_rotation_hint(X); + glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); + render_sidebar_rotation_hint(X); } else if (boost::ends_with(sidebar_field, "y")) { - ::glRotated(-90.0, 1.0, 0.0, 0.0); - _render_sidebar_rotation_hint(Y); + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + render_sidebar_rotation_hint(Y); } else if (boost::ends_with(sidebar_field, "z")) - _render_sidebar_rotation_hint(Z); + render_sidebar_rotation_hint(Z); } -void Selection::_render_sidebar_scale_hints(const std::string& sidebar_field) const +void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const { bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); if (boost::ends_with(sidebar_field, "x") || uniform_scale) { - ::glPushMatrix(); - ::glRotated(-90.0, 0.0, 0.0, 1.0); - _render_sidebar_scale_hint(X); - ::glPopMatrix(); + glsafe(::glPushMatrix()); + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + render_sidebar_scale_hint(X); + glsafe(::glPopMatrix()); } if (boost::ends_with(sidebar_field, "y") || uniform_scale) { - ::glPushMatrix(); - _render_sidebar_scale_hint(Y); - ::glPopMatrix(); + glsafe(::glPushMatrix()); + render_sidebar_scale_hint(Y); + glsafe(::glPopMatrix()); } if (boost::ends_with(sidebar_field, "z") || uniform_scale) { - ::glPushMatrix(); - ::glRotated(90.0, 1.0, 0.0, 0.0); - _render_sidebar_scale_hint(Z); - ::glPopMatrix(); + glsafe(::glPushMatrix()); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + render_sidebar_scale_hint(Z); + glsafe(::glPopMatrix()); } } -void Selection::_render_sidebar_size_hints(const std::string& sidebar_field) const +void Selection::render_sidebar_size_hints(const std::string& sidebar_field) const { - _render_sidebar_scale_hints(sidebar_field); + render_sidebar_scale_hints(sidebar_field); } -void Selection::_render_sidebar_position_hint(Axis axis) const +void Selection::render_sidebar_position_hint(Axis axis) const { m_arrow.set_color(AXES_COLOR[axis], 3); m_arrow.render(); } -void Selection::_render_sidebar_rotation_hint(Axis axis) const +void Selection::render_sidebar_rotation_hint(Axis axis) const { m_curved_arrow.set_color(AXES_COLOR[axis], 3); m_curved_arrow.render(); - ::glRotated(180.0, 0.0, 0.0, 1.0); + glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); m_curved_arrow.render(); } -void Selection::_render_sidebar_scale_hint(Axis axis) const +void Selection::render_sidebar_scale_hint(Axis axis) const { m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); - ::glTranslated(0.0, 5.0, 0.0); + glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); - ::glTranslated(0.0, -10.0, 0.0); - ::glRotated(180.0, 0.0, 0.0, 1.0); + glsafe(::glTranslated(0.0, -10.0, 0.0)); + glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); m_arrow.render(); } -void Selection::_render_sidebar_size_hint(Axis axis, double length) const +void Selection::render_sidebar_size_hint(Axis axis, double length) const { } @@ -1542,7 +1543,7 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV } #endif /* NDEBUG */ -void Selection::_synchronize_unselected_instances(SyncRotationType sync_rotation_type) +void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_type) { std::set done; // prevent processing volumes twice done.insert(m_list.begin(), m_list.end()); @@ -1605,7 +1606,7 @@ void Selection::_synchronize_unselected_instances(SyncRotationType sync_rotation #endif /* NDEBUG */ } -void Selection::_synchronize_unselected_volumes() +void Selection::synchronize_unselected_volumes() { for (unsigned int i : m_list) { @@ -1638,7 +1639,7 @@ void Selection::_synchronize_unselected_volumes() } } -void Selection::_ensure_on_bed() +void Selection::ensure_on_bed() { typedef std::map, double> InstancesToZMap; InstancesToZMap instances_min_z; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 3a21122df5..ce374b060a 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -261,27 +261,27 @@ public: bool requires_local_axes() const; private: - void _update_valid(); - void _update_type(); - void _set_caches(); - void _add_volume(unsigned int volume_idx); - void _add_instance(unsigned int object_idx, unsigned int instance_idx); - void _add_object(unsigned int object_idx); - void _remove_volume(unsigned int volume_idx); - void _remove_instance(unsigned int object_idx, unsigned int instance_idx); - void _remove_object(unsigned int object_idx); - void _calc_bounding_box() const; - void _render_selected_volumes() const; - void _render_synchronized_volumes() const; - void _render_bounding_box(const BoundingBoxf3& box, float* color) const; - void _render_sidebar_position_hints(const std::string& sidebar_field) const; - void _render_sidebar_rotation_hints(const std::string& sidebar_field) const; - void _render_sidebar_scale_hints(const std::string& sidebar_field) const; - void _render_sidebar_size_hints(const std::string& sidebar_field) const; - void _render_sidebar_position_hint(Axis axis) const; - void _render_sidebar_rotation_hint(Axis axis) const; - void _render_sidebar_scale_hint(Axis axis) const; - void _render_sidebar_size_hint(Axis axis, double length) const; + void update_valid(); + void update_type(); + void set_caches(); + void do_add_volume(unsigned int volume_idx); + void do_add_instance(unsigned int object_idx, unsigned int instance_idx); + void do_add_object(unsigned int object_idx); + void do_remove_volume(unsigned int volume_idx); + void do_remove_instance(unsigned int object_idx, unsigned int instance_idx); + void do_remove_object(unsigned int object_idx); + void calc_bounding_box() const; + void render_selected_volumes() const; + void render_synchronized_volumes() const; + void render_bounding_box(const BoundingBoxf3& box, float* color) const; + void render_sidebar_position_hints(const std::string& sidebar_field) const; + void render_sidebar_rotation_hints(const std::string& sidebar_field) const; + void render_sidebar_scale_hints(const std::string& sidebar_field) const; + void render_sidebar_size_hints(const std::string& sidebar_field) const; + void render_sidebar_position_hint(Axis axis) const; + void render_sidebar_rotation_hint(Axis axis) const; + void render_sidebar_scale_hint(Axis axis) const; + void render_sidebar_size_hint(Axis axis, double length) const; enum SyncRotationType { // Do not synchronize rotation. Either not rotating at all, or rotating by world Z axis. SYNC_ROTATION_NONE = 0, @@ -290,9 +290,9 @@ private: // Synchronize after rotation by an axis not parallel with Z. SYNC_ROTATION_GENERAL = 2, }; - void _synchronize_unselected_instances(SyncRotationType sync_rotation_type); - void _synchronize_unselected_volumes(); - void _ensure_on_bed(); + void synchronize_unselected_instances(SyncRotationType sync_rotation_type); + void synchronize_unselected_volumes(); + void ensure_on_bed(); }; } // namespace GUI From a09197879d9b2958d9388aaff251d0c97c5a2b12 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Mar 2019 09:10:35 +0100 Subject: [PATCH 05/61] Code cleanup --- src/slic3r/GUI/GLCanvas3D.cpp | 109 +--------------------- src/slic3r/GUI/GLCanvas3D.hpp | 5 - src/slic3r/GUI/GLToolbar.cpp | 5 - src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 100 -------------------- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 12 --- 5 files changed, 1 insertion(+), 230 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e4f0f461e8..f8292cb4f7 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2016,10 +2016,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_selection.volumes_changed(map_glvolume_old_to_new); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Update the toolbar post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); @@ -2334,10 +2331,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) { if (m_gizmos.handle_shortcut(keyCode, m_selection)) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_dirty = true; } else @@ -2516,15 +2510,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) return; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - std::cout << to_string(m_mouse.position) << std::endl; - if (m_gizmos.on_mouse(evt, *this)) { m_mouse.set_start_position_3D_as_invalid(); return; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_picking_enabled) _set_current(); @@ -2532,9 +2522,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) int selected_object_idx = m_selection.get_object_idx(); int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1; m_layers_editing.select_object(*m_model, layer_editing_object_idx); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_mouse.drag.move_requires_threshold && m_mouse.is_move_start_threshold_position_2D_defined() && m_mouse.is_move_threshold_met(pos)) { @@ -2604,27 +2591,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (!m_selection.is_empty() && gizmos_overlay_contains_mouse) -// { -// m_gizmos.update_on_off_state(*this, m_mouse.position, m_selection); -// _update_gizmos_data(); -// m_dirty = true; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.LeftDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) -// else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // the gizmo got the event and took some action, there is no need to do anything more } else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_selection.start_dragging(); m_gizmos.start_dragging(m_selection); @@ -2637,10 +2610,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown)) -// else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown)) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // event was taken care of by the SlaSupports gizmo } @@ -2676,10 +2646,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { m_gizmos.update_on_off_state(m_selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_dirty = true; } @@ -2706,10 +2673,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) -// else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) { if (!m_mouse.drag.move_requires_threshold) @@ -2808,11 +2772,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // the gizmo got the event and took some action, no need to do anything more here m_dirty = true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.Dragging()) -// // do not process dragging if the mouse is into any of the HUD elements -// else if (evt.Dragging() && !gizmos_overlay_contains_mouse) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { m_mouse.dragging = true; @@ -2874,10 +2834,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !m_gizmos.is_dragging() -// else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ && !is_layers_editing_enabled()) { // deselect and propagate event through callback @@ -2887,10 +2844,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.set_mode(Selection::Instance); wxGetApp().obj_manipul()->update_settings_value(m_selection); m_gizmos.reset_all_states(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); } m_mouse.ignore_up_event = false; @@ -2919,10 +2873,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) break; } m_gizmos.stop_dragging(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().obj_manipul()->update_settings_value(m_selection); // Let the platter know that the dragging finished, so a delayed refresh @@ -2947,10 +2898,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.add(m_hover_volume_id); m_gizmos.update_on_off_state(m_selection); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().obj_manipul()->update_settings_value(m_selection); // forces a frame render to update the view before the context menu is shown render(); @@ -2980,16 +2928,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.position = pos.cast(); std::string tooltip = ""; - // updates gizmos overlay -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (tooltip.empty()) tooltip = m_gizmos.get_tooltip(); -// tooltip = m_gizmos.update_hover_state(*this, m_mouse.position, m_selection); -// if (m_selection.is_empty()) -// m_gizmos.reset_all_states(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - if (tooltip.empty()) tooltip = m_toolbar.get_tooltip(); @@ -2998,10 +2939,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) set_tooltip(tooltip); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // updates gizmos overlay if (m_selection.is_empty()) m_gizmos.reset_all_states(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor hovers over. if (m_picking_enabled) @@ -3310,10 +3250,7 @@ void GLCanvas3D::set_camera_zoom(float zoom) void GLCanvas3D::update_gizmos_on_off_state() { set_as_dirty(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); -// _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gizmos.update_on_off_state(get_selection()); } @@ -3348,7 +3285,6 @@ void GLCanvas3D::update_ui_from_settings() #endif } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::update_gizmos_data() { if (!m_gizmos.is_enabled()) @@ -3388,7 +3324,6 @@ void GLCanvas3D::update_gizmos_data() m_gizmos.set_sla_support_data(nullptr, m_selection); } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLCanvas3D::_is_shown_on_screen() const { @@ -4304,48 +4239,6 @@ void GLCanvas3D::_update_volumes_hover_state() const } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//void GLCanvas3D::_update_gizmos_data() -//{ -// if (!m_gizmos.is_enabled()) -// return; -// -// bool enable_move_z = !m_selection.is_wipe_tower(); -// m_gizmos.enable_grabber(GLGizmosManager::Move, 2, enable_move_z); -// bool enable_scale_xyz = m_selection.is_single_full_instance() || m_selection.is_single_volume() || m_selection.is_single_modifier(); -// for (int i = 0; i < 6; ++i) -// { -// m_gizmos.enable_grabber(GLGizmosManager::Scale, i, enable_scale_xyz); -// } -// -// if (m_selection.is_single_full_instance()) -// { -// // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first -// const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()]; -// m_gizmos.set_scale(volume->get_instance_scaling_factor()); -// m_gizmos.set_rotation(Vec3d::Zero()); -// ModelObject* model_object = m_model->objects[m_selection.get_object_idx()]; -// m_gizmos.set_flattening_data(model_object); -// m_gizmos.set_sla_support_data(model_object, m_selection); -// } -// else if (m_selection.is_single_volume() || m_selection.is_single_modifier()) -// { -// const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()]; -// m_gizmos.set_scale(volume->get_volume_scaling_factor()); -// m_gizmos.set_rotation(Vec3d::Zero()); -// m_gizmos.set_flattening_data(nullptr); -// m_gizmos.set_sla_support_data(nullptr, m_selection); -// } -// else -// { -// m_gizmos.set_scale(Vec3d::Ones()); -// m_gizmos.set_rotation(Vec3d::Zero()); -// m_gizmos.set_flattening_data(m_selection.is_from_single_object() ? m_model->objects[m_selection.get_object_idx()] : nullptr); -// m_gizmos.set_sla_support_data(nullptr, m_selection); -// } -//} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt) { int object_idx_selected = m_layers_editing.last_object_id; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index f18c4a4f10..ce44062869 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -565,9 +565,7 @@ public: float get_view_toolbar_height() const { return m_view_toolbar.get_height(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: bool _is_shown_on_screen() const; @@ -608,9 +606,6 @@ private: void _render_selection_sidebar_hints() const; void _update_volumes_hover_state() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// void _update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _perform_layer_editing_action(wxMouseEvent* evt = nullptr); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index de3236fc8d..a485698b42 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -444,16 +444,11 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) { m_mouse_capture.left = true; m_mouse_capture.parent = &parent; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ processed = true; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if ((item_id != -2) && !m_items[item_id]->is_separator()) { // mouse is inside an icon do_action((unsigned int)item_id, parent); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// processed = true; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } else if (evt.MiddleDown()) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 9ac7af5163..bfef1c1d11 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -23,9 +23,7 @@ GLGizmosManager::GLGizmosManager() , m_overlay_scale(1.0f) , m_overlay_border(5.0f) , m_overlay_gap_y(5.0f) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ , m_tooltip("") -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { } #else @@ -189,54 +187,6 @@ void GLGizmosManager::set_overlay_scale(float scale) #endif // ENABLE_SVG_ICONS } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) -//{ -// std::string name = ""; -// -// if (!m_enabled) -// return name; -// -// float cnv_h = (float)canvas.get_canvas_size().get_height(); -// float height = get_total_overlay_height(); -//#if ENABLE_SVG_ICONS -// float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; -// float scaled_border = m_overlay_border * m_overlay_scale; -// float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; -// float scaled_stride_y = scaled_icons_size + scaled_gap_y; -// float top_y = 0.5f * (cnv_h - height) + scaled_border; -//#else -// float top_y = 0.5f * (cnv_h - height) + m_overlay_border; -// float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -//#endif // ENABLE_SVG_ICONS -// -// for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) -// { -// if ((it->second == nullptr) || !it->second->is_selectable()) -// continue; -// -//#if ENABLE_SVG_ICONS -// bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -//#else -// bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -//#endif // ENABLE_SVG_ICONS -// if (inside) -// name = it->second->get_name(); -// -// if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On)) -// it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off); -// -//#if ENABLE_SVG_ICONS -// top_y += scaled_stride_y; -//#else -// top_y += (scaled_icons_size + m_overlay_gap_y); -//#endif // ENABLE_SVG_ICONS -// } -// -// return name; -//} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) { if (!m_enabled) @@ -351,49 +301,6 @@ void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const -//{ -// if (!m_enabled) -// return false; -// -// float cnv_h = (float)canvas.get_canvas_size().get_height(); -// float height = get_total_overlay_height(); -// -//#if ENABLE_SVG_ICONS -// float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; -// float scaled_border = m_overlay_border * m_overlay_scale; -// float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; -// float scaled_stride_y = scaled_icons_size + scaled_gap_y; -// float top_y = 0.5f * (cnv_h - height) + scaled_border; -//#else -// float top_y = 0.5f * (cnv_h - height) + m_overlay_border; -// float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -//#endif // ENABLE_SVG_ICONS -// -// for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) -// { -// if ((it->second == nullptr) || !it->second->is_selectable()) -// continue; -// -//#if ENABLE_SVG_ICONS -// if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) -//#else -// if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size)) -//#endif // ENABLE_SVG_ICONS -// return true; -// -//#if ENABLE_SVG_ICONS -// top_y += scaled_stride_y; -//#else -// top_y += (scaled_icons_size + m_overlay_gap_y); -//#endif // ENABLE_SVG_ICONS -// } -// -// return false; -//} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - bool GLGizmosManager::grabber_contains_mouse() const { if (!m_enabled) @@ -621,14 +528,10 @@ void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& glsafe(::glPopMatrix()); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); - std::cout << to_string(mouse_pos) << std::endl; - - const Selection& selection = canvas.get_selection(); bool processed = false; @@ -691,7 +594,6 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) return processed; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLGizmosManager::reset() { @@ -940,7 +842,6 @@ bool GLGizmosManager::generate_icons_texture() const } #endif // ENABLE_SVG_ICONS -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos) { std::string name = ""; @@ -1029,7 +930,6 @@ bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec return false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index c280eda505..2a867314eb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -83,7 +83,6 @@ private: float m_overlay_border; float m_overlay_gap_y; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ struct MouseCapture { bool left; @@ -99,7 +98,6 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: GLGizmosManager(); @@ -115,9 +113,6 @@ public: #endif // ENABLE_SVG_ICONS void set_overlay_scale(float scale); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); void update_on_off_state(const Selection& selection); void reset_all_states(); @@ -125,9 +120,6 @@ public: void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool grabber_contains_mouse() const; void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr); Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; @@ -160,11 +152,9 @@ public: void render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string& get_tooltip() const { return m_tooltip; } bool on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: void reset(); @@ -180,10 +170,8 @@ private: bool generate_icons_texture() const; #endif // ENABLE_SVG_ICONS -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos); bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; } // namespace GUI From eafdcb04bada8a828e57c099ea2d7c5079e5988e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Mar 2019 12:30:17 +0100 Subject: [PATCH 06/61] Handling of gizmos related mouse events moved into GLGizmosManager::on_mouse() --- src/slic3r/GUI/GLCanvas3D.cpp | 361 +++++++++++++--------- src/slic3r/GUI/GLCanvas3D.hpp | 22 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 345 +++++++++++++++++---- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 19 +- 4 files changed, 535 insertions(+), 212 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f8292cb4f7..25abf1dc7c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -675,7 +675,9 @@ GLCanvas3D::Mouse::Mouse() : dragging(false) , position(DBL_MAX, DBL_MAX) , scene_position(DBL_MAX, DBL_MAX, DBL_MAX) - , ignore_up_event(false) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// , ignore_up_event(false) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { } @@ -2465,6 +2467,20 @@ std::string format_mouse_event_debug_message(const wxMouseEvent &evt) void GLCanvas3D::on_mouse(wxMouseEvent& evt) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + auto mouse_up_cleanup = [this](){ + m_moving = false; + m_mouse.drag.move_volume_idx = -1; + m_mouse.set_start_position_3D_as_invalid(); + m_mouse.set_start_position_2D_as_invalid(); + m_mouse.dragging = false; + m_dirty = true; + + if (m_canvas->HasCapture()) + m_canvas->ReleaseMouse(); + }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #if ENABLE_RETINA_GL const float scale = m_retina_helper->get_scale_factor(); evt.SetX(evt.GetX() * scale); @@ -2501,17 +2517,39 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) #endif /* SLIC3R_DEBUG_MOUSE_EVENTS */ } - bool processed_by_toolbar = m_toolbar.on_mouse(evt, *this); - processed_by_toolbar |= m_view_toolbar.on_mouse(evt, *this); - - if (processed_by_toolbar) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_toolbar.on_mouse(evt, *this)) { + if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) + mouse_up_cleanup(); m_mouse.set_start_position_3D_as_invalid(); return; } + if (m_view_toolbar.on_mouse(evt, *this)) + { + if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) + mouse_up_cleanup(); + m_mouse.set_start_position_3D_as_invalid(); + return; + } + +// bool processed_by_toolbar = m_toolbar.on_mouse(evt, *this); +// processed_by_toolbar |= m_view_toolbar.on_mouse(evt, *this); +// +// if (processed_by_toolbar) +// { +// m_mouse.set_start_position_3D_as_invalid(); +// return; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_gizmos.on_mouse(evt, *this)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) + mouse_up_cleanup(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_mouse.set_start_position_3D_as_invalid(); return; } @@ -2563,10 +2601,12 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.position = Vec2d(-1.0, -1.0); m_dirty = true; } - else if (evt.LeftDClick() && (m_gizmos.get_current_type() != GLGizmosManager::Undefined)) - { - m_mouse.ignore_up_event = true; - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// else if (evt.LeftDClick() && (m_gizmos.get_current_type() != GLGizmosManager::Undefined)) +// { +// m_mouse.ignore_up_event = true; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.LeftDown() || evt.RightDown()) { // If user pressed left or right button we first check whether this happened @@ -2591,29 +2631,31 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } - else if (evt.LeftDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) - { - // the gizmo got the event and took some action, there is no need to do anything more - } - else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) - { - update_gizmos_data(); - m_selection.start_dragging(); - m_gizmos.start_dragging(m_selection); - - if (m_gizmos.get_current_type() == GLGizmosManager::Flatten) { - // Rotate the object so the normal points downward: - m_selection.flattening_rotate(m_gizmos.get_flattening_normal()); - do_flatten(); - wxGetApp().obj_manipul()->update_settings_value(m_selection); - } - - m_dirty = true; - } - else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown)) - { - // event was taken care of by the SlaSupports gizmo - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// else if (evt.LeftDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) +// { +// // the gizmo got the event and took some action, there is no need to do anything more +// } +// else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) +// { +// update_gizmos_data(); +// m_selection.start_dragging(); +// m_gizmos.start_dragging(m_selection); +// +// if (m_gizmos.get_current_type() == GLGizmosManager::Flatten) { +// // Rotate the object so the normal points downward: +// m_selection.flattening_rotate(m_gizmos.get_flattening_normal()); +// do_flatten(); +// wxGetApp().obj_manipul()->update_settings_value(m_selection); +// } +// +// m_dirty = true; +// } +// else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown)) +// { +// // event was taken care of by the SlaSupports gizmo +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else { // Select volume in this 3D canvas. @@ -2644,8 +2686,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (curr_idxs != m_selection.get_volume_idxs()) { - - m_gizmos.update_on_off_state(m_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_gizmos.refresh_on_off_state(m_selection); +// m_gizmos.update_on_off_state(m_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_dirty = true; @@ -2674,7 +2718,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) - && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + && (m_mouse.drag.move_volume_idx != -1)) +// && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if (!m_mouse.drag.move_requires_threshold) { @@ -2727,51 +2774,53 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } - else if (evt.Dragging() && m_gizmos.is_dragging()) - { - if (!m_canvas->HasCapture()) - m_canvas->CaptureMouse(); - - m_mouse.dragging = true; - m_gizmos.update(mouse_ray(pos), m_selection, evt.ShiftDown(), &pos); - - switch (m_gizmos.get_current_type()) - { - case GLGizmosManager::Move: - { - // Apply new temporary offset - m_selection.translate(m_gizmos.get_displacement()); - wxGetApp().obj_manipul()->update_settings_value(m_selection); - break; - } - case GLGizmosManager::Scale: - { - // Apply new temporary scale factors - m_selection.scale(m_gizmos.get_scale(), evt.AltDown()); - wxGetApp().obj_manipul()->update_settings_value(m_selection); - break; - } - case GLGizmosManager::Rotate: - { - // Apply new temporary rotations - TransformationType transformation_type(TransformationType::World_Relative_Joint); - if (evt.AltDown()) - transformation_type.set_independent(); - m_selection.rotate(m_gizmos.get_rotation(), transformation_type); - wxGetApp().obj_manipul()->update_settings_value(m_selection); - break; - } - default: - break; - } - - m_dirty = true; - } - else if (evt.Dragging() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) - { - // the gizmo got the event and took some action, no need to do anything more here - m_dirty = true; - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// else if (evt.Dragging() && m_gizmos.is_dragging()) +// { +// if (!m_canvas->HasCapture()) +// m_canvas->CaptureMouse(); +// +// m_mouse.dragging = true; +// m_gizmos.update(mouse_ray(pos), m_selection, evt.ShiftDown(), &pos); +// +// switch (m_gizmos.get_current_type()) +// { +// case GLGizmosManager::Move: +// { +// // Apply new temporary offset +// m_selection.translate(m_gizmos.get_displacement()); +// wxGetApp().obj_manipul()->update_settings_value(m_selection); +// break; +// } +// case GLGizmosManager::Scale: +// { +// // Apply new temporary scale factors +// m_selection.scale(m_gizmos.get_scale(), evt.AltDown()); +// wxGetApp().obj_manipul()->update_settings_value(m_selection); +// break; +// } +// case GLGizmosManager::Rotate: +// { +// // Apply new temporary rotations +// TransformationType transformation_type(TransformationType::World_Relative_Joint); +// if (evt.AltDown()) +// transformation_type.set_independent(); +// m_selection.rotate(m_gizmos.get_rotation(), transformation_type); +// wxGetApp().obj_manipul()->update_settings_value(m_selection); +// break; +// } +// default: +// break; +// } +// +// m_dirty = true; +// } +// else if (evt.Dragging() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) +// { +// // the gizmo got the event and took some action, no need to do anything more here +// m_dirty = true; +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.Dragging()) { m_mouse.dragging = true; @@ -2818,13 +2867,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _stop_timer(); m_layers_editing.accept_changes(*this); } - else if (evt.LeftUp() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && !m_gizmos.is_dragging() - && !m_mouse.dragging) - { - // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither - // object moving or selecting is suppressed in that case - m_gizmos.gizmo_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown()); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// else if (evt.LeftUp() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && !m_gizmos.is_dragging() +// && !m_mouse.dragging) +// { +// // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither +// // object moving or selecting is suppressed in that case +// m_gizmos.gizmo_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown()); +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) { m_regenerate_volumes = false; @@ -2834,11 +2885,17 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } - else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !m_gizmos.is_dragging() - && !is_layers_editing_enabled()) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !is_layers_editing_enabled()) +// else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !m_gizmos.is_dragging() +// && !is_layers_editing_enabled()) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // deselect and propagate event through callback - if (!evt.ShiftDown() && m_picking_enabled && !m_mouse.ignore_up_event) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (!evt.ShiftDown() && m_picking_enabled) +// if (!evt.ShiftDown() && m_picking_enabled && !m_mouse.ignore_up_event) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { m_selection.clear(); m_selection.set_mode(Selection::Instance); @@ -2847,40 +2904,44 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) update_gizmos_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); } - m_mouse.ignore_up_event = false; - } - else if (evt.LeftUp() && m_gizmos.is_dragging()) - { - switch (m_gizmos.get_current_type()) - { - case GLGizmosManager::Move: - { - m_regenerate_volumes = false; - do_move(); - break; - } - case GLGizmosManager::Scale: - { - do_scale(); - break; - } - case GLGizmosManager::Rotate: - { - do_rotate(); - break; - } - default: - break; - } - m_gizmos.stop_dragging(); - update_gizmos_data(); - - wxGetApp().obj_manipul()->update_settings_value(m_selection); - // Let the platter know that the dragging finished, so a delayed refresh - // of the scene with the background processing data should be performed. - post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); - m_camera.set_scene_box(scene_bounding_box()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// m_mouse.ignore_up_event = false; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// else if (evt.LeftUp() && m_gizmos.is_dragging()) +// { +// switch (m_gizmos.get_current_type()) +// { +// case GLGizmosManager::Move: +// { +// m_regenerate_volumes = false; +// do_move(); +// break; +// } +// case GLGizmosManager::Scale: +// { +// do_scale(); +// break; +// } +// case GLGizmosManager::Rotate: +// { +// do_rotate(); +// break; +// } +// default: +// break; +// } +// m_gizmos.stop_dragging(); +// update_gizmos_data(); +// +// wxGetApp().obj_manipul()->update_settings_value(m_selection); +// // Let the platter know that the dragging finished, so a delayed refresh +// // of the scene with the background processing data should be performed. +// post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); +// m_camera.set_scene_box(scene_bounding_box()); +// } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.RightUp()) { m_mouse.position = pos.cast(); @@ -2896,7 +2957,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { // forces the selection of the volume m_selection.add(m_hover_volume_id); - m_gizmos.update_on_off_state(m_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_gizmos.refresh_on_off_state(m_selection); +// m_gizmos.update_on_off_state(m_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); update_gizmos_data(); wxGetApp().obj_manipul()->update_settings_value(m_selection); @@ -2913,15 +2977,18 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } - m_moving = false; - m_mouse.drag.move_volume_idx = -1; - m_mouse.set_start_position_3D_as_invalid(); - m_mouse.set_start_position_2D_as_invalid(); - m_mouse.dragging = false; - m_dirty = true; - - if (m_canvas->HasCapture()) - m_canvas->ReleaseMouse(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + mouse_up_cleanup(); +// m_moving = false; +// m_mouse.drag.move_volume_idx = -1; +// m_mouse.set_start_position_3D_as_invalid(); +// m_mouse.set_start_position_2D_as_invalid(); +// m_mouse.dragging = false; +// m_dirty = true; +// +// if (m_canvas->HasCapture()) +// m_canvas->ReleaseMouse(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else if (evt.Moving()) { @@ -3251,7 +3318,10 @@ void GLCanvas3D::update_gizmos_on_off_state() { set_as_dirty(); update_gizmos_data(); - m_gizmos.update_on_off_state(get_selection()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_gizmos.refresh_on_off_state(get_selection()); +// m_gizmos.update_on_off_state(get_selection()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool focus_on) @@ -3325,6 +3395,15 @@ void GLCanvas3D::update_gizmos_data() } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) +{ + float z0 = 0.0f; + float z1 = 1.0f; + return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1)); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; @@ -4294,12 +4373,14 @@ Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos) return mouse_ray(mouse_pos).intersect_plane(0.0); } -Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) -{ - float z0 = 0.0f; - float z1 = 1.0f; - return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1)); -} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) +//{ +// float z0 = 0.0f; +// float z1 = 1.0f; +// return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1)); +//} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::_start_timer() { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ce44062869..8592dc5808 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -271,7 +271,9 @@ class GLCanvas3D Vec2d position; Vec3d scene_position; Drag drag; - bool ignore_up_event; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// bool ignore_up_event; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Mouse(); @@ -567,6 +569,18 @@ public: void update_gizmos_data(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } + + // Returns the view ray line, in world coordinate, at the given mouse position. + Linef3 mouse_ray(const Point& mouse_pos); + + void set_mouse_as_dragging() { m_mouse.dragging = true; } + void disable_regenerate_volumes() { m_regenerate_volumes = false; } + void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); } + bool is_mouse_dragging() const { return m_mouse.dragging; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + private: bool _is_shown_on_screen() const; @@ -616,8 +630,10 @@ private: // Convert the screen space coordinate to world coordinate on the bed. Vec3d _mouse_to_bed_3d(const Point& mouse_pos); - // Returns the view ray line, in world coordinate, at the given mouse position. - Linef3 mouse_ray(const Point& mouse_pos); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// // Returns the view ray line, in world coordinate, at the given mouse position. +// Linef3 mouse_ray(const Point& mouse_pos); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _start_timer(); void _stop_timer(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index bfef1c1d11..7334410462 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -2,8 +2,15 @@ #include "GLGizmosManager.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/3DScene.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/GUI_ObjectManipulation.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace GUI { @@ -187,64 +194,69 @@ void GLGizmosManager::set_overlay_scale(float scale) #endif // ENABLE_SVG_ICONS } -void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) -{ - if (!m_enabled) - return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) +//{ +// if (!m_enabled) +// return; +// +// float cnv_h = (float)canvas.get_canvas_size().get_height(); +// float height = get_total_overlay_height(); +// +//#if ENABLE_SVG_ICONS +// float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; +// float scaled_border = m_overlay_border * m_overlay_scale; +// float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; +// float scaled_stride_y = scaled_icons_size + scaled_gap_y; +// float top_y = 0.5f * (cnv_h - height) + scaled_border; +//#else +// float top_y = 0.5f * (cnv_h - height) + m_overlay_border; +// float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; +//#endif // ENABLE_SVG_ICONS +// +// for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) +// { +// if ((it->second == nullptr) || !it->second->is_selectable()) +// continue; +// +//#if ENABLE_SVG_ICONS +// bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +//#else +// bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +//#endif // ENABLE_SVG_ICONS +// if (it->second->is_activable(selection) && inside) +// { +// if ((it->second->get_state() == GLGizmoBase::On)) +// { +// it->second->set_state(GLGizmoBase::Hover); +// m_current = Undefined; +// } +// else if ((it->second->get_state() == GLGizmoBase::Hover)) +// { +// it->second->set_state(GLGizmoBase::On); +// m_current = it->first; +// } +// } +// else +// it->second->set_state(GLGizmoBase::Off); +// +//#if ENABLE_SVG_ICONS +// top_y += scaled_stride_y; +//#else +// top_y += (scaled_icons_size + m_overlay_gap_y); +//#endif // ENABLE_SVG_ICONS +// } +// +// GizmosMap::iterator it = m_gizmos.find(m_current); +// if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) +// it->second->set_state(GLGizmoBase::On); +//} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = get_total_overlay_height(); - -#if ENABLE_SVG_ICONS - float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; - float scaled_border = m_overlay_border * m_overlay_scale; - float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; - float scaled_stride_y = scaled_icons_size + scaled_gap_y; - float top_y = 0.5f * (cnv_h - height) + scaled_border; -#else - float top_y = 0.5f * (cnv_h - height) + m_overlay_border; - float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -#endif // ENABLE_SVG_ICONS - - for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - -#if ENABLE_SVG_ICONS - bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#else - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -#endif // ENABLE_SVG_ICONS - if (it->second->is_activable(selection) && inside) - { - if ((it->second->get_state() == GLGizmoBase::On)) - { - it->second->set_state(GLGizmoBase::Hover); - m_current = Undefined; - } - else if ((it->second->get_state() == GLGizmoBase::Hover)) - { - it->second->set_state(GLGizmoBase::On); - m_current = it->first; - } - } - else - it->second->set_state(GLGizmoBase::Off); - -#if ENABLE_SVG_ICONS - top_y += scaled_stride_y; -#else - top_y += (scaled_icons_size + m_overlay_gap_y); -#endif // ENABLE_SVG_ICONS - } - - GizmosMap::iterator it = m_gizmos.find(m_current); - if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) - it->second->set_state(GLGizmoBase::On); -} - -void GLGizmosManager::update_on_off_state(const Selection& selection) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void GLGizmosManager::refresh_on_off_state(const Selection& selection) +//void GLGizmosManager::update_on_off_state(const Selection& selection) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { GizmosMap::iterator it = m_gizmos.find(m_current); if ((it != m_gizmos.end()) && (it->second != nullptr)) @@ -301,14 +313,16 @@ void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) } } -bool GLGizmosManager::grabber_contains_mouse() const -{ - if (!m_enabled) - return false; - - GLGizmoBase* curr = get_current(); - return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; -} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//bool GLGizmosManager::grabber_contains_mouse() const +//{ +// if (!m_enabled) +// return false; +// +// GLGizmoBase* curr = get_current(); +// return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; +//} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLGizmosManager::update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos) { @@ -530,9 +544,16 @@ void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + Point pos(evt.GetX(), evt.GetY()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); - const Selection& selection = canvas.get_selection(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + Selection& selection = canvas.get_selection(); + int selected_object_idx = selection.get_object_idx(); +// const Selection& selection = canvas.get_selection(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool processed = false; // mouse anywhere @@ -562,6 +583,128 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { // mouse is outside the toolbar m_tooltip = ""; + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (evt.LeftDown()) + { + if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown())) + // the gizmo got the event and took some action, there is no need to do anything more + processed = true; + else if (!selection.is_empty() && grabber_contains_mouse()) + { + canvas.update_gizmos_data(); + selection.start_dragging(); + start_dragging(selection); + + if (m_current == Flatten) + { + // Rotate the object so the normal points downward: + selection.flattening_rotate(get_flattening_normal()); + canvas.do_flatten(); + wxGetApp().obj_manipul()->update_settings_value(selection); + } + + canvas.set_as_dirty(); + processed = true; + } + } + else if (evt.RightDown() && (selected_object_idx != -1) && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::RightDown)) + // event was taken care of by the SlaSupports gizmo + processed = true; + else if (evt.Dragging() && (canvas.get_move_volume_id() != -1) && (m_current == SlaSupports)) + // don't allow dragging objects with the Sla gizmo on + processed = true; + else if (evt.Dragging() && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown())) + { + // the gizmo got the event and took some action, no need to do anything more here + canvas.set_as_dirty(); + processed = true; + } + else if (evt.Dragging() && is_dragging()) + { + if (!canvas.get_wxglcanvas()->HasCapture()) + canvas.get_wxglcanvas()->CaptureMouse(); + + canvas.set_mouse_as_dragging(); + update(canvas.mouse_ray(pos), selection, evt.ShiftDown(), &pos); + + switch (m_current) + { + case Move: + { + // Apply new temporary offset + selection.translate(get_displacement()); + wxGetApp().obj_manipul()->update_settings_value(selection); + break; + } + case Scale: + { + // Apply new temporary scale factors + selection.scale(get_scale(), evt.AltDown()); + wxGetApp().obj_manipul()->update_settings_value(selection); + break; + } + case Rotate: + { + // Apply new temporary rotations + TransformationType transformation_type(TransformationType::World_Relative_Joint); + if (evt.AltDown()) + transformation_type.set_independent(); + selection.rotate(get_rotation(), transformation_type); + wxGetApp().obj_manipul()->update_settings_value(selection); + break; + } + default: + break; + } + + canvas.set_as_dirty(); + processed = true; + } + else if (evt.LeftUp() && is_dragging()) + { + switch (m_current) + { + case Move: + { + canvas.disable_regenerate_volumes(); + canvas.do_move(); + break; + } + case Scale: + { + canvas.do_scale(); + break; + } + case Rotate: + { + canvas.do_rotate(); + break; + } + default: + break; + } + + stop_dragging(); + canvas.update_gizmos_data(); + + wxGetApp().obj_manipul()->update_settings_value(selection); + // Let the platter know that the dragging finished, so a delayed refresh + // of the scene with the background processing data should be performed. + canvas.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); + // updates camera target constraints + canvas.refresh_camera_scene_box(); + + processed = true; + } + else if (evt.LeftUp() && (m_current == SlaSupports) && !canvas.is_mouse_dragging()) + { + // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither + // object moving or selecting is suppressed in that case + gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown()); + processed = true; + } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else { @@ -842,6 +985,65 @@ bool GLGizmosManager::generate_icons_texture() const } #endif // ENABLE_SVG_ICONS +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) +{ + if (!m_enabled) + return; + + float cnv_h = (float)canvas.get_canvas_size().get_height(); + float height = get_total_overlay_height(); + +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; + float scaled_border = m_overlay_border * m_overlay_scale; + float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; + float scaled_stride_y = scaled_icons_size + scaled_gap_y; + float top_y = 0.5f * (cnv_h - height) + scaled_border; +#else + float top_y = 0.5f * (cnv_h - height) + m_overlay_border; + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; +#endif // ENABLE_SVG_ICONS + + for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + if ((it->second == nullptr) || !it->second->is_selectable()) + continue; + +#if ENABLE_SVG_ICONS + bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +#else + bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); +#endif // ENABLE_SVG_ICONS + if (it->second->is_activable(selection) && inside) + { + if ((it->second->get_state() == GLGizmoBase::On)) + { + it->second->set_state(GLGizmoBase::Hover); + m_current = Undefined; + } + else if ((it->second->get_state() == GLGizmoBase::Hover)) + { + it->second->set_state(GLGizmoBase::On); + m_current = it->first; + } + } + else + it->second->set_state(GLGizmoBase::Off); + +#if ENABLE_SVG_ICONS + top_y += scaled_stride_y; +#else + top_y += (scaled_icons_size + m_overlay_gap_y); +#endif // ENABLE_SVG_ICONS + } + + GizmosMap::iterator it = m_gizmos.find(m_current); + if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) + it->second->set_state(GLGizmoBase::On); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos) { std::string name = ""; @@ -931,5 +1133,16 @@ bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec return false; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +bool GLGizmosManager::grabber_contains_mouse() const +{ + if (!m_enabled) + return false; + + GLGizmoBase* curr = get_current(); + return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 2a867314eb..bb2fdb1942 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -113,14 +113,21 @@ public: #endif // ENABLE_SVG_ICONS void set_overlay_scale(float scale); - void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); - void update_on_off_state(const Selection& selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void refresh_on_off_state(const Selection& selection); +// void update_on_off_state(const Selection& selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void reset_all_states(); void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); - bool grabber_contains_mouse() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// bool grabber_contains_mouse() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr); Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; EType get_current_type() const { return m_current; } @@ -170,8 +177,14 @@ private: bool generate_icons_texture() const; #endif // ENABLE_SVG_ICONS +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos); bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool grabber_contains_mouse() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; } // namespace GUI From c1d74d2943839b788298d7234bf8d30ba746d45e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Mar 2019 12:39:40 +0100 Subject: [PATCH 07/61] Code cleanup --- src/slic3r/GUI/GLCanvas3D.cpp | 187 +--------------------- src/slic3r/GUI/GLCanvas3D.hpp | 10 -- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 88 ---------- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 13 -- 4 files changed, 2 insertions(+), 296 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 25abf1dc7c..5c695cf6f5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -675,9 +675,6 @@ GLCanvas3D::Mouse::Mouse() : dragging(false) , position(DBL_MAX, DBL_MAX) , scene_position(DBL_MAX, DBL_MAX, DBL_MAX) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// , ignore_up_event(false) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { } @@ -2467,7 +2464,6 @@ std::string format_mouse_event_debug_message(const wxMouseEvent &evt) void GLCanvas3D::on_mouse(wxMouseEvent& evt) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto mouse_up_cleanup = [this](){ m_moving = false; m_mouse.drag.move_volume_idx = -1; @@ -2479,7 +2475,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (m_canvas->HasCapture()) m_canvas->ReleaseMouse(); }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_RETINA_GL const float scale = m_retina_helper->get_scale_factor(); @@ -2517,7 +2512,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) #endif /* SLIC3R_DEBUG_MOUSE_EVENTS */ } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_toolbar.on_mouse(evt, *this)) { if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) @@ -2534,22 +2528,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) return; } -// bool processed_by_toolbar = m_toolbar.on_mouse(evt, *this); -// processed_by_toolbar |= m_view_toolbar.on_mouse(evt, *this); -// -// if (processed_by_toolbar) -// { -// m_mouse.set_start_position_3D_as_invalid(); -// return; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - if (m_gizmos.on_mouse(evt, *this)) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) mouse_up_cleanup(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_mouse.set_start_position_3D_as_invalid(); return; } @@ -2601,12 +2584,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.position = Vec2d(-1.0, -1.0); m_dirty = true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (evt.LeftDClick() && (m_gizmos.get_current_type() != GLGizmosManager::Undefined)) -// { -// m_mouse.ignore_up_event = true; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.LeftDown() || evt.RightDown()) { // If user pressed left or right button we first check whether this happened @@ -2631,31 +2608,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (evt.LeftDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown())) -// { -// // the gizmo got the event and took some action, there is no need to do anything more -// } -// else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse()) -// { -// update_gizmos_data(); -// m_selection.start_dragging(); -// m_gizmos.start_dragging(m_selection); -// -// if (m_gizmos.get_current_type() == GLGizmosManager::Flatten) { -// // Rotate the object so the normal points downward: -// m_selection.flattening_rotate(m_gizmos.get_flattening_normal()); -// do_flatten(); -// wxGetApp().obj_manipul()->update_settings_value(m_selection); -// } -// -// m_dirty = true; -// } -// else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown)) -// { -// // event was taken care of by the SlaSupports gizmo -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else { // Select volume in this 3D canvas. @@ -2686,10 +2638,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (curr_idxs != m_selection.get_volume_idxs()) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gizmos.refresh_on_off_state(m_selection); -// m_gizmos.update_on_off_state(m_selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_gizmos_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_dirty = true; @@ -2717,11 +2666,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } } - else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - && (m_mouse.drag.move_volume_idx != -1)) -// && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports /* don't allow dragging objects with the Sla gizmo on */) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.move_volume_idx != -1)) { if (!m_mouse.drag.move_requires_threshold) { @@ -2774,53 +2719,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (evt.Dragging() && m_gizmos.is_dragging()) -// { -// if (!m_canvas->HasCapture()) -// m_canvas->CaptureMouse(); -// -// m_mouse.dragging = true; -// m_gizmos.update(mouse_ray(pos), m_selection, evt.ShiftDown(), &pos); -// -// switch (m_gizmos.get_current_type()) -// { -// case GLGizmosManager::Move: -// { -// // Apply new temporary offset -// m_selection.translate(m_gizmos.get_displacement()); -// wxGetApp().obj_manipul()->update_settings_value(m_selection); -// break; -// } -// case GLGizmosManager::Scale: -// { -// // Apply new temporary scale factors -// m_selection.scale(m_gizmos.get_scale(), evt.AltDown()); -// wxGetApp().obj_manipul()->update_settings_value(m_selection); -// break; -// } -// case GLGizmosManager::Rotate: -// { -// // Apply new temporary rotations -// TransformationType transformation_type(TransformationType::World_Relative_Joint); -// if (evt.AltDown()) -// transformation_type.set_independent(); -// m_selection.rotate(m_gizmos.get_rotation(), transformation_type); -// wxGetApp().obj_manipul()->update_settings_value(m_selection); -// break; -// } -// default: -// break; -// } -// -// m_dirty = true; -// } -// else if (evt.Dragging() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown())) -// { -// // the gizmo got the event and took some action, no need to do anything more here -// m_dirty = true; -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.Dragging()) { m_mouse.dragging = true; @@ -2867,15 +2765,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) _stop_timer(); m_layers_editing.accept_changes(*this); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (evt.LeftUp() && m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && !m_gizmos.is_dragging() -// && !m_mouse.dragging) -// { -// // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither -// // object moving or selecting is suppressed in that case -// m_gizmos.gizmo_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown()); -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging) { m_regenerate_volumes = false; @@ -2885,17 +2774,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // of the scene with the background processing data should be performed. post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !is_layers_editing_enabled()) -// else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !m_gizmos.is_dragging() -// && !is_layers_editing_enabled()) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // deselect and propagate event through callback -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!evt.ShiftDown() && m_picking_enabled) -// if (!evt.ShiftDown() && m_picking_enabled && !m_mouse.ignore_up_event) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { m_selection.clear(); m_selection.set_mode(Selection::Instance); @@ -2904,44 +2786,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) update_gizmos_data(); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// m_mouse.ignore_up_event = false; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// else if (evt.LeftUp() && m_gizmos.is_dragging()) -// { -// switch (m_gizmos.get_current_type()) -// { -// case GLGizmosManager::Move: -// { -// m_regenerate_volumes = false; -// do_move(); -// break; -// } -// case GLGizmosManager::Scale: -// { -// do_scale(); -// break; -// } -// case GLGizmosManager::Rotate: -// { -// do_rotate(); -// break; -// } -// default: -// break; -// } -// m_gizmos.stop_dragging(); -// update_gizmos_data(); -// -// wxGetApp().obj_manipul()->update_settings_value(m_selection); -// // Let the platter know that the dragging finished, so a delayed refresh -// // of the scene with the background processing data should be performed. -// post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); -// m_camera.set_scene_box(scene_bounding_box()); -// } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ else if (evt.RightUp()) { m_mouse.position = pos.cast(); @@ -2957,10 +2802,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { // forces the selection of the volume m_selection.add(m_hover_volume_id); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gizmos.refresh_on_off_state(m_selection); -// m_gizmos.update_on_off_state(m_selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); update_gizmos_data(); wxGetApp().obj_manipul()->update_settings_value(m_selection); @@ -2977,18 +2819,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mouse_up_cleanup(); -// m_moving = false; -// m_mouse.drag.move_volume_idx = -1; -// m_mouse.set_start_position_3D_as_invalid(); -// m_mouse.set_start_position_2D_as_invalid(); -// m_mouse.dragging = false; -// m_dirty = true; -// -// if (m_canvas->HasCapture()) -// m_canvas->ReleaseMouse(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else if (evt.Moving()) { @@ -3318,10 +3149,7 @@ void GLCanvas3D::update_gizmos_on_off_state() { set_as_dirty(); update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_gizmos.refresh_on_off_state(get_selection()); -// m_gizmos.update_on_off_state(get_selection()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool focus_on) @@ -3395,14 +3223,12 @@ void GLCanvas3D::update_gizmos_data() } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) { float z0 = 0.0f; float z1 = 1.0f; return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1)); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLCanvas3D::_is_shown_on_screen() const { @@ -4373,15 +4199,6 @@ Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos) return mouse_ray(mouse_pos).intersect_plane(0.0); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) -//{ -// float z0 = 0.0f; -// float z1 = 1.0f; -// return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1)); -//} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void GLCanvas3D::_start_timer() { m_timer.Start(100, wxTIMER_CONTINUOUS); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8592dc5808..023a79d6e1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -271,9 +271,6 @@ class GLCanvas3D Vec2d position; Vec3d scene_position; Drag drag; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// bool ignore_up_event; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Mouse(); @@ -569,7 +566,6 @@ public: void update_gizmos_data(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } // Returns the view ray line, in world coordinate, at the given mouse position. @@ -579,7 +575,6 @@ public: void disable_regenerate_volumes() { m_regenerate_volumes = false; } void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); } bool is_mouse_dragging() const { return m_mouse.dragging; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: bool _is_shown_on_screen() const; @@ -630,11 +625,6 @@ private: // Convert the screen space coordinate to world coordinate on the bed. Vec3d _mouse_to_bed_3d(const Point& mouse_pos); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// // Returns the view ray line, in world coordinate, at the given mouse position. -// Linef3 mouse_ray(const Point& mouse_pos); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void _start_timer(); void _stop_timer(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 7334410462..66901f34de 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -2,15 +2,11 @@ #include "GLGizmosManager.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/3DScene.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace GUI { @@ -194,69 +190,7 @@ void GLGizmosManager::set_overlay_scale(float scale) #endif // ENABLE_SVG_ICONS } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) -//{ -// if (!m_enabled) -// return; -// -// float cnv_h = (float)canvas.get_canvas_size().get_height(); -// float height = get_total_overlay_height(); -// -//#if ENABLE_SVG_ICONS -// float scaled_icons_size = m_overlay_icons_size * m_overlay_scale; -// float scaled_border = m_overlay_border * m_overlay_scale; -// float scaled_gap_y = m_overlay_gap_y * m_overlay_scale; -// float scaled_stride_y = scaled_icons_size + scaled_gap_y; -// float top_y = 0.5f * (cnv_h - height) + scaled_border; -//#else -// float top_y = 0.5f * (cnv_h - height) + m_overlay_border; -// float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale; -//#endif // ENABLE_SVG_ICONS -// -// for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) -// { -// if ((it->second == nullptr) || !it->second->is_selectable()) -// continue; -// -//#if ENABLE_SVG_ICONS -// bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -//#else -// bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size); -//#endif // ENABLE_SVG_ICONS -// if (it->second->is_activable(selection) && inside) -// { -// if ((it->second->get_state() == GLGizmoBase::On)) -// { -// it->second->set_state(GLGizmoBase::Hover); -// m_current = Undefined; -// } -// else if ((it->second->get_state() == GLGizmoBase::Hover)) -// { -// it->second->set_state(GLGizmoBase::On); -// m_current = it->first; -// } -// } -// else -// it->second->set_state(GLGizmoBase::Off); -// -//#if ENABLE_SVG_ICONS -// top_y += scaled_stride_y; -//#else -// top_y += (scaled_icons_size + m_overlay_gap_y); -//#endif // ENABLE_SVG_ICONS -// } -// -// GizmosMap::iterator it = m_gizmos.find(m_current); -// if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) -// it->second->set_state(GLGizmoBase::On); -//} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLGizmosManager::refresh_on_off_state(const Selection& selection) -//void GLGizmosManager::update_on_off_state(const Selection& selection) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { GizmosMap::iterator it = m_gizmos.find(m_current); if ((it != m_gizmos.end()) && (it->second != nullptr)) @@ -313,17 +247,6 @@ void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable) } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//bool GLGizmosManager::grabber_contains_mouse() const -//{ -// if (!m_enabled) -// return false; -// -// GLGizmoBase* curr = get_current(); -// return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; -//} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - void GLGizmosManager::update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos) { if (!m_enabled) @@ -544,16 +467,11 @@ void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Point pos(evt.GetX(), evt.GetY()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Selection& selection = canvas.get_selection(); int selected_object_idx = selection.get_object_idx(); -// const Selection& selection = canvas.get_selection(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool processed = false; // mouse anywhere @@ -584,7 +502,6 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) // mouse is outside the toolbar m_tooltip = ""; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (evt.LeftDown()) { if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown())) @@ -704,7 +621,6 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown()); processed = true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else { @@ -985,7 +901,6 @@ bool GLGizmosManager::generate_icons_texture() const } #endif // ENABLE_SVG_ICONS -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection) { if (!m_enabled) @@ -1042,7 +957,6 @@ void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On)) it->second->set_state(GLGizmoBase::On); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos) { @@ -1133,7 +1047,6 @@ bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec return false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool GLGizmosManager::grabber_contains_mouse() const { if (!m_enabled) @@ -1142,7 +1055,6 @@ bool GLGizmosManager::grabber_contains_mouse() const GLGizmoBase* curr = get_current(); return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index bb2fdb1942..6b178e7489 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -113,21 +113,12 @@ public: #endif // ENABLE_SVG_ICONS void set_overlay_scale(float scale); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void refresh_on_off_state(const Selection& selection); -// void update_on_off_state(const Selection& selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void reset_all_states(); void set_hover_id(int id); void enable_grabber(EType type, unsigned int id, bool enable); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -// bool grabber_contains_mouse() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr); Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; EType get_current_type() const { return m_current; } @@ -177,14 +168,10 @@ private: bool generate_icons_texture() const; #endif // ENABLE_SVG_ICONS -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos); bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool grabber_contains_mouse() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; } // namespace GUI From d18208458bd8cbd7e172b6459ca7242f51d4c7b6 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Mar 2019 14:08:02 +0100 Subject: [PATCH 08/61] Handling of gizmos related char events moved into new method GLGizmosManager::on_char() --- src/slic3r/GUI/GLCanvas3D.cpp | 51 ++----------- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 91 +++++++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 1 + 3 files changed, 98 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5c695cf6f5..ea04744ed8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2240,6 +2240,9 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) return; } + if (m_gizmos.on_char(evt, *this)) + return; + //#ifdef __APPLE__ // ctrlMask |= wxMOD_RAW_CONTROL; //#endif /* __APPLE__ */ @@ -2248,9 +2251,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'a': case 'A': case WXK_CONTROL_A: - if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::SelectAll)) // Sla gizmo selects all support points - m_dirty = true; - else post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); break; #ifdef __APPLE__ @@ -2266,29 +2266,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } else { switch (keyCode) { - // key ESC - case WXK_ESCAPE: { - if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports || !m_gizmos.gizmo_event(SLAGizmoEventType::DiscardChanges)) - m_gizmos.reset_all_states(); - m_dirty = true; - break; - } - - case WXK_RETURN: { - if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::ApplyChanges)) - m_dirty = true; - break; - } - #ifdef __APPLE__ case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. #else /* __APPLE__ */ case WXK_DELETE: #endif /* __APPLE__ */ - if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::Delete)) - m_dirty = true; - else - post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); + post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; case '0': { select_view("iso"); break; } @@ -2302,15 +2285,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case '-': { post_event(Event(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; } case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; } case 'A': - case 'a': { - if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports) { - if (m_gizmos.gizmo_event(SLAGizmoEventType::AutomaticGeneration)) - m_dirty = true; - } - else - post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); - break; - } + case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; } case 'B': case 'b': { zoom_to_bed(); break; } case 'I': @@ -2319,23 +2294,9 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'o': { set_camera_zoom(-1.0f); break; } case 'Z': case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; } - case 'M': - case 'm': { - if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::ManualEditing)) { - m_dirty = true; - break; - } - } // intentional fallthrough default: { - if (m_gizmos.handle_shortcut(keyCode, m_selection)) - { - update_gizmos_data(); - m_dirty = true; - } - else - evt.Skip(); - + evt.Skip(); break; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 66901f34de..23e4204893 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -654,6 +654,97 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) return processed; } +bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) +{ + // see include/wx/defs.h enum wxKeyCode + int keyCode = evt.GetKeyCode(); + int ctrlMask = wxMOD_CONTROL; + + const Selection& selection = canvas.get_selection(); + bool processed = false; + + if ((evt.GetModifiers() & ctrlMask) != 0) + { + switch (keyCode) + { + case WXK_CONTROL_A: + { + // Sla gizmo selects all support points + if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::SelectAll)) + processed = true; + + break; + } + } + } + else if (!evt.HasModifiers()) + { + switch (keyCode) + { + // key ESC + case WXK_ESCAPE: + { + if ((m_current != SlaSupports) || !gizmo_event(SLAGizmoEventType::DiscardChanges)) + reset_all_states(); + + processed = true; + break; + } + case WXK_RETURN: + { + if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::ApplyChanges)) + processed = true; + + break; + } +#ifdef __APPLE__ + case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. +#else /* __APPLE__ */ + case WXK_DELETE: +#endif /* __APPLE__ */ + { + if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::Delete)) + processed = true; + + break; + } + case 'A': + case 'a': + { + if (m_current == SlaSupports) + { + gizmo_event(SLAGizmoEventType::AutomaticGeneration); + // set as processed no matter what's returned by gizmo_event() to avoid the calling canvas to process 'A' as arrange + processed = true; + } + break; + } + case 'M': + case 'm': + { + if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::ManualEditing)) + processed = true; + + break; + } + } + } + + if (!processed) + { + if (handle_shortcut(keyCode, selection)) + { + canvas.update_gizmos_data(); + processed = true; + } + } + + if (processed) + canvas.set_as_dirty(); + + return processed; +} + void GLGizmosManager::reset() { for (GizmosMap::value_type& gizmo : m_gizmos) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 6b178e7489..e269ce5ff8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -153,6 +153,7 @@ public: const std::string& get_tooltip() const { return m_tooltip; } bool on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas); + bool on_char(wxKeyEvent& evt, GLCanvas3D& canvas); private: void reset(); From 47c39f51e52e23cf96ed399c2f966133079b4d47 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Mar 2019 14:38:30 +0100 Subject: [PATCH 09/61] Handling of gizmos related key events moved into new method GLGizmosManager::on_key() --- src/slic3r/GUI/GLCanvas3D.cpp | 26 +++++++++++++---------- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 21 ++++++++++++++++-- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 1 + 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ee3c5788f1..f8704f3abf 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2310,18 +2310,22 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) auto imgui = wxGetApp().imgui(); if (imgui->update_key_data(evt)) { render(); - } else - if (evt.GetEventType() == wxEVT_KEY_UP) { - if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) { - // Enable switching between 3D and Preview with Tab - // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux - post_event(SimpleEvent(EVT_GLCANVAS_TAB)); - } else if (m_gizmos.get_current_type() == GLGizmosManager::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.gizmo_event(SLAGizmoEventType::ShiftUp)) { - // shift has been just released - SLA gizmo might want to close rectangular selection. - m_dirty = true; + } + else + { + if (!m_gizmos.on_key(evt, *this)) + { + if (evt.GetEventType() == wxEVT_KEY_UP) { + if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) { + // Enable switching between 3D and Preview with Tab + // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux + post_event(SimpleEvent(EVT_GLCANVAS_TAB)); + } + } + else if (evt.GetEventType() == wxEVT_KEY_DOWN) { + m_tab_down = keyCode == WXK_TAB && !evt.HasAnyModifiers(); + } } - } else if (evt.GetEventType() == wxEVT_KEY_DOWN) { - m_tab_down = keyCode == WXK_TAB && !evt.HasAnyModifiers(); } if (keyCode != WXK_TAB diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 23e4204893..e1a1300ba1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -660,7 +660,6 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) int keyCode = evt.GetKeyCode(); int ctrlMask = wxMOD_CONTROL; - const Selection& selection = canvas.get_selection(); bool processed = false; if ((evt.GetModifiers() & ctrlMask) != 0) @@ -732,7 +731,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) if (!processed) { - if (handle_shortcut(keyCode, selection)) + if (handle_shortcut(keyCode, canvas.get_selection())) { canvas.update_gizmos_data(); processed = true; @@ -745,6 +744,24 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) return processed; } +bool GLGizmosManager::on_key(wxKeyEvent& evt, GLCanvas3D& canvas) +{ + const int keyCode = evt.GetKeyCode(); + bool processed = false; + + if (evt.GetEventType() == wxEVT_KEY_UP) + { + if ((m_current == SlaSupports) && (keyCode == WXK_SHIFT) && gizmo_event(SLAGizmoEventType::ShiftUp)) + // shift has been just released - SLA gizmo might want to close rectangular selection. + processed = true; + } + + if (processed) + canvas.set_as_dirty(); + + return processed; +} + void GLGizmosManager::reset() { for (GizmosMap::value_type& gizmo : m_gizmos) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index e269ce5ff8..348cc26871 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -154,6 +154,7 @@ public: bool on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas); bool on_char(wxKeyEvent& evt, GLCanvas3D& canvas); + bool on_key(wxKeyEvent& evt, GLCanvas3D& canvas); private: void reset(); From fee0a6b6b5cafcc7b935019650a40ad471d5968a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Mar 2019 15:55:47 +0100 Subject: [PATCH 10/61] void GLCanvas3D::update_gizmos_data() moved into void GLGizmosManager::update_data(GLCanvas3D& canvas) --- src/slic3r/GUI/GLCanvas3D.cpp | 50 +++-------------------- src/slic3r/GUI/GLCanvas3D.hpp | 3 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 50 +++++++++++++++++++++-- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 + 4 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f8704f3abf..4652b73c18 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2015,7 +2015,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re m_selection.volumes_changed(map_glvolume_old_to_new); } - update_gizmos_data(); + m_gizmos.update_data(*this); // Update the toolbar post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); @@ -2604,7 +2604,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (curr_idxs != m_selection.get_volume_idxs()) { m_gizmos.refresh_on_off_state(m_selection); - update_gizmos_data(); + m_gizmos.update_data(*this); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); m_dirty = true; } @@ -2748,7 +2748,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.set_mode(Selection::Instance); wxGetApp().obj_manipul()->update_settings_value(m_selection); m_gizmos.reset_all_states(); - update_gizmos_data(); + m_gizmos.update_data(*this); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); } } @@ -2769,7 +2769,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_selection.add(m_hover_volume_id); m_gizmos.refresh_on_off_state(m_selection); post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); - update_gizmos_data(); + m_gizmos.update_data(*this); wxGetApp().obj_manipul()->update_settings_value(m_selection); // forces a frame render to update the view before the context menu is shown render(); @@ -3113,7 +3113,7 @@ void GLCanvas3D::set_camera_zoom(float zoom) void GLCanvas3D::update_gizmos_on_off_state() { set_as_dirty(); - update_gizmos_data(); + m_gizmos.update_data(*this); m_gizmos.refresh_on_off_state(get_selection()); } @@ -3148,46 +3148,6 @@ void GLCanvas3D::update_ui_from_settings() #endif } -void GLCanvas3D::update_gizmos_data() -{ - if (!m_gizmos.is_enabled()) - return; - - bool enable_move_z = !m_selection.is_wipe_tower(); - m_gizmos.enable_grabber(GLGizmosManager::Move, 2, enable_move_z); - bool enable_scale_xyz = m_selection.is_single_full_instance() || m_selection.is_single_volume() || m_selection.is_single_modifier(); - for (int i = 0; i < 6; ++i) - { - m_gizmos.enable_grabber(GLGizmosManager::Scale, i, enable_scale_xyz); - } - - if (m_selection.is_single_full_instance()) - { - // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first - const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()]; - m_gizmos.set_scale(volume->get_instance_scaling_factor()); - m_gizmos.set_rotation(Vec3d::Zero()); - ModelObject* model_object = m_model->objects[m_selection.get_object_idx()]; - m_gizmos.set_flattening_data(model_object); - m_gizmos.set_sla_support_data(model_object, m_selection); - } - else if (m_selection.is_single_volume() || m_selection.is_single_modifier()) - { - const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()]; - m_gizmos.set_scale(volume->get_volume_scaling_factor()); - m_gizmos.set_rotation(Vec3d::Zero()); - m_gizmos.set_flattening_data(nullptr); - m_gizmos.set_sla_support_data(nullptr, m_selection); - } - else - { - m_gizmos.set_scale(Vec3d::Ones()); - m_gizmos.set_rotation(Vec3d::Zero()); - m_gizmos.set_flattening_data(m_selection.is_from_single_object() ? m_model->objects[m_selection.get_object_idx()] : nullptr); - m_gizmos.set_sla_support_data(nullptr, m_selection); - } -} - Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos) { float z0 = 0.0f; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 023a79d6e1..990bf4782a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -464,6 +464,7 @@ public: void set_config(const DynamicPrintConfig* config); void set_process(BackgroundSlicingProcess* process); void set_model(Model* model); + Model* get_model() { return m_model; } const Selection& get_selection() const { return m_selection; } Selection& get_selection() { return m_selection; } @@ -564,8 +565,6 @@ public: float get_view_toolbar_height() const { return m_view_toolbar.get_height(); } - void update_gizmos_data(); - int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } // Returns the view ray line, in world coordinate, at the given mouse position. diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index e1a1300ba1..9e2386f904 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -257,6 +257,48 @@ void GLGizmosManager::update(const Linef3& mouse_ray, const Selection& selection curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection); } +void GLGizmosManager::update_data(GLCanvas3D& canvas) +{ + if (!m_enabled) + return; + + const Selection& selection = canvas.get_selection(); + + bool enable_move_z = !selection.is_wipe_tower(); + enable_grabber(Move, 2, enable_move_z); + bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); + for (int i = 0; i < 6; ++i) + { + enable_grabber(Scale, i, enable_scale_xyz); + } + + if (selection.is_single_full_instance()) + { + // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first + const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); + set_scale(volume->get_instance_scaling_factor()); + set_rotation(Vec3d::Zero()); + ModelObject* model_object = canvas.get_model()->objects[selection.get_object_idx()]; + set_flattening_data(model_object); + set_sla_support_data(model_object, selection); + } + else if (selection.is_single_volume() || selection.is_single_modifier()) + { + const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); + set_scale(volume->get_volume_scaling_factor()); + set_rotation(Vec3d::Zero()); + set_flattening_data(nullptr); + set_sla_support_data(nullptr, selection); + } + else + { + set_scale(Vec3d::Ones()); + set_rotation(Vec3d::Zero()); + set_flattening_data(selection.is_from_single_object() ? canvas.get_model()->objects[selection.get_object_idx()] : nullptr); + set_sla_support_data(nullptr, selection); + } +} + bool GLGizmosManager::is_running() const { if (!m_enabled) @@ -509,7 +551,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) processed = true; else if (!selection.is_empty() && grabber_contains_mouse()) { - canvas.update_gizmos_data(); + update_data(canvas); selection.start_dragging(); start_dragging(selection); @@ -603,7 +645,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) } stop_dragging(); - canvas.update_gizmos_data(); + update_data(canvas); wxGetApp().obj_manipul()->update_settings_value(selection); // Let the platter know that the dragging finished, so a delayed refresh @@ -633,7 +675,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas) if (!selection.is_empty()) { update_on_off_state(canvas, mouse_pos, selection); - canvas.update_gizmos_data(); + update_data(canvas); canvas.set_as_dirty(); } } @@ -733,7 +775,7 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas) { if (handle_shortcut(keyCode, canvas.get_selection())) { - canvas.update_gizmos_data(); + update_data(canvas); processed = true; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 348cc26871..82dbdc0db6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -120,6 +120,8 @@ public: void enable_grabber(EType type, unsigned int id, bool enable); void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr); + void update_data(GLCanvas3D& canvas); + Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const; EType get_current_type() const { return m_current; } From d795f07e7b8d4096d5b06ffae88c13f766b619cf Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 27 Mar 2019 14:42:09 +0100 Subject: [PATCH 11/61] Added glsafe() around OpenGL calls where missing --- src/slic3r/GUI/3DBed.cpp | 9 +- src/slic3r/GUI/3DScene.cpp | 132 ++++---- src/slic3r/GUI/3DScene.hpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 309 ++++++++++--------- src/slic3r/GUI/GLShader.cpp | 62 ++-- src/slic3r/GUI/GLTexture.cpp | 82 ++--- src/slic3r/GUI/GLToolbar.cpp | 8 +- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 66 ++-- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 24 +- src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp | 42 +-- src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 34 +- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 76 ++--- src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 26 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 94 +++--- src/slic3r/GUI/ImGuiWrapper.cpp | 113 +++---- 15 files changed, 544 insertions(+), 534 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 2367938147..05f4fd8fdb 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -495,11 +495,11 @@ void Bed3D::render_prusa(const std::string &key, bool bottom) const // use anisotropic filter if graphic card allows GLfloat max_anisotropy = 0.0f; if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) - ::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); + glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy)); // use higher resolution images if graphic card allows GLint max_tex_size; - ::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); + glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size)); // clamp or the texture generation becomes too slow max_tex_size = std::min(max_tex_size, 8192); @@ -621,7 +621,6 @@ void Bed3D::render_prusa_shader(bool transparent) const m_shader.stop_using(); } } - #else void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) const { @@ -629,7 +628,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons // use higher resolution images if graphic card allows GLint max_tex_size; - ::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); + glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size)); // temporary set to lowest resolution max_tex_size = 2048; @@ -644,7 +643,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons // use anisotropic filter if graphic card allows GLfloat max_anisotropy = 0.0f; if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) - ::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); + glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy)); std::string filename = tex_path + "_top.png"; if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename)) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c845ca4b40..aafc3215a1 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -99,25 +99,25 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs) if (use_VBOs) { if (! empty()) { - glsafe(glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); - glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); - glsafe(glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW)); - glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); this->vertices_and_normals_interleaved.clear(); } if (! this->triangle_indices.empty()) { - glsafe(glGenBuffers(1, &this->triangle_indices_VBO_id)); - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); - glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW)); + glsafe(::glGenBuffers(1, &this->triangle_indices_VBO_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW)); this->triangle_indices.clear(); } if (! this->quad_indices.empty()) { - glsafe(glGenBuffers(1, &this->quad_indices_VBO_id)); - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); - glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW)); + glsafe(::glGenBuffers(1, &this->quad_indices_VBO_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW)); this->quad_indices.clear(); } - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } this->shrink_to_fit(); } @@ -125,15 +125,15 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs) void GLIndexedVertexArray::release_geometry() { if (this->vertices_and_normals_interleaved_VBO_id) { - glsafe(glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id)); this->vertices_and_normals_interleaved_VBO_id = 0; } if (this->triangle_indices_VBO_id) { - glsafe(glDeleteBuffers(1, &this->triangle_indices_VBO_id)); + glsafe(::glDeleteBuffers(1, &this->triangle_indices_VBO_id)); this->triangle_indices_VBO_id = 0; } if (this->quad_indices_VBO_id) { - glsafe(glDeleteBuffers(1, &this->quad_indices_VBO_id)); + glsafe(::glDeleteBuffers(1, &this->quad_indices_VBO_id)); this->quad_indices_VBO_id = 0; } this->clear(); @@ -143,42 +143,42 @@ void GLIndexedVertexArray::release_geometry() void GLIndexedVertexArray::render() const { if (this->vertices_and_normals_interleaved_VBO_id) { - glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); - glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); - glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); } else { - glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); - glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); } - glsafe(glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(glEnableClientState(GL_NORMAL_ARRAY)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); if (this->indexed()) { if (this->vertices_and_normals_interleaved_VBO_id) { // Render using the Vertex Buffer Objects. if (this->triangle_indices_size > 0) { - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); - glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr)); } if (this->quad_indices_size > 0) { - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); - glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr)); } glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { // Render in an immediate mode. if (! this->triangle_indices.empty()) - glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data())); + glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data())); if (! this->quad_indices.empty()) - glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data())); + glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data())); } } else - glsafe(glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6))); + glsafe(::glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6))); if (this->vertices_and_normals_interleaved_VBO_id) - glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0)); - glsafe(glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); } void GLIndexedVertexArray::render( @@ -191,35 +191,35 @@ void GLIndexedVertexArray::render( if (this->vertices_and_normals_interleaved_VBO_id) { // Render using the Vertex Buffer Objects. - glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); - glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); - glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); - glsafe(glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(glEnableClientState(GL_NORMAL_ARRAY)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)))); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); if (this->triangle_indices_size > 0) { - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); - glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id)); + glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4))); } if (this->quad_indices_size > 0) { - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); - glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id)); + glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4))); } - glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0)); - glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { // Render in an immediate mode. - glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); - glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); - glsafe(glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(glEnableClientState(GL_NORMAL_ARRAY)); + glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3)); + glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data())); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); if (! this->triangle_indices.empty()) - glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first))); + glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first))); if (! this->quad_indices.empty()) - glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first))); + glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first))); } - glsafe(glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); } const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; @@ -761,12 +761,13 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool GLint current_program_id; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; - GLint z_range_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "z_range") : -1; - GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1; - GLint print_box_max_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.max") : -1; - GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; - GLint print_box_worldmatrix_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1; + GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1; + GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1; + GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1; + GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; + GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1; + glcheck(); if (print_box_min_id != -1) glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min)); @@ -797,15 +798,15 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, std::function filter_func) const { - glsafe(glEnable(GL_BLEND)); - glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - glsafe(glCullFace(GL_BACK)); + glsafe(::glCullFace(GL_BACK)); if (disable_cullface) glsafe(::glDisable(GL_CULL_FACE)); - glsafe(glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(glEnableClientState(GL_NORMAL_ARRAY)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func); for (GLVolumeWithZ& volume : to_render) @@ -814,13 +815,13 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, volume.first->render_legacy(); } - glsafe(glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); if (disable_cullface) glsafe(::glEnable(GL_CULL_FACE)); - glsafe(glDisable(GL_BLEND)); + glsafe(::glDisable(GL_BLEND)); } bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state) @@ -1749,7 +1750,8 @@ void GLModel::render_VBOs() const GLint current_program_id; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); - GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; + GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + glcheck(); m_volume.render_VBOs(color_id, -1, -1); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index e421997e5d..fa58ddb502 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -19,6 +19,7 @@ extern void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char *function_name); inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } #define glsafe(cmd) do { cmd; glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false) +#define glcheck() do { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false) #else inline void glAssertRecentCall() { } #define glsafe(cmd) cmd diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index fe74bb5759..9514eaaa83 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -227,7 +227,7 @@ GLCanvas3D::LayersEditing::~LayersEditing() { if (m_z_texture_id != 0) { - ::glDeleteTextures(1, &m_z_texture_id); + glsafe(::glDeleteTextures(1, &m_z_texture_id)); m_z_texture_id = 0; } delete m_slicing_parameters; @@ -241,14 +241,14 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, if (!m_shader.init(vertex_shader_filename, fragment_shader_filename)) return false; - ::glGenTextures(1, (GLuint*)&m_z_texture_id); - ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - ::glBindTexture(GL_TEXTURE_2D, 0); + glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); return true; } @@ -304,12 +304,12 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const const Rect& bar_rect = get_bar_rect_viewport(canvas); const Rect& reset_rect = get_reset_rect_viewport(canvas); - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST)); // The viewport and camera are set to complete view and glOrtho(-$x / 2, $x / 2, -$y / 2, $y / 2, -$depth, $depth), // where x, y is the window size divided by $self->_zoom. - ::glPushMatrix(); - ::glLoadIdentity(); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); _render_tooltip_texture(canvas, bar_rect, reset_rect); _render_reset_texture(reset_rect); @@ -317,9 +317,9 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const _render_profile(bar_rect); // Revert the matrices. - ::glPopMatrix(); + glsafe(::glPopMatrix()); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_DEPTH_TEST)); } float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas) @@ -455,8 +455,8 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas // The shader requires the original model coordinates when rendering to the texture, so we pass it the unit matrix m_shader.set_uniform("volume_world_matrix", UNIT_MATRIX); - ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id); + glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); // Render the color bar float l = bar_rect.get_left(); @@ -470,8 +470,8 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas ::glVertex3f(r, b, 0.0f); ::glVertex3f(r, t, m_object_max_z); ::glVertex3f(l, t, m_object_max_z); - ::glEnd(); - ::glBindTexture(GL_TEXTURE_2D, 0); + glsafe(::glEnd()); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); m_shader.stop_using(); } @@ -487,18 +487,18 @@ void GLCanvas3D::LayersEditing::_render_profile(const Rect& bar_rect) const float x = bar_rect.get_left() + (float)m_slicing_parameters->layer_height * scale_x; // Baseline - ::glColor3f(0.0f, 0.0f, 0.0f); + glsafe(::glColor3f(0.0f, 0.0f, 0.0f)); ::glBegin(GL_LINE_STRIP); ::glVertex2f(x, bar_rect.get_bottom()); ::glVertex2f(x, bar_rect.get_top()); - ::glEnd(); + glsafe(::glEnd()); // Curve - ::glColor3f(0.0f, 0.0f, 1.0f); + glsafe(::glColor3f(0.0f, 0.0f, 1.0f)); ::glBegin(GL_LINE_STRIP); for (unsigned int i = 0; i < m_layer_height_profile.size(); i += 2) ::glVertex2f(bar_rect.get_left() + (float)m_layer_height_profile[i + 1] * scale_x, bar_rect.get_bottom() + (float)m_layer_height_profile[i] * scale_y); - ::glEnd(); + glsafe(::glEnd()); } void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection &volumes) const @@ -509,51 +509,52 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G assert(shader_id > 0); GLint current_program_id; - glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); if (shader_id > 0 && shader_id != current_program_id) // The layer editing shader is not yet active. Activate it. - glUseProgram(shader_id); + glsafe(::glUseProgram(shader_id)); else // The layer editing shader was already active. current_program_id = -1; - GLint z_to_texture_row_id = glGetUniformLocation(shader_id, "z_to_texture_row"); - GLint z_texture_row_to_normalized_id = glGetUniformLocation(shader_id, "z_texture_row_to_normalized"); - GLint z_cursor_id = glGetUniformLocation(shader_id, "z_cursor"); - GLint z_cursor_band_width_id = glGetUniformLocation(shader_id, "z_cursor_band_width"); - GLint world_matrix_id = glGetUniformLocation(shader_id, "volume_world_matrix"); + GLint z_to_texture_row_id = ::glGetUniformLocation(shader_id, "z_to_texture_row"); + GLint z_texture_row_to_normalized_id = ::glGetUniformLocation(shader_id, "z_texture_row_to_normalized"); + GLint z_cursor_id = ::glGetUniformLocation(shader_id, "z_cursor"); + GLint z_cursor_band_width_id = ::glGetUniformLocation(shader_id, "z_cursor_band_width"); + GLint world_matrix_id = ::glGetUniformLocation(shader_id, "volume_world_matrix"); + glcheck(); if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1) { const_cast(this)->generate_layer_height_texture(); // Uniforms were resolved, go ahead using the layer editing shader. - glUniform1f(z_to_texture_row_id, GLfloat(m_layers_texture.cells - 1) / (GLfloat(m_layers_texture.width) * GLfloat(m_object_max_z))); - glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height)); - glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas))); - glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width)); + glsafe(::glUniform1f(z_to_texture_row_id, GLfloat(m_layers_texture.cells - 1) / (GLfloat(m_layers_texture.width) * GLfloat(m_object_max_z)))); + glsafe(::glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height))); + glsafe(::glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas)))); + glsafe(::glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width))); // Initialize the layer height texture mapping. GLsizei w = (GLsizei)m_layers_texture.width; GLsizei h = (GLsizei)m_layers_texture.height; GLsizei half_w = w / 2; GLsizei half_h = h / 2; - ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBindTexture(GL_TEXTURE_2D, m_z_texture_id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data()); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4); + glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data())); + glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4)); for (const GLVolume *glvolume : volumes.volumes) { // Render the object using the layer editing shader and texture. if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) continue; - ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data()); + glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); glvolume->render(); } // Revert back to the previous shader. glBindTexture(GL_TEXTURE_2D, 0); if (current_program_id > 0) - glUseProgram(current_program_id); + glsafe(::glUseProgram(current_program_id)); } else { @@ -563,7 +564,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G // Render the object using the layer editing shader and texture. if (!glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) continue; - ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data()); + glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data())); glvolume->render(); } } @@ -846,14 +847,14 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL } // sends buffer to gpu - ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - ::glGenTextures(1, &m_id); - ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - ::glBindTexture(GL_TEXTURE_2D, 0); + glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + glsafe(::glGenTextures(1, &m_id)); + glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data())); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); return true; } @@ -865,9 +866,9 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0)) { - ::glDisable(GL_DEPTH_TEST); - ::glPushMatrix(); - ::glLoadIdentity(); + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); const Size& cnv_size = canvas.get_canvas_size(); float zoom = canvas.get_camera_zoom(); @@ -890,8 +891,8 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs); - ::glPopMatrix(); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glPopMatrix()); + glsafe(::glEnable(GL_DEPTH_TEST)); } } @@ -1118,14 +1119,14 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c } // sends buffer to gpu - ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - ::glGenTextures(1, &m_id); - ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - ::glBindTexture(GL_TEXTURE_2D, 0); + glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + glsafe(::glGenTextures(1, &m_id)); + glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data())); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); return true; } @@ -1134,9 +1135,9 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const { if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0)) { - ::glDisable(GL_DEPTH_TEST); - ::glPushMatrix(); - ::glLoadIdentity(); + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); const Size& cnv_size = canvas.get_canvas_size(); float zoom = canvas.get_camera_zoom(); @@ -1159,8 +1160,8 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs); - ::glPopMatrix(); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glPopMatrix()); + glsafe(::glEnable(GL_DEPTH_TEST)); } } @@ -1249,48 +1250,48 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) if ((m_canvas == nullptr) || (m_context == nullptr)) return false; - ::glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - ::glClearDepth(1.0f); + glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f)); + glsafe(::glClearDepth(1.0f)); - ::glDepthFunc(GL_LESS); + glsafe(::glDepthFunc(GL_LESS)); - ::glEnable(GL_DEPTH_TEST); - ::glEnable(GL_CULL_FACE); - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glEnable(GL_CULL_FACE)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); // Set antialiasing / multisampling - ::glDisable(GL_LINE_SMOOTH); - ::glDisable(GL_POLYGON_SMOOTH); + glsafe(::glDisable(GL_LINE_SMOOTH)); + glsafe(::glDisable(GL_POLYGON_SMOOTH)); // ambient lighting GLfloat ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f }; - ::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + glsafe(::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient)); - ::glEnable(GL_LIGHT0); - ::glEnable(GL_LIGHT1); + glsafe(::glEnable(GL_LIGHT0)); + glsafe(::glEnable(GL_LIGHT1)); // light from camera GLfloat specular_cam[4] = { 0.3f, 0.3f, 0.3f, 1.0f }; - ::glLightfv(GL_LIGHT1, GL_SPECULAR, specular_cam); + glsafe(::glLightfv(GL_LIGHT1, GL_SPECULAR, specular_cam)); GLfloat diffuse_cam[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; - ::glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_cam); + glsafe(::glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_cam)); // light from above GLfloat specular_top[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; - ::glLightfv(GL_LIGHT0, GL_SPECULAR, specular_top); + glsafe(::glLightfv(GL_LIGHT0, GL_SPECULAR, specular_top)); GLfloat diffuse_top[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; - ::glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_top); + glsafe(::glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_top)); // Enables Smooth Color Shading; try GL_FLAT for (lack of) fun. - ::glShadeModel(GL_SMOOTH); + glsafe(::glShadeModel(GL_SMOOTH)); // A handy trick -- have surface material mirror the color. - ::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - ::glEnable(GL_COLOR_MATERIAL); + glsafe(::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)); + glsafe(::glEnable(GL_COLOR_MATERIAL)); if (m_multisample_allowed) - ::glEnable(GL_MULTISAMPLE); + glsafe(::glEnable(GL_MULTISAMPLE)); if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs")) return false; @@ -1605,9 +1606,9 @@ void GLCanvas3D::render() _camera_tranform(); GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; - ::glLightfv(GL_LIGHT1, GL_POSITION, position_cam); + glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam)); GLfloat position_top[4] = { -0.5f, -0.5f, 1.0f, 0.0f }; - ::glLightfv(GL_LIGHT0, GL_POSITION, position_top); + glsafe(::glLightfv(GL_LIGHT0, GL_POSITION, position_top)); float theta = m_camera.get_theta(); if (theta > 180.f) @@ -1620,7 +1621,7 @@ void GLCanvas3D::render() _picking_pass(); // draw scene - ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); _render_background(); // textured bed needs to be rendered after objects if the texture is transparent @@ -2656,7 +2657,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // get the view matrix back from opengl GLfloat matrix[16]; - ::glGetFloatv(GL_MODELVIEW_MATRIX, matrix); + 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]); @@ -3339,10 +3340,10 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) // ensures that this canvas is current _set_current(); - ::glViewport(0, 0, w, h); + glsafe(::glViewport(0, 0, w, h)); - ::glMatrixMode(GL_PROJECTION); - ::glLoadIdentity(); + glsafe(::glMatrixMode(GL_PROJECTION)); + glsafe(::glLoadIdentity()); const BoundingBoxf3& bbox = _max_bounding_box(); @@ -3362,7 +3363,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(); - ::glOrtho(-w2, w2, -h2, h2, -depth, depth); + glsafe(::glOrtho(-w2, w2, -h2, h2, -depth, depth)); break; } @@ -3395,7 +3396,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) } } - ::glMatrixMode(GL_MODELVIEW); + glsafe(::glMatrixMode(GL_MODELVIEW)); m_dirty = false; } @@ -3434,7 +3435,7 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co // get the view matrix back from opengl GLfloat matrix[16]; - ::glGetFloatv(GL_MODELVIEW_MATRIX, matrix); + glsafe(::glGetFloatv(GL_MODELVIEW_MATRIX, matrix)); // camera axes Vec3d right((double)matrix[0], (double)matrix[4], (double)matrix[8]); @@ -3502,13 +3503,13 @@ void GLCanvas3D::_refresh_if_shown_on_screen() void GLCanvas3D::_camera_tranform() const { - ::glMatrixMode(GL_MODELVIEW); - ::glLoadIdentity(); + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glLoadIdentity()); - ::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch - ::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw + 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(); - ::glTranslated(target(0), target(1), target(2)); + glsafe(::glTranslated(target(0), target(1), target(2))); } void GLCanvas3D::_picking_pass() const @@ -3522,18 +3523,18 @@ void GLCanvas3D::_picking_pass() const // Better to use software ray - casting on a bounding - box hierarchy. if (m_multisample_allowed) - ::glDisable(GL_MULTISAMPLE); + glsafe(::glDisable(GL_MULTISAMPLE)); - ::glDisable(GL_BLEND); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); - ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); _render_volumes(true); m_gizmos.render_current_gizmo_for_picking_pass(m_selection); if (m_multisample_allowed) - ::glEnable(GL_MULTISAMPLE); + glsafe(::glEnable(GL_MULTISAMPLE)); int volume_id = -1; @@ -3542,7 +3543,7 @@ void GLCanvas3D::_picking_pass() const bool inside = (0 <= pos(0)) && (pos(0) < cnv_size.get_width()) && (0 <= pos(1)) && (pos(1) < cnv_size.get_height()); if (inside) { - ::glReadPixels(pos(0), cnv_size.get_height() - pos(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); + glsafe(::glReadPixels(pos(0), cnv_size.get_height() - pos(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color)); volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256; } if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) @@ -3562,14 +3563,14 @@ void GLCanvas3D::_picking_pass() const void GLCanvas3D::_render_background() const { - ::glPushMatrix(); - ::glLoadIdentity(); - ::glMatrixMode(GL_PROJECTION); - ::glPushMatrix(); - ::glLoadIdentity(); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); + glsafe(::glMatrixMode(GL_PROJECTION)); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); // Draws a bottom to top gradient over the complete screen. - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST)); ::glBegin(GL_QUADS); if (m_dynamic_background_enabled && _is_any_volume_outside()) @@ -3587,13 +3588,13 @@ void GLCanvas3D::_render_background() const ::glVertex2f(1.0f, 1.0f); ::glVertex2f(-1.0f, 1.0f); - ::glEnd(); + glsafe(::glEnd()); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_DEPTH_TEST)); - ::glPopMatrix(); - ::glMatrixMode(GL_MODELVIEW); - ::glPopMatrix(); + glsafe(::glPopMatrix()); + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glPopMatrix()); } void GLCanvas3D::_render_bed(float theta) const @@ -3615,8 +3616,8 @@ void GLCanvas3D::_render_objects() const if (m_volumes.empty()) return; - ::glEnable(GL_LIGHTING); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); if (m_use_VBOs) { @@ -3660,10 +3661,10 @@ void GLCanvas3D::_render_objects() const { if (m_use_clipping_planes) { - ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_clipping_planes[0].get_data()); - ::glEnable(GL_CLIP_PLANE0); - ::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[1].get_data()); - ::glEnable(GL_CLIP_PLANE1); + glsafe(::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_clipping_planes[0].get_data())); + glsafe(::glEnable(GL_CLIP_PLANE0)); + glsafe(::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[1].get_data())); + glsafe(::glEnable(GL_CLIP_PLANE1)); } // do not cull backfaces to show broken geometry, if any @@ -3674,12 +3675,12 @@ void GLCanvas3D::_render_objects() const if (m_use_clipping_planes) { - ::glDisable(GL_CLIP_PLANE0); - ::glDisable(GL_CLIP_PLANE1); + glsafe(::glDisable(GL_CLIP_PLANE0)); + glsafe(::glDisable(GL_CLIP_PLANE1)); } } - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); } void GLCanvas3D::_render_selection() const @@ -3719,16 +3720,16 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const static const GLfloat INV_255 = 1.0f / 255.0f; if (!fake_colors) - ::glEnable(GL_LIGHTING); + glsafe(::glEnable(GL_LIGHTING)); // do not cull backfaces to show broken geometry, if any - ::glDisable(GL_CULL_FACE); + glsafe(::glDisable(GL_CULL_FACE)); - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - ::glEnableClientState(GL_VERTEX_ARRAY); - ::glEnableClientState(GL_NORMAL_ARRAY); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); unsigned int volume_id = 0; for (GLVolume* vol : m_volumes.volumes) @@ -3739,12 +3740,12 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const unsigned int r = (volume_id & 0x000000FF) >> 0; unsigned int g = (volume_id & 0x0000FF00) >> 8; unsigned int b = (volume_id & 0x00FF0000) >> 16; - ::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255); + glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255)); } else { vol->set_render_color(); - ::glColor4fv(vol->render_color); + glsafe(::glColor4fv(vol->render_color)); } if ((!fake_colors || !vol->disabled) && (vol->composite_id.volume_id >= 0 || m_render_sla_auxiliaries)) @@ -3753,14 +3754,14 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const ++volume_id; } - ::glDisableClientState(GL_NORMAL_ARRAY); - ::glDisableClientState(GL_VERTEX_ARRAY); - ::glDisable(GL_BLEND); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisable(GL_BLEND)); - ::glEnable(GL_CULL_FACE); + glsafe(::glEnable(GL_CULL_FACE)); if (!fake_colors) - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); } void GLCanvas3D::_render_current_gizmo() const @@ -3874,9 +3875,9 @@ void GLCanvas3D::_render_camera_target() const { double half_length = 5.0; - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST)); - ::glLineWidth(2.0f); + glsafe(::glLineWidth(2.0f)); ::glBegin(GL_LINES); const Vec3d& target = m_camera.get_target(); // draw line for x axis @@ -3891,7 +3892,7 @@ void GLCanvas3D::_render_camera_target() const ::glColor3f(0.0f, 0.0f, 1.0f); ::glVertex3d(target(0), target(1), target(2) - half_length); ::glVertex3d(target(0), target(1), target(2) + half_length); - ::glEnd(); + glsafe(::glEnd()); } #endif // ENABLE_SHOW_CAMERA_TARGET @@ -3993,9 +3994,9 @@ void GLCanvas3D::_render_sla_slices() const { for (const InstanceTransform& inst : instance_transforms) { - ::glPushMatrix(); - ::glTranslated(inst.offset(0), inst.offset(1), inst.offset(2)); - ::glRotatef(inst.rotation, 0.0, 0.0, 1.0); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(inst.offset(0), inst.offset(1), inst.offset(2))); + glsafe(::glRotatef(inst.rotation, 0.0, 0.0, 1.0)); ::glBegin(GL_TRIANGLES); @@ -4023,9 +4024,9 @@ void GLCanvas3D::_render_sla_slices() const ::glVertex3dv((GLdouble*)v.data()); } - ::glEnd(); + glsafe(::glEnd()); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } } } @@ -4109,16 +4110,16 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z) _camera_tranform(); GLint viewport[4]; - ::glGetIntegerv(GL_VIEWPORT, viewport); + glsafe(::glGetIntegerv(GL_VIEWPORT, viewport)); GLdouble modelview_matrix[16]; - ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix); + glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix)); GLdouble projection_matrix[16]; - ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix); + glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix)); GLint y = viewport[3] - (GLint)mouse_pos(1); GLfloat mouse_z; if (z == nullptr) - ::glReadPixels((GLint)mouse_pos(0), y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&mouse_z); + glsafe(::glReadPixels((GLint)mouse_pos(0), y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&mouse_z)); else mouse_z = *z; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index f401f54662..7f3bc0893a 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -3,6 +3,7 @@ #include "GLShader.hpp" #include "libslic3r/Utils.hpp" +#include "3DScene.hpp" #include #include @@ -52,21 +53,22 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh } if (fragment_shader != nullptr) { - this->fragment_program_id = glCreateShader(GL_FRAGMENT_SHADER); + this->fragment_program_id = ::glCreateShader(GL_FRAGMENT_SHADER); + glcheck(); if (this->fragment_program_id == 0) { last_error = "glCreateShader(GL_FRAGMENT_SHADER) failed."; return false; } GLint len = (GLint)strlen(fragment_shader); - glShaderSource(this->fragment_program_id, 1, &fragment_shader, &len); - glCompileShader(this->fragment_program_id); + glsafe(::glShaderSource(this->fragment_program_id, 1, &fragment_shader, &len)); + glsafe(::glCompileShader(this->fragment_program_id)); GLint params; - glGetShaderiv(this->fragment_program_id, GL_COMPILE_STATUS, ¶ms); + glsafe(::glGetShaderiv(this->fragment_program_id, GL_COMPILE_STATUS, ¶ms)); if (params == GL_FALSE) { // Compilation failed. Get the log. - glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, ¶ms); + glsafe(::glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, ¶ms)); std::vector msg(params); - glGetShaderInfoLog(this->fragment_program_id, params, ¶ms, msg.data()); + glsafe(::glGetShaderInfoLog(this->fragment_program_id, params, ¶ms, msg.data())); this->last_error = std::string("Fragment shader compilation failed:\n") + msg.data(); this->release(); return false; @@ -74,22 +76,23 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh } if (vertex_shader != nullptr) { - this->vertex_program_id = glCreateShader(GL_VERTEX_SHADER); + this->vertex_program_id = ::glCreateShader(GL_VERTEX_SHADER); + glcheck(); if (this->vertex_program_id == 0) { last_error = "glCreateShader(GL_VERTEX_SHADER) failed."; this->release(); return false; } GLint len = (GLint)strlen(vertex_shader); - glShaderSource(this->vertex_program_id, 1, &vertex_shader, &len); - glCompileShader(this->vertex_program_id); + glsafe(::glShaderSource(this->vertex_program_id, 1, &vertex_shader, &len)); + glsafe(::glCompileShader(this->vertex_program_id)); GLint params; - glGetShaderiv(this->vertex_program_id, GL_COMPILE_STATUS, ¶ms); + glsafe(::glGetShaderiv(this->vertex_program_id, GL_COMPILE_STATUS, ¶ms)); if (params == GL_FALSE) { // Compilation failed. Get the log. - glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms); + glsafe(::glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms)); std::vector msg(params); - glGetShaderInfoLog(this->vertex_program_id, params, ¶ms, msg.data()); + glsafe(::glGetShaderInfoLog(this->vertex_program_id, params, ¶ms, msg.data())); this->last_error = std::string("Vertex shader compilation failed:\n") + msg.data(); this->release(); return false; @@ -97,7 +100,8 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh } // Link shaders - this->shader_program_id = glCreateProgram(); + this->shader_program_id = ::glCreateProgram(); + glcheck(); if (this->shader_program_id == 0) { last_error = "glCreateProgram() failed."; this->release(); @@ -105,18 +109,18 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh } if (this->fragment_program_id) - glAttachShader(this->shader_program_id, this->fragment_program_id); + glsafe(::glAttachShader(this->shader_program_id, this->fragment_program_id)); if (this->vertex_program_id) - glAttachShader(this->shader_program_id, this->vertex_program_id); - glLinkProgram(this->shader_program_id); + glsafe(::glAttachShader(this->shader_program_id, this->vertex_program_id)); + glsafe(::glLinkProgram(this->shader_program_id)); GLint params; - glGetProgramiv(this->shader_program_id, GL_LINK_STATUS, ¶ms); + glsafe(::glGetProgramiv(this->shader_program_id, GL_LINK_STATUS, ¶ms)); if (params == GL_FALSE) { // Linking failed. Get the log. - glGetProgramiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms); + glsafe(::glGetProgramiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms)); std::vector msg(params); - glGetProgramInfoLog(this->vertex_program_id, params, ¶ms, msg.data()); + glsafe(::glGetProgramInfoLog(this->vertex_program_id, params, ¶ms, msg.data())); this->last_error = std::string("Shader linking failed:\n") + msg.data(); this->release(); return false; @@ -165,31 +169,31 @@ void GLShader::release() { if (this->shader_program_id) { if (this->vertex_program_id) - glDetachShader(this->shader_program_id, this->vertex_program_id); + glsafe(::glDetachShader(this->shader_program_id, this->vertex_program_id)); if (this->fragment_program_id) - glDetachShader(this->shader_program_id, this->fragment_program_id); - glDeleteProgram(this->shader_program_id); + glsafe(::glDetachShader(this->shader_program_id, this->fragment_program_id)); + glsafe(::glDeleteProgram(this->shader_program_id)); this->shader_program_id = 0; } if (this->vertex_program_id) { - glDeleteShader(this->vertex_program_id); + glsafe(::glDeleteShader(this->vertex_program_id)); this->vertex_program_id = 0; } if (this->fragment_program_id) { - glDeleteShader(this->fragment_program_id); + glsafe(::glDeleteShader(this->fragment_program_id)); this->fragment_program_id = 0; } } void GLShader::enable() const { - glUseProgram(this->shader_program_id); + glsafe(::glUseProgram(this->shader_program_id)); } void GLShader::disable() const { - glUseProgram(0); + glsafe(::glUseProgram(0)); } // Return shader vertex attribute ID @@ -208,7 +212,7 @@ bool GLShader::set_uniform(const char *name, float value) const { int id = this->get_uniform_location(name); if (id >= 0) { - glUniform1fARB(id, value); + glsafe(::glUniform1fARB(id, value)); return true; } return false; @@ -219,7 +223,7 @@ bool GLShader::set_uniform(const char* name, const float* matrix) const int id = get_uniform_location(name); if (id >= 0) { - ::glUniformMatrix4fv(id, 1, GL_FALSE, (const GLfloat*)matrix); + glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, (const GLfloat*)matrix)); return true; } return false; @@ -230,7 +234,7 @@ bool GLShader::set_uniform(const char* name, int value) const int id = get_uniform_location(name); if (id >= 0) { - ::glUniform1i(id, value); + glsafe(::glUniform1i(id, value)); return true; } return false; diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index c1a0357544..ec41d7e93d 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -1,6 +1,8 @@ #include "libslic3r/libslic3r.h" #include "GLTexture.hpp" +#include "3DScene.hpp" + #include #include @@ -177,15 +179,15 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vectorget_instance_transformation().get_matrix(); - ::glPushMatrix(); - ::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()); - ::glMultMatrixd(m.data()); + glsafe(::glPushMatrix()); + glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); + glsafe(::glMultMatrixd(m.data())); if (this->is_plane_update_necessary()) const_cast(this)->update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { if (i == m_hover_id) - ::glColor4f(0.9f, 0.9f, 0.9f, 0.75f); + glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.75f)); else - ::glColor4f(0.9f, 0.9f, 0.9f, 0.5f); + glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.5f)); ::glBegin(GL_POLYGON); for (const Vec3d& vertex : m_planes[i].vertices) { ::glVertex3dv(vertex.data()); } - ::glEnd(); + glsafe(::glEnd()); } - ::glPopMatrix(); + glsafe(::glPopMatrix()); } - ::glEnable(GL_CULL_FACE); - ::glDisable(GL_BLEND); + glsafe(::glEnable(GL_CULL_FACE)); + glsafe(::glDisable(GL_BLEND)); } void GLGizmoFlatten::on_render_for_picking(const Selection& selection) const { - ::glDisable(GL_DEPTH_TEST); - ::glDisable(GL_BLEND); + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_BLEND)); if (selection.is_single_full_instance()) { const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(); - ::glPushMatrix(); - ::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()); - ::glMultMatrixd(m.data()); + glsafe(::glPushMatrix()); + glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z())); + glsafe(::glMultMatrixd(m.data())); if (this->is_plane_update_necessary()) const_cast(this)->update_planes(); for (int i = 0; i < (int)m_planes.size(); ++i) { - ::glColor3fv(picking_color_component(i).data()); + glsafe(::glColor3fv(picking_color_component(i).data())); ::glBegin(GL_POLYGON); for (const Vec3d& vertex : m_planes[i].vertices) { ::glVertex3dv(vertex.data()); } - ::glEnd(); + glsafe(::glEnd()); } - ::glPopMatrix(); + glsafe(::glPopMatrix()); } - ::glEnable(GL_CULL_FACE); + glsafe(::glEnable(GL_CULL_FACE)); } void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 61f219dbff..7cc5b6485b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -97,8 +97,8 @@ void GLGizmoMove3D::on_render(const Selection& selection) const else if (!m_grabbers[2].dragging && (m_hover_id == 2)) set_tooltip("Z"); - ::glClear(GL_DEPTH_BUFFER_BIT); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_DEPTH_TEST)); const BoundingBoxf3& box = selection.get_bounding_box(); const Vec3d& center = box.center(); @@ -115,7 +115,7 @@ void GLGizmoMove3D::on_render(const Selection& selection) const m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset); ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float)); - ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f); + glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); if (m_hover_id == -1) { @@ -124,11 +124,11 @@ void GLGizmoMove3D::on_render(const Selection& selection) const { if (m_grabbers[i].enabled) { - ::glColor3fv(AXES_COLOR[i]); + glsafe(::glColor3fv(AXES_COLOR[i])); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[i].center.data()); - ::glEnd(); + glsafe(::glEnd()); } } @@ -143,11 +143,11 @@ void GLGizmoMove3D::on_render(const Selection& selection) const else { // draw axis - ::glColor3fv(AXES_COLOR[m_hover_id]); + glsafe(::glColor3fv(AXES_COLOR[m_hover_id])); ::glBegin(GL_LINES); ::glVertex3dv(center.data()); ::glVertex3dv(m_grabbers[m_hover_id].center.data()); - ::glEnd(); + glsafe(::glEnd()); // draw grabber m_grabbers[m_hover_id].render(true, box.max_size()); @@ -157,7 +157,7 @@ void GLGizmoMove3D::on_render(const Selection& selection) const void GLGizmoMove3D::on_render_for_picking(const Selection& selection) const { - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST)); const BoundingBoxf3& box = selection.get_bounding_box(); render_grabbers_for_picking(box); @@ -229,25 +229,25 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box } if (!picking) - ::glEnable(GL_LIGHTING); + glsafe(::glEnable(GL_LIGHTING)); - ::glColor3fv(color); - ::glPushMatrix(); - ::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2)); + glsafe(::glColor3fv(color)); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2))); if (axis == X) - ::glRotated(90.0, 0.0, 1.0, 0.0); + glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); else if (axis == Y) - ::glRotated(-90.0, 1.0, 0.0, 0.0); + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); - ::glTranslated(0.0, 0.0, 2.0 * size); + glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); ::gluQuadricOrientation(m_quadric, GLU_INSIDE); ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); - ::glPopMatrix(); + glsafe(::glPopMatrix()); if (!picking) - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index e05ad00fe0..ff9cf380e2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -155,13 +155,13 @@ void GLGizmoRotate::on_render(const Selection& selection) const m_snap_fine_out_radius = m_radius * (1.0f + ScaleLongTooth); } - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_DEPTH_TEST)); - ::glPushMatrix(); + glsafe(::glPushMatrix()); transform_to_local(selection); - ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f); - ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color); + glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); + glsafe(::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); render_circle(); @@ -172,7 +172,7 @@ void GLGizmoRotate::on_render(const Selection& selection) const render_reference_radius(); } - ::glColor3fv(m_highlight_color); + glsafe(::glColor3fv(m_highlight_color)); if (m_hover_id != -1) render_angle(); @@ -180,14 +180,14 @@ void GLGizmoRotate::on_render(const Selection& selection) const render_grabber(box); render_grabber_extension(box, false); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } void GLGizmoRotate::on_render_for_picking(const Selection& selection) const { - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST)); - ::glPushMatrix(); + glsafe(::glPushMatrix()); transform_to_local(selection); @@ -195,7 +195,7 @@ void GLGizmoRotate::on_render_for_picking(const Selection& selection) const render_grabbers_for_picking(box); render_grabber_extension(box, true); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } void GLGizmoRotate::render_circle() const @@ -209,7 +209,7 @@ void GLGizmoRotate::render_circle() const float z = 0.0f; ::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z); } - ::glEnd(); + glsafe(::glEnd()); } void GLGizmoRotate::render_scale() const @@ -232,7 +232,7 @@ void GLGizmoRotate::render_scale() const ::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z); ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z); } - ::glEnd(); + glsafe(::glEnd()); } void GLGizmoRotate::render_snap_radii() const @@ -257,7 +257,7 @@ void GLGizmoRotate::render_snap_radii() const ::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z); ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z); } - ::glEnd(); + glsafe(::glEnd()); } void GLGizmoRotate::render_reference_radius() const @@ -265,7 +265,7 @@ void GLGizmoRotate::render_reference_radius() const ::glBegin(GL_LINES); ::glVertex3f(0.0f, 0.0f, 0.0f); ::glVertex3f((GLfloat)(m_radius * (1.0f + GrabberOffset)), 0.0f, 0.0f); - ::glEnd(); + glsafe(::glEnd()); } void GLGizmoRotate::render_angle() const @@ -282,7 +282,7 @@ void GLGizmoRotate::render_angle() const float z = 0.0f; ::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z); } - ::glEnd(); + glsafe(::glEnd()); } void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const @@ -291,12 +291,12 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); m_grabbers[0].angles(2) = m_angle; - ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color); + glsafe(::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color)); ::glBegin(GL_LINES); ::glVertex3f(0.0f, 0.0f, 0.0f); ::glVertex3dv(m_grabbers[0].center.data()); - ::glEnd(); + glsafe(::glEnd()); ::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 3 * sizeof(float)); render_grabbers(box); @@ -320,56 +320,56 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick } if (!picking) - ::glEnable(GL_LIGHTING); + glsafe(::glEnable(GL_LIGHTING)); - ::glColor3fv(color); - ::glPushMatrix(); - ::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2)); - ::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0); - ::glRotated(90.0, 1.0, 0.0, 0.0); - ::glTranslated(0.0, 0.0, 2.0 * size); + glsafe(::glColor3fv(color)); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); + glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); ::gluQuadricOrientation(m_quadric, GLU_INSIDE); ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); - ::glPopMatrix(); - ::glPushMatrix(); - ::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2)); - ::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0); - ::glRotated(-90.0, 1.0, 0.0, 0.0); - ::glTranslated(0.0, 0.0, 2.0 * size); + glsafe(::glPopMatrix()); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2))); + glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); ::gluQuadricOrientation(m_quadric, GLU_OUTSIDE); ::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1); ::gluQuadricOrientation(m_quadric, GLU_INSIDE); ::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1); - ::glPopMatrix(); + glsafe(::glPopMatrix()); if (!picking) - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); } void GLGizmoRotate::transform_to_local(const Selection& selection) const { - ::glTranslated(m_center(0), m_center(1), m_center(2)); + glsafe(::glTranslated(m_center(0), m_center(1), m_center(2))); if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) { Transform3d orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true); - ::glMultMatrixd(orient_matrix.data()); + glsafe(::glMultMatrixd(orient_matrix.data())); } switch (m_axis) { case X: { - ::glRotatef(90.0f, 0.0f, 1.0f, 0.0f); - ::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f); + glsafe(::glRotatef(90.0f, 0.0f, 1.0f, 0.0f)); + glsafe(::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f)); break; } case Y: { - ::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f); - ::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + glsafe(::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f)); + glsafe(::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f)); break; } default: @@ -472,7 +472,7 @@ void GLGizmoRotate3D::on_stop_dragging() void GLGizmoRotate3D::on_render(const Selection& selection) const { - ::glClear(GL_DEPTH_BUFFER_BIT); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); if ((m_hover_id == -1) || (m_hover_id == 0)) m_gizmos[X].render(selection); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index e9f7e2ae2d..a4f3969341 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -108,8 +108,8 @@ void GLGizmoScale3D::on_render(const Selection& selection) const ((m_hover_id == 6) || (m_hover_id == 7) || (m_hover_id == 8) || (m_hover_id == 9))) set_tooltip("X/Y/Z"); - ::glClear(GL_DEPTH_BUFFER_BIT); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_DEPTH_TEST)); BoundingBoxf3 box; Transform3d transform = Transform3d::Identity(); @@ -187,7 +187,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const m_grabbers[i].angles = angles; } - ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f); + glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); const BoundingBoxf3& selection_box = selection.get_bounding_box(); @@ -198,20 +198,20 @@ void GLGizmoScale3D::on_render(const Selection& selection) const // draw connections if (m_grabbers[0].enabled && m_grabbers[1].enabled) { - ::glColor3fv(m_grabbers[0].color); + glsafe(::glColor3fv(m_grabbers[0].color)); render_grabbers_connection(0, 1); } if (m_grabbers[2].enabled && m_grabbers[3].enabled) { - ::glColor3fv(m_grabbers[2].color); + glsafe(::glColor3fv(m_grabbers[2].color)); render_grabbers_connection(2, 3); } if (m_grabbers[4].enabled && m_grabbers[5].enabled) { - ::glColor3fv(m_grabbers[4].color); + glsafe(::glColor3fv(m_grabbers[4].color)); render_grabbers_connection(4, 5); } - ::glColor3fv(m_base_color); + glsafe(::glColor3fv(m_base_color)); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); @@ -222,7 +222,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const else if ((m_hover_id == 0) || (m_hover_id == 1)) { // draw connection - ::glColor3fv(m_grabbers[0].color); + glsafe(::glColor3fv(m_grabbers[0].color)); render_grabbers_connection(0, 1); // draw grabbers m_grabbers[0].render(true, grabber_mean_size); @@ -231,7 +231,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const else if ((m_hover_id == 2) || (m_hover_id == 3)) { // draw connection - ::glColor3fv(m_grabbers[2].color); + glsafe(::glColor3fv(m_grabbers[2].color)); render_grabbers_connection(2, 3); // draw grabbers m_grabbers[2].render(true, grabber_mean_size); @@ -240,7 +240,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const else if ((m_hover_id == 4) || (m_hover_id == 5)) { // draw connection - ::glColor3fv(m_grabbers[4].color); + glsafe(::glColor3fv(m_grabbers[4].color)); render_grabbers_connection(4, 5); // draw grabbers m_grabbers[4].render(true, grabber_mean_size); @@ -249,7 +249,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const else if (m_hover_id >= 6) { // draw connection - ::glColor3fv(m_drag_color); + glsafe(::glColor3fv(m_drag_color)); render_grabbers_connection(6, 7); render_grabbers_connection(7, 8); render_grabbers_connection(8, 9); @@ -264,7 +264,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const void GLGizmoScale3D::on_render_for_picking(const Selection& selection) const { - ::glDisable(GL_DEPTH_TEST); + glsafe(::glDisable(GL_DEPTH_TEST)); render_grabbers_for_picking(selection.get_bounding_box()); } @@ -291,7 +291,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int ::glBegin(GL_LINES); ::glVertex3dv(m_grabbers[id_1].center.data()); ::glVertex3dv(m_grabbers[id_2].center.data()); - ::glEnd(); + glsafe(::glEnd()); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 0f6713e0d7..ae3d3ee1e6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -75,13 +75,13 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S void GLGizmoSlaSupports::on_render(const Selection& selection) const { - ::glEnable(GL_BLEND); - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glEnable(GL_DEPTH_TEST)); render_points(selection, false); render_selection_rectangle(); - ::glDisable(GL_BLEND); + glsafe(::glDisable(GL_BLEND)); } void GLGizmoSlaSupports::render_selection_rectangle() const @@ -89,44 +89,44 @@ void GLGizmoSlaSupports::render_selection_rectangle() const if (!m_selection_rectangle_active) return; - ::glLineWidth(1.5f); + glsafe(::glLineWidth(1.5f)); float render_color[3] = {1.f, 0.f, 0.f}; - ::glColor3fv(render_color); + glsafe(::glColor3fv(render_color)); - ::glPushAttrib(GL_TRANSFORM_BIT); // remember current MatrixMode + glsafe(::glPushAttrib(GL_TRANSFORM_BIT)); // remember current MatrixMode - ::glMatrixMode(GL_MODELVIEW); // cache modelview matrix and set to identity - ::glPushMatrix(); - ::glLoadIdentity(); + glsafe(::glMatrixMode(GL_MODELVIEW)); // cache modelview matrix and set to identity + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); - ::glMatrixMode(GL_PROJECTION); // cache projection matrix and set to identity - ::glPushMatrix(); - ::glLoadIdentity(); + glsafe(::glMatrixMode(GL_PROJECTION)); // cache projection matrix and set to identity + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); - ::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f); // set projection matrix so that world coords = window coords + glsafe(::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f)); // set projection matrix so that world coords = window coords // render the selection rectangle (window coordinates): - ::glPushAttrib(GL_ENABLE_BIT); - ::glLineStipple(4, 0xAAAA); - ::glEnable(GL_LINE_STIPPLE); + glsafe(::glPushAttrib(GL_ENABLE_BIT)); + glsafe(::glLineStipple(4, 0xAAAA)); + glsafe(::glEnable(GL_LINE_STIPPLE)); ::glBegin(GL_LINE_LOOP); ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f); ::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); ::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f); - ::glEnd(); - ::glPopAttrib(); + glsafe(::glEnd()); + glsafe(::glPopAttrib()); - ::glPopMatrix(); // restore former projection matrix - ::glMatrixMode(GL_MODELVIEW); - ::glPopMatrix(); // restore former modelview matrix - ::glPopAttrib(); // restore former MatrixMode + glsafe(::glPopMatrix()); // restore former projection matrix + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glPopMatrix()); // restore former modelview matrix + glsafe(::glPopAttrib()); // restore former MatrixMode } void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const { - ::glEnable(GL_DEPTH_TEST); + glsafe(::glEnable(GL_DEPTH_TEST)); render_points(selection, true); } @@ -137,16 +137,16 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) return; if (!picking) - ::glEnable(GL_LIGHTING); + glsafe(::glEnable(GL_LIGHTING)); const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); double z_shift = vol->get_sla_shift_z(); const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix(); - ::glPushMatrix(); - ::glTranslated(0.0, 0.0, z_shift); - ::glMultMatrixd(instance_matrix.data()); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(0.0, 0.0, z_shift)); + glsafe(::glMultMatrixd(instance_matrix.data())); float render_color[3]; for (int i = 0; i < (int)m_editing_mode_cache.size(); ++i) @@ -178,14 +178,14 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f; } } - ::glColor3fv(render_color); + glsafe(::glColor3fv(render_color)); float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f}; - ::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive); + glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. - ::glPushMatrix(); - ::glTranslated(support_point.pos(0), support_point.pos(1), support_point.pos(2)); - ::glMultMatrixd(instance_scaling_matrix_inverse.data()); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(support_point.pos(0), support_point.pos(1), support_point.pos(2))); + glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); // Matrices set, we can render the point mark now. // If in editing mode, we'll also render a cone pointing to the sphere. @@ -196,31 +196,31 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_mode_cache[i].normal.cast()); Eigen::AngleAxisd aa(q); - ::glRotated(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)); + glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); const float cone_radius = 0.25f; // mm const float cone_height = 0.75f; - ::glPushMatrix(); - ::glTranslatef(0.f, 0.f, m_editing_mode_cache[i].support_point.head_front_radius * RenderPointScale); + glsafe(::glPushMatrix()); + glsafe(::glTranslatef(0.f, 0.f, m_editing_mode_cache[i].support_point.head_front_radius * RenderPointScale)); ::gluCylinder(m_quadric, 0.f, cone_radius, cone_height, 24, 1); - ::glTranslatef(0.f, 0.f, cone_height); + glsafe(::glTranslatef(0.f, 0.f, cone_height)); ::gluDisk(m_quadric, 0.0, cone_radius, 24, 1); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } ::gluSphere(m_quadric, m_editing_mode_cache[i].support_point.head_front_radius * RenderPointScale, 24, 12); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } { // Reset emissive component to zero (the default value) float render_color_emissive[4] = { 0.f, 0.f, 0.f, 1.f }; - ::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive); + glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive)); } if (!picking) - ::glDisable(GL_LIGHTING); + glsafe(::glDisable(GL_LIGHTING)); - ::glPopMatrix(); + glsafe(::glPopMatrix()); } bool GLGizmoSlaSupports::is_mesh_update_necessary() const @@ -264,11 +264,11 @@ std::pair GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse update_mesh(); Eigen::Matrix viewport; - ::glGetIntegerv(GL_VIEWPORT, viewport.data()); + glsafe(::glGetIntegerv(GL_VIEWPORT, viewport.data())); Eigen::Matrix modelview_matrix; - ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()); + glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data())); Eigen::Matrix projection_matrix; - ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data()); + glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data())); Vec3d point1; Vec3d point2; @@ -356,11 +356,11 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous 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]; - ::glGetIntegerv(GL_VIEWPORT, viewport); + glsafe(::glGetIntegerv(GL_VIEWPORT, viewport)); GLdouble modelview_matrix[16]; - ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix); + glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix)); GLdouble projection_matrix[16]; - ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix); + glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix)); const Selection& selection = m_parent.get_selection(); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 0932c8ce93..46379d6161 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -19,6 +19,7 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" +#include "3DScene.hpp" #include "GUI.hpp" namespace Slic3r { @@ -360,19 +361,19 @@ void ImGuiWrapper::create_fonts_texture() // Upload texture to graphics system GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &m_font_texture); - glBindTexture(GL_TEXTURE_2D, m_font_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); + glsafe(::glGenTextures(1, &m_font_texture)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_font_texture)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); // Store our identifier io.Fonts->TexID = (ImTextureID)(intptr_t)m_font_texture; // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); + glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture)); } void ImGuiWrapper::init_input() @@ -467,39 +468,39 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) // We are using the OpenGL fixed pipeline to make the example code simpler to read! // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GLint last_texture; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); + GLint last_polygon_mode[2]; glsafe(::glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode)); + GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport)); + GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)); + glsafe(::glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glDisable(GL_COLOR_MATERIAL)); + glsafe(::glEnable(GL_SCISSOR_TEST)); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY)); + glsafe(::glEnableClientState(GL_COLOR_ARRAY)); + glsafe(::glEnable(GL_TEXTURE_2D)); + glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); + glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)); GLint texture_env_mode = GL_MODULATE; - glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texture_env_mode); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texture_env_mode)); + glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound // Setup viewport, orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); + glsafe(::glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height)); + glsafe(::glMatrixMode(GL_PROJECTION)); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); + glsafe(::glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f)); + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glPushMatrix()); + glsafe(::glLoadIdentity()); // Render command lists ImVec2 pos = draw_data->DisplayPos; @@ -508,9 +509,9 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); + glsafe(::glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos)))); + glsafe(::glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv)))); + glsafe(::glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col)))); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -526,11 +527,11 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { // Apply scissor/clipping rectangle - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + glsafe(::glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y))); // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId)); + glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer)); } } idx_buffer += pcmd->ElemCount; @@ -538,19 +539,19 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) } // Restore modified state - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_env_mode); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); - glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); + glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_env_mode)); + glsafe(::glDisableClientState(GL_COLOR_ARRAY)); + glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY)); + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture)); + glsafe(::glMatrixMode(GL_MODELVIEW)); + glsafe(::glPopMatrix()); + glsafe(::glMatrixMode(GL_PROJECTION)); + glsafe(::glPopMatrix()); + glsafe(::glPopAttrib()); + glsafe(::glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1])); + glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3])); + glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3])); } bool ImGuiWrapper::display_initialized() const @@ -569,7 +570,7 @@ void ImGuiWrapper::destroy_fonts_texture() if (m_font_texture) { ImGuiIO& io = ImGui::GetIO(); io.Fonts->TexID = 0; - glDeleteTextures(1, &m_font_texture); + glsafe(::glDeleteTextures(1, &m_font_texture)); m_font_texture = 0; } } From d0046283fa09bbfb07c26ba9b8c8486ab6e57090 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 27 Mar 2019 15:14:40 +0100 Subject: [PATCH 12/61] Added #define glcheck() for the case HAS_GLSAFE not defined --- src/slic3r/GUI/3DScene.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index fa58ddb502..a1dee9e573 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -23,6 +23,7 @@ inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __ #else inline void glAssertRecentCall() { } #define glsafe(cmd) cmd +#define glcheck() #endif namespace Slic3r { From 9b3f1a89420902670071d13d37bd32c2ae432716 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 28 Mar 2019 09:30:01 +0100 Subject: [PATCH 13/61] Small refactoring -> GLGizmosManager gets model from selection and not from canvas --- src/slic3r/GUI/GLCanvas3D.hpp | 1 - src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 0f6333f733..489f3e237f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -465,7 +465,6 @@ public: void set_config(const DynamicPrintConfig* config); void set_process(BackgroundSlicingProcess* process); void set_model(Model* model); - Model* get_model() { return m_model; } const Selection& get_selection() const { return m_selection; } Selection& get_selection() { return m_selection; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 35bf2ef8a0..7f4d4d4959 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -278,7 +278,7 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); set_scale(volume->get_instance_scaling_factor()); set_rotation(Vec3d::Zero()); - ModelObject* model_object = canvas.get_model()->objects[selection.get_object_idx()]; + ModelObject* model_object = selection.get_model()->objects[selection.get_object_idx()]; set_flattening_data(model_object); set_sla_support_data(model_object, selection); } @@ -294,7 +294,7 @@ void GLGizmosManager::update_data(GLCanvas3D& canvas) { set_scale(Vec3d::Ones()); set_rotation(Vec3d::Zero()); - set_flattening_data(selection.is_from_single_object() ? canvas.get_model()->objects[selection.get_object_idx()] : nullptr); + set_flattening_data(selection.is_from_single_object() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr); set_sla_support_data(nullptr, selection); } } From ac6a232795c1b78f600423012bb0cf5ead6c2fe1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 29 Mar 2019 14:36:09 +0100 Subject: [PATCH 14/61] Improved Selection from ObjectList side --- src/slic3r/GUI/GUI_ObjectList.cpp | 102 ++++++++++++++++++---- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 +- src/slic3r/GUI/Selection.hpp | 2 + src/slic3r/GUI/wxExtensions.cpp | 26 ++++++ src/slic3r/GUI/wxExtensions.hpp | 2 +- 6 files changed, 117 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 224bb802eb..4c46e7135d 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1639,16 +1639,20 @@ void ObjectList::part_selection_changed() bool update_and_show_manipulations = false; bool update_and_show_settings = false; - if (multiple_selection()) { + const auto item = GetSelection(); + + if ( multiple_selection() || item && m_objects_model->GetItemType(item) == itInstanceRoot ) + { og_name = _(L("Group manipulation")); - update_and_show_manipulations = true; + + const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); + // don't show manipulation panel for case of all Object's parts selection + update_and_show_manipulations = !selection.is_single_full_instance(); } else { - const auto item = GetSelection(); if (item) { - bool is_part = false; if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { obj_idx = m_objects_model->GetIdByItem(item); og_name = _(L("Object manipulation")); @@ -1666,7 +1670,6 @@ void ObjectList::part_selection_changed() } else { og_name = _(L("Part Settings to modify")); - is_part = true; auto main_parent = m_objects_model->GetParent(parent); obj_idx = m_objects_model->GetIdByItem(main_parent); const auto volume_id = m_objects_model->GetVolumeIdByItem(parent); @@ -1676,7 +1679,6 @@ void ObjectList::part_selection_changed() } else if (m_objects_model->GetItemType(item) == itVolume) { og_name = _(L("Part manipulation")); - is_part = true; const auto volume_id = m_objects_model->GetVolumeIdByItem(item); m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; update_and_show_manipulations = true; @@ -1924,6 +1926,15 @@ bool ObjectList::multiple_selection() const return GetSelectedItemsCount() > 1; } +bool ObjectList::is_selected(const ItemType type) const +{ + const wxDataViewItem& item = GetSelection(); + if (item) + return m_objects_model->GetItemType(item) == type; + + return false; +} + void ObjectList::update_selections() { const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); @@ -1942,25 +1953,64 @@ void ObjectList::update_selections() return; } } - - if (selection.is_single_full_object()) +// if (selection.is_single_full_object() && selection.get_instance_idx() != -1) +// { +// sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); +// } +// else if (selection.is_single_volume() || selection.is_modifier() || +// selection.is_multiple_volume() || selection.is_multiple_full_object()) +// { +// for (auto idx : selection.get_volume_idxs()) { +// const auto gl_vol = selection.get_volume(idx); +// if (selection.is_multiple_full_object()) +// sels.Add(m_objects_model->GetItemById(gl_vol->object_idx())); +// else if (gl_vol->volume_idx() >= 0) +// // Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids +// // are not associated with ModelVolumes, but they are temporarily generated by the backend +// // (for example, SLA supports or SLA pad). +// sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx())); +// } +// } + else if (selection.is_single_full_object() || selection.is_multiple_full_object()) { - sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); + const Selection::ObjectIdxsToInstanceIdxsMap& objects_content = selection.get_content(); + for (const auto& object : objects_content) { + if (object.second.size() == 1) // object with 1 instance + sels.Add(m_objects_model->GetItemById(object.first)); + else if (object.second.size() > 1) // object with several instances + { + wxDataViewItemArray current_sels; + GetSelections(current_sels); + const wxDataViewItem frst_inst_item = m_objects_model->GetItemByInstanceId(object.first, 0); + + bool root_is_selected = false; + for (const auto& item:current_sels) + if (item == m_objects_model->GetParent(frst_inst_item)) { + root_is_selected = true; + break; + } + if (root_is_selected) + continue; + + const Selection::InstanceIdxsList& instances = object.second; + for (const auto& inst : instances) + sels.Add(m_objects_model->GetItemByInstanceId(object.first, inst)); + } + } } - else if (selection.is_single_volume() || selection.is_modifier() || - selection.is_multiple_volume() || selection.is_multiple_full_object()) { + else if (selection.is_single_volume() || selection.is_modifier() || selection.is_multiple_volume()) + { for (auto idx : selection.get_volume_idxs()) { const auto gl_vol = selection.get_volume(idx); - if (selection.is_multiple_full_object()) - sels.Add(m_objects_model->GetItemById(gl_vol->object_idx())); - else if (gl_vol->volume_idx() >= 0) + if (gl_vol->volume_idx() >= 0) // Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids // are not associated with ModelVolumes, but they are temporarily generated by the backend // (for example, SLA supports or SLA pad). sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx())); } } - else if (selection.is_single_full_instance() || selection.is_multiple_full_instance()) { + else if (selection.is_single_full_instance() || selection.is_multiple_full_instance()) + { for (auto idx : selection.get_instance_idxs()) { sels.Add(m_objects_model->GetItemByInstanceId(selection.get_object_idx(), idx)); } @@ -2136,11 +2186,25 @@ void ObjectList::fix_multiselection_conflicts() wxDataViewItemArray sels; GetSelections(sels); - for (auto item : sels) { - if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot)) + for (const auto item : sels) { + if (!IsSelected(item)) // if this item is unselected now (from previous actions) + continue; + + if (m_objects_model->GetItemType(item) & itSettings) { Unselect(item); - else if (m_objects_model->GetParent(item) != wxDataViewItem(0)) - Unselect(m_objects_model->GetParent(item)); + continue; + } + + const wxDataViewItem& parent = m_objects_model->GetParent(item); + if (parent != wxDataViewItem(0) && IsSelected(parent)) + Unselect(parent); + else + { + wxDataViewItemArray unsels; + m_objects_model->GetAllChildren(item, unsels); + for (const auto unsel_item : unsels) + Unselect(unsel_item); + } } m_prevent_list_events = false; diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 4ddc6ea71f..b0ed756f86 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -251,6 +251,7 @@ public: void init_objects(); bool multiple_selection() const ; + bool is_selected(const ItemType type) const; void update_selections(); void update_selections_on_canvas(); void select_item(const wxDataViewItem& item); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 6c8fdcab73..6375965915 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -161,6 +161,8 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_move_label_string = L("Position"); m_new_rotate_label_string = L("Rotation"); m_new_scale_label_string = L("Scale factors"); + + ObjectList* obj_list = wxGetApp().obj_list(); if (selection.is_single_full_instance()) { // all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one @@ -187,7 +189,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_enabled = true; } - else if (selection.is_single_full_object()) + else if (selection.is_single_full_object() && obj_list->is_selected(itObject)) { m_cache.instance.reset(); @@ -212,7 +214,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_size = volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size(); m_new_enabled = true; } - else if (wxGetApp().obj_list()->multiple_selection()) + else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) { reset_settings_value(); m_new_move_label_string = L("Translate"); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 200f239c1f..6390214cd3 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -133,10 +133,12 @@ private: const Transform3d& get_instance_full_matrix() const { return m_instance.full_matrix; } }; +public: typedef std::map VolumesCache; typedef std::set InstanceIdxsList; typedef std::map ObjectIdxsToInstanceIdxsMap; +private: struct Cache { // Cache of GLVolume derived transformation matrices, valid during mouse dragging. diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 55544f28e3..77d9a4a101 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1239,6 +1239,32 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, return count; } +void PrusaObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const +{ + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); + if (!node) { + for (auto object : m_objects) + array.Add(wxDataViewItem((void*)object)); + } + else if (node->GetChildCount() == 0) + return; + else { + const size_t count = node->GetChildren().GetCount(); + for (size_t pos = 0; pos < count; pos++) { + PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos); + array.Add(wxDataViewItem((void*)child)); + } + } + + wxDataViewItemArray new_array = array; + for (const auto item : new_array) + { + wxDataViewItemArray children; + GetAllChildren(item, children); + WX_APPEND_ARRAY(array, children); + } +} + ItemType PrusaObjectDataViewModel::GetItemType(const wxDataViewItem &item) const { if (!item.IsOk()) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 27da67deb7..72221962c3 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -511,7 +511,7 @@ public: virtual bool IsContainer(const wxDataViewItem &item) const override; virtual unsigned int GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const override; - + void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const; // Is the container just a header or an item with all columns // In our case it is an item with all columns virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } From 2ae5f386ae752da6804415919b672b7ba16961af Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 1 Apr 2019 10:28:04 +0200 Subject: [PATCH 15/61] Added missing include --- src/slic3r/GUI/Camera.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index ff2d3aa313..d19bc870ef 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -2,6 +2,7 @@ #define slic3r_Camera_hpp_ #include "libslic3r/BoundingBox.hpp" +#include namespace Slic3r { namespace GUI { From 81809018bc9087cb563fc74591eac4a7309a91f6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 2 Apr 2019 16:33:52 +0200 Subject: [PATCH 16/61] Selection improvements + "Delete" menu_item for Instances under OSX --- src/slic3r/GUI/GUI_ObjectList.cpp | 158 ++++++++++++++++++++++-------- src/slic3r/GUI/GUI_ObjectList.hpp | 10 ++ 2 files changed, 129 insertions(+), 39 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 4c46e7135d..b61b8280f2 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -82,13 +82,14 @@ ObjectList::ObjectList(wxWindow* parent) : init_icons(); // describe control behavior - Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) { + Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxDataViewEvent& event) { #ifndef __APPLE__ // On Windows and Linux, forces a kill focus emulation on the object manipulator fields because this event handler is called // before the kill focus event handler on the object manipulator when changing selection in the list, invalidating the object // manipulator cache with the following call to selection_changed() wxGetApp().obj_manipul()->emulate_kill_focus(); #endif // __APPLE__ + m_last_selected_item = event.GetItem(); selection_changed(); #ifndef __WXMSW__ set_tooltip_for_item(get_mouse_position_in_control()); @@ -1006,8 +1007,7 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) void ObjectList::append_menu_items_osx(wxMenu* menu) { - append_menu_item(menu, wxID_ANY, _(L("Delete item")), "", - [this](wxCommandEvent&) { remove(); }, "", menu); + append_menu_item_delete(menu); append_menu_item(menu, wxID_ANY, _(L("Rename")), "", [this](wxCommandEvent&) { rename_item(); }, "", menu); @@ -1062,6 +1062,12 @@ void ObjectList::append_menu_item_change_extruder(wxMenu* menu) const } } +void ObjectList::append_menu_item_delete(wxMenu* menu) +{ + append_menu_item(menu, wxID_ANY, _(L("Delete")), "", + [this](wxCommandEvent&) { remove(); }, "", menu); +} + void ObjectList::create_object_popupmenu(wxMenu *menu) { #ifdef __WXOSX__ @@ -1118,6 +1124,9 @@ void ObjectList::create_part_popupmenu(wxMenu *menu) void ObjectList::create_instance_popupmenu(wxMenu*menu) { +#ifdef __WXOSX__ + append_menu_item_delete(menu); +#endif // __WXOSX__ m_menu_item_split_instances = append_menu_item_instance_to_object(menu); wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { @@ -1552,7 +1561,7 @@ void ObjectList::split() auto opt_keys = model_object->volumes[id]->config.keys(); if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) { select_item(m_objects_model->AddSettingsChild(vol_item)); - Collapse(vol_item); + /*Collapse*/Expand(vol_item); } } @@ -1746,7 +1755,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) auto opt_keys = model_object->volumes[id]->config.keys(); if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { select_item(m_objects_model->AddSettingsChild(vol_item)); - Collapse(vol_item); + /*Collapse*/Expand(vol_item); } } Expand(item); @@ -1760,7 +1769,7 @@ void ObjectList::add_object_to_list(size_t obj_idx) auto opt_keys = model_object->config.keys(); if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) { select_item(m_objects_model->AddSettingsChild(item)); - Collapse(item); + /*Collapse*/Expand(item); } #ifndef __WXOSX__ @@ -1940,6 +1949,8 @@ void ObjectList::update_selections() const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); wxDataViewItemArray sels; + m_selection_mode = smInstance; + // We doesn't update selection if SettingsItem for the current object/part is selected if (GetSelectedItemsCount() == 1 && m_objects_model->GetItemType(GetSelection()) == itSettings ) { @@ -1953,24 +1964,6 @@ void ObjectList::update_selections() return; } } -// if (selection.is_single_full_object() && selection.get_instance_idx() != -1) -// { -// sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); -// } -// else if (selection.is_single_volume() || selection.is_modifier() || -// selection.is_multiple_volume() || selection.is_multiple_full_object()) -// { -// for (auto idx : selection.get_volume_idxs()) { -// const auto gl_vol = selection.get_volume(idx); -// if (selection.is_multiple_full_object()) -// sels.Add(m_objects_model->GetItemById(gl_vol->object_idx())); -// else if (gl_vol->volume_idx() >= 0) -// // Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids -// // are not associated with ModelVolumes, but they are temporarily generated by the backend -// // (for example, SLA supports or SLA pad). -// sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx())); -// } -// } else if (selection.is_single_full_object() || selection.is_multiple_full_object()) { const Selection::ObjectIdxsToInstanceIdxsMap& objects_content = selection.get_content(); @@ -1985,8 +1978,10 @@ void ObjectList::update_selections() bool root_is_selected = false; for (const auto& item:current_sels) - if (item == m_objects_model->GetParent(frst_inst_item)) { + if (item == m_objects_model->GetParent(frst_inst_item) || + item == m_objects_model->GetTopParent(frst_inst_item)) { root_is_selected = true; + sels.Add(item); break; } if (root_is_selected) @@ -2008,6 +2003,7 @@ void ObjectList::update_selections() // (for example, SLA supports or SLA pad). sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx())); } + m_selection_mode = smVolume; } else if (selection.is_single_full_instance() || selection.is_multiple_full_instance()) { @@ -2017,7 +2013,7 @@ void ObjectList::update_selections() } else if (selection.is_mixed()) { - auto& objects_content_list = selection.get_content(); + const Selection::ObjectIdxsToInstanceIdxsMap& objects_content_list = selection.get_content(); for (auto idx : selection.get_volume_idxs()) { const auto gl_vol = selection.get_volume(idx); @@ -2050,6 +2046,9 @@ void ObjectList::update_selections() sels.Add(m_objects_model->GetItemByVolumeId(glv_obj_idx, glv_vol_idx)); } } + + if (sels.size() == 0) + m_selection_mode = smUndef; select_items(sels); @@ -2085,29 +2084,34 @@ void ObjectList::update_selections_on_canvas() auto add_to_selection = [this](const wxDataViewItem& item, Selection& selection, int instance_idx, bool as_single_selection) { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - selection.add_object(m_objects_model->GetIdByItem(item), as_single_selection); + const ItemType& type = m_objects_model->GetItemType(item); + if ( type == itInstanceRoot || m_objects_model->GetParent(item) == wxDataViewItem(0) ) { + wxDataViewItem obj_item = type == itInstanceRoot ? m_objects_model->GetParent(item) : item; + selection.add_object(m_objects_model->GetIdByItem(obj_item), as_single_selection); return; } - if (m_objects_model->GetItemType(item) == itVolume) { + if (type == itVolume) { const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item)); const int vol_idx = m_objects_model->GetVolumeIdByItem(item); selection.add_volume(obj_idx, vol_idx, std::max(instance_idx, 0), as_single_selection); } - else if (m_objects_model->GetItemType(item) == itInstance) { + else if (type == itInstance) { const int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); const int inst_idx = m_objects_model->GetInstanceIdByItem(item); selection.add_instance(obj_idx, inst_idx, as_single_selection); } }; + // stores current instance idx before to clear the selection + int instance_idx = selection.get_instance_idx(); + if (sel_cnt == 1) { wxDataViewItem item = GetSelection(); if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot)) - add_to_selection(m_objects_model->GetParent(item), selection, -1, true); + add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, true); else - add_to_selection(item, selection, -1, true); + add_to_selection(item, selection, instance_idx, true); wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state(); return; @@ -2116,8 +2120,6 @@ void ObjectList::update_selections_on_canvas() wxDataViewItemArray sels; GetSelections(sels); - // stores current instance idx before to clear the selection - int instance_idx = selection.get_instance_idx(); selection.clear(); for (auto item: sels) add_to_selection(item, selection, instance_idx, false); @@ -2163,22 +2165,79 @@ void ObjectList::select_item_all_children() if (!GetSelection() || m_objects_model->GetItemType(GetSelection()) == itObject) { for (int i = 0; i < m_objects->size(); i++) sels.Add(m_objects_model->GetItemById(i)); + m_selection_mode = smInstance; } else { const auto item = GetSelection(); // Some volume(instance) is selected => select all volumes(instances) inside the current object - if (m_objects_model->GetItemType(item) & (itVolume | itInstance)) { + if (m_objects_model->GetItemType(item) & (itVolume | itInstance)) m_objects_model->GetChildren(m_objects_model->GetParent(item), sels); - } + + m_selection_mode = m_objects_model->GetItemType(item)&itVolume ? smVolume : smInstance; } SetSelections(sels); selection_changed(); } +// update selection mode for non-multiple selection +void ObjectList::update_selection_mode() +{ + m_last_selected_item = wxDataViewItem(0); + + // All items are unselected + if (!GetSelection()) + { + m_selection_mode = smUndef; + return; + } + + const ItemType type = m_objects_model->GetItemType(GetSelection()); + m_selection_mode = type&itSettings ? smUndef : + type&itVolume ? smVolume : smInstance; +} + +// check last selected item. If is it possible to select it +bool ObjectList::check_last_selection() +{ + if (!m_last_selected_item) + return true; + + /* We can't mix Parts and Objects/Instances. + * So, unselect last selected item and show information about it + */ + const ItemType type = m_objects_model->GetItemType(m_last_selected_item); + if (type & itSettings || + type & itVolume && m_selection_mode == smInstance || + !(type & itVolume) && m_selection_mode == smVolume) + { + Unselect(m_last_selected_item); + + // Inform user why selection isn't complited + const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part")); + + const wxString msg_str = wxString::Format(_(L("You started your selection with %s Item.")) + "\n" + + _(L("In this mode you can select only another %s Items%s")), item_type, item_type, + m_selection_mode == smInstance ? "." : " " + _(L("of a current Object"))); + + wxMessageDialog dialog(this, _(L("Unsupported selection")) + "\n\n" + msg_str, + _(L("Info")), wxICON_INFORMATION); + dialog.ShowModal(); + + return false; + } + + return true; +} + void ObjectList::fix_multiselection_conflicts() { - if (GetSelectedItemsCount() <= 1) + if (GetSelectedItemsCount() <= 1) { + update_selection_mode(); + return; + } + + if (!check_last_selection()) return; m_prevent_list_events = true; @@ -2186,6 +2245,8 @@ void ObjectList::fix_multiselection_conflicts() wxDataViewItemArray sels; GetSelections(sels); + m_selection_mode = smInstance; + for (const auto item : sels) { if (!IsSelected(item)) // if this item is unselected now (from previous actions) continue; @@ -2205,6 +2266,26 @@ void ObjectList::fix_multiselection_conflicts() for (const auto unsel_item : unsels) Unselect(unsel_item); } + + if (m_objects_model->GetItemType(item) == itVolume) + { + // If some part is selected, unselect all items except of selected parts of the current object + sels.clear(); + + wxDataViewItemArray children; // selected volumes from current parent + m_objects_model->GetChildren(parent, children); + for (const auto child : children) + { + if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume) + sels.Add(child); + } + + UnselectAll(); + SetSelections(sels); + + m_selection_mode = smVolume; + break; + } } m_prevent_list_events = false; @@ -2489,8 +2570,7 @@ void ObjectList::show_multi_selection_menu() wxMenu* menu = new wxMenu(); #ifdef __WXOSX__ - append_menu_item(menu, wxID_ANY, _(L("Delete items")), "", - [this](wxCommandEvent&) { remove(); }, "", menu); + append_menu_item_delete(); #endif //__WXOSX__ if (extruders_count() > 1) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index b0ed756f86..0611cc4f19 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -60,6 +60,12 @@ struct ItemForDelete class ObjectList : public wxDataViewCtrl { + enum SELECTION_MODE + { + smUndef, + smVolume, + smInstance + } m_selection_mode {smUndef}; struct dragged_item_data { @@ -135,6 +141,7 @@ class ObjectList : public wxDataViewCtrl bool m_part_settings_changed = false; int m_selected_row = 0; + wxDataViewItem m_last_selected_item {nullptr}; #if 0 FreqSettingsBundle m_freq_settings_fff; @@ -188,6 +195,7 @@ public: void append_menu_item_fix_through_netfabb(wxMenu* menu); void append_menu_item_export_stl(wxMenu* menu) const ; void append_menu_item_change_extruder(wxMenu* menu) const; + void append_menu_item_delete(wxMenu* menu); void create_object_popupmenu(wxMenu *menu); void create_sla_object_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu); @@ -258,6 +266,8 @@ public: void select_items(const wxDataViewItemArray& sels); void select_all(); void select_item_all_children(); + void update_selection_mode(); + bool check_last_selection(); // correct current selections to avoid of the possible conflicts void fix_multiselection_conflicts(); From fed0f189d3de2cf4439b7aea429b4422f076450c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 3 Apr 2019 08:39:36 +0200 Subject: [PATCH 17/61] Fixed typo --- src/slic3r/GUI/GUI_ObjectList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b61b8280f2..203e765731 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2570,7 +2570,7 @@ void ObjectList::show_multi_selection_menu() wxMenu* menu = new wxMenu(); #ifdef __WXOSX__ - append_menu_item_delete(); + append_menu_item_delete(menu); #endif //__WXOSX__ if (extruders_count() > 1) From a7318dbe197d0a05d368865fe169751f07840cd7 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Apr 2019 09:01:47 +0200 Subject: [PATCH 18/61] Keeps non selected instances as disabled for any combination of current instance's volumes selection --- src/slic3r/GUI/Selection.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index ca245029c1..db25e6332f 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1147,16 +1147,12 @@ void Selection::_update_type() } if (modifiers_count == 0) - { m_type = MultipleVolume; - requires_disable = true; - } else if (modifiers_count == (unsigned int)m_list.size()) - { m_type = MultipleModifier; - requires_disable = true; - } } + + requires_disable = true; } else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size())) { From 8e63a6ba97167965764dcbaa85ea65a219170470 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Apr 2019 09:02:53 +0200 Subject: [PATCH 19/61] First batch of SVG icons. Support for loading SVG icons into a BitmapCache. --- resources/icons/cog.svg | 17 ++++++++++++++ resources/icons/cooling.svg | 25 ++++++++++++++++++++ resources/icons/funnel.svg | 15 ++++++++++++ resources/icons/infill.svg | 33 +++++++++++++++++++++++++++ resources/icons/note.svg | 25 ++++++++++++++++++++ resources/icons/output+page_white.svg | 21 +++++++++++++++++ resources/icons/printer.svg | 14 ++++++++++++ resources/icons/skirt+brim.svg | 19 +++++++++++++++ resources/icons/spool.svg | 21 +++++++++++++++++ resources/icons/support.svg | 25 ++++++++++++++++++++ resources/icons/time.svg | 16 +++++++++++++ resources/icons/wrench.svg | 24 +++++++++++++++++++ 12 files changed, 255 insertions(+) create mode 100644 resources/icons/cog.svg create mode 100644 resources/icons/cooling.svg create mode 100644 resources/icons/funnel.svg create mode 100644 resources/icons/infill.svg create mode 100644 resources/icons/note.svg create mode 100644 resources/icons/output+page_white.svg create mode 100644 resources/icons/printer.svg create mode 100644 resources/icons/skirt+brim.svg create mode 100644 resources/icons/spool.svg create mode 100644 resources/icons/support.svg create mode 100644 resources/icons/time.svg create mode 100644 resources/icons/wrench.svg diff --git a/resources/icons/cog.svg b/resources/icons/cog.svg new file mode 100644 index 0000000000..07adb66101 --- /dev/null +++ b/resources/icons/cog.svg @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/resources/icons/cooling.svg b/resources/icons/cooling.svg new file mode 100644 index 0000000000..b5d80e434a --- /dev/null +++ b/resources/icons/cooling.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/funnel.svg b/resources/icons/funnel.svg new file mode 100644 index 0000000000..8877722e33 --- /dev/null +++ b/resources/icons/funnel.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/resources/icons/infill.svg b/resources/icons/infill.svg new file mode 100644 index 0000000000..fcb1f99c9e --- /dev/null +++ b/resources/icons/infill.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/note.svg b/resources/icons/note.svg new file mode 100644 index 0000000000..c142142010 --- /dev/null +++ b/resources/icons/note.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/output+page_white.svg b/resources/icons/output+page_white.svg new file mode 100644 index 0000000000..ec1518f252 --- /dev/null +++ b/resources/icons/output+page_white.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/resources/icons/printer.svg b/resources/icons/printer.svg new file mode 100644 index 0000000000..91e103ec70 --- /dev/null +++ b/resources/icons/printer.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/resources/icons/skirt+brim.svg b/resources/icons/skirt+brim.svg new file mode 100644 index 0000000000..9242761b61 --- /dev/null +++ b/resources/icons/skirt+brim.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/resources/icons/spool.svg b/resources/icons/spool.svg new file mode 100644 index 0000000000..8403659381 --- /dev/null +++ b/resources/icons/spool.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/support.svg b/resources/icons/support.svg new file mode 100644 index 0000000000..65c7592c83 --- /dev/null +++ b/resources/icons/support.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/time.svg b/resources/icons/time.svg new file mode 100644 index 0000000000..5d8f23cfc3 --- /dev/null +++ b/resources/icons/time.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/resources/icons/wrench.svg b/resources/icons/wrench.svg new file mode 100644 index 0000000000..7966da8d8f --- /dev/null +++ b/resources/icons/wrench.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + From c29f7bc1470e6a249621c65fc15cea1eb29eceef Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 2 Apr 2019 09:03:45 +0200 Subject: [PATCH 20/61] Fix of #2044 Added sorting by z of the preview data used to generate the gcode preview because there can be shuffling in case of sequential printing --- src/libslic3r/GCode/Analyzer.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index d1ad4f5752..321d9a3427 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -776,6 +776,9 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ preview_data.ranges.width.update_from(width_range); preview_data.ranges.feedrate.update_from(feedrate_range); preview_data.ranges.volumetric_rate.update_from(volumetric_rate_range); + + // we need to sort the layers by their z as they can be shuffled in case of sequential prints + std::sort(preview_data.extrusion.layers.begin(), preview_data.extrusion.layers.end(), [](const GCodePreviewData::Extrusion::Layer& l1, const GCodePreviewData::Extrusion::Layer& l2)->bool { return l1.z < l2.z; }); } void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data, std::function cancel_callback) @@ -855,6 +858,11 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data, s preview_data.ranges.height.update_from(height_range); preview_data.ranges.width.update_from(width_range); preview_data.ranges.feedrate.update_from(feedrate_range); + + // we need to sort the polylines by their min z as they can be shuffled in case of sequential prints + std::sort(preview_data.travel.polylines.begin(), preview_data.travel.polylines.end(), + [](const GCodePreviewData::Travel::Polyline& p1, const GCodePreviewData::Travel::Polyline& p2)->bool + { return unscale(p1.polyline.bounding_box().min(2)) < unscale(p2.polyline.bounding_box().min(2)); }); } void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_data, std::function cancel_callback) @@ -877,6 +885,11 @@ void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_da Vec3crd position(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z())); preview_data.retraction.positions.emplace_back(position, move.data.width, move.data.height); } + + // we need to sort the positions by their z as they can be shuffled in case of sequential prints + std::sort(preview_data.retraction.positions.begin(), preview_data.retraction.positions.end(), + [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2)->bool + { return unscale(p1.position(2)) < unscale(p2.position(2)); }); } void GCodeAnalyzer::_calc_gcode_preview_unretractions(GCodePreviewData& preview_data, std::function cancel_callback) @@ -899,6 +912,11 @@ void GCodeAnalyzer::_calc_gcode_preview_unretractions(GCodePreviewData& preview_ Vec3crd position(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z())); preview_data.unretraction.positions.emplace_back(position, move.data.width, move.data.height); } + + // we need to sort the positions by their z as they can be shuffled in case of sequential prints + std::sort(preview_data.unretraction.positions.begin(), preview_data.unretraction.positions.end(), + [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2)->bool + { return unscale(p1.position(2)) < unscale(p2.position(2)); }); } // Return an estimate of the memory consumed by the time estimator. From a36bdefda51833f7c3ac63d2ce1870fcea671d34 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Apr 2019 09:20:11 +0200 Subject: [PATCH 21/61] Code to load SVG icons into the BitmapCache class. --- resources/icons/layers.svg | 40 +++++++++--------- src/slic3r/GUI/BitmapCache.cpp | 73 +++++++++++++++++++++++++++++++++ src/slic3r/GUI/BitmapCache.hpp | 6 +++ src/slic3r/GUI/GLTexture.cpp | 5 +-- src/slic3r/GUI/Tab.cpp | 2 +- src/slic3r/GUI/wxExtensions.cpp | 23 +++++------ 6 files changed, 113 insertions(+), 36 deletions(-) diff --git a/resources/icons/layers.svg b/resources/icons/layers.svg index 7718a8cbd5..da5dec21d5 100644 --- a/resources/icons/layers.svg +++ b/resources/icons/layers.svg @@ -1,25 +1,27 @@ - + - + viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 16baa1629e..4c7f999ffc 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -1,5 +1,7 @@ #include "BitmapCache.hpp" +#include "libslic3r/Utils.hpp" + #if ! defined(WIN32) && ! defined(__APPLE__) #define BROKEN_ALPHA #endif @@ -9,6 +11,11 @@ #include #endif /* BROKEN_ALPHA */ +#define NANOSVG_IMPLEMENTATION +#include "nanosvg/nanosvg.h" +#define NANOSVGRAST_IMPLEMENTATION +#include "nanosvg/nanosvgrast.h" + namespace Slic3r { namespace GUI { void BitmapCache::clear() @@ -155,6 +162,72 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg #endif } +wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned int width, unsigned int height, const unsigned char *raw_data) +{ + wxImage image(width, height); + image.InitAlpha(); + unsigned char *rgb = image.GetData(); + unsigned char *alpha = image.GetAlpha(); + unsigned int pixels = width * height; + for (unsigned int i = 0; i < pixels; ++ i) { + *rgb ++ = *raw_data ++; + *rgb ++ = *raw_data ++; + *rgb ++ = *raw_data ++; + *alpha ++ = *raw_data ++; + } + return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image))); +} + +wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int height) +{ + std::string bitmap_key = bitmap_name + "-h" + std::to_string(height); + auto it = m_map.find(bitmap_key); + if (it != m_map.end()) + return it->second; + + wxImage image; + if (! image.LoadFile(Slic3r::GUI::from_u8(Slic3r::var(bitmap_name + ".png")), wxBITMAP_TYPE_PNG) || + image.GetWidth() == 0 || image.GetHeight() == 0) + return nullptr; + if (image.GetHeight() != height) + image.Rescale(int(0.5f + float(image.GetWidth()) * height / image.GetHeight()), height, wxIMAGE_QUALITY_BILINEAR); + return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image))); +} + +wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int target_height) +{ + std::string bitmap_key = bitmap_name + "-h" + std::to_string(target_height); + auto it = m_map.find(bitmap_key); + if (it != m_map.end()) + return it->second; + + NSVGimage *image = ::nsvgParseFromFile(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f); + if (image == nullptr) + return nullptr; + + float scale = (float)target_height / image->height; + int width = (int)(scale * image->width + 0.5f); + int height = (int)(scale * image->height + 0.5f); + int n_pixels = width * height; + if (n_pixels <= 0) { + ::nsvgDelete(image); + return nullptr; + } + + NSVGrasterizer *rast = ::nsvgCreateRasterizer(); + if (rast == nullptr) { + ::nsvgDelete(image); + return nullptr; + } + + std::vector data(n_pixels * 4, 0); + ::nsvgRasterize(rast, image, 0, 0, scale, data.data(), width, height, width * 4); + ::nsvgDeleteRasterizer(rast); + ::nsvgDelete(image); + + return this->insert_raw_rgba(bitmap_key, width, height, data.data()); +} + wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency) { wxImage image(width, height); diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index 0cb70d28b9..ce5eb3c77a 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -29,6 +29,12 @@ public: wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3); wxBitmap* insert(const std::string &name, const std::vector &bmps) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); } wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end); + wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned int width, unsigned int height, const unsigned char *raw_data); + + // Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height if nonzero. + wxBitmap* load_png(const std::string &bitmap_key, unsigned int height = 0); + // Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height. + wxBitmap* load_svg(const std::string &bitmap_key, unsigned int height); static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency); static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); } diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index b48ca20448..68369d9d03 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -11,15 +11,11 @@ #include #include -#define NANOSVG_IMPLEMENTATION #include "nanosvg/nanosvg.h" -#define NANOSVGRAST_IMPLEMENTATION #include "nanosvg/nanosvgrast.h" #include "libslic3r/Utils.hpp" -#include "libslic3r/Utils.hpp" - namespace Slic3r { namespace GUI { @@ -378,6 +374,7 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, uns if (n_pixels <= 0) { reset(); + nsvgDelete(image); return false; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 631050f297..a91dae0265 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1446,7 +1446,7 @@ void TabFilament::build() line.append_option(optgroup->get_option("bed_temperature")); optgroup->append_line(line); - page = add_options_page(_(L("Cooling")), "hourglass.png"); + page = add_options_page(_(L("Cooling")), "cooling"); optgroup = page->new_optgroup(_(L("Enable"))); optgroup->append_single_option_line("fan_always_on"); optgroup->append_single_option_line("cooling"); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 55544f28e3..09096cb059 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include "BitmapCache.hpp" #include "GUI.hpp" #include "GUI_App.hpp" @@ -421,19 +423,16 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) // PrusaObjectDataViewModelNode // ---------------------------------------------------------------------------- -wxBitmap create_scaled_bitmap(const std::string& bmp_name) +wxBitmap create_scaled_bitmap(const std::string& bmp_name_in) { - const double scale_f = Slic3r::GUI::wxGetApp().em_unit()* 0.1;//GetContentScaleFactor(); - if (scale_f == 1.0) - return wxBitmap(Slic3r::GUI::from_u8(Slic3r::var(bmp_name)), wxBITMAP_TYPE_PNG); -// else if (scale_f == 2.0) // use biger icon -// return wxBitmap(Slic3r::GUI::from_u8(Slic3r::var(bmp_name_X2)), wxBITMAP_TYPE_PNG); - - wxImage img = wxImage(Slic3r::GUI::from_u8(Slic3r::var(bmp_name)), wxBITMAP_TYPE_PNG); - const int sz_w = int(img.GetWidth()*scale_f); - const int sz_h = int(img.GetHeight()*scale_f); - img.Rescale(sz_w, sz_h, wxIMAGE_QUALITY_BILINEAR); - return wxBitmap(img); + static Slic3r::GUI::BitmapCache cache; + const auto height = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * 1.6f + 0.5f); + std::string bmp_name = bmp_name_in; + boost::replace_last(bmp_name, ".png", ""); + wxBitmap *bmp = cache.load_svg(bmp_name, height); + if (bmp == nullptr) + bmp = cache.load_png(bmp_name, height); + return *bmp; } void PrusaObjectDataViewModelNode::set_object_action_icon() { From 936f7a3b844813efe6dec8e75117c1e9cf5ab258 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Apr 2019 09:35:13 +0200 Subject: [PATCH 22/61] Select newly added parts/volumes from current selected instance when adding from 3D scene's context menu --- src/slic3r/GUI/GUI_ObjectList.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c0dcc659d9..c725fae432 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2051,12 +2051,15 @@ void ObjectList::update_selections_on_canvas() } }; + // stores current instance idx before to clear the selection + int instance_idx = selection.get_instance_idx(); + if (sel_cnt == 1) { wxDataViewItem item = GetSelection(); if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot)) add_to_selection(m_objects_model->GetParent(item), selection, -1, true); else - add_to_selection(item, selection, -1, true); + add_to_selection(item, selection, instance_idx, true); wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state(); return; @@ -2065,8 +2068,6 @@ void ObjectList::update_selections_on_canvas() wxDataViewItemArray sels; GetSelections(sels); - // stores current instance idx before to clear the selection - int instance_idx = selection.get_instance_idx(); selection.clear(); for (auto item: sels) add_to_selection(item, selection, instance_idx, false); From 30f44880d7f3b76e503a0c329f87ee84eff6c139 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Apr 2019 11:31:26 +0200 Subject: [PATCH 23/61] Removed 'Export print config' checkbox from save dialog for 3mf and amf files --- src/slic3r/GUI/Plater.cpp | 70 +++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 435d9548f8..bc9b7d5b5f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1199,7 +1199,7 @@ struct Plater::priv BoundingBox scaled_bed_shape_bb() const; std::vector load_files(const std::vector& input_files, bool load_model, bool load_config); std::vector load_model_objects(const ModelObjectPtrs &model_objects); - std::unique_ptr get_export_file(GUI::FileType file_type); + wxString get_export_file(GUI::FileType file_type); const Selection& get_selection() const; Selection& get_selection(); @@ -1784,7 +1784,7 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs &mode return obj_idxs; } -std::unique_ptr Plater::priv::get_export_file(GUI::FileType file_type) +wxString Plater::priv::get_export_file(GUI::FileType file_type) { wxString wildcard; switch (file_type) { @@ -1804,31 +1804,43 @@ std::unique_ptr Plater::priv::get_export_file(GUI::FileType // Find the file name of the first printable object. fs::path output_file = this->model.propose_export_file_name_and_path(); + wxString dlg_title; switch (file_type) { - case FT_STL: output_file.replace_extension("stl"); break; - case FT_AMF: output_file.replace_extension("zip.amf"); break; // XXX: Problem on OS X with double extension? - case FT_3MF: output_file.replace_extension("3mf"); break; + case FT_STL: + { + output_file.replace_extension("stl"); + dlg_title = _(L("Export STL file:")); + break; + } + case FT_AMF: + { + // XXX: Problem on OS X with double extension? + output_file.replace_extension("zip.amf"); + dlg_title = _(L("Export AMF file:")); + break; + } + case FT_3MF: + { + output_file.replace_extension("3mf"); + dlg_title = _(L("Save file as:")); + break; + } default: break; } - auto dlg = Slic3r::make_unique(q, - ((file_type == FT_AMF) || (file_type == FT_3MF)) ? _(L("Export print config")) : "", - true, - _(L("Save file as:")), - from_path(output_file.parent_path()), - from_path(output_file.filename()), - wildcard, - wxFD_SAVE | wxFD_OVERWRITE_PROMPT - ); + wxFileDialog* dlg = new wxFileDialog(q, dlg_title, + from_path(output_file.parent_path()), from_path(output_file.filename()), + wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (dlg->ShowModal() != wxID_OK) { - return nullptr; + return wxEmptyString; } - fs::path path(into_path(dlg->GetPath())); + wxString out_path = dlg->GetPath(); + fs::path path(into_path(out_path)); wxGetApp().app_config->update_last_output_dir(path.parent_path().string()); - return dlg; + return out_path; } const Selection& Plater::priv::get_selection() const @@ -3243,11 +3255,8 @@ void Plater::export_stl(bool selection_only) { if (p->model.objects.empty()) { return; } - auto dialog = p->get_export_file(FT_STL); - if (! dialog) { return; } - - // Store a binary STL - const wxString path = dialog->GetPath(); + wxString path = p->get_export_file(FT_STL); + if (path.empty()) { return; } const std::string path_u8 = into_u8(path); wxBusyCursor wait; @@ -3272,15 +3281,14 @@ void Plater::export_amf() { if (p->model.objects.empty()) { return; } - auto dialog = p->get_export_file(FT_AMF); - if (! dialog) { return; } - - const wxString path = dialog->GetPath(); + wxString path = p->get_export_file(FT_AMF); + if (path.empty()) { return; } const std::string path_u8 = into_u8(path); - DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); wxBusyCursor wait; - if (Slic3r::store_amf(path_u8.c_str(), &p->model, dialog->get_checkbox_value() ? &cfg : nullptr)) { + bool export_config = true; + DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); + if (Slic3r::store_amf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { // Success p->statusbar()->set_status_text(wxString::Format(_(L("AMF file exported to %s")), path)); } else { @@ -3297,10 +3305,8 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) bool export_config = true; if (output_path.empty()) { - auto dialog = p->get_export_file(FT_3MF); - if (!dialog) { return; } - path = dialog->GetPath(); - export_config = dialog->get_checkbox_value(); + path = p->get_export_file(FT_3MF); + if (path.empty()) { return; } } else path = from_path(output_path); From 369cdd8b3ba61f975e59682b4615d2b93855dc48 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Apr 2019 12:02:13 +0200 Subject: [PATCH 24/61] Ask user to switch to expert mode when loading a 3mf or an amf file containing instances or modifiers from simple mode --- src/slic3r/GUI/Plater.cpp | 41 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bc9b7d5b5f..9cf9768a5e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1617,6 +1617,45 @@ std::vector Plater::priv::load_files(const std::vector& input_ } #if ENABLE_VOLUMES_CENTERING_FIXES } + else if ((wxGetApp().get_mode() == comSimple) && (type_3mf || type_any_amf)) + { + bool advanced = false; + for (const ModelObject* model_object : model.objects) + { + // is there more than one instance ? + if (model_object->instances.size() > 1) + { + advanced = true; + break; + } + + // is there any modifier ? + for (const ModelVolume* model_volume : model_object->volumes) + { + if (!model_volume->is_model_part()) + { + advanced = true; + break; + } + } + + if (advanced) + break; + } + + if (advanced) + { + wxMessageDialog dlg(q, _(L("This file cannot be loaded in simple mode. Do you want to switch to expert mode?\n")), + _(L("Detected advanced data")), wxICON_WARNING | wxYES | wxNO); + if (dlg.ShowModal() == wxID_YES) + { + Slic3r::GUI::wxGetApp().save_mode(comExpert); + view3D->set_as_dirty(); + } + else + return obj_idxs; + } + } #endif // ENABLE_VOLUMES_CENTERING_FIXES #if !ENABLE_VOLUMES_CENTERING_FIXES @@ -1642,7 +1681,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ Slic3r::GUI::show_error(nullptr, wxString::Format(_(L("You can't to add the object(s) from %s because of one or some of them is(are) multi-part")), from_path(filename))); - return std::vector(); + return obj_idxs; } } From 590ae25b13d2ff27843a82f821ec6b2d9e2e12f6 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 4 Apr 2019 12:30:11 +0200 Subject: [PATCH 25/61] Altering sla export interface to support explicit project name. --- src/libslic3r/Print.cpp | 2 +- src/libslic3r/PrintExport.hpp | 19 ++++++++++--------- src/libslic3r/SLAPrint.hpp | 20 ++++++++------------ src/libslic3r/Zipper.cpp | 5 ----- src/libslic3r/Zipper.hpp | 3 --- 5 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 7943901339..c13f0bc2a3 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -10,7 +10,7 @@ #include "GCode/WipeTowerPrusaMM.hpp" #include "Utils.hpp" -#include "PrintExport.hpp" +//#include "PrintExport.hpp" #include #include diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index 04b993a529..ce62f7cb0f 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -7,6 +7,7 @@ #include #include +#include #include "Rasterizer/Rasterizer.hpp" //#include @@ -72,7 +73,8 @@ public: void finish_layer(); // Save all the layers into the file (or dir) specified in the path argument - void save(const std::string& path); + // An optional project name can be added to be used for the layer file names + void save(const std::string& path, const std::string& projectname = ""); // Save only the selected layer to the file specified in path argument. void save_layer(unsigned lyr, const std::string& path); @@ -86,7 +88,8 @@ template struct VeryFalse { static const bool value = false; }; template class LayerWriter { public: - LayerWriter(const std::string& /*zipfile_path*/) { + LayerWriter(const std::string& /*zipfile_path*/) + { static_assert(VeryFalse::value, "No layer writer implementation provided!"); } @@ -99,10 +102,6 @@ public: void binary_entry(const std::string& /*fname*/, const std::uint8_t* buf, size_t len); - // Get the name of the archive but only the name part without the path or - // the extension. - std::string get_name() { return ""; } - // Test whether the object can still be used for writing. bool is_ok() { return false; } @@ -253,12 +252,14 @@ public: } template - inline void save(const std::string& path) { + inline void save(const std::string& fpath, const std::string& prjname = "") + { try { - LayerWriter writer(path); + LayerWriter writer(fpath); if(!writer.is_ok()) return; - std::string project = writer.get_name(); + std::string project = prjname.empty()? + boost::filesystem::path(fpath).stem().string() : prjname; writer.next_entry("config.ini"); if(!writer.is_ok()) return; diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index a1e382acbc..d4443d9155 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -320,10 +320,8 @@ struct SLAPrintStatistics } }; -struct SLAminzZipper {}; - // The implementation of creating zipped archives with wxWidgets -template<> class LayerWriter { +template<> class LayerWriter { Zipper m_zip; public: @@ -332,16 +330,12 @@ public: void next_entry(const std::string& fname) { m_zip.add_entry(fname); } void binary_entry(const std::string& fname, - const std::uint8_t* buf, - size_t l) + const std::uint8_t* buf, + size_t l) { m_zip.add_entry(fname, buf, l); } - std::string get_name() const { - return m_zip.get_name(); - } - template inline LayerWriter& operator<<(T&& arg) { m_zip << std::forward(arg); return *this; } @@ -389,9 +383,11 @@ public: // Returns true if the last step was finished with success. bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); } - template - void export_raster(const std::string& fname) { - if(m_printer) m_printer->save(fname); + template + inline void export_raster(const std::string& fpath, + const std::string& projectname = "") + { + if(m_printer) m_printer->save(fpath, projectname); } const PrintObjects& objects() const { return m_objects; } diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp index 6b7faaddcb..4466f1b045 100644 --- a/src/libslic3r/Zipper.cpp +++ b/src/libslic3r/Zipper.cpp @@ -4,7 +4,6 @@ #include "Zipper.hpp" #include "miniz/miniz_zip.h" -#include #include #include "I18N.hpp" @@ -213,10 +212,6 @@ void Zipper::finish_entry() m_entry.clear(); } -std::string Zipper::get_name() const { - return boost::filesystem::path(m_impl->m_zipname).stem().string(); -} - void Zipper::finalize() { finish_entry(); diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp index 6566dad426..7d95ffdac7 100644 --- a/src/libslic3r/Zipper.hpp +++ b/src/libslic3r/Zipper.hpp @@ -81,9 +81,6 @@ public: /// file is up to minz after the erroneous write. void finish_entry(); - /// Gets the name of the archive without the path or extension. - std::string get_name() const; - void finalize(); }; From 251747e6faffa2426acb6bb43ba071e288abc49c Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 4 Apr 2019 10:28:41 +0200 Subject: [PATCH 26/61] GLGizmoCut: Scale input field --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 02d663e93b..5eb0d05839 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -15,12 +15,6 @@ namespace Slic3r { namespace GUI { - - - - -// GLGizmoCut - class GLGizmoCutPanel : public wxPanel { public: @@ -192,7 +186,7 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, co m_imgui->set_next_window_bg_alpha(0.5f); m_imgui->begin(_(L("Cut")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - ImGui::PushItemWidth(100.0f); + ImGui::PushItemWidth(m_imgui->scaled(5.0f)); bool _value_changed = ImGui::InputDouble("Z", &m_cut_z, 0.0f, 0.0f, "%.2f"); m_imgui->checkbox(_(L("Keep upper part")), m_keep_upper); From 70ce79c86e6131862b59e3fc2124d6c6166f9cea Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 4 Apr 2019 12:31:09 +0200 Subject: [PATCH 27/61] SLA export: Finalize filename when exporting & uploading, set correct project name when uploading --- src/slic3r.cpp | 5 +++-- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/slic3r.cpp b/src/slic3r.cpp index 958b663059..780efea7b3 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -397,8 +397,9 @@ int CLI::run(int argc, char **argv) outfile_final = fff_print.print_statistics().finalize_output_path(outfile); } else { outfile = sla_print.output_filepath(outfile); - sla_print.export_raster(outfile); - outfile_final = sla_print.print_statistics().finalize_output_path(outfile); + // We need to finalize the filename beforehand because the export function sets the filename inside the zip metadata + outfile_final = sla_print.print_statistics().finalize_output_path(outfile); + sla_print.export_raster(outfile_final); } if (outfile != outfile_final && Slic3r::rename_file(outfile, outfile_final) != 0) { boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 2601842ef4..c6a73864d6 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -98,8 +98,9 @@ void BackgroundSlicingProcess::process_sla() m_print->process(); if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { - m_sla_print->export_raster(m_export_path); - m_print->set_status(100, "Masked SLA file exported to " + m_export_path); + const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); + m_sla_print->export_raster(export_path); + m_print->set_status(100, "Masked SLA file exported to " + export_path); } else if (! m_upload_job.empty()) { prepare_upload(); } else { @@ -389,7 +390,7 @@ void BackgroundSlicingProcess::prepare_upload() // Generate a unique temp path to which the gcode/zip file is copied/exported boost::filesystem::path source_path = boost::filesystem::temp_directory_path() - / boost::filesystem::unique_path(".printhost.%%%%-%%%%-%%%%-%%%%.gcode"); + / boost::filesystem::unique_path(".Slic3rPE.upload.%%%%-%%%%-%%%%-%%%%"); if (m_print == m_fff_print) { m_print->set_status(95, "Running post-processing scripts"); @@ -399,8 +400,8 @@ void BackgroundSlicingProcess::prepare_upload() run_post_process_scripts(source_path.string(), m_fff_print->config()); m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); } else { - m_sla_print->export_raster(source_path.string()); - // TODO: Also finalize upload path like with FFF when there are statistics for SLA print + m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + m_sla_print->export_raster(source_path.string(), m_upload_job.upload_data.upload_path.string()); } m_print->set_status(100, (boost::format("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue") % m_upload_job.printhost->get_host()).str()); From 6197f48321f9a7646c88d39d8a8c76a59f56543a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Apr 2019 14:00:31 +0200 Subject: [PATCH 28/61] Use current selection to determine proposed filename when exporting to stl files --- src/libslic3r/Model.cpp | 36 +++++++++++++++++++++++------------- src/libslic3r/Model.hpp | 2 ++ src/slic3r/GUI/Plater.cpp | 14 ++++++++++++-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index ba898d9d52..e634dd1383 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -556,19 +556,9 @@ std::string Model::propose_export_file_name_and_path() const for (const ModelObject *model_object : this->objects) for (ModelInstance *model_instance : model_object->instances) if (model_instance->is_printable()) { - input_file = model_object->input_file; - if (! model_object->name.empty()) { - if (input_file.empty()) - // model_object->input_file was empty, just use model_object->name - input_file = model_object->name; - else { - // Replace file name in input_file with model_object->name, but keep the path and file extension. - input_file = (boost::filesystem::path(model_object->name).parent_path().empty()) ? - (boost::filesystem::path(input_file).parent_path() / model_object->name).make_preferred().string() : - model_object->name; - } - } - if (! input_file.empty()) + input_file = model_object->get_export_filename(); + + if (!input_file.empty()) goto end; // Other instances will produce the same name, skip them. break; @@ -1433,6 +1423,26 @@ void ModelObject::print_info() const cout << "volume = " << mesh.volume() << endl; } +std::string ModelObject::get_export_filename() const +{ + std::string ret = input_file; + + if (!name.empty()) + { + if (ret.empty()) + // input_file was empty, just use name + ret = name; + else + { + // Replace file name in input_file with name, but keep the path and file extension. + ret = (boost::filesystem::path(name).parent_path().empty()) ? + (boost::filesystem::path(ret).parent_path() / name).make_preferred().string() : name; + } + } + + return ret; +} + void ModelVolume::set_material_id(t_model_material_id material_id) { m_material_id = material_id; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 5cf7f49cad..9514012434 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -275,6 +275,8 @@ public: // Print object statistics to console. void print_info() const; + std::string get_export_filename() const; + protected: friend class Print; friend class SLAPrint; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9cf9768a5e..53d9992839 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1840,8 +1840,18 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type) // Update printbility state of each of the ModelInstances. this->update_print_volume_state(); - // Find the file name of the first printable object. - fs::path output_file = this->model.propose_export_file_name_and_path(); + + const Selection& selection = get_selection(); + int obj_idx = selection.get_object_idx(); + + fs::path output_file; + // first try to get the file name from the current selection + if ((0 <= obj_idx) && (obj_idx < (int)this->model.objects.size())) + output_file = this->model.objects[obj_idx]->get_export_filename(); + + if (output_file.empty()) + // Find the file name of the first printable object. + output_file = this->model.propose_export_file_name_and_path(); wxString dlg_title; switch (file_type) { From 09054a0bc9de788c646d35e0d5cd10c1b28c8abd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 4 Apr 2019 15:07:54 +0200 Subject: [PATCH 29/61] Fixed non-consistency of the selection --- src/slic3r/GUI/GUI_ObjectList.cpp | 149 ++++++++++++++++++++---------- src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- 2 files changed, 100 insertions(+), 51 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 203e765731..f495e168a0 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -89,7 +89,24 @@ ObjectList::ObjectList(wxWindow* parent) : // manipulator cache with the following call to selection_changed() wxGetApp().obj_manipul()->emulate_kill_focus(); #endif // __APPLE__ - m_last_selected_item = event.GetItem(); + + /* For multiple selection with pressed SHIFT, + * event.GetItem() returns value of a first item in selection list + * instead of real last clicked item. + * So, let check last selected item in such strange way + */ + if (wxGetKeyState(WXK_SHIFT)) + { + wxDataViewItemArray sels; + GetSelections(sels); + if (sels.front() == m_last_selected_item) + m_last_selected_item = sels.back(); + else + m_last_selected_item = event.GetItem(); + } + else + m_last_selected_item = event.GetItem(); + selection_changed(); #ifndef __WXMSW__ set_tooltip_for_item(get_mouse_position_in_control()); @@ -511,7 +528,7 @@ void ObjectList::key_event(wxKeyEvent& event) printf("WXK_BACK\n"); remove(); } - else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT)) + else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/)) select_item_all_children(); else event.Skip(); @@ -2183,11 +2200,10 @@ void ObjectList::select_item_all_children() // update selection mode for non-multiple selection void ObjectList::update_selection_mode() { - m_last_selected_item = wxDataViewItem(0); - // All items are unselected if (!GetSelection()) { + m_last_selected_item = wxDataViewItem(0); m_selection_mode = smUndef; return; } @@ -2198,33 +2214,55 @@ void ObjectList::update_selection_mode() } // check last selected item. If is it possible to select it -bool ObjectList::check_last_selection() +bool ObjectList::check_last_selection(wxString& msg_str) { if (!m_last_selected_item) return true; + + const bool is_shift_pressed = wxGetKeyState(WXK_SHIFT); /* We can't mix Parts and Objects/Instances. - * So, unselect last selected item and show information about it + * So, show information about it */ const ItemType type = m_objects_model->GetItemType(m_last_selected_item); - if (type & itSettings || + + // check a case of a selection of the Parts from different Objects + bool impossible_multipart_selection = false; + if (type & itVolume && m_selection_mode == smVolume) + { + wxDataViewItemArray sels; + GetSelections(sels); + for (const auto& sel: sels) + if (sel != m_last_selected_item && + m_objects_model->GetParent(sel) != m_objects_model->GetParent(m_last_selected_item)) + { + impossible_multipart_selection = true; + break; + } + } + + if (impossible_multipart_selection || + type & itSettings || type & itVolume && m_selection_mode == smInstance || !(type & itVolume) && m_selection_mode == smVolume) { - Unselect(m_last_selected_item); - // Inform user why selection isn't complited const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part")); - const wxString msg_str = wxString::Format(_(L("You started your selection with %s Item.")) + "\n" + - _(L("In this mode you can select only another %s Items%s")), item_type, item_type, - m_selection_mode == smInstance ? "." : " " + _(L("of a current Object"))); + msg_str = wxString::Format( _(L("Unsupported selection")) + "\n\n" + + _(L("You started your selection with %s Item.")) + "\n" + + _(L("In this mode you can select only other %s Items%s")), + item_type, item_type, + m_selection_mode == smInstance ? "." : + " " + _(L("of a current Object"))); - wxMessageDialog dialog(this, _(L("Unsupported selection")) + "\n\n" + msg_str, - _(L("Info")), wxICON_INFORMATION); - dialog.ShowModal(); - - return false; + // Unselect last selected item, if selection is without SHIFT + if (!is_shift_pressed) { + Unselect(m_last_selected_item); + show_info(this, msg_str, _(L("Info"))); + } + + return is_shift_pressed; } return true; @@ -2237,7 +2275,8 @@ void ObjectList::fix_multiselection_conflicts() return; } - if (!check_last_selection()) + wxString msg_string; + if (!check_last_selection(msg_string)) return; m_prevent_list_events = true; @@ -2245,49 +2284,59 @@ void ObjectList::fix_multiselection_conflicts() wxDataViewItemArray sels; GetSelections(sels); - m_selection_mode = smInstance; + if (m_selection_mode == smVolume) + { + // identify correct parent of the initial selected item + const wxDataViewItem& parent = m_objects_model->GetParent(m_last_selected_item == sels.front() ? sels.back() : sels.front()); - for (const auto item : sels) { - if (!IsSelected(item)) // if this item is unselected now (from previous actions) - continue; + sels.clear(); + wxDataViewItemArray children; // selected volumes from current parent + m_objects_model->GetChildren(parent, children); - if (m_objects_model->GetItemType(item) & itSettings) { - Unselect(item); - continue; - } + for (const auto child : children) + if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume) + sels.Add(child); - const wxDataViewItem& parent = m_objects_model->GetParent(item); - if (parent != wxDataViewItem(0) && IsSelected(parent)) - Unselect(parent); - else + // If some part is selected, unselect all items except of selected parts of the current object + UnselectAll(); + SetSelections(sels); + } + else + { + for (const auto item : sels) { - wxDataViewItemArray unsels; - m_objects_model->GetAllChildren(item, unsels); - for (const auto unsel_item : unsels) - Unselect(unsel_item); - } + if (!IsSelected(item)) // if this item is unselected now (from previous actions) + continue; - if (m_objects_model->GetItemType(item) == itVolume) - { - // If some part is selected, unselect all items except of selected parts of the current object - sels.clear(); - - wxDataViewItemArray children; // selected volumes from current parent - m_objects_model->GetChildren(parent, children); - for (const auto child : children) - { - if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume) - sels.Add(child); + if (m_objects_model->GetItemType(item) & itSettings) { + Unselect(item); + continue; } - UnselectAll(); - SetSelections(sels); + const wxDataViewItem& parent = m_objects_model->GetParent(item); + if (parent != wxDataViewItem(0) && IsSelected(parent)) + Unselect(parent); + else + { + wxDataViewItemArray unsels; + m_objects_model->GetAllChildren(item, unsels); + for (const auto unsel_item : unsels) + Unselect(unsel_item); + } - m_selection_mode = smVolume; - break; + if (m_objects_model->GetItemType(item) & itVolume) + Unselect(item); + + m_selection_mode = smInstance; } } + if (!msg_string.IsEmpty()) + show_info(this, msg_string, _(L("Info"))); + + if (!IsSelected(m_last_selected_item)) + m_last_selected_item = wxDataViewItem(0); + m_prevent_list_events = false; } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 0611cc4f19..43d5dc0598 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -267,7 +267,7 @@ public: void select_all(); void select_item_all_children(); void update_selection_mode(); - bool check_last_selection(); + bool check_last_selection(wxString& msg_str); // correct current selections to avoid of the possible conflicts void fix_multiselection_conflicts(); From 763a91e2ca73a2a9189ea47bbdcb80089e3262b8 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Apr 2019 15:13:43 +0200 Subject: [PATCH 30/61] Export to stl of parts and modifiers --- src/slic3r/GUI/GUI_ObjectList.cpp | 3 ++- src/slic3r/GUI/Plater.cpp | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c725fae432..7148be513c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1025,7 +1025,7 @@ void ObjectList::append_menu_item_fix_through_netfabb(wxMenu* menu) void ObjectList::append_menu_item_export_stl(wxMenu* menu) const { - append_menu_item(menu, wxID_ANY, _(L("Export object as STL")) + dots, "", + append_menu_item(menu, wxID_ANY, _(L("Export as STL")) + dots, "", [](wxCommandEvent&) { wxGetApp().plater()->export_stl(true); }, "", menu); menu->AppendSeparator(); } @@ -1101,6 +1101,7 @@ void ObjectList::create_part_popupmenu(wxMenu *menu) #endif // __WXOSX__ append_menu_item_fix_through_netfabb(menu); + append_menu_item_export_stl(menu); m_menu_item_split_part = append_menu_item_split(menu); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 53d9992839..247e4a0e87 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2775,7 +2775,10 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ if (is_part) { item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")), [this](wxCommandEvent&) { q->remove_selected(); }, "brick_delete.png"); - } else { + + sidebar->obj_list()->append_menu_item_export_stl(menu); + } + else { wxMenuItem* item_increase = append_menu_item(menu, wxID_ANY, _(L("Increase copies")) + "\t+", _(L("Place one more copy of the selected object")), [this](wxCommandEvent&) { q->increase_instances(); }, "add.png"); wxMenuItem* item_decrease = append_menu_item(menu, wxID_ANY, _(L("Decrease copies")) + "\t-", _(L("Remove one copy of the selected object")), @@ -2808,8 +2811,9 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ append_menu_item(menu, wxID_ANY, _(L("Export object as STL")) + dots, _(L("Export this single object as STL file")), [this](wxCommandEvent&) { q->export_stl(true); }); + + menu->AppendSeparator(); } - menu->AppendSeparator(); sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu); @@ -3317,8 +3321,17 @@ void Plater::export_stl(bool selection_only) const auto obj_idx = selection.get_object_idx(); if (obj_idx == -1) { return; } - mesh = p->model.objects[obj_idx]->mesh(); - } else { + + if (selection.get_mode() == Selection::Instance) + mesh = p->model.objects[obj_idx]->mesh(); + else + { + const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); + mesh = p->model.objects[obj_idx]->volumes[volume->volume_idx()]->mesh; + mesh.transform(volume->get_volume_transformation().get_matrix()); + } + } + else { mesh = p->model.mesh(); } From b56991d780b342bcc7d9b4894be3ae98aa8ff0f0 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 4 Apr 2019 16:03:23 +0200 Subject: [PATCH 31/61] Fix for leaving the object outside bed after "optimize orientation" --- src/slic3r/GUI/Plater.cpp | 61 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 247e4a0e87..b9eea5bd4a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -38,6 +38,8 @@ #include "libslic3r/SLA/SLARotfinder.hpp" #include "libslic3r/Utils.hpp" +#include "libnest2d/optimizers/nlopt/genetic.hpp" + #include "GUI.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" @@ -2100,7 +2102,9 @@ void Plater::priv::sla_optimize_rotation() { rotoptimizing.store(true); int obj_idx = get_selected_object_idx(); - ModelObject * o = model.objects[obj_idx]; + if(obj_idx < 0) { rotoptimizing.store(false); return; } + + ModelObject * o = model.objects[size_t(obj_idx)]; background_process.stop(); @@ -2108,7 +2112,7 @@ void Plater::priv::sla_optimize_rotation() { statusbar()->set_range(100); auto stfn = [this] (unsigned st, const std::string& msg) { - statusbar()->set_progress(st); + statusbar()->set_progress(int(st)); statusbar()->set_status_text(msg); // could be problematic, but we need the cancel button. @@ -2126,8 +2130,59 @@ void Plater::priv::sla_optimize_rotation() { [this](){ return !rotoptimizing.load(); } ); + const auto *bed_shape_opt = config->opt("bed_shape"); + assert(bed_shape_opt); + + auto& bedpoints = bed_shape_opt->values; + Polyline bed; bed.points.reserve(bedpoints.size()); + for(auto& v : bedpoints) bed.append(Point::new_scale(v(0), v(1))); + + double mindist = 6.0; // FIXME + double offs = mindist / 2.0 - EPSILON; + if(rotoptimizing.load()) // wasn't canceled - for(ModelInstance * oi : o->instances) oi->set_rotation({r[X], r[Y], r[Z]}); + for(ModelInstance * oi : o->instances) { + oi->set_rotation({r[X], r[Y], r[Z]}); + + auto trchull = o->convex_hull_2d(oi->get_transformation().get_matrix()); + + namespace opt = libnest2d::opt; + opt::StopCriteria stopcr; + stopcr.relative_score_difference = 0.01; + stopcr.max_iterations = 10000; + stopcr.stop_score = 0.0; + opt::GeneticOptimizer solver(stopcr); + Polygon pbed(bed); + + auto bin = pbed.bounding_box(); + double binw = bin.size()(X) * SCALING_FACTOR - offs; + double binh = bin.size()(Y) * SCALING_FACTOR - offs; + + auto result = solver.optimize_min([&trchull, binw, binh](double rot){ + auto chull = trchull; + chull.rotate(rot); + + auto bb = chull.bounding_box(); + double bbw = bb.size()(X) * SCALING_FACTOR; + double bbh = bb.size()(Y) * SCALING_FACTOR; + + auto wdiff = bbw - binw; + auto hdiff = bbh - binh; + double diff = 0; + if(wdiff < 0 && hdiff < 0) diff = wdiff + hdiff; + if(wdiff > 0) diff += wdiff; + if(hdiff > 0) diff += hdiff; + + return diff; + }, opt::initvals(0.0), opt::bound(-PI/2, PI/2)); + + double r = std::get<0>(result.optimum); + + Vec3d rt = oi->get_rotation(); rt(Z) += r; + oi->set_rotation(rt); + } + + arr::find_new_position(model, o->instances, coord_t(mindist/SCALING_FACTOR), bed); // Correct the z offset of the object which was corrupted be the rotation o->ensure_on_bed(); From ef1a273f0c31e6f606681a9b94be41c3d09d5feb Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Apr 2019 16:16:57 +0200 Subject: [PATCH 32/61] Fix of "Latest commit of Slic3r 1.42.0 cuts away part of the model #2063" Fixed one bug of many in admesh library, where the face connectivity was broken when removing a degenerate face. Likely there are some similar issues left to be solved. Placed a workaround to always recalculate face connectivity before slicing. --- src/admesh/connect.cpp | 64 +++++++++++++++++------------------ src/admesh/stl.h | 2 -- src/admesh/stl_io.cpp | 18 ---------- src/libslic3r/PrintObject.cpp | 11 +++++- 4 files changed, 41 insertions(+), 54 deletions(-) diff --git a/src/admesh/connect.cpp b/src/admesh/connect.cpp index 5fc992b63f..fb32132194 100644 --- a/src/admesh/connect.cpp +++ b/src/admesh/connect.cpp @@ -39,8 +39,7 @@ static void stl_record_neighbors(stl_file *stl, stl_hash_edge *edge_a, stl_hash_edge *edge_b); static void stl_initialize_facet_check_exact(stl_file *stl); static void stl_initialize_facet_check_nearby(stl_file *stl); -static void stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge, - stl_vertex *a, stl_vertex *b); +static void stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge, const stl_vertex *a, const stl_vertex *b); static int stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge, stl_vertex *a, stl_vertex *b, float tolerance); static void insert_hash_edge(stl_file *stl, stl_hash_edge edge, @@ -60,41 +59,40 @@ extern int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag); static void stl_update_connects_remove_1(stl_file *stl, int facet_num); - -void -stl_check_facets_exact(stl_file *stl) { - /* This function builds the neighbors list. No modifications are made - * to any of the facets. The edges are said to match only if all six - * floats of the first edge matches all six floats of the second edge. - */ - - stl_hash_edge edge; - stl_facet facet; - int i; - int j; - - if (stl->error) return; +// This function builds the neighbors list. No modifications are made +// to any of the facets. The edges are said to match only if all six +// floats of the first edge matches all six floats of the second edge. +void stl_check_facets_exact(stl_file *stl) +{ + if (stl->error) + return; stl->stats.connected_edges = 0; stl->stats.connected_facets_1_edge = 0; stl->stats.connected_facets_2_edge = 0; stl->stats.connected_facets_3_edge = 0; - stl_initialize_facet_check_exact(stl); + // If any two of the three vertices are found to be exactally the same, call them degenerate and remove the facet. + // Do it before the next step, as the next step stores references to the face indices in the hash tables and removing a facet + // will break the references. + for (int i = 0; i < stl->stats.number_of_facets;) { + stl_facet &facet = stl->facet_start[i]; + if (facet.vertex[0] == facet.vertex[1] || facet.vertex[1] == facet.vertex[2] || facet.vertex[0] == facet.vertex[2]) { + // Remove the degenerate facet. + facet = stl->facet_start[--stl->stats.number_of_facets]; + stl->stats.facets_removed += 1; + stl->stats.degenerate_facets += 1; + } else + ++ i; + } - for(i = 0; i < stl->stats.number_of_facets; i++) { - facet = stl->facet_start[i]; - // If any two of the three vertices are found to be exactally the same, call them degenerate and remove the facet. - if (facet.vertex[0] == facet.vertex[1] || - facet.vertex[1] == facet.vertex[2] || - facet.vertex[0] == facet.vertex[2]) { - stl->stats.degenerate_facets += 1; - stl_remove_facet(stl, i); - -- i; - continue; - } - for(j = 0; j < 3; j++) { - edge.facet_number = i; + // Connect neighbor edges. + stl_initialize_facet_check_exact(stl); + for (int i = 0; i < stl->stats.number_of_facets; i++) { + const stl_facet &facet = stl->facet_start[i]; + for (int j = 0; j < 3; j++) { + stl_hash_edge edge; + edge.facet_number = i; edge.which_edge = j; stl_load_edge_exact(stl, &edge, &facet.vertex[j], &facet.vertex[(j + 1) % 3]); insert_hash_edge(stl, edge, stl_record_neighbors); @@ -109,9 +107,7 @@ stl_check_facets_exact(stl_file *stl) { #endif } -static void -stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge, - stl_vertex *a, stl_vertex *b) { +static void stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge, const stl_vertex *a, const stl_vertex *b) { if (stl->error) return; @@ -333,7 +329,9 @@ static void stl_free_edges(stl_file *stl) } } free(stl->heads); + stl->heads = nullptr; free(stl->tail); + stl->tail = nullptr; } static void stl_initialize_facet_check_nearby(stl_file *stl) diff --git a/src/admesh/stl.h b/src/admesh/stl.h index afff3deac1..2c436b426b 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -127,7 +127,6 @@ typedef struct { typedef struct { FILE *fp; stl_facet *facet_start; - stl_edge *edge_start; stl_hash_edge **heads; stl_hash_edge *tail; int M; @@ -142,7 +141,6 @@ typedef struct { extern void stl_open(stl_file *stl, const char *file); extern void stl_close(stl_file *stl); extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file); -extern void stl_print_edges(stl_file *stl, FILE *file); extern void stl_print_neighbors(stl_file *stl, char *file); extern void stl_put_little_int(FILE *fp, int value_in); extern void stl_put_little_float(FILE *fp, float value_in); diff --git a/src/admesh/stl_io.cpp b/src/admesh/stl_io.cpp index 71e434cbcd..85f66785b3 100644 --- a/src/admesh/stl_io.cpp +++ b/src/admesh/stl_io.cpp @@ -33,24 +33,6 @@ #define SEEK_END 2 #endif -void -stl_print_edges(stl_file *stl, FILE *file) { - int i; - int edges_allocated; - - if (stl->error) return; - - edges_allocated = stl->stats.number_of_facets * 3; - for(i = 0; i < edges_allocated; i++) { - fprintf(file, "%d, %f, %f, %f, %f, %f, %f\n", - stl->edge_start[i].facet_number, - stl->edge_start[i].p1(0), stl->edge_start[i].p1(1), - stl->edge_start[i].p1(2), stl->edge_start[i].p2(0), - stl->edge_start[i].p2(1), stl->edge_start[i].p2(2)); - } -} - - void stl_stats_out(stl_file *stl, FILE *file, char *input_file) { if (stl->error) return; diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 42c6fbf754..954e583f7c 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1790,8 +1790,13 @@ std::vector PrintObject::_slice_volumes(const std::vector &z, if (! volumes.empty()) { // Compose mesh. //FIXME better to perform slicing over each volume separately and then to use a Boolean operation to merge them. - TriangleMesh mesh(volumes.front()->mesh); + TriangleMesh mesh(volumes.front()->mesh); mesh.transform(volumes.front()->get_matrix(), true); + assert(mesh.repaired); + if (volumes.size() == 1 && mesh.repaired) { + //FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it. + stl_check_facets_exact(&mesh.stl); + } for (size_t idx_volume = 1; idx_volume < volumes.size(); ++ idx_volume) { const ModelVolume &model_volume = *volumes[idx_volume]; TriangleMesh vol_mesh(model_volume.mesh); @@ -1821,6 +1826,10 @@ std::vector PrintObject::_slice_volume(const std::vector &z, //FIXME better to perform slicing over each volume separately and then to use a Boolean operation to merge them. TriangleMesh mesh(volume.mesh); mesh.transform(volume.get_matrix(), true); + if (mesh.repaired) { + //FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it. + stl_check_facets_exact(&mesh.stl); + } if (mesh.stl.stats.number_of_facets > 0) { mesh.transform(m_trafo, true); // apply XY shift From 8631cb006b73559728d307723912a14e9947280e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 29 Mar 2019 14:36:09 +0100 Subject: [PATCH 33/61] Improved Selection from ObjectList side --- src/slic3r/GUI/GUI_ObjectList.cpp | 102 ++++++++++++++++++---- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 +- src/slic3r/GUI/Selection.hpp | 2 + src/slic3r/GUI/wxExtensions.cpp | 26 ++++++ src/slic3r/GUI/wxExtensions.hpp | 2 +- 6 files changed, 117 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 7148be513c..550337ab7e 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1639,16 +1639,20 @@ void ObjectList::part_selection_changed() bool update_and_show_manipulations = false; bool update_and_show_settings = false; - if (multiple_selection()) { + const auto item = GetSelection(); + + if ( multiple_selection() || item && m_objects_model->GetItemType(item) == itInstanceRoot ) + { og_name = _(L("Group manipulation")); - update_and_show_manipulations = true; + + const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); + // don't show manipulation panel for case of all Object's parts selection + update_and_show_manipulations = !selection.is_single_full_instance(); } else { - const auto item = GetSelection(); if (item) { - bool is_part = false; if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { obj_idx = m_objects_model->GetIdByItem(item); og_name = _(L("Object manipulation")); @@ -1666,7 +1670,6 @@ void ObjectList::part_selection_changed() } else { og_name = _(L("Part Settings to modify")); - is_part = true; auto main_parent = m_objects_model->GetParent(parent); obj_idx = m_objects_model->GetIdByItem(main_parent); const auto volume_id = m_objects_model->GetVolumeIdByItem(parent); @@ -1676,7 +1679,6 @@ void ObjectList::part_selection_changed() } else if (m_objects_model->GetItemType(item) == itVolume) { og_name = _(L("Part manipulation")); - is_part = true; const auto volume_id = m_objects_model->GetVolumeIdByItem(item); m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config; update_and_show_manipulations = true; @@ -1924,6 +1926,15 @@ bool ObjectList::multiple_selection() const return GetSelectedItemsCount() > 1; } +bool ObjectList::is_selected(const ItemType type) const +{ + const wxDataViewItem& item = GetSelection(); + if (item) + return m_objects_model->GetItemType(item) == type; + + return false; +} + void ObjectList::update_selections() { const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); @@ -1942,25 +1953,64 @@ void ObjectList::update_selections() return; } } - - if (selection.is_single_full_object()) +// if (selection.is_single_full_object() && selection.get_instance_idx() != -1) +// { +// sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); +// } +// else if (selection.is_single_volume() || selection.is_modifier() || +// selection.is_multiple_volume() || selection.is_multiple_full_object()) +// { +// for (auto idx : selection.get_volume_idxs()) { +// const auto gl_vol = selection.get_volume(idx); +// if (selection.is_multiple_full_object()) +// sels.Add(m_objects_model->GetItemById(gl_vol->object_idx())); +// else if (gl_vol->volume_idx() >= 0) +// // Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids +// // are not associated with ModelVolumes, but they are temporarily generated by the backend +// // (for example, SLA supports or SLA pad). +// sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx())); +// } +// } + else if (selection.is_single_full_object() || selection.is_multiple_full_object()) { - sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); + const Selection::ObjectIdxsToInstanceIdxsMap& objects_content = selection.get_content(); + for (const auto& object : objects_content) { + if (object.second.size() == 1) // object with 1 instance + sels.Add(m_objects_model->GetItemById(object.first)); + else if (object.second.size() > 1) // object with several instances + { + wxDataViewItemArray current_sels; + GetSelections(current_sels); + const wxDataViewItem frst_inst_item = m_objects_model->GetItemByInstanceId(object.first, 0); + + bool root_is_selected = false; + for (const auto& item:current_sels) + if (item == m_objects_model->GetParent(frst_inst_item)) { + root_is_selected = true; + break; + } + if (root_is_selected) + continue; + + const Selection::InstanceIdxsList& instances = object.second; + for (const auto& inst : instances) + sels.Add(m_objects_model->GetItemByInstanceId(object.first, inst)); + } + } } - else if (selection.is_single_volume() || selection.is_modifier() || - selection.is_multiple_volume() || selection.is_multiple_full_object()) { + else if (selection.is_single_volume() || selection.is_modifier() || selection.is_multiple_volume()) + { for (auto idx : selection.get_volume_idxs()) { const auto gl_vol = selection.get_volume(idx); - if (selection.is_multiple_full_object()) - sels.Add(m_objects_model->GetItemById(gl_vol->object_idx())); - else if (gl_vol->volume_idx() >= 0) + if (gl_vol->volume_idx() >= 0) // Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids // are not associated with ModelVolumes, but they are temporarily generated by the backend // (for example, SLA supports or SLA pad). sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx())); } } - else if (selection.is_single_full_instance() || selection.is_multiple_full_instance()) { + else if (selection.is_single_full_instance() || selection.is_multiple_full_instance()) + { for (auto idx : selection.get_instance_idxs()) { sels.Add(m_objects_model->GetItemByInstanceId(selection.get_object_idx(), idx)); } @@ -2137,11 +2187,25 @@ void ObjectList::fix_multiselection_conflicts() wxDataViewItemArray sels; GetSelections(sels); - for (auto item : sels) { - if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot)) + for (const auto item : sels) { + if (!IsSelected(item)) // if this item is unselected now (from previous actions) + continue; + + if (m_objects_model->GetItemType(item) & itSettings) { Unselect(item); - else if (m_objects_model->GetParent(item) != wxDataViewItem(0)) - Unselect(m_objects_model->GetParent(item)); + continue; + } + + const wxDataViewItem& parent = m_objects_model->GetParent(item); + if (parent != wxDataViewItem(0) && IsSelected(parent)) + Unselect(parent); + else + { + wxDataViewItemArray unsels; + m_objects_model->GetAllChildren(item, unsels); + for (const auto unsel_item : unsels) + Unselect(unsel_item); + } } m_prevent_list_events = false; diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 4ddc6ea71f..b0ed756f86 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -251,6 +251,7 @@ public: void init_objects(); bool multiple_selection() const ; + bool is_selected(const ItemType type) const; void update_selections(); void update_selections_on_canvas(); void select_item(const wxDataViewItem& item); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 61e98d5425..48bb1f6903 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -161,6 +161,8 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_move_label_string = L("Position"); m_new_rotate_label_string = L("Rotation"); m_new_scale_label_string = L("Scale factors"); + + ObjectList* obj_list = wxGetApp().obj_list(); if (selection.is_single_full_instance()) { // all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one @@ -187,7 +189,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_enabled = true; } - else if (selection.is_single_full_object()) + else if (selection.is_single_full_object() && obj_list->is_selected(itObject)) { m_cache.instance.reset(); @@ -212,7 +214,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_size = (volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size()).cwiseAbs(); m_new_enabled = true; } - else if (wxGetApp().obj_list()->multiple_selection()) + else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) { reset_settings_value(); m_new_move_label_string = L("Translate"); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 4b2a72d7c0..883fb54008 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -133,10 +133,12 @@ private: const Transform3d& get_instance_full_matrix() const { return m_instance.full_matrix; } }; +public: typedef std::map VolumesCache; typedef std::set InstanceIdxsList; typedef std::map ObjectIdxsToInstanceIdxsMap; +private: struct Cache { // Cache of GLVolume derived transformation matrices, valid during mouse dragging. diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 09096cb059..0671bb62cc 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1238,6 +1238,32 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, return count; } +void PrusaObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const +{ + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); + if (!node) { + for (auto object : m_objects) + array.Add(wxDataViewItem((void*)object)); + } + else if (node->GetChildCount() == 0) + return; + else { + const size_t count = node->GetChildren().GetCount(); + for (size_t pos = 0; pos < count; pos++) { + PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos); + array.Add(wxDataViewItem((void*)child)); + } + } + + wxDataViewItemArray new_array = array; + for (const auto item : new_array) + { + wxDataViewItemArray children; + GetAllChildren(item, children); + WX_APPEND_ARRAY(array, children); + } +} + ItemType PrusaObjectDataViewModel::GetItemType(const wxDataViewItem &item) const { if (!item.IsOk()) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 27da67deb7..72221962c3 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -511,7 +511,7 @@ public: virtual bool IsContainer(const wxDataViewItem &item) const override; virtual unsigned int GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const override; - + void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const; // Is the container just a header or an item with all columns // In our case it is an item with all columns virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } From ccee04cd689017ba4880e6cd74d8c170ac40e7af Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 4 Apr 2019 18:01:53 +0200 Subject: [PATCH 34/61] Implemented new logic for Instances splitting --- src/slic3r/GUI/GUI_ObjectList.cpp | 41 ++++++++++++++++++++++++++++++- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 550337ab7e..c93096875b 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1120,8 +1120,16 @@ void ObjectList::create_instance_popupmenu(wxMenu*menu) { m_menu_item_split_instances = append_menu_item_instance_to_object(menu); + /* New behavior logic: + * 1. Split Object to several separated object, if ALL instances are selected + * 2. Separate selected instances from the initial object to the separated object, + * if some (not all) instances are selected + */ wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { - evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId()); +// evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId()); + evt.SetText(wxGetApp().plater()->canvas3D()->get_selection().is_single_full_object() ? + _(L("Set as a Separated Objects")) : _(L("Set as a Separated Object"))); + }, m_menu_item_split_instances->GetId()); } wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) @@ -2358,6 +2366,31 @@ void ObjectList::instances_to_separated_object(const int obj_idx, const std::set } } +void ObjectList::instances_to_separated_objects(const int obj_idx) +{ + const int inst_cnt = (*m_objects)[obj_idx]->instances.size(); + + for (int i = inst_cnt-1; i > 0 ; i--) + { + // create new object from initial + ModelObject* object = (*m_objects)[obj_idx]->get_model()->add_object(*(*m_objects)[obj_idx]); + for (int inst_idx = object->instances.size() - 1; inst_idx >= 0; inst_idx--) + { + if (inst_idx == i) + continue; + // delete unnecessary instances + object->delete_instance(inst_idx); + } + + // Add new object to the object_list + add_object_to_list(m_objects->size() - 1); + + // delete current instance from the initial object + del_subobject_from_object(obj_idx, i, itInstance); + delete_instance_from_list(obj_idx, i); + } +} + void ObjectList::split_instances() { const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); @@ -2365,6 +2398,12 @@ void ObjectList::split_instances() if (obj_idx == -1) return; + if (selection.is_single_full_object()) + { + instances_to_separated_objects(obj_idx); + return; + } + const int inst_idx = selection.get_instance_idx(); const std::set inst_idxs = inst_idx < 0 ? selection.get_instance_idxs() : diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index b0ed756f86..48d87db3c8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -270,6 +270,7 @@ public: void update_object_menu(); void instances_to_separated_object(const int obj_idx, const std::set& inst_idx); + void instances_to_separated_objects(const int obj_idx); void split_instances(); void rename_item(); void fix_through_netfabb() const; From 77dcb7f5a39d5f99c3c6a50e225e7e1b4be1bc54 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 5 Apr 2019 09:04:52 +0200 Subject: [PATCH 35/61] Added missed code for my last commit --- src/slic3r/GUI/GUI_ObjectList.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index c93096875b..62cdb2d7c8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2346,6 +2346,12 @@ void ObjectList::update_object_menu() void ObjectList::instances_to_separated_object(const int obj_idx, const std::set& inst_idxs) { + if ((*m_objects)[obj_idx]->instances.size() == inst_idxs.size()) + { + instances_to_separated_objects(obj_idx); + return; + } + // create new object from selected instance ModelObject* model_object = (*m_objects)[obj_idx]->get_model()->add_object(*(*m_objects)[obj_idx]); for (int inst_idx = model_object->instances.size() - 1; inst_idx >= 0; inst_idx--) From 177f5b02fa1472f25eb47c6925f20dfae983d7da Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 5 Apr 2019 09:51:58 +0200 Subject: [PATCH 36/61] Disabled layer editing mode for SLA --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 79a3684ef5..cc17942168 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4382,7 +4382,7 @@ bool GLCanvas3D::_init_toolbar() item.sprite_id = 8; item.is_toggable = true; item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; - item.visibility_callback = GLToolbarItem::Default_Visibility_Callback; + item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; }; item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_layers_editing(); }; if (!m_toolbar.add_item(item)) return false; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b9eea5bd4a..c3352866ad 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3027,6 +3027,9 @@ bool Plater::priv::can_split() const bool Plater::priv::layers_height_allowed() const { + if (printer_technology != ptFFF) + return false; + int obj_idx = get_selected_object_idx(); return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed(); } From 88059baddba34fafd9952775491732192999fb3d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 5 Apr 2019 10:01:48 +0200 Subject: [PATCH 37/61] Detect Remote Desktop connection and use Mesa OpenGL renderer. --- src/slic3r_app_msvc.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/slic3r_app_msvc.cpp b/src/slic3r_app_msvc.cpp index 48c166406e..380d30cf40 100644 --- a/src/slic3r_app_msvc.cpp +++ b/src/slic3r_app_msvc.cpp @@ -212,7 +212,12 @@ int wmain(int argc, wchar_t **argv) argv_extended.emplace_back(nullptr); OpenGLVersionCheck opengl_version_check; - bool load_mesa = ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); + bool load_mesa = + // Running over a rempote desktop, and the RemoteFX is not enabled, therefore Windows will only provide SW OpenGL 1.1 context. + // In that case, use Mesa. + ::GetSystemMetrics(SM_REMOTESESSION) || + // Try to load the default OpenGL driver and test its context version. + ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); wchar_t path_to_exe[MAX_PATH + 1] = { 0 }; ::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH); From a9223aeb5f803736b0c94b2ebbb466ae79e69399 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 5 Apr 2019 10:08:34 +0200 Subject: [PATCH 38/61] Follow-up of 763a91e2ca73a2a9189ea47bbdcb80089e3262b8 -> take in account of ModelObject::origin_translation when saving parts and modifiers to stl --- src/libslic3r/TriangleMesh.cpp | 5 +++++ src/libslic3r/TriangleMesh.hpp | 1 + src/slic3r/GUI/Plater.cpp | 9 +++++---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 0d9a79978d..bfba364af6 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -273,6 +273,11 @@ void TriangleMesh::translate(float x, float y, float z) stl_invalidate_shared_vertices(&this->stl); } +void TriangleMesh::translate(const Vec3f &displacement) +{ + translate(displacement(0), displacement(1), displacement(2)); +} + void TriangleMesh::rotate(float angle, const Axis &axis) { if (angle == 0.f) diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 527846f9d9..d389500c69 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -40,6 +40,7 @@ public: void scale(float factor); void scale(const Vec3d &versor); void translate(float x, float y, float z); + void translate(const Vec3f &displacement); void rotate(float angle, const Axis &axis); void rotate(float angle, const Vec3d& axis); void rotate_x(float angle) { this->rotate(angle, X); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c3352866ad..ec2e88f848 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3380,18 +3380,19 @@ void Plater::export_stl(bool selection_only) const auto obj_idx = selection.get_object_idx(); if (obj_idx == -1) { return; } + const ModelObject* model_object = p->model.objects[obj_idx]; if (selection.get_mode() == Selection::Instance) - mesh = p->model.objects[obj_idx]->mesh(); + mesh = model_object->mesh(); else { const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); - mesh = p->model.objects[obj_idx]->volumes[volume->volume_idx()]->mesh; + mesh = model_object->volumes[volume->volume_idx()]->mesh; mesh.transform(volume->get_volume_transformation().get_matrix()); + mesh.translate(-model_object->origin_translation.cast()); } } - else { + else mesh = p->model.mesh(); - } Slic3r::store_stl(path_u8.c_str(), &mesh, true); p->statusbar()->set_status_text(wxString::Format(_(L("STL file exported to %s")), path)); From ef5281c3c989a3022ee32f390f8bf76d0202adf4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 5 Apr 2019 11:18:13 +0200 Subject: [PATCH 39/61] Some improvements for a loading of icons --- src/slic3r/GUI/BitmapCache.cpp | 28 +++++++++++++++++++++------- src/slic3r/GUI/BitmapCache.hpp | 8 ++++---- src/slic3r/GUI/Tab.cpp | 3 ++- src/slic3r/GUI/wxExtensions.cpp | 19 ++++++++++++------- src/slic3r/GUI/wxExtensions.hpp | 2 +- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 4c7f999ffc..bea242470b 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -178,9 +178,11 @@ wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned i return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image))); } -wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int height) +wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int width, unsigned int height) { - std::string bitmap_key = bitmap_name + "-h" + std::to_string(height); + std::string bitmap_key = bitmap_name + ( height !=0 ? + "-h" + std::to_string(height) : + "-w" + std::to_string(width)); auto it = m_map.find(bitmap_key); if (it != m_map.end()) return it->second; @@ -189,14 +191,23 @@ wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int hei if (! image.LoadFile(Slic3r::GUI::from_u8(Slic3r::var(bitmap_name + ".png")), wxBITMAP_TYPE_PNG) || image.GetWidth() == 0 || image.GetHeight() == 0) return nullptr; - if (image.GetHeight() != height) - image.Rescale(int(0.5f + float(image.GetWidth()) * height / image.GetHeight()), height, wxIMAGE_QUALITY_BILINEAR); + + if (height != 0 && image.GetHeight() != height) + width = int(0.5f + float(image.GetWidth()) * height / image.GetHeight()); + else if (width != 0 && image.GetWidth() != width) + height = int(0.5f + float(image.GetHeight()) * width / image.GetWidth()); + + if (height != 0 && width != 0) + image.Rescale(width, height, wxIMAGE_QUALITY_BILINEAR); + return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image))); } -wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int target_height) +wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int target_width, unsigned int target_height) { - std::string bitmap_key = bitmap_name + "-h" + std::to_string(target_height); + std::string bitmap_key = bitmap_name + (target_height != 0 ? + "-h" + std::to_string(target_height) : + "-w" + std::to_string(target_width)); auto it = m_map.find(bitmap_key); if (it != m_map.end()) return it->second; @@ -205,7 +216,10 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int tar if (image == nullptr) return nullptr; - float scale = (float)target_height / image->height; + float scale = target_height != 0 ? + (float)target_height / image->height : target_width != 0 ? + (float)target_width / image->width : 1; + int width = (int)(scale * image->width + 0.5f); int height = (int)(scale * image->height + 0.5f); int n_pixels = width * height; diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index ce5eb3c77a..8915783a34 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -31,10 +31,10 @@ public: wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end); wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned int width, unsigned int height, const unsigned char *raw_data); - // Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height if nonzero. - wxBitmap* load_png(const std::string &bitmap_key, unsigned int height = 0); - // Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height. - wxBitmap* load_svg(const std::string &bitmap_key, unsigned int height); + // Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height/width if nonzero. + wxBitmap* load_png(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0); + // Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height/width. + wxBitmap* load_svg(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0); static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency); static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a91dae0265..c2cdf8f034 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1638,7 +1638,8 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) } auto printhost_browse = [=](wxWindow* parent) { - auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots, + wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetBitmap(create_scaled_bitmap("zoom.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 0671bb62cc..7755bc30af 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -423,15 +423,20 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) // PrusaObjectDataViewModelNode // ---------------------------------------------------------------------------- -wxBitmap create_scaled_bitmap(const std::string& bmp_name_in) +// If an icon has horizontal orientation (width > height) call this function with is_horizontal = true +wxBitmap create_scaled_bitmap(const std::string& bmp_name_in, const bool is_horizontal /* = false*/) { static Slic3r::GUI::BitmapCache cache; - const auto height = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * 1.6f + 0.5f); - std::string bmp_name = bmp_name_in; + + unsigned int height, width = height = 0; + unsigned int& scale_base = is_horizontal ? width : height; + scale_base = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * 1.6f + 0.5f); + + std::string bmp_name = bmp_name_in; boost::replace_last(bmp_name, ".png", ""); - wxBitmap *bmp = cache.load_svg(bmp_name, height); + wxBitmap *bmp = cache.load_svg(bmp_name, height, width); if (bmp == nullptr) - bmp = cache.load_png(bmp_name, height); + bmp = cache.load_png(bmp_name, height, width); return *bmp; } @@ -1481,8 +1486,8 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX - m_bmp_thumb_higher = wxBitmap(create_scaled_bitmap(style == wxSL_HORIZONTAL ? "right_half_circle.png" : "up_half_circle.png")); - m_bmp_thumb_lower = wxBitmap(create_scaled_bitmap(style == wxSL_HORIZONTAL ? "left_half_circle.png" : "down_half_circle.png")); + m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("right_half_circle.png") : create_scaled_bitmap("up_half_circle.png", true)); + m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("left_half_circle.png" ) : create_scaled_bitmap("down_half_circle.png", true)); m_thumb_size = m_bmp_thumb_lower.GetSize(); m_bmp_add_tick_on = create_scaled_bitmap("colorchange_add_on.png"); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 72221962c3..912475ceda 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -31,7 +31,7 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler); -wxBitmap create_scaled_bitmap(const std::string& bmp_name); +wxBitmap create_scaled_bitmap(const std::string& bmp_name, const bool is_horizontal = false); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { From 233eda28131081a052a401744ee4e94143972726 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 5 Apr 2019 11:30:49 +0200 Subject: [PATCH 40/61] Export to stl of instances --- src/slic3r/GUI/Plater.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ec2e88f848..3e7ab3bbc3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2864,7 +2864,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ append_menu_item(menu, wxID_ANY, _(L("Reload from Disk")), _(L("Reload the selected file from Disk")), [this](wxCommandEvent&) { reload_from_disk(); }); - append_menu_item(menu, wxID_ANY, _(L("Export object as STL")) + dots, _(L("Export this single object as STL file")), + append_menu_item(menu, wxID_ANY, _(L("Export as STL")) + dots, _(L("Export the selected object as STL file")), [this](wxCommandEvent&) { q->export_stl(true); }); menu->AppendSeparator(); @@ -3382,7 +3382,12 @@ void Plater::export_stl(bool selection_only) const ModelObject* model_object = p->model.objects[obj_idx]; if (selection.get_mode() == Selection::Instance) - mesh = model_object->mesh(); + { + if (selection.is_single_full_object()) + mesh = model_object->mesh(); + else + mesh = model_object->full_raw_mesh(); + } else { const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); From d31590f438549440e87ed8bd46bd72e5f2317db1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 5 Apr 2019 12:17:45 +0200 Subject: [PATCH 41/61] Fixed Typo for the last commit --- src/slic3r/GUI/wxExtensions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 7755bc30af..932db9cc2c 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -434,9 +434,9 @@ wxBitmap create_scaled_bitmap(const std::string& bmp_name_in, const bool is_hori std::string bmp_name = bmp_name_in; boost::replace_last(bmp_name, ".png", ""); - wxBitmap *bmp = cache.load_svg(bmp_name, height, width); + wxBitmap *bmp = cache.load_svg(bmp_name, width, height); if (bmp == nullptr) - bmp = cache.load_png(bmp_name, height, width); + bmp = cache.load_png(bmp_name, width, height); return *bmp; } From 08b9d9a5198282ba65dcdf41640b661efb69a1bb Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 5 Apr 2019 16:24:23 +0200 Subject: [PATCH 42/61] fix for hole disappearance --- src/libslic3r/SLAPrint.cpp | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 809b32d901..7dc920517b 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1041,37 +1041,31 @@ void SLAPrint::process() { ClipperPolygon poly; - // We need to reverse if flpXY OR is_lefthanded is true but - // not if both are true which is a logical inequality (XOR) - bool needreverse = flpXY != is_lefthanded; - // should be a move poly.Contour.reserve(polygon.contour.size() + 1); - auto& cntr = polygon.contour.points; - if(needreverse) - for(auto it = cntr.rbegin(); it != cntr.rend(); ++it) - poly.Contour.emplace_back(it->x(), it->y()); - else - for(auto& p : cntr) - poly.Contour.emplace_back(p.x(), p.y()); + for(auto& p : polygon.contour.points) + poly.Contour.emplace_back(p.x(), p.y()); + + auto pfirst = poly.Contour.front(); + poly.Contour.emplace_back(pfirst); for(auto& h : polygon.holes) { poly.Holes.emplace_back(); auto& hole = poly.Holes.back(); hole.reserve(h.points.size() + 1); - if(needreverse) - for(auto& p : h.points) - hole.emplace_back(p.x(), p.y()); - else - for(auto it = h.points.rbegin(); it != h.points.rend(); ++it) - hole.emplace_back(it->x(), it->y()); + for(auto& p : h.points) hole.emplace_back(p.x(), p.y()); + auto pfirst = hole.front(); hole.emplace_back(pfirst); } if(is_lefthanded) { for(auto& p : poly.Contour) p.X = -p.X; - for(auto& h : poly.Holes) for(auto& p : h) p.X = -p.X; + std::reverse(poly.Contour.begin(), poly.Contour.end()); + for(auto& h : poly.Holes) { + for(auto& p : h) p.X = -p.X; + std::reverse(h.begin(), h.end()); + } } sl::rotate(poly, double(instances[i].rotation)); @@ -1080,7 +1074,12 @@ void SLAPrint::process() if (flpXY) { for(auto& p : poly.Contour) std::swap(p.X, p.Y); - for(auto& h : poly.Holes) for(auto& p : h) std::swap(p.X, p.Y); + std::reverse(poly.Contour.begin(), poly.Contour.end()); + + for(auto& h : poly.Holes) { + for(auto& p : h) std::swap(p.X, p.Y); + std::reverse(h.begin(), h.end()); + } } polygons.emplace_back(std::move(poly)); From 2487bb8794e550ae1174e3cdb33fb7138d1dec04 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 5 Apr 2019 17:04:55 +0200 Subject: [PATCH 43/61] Remove unnecessary reversals of print polygons. second take... --- src/libslic3r/SLAPrint.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 7dc920517b..694bc64447 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1041,31 +1041,37 @@ void SLAPrint::process() { ClipperPolygon poly; + // We need to reverse if flpXY OR is_lefthanded is true but + // not if both are true which is a logical inequality (XOR) + bool needreverse = flpXY != is_lefthanded; + // should be a move poly.Contour.reserve(polygon.contour.size() + 1); - for(auto& p : polygon.contour.points) - poly.Contour.emplace_back(p.x(), p.y()); - - auto pfirst = poly.Contour.front(); - poly.Contour.emplace_back(pfirst); + auto& cntr = polygon.contour.points; + if(needreverse) + for(auto it = cntr.rbegin(); it != cntr.rend(); ++it) + poly.Contour.emplace_back(it->x(), it->y()); + else + for(auto& p : cntr) + poly.Contour.emplace_back(p.x(), p.y()); for(auto& h : polygon.holes) { poly.Holes.emplace_back(); auto& hole = poly.Holes.back(); hole.reserve(h.points.size() + 1); - for(auto& p : h.points) hole.emplace_back(p.x(), p.y()); - auto pfirst = hole.front(); hole.emplace_back(pfirst); + if(needreverse) + for(auto it = h.points.rbegin(); it != h.points.rend(); ++it) + hole.emplace_back(it->x(), it->y()); + else + for(auto& p : h.points) + hole.emplace_back(p.x(), p.y()); } if(is_lefthanded) { for(auto& p : poly.Contour) p.X = -p.X; - std::reverse(poly.Contour.begin(), poly.Contour.end()); - for(auto& h : poly.Holes) { - for(auto& p : h) p.X = -p.X; - std::reverse(h.begin(), h.end()); - } + for(auto& h : poly.Holes) for(auto& p : h) p.X = -p.X; } sl::rotate(poly, double(instances[i].rotation)); @@ -1074,12 +1080,7 @@ void SLAPrint::process() if (flpXY) { for(auto& p : poly.Contour) std::swap(p.X, p.Y); - std::reverse(poly.Contour.begin(), poly.Contour.end()); - - for(auto& h : poly.Holes) { - for(auto& p : h) std::swap(p.X, p.Y); - std::reverse(h.begin(), h.end()); - } + for(auto& h : poly.Holes) for(auto& p : h) std::swap(p.X, p.Y); } polygons.emplace_back(std::move(poly)); From 433e232aa0ef330a7619a94939aec8a9260bb95a Mon Sep 17 00:00:00 2001 From: lf- Date: Sat, 6 Apr 2019 00:20:49 -0600 Subject: [PATCH 44/61] Add a note for users of newer VS versions --- doc/How to build - Windows.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md index 5de983dd77..8b750ce0d7 100644 --- a/doc/How to build - Windows.md +++ b/doc/How to build - Windows.md @@ -12,7 +12,7 @@ _Note:_ Thanks to [**@supermerill**](https://github.com/supermerill) for testing ### Dependencies On Windows Slic3r is built against statically built libraries. -We provide a prebuilt package of all the needed dependencies. +We provide a prebuilt package of all the needed dependencies. This package only works on Visual Studio 2013, so if you are using a newer version of Visual Studio, you need to compile the dependencies yourself as per [below](#building-the-dependencies-package-yourself). The package comes in a several variants: - [64 bit, Release mode only](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=destdir-64.7z) (41 MB, 578 MB unpacked) @@ -28,7 +28,7 @@ Alternatively you can also compile the dependencies yourself, see below. ### Building Slic3r PE with Visual Studio -First obtain the Slic3 PE sources via either git or by extracting the source archive. +First obtain the Slic3r PE sources via either git or by extracting the source archive. Then you will need to note down the so-called 'prefix path' to the dependencies, this is the location of the dependencies packages + `\usr\local` appended. For example on 64 bits this would be `C:\local\destdir-64\usr\local`. The prefix path will need to be passed to CMake. From 68ec858e9a5ee3563a0265a9a627a688a36c2af4 Mon Sep 17 00:00:00 2001 From: lf- Date: Sat, 6 Apr 2019 19:29:25 -0600 Subject: [PATCH 45/61] Initial fixes on README to bring it up to date with Prusa changes The section about the command line arguments still needs addressing - it is likely outdated and in need of updates. --- README.md | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index f6c0677c48..4c56a882a7 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,20 @@ Prebuilt Windows, OSX and Linux binaries are available through the [git releases -Slic3r takes 3D models (STL, OBJ, AMF) and converts them into G-code instructions for -3D printers. It's compatible with any modern printer based on the RepRap toolchain, -including all those based on the Marlin, Sprinter and Repetier firmware. It also works +Slic3r takes 3D models (STL, OBJ, AMF) and converts them into G-code +instructions for FFF printers or PNG layers for mSLA 3D printers. It's +compatible with any modern printer based on the RepRap toolchain, including all +those based on the Marlin, Prusa, Sprinter and Repetier firmware. It also works with Mach3, LinuxCNC and Machinekit controllers. -See the [project homepage](http://slic3r.org/) at slic3r.org and the -[manual](http://manual.slic3r.org/) for more information. +See the [project homepage](https://www.prusa3d.com/slic3r-prusa-edition/) and +the [documentation directory](doc/) for more information. ### What language is it written in? -The core geometric algorithms and data structures are written in C++, -and Perl is used for high-level flow abstraction, GUI and testing. -If you're wondering why Perl, see https://xkcd.com/224/ +All user facing code is written in C++, and some legacy code as well as unit +tests are written in Perl. Perl is not required for either development or use +of Slic3r. The C++ API is public and its use in other projects is encouraged. The goal is to make Slic3r fully modular so that any part of its logic @@ -49,34 +50,23 @@ Other major features are: * several infill patterns including honeycomb, spirals, Hilbert curves * support material, raft, brim, skirt * **standby temperature** and automatic wiping for multi-extruder printing -* customizable **G-code macros** and output filename with variable placeholders +* [customizable **G-code macros**](https://github.com/prusa3d/Slic3r/wiki/Slic3r-Prusa-Edition-Macro-Language) and output filename with variable placeholders * support for **post-processing scripts** * **cooling logic** controlling fan speed and dynamic print speed -### How to install? +### Development -You can download a precompiled package from [slic3r.org](http://slic3r.org/); -it will run without the need for any dependency. - -If you want to compile the source yourself follow the instructions on one of these wiki pages: -* [Linux](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-GNU-Linux) -* [Windows](https://github.com/prusa3d/Slic3r/wiki/How-to-compile-Slic3r-Prusa-Edition-on-MS-Windows) -* [Mac OSX](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-OS-X) +If you want to compile the source yourself, follow the instructions on one of +these documentation pages: +* [Linux](doc/How%20to%20build%20-%20Linux%20et%20al.md) +* [macOS](doc/How%20to%20build%20-%20Mac%20OS.md) +* [Windows](doc/How%20to%20build%20-%20Windows.md) ### Can I help? Sure! You can do the following to find things that are available to help with: -* [Pull Request Milestone](https://github.com/alexrj/Slic3r/milestone/31) - * Please comment in the related github issue that you are working on it so that other people know. -* Items in the [TODO](https://github.com/alexrj/Slic3r/wiki/TODO) wiki page. - * Please comment in the related github issue that you are working on it so that other people know. -* Drop me a line at aar@cpan.org. -* You can also find me (rarely) in #reprap and in #slic3r on [FreeNode](https://webchat.freenode.net) with the nickname _Sound_. Another contributor, _LoH_, is also in both channels. -* Add an [issue](https://github.com/alexrj/Slic3r/issues) to the github tracker if it isn't already present. - -Before sending patches and pull requests contact me (preferably through opening a github issue or commenting on an existing, related, issue) to discuss your proposed -changes: this way we'll ensure nobody wastes their time and no conflicts arise -in development. +* Add an [issue](https://github.com/prusa3d/Slic3r/issues) to the github tracker if it isn't already present. +* Look at [issues labeled "volunteer needed"](https://github.com/prusa3d/Slic3r/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3A%22volunteer+needed%22) ### What's Slic3r license? From 8cdc461d34a5b177de748f71584297db82303485 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Apr 2019 08:30:28 +0200 Subject: [PATCH 46/61] CTRL-click replace SHIFT-click for addind/removing objects to the current selection from the 3D scene --- src/slic3r/GUI/GLCanvas3D.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cc17942168..bc03eab73e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3563,15 +3563,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if (evt.LeftDown() && (m_hover_volume_id != -1)) { bool already_selected = m_selection.contains_volume(m_hover_volume_id); - bool shift_down = evt.ShiftDown(); + bool ctrl_down = evt.CmdDown(); Selection::IndicesList curr_idxs = m_selection.get_volume_idxs(); - if (already_selected && shift_down) + if (already_selected && ctrl_down) m_selection.remove(m_hover_volume_id); else { - bool add_as_single = !already_selected && !shift_down; + bool add_as_single = !already_selected && !ctrl_down; m_selection.add(m_hover_volume_id, add_as_single); m_mouse.drag.move_requires_threshold = !already_selected; if (already_selected) From 09c7eb1d281717f28842b0dcb01e969ed2aeea8f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Apr 2019 09:49:21 +0200 Subject: [PATCH 47/61] Follow-up of a7318dbe197d0a05d368865fe169751f07840cd7 -> Do not disable other instances when an instance is selected --- src/slic3r/GUI/Selection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 0ae6199e12..00ff2dd061 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1151,9 +1151,9 @@ void Selection::update_type() m_type = MultipleVolume; else if (modifiers_count == (unsigned int)m_list.size()) m_type = MultipleModifier; - } - requires_disable = true; + requires_disable = true; + } } else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size())) { From a8a2125069cedf2e5b3121b1d68051c36b09a1d5 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 8 Apr 2019 10:02:50 +0200 Subject: [PATCH 48/61] Windows deps & build doc: Fix msbuild parallelism, cf. #2078 --- deps/deps-windows.cmake | 16 ++++++++-------- doc/How to build - Windows.md | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index a7397316f4..0806c23887 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -62,7 +62,7 @@ ExternalProject_Add(dep_tbb -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local" - BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) if (${DEP_DEBUG}) @@ -70,7 +70,7 @@ if (${DEP_DEBUG}) ExternalProject_Add_Step(dep_tbb build_debug DEPENDEES build DEPENDERS install - COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj + COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj WORKING_DIRECTORY "${BINARY_DIR}" ) endif () @@ -86,7 +86,7 @@ ExternalProject_Add(dep_gtest -Dgtest_force_shared_crt=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local" - BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) if (${DEP_DEBUG}) @@ -94,7 +94,7 @@ if (${DEP_DEBUG}) ExternalProject_Add_Step(dep_gtest build_debug DEPENDEES build DEPENDERS install - COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj + COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj WORKING_DIRECTORY "${BINARY_DIR}" ) endif () @@ -114,7 +114,7 @@ ExternalProject_Add(dep_nlopt -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_DEBUG_POSTFIX=d "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local" - BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) if (${DEP_DEBUG}) @@ -122,7 +122,7 @@ if (${DEP_DEBUG}) ExternalProject_Add_Step(dep_nlopt build_debug DEPENDEES build DEPENDERS install - COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj + COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj WORKING_DIRECTORY "${BINARY_DIR}" ) endif () @@ -138,7 +138,7 @@ ExternalProject_Add(dep_zlib "-DINSTALL_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}\\fallout" # I found no better way of preventing zlib from creating & installing DLLs :-/ -DCMAKE_POSITION_INDEPENDENT_CODE=ON "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local" - BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) if (${DEP_DEBUG}) @@ -146,7 +146,7 @@ if (${DEP_DEBUG}) ExternalProject_Add_Step(dep_zlib build_debug DEPENDEES build DEPENDERS install - COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj + COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj WORKING_DIRECTORY "${BINARY_DIR}" ) endif () diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md index 8b750ce0d7..e223239ba8 100644 --- a/doc/How to build - Windows.md +++ b/doc/How to build - Windows.md @@ -66,7 +66,7 @@ There are several options for building from the command line: To build with msbuild, use the same CMake command as in previous paragraph and then build using - msbuild /P:Configuration=Release ALL_BUILD.vcxproj + msbuild /m /P:Configuration=Release ALL_BUILD.vcxproj To build with Ninja or nmake, replace the `-G` option in the CMake call with `-G Ninja` or `-G "NMake Makefiles"` , respectively. Then use either `ninja` or `nmake` to start the build. @@ -84,7 +84,7 @@ Then `cd` into the `deps` directory and use these commands to build: mkdir build cd build cmake .. -G "Visual Studio 12 Win64" -DDESTDIR="C:\local\destdir-custom" - msbuild ALL_BUILD.vcxproj + msbuild /m ALL_BUILD.vcxproj You can also use the Visual Studio GUI or other generators as mentioned above. From 814471c89093c0d59ab64b910e62b3d115e77dd8 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 8 Apr 2019 10:09:35 +0200 Subject: [PATCH 49/61] doc: Fix line break issue --- doc/How to build - Windows.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md index e223239ba8..331a3533a1 100644 --- a/doc/How to build - Windows.md +++ b/doc/How to build - Windows.md @@ -97,7 +97,11 @@ place the `build` directory relatively close to the drive root. Note that the build variant that you may choose using Visual Studio (i.e. _Release_ or _Debug_ etc.) when building the dependency package is **not relevant**. The dependency build will by default build _both_ the _Release_ and _Debug_ variants regardless of what you choose in Visual Studio. -You can disable building of the debug variant by passing the `-DDEP_DEBUG=OFF` option to CMake, this will only produce a _Release_ build. +You can disable building of the debug variant by passing the + + -DDEP_DEBUG=OFF + +option to CMake, this will only produce a _Release_ build. Refer to the CMake scripts inside the `deps` directory to see which dependencies are built in what versions and how this is done. From ecbf4b51ebf4f655f99f875ca3e6aa781cd4f576 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 8 Apr 2019 10:14:05 +0200 Subject: [PATCH 50/61] Tidy up Readme a little bit --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 4c56a882a7..9d8f210d21 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,7 @@ -_Q: Oh cool, a new RepRap slicer?_ +# Slic3r Prusa Edition -A: Yes. - -Slic3r -====== Prebuilt Windows, OSX and Linux binaries are available through the [git releases page](https://github.com/prusa3d/Slic3r/releases). - - Slic3r takes 3D models (STL, OBJ, AMF) and converts them into G-code instructions for FFF printers or PNG layers for mSLA 3D printers. It's compatible with any modern printer based on the RepRap toolchain, including all From 5eca68eeebc27dc36cf6fe0b98162d5ca02fe56f Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 8 Apr 2019 10:16:50 +0200 Subject: [PATCH 51/61] Readme: Add logo link --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9d8f210d21..3939747fc9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ + +![Slic3rPE logo](/resources/icons/Slic3r.png?raw=true) + # Slic3r Prusa Edition Prebuilt Windows, OSX and Linux binaries are available through the [git releases page](https://github.com/prusa3d/Slic3r/releases). From 43fb8df1fb79467c607b3e3d0e2f0e61c4f777d0 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 8 Apr 2019 10:27:56 +0200 Subject: [PATCH 52/61] Increased the default SLA support density to 130% of the previous value (100% now works as 130% before) --- src/libslic3r/SLA/SLAAutoSupports.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/SLA/SLAAutoSupports.hpp b/src/libslic3r/SLA/SLAAutoSupports.hpp index 038b505dac..6aef7eac9e 100644 --- a/src/libslic3r/SLA/SLAAutoSupports.hpp +++ b/src/libslic3r/SLA/SLAAutoSupports.hpp @@ -19,7 +19,7 @@ public: float minimal_distance; float head_diameter; /////////////// - inline float support_force() const { return 10.f / density_relative; } // a force one point can support (arbitrary force unit) + inline float support_force() const { return 7.7f / density_relative; } // a force one point can support (arbitrary force unit) inline float tear_pressure() const { return 1.f; } // pressure that the display exerts (the force unit per mm2) }; From 86cb5bb00d2ecd471ae8f19962fe85ba5bb3c104 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Apr 2019 10:38:48 +0200 Subject: [PATCH 53/61] Fixed icon layers.svg --- resources/icons/layers.svg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/icons/layers.svg b/resources/icons/layers.svg index da5dec21d5..cd71fab3a3 100644 --- a/resources/icons/layers.svg +++ b/resources/icons/layers.svg @@ -5,13 +5,13 @@ - + - + - + @@ -20,7 +20,7 @@ - + From 618d124bfbcfaf5a7146ff276e05f923b5869076 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 8 Apr 2019 09:37:23 +0200 Subject: [PATCH 54/61] Icon updating for all application --- src/slic3r/GUI/AboutDialog.cpp | 4 +- src/slic3r/GUI/BitmapCache.cpp | 4 ++ src/slic3r/GUI/GUI_ObjectList.cpp | 36 +++++--------- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 1 - src/slic3r/GUI/GUI_ObjectSettings.cpp | 1 - src/slic3r/GUI/KBShortcutsDialog.cpp | 3 +- src/slic3r/GUI/MainFrame.cpp | 10 ++-- src/slic3r/GUI/MsgDialog.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 16 +++---- src/slic3r/GUI/Preset.cpp | 7 ++- src/slic3r/GUI/PresetBundle.cpp | 49 +++++++++++++------ src/slic3r/GUI/PresetBundle.hpp | 2 + src/slic3r/GUI/SysInfoDialog.cpp | 4 +- src/slic3r/GUI/Tab.cpp | 58 +++++++++-------------- src/slic3r/GUI/wxExtensions.cpp | 49 +++++++++++-------- src/slic3r/GUI/wxExtensions.hpp | 3 +- 16 files changed, 130 insertions(+), 119 deletions(-) diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index db2e76736e..9825f0cf90 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -42,9 +42,7 @@ AboutDialog::AboutDialog() main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20); // logo -// wxBitmap logo_bmp = wxBitmap(from_u8(Slic3r::var("Slic3r_192px.png")), wxBITMAP_TYPE_PNG); -// auto *logo = new wxStaticBitmap(this, wxID_ANY, std::move(logo_bmp)); - auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("Slic3r_192px.png")); + auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("Slic3r_192px.png", 192)); hsizer->Add(logo, 1, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index bea242470b..7ad36f09bb 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -15,6 +15,7 @@ #include "nanosvg/nanosvg.h" #define NANOSVGRAST_IMPLEMENTATION #include "nanosvg/nanosvgrast.h" +#include "GUI_App.hpp" namespace Slic3r { namespace GUI { @@ -244,6 +245,9 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int tar wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency) { + width = width * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f; + height = height * 0.1f * Slic3r::GUI::wxGetApp().em_unit() + 0.5f; + wxImage image(width, height); image.InitAlpha(); unsigned char* imgdata = image.GetData(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 8b574fc8d5..80b7c3648f 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -62,18 +62,18 @@ ObjectList::ObjectList(wxWindow* parent) : // Fill CATEGORY_ICON { // ptFFF - CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap("layers.png"); // wxBitmap(from_u8(var("layers.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Infill")] = create_scaled_bitmap("infill.png"); // wxBitmap(from_u8(var("infill.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Support material")] = create_scaled_bitmap("building.png"); // wxBitmap(from_u8(var("building.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Speed")] = create_scaled_bitmap("time.png"); // wxBitmap(from_u8(var("time.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap("funnel.png"); // wxBitmap(from_u8(var("funnel.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap("funnel.png"); // wxBitmap(from_u8(var("funnel.png")), wxBITMAP_TYPE_PNG); -// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("box.png"); // wxBitmap(from_u8(var("box.png")), wxBITMAP_TYPE_PNG); -// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap("time.png"); // wxBitmap(from_u8(var("time.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap("wand.png"); // wxBitmap(from_u8(var("wand.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap("layers"); + CATEGORY_ICON[L("Infill")] = create_scaled_bitmap("infill"); + CATEGORY_ICON[L("Support material")] = create_scaled_bitmap("support"); + CATEGORY_ICON[L("Speed")] = create_scaled_bitmap("time"); + CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap("funnel"); + CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap("funnel"); +// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap("skirt+brim"); +// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap("time"); + CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap("wrench"); // ptSLA - CATEGORY_ICON[L("Supports")] = create_scaled_bitmap("building.png"); // wxBitmap(from_u8(var("building.png")), wxBITMAP_TYPE_PNG); - CATEGORY_ICON[L("Pad")] = create_scaled_bitmap("brick.png"); // wxBitmap(from_u8(var("brick.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Supports")] = create_scaled_bitmap("sla_supports"); + CATEGORY_ICON[L("Pad")] = create_scaled_bitmap("brick.png"); } // create control @@ -386,13 +386,6 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const void ObjectList::init_icons() { -// m_bmp_modifiermesh = wxBitmap(from_u8(var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); -// m_bmp_solidmesh = wxBitmap(from_u8(var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); - -// m_bmp_support_enforcer = wxBitmap(from_u8(var("support_enforcer_.png")), wxBITMAP_TYPE_PNG); -// m_bmp_support_blocker = wxBitmap(from_u8(var("support_blocker_.png")), wxBITMAP_TYPE_PNG); - - m_bmp_modifiermesh = create_scaled_bitmap("lambda.png"); m_bmp_solidmesh = create_scaled_bitmap("object.png"); m_bmp_support_enforcer = create_scaled_bitmap("support_enforcer_.png"); @@ -407,16 +400,13 @@ void ObjectList::init_icons() m_objects_model->SetVolumeBitmaps(m_bmp_vector); // init icon for manifold warning -// m_bmp_manifold_warning = wxBitmap(from_u8(var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); m_bmp_manifold_warning = create_scaled_bitmap("exclamation_mark_.png"); // init bitmap for "Split to sub-objects" context menu -// m_bmp_split = wxBitmap(from_u8(var("split.png")), wxBITMAP_TYPE_PNG); - m_bmp_split = create_scaled_bitmap("split.png"); + m_bmp_split = create_scaled_bitmap("split_parts"); // init bitmap for "Add Settings" context menu -// m_bmp_cog = wxBitmap(from_u8(var("cog.png")), wxBITMAP_TYPE_PNG); - m_bmp_cog = create_scaled_bitmap("cog.png"); + m_bmp_cog = create_scaled_bitmap("cog"); } diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 48bb1f6903..7e7d8a1d5a 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -92,7 +92,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : else if (option_name == "Size") { line.near_label_widget = [this](wxWindow* parent) { return new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, -// wxBitmap(from_u8(var("one_layer_lock_on.png")), wxBITMAP_TYPE_PNG).GetSize()); create_scaled_bitmap("one_layer_lock_on.png").GetSize()); }; } diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index cd995bc094..b1f33eea11 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -77,7 +77,6 @@ void ObjectSettings::update_settings_list() { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line -// auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG), auto btn = new wxBitmapButton(parent, wxID_ANY, create_scaled_bitmap("colorchange_delete_on.png"), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); #ifdef __WXMSW__ diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 66e9deec86..b4d25fa5da 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -17,8 +17,7 @@ KBShortcutsDialog::KBShortcutsDialog() auto main_sizer = new wxBoxSizer(wxVERTICAL); // logo -// wxBitmap logo_bmp = wxBitmap(from_u8(Slic3r::var("Slic3r_32px.png")), wxBITMAP_TYPE_PNG); - const wxBitmap logo_bmp = create_scaled_bitmap("Slic3r_32px.png"); + const wxBitmap logo_bmp = create_scaled_bitmap("Slic3r_32px.png", 32); // fonts wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d69480b28f..0c3cf316d0 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -56,9 +56,13 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL // initialize default width_unit according to the width of the one symbol ("x") of the current system font const wxSize size = GetTextExtent("m"); -// wxGetApp().set_em_unit(size.x-1); wxGetApp().set_em_unit(std::max(10, size.x - 1)); + /* Load default preset bitmaps before a tabpanel initialization, + * but after filling of an em_unit value + */ + wxGetApp().preset_bundle->load_default_preset_bitmaps(); + // initialize tabpanel and menubar init_tabpanel(); init_menubar(); @@ -388,11 +392,11 @@ void MainFrame::init_menubar() windowMenu->AppendSeparator(); } append_menu_item(windowMenu, wxID_HIGHEST + 2, _(L("P&rint Settings Tab")) + "\tCtrl+2", _(L("Show the print settings")), - [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog.png"); + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog"); append_menu_item(windowMenu, wxID_HIGHEST + 3, _(L("&Filament Settings Tab")) + "\tCtrl+3", _(L("Show the filament settings")), [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 1); }, "spool.png"); append_menu_item(windowMenu, wxID_HIGHEST + 4, _(L("Print&er Settings Tab")) + "\tCtrl+4", _(L("Show the printer settings")), - [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer_empty.png"); + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer"); if (m_plater) { windowMenu->AppendSeparator(); wxMenuItem* item_3d = append_menu_item(windowMenu, wxID_HIGHEST + 5, _(L("3&D")) + "\tCtrl+5", _(L("Show the 3D editing view")), diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index cc2b9c8425..beb0c97cd6 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -24,7 +24,7 @@ namespace GUI { MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id) : - MsgDialog(parent, title, headline, create_scaled_bitmap("Slic3r_192px.png"), button_id) + MsgDialog(parent, title, headline, create_scaled_bitmap("Slic3r_192px.png", 192), button_id) {} MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id) : diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3e7ab3bbc3..8f75d0ec9b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -286,7 +286,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * #ifdef __WINDOWS__ edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif - edit_btn->SetBitmap(create_scaled_bitmap("cog.png")); + edit_btn->SetBitmap(create_scaled_bitmap("cog")); edit_btn->SetToolTip(_(L("Click to edit preset"))); edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) @@ -2829,15 +2829,15 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ wxMenuItem* item_delete = nullptr; if (is_part) { item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")), - [this](wxCommandEvent&) { q->remove_selected(); }, "brick_delete.png"); + [this](wxCommandEvent&) { q->remove_selected(); }, "remove"); sidebar->obj_list()->append_menu_item_export_stl(menu); } else { wxMenuItem* item_increase = append_menu_item(menu, wxID_ANY, _(L("Increase copies")) + "\t+", _(L("Place one more copy of the selected object")), - [this](wxCommandEvent&) { q->increase_instances(); }, "add.png"); + [this](wxCommandEvent&) { q->increase_instances(); }, "instance_add"); wxMenuItem* item_decrease = append_menu_item(menu, wxID_ANY, _(L("Decrease copies")) + "\t-", _(L("Remove one copy of the selected object")), - [this](wxCommandEvent&) { q->decrease_instances(); }, "delete.png"); + [this](wxCommandEvent&) { q->decrease_instances(); }, "instance_remove"); wxMenuItem* item_set_number_of_copies = append_menu_item(menu, wxID_ANY, _(L("Set number of copies")) + dots, _(L("Change the number of copies of the selected object")), [this](wxCommandEvent&) { q->set_number_of_copies(); }, "textfield.png"); @@ -2847,7 +2847,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/ // Delete menu was moved to be after +/- instace to make it more difficult to be selected by mistake. item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")), - [this](wxCommandEvent&) { q->remove_selected(); }, "brick_delete.png"); + [this](wxCommandEvent&) { q->remove_selected(); }, "remove"); menu->AppendSeparator(); wxMenuItem* item_instance_to_object = sidebar->obj_list()->append_menu_item_instance_to_object(menu); @@ -2902,11 +2902,11 @@ bool Plater::priv::complit_init_object_menu() return false; wxMenuItem* item_split_objects = append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")), - [this](wxCommandEvent&) { split_object(); }, "shape_ungroup_o.png", &object_menu); + [this](wxCommandEvent&) { split_object(); }, "split_objects.png", &object_menu); wxMenuItem* item_split_volumes = append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")), - [this](wxCommandEvent&) { split_volume(); }, "shape_ungroup_p.png", &object_menu); + [this](wxCommandEvent&) { split_volume(); }, "split_parts.png", &object_menu); - wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "shape_ungroup.png"); + wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object"))/*, "shape_ungroup.png"*/); object_menu.AppendSeparator(); // "Add (volumes)" popupmenu will be added later in append_menu_items_add_volume() diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 82223b15c0..7d1cedc96e 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -4,6 +4,7 @@ #include "AppConfig.hpp" #include "BitmapCache.hpp" #include "I18N.hpp" +#include "wxExtensions.hpp" #ifdef _MSC_VER #define WIN32_LEAN_AND_MEAN @@ -798,12 +799,14 @@ bool PresetCollection::delete_current_preset() bool PresetCollection::load_bitmap_default(const std::string &file_name) { - return m_bitmap_main_frame->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG); +// return m_bitmap_main_frame->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG); + return load_scaled_bitmap(&m_bitmap_main_frame, file_name); } bool PresetCollection::load_bitmap_add(const std::string &file_name) { - return m_bitmap_add->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG); +// return m_bitmap_add->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG); + return load_scaled_bitmap(&m_bitmap_add, file_name); } const Preset* PresetCollection::get_selected_preset_parent() const diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index f78a04126f..d8fefbf3f2 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -4,6 +4,7 @@ #include "BitmapCache.hpp" #include "Plater.hpp" #include "I18N.hpp" +#include "wxExtensions.hpp" #include #include @@ -102,13 +103,14 @@ PresetBundle::PresetBundle() : } // Load the default preset bitmaps. - this->prints .load_bitmap_default("cog.png"); - this->sla_prints .load_bitmap_default("package_green.png"); - this->filaments .load_bitmap_default("spool.png"); - this->sla_materials.load_bitmap_default("package_green.png"); - this->printers .load_bitmap_default("printer_empty.png"); - this->printers .load_bitmap_add("add.png"); - this->load_compatible_bitmaps(); + // #ys_FIXME_to_delete we'll load them later, using em_unit() +// this->prints .load_bitmap_default("cog"); +// this->sla_prints .load_bitmap_default("package_green.png"); +// this->filaments .load_bitmap_default("spool.png"); +// this->sla_materials.load_bitmap_default("package_green.png"); +// this->printers .load_bitmap_default("printer_empty.png"); +// this->printers .load_bitmap_add("add.png"); +// this->load_compatible_bitmaps(); // Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above. this->prints .select_preset(0); @@ -400,14 +402,20 @@ bool PresetBundle::load_compatible_bitmaps() const std::string path_bitmap_incompatible = "flag-red-icon.png"; const std::string path_bitmap_lock = "sys_lock.png";//"lock.png"; const std::string path_bitmap_lock_open = "sys_unlock.png";//"lock_open.png"; - bool loaded_compatible = m_bitmapCompatible ->LoadFile( - wxString::FromUTF8(Slic3r::var(path_bitmap_compatible).c_str()), wxBITMAP_TYPE_PNG); - bool loaded_incompatible = m_bitmapIncompatible->LoadFile( - wxString::FromUTF8(Slic3r::var(path_bitmap_incompatible).c_str()), wxBITMAP_TYPE_PNG); - bool loaded_lock = m_bitmapLock->LoadFile( - wxString::FromUTF8(Slic3r::var(path_bitmap_lock).c_str()), wxBITMAP_TYPE_PNG); - bool loaded_lock_open = m_bitmapLockOpen->LoadFile( - wxString::FromUTF8(Slic3r::var(path_bitmap_lock_open).c_str()), wxBITMAP_TYPE_PNG); +// bool loaded_compatible = m_bitmapCompatible ->LoadFile( +// wxString::FromUTF8(Slic3r::var(path_bitmap_compatible).c_str()), wxBITMAP_TYPE_PNG); +// bool loaded_incompatible = m_bitmapIncompatible->LoadFile( +// wxString::FromUTF8(Slic3r::var(path_bitmap_incompatible).c_str()), wxBITMAP_TYPE_PNG); +// bool loaded_lock = m_bitmapLock->LoadFile( +// wxString::FromUTF8(Slic3r::var(path_bitmap_lock).c_str()), wxBITMAP_TYPE_PNG); +// bool loaded_lock_open = m_bitmapLockOpen->LoadFile( +// wxString::FromUTF8(Slic3r::var(path_bitmap_lock_open).c_str()), wxBITMAP_TYPE_PNG); + + bool loaded_compatible = load_scaled_bitmap(&m_bitmapCompatible, path_bitmap_compatible); + bool loaded_incompatible = load_scaled_bitmap(&m_bitmapIncompatible,path_bitmap_incompatible); + bool loaded_lock = load_scaled_bitmap(&m_bitmapLock, path_bitmap_lock); + bool loaded_lock_open = load_scaled_bitmap(&m_bitmapLockOpen, path_bitmap_lock_open); + if (loaded_compatible) { prints .set_bitmap_compatible(m_bitmapCompatible); filaments .set_bitmap_compatible(m_bitmapCompatible); @@ -1438,6 +1446,17 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out return true; } +void PresetBundle::load_default_preset_bitmaps() +{ + this->prints.load_bitmap_default("cog"); + this->sla_prints.load_bitmap_default("package_green.png"); + this->filaments.load_bitmap_default("spool.png"); + this->sla_materials.load_bitmap_default("package_green.png"); + this->printers.load_bitmap_default("printer"); + this->printers.load_bitmap_add("add.png"); + this->load_compatible_bitmaps(); +} + void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, GUI::PresetComboBox *ui) { if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA || diff --git a/src/slic3r/GUI/PresetBundle.hpp b/src/slic3r/GUI/PresetBundle.hpp index 9f289f1e9b..abd936ee21 100644 --- a/src/slic3r/GUI/PresetBundle.hpp +++ b/src/slic3r/GUI/PresetBundle.hpp @@ -127,6 +127,8 @@ public: static bool parse_color(const std::string &scolor, unsigned char *rgb_out); + void load_default_preset_bitmaps(); + private: std::string load_system_presets(); // Merge one vendor's presets with the other vendor's presets, report duplicates. diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index dfaba71ae6..95bd7e61ad 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -52,9 +52,7 @@ SysInfoDialog::SysInfoDialog() main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10); // logo -// wxBitmap logo_bmp = wxBitmap(from_u8(Slic3r::var("Slic3r_192px.png")), wxBITMAP_TYPE_PNG); -// auto *logo = new wxStaticBitmap(this, wxID_ANY, std::move(logo_bmp)); - auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("Slic3r_192px.png")); + auto *logo = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("Slic3r_192px.png", 192)); hsizer->Add(logo, 0, wxALIGN_CENTER_VERTICAL); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index c2cdf8f034..5b200a194d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -116,18 +116,14 @@ void Tab::create_preset_tab() //buttons wxBitmap bmpMenu; -// bmpMenu = wxBitmap(from_u8(Slic3r::var("disk.png")), wxBITMAP_TYPE_PNG); bmpMenu = create_scaled_bitmap("disk.png"); m_btn_save_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); if (wxMSW) m_btn_save_preset->SetBackgroundColour(color); -// bmpMenu = wxBitmap(from_u8(Slic3r::var("delete.png")), wxBITMAP_TYPE_PNG); bmpMenu = create_scaled_bitmap("delete.png"); m_btn_delete_preset = new wxBitmapButton(panel, wxID_ANY, bmpMenu, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color); m_show_incompatible_presets = false; -// m_bmp_show_incompatible_presets.LoadFile(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG); -// m_bmp_hide_incompatible_presets.LoadFile(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG); m_bmp_show_incompatible_presets = create_scaled_bitmap("flag-red-icon.png"); m_bmp_hide_incompatible_presets = create_scaled_bitmap("flag-green-icon.png"); m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); @@ -152,15 +148,10 @@ void Tab::create_preset_tab() // Determine the theme color of OS (dark or light) auto luma = wxGetApp().get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field. -// m_bmp_value_lock .LoadFile(from_u8(var("sys_lock.png")), wxBITMAP_TYPE_PNG); -// m_bmp_value_unlock .LoadFile(from_u8(var(luma >= 128 ? "sys_unlock.png" : "sys_unlock_grey.png")), wxBITMAP_TYPE_PNG); m_bmp_value_lock = create_scaled_bitmap("sys_lock.png"); m_bmp_value_unlock = create_scaled_bitmap(luma >= 128 ? "sys_unlock.png" : "sys_unlock_grey.png"); m_bmp_non_system = &m_bmp_white_bullet; // Bitmaps to be shown on the "Undo user changes" button next to each input field. -// m_bmp_value_revert .LoadFile(from_u8(var(luma >= 128 ? "action_undo.png" : "action_undo_grey.png")), wxBITMAP_TYPE_PNG); -// m_bmp_white_bullet .LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG); -// m_bmp_question .LoadFile(from_u8(var("question_mark_01.png")), wxBITMAP_TYPE_PNG); m_bmp_value_revert = create_scaled_bitmap(luma >= 128 ? "action_undo.png" : "action_undo_grey.png"); m_bmp_white_bullet = create_scaled_bitmap("bullet_white.png"); m_bmp_question = create_scaled_bitmap("question_mark_01.png"); @@ -954,7 +945,7 @@ void TabPrint::build() m_presets = &m_preset_bundle->prints; load_initial_data(); - auto page = add_options_page(_(L("Layers and perimeters")), "layers.png"); + auto page = add_options_page(_(L("Layers and perimeters")), "layers"); auto optgroup = page->new_optgroup(_(L("Layer height"))); optgroup->append_single_option_line("layer_height"); optgroup->append_single_option_line("first_layer_height"); @@ -987,7 +978,7 @@ void TabPrint::build() optgroup->append_single_option_line("seam_position"); optgroup->append_single_option_line("external_perimeters_first"); - page = add_options_page(_(L("Infill")), "infill.png"); + page = add_options_page(_(L("Infill")), "infill"); optgroup = page->new_optgroup(_(L("Infill"))); optgroup->append_single_option_line("fill_density"); optgroup->append_single_option_line("fill_pattern"); @@ -1006,7 +997,7 @@ void TabPrint::build() optgroup->append_single_option_line("only_retract_when_crossing_perimeters"); optgroup->append_single_option_line("infill_first"); - page = add_options_page(_(L("Skirt and brim")), "box.png"); + page = add_options_page(_(L("Skirt and brim")), "skirt+brim"); optgroup = page->new_optgroup(_(L("Skirt"))); optgroup->append_single_option_line("skirts"); optgroup->append_single_option_line("skirt_distance"); @@ -1016,7 +1007,7 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Brim"))); optgroup->append_single_option_line("brim_width"); - page = add_options_page(_(L("Support material")), "building.png"); + page = add_options_page(_(L("Support material")), "support"); optgroup = page->new_optgroup(_(L("Support material"))); optgroup->append_single_option_line("support_material"); optgroup->append_single_option_line("support_material_auto"); @@ -1041,7 +1032,7 @@ void TabPrint::build() optgroup->append_single_option_line("dont_support_bridges"); optgroup->append_single_option_line("support_material_synchronize_layers"); - page = add_options_page(_(L("Speed")), "time.png"); + page = add_options_page(_(L("Speed")), "time"); optgroup = page->new_optgroup(_(L("Speed for print moves"))); optgroup->append_single_option_line("perimeter_speed"); optgroup->append_single_option_line("small_perimeter_speed"); @@ -1075,7 +1066,7 @@ void TabPrint::build() optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative"); #endif /* HAS_PRESSURE_EQUALIZER */ - page = add_options_page(_(L("Multiple Extruders")), "funnel.png"); + page = add_options_page(_(L("Multiple Extruders")), "funnel"); optgroup = page->new_optgroup(_(L("Extruders"))); optgroup->append_single_option_line("perimeter_extruder"); optgroup->append_single_option_line("infill_extruder"); @@ -1125,7 +1116,7 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Other"))); optgroup->append_single_option_line("clip_multipart_objects"); - page = add_options_page(_(L("Output options")), "page_white_go.png"); + page = add_options_page(_(L("Output options")), "output+page_white"); optgroup = page->new_optgroup(_(L("Sequential printing"))); optgroup->append_single_option_line("complete_objects"); line = { _(L("Extruder clearance (mm)")), "" }; @@ -1520,7 +1511,7 @@ void TabFilament::build() const int gcode_field_height = 15 * m_em_unit; // 150 const int notes_field_height = 25 * m_em_unit; // 250 - page = add_options_page(_(L("Custom G-code")), "cog.png"); + page = add_options_page(_(L("Custom G-code")), "cog"); optgroup = page->new_optgroup(_(L("Start G-code")), 0); Option option = optgroup->get_option("start_filament_gcode"); option.opt.full_width = true; @@ -1696,7 +1687,6 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); -// btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG)); btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetBitmap(create_scaled_bitmap("zoom.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1769,15 +1759,14 @@ void TabPrinter::build_fff() m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); - auto page = add_options_page(_(L("General")), "printer_empty.png"); + auto page = add_options_page(_(L("General")), "printer"); auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(wxGetApp().small_font()); -// btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); - btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); + btn->SetBitmap(create_scaled_bitmap("printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1906,7 +1895,7 @@ void TabPrinter::build_fff() const int gcode_field_height = 15 * m_em_unit; // 150 const int notes_field_height = 25 * m_em_unit; // 250 - page = add_options_page(_(L("Custom G-code")), "cog.png"); + page = add_options_page(_(L("Custom G-code")), "cog"); optgroup = page->new_optgroup(_(L("Start G-code")), 0); option = optgroup->get_option("start_gcode"); option.opt.full_width = true; @@ -1971,15 +1960,14 @@ void TabPrinter::build_sla() { if (!m_pages.empty()) m_pages.resize(0); - auto page = add_options_page(_(L("General")), "printer_empty.png"); + auto page = add_options_page(_(L("General")), "printer"); auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); btn->SetFont(wxGetApp().small_font()); -// btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); - btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); + btn->SetBitmap(create_scaled_bitmap("printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -2081,7 +2069,7 @@ void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::s PageShp TabPrinter::build_kinematics_page() { - auto page = add_options_page(_(L("Machine limits")), "cog.png", true); + auto page = add_options_page(_(L("Machine limits")), "cog", true); if (m_use_silent_mode) { // Legend for OptionsGroups @@ -2173,7 +2161,7 @@ void TabPrinter::build_extruder_pages() } if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page) { // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves - auto page = add_options_page(_(L("Single extruder MM setup")), "printer_empty.png", true); + auto page = add_options_page(_(L("Single extruder MM setup")), "printer", true); auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); optgroup->append_single_option_line("cooling_tube_retraction"); optgroup->append_single_option_line("cooling_tube_length"); @@ -2189,7 +2177,7 @@ void TabPrinter::build_extruder_pages() //# build page char buf[512]; sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); - auto page = add_options_page(from_u8(buf), "funnel.png", true); + auto page = add_options_page(from_u8(buf), "funnel", true); m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); auto optgroup = page->new_optgroup(_(L("Size"))); @@ -2921,8 +2909,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); -// deps.btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); - deps.btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); + deps.btn->SetBitmap(create_scaled_bitmap("printer")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add((deps.checkbox), 0, wxALIGN_CENTER_VERTICAL); @@ -3113,7 +3100,6 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la bmp_name = mode == comExpert ? "mode_expert_.png" : mode == comAdvanced ? "mode_middle_.png" : "mode_simple_.png"; } -// auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG)); auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(bmp_name)); bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); return bmp; @@ -3312,13 +3298,13 @@ void TabSLAPrint::build() m_presets = &m_preset_bundle->sla_prints; load_initial_data(); - auto page = add_options_page(_(L("Layers and perimeters")), "package_green.png"); + auto page = add_options_page(_(L("Layers and perimeters")), "layers"); auto optgroup = page->new_optgroup(_(L("Layers"))); optgroup->append_single_option_line("layer_height"); optgroup->append_single_option_line("faded_layers"); - page = add_options_page(_(L("Supports")), "building.png"); + page = add_options_page(_(L("Supports")), "sla_supports"); optgroup = page->new_optgroup(_(L("Supports"))); optgroup->append_single_option_line("supports_enable"); @@ -3356,17 +3342,17 @@ void TabSLAPrint::build() // optgroup->append_single_option_line("pad_edge_radius"); optgroup->append_single_option_line("pad_wall_slope"); - page = add_options_page(_(L("Advanced")), "wrench.png"); + page = add_options_page(_(L("Advanced")), "wrench"); optgroup = page->new_optgroup(_(L("Slicing"))); optgroup->append_single_option_line("slice_closing_radius"); - page = add_options_page(_(L("Output options")), "page_white_go.png"); + page = add_options_page(_(L("Output options")), "output+page_white"); optgroup = page->new_optgroup(_(L("Output file"))); Option option = optgroup->get_option("output_filename_format"); option.opt.full_width = true; optgroup->append_single_option_line(option); - page = add_options_page(_(L("Dependencies")), "wrench.png"); + page = add_options_page(_(L("Dependencies")), "wrench"); optgroup = page->new_optgroup(_(L("Profile dependencies"))); Line line = optgroup->create_single_option_line("compatible_printers");//Line { _(L("Compatible printers")), "" }; line.widget = [this](wxWindow* parent) { diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 932db9cc2c..a27b84058d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -418,33 +418,42 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) } #endif //__WXMSW__ + +// If an icon has horizontal orientation (width > height) call this function with is_horizontal = true +bool load_scaled_bitmap(wxBitmap** bmp, const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /*= false*/) +{ + static Slic3r::GUI::BitmapCache cache; + + unsigned int height, width = height = 0; + unsigned int& scale_base = is_horizontal ? width : height; + scale_base = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * px_cnt * 0.1f + 0.5f); + + std::string bmp_name = bmp_name_in; + boost::replace_last(bmp_name, ".png", ""); + *bmp = cache.load_svg(bmp_name, width, height); + if (*bmp == nullptr) + *bmp = cache.load_png(bmp_name, width, height); + return *bmp != nullptr; +} + +// If an icon has horizontal orientation (width > height) call this function with is_horizontal = true +wxBitmap create_scaled_bitmap(const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /* = false*/) +{ + wxBitmap *bmp {nullptr}; + load_scaled_bitmap(&bmp, bmp_name_in, px_cnt, is_horizontal); + return *bmp; +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // PrusaObjectDataViewModelNode // ---------------------------------------------------------------------------- -// If an icon has horizontal orientation (width > height) call this function with is_horizontal = true -wxBitmap create_scaled_bitmap(const std::string& bmp_name_in, const bool is_horizontal /* = false*/) -{ - static Slic3r::GUI::BitmapCache cache; - - unsigned int height, width = height = 0; - unsigned int& scale_base = is_horizontal ? width : height; - scale_base = (unsigned int)(Slic3r::GUI::wxGetApp().em_unit() * 1.6f + 0.5f); - - std::string bmp_name = bmp_name_in; - boost::replace_last(bmp_name, ".png", ""); - wxBitmap *bmp = cache.load_svg(bmp_name, width, height); - if (bmp == nullptr) - bmp = cache.load_png(bmp_name, width, height); - return *bmp; -} - void PrusaObjectDataViewModelNode::set_object_action_icon() { m_action_icon = create_scaled_bitmap("add_object.png"); } void PrusaObjectDataViewModelNode::set_part_action_icon() { - m_action_icon = create_scaled_bitmap(m_type == itVolume ? "cog.png" : "brick_go.png"); + m_action_icon = create_scaled_bitmap(m_type == itVolume ? "cog" : "brick_go.png"); } Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; @@ -1486,8 +1495,8 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX - m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("right_half_circle.png") : create_scaled_bitmap("up_half_circle.png", true)); - m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("left_half_circle.png" ) : create_scaled_bitmap("down_half_circle.png", true)); + m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("right_half_circle.png") : create_scaled_bitmap("up_half_circle.png", 16, true)); + m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? create_scaled_bitmap("left_half_circle.png" ) : create_scaled_bitmap("down_half_circle.png",16, true)); m_thumb_size = m_bmp_thumb_lower.GetSize(); m_bmp_add_tick_on = create_scaled_bitmap("colorchange_add_on.png"); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 912475ceda..1a50a8adb7 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -31,7 +31,8 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler); -wxBitmap create_scaled_bitmap(const std::string& bmp_name, const bool is_horizontal = false); +bool load_scaled_bitmap(wxBitmap** bmp, const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); +wxBitmap create_scaled_bitmap(const std::string& bmp_name, const int px_cnt=16, const bool is_horizontal = false); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { From af05e5fc2ca33b5a5ac054356a83987977f4fbde Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 8 Apr 2019 11:06:15 +0200 Subject: [PATCH 55/61] Fixed crash under oSX after selection with SHIFT from 3DScene --- src/slic3r/GUI/GUI_ObjectList.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 80b7c3648f..37d30bbe2b 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -88,6 +88,10 @@ ObjectList::ObjectList(wxWindow* parent) : // before the kill focus event handler on the object manipulator when changing selection in the list, invalidating the object // manipulator cache with the following call to selection_changed() wxGetApp().obj_manipul()->emulate_kill_focus(); + + // To avoid selection update from SetSelection() and UnselectAll() under osx + if (m_prevent_list_events) + return; #endif // __APPLE__ /* For multiple selection with pressed SHIFT, From 7e32f2df711e524cac803aacaee5040509205bb8 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 2 Apr 2019 12:00:50 +0200 Subject: [PATCH 56/61] Implement per-screen DPI on Windows, DPI change event, wxDialog & wxFrame mixin base classes --- src/slic3r/GUI/GUI_App.cpp | 20 +++++++++++ src/slic3r/GUI/GUI_Utils.cpp | 63 ++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GUI_Utils.hpp | 65 ++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/MainFrame.cpp | 7 +++- src/slic3r/GUI/MainFrame.hpp | 6 +++- 5 files changed, 159 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index f1a7d92632..8c34337dcb 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -76,6 +76,24 @@ wxString file_wildcards(FileType file_type, const std::string &custom_extension) static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); } +static void register_dpi_event() +{ +#ifdef WIN32 + enum { WM_DPICHANGED_ = 0x02e0 }; + + wxWindow::MSWRegisterMessageHandler(WM_DPICHANGED_, [](wxWindow *win, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { + const int dpi = wParam & 0xffff; + const auto rect = reinterpret_cast(lParam); + const wxRect wxrect(wxPoint(rect->top, rect->left), wxPoint(rect->bottom, rect->right)); + + DpiChangedEvent evt(EVT_DPI_CHANGED, dpi, wxrect); + win->GetEventHandler()->AddPendingEvent(evt); + + return true; + }); +#endif +} + IMPLEMENT_APP(GUI_App) GUI_App::GUI_App() @@ -149,6 +167,8 @@ bool GUI_App::OnInit() show_error(nullptr, ex.what()); } + register_dpi_event(); + // Let the libslic3r know the callback, which will translate messages on demand. Slic3r::I18N::set_translate_callback(libslic3r_translate_callback); diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index 56d6eaeb58..6dc5c5b4c7 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -4,9 +4,14 @@ #include #include +#ifdef _WIN32 +#include +#endif + #include #include #include +#include #include "libslic3r/Config.hpp" @@ -48,6 +53,64 @@ void on_window_geometry(wxTopLevelWindow *tlw, std::function callback) #endif } +wxDEFINE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent); + +#ifdef _WIN32 +template typename F::FN winapi_get_function(const wchar_t *dll, const char *fn_name) { + static HINSTANCE dll_handle = LoadLibraryExW(dll, nullptr, 0); + + if (dll_handle == nullptr) { return nullptr; } + return (F::FN)GetProcAddress(dll_handle, fn_name); +} +#endif + +int get_dpi_for_window(wxWindow *window) +{ +#ifdef _WIN32 + enum MONITOR_DPI_TYPE_ { + // This enum is inlined here to avoid build-time dependency + MDT_EFFECTIVE_DPI_ = 0, + MDT_ANGULAR_DPI_ = 1, + MDT_RAW_DPI_ = 2, + MDT_DEFAULT_ = MDT_EFFECTIVE_DPI_, + }; + + // Need strong types for winapi_get_function() to work + struct GetDpiForWindow_t { typedef HRESULT (WINAPI *FN)(HWND hwnd); }; + struct GetDpiForMonitor_t { typedef HRESULT (WINAPI *FN)(HMONITOR hmonitor, MONITOR_DPI_TYPE_ dpiType, UINT *dpiX, UINT *dpiY); }; + + static auto GetDpiForWindow_fn = winapi_get_function(L"User32.dll", "GetDpiForWindow"); + static auto GetDpiForMonitor_fn = winapi_get_function(L"Shcore.dll", "GetDpiForMonitor"); + + const HWND hwnd = window->GetHandle(); + + if (GetDpiForWindow_fn != nullptr) { + // We're on Windows 10, we have per-screen DPI settings + return GetDpiForWindow_fn(hwnd); + } else if (GetDpiForMonitor_fn != nullptr) { + // We're on Windows 8.1, we have per-system DPI + // Note: MonitorFromWindow() is available on all Windows. + + const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + UINT dpiX; + UINT dpiY; + return GetDpiForMonitor_fn(monitor, MDT_EFFECTIVE_DPI_, &dpiX, &dpiY) == S_OK ? dpiX : DPI_DEFAULT; + } else { + // We're on Windows earlier than 8.1, use DC + + const HDC hdc = GetDC(hwnd); + if (hdc == NULL) { return DPI_DEFAULT; } + return GetDeviceCaps(hdc, LOGPIXELSX); + } +#elif defined __linux__ + // TODO + return DPI_DEFAULT; +#elif defined __APPLE__ + // TODO + return DPI_DEFAULT; +#endif +} + CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index 8d942dcf84..e121536259 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -8,10 +8,13 @@ #include +#include +#include #include #include #include #include +#include #include class wxCheckBox; @@ -27,6 +30,68 @@ wxTopLevelWindow* find_toplevel_parent(wxWindow *window); void on_window_geometry(wxTopLevelWindow *tlw, std::function callback); +enum { DPI_DEFAULT = 96 }; + +int get_dpi_for_window(wxWindow *window); + +struct DpiChangedEvent : public wxEvent { + int dpi; + wxRect rect; + + DpiChangedEvent(wxEventType eventType, int dpi, wxRect rect) + : wxEvent(0, eventType), dpi(dpi), rect(rect) + {} + + virtual wxEvent *Clone() const + { + return new DpiChangedEvent(*this); + } +}; + +wxDECLARE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent); + +template class DPIAware : public P +{ +public: + DPIAware(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, + const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE, const wxString &name=wxFrameNameStr) + : P(parent, id, title, pos, size, style, name) + { + m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT; + recalc_font(); + + this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) { + m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT; + on_dpi_changed(evt.rect); + }); + } + + virtual ~DPIAware() {} + + float scale_factor() const { return m_scale_factor; } + int em_unit() const { return m_em_unit; } + int font_size() const { return m_font_size; } + +protected: + virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; + +private: + int m_scale_factor; + int m_em_unit; + int m_font_size; + + void recalc_font() + { + wxClientDC dc(this); + const auto metrics = dc.GetFontMetrics(); + m_font_size = metrics.height; + m_em_unit = metrics.averageWidth; + } +}; + +typedef DPIAware DPIFrame; +typedef DPIAware DPIDialog; + class EventGuard { diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 0c3cf316d0..059d04f856 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -32,7 +32,7 @@ namespace Slic3r { namespace GUI { MainFrame::MainFrame() : -wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "mainframe"), +DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "mainframe"), m_printhost_queue_dlg(new PrintHostQueueDialog(this)) { // Load the icon either from the exe, or from the ico file. @@ -256,6 +256,11 @@ bool MainFrame::can_delete_all() const return (m_plater != nullptr) ? !m_plater->model().objects.empty() : false; } +void MainFrame::on_dpi_changed(const wxRect &suggested_rect) +{ + // TODO +} + void MainFrame::init_menubar() { #ifdef __APPLE__ diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index b44c73f91f..625e70b83b 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -9,6 +9,7 @@ #include #include +#include "GUI_Utils.hpp" #include "Plater.hpp" #include "Event.hpp" @@ -40,7 +41,7 @@ struct PresetTab { PrinterTechnology technology; }; -class MainFrame : public wxFrame +class MainFrame : public DPIFrame { bool m_loaded {false}; @@ -68,6 +69,9 @@ class MainFrame : public wxFrame bool can_delete() const; bool can_delete_all() const; +protected: + virtual void on_dpi_changed(const wxRect &suggested_rect); + public: MainFrame(); ~MainFrame() {} From ea3d30bff126ad096d98ed009cc011df08d2241b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Apr 2019 11:54:58 +0200 Subject: [PATCH 57/61] Fix of #2082 -> Added lines M73 P100 and M73 Q100 to gcode to signal that print is finished --- src/libslic3r/GCode.cpp | 9 +++++++++ src/libslic3r/GCodeTimeEstimator.cpp | 10 ++++++++++ src/libslic3r/GCodeTimeEstimator.hpp | 2 ++ 3 files changed, 21 insertions(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index d9f907f034..dc017f737f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1034,6 +1034,15 @@ void GCode::_do_export(Print &print, FILE *file) } _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% _write(file, m_writer.postamble()); + + // adds tags for time estimators + if (print.config().remaining_times.value) + { + _writeln(file, GCodeTimeEstimator::Normal_Last_M73_Output_Placeholder_Tag); + if (m_silent_time_estimator_enabled) + _writeln(file, GCodeTimeEstimator::Silent_Last_M73_Output_Placeholder_Tag); + } + print.throw_if_canceled(); // calculates estimated printing time diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 461b4cd356..4b4e9f587e 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -171,6 +171,8 @@ namespace Slic3r { const std::string GCodeTimeEstimator::Normal_First_M73_Output_Placeholder_Tag = "; NORMAL_FIRST_M73_OUTPUT_PLACEHOLDER"; const std::string GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag = "; SILENT_FIRST_M73_OUTPUT_PLACEHOLDER"; + const std::string GCodeTimeEstimator::Normal_Last_M73_Output_Placeholder_Tag = "; NORMAL_LAST_M73_OUTPUT_PLACEHOLDER"; + const std::string GCodeTimeEstimator::Silent_Last_M73_Output_Placeholder_Tag = "; SILENT_LAST_M73_OUTPUT_PLACEHOLDER"; GCodeTimeEstimator::GCodeTimeEstimator(EMode mode) : _mode(mode) @@ -306,9 +308,17 @@ namespace Slic3r { sprintf(time_line, time_mask.c_str(), "0", _get_time_minutes(_time).c_str()); gcode_line = time_line; } + // replaces placeholders for final line M73 with the real lines + else if (((_mode == Normal) && (gcode_line == Normal_Last_M73_Output_Placeholder_Tag)) || + ((_mode == Silent) && (gcode_line == Silent_Last_M73_Output_Placeholder_Tag))) + { + sprintf(time_line, time_mask.c_str(), "100", "0"); + gcode_line = time_line; + } else gcode_line += "\n"; + // add remaining time lines where needed _parser.parse_line(gcode_line, [this, &it_line_id, &g1_lines_count, &last_recorded_time, &time_line, &gcode_line, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line) diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index ef91d5ff1d..1fbc1c14bf 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -19,6 +19,8 @@ namespace Slic3r { public: static const std::string Normal_First_M73_Output_Placeholder_Tag; static const std::string Silent_First_M73_Output_Placeholder_Tag; + static const std::string Normal_Last_M73_Output_Placeholder_Tag; + static const std::string Silent_Last_M73_Output_Placeholder_Tag; enum EMode : unsigned char { From 837bc43c9f6ed6bfc30fb72e330adcbb5b974155 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 8 Apr 2019 11:54:56 +0200 Subject: [PATCH 58/61] SLA gizmo on_set_state code is now called through CallAfter to prevent repeated wxMessageDialog appearances (seen on OSX) --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 61 +++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index cb52bccde4..63bff63056 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -726,40 +726,45 @@ std::string GLGizmoSlaSupports::on_get_name() const void GLGizmoSlaSupports::on_set_state() { - if (m_state == On && m_old_state != On) { // the gizmo was just turned on + // Following is called through CallAfter, because otherwise there was a problem + // on OSX with the wxMessageDialog being shown several times when clicked into. - if (is_mesh_update_necessary()) - update_mesh(); + wxGetApp().CallAfter([this]() { + if (m_state == On && m_old_state != On) { // the gizmo was just turned on - // we'll now reload support points: - if (m_model_object) - editing_mode_reload_cache(); + if (is_mesh_update_necessary()) + update_mesh(); - m_parent.toggle_model_objects_visibility(false); - if (m_model_object) - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + // we'll now reload support points: + if (m_model_object) + editing_mode_reload_cache(); - // Set default head diameter from config. - const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; - m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; - } - if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off - if (m_model_object) { - if (m_unsaved_changes) { - wxMessageDialog dlg(GUI::wxGetApp().plater(), _(L("Do you want to save your manually edited support points ?\n")), - _(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO); - if (dlg.ShowModal() == wxID_YES) - editing_mode_apply_changes(); - else - editing_mode_discard_changes(); - } + m_parent.toggle_model_objects_visibility(false); + if (m_model_object) + m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + + // Set default head diameter from config. + const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; + m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; } + if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off + if (m_model_object) { + if (m_unsaved_changes) { + wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually edited support points ?\n")), + _(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO); + if (dlg.ShowModal() == wxID_YES) + editing_mode_apply_changes(); + else + editing_mode_discard_changes(); + } + } - m_parent.toggle_model_objects_visibility(true); - m_editing_mode = false; // so it is not active next time the gizmo opens - m_editing_mode_cache.clear(); - } - m_old_state = m_state; + m_parent.toggle_model_objects_visibility(true); + m_editing_mode = false; // so it is not active next time the gizmo opens + m_editing_mode_cache.clear(); + } + m_old_state = m_state; + }); } From e0340f4f81faf15252d92366efd9f7e86770f1ce Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 8 Apr 2019 12:28:42 +0200 Subject: [PATCH 59/61] Set "cog" ison for sla_print preset --- src/slic3r/GUI/PresetBundle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index d8fefbf3f2..19f9040bf4 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1449,7 +1449,7 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out void PresetBundle::load_default_preset_bitmaps() { this->prints.load_bitmap_default("cog"); - this->sla_prints.load_bitmap_default("package_green.png"); + this->sla_prints.load_bitmap_default("cog"); this->filaments.load_bitmap_default("spool.png"); this->sla_materials.load_bitmap_default("package_green.png"); this->printers.load_bitmap_default("printer"); From ffc5a43c331e745579cf7ad5feb81eda399959d0 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 8 Apr 2019 13:05:12 +0200 Subject: [PATCH 60/61] More fixes in the Readme --- README.md | 309 ++---------------------------------------------------- 1 file changed, 6 insertions(+), 303 deletions(-) diff --git a/README.md b/README.md index 3939747fc9..53c8315617 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,8 @@ All user facing code is written in C++, and some legacy code as well as unit tests are written in Perl. Perl is not required for either development or use of Slic3r. -The C++ API is public and its use in other projects is encouraged. -The goal is to make Slic3r fully modular so that any part of its logic -can be used separately. +The slicing core is the `libslic3r` library, which can be built and used in a standalone way. +The command line interface is a thin wrapper over `libslic3r`. ### What are Slic3r's main features? @@ -67,309 +66,13 @@ Sure! You can do the following to find things that are available to help with: ### What's Slic3r license? -Slic3r is licensed under the _GNU Affero General Public License, version 3_. -The author is Alessandro Ranellucci. +Slic3r PE is licensed under the _GNU Affero General Public License, version 3_. +The Prusa Edition is originally based on Slic3r by Alessandro Ranellucci. The [Silk icon set](http://www.famfamfam.com/lab/icons/silk/) used in Slic3r is licensed under the _Creative Commons Attribution 3.0 License_. The author of the Silk icon set is Mark James. -### How can I invoke slic3r.pl using the command line? +### How can I use Slic3r PE from the command line? - Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ... - - --help Output this usage screen and exit - --version Output the version of Slic3r and exit - --save Save configuration to the specified file - --load Load configuration from the specified file. It can be used - more than once to load options from multiple files. - -o, --output File to output gcode to (by default, the file will be saved - into the same directory as the input file using the - --output-filename-format to generate the filename.) If a - directory is specified for this option, the output will - be saved under that directory, and the filename will be - generated by --output-filename-format. - - Non-slicing actions (no G-code will be generated): - --repair Repair given STL files and save them as _fixed.obj - --cut Cut given input files at given Z (relative) and export - them as _upper.stl and _lower.stl - --split Split the shells contained in given STL file into several STL files - --info Output information about the supplied file(s) and exit - - -j, --threads Number of threads to use (1+, default: 2) - - GUI options: - --gui Forces the GUI launch instead of command line slicing (if you - supply a model file, it will be loaded into the plater) - --no-plater Disable the plater tab - --no-gui Forces the command line slicing instead of gui. - This takes precedence over --gui if both are present. - --autosave Automatically export current configuration to the specified file - - Output options: - --output-filename-format - Output file name format; all config options enclosed in brackets - will be replaced by their values, as well as [input_filename_base] - and [input_filename] (default: [input_filename_base].gcode) - --post-process Generated G-code will be processed with the supplied script; - call this more than once to process through multiple scripts. - --export-png Export zipped PNG files containing slices instead of G-code. - -m, --merge If multiple files are supplied, they will be composed into a single - print rather than processed individually. - - Printer options: - --nozzle-diameter Diameter of nozzle in mm (default: 0.5) - --print-center Coordinates in mm of the point to center the print around - (default: 100,100) - --z-offset Additional height in mm to add to vertical coordinates - (+/-, default: 0) - --gcode-flavor The type of G-code to generate (reprap/teacup/repetier/makerware/sailfish/mach3/machinekit/smoothie/no-extrusion, - default: reprap) - --use-relative-e-distances Enable this to get relative E values (default: no) - --use-firmware-retraction Enable firmware-controlled retraction using G10/G11 (default: no) - --use-volumetric-e Express E in cubic millimeters and prepend M200 (default: no) - --gcode-comments Make G-code verbose by adding comments (default: no) - - Filament options: - --filament-diameter Diameter in mm of your raw filament (default: 3) - --extrusion-multiplier - Change this to alter the amount of plastic extruded. There should be - very little need to change this value, which is only useful to - compensate for filament packing (default: 1) - --temperature Extrusion temperature in degree Celsius, set 0 to disable (default: 200) - --first-layer-temperature Extrusion temperature for the first layer, in degree Celsius, - set 0 to disable (default: same as --temperature) - --bed-temperature Heated bed temperature in degree Celsius, set 0 to disable (default: 0) - --first-layer-bed-temperature Heated bed temperature for the first layer, in degree Celsius, - set 0 to disable (default: same as --bed-temperature) - - Speed options: - --travel-speed Speed of non-print moves in mm/s (default: 130) - --perimeter-speed Speed of print moves for perimeters in mm/s (default: 30) - --small-perimeter-speed - Speed of print moves for small perimeters in mm/s or % over perimeter speed - (default: 30) - --external-perimeter-speed - Speed of print moves for the external perimeter in mm/s or % over perimeter speed - (default: 70%) - --infill-speed Speed of print moves in mm/s (default: 60) - --solid-infill-speed Speed of print moves for solid surfaces in mm/s or % over infill speed - (default: 60) - --top-solid-infill-speed Speed of print moves for top surfaces in mm/s or % over solid infill speed - (default: 50) - --support-material-speed - Speed of support material print moves in mm/s (default: 60) - --support-material-interface-speed - Speed of support material interface print moves in mm/s or % over support material - speed (default: 100%) - --bridge-speed Speed of bridge print moves in mm/s (default: 60) - --gap-fill-speed Speed of gap fill print moves in mm/s (default: 20) - --first-layer-speed Speed of print moves for bottom layer, expressed either as an absolute - value or as a percentage over normal speeds (default: 30%) - - Acceleration options: - --perimeter-acceleration - Overrides firmware's default acceleration for perimeters. (mm/s^2, set zero - to disable; default: 0) - --infill-acceleration - Overrides firmware's default acceleration for infill. (mm/s^2, set zero - to disable; default: 0) - --bridge-acceleration - Overrides firmware's default acceleration for bridges. (mm/s^2, set zero - to disable; default: 0) - --first-layer-acceleration - Overrides firmware's default acceleration for first layer. (mm/s^2, set zero - to disable; default: 0) - --default-acceleration - Acceleration will be reset to this value after the specific settings above - have been applied. (mm/s^2, set zero to disable; default: 0) - - Accuracy options: - --layer-height Layer height in mm (default: 0.3) - --first-layer-height Layer height for first layer (mm or %, default: 0.35) - --infill-every-layers - Infill every N layers (default: 1) - --solid-infill-every-layers - Force a solid layer every N layers (default: 0) - - Print options: - --perimeters Number of perimeters/horizontal skins (range: 0+, default: 3) - --top-solid-layers Number of solid layers to do for top surfaces (range: 0+, default: 3) - --bottom-solid-layers Number of solid layers to do for bottom surfaces (range: 0+, default: 3) - --solid-layers Shortcut for setting the two options above at once - --fill-density Infill density (range: 0%-100%, default: 40%) - --fill-angle Infill angle in degrees (range: 0-90, default: 45) - --fill-pattern Pattern to use to fill non-solid layers (default: honeycomb) - --solid-fill-pattern Pattern to use to fill solid layers (default: rectilinear) - --start-gcode Load initial G-code from the supplied file. This will overwrite - the default command (home all axes [G28]). - --end-gcode Load final G-code from the supplied file. This will overwrite - the default commands (turn off temperature [M104 S0], - home X axis [G28 X], disable motors [M84]). - --before-layer-gcode Load before-layer-change G-code from the supplied file (default: nothing). - --layer-gcode Load after-layer-change G-code from the supplied file (default: nothing). - --toolchange-gcode Load tool-change G-code from the supplied file (default: nothing). - --seam-position Position of loop starting points (random/nearest/aligned, default: aligned). - --external-perimeters-first Reverse perimeter order. (default: no) - --spiral-vase Experimental option to raise Z gradually when printing single-walled vases - (default: no) - --only-retract-when-crossing-perimeters - Disable retraction when travelling between infill paths inside the same island. - (default: no) - --solid-infill-below-area - Force solid infill when a region has a smaller area than this threshold - (mm^2, default: 70) - --infill-only-where-needed - Only infill under ceilings (default: no) - --infill-first Make infill before perimeters (default: no) - - Quality options (slower slicing): - --extra-perimeters Add more perimeters when needed (default: yes) - --avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (default: no) - --thin-walls Detect single-width walls (default: yes) - --overhangs Experimental option to use bridge flow, speed and fan for overhangs - (default: yes) - - Support material options: - --support-material Generate support material for overhangs - --support-material-threshold - Overhang threshold angle (range: 0-90, set 0 for automatic detection, - default: 0) - --support-material-pattern - Pattern to use for support material (default: honeycomb) - --support-material-spacing - Spacing between pattern lines (mm, default: 2.5) - --support-material-angle - Support material angle in degrees (range: 0-90, default: 0) - --support-material-contact-distance - Vertical distance between object and support material - (0+, default: 0.2) - --support-material-interface-layers - Number of perpendicular layers between support material and object (0+, default: 3) - --support-material-interface-spacing - Spacing between interface pattern lines (mm, set 0 to get a solid layer, default: 0) - --raft-layers Number of layers to raise the printed objects by (range: 0+, default: 0) - --support-material-enforce-layers - Enforce support material on the specified number of layers from bottom, - regardless of --support-material and threshold (0+, default: 0) - --dont-support-bridges - Experimental option for preventing support material from being generated under bridged areas (default: yes) - - Retraction options: - --retract-length Length of retraction in mm when pausing extrusion (default: 1) - --retract-speed Speed for retraction in mm/s (default: 30) - --retract-restart-extra - Additional amount of filament in mm to push after - compensating retraction (default: 0) - --retract-before-travel - Only retract before travel moves of this length in mm (default: 2) - --retract-lift Lift Z by the given distance in mm when retracting (default: 0) - --retract-lift-above Only lift Z when above the specified height (default: 0) - --retract-lift-below Only lift Z when below the specified height (default: 0) - --retract-layer-change - Enforce a retraction before each Z move (default: no) - --wipe Wipe the nozzle while doing a retraction (default: no) - - Retraction options for multi-extruder setups: - --retract-length-toolchange - Length of retraction in mm when disabling tool (default: 10) - --retract-restart-extra-toolchange - Additional amount of filament in mm to push after - switching tool (default: 0) - - Cooling options: - --cooling Enable fan and cooling control - --min-fan-speed Minimum fan speed (default: 35%) - --max-fan-speed Maximum fan speed (default: 100%) - --bridge-fan-speed Fan speed to use when bridging (default: 100%) - --fan-below-layer-time Enable fan if layer print time is below this approximate number - of seconds (default: 60) - --slowdown-below-layer-time Slow down if layer print time is below this approximate number - of seconds (default: 30) - --min-print-speed Minimum print speed (mm/s, default: 10) - --disable-fan-first-layers Disable fan for the first N layers (default: 1) - --fan-always-on Keep fan always on at min fan speed, even for layers that don't need - cooling - - Skirt options: - --skirts Number of skirts to draw (0+, default: 1) - --skirt-distance Distance in mm between innermost skirt and object - (default: 6) - --skirt-height Height of skirts to draw (expressed in layers, 0+, default: 1) - --min-skirt-length Generate no less than the number of loops required to consume this length - of filament on the first layer, for each extruder (mm, 0+, default: 0) - --brim-width Width of the brim that will get added to each object to help adhesion - (mm, default: 0) - - Transform options: - --scale Factor for scaling input object (default: 1) - --rotate Rotation angle in degrees (0-360, default: 0) - --duplicate Number of items with auto-arrange (1+, default: 1) - --duplicate-grid Number of items with grid arrangement (default: 1,1) - --duplicate-distance Distance in mm between copies (default: 6) - --dont-arrange Don't arrange the objects on the build plate. The model coordinates - define the absolute positions on the build plate. - The option --print-center will be ignored. - --xy-size-compensation - Grow/shrink objects by the configured absolute distance (mm, default: 0) - - Sequential printing options: - --complete-objects When printing multiple objects and/or copies, complete each one before - starting the next one; watch out for extruder collisions (default: no) - --extruder-clearance-radius Radius in mm above which extruder won't collide with anything - (default: 20) - --extruder-clearance-height Maximum vertical extruder depth; i.e. vertical distance from - extruder tip and carriage bottom (default: 20) - - Miscellaneous options: - --notes Notes to be added as comments to the output file - --resolution Minimum detail resolution (mm, set zero for full resolution, default: 0) - - Flow options (advanced): - --extrusion-width Set extrusion width manually; it accepts either an absolute value in mm - (like 0.65) or a percentage over layer height (like 200%) - --first-layer-extrusion-width - Set a different extrusion width for first layer - --perimeter-extrusion-width - Set a different extrusion width for perimeters - --external-perimeter-extrusion-width - Set a different extrusion width for external perimeters - --infill-extrusion-width - Set a different extrusion width for infill - --solid-infill-extrusion-width - Set a different extrusion width for solid infill - --top-infill-extrusion-width - Set a different extrusion width for top infill - --support-material-extrusion-width - Set a different extrusion width for support material - --infill-overlap Overlap between infill and perimeters (default: 15%) - --bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: 1) - - Multiple extruder options: - --extruder-offset Offset of each extruder, if firmware doesn't handle the displacement - (can be specified multiple times, default: 0x0) - --perimeter-extruder - Extruder to use for perimeters and brim (1+, default: 1) - --infill-extruder Extruder to use for infill (1+, default: 1) - --solid-infill-extruder Extruder to use for solid infill (1+, default: 1) - --support-material-extruder - Extruder to use for support material, raft and skirt (1+, default: 1) - --support-material-interface-extruder - Extruder to use for support material interface (1+, default: 1) - --ooze-prevention Drop temperature and park extruders outside a full skirt for automatic wiping - (default: no) - --ooze-prevention Drop temperature and park extruders outside a full skirt for automatic wiping - (default: no) - --standby-temperature-delta - Temperature difference to be applied when an extruder is not active and - --ooze-prevention is enabled (default: -5) - - -If you want to change a preset file, just do - - slic3r.pl --load config.ini --layer-height 0.25 --save config.ini - -If you want to slice a file overriding an option contained in your preset file: - - slic3r.pl --load config.ini --layer-height 0.25 file.stl +Please refer to the [Command Line Interface](https://github.com/prusa3d/Slic3r/wiki/Command-Line-Interface) wiki page. From ca6a5af1dc2412f7c8a5b0edff7cc18b8b7e37c4 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 8 Apr 2019 13:35:03 +0200 Subject: [PATCH 61/61] Fixed rotation of SLA instances in case a rotation in X or Y was applied to the instances. --- src/libslic3r/Geometry.cpp | 24 ++++++++++++++++++++++++ src/libslic3r/Geometry.hpp | 7 +++++++ src/libslic3r/SLAPrint.cpp | 20 +++++++++++++------- src/slic3r/GUI/Selection.cpp | 30 +++--------------------------- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 8f3423a3db..a16b754a4c 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1455,4 +1455,28 @@ Transformation Transformation::operator * (const Transformation& other) const return Transformation(get_matrix() * other.get_matrix()); } +Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) +{ + return + // From the current coordinate system to world. + Eigen::AngleAxisd(rot_xyz_to(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to(0), Vec3d::UnitX()) * + // From world to the initial coordinate system. + Eigen::AngleAxisd(-rot_xyz_from(0), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from(1), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from(2), Vec3d::UnitZ()); +} + +// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis. +double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) +{ + Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); + Vec3d axis = angle_axis.axis(); + double angle = angle_axis.angle(); +#ifndef NDEBUG + if (std::abs(angle) > 1e-8) { + assert(std::abs(axis.x()) < 1e-8); + assert(std::abs(axis.y()) < 1e-8); + } +#endif /* NDEBUG */ + return (axis.z() < 0) ? -angle : angle; +} + } } diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index d556f664c8..25b849d8ce 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -262,6 +262,13 @@ public: Transformation operator * (const Transformation& other) const; }; +// Rotation when going from the first coordinate system with rotation rot_xyz_from applied +// to a coordinate system with rot_xyz_to applied. +extern Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to); +// Rotation by Z to align rot_xyz_from to rot_xyz_to. +// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis. +extern double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to); + } } #endif diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 694bc64447..5e590e7e2d 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -3,6 +3,7 @@ #include "SLA/SLABasePool.hpp" #include "SLA/SLAAutoSupports.hpp" #include "ClipperUtils.hpp" +#include "Geometry.hpp" #include "MTUtils.hpp" #include @@ -103,13 +104,18 @@ static Transform3d sla_trafo(const ModelObject &model_object) static std::vector sla_instances(const ModelObject &model_object) { std::vector instances; - for (ModelInstance *model_instance : model_object.instances) - if (model_instance->is_printable()) { - instances.emplace_back( - model_instance->id(), - Point::new_scale(model_instance->get_offset(X), model_instance->get_offset(Y)), - float(model_instance->get_rotation(Z))); - } + assert(! model_object.instances.empty()); + if (! model_object.instances.empty()) { + Vec3d rotation0 = model_object.instances.front()->get_rotation(); + rotation0(2) = 0.; + for (ModelInstance *model_instance : model_object.instances) + if (model_instance->is_printable()) { + instances.emplace_back( + model_instance->id(), + Point::new_scale(model_instance->get_offset(X), model_instance->get_offset(Y)), + float(Geometry::rotation_diff_z(rotation0, model_instance->get_rotation()))); + } + } return instances; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 00ff2dd061..6f148ca24a 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -482,30 +482,6 @@ void Selection::translate(const Vec3d& displacement, bool local) m_bounding_box_dirty = true; } -static Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) -{ - return - // From the current coordinate system to world. - Eigen::AngleAxisd(rot_xyz_to(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to(0), Vec3d::UnitX()) * - // From world to the initial coordinate system. - Eigen::AngleAxisd(-rot_xyz_from(0), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from(1), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from(2), Vec3d::UnitZ()); -} - -// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis. -static double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) -{ - Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); - Vec3d axis = angle_axis.axis(); - double angle = angle_axis.angle(); -#ifndef NDEBUG - if (std::abs(angle) > 1e-8) { - assert(std::abs(axis.x()) < 1e-8); - assert(std::abs(axis.y()) < 1e-8); - } -#endif /* NDEBUG */ - return (axis.z() < 0) ? -angle : angle; -} - // Rotate an object around one of the axes. Only one rotation component is expected to be changing. void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) { @@ -548,7 +524,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ assert(is_approx(rotation.z(), 0.0)); const GLVolume &first_volume = *(*m_volumes)[first_volume_idx]; const Vec3d &rotation = first_volume.get_instance_rotation(); - double z_diff = rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation()); + double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation()); volume.set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff)); } else { @@ -1538,7 +1514,7 @@ void Selection::render_sidebar_size_hint(Axis axis, double length) const #ifndef NDEBUG static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) { - Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); + Eigen::AngleAxisd angle_axis(Geometry::rotation_xyz_diff(rot_xyz_from, rot_xyz_to)); Vec3d axis = angle_axis.axis(); double angle = angle_axis.angle(); if (std::abs(angle) < 1e-8) @@ -1618,7 +1594,7 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_ break; case SYNC_ROTATION_GENERAL: // generic rotation -> update instance z with the delta of the rotation. - double z_diff = rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()); + double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()); v->set_instance_rotation(Vec3d(rotation(0), rotation(1), rotation(2) + z_diff)); break; }