From 2ae3378605b1d0e5004a08535edbebdcd2bb74da Mon Sep 17 00:00:00 2001
From: githubber4ever <99887737+githubber4ever@users.noreply.github.com>
Date: Sat, 1 Nov 2025 17:23:26 +0100
Subject: [PATCH] toggle axis visibility on canvas (#9666)
* toggle axis visibility on canvas
* set show_axes config on toggle
---
resources/images/axis_toggle.svg | 167 ++++++++++++++++++++
resources/images/axis_toggle_dark.svg | 167 ++++++++++++++++++++
resources/images/axis_toggle_hover.svg | 167 ++++++++++++++++++++
resources/images/axis_toggle_hover_dark.svg | 167 ++++++++++++++++++++
src/libslic3r/AppConfig.cpp | 3 +
src/slic3r/GUI/GLCanvas3D.cpp | 72 ++++++++-
src/slic3r/GUI/GLCanvas3D.hpp | 7 +-
src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 30 +++-
src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 6 +-
9 files changed, 774 insertions(+), 12 deletions(-)
create mode 100644 resources/images/axis_toggle.svg
create mode 100644 resources/images/axis_toggle_dark.svg
create mode 100644 resources/images/axis_toggle_hover.svg
create mode 100644 resources/images/axis_toggle_hover_dark.svg
diff --git a/resources/images/axis_toggle.svg b/resources/images/axis_toggle.svg
new file mode 100644
index 0000000000..679c34e5ca
--- /dev/null
+++ b/resources/images/axis_toggle.svg
@@ -0,0 +1,167 @@
+
+
diff --git a/resources/images/axis_toggle_dark.svg b/resources/images/axis_toggle_dark.svg
new file mode 100644
index 0000000000..08c52a8398
--- /dev/null
+++ b/resources/images/axis_toggle_dark.svg
@@ -0,0 +1,167 @@
+
+
diff --git a/resources/images/axis_toggle_hover.svg b/resources/images/axis_toggle_hover.svg
new file mode 100644
index 0000000000..1d462ffb1d
--- /dev/null
+++ b/resources/images/axis_toggle_hover.svg
@@ -0,0 +1,167 @@
+
+
diff --git a/resources/images/axis_toggle_hover_dark.svg b/resources/images/axis_toggle_hover_dark.svg
new file mode 100644
index 0000000000..14f9bd2767
--- /dev/null
+++ b/resources/images/axis_toggle_hover_dark.svg
@@ -0,0 +1,167 @@
+
+
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 73c038f143..4d8e48af2c 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -214,6 +214,9 @@ void AppConfig::set_defaults()
if (get("show_outline").empty())
set_bool("show_outline", false);
+
+ if (get("show_axes").empty())
+ set_bool("show_axes", true);
#ifdef _WIN32
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 9a1d538b8f..27b10e32e4 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1258,6 +1258,8 @@ bool GLCanvas3D::init()
// init dark mode status
on_change_color_mode(wxGetApp().app_config->get("dark_color_mode") == "1", false);
+ m_show_world_axes = wxGetApp().app_config->get("show_axes") == "true";
+
BOOST_LOG_TRIVIAL(info) <<__FUNCTION__<< " enter";
glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f));
glsafe(::glClearDepth(1.0f));
@@ -1534,6 +1536,17 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state(ObjectFil
return state;
}
+void GLCanvas3D::toggle_world_axes_visibility(bool force_show)
+{
+ if (force_show) {
+ m_show_world_axes = true;
+ } else {
+ m_show_world_axes = !m_show_world_axes;
+ }
+ wxGetApp().app_config->set_bool("show_axes", m_show_world_axes);
+ set_as_dirty();
+}
+
void GLCanvas3D::toggle_selected_volume_visibility(bool selected_visible)
{
m_render_sla_auxiliaries = !selected_visible;
@@ -2085,7 +2098,7 @@ void GLCanvas3D::render(bool only_init)
_render_background();
//BBS add partplater rendering logic
- bool only_current = false, only_body = false, show_axes = true, no_partplate = false;
+ bool only_current = false, only_body = false, no_partplate = false;
bool show_grid = true;
GLGizmosManager::EType gizmo_type = m_gizmos.get_current_type();
if (!m_main_toolbar.is_enabled()) {
@@ -2105,7 +2118,7 @@ void GLCanvas3D::render(bool only_init)
_render_sla_slices();
_render_selection();
if (!no_partplate)
- _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
+ _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), m_show_world_axes);
if (!no_partplate) //BBS: add outline logic
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true, show_grid);
_render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running());
@@ -2115,7 +2128,7 @@ void GLCanvas3D::render(bool only_init)
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
_render_sla_slices();
_render_selection();
- _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
+ _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), m_show_world_axes);
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, true, hover_id);
// BBS: GUI refactor: add canvas size as parameters
_render_gcode(cnv_size.get_width(), cnv_size.get_height());
@@ -2123,9 +2136,9 @@ void GLCanvas3D::render(bool only_init)
/* assemble render*/
else if (m_canvas_type == ECanvasType::CanvasAssembleView) {
//BBS: add outline logic
- if (m_show_world_axes) {
- m_axes.render();
- }
+ //if (m_show_world_axes) {
+ // m_axes.render();
+ //}
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
_render_selection();
//_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
@@ -6069,6 +6082,7 @@ void GLCanvas3D::_render_3d_navigator()
}
const float size = 128 * sc;
+ m_axis_button_pos[0] = size - 10;
const auto result = ImGuizmo::ViewManipulate(cameraView, cameraProjection, ImGuizmo::OPERATION::ROTATE, ImGuizmo::MODE::WORLD, nullptr,
camDistance, ImVec2(viewManipulateLeft, viewManipulateTop - size), ImVec2(size, size),
0x00101010);
@@ -6104,6 +6118,7 @@ void GLCanvas3D::_render_3d_navigator()
request_extra_frame();
}
+ _render_camera_toolbar();
}
#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0
@@ -8604,6 +8619,51 @@ void GLCanvas3D::_render_return_toolbar() const
imgui.end();
}
+void GLCanvas3D::_render_camera_toolbar()
+{
+ float font_size = ImGui::GetFontSize();
+ float sc = get_scale();
+ ImVec2 button_icon_size = ImVec2(font_size * 2.5, font_size * 2.5);
+
+ ImGuiWrapper &imgui = *wxGetApp().imgui();
+ float window_width = button_icon_size.x + imgui.scaled(2.0f);
+ float window_height = button_icon_size.y + imgui.scaled(2.0f);
+
+ Size cnv_size = get_canvas_size();
+ m_axis_button_pos[1] = cnv_size.get_height() - button_icon_size[1] - 20 * sc;
+ imgui.set_next_window_pos(m_axis_button_pos[0], m_axis_button_pos[1], ImGuiCond_Always, 0, 0);
+#ifdef __WINDOWS__
+ imgui.set_next_window_size(window_width, window_height, ImGuiCond_Always);
+#endif
+
+ imgui.begin(_L("Toggle Axis"), ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove |
+ ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse);//
+
+ ImTextureID normal_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE_DARK : GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE);
+ ImTextureID hover_id = m_gizmos.get_icon_texture_id(m_is_dark ? GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE_DARK_HOVER : GLGizmosManager::MENU_ICON_NAME::IC_AXIS_TOGGLE_HOVER);
+
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0});
+
+ if (ImGui::ImageButton3(normal_id, hover_id, button_icon_size, ImVec2(0, 0), ImVec2(1, 1), -1,
+ ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1), ImVec2(10, 0))) {
+ //select_view("plate");
+
+ if (m_canvas_type == ECanvasType::CanvasView3D || m_canvas_type == ECanvasType::CanvasPreview) {
+ toggle_world_axes_visibility(false);
+ }
+
+ }
+ if (ImGui::IsItemHovered()) {
+ auto temp_tooltip = _L("Toggle Axis");
+ auto width = ImGui::CalcTextSize(temp_tooltip.c_str()).x + imgui.scaled(2.0f);
+ imgui.tooltip(temp_tooltip, width);
+ }
+ ImGui::PopStyleVar(2);
+
+ imgui.end();
+}
+
void GLCanvas3D::_render_separator_toolbar_right() const
{
if (!m_separator_toolbar.is_enabled())
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 0c787ae729..c373fe1164 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -542,6 +542,8 @@ private:
mutable IMToolbar m_sel_plate_toolbar;
mutable GLToolbar m_assemble_view_toolbar;
mutable IMReturnToolbar m_return_toolbar;
+ mutable Vec2i32 m_axis_button_pos = {128, 5};
+ mutable float m_sc{1};
mutable float m_paint_toolbar_width;
//BBS: add canvas type for assemble view usage
@@ -625,7 +627,7 @@ private:
PrinterTechnology current_printer_technology() const;
- bool m_show_world_axes{false};
+ bool m_show_world_axes{true};
Bed3D::Axes m_axes;
//BBS:record key botton frequency
int auto_orient_count = 0;
@@ -821,7 +823,7 @@ public:
void set_color_clip_plane(const Vec3d& cp_normal, double offset) { m_volumes.set_color_clip_plane(cp_normal, offset); }
void set_color_clip_plane_colors(const std::array& colors) { m_volumes.set_color_clip_plane_colors(colors); }
- void set_show_world_axes(bool flag) { m_show_world_axes = flag; }
+ void toggle_world_axes_visibility(bool force_show = false);
void refresh_camera_scene_box();
void set_color_by(const std::string& value);
@@ -1243,6 +1245,7 @@ private:
void _render_imgui_select_plate_toolbar();
void _render_assemble_view_toolbar() const;
void _render_return_toolbar() const;
+ void _render_camera_toolbar();
void _render_separator_toolbar_right() const;
void _render_separator_toolbar_left() const;
void _render_collapse_toolbar() const;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 762b371778..4ac3d56a0c 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -183,8 +183,9 @@ void GLGizmosManager::switch_gizmos_icon_filename()
bool GLGizmosManager::init()
{
- bool result = init_icon_textures();
- if (!result) return result;
+ if (!m_gizmos.empty())
+ return true;
+ init_icon_textures();
m_background_texture.metadata.filename = m_is_dark ? "toolbar_background_dark.png" : "toolbar_background.png";
m_background_texture.metadata.left = 16;
@@ -241,9 +242,12 @@ bool GLGizmosManager::init()
return true;
}
-
+std::map GLGizmosManager::icon_list = {};
bool GLGizmosManager::init_icon_textures()
{
+ if (icon_list.size() > 0) {
+ return true;
+ }
ImTextureID texture_id;
icon_list.clear();
@@ -277,6 +281,26 @@ bool GLGizmosManager::init_icon_textures()
else
return false;
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle.svg", 64, 64, texture_id))
+ icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle_hover.svg", 64, 64, texture_id))
+ icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE_HOVER, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle_dark.svg", 64, 64, texture_id))
+ icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE_DARK, texture_id));
+ else
+ return false;
+
+ if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/axis_toggle_hover_dark.svg", 64, 64, texture_id))
+ icon_list.insert(std::make_pair((int) IC_AXIS_TOGGLE_DARK_HOVER, texture_id));
+ else
+ return false;
+
return true;
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index f68d4038ad..ba7d5afdb9 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -147,7 +147,7 @@ private:
void on_set_color_timer(wxTimerEvent& evt);
// key MENU_ICON_NAME, value = ImtextureID
- std::map icon_list;
+ static std::map icon_list;
bool m_is_dark = false;
@@ -170,6 +170,10 @@ public:
IC_TOOLBAR_TOOLTIP,
IC_TOOLBAR_TOOLTIP_HOVER,
IC_NAME_COUNT,
+ IC_AXIS_TOGGLE,
+ IC_AXIS_TOGGLE_HOVER,
+ IC_AXIS_TOGGLE_DARK,
+ IC_AXIS_TOGGLE_DARK_HOVER,
};
explicit GLGizmosManager(GLCanvas3D& parent);