Skip to content

Commit

Permalink
Extended the Cooling Buffer G-code filter to remove repeated
Browse files Browse the repository at this point in the history
G1 Fxx entries to reduce the G-code size and printer stutter.
Fixes prusa3d#448
  • Loading branch information
bubnikv committed Mar 19, 2018
1 parent bfc9678 commit ebf0ef4
Showing 1 changed file with 88 additions and 37 deletions.
125 changes: 88 additions & 37 deletions xs/src/libslic3r/GCode/CoolingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
TYPE_G1 = 1 << 5,
TYPE_ADJUSTABLE = 1 << 6,
TYPE_EXTERNAL_PERIMETER = 1 << 7,
TYPE_WIPE = 1 << 8,
TYPE_G4 = 1 << 9,
TYPE_G92 = 1 << 10,
// The line sets a feedrate.
TYPE_HAS_F = 1 << 8,
TYPE_WIPE = 1 << 9,
TYPE_G4 = 1 << 10,
TYPE_G92 = 1 << 11,
};

Line(unsigned int type, size_t line_start, size_t line_end) :
Expand Down Expand Up @@ -187,9 +189,13 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
(*c == extrusion_axis) ? 3 : (*c == 'F') ? 4 : size_t(-1);
if (axis != size_t(-1)) {
new_pos[axis] = float(atof(++c));
if (axis == 4)
if (axis == 4) {
// Convert mm/min to mm/sec.
new_pos[4] /= 60.f;
if ((line.type & Adjustment::Line::TYPE_G92) == 0)
// This is G0 or G1 line and it sets the feedrate. This mark is used for reducing the duplicate F calls.
line.type |= Adjustment::Line::TYPE_HAS_F;
}
}
// Skip this word.
for (; *c != ' ' && *c != '\t' && *c != 0; ++ c);
Expand Down Expand Up @@ -227,6 +233,8 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
if ((line.type & Adjustment::Line::TYPE_ADJUSTABLE) || active_speed_modifier != size_t(-1))
line.time_max = (min_print_speed == 0.f) ? FLT_MAX : std::max(line.time, line.length / min_print_speed);
if (active_speed_modifier < adjustment->lines.size() && (line.type & Adjustment::Line::TYPE_G1)) {
// Inside the ";_EXTRUDE_SET_SPEED" blocks, there must not be a G1 Fxx entry.
assert((line.type & Adjustment::Line::TYPE_HAS_F) == 0);
Adjustment::Line &sm = adjustment->lines[active_speed_modifier];
sm.length += line.length;
sm.time += line.time;
Expand Down Expand Up @@ -415,17 +423,20 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
};
change_extruder_set_fan();

