mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-05 17:00:38 +08:00
Merge branch 'lh_pe_improvements'
This commit is contained in:
commit
a937e1f042
@ -41,6 +41,11 @@ static constexpr int max_look_back_limit = 128;
|
|||||||
// Lines where some extruder pressure will remain (so we should equalize between these small travels).
|
// Lines where some extruder pressure will remain (so we should equalize between these small travels).
|
||||||
static constexpr double max_ignored_gap_between_extruding_segments = 3.;
|
static constexpr double max_ignored_gap_between_extruding_segments = 3.;
|
||||||
|
|
||||||
|
// Minimum feedrate change that will be emitted into the G-code.
|
||||||
|
// Changes below this value will not be emitted into the G-code to filter out tiny changes
|
||||||
|
// of feedrate and reduce the size of the G-code.
|
||||||
|
static constexpr float min_emitted_feedrate_change = 0.20f * 60.f;
|
||||||
|
|
||||||
PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig &config) : m_use_relative_e_distances(config.use_relative_e_distances.value)
|
PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig &config) : m_use_relative_e_distances(config.use_relative_e_distances.value)
|
||||||
{
|
{
|
||||||
// Preallocate some data, so that output_buffer.data() will return an empty string.
|
// Preallocate some data, so that output_buffer.data() will return an empty string.
|
||||||
@ -324,8 +329,6 @@ bool PressureEqualizer::process_line(const char *line, const char *line_end, GCo
|
|||||||
{
|
{
|
||||||
// G0, G1: A FFF 3D printer does not make a difference between the two.
|
// G0, G1: A FFF 3D printer does not make a difference between the two.
|
||||||
buf.adjustable_flow = this->opened_extrude_set_speed_block;
|
buf.adjustable_flow = this->opened_extrude_set_speed_block;
|
||||||
buf.extrude_set_speed_tag = found_extrude_set_speed_tag;
|
|
||||||
buf.extrude_end_tag = found_extrude_end_tag;
|
|
||||||
float new_pos[5];
|
float new_pos[5];
|
||||||
memcpy(new_pos, m_current_pos, sizeof(float)*5);
|
memcpy(new_pos, m_current_pos, sizeof(float)*5);
|
||||||
bool changed[5] = { false, false, false, false, false };
|
bool changed[5] = { false, false, false, false, false };
|
||||||
@ -477,6 +480,30 @@ bool PressureEqualizer::process_line(const char *line, const char *line_end, GCo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PressureEqualizer::GCodeLine::update_end_position(const float *position_end, const bool *position_provided_original)
|
||||||
|
{
|
||||||
|
assert(position_end != nullptr);
|
||||||
|
if (position_end == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
this->pos_end[i] = position_end[i];
|
||||||
|
this->pos_provided[i] = position_provided_original[i] || (this->pos_end[i] != this->pos_start[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PressureEqualizer::GCodeLine::update_end_position(const float *position_start, const float *position_end, const float t, const bool *position_provided_original)
|
||||||
|
{
|
||||||
|
assert(position_start != nullptr && position_end != nullptr);
|
||||||
|
if (position_start == nullptr || position_end == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; ++i) {
|
||||||
|
this->pos_end[i] = position_start[i] + (position_end[i] - position_start[i]) * t;
|
||||||
|
this->pos_provided[i] = position_provided_original[i] || (this->pos_end[i] != this->pos_start[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
||||||
{
|
{
|
||||||
GCodeLine &line = m_gcode_lines[line_idx];
|
GCodeLine &line = m_gcode_lines[line_idx];
|
||||||
@ -493,21 +520,27 @@ void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
|||||||
comment = nullptr;
|
comment = nullptr;
|
||||||
|
|
||||||
// Emit the line with lowered extrusion rates.
|
// Emit the line with lowered extrusion rates.
|
||||||
float l = line.dist_xyz();
|
const float l = line.dist_xyz();
|
||||||
if (auto nSegments = size_t(ceil(l / max_segment_length)); nSegments == 1) { // Just update this segment.
|
const float feedrate_start = line.volumetric_extrusion_rate_start * line.feedrate() / line.volumetric_extrusion_rate;
|
||||||
|
const float feedrate_end = line.volumetric_extrusion_rate_end * line.feedrate() / line.volumetric_extrusion_rate;
|
||||||
|
const float feedrate_avg = 0.5f * (feedrate_start + feedrate_end);
|
||||||
|
if (std::abs(feedrate_avg - line.pos_end[4]) <= min_emitted_feedrate_change) {
|
||||||
|
// The average feedrate is close to the original feedrate, so we emit the line with the original feedrate.
|
||||||
|
push_line_to_output(line_idx, line.pos_end[4], comment);
|
||||||
|
} else if (auto nSegments = size_t(ceil(l / max_segment_length)); nSegments == 1) { // Just update this segment.
|
||||||
push_line_to_output(line_idx, line.feedrate() * line.volumetric_correction_avg(), comment);
|
push_line_to_output(line_idx, line.feedrate() * line.volumetric_correction_avg(), comment);
|
||||||
} else {
|
} else {
|
||||||
bool accelerating = line.volumetric_extrusion_rate_start < line.volumetric_extrusion_rate_end;
|
bool accelerating = line.volumetric_extrusion_rate_start < line.volumetric_extrusion_rate_end;
|
||||||
// Update the initial and final feed rate values.
|
// Update the initial and final feed rate values.
|
||||||
line.pos_start[4] = line.volumetric_extrusion_rate_start * line.pos_end[4] / line.volumetric_extrusion_rate;
|
line.pos_start[4] = feedrate_start;
|
||||||
line.pos_end [4] = line.volumetric_extrusion_rate_end * line.pos_end[4] / line.volumetric_extrusion_rate;
|
line.pos_end [4] = feedrate_end;
|
||||||
float feed_avg = 0.5f * (line.pos_start[4] + line.pos_end[4]);
|
|
||||||
// Limiting volumetric extrusion rate slope for this segment.
|
// Limiting volumetric extrusion rate slope for this segment.
|
||||||
float max_volumetric_extrusion_rate_slope = accelerating ? line.max_volumetric_extrusion_rate_slope_positive :
|
float max_volumetric_extrusion_rate_slope = accelerating ? line.max_volumetric_extrusion_rate_slope_positive :
|
||||||
line.max_volumetric_extrusion_rate_slope_negative;
|
line.max_volumetric_extrusion_rate_slope_negative;
|
||||||
// Total time for the segment, corrected for the possibly lowered volumetric feed rate,
|
// Total time for the segment, corrected for the possibly lowered volumetric feed rate,
|
||||||
// if accelerating / decelerating over the complete segment.
|
// if accelerating / decelerating over the complete segment.
|
||||||
float t_total = line.dist_xyz() / feed_avg;
|
float t_total = line.dist_xyz() / feedrate_avg;
|
||||||
// Time of the acceleration / deceleration part of the segment, if accelerating / decelerating
|
// Time of the acceleration / deceleration part of the segment, if accelerating / decelerating
|
||||||
// with the maximum volumetric extrusion rate slope.
|
// with the maximum volumetric extrusion rate slope.
|
||||||
float t_acc = 0.5f * (line.volumetric_extrusion_rate_start + line.volumetric_extrusion_rate_end) / max_volumetric_extrusion_rate_slope;
|
float t_acc = 0.5f * (line.volumetric_extrusion_rate_start + line.volumetric_extrusion_rate_end) / max_volumetric_extrusion_rate_slope;
|
||||||
@ -515,7 +548,7 @@ void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
|||||||
float l_steady = 0.f;
|
float l_steady = 0.f;
|
||||||
if (t_acc < t_total) {
|
if (t_acc < t_total) {
|
||||||
// One may achieve higher print speeds if part of the segment is not speed limited.
|
// One may achieve higher print speeds if part of the segment is not speed limited.
|
||||||
l_acc = t_acc * feed_avg;
|
l_acc = t_acc * feedrate_avg;
|
||||||
l_steady = l - l_acc;
|
l_steady = l - l_acc;
|
||||||
if (l_steady < 0.5f * max_segment_length) {
|
if (l_steady < 0.5f * max_segment_length) {
|
||||||
l_acc = l;
|
l_acc = l;
|
||||||
@ -523,11 +556,15 @@ void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
|||||||
} else
|
} else
|
||||||
nSegments = size_t(ceil(l_acc / max_segment_length));
|
nSegments = size_t(ceil(l_acc / max_segment_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
float pos_start[5];
|
float pos_start[5];
|
||||||
float pos_end[5];
|
float pos_end[5];
|
||||||
float pos_end2[4];
|
float pos_end2[4];
|
||||||
memcpy(pos_start, line.pos_start, sizeof(float) * 5);
|
memcpy(pos_start, line.pos_start, sizeof(float) * 5);
|
||||||
memcpy(pos_end, line.pos_end, sizeof(float) * 5);
|
memcpy(pos_end, line.pos_end, sizeof(float) * 5);
|
||||||
|
|
||||||
|
bool pos_provided_original[5];
|
||||||
|
memcpy(pos_provided_original, line.pos_provided, sizeof(bool) * 5);
|
||||||
if (l_steady > 0.f) {
|
if (l_steady > 0.f) {
|
||||||
// There will be a steady feed segment emitted.
|
// There will be a steady feed segment emitted.
|
||||||
if (accelerating) {
|
if (accelerating) {
|
||||||
@ -536,15 +573,11 @@ void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
|||||||
float t = l_acc / l;
|
float t = l_acc / l;
|
||||||
for (int i = 0; i < 4; ++ i) {
|
for (int i = 0; i < 4; ++ i) {
|
||||||
pos_end[i] = pos_start[i] + (pos_end[i] - pos_start[i]) * t;
|
pos_end[i] = pos_start[i] + (pos_end[i] - pos_start[i]) * t;
|
||||||
line.pos_provided[i] = true;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Emit the steady feed rate segment.
|
// Emit the steady feed rate segment.
|
||||||
float t = l_steady / l;
|
const float t = l_steady / l;
|
||||||
for (int i = 0; i < 4; ++ i) {
|
line.update_end_position(pos_start, pos_end, t, pos_provided_original);
|
||||||
line.pos_end[i] = pos_start[i] + (pos_end[i] - pos_start[i]) * t;
|
|
||||||
line.pos_provided[i] = true;
|
|
||||||
}
|
|
||||||
push_line_to_output(line_idx, pos_start[4], comment);
|
push_line_to_output(line_idx, pos_start[4], comment);
|
||||||
comment = nullptr;
|
comment = nullptr;
|
||||||
|
|
||||||
@ -557,29 +590,23 @@ void PressureEqualizer::output_gcode_line(const size_t line_idx)
|
|||||||
pos_start[4] = new_pos_start_feedrate;
|
pos_start[4] = new_pos_start_feedrate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split the segment into pieces.
|
// Split the segment into pieces.
|
||||||
for (size_t i = 1; i < nSegments; ++ i) {
|
for (size_t i = 1; i < nSegments; ++ i) {
|
||||||
float t = float(i) / float(nSegments);
|
const float t = float(i) / float(nSegments);
|
||||||
for (size_t j = 0; j < 4; ++ j) {
|
line.update_end_position(pos_start, pos_end, t, pos_provided_original);
|
||||||
line.pos_end[j] = pos_start[j] + (pos_end[j] - pos_start[j]) * t;
|
|
||||||
line.pos_provided[j] = true;
|
|
||||||
}
|
|
||||||
// Interpolate the feed rate at the center of the segment.
|
// Interpolate the feed rate at the center of the segment.
|
||||||
push_line_to_output(line_idx, pos_start[4] + (pos_end[4] - pos_start[4]) * (float(i) - 0.5f) / float(nSegments), comment);
|
push_line_to_output(line_idx, pos_start[4] + (pos_end[4] - pos_start[4]) * (float(i) - 0.5f) / float(nSegments), comment);
|
||||||
comment = nullptr;
|
comment = nullptr;
|
||||||
memcpy(line.pos_start, line.pos_end, sizeof(float)*5);
|
memcpy(line.pos_start, line.pos_end, sizeof(float)*5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l_steady > 0.f && accelerating) {
|
if (l_steady > 0.f && accelerating) {
|
||||||
for (int i = 0; i < 4; ++ i) {
|
line.update_end_position(pos_end2, pos_provided_original);
|
||||||
line.pos_end[i] = pos_end2[i];
|
|
||||||
line.pos_provided[i] = true;
|
|
||||||
}
|
|
||||||
push_line_to_output(line_idx, pos_end[4], comment);
|
push_line_to_output(line_idx, pos_end[4], comment);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 4; ++ i) {
|
line.update_end_position(pos_end, pos_provided_original);
|
||||||
line.pos_end[i] = pos_end[i];
|
|
||||||
line.pos_provided[i] = true;
|
|
||||||
}
|
|
||||||
push_line_to_output(line_idx, pos_end[4], comment);
|
push_line_to_output(line_idx, pos_end[4], comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,8 +178,8 @@ private:
|
|||||||
|
|
||||||
bool adjustable_flow = false;
|
bool adjustable_flow = false;
|
||||||
|
|
||||||
bool extrude_set_speed_tag = false;
|
void update_end_position(const float *position_end, const bool *position_provided_original);
|
||||||
bool extrude_end_tag = false;
|
void update_end_position(const float *position_start, const float *position_end, float t, const bool *position_provided_original);
|
||||||
};
|
};
|
||||||
|
|
||||||
using GCodeLines = std::vector<GCodeLine>;
|
using GCodeLines = std::vector<GCodeLine>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user