From 2c8f385c7f468c64ba08984f637ab4712a37089f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 2 Mar 2021 10:01:06 +0100 Subject: [PATCH 1/9] 1st installment of g-code window in preview --- src/libslic3r/GCode.cpp | 8 ++ src/libslic3r/GCode/GCodeProcessor.cpp | 6 + src/libslic3r/GCode/GCodeProcessor.hpp | 6 +- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 161 ++++++++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 36 ++++++ src/slic3r/GUI/GLCanvas3D.cpp | 19 +++ src/slic3r/GUI/GLCanvas3D.hpp | 5 + src/slic3r/GUI/KBShortcutsDialog.cpp | 3 + src/slic3r/GUI/Plater.cpp | 10 ++ 10 files changed, 251 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f3bffe331..27e5b478b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -747,8 +747,16 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re BOOST_LOG_TRIVIAL(debug) << "Start processing gcode, " << log_memory_info(); m_processor.process_file(path_tmp, true, [print]() { print->throw_if_canceled(); }); DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics); +#if ENABLE_GCODE_WINDOW + if (result != nullptr) { + *result = std::move(m_processor.extract_result()); + // set the filename to the correct value + result->filename = path; + } +#else if (result != nullptr) *result = std::move(m_processor.extract_result()); +#endif // ENABLE_GCODE_WINDOW BOOST_LOG_TRIVIAL(debug) << "Finished processing gcode, " << log_memory_info(); if (rename_file(path_tmp, path)) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index c4b2a3518..eb5c616a1 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -6,6 +6,9 @@ #include #include #include +#if ENABLE_GCODE_WINDOW +#include +#endif // ENABLE_GCODE_WINDOW #include #include @@ -976,6 +979,9 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr } // process gcode +#if ENABLE_GCODE_WINDOW + m_result.filename = filename; +#endif // ENABLE_GCODE_WINDOW m_result.id = ++s_result_id; // 1st move must be a dummy move m_result.moves.emplace_back(MoveVertex()); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 05f9a2ce3..04d4c9eee 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -334,13 +334,15 @@ namespace Slic3r { std::vector filament; std::string printer; - void reset() - { + void reset() { print = ""; filament = std::vector(); printer = ""; } }; +#if ENABLE_GCODE_WINDOW + std::string filename; +#endif // ENABLE_GCODE_WINDOW unsigned int id; std::vector moves; Pointfs bed_shape; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 1c21e2f86..e5b6bd9d6 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -99,6 +99,7 @@ #define ENABLE_WARNING_TEXTURE_REMOVAL (1 && ENABLE_2_3_1_ALPHA1) #define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_3_1_ALPHA1) #define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1) +#define ENABLE_GCODE_WINDOW (1 && ENABLE_2_3_1_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 71441e037..2f2632e07 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -21,6 +21,9 @@ #include #include +#if ENABLE_GCODE_WINDOW +#include +#endif // ENABLE_GCODE_WINDOW #include #include #include @@ -278,7 +281,7 @@ void GCodeViewer::SequentialView::Marker::render() const imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Tool position") + ":"); ImGui::SameLine(); char buf[1024]; - sprintf(buf, "X: %.2f, Y: %.2f, Z: %.2f", m_world_position(0), m_world_position(1), m_world_position(2)); + sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", m_world_position(0), m_world_position(1), m_world_position(2)); imgui.text(std::string(buf)); // force extra frame to automatically update window size @@ -295,6 +298,149 @@ void GCodeViewer::SequentialView::Marker::render() const ImGui::PopStyleVar(); } +#if ENABLE_GCODE_WINDOW +const unsigned int GCodeViewer::SequentialView::GCodeWindow::DefaultMaxLinesCount = 20; + +void GCodeViewer::SequentialView::GCodeWindow::load_gcode() +{ + m_gcode.clear(); + if (m_filename.empty()) + return; + + boost::nowide::ifstream f(m_filename); + std::string line; + while (std::getline(f, line)) { + m_gcode.push_back(line); + } + + m_file_size = static_cast(m_gcode.size()); + m_max_lines_count = std::min(DefaultMaxLinesCount, m_file_size); +} + +void GCodeViewer::SequentialView::GCodeWindow::start_mapping_file() +{ + std::cout << "GCodeViewer::SequentialView::GCodeWindow::start_mapping_file()\n"; +} + +void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() +{ + std::cout << "GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()\n"; +} + +void GCodeViewer::SequentialView::GCodeWindow::render(unsigned int curr_line_id) const +{ + static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; + static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; + static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; + + if (!m_visible) + return; + + if (m_filename.empty() || m_gcode.empty()) + return; + + if (curr_line_id == 0) + return; + + // calculate visible range + unsigned int half_max_lines_count = m_max_lines_count / 2; + unsigned int start_id = (curr_line_id >= half_max_lines_count) ? curr_line_id - half_max_lines_count : 0; + unsigned int end_id = start_id + m_max_lines_count - 1; + if (end_id >= m_file_size) { + end_id = m_file_size - 1; + start_id = end_id - m_max_lines_count + 1; + } + + ImGuiWrapper& imgui = *wxGetApp().imgui(); + + imgui.set_next_window_pos(0.0f, 0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height(), ImGuiCond_Always, 0.0f, 0.5f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::SetNextWindowBgAlpha(0.6f); + imgui.begin(std::string("G-code"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const auto& [id_offset, text_height] = ImGui::CalcTextSize(std::to_string(end_id).c_str()); + + for (unsigned int id = start_id; id <= end_id; ++id) { + const std::string& line = m_gcode[id]; + + std::string command; + std::string parameters; + std::string comment; + + // extract comment + std::vector tokens; + boost::split(tokens, line, boost::is_any_of(";"), boost::token_compress_on); + command = tokens.front(); + if (tokens.size() > 1) + comment = ";" + tokens.back(); + + // extract gcode command and parameters + if (!command.empty()) { + boost::split(tokens, command, boost::is_any_of(" "), boost::token_compress_on); + command = tokens.front(); + if (tokens.size() > 1) { + for (size_t i = 1; i < tokens.size(); ++i) { + parameters += " " + tokens[i]; + } + } + } + + // background rect for the current selected move + if (id == curr_line_id - 2) { + ImVec2 pos = ImGui::GetCursorScreenPos(); + const float window_border_size = ImGui::GetCurrentWindow()->WindowBorderSize; + draw_list->AddRectFilled({ window_border_size, pos.y - 1 }, { ImGui::GetCurrentWindow()->Size.x - window_border_size, pos.y + text_height + 1 }, + ImGui::GetColorU32({ 0.1f, 0.1f, 0.1f, 1.0f })); + } + + // render line number + ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR); + const std::string id_str = std::to_string(id + 1); + ImGui::SameLine(0.0f, id_offset - ImGui::CalcTextSize(id_str.c_str()).x); + imgui.text(id_str); + ImGui::PopStyleColor(); + + if (!command.empty() || !comment.empty()) + ImGui::SameLine(); + + // render command + if (!command.empty()) { + ImGui::PushStyleColor(ImGuiCol_Text, COMMAND_COLOR); + imgui.text(command); + ImGui::PopStyleColor(); + } + + // render command parameters + if (!parameters.empty()) { + ImGui::SameLine(0.0f, 0.0f); + imgui.text(parameters); + } + + // render comment + if (!comment.empty()) { + if (!command.empty()) + ImGui::SameLine(0.0f, 0.0f); + ImGui::PushStyleColor(ImGuiCol_Text, COMMENT_COLOR); + imgui.text(comment); + ImGui::PopStyleColor(); + } + + if (id < end_id) + ImGui::NewLine(); + } + + imgui.end(); + ImGui::PopStyleVar(); +} + +void GCodeViewer::SequentialView::render() const +{ + marker.render(); + gcode_window.render(gcode_ids[current.last]); +} +#endif // ENABLE_GCODE_WINDOW + const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.75f, 0.75f, 0.75f }, // erNone { 1.00f, 0.90f, 0.30f }, // erPerimeter @@ -393,6 +539,11 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& // release gpu memory, if used reset(); +#if ENABLE_GCODE_WINDOW + m_sequential_view.gcode_window.set_filename(gcode_result.filename); + m_sequential_view.gcode_window.load_gcode(); +#endif // ENABLE_GCODE_WINDOW + load_toolpaths(gcode_result); if (m_layers.empty()) @@ -545,7 +696,9 @@ void GCodeViewer::reset() m_layers_z_range = { 0, 0 }; m_roles = std::vector(); m_time_statistics.reset(); - +#if ENABLE_GCODE_WINDOW + m_sequential_view.gcode_window.reset(); +#endif // ENABLE_GCODE_WINDOW #if ENABLE_GCODE_VIEWER_STATISTICS m_statistics.reset_all(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -608,7 +761,11 @@ void GCodeViewer::render() const SequentialView* sequential_view = const_cast(&m_sequential_view); if (sequential_view->current.last != sequential_view->endpoints.last) { sequential_view->marker.set_world_position(sequential_view->current_position); +#if ENABLE_GCODE_WINDOW + sequential_view->render(); +#else sequential_view->marker.render(); +#endif // ENABLE_GCODE_WINDOW } render_shells(); render_legend(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 290c13d51..e8f9571fc 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -602,6 +602,29 @@ public: void render() const; }; +#if ENABLE_GCODE_WINDOW + class GCodeWindow + { + static const unsigned int DefaultMaxLinesCount; + bool m_visible{ false }; + unsigned int m_max_lines_count{ DefaultMaxLinesCount }; + unsigned int m_file_size{ 0 }; + std::string m_filename; + std::vector m_gcode; + + public: + void set_filename(const std::string& filename) { m_filename = filename; } + void load_gcode(); + void start_mapping_file(); + void stop_mapping_file(); + void reset() { m_filename.clear(); } + + void toggle_visibility() { m_visible = !m_visible; } + + void render(unsigned int curr_line_id) const; + }; +#endif // ENABLE_GCODE_WINDOW + struct Endpoints { size_t first{ 0 }; @@ -614,9 +637,16 @@ public: Endpoints last_current; Vec3f current_position{ Vec3f::Zero() }; Marker marker; +#if ENABLE_GCODE_WINDOW + GCodeWindow gcode_window; +#endif // ENABLE_GCODE_WINDOW #if ENABLE_GCODE_LINES_ID_IN_H_SLIDER std::vector gcode_ids; #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + +#if ENABLE_GCODE_WINDOW + void render() const; +#endif // ENABLE_GCODE_WINDOW }; enum class EViewType : unsigned char @@ -710,6 +740,12 @@ public: void export_toolpaths_to_obj(const char* filename) const; +#if ENABLE_GCODE_WINDOW + void start_mapping_gcode_file() { m_sequential_view.gcode_window.start_mapping_file(); } + void stop_mapping_gcode_file() { m_sequential_view.gcode_window.stop_mapping_file(); } + void toggle_gcode_window_visibility() { m_sequential_view.gcode_window.toggle_visibility(); } +#endif // ENABLE_GCODE_WINDOW + private: void load_toolpaths(const GCodeProcessor::Result& gcode_result); void load_shells(const Print& print, bool initialized); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0aec25404..54c4844be 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1195,6 +1195,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) GLCanvas3D::~GLCanvas3D() { +#if ENABLE_GCODE_WINDOW + m_gcode_viewer.stop_mapping_gcode_file(); +#endif // ENABLE_GCODE_WINDOW reset_volumes(); } @@ -2621,6 +2624,10 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; } case 'B': case 'b': { zoom_to_bed(); break; } +#if ENABLE_GCODE_WINDOW + case 'C': + case 'c': { m_gcode_viewer.toggle_gcode_window_visibility(); m_dirty = true; request_extra_frame(); break; } +#endif // ENABLE_GCODE_WINDOW case 'E': case 'e': { m_labels.show(!m_labels.is_shown()); m_dirty = true; break; } case 'G': @@ -3909,6 +3916,18 @@ void GLCanvas3D::mouse_up_cleanup() m_canvas->ReleaseMouse(); } +#if ENABLE_GCODE_WINDOW +void GLCanvas3D::start_mapping_gcode_file() +{ + m_gcode_viewer.start_mapping_gcode_file(); +} + +void GLCanvas3D::stop_mapping_gcode_file() +{ + m_gcode_viewer.stop_mapping_gcode_file(); +} +#endif // ENABLE_GCODE_WINDOW + bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 10294931f..990c8c048 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -785,6 +785,11 @@ public: #endif } +#if ENABLE_GCODE_WINDOW + void start_mapping_gcode_file(); + void stop_mapping_gcode_file(); +#endif // ENABLE_GCODE_WINDOW + private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 04e6769e4..c1efa324e 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -202,6 +202,9 @@ void KBShortcutsDialog::fill_shortcuts() { "D", L("Horizontal slider - Move active thumb Right") }, { "X", L("On/Off one layer mode of the vertical slider") }, { "L", L("Show/Hide Legend and Estimated printing time") }, +#if ENABLE_GCODE_WINDOW + { "C", L("Show/Hide G-code window") }, +#endif // ENABLE_GCODE_WINDOW }; m_full_shortcuts.push_back({ { _L("Preview"), "" }, preview_shortcuts }); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6400bbbcc..b23d81174 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3289,8 +3289,15 @@ void Plater::priv::set_current_panel(wxPanel* panel) panel_sizer->Layout(); if (current_panel == view3D) { +#if ENABLE_GCODE_WINDOW + if (old_panel == preview) { + preview->get_canvas3d()->stop_mapping_gcode_file(); + preview->get_canvas3d()->unbind_event_handlers(); + } +#else if (old_panel == preview) preview->get_canvas3d()->unbind_event_handlers(); +#endif // ENABLE_GCODE_WINDOW view3D->get_canvas3d()->bind_event_handlers(); @@ -3315,6 +3322,9 @@ void Plater::priv::set_current_panel(wxPanel* panel) view3D->get_canvas3d()->unbind_event_handlers(); preview->get_canvas3d()->bind_event_handlers(); +#if ENABLE_GCODE_WINDOW + preview->get_canvas3d()->start_mapping_gcode_file(); +#endif // ENABLE_GCODE_WINDOW // see: Plater::priv::object_list_changed() // FIXME: it may be better to have a single function making this check and let it be called wherever needed From f586bb6f9ee0ea97265fe2ee4e6fc6a9c7cdf860 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 3 Mar 2021 09:03:07 +0100 Subject: [PATCH 2/9] Fit G-code window between preview legend and view toolbar --- src/slic3r/GUI/GCodeViewer.cpp | 76 ++++++++++++++++++++++------------ src/slic3r/GUI/GCodeViewer.hpp | 12 +++--- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2f2632e07..ec2bc9797 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -299,8 +299,6 @@ void GCodeViewer::SequentialView::Marker::render() const } #if ENABLE_GCODE_WINDOW -const unsigned int GCodeViewer::SequentialView::GCodeWindow::DefaultMaxLinesCount = 20; - void GCodeViewer::SequentialView::GCodeWindow::load_gcode() { m_gcode.clear(); @@ -314,7 +312,6 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() } m_file_size = static_cast(m_gcode.size()); - m_max_lines_count = std::min(DefaultMaxLinesCount, m_file_size); } void GCodeViewer::SequentialView::GCodeWindow::start_mapping_file() @@ -327,42 +324,52 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() std::cout << "GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()\n"; } -void GCodeViewer::SequentialView::GCodeWindow::render(unsigned int curr_line_id) const +void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, unsigned int curr_line_id) const { static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; - if (!m_visible) + if (!m_visible || m_filename.empty() || m_gcode.empty() || curr_line_id == 0) return; - if (m_filename.empty() || m_gcode.empty()) + // winodws height + const float text_height = ImGui::CalcTextSize("0").y; + const ImGuiStyle& style = ImGui::GetStyle(); + const float height = bottom - top; + if (height < 2.0f * (text_height + style.ItemSpacing.y + style.WindowBorderSize + style.WindowPadding.y)) return; - if (curr_line_id == 0) - return; + // number of visible lines + const unsigned int lines_count = (height - 2.0f * (style.WindowPadding.y + style.WindowBorderSize) + style.ItemSpacing.y) / (text_height + style.ItemSpacing.y); // calculate visible range - unsigned int half_max_lines_count = m_max_lines_count / 2; - unsigned int start_id = (curr_line_id >= half_max_lines_count) ? curr_line_id - half_max_lines_count : 0; - unsigned int end_id = start_id + m_max_lines_count - 1; + const unsigned int half_lines_count = lines_count / 2; + unsigned int start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0; + unsigned int end_id = start_id + lines_count - 1; if (end_id >= m_file_size) { end_id = m_file_size - 1; - start_id = end_id - m_max_lines_count + 1; + start_id = end_id - lines_count + 1; } + const float id_offset = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x; + ImGuiWrapper& imgui = *wxGetApp().imgui(); - imgui.set_next_window_pos(0.0f, 0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height(), ImGuiCond_Always, 0.0f, 0.5f); + imgui.set_next_window_pos(0.0f, top, ImGuiCond_Always, 0.0f, 0.0f); + imgui.set_next_window_size(0.0f, height, ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.6f); imgui.begin(std::string("G-code"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - const auto& [id_offset, text_height] = ImGui::CalcTextSize(std::to_string(end_id).c_str()); + + + float f_lines_count = static_cast(lines_count); + ImGui::ItemSize({ 0.0f, 0.5f * (height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y) }); for (unsigned int id = start_id; id <= end_id; ++id) { - const std::string& line = m_gcode[id]; + const std::string& line = m_gcode[id - 1]; std::string command; std::string parameters; @@ -387,16 +394,17 @@ void GCodeViewer::SequentialView::GCodeWindow::render(unsigned int curr_line_id) } // background rect for the current selected move - if (id == curr_line_id - 2) { - ImVec2 pos = ImGui::GetCursorScreenPos(); - const float window_border_size = ImGui::GetCurrentWindow()->WindowBorderSize; - draw_list->AddRectFilled({ window_border_size, pos.y - 1 }, { ImGui::GetCurrentWindow()->Size.x - window_border_size, pos.y + text_height + 1 }, - ImGui::GetColorU32({ 0.1f, 0.1f, 0.1f, 1.0f })); + if (id == curr_line_id - 1) { + const float pos_y = ImGui::GetCursorScreenPos().y; + const float half_ItemSpacing_y = 0.5f * style.ItemSpacing.y; + draw_list->AddRectFilled({ style.WindowBorderSize, pos_y - half_ItemSpacing_y }, + { ImGui::GetCurrentWindow()->Size.x - style.WindowBorderSize, pos_y + text_height + half_ItemSpacing_y }, + ImGui::GetColorU32({ 0.15f, 0.15f, 0.15f, 1.0f })); } // render line number ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR); - const std::string id_str = std::to_string(id + 1); + const std::string id_str = std::to_string(id); ImGui::SameLine(0.0f, id_offset - ImGui::CalcTextSize(id_str.c_str()).x); imgui.text(id_str); ImGui::PopStyleColor(); @@ -434,10 +442,13 @@ void GCodeViewer::SequentialView::GCodeWindow::render(unsigned int curr_line_id) ImGui::PopStyleVar(); } -void GCodeViewer::SequentialView::render() const +void GCodeViewer::SequentialView::render(float legend_height) const { marker.render(); - gcode_window.render(gcode_ids[current.last]); + float bottom = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height(); + if (wxGetApp().is_editor()) + bottom -= wxGetApp().plater()->get_view_toolbar().get_height(); + gcode_window.render(legend_height, bottom, gcode_ids[current.last]); } #endif // ENABLE_GCODE_WINDOW @@ -758,17 +769,22 @@ void GCodeViewer::render() const glsafe(::glEnable(GL_DEPTH_TEST)); render_toolpaths(); + render_shells(); +#if ENABLE_GCODE_WINDOW + float legend_height = 0.0f; + render_legend(legend_height); +#else + render_legend(); +#endif // ENABLE_GCODE_WINDOW SequentialView* sequential_view = const_cast(&m_sequential_view); if (sequential_view->current.last != sequential_view->endpoints.last) { sequential_view->marker.set_world_position(sequential_view->current_position); #if ENABLE_GCODE_WINDOW - sequential_view->render(); + sequential_view->render(legend_height); #else sequential_view->marker.render(); #endif // ENABLE_GCODE_WINDOW } - render_shells(); - render_legend(); #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -3923,7 +3939,11 @@ void GCodeViewer::render_shells() const // glsafe(::glDepthMask(GL_TRUE)); } +#if ENABLE_GCODE_WINDOW +void GCodeViewer::render_legend(float& legend_height) const +#else void GCodeViewer::render_legend() const +#endif // ENABLE_GCODE_WINDOW { if (!m_legend_enabled) return; @@ -4606,6 +4626,10 @@ void GCodeViewer::render_legend() const } } +#if ENABLE_GCODE_WINDOW + legend_height = ImGui::GetCurrentWindow()->Size.y; +#endif // ENABLE_GCODE_WINDOW + imgui.end(); ImGui::PopStyleVar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e8f9571fc..0302b28bf 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -605,9 +605,7 @@ public: #if ENABLE_GCODE_WINDOW class GCodeWindow { - static const unsigned int DefaultMaxLinesCount; - bool m_visible{ false }; - unsigned int m_max_lines_count{ DefaultMaxLinesCount }; + bool m_visible{ true }; unsigned int m_file_size{ 0 }; std::string m_filename; std::vector m_gcode; @@ -621,7 +619,7 @@ public: void toggle_visibility() { m_visible = !m_visible; } - void render(unsigned int curr_line_id) const; + void render(float top, float bottom, unsigned int curr_line_id) const; }; #endif // ENABLE_GCODE_WINDOW @@ -645,7 +643,7 @@ public: #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER #if ENABLE_GCODE_WINDOW - void render() const; + void render(float legend_height) const; #endif // ENABLE_GCODE_WINDOW }; @@ -752,7 +750,11 @@ private: void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const; void render_toolpaths() const; void render_shells() const; +#if ENABLE_GCODE_WINDOW + void render_legend(float& legend_height) const; +#else void render_legend() const; +#endif // ENABLE_GCODE_WINDOW #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS From a820e8c22fdb9aec26f43c25a0220616c4309238 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 4 Mar 2021 08:37:21 +0100 Subject: [PATCH 3/9] Vertically center text in G-code window --- src/slic3r/GUI/GCodeViewer.cpp | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c8463e2d0..6d5986690 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -329,23 +329,24 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, unsigned int curr_line_id) const { static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; + static const ImVec4 HIGHLIGHT_RECT_COLOR = ImGuiWrapper::COL_ORANGE_DARK; static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; if (!m_visible || m_filename.empty() || m_gcode.empty() || curr_line_id == 0) return; - // winodws height + // window height const float text_height = ImGui::CalcTextSize("0").y; const ImGuiStyle& style = ImGui::GetStyle(); - const float height = bottom - top; - if (height < 2.0f * (text_height + style.ItemSpacing.y + style.WindowBorderSize + style.WindowPadding.y)) + const float wnd_height = bottom - top; + if (wnd_height < 2.0f * (text_height + style.ItemSpacing.y + style.WindowPadding.y)) return; // number of visible lines - const unsigned int lines_count = (height - 2.0f * (style.WindowPadding.y + style.WindowBorderSize) + style.ItemSpacing.y) / (text_height + style.ItemSpacing.y); + const unsigned int lines_count = (wnd_height - 2.0f * style.WindowPadding.y + style.ItemSpacing.y) / (text_height + style.ItemSpacing.y); - // calculate visible range + // visible range const unsigned int half_lines_count = lines_count / 2; unsigned int start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0; unsigned int end_id = start_id + lines_count - 1; @@ -354,21 +355,21 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u start_id = end_id - lines_count + 1; } - const float id_offset = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x; + // line id number column width + const float id_width = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x; ImGuiWrapper& imgui = *wxGetApp().imgui(); imgui.set_next_window_pos(0.0f, top, ImGuiCond_Always, 0.0f, 0.0f); - imgui.set_next_window_size(0.0f, height, ImGuiCond_Always); + imgui.set_next_window_size(0.0f, wnd_height, ImGuiCond_Always); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::SetNextWindowBgAlpha(0.6f); imgui.begin(std::string("G-code"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - - float f_lines_count = static_cast(lines_count); - ImGui::ItemSize({ 0.0f, 0.5f * (height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y) }); + const float f_lines_count = static_cast(lines_count); + ImGui::SetCursorPosY({ 0.5f * (wnd_height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y) }); for (unsigned int id = start_id; id <= end_id; ++id) { const std::string& line = m_gcode[id - 1]; @@ -395,19 +396,21 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u } } - // background rect for the current selected move - if (id == curr_line_id - 1) { + // rect for the current selected move + if (id == curr_line_id) { const float pos_y = ImGui::GetCursorScreenPos().y; const float half_ItemSpacing_y = 0.5f * style.ItemSpacing.y; - draw_list->AddRectFilled({ style.WindowBorderSize, pos_y - half_ItemSpacing_y }, - { ImGui::GetCurrentWindow()->Size.x - style.WindowBorderSize, pos_y + text_height + half_ItemSpacing_y }, - ImGui::GetColorU32({ 0.15f, 0.15f, 0.15f, 1.0f })); + const float half_padding_x = 0.5f * style.WindowPadding.x; + draw_list->AddRect({ half_padding_x, pos_y - half_ItemSpacing_y }, + { ImGui::GetCurrentWindow()->Size.x - half_padding_x, pos_y + text_height + half_ItemSpacing_y }, + ImGui::GetColorU32(HIGHLIGHT_RECT_COLOR)); } // render line number - ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR); const std::string id_str = std::to_string(id); - ImGui::SameLine(0.0f, id_offset - ImGui::CalcTextSize(id_str.c_str()).x); + ImGui::Dummy({ id_width - ImGui::CalcTextSize(id_str.c_str()).x, text_height }); + ImGui::SameLine(0.0f, 0.0f); + ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR); imgui.text(id_str); ImGui::PopStyleColor(); @@ -435,9 +438,6 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u imgui.text(comment); ImGui::PopStyleColor(); } - - if (id < end_id) - ImGui::NewLine(); } imgui.end(); From cee4ed9ff24f2ea09c4ab9bf87d6e1dcebbc87c2 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 4 Mar 2021 13:23:24 +0100 Subject: [PATCH 4/9] G-code window optimization: parse g-code lines only when needed --- src/slic3r/GUI/GCodeViewer.cpp | 88 +++++++++++++++++++++------------- src/slic3r/GUI/GCodeViewer.hpp | 9 ++++ 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 6d5986690..3cbf3262f 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -314,6 +314,8 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() } m_file_size = static_cast(m_gcode.size()); + m_last_line_id = 0; + m_last_lines_size = 0; } void GCodeViewer::SequentialView::GCodeWindow::start_mapping_file() @@ -328,6 +330,38 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, unsigned int curr_line_id) const { + auto update_lines = [this](unsigned int start_id, unsigned int end_id) { + std::vector ret; + ret.reserve(end_id - start_id + 1); + for (unsigned int id = start_id; id <= end_id; ++id) { + const std::string& gline = m_gcode[id - 1]; + + std::string command; + std::string parameters; + std::string comment; + + // extract comment + std::vector tokens; + boost::split(tokens, gline, boost::is_any_of(";"), boost::token_compress_on); + command = tokens.front(); + if (tokens.size() > 1) + comment = ";" + tokens.back(); + + // extract gcode command and parameters + if (!command.empty()) { + boost::split(tokens, command, boost::is_any_of(" "), boost::token_compress_on); + command = tokens.front(); + if (tokens.size() > 1) { + for (size_t i = 1; i < tokens.size(); ++i) { + parameters += " " + tokens[i]; + } + } + } + ret.push_back({ command, parameters, comment }); + } + return ret; + }; + static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; static const ImVec4 HIGHLIGHT_RECT_COLOR = ImGuiWrapper::COL_ORANGE_DARK; static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; @@ -340,12 +374,13 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u const float text_height = ImGui::CalcTextSize("0").y; const ImGuiStyle& style = ImGui::GetStyle(); const float wnd_height = bottom - top; - if (wnd_height < 2.0f * (text_height + style.ItemSpacing.y + style.WindowPadding.y)) - return; // number of visible lines const unsigned int lines_count = (wnd_height - 2.0f * style.WindowPadding.y + style.ItemSpacing.y) / (text_height + style.ItemSpacing.y); + if (lines_count == 0) + return; + // visible range const unsigned int half_lines_count = lines_count / 2; unsigned int start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0; @@ -355,6 +390,13 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u start_id = end_id - lines_count + 1; } + if (m_last_line_id != curr_line_id || m_last_lines_size != static_cast(end_id - start_id + 1)) { + // updates list of lines to show + *const_cast*>(&m_lines) = update_lines(start_id, end_id); + *const_cast(&m_last_line_id) = curr_line_id; + *const_cast(&m_last_lines_size) = m_lines.size(); + } + // line id number column width const float id_width = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x; @@ -368,33 +410,13 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u ImDrawList* draw_list = ImGui::GetWindowDrawList(); + // center the text in the window by pushing down the first line const float f_lines_count = static_cast(lines_count); ImGui::SetCursorPosY({ 0.5f * (wnd_height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y) }); + // render text lines for (unsigned int id = start_id; id <= end_id; ++id) { - const std::string& line = m_gcode[id - 1]; - - std::string command; - std::string parameters; - std::string comment; - - // extract comment - std::vector tokens; - boost::split(tokens, line, boost::is_any_of(";"), boost::token_compress_on); - command = tokens.front(); - if (tokens.size() > 1) - comment = ";" + tokens.back(); - - // extract gcode command and parameters - if (!command.empty()) { - boost::split(tokens, command, boost::is_any_of(" "), boost::token_compress_on); - command = tokens.front(); - if (tokens.size() > 1) { - for (size_t i = 1; i < tokens.size(); ++i) { - parameters += " " + tokens[i]; - } - } - } + const Line& line = m_lines[id - start_id]; // rect for the current selected move if (id == curr_line_id) { @@ -414,28 +436,28 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u imgui.text(id_str); ImGui::PopStyleColor(); - if (!command.empty() || !comment.empty()) + if (!line.command.empty() || !line.comment.empty()) ImGui::SameLine(); // render command - if (!command.empty()) { + if (!line.command.empty()) { ImGui::PushStyleColor(ImGuiCol_Text, COMMAND_COLOR); - imgui.text(command); + imgui.text(line.command); ImGui::PopStyleColor(); } // render command parameters - if (!parameters.empty()) { + if (!line.parameters.empty()) { ImGui::SameLine(0.0f, 0.0f); - imgui.text(parameters); + imgui.text(line.parameters); } // render comment - if (!comment.empty()) { - if (!command.empty()) + if (!line.comment.empty()) { + if (!line.command.empty()) ImGui::SameLine(0.0f, 0.0f); ImGui::PushStyleColor(ImGuiCol_Text, COMMENT_COLOR); - imgui.text(comment); + imgui.text(line.comment); ImGui::PopStyleColor(); } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index ada377d36..428a50e85 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -609,8 +609,17 @@ public: #if ENABLE_GCODE_WINDOW class GCodeWindow { + struct Line + { + std::string command; + std::string parameters; + std::string comment; + }; bool m_visible{ true }; unsigned int m_file_size{ 0 }; + unsigned int m_last_line_id{ 0 }; + size_t m_last_lines_size{ 0 }; + std::vector m_lines; std::string m_filename; std::vector m_gcode; From 0472c8452588809b382681ef1e418242f41b47e0 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Mar 2021 08:35:32 +0100 Subject: [PATCH 5/9] G-code window uses file mapping --- CMakeLists.txt | 2 +- src/libslic3r/Technologies.hpp | 3 + src/slic3r/GUI/GCodeViewer.cpp | 140 +++++++++++++++++++++++++-------- src/slic3r/GUI/GCodeViewer.hpp | 40 +++++++++- src/slic3r/GUI/GLCanvas3D.cpp | 4 + src/slic3r/GUI/GLCanvas3D.hpp | 2 + src/slic3r/GUI/Plater.cpp | 4 + 7 files changed, 159 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 98ae4f0c6..5ebda365d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -300,7 +300,7 @@ endif() # boost::process was introduced first in version 1.64.0, # boost::beast::detail::base64 was introduced first in version 1.66.0 set(MINIMUM_BOOST_VERSION "1.66.0") -set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time") +set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time;iostreams") find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components}) add_library(boost_libs INTERFACE) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c2139bb33..a4c6aa214 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -53,7 +53,10 @@ #define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_3_1_ALPHA1) // Enable validation of custom gcode against gcode processor reserved keywords #define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1) +// Enable showing a imgui window containing gcode in preview #define ENABLE_GCODE_WINDOW (1 && ENABLE_2_3_1_ALPHA1) +// Enable using file mapping to show a imgui window containing gcode in preview +#define ENABLE_GCODE_WINDOW_USE_MAPPED_FILE (1 && ENABLE_GCODE_WINDOW) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3cbf3262f..c6010ae42 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -303,21 +303,57 @@ void GCodeViewer::SequentialView::Marker::render() const #if ENABLE_GCODE_WINDOW void GCodeViewer::SequentialView::GCodeWindow::load_gcode() { +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE m_gcode.clear(); +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE if (m_filename.empty()) return; - boost::nowide::ifstream f(m_filename); - std::string line; - while (std::getline(f, line)) { - m_gcode.push_back(line); + try + { + boost::nowide::ifstream f(m_filename); + std::string line; +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + // generate mapping for accessing data in file by line number + uint64_t offset = 0; +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + while (std::getline(f, line)) { +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + size_t line_length = static_cast(line.length()); + m_lines_map.push_back({ offset, line_length }); + offset += static_cast(line_length) + 1; +#else + m_gcode.push_back(line); +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + } + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "Unable to load data from " << m_filename << ". Cannot show G-code window."; + reset(); + return; } - m_file_size = static_cast(m_gcode.size()); - m_last_line_id = 0; + m_selected_line_id = 0; m_last_lines_size = 0; + +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + try + { + m_file.open(boost::filesystem::path(m_filename)); + if (m_file.is_open()) { + std::cout << "open file: " << m_filename << "\n"; + } + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "Unable to map file " << m_filename << ". Cannot show G-code window."; + reset(); + } +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE } +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void GCodeViewer::SequentialView::GCodeWindow::start_mapping_file() { std::cout << "GCodeViewer::SequentialView::GCodeWindow::start_mapping_file()\n"; @@ -327,14 +363,20 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() { std::cout << "GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()\n"; } +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, unsigned int curr_line_id) const +void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, uint64_t curr_line_id) const { - auto update_lines = [this](unsigned int start_id, unsigned int end_id) { + auto update_lines = [this](uint64_t start_id, uint64_t end_id) { std::vector ret; ret.reserve(end_id - start_id + 1); - for (unsigned int id = start_id; id <= end_id; ++id) { + for (uint64_t id = start_id; id <= end_id; ++id) { +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + // read line from file + std::string gline(m_file.data() + m_lines_map[id - 1].first, m_lines_map[id - 1].second); +#else const std::string& gline = m_gcode[id - 1]; +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE std::string command; std::string parameters; @@ -363,41 +405,66 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u }; static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; - static const ImVec4 HIGHLIGHT_RECT_COLOR = ImGuiWrapper::COL_ORANGE_DARK; + static const ImVec4 SELECTION_RECT_COLOR = ImGuiWrapper::COL_ORANGE_DARK; static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; + static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + if (!m_visible || m_filename.empty() || m_lines_map.empty() || curr_line_id == 0) + return; +#else if (!m_visible || m_filename.empty() || m_gcode.empty() || curr_line_id == 0) return; +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE // window height - const float text_height = ImGui::CalcTextSize("0").y; - const ImGuiStyle& style = ImGui::GetStyle(); const float wnd_height = bottom - top; // number of visible lines - const unsigned int lines_count = (wnd_height - 2.0f * style.WindowPadding.y + style.ItemSpacing.y) / (text_height + style.ItemSpacing.y); + const float text_height = ImGui::CalcTextSize("0").y; + const ImGuiStyle& style = ImGui::GetStyle(); + const uint64_t lines_count = static_cast((wnd_height - 2.0f * style.WindowPadding.y + style.ItemSpacing.y) / (text_height + style.ItemSpacing.y)); if (lines_count == 0) return; // visible range - const unsigned int half_lines_count = lines_count / 2; - unsigned int start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0; - unsigned int end_id = start_id + lines_count - 1; - if (end_id >= m_file_size) { - end_id = m_file_size - 1; + const uint64_t half_lines_count = lines_count / 2; + uint64_t start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0; + uint64_t end_id = start_id + lines_count - 1; +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + if (end_id >= static_cast(m_lines_map.size())) { + end_id = static_cast(m_lines_map.size()) - 1; start_id = end_id - lines_count + 1; } +#else + if (end_id >= static_cast(m_gcode.size())) { + end_id = static_cast(m_gcode.size()) - 1; + start_id = end_id - lines_count + 1; + } +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - if (m_last_line_id != curr_line_id || m_last_lines_size != static_cast(end_id - start_id + 1)) { - // updates list of lines to show + // updates list of lines to show, if needed + if (m_selected_line_id != curr_line_id || m_last_lines_size != end_id - start_id + 1) { +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + try + { + *const_cast*>(&m_lines) = update_lines(start_id, end_id); + } + catch (...) + { + BOOST_LOG_TRIVIAL(error) << "Error while loading from file " << m_filename << ". Cannot show G-code window."; + return; + } +#else *const_cast*>(&m_lines) = update_lines(start_id, end_id); - *const_cast(&m_last_line_id) = curr_line_id; - *const_cast(&m_last_lines_size) = m_lines.size(); +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + *const_cast(&m_selected_line_id) = curr_line_id; + *const_cast(&m_last_lines_size) = static_cast(m_lines.size()); } - // line id number column width + // line number's column width const float id_width = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x; ImGuiWrapper& imgui = *wxGetApp().imgui(); @@ -408,28 +475,27 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u ImGui::SetNextWindowBgAlpha(0.6f); imgui.begin(std::string("G-code"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - // center the text in the window by pushing down the first line const float f_lines_count = static_cast(lines_count); ImGui::SetCursorPosY({ 0.5f * (wnd_height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y) }); // render text lines - for (unsigned int id = start_id; id <= end_id; ++id) { + for (uint64_t id = start_id; id <= end_id; ++id) { const Line& line = m_lines[id - start_id]; - // rect for the current selected move + // rect around the current selected line if (id == curr_line_id) { const float pos_y = ImGui::GetCursorScreenPos().y; const float half_ItemSpacing_y = 0.5f * style.ItemSpacing.y; const float half_padding_x = 0.5f * style.WindowPadding.x; - draw_list->AddRect({ half_padding_x, pos_y - half_ItemSpacing_y }, + ImGui::GetWindowDrawList()->AddRect({ half_padding_x, pos_y - half_ItemSpacing_y }, { ImGui::GetCurrentWindow()->Size.x - half_padding_x, pos_y + text_height + half_ItemSpacing_y }, - ImGui::GetColorU32(HIGHLIGHT_RECT_COLOR)); + ImGui::GetColorU32(SELECTION_RECT_COLOR)); } // render line number const std::string id_str = std::to_string(id); + // spacer to right align text ImGui::Dummy({ id_width - ImGui::CalcTextSize(id_str.c_str()).x, text_height }); ImGui::SameLine(0.0f, 0.0f); ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR); @@ -446,10 +512,12 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u ImGui::PopStyleColor(); } - // render command parameters + // render parameters if (!line.parameters.empty()) { ImGui::SameLine(0.0f, 0.0f); + ImGui::PushStyleColor(ImGuiCol_Text, PARAMETERS_COLOR); imgui.text(line.parameters); + ImGui::PopStyleColor(); } // render comment @@ -466,13 +534,23 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u ImGui::PopStyleVar(); } +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE +void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() +{ + if (m_file.is_open()) { + m_file.close(); + std::cout << "closed file: " << m_filename << "\n"; + } +} +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + void GCodeViewer::SequentialView::render(float legend_height) const { marker.render(); float bottom = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height(); if (wxGetApp().is_editor()) bottom -= wxGetApp().plater()->get_view_toolbar().get_height(); - gcode_window.render(legend_height, bottom, gcode_ids[current.last]); + gcode_window.render(legend_height, bottom, static_cast(gcode_ids[current.last])); } #endif // ENABLE_GCODE_WINDOW diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 428a50e85..890961a82 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -5,6 +5,10 @@ #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GLModel.hpp" +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE +#include +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + #include #include #include @@ -616,23 +620,49 @@ public: std::string comment; }; bool m_visible{ true }; - unsigned int m_file_size{ 0 }; - unsigned int m_last_line_id{ 0 }; + uint64_t m_selected_line_id{ 0 }; size_t m_last_lines_size{ 0 }; - std::vector m_lines; std::string m_filename; +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + boost::iostreams::mapped_file_source m_file; + // map for accessing data in file by line number + std::vector> m_lines_map; +#else std::vector m_gcode; +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + // current visible lines + std::vector m_lines; public: +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + GCodeWindow() = default; + ~GCodeWindow() { stop_mapping_file(); } +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void set_filename(const std::string& filename) { m_filename = filename; } void load_gcode(); +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void start_mapping_file(); void stop_mapping_file(); +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + void reset() { + stop_mapping_file(); + m_lines_map.clear(); + m_lines.clear(); + m_filename.clear(); + } +#else void reset() { m_filename.clear(); } +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void toggle_visibility() { m_visible = !m_visible; } - void render(float top, float bottom, unsigned int curr_line_id) const; + void render(float top, float bottom, uint64_t curr_line_id) const; + +#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE + private: + void stop_mapping_file(); +#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE }; #endif // ENABLE_GCODE_WINDOW @@ -753,8 +783,10 @@ public: void export_toolpaths_to_obj(const char* filename) const; #if ENABLE_GCODE_WINDOW +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void start_mapping_gcode_file() { m_sequential_view.gcode_window.start_mapping_file(); } void stop_mapping_gcode_file() { m_sequential_view.gcode_window.stop_mapping_file(); } +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void toggle_gcode_window_visibility() { m_sequential_view.gcode_window.toggle_visibility(); } #endif // ENABLE_GCODE_WINDOW diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4931e7362..a6b6c636a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1196,7 +1196,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) GLCanvas3D::~GLCanvas3D() { #if ENABLE_GCODE_WINDOW +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE m_gcode_viewer.stop_mapping_gcode_file(); +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE #endif // ENABLE_GCODE_WINDOW reset_volumes(); } @@ -3903,6 +3905,7 @@ void GLCanvas3D::mouse_up_cleanup() } #if ENABLE_GCODE_WINDOW +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void GLCanvas3D::start_mapping_gcode_file() { m_gcode_viewer.start_mapping_gcode_file(); @@ -3912,6 +3915,7 @@ void GLCanvas3D::stop_mapping_gcode_file() { m_gcode_viewer.stop_mapping_gcode_file(); } +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE #endif // ENABLE_GCODE_WINDOW bool GLCanvas3D::_is_shown_on_screen() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 990c8c048..27e8b49c7 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -786,8 +786,10 @@ public: } #if ENABLE_GCODE_WINDOW +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void start_mapping_gcode_file(); void stop_mapping_gcode_file(); +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE #endif // ENABLE_GCODE_WINDOW private: diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4ca9834b9..b3093a574 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3379,7 +3379,9 @@ void Plater::priv::set_current_panel(wxPanel* panel) if (current_panel == view3D) { #if ENABLE_GCODE_WINDOW if (old_panel == preview) { +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE preview->get_canvas3d()->stop_mapping_gcode_file(); +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE preview->get_canvas3d()->unbind_event_handlers(); } #else @@ -3411,7 +3413,9 @@ void Plater::priv::set_current_panel(wxPanel* panel) preview->get_canvas3d()->bind_event_handlers(); #if ENABLE_GCODE_WINDOW +#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE preview->get_canvas3d()->start_mapping_gcode_file(); +#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE #endif // ENABLE_GCODE_WINDOW // see: Plater::priv::object_list_changed() From 9359d6d3d0a5f78bc2d05c42c5693725dfe049c4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Mar 2021 09:01:15 +0100 Subject: [PATCH 6/9] Follow-up of 0472c8452588809b382681ef1e418242f41b47e0 - Fixed syntax errors --- src/slic3r/GUI/GCodeViewer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index de17a4d8e..4c934624d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -461,7 +461,7 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u *const_cast*>(&m_lines) = update_lines(start_id, end_id); #endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE *const_cast(&m_selected_line_id) = curr_line_id; - *const_cast(&m_last_lines_size) = static_cast(m_lines.size()); + *const_cast(&m_last_lines_size) = m_lines.size(); } // line number's column width @@ -477,7 +477,7 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u // center the text in the window by pushing down the first line const float f_lines_count = static_cast(lines_count); - ImGui::SetCursorPosY({ 0.5f * (wnd_height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y) }); + ImGui::SetCursorPosY(0.5f * (wnd_height - f_lines_count * text_height - (f_lines_count - 1.0f) * style.ItemSpacing.y)); // render text lines for (uint64_t id = start_id; id <= end_id; ++id) { From 5998ee8f2e473ccb1d29aa976b04eec79b152fdd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Mar 2021 09:29:47 +0100 Subject: [PATCH 7/9] Code cleanup --- src/slic3r/GUI/GCodeViewer.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 4c934624d..259f37899 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -341,9 +341,6 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() try { m_file.open(boost::filesystem::path(m_filename)); - if (m_file.is_open()) { - std::cout << "open file: " << m_filename << "\n"; - } } catch (...) { @@ -537,10 +534,8 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u #if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() { - if (m_file.is_open()) { + if (m_file.is_open()) m_file.close(); - std::cout << "closed file: " << m_filename << "\n"; - } } #endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE From 14aca210cb24e093fff0063a781b46075e6d3557 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 8 Mar 2021 10:20:07 +0100 Subject: [PATCH 8/9] Tech ENABLE_GCODE_WINDOW_USE_MAPPED_FILE merged into ENABLE_GCODE_WINDOW --- src/libslic3r/Technologies.hpp | 2 -- src/slic3r/GUI/GCodeViewer.cpp | 47 +--------------------------------- src/slic3r/GUI/GCodeViewer.hpp | 24 ++--------------- src/slic3r/GUI/GLCanvas3D.cpp | 19 -------------- src/slic3r/GUI/GLCanvas3D.hpp | 7 ----- src/slic3r/GUI/Plater.cpp | 14 ---------- 6 files changed, 3 insertions(+), 110 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a4c6aa214..63ee79805 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,8 +55,6 @@ #define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_3_1_ALPHA1) // Enable showing a imgui window containing gcode in preview #define ENABLE_GCODE_WINDOW (1 && ENABLE_2_3_1_ALPHA1) -// Enable using file mapping to show a imgui window containing gcode in preview -#define ENABLE_GCODE_WINDOW_USE_MAPPED_FILE (1 && ENABLE_GCODE_WINDOW) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 259f37899..7abcbdc41 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -303,9 +303,6 @@ void GCodeViewer::SequentialView::Marker::render() const #if ENABLE_GCODE_WINDOW void GCodeViewer::SequentialView::GCodeWindow::load_gcode() { -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - m_gcode.clear(); -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE if (m_filename.empty()) return; @@ -313,19 +310,13 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() { boost::nowide::ifstream f(m_filename); std::string line; -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE // generate mapping for accessing data in file by line number uint64_t offset = 0; -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE while (std::getline(f, line)) { -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE size_t line_length = static_cast(line.length()); m_lines_map.push_back({ offset, line_length }); offset += static_cast(line_length) + 1; -#else - m_gcode.push_back(line); -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - } + } } catch (...) { @@ -337,7 +328,6 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() m_selected_line_id = 0; m_last_lines_size = 0; -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE try { m_file.open(boost::filesystem::path(m_filename)); @@ -347,33 +337,16 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() BOOST_LOG_TRIVIAL(error) << "Unable to map file " << m_filename << ". Cannot show G-code window."; reset(); } -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE } -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -void GCodeViewer::SequentialView::GCodeWindow::start_mapping_file() -{ - std::cout << "GCodeViewer::SequentialView::GCodeWindow::start_mapping_file()\n"; -} - -void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() -{ - std::cout << "GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()\n"; -} -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, uint64_t curr_line_id) const { auto update_lines = [this](uint64_t start_id, uint64_t end_id) { std::vector ret; ret.reserve(end_id - start_id + 1); for (uint64_t id = start_id; id <= end_id; ++id) { -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE // read line from file std::string gline(m_file.data() + m_lines_map[id - 1].first, m_lines_map[id - 1].second); -#else - const std::string& gline = m_gcode[id - 1]; -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE std::string command; std::string parameters; @@ -407,13 +380,8 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE if (!m_visible || m_filename.empty() || m_lines_map.empty() || curr_line_id == 0) return; -#else - if (!m_visible || m_filename.empty() || m_gcode.empty() || curr_line_id == 0) - return; -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE // window height const float wnd_height = bottom - top; @@ -430,21 +398,13 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u const uint64_t half_lines_count = lines_count / 2; uint64_t start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0; uint64_t end_id = start_id + lines_count - 1; -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE if (end_id >= static_cast(m_lines_map.size())) { end_id = static_cast(m_lines_map.size()) - 1; start_id = end_id - lines_count + 1; } -#else - if (end_id >= static_cast(m_gcode.size())) { - end_id = static_cast(m_gcode.size()) - 1; - start_id = end_id - lines_count + 1; - } -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE // updates list of lines to show, if needed if (m_selected_line_id != curr_line_id || m_last_lines_size != end_id - start_id + 1) { -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE try { *const_cast*>(&m_lines) = update_lines(start_id, end_id); @@ -454,9 +414,6 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u BOOST_LOG_TRIVIAL(error) << "Error while loading from file " << m_filename << ". Cannot show G-code window."; return; } -#else - *const_cast*>(&m_lines) = update_lines(start_id, end_id); -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE *const_cast(&m_selected_line_id) = curr_line_id; *const_cast(&m_last_lines_size) = m_lines.size(); } @@ -531,13 +488,11 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u ImGui::PopStyleVar(); } -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file() { if (m_file.is_open()) m_file.close(); } -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void GCodeViewer::SequentialView::render(float legend_height) const { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 890961a82..cc897c7bc 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -5,9 +5,9 @@ #include "libslic3r/GCode/GCodeProcessor.hpp" #include "GLModel.hpp" -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE +#if ENABLE_GCODE_WINDOW #include -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE +#endif // ENABLE_GCODE_WINDOW #include #include @@ -623,46 +623,30 @@ public: uint64_t m_selected_line_id{ 0 }; size_t m_last_lines_size{ 0 }; std::string m_filename; -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE boost::iostreams::mapped_file_source m_file; // map for accessing data in file by line number std::vector> m_lines_map; -#else - std::vector m_gcode; -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE // current visible lines std::vector m_lines; public: -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE GCodeWindow() = default; ~GCodeWindow() { stop_mapping_file(); } -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void set_filename(const std::string& filename) { m_filename = filename; } void load_gcode(); -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - void start_mapping_file(); - void stop_mapping_file(); -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void reset() { stop_mapping_file(); m_lines_map.clear(); m_lines.clear(); m_filename.clear(); } -#else - void reset() { m_filename.clear(); } -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void toggle_visibility() { m_visible = !m_visible; } void render(float top, float bottom, uint64_t curr_line_id) const; -#if ENABLE_GCODE_WINDOW_USE_MAPPED_FILE private: void stop_mapping_file(); -#endif // ENABLE_GCODE_WINDOW_USE_MAPPED_FILE }; #endif // ENABLE_GCODE_WINDOW @@ -783,10 +767,6 @@ public: void export_toolpaths_to_obj(const char* filename) const; #if ENABLE_GCODE_WINDOW -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - void start_mapping_gcode_file() { m_sequential_view.gcode_window.start_mapping_file(); } - void stop_mapping_gcode_file() { m_sequential_view.gcode_window.stop_mapping_file(); } -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE void toggle_gcode_window_visibility() { m_sequential_view.gcode_window.toggle_visibility(); } #endif // ENABLE_GCODE_WINDOW diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8f78e63e2..a77581535 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1195,11 +1195,6 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) GLCanvas3D::~GLCanvas3D() { -#if ENABLE_GCODE_WINDOW -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - m_gcode_viewer.stop_mapping_gcode_file(); -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -#endif // ENABLE_GCODE_WINDOW reset_volumes(); } @@ -3900,20 +3895,6 @@ void GLCanvas3D::mouse_up_cleanup() m_canvas->ReleaseMouse(); } -#if ENABLE_GCODE_WINDOW -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -void GLCanvas3D::start_mapping_gcode_file() -{ - m_gcode_viewer.start_mapping_gcode_file(); -} - -void GLCanvas3D::stop_mapping_gcode_file() -{ - m_gcode_viewer.stop_mapping_gcode_file(); -} -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -#endif // ENABLE_GCODE_WINDOW - bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 27e8b49c7..10294931f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -785,13 +785,6 @@ public: #endif } -#if ENABLE_GCODE_WINDOW -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - void start_mapping_gcode_file(); - void stop_mapping_gcode_file(); -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -#endif // ENABLE_GCODE_WINDOW - private: bool _is_shown_on_screen() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 67aae3f9b..7a38dd3a1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3368,17 +3368,8 @@ void Plater::priv::set_current_panel(wxPanel* panel) panel_sizer->Layout(); if (current_panel == view3D) { -#if ENABLE_GCODE_WINDOW - if (old_panel == preview) { -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - preview->get_canvas3d()->stop_mapping_gcode_file(); -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - preview->get_canvas3d()->unbind_event_handlers(); - } -#else if (old_panel == preview) preview->get_canvas3d()->unbind_event_handlers(); -#endif // ENABLE_GCODE_WINDOW view3D->get_canvas3d()->bind_event_handlers(); @@ -3403,11 +3394,6 @@ void Plater::priv::set_current_panel(wxPanel* panel) view3D->get_canvas3d()->unbind_event_handlers(); preview->get_canvas3d()->bind_event_handlers(); -#if ENABLE_GCODE_WINDOW -#if !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE - preview->get_canvas3d()->start_mapping_gcode_file(); -#endif // !ENABLE_GCODE_WINDOW_USE_MAPPED_FILE -#endif // ENABLE_GCODE_WINDOW // see: Plater::priv::object_list_changed() // FIXME: it may be better to have a single function making this check and let it be called wherever needed From 117a6ace5a31b5f44a2b1e354d0c44cf5d2e2289 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 15 Mar 2021 11:27:24 +0100 Subject: [PATCH 9/9] G-code window - Fixed file mapping for gcode files generated by other slicers --- src/slic3r/GUI/GCodeViewer.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 7abcbdc41..17e3ac68c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -308,15 +308,28 @@ void GCodeViewer::SequentialView::GCodeWindow::load_gcode() try { - boost::nowide::ifstream f(m_filename); - std::string line; // generate mapping for accessing data in file by line number + boost::nowide::ifstream f(m_filename); + + f.seekg(0, f.end); + uint64_t file_length = static_cast(f.tellg()); + f.seekg(0, f.beg); + + std::string line; uint64_t offset = 0; while (std::getline(f, line)) { - size_t line_length = static_cast(line.length()); + uint64_t line_length = static_cast(line.length()); m_lines_map.push_back({ offset, line_length }); offset += static_cast(line_length) + 1; - } + } + + if (offset != file_length) { + // if the final offset does not match with file length, lines are terminated with CR+LF + // so update all offsets accordingly + for (size_t i = 0; i < m_lines_map.size(); ++i) { + m_lines_map[i].first += static_cast(i); + } + } } catch (...) {