size_t pos = 0;
const char *pos = gcode.c_str();
int current_feedrate = 0;
for (const Adjustment::Line *line : lines) {
if (line->line_start > pos)
new_gcode.append(gcode.c_str() + pos, line->line_start - pos);
const char *line_start = gcode.c_str() + line->line_start;
const char *line_end = gcode.c_str() + line->line_end;
if (line_start > pos)
new_gcode.append(pos, line_start - pos);
if (line->type & Adjustment::Line::TYPE_SET_TOOL) {
unsigned int new_extruder = (unsigned int)atoi(gcode.c_str() + line->line_start + toolchange_prefix.size());
unsigned int new_extruder = (unsigned int)atoi(line_start + toolchange_prefix.size());
if (new_extruder != m_current_extruder) {
m_current_extruder = new_extruder;
change_extruder_set_fan();
}
new_gcode.append(gcode.c_str() + line->line_start, line->line_end - line->line_start);
new_gcode.append(line_start, line_end - line_start);
} else if (line->type & Adjustment::Line::TYPE_BRIDGE_FAN_START) {
if (bridge_fan_control)
new_gcode += m_gcodegen.writer().set_fan(bridge_fan_speed, true);
Expand All @@ -434,40 +445,80 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
new_gcode += m_gcodegen.writer().set_fan(fan_speed, true);
} else if (line->type & Adjustment::Line::TYPE_EXTRUDE_END) {
// Just remove this comment.
} else if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) {
// Start of the comment. The line type indicates there must be some comment present.
const char *end = strchr(gcode.c_str() + line->line_start, ';');
} else if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE | Adjustment::Line::TYPE_HAS_F)) {
// Find the start of a comment, or roll to the end of line.
const char *end = line_start;
for (; end < line_end && *end != ';'; ++ end);
// Find the 'F' word.
const char *fpos = strstr(line_start + 2, " F") + 2;
int new_feedrate = current_feedrate;
bool modify = false;
assert(fpos != nullptr);
if (line->slowdown) {
// Replace the feedrate.
const char *pos = strstr(gcode.c_str() + line->line_start + 2, " F") + 2;
new_gcode.append(gcode.c_str() + line->line_start, pos - gcode.c_str() - line->line_start);
char buf[64];
sprintf(buf, "%d", int(floor(60. * (line->length / line->time) + 0.5)));
new_gcode += buf;
// Skip the non-whitespaces up to the comment.
for (; *pos != ' ' && *pos != ';'; ++ pos);
// Append the rest of the line without the comment.
if (pos < end)
new_gcode.append(pos, end - pos);
modify = true;
new_feedrate = int(floor(60. * (line->length / line->time) + 0.5));
} else {
// Append the line without the comment.
new_gcode.append(gcode.c_str() + line->line_start, end - gcode.c_str() - line->line_start);
new_feedrate = atoi(fpos);
if (new_feedrate != current_feedrate) {
// Append the line without the comment.
new_gcode.append(line_start, end - line_start);
current_feedrate = new_feedrate;
} else if ((line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) || line->length == 0.) {
// Feedrate does not change and this line does not move the print head. Skip the complete G-code line including the G-code comment.
end = line_end;
} else {
// Remove the feedrate from the G0/G1 line.
modify = true;
}
}
if (modify) {
if (new_feedrate != current_feedrate) {
// Replace the feedrate.
new_gcode.append(line_start, fpos - line_start);
current_feedrate = new_feedrate;
char buf[64];
sprintf(buf, "%d", int(current_feedrate));
new_gcode += buf;
} else {
// Remove the feedrate word.
const char *f = fpos;
// Roll the pointer before the 'F' word.
for (f -= 2; f > line_start && (*f == ' ' || *f == '\t'); -- f);
// Append up to the F word, without the trailing whitespace.
new_gcode.append(line_start, f - line_start + 1);
}
// Skip the non-whitespaces of the F parameter up the comment or end of line.
for (; fpos != end && *fpos != ' ' && *fpos != ';' && *fpos != '\n'; ++fpos);
// Append the rest of the line without the comment.
if (fpos < end)
new_gcode.append(fpos, end - fpos);
// There should never be an empty G1 statement emited by the filter. Such lines should be removed completely.
assert(new_gcode.size() < 4 || new_gcode.substr(new_gcode.size() - 4) != "G1 \n");
}
// Process the rest of the line.
if (end < line_end) {
if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) {
// Process comments, remove ";_EXTRUDE_SET_SPEED", ";_EXTERNAL_PERIMETER", ";_WIPE"
std::string comment(end, line_end);
boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
if (line->type & Adjustment::Line::TYPE_EXTERNAL_PERIMETER)
boost::replace_all(comment, ";_EXTERNAL_PERIMETER", "");
if (line->type & Adjustment::Line::TYPE_WIPE)
boost::replace_all(comment, ";_WIPE", "");
new_gcode += comment;
} else {
// Just attach the rest of the source line.
new_gcode.append(end, line_end - end);
}
}
// Process the comments, remove ";_EXTRUDE_SET_SPEED", ";_EXTERNAL_PERIMETER", ";_WIPE"
std::string comment(end, gcode.c_str() + line->line_end);
boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
if (line->type & Adjustment::Line::TYPE_EXTERNAL_PERIMETER)
boost::replace_all(comment, ";_EXTERNAL_PERIMETER", "");
if (line->type & Adjustment::Line::TYPE_WIPE)
boost::replace_all(comment, ";_WIPE", "");
new_gcode += comment;
} else {
new_gcode.append(gcode.c_str() + line->line_start, line->line_end - line->line_start);
new_gcode.append(line_start, line_end - line_start);
}
pos = line->line_end;
pos = line_end;
}
if (pos < gcode.size())
new_gcode.append(gcode.c_str() + pos, gcode.size() - pos);
const char *gcode_end = gcode.c_str() + gcode.size();
if (pos < gcode_end)
new_gcode.append(pos, gcode_end - pos);

return new_gcode;
}
Expand Down

0 comments on commit ebf0ef4

Please sign in to comment.