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.
|
||||
if (new_extruder_id >= 0 && gcodegen.writer().need_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.
|
||||
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));
|
||||
@ -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";
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -35,12 +35,12 @@ void CoolingBuffer::reset()
|
||||
std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id)
|
||||
{
|
||||
const FullPrintConfig &config = m_gcodegen.config();
|
||||
const auto &elapsed_times = m_gcodegen.writer().elapsed_times();
|
||||
const size_t num_extruders = elapsed_times.size();
|
||||
const std::vector<Extruder> &extruders = m_gcodegen.writer().extruders();
|
||||
const size_t num_extruders = extruders.size();
|
||||
|
||||
// Calculate the required per extruder time stretches.
|
||||
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.
|
||||
float elapsed_time_total() {
|
||||
float time_total = 0.f;
|
||||
@ -94,6 +94,8 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
||||
return time_total;
|
||||
}
|
||||
|
||||
bool operator<(const Adjustment &rhs) const { return this->extruder_id < rhs.extruder_id; }
|
||||
|
||||
struct Line
|
||||
{
|
||||
enum Type {
|
||||
@ -135,16 +137,19 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
||||
bool slowdown;
|
||||
};
|
||||
|
||||
// Extruder, for which the G-code will be adjusted.
|
||||
unsigned int extruder_id;
|
||||
// Parsed lines.
|
||||
std::vector<Line> lines;
|
||||
};
|
||||
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();
|
||||
// Parse the layer G-code for the moves, which could be adjusted.
|
||||
{
|
||||
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));
|
||||
Adjustment *adjustment = &adjustments[it_elapsed_time - elapsed_times.begin()];
|
||||
auto adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
|
||||
unsigned int initial_extruder = m_current_extruder;
|
||||
const char *line_start = gcode.c_str();
|
||||
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) {
|
||||
m_current_extruder = new_extruder;
|
||||
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 = &adjustments[it_elapsed_time - elapsed_times.begin()];
|
||||
adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
|
||||
}
|
||||
} else if (boost::starts_with(sline, ";_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.
|
||||
float elapsed_time_total_non_adjustable = 0.f;
|
||||
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);
|
||||
else
|
||||
elapsed_time_total_non_adjustable += adjustments[i].elapsed_time_total();
|
||||
}
|
||||
std::sort(by_slowdown_layer_time.begin(), by_slowdown_layer_time.end(),
|
||||
[&config, &elapsed_times](const size_t idx1, const size_t idx2){
|
||||
return config.slowdown_below_layer_time.get_at(elapsed_times[idx1].extruder_id) <
|
||||
config.slowdown_below_layer_time.get_at(elapsed_times[idx2].extruder_id);
|
||||
[&config, &extruders](const size_t idx1, const size_t idx2){
|
||||
return config.slowdown_below_layer_time.get_at(extruders[idx1].id()) <
|
||||
config.slowdown_below_layer_time.get_at(extruders[idx2].id());
|
||||
});
|
||||
|
||||
// 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.
|
||||
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) {
|
||||
// Idx in elapsed_times and adjustments.
|
||||
// Idx in adjustments.
|
||||
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.
|
||||
#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.
|
||||
float 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) {
|
||||
// The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
|
||||
} else {
|
||||
@ -462,7 +466,6 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
|
||||
if (pos < gcode.size())
|
||||
new_gcode.append(gcode.c_str() + pos, gcode.size() - pos);
|
||||
|
||||
m_gcodegen.writer().reset_elapsed_times();
|
||||
return new_gcode;
|
||||
}
|
||||
|
||||
|
@ -10,54 +10,6 @@ namespace Slic3r {
|
||||
class GCode;
|
||||
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.
|
||||
The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
|
||||
|
@ -27,11 +27,6 @@ void GCodeWriter::set_extruders(const std::vector<unsigned int> &extruder_ids)
|
||||
for (unsigned int extruder_id : extruder_ids)
|
||||
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
|
||||
(even if prints only uses that one) since we need to output Tx commands
|
||||
first extruder has index 0 */
|
||||
@ -249,10 +244,6 @@ std::string GCodeWriter::toolchange(unsigned int extruder_id)
|
||||
assert(it_extruder != m_extruders.end());
|
||||
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
|
||||
// if we are running a single-extruder setup, just set the extruder and return nothing
|
||||
std::ostringstream gcode;
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
bool multiple_extruders;
|
||||
|
||||
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_last_acceleration(0), m_last_fan_speed(0),
|
||||
m_last_bed_temperature(0), m_last_bed_temperature_reached(true),
|
||||
@ -24,10 +24,6 @@ public:
|
||||
{}
|
||||
Extruder* extruder() { 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; }
|
||||
void apply_print_config(const PrintConfig &print_config);
|
||||
@ -74,11 +70,9 @@ public:
|
||||
|
||||
private:
|
||||
std::vector<Extruder> m_extruders;
|
||||
std::vector<ElapsedTime> m_elapsed_times;
|
||||
std::string m_extrusion_axis;
|
||||
bool m_single_extruder_multi_material;
|
||||
Extruder* m_extruder;
|
||||
ElapsedTime* m_elapsed_time;
|
||||
unsigned int m_last_acceleration;
|
||||
unsigned int m_last_fan_speed;
|
||||
unsigned int m_last_bed_temperature;
|
||||
|
Loading…
Reference in New Issue
Block a user