mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-25 01:44:27 +08:00
fan delay & kickstart fixes
now shouldn't be crazy like before. supermerill/SuperSlicer#1665 supermerill/SuperSlicer#1530 supermerill/SuperSlicer#939 supermerill/SuperSlicer#834 supermerill/SuperSlicer#714
This commit is contained in:
parent
499c2d45df
commit
c12542d832
@ -50,12 +50,13 @@ float get_axis_value(const std::string& line, char axis)
|
||||
match[1] = axis;
|
||||
|
||||
size_t pos = line.find(match) + 2;
|
||||
size_t end = line.find(' ', pos + 1);
|
||||
//size_t end = std::min(line.find(' ', pos + 1), line.find(';', pos + 1));
|
||||
// Try to parse the numeric value.
|
||||
const char* c = line.c_str();
|
||||
char* pend = nullptr;
|
||||
double v = strtod(c+ pos, &pend);
|
||||
if (pend != nullptr && is_end_of_word(*pend)) {
|
||||
errno = 0;
|
||||
double v = strtod(c + pos, &pend);
|
||||
if (pend != nullptr && errno == 0 && pend != c) {
|
||||
// The axis value has been parsed correctly.
|
||||
return float(v);
|
||||
}
|
||||
@ -72,7 +73,7 @@ void change_axis_value(std::string& line, char axis, const float new_value, cons
|
||||
match[1] = axis;
|
||||
|
||||
size_t pos = line.find(match) + 2;
|
||||
size_t end = line.find(' ', pos + 1);
|
||||
size_t end = std::min(line.find(' ', pos + 1), line.find(';', pos + 1));
|
||||
line = line.replace(pos, end - pos, ss.str());
|
||||
}
|
||||
|
||||
@ -93,19 +94,19 @@ int16_t get_fan_speed(const std::string &line, GCodeFlavor flavor) {
|
||||
|
||||
}
|
||||
|
||||
void FanMover::_put_in_middle_G1(std::list<BufferData>::iterator item_to_split, float nb_sec, BufferData &&line_to_write) {
|
||||
void FanMover::_put_in_middle_G1(std::list<BufferData>::iterator item_to_split, float nb_sec_since_itemtosplit_start, BufferData &&line_to_write) {
|
||||
//std::cout << "_put_in_middle_G1\n";
|
||||
assert(item_to_split != m_buffer.end());
|
||||
if (nb_sec < item_to_split->time * 0.1) {
|
||||
if (nb_sec_since_itemtosplit_start > item_to_split->time * 0.9) {
|
||||
// doesn't really need to be split, print it after
|
||||
m_buffer.insert(next(item_to_split), line_to_write);
|
||||
} else if (nb_sec > item_to_split->time * 0.9) {
|
||||
} else if (nb_sec_since_itemtosplit_start < item_to_split->time * 0.1) {
|
||||
// doesn't really need to be split, print it before
|
||||
//will also print before if line_to_split.time == 0
|
||||
m_buffer.insert(item_to_split, line_to_write);
|
||||
} else if (item_to_split->raw.size() > 2
|
||||
&& item_to_split->raw[0] == 'G' && item_to_split->raw[1] == '1' && item_to_split->raw[2] == ' ') {
|
||||
float percent = nb_sec / item_to_split->time;
|
||||
float percent = nb_sec_since_itemtosplit_start / item_to_split->time;
|
||||
BufferData before = *item_to_split;
|
||||
before.time *= percent;
|
||||
item_to_split->time *= (1-percent);
|
||||
@ -238,62 +239,106 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode
|
||||
case 'M':
|
||||
{
|
||||
fan_speed = get_fan_speed(line.raw(), m_writer.config.gcode_flavor);
|
||||
if (fan_speed > 0 && !m_is_custom_gcode) {
|
||||
if (nb_seconds_delay > 0 && (!only_overhangs || current_role != ExtrusionRole::erOverhangPerimeter)) {
|
||||
// this M106 need to go in the past
|
||||
//check if we have !( kickstart and not in slowdown )
|
||||
if (kickstart <= 0 || fan_speed < m_current_fan_speed) {
|
||||
// first erase everything lower that that value
|
||||
_remove_slow_fan(fan_speed, m_buffer_time_size + 1);
|
||||
// then write the fan command
|
||||
if (std::abs(m_buffer_time_size - nb_seconds_delay) < EPSILON) {
|
||||
_print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, line.raw());
|
||||
remove_from_buffer(m_buffer.begin());
|
||||
} else {
|
||||
m_process_output += line.raw() + "\n";
|
||||
}
|
||||
} else {
|
||||
//if kickstart
|
||||
// first erase everything lower that that value
|
||||
_remove_slow_fan(fan_speed, m_buffer_time_size + 1);
|
||||
// first erase everything lower that kickstart
|
||||
_remove_slow_fan(255, kickstart);
|
||||
// print me
|
||||
if (m_buffer_time_size > nb_seconds_delay) {
|
||||
_print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, m_writer.set_fan(100, true));
|
||||
remove_from_buffer(m_buffer.begin());
|
||||
} else {
|
||||
m_process_output += m_writer.set_fan(100, true);
|
||||
}
|
||||
//write it in the queue if possible
|
||||
float time_count = kickstart;
|
||||
auto it = m_buffer.begin();
|
||||
while (it != m_buffer.end() && time_count > 0) {
|
||||
if (time_count - it->time < 0) {
|
||||
//found something that is lower than us
|
||||
_put_in_middle_G1(it, time_count, BufferData( std::string(line.cmd()), 0, fan_speed ));
|
||||
//found, stop
|
||||
break;
|
||||
}
|
||||
time_count -= it->time;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (kickstart <= 0) {
|
||||
//nothing to do
|
||||
//we don't put time = -1; so it will printed in the buffer as other line are done
|
||||
} else {
|
||||
//if kickstart, write the M106 255 first
|
||||
time = -1;
|
||||
//set the target speed and set the kickstart flag
|
||||
put_in_buffer(BufferData(m_writer.set_fan(100, true), 0, fan_speed, true));
|
||||
//add the normal speed line for the future
|
||||
m_current_kickstart.fan_speed = fan_speed;
|
||||
m_current_kickstart.time = kickstart;
|
||||
m_current_kickstart.raw = line.raw();
|
||||
}
|
||||
if (fan_speed >= 0) {
|
||||
const auto fan_baseline = (m_writer.config.fan_percentage.value ? 100.0 : 255.0);
|
||||
fan_speed = 100 * fan_speed / fan_baseline;
|
||||
if (!m_is_custom_gcode) {
|
||||
// if slow down => put in the queue. if not =>
|
||||
if (m_back_buffer_fan_speed < fan_speed) {
|
||||
if (nb_seconds_delay > 0 && (!only_overhangs || current_role != ExtrusionRole::erOverhangPerimeter)) {
|
||||
//don't put this command in the queue
|
||||
time = -1;
|
||||
// this M106 need to go in the past
|
||||
//check if we have ( kickstart and not in slowdown )
|
||||
if (kickstart > 0 && fan_speed > m_front_buffer_fan_speed) {
|
||||
//stop current kickstart , it's not relevant anymore
|
||||
if (m_current_kickstart.time > 0) {
|
||||
m_current_kickstart.time = (-1);
|
||||
}
|
||||
|
||||
//if kickstart
|
||||
// first erase everything lower that that value
|
||||
_remove_slow_fan(fan_speed, m_buffer_time_size + 1);
|
||||
// then erase everything lower that kickstart
|
||||
_remove_slow_fan(fan_baseline, kickstart);
|
||||
// print me
|
||||
if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) {
|
||||
_print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, m_writer.set_fan(100, true));
|
||||
remove_from_buffer(m_buffer.begin());
|
||||
} else {
|
||||
m_process_output += m_writer.set_fan(100, true);
|
||||
}
|
||||
//write it in the queue if possible
|
||||
const float kickstart_duration = kickstart * float(fan_speed - m_front_buffer_fan_speed) / 100.f;
|
||||
float time_count = kickstart_duration;
|
||||
auto it = m_buffer.begin();
|
||||
while (it != m_buffer.end() && time_count > 0) {
|
||||
time_count -= it->time;
|
||||
if (time_count< 0) {
|
||||
//found something that is lower than us
|
||||
_put_in_middle_G1(it, it->time + time_count, BufferData(std::string(line.raw()), 0, fan_speed, true));
|
||||
//found, stop
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
if (time_count > 0) {
|
||||
//can't place it in the buffer, use m_current_kickstart
|
||||
m_current_kickstart.fan_speed = fan_speed;
|
||||
m_current_kickstart.time = time_count;
|
||||
m_current_kickstart.raw = line.raw();
|
||||
}
|
||||
m_front_buffer_fan_speed = fan_speed;
|
||||
} else {
|
||||
// first erase everything lower that that value
|
||||
_remove_slow_fan(fan_speed, m_buffer_time_size + 1);
|
||||
// then write the fan command
|
||||
if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) {
|
||||
_print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, line.raw());
|
||||
remove_from_buffer(m_buffer.begin());
|
||||
} else {
|
||||
m_process_output += line.raw() + "\n";
|
||||
}
|
||||
m_front_buffer_fan_speed = fan_speed;
|
||||
}
|
||||
} else {
|
||||
if (kickstart <= 0) {
|
||||
//nothing to do
|
||||
//we don't put time = -1; so it will printed in the buffer as other line are done
|
||||
} else if (m_current_kickstart.time > 0) {
|
||||
//cherry-pick this one
|
||||
if (m_back_buffer_fan_speed >= fan_speed) {
|
||||
//stop kickstart
|
||||
m_current_kickstart.time = -1;
|
||||
//this will print me just after as time >=0
|
||||
} else {
|
||||
// add some duration to the kickstart and use it for me.
|
||||
float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f;
|
||||
m_current_kickstart.fan_speed = fan_speed;
|
||||
m_current_kickstart.time += kickstart_duration;
|
||||
m_current_kickstart.raw = line.raw();
|
||||
//i'm printed by the m_current_kickstart
|
||||
time = -1;
|
||||
}
|
||||
} else if(m_back_buffer_fan_speed < fan_speed - 10){ //only kickstart if more than 10% change
|
||||
//don't write this line, as it will need to be delayed
|
||||
time = -1;
|
||||
//get the duration of kickstart
|
||||
float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f;
|
||||
//if kickstart, write the M106 S[fan_baseline] first
|
||||
//set the target speed and set the kickstart flag
|
||||
put_in_buffer(BufferData(m_writer.set_fan(100, true), 0, fan_speed, true));
|
||||
//kickstart!
|
||||
//m_process_output += m_writer.set_fan(100, true);
|
||||
//add the normal speed line for the future
|
||||
m_current_kickstart.fan_speed = fan_speed;
|
||||
m_current_kickstart.time = kickstart_duration;
|
||||
m_current_kickstart.raw = line.raw();
|
||||
}
|
||||
}
|
||||
}
|
||||
//update back buffer fan speed
|
||||
m_back_buffer_fan_speed = fan_speed;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -335,30 +380,51 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode
|
||||
new_data.de = line.dist_E(reader);
|
||||
}
|
||||
|
||||
if (m_current_kickstart.time > 0) {
|
||||
if (m_current_kickstart.time > 0 && time > 0) {
|
||||
m_current_kickstart.time -= time;
|
||||
if (m_current_kickstart.time < 0) {
|
||||
//prev is possible because we just do a emplace_back.
|
||||
_put_in_middle_G1(prev(m_buffer.end()), time + m_current_kickstart.time, BufferData{ m_current_kickstart.raw, 0, m_current_kickstart.fan_speed });
|
||||
_put_in_middle_G1(prev(m_buffer.end()), time + m_current_kickstart.time, BufferData{ m_current_kickstart.raw, 0, m_current_kickstart.fan_speed, true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}/* else {
|
||||
BufferData& new_data = put_in_buffer(BufferData("; del? "+line.raw(), 0, fan_speed));
|
||||
if (line.has(Axis::X)) {
|
||||
new_data.x = reader.x();
|
||||
new_data.dx = line.dist_X(reader);
|
||||
}
|
||||
if (line.has(Axis::Y)) {
|
||||
new_data.y = reader.y();
|
||||
new_data.dy = line.dist_Y(reader);
|
||||
}
|
||||
if (line.has(Axis::Z)) {
|
||||
new_data.z = reader.z();
|
||||
new_data.dz = line.dist_Z(reader);
|
||||
}
|
||||
if (line.has(Axis::E)) {
|
||||
new_data.e = reader.e();
|
||||
if (relative_e)
|
||||
new_data.de = line.e();
|
||||
else
|
||||
new_data.de = line.dist_E(reader);
|
||||
}
|
||||
}*/
|
||||
// puts the line back into the gcode
|
||||
//if buffer too big, flush it.
|
||||
if (time > 0) {
|
||||
while (!m_buffer.empty() && m_buffer_time_size - m_buffer.front().time > nb_seconds_delay) {
|
||||
BufferData& backdata = m_buffer.front();
|
||||
if (backdata.fan_speed < 0 || backdata.fan_speed != m_current_fan_speed) {
|
||||
if (backdata.is_kickstart && backdata.fan_speed < m_current_fan_speed) {
|
||||
if (time >= 0) {
|
||||
while (!m_buffer.empty() && m_buffer_time_size - m_buffer.front().time > nb_seconds_delay - EPSILON) {
|
||||
BufferData& frontdata = m_buffer.front();
|
||||
if (frontdata.fan_speed < 0 || frontdata.fan_speed != m_front_buffer_fan_speed || frontdata.is_kickstart) {
|
||||
if (frontdata.is_kickstart && frontdata.fan_speed < m_front_buffer_fan_speed) {
|
||||
//you have to slow down! not kickstart! rewrite the fan speed.
|
||||
m_process_output += m_writer.set_fan(backdata.fan_speed,true);
|
||||
m_current_fan_speed = backdata.fan_speed;
|
||||
m_process_output += m_writer.set_fan(frontdata.fan_speed,true);
|
||||
m_front_buffer_fan_speed = frontdata.fan_speed;
|
||||
} else {
|
||||
m_process_output += backdata.raw + "\n";
|
||||
if (backdata.fan_speed >= 0) {
|
||||
//note that this is the only plce where the fan_speed is set and we print from the buffer, as if the fan_speed >= 0 => time == 0
|
||||
//and as this flush all time == 0 lines fromt he back of the queue...
|
||||
m_current_fan_speed = backdata.fan_speed;
|
||||
m_process_output += frontdata.raw + "\n";
|
||||
if (frontdata.fan_speed >= 0) {
|
||||
//note that this is the only place where the fan_speed is set and we print from the buffer, as if the fan_speed >= 0 => time == 0
|
||||
//and as this flush all time == 0 lines from the back of the queue...
|
||||
m_front_buffer_fan_speed = frontdata.fan_speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,8 @@ private:
|
||||
bool m_is_custom_gcode = false;
|
||||
|
||||
// variable for when you add a line (front of the buffer)
|
||||
int m_current_fan_speed = 0;
|
||||
int m_front_buffer_fan_speed = 0;
|
||||
int m_back_buffer_fan_speed = 0;
|
||||
BufferData m_current_kickstart{"",-1,0};
|
||||
|
||||
//buffer
|
||||
|
Loading…
x
Reference in New Issue
Block a user