diff --git a/resources/icons/add.svg b/resources/icons/add.svg new file mode 100644 index 000000000..8a9b253de --- /dev/null +++ b/resources/icons/add.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/resources/icons/arrange.svg b/resources/icons/arrange.svg new file mode 100644 index 000000000..4f30e979e --- /dev/null +++ b/resources/icons/arrange.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/cut.svg b/resources/icons/cut.svg new file mode 100644 index 000000000..c5c952742 --- /dev/null +++ b/resources/icons/cut.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/resources/icons/delete_all.svg b/resources/icons/delete_all.svg new file mode 100644 index 000000000..80e2e503c --- /dev/null +++ b/resources/icons/delete_all.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/editor.svg b/resources/icons/editor.svg new file mode 100644 index 000000000..5866ce055 --- /dev/null +++ b/resources/icons/editor.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/resources/icons/gizmos.png b/resources/icons/gizmos.png new file mode 100644 index 000000000..448e826b8 Binary files /dev/null and b/resources/icons/gizmos.png differ diff --git a/resources/icons/instance_add.svg b/resources/icons/instance_add.svg new file mode 100644 index 000000000..5ef492cfa --- /dev/null +++ b/resources/icons/instance_add.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/resources/icons/instance_remove.svg b/resources/icons/instance_remove.svg new file mode 100644 index 000000000..466752ea8 --- /dev/null +++ b/resources/icons/instance_remove.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + diff --git a/resources/icons/layers.svg b/resources/icons/layers.svg new file mode 100644 index 000000000..7718a8cbd --- /dev/null +++ b/resources/icons/layers.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/move.svg b/resources/icons/move.svg new file mode 100644 index 000000000..019ea8ca7 --- /dev/null +++ b/resources/icons/move.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/place.svg b/resources/icons/place.svg new file mode 100644 index 000000000..6acc2451e --- /dev/null +++ b/resources/icons/place.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/preview.svg b/resources/icons/preview.svg new file mode 100644 index 000000000..658bba2c6 --- /dev/null +++ b/resources/icons/preview.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/remove.svg b/resources/icons/remove.svg new file mode 100644 index 000000000..acd21256c --- /dev/null +++ b/resources/icons/remove.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/resources/icons/rotate.svg b/resources/icons/rotate.svg new file mode 100644 index 000000000..508c4f39d --- /dev/null +++ b/resources/icons/rotate.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + diff --git a/resources/icons/scale.svg b/resources/icons/scale.svg new file mode 100644 index 000000000..ee9cef95a --- /dev/null +++ b/resources/icons/scale.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/sla_supports.svg b/resources/icons/sla_supports.svg new file mode 100644 index 000000000..119fb6afc --- /dev/null +++ b/resources/icons/sla_supports.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/split_objects.svg b/resources/icons/split_objects.svg new file mode 100644 index 000000000..a7ccc5df8 --- /dev/null +++ b/resources/icons/split_objects.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/resources/icons/split_parts.svg b/resources/icons/split_parts.svg new file mode 100644 index 000000000..82a292770 --- /dev/null +++ b/resources/icons/split_parts.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 755ca5ffa..e978b5838 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -42,15 +42,6 @@ #define ENABLE_VOLUMES_CENTERING_FIXES (1 && ENABLE_1_42_0_ALPHA4) -//==================== -// 1.42.0.alpha5 techs -//==================== -#define ENABLE_1_42_0_ALPHA5 1 - -// Toolbar items hidden/shown in dependence of the user mode -#define ENABLE_MODE_AWARE_TOOLBAR_ITEMS (1 && ENABLE_1_42_0_ALPHA5) - - //==================== // 1.42.0.alpha7 techs //==================== @@ -59,4 +50,13 @@ // Printbed textures generated from svg files #define ENABLE_TEXTURES_FROM_SVG (1 && ENABLE_1_42_0_ALPHA7) + +//==================== +// 1.42.0.alpha8 techs +//==================== +#define ENABLE_1_42_0_ALPHA8 1 + +// Toolbars and Gizmos use icons imported from svg files +#define ENABLE_SVG_ICONS (1 && ENABLE_1_42_0_ALPHA8 && ENABLE_TEXTURES_FROM_SVG) + #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2ad9ec851..aacc6f0e3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2416,85 +2416,49 @@ void GLCanvas3D::Selection::_ensure_on_bed() } } +#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(); + reset(); } bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) { - GLGizmoBase* gizmo = new GLGizmoMove3D(parent); - if (gizmo == nullptr) - return false; +#if !ENABLE_SVG_ICONS + m_icons_texture.metadata.filename = "gizmos.png"; + m_icons_texture.metadata.icon_size = 64; - if (!gizmo->init()) - return false; - - m_gizmos.insert(GizmosMap::value_type(Move, gizmo)); - - gizmo = new GLGizmoScale3D(parent); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) - return false; - - m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); - - gizmo = new GLGizmoRotate3D(parent); - if (gizmo == nullptr) + if (!m_icons_texture.metadata.filename.empty()) { - _reset(); - return false; + if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false)) + { + reset(); + return false; + } } - - if (!gizmo->init()) - { - _reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); - - gizmo = new GLGizmoFlatten(parent); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - _reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo)); - - gizmo = new GLGizmoCut(parent); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - _reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(Cut, gizmo)); - - gizmo = new GLGizmoSlaSupports(parent); - if (gizmo == nullptr) - return false; - - if (!gizmo->init()) { - _reset(); - return false; - } - - m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo)); +#endif // !ENABLE_SVG_ICONS m_background_texture.metadata.filename = "toolbar_background.png"; m_background_texture.metadata.left = 16; @@ -2506,11 +2470,101 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent) { if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false)) { - _reset(); + 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; } @@ -2524,11 +2578,30 @@ 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 GLCanvas3D::Selection& selection) @@ -2539,23 +2612,39 @@ std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, con return name; float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = _get_total_overlay_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; - float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale; - - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size); +#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); - top_y += (icon_size + m_overlay_gap_y); +#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; @@ -2567,17 +2656,29 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec return; float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = _get_total_overlay_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; - float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale; - - bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size); +#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)) @@ -2594,7 +2695,11 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec else it->second->set_state(GLGizmoBase::Off); - top_y += (icon_size + m_overlay_gap_y); +#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); @@ -2665,19 +2770,36 @@ bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const return false; float cnv_h = (float)canvas.get_canvas_size().get_height(); - float height = _get_total_overlay_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; - float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale; - - if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size)) +#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; - top_y += (icon_size + m_overlay_gap_y); +#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; @@ -2688,7 +2810,7 @@ bool GLCanvas3D::Gizmos::grabber_contains_mouse() const if (!m_enabled) return false; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); return (curr != nullptr) ? (curr->get_hover_id() != -1) : false; } @@ -2697,7 +2819,7 @@ void GLCanvas3D::Gizmos::update(const Linef3& mouse_ray, const Selection& select if (!m_enabled) return; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); if (curr != nullptr) curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection); } @@ -2712,7 +2834,7 @@ bool GLCanvas3D::Gizmos::is_running() const if (!m_enabled) return false; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; } @@ -2762,7 +2884,7 @@ bool GLCanvas3D::Gizmos::is_dragging() const if (!m_enabled) return false; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); return (curr != nullptr) ? curr->is_dragging() : false; } @@ -2771,7 +2893,7 @@ void GLCanvas3D::Gizmos::start_dragging(const GLCanvas3D::Selection& selection) if (!m_enabled) return; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); if (curr != nullptr) curr->start_dragging(selection); } @@ -2781,7 +2903,7 @@ void GLCanvas3D::Gizmos::stop_dragging() if (!m_enabled) return; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); if (curr != nullptr) curr->stop_dragging(); } @@ -2881,7 +3003,7 @@ void GLCanvas3D::Gizmos::render_current_gizmo(const GLCanvas3D::Selection& selec if (!m_enabled) return; - _render_current_gizmo(selection); + do_render_current_gizmo(selection); } void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const GLCanvas3D::Selection& selection) const @@ -2889,7 +3011,7 @@ void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const GLCanvas3D: if (!m_enabled) return; - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); if (curr != nullptr) curr->render_for_picking(selection); } @@ -2899,12 +3021,17 @@ void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas, const GLCanvas 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(); - _render_overlay(canvas, selection); + do_render_overlay(canvas, selection); ::glPopMatrix(); } @@ -2918,7 +3045,7 @@ void GLCanvas3D::Gizmos::create_external_gizmo_widgets(wxWindow *parent) } #endif // not ENABLE_IMGUI -void GLCanvas3D::Gizmos::_reset() +void GLCanvas3D::Gizmos::reset() { for (GizmosMap::value_type& gizmo : m_gizmos) { @@ -2929,7 +3056,7 @@ void GLCanvas3D::Gizmos::_reset() m_gizmos.clear(); } -void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanvas3D::Selection& selection) const +void GLCanvas3D::Gizmos::do_render_overlay(const GLCanvas3D& canvas, const GLCanvas3D::Selection& selection) const { if (m_gizmos.empty()) return; @@ -2941,15 +3068,19 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva float zoom = canvas.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - float height = _get_total_overlay_height(); + float height = get_total_overlay_height(); +#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 + _get_total_overlay_width() * inv_zoom; + float right = left + get_total_overlay_width() * inv_zoom; float bottom = top - height * inv_zoom; // renders background @@ -3018,68 +3149,159 @@ void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanva } } +#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; - float icon_size = (float)it->second->get_textures_size() * m_overlay_icons_scale * inv_zoom; - GLTexture::render_texture(it->second->get_texture_id(), top_x, top_x + icon_size, top_y - icon_size, top_y); + 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 top = sprite_id * v_icon_size; + float left = state * u_icon_size; + float bottom = top + v_icon_size; + float right = left + u_icon_size; +#else + float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size; + float top = sprite_id * uv_icon_size; + float left = state * uv_icon_size; + float bottom = top + uv_icon_size; + float right = 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, { { left, bottom }, { right, bottom }, { right, top }, { left, top } }); #if ENABLE_IMGUI 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(2.0f * scaled_border + scaled_icons_size * zoom, 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 } #endif // ENABLE_IMGUI - top_y -= (icon_size + scaled_gap_y); +#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::_render_current_gizmo(const GLCanvas3D::Selection& selection) const +void GLCanvas3D::Gizmos::do_render_current_gizmo(const GLCanvas3D::Selection& selection) const { - GLGizmoBase* curr = _get_current(); + GLGizmoBase* curr = get_current(); if (curr != nullptr) curr->render(selection); } -float GLCanvas3D::Gizmos::_get_total_overlay_height() const +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; - height += (float)it->second->get_textures_size() * m_overlay_icons_scale + m_overlay_gap_y; +#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 +float GLCanvas3D::Gizmos::get_total_overlay_width() const { - float max_icon_width = 0.0f; - for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) - { - if ((it->second == nullptr) || !it->second->is_selectable()) - continue; - - max_icon_width = std::max(max_icon_width, (float)it->second->get_textures_size() * m_overlay_icons_scale); - } - - return max_icon_width + 2.0f * m_overlay_border; +#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 +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] = { 9, 91, 134 }; const unsigned char GLCanvas3D::WarningTexture::Opacity = 255; @@ -3188,7 +3410,7 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanva ::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, 1); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); ::glBindTexture(GL_TEXTURE_2D, 0); return true; @@ -3441,7 +3663,7 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c ::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, 1); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); ::glBindTexture(GL_TEXTURE_2D, 0); return true; @@ -3509,7 +3731,11 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) #endif , m_in_render(false) , m_bed(nullptr) +#if ENABLE_SVG_ICONS + , m_toolbar(GLToolbar::Normal, "Top") +#else , m_toolbar(GLToolbar::Normal) +#endif // ENABLE_SVG_ICONS , m_view_toolbar(nullptr) , m_use_clipping_planes(false) , m_sidebar_field("") @@ -3922,7 +4148,6 @@ void GLCanvas3D::update_volumes_colors_by_extruder() m_volumes.update_colors_by_extruder(m_config); } -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS void GLCanvas3D::update_toolbar_items_visibility() { ConfigOptionMode mode = wxGetApp().get_mode(); @@ -3931,7 +4156,6 @@ void GLCanvas3D::update_toolbar_items_visibility() m_toolbar.set_item_visible("splitvolumes", mode != comSimple); m_dirty = true; } -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS // Returns a Rect object denoting size and position of the Reset button used by a gizmo. // Returns in either screen or viewport coords. @@ -4045,7 +4269,9 @@ void GLCanvas3D::render() _render_gizmos_overlay(); _render_warning_texture(); _render_legend_texture(); +#if !ENABLE_SVG_ICONS _resize_toolbars(); +#endif // !ENABLE_SVG_ICONS _render_toolbar(); _render_view_toolbar(); if (m_layers_editing.last_object_id >= 0) @@ -5713,16 +5939,11 @@ bool GLCanvas3D::_init_toolbar() if (!m_toolbar.is_enabled()) return true; +#if !ENABLE_SVG_ICONS ItemsIconsTexture::Metadata icons_data; icons_data.filename = "toolbar.png"; - icons_data.icon_size = 36; - icons_data.icon_border_size = 1; - icons_data.icon_gap_size = 1; - -// icons_data.filename = "toolbar141.png"; -// icons_data.icon_size = 52; -// icons_data.icon_border_size = 0; -// icons_data.icon_gap_size = 0; + icons_data.icon_size = 37; +#endif // !ENABLE_SVG_ICONS BackgroundTexture::Metadata background_data; background_data.filename = "toolbar_background.png"; @@ -5731,7 +5952,11 @@ bool GLCanvas3D::_init_toolbar() background_data.right = 16; background_data.bottom = 16; +#if ENABLE_SVG_ICONS + if (!m_toolbar.init(background_data)) +#else if (!m_toolbar.init(icons_data, background_data)) +#endif // ENABLE_SVG_ICONS { // unable to init the toolbar texture, disable it m_toolbar.set_enabled(false); @@ -5748,6 +5973,9 @@ bool GLCanvas3D::_init_toolbar() GLToolbarItem::Data item; item.name = "add"; +#if ENABLE_SVG_ICONS + item.icon_filename = "add.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Add...") + " [" + GUI::shortkey_ctrl_prefix() + "I]"; item.sprite_id = 0; item.action_event = EVT_GLTOOLBAR_ADD; @@ -5755,6 +5983,9 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "delete"; +#if ENABLE_SVG_ICONS + item.icon_filename = "remove.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Delete") + " [Del]"; item.sprite_id = 1; item.action_event = EVT_GLTOOLBAR_DELETE; @@ -5762,6 +5993,9 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "deleteall"; +#if ENABLE_SVG_ICONS + item.icon_filename = "delete_all.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Delete all") + " [" + GUI::shortkey_ctrl_prefix() + "Del]"; item.sprite_id = 2; item.action_event = EVT_GLTOOLBAR_DELETE_ALL; @@ -5769,6 +6003,9 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "arrange"; +#if ENABLE_SVG_ICONS + item.icon_filename = "arrange.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Arrange [A]"); item.sprite_id = 3; item.action_event = EVT_GLTOOLBAR_ARRANGE; @@ -5779,6 +6016,9 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "more"; +#if ENABLE_SVG_ICONS + item.icon_filename = "instance_add.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Add instance [+]"); item.sprite_id = 4; item.action_event = EVT_GLTOOLBAR_MORE; @@ -5786,6 +6026,9 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "fewer"; +#if ENABLE_SVG_ICONS + item.icon_filename = "instance_remove.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Remove instance [-]"); item.sprite_id = 5; item.action_event = EVT_GLTOOLBAR_FEWER; @@ -5796,6 +6039,9 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "splitobjects"; +#if ENABLE_SVG_ICONS + item.icon_filename = "split_objects.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Split to objects"); item.sprite_id = 6; item.action_event = EVT_GLTOOLBAR_SPLIT_OBJECTS; @@ -5803,8 +6049,11 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "splitvolumes"; +#if ENABLE_SVG_ICONS + item.icon_filename = "split_parts.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Split to parts"); - item.sprite_id = 8; + item.sprite_id = 7; item.action_event = EVT_GLTOOLBAR_SPLIT_VOLUMES; if (!m_toolbar.add_item(item)) return false; @@ -5813,8 +6062,11 @@ bool GLCanvas3D::_init_toolbar() return false; item.name = "layersediting"; +#if ENABLE_SVG_ICONS + item.icon_filename = "layers.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Layers editing"); - item.sprite_id = 7; + item.sprite_id = 8; item.is_toggable = true; item.action_event = EVT_GLTOOLBAR_LAYERSEDITING; if (!m_toolbar.add_item(item)) @@ -5822,9 +6074,7 @@ bool GLCanvas3D::_init_toolbar() enable_toolbar_item("add", true); -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS update_toolbar_items_visibility(); -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS return true; } @@ -6304,11 +6554,63 @@ void GLCanvas3D::_render_gizmos_overlay() const void GLCanvas3D::_render_toolbar() const { +#if ENABLE_SVG_ICONS +#if ENABLE_RETINA_GL + m_toolbar.set_scale(m_retina_helper->get_scale_factor()); +#else + m_toolbar.set_scale(m_canvas->GetContentScaleFactor()); +#endif // ENABLE_RETINA_GL + + Size cnv_size = get_canvas_size(); + float zoom = get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation(); + + float top = 0.0f; + float left = 0.0f; + switch (m_toolbar.get_layout_type()) + { + default: + case GLToolbar::Layout::Horizontal: + { + // centers the toolbar on the top edge of the 3d scene + if (orientation == GLToolbar::Layout::Top) + { + top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + left = -0.5f * m_toolbar.get_width() * inv_zoom; + } + else + { + top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom; + left = -0.5f * m_toolbar.get_width() * inv_zoom; + } + break; + } + case GLToolbar::Layout::Vertical: + { + // centers the toolbar on the right edge of the 3d scene + if (orientation == GLToolbar::Layout::Left) + { + top = 0.5f * m_toolbar.get_height() * inv_zoom; + left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; + } + else + { + top = 0.5f * m_toolbar.get_height() * inv_zoom; + left = (0.5f * (float)cnv_size.get_width() - m_toolbar.get_width()) * inv_zoom; + } + break; + } + } + m_toolbar.set_position(top, left); +#else #if ENABLE_RETINA_GL m_toolbar.set_icons_scale(m_retina_helper->get_scale_factor()); #else m_toolbar.set_icons_scale(m_canvas->GetContentScaleFactor()); #endif /* __WXMSW__ */ +#endif // ENABLE_SVG_ICONS m_toolbar.render(*this); } @@ -6316,11 +6618,28 @@ void GLCanvas3D::_render_toolbar() const void GLCanvas3D::_render_view_toolbar() const { if (m_view_toolbar != nullptr) { +#if ENABLE_SVG_ICONS +#if ENABLE_RETINA_GL + m_view_toolbar->set_scale(m_retina_helper->get_scale_factor()); +#else + m_view_toolbar->set_scale(m_canvas->GetContentScaleFactor()); +#endif // ENABLE_RETINA_GL + + Size cnv_size = get_canvas_size(); + float zoom = get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + // places the toolbar on the bottom-left corner of the 3d scene + float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom; + float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; + m_view_toolbar->set_position(top, left); +#else #if ENABLE_RETINA_GL m_view_toolbar->set_icons_scale(m_retina_helper->get_scale_factor()); #else m_view_toolbar->set_icons_scale(m_canvas->GetContentScaleFactor()); #endif /* __WXMSW__ */ +#endif // ENABLE_SVG_ICONS m_view_toolbar->render(*this); } } @@ -7809,6 +8128,7 @@ bool GLCanvas3D::_is_any_volume_outside() const return false; } +#if !ENABLE_SVG_ICONS void GLCanvas3D::_resize_toolbars() const { Size cnv_size = get_canvas_size(); @@ -7876,6 +8196,7 @@ void GLCanvas3D::_resize_toolbars() const m_view_toolbar->set_position(top, left); } } +#endif // !ENABLE_SVG_ICONS const Print* GLCanvas3D::fff_print() const { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 06fda3e5c..d47b7c976 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -688,6 +688,10 @@ private: class Gizmos { public: +#if ENABLE_SVG_ICONS + static const float Default_Icons_Size; +#endif // ENABLE_SVG_ICONS + enum EType : unsigned char { Undefined, @@ -704,10 +708,21 @@ 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; @@ -720,6 +735,9 @@ private: 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); @@ -769,15 +787,19 @@ private: #endif // not ENABLE_IMGUI private: - void _reset(); + void reset(); - void _render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; - void _render_current_gizmo(const Selection& selection) const; + 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; + float get_total_overlay_height() const; + float get_total_overlay_width() const; - GLGizmoBase* _get_current() const; + GLGizmoBase* get_current() const; + +#if ENABLE_SVG_ICONS + bool generate_icons_texture() const; +#endif // ENABLE_SVG_ICONS }; struct SlaCap @@ -984,9 +1006,7 @@ public: void update_volumes_colors_by_extruder(); -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS void update_toolbar_items_visibility(); -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS #if !ENABLE_IMGUI Rect get_gizmo_reset_rect(const GLCanvas3D& canvas, bool viewport) const; @@ -1148,7 +1168,9 @@ private: bool _is_any_volume_outside() const; +#if !ENABLE_SVG_ICONS void _resize_toolbars() const; +#endif // !ENABLE_SVG_ICONS static std::vector _parse_colors(const std::vector& colors); diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index b2686e1f3..d4b2bf526 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -159,11 +159,19 @@ void GLGizmoBase::Grabber::render_face(float half_size) const ::glEnd(); } -GLGizmoBase::GLGizmoBase(GLCanvas3D& parent) +#if ENABLE_SVG_ICONS +GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) +#else +GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, unsigned int sprite_id) +#endif // ENABLE_SVG_ICONS : m_parent(parent) , m_group_id(-1) , m_state(Off) , m_shortcut_key(0) +#if ENABLE_SVG_ICONS + , m_icon_filename(icon_filename) +#endif // ENABLE_SVG_ICONS + , m_sprite_id(sprite_id) , m_hover_id(-1) , m_dragging(false) #if ENABLE_IMGUI @@ -306,7 +314,11 @@ const unsigned int GLGizmoRotate::SnapRegionsCount = 8; const float GLGizmoRotate::GrabberOffset = 0.15f; // in percent of radius GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) - : GLGizmoBase(parent) +#if ENABLE_SVG_ICONS + : GLGizmoBase(parent, "", -1) +#else + : GLGizmoBase(parent, -1) +#endif // ENABLE_SVG_ICONS , m_axis(axis) , m_angle(0.0) , m_quadric(nullptr) @@ -323,7 +335,11 @@ GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis) } GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other) - : GLGizmoBase(other.m_parent) +#if ENABLE_SVG_ICONS + : GLGizmoBase(other.m_parent, other.m_icon_filename, other.m_sprite_id) +#else + : GLGizmoBase(other.m_parent, other.m_sprite_id) +#endif // ENABLE_SVG_ICONS , m_axis(other.m_axis) , m_angle(other.m_angle) , m_quadric(nullptr) @@ -695,8 +711,13 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, cons return transform(mouse_ray, m).intersect_plane(0.0); } -GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent) - : GLGizmoBase(parent) +#if ENABLE_SVG_ICONS +GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +#else +GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, unsigned int sprite_id) + : GLGizmoBase(parent, sprite_id) +#endif // ENABLE_SVG_ICONS { m_gizmos.emplace_back(parent, GLGizmoRotate::X); m_gizmos.emplace_back(parent, GLGizmoRotate::Y); @@ -721,17 +742,6 @@ bool GLGizmoRotate3D::on_init() m_gizmos[i].set_highlight_color(AXES_COLOR[i]); } - std::string path = resources_dir() + "/icons/overlay/"; - - if (!m_textures[Off].load_from_file(path + "rotate_off.png", false)) - return false; - - if (!m_textures[Hover].load_from_file(path + "rotate_hover.png", false)) - return false; - - if (!m_textures[On].load_from_file(path + "rotate_on.png", false)) - return false; - m_shortcut_key = WXK_CONTROL_R; return true; @@ -786,8 +796,13 @@ void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limi const float GLGizmoScale3D::Offset = 5.0f; -GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent) - : GLGizmoBase(parent) +#if ENABLE_SVG_ICONS +GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +#else +GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, unsigned int sprite_id) + : GLGizmoBase(parent, sprite_id) +#endif // ENABLE_SVG_ICONS , m_scale(Vec3d::Ones()) , m_snap_step(0.05) , m_starting_scale(Vec3d::Ones()) @@ -796,17 +811,6 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent) bool GLGizmoScale3D::on_init() { - std::string path = resources_dir() + "/icons/overlay/"; - - if (!m_textures[Off].load_from_file(path + "scale_off.png", false)) - return false; - - if (!m_textures[Hover].load_from_file(path + "scale_hover.png", false)) - return false; - - if (!m_textures[On].load_from_file(path + "scale_on.png", false)) - return false; - for (int i = 0; i < 10; ++i) { m_grabbers.push_back(Grabber()); @@ -1143,8 +1147,13 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const const double GLGizmoMove3D::Offset = 10.0; -GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent) - : GLGizmoBase(parent) +#if ENABLE_SVG_ICONS +GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +#else +GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, unsigned int sprite_id) + : GLGizmoBase(parent, sprite_id) +#endif // ENABLE_SVG_ICONS , m_displacement(Vec3d::Zero()) , m_snap_step(1.0) , m_starting_drag_position(Vec3d::Zero()) @@ -1165,17 +1174,6 @@ GLGizmoMove3D::~GLGizmoMove3D() bool GLGizmoMove3D::on_init() { - std::string path = resources_dir() + "/icons/overlay/"; - - if (!m_textures[Off].load_from_file(path + "move_off.png", false)) - return false; - - if (!m_textures[Hover].load_from_file(path + "move_hover.png", false)) - return false; - - if (!m_textures[On].load_from_file(path + "move_on.png", false)) - return false; - for (int i = 0; i < 3; ++i) { m_grabbers.push_back(Grabber()); @@ -1391,8 +1389,13 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box ::glDisable(GL_LIGHTING); } -GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent) - : GLGizmoBase(parent) +#if ENABLE_SVG_ICONS +GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +#else +GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent, unsigned int sprite_id) + : GLGizmoBase(parent, sprite_id) +#endif // ENABLE_SVG_ICONS , m_normal(Vec3d::Zero()) , m_starting_center(Vec3d::Zero()) { @@ -1400,19 +1403,7 @@ GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent) bool GLGizmoFlatten::on_init() { - std::string path = resources_dir() + "/icons/overlay/"; - - if (!m_textures[Off].load_from_file(path + "layflat_off.png", false)) - return false; - - if (!m_textures[Hover].load_from_file(path + "layflat_hover.png", false)) - return false; - - if (!m_textures[On].load_from_file(path + "layflat_on.png", false)) - return false; - m_shortcut_key = WXK_CONTROL_F; - return true; } @@ -1742,8 +1733,14 @@ Vec3d GLGizmoFlatten::get_flattening_normal() const return out; } -GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent) - : GLGizmoBase(parent), m_starting_center(Vec3d::Zero()), m_quadric(nullptr) +#if ENABLE_SVG_ICONS +GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +#else +GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, unsigned int sprite_id) + : GLGizmoBase(parent, sprite_id) +#endif // ENABLE_SVG_ICONS + , m_starting_center(Vec3d::Zero()), m_quadric(nullptr) { m_quadric = ::gluNewQuadric(); if (m_quadric != nullptr) @@ -1760,19 +1757,7 @@ GLGizmoSlaSupports::~GLGizmoSlaSupports() bool GLGizmoSlaSupports::on_init() { - std::string path = resources_dir() + "/icons/overlay/"; - - if (!m_textures[Off].load_from_file(path + "sla_support_points_off.png", false)) - return false; - - if (!m_textures[Hover].load_from_file(path + "sla_support_points_hover.png", false)) - return false; - - if (!m_textures[On].load_from_file(path + "sla_support_points_on.png", false)) - return false; - m_shortcut_key = WXK_CONTROL_L; - return true; } @@ -2651,8 +2636,13 @@ const double GLGizmoCut::Offset = 10.0; const double GLGizmoCut::Margin = 20.0; const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 }; -GLGizmoCut::GLGizmoCut(GLCanvas3D& parent) - : GLGizmoBase(parent) +#if ENABLE_SVG_ICONS +GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +#else +GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, unsigned int sprite_id) + : GLGizmoBase(parent, sprite_id) +#endif // ENABLE_SVG_ICONS , m_cut_z(0.0) , m_max_z(0.0) #if !ENABLE_IMGUI @@ -2685,26 +2675,8 @@ void GLGizmoCut::create_external_gizmo_widgets(wxWindow *parent) bool GLGizmoCut::on_init() { - // TODO: icon - - std::string path = resources_dir() + "/icons/overlay/"; - - if (!m_textures[Off].load_from_file(path + "cut_off.png", false)) { - return false; - } - - if (!m_textures[Hover].load_from_file(path + "cut_hover.png", false)) { - return false; - } - - if (!m_textures[On].load_from_file(path + "cut_on.png", false)) { - return false; - } - m_grabbers.emplace_back(); - m_shortcut_key = WXK_CONTROL_C; - return true; } diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index 9d7472d21..fc8d40a65 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -87,8 +87,10 @@ protected: int m_group_id; EState m_state; int m_shortcut_key; - // textures are assumed to be square and all with the same size in pixels, no internal check is done - GLTexture m_textures[Num_States]; +#if ENABLE_SVG_ICONS + std::string m_icon_filename; +#endif // ENABLE_SVG_ICONS + unsigned int m_sprite_id; int m_hover_id; bool m_dragging; float m_base_color[3]; @@ -100,7 +102,11 @@ protected: #endif // ENABLE_IMGUI public: - explicit GLGizmoBase(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoBase(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS virtual ~GLGizmoBase() {} bool init() { return on_init(); } @@ -116,11 +122,14 @@ public: int get_shortcut_key() const { return m_shortcut_key; } void set_shortcut_key(int key) { m_shortcut_key = key; } +#if ENABLE_SVG_ICONS + const std::string& get_icon_filename() const { return m_icon_filename; } +#endif // ENABLE_SVG_ICONS + bool is_activable(const GLCanvas3D::Selection& selection) const { return on_is_activable(selection); } bool is_selectable() const { return on_is_selectable(); } - unsigned int get_texture_id() const { return m_textures[m_state].get_id(); } - int get_textures_size() const { return m_textures[Off].get_width(); } + unsigned int get_sprite_id() const { return m_sprite_id; } int get_hover_id() const { return m_hover_id; } void set_hover_id(int id); @@ -244,7 +253,11 @@ class GLGizmoRotate3D : public GLGizmoBase std::vector m_gizmos; public: - explicit GLGizmoRotate3D(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoRotate3D(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS Vec3d get_rotation() const { return Vec3d(m_gizmos[X].get_angle(), m_gizmos[Y].get_angle(), m_gizmos[Z].get_angle()); } void set_rotation(const Vec3d& rotation) { m_gizmos[X].set_angle(rotation(0)); m_gizmos[Y].set_angle(rotation(1)); m_gizmos[Z].set_angle(rotation(2)); } @@ -315,7 +328,11 @@ class GLGizmoScale3D : public GLGizmoBase BoundingBoxf3 m_starting_box; public: - explicit GLGizmoScale3D(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoScale3D(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS double get_snap_step(double step) const { return m_snap_step; } void set_snap_step(double step) { m_snap_step = step; } @@ -362,7 +379,11 @@ class GLGizmoMove3D : public GLGizmoBase GLUquadricObj* m_quadric; public: - explicit GLGizmoMove3D(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoMove3D(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS virtual ~GLGizmoMove3D(); double get_snap_step(double step) const { return m_snap_step; } @@ -417,7 +438,11 @@ private: bool is_plane_update_necessary() const; public: - explicit GLGizmoFlatten(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoFlatten(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS void set_flattening_data(const ModelObject* model_object); Vec3d get_flattening_normal() const; @@ -437,7 +462,7 @@ protected: } }; - +#define SLAGIZMO_IMGUI_MODAL 0 class GLGizmoSlaSupports : public GLGizmoBase { @@ -465,7 +490,11 @@ private: mutable Vec3d m_starting_center; public: - explicit GLGizmoSlaSupports(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoSlaSupports(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS virtual ~GLGizmoSlaSupports(); void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection); bool mouse_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down); @@ -560,7 +589,11 @@ class GLGizmoCut : public GLGizmoBase #endif // not ENABLE_IMGUI public: - explicit GLGizmoCut(GLCanvas3D& parent); +#if ENABLE_SVG_ICONS + GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); +#else + GLGizmoCut(GLCanvas3D& parent, unsigned int sprite_id); +#endif // ENABLE_SVG_ICONS #if !ENABLE_IMGUI virtual void create_external_gizmo_widgets(wxWindow *parent); diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 19eff88e0..ab83d8051 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -6,19 +6,17 @@ #include #include -#if ENABLE_TEXTURES_FROM_SVG #include -#endif // ENABLE_TEXTURES_FROM_SVG #include #include -#if ENABLE_TEXTURES_FROM_SVG #define NANOSVG_IMPLEMENTATION #include "nanosvg/nanosvg.h" #define NANOSVGRAST_IMPLEMENTATION #include "nanosvg/nanosvgrast.h" -#endif // ENABLE_TEXTURES_FROM_SVG + +#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp" @@ -40,7 +38,6 @@ GLTexture::~GLTexture() reset(); } -#if ENABLE_TEXTURES_FROM_SVG bool GLTexture::load_from_file(const std::string& filename, bool use_mipmaps) { reset(); @@ -66,25 +63,20 @@ bool GLTexture::load_from_svg_file(const std::string& filename, bool use_mipmaps else return false; } -#else -bool GLTexture::load_from_file(const std::string& filename, bool use_mipmaps) + +bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector& filenames, const std::vector>& states, unsigned int sprite_size_px) { reset(); - if (!boost::filesystem::exists(filename)) + if (filenames.empty() || states.empty() || (sprite_size_px == 0)) return false; - // Load a PNG with an alpha channel. - wxImage image; - if (!image.LoadFile(wxString::FromUTF8(filename.c_str()), wxBITMAP_TYPE_PNG)) - { - reset(); - return false; - } - - m_width = image.GetWidth(); - m_height = image.GetHeight(); + m_width = (int)(sprite_size_px * states.size()); + m_height = (int)(sprite_size_px * filenames.size()); int n_pixels = m_width * m_height; + int sprite_n_pixels = sprite_size_px * sprite_size_px; + int sprite_bytes = sprite_n_pixels * 4; + int sprite_stride = sprite_size_px * 4; if (n_pixels <= 0) { @@ -92,52 +84,136 @@ bool GLTexture::load_from_file(const std::string& filename, bool use_mipmaps) return false; } - // Get RGB & alpha raw data from wxImage, pack them into an array. - unsigned char* img_rgb = image.GetData(); - if (img_rgb == nullptr) + std::vector data(n_pixels * 4, 0); + std::vector sprite_data(sprite_bytes, 0); + std::vector sprite_white_only_data(sprite_bytes, 0); + std::vector sprite_gray_only_data(sprite_bytes, 0); + std::vector output_data(sprite_bytes, 0); + + NSVGrasterizer* rast = nsvgCreateRasterizer(); + if (rast == nullptr) { reset(); return false; } - unsigned char* img_alpha = image.GetAlpha(); - - std::vector data(n_pixels * 4, 0); - for (int i = 0; i < n_pixels; ++i) + int sprite_id = -1; + for (const std::string& filename : filenames) { - int data_id = i * 4; - int img_id = i * 3; - data[data_id + 0] = img_rgb[img_id + 0]; - data[data_id + 1] = img_rgb[img_id + 1]; - data[data_id + 2] = img_rgb[img_id + 2]; - data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255; + ++sprite_id; + + if (!boost::filesystem::exists(filename)) + continue; + + if (!boost::algorithm::iends_with(filename, ".svg")) + continue; + + NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96.0f); + if (image == nullptr) + continue; + + float scale = (float)sprite_size_px / std::max(image->width, image->height); + + nsvgRasterize(rast, image, 0, 0, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_stride); + + // makes white only copy of the sprite + ::memcpy((void*)sprite_white_only_data.data(), (const void*)sprite_data.data(), sprite_bytes); + for (int i = 0; i < sprite_n_pixels; ++i) + { + int offset = i * 4; + if (sprite_white_only_data.data()[offset] != 0) + ::memset((void*)&sprite_white_only_data.data()[offset], 255, 3); + } + + // makes gray only copy of the sprite + ::memcpy((void*)sprite_gray_only_data.data(), (const void*)sprite_data.data(), sprite_bytes); + for (int i = 0; i < sprite_n_pixels; ++i) + { + int offset = i * 4; + if (sprite_gray_only_data.data()[offset] != 0) + ::memset((void*)&sprite_gray_only_data.data()[offset], 128, 3); + } + + int sprite_offset_px = sprite_id * sprite_size_px * m_width; + int state_id = -1; + for (const std::pair& state : states) + { + ++state_id; + + // select the sprite variant + std::vector* src = nullptr; + switch (state.first) + { + case 1: { src = &sprite_white_only_data; break; } + case 2: { src = &sprite_gray_only_data; break; } + default: { src = &sprite_data; break; } + } + + ::memcpy((void*)output_data.data(), (const void*)src->data(), sprite_bytes); + // applies background, if needed + if (state.second) + { + for (int i = 0; i < sprite_n_pixels; ++i) + { + int offset = i * 4; + float alpha = (float)output_data.data()[offset + 3] / 255.0f; + output_data.data()[offset + 0] = (unsigned char)(output_data.data()[offset + 0] * alpha); + output_data.data()[offset + 1] = (unsigned char)(output_data.data()[offset + 1] * alpha); + output_data.data()[offset + 2] = (unsigned char)(output_data.data()[offset + 2] * alpha); + output_data.data()[offset + 3] = (unsigned char)(128 * (1.0f - alpha) + output_data.data()[offset + 3] * alpha); + } + } + + int state_offset_px = sprite_offset_px + state_id * sprite_size_px; + for (int j = 0; j < sprite_size_px; ++j) + { + ::memcpy((void*)&data.data()[(state_offset_px + j * m_width) * 4], (const void*)&output_data.data()[j * sprite_stride], sprite_stride); + } + } + + nsvgDelete(image); } + nsvgDeleteRasterizer(rast); + // sends data to gpu ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); ::glGenTextures(1, &m_id); ::glBindTexture(GL_TEXTURE_2D, 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()); - if (use_mipmaps) - { - // we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards - unsigned int levels_count = generate_mipmaps(image); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 + levels_count); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - else - { - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - } + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ::glBindTexture(GL_TEXTURE_2D, 0); - m_source = filename; + m_source = filenames.front(); + +#if 0 + // debug output + static int pass = 0; + ++pass; + + wxImage output(m_width, m_height); + output.InitAlpha(); + + for (int h = 0; h < m_height; ++h) + { + int px_h = h * m_width; + for (int w = 0; w < m_width; ++w) + { + int offset = (px_h + w) * 4; + output.SetRGB(w, h, data.data()[offset + 0], data.data()[offset + 1], data.data()[offset + 2]); + output.SetAlpha(w, h, data.data()[offset + 3]); + } + } + + std::string out_filename = resources_dir() + "/icons/test_" + std::to_string(pass) + ".png"; + output.SaveFile(out_filename, wxBITMAP_TYPE_PNG); +#endif // 0 + return true; } -#endif // ENABLE_TEXTURES_FROM_SVG void GLTexture::reset() { @@ -216,7 +292,6 @@ unsigned int GLTexture::generate_mipmaps(wxImage& image) return (unsigned int)level; } -#if ENABLE_TEXTURES_FROM_SVG bool GLTexture::load_from_png(const std::string& filename, bool use_mipmaps) { // Load a PNG with an alpha channel. @@ -267,13 +342,13 @@ bool GLTexture::load_from_png(const std::string& filename, bool use_mipmaps) { // we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards unsigned int levels_count = generate_mipmaps(image); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 + levels_count); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels_count); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -342,13 +417,13 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, uns ::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)lod_w, (GLsizei)lod_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); } - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 + level); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -361,7 +436,6 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, uns return true; } -#endif // ENABLE_TEXTURES_FROM_SVG } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLTexture.hpp b/src/slic3r/GUI/GLTexture.hpp index af41ac342..017255647 100644 --- a/src/slic3r/GUI/GLTexture.hpp +++ b/src/slic3r/GUI/GLTexture.hpp @@ -38,9 +38,16 @@ namespace GUI { virtual ~GLTexture(); bool load_from_file(const std::string& filename, bool use_mipmaps); -#if ENABLE_TEXTURES_FROM_SVG bool load_from_svg_file(const std::string& filename, bool use_mipmaps, unsigned int max_size_px); -#endif // ENABLE_TEXTURES_FROM_SVG + // meanings of states: (std::pair) + // first field (int): + // 0 -> no changes + // 1 -> use white only color variant + // 2 -> use gray only color variant + // second field (bool): + // false -> no changes + // true -> add background color + bool load_from_svg_files_as_sprites_array(const std::vector& filenames, const std::vector>& states, unsigned int sprite_size_px); void reset(); unsigned int get_id() const { return m_id; } @@ -54,11 +61,9 @@ namespace GUI { protected: unsigned int generate_mipmaps(wxImage& image); -#if ENABLE_TEXTURES_FROM_SVG private: bool load_from_png(const std::string& filename, bool use_mipmaps); bool load_from_svg(const std::string& filename, bool use_mipmaps, unsigned int max_size_px); -#endif // ENABLE_TEXTURES_FROM_SVG }; } // namespace GUI diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 8d04868f8..1b8ccc165 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -32,12 +32,13 @@ wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent); GLToolbarItem::Data::Data() : name("") +#if ENABLE_SVG_ICONS + , icon_filename("") +#endif // ENABLE_SVG_ICONS , tooltip("") , sprite_id(-1) , is_toggable(false) -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS , visible(true) -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS { } @@ -53,26 +54,24 @@ void GLToolbarItem::do_action(wxEvtHandler *target) wxPostEvent(target, SimpleEvent(m_data.action_event)); } -void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const +void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const { - GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size)); + GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); } -GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const +GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const { GLTexture::Quad_UVs uvs; - float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f; + 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; - float scaled_icon_size = (float)icon_size * inv_texture_size; - float scaled_border_size = (float)border_size * inv_texture_size; - float scaled_gap_size = (float)gap_size * inv_texture_size; - float stride = scaled_icon_size + scaled_gap_size; - - float left = scaled_border_size + (float)m_state * stride; - float right = left + scaled_icon_size; - float top = scaled_border_size + (float)m_data.sprite_id * stride; - float bottom = top + scaled_icon_size; + float scaled_icon_width = (float)icon_size * inv_tex_width; + float scaled_icon_height = (float)icon_size * inv_tex_height; + float left = (float)m_state * scaled_icon_width; + float right = left + scaled_icon_width; + float top = (float)m_data.sprite_id * scaled_icon_height; + float bottom = top + scaled_icon_height; uvs.left_top = { left, top }; uvs.left_bottom = { left, bottom }; @@ -82,13 +81,13 @@ GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int texture_size, unsigned i return uvs; } +#if !ENABLE_SVG_ICONS ItemsIconsTexture::Metadata::Metadata() : filename("") , icon_size(0) - , icon_border_size(0) - , icon_gap_size(0) { } +#endif // !ENABLE_SVG_ICONS BackgroundTexture::Metadata::Metadata() : filename("") @@ -99,6 +98,10 @@ BackgroundTexture::Metadata::Metadata() { } +#if ENABLE_SVG_ICONS +const float GLToolbar::Default_Icons_Size = 64.0f; +#endif // ENABLE_SVG_ICONS + GLToolbar::Layout::Layout() : type(Horizontal) , orientation(Center) @@ -107,16 +110,31 @@ GLToolbar::Layout::Layout() , border(0.0f) , separator_size(0.0f) , gap_size(0.0f) +#if ENABLE_SVG_ICONS + , icons_size(Default_Icons_Size) + , scale(1.0f) +#else , icons_scale(1.0f) +#endif // ENABLE_SVG_ICONS , width(0.0f) , height(0.0f) , dirty(true) { } +#if ENABLE_SVG_ICONS +GLToolbar::GLToolbar(GLToolbar::EType type, const std::string& name) +#else GLToolbar::GLToolbar(GLToolbar::EType type) +#endif // ENABLE_SVG_ICONS : m_type(type) +#if ENABLE_SVG_ICONS + , m_name(name) +#endif // ENABLE_SVG_ICONS , m_enabled(false) +#if ENABLE_SVG_ICONS + , m_icons_texture_dirty(true) +#endif // ENABLE_SVG_ICONS { } @@ -128,8 +146,19 @@ GLToolbar::~GLToolbar() } } +#if ENABLE_SVG_ICONS +bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture) +#else bool GLToolbar::init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture) +#endif // ENABLE_SVG_ICONS { +#if ENABLE_SVG_ICONS + if (m_background_texture.texture.get_id() != 0) + return true; + + std::string path = resources_dir() + "/icons/"; + bool res = false; +#else if (m_icons_texture.texture.get_id() != 0) return true; @@ -137,6 +166,7 @@ bool GLToolbar::init(const ItemsIconsTexture::Metadata& icons_texture, const Bac bool res = !icons_texture.filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture.filename, false); if (res) m_icons_texture.metadata = icons_texture; +#endif // ENABLE_SVG_ICONS if (!background_texture.filename.empty()) res = m_background_texture.texture.load_from_file(path + background_texture.filename, false); @@ -192,11 +222,33 @@ void GLToolbar::set_gap_size(float size) m_layout.dirty = true; } +#if ENABLE_SVG_ICONS +void GLToolbar::set_icons_size(float size) +{ + if (m_layout.icons_size != size) + { + m_layout.icons_size = size; + m_layout.dirty = true; + m_icons_texture_dirty = true; + } +} + +void GLToolbar::set_scale(float scale) +{ + if (m_layout.scale != scale) + { + m_layout.scale = scale; + m_layout.dirty = true; + m_icons_texture_dirty = true; + } +} +#else void GLToolbar::set_icons_scale(float scale) { m_layout.icons_scale = scale; m_layout.dirty = true; } +#endif // ENABLE_SVG_ICONS bool GLToolbar::is_enabled() const { @@ -308,7 +360,6 @@ bool GLToolbar::is_item_disabled(const std::string& name) const return false; } -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS bool GLToolbar::is_item_visible(const std::string& name) const { for (GLToolbarItem* item : m_items) @@ -346,7 +397,6 @@ void GLToolbar::set_item_visible(const std::string& name, bool visible) } } -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent) { @@ -417,6 +467,11 @@ void GLToolbar::render(const GLCanvas3D& parent) const if (!m_enabled || m_items.empty()) return; +#if ENABLE_SVG_ICONS + if (m_icons_texture_dirty) + generate_icons_texture(); +#endif // ENABLE_SVG_ICONS + ::glDisable(GL_DEPTH_TEST); ::glPushMatrix(); @@ -461,12 +516,20 @@ float GLToolbar::get_width_horizontal() const float GLToolbar::get_width_vertical() const { +#if ENABLE_SVG_ICONS + return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; +#else return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale; +#endif // ENABLE_SVG_ICONS } float GLToolbar::get_height_horizontal() const { +#if ENABLE_SVG_ICONS + return (2.0f * m_layout.border + m_layout.icons_size) * m_layout.scale; +#else return 2.0f * m_layout.border * m_layout.icons_scale + m_icons_texture.metadata.icon_size * m_layout.icons_scale; +#endif // ENABLE_SVG_ICONS } float GLToolbar::get_height_vertical() const @@ -476,13 +539,29 @@ float GLToolbar::get_height_vertical() const float GLToolbar::get_main_size() const { +#if ENABLE_SVG_ICONS + float size = 2.0f * m_layout.border; + for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) + { + if (!m_items[i]->is_visible()) + continue; + + if (m_items[i]->is_separator()) + size += m_layout.separator_size; + else + size += (float)m_layout.icons_size; + } + + if (m_items.size() > 1) + size += ((float)m_items.size() - 1.0f) * m_layout.gap_size; + + size *= m_layout.scale; +#else float size = 2.0f * m_layout.border * m_layout.icons_scale; for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) { -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!m_items[i]->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (m_items[i]->is_separator()) size += m_layout.separator_size * m_layout.icons_scale; @@ -492,6 +571,7 @@ float GLToolbar::get_main_size() const if (m_items.size() > 1) size += ((float)m_items.size() - 1.0f) * m_layout.gap_size * m_layout.icons_scale; +#endif // ENABLE_SVG_ICONS return size; } @@ -502,12 +582,20 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC float zoom = parent.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_SVG_ICONS + float factor = m_layout.scale * inv_zoom; +#else float factor = m_layout.icons_scale * inv_zoom; +#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_layout.icons_size * factor; +#else float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; +#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -522,10 +610,8 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC for (GLToolbarItem* item : m_items) { -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!item->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (item->is_separator()) left += separator_stride; @@ -601,16 +687,23 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan float zoom = parent.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_SVG_ICONS + float factor = m_layout.scale * inv_zoom; +#else float factor = m_layout.icons_scale * inv_zoom; +#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_layout.icons_size * factor; +#else float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; +#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; - float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; @@ -621,10 +714,8 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan for (GLToolbarItem* item : m_items) { -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!item->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (item->is_separator()) top -= separator_stride; @@ -700,16 +791,23 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 float zoom = parent.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_SVG_ICONS + float factor = m_layout.scale * inv_zoom; +#else float factor = m_layout.icons_scale * inv_zoom; +#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_layout.icons_size * factor; +#else float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; +#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; - float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; @@ -722,10 +820,8 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 { ++id; -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!item->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (item->is_separator()) left += separator_stride; @@ -733,7 +829,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3 { float right = left + scaled_icons_size; float bottom = top - scaled_icons_size; - + if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top)) return id; @@ -750,12 +846,20 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& float zoom = parent.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_SVG_ICONS + float factor = m_layout.scale * inv_zoom; +#else float factor = m_layout.icons_scale * inv_zoom; +#endif // ENABLE_SVG_ICONS Size cnv_size = parent.get_canvas_size(); Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom); +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_layout.icons_size * factor; +#else float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; +#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -772,10 +876,8 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& { ++id; -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!item->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (item->is_separator()) top -= separator_stride; @@ -796,17 +898,34 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& void GLToolbar::render_horizontal(const GLCanvas3D& parent) const { +#if ENABLE_SVG_ICONS + unsigned int tex_id = m_icons_texture.get_id(); + int tex_width = m_icons_texture.get_width(); + int tex_height = m_icons_texture.get_height(); +#else unsigned int tex_id = m_icons_texture.texture.get_id(); - int tex_size = m_icons_texture.texture.get_width(); + int tex_width = m_icons_texture.texture.get_width(); + int tex_height = m_icons_texture.texture.get_height(); +#endif // ENABLE_SVG_ICONS - if ((tex_id == 0) || (tex_size <= 0)) +#if !ENABLE_SVG_ICONS + if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; +#endif // !ENABLE_SVG_ICONS float zoom = parent.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_SVG_ICONS + float factor = inv_zoom * m_layout.scale; +#else float factor = inv_zoom * m_layout.icons_scale; +#endif // ENABLE_SVG_ICONS +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_layout.icons_size * factor; +#else float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * factor; +#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -907,19 +1026,26 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const left += scaled_border; top -= scaled_border; +#if ENABLE_SVG_ICONS + if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) + return; +#endif // ENABLE_SVG_ICONS + // renders icons for (const GLToolbarItem* item : m_items) { -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!item->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (item->is_separator()) left += separator_stride; else { - item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.metadata.icon_border_size, m_icons_texture.metadata.icon_size, m_icons_texture.metadata.icon_gap_size); +#if ENABLE_SVG_ICONS + item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); +#else + item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, m_icons_texture.metadata.icon_size); +#endif // ENABLE_SVG_ICONS left += icon_stride; } } @@ -927,17 +1053,34 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const void GLToolbar::render_vertical(const GLCanvas3D& parent) const { +#if ENABLE_SVG_ICONS + unsigned int tex_id = m_icons_texture.get_id(); + int tex_width = m_icons_texture.get_width(); + int tex_height = m_icons_texture.get_height(); +#else unsigned int tex_id = m_icons_texture.texture.get_id(); - int tex_size = m_icons_texture.texture.get_width(); + int tex_width = m_icons_texture.texture.get_width(); + int tex_height = m_icons_texture.texture.get_height(); +#endif // ENABLE_SVG_ICONS - if ((tex_id == 0) || (tex_size <= 0)) +#if !ENABLE_SVG_ICONS + if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) return; +#endif // !ENABLE_SVG_ICONS float zoom = parent.get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_SVG_ICONS + float factor = inv_zoom * m_layout.scale; +#else float factor = inv_zoom * m_layout.icons_scale; +#endif // ENABLE_SVG_ICONS +#if ENABLE_SVG_ICONS + float scaled_icons_size = m_layout.icons_size * factor; +#else float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_layout.icons_scale * factor; +#endif // ENABLE_SVG_ICONS float scaled_separator_size = m_layout.separator_size * factor; float scaled_gap_size = m_layout.gap_size * factor; float scaled_border = m_layout.border * factor; @@ -1038,23 +1181,68 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const left += scaled_border; top -= scaled_border; +#if ENABLE_SVG_ICONS + if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0)) + return; +#endif // ENABLE_SVG_ICONS + // renders icons for (const GLToolbarItem* item : m_items) { -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (!item->is_visible()) continue; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (item->is_separator()) top -= separator_stride; else { - item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.metadata.icon_border_size, m_icons_texture.metadata.icon_size, m_icons_texture.metadata.icon_gap_size); +#if ENABLE_SVG_ICONS + item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale)); +#else + item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, m_icons_texture.metadata.icon_size); +#endif // ENABLE_SVG_ICONS top -= icon_stride; } } } +#if ENABLE_SVG_ICONS +bool GLToolbar::generate_icons_texture() const +{ + std::string path = resources_dir() + "/icons/"; + std::vector filenames; + for (GLToolbarItem* item : m_items) + { + const std::string& icon_filename = item->get_icon_filename(); + if (!icon_filename.empty()) + filenames.push_back(path + icon_filename); + } + + std::vector> states; + if (m_name == "Top") + { + states.push_back(std::make_pair(1, false)); + states.push_back(std::make_pair(0, false)); + states.push_back(std::make_pair(2, false)); + states.push_back(std::make_pair(0, false)); + states.push_back(std::make_pair(0, false)); + } + else if (m_name == "View") + { + states.push_back(std::make_pair(1, false)); + states.push_back(std::make_pair(1, true)); + states.push_back(std::make_pair(1, false)); + states.push_back(std::make_pair(0, false)); + states.push_back(std::make_pair(1, true)); + } + + bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_layout.icons_size * m_layout.scale)); + if (res) + m_icons_texture_dirty = false; + + return res; +} +#endif // ENABLE_SVG_ICONS + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 951d5e072..4ca72fc4a 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -51,13 +51,14 @@ public: struct Data { std::string name; +#if ENABLE_SVG_ICONS + std::string icon_filename; +#endif // ENABLE_SVG_ICONS std::string tooltip; unsigned int sprite_id; bool is_toggable; wxEventType action_event; -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS bool visible; -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS Data(); }; @@ -74,6 +75,9 @@ public: void set_state(EState state) { m_state = state; } const std::string& get_name() const { return m_data.name; } +#if ENABLE_SVG_ICONS + const std::string& get_icon_filename() const { return m_data.icon_filename; } +#endif // ENABLE_SVG_ICONS const std::string& get_tooltip() const { return m_data.tooltip; } void do_action(wxEvtHandler *target); @@ -84,18 +88,17 @@ public: bool is_pressed() const { return (m_state == Pressed) || (m_state == HoverPressed); } bool is_toggable() const { return m_data.is_toggable; } -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS bool is_visible() const { return m_data.visible; } void set_visible(bool visible) { m_data.visible = visible; } -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS bool is_separator() const { return m_type == Separator; } - void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const; + void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const; private: - GLTexture::Quad_UVs get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const; + GLTexture::Quad_UVs get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const; }; +#if !ENABLE_SVG_ICONS // items icon textures are assumed to be square and all with the same size in pixels, no internal check is done // icons are layed-out into the texture starting from the top-left corner in the same order as enum GLToolbarItem::EState // from left to right @@ -107,10 +110,6 @@ struct ItemsIconsTexture std::string filename; // size of the square icons, in pixels unsigned int icon_size; - // size of the border, in pixels - unsigned int icon_border_size; - // distance between two adjacent icons (to avoid filtering artifacts), in pixels - unsigned int icon_gap_size; Metadata(); }; @@ -118,6 +117,7 @@ struct ItemsIconsTexture GLTexture texture; Metadata metadata; }; +#endif // !ENABLE_SVG_ICONS struct BackgroundTexture { @@ -144,6 +144,10 @@ struct BackgroundTexture class GLToolbar { public: +#if ENABLE_SVG_ICONS + static const float Default_Icons_Size; +#endif // ENABLE_SVG_ICONS + enum EType : unsigned char { Normal, @@ -177,7 +181,12 @@ public: float border; float separator_size; float gap_size; +#if ENABLE_SVG_ICONS + float icons_size; + float scale; +#else float icons_scale; +#endif // ENABLE_SVG_ICONS float width; float height; @@ -190,18 +199,34 @@ private: typedef std::vector ItemsList; EType m_type; +#if ENABLE_SVG_ICONS + std::string m_name; +#endif // ENABLE_SVG_ICONS bool m_enabled; +#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; mutable Layout m_layout; ItemsList m_items; public: +#if ENABLE_SVG_ICONS + GLToolbar(EType type, const std::string& name); +#else explicit GLToolbar(EType type); +#endif // ENABLE_SVG_ICONS ~GLToolbar(); +#if ENABLE_SVG_ICONS + bool init(const BackgroundTexture::Metadata& background_texture); +#else bool init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture); +#endif // ENABLE_SVG_ICONS Layout::EType get_layout_type() const; void set_layout_type(Layout::EType type); @@ -212,7 +237,12 @@ public: void set_border(float border); void set_separator_size(float size); void set_gap_size(float size); +#if ENABLE_SVG_ICONS + void set_icons_size(float size); + void set_scale(float scale); +#else void set_icons_scale(float scale); +#endif // ENABLE_SVG_ICONS bool is_enabled() const; void set_enabled(bool enable); @@ -229,10 +259,8 @@ public: bool is_item_pressed(const std::string& name) const; bool is_item_disabled(const std::string& name) const; -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS bool is_item_visible(const std::string& name) const; void set_item_visible(const std::string& name, bool visible); -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent); @@ -257,6 +285,10 @@ private: void render_horizontal(const GLCanvas3D& parent) const; void render_vertical(const GLCanvas3D& parent) const; + +#if ENABLE_SVG_ICONS + bool generate_icons_texture() const; +#endif // ENABLE_SVG_ICONS }; } // namespace GUI diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 0857265f3..c2ff7bfb7 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -259,7 +259,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder) void ObjectList::update_objects_list_extruder_column(int extruders_count) { if (!this) return; // #ys_FIXME - if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA) + if (printer_technology() == ptSLA) extruders_count = 1; wxDataViewChoiceRenderer* ch_render = dynamic_cast(GetColumn(1)->GetRenderer()); @@ -452,7 +452,7 @@ void ObjectList::show_context_menu() wxMenu* menu = type & itInstance ? &m_menu_instance : m_objects_model->GetParent(item) != wxDataViewItem(0) ? &m_menu_part : - wxGetApp().plater()->printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; + printer_technology() == ptFFF ? &m_menu_object : &m_menu_sla_object; if (!(type & itInstance)) append_menu_item_settings(menu); @@ -597,7 +597,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) std::vector ObjectList::get_options(const bool is_part) { - if (wxGetApp().plater()->printer_technology() == ptSLA) { + if (printer_technology() == ptSLA) { SLAPrintObjectConfig full_sla_config; auto options = full_sla_config.keys(); options.erase(find(options.begin(), options.end(), "layer_height")); @@ -616,7 +616,7 @@ std::vector ObjectList::get_options(const bool is_part) const std::vector& ObjectList::get_options_for_bundle(const wxString& bundle_name) { - const FreqSettingsBundle& bundle = wxGetApp().plater()->printer_technology() == ptSLA ? + const FreqSettingsBundle& bundle = printer_technology() == ptSLA ? FREQ_SETTINGS_BUNDLE_SLA : FREQ_SETTINGS_BUNDLE_FFF; for (auto& it : bundle) @@ -626,7 +626,7 @@ const std::vector& ObjectList::get_options_for_bundle(const wxStrin } #if 0 // if "Quick menu" is selected - FreqSettingsBundle& bundle_quick = wxGetApp().plater()->printer_technology() == ptSLA ? + FreqSettingsBundle& bundle_quick = printer_technology() == ptSLA ? m_freq_settings_sla: m_freq_settings_fff; for (auto& it : bundle_quick) @@ -644,7 +644,7 @@ void ObjectList::get_options_menu(settings_menu_hierarchy& settings_menu, const { auto options = get_options(is_part); - auto extruders_cnt = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : + auto extruders_cnt = printer_technology() == ptSLA ? 1 : wxGetApp().preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); DynamicPrintConfig config; @@ -667,6 +667,11 @@ void ObjectList::get_options_menu(settings_menu_hierarchy& settings_menu, const } } +Slic3r::PrinterTechnology ObjectList::printer_technology() const +{ + return wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(); +} + void ObjectList::get_settings_choice(const wxString& category_name) { wxArrayString names; @@ -705,7 +710,7 @@ void ObjectList::get_settings_choice(const wxString& category_name) if (selection_cnt > 0) { // Add selected items to the "Quick menu" - FreqSettingsBundle& freq_settings = wxGetApp().plater()->printer_technology() == ptSLA ? + FreqSettingsBundle& freq_settings = printer_technology() == ptSLA ? m_freq_settings_sla : m_freq_settings_fff; bool changed_existing = false; @@ -751,7 +756,9 @@ void ObjectList::get_settings_choice(const wxString& category_name) for (auto sel : selections) selected_options.push_back((*settings_list)[sel].first); - const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + const DynamicPrintConfig& from_config = printer_technology() == ptFFF ? + wxGetApp().preset_bundle->prints.get_edited_preset().config : + wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; for (auto& setting : (*settings_list)) { @@ -1065,10 +1072,10 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu) void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) { // Add default settings bundles - const FreqSettingsBundle& bundle = wxGetApp().plater()->printer_technology() == ptFFF ? + const FreqSettingsBundle& bundle = printer_technology() == ptFFF ? FREQ_SETTINGS_BUNDLE_FFF : FREQ_SETTINGS_BUNDLE_SLA; - auto extruders_cnt = wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA ? 1 : + auto extruders_cnt = printer_technology() == ptSLA ? 1 : wxGetApp().preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); for (auto& it : bundle) { @@ -1081,7 +1088,7 @@ void ObjectList::create_freq_settings_popupmenu(wxMenu *menu) } #if 0 // Add "Quick" settings bundles - const FreqSettingsBundle& bundle_quick = wxGetApp().plater()->printer_technology() == ptFFF ? + const FreqSettingsBundle& bundle_quick = printer_technology() == ptFFF ? m_freq_settings_fff : m_freq_settings_sla; for (auto& it : bundle_quick) { diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 7d14eb13f..9e24b4b49 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -284,6 +284,8 @@ private: std::vector get_options(const bool is_part); const std::vector& get_options_for_bundle(const wxString& bundle_name); void get_options_menu(settings_menu_hierarchy& settings_menu, const bool is_part); + + PrinterTechnology printer_technology() const ; }; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index f85df395d..d48bb5f49 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -137,13 +137,11 @@ void View3D::mirror_selection(Axis axis) m_canvas->mirror_selection(axis); } -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS void View3D::update_toolbar_items_visibility() { if (m_canvas != nullptr) m_canvas->update_toolbar_items_visibility(); } -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS void View3D::enable_toolbar_item(const std::string& name, bool enable) { diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index d3cb4e5bf..1d65aff1b 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -60,9 +60,7 @@ public: void delete_selected(); void mirror_selection(Axis axis); -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS void update_toolbar_items_visibility(); -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS void enable_toolbar_item(const std::string& name, bool enable); int check_volumes_outside_state() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e90752e19..4e3ed4797 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1178,7 +1178,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) , sidebar(new Sidebar(q)) , delayed_scene_refresh(false) , project_filename(wxEmptyString) +#if ENABLE_SVG_ICONS + , view_toolbar(GLToolbar::Radio, "View") +#else , view_toolbar(GLToolbar::Radio) +#endif // ENABLE_SVG_ICONS { arranging.store(false); rotoptimizing.store(false); @@ -2624,11 +2628,11 @@ bool Plater::priv::complit_init_part_menu() void Plater::priv::init_view_toolbar() { +#if !ENABLE_SVG_ICONS ItemsIconsTexture::Metadata icons_data; icons_data.filename = "view_toolbar.png"; icons_data.icon_size = 64; - icons_data.icon_border_size = 0; - icons_data.icon_gap_size = 0; +#endif // !ENABLE_SVG_ICONS BackgroundTexture::Metadata background_data; background_data.filename = "toolbar_background.png"; @@ -2637,7 +2641,11 @@ void Plater::priv::init_view_toolbar() background_data.right = 16; background_data.bottom = 16; +#if ENABLE_SVG_ICONS + if (!view_toolbar.init(background_data)) +#else if (!view_toolbar.init(icons_data, background_data)) +#endif // ENABLE_SVG_ICONS return; view_toolbar.set_layout_orientation(GLToolbar::Layout::Bottom); @@ -2647,6 +2655,9 @@ void Plater::priv::init_view_toolbar() GLToolbarItem::Data item; item.name = "3D"; +#if ENABLE_SVG_ICONS + item.icon_filename = "editor.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("3D editor view") + " [" + GUI::shortkey_ctrl_prefix() + "5]"; item.sprite_id = 0; item.action_event = EVT_GLVIEWTOOLBAR_3D; @@ -2655,6 +2666,9 @@ void Plater::priv::init_view_toolbar() return; item.name = "Preview"; +#if ENABLE_SVG_ICONS + item.icon_filename = "preview.svg"; +#endif // ENABLE_SVG_ICONS item.tooltip = GUI::L_str("Preview") + " [" + GUI::shortkey_ctrl_prefix() + "6]"; item.sprite_id = 1; item.action_event = EVT_GLVIEWTOOLBAR_PREVIEW; @@ -2750,10 +2764,8 @@ void Plater::priv::set_bed_shape(const Pointfs& shape) void Plater::priv::update_object_menu() { sidebar->obj_list()->append_menu_items_add_volume(&object_menu); -#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS if (view3D != nullptr) view3D->update_toolbar_items_visibility(); -#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS } // Plater / Public