From 58258df113249505ebe872bd1608fb08b6051884 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 12 May 2020 16:15:43 +0200 Subject: [PATCH] Tech ENABLE_GCODE_VIEWER -> Selection curved arrows rendered using the new OpenGL model class --- src/slic3r/GUI/3DScene.cpp | 2 + src/slic3r/GUI/3DScene.hpp | 2 + src/slic3r/GUI/GLModel.cpp | 184 +++++++++++++++++++++++++++++++---- src/slic3r/GUI/GLModel.hpp | 5 + src/slic3r/GUI/Selection.cpp | 54 +++++++++- src/slic3r/GUI/Selection.hpp | 9 ++ 6 files changed, 236 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 6aaf0b500..ef5e22c82 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -2002,6 +2002,7 @@ bool GLArrow::on_init() return true; } +#if !ENABLE_GCODE_VIEWER GLCurvedArrow::GLCurvedArrow(unsigned int resolution) : GLModel() , m_resolution(resolution) @@ -2115,6 +2116,7 @@ bool GLCurvedArrow::on_init() m_volume.indexed_vertex_array.finalize_geometry(true); return true; } +#endif // !ENABLE_GCODE_VIEWER bool GLBed::on_init_from_file(const std::string& filename) { diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 07c5cd53e..d6ee72bdc 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -648,6 +648,7 @@ protected: bool on_init() override; }; +#if !ENABLE_GCODE_VIEWER class GLCurvedArrow : public GLModel { unsigned int m_resolution; @@ -658,6 +659,7 @@ public: protected: bool on_init() override; }; +#endif // !ENABLE_GCODE_VIEWER class GLBed : public GLModel { diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 4b2ce4e9e..6590da140 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -11,7 +11,6 @@ namespace GUI { void GL_Model::init_from(const GLModelInitializationData& data) { - assert(!data.positions.empty() && !data.triangles.empty()); assert(data.positions.size() == data.normals.size()); @@ -134,9 +133,16 @@ void GL_Model::send_to_gpu(const std::vector& vertices, const std::vector GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height) { + auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { + data.positions.emplace_back(position); + data.normals.emplace_back(normal); + }; + + resolution = std::max(4, resolution); + GLModelInitializationData data; - float angle_step = 2.0f * M_PI / static_cast(resolution); + const float angle_step = 2.0f * M_PI / static_cast(resolution); std::vector cosines(resolution); std::vector sines(resolution); @@ -147,15 +153,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float sines[i] = -::sin(angle); } - float total_height = tip_height + stem_height; + const float total_height = tip_height + stem_height; // tip vertices/normals - data.positions.emplace_back(0.0f, 0.0f, total_height); - data.normals.emplace_back(Vec3f::UnitZ()); + append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ()); for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height); - data.normals.emplace_back(sines[i], cosines[i], 0.0f); + append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); } // tip triangles @@ -168,15 +172,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float // tip cap outer perimeter vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(tip_radius * sines[i], tip_radius * cosines[i], stem_height); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); } // tip cap inner perimeter vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ()); } // tip cap triangles @@ -191,15 +193,13 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float // stem bottom vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], stem_height); - data.normals.emplace_back(sines[i], cosines[i], 0.0f); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f }); } // stem top vertices for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius * sines[i], stem_radius * cosines[i], 0.0f); - data.normals.emplace_back(sines[i], cosines[i], 0.0f); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f }); } // stem triangles @@ -212,12 +212,10 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float } // stem cap vertices - data.positions.emplace_back(0.0f, 0.0f, 0.0f); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ()); for (int i = 0; i < resolution; ++i) { - data.positions.emplace_back(stem_radius* sines[i], stem_radius* cosines[i], 0.0f); - data.normals.emplace_back(-Vec3f::UnitZ()); + append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ()); } // stem cap triangles @@ -230,5 +228,153 @@ GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float return data; } +GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness) +{ + auto append_vertex = [](GLModelInitializationData& data, const Vec3f& position, const Vec3f& normal) { + data.positions.emplace_back(position); + data.normals.emplace_back(normal); + }; + + resolution = std::max(2, resolution); + + 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 outer_radius = radius + half_stem_width; + const float inner_radius = radius - half_stem_width; + const float step_angle = 0.5f * PI / static_cast(resolution); + + // tip + // top face vertices + append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { -tip_height, radius, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ()); + append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ()); + + // top face triangles + data.triangles.emplace_back(0, 1, 2); + data.triangles.emplace_back(0, 2, 4); + data.triangles.emplace_back(4, 2, 3); + + // bottom face vertices + append_vertex(data, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ()); + append_vertex(data, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ()); + + // bottom face triangles + data.triangles.emplace_back(5, 7, 6); + data.triangles.emplace_back(5, 9, 7); + data.triangles.emplace_back(9, 8, 7); + + // side faces vertices + append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitY()); + append_vertex(data, { -tip_height, radius, half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX()); + + append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitY()); + append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitX()); + append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitY()); + append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX()); + + // side faces triangles + for (int i = 0; i < 4; ++i) + { + data.triangles.emplace_back(15 + i, 11 + i, 10 + i); + data.triangles.emplace_back(15 + i, 16 + i, 11 + i); + } + + // stem + // top face vertices + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + } + + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ()); + } + + // top face triangles + for (int i = 0; i < resolution; ++i) + { + data.triangles.emplace_back(20 + i, 21 + i, 21 + resolution + i); + data.triangles.emplace_back(21 + i, 22 + resolution + i, 21 + resolution + i); + } + + // bottom face vertices + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + } + + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ()); + } + + // bottom face triangles + for (int i = 0; i < resolution; ++i) + { + data.triangles.emplace_back(22 + 2 * resolution + i, 23 + 3 * resolution + i, 23 + 2 * resolution + i); + data.triangles.emplace_back(23 + 2 * resolution + i, 23 + 3 * resolution + i, 24 + 3 * resolution + i); + } + + // side faces vertices + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f}); + } + + for (int i = resolution; i >= 0; --i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { outer_radius * s, outer_radius * c, half_thickness }, { s, c, 0.0f }); + } + + for (int i = 0; i <= resolution; ++i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f }); + } + + for (int i = resolution; i >= 0; --i) + { + float angle = static_cast(i) * step_angle; + float c = ::cos(angle); + float s = ::sin(angle); + append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f }); + } + + // side faces triangles + for (int i = 0; i < 2 * resolution + 1; ++i) + { + data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i); + data.triangles.emplace_back(20 + 6 * (resolution + 1) + i, 21 + 4 * (resolution + 1) + i, 20 + 4 * (resolution + 1) + i); + } + + return data; +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 7b135ada6..c55931ef1 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -47,6 +47,11 @@ namespace GUI { GLModelInitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); + // 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 + GLModelInitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness); + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 87f8b60ed..62a046a25 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -13,6 +13,9 @@ #include #include +#if ENABLE_GCODE_VIEWER +#include +#endif // ENABLE_GCODE_VIEWER static const float UNIFORM_SCALE_COLOR[3] = { 1.0f, 0.38f, 0.0f }; @@ -76,7 +79,9 @@ Selection::Selection() , m_mode(Instance) , m_type(Empty) , m_valid(false) +#if !ENABLE_GCODE_VIEWER , m_curved_arrow(16) +#endif // !ENABLE_GCODE_VIEWER , m_scale_factor(1.0f) { this->set_bounding_boxes_dirty(); @@ -109,10 +114,21 @@ bool Selection::init() m_arrow.set_scale(5.0 * Vec3d::Ones()); +#if ENABLE_GCODE_VIEWER + 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")) + { + BOOST_LOG_TRIVIAL(error) << "Unable to initialize gouraud_light shader: please, check that the files gouraud_light.vs and gouraud_light.fs are available"; + return false; + } +#else if (!m_curved_arrow.init()) return false; m_curved_arrow.set_scale(5.0 * Vec3d::Ones()); +#endif //ENABLE_GCODE_VIEWER + return true; } @@ -1927,6 +1943,40 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field) 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")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[0])); + + glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); + render_sidebar_rotation_hint(X); + } + else if (boost::ends_with(sidebar_field, "y")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[1])); + + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + render_sidebar_rotation_hint(Y); + } + else if (boost::ends_with(sidebar_field, "z")) + { + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)AXES_COLOR[2])); + + render_sidebar_rotation_hint(Z); + } + + m_arrows_shader.stop_using(); + +#else if (boost::ends_with(sidebar_field, "x")) { glsafe(::glRotated(90.0, 0.0, 1.0, 0.0)); @@ -1939,6 +1989,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) } else if (boost::ends_with(sidebar_field, "z")) render_sidebar_rotation_hint(Z); +#endif // ENABLE_GCODE_VIEWER } void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const @@ -2054,9 +2105,10 @@ void Selection::render_sidebar_position_hint(Axis axis) const void Selection::render_sidebar_rotation_hint(Axis axis) const { +#if !ENABLE_GCODE_VIEWER m_curved_arrow.set_color(AXES_COLOR[axis], 3); +#endif // !ENABLE_GCODE_VIEWER m_curved_arrow.render(); - glsafe(::glRotated(180.0, 0.0, 0.0, 1.0)); m_curved_arrow.render(); } diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index c27b4cc29..321cb70e0 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -4,6 +4,10 @@ #include #include "libslic3r/Geometry.hpp" #include "3DScene.hpp" +#if ENABLE_GCODE_VIEWER +#include "GLModel.hpp" +#include "GLShader.hpp" +#endif // ENABLE_GCODE_VIEWER #if ENABLE_RENDER_SELECTION_CENTER class GLUquadric; @@ -201,7 +205,12 @@ private: GLUquadricObj* m_quadric; #endif // ENABLE_RENDER_SELECTION_CENTER mutable GLArrow m_arrow; +#if ENABLE_GCODE_VIEWER + GL_Model m_curved_arrow; + Shader m_arrows_shader; +#else mutable GLCurvedArrow m_curved_arrow; +#endif // ENABLE_GCODE_VIEWER mutable float m_scale_factor;