mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-01-31 16:08:43 +03:00
PRUSA 2.7.0
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0)
|
||||
CoolingBuffer::CoolingBuffer(GCodeGenerator &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0)
|
||||
{
|
||||
this->reset(gcodegen.writer().get_position());
|
||||
|
||||
@@ -33,39 +33,45 @@ CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_t
|
||||
|
||||
void CoolingBuffer::reset(const Vec3d &position)
|
||||
{
|
||||
m_current_pos.assign(5, 0.f);
|
||||
m_current_pos[0] = float(position.x());
|
||||
m_current_pos[1] = float(position.y());
|
||||
m_current_pos[2] = float(position.z());
|
||||
m_current_pos[4] = float(m_config.travel_speed.value);
|
||||
m_fan_speed = -1;
|
||||
//Y12
|
||||
m_fan_speed = -1;
|
||||
assert(m_current_pos.size() == 5);
|
||||
m_current_pos[AxisIdx::X] = float(position.x());
|
||||
m_current_pos[AxisIdx::Y] = float(position.y());
|
||||
m_current_pos[AxisIdx::Z] = float(position.z());
|
||||
m_current_pos[AxisIdx::E] = 0.f;
|
||||
m_current_pos[AxisIdx::F] = float(m_config.travel_speed.value);
|
||||
m_fan_speed = -1;
|
||||
}
|
||||
|
||||
struct CoolingLine
|
||||
{
|
||||
enum Type {
|
||||
enum Type : uint32_t {
|
||||
TYPE_SET_TOOL = 1 << 0,
|
||||
TYPE_EXTRUDE_END = 1 << 1,
|
||||
TYPE_BRIDGE_FAN_START = 1 << 2,
|
||||
TYPE_BRIDGE_FAN_END = 1 << 3,
|
||||
TYPE_G0 = 1 << 4,
|
||||
TYPE_G1 = 1 << 5,
|
||||
TYPE_ADJUSTABLE = 1 << 6,
|
||||
TYPE_EXTERNAL_PERIMETER = 1 << 7,
|
||||
// G2 or G3: Arc interpolation
|
||||
TYPE_G2G3 = 1 << 6,
|
||||
TYPE_ADJUSTABLE = 1 << 7,
|
||||
TYPE_EXTERNAL_PERIMETER = 1 << 8,
|
||||
// Arc interpolation, counter-clockwise.
|
||||
TYPE_G2G3_CCW = 1 << 9,
|
||||
// Arc interpolation, arc defined by IJ (offset of arc center from its start position).
|
||||
TYPE_G2G3_IJ = 1 << 10,
|
||||
// Arc interpolation, arc defined by R (arc radius, positive - smaller, negative - larger).
|
||||
TYPE_G2G3_R = 1 << 11,
|
||||
// The line sets a feedrate.
|
||||
TYPE_HAS_F = 1 << 8,
|
||||
TYPE_WIPE = 1 << 9,
|
||||
TYPE_G4 = 1 << 10,
|
||||
TYPE_G92 = 1 << 11,
|
||||
TYPE_HAS_F = 1 << 12,
|
||||
TYPE_WIPE = 1 << 13,
|
||||
TYPE_G4 = 1 << 14,
|
||||
TYPE_G92 = 1 << 15,
|
||||
// Would be TYPE_ADJUSTABLE, but the block of G-code lines has zero extrusion length, thus the block
|
||||
// cannot have its speed adjusted. This should not happen (sic!).
|
||||
TYPE_ADJUSTABLE_EMPTY = 1 << 12,
|
||||
TYPE_ADJUSTABLE_EMPTY = 1 << 16,
|
||||
// Custom fan speed (introduced for overhang fan speed)
|
||||
TYPE_SET_FAN_SPEED = 1 << 13,
|
||||
TYPE_RESET_FAN_SPEED = 1 << 14,
|
||||
TYPE_SET_FAN_SPEED = 1 << 17,
|
||||
TYPE_RESET_FAN_SPEED = 1 << 18,
|
||||
};
|
||||
|
||||
CoolingLine(unsigned int type, size_t line_start, size_t line_end) :
|
||||
@@ -327,7 +333,7 @@ std::string CoolingBuffer::process_layer(std::string &&gcode, size_t layer_id, b
|
||||
|
||||
// Parse the layer G-code for the moves, which could be adjusted.
|
||||
// Return the list of parsed lines, bucketed by an extruder.
|
||||
std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::string &gcode, std::vector<float> ¤t_pos) const
|
||||
std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::string &gcode, std::array<float, 5> ¤t_pos) const
|
||||
{
|
||||
std::vector<PerExtruderAdjustments> per_extruder_adjustments(m_extruder_ids.size());
|
||||
std::vector<size_t> map_extruder_to_per_extruder_adjustment(m_num_extruders, 0);
|
||||
@@ -350,7 +356,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
// for a sequence of extrusion moves.
|
||||
size_t active_speed_modifier = size_t(-1);
|
||||
|
||||
std::vector<float> new_pos;
|
||||
std::array<float, AxisIdx::Count> new_pos;
|
||||
for (; *line_start != 0; line_start = line_end)
|
||||
{
|
||||
while (*line_end != '\n' && *line_end != 0)
|
||||
@@ -365,12 +371,20 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
line.type = CoolingLine::TYPE_G0;
|
||||
else if (boost::starts_with(sline, "G1 "))
|
||||
line.type = CoolingLine::TYPE_G1;
|
||||
else if (boost::starts_with(sline, "G2 "))
|
||||
// Arc, clockwise.
|
||||
line.type = CoolingLine::TYPE_G2G3;
|
||||
else if (boost::starts_with(sline, "G3 "))
|
||||
// Arc, counter-clockwise.
|
||||
line.type = CoolingLine::TYPE_G2G3 | CoolingLine::TYPE_G2G3_CCW;
|
||||
else if (boost::starts_with(sline, "G92 "))
|
||||
line.type = CoolingLine::TYPE_G92;
|
||||
if (line.type) {
|
||||
// G0, G1 or G92
|
||||
// G0, G1, G2, G3 or G92
|
||||
// Initialize current_pos from new_pos, set IJKR to zero.
|
||||
std::fill(std::copy(std::begin(current_pos), std::end(current_pos), std::begin(new_pos)),
|
||||
std::end(new_pos), 0.f);
|
||||
// Parse the G-code line.
|
||||
new_pos = current_pos;
|
||||
for (auto c = sline.begin() + 3;;) {
|
||||
// Skip whitespaces.
|
||||
for (; c != sline.end() && (*c == ' ' || *c == '\t'); ++ c);
|
||||
@@ -379,21 +393,31 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
|
||||
// Parse the axis.
|
||||
size_t axis = (*c >= 'X' && *c <= 'Z') ? (*c - 'X') :
|
||||
(*c == extrusion_axis) ? 3 : (*c == 'F') ? 4 : size_t(-1);
|
||||
(*c == extrusion_axis) ? AxisIdx::E : (*c == 'F') ? AxisIdx::F :
|
||||
(*c >= 'I' && *c <= 'K') ? int(AxisIdx::I) + (*c - 'I') :
|
||||
(*c == 'R') ? AxisIdx::R : size_t(-1);
|
||||
if (axis != size_t(-1)) {
|
||||
//auto [pend, ec] =
|
||||
fast_float::from_chars(&*(++ c), sline.data() + sline.size(), new_pos[axis]);
|
||||
if (axis == 4) {
|
||||
if (axis == AxisIdx::F) {
|
||||
// Convert mm/min to mm/sec.
|
||||
new_pos[4] /= 60.f;
|
||||
new_pos[AxisIdx::F] /= 60.f;
|
||||
if ((line.type & CoolingLine::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 |= CoolingLine::TYPE_HAS_F;
|
||||
}
|
||||
} else if (axis >= AxisIdx::I && axis <= AxisIdx::J)
|
||||
line.type |= CoolingLine::TYPE_G2G3_IJ;
|
||||
else if (axis == AxisIdx::R)
|
||||
line.type |= CoolingLine::TYPE_G2G3_R;
|
||||
}
|
||||
// Skip this word.
|
||||
for (; c != sline.end() && *c != ' ' && *c != '\t'; ++ c);
|
||||
}
|
||||
// If G2 or G3, then either center of the arc or radius has to be defined.
|
||||
assert(! (line.type & CoolingLine::TYPE_G2G3) ||
|
||||
(line.type & (CoolingLine::TYPE_G2G3_IJ | CoolingLine::TYPE_G2G3_R)));
|
||||
// Arc is defined either by IJ or by R, not by both.
|
||||
assert(! ((line.type & CoolingLine::TYPE_G2G3_IJ) && (line.type & CoolingLine::TYPE_G2G3_R)));
|
||||
bool external_perimeter = boost::contains(sline, ";_EXTERNAL_PERIMETER");
|
||||
bool wipe = boost::contains(sline, ";_WIPE");
|
||||
if (external_perimeter)
|
||||
@@ -405,23 +429,41 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
active_speed_modifier = adjustment->lines.size();
|
||||
}
|
||||
if ((line.type & CoolingLine::TYPE_G92) == 0) {
|
||||
// G0 or G1. Calculate the duration.
|
||||
// G0, G1, G2, G3. Calculate the duration.
|
||||
assert((line.type & CoolingLine::TYPE_G0) != 0 + (line.type & CoolingLine::TYPE_G1) != 0 + (line.type & CoolingLine::TYPE_G2G3) != 0 == 1);
|
||||
if (m_config.use_relative_e_distances.value)
|
||||
// Reset extruder accumulator.
|
||||
current_pos[3] = 0.f;
|
||||
current_pos[AxisIdx::E] = 0.f;
|
||||
float dif[4];
|
||||
for (size_t i = 0; i < 4; ++ i)
|
||||
dif[i] = new_pos[i] - current_pos[i];
|
||||
float dxy2 = dif[0] * dif[0] + dif[1] * dif[1];
|
||||
float dxyz2 = dxy2 + dif[2] * dif[2];
|
||||
float dxy2;
|
||||
if (line.type & CoolingLine::TYPE_G2G3) {
|
||||
// Measure arc length.
|
||||
if (line.type & CoolingLine::TYPE_G2G3_IJ) {
|
||||
dxy2 = sqr(Geometry::ArcWelder::arc_length(
|
||||
Vec2d(current_pos[AxisIdx::X], current_pos[AxisIdx::Y]),
|
||||
Vec2d(new_pos[AxisIdx::X], new_pos[AxisIdx::Y]),
|
||||
Vec2d(current_pos[AxisIdx::X] + new_pos[AxisIdx::I], current_pos[AxisIdx::Y] + new_pos[AxisIdx::J]),
|
||||
line.type & CoolingLine::TYPE_G2G3_CCW));
|
||||
} else if (line.type & CoolingLine::TYPE_G2G3_R) {
|
||||
dxy2 = sqr(Geometry::ArcWelder::arc_length(
|
||||
Vec2d(current_pos[AxisIdx::X], current_pos[AxisIdx::Y]),
|
||||
Vec2d(new_pos[AxisIdx::X], new_pos[AxisIdx::Y]),
|
||||
double(new_pos[AxisIdx::R])));
|
||||
} else
|
||||
dxy2 = 0;
|
||||
} else
|
||||
dxy2 = sqr(dif[AxisIdx::X]) + sqr(dif[AxisIdx::Y]);
|
||||
float dxyz2 = dxy2 + sqr(dif[AxisIdx::Z]);
|
||||
if (dxyz2 > 0.f) {
|
||||
// Movement in xyz, calculate time from the xyz Euclidian distance.
|
||||
line.length = sqrt(dxyz2);
|
||||
} else if (std::abs(dif[3]) > 0.f) {
|
||||
} else if (std::abs(dif[AxisIdx::E]) > 0.f) {
|
||||
// Movement in the extruder axis.
|
||||
line.length = std::abs(dif[3]);
|
||||
line.length = std::abs(dif[AxisIdx::E]);
|
||||
}
|
||||
line.feedrate = new_pos[4];
|
||||
line.feedrate = new_pos[AxisIdx::F];
|
||||
assert((line.type & CoolingLine::TYPE_ADJUSTABLE) == 0 || line.feedrate > 0.f);
|
||||
if (line.length > 0) {
|
||||
assert(line.feedrate > 0);
|
||||
@@ -433,7 +475,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
assert(adjustment->min_print_speed >= 0);
|
||||
line.time_max = (adjustment->min_print_speed == 0.f) ? FLT_MAX : std::max(line.time, line.length / adjustment->min_print_speed);
|
||||
}
|
||||
if (active_speed_modifier < adjustment->lines.size() && (line.type & CoolingLine::TYPE_G1)) {
|
||||
if (active_speed_modifier < adjustment->lines.size() && (line.type & (CoolingLine::TYPE_G1 | CoolingLine::TYPE_G2G3))) {
|
||||
// Inside the ";_EXTRUDE_SET_SPEED" blocks, there must not be a G1 Fxx entry.
|
||||
assert((line.type & CoolingLine::TYPE_HAS_F) == 0);
|
||||
CoolingLine &sm = adjustment->lines[active_speed_modifier];
|
||||
@@ -450,7 +492,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
line.type = 0;
|
||||
}
|
||||
}
|
||||
current_pos = std::move(new_pos);
|
||||
std::copy(std::begin(new_pos), std::begin(new_pos) + 5, std::begin(current_pos));
|
||||
} else if (boost::starts_with(sline, ";_EXTRUDE_END")) {
|
||||
// Closing a block of non-zero length extrusion moves.
|
||||
line.type = CoolingLine::TYPE_EXTRUDE_END;
|
||||
@@ -508,16 +550,18 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
} else
|
||||
line.time = 0;
|
||||
line.time_max = line.time;
|
||||
} else if (boost::contains(sline, ";_SET_FAN_SPEED")) {
|
||||
}
|
||||
|
||||
if (boost::contains(sline, ";_SET_FAN_SPEED")) {
|
||||
auto speed_start = sline.find_last_of('D');
|
||||
int speed = 0;
|
||||
for (char num : sline.substr(speed_start + 1)) {
|
||||
speed = speed * 10 + (num - '0');
|
||||
}
|
||||
line.type = CoolingLine::TYPE_SET_FAN_SPEED;
|
||||
line.type |= CoolingLine::TYPE_SET_FAN_SPEED;
|
||||
line.fan_speed = speed;
|
||||
} else if (boost::contains(sline, ";_RESET_FAN_SPEED")) {
|
||||
line.type = CoolingLine::TYPE_RESET_FAN_SPEED;
|
||||
line.type |= CoolingLine::TYPE_RESET_FAN_SPEED;
|
||||
}
|
||||
|
||||
if (line.type != 0)
|
||||
|
||||
Reference in New Issue
Block a user