Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2019-06-24 16:27:43 +0300
committerbubnikv <bubnikv@gmail.com>2019-06-24 16:27:43 +0300
commit5320ed9374d4559ac0fcc5a299bd79018ed9a1cb (patch)
treea130db0c7adfed8b5cf2ce63645387da36cf5927 /src/slic3r/GUI/GLCanvas3D.cpp
parent198600543dd707a51f29660c2583459ae2b34933 (diff)
parente737f15bfa68236d184dfba5861a3389fb903986 (diff)
Merge branch 'master' of https://github.com/Prusa3d/PrusaSlicer
Diffstat (limited to 'src/slic3r/GUI/GLCanvas3D.cpp')
-rw-r--r--src/slic3r/GUI/GLCanvas3D.cpp333
1 files changed, 114 insertions, 219 deletions
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 3d9b24c11..25319e9ce 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -17,6 +17,7 @@
#include "slic3r/GUI/GUI.hpp"
#include "slic3r/GUI/PresetBundle.hpp"
#include "slic3r/GUI/Tab.hpp"
+#include "slic3r/GUI/GUI_Preview.hpp"
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
#include "GUI_ObjectManipulation.hpp"
@@ -299,22 +300,10 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
const Rect& bar_rect = get_bar_rect_viewport(canvas);
const Rect& reset_rect = get_reset_rect_viewport(canvas);
- glsafe(::glDisable(GL_DEPTH_TEST));
-
- // The viewport and camera are set to complete view and glOrtho(-$x / 2, $x / 2, -$y / 2, $y / 2, -$depth, $depth),
- // where x, y is the window size divided by $self->_zoom.
- glsafe(::glPushMatrix());
- glsafe(::glLoadIdentity());
-
_render_tooltip_texture(canvas, bar_rect, reset_rect);
_render_reset_texture(reset_rect);
_render_active_object_annotations(canvas, bar_rect);
_render_profile(bar_rect);
-
- // Revert the matrices.
- glsafe(::glPopMatrix());
-
- glsafe(::glEnable(GL_DEPTH_TEST));
}
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
@@ -369,7 +358,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
float half_w = 0.5f * (float)cnv_size.get_width();
float half_h = 0.5f * (float)cnv_size.get_height();
- float zoom = canvas.get_camera().zoom;
+ float zoom = (float)canvas.get_camera().get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom);
@@ -381,7 +370,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas
float half_w = 0.5f * (float)cnv_size.get_width();
float half_h = 0.5f * (float)cnv_size.get_height();
- float zoom = canvas.get_camera().zoom;
+ float zoom = (float)canvas.get_camera().get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
@@ -400,7 +389,7 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas
if (m_tooltip_texture.get_id() == 0)
{
std::string filename = resources_dir() + "/icons/variable_layer_height_tooltip.png";
- if (!m_tooltip_texture.load_from_file(filename, false))
+ if (!m_tooltip_texture.load_from_file(filename, false, true))
return;
}
@@ -412,7 +401,7 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas
const float width = (float)m_tooltip_texture.get_width() * scale;
const float height = (float)m_tooltip_texture.get_height() * scale;
- float zoom = canvas.get_camera().zoom;
+ float zoom = (float)canvas.get_camera().get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float gap = 10.0f * inv_zoom;
@@ -432,7 +421,7 @@ void GLCanvas3D::LayersEditing::_render_reset_texture(const Rect& reset_rect) co
if (m_reset_texture.get_id() == 0)
{
std::string filename = resources_dir() + "/icons/variable_layer_height_reset.png";
- if (!m_reset_texture.load_from_file(filename, false))
+ if (!m_reset_texture.load_from_file(filename, false, true))
return;
}
@@ -727,7 +716,7 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool
}
}
- _generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...)
+ generate(text, canvas, true, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...)
// save information for rescaling
m_msg_text = text;
@@ -788,7 +777,7 @@ static void msw_disable_cleartype(wxFont &font)
}
#endif /* __WXMSW__ */
-bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GLCanvas3D& canvas, const bool red_colored/* = false*/)
+bool GLCanvas3D::WarningTexture::generate(const std::string& msg_utf8, const GLCanvas3D& canvas, bool compress, bool red_colored/* = false*/)
{
reset();
@@ -862,7 +851,10 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
- glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
+ if (compress && GLEW_EXT_texture_compression_s3tc)
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
+ else
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
@@ -878,12 +870,8 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
{
- glsafe(::glDisable(GL_DEPTH_TEST));
- glsafe(::glPushMatrix());
- glsafe(::glLoadIdentity());
-
const Size& cnv_size = canvas.get_canvas_size();
- float zoom = canvas.get_camera().zoom;
+ float zoom = (float)canvas.get_camera().get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float left = (-0.5f * (float)m_original_width) * inv_zoom;
float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom;
@@ -902,9 +890,6 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
uvs.right_top = { uv_right, uv_top };
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
-
- glsafe(::glPopMatrix());
- glsafe(::glEnable(GL_DEPTH_TEST));
}
}
@@ -913,7 +898,7 @@ void GLCanvas3D::WarningTexture::msw_rescale(const GLCanvas3D& canvas)
if (m_msg_text.empty())
return;
- _generate(m_msg_text, canvas, m_is_colored_red);
+ generate(m_msg_text, canvas, true, m_is_colored_red);
}
const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 };
@@ -956,7 +941,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie
}
}
-bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas)
+bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool compress)
{
reset();
@@ -1145,7 +1130,10 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
- glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
+ if (compress && GLEW_EXT_texture_compression_s3tc)
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
+ else
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
@@ -1158,12 +1146,8 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
{
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
{
- glsafe(::glDisable(GL_DEPTH_TEST));
- glsafe(::glPushMatrix());
- glsafe(::glLoadIdentity());
-
const Size& cnv_size = canvas.get_canvas_size();
- float zoom = canvas.get_camera().zoom;
+ float zoom = (float)canvas.get_camera().get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom;
@@ -1182,9 +1166,6 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
uvs.right_top = { uv_right, uv_top };
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
-
- glsafe(::glPopMatrix());
- glsafe(::glEnable(GL_DEPTH_TEST));
}
}
@@ -1209,6 +1190,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
+wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
: m_canvas(canvas)
@@ -1227,6 +1209,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar
#endif // ENABLE_SVG_ICONS
, m_use_clipping_planes(false)
, m_sidebar_field("")
+ , m_keep_dirty(false)
, m_config(nullptr)
, m_process(nullptr)
, m_model(nullptr)
@@ -1444,6 +1427,8 @@ void GLCanvas3D::bed_shape_changed()
m_camera.set_scene_box(scene_bounding_box());
m_camera.requires_zoom_to_bed = true;
m_dirty = true;
+ if (m_bed.is_prusa())
+ start_keeping_dirty();
}
void GLCanvas3D::set_color_by(const std::string& value)
@@ -1465,7 +1450,7 @@ BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
{
BoundingBoxf3 bb = volumes_bounding_box();
- bb.merge(m_bed.get_bounding_box());
+ bb.merge(m_bed.get_bounding_box(false));
if (m_config != nullptr)
{
@@ -1473,6 +1458,7 @@ BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
bb.min(2) = std::min(bb.min(2), -h);
bb.max(2) = std::max(bb.max(2), h);
}
+
return bb;
}
@@ -1548,20 +1534,20 @@ void GLCanvas3D::allow_multisample(bool allow)
void GLCanvas3D::zoom_to_bed()
{
- _zoom_to_bounding_box(m_bed.get_bounding_box());
+ _zoom_to_box(m_bed.get_bounding_box(false));
}
void GLCanvas3D::zoom_to_volumes()
{
m_apply_zoom_to_volumes_filter = true;
- _zoom_to_bounding_box(volumes_bounding_box());
+ _zoom_to_box(volumes_bounding_box());
m_apply_zoom_to_volumes_filter = false;
}
void GLCanvas3D::zoom_to_selection()
{
if (!m_selection.is_empty())
- _zoom_to_bounding_box(m_selection.get_bounding_box());
+ _zoom_to_box(m_selection.get_bounding_box());
}
void GLCanvas3D::select_view(const std::string& direction)
@@ -1622,6 +1608,7 @@ void GLCanvas3D::render()
}
m_camera.apply_view_matrix();
+ m_camera.apply_projection(_max_bounding_box(true));
GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam));
@@ -1683,29 +1670,31 @@ void GLCanvas3D::render()
m_rectangle_selection.render(*this);
// draw overlays
- _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) && (m_layers_editing.object_max_z() > 0.0f))
- m_layers_editing.render_overlay(*this);
+ _render_overlays();
#if ENABLE_RENDER_STATISTICS
ImGuiWrapper& imgui = *wxGetApp().imgui();
imgui.set_next_window_bg_alpha(0.5f);
imgui.begin(std::string("Render statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
- imgui.text(_(L("Last frame")) +": ");
+ imgui.text("Last frame: ");
ImGui::SameLine();
imgui.text(std::to_string(m_render_stats.last_frame));
ImGui::SameLine();
- imgui.text(" "+_(L("ms")));
+ imgui.text(" ms");
+ ImGui::Separator();
+ imgui.text("Compressed textures: ");
+ ImGui::SameLine();
+ imgui.text(GLCanvas3DManager::are_compressed_textures_supported() ? "supported" : "not supported");
+ imgui.text("Max texture size: ");
+ ImGui::SameLine();
+ imgui.text(std::to_string(GLCanvas3DManager::get_gl_info().get_max_tex_size()));
imgui.end();
#endif // ENABLE_RENDER_STATISTICS
+#if ENABLE_CAMERA_STATISTICS
+ m_camera.debug_render();
+#endif // ENABLE_CAMERA_STATISTICS
+
wxGetApp().imgui()->render();
m_canvas->SwapBuffers();
@@ -2309,6 +2298,9 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
return;
_refresh_if_shown_on_screen();
+
+ if (m_keep_dirty)
+ m_dirty = true;
}
void GLCanvas3D::on_char(wxKeyEvent& evt)
@@ -2387,17 +2379,29 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case '4': { select_view("rear"); break; }
case '5': { select_view("left"); break; }
case '6': { select_view("right"); break; }
- case '+': { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; }
- case '-': { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; }
+ case '+': {
+ if (dynamic_cast<Preview*>(m_canvas->GetParent()) != nullptr)
+ post_event(wxKeyEvent(EVT_GLCANVAS_EDIT_COLOR_CHANGE, evt));
+ else
+ post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, +1));
+ break; }
+ case '-': {
+ if (dynamic_cast<Preview*>(m_canvas->GetParent()) != nullptr)
+ post_event(wxKeyEvent(EVT_GLCANVAS_EDIT_COLOR_CHANGE, evt));
+ else
+ post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1));
+ break; }
case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; }
case 'A':
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
case 'B':
case 'b': { zoom_to_bed(); break; }
case 'I':
- case 'i': { set_camera_zoom(1.0f); break; }
+ case 'i': { set_camera_zoom(1.0); break; }
+ case 'K':
+ case 'k': { m_camera.select_next_type(); m_dirty = true; break; }
case 'O':
- case 'o': { set_camera_zoom(-1.0f); break; }
+ case 'o': { set_camera_zoom(-1.0); break; }
case 'Z':
case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; }
default: { evt.Skip(); break; }
@@ -2472,15 +2476,10 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
else if (keyCode == WXK_LEFT ||
keyCode == WXK_RIGHT ||
keyCode == WXK_UP ||
- keyCode == WXK_DOWN ||
- keyCode == '+' ||
- keyCode == WXK_NUMPAD_ADD ||
- keyCode == '-' ||
- keyCode == 390 ||
- keyCode == WXK_DELETE ||
- keyCode == WXK_BACK )
+ keyCode == WXK_DOWN )
{
- post_event(wxKeyEvent(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, evt));
+ if (dynamic_cast<Preview*>(m_canvas->GetParent()) != nullptr)
+ post_event(wxKeyEvent(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, evt));
}
}
}
@@ -2523,7 +2522,7 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
m_layers_editing.band_width = std::max(std::min(m_layers_editing.band_width * (1.0f + 0.1f * (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta()), 10.0f), 1.5f);
if (m_canvas != nullptr)
m_canvas->Refresh();
-
+
return;
}
}
@@ -2534,8 +2533,7 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
return;
// Calculate the zoom delta and apply it to the current zoom factor
- float zoom = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
- set_camera_zoom(zoom);
+ set_camera_zoom((double)evt.GetWheelRotation() / (double)evt.GetWheelDelta());
}
void GLCanvas3D::on_timer(wxTimerEvent& evt)
@@ -3287,21 +3285,11 @@ void GLCanvas3D::do_mirror()
post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}
-void GLCanvas3D::set_camera_zoom(float zoom)
+void GLCanvas3D::set_camera_zoom(double zoom)
{
- zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f;
- zoom = m_camera.zoom / (1.0f - zoom);
-
- // Don't allow to zoom too far outside the scene.
- float zoom_min = _get_zoom_to_bounding_box_factor(_max_bounding_box());
- if (zoom_min > 0.0f)
- zoom = std::max(zoom, zoom_min * 0.7f);
-
- // Don't allow to zoom too close to the scene.
- zoom = std::min(zoom, 100.0f);
-
- m_camera.zoom = zoom;
- _refresh_if_shown_on_screen();
+ const Size& cnv_size = get_canvas_size();
+ m_camera.set_zoom(zoom, _max_bounding_box(false), cnv_size.get_width(), cnv_size.get_height());
+ m_dirty = true;
}
void GLCanvas3D::update_gizmos_on_off_state()
@@ -3335,8 +3323,7 @@ void GLCanvas3D::update_ui_from_settings()
if (new_scaling != orig_scaling) {
BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << new_scaling;
- m_camera.zoom /= orig_scaling;
- m_camera.zoom *= new_scaling;
+ m_camera.set_zoom(m_camera.get_zoom() * new_scaling / orig_scaling);
_refresh_if_shown_on_screen();
}
#endif
@@ -3383,7 +3370,7 @@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
{
- return factor * m_bed.get_bounding_box().max_size();
+ return factor * m_bed.get_bounding_box(false).max_size();
}
void GLCanvas3D::set_cursor(ECursorType type)
@@ -3501,7 +3488,7 @@ bool GLCanvas3D::_init_toolbar()
item.tooltip = _utf8(L("Copy")) + " [" + GUI::shortkey_ctrl_prefix() + "C]";
item.sprite_id = 4;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); };
- item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_copy(); };
+ item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_copy_to_clipboard(); };
if (!m_toolbar.add_item(item))
return false;
@@ -3512,7 +3499,7 @@ bool GLCanvas3D::_init_toolbar()
item.tooltip = _utf8(L("Paste")) + " [" + GUI::shortkey_ctrl_prefix() + "V]";
item.sprite_id = 5;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); };
- item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_paste(); };
+ item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_paste_from_clipboard(); };
if (!m_toolbar.add_item(item))
return false;
@@ -3614,143 +3601,25 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
// ensures that this canvas is current
_set_current();
- m_camera.apply_viewport(0, 0, w, h);
-
- const BoundingBoxf3& bbox = _max_bounding_box();
-
- switch (m_camera.type)
- {
- case Camera::Ortho:
- {
- float w2 = w;
- float h2 = h;
- float two_zoom = 2.0f * m_camera.zoom;
- if (two_zoom != 0.0f)
- {
- float inv_two_zoom = 1.0f / two_zoom;
- w2 *= inv_two_zoom;
- h2 *= inv_two_zoom;
- }
-
- // FIXME: calculate a tighter value for depth will improve z-fighting
- // Set at least some minimum depth in case the bounding box is empty to avoid an OpenGL driver error.
- float depth = std::max(1.f, 5.0f * (float)bbox.max_size());
- m_camera.apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth);
- break;
- }
-// case Camera::Perspective:
-// {
-// float bbox_r = (float)bbox.radius();
-// float fov = PI * 45.0f / 180.0f;
-// float fov_tan = tan(0.5f * fov);
-// float cam_distance = 0.5f * bbox_r / fov_tan;
-// m_camera.distance = cam_distance;
-//
-// float nr = cam_distance - bbox_r * 1.1f;
-// float fr = cam_distance + bbox_r * 1.1f;
-// if (nr < 1.0f)
-// nr = 1.0f;
-//
-// if (fr < nr + 1.0f)
-// fr = nr + 1.0f;
-//
-// float h2 = fov_tan * nr;
-// float w2 = h2 * w / h;
-// ::glFrustum(-w2, w2, -h2, h2, nr, fr);
-//
-// break;
-// }
- default:
- {
- throw std::runtime_error("Invalid camera type.");
- break;
- }
- }
+ // updates camera
+ m_camera.apply_viewport(0, 0, w, h);
m_dirty = false;
}
-BoundingBoxf3 GLCanvas3D::_max_bounding_box() const
+BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_bed_model) const
{
BoundingBoxf3 bb = volumes_bounding_box();
- bb.merge(m_bed.get_bounding_box());
+ bb.merge(m_bed.get_bounding_box(include_bed_model));
return bb;
}
-void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox)
-{
- // Calculate the zoom factor needed to adjust viewport to bounding box.
- float zoom = _get_zoom_to_bounding_box_factor(bbox);
- if (zoom > 0.0f)
- {
- m_camera.zoom = zoom;
- // center view around bounding box center
- m_camera.set_target(bbox.center());
- m_dirty = true;
- }
-}
-
-float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const
+void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box)
{
- float max_bb_size = bbox.max_size();
- if (max_bb_size == 0.0f)
- return -1.0f;
-
- // project the bbox vertices on a plane perpendicular to the camera forward axis
- // then calculates the vertices coordinate on this plane along the camera xy axes
-
- // we need the view matrix, we let opengl calculate it (same as done in render())
- m_camera.apply_view_matrix();
-
- Vec3d right = m_camera.get_dir_right();
- Vec3d up = m_camera.get_dir_up();
- Vec3d forward = m_camera.get_dir_forward();
-
- Vec3d bb_min = bbox.min;
- Vec3d bb_max = bbox.max;
- Vec3d bb_center = bbox.center();
-
- // bbox vertices in world space
- std::vector<Vec3d> vertices;
- vertices.reserve(8);
- vertices.push_back(bb_min);
- vertices.emplace_back(bb_max(0), bb_min(1), bb_min(2));
- vertices.emplace_back(bb_max(0), bb_max(1), bb_min(2));
- vertices.emplace_back(bb_min(0), bb_max(1), bb_min(2));
- vertices.emplace_back(bb_min(0), bb_min(1), bb_max(2));
- vertices.emplace_back(bb_max(0), bb_min(1), bb_max(2));
- vertices.push_back(bb_max);
- vertices.emplace_back(bb_min(0), bb_max(1), bb_max(2));
-
- double max_x = 0.0;
- double max_y = 0.0;
-
- // margin factor to give some empty space around the bbox
- double margin_factor = 1.25;
-
- for (const Vec3d& v : vertices)
- {
- // project vertex on the plane perpendicular to camera forward axis
- Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2));
- Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
-
- // calculates vertex coordinate along camera xy axes
- double x_on_plane = proj_on_plane.dot(right);
- double y_on_plane = proj_on_plane.dot(up);
-
- max_x = std::max(max_x, margin_factor * std::abs(x_on_plane));
- max_y = std::max(max_y, margin_factor * std::abs(y_on_plane));
- }
-
- if ((max_x == 0.0) || (max_y == 0.0))
- return -1.0f;
-
- max_x *= 2.0;
- max_y *= 2.0;
-
const Size& cnv_size = get_canvas_size();
- return (float)std::min((double)cnv_size.get_width() / max_x, (double)cnv_size.get_height() / max_y);
+ m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height());
+ m_dirty = true;
}
void GLCanvas3D::_refresh_if_shown_on_screen()
@@ -3936,7 +3805,7 @@ void GLCanvas3D::_render_bed(float theta) const
#if ENABLE_RETINA_GL
scale_factor = m_retina_helper->get_scale_factor();
#endif // ENABLE_RETINA_GL
- m_bed.render(theta, m_use_VBOs, scale_factor);
+ m_bed.render(const_cast<GLCanvas3D*>(this), theta, m_use_VBOs, scale_factor);
}
void GLCanvas3D::_render_axes() const
@@ -3965,7 +3834,7 @@ void GLCanvas3D::_render_objects() const
if (m_config != nullptr)
{
- const BoundingBoxf3& bed_bb = m_bed.get_bounding_box();
+ const BoundingBoxf3& bed_bb = m_bed.get_bounding_box(false);
m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height"));
m_volumes.check_outside_state(m_config, nullptr);
}
@@ -4047,6 +3916,32 @@ void GLCanvas3D::_render_selection_center() const
}
#endif // ENABLE_RENDER_SELECTION_CENTER
+void GLCanvas3D::_render_overlays() const
+{
+ glsafe(::glDisable(GL_DEPTH_TEST));
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
+ // ensure that the textures are renderered inside the frustrum
+ glsafe(::glTranslated(0.0, 0.0, -(m_camera.get_near_z() + 0.5)));
+ // ensure that the overlay fits the frustrum near z plane
+ double gui_scale = m_camera.get_gui_scale();
+ glsafe(::glScaled(gui_scale, gui_scale, 1.0));
+
+ _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) && (m_layers_editing.object_max_z() > 0.0f))
+ m_layers_editing.render_overlay(*this);
+
+ glsafe(::glPopMatrix());
+}
+
void GLCanvas3D::_render_warning_texture() const
{
m_warning_texture.render(*this);
@@ -4143,7 +4038,7 @@ void GLCanvas3D::_render_toolbar() const
#endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size();
- float zoom = m_camera.zoom;
+ float zoom = (float)m_camera.get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation();
@@ -4211,7 +4106,7 @@ void GLCanvas3D::_render_view_toolbar() const
#endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size();
- float zoom = m_camera.zoom;
+ float zoom = (float)m_camera.get_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
// places the toolbar on the bottom-left corner of the 3d scene
@@ -5704,7 +5599,7 @@ std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& col
void GLCanvas3D::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
{
- m_legend_texture.generate(preview_data, tool_colors, *this);
+ m_legend_texture.generate(preview_data, tool_colors, *this, true);
}
void GLCanvas3D::_set_warning_texture(WarningTexture::Warning warning, bool state)