Fix acceleration/jerk state after custom G-code (#14613)

This commit is contained in:
Kiss Lorand
2026-07-22 22:30:43 +03:00
committed by GitHub
parent 857adad293
commit 5edd4963eb
4 changed files with 72 additions and 2 deletions

View File

@@ -730,6 +730,42 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
return temp_set_by_gcode;
}
struct CustomGCodeMotionStateChanges
{
bool acceleration = false;
bool jerk = false;
};
static bool custom_gcode_line_has_xy_parameter(const std::string &raw)
{
const size_t comment_pos = raw.find(';');
const std::string_view code(raw.data(), comment_pos == std::string::npos ? raw.size() : comment_pos);
return code.find_first_of("XxYy") != std::string_view::npos;
}
static CustomGCodeMotionStateChanges custom_gcode_motion_state_changes(const std::string &gcode)
{
CustomGCodeMotionStateChanges changes;
GCodeReader parser;
parser.parse_buffer(gcode, [&changes](GCodeReader &parser, const GCodeReader::GCodeLine &line) {
const std::string_view cmd = line.cmd();
if (boost::iequals(cmd, "M204") || boost::iequals(cmd, "M201") ||
boost::iequals(cmd, "M202"))
changes.acceleration = true;
else if ((boost::iequals(cmd, "M205") || boost::iequals(cmd, "M207") || boost::iequals(cmd, "M566")) &&
custom_gcode_line_has_xy_parameter(line.raw()))
changes.jerk = true;
else if (boost::iequals(cmd, "SET_VELOCITY_LIMIT")) {
changes.acceleration |= boost::icontains(line.raw(), "ACCEL=");
changes.jerk |= boost::icontains(line.raw(), "SQUARE_CORNER_VELOCITY=");
}
if (changes.acceleration && changes.jerk)
parser.quit_parsing();
});
return changes;
}
// BBS
// start_pos refers to the last position before the wipe_tower.
// end_pos refers to the wipe tower's start_pos.
@@ -4335,6 +4371,11 @@ PlaceholderParserIntegration &ppi = m_placeholder_parser_integration;
ppi.update_from_gcodewriter(m_writer);
std::string output = ppi.parser.process(templ, current_filament_id, config_override, &ppi.output_config, &ppi.context);
ppi.validate_output_vector_variables();
const CustomGCodeMotionStateChanges motion_state_changes = custom_gcode_motion_state_changes(output);
if (motion_state_changes.acceleration)
m_writer.invalidate_acceleration();
if (motion_state_changes.jerk)
m_writer.invalidate_jerk();
if (const std::vector<double> &pos = ppi.opt_position->values; ppi.position != pos) {
// Update G-code writer.

View File

@@ -133,6 +133,8 @@ public:
const bool is_bbl_printers() const {return m_is_bbl_printers;}
void set_is_first_layer(bool bval) { m_is_first_layer = bval; }
GCodeFlavor get_gcode_flavor() const { return config.gcode_flavor; }
void invalidate_acceleration() { m_last_acceleration = 0; m_last_travel_acceleration = 0; }
void invalidate_jerk() { m_last_jerk = 0; }
// Returns whether this flavor supports separate print and travel acceleration.
static bool supports_separate_travel_acceleration(GCodeFlavor flavor);

View File

@@ -215,8 +215,8 @@ GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, const std::ve
const EOptionType option_type = move_type_to_option(curr_type);
if (option_type == EOptionType::COUNT || option_type == EOptionType::Travels || option_type == EOptionType::Wipes) {
if (ret.vertices.empty() || prev.type != curr.type || prev.extrusion_role != curr.extrusion_role
// ORCA: Fix issue with flow rate changes being visualized incorrectly
|| prev.mm3_per_mm != curr.mm3_per_mm) {
// ORCA: Split the path when a preview value changes.
|| prev.mm3_per_mm != curr.mm3_per_mm || prev.acceleration != curr.acceleration || prev.jerk != curr.jerk) {
// to allow libvgcode to properly detect the start/end of a path we need to add a 'phantom' vertex
// equal to the current one with the exception of the position, which should match the previous move position,
// and the times, which are set to zero

View File

@@ -820,3 +820,30 @@ SCENARIO("Shipped dual-nozzle change_filament_gcode resolves during a real slice
}
}
}
TEST_CASE("Custom G-code motion limits are restored before generated moves", "[GCodeWriter]")
{
const std::string gcode = Slic3r::Test::slice({ cube(20) }, {
{ "gcode_flavor", "marlin" },
{ "gcode_comments", "1" },
{ "machine_start_gcode", "" },
{ "layer_change_gcode", "M204 S5000\nm205 x5 y5\n" },
{ "layer_height", "0.2" },
{ "initial_layer_print_height", "0.2" },
{ "initial_layer_line_width", "0" },
{ "z_hop", "0" },
{ "default_acceleration", "6000" },
{ "initial_layer_acceleration", "6000" },
{ "outer_wall_acceleration", "6000" },
{ "inner_wall_acceleration", "0" },
{ "default_jerk", "8" },
{ "initial_layer_jerk", "8" },
{ "outer_wall_jerk", "8" },
{ "inner_wall_jerk", "0" },
});
const size_t custom_gcode_pos = gcode.find("m205 x5 y5");
REQUIRE(custom_gcode_pos != std::string::npos);
REQUIRE(gcode.find("M204 S6000 ; adjust acceleration", custom_gcode_pos) != std::string::npos);
REQUIRE(gcode.find("M205 X8 Y8 ; adjust jerk", custom_gcode_pos) != std::string::npos);
}