diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ba8d3b1ba..1cbfac4e4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5976,7 +5976,11 @@ void GLCanvas3D::_render_sla_slices() const void GLCanvas3D::_render_selection_sidebar_hints() const { +#if ENABLE_GCODE_VIEWER + m_selection.render_sidebar_hints(m_sidebar_field); +#else m_selection.render_sidebar_hints(m_sidebar_field, m_shader); +#endif // ENABLE_GCODE_VIEWER } void GLCanvas3D::_update_volumes_hover_state() const diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 6590da140..ee98ce678 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -376,5 +376,102 @@ GLModelInitializationData circular_arrow(int resolution, float radius, float tip return data; } +GLModelInitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness) +{ + auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { + data.positions.emplace_back(position); + data.normals.emplace_back(normal); + }; + + GLModelInitializationData data; + + const float half_thickness = 0.5f * thickness; + const float half_stem_width = 0.5f * stem_width; + const float half_tip_width = 0.5f * tip_width; + const float total_height = tip_height + stem_height; + + // top face vertices + append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0, total_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ()); + + // top face triangles + data.triangles.emplace_back(0, 1, 6); + data.triangles.emplace_back(6, 1, 5); + data.triangles.emplace_back(4, 5, 3); + data.triangles.emplace_back(5, 1, 3); + data.triangles.emplace_back(1, 2, 3); + + // bottom face vertices + append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ()); + + // bottom face triangles + data.triangles.emplace_back(7, 13, 8); + data.triangles.emplace_back(13, 12, 8); + data.triangles.emplace_back(12, 11, 10); + data.triangles.emplace_back(8, 12, 10); + data.triangles.emplace_back(9, 8, 10); + + // side faces vertices + append_vertex(data, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX()); + append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX()); + + append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + + Vec3f normal(tip_height, half_tip_width, 0.0f); + normal.normalize(); + append_vertex(data, { half_tip_width, stem_height, -half_thickness }, normal); + append_vertex(data, { 0.0, total_height, -half_thickness }, normal); + append_vertex(data, { half_tip_width, stem_height, half_thickness }, normal); + append_vertex(data, { 0.0, total_height, half_thickness }, normal); + + normal = Vec3f(-tip_height, half_tip_width, 0.0f); + normal.normalize(); + append_vertex(data, { 0.0, total_height, -half_thickness }, normal); + append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, normal); + append_vertex(data, { 0.0, total_height, half_thickness }, normal); + append_vertex(data, { -half_tip_width, stem_height, half_thickness }, normal); + + append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY()); + + append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX()); + + append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY()); + + // side face triangles + for (int i = 0; i < 7; ++i) + { + int ii = i * 4; + data.triangles.emplace_back(14 + ii, 15 + ii, 17 + ii); + data.triangles.emplace_back(14 + ii, 17 + ii, 16 + ii); + } + + return data; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index c55931ef1..a11073b19 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -49,9 +49,14 @@ namespace GUI { // create an arrow whose stem is a quarter of circle, with the given dimensions and resolution // the origin of the arrow is in the center of the circle - // the arrow is contained in the 1st quadrant and is pointing counterclockwise + // the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); + // create an arrow with the given dimensions + // the origin of the arrow is in the center of the stem cap + // the arrow is contained in XY plane and has its main axis along the Y axis + GLModelInitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness); + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 62a046a25..3bab06b4d 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -109,12 +109,8 @@ void Selection::set_volumes(GLVolumePtrs* volumes) // Init shall be called from the OpenGL render function, so that the OpenGL context is initialized! bool Selection::init() { - if (!m_arrow.init()) - return false; - - m_arrow.set_scale(5.0 * Vec3d::Ones()); - #if ENABLE_GCODE_VIEWER + m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); if (!m_arrows_shader.init("gouraud_light.vs", "gouraud_light.fs")) @@ -123,6 +119,11 @@ bool Selection::init() return false; } #else + if (!m_arrow.init()) + return false; + + m_arrow.set_scale(5.0 * Vec3d::Ones()); + if (!m_curved_arrow.init()) return false; @@ -1243,16 +1244,28 @@ void Selection::render_center(bool gizmo_is_dragging) const } #endif // ENABLE_RENDER_SELECTION_CENTER +#if ENABLE_GCODE_VIEWER +void Selection::render_sidebar_hints(const std::string& sidebar_field) const +#else void Selection::render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const +#endif // ENABLE_GCODE_VIEWER { if (sidebar_field.empty()) return; if (!boost::starts_with(sidebar_field, "layer")) { +#if ENABLE_GCODE_VIEWER + if (!m_arrows_shader.is_initialized()) + return; + + m_arrows_shader.start_using(); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); +#else shader.start_using(); glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_LIGHTING)); +#endif // ENABLE_GCODE_VIEWER } glsafe(::glEnable(GL_DEPTH_TEST)); @@ -1323,8 +1336,12 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, const Sha if (!boost::starts_with(sidebar_field, "layer")) { +#if ENABLE_GCODE_VIEWER + m_arrows_shader.stop_using(); +#else glsafe(::glDisable(GL_LIGHTING)); shader.stop_using(); +#endif // ENABLE_GCODE_VIEWER } } @@ -1927,6 +1944,33 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const { +#if ENABLE_GCODE_VIEWER + GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); + + if (boost::ends_with(sidebar_field, "x")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); + + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + m_arrow.render(); + } + else if (boost::ends_with(sidebar_field, "y")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); + + m_arrow.render(); + } + else if (boost::ends_with(sidebar_field, "z")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); + + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + m_arrow.render(); + } +#else if (boost::ends_with(sidebar_field, "x")) { glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); @@ -1939,15 +1983,12 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); render_sidebar_position_hint(Z); } +#endif // ENABLE_GCODE_VIEWER } void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const { #if ENABLE_GCODE_VIEWER - if (!m_arrows_shader.is_initialized()) - return; - - m_arrows_shader.start_using(); GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); if (boost::ends_with(sidebar_field, "x")) @@ -1973,9 +2014,6 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) render_sidebar_rotation_hint(Z); } - - m_arrows_shader.stop_using(); - #else if (boost::ends_with(sidebar_field, "x")) { @@ -1996,6 +2034,7 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con { bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); +#if ENABLE_GCODE_VIEWER if (boost::ends_with(sidebar_field, "x") || uniform_scale) { glsafe(::glPushMatrix()); @@ -2018,6 +2057,30 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con render_sidebar_scale_hint(Z); glsafe(::glPopMatrix()); } +#else + if (boost::ends_with(sidebar_field, "x") || uniform_scale) + { + glsafe(::glPushMatrix()); + glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0)); + render_sidebar_scale_hint(X); + glsafe(::glPopMatrix()); + } + + if (boost::ends_with(sidebar_field, "y") || uniform_scale) + { + glsafe(::glPushMatrix()); + render_sidebar_scale_hint(Y); + glsafe(::glPopMatrix()); + } + + if (boost::ends_with(sidebar_field, "z") || uniform_scale) + { + glsafe(::glPushMatrix()); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + render_sidebar_scale_hint(Z); + glsafe(::glPopMatrix()); + } +#endif // ENABLE_GCODE_VIEWER } void Selection::render_sidebar_size_hints(const std::string& sidebar_field) const @@ -2097,11 +2160,13 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co glsafe(::glDisable(GL_BLEND)); } +#if !ENABLE_GCODE_VIEWER void Selection::render_sidebar_position_hint(Axis axis) const { m_arrow.set_color(AXES_COLOR[axis], 3); m_arrow.render(); } +#endif // !ENABLE_GCODE_VIEWER void Selection::render_sidebar_rotation_hint(Axis axis) const { @@ -2115,7 +2180,14 @@ void Selection::render_sidebar_rotation_hint(Axis axis) const void Selection::render_sidebar_scale_hint(Axis axis) const { +#if ENABLE_GCODE_VIEWER + GLint color_id = ::glGetUniformLocation(m_arrows_shader.get_shader_program_id(), "uniform_color"); + + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? (const GLfloat*)UNIFORM_SCALE_COLOR : (const GLfloat*)AXES_COLOR[axis])); +#else m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); +#endif // ENABLE_GCODE_VIEWER glsafe(::glTranslated(0.0, 5.0, 0.0)); m_arrow.render(); @@ -2125,9 +2197,11 @@ void Selection::render_sidebar_scale_hint(Axis axis) const m_arrow.render(); } +#if !ENABLE_GCODE_VIEWER void Selection::render_sidebar_size_hint(Axis axis, double length) const { } +#endif // !ENABLE_GCODE_VIEWER #ifndef NDEBUG static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to) diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 321cb70e0..53caf1106 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -204,11 +204,12 @@ private: #if ENABLE_RENDER_SELECTION_CENTER GLUquadricObj* m_quadric; #endif // ENABLE_RENDER_SELECTION_CENTER - mutable GLArrow m_arrow; #if ENABLE_GCODE_VIEWER + GL_Model m_arrow; GL_Model m_curved_arrow; Shader m_arrows_shader; #else + mutable GLArrow m_arrow; mutable GLCurvedArrow m_curved_arrow; #endif // ENABLE_GCODE_VIEWER @@ -325,7 +326,11 @@ public: #if ENABLE_RENDER_SELECTION_CENTER void render_center(bool gizmo_is_dragging) const; #endif // ENABLE_RENDER_SELECTION_CENTER +#if ENABLE_GCODE_VIEWER + void render_sidebar_hints(const std::string& sidebar_field) const; +#else void render_sidebar_hints(const std::string& sidebar_field, const Shader& shader) const; +#endif // ENABLE_GCODE_VIEWER bool requires_local_axes() const; @@ -368,10 +373,14 @@ private: 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_layers_hints(const std::string& sidebar_field) const; +#if !ENABLE_GCODE_VIEWER void render_sidebar_position_hint(Axis axis) const; +#endif // !ENABLE_GCODE_VIEWER void render_sidebar_rotation_hint(Axis axis) const; void render_sidebar_scale_hint(Axis axis) const; +#if !ENABLE_GCODE_VIEWER void render_sidebar_size_hint(Axis axis, double length) const; +#endif // !ENABLE_GCODE_VIEWER public: enum SyncRotationType {