Refactored the cooling buffer: Removed ElapsedTime.
This commit is contained in:
parent
bf9027ff2d
commit
0ad4e9d51f
@ -168,11 +168,6 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
||||||
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))
|
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))
|
||||||
gcodegen.writer().toolchange(new_extruder_id);
|
gcodegen.writer().toolchange(new_extruder_id);
|
||||||
// Accumulate the elapsed time for the correct calculation of layer cooling.
|
|
||||||
//FIXME currently disabled as Slic3r PE needs to be updated to differentiate the moves it could slow down
|
|
||||||
// from the moves it could not.
|
|
||||||
gcodegen.writer().elapsed_time()->total += tcr.elapsed_time;
|
|
||||||
gcodegen.writer().elapsed_time()->other += tcr.elapsed_time;
|
|
||||||
// A phony move to the end position at the wipe tower.
|
// A phony move to the end position at the wipe tower.
|
||||||
gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y));
|
gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y));
|
||||||
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
|
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
|
||||||
@ -1868,24 +1863,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
gcode += is_bridge(path.role()) ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
|
gcode += is_bridge(path.role()) ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
|
||||||
|
|
||||||
this->set_last_pos(path.last_point());
|
this->set_last_pos(path.last_point());
|
||||||
|
|
||||||
if (m_config.cooling.values.front()) {
|
|
||||||
float t = float(path_length / F * 60);
|
|
||||||
m_writer.elapsed_time()->total += t;
|
|
||||||
assert(! (is_bridge(path.role()) && path.role() == erExternalPerimeter));
|
|
||||||
if (is_bridge(path.role()))
|
|
||||||
m_writer.elapsed_time()->bridges += t;
|
|
||||||
else {
|
|
||||||
// Maximum print time of this extrusion, respecting the min_print_speed.
|
|
||||||
float t_max = std::max(t, float(path_length / std::max(0.1, EXTRUDER_CONFIG(min_print_speed))));
|
|
||||||
if (path.role() == erExternalPerimeter)
|
|
||||||
m_writer.elapsed_time()->external_perimeters += t;
|
|
||||||
else
|
|
||||||
m_writer.elapsed_time()->max_stretch_time_no_ext_perimetes += t_max;
|
|
||||||
m_writer.elapsed_time()->max_stretch_time_total += t_max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1931,9 +1908,6 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
|
|||||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line)
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line)
|
||||||
gcode += m_writer.travel_to_xy(this->point_to_gcode(line->b), comment);
|
gcode += m_writer.travel_to_xy(this->point_to_gcode(line->b), comment);
|
||||||
|
|
||||||
if (m_config.cooling.values.front())
|
|
||||||
m_writer.elapsed_time()->travel += unscale(travel.length()) / m_config.get_abs_value("travel_speed");
|
|
||||||
|
|
||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,13 +34,13 @@ void CoolingBuffer::reset()
|
|||||||
|
|
||||||
std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id)
|
std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id)
|
||||||
{
|
{
|
||||||
const FullPrintConfig &config = m_gcodegen.config();
|
const FullPrintConfig &config = m_gcodegen.config();
|
||||||
const auto &elapsed_times = m_gcodegen.writer().elapsed_times();
|
const std::vector<Extruder> &extruders = m_gcodegen.writer().extruders();
|
||||||
const size_t num_extruders = elapsed_times.size();
|
const size_t num_extruders = extruders.size();
|
||||||
|
|
||||||
// Calculate the required per extruder time stretches.
|
// Calculate the required per extruder time stretches.
|
||||||
struct Adjustment {
|
struct Adjustment {
|
||||||
Adjustment() {}
|
Adjustment(unsigned int extruder_id = 0) : extruder_id(extruder_id) {}
|
||||||
// Calculate the total elapsed time per this extruder, adjusted for the slowdown.
|
// Calculate the total elapsed time per this extruder, adjusted for the slowdown.
|
||||||
float elapsed_time_total() {
|
float elapsed_time_total() {
|
||||||
float time_total = 0.f;
|
float time_total = 0.f;
|
||||||
@ -94,6 +94,8 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
return time_total;
|
return time_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(const Adjustment &rhs) const { return this->extruder_id < rhs.extruder_id; }
|
||||||
|
|
||||||
struct Line
|
struct Line
|
||||||
{
|
{
|
||||||
enum Type {
|
enum Type {
|
||||||
@ -135,16 +137,19 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
bool slowdown;
|
bool slowdown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Extruder, for which the G-code will be adjusted.
|
||||||
|
unsigned int extruder_id;
|
||||||
// Parsed lines.
|
// Parsed lines.
|
||||||
std::vector<Line> lines;
|
std::vector<Line> lines;
|
||||||
};
|
};
|
||||||
std::vector<Adjustment> adjustments(num_extruders, Adjustment());
|
std::vector<Adjustment> adjustments(num_extruders, Adjustment());
|
||||||
|
for (size_t i = 0; i < num_extruders; ++ i)
|
||||||
|
adjustments[i].extruder_id = extruders[i].id();
|
||||||
const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
|
const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
|
||||||
// Parse the layer G-code for the moves, which could be adjusted.
|
// Parse the layer G-code for the moves, which could be adjusted.
|
||||||
{
|
{
|
||||||
float min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
|
float min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
|
||||||
auto it_elapsed_time = std::lower_bound(elapsed_times.begin(), elapsed_times.end(), ElapsedTime(m_current_extruder));
|
auto adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
|
||||||
Adjustment *adjustment = &adjustments[it_elapsed_time - elapsed_times.begin()];
|
|
||||||
unsigned int initial_extruder = m_current_extruder;
|
unsigned int initial_extruder = m_current_extruder;
|
||||||
const char *line_start = gcode.c_str();
|
const char *line_start = gcode.c_str();
|
||||||
const char *line_end = line_start;
|
const char *line_end = line_start;
|
||||||
@ -242,8 +247,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
if (new_extruder != m_current_extruder) {
|
if (new_extruder != m_current_extruder) {
|
||||||
m_current_extruder = new_extruder;
|
m_current_extruder = new_extruder;
|
||||||
min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
|
min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
|
||||||
it_elapsed_time = std::lower_bound(elapsed_times.begin(), elapsed_times.end(), ElapsedTime(m_current_extruder));
|
adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
|
||||||
adjustment = &adjustments[it_elapsed_time - elapsed_times.begin()];
|
|
||||||
}
|
}
|
||||||
} else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
|
} else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
|
||||||
line.type = Adjustment::Line::TYPE_BRIDGE_FAN_START;
|
line.type = Adjustment::Line::TYPE_BRIDGE_FAN_START;
|
||||||
@ -273,15 +277,15 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
// Collect total print time of non-adjustable extruders.
|
// Collect total print time of non-adjustable extruders.
|
||||||
float elapsed_time_total_non_adjustable = 0.f;
|
float elapsed_time_total_non_adjustable = 0.f;
|
||||||
for (size_t i = 0; i < num_extruders; ++ i) {
|
for (size_t i = 0; i < num_extruders; ++ i) {
|
||||||
if (config.cooling.get_at(elapsed_times[i].extruder_id))
|
if (config.cooling.get_at(extruders[i].id()))
|
||||||
by_slowdown_layer_time.emplace_back(i);
|
by_slowdown_layer_time.emplace_back(i);
|
||||||
else
|
else
|
||||||
elapsed_time_total_non_adjustable += adjustments[i].elapsed_time_total();
|
elapsed_time_total_non_adjustable += adjustments[i].elapsed_time_total();
|
||||||
}
|
}
|
||||||
std::sort(by_slowdown_layer_time.begin(), by_slowdown_layer_time.end(),
|
std::sort(by_slowdown_layer_time.begin(), by_slowdown_layer_time.end(),
|
||||||
[&config, &elapsed_times](const size_t idx1, const size_t idx2){
|
[&config, &extruders](const size_t idx1, const size_t idx2){
|
||||||
return config.slowdown_below_layer_time.get_at(elapsed_times[idx1].extruder_id) <
|
return config.slowdown_below_layer_time.get_at(extruders[idx1].id()) <
|
||||||
config.slowdown_below_layer_time.get_at(elapsed_times[idx2].extruder_id);
|
config.slowdown_below_layer_time.get_at(extruders[idx2].id());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Elapsed time after adjustment.
|
// Elapsed time after adjustment.
|
||||||
@ -290,7 +294,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
// Elapsed time for the already adjusted extruders.
|
// Elapsed time for the already adjusted extruders.
|
||||||
float elapsed_time_total0 = elapsed_time_total_non_adjustable;
|
float elapsed_time_total0 = elapsed_time_total_non_adjustable;
|
||||||
for (size_t i_by_slowdown_layer_time = 0; i_by_slowdown_layer_time < by_slowdown_layer_time.size(); ++ i_by_slowdown_layer_time) {
|
for (size_t i_by_slowdown_layer_time = 0; i_by_slowdown_layer_time < by_slowdown_layer_time.size(); ++ i_by_slowdown_layer_time) {
|
||||||
// Idx in elapsed_times and adjustments.
|
// Idx in adjustments.
|
||||||
size_t idx = by_slowdown_layer_time[i_by_slowdown_layer_time];
|
size_t idx = by_slowdown_layer_time[i_by_slowdown_layer_time];
|
||||||
// Macro to sum or adjust all sections starting with i_by_slowdown_layer_time.
|
// Macro to sum or adjust all sections starting with i_by_slowdown_layer_time.
|
||||||
#define FORALL_UNPROCESSED(ACCUMULATOR, ACTION) \
|
#define FORALL_UNPROCESSED(ACCUMULATOR, ACTION) \
|
||||||
@ -300,7 +304,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
// Calculate the current adjusted elapsed_time_total over the non-finalized extruders.
|
// Calculate the current adjusted elapsed_time_total over the non-finalized extruders.
|
||||||
float total;
|
float total;
|
||||||
FORALL_UNPROCESSED(total, elapsed_time_total());
|
FORALL_UNPROCESSED(total, elapsed_time_total());
|
||||||
float slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(elapsed_times[idx].extruder_id)) * 1.001f;
|
float slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(adjustments[idx].extruder_id)) * 1.001f;
|
||||||
if (total > slowdown_below_layer_time) {
|
if (total > slowdown_below_layer_time) {
|
||||||
// The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
|
// The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
|
||||||
} else {
|
} else {
|
||||||
@ -462,7 +466,6 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
|||||||
if (pos < gcode.size())
|
if (pos < gcode.size())
|
||||||
new_gcode.append(gcode.c_str() + pos, gcode.size() - pos);
|
new_gcode.append(gcode.c_str() + pos, gcode.size() - pos);
|
||||||
|
|
||||||
m_gcodegen.writer().reset_elapsed_times();
|
|
||||||
return new_gcode;
|
return new_gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,54 +10,6 @@ namespace Slic3r {
|
|||||||
class GCode;
|
class GCode;
|
||||||
class Layer;
|
class Layer;
|
||||||
|
|
||||||
struct ElapsedTime
|
|
||||||
{
|
|
||||||
ElapsedTime(unsigned int extruder_id = 0) : extruder_id(extruder_id) { this->reset(); }
|
|
||||||
void reset() {
|
|
||||||
total = bridges = external_perimeters = travel = other = 0.f;
|
|
||||||
max_stretch_time_total = max_stretch_time_no_ext_perimetes = 0.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
ElapsedTime& operator+=(const ElapsedTime &rhs) {
|
|
||||||
this->total += rhs.total;
|
|
||||||
this->bridges += rhs.bridges;
|
|
||||||
this->external_perimeters += rhs.external_perimeters;
|
|
||||||
this->travel += rhs.travel;
|
|
||||||
this->other += rhs.other;
|
|
||||||
this->max_stretch_time_total += rhs.max_stretch_time_total;
|
|
||||||
this->max_stretch_time_no_ext_perimetes += rhs.max_stretch_time_no_ext_perimetes;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Potion of the total time, which cannot be stretched to heed the minimum layer print time.
|
|
||||||
float non_stretchable(bool stretch_external_perimeters = true) const
|
|
||||||
{ return this->bridges + this->travel + this->other + (stretch_external_perimeters ? 0.f : this->external_perimeters); }
|
|
||||||
// Potion of the total time, which could be stretched to heed the minimum layer print time.
|
|
||||||
float stretchable(bool stretch_external_perimeters = true) const
|
|
||||||
{ return this->total - this->non_stretchable(stretch_external_perimeters); }
|
|
||||||
|
|
||||||
// For which extruder ID has this statistics been collected?
|
|
||||||
unsigned int extruder_id;
|
|
||||||
// Total time.
|
|
||||||
float total;
|
|
||||||
// Per feature time slices.
|
|
||||||
float bridges;
|
|
||||||
float external_perimeters;
|
|
||||||
float travel;
|
|
||||||
float other;
|
|
||||||
// Per feature maximum time, to which the extrusion could be stretched to respect the extruder specific min_print_speed.
|
|
||||||
// Maximum stretch time, to which the time this->stretchable() could be extended.
|
|
||||||
float max_stretch_time_total;
|
|
||||||
// Maximum stretch time, to which the time (this->stretchable() - external_perimeters) could be extended.
|
|
||||||
float max_stretch_time_no_ext_perimetes;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sort ElapsedTime objects by the extruder id by default.
|
|
||||||
inline bool operator==(const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id == e2.extruder_id; }
|
|
||||||
inline bool operator!=(const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id != e2.extruder_id; }
|
|
||||||
inline bool operator< (const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id < e2.extruder_id; }
|
|
||||||
inline bool operator> (const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id > e2.extruder_id; }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A standalone G-code filter, to control cooling of the print.
|
A standalone G-code filter, to control cooling of the print.
|
||||||
The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
|
The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
|
||||||
|
@ -26,11 +26,6 @@ void GCodeWriter::set_extruders(const std::vector<unsigned int> &extruder_ids)
|
|||||||
m_extruders.reserve(extruder_ids.size());
|
m_extruders.reserve(extruder_ids.size());
|
||||||
for (unsigned int extruder_id : extruder_ids)
|
for (unsigned int extruder_id : extruder_ids)
|
||||||
m_extruders.emplace_back(Extruder(extruder_id, &this->config));
|
m_extruders.emplace_back(Extruder(extruder_id, &this->config));
|
||||||
|
|
||||||
m_elapsed_times.clear();
|
|
||||||
m_elapsed_times.reserve(extruder_ids.size());
|
|
||||||
for (unsigned int extruder_id : extruder_ids)
|
|
||||||
m_elapsed_times.emplace_back(ElapsedTime(extruder_id));
|
|
||||||
|
|
||||||
/* we enable support for multiple extruder if any extruder greater than 0 is used
|
/* we enable support for multiple extruder if any extruder greater than 0 is used
|
||||||
(even if prints only uses that one) since we need to output Tx commands
|
(even if prints only uses that one) since we need to output Tx commands
|
||||||
@ -249,10 +244,6 @@ std::string GCodeWriter::toolchange(unsigned int extruder_id)
|
|||||||
assert(it_extruder != m_extruders.end());
|
assert(it_extruder != m_extruders.end());
|
||||||
m_extruder = const_cast<Extruder*>(&*it_extruder);
|
m_extruder = const_cast<Extruder*>(&*it_extruder);
|
||||||
|
|
||||||
auto it_elapsed_time = std::lower_bound(m_elapsed_times.begin(), m_elapsed_times.end(), ElapsedTime(extruder_id));
|
|
||||||
assert(it_elapsed_time != m_elapsed_times.end());
|
|
||||||
m_elapsed_time = const_cast<ElapsedTime*>(&*it_elapsed_time);
|
|
||||||
|
|
||||||
// return the toolchange command
|
// return the toolchange command
|
||||||
// if we are running a single-extruder setup, just set the extruder and return nothing
|
// if we are running a single-extruder setup, just set the extruder and return nothing
|
||||||
std::ostringstream gcode;
|
std::ostringstream gcode;
|
||||||
|
@ -16,7 +16,7 @@ public:
|
|||||||
bool multiple_extruders;
|
bool multiple_extruders;
|
||||||
|
|
||||||
GCodeWriter() :
|
GCodeWriter() :
|
||||||
multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr), m_elapsed_time(nullptr),
|
multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr),
|
||||||
m_single_extruder_multi_material(false),
|
m_single_extruder_multi_material(false),
|
||||||
m_last_acceleration(0), m_last_fan_speed(0),
|
m_last_acceleration(0), m_last_fan_speed(0),
|
||||||
m_last_bed_temperature(0), m_last_bed_temperature_reached(true),
|
m_last_bed_temperature(0), m_last_bed_temperature_reached(true),
|
||||||
@ -24,10 +24,6 @@ public:
|
|||||||
{}
|
{}
|
||||||
Extruder* extruder() { return m_extruder; }
|
Extruder* extruder() { return m_extruder; }
|
||||||
const Extruder* extruder() const { return m_extruder; }
|
const Extruder* extruder() const { return m_extruder; }
|
||||||
ElapsedTime* elapsed_time() { return m_elapsed_time; }
|
|
||||||
const ElapsedTime* elapsed_time() const { return m_elapsed_time; }
|
|
||||||
const std::vector<ElapsedTime>& elapsed_times() const { return m_elapsed_times; }
|
|
||||||
void reset_elapsed_times() { for (auto &et : m_elapsed_times) et.reset(); }
|
|
||||||
|
|
||||||
std::string extrusion_axis() const { return m_extrusion_axis; }
|
std::string extrusion_axis() const { return m_extrusion_axis; }
|
||||||
void apply_print_config(const PrintConfig &print_config);
|
void apply_print_config(const PrintConfig &print_config);
|
||||||
@ -74,11 +70,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Extruder> m_extruders;
|
std::vector<Extruder> m_extruders;
|
||||||
std::vector<ElapsedTime> m_elapsed_times;
|
|
||||||
std::string m_extrusion_axis;
|
std::string m_extrusion_axis;
|
||||||
bool m_single_extruder_multi_material;
|
bool m_single_extruder_multi_material;
|
||||||
Extruder* m_extruder;
|
Extruder* m_extruder;
|
||||||
ElapsedTime* m_elapsed_time;
|
|
||||||
unsigned int m_last_acceleration;
|
unsigned int m_last_acceleration;
|
||||||
unsigned int m_last_fan_speed;
|
unsigned int m_last_fan_speed;
|
||||||
unsigned int m_last_bed_temperature;
|
unsigned int m_last_bed_temperature;
|
||||||
|
Loading…
Reference in New Issue
Block a user