From 54fae970329609c1231e475095aa80d3d28e54ef Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 20 Dec 2018 11:14:53 +0100 Subject: [PATCH] Visual hints in the 3D scene when sidebar matrix fields have focus -> Completed VBOs case --- src/libslic3r/Technologies.hpp | 2 +- src/slic3r/GUI/3DScene.cpp | 160 +++++++++++++++++++++++++++++++-- src/slic3r/GUI/3DScene.hpp | 18 +++- src/slic3r/GUI/GLCanvas3D.cpp | 76 +++++++++------- src/slic3r/GUI/GLCanvas3D.hpp | 9 +- 5 files changed, 214 insertions(+), 51 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 797272223..5d49c3675 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -43,7 +43,7 @@ // Renders a small sphere in the center of the bounding box of the current selection when no gizmo is active #define ENABLE_RENDER_SELECTION_CENTER (0 && ENABLE_1_42_0) // Show visual hints in the 3D scene when sidebar matrix fields have focus -#define ENABLE_SIDEBAR_VISUAL_HINTS (0 && ENABLE_1_42_0) +#define ENABLE_SIDEBAR_VISUAL_HINTS (1 && ENABLE_1_42_0) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 012203450..b431cf8bc 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1872,6 +1872,7 @@ GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; GLModel::GLModel() : m_useVBOs(false) { + m_volume.shader_outside_printer_detection_enabled = false; } GLModel::~GLModel() @@ -1879,11 +1880,36 @@ GLModel::~GLModel() m_volume.release_geometry(); } -void GLModel::set_color(float* color, unsigned int size) +void GLModel::set_color(const float* color, unsigned int size) { m_volume.set_render_color(color, size); } +const Vec3d& GLModel::get_offset() const +{ + return m_volume.get_volume_offset(); +} + +void GLModel::set_offset(const Vec3d& offset) +{ + m_volume.set_volume_offset(offset); +} + +const Vec3d& GLModel::get_rotation() const +{ + return m_volume.get_volume_rotation(); +} + +void GLModel::set_rotation(const Vec3d& rotation) +{ + m_volume.set_volume_rotation(rotation); +} + +const Vec3d& GLModel::get_scale() const +{ + return m_volume.get_volume_scaling_factor(); +} + void GLModel::set_scale(const Vec3d& scale) { m_volume.set_volume_scaling_factor(scale); @@ -1910,8 +1936,9 @@ void GLModel::render_VBOs() const GLint current_program_id; ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; + GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; - m_volume.render_VBOs(color_id, -1, -1); + m_volume.render_VBOs(color_id, print_box_detection_id, -1); ::glBindBuffer(GL_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -1922,17 +1949,12 @@ void GLModel::render_VBOs() const ::glDisable(GL_BLEND); } -GLArrow::GLArrow() - : GLModel() -{ -} - bool GLArrow::on_init(bool useVBOs) { Pointf3s vertices; std::vector triangles; - // top face + // bottom face vertices.emplace_back(0.5, 0.0, -0.1); vertices.emplace_back(0.5, 2.0, -0.1); vertices.emplace_back(1.0, 2.0, -0.1); @@ -1941,7 +1963,7 @@ bool GLArrow::on_init(bool useVBOs) vertices.emplace_back(-0.5, 2.0, -0.1); vertices.emplace_back(-0.5, 0.0, -0.1); - // bottom face + // top face vertices.emplace_back(0.5, 0.0, 0.1); vertices.emplace_back(0.5, 2.0, 0.1); vertices.emplace_back(1.0, 2.0, 0.1); @@ -1990,6 +2012,126 @@ bool GLArrow::on_init(bool useVBOs) m_volume.finalize_geometry(m_useVBOs); return true; } + +GLCurvedArrow::GLCurvedArrow(unsigned int resolution) + : GLModel() + , m_resolution(resolution) +{ + if (m_resolution == 0) + m_resolution = 1; +} + +bool GLCurvedArrow::on_init(bool useVBOs) +{ + Pointf3s vertices; + std::vector triangles; + + double ext_radius = 2.5; + double int_radius = 1.5; + double step = 0.5 * (double)PI / (double)m_resolution; + + unsigned int vertices_per_level = 4 + 2 * m_resolution; + + // bottom face + vertices.emplace_back(0.0, 1.5, -0.1); + vertices.emplace_back(0.0, 1.0, -0.1); + vertices.emplace_back(-1.0, 2.0, -0.1); + vertices.emplace_back(0.0, 3.0, -0.1); + vertices.emplace_back(0.0, 2.5, -0.1); + + for (unsigned int i = 1; i <= m_resolution; ++i) + { + double angle = (double)i * step; + double x = ext_radius * ::sin(angle); + double y = ext_radius * ::cos(angle); + + vertices.emplace_back(x, y, -0.1); + } + + for (unsigned int i = 0; i < m_resolution; ++i) + { + double angle = (double)i * step; + double x = int_radius * ::cos(angle); + double y = int_radius * ::sin(angle); + + vertices.emplace_back(x, y, -0.1); + } + + // top face + vertices.emplace_back(0.0, 1.5, 0.1); + vertices.emplace_back(0.0, 1.0, 0.1); + vertices.emplace_back(-1.0, 2.0, 0.1); + vertices.emplace_back(0.0, 3.0, 0.1); + vertices.emplace_back(0.0, 2.5, 0.1); + + for (unsigned int i = 1; i <= m_resolution; ++i) + { + double angle = (double)i * step; + double x = ext_radius * ::sin(angle); + double y = ext_radius * ::cos(angle); + + vertices.emplace_back(x, y, 0.1); + } + + for (unsigned int i = 0; i < m_resolution; ++i) + { + double angle = (double)i * step; + double x = int_radius * ::cos(angle); + double y = int_radius * ::sin(angle); + + vertices.emplace_back(x, y, 0.1); + } + + // bottom face + triangles.emplace_back(0, 1, 2); + triangles.emplace_back(0, 2, 4); + triangles.emplace_back(4, 2, 3); + + int first_id = 4; + int last_id = (int)vertices_per_level; + triangles.emplace_back(last_id, 0, first_id); + triangles.emplace_back(last_id, first_id, first_id + 1); + for (unsigned int i = 1; i < m_resolution; ++i) + { + triangles.emplace_back(last_id - i, last_id - i + 1, first_id + i); + triangles.emplace_back(last_id - i, first_id + i, first_id + i + 1); + } + + // top face + last_id += 1; + triangles.emplace_back(last_id + 0, last_id + 2, last_id + 1); + triangles.emplace_back(last_id + 0, last_id + 4, last_id + 2); + triangles.emplace_back(last_id + 4, last_id + 3, last_id + 2); + + first_id = last_id + 4; + last_id = last_id + 4 + 2 * (int)m_resolution; + triangles.emplace_back(last_id, first_id, (int)vertices_per_level + 1); + triangles.emplace_back(last_id, first_id + 1, first_id); + for (unsigned int i = 1; i < m_resolution; ++i) + { + triangles.emplace_back(last_id - i, first_id + i, last_id - i + 1); + triangles.emplace_back(last_id - i, first_id + i + 1, first_id + i); + } + + // side face + for (unsigned int i = 0; i < 4 + 2 * (int)m_resolution; ++i) + { + triangles.emplace_back(i, vertices_per_level + 2 + i, i + 1); + triangles.emplace_back(i, vertices_per_level + 1 + i, vertices_per_level + 2 + i); + } + triangles.emplace_back(vertices_per_level, vertices_per_level + 1, 0); + triangles.emplace_back(vertices_per_level, 2 * vertices_per_level + 1, vertices_per_level + 1); + + m_useVBOs = useVBOs; + + if (m_useVBOs) + m_volume.indexed_vertex_array.load_mesh_full_shading(TriangleMesh(vertices, triangles)); + else + m_volume.indexed_vertex_array.load_mesh_flat_shading(TriangleMesh(vertices, triangles)); + + m_volume.finalize_geometry(m_useVBOs); + return true; +} #endif // ENABLE_SIDEBAR_VISUAL_HINTS std::string _3DScene::get_gl_info(bool format_as_html, bool extensions) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 22b80d627..09bb54e2f 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -595,7 +595,13 @@ public: bool init(bool useVBOs) { return on_init(useVBOs); } - void set_color(float* color, unsigned int size); + void set_color(const float* color, unsigned int size); + + const Vec3d& get_offset() const; + void set_offset(const Vec3d& offset); + const Vec3d& get_rotation() const; + void set_rotation(const Vec3d& rotation); + const Vec3d& get_scale() const; void set_scale(const Vec3d& scale); void render() const; @@ -609,8 +615,16 @@ private: class GLArrow : public GLModel { +protected: + virtual bool on_init(bool useVBOs); +}; + +class GLCurvedArrow : public GLModel +{ + unsigned int m_resolution; + public: - GLArrow(); + explicit GLCurvedArrow(unsigned int resolution); protected: virtual bool on_init(bool useVBOs); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3c4debba0..77d0f0776 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -73,6 +73,11 @@ static const float DEFAULT_BG_LIGHT_COLOR[3] = { 0.753f, 0.753f, 0.753f }; static const float ERROR_BG_DARK_COLOR[3] = { 0.478f, 0.192f, 0.039f }; static const float ERROR_BG_LIGHT_COLOR[3] = { 0.753f, 0.192f, 0.039f }; +#if ENABLE_SIDEBAR_VISUAL_HINTS +static const float UNIFORM_SCALE_COLOR[3] = { 1.0f, 0.38f, 0.0f }; +static const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; +#endif // ENABLE_SIDEBAR_VISUAL_HINTS + namespace Slic3r { namespace GUI { @@ -1154,12 +1159,6 @@ GLCanvas3D::Selection::VolumeCache::VolumeCache(const Vec3d& position, const Vec } #endif // ENABLE_MODELVOLUME_TRANSFORM -#if ENABLE_SIDEBAR_VISUAL_HINTS -const float GLCanvas3D::Selection::RED[3] = { 1.0f, 0.0f, 0.0f }; -const float GLCanvas3D::Selection::GREEN[3] = { 0.0f, 1.0f, 0.0f }; -const float GLCanvas3D::Selection::BLUE[3] = { 0.0f, 0.0f, 1.0f }; -#endif // ENABLE_SIDEBAR_VISUAL_HINTS - GLCanvas3D::Selection::Selection() : m_volumes(nullptr) , m_model(nullptr) @@ -1167,6 +1166,7 @@ GLCanvas3D::Selection::Selection() , m_type(Empty) , m_valid(false) , m_bounding_box_dirty(true) + , m_curved_arrow(16) { #if ENABLE_RENDER_SELECTION_CENTER m_quadric = ::gluNewQuadric(); @@ -1192,13 +1192,16 @@ void GLCanvas3D::Selection::set_volumes(GLVolumePtrs* volumes) #if ENABLE_SIDEBAR_VISUAL_HINTS bool GLCanvas3D::Selection::init(bool useVBOs) { - if (m_arrow.init(useVBOs)) - { - m_arrow.set_scale(5.0 * Vec3d::Ones()); - return true; - } + if (!m_arrow.init(useVBOs)) + return false; - return false; + m_arrow.set_scale(5.0 * Vec3d::Ones()); + + if (!m_curved_arrow.init(useVBOs)) + return false; + + m_curved_arrow.set_scale(5.0 * Vec3d::Ones()); + return true; } #endif // ENABLE_SIDEBAR_VISUAL_HINTS @@ -2094,14 +2097,22 @@ void GLCanvas3D::Selection::render_sidebar_hints(const std::string& sidebar_fiel else if (is_single_volume() || is_single_modifier()) { const GLVolume* volume = (*m_volumes)[*m_list.begin()]; - Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true) * volume->get_volume_transformation().get_matrix(true, false, true, true); + Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true); const Vec3d& offset = get_bounding_box().center(); ::glTranslated(offset(0), offset(1), offset(2)); ::glMultMatrixd(orient_matrix.data()); } else + { ::glTranslated(center(0), center(1), center(2)); + if (requires_local_axes()) + { + const GLVolume* volume = (*m_volumes)[*m_list.begin()]; + Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true); + ::glMultMatrixd(orient_matrix.data()); + } + } if (boost::starts_with(sidebar_field, "position")) _render_sidebar_position_hints(sidebar_field); @@ -2544,6 +2555,18 @@ void GLCanvas3D::Selection::_render_sidebar_position_hints(const std::string& si void GLCanvas3D::Selection::_render_sidebar_rotation_hints(const std::string& sidebar_field) const { + if (boost::ends_with(sidebar_field, "x")) + { + ::glRotated(90.0, 0.0, 1.0, 0.0); + _render_sidebar_rotation_hint(X); + } + else if (boost::ends_with(sidebar_field, "y")) + { + ::glRotated(-90.0, 1.0, 0.0, 0.0); + _render_sidebar_rotation_hint(Y); + } + else if (boost::ends_with(sidebar_field, "z")) + _render_sidebar_rotation_hint(Z); } void GLCanvas3D::Selection::_render_sidebar_scale_hints(const std::string& sidebar_field) const @@ -2579,33 +2602,22 @@ void GLCanvas3D::Selection::_render_sidebar_size_hints(const std::string& sideba void GLCanvas3D::Selection::_render_sidebar_position_hint(Axis axis) const { - float color[3]; - switch (axis) - { - case X: { ::memcpy((void*)color, (const void*)RED, 3 * sizeof(float)); break; } - case Y: { ::memcpy((void*)color, (const void*)GREEN, 3 * sizeof(float)); break; } - case Z: { ::memcpy((void*)color, (const void*)BLUE, 3 * sizeof(float)); break; } - } - - m_arrow.set_color(color, 3); + m_arrow.set_color(AXES_COLOR[axis], 3); m_arrow.render(); } -void GLCanvas3D::Selection::_render_sidebar_rotation_hint(Axis axis, double length) const +void GLCanvas3D::Selection::_render_sidebar_rotation_hint(Axis axis) const { + m_curved_arrow.set_color(AXES_COLOR[axis], 3); + m_curved_arrow.render(); + + ::glRotated(180.0, 0.0, 0.0, 1.0); + m_curved_arrow.render(); } void GLCanvas3D::Selection::_render_sidebar_scale_hint(Axis axis) const { - float color[3]; - switch (axis) - { - case X: { ::memcpy((void*)color, (const void*)RED, 3 * sizeof(float)); break; } - case Y: { ::memcpy((void*)color, (const void*)GREEN, 3 * sizeof(float)); break; } - case Z: { ::memcpy((void*)color, (const void*)BLUE, 3 * sizeof(float)); break; } - } - - m_arrow.set_color(color, 3); + m_arrow.set_color((requires_uniform_scale() ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); ::glTranslated(0.0, 5.0, 0.0); m_arrow.render(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 413d625f1..8e9d44a4b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -369,12 +369,6 @@ class GLCanvas3D public: class Selection { -#if ENABLE_SIDEBAR_VISUAL_HINTS - static const float RED[3]; - static const float GREEN[3]; - static const float BLUE[3]; -#endif // ENABLE_SIDEBAR_VISUAL_HINTS - public: typedef std::set IndicesList; @@ -504,6 +498,7 @@ public: #endif // ENABLE_RENDER_SELECTION_CENTER #if ENABLE_SIDEBAR_VISUAL_HINTS mutable GLArrow m_arrow; + mutable GLCurvedArrow m_curved_arrow; #endif // ENABLE_SIDEBAR_VISUAL_HINTS public: @@ -619,7 +614,7 @@ public: void _render_sidebar_scale_hints(const std::string& sidebar_field) const; void _render_sidebar_size_hints(const std::string& sidebar_field) const; void _render_sidebar_position_hint(Axis axis) const; - void _render_sidebar_rotation_hint(Axis axis, double length) const; + void _render_sidebar_rotation_hint(Axis axis) const; void _render_sidebar_scale_hint(Axis axis) const; void _render_sidebar_size_hint(Axis axis, double length) const; #endif // ENABLE_SIDEBAR_VISUAL_HINTS