diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 18545db3e..66d2f2f7b 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -132,6 +132,7 @@ sub new { Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { $self->remove() }); Slic3r::GUI::_3DScene::register_on_instance_moved_callback($self->{canvas3D}, $on_instances_moved); Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons); + Slic3r::GUI::_3DScene::enable_gizmos($self->{canvas3D}, 1); Slic3r::GUI::_3DScene::enable_shader($self->{canvas3D}, 1); Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($self->{canvas3D}, 1); diff --git a/resources/icons/overlay/rotate_hover.png b/resources/icons/overlay/rotate_hover.png new file mode 100644 index 000000000..56d4fd277 Binary files /dev/null and b/resources/icons/overlay/rotate_hover.png differ diff --git a/resources/icons/overlay/rotate_off.png b/resources/icons/overlay/rotate_off.png new file mode 100644 index 000000000..8491f7e43 Binary files /dev/null and b/resources/icons/overlay/rotate_off.png differ diff --git a/resources/icons/overlay/rotate_on.png b/resources/icons/overlay/rotate_on.png new file mode 100644 index 000000000..e2db5120c Binary files /dev/null and b/resources/icons/overlay/rotate_on.png differ diff --git a/resources/icons/overlay/scale_hover.png b/resources/icons/overlay/scale_hover.png new file mode 100644 index 000000000..d620aee7a Binary files /dev/null and b/resources/icons/overlay/scale_hover.png differ diff --git a/resources/icons/overlay/scale_off.png b/resources/icons/overlay/scale_off.png new file mode 100644 index 000000000..1ae999bbe Binary files /dev/null and b/resources/icons/overlay/scale_off.png differ diff --git a/resources/icons/overlay/scale_on.png b/resources/icons/overlay/scale_on.png new file mode 100644 index 000000000..62e805f12 Binary files /dev/null and b/resources/icons/overlay/scale_on.png differ diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index d0d03dc6c..5dbc2a2f7 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -181,13 +181,15 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/GUI/3DScene.cpp ${LIBDIR}/slic3r/GUI/3DScene.hpp ${LIBDIR}/slic3r/GUI/GLShader.cpp - ${LIBDIR}/slic3r/GUI/GLShader.hpp - + ${LIBDIR}/slic3r/GUI/GLShader.hpp ${LIBDIR}/slic3r/GUI/GLCanvas3D.hpp ${LIBDIR}/slic3r/GUI/GLCanvas3D.cpp ${LIBDIR}/slic3r/GUI/GLCanvas3DManager.hpp ${LIBDIR}/slic3r/GUI/GLCanvas3DManager.cpp - + ${LIBDIR}/slic3r/GUI/GLGizmo.hpp + ${LIBDIR}/slic3r/GUI/GLGizmo.cpp + ${LIBDIR}/slic3r/GUI/GLTexture.hpp + ${LIBDIR}/slic3r/GUI/GLTexture.cpp ${LIBDIR}/slic3r/GUI/Preferences.cpp ${LIBDIR}/slic3r/GUI/Preferences.hpp ${LIBDIR}/slic3r/GUI/Preset.cpp diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 9a11699a2..3770ad0e6 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1735,20 +1735,16 @@ bool _3DScene::use_VBOs() bool _3DScene::add_canvas(wxGLCanvas* canvas) { - std::cout << "_3DScene::add_canvas()" << std::endl; return s_canvas_mgr.add(canvas); } bool _3DScene::remove_canvas(wxGLCanvas* canvas) { - std::cout << "_3DScene::remove_canvas()" << std::endl; return s_canvas_mgr.remove(canvas); } void _3DScene::remove_all_canvases() { - std::cout << "_3DScene::remove_all_canvases()" << std::endl; - std::cout << "# canvases not yet released: " << s_canvas_mgr.count() << std::endl; s_canvas_mgr.remove_all(); } @@ -1907,6 +1903,13 @@ void _3DScene::enable_moving(wxGLCanvas* canvas, bool enable) s_canvas_mgr.enable_moving(canvas, enable); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void _3DScene::enable_gizmos(wxGLCanvas* canvas, bool enable) +{ + s_canvas_mgr.enable_gizmos(canvas, enable); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void _3DScene::enable_shader(wxGLCanvas* canvas, bool enable) { s_canvas_mgr.enable_shader(canvas, enable); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 138b220fc..ad2b8d5c5 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -557,6 +557,9 @@ public: static void enable_legend_texture(wxGLCanvas* canvas, bool enable); static void enable_picking(wxGLCanvas* canvas, bool enable); static void enable_moving(wxGLCanvas* canvas, bool enable); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + static void enable_gizmos(wxGLCanvas* canvas, bool enable); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static void enable_shader(wxGLCanvas* canvas, bool enable); static void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable); static void allow_multisample(wxGLCanvas* canvas, bool allow); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index b032ce353..348588ee2 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -4,6 +4,9 @@ #include "../../slic3r/GUI/GLShader.hpp" #include "../../slic3r/GUI/GUI.hpp" #include "../../slic3r/GUI/PresetBundle.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include "../../slic3r/GUI/GLGizmo.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "../../libslic3r/ClipperUtils.hpp" #include "../../libslic3r/PrintConfig.hpp" #include "../../libslic3r/Print.hpp" @@ -12,7 +15,9 @@ #include #include -#include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include #include @@ -23,6 +28,9 @@ #include #include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ static const float TRACKBALLSIZE = 0.8f; static const float GIMBALL_LOCK_THETA_MAX = 180.0f; @@ -237,105 +245,107 @@ void Rect::set_bottom(float bottom) m_bottom = bottom; } -GLCanvas3D::GLTextureData::GLTextureData() - : m_id(0) - , m_width(0) - , m_height(0) - , m_source("") -{ -} - -GLCanvas3D::GLTextureData::~GLTextureData() -{ - reset(); -} - -bool GLCanvas3D::GLTextureData::load_from_file(const std::string& filename) -{ - reset(); - - // Load a PNG with an alpha channel. - wxImage image; - if (!image.LoadFile(filename, wxBITMAP_TYPE_PNG)) - { - reset(); - return false; - } - - m_width = image.GetWidth(); - m_height = image.GetHeight(); - int n_pixels = m_width * m_height; - - if (n_pixels <= 0) - { - reset(); - return false; - } - - // Get RGB & alpha raw data from wxImage, pack them into an array. - unsigned char* img_rgb = image.GetData(); - if (img_rgb == 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 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; - } - - // sends data to gpu - ::glGenTextures(1, &m_id); - ::glBindTexture(GL_TEXTURE_2D, m_id); - ::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); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); - ::glBindTexture(GL_TEXTURE_2D, 0); - - m_source = filename; - return true; -} - -void GLCanvas3D::GLTextureData::reset() -{ - if (m_id != 0) - ::glDeleteTextures(1, &m_id); - - m_id = 0; - m_width = 0; - m_height = 0; - m_source = ""; -} - -unsigned int GLCanvas3D::GLTextureData::get_id() const -{ - return m_id; -} - -int GLCanvas3D::GLTextureData::get_width() const -{ - return m_width; -} - -int GLCanvas3D::GLTextureData::get_height() const -{ - return m_height; -} - -const std::string& GLCanvas3D::GLTextureData::get_source() const -{ - return m_source; -} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//GLCanvas3D::GLTextureData::GLTextureData() +// : m_id(0) +// , m_width(0) +// , m_height(0) +// , m_source("") +//{ +//} +// +//GLCanvas3D::GLTextureData::~GLTextureData() +//{ +// reset(); +//} +// +//bool GLCanvas3D::GLTextureData::load_from_file(const std::string& filename) +//{ +// reset(); +// +// // Load a PNG with an alpha channel. +// wxImage image; +// if (!image.LoadFile(filename, wxBITMAP_TYPE_PNG)) +// { +// reset(); +// return false; +// } +// +// m_width = image.GetWidth(); +// m_height = image.GetHeight(); +// int n_pixels = m_width * m_height; +// +// if (n_pixels <= 0) +// { +// reset(); +// return false; +// } +// +// // Get RGB & alpha raw data from wxImage, pack them into an array. +// unsigned char* img_rgb = image.GetData(); +// if (img_rgb == 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 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; +// } +// +// // sends data to gpu +// ::glGenTextures(1, &m_id); +// ::glBindTexture(GL_TEXTURE_2D, m_id); +// ::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); +// ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); +// ::glBindTexture(GL_TEXTURE_2D, 0); +// +// m_source = filename; +// return true; +//} +// +//void GLCanvas3D::GLTextureData::reset() +//{ +// if (m_id != 0) +// ::glDeleteTextures(1, &m_id); +// +// m_id = 0; +// m_width = 0; +// m_height = 0; +// m_source = ""; +//} +// +//unsigned int GLCanvas3D::GLTextureData::get_id() const +//{ +// return m_id; +//} +// +//int GLCanvas3D::GLTextureData::get_width() const +//{ +// return m_width; +//} +// +//int GLCanvas3D::GLTextureData::get_height() const +//{ +// return m_height; +//} +// +//const std::string& GLCanvas3D::GLTextureData::get_source() const +//{ +// return m_source; +//} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ GLCanvas3D::Camera::Camera() : type(Ortho) @@ -908,7 +918,10 @@ void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObje ::glLoadIdentity(); _render_tooltip_texture(canvas, bar_rect, reset_rect); - _render_reset_texture(canvas, reset_rect); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + _render_reset_texture(reset_rect); +// _render_reset_texture(canvas, reset_rect); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ _render_active_object_annotations(canvas, volume, print_object, bar_rect); _render_profile(print_object, bar_rect); @@ -1036,10 +1049,16 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas float t = reset_bottom + (float)m_tooltip_texture.get_height() * inv_zoom + gap; float b = reset_bottom + gap; - canvas.render_texture(m_tooltip_texture.get_id(), l, r, b, t); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GLTexture::render_texture(m_tooltip_texture.get_id(), l, r, b, t); +// canvas.render_texture(m_tooltip_texture.get_id(), l, r, b, t); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } -void GLCanvas3D::LayersEditing::_render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void GLCanvas3D::LayersEditing::_render_reset_texture(const Rect& reset_rect) const +//void GLCanvas3D::LayersEditing::_render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if (m_reset_texture.get_id() == 0) { @@ -1048,7 +1067,10 @@ void GLCanvas3D::LayersEditing::_render_reset_texture(const GLCanvas3D& canvas, return; } - canvas.render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GLTexture::render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); +// canvas.render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const @@ -1181,6 +1203,140 @@ bool GLCanvas3D::Mouse::is_start_position_3D_defined() const return (drag.start_position_3D != Drag::Invalid_3D_Point); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +const float GLCanvas3D::Gizmos::OverlayOffsetX = 10.0f; +const float GLCanvas3D::Gizmos::OverlayGapY = 10.0f; + +GLCanvas3D::Gizmos::Gizmos() + : m_enabled(false) + , m_current(None) +{ +} + +GLCanvas3D::Gizmos::~Gizmos() +{ + _reset(); +} + +bool GLCanvas3D::Gizmos::init() +{ + GLGizmoBase* gizmo = new GLGizmoScale; + if (gizmo == nullptr) + return false; + + if (!gizmo->init()) + return false; + + m_gizmos.insert(GizmosMap::value_type(Scale, gizmo)); + + gizmo = new GLGizmoRotate; + if (gizmo == nullptr) + { + _reset(); + return false; + } + + if (!gizmo->init()) + { + _reset(); + return false; + } + + m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo)); + + return true; +} + +bool GLCanvas3D::Gizmos::is_enabled() const +{ + return m_enabled; +} + +void GLCanvas3D::Gizmos::set_enabled(bool enable) +{ + m_enabled = enable; +} + +void GLCanvas3D::Gizmos::select(EType type) +{ + if (m_gizmos.find(type) != m_gizmos.end()) + m_current = type; +} + +void GLCanvas3D::Gizmos::reset_selection() +{ + m_current = None; +} + +void GLCanvas3D::Gizmos::render(const GLCanvas3D& canvas) const +{ + if (!m_enabled) + return; + + ::glDisable(GL_DEPTH_TEST); + + ::glPushMatrix(); + ::glLoadIdentity(); + + _render_overlay(canvas); + _render_current_gizmo(); + + ::glPopMatrix(); +} + +void GLCanvas3D::Gizmos::_reset() +{ + for (GizmosMap::value_type& gizmo : m_gizmos) + { + delete gizmo.second; + gizmo.second = nullptr; + } + + m_gizmos.clear(); +} + +void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas) const +{ + if (m_gizmos.empty()) + return; + + const Size& cnv_size = canvas.get_canvas_size(); + + float cnv_w = (float)cnv_size.get_width(); + + float zoom = canvas.get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + float total_h = 0.0f; + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + total_h += (float)it->second->get_textures_height(); + if (std::distance(it, m_gizmos.end()) > 1) + total_h += OverlayGapY; + } + + float top_x = (OverlayOffsetX - 0.5f * cnv_w) * inv_zoom; + float top_y = 0.5f * total_h * inv_zoom; + float scaled_gap_y = OverlayGapY * inv_zoom; + for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) + { + float tex_w = (float)it->second->get_textures_width() * inv_zoom; + float tex_h = (float)it->second->get_textures_height() * inv_zoom; + GLTexture::render_texture(it->second->get_textures_id(), top_x, top_x + tex_w, top_y - tex_h, top_y); + top_y -= (tex_h + scaled_gap_y); + } +} + +void GLCanvas3D::Gizmos::_render_current_gizmo() const +{ + GizmosMap::const_iterator it = m_gizmos.find(m_current); + if (it == m_gizmos.end()) + return; + + it->second->render(); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) : m_canvas(canvas) , m_context(context) @@ -1228,8 +1384,6 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) if (m_initialized) return true; - std::cout << "init: " << (void*)m_canvas << " (" << (void*)this << ")" << std::endl; - ::glClearColor(1.0f, 1.0f, 1.0f, 1.0f); ::glClearDepth(1.0f); @@ -1287,6 +1441,11 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) if (!m_volumes.empty()) m_volumes.finalize_geometry(m_use_VBOs); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_gizmos.is_enabled() && !m_gizmos.init()) + return false; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_initialized = true; return true; @@ -1528,6 +1687,13 @@ void GLCanvas3D::enable_moving(bool enable) m_moving_enabled = enable; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void GLCanvas3D::enable_gizmos(bool enable) +{ + m_gizmos.set_enabled(enable); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void GLCanvas3D::enable_shader(bool enable) { m_shader_enabled = enable; @@ -1645,34 +1811,39 @@ void GLCanvas3D::render() _render_warning_texture(); _render_legend_texture(); _render_layer_editing_overlay(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + _render_gizmo(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_canvas->SwapBuffers(); } -void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const -{ - ::glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - ::glDisable(GL_LIGHTING); - ::glEnable(GL_BLEND); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - ::glEnable(GL_TEXTURE_2D); - - ::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id); - - ::glBegin(GL_QUADS); - ::glTexCoord2d(0.0f, 1.0f); glVertex3f(left, bottom, 0.0f); - ::glTexCoord2d(1.0f, 1.0f); glVertex3f(right, bottom, 0.0f); - ::glTexCoord2d(1.0f, 0.0f); glVertex3f(right, top, 0.0f); - ::glTexCoord2d(0.0f, 0.0f); glVertex3f(left, top, 0.0f); - ::glEnd(); - - ::glBindTexture(GL_TEXTURE_2D, 0); - - ::glDisable(GL_TEXTURE_2D); - ::glDisable(GL_BLEND); - ::glEnable(GL_LIGHTING); -} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const +//{ +// ::glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +// +// ::glDisable(GL_LIGHTING); +// ::glEnable(GL_BLEND); +// ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// ::glEnable(GL_TEXTURE_2D); +// +// ::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id); +// +// ::glBegin(GL_QUADS); +// ::glTexCoord2d(0.0f, 1.0f); ::glVertex3f(left, bottom, 0.0f); +// ::glTexCoord2d(1.0f, 1.0f); ::glVertex3f(right, bottom, 0.0f); +// ::glTexCoord2d(1.0f, 0.0f); ::glVertex3f(right, top, 0.0f); +// ::glTexCoord2d(0.0f, 0.0f); ::glVertex3f(left, top, 0.0f); +// ::glEnd(); +// +// ::glBindTexture(GL_TEXTURE_2D, 0); +// +// ::glDisable(GL_TEXTURE_2D); +// ::glDisable(GL_BLEND); +// ::glEnable(GL_LIGHTING); +//} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector GLCanvas3D::get_current_print_zs(bool active_only) const { @@ -3130,7 +3301,10 @@ void GLCanvas3D::_render_warning_texture() const float r = l + (float)w * inv_zoom; float b = t - (float)h * inv_zoom; - render_texture(tex_id, l, r, b, t); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GLTexture::render_texture(tex_id, l, r, b, t); +// render_texture(tex_id, l, r, b, t); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ::glPopMatrix(); ::glEnable(GL_DEPTH_TEST); @@ -3162,7 +3336,10 @@ void GLCanvas3D::_render_legend_texture() const float t = (0.5f * (float)cnv_size.get_height()) * inv_zoom; float r = l + (float)w * inv_zoom; float b = t - (float)h * inv_zoom; - render_texture(tex_id, l, r, b, t); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GLTexture::render_texture(tex_id, l, r, b, t); +// render_texture(tex_id, l, r, b, t); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ::glPopMatrix(); ::glEnable(GL_DEPTH_TEST); @@ -3248,6 +3425,13 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const ::glEnable(GL_CULL_FACE); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void GLCanvas3D::_render_gizmo() const +{ + m_gizmos.render(*this); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + float GLCanvas3D::_get_layers_editing_cursor_z_relative() const { return m_layers_editing.get_cursor_z_relative(*this); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index d694db4e2..6421e44ec 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -2,6 +2,9 @@ #define slic3r_GLCanvas3D_hpp_ #include "../../slic3r/GUI/3DScene.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include "../../slic3r/GUI/GLTexture.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class wxTimer; class wxSizeEvent; @@ -18,6 +21,10 @@ class ExPolygon; namespace GUI { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +class GLGizmoBase; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + class GeometryBuffer { std::vector m_vertices; @@ -102,26 +109,28 @@ class GLCanvas3D void reset() { first_volumes.clear(); } }; - struct GLTextureData - { - private: - unsigned int m_id; - int m_width; - int m_height; - std::string m_source; - - public: - GLTextureData(); - ~GLTextureData(); - - bool load_from_file(const std::string& filename); - void reset(); - - unsigned int get_id() const; - int get_width() const; - int get_height() const; - const std::string& get_source() const; - }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// struct GLTextureData +// { +// private: +// unsigned int m_id; +// int m_width; +// int m_height; +// std::string m_source; +// +// public: +// GLTextureData(); +// ~GLTextureData(); +// +// bool load_from_file(const std::string& filename); +// void reset(); +// +// unsigned int get_id() const; +// int get_width() const; +// int get_height() const; +// const std::string& get_source() const; +// }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: struct Camera @@ -170,8 +179,12 @@ public: Polygon m_polygon; GeometryBuffer m_triangles; GeometryBuffer m_gridlines; - mutable GLTextureData m_top_texture; - mutable GLTextureData m_bottom_texture; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + mutable GLTexture m_top_texture; + mutable GLTexture m_bottom_texture; +// mutable GLTextureData m_top_texture; +// mutable GLTextureData m_bottom_texture; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: Bed(); @@ -266,8 +279,12 @@ public: bool m_enabled; Shader m_shader; unsigned int m_z_texture_id; - mutable GLTextureData m_tooltip_texture; - mutable GLTextureData m_reset_texture; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + mutable GLTexture m_tooltip_texture; + mutable GLTexture m_reset_texture; +// mutable GLTextureData m_tooltip_texture; +// mutable GLTextureData m_reset_texture; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public: EState state; @@ -306,7 +323,10 @@ public: private: bool _is_initialized() const; void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const; - void _render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void _render_reset_texture(const Rect& reset_rect) const; +// void _render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const; void _render_profile(const PrintObject& print_object, const Rect& bar_rect) const; }; @@ -340,6 +360,49 @@ public: bool is_start_position_3D_defined() const; }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + class Gizmos + { + static const float OverlayOffsetX; + static const float OverlayGapY; + + public: + enum EType : unsigned char + { + None, + Scale, + Rotate, + Num_Types + }; + + private: + bool m_enabled; + typedef std::map GizmosMap; + GizmosMap m_gizmos; + EType m_current; + + public: + Gizmos(); + ~Gizmos(); + + bool init(); + + bool is_enabled() const; + void set_enabled(bool enable); + + void select(EType type); + void reset_selection(); + + void render(const GLCanvas3D& canvas) const; + + private: + void _reset(); + + void _render_overlay(const GLCanvas3D& canvas) const; + void _render_current_gizmo() const; + }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + private: wxGLCanvas* m_canvas; wxGLContext* m_context; @@ -351,6 +414,9 @@ private: LayersEditing m_layers_editing; Shader m_shader; Mouse m_mouse; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + Gizmos m_gizmos; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ mutable GLVolumeCollection m_volumes; DynamicPrintConfig* m_config; @@ -455,6 +521,9 @@ public: void enable_legend_texture(bool enable); void enable_picking(bool enable); void enable_moving(bool enable); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void enable_gizmos(bool enable); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void enable_shader(bool enable); void enable_force_zoom_to_bed(bool enable); void allow_multisample(bool allow); @@ -467,7 +536,9 @@ public: void update_volumes_colors_by_extruder(); void render(); - void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +// void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector get_current_print_zs(bool active_only) const; void set_toolpaths_range(double low, double high); @@ -546,6 +617,9 @@ private: void _render_legend_texture() const; void _render_layer_editing_overlay() const; void _render_volumes(bool fake_colors) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void _render_gizmo() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ float _get_layers_editing_cursor_z_relative() const; int _get_layers_editing_first_selected_object_id(unsigned int objects_count) const; diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index b021e65a8..8a84d4cb5 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -159,8 +159,6 @@ bool GLCanvas3DManager::add(wxGLCanvas* canvas) canvas3D->bind_event_handlers(); m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D)); - std::cout << "canvas added: " << (void*)canvas << " (" << (void*)canvas3D << ")" << std::endl; - return true; } @@ -174,8 +172,6 @@ bool GLCanvas3DManager::remove(wxGLCanvas* canvas) delete it->second; m_canvases.erase(it); - std::cout << "canvas removed: " << (void*)canvas << std::endl; - return true; } @@ -183,8 +179,6 @@ void GLCanvas3DManager::remove_all() { for (CanvasesMap::value_type& item : m_canvases) { - std::cout << "canvas removed: " << (void*)item.second << std::endl; - item.second->unbind_event_handlers(); delete item.second; } @@ -200,8 +194,6 @@ void GLCanvas3DManager::init_gl() { if (!m_gl_initialized) { - std::cout << "GLCanvas3DManager::init_gl()" << std::endl; - glewInit(); if (m_gl_info.detect()) { @@ -209,10 +201,6 @@ void GLCanvas3DManager::init_gl() m_use_legacy_opengl = (config == nullptr) || (config->get("use_legacy_opengl") == "1"); m_use_VBOs = !m_use_legacy_opengl && m_gl_info.is_version_greater_or_equal_to(2, 0); m_gl_initialized = true; - - std::cout << "DETECTED OPENGL: " << m_gl_info.version << std::endl; - std::cout << "USE VBOS = " << (m_use_VBOs ? "YES" : "NO") << std::endl; - std::cout << "LAYER EDITING ALLOWED = " << (!m_use_legacy_opengl ? "YES" : "NO") << std::endl; } else throw std::runtime_error(std::string("Unable to initialize OpenGL driver\n")); @@ -439,6 +427,15 @@ void GLCanvas3DManager::enable_moving(wxGLCanvas* canvas, bool enable) it->second->enable_moving(enable); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +void GLCanvas3DManager::enable_gizmos(wxGLCanvas* canvas, bool enable) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->enable_gizmos(enable); +} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void GLCanvas3DManager::enable_shader(wxGLCanvas* canvas, bool enable) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 741c8e29b..9ec645c1a 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -110,6 +110,9 @@ public: void enable_legend_texture(wxGLCanvas* canvas, bool enable); void enable_picking(wxGLCanvas* canvas, bool enable); void enable_moving(wxGLCanvas* canvas, bool enable); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void enable_gizmos(wxGLCanvas* canvas, bool enable); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void enable_shader(wxGLCanvas* canvas, bool enable); void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable); void allow_multisample(wxGLCanvas* canvas, bool allow); diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp new file mode 100644 index 000000000..06ceee881 --- /dev/null +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -0,0 +1,109 @@ +#include "GLGizmo.hpp" + +#include "../../libslic3r/utils.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +GLGizmoBase::GLGizmoBase() + : m_state(Off) +{ +} + +GLGizmoBase::~GLGizmoBase() +{ +} + +GLGizmoBase::EState GLGizmoBase::get_state() const +{ + return m_state; +} + +unsigned int GLGizmoBase::get_textures_id() const +{ + return m_textures[m_state].get_id(); +} + +int GLGizmoBase::get_textures_height() const +{ + return m_textures[Off].get_height(); +} + +int GLGizmoBase::get_textures_width() const +{ + return m_textures[Off].get_width(); +} + +bool GLGizmoBase::init() +{ + return on_init(); +} + +GLGizmoRotate::GLGizmoRotate() + : GLGizmoBase() + , m_angle_x(0.0f) + , m_angle_y(0.0f) + , m_angle_z(0.0f) +{ +} + +void GLGizmoRotate::render() const +{ + std::cout << "GLGizmoRotate::render()" << std::endl; +} + +bool GLGizmoRotate::on_init() +{ + std::string path = resources_dir() + "/icons/overlay/"; + + std::string filename = path + "rotate_off.png"; + if (!m_textures[Off].load_from_file(filename)) + return false; + + filename = path + "rotate_hover.png"; + if (!m_textures[Hover].load_from_file(filename)) + return false; + + filename = path + "rotate_on.png"; + if (!m_textures[On].load_from_file(filename)) + return false; + + return true; +} + +GLGizmoScale::GLGizmoScale() + : GLGizmoBase() + , m_scale_x(1.0f) + , m_scale_y(1.0f) + , m_scale_z(1.0f) +{ +} + +void GLGizmoScale::render() const +{ + std::cout << "GLGizmoScale::render()" << std::endl; +} + +bool GLGizmoScale::on_init() +{ + std::string path = resources_dir() + "/icons/overlay/"; + + std::string filename = path + "scale_off.png"; + if (!m_textures[Off].load_from_file(filename)) + return false; + + filename = path + "scale_hover.png"; + if (!m_textures[Hover].load_from_file(filename)) + return false; + + filename = path + "scale_on.png"; + if (!m_textures[On].load_from_file(filename)) + return false; + + return true; +} + +} // namespace GUI +} // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp new file mode 100644 index 000000000..1da216ba9 --- /dev/null +++ b/xs/src/slic3r/GUI/GLGizmo.hpp @@ -0,0 +1,78 @@ +#ifndef slic3r_GLGizmo_hpp_ +#define slic3r_GLGizmo_hpp_ + +#include "../../slic3r/GUI/GLTexture.hpp" + +namespace Slic3r { +namespace GUI { + +class GLGizmoBase +{ +public: + enum EState + { + Off, + Hover, + On, + Num_States + }; + +protected: + EState m_state; + // textures are assumed to be all the same size in pixels + // no internal check is done + GLTexture m_textures[Num_States]; + +public: + GLGizmoBase(); + virtual ~GLGizmoBase(); + + bool init(); + + EState get_state() const; + + unsigned int get_textures_id() const; + int get_textures_height() const; + int get_textures_width() const; + + virtual void render() const = 0; + +protected: + virtual bool on_init() = 0; +}; + +class GLGizmoRotate : public GLGizmoBase +{ + float m_angle_x; + float m_angle_y; + float m_angle_z; + +public: + GLGizmoRotate(); + + void render() const; + +protected: + virtual bool on_init(); +}; + +class GLGizmoScale : public GLGizmoBase +{ + float m_scale_x; + float m_scale_y; + float m_scale_z; + +public: + GLGizmoScale(); + + void render() const; + +protected: + virtual bool on_init(); +}; + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GLGizmo_hpp_ + diff --git a/xs/src/slic3r/GUI/GLTexture.cpp b/xs/src/slic3r/GUI/GLTexture.cpp new file mode 100644 index 000000000..b9eb118a9 --- /dev/null +++ b/xs/src/slic3r/GUI/GLTexture.cpp @@ -0,0 +1,138 @@ +#include "GLTexture.hpp" + +#include + +#include + +#include + +namespace Slic3r { +namespace GUI { + +GLTexture::GLTexture() + : m_id(0) + , m_width(0) + , m_height(0) + , m_source("") +{ +} + +GLTexture::~GLTexture() +{ + reset(); +} + +bool GLTexture::load_from_file(const std::string& filename) +{ + reset(); + + // Load a PNG with an alpha channel. + wxImage image; + if (!image.LoadFile(filename, wxBITMAP_TYPE_PNG)) + { + reset(); + return false; + } + + m_width = image.GetWidth(); + m_height = image.GetHeight(); + int n_pixels = m_width * m_height; + + if (n_pixels <= 0) + { + reset(); + return false; + } + + // Get RGB & alpha raw data from wxImage, pack them into an array. + unsigned char* img_rgb = image.GetData(); + if (img_rgb == 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 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; + } + + // sends data to gpu + ::glGenTextures(1, &m_id); + ::glBindTexture(GL_TEXTURE_2D, m_id); + ::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); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); + ::glBindTexture(GL_TEXTURE_2D, 0); + + m_source = filename; + return true; +} + +void GLTexture::reset() +{ + if (m_id != 0) + ::glDeleteTextures(1, &m_id); + + m_id = 0; + m_width = 0; + m_height = 0; + m_source = ""; +} + +unsigned int GLTexture::get_id() const +{ + return m_id; +} + +int GLTexture::get_width() const +{ + return m_width; +} + +int GLTexture::get_height() const +{ + return m_height; +} + +const std::string& GLTexture::get_source() const +{ + return m_source; +} + +void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) +{ + ::glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + ::glDisable(GL_LIGHTING); + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + ::glEnable(GL_TEXTURE_2D); + + ::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id); + + ::glBegin(GL_QUADS); + ::glTexCoord2d(0.0f, 1.0f); ::glVertex3f(left, bottom, 0.0f); + ::glTexCoord2d(1.0f, 1.0f); ::glVertex3f(right, bottom, 0.0f); + ::glTexCoord2d(1.0f, 0.0f); ::glVertex3f(right, top, 0.0f); + ::glTexCoord2d(0.0f, 0.0f); ::glVertex3f(left, top, 0.0f); + ::glEnd(); + + ::glBindTexture(GL_TEXTURE_2D, 0); + + ::glDisable(GL_TEXTURE_2D); + ::glDisable(GL_BLEND); + ::glEnable(GL_LIGHTING); +} + +} // namespace GUI +} // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLTexture.hpp b/xs/src/slic3r/GUI/GLTexture.hpp new file mode 100644 index 000000000..3e3bf83f7 --- /dev/null +++ b/xs/src/slic3r/GUI/GLTexture.hpp @@ -0,0 +1,36 @@ +#ifndef slic3r_GLTexture_hpp_ +#define slic3r_GLTexture_hpp_ + +#include + +namespace Slic3r { +namespace GUI { + + struct GLTexture + { + private: + unsigned int m_id; + int m_width; + int m_height; + std::string m_source; + + public: + GLTexture(); + ~GLTexture(); + + bool load_from_file(const std::string& filename); + void reset(); + + unsigned int get_id() const; + int get_width() const; + int get_height() const; + const std::string& get_source() const; + + static void render_texture(unsigned int tex_id, float left, float right, float bottom, float top); + }; + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GLTexture_hpp_ + diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index c7f3670fc..426395ef2 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -410,6 +410,13 @@ enable_moving(canvas, enable) CODE: _3DScene::enable_moving((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable); +void +enable_gizmos(canvas, enable) + SV *canvas; + bool enable; + CODE: + _3DScene::enable_gizmos((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable); + void enable_shader(canvas, enable) SV *canvas;