From e3a772597ab6a4d60beb3b5f5ee1ecf2271bf3c4 Mon Sep 17 00:00:00 2001 From: minicx Date: Tue, 16 Dec 2025 22:47:38 +0300 Subject: [PATCH] Add Pressure Advance visualization support Signed-off-by: minicx --- src/libslic3r/GCode/GCodeProcessor.cpp | 39 ++++++++++++++++++++++++++ src/libslic3r/GCode/GCodeProcessor.hpp | 7 +++++ src/slic3r/GUI/GCodeViewer.cpp | 20 ++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 5 ++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9f7687d2c6..745855de50 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1638,6 +1638,9 @@ void GCodeProcessor::register_commands() {"M702", [this](const GCodeReader::GCodeLine& line) { process_M702(line); }}, // Unload the current filament into the MK3 MMU2 unit at the end of print. {"M1020", [this](const GCodeReader::GCodeLine& line) { process_M1020(line); }}, // Select Tool + {"M900", [this](const GCodeReader::GCodeLine& line) { process_M900(line); }}, // Marlin: Set pressure advance + {"M572", [this](const GCodeReader::GCodeLine& line) { process_M572(line); }}, // RepRapFirmware/Duet: Set pressure advance + {"T", [this](const GCodeReader::GCodeLine& line) { process_T(line); }}, // Select Tool {"SYNC", [this](const GCodeReader::GCodeLine& line) { process_SYNC(line); }}, // SYNC TIME @@ -2764,6 +2767,11 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool process_SET_VELOCITY_LIMIT(line); return; } + if (boost::iequals(cmd, "SET_PRESSURE_ADVANCE")) + { + process_SET_PRESSURE_ADVANCE(line); + return; + } } if (cmd.length() > 1) { @@ -5116,6 +5124,36 @@ void GCodeProcessor::process_M106(const GCodeReader::GCodeLine& line) } } +void GCodeProcessor::process_M900(const GCodeReader::GCodeLine &line) +{ + float pa_value = m_pressure_advance; + line.has_value('K', pa_value); + m_pressure_advance = std::max(0.0f, pa_value); + // BOOST_LOG_TRIVIAL(debug) << "M900 command: PA set to " << m_pressure_advance; +} + +void GCodeProcessor::process_M572(const GCodeReader::GCodeLine &line) +{ + float pa_value = m_pressure_advance; + line.has_value('S', pa_value); + m_pressure_advance = std::max(0.0f, pa_value); + // BOOST_LOG_TRIVIAL(debug) << "M572 command: PA set to " << m_pressure_advance; +} + +void GCodeProcessor::process_SET_PRESSURE_ADVANCE(const GCodeReader::GCodeLine& line) +{ + std::regex regex(R"(SET_PRESSURE_ADVANCE\s+(?:.*\s+)?ADVANCE\s*=\s*([\d.]+))"); + std::smatch matches; + + if (std::regex_search(line.raw(), matches, regex) && matches.size() > 1) { + float pa_value = 0; + try { + pa_value = std::stof(matches[1].str()); + } catch (...) {} + m_pressure_advance = std::max(0.0f, pa_value); + } +} + void GCodeProcessor::process_M107(const GCodeReader::GCodeLine& line) { m_fan_speed = 0.0f; @@ -5665,6 +5703,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type) m_travel_dist, m_fan_speed, m_extruder_temps[filament_id], + m_pressure_advance, static_cast(m_result.moves.size()), static_cast(m_layer_id), //layer_duration: set later //BBS: add arc move related data diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 080906da42..cdf0906a34 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -192,6 +192,7 @@ class Print; float travel_dist{ 0.0f }; // mm float fan_speed{ 0.0f }; // percentage float temperature{ 0.0f }; // Celsius degrees + float pressure_advance{ 0.0f }; float time{ 0.0f }; // s float layer_duration{ 0.0f }; // s (layer id before finalize) @@ -781,6 +782,7 @@ class Print; float m_travel_dist; // mm float m_fan_speed; // percentage float m_z_offset; // mm + float m_pressure_advance; ExtrusionRole m_extrusion_role; std::vector m_filament_maps; std::vector m_last_filament_id; @@ -982,6 +984,11 @@ class Print; // Disable fan void process_M107(const GCodeReader::GCodeLine& line); + // Set pressure advance + void process_M900(const GCodeReader::GCodeLine& line); + void process_M572(const GCodeReader::GCodeLine &line); + void process_SET_PRESSURE_ADVANCE(const GCodeReader::GCodeLine& line); + // Set tool (Sailfish) void process_M108(const GCodeReader::GCodeLine& line); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 98cbcc0e54..8422055e89 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -82,6 +82,8 @@ static std::string get_view_type_string(GCodeViewer::EViewType view_type) return _u8L("Layer Time"); else if (view_type == GCodeViewer::EViewType::LayerTimeLog) return _u8L("Layer Time (log)"); + else if (view_type == GCodeViewer::EViewType::PressureAdvance) + return _u8L("Pressure Advance"); return ""; } @@ -227,7 +229,7 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move paths.push_back({ move.type, move.extrusion_role, move.delta_extruder, round_to_bin(move.height), round_to_bin(move.width), move.feedrate, move.fan_speed, move.temperature, - move.volumetric_rate(), move.layer_duration, move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); + move.volumetric_rate(), move.layer_duration, move.pressure_advance, move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); } ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -364,6 +366,7 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he std::string layer_time = ImGui::ColorMarkerStart + _u8L("Layer Time: ") + ImGui::ColorMarkerEnd; std::string fanspeed = ImGui::ColorMarkerStart + _u8L("Fan: ") + ImGui::ColorMarkerEnd; std::string temperature = ImGui::ColorMarkerStart + _u8L("Temperature: ") + ImGui::ColorMarkerEnd; + std::string pressure_advance = ImGui::ColorMarkerStart + _u8L("PA: ") + ImGui::ColorMarkerEnd; const float item_size = imgui.calc_text_size(std::string_view{"X: 000.000 "}).x; const float item_spacing = imgui.get_item_spacing().x; const float window_padding = ImGui::GetStyle().WindowPadding.x; @@ -443,6 +446,13 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he imgui.text(buf); break; } + case EViewType::PressureAdvance: { + ImGui::SameLine(startx2); + sprintf(buf, "%s%.4f", pressure_advance.c_str(), m_curr_move.pressure_advance); + ImGui::PushItemWidth(item_size); + imgui.text(buf); + break; + } default: break; } @@ -916,6 +926,7 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode) view_type_items.push_back(EViewType::LayerTimeLog); view_type_items.push_back(EViewType::FanSpeed); view_type_items.push_back(EViewType::Temperature); + view_type_items.push_back(EViewType::PressureAdvance); //if (mode == ConfigOptionMode::comDevelop) { // view_type_items.push_back(EViewType::Tool); //} @@ -1194,6 +1205,10 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v m_extrusions.ranges.layer_duration.update_from(curr.layer_duration); m_extrusions.ranges.layer_duration_log.update_from(curr.layer_duration); } + + if (curr.pressure_advance >= 0.0f) { + m_extrusions.ranges.pressure_advance.update_from(curr.pressure_advance); + } [[fallthrough]]; } case EMoveType::Travel: @@ -3254,6 +3269,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool case EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } case EViewType::LayerTime: { color = m_extrusions.ranges.layer_duration.get_color_at(path.layer_time); break; } case EViewType::LayerTimeLog: { color = m_extrusions.ranges.layer_duration_log.get_color_at(path.layer_time); break; } + case EViewType::PressureAdvance: { color = m_extrusions.ranges.pressure_advance.get_color_at(path.pressure_advance); break; } case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } case EViewType::Tool: { color = m_tools.m_tool_colors[path.extruder_id]; break; } case EViewType::Summary: @@ -5221,6 +5237,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv case EViewType::FanSpeed: { imgui.title(_u8L("Fan Speed (%)")); break; } case EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } + case EViewType::PressureAdvance:{ imgui.title(_u8L("Pressure Advance")); break; } case EViewType::LayerTime: { imgui.title(_u8L("Layer Time")); break; } case EViewType::LayerTimeLog: { imgui.title(_u8L("Layer Time (log)")); break; } @@ -5379,6 +5396,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv case EViewType::Temperature: { append_range(m_extrusions.ranges.temperature, 0); break; } case EViewType::LayerTime: { append_range(m_extrusions.ranges.layer_duration, true); break; } case EViewType::LayerTimeLog: { append_range(m_extrusions.ranges.layer_duration_log, true); break; } + case EViewType::PressureAdvance:{ append_range(m_extrusions.ranges.pressure_advance, 3); break; } case EViewType::VolumetricRate: { append_range(m_extrusions.ranges.volumetric_rate, 2); break; } case EViewType::Tool: { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 7c86a37e1c..65149e4dd4 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -221,6 +221,7 @@ class GCodeViewer float temperature{ 0.0f }; float volumetric_rate{ 0.0f }; float layer_time{ 0.0f }; + float pressure_advance{ 0.0f }; unsigned char extruder_id{ 0 }; unsigned char cp_color_id{ 0 }; std::vector sub_paths; @@ -420,6 +421,8 @@ class GCodeViewer // Color mapping by layer time. Range layer_duration; Range layer_duration_log; + // Color mapping by pressure advance. + Range pressure_advance; void reset() { height.reset(); width.reset(); @@ -429,6 +432,7 @@ Range layer_duration_log; temperature.reset(); layer_duration.reset(); layer_duration_log.reset(true); + pressure_advance.reset(); } }; @@ -722,6 +726,7 @@ public: FilamentId, LayerTime, LayerTimeLog, + PressureAdvance, Count }; // helper to render shells