Tsmith35 per BS PR4631 (#6709)

ENH: support spiral lift with timelapse gcode
The existing implementation did only read the new Z position from the injected timelapse_gcode and flagged the position as unsafe because of this.

This change reads X, Y and Z pos from the timelapgse_gcode and will keep the position state correct to enable safety checks required for using spiral Z hop.

Because of this, spiral Z hop can be used everyhwere now. The same pattern is also applied for layer_change/toolhead gcode injection.

The set_current_position_clear method is unused but will be kept in implementation for future scenarios.

Co-authored-by: Simon ziehmon@users.noreply.github.com
This commit is contained in:
Tom 2024-09-14 10:52:04 -05:00 committed by GitHub
parent 603e3e76b0
commit c8216accfd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 237 additions and 93 deletions

View file

@ -2185,13 +2185,14 @@ int GCodeProcessor::get_gcode_last_filament(const std::string& gcode_str)
return out_filament;
}
//BBS: get last z position from gcode
bool GCodeProcessor::get_last_z_from_gcode(const std::string& gcode_str, double& z)
//BBS: get last position from gcode for specified axis
//axis index is the same as Vec3d (X=0, Y=1, Z=2)
bool GCodeProcessor::get_last_pos_from_gcode(const std::string& gcode_str, int axis, double& pos)
{
int str_size = gcode_str.size();
int start_index = 0;
int end_index = 0;
bool is_z_changed = false;
bool is_axis_changed = false;
while (end_index < str_size) {
//find a full line
if (gcode_str[end_index] != '\n') {
@ -2211,24 +2212,32 @@ bool GCodeProcessor::get_last_z_from_gcode(const std::string& gcode_str, double&
|| line_str.find("G2 ") == 0
|| line_str.find("G3 ") == 0))
{
auto z_pos = line_str.find(" Z");
double temp_z = 0;
if (z_pos != line_str.npos
&& z_pos + 2 < line_str.size()) {
std::string axis_str;
if (axis == 0) {
axis_str = "X";
} else if (axis == 1) {
axis_str = "Y";
} else if (axis == 2) {
axis_str = "Z";
}
auto axis_pos = line_str.find(" " + axis_str);
double temp_axis_pos = 0;
if (axis_pos != line_str.npos
&& axis_pos + 2 < line_str.size()) {
// Try to parse the numeric value.
std::string z_sub = line_str.substr(z_pos + 2);
char* c = &z_sub[0];
char* end = c + sizeof(z_sub.c_str());
std::string axis_substr = line_str.substr(axis_pos + 2);
char* start_ptr = &axis_substr[0];
char* end_ptr = start_ptr + sizeof(axis_substr.c_str());
auto is_end_of_word = [](char c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 0 || c == ';';
};
auto [pend, ec] = fast_float::from_chars(c, end, temp_z);
if (pend != c && is_end_of_word(*pend)) {
auto [parsed_ptr, error_code] = fast_float::from_chars(start_ptr, end_ptr, temp_axis_pos);
if (parsed_ptr != start_ptr && is_end_of_word(*parsed_ptr)) {
// The axis value has been parsed correctly.
z = temp_z;
is_z_changed = true;
pos = temp_axis_pos;
is_axis_changed = true;
}
}
}
@ -2237,7 +2246,7 @@ bool GCodeProcessor::get_last_z_from_gcode(const std::string& gcode_str, double&
start_index = end_index + 1;
end_index = start_index;
}
return is_z_changed;
return is_axis_changed;
}
void GCodeProcessor::process_tags(const std::string_view comment, bool producers_enabled)
@ -5401,4 +5410,4 @@ void GCodeProcessor::update_slice_warnings()
m_result.warnings.shrink_to_fit();
}
} /* namespace Slic3r */
} /* slic3r_GCodeProcessor_cpp_ */