diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs index 1c53f6c72..90d417b6e 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120.fs @@ -2,6 +2,26 @@ #version 120 uniform vec3 uniform_color; +uniform float percent_outline_radius; +uniform float percent_center_radius; + +vec4 hard_color(float sq_radius) +{ + if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) + return vec4(0.5 * uniform_color, 1.0); + else + return vec4(uniform_color, 1.0); +} + +vec4 custom_color(float sq_radius) +{ + float in_radius = 0.5 * percent_center_radius; + float out_radius = 0.5 * (1.0 - percent_outline_radius); + if ((sq_radius < in_radius * in_radius) || (sq_radius > out_radius * out_radius)) + return vec4(0.5 * uniform_color, 1.0); + else + return vec4(uniform_color, 1.0); +} void main() { @@ -9,9 +29,6 @@ void main() float sq_radius = dot(pos, pos); if (sq_radius > 0.25) discard; - - if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) - gl_FragColor = vec4(0.5 * uniform_color, 1.0); - else - gl_FragColor = vec4(uniform_color, 1.0); + + gl_FragColor = custom_color(sq_radius); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 3df9da961..5631dadf3 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -45,5 +45,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_SHADERS_EDITOR (1 && ENABLE_GCODE_VIEWER) + #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 54c7d3bb5..6d4197694 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -221,6 +221,19 @@ const std::vector<GCodeViewer::Color> GCodeViewer::Range_Colors {{ { 0.761f, 0.322f, 0.235f } // reddish }}; +bool GCodeViewer::init() +{ + set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); + m_sequential_view.marker.init(); + init_shaders(); + + std::array<int, 2> point_sizes; + ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data()); + m_detected_point_sizes = { static_cast<float>(point_sizes[0]), static_cast<float>(point_sizes[1]) }; + + return true; +} + void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) { // avoid processing if called with the same gcode_result @@ -328,6 +341,9 @@ void GCodeViewer::render() const #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + render_shaders_editor(); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR } bool GCodeViewer::is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const @@ -737,30 +753,47 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + bool is_glsl_120 = m_shaders_editor.glsl_version == 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); + std::array<float, 2> point_sizes; + if (m_shaders_editor.size_dependent_on_zoom) + { + point_sizes = { std::min(static_cast<float>(m_shaders_editor.sizes[0]), m_detected_point_sizes[1]), std::min(static_cast<float>(m_shaders_editor.sizes[1]), m_detected_point_sizes[1]) }; + } + else + point_sizes = { static_cast<float>(m_shaders_editor.fixed_size), static_cast<float>(m_shaders_editor.fixed_size) }; +#else bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); - int detected_point_sizes[2]; - ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, detected_point_sizes); - std::array<float, 2> point_sizes = { std::min(8.0f, static_cast<float>(detected_point_sizes[1])), std::min(48.0f, static_cast<float>(detected_point_sizes[1])) }; + std::array<float, 2> point_sizes = { std::min(8.0f, m_detected_point_sizes[1]), std::min(48.0f, m_detected_point_sizes[1]) }; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR double zoom = wxGetApp().plater()->get_camera().get_zoom(); auto render_options = [this, is_glsl_120, zoom, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast<unsigned int>(colors_id)]); +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); + shader.set_uniform("percent_outline_radius", 0.01f * static_cast<float>(m_shaders_editor.percent_outline)); + shader.set_uniform("percent_center_radius", 0.01f * static_cast<float>(m_shaders_editor.percent_center)); +#else shader.set_uniform("zoom", zoom); + shader.set_uniform("percent_outline_radius", 0.15f); + shader.set_uniform("percent_center_radius", 0.15f); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("point_sizes", point_sizes); - if (is_glsl_120) { + glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); + if (is_glsl_120) glsafe(::glEnable(GL_POINT_SPRITE)); - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - } + for (const RenderPath& path : buffer.render_paths) { glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_points_calls_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS } - if (is_glsl_120) { - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); + if (is_glsl_120) glsafe(::glDisable(GL_POINT_SPRITE)); - } + + glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); }; glsafe(::glCullFace(GL_BACK)); @@ -900,7 +933,11 @@ void GCodeViewer::render_legend() const Line }; +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + auto add_item = [this, draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function<void()> callback = nullptr) { +#else auto add_item = [draw_list, &imgui](EItemType type, const Color& color, const std::string& label, std::function<void()> callback = nullptr) { +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorPos(); switch (type) @@ -915,6 +952,20 @@ void GCodeViewer::render_legend() const } case EItemType::Circle: { +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast<float>(m_shaders_editor.percent_outline)); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + if (m_shaders_editor.percent_center > 0) + { + radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast<float>(m_shaders_editor.percent_center); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + } +#else draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); @@ -922,6 +973,7 @@ void GCodeViewer::render_legend() const ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 1.5f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } case EItemType::Line: @@ -1266,6 +1318,63 @@ void GCodeViewer::render_statistics() const } #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR +void GCodeViewer::render_shaders_editor() const +{ + auto set_shader = [this](const std::string& shader) { + unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); + unsigned char end_id = buffer_id(GCodeProcessor::EMoveType::Custom_GCode); + for (unsigned char i = begin_id; i <= end_id; ++i) { + m_buffers[i].shader = shader; + } + }; + + static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + + Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size(); + imgui.set_next_window_pos(static_cast<float>(cnv_size.get_width()), 0.5f * static_cast<float>(cnv_size.get_height()), ImGuiCond_Once, 1.0f, 0.5f); + imgui.begin(std::string("Shaders editor (DEV only)"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); + + ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.glsl_version, 0); + ImGui::RadioButton("glsl version 1.20 (default)", &m_shaders_editor.glsl_version, 1); + switch (m_shaders_editor.glsl_version) + { + case 0: { set_shader("options_110"); break; } + case 1: { set_shader("options_120"); break; } + } + + if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::Checkbox("size dependent on zoom", &m_shaders_editor.size_dependent_on_zoom); + if (m_shaders_editor.size_dependent_on_zoom) + { + if (ImGui::SliderInt("min size (min zoom)", &m_shaders_editor.sizes[0], 1, 100)) + { + if (m_shaders_editor.sizes[1] < m_shaders_editor.sizes[0]) + m_shaders_editor.sizes[1] = m_shaders_editor.sizes[0]; + } + ImGui::SliderInt("max size (max zoom)", &m_shaders_editor.sizes[1], 1, 100); + { + if (m_shaders_editor.sizes[1] < m_shaders_editor.sizes[0]) + m_shaders_editor.sizes[0] = m_shaders_editor.sizes[1]; + } + } + else + ImGui::SliderInt("fixed size", &m_shaders_editor.fixed_size, 1, 100); + + if (m_shaders_editor.glsl_version == 1) + { + ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); + ImGui::SliderInt("percent center", &m_shaders_editor.percent_center, 0, 50); + } + } + + imgui.end(); +} +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + bool GCodeViewer::is_travel_in_z_range(size_t id) const { const IBuffer& buffer = m_buffers[buffer_id(GCodeProcessor::EMoveType::Travel)]; diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 5ab9f6832..e7c620fc5 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -202,6 +202,18 @@ class GCodeViewer }; #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + struct ShadersEditor + { + int glsl_version{ 1 }; + bool size_dependent_on_zoom{ true }; + int fixed_size{ 16 }; + std::array<int, 2> sizes{ 8, 64 }; + int percent_outline{ 15 }; + int percent_center{ 15 }; + }; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + public: struct SequentialView { @@ -271,17 +283,16 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS mutable Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + mutable ShadersEditor m_shaders_editor; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + std::array<float, 2> m_detected_point_sizes = { 0.0f, 0.0f }; public: GCodeViewer() = default; ~GCodeViewer() { reset(); } - bool init() { - set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Extrude, true); - m_sequential_view.marker.init(); - init_shaders(); - return true; - } + bool init(); // extract rendering data from the given parameters void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); @@ -334,6 +345,9 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + void render_shaders_editor() const; +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR bool is_visible(ExtrusionRole role) const { return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ee23783c3..0c0bad7a0 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3502,6 +3502,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) #ifdef SLIC3R_DEBUG_MOUSE_EVENTS printf((format_mouse_event_debug_message(evt) + " - Consumed by ImGUI\n").c_str()); #endif /* SLIC3R_DEBUG_MOUSE_EVENTS */ +#if ENABLE_GCODE_VIEWER + m_dirty = true; +#endif // ENABLE_GCODE_VIEWER // do not return if dragging or tooltip not empty to allow for tooltip update if (!m_mouse.dragging && m_tooltip.is_empty()) return;