OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::FanMover Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/GCode/FanMover.hpp>

Collaboration diagram for Slic3r::FanMover:

Public Member Functions

 FanMover (const GCodeWriter &writer, const float nb_seconds_delay, const bool with_D_option, const bool relative_e, const bool only_overhangs, const float kickstart)
const std::string & process_gcode (const std::string &gcode, bool flush)

Private Member Functions

BufferData & put_in_buffer (BufferData &&data)
std::list< BufferData >::iterator remove_from_buffer (std::list< BufferData >::iterator data)
void _process_gcode_line (GCodeReader &reader, const GCodeReader::GCodeLine &line)
void _process_T (const std::string_view command)
bool high_precision (const BufferData &line) const
void _put_in_middle_G1 (std::list< BufferData >::iterator item_to_split, float nb_sec, BufferData &&line_to_write)
void _print_in_middle_G1 (BufferData &line_to_split, float nb_sec, const std::string &line_to_write)
void _remove_slow_fan (int16_t min_speed, float past_sec)
std::string _set_fan (int16_t speed)

Private Attributes

const std::regex regex_fan_speed
const float nb_seconds_delay
const bool with_D_option
const bool relative_e
const bool only_overhangs
const float kickstart
const bool m_high_precision
GCodeReader m_parser {}
const GCodeWriter & m_writer
ExtrusionRole current_role = ExtrusionRole::erCustom
double m_current_speed = 1000 / 60.0
bool m_is_custom_gcode = false
uint16_t m_currrent_extruder = 0
int m_front_buffer_fan_speed = 0
int m_back_buffer_fan_speed = 0
BufferData m_current_kickstart {"",-1,0}
std::list< BufferData > m_buffer
double m_buffer_time_size = 0
std::string m_process_output

Detailed Description

Constructor & Destructor Documentation

◆ FanMover()

Slic3r::FanMover::FanMover ( const GCodeWriter & writer,
const float nb_seconds_delay,
const bool with_D_option,
const bool relative_e,
const bool only_overhangs,
const float kickstart )
inline
71 : regex_fan_speed("S[0-9]+"),
72 nb_seconds_delay(nb_seconds_delay>0 ? std::max(0.01f,nb_seconds_delay) : 0),
75 , m_high_precision(writer.config.high_precision_gcode.value), m_writer(writer){
76 m_parser.apply_config(writer.config);
77 }
const bool relative_e
Definition FanMover.hpp:40
const std::regex regex_fan_speed
Definition FanMover.hpp:36
const bool with_D_option
Definition FanMover.hpp:39
const GCodeWriter & m_writer
Definition FanMover.hpp:47
const bool only_overhangs
Definition FanMover.hpp:41
const bool m_high_precision
Definition FanMover.hpp:44
const float nb_seconds_delay
Definition FanMover.hpp:37
GCodeReader m_parser
Definition FanMover.hpp:46
const float kickstart
Definition FanMover.hpp:42

References Slic3r::GCodeWriter::config, Slic3r::high_precision_gcode(), kickstart, m_high_precision, m_parser, m_writer, nb_seconds_delay, only_overhangs, regex_fan_speed, relative_e, and with_D_option.

Here is the call graph for this function:

Member Function Documentation

◆ _print_in_middle_G1()

void Slic3r::FanMover::_print_in_middle_G1 ( BufferData & line_to_split,
float nb_sec,
const std::string & line_to_write )
private
193 {
194 if (nb_sec < line_to_split.time * 0.1) {
195 // Doesn't need to be split: the insertion point is at the start.
196 m_process_output += line_to_write + (line_to_write.back() == '\n'?"":"\n");
197 m_process_output += line_to_split.raw + "\n";
198 } else if (nb_sec > line_to_split.time * 0.9) {
199 // Doesn't need to be split: the insertion point is at the end.
200 m_process_output += line_to_split.raw + "\n";
201 m_process_output += line_to_write + (line_to_write.back() == '\n' ? "" : "\n");
202 }else if(line_to_split.raw.size() > 2
203 && line_to_split.raw[0] == 'G' && line_to_split.raw[1] == '1' && line_to_split.raw[2] == ' ') {
204 float percent = nb_sec / line_to_split.time;
205 const int xyz_digits = GCodeFormatter::xyz_digits(high_precision(line_to_split));
206 const int e_digits = GCodeFormatter::e_digits(high_precision(line_to_split));
207 std::string before = line_to_split.raw;
208 std::string& after = line_to_split.raw;
209 if (line_to_split.dx != 0) {
210 change_axis_value(before, 'X', line_to_split.x + line_to_split.dx * percent, xyz_digits);
211 }
212 if (line_to_split.dy != 0) {
213 change_axis_value(before, 'Y', line_to_split.y + line_to_split.dy * percent, xyz_digits);
214 }
215 if (line_to_split.dz != 0) {
216 change_axis_value(before, 'Z', line_to_split.z + line_to_split.dz * percent, xyz_digits);
217 }
218 if (line_to_split.de != 0) {
219 if (relative_e) {
220 change_axis_value(before, 'E', line_to_split.de * percent, e_digits);
221 change_axis_value(after, 'E', line_to_split.de * (1 - percent), e_digits);
222 } else {
223 change_axis_value(before, 'E', line_to_split.e + line_to_split.de * percent, e_digits);
224 }
225 }
226 m_process_output += before + "\n";
227 m_process_output += line_to_write + (line_to_write.back() == '\n' ? "" : "\n");
228 m_process_output += line_to_split.raw + "\n";
229
230 } else {
231 //not a G1, print it before
232 m_process_output += line_to_write + (line_to_write.back() == '\n' ? "" : "\n");
233 m_process_output += line_to_split.raw + "\n";
234 }
235}
bool high_precision(const BufferData &line) const
Definition FanMover.hpp:97
std::string m_process_output
Definition FanMover.hpp:66
static constexpr int e_digits(bool high_precision)
Definition GCodeWriter.hpp:335
static constexpr int xyz_digits(bool high_precision)
Definition GCodeWriter.hpp:334
void change_axis_value(std::string &line, char axis, const float new_value, const int decimal_digits)
Definition FanMover.cpp:95

References Slic3r::change_axis_value(), Slic3r::BufferData::de, Slic3r::BufferData::dx, Slic3r::BufferData::dy, Slic3r::BufferData::dz, Slic3r::BufferData::e, Slic3r::GCodeFormatter::e_digits(), high_precision(), m_process_output, Slic3r::BufferData::raw, relative_e, Slic3r::BufferData::time, Slic3r::BufferData::x, Slic3r::GCodeFormatter::xyz_digits(), Slic3r::BufferData::y, and Slic3r::BufferData::z.

Referenced by _process_gcode_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_gcode_line()

void Slic3r::FanMover::_process_gcode_line ( GCodeReader & reader,
const GCodeReader::GCodeLine & line )
private
303{
304 // processes 'normal' gcode lines
305 bool need_flush = false;
306 std::string cmd(line.cmd());
307 double time = 0;
308 int16_t fan_speed = -1;
309 if (cmd.length() > 1) {
310 if (line.has_f())
311 m_current_speed = line.f() / 60.0f;
312 switch (::toupper(cmd[0])) {
313 case 'T':
314 case 't':
315 _process_T(cmd);
316 break;
317 case 'G':
318 {
319 if (::atoi(&cmd[1]) == 1 || ::atoi(&cmd[1]) == 0) {
320 double distx = line.dist_X(reader);
321 double disty = line.dist_Y(reader);
322 double distz = line.dist_Z(reader);
323 double dist = distx * distx + disty * disty + distz * distz;
324 if (dist > 0) {
325 dist = std::sqrt(dist);
326 time = dist / m_current_speed;
327 }
328 }
329 break;
330 }
331 case 'M':
332 {
333 fan_speed = get_fan_speed(line.raw(), m_writer.config.gcode_flavor);
334 if (fan_speed >= 0) {
335 const auto fan_baseline = 255.0;
336 fan_speed = 100 * fan_speed / fan_baseline;
337 //speed change: stop kickstart reverting if any
338 m_current_kickstart.time = -1;
339 if (!m_is_custom_gcode) {
340 // if slow down => put in the queue. if not =>
341 if (m_back_buffer_fan_speed < fan_speed) {
343 //don't put this command in the queue
344 time = -1;
345 // this M106 need to go in the past
346 //check if we have ( kickstart and not in slowdown )
347 if (kickstart > 0 && fan_speed > m_front_buffer_fan_speed) {
348 //stop current kickstart , it's not relevant anymore
349 if (m_current_kickstart.time > 0) {
350 m_current_kickstart.time = (-1);
351 }
352
353 //if kickstart
354 // first erase everything lower that that value
355 _remove_slow_fan(fan_speed, m_buffer_time_size + 1);
356 // then erase everything lower that kickstart
357 _remove_slow_fan(fan_baseline, kickstart);
358 // print me
359 if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) {
360 _print_in_middle_G1(m_buffer.front(), m_buffer_time_size - nb_seconds_delay, _set_fan(100));//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing
362 } else {
363 m_process_output += _set_fan(100);//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing
364 }
365 //write it in the queue if possible
366 const float kickstart_duration = kickstart * float(fan_speed - m_front_buffer_fan_speed) / 100.f;
367 float time_count = kickstart_duration;
368 auto it = m_buffer.begin();
369 while (it != m_buffer.end() && time_count > 0) {
370 time_count -= it->time;
371 if (time_count< 0) {
372 //found something that is lower than us
373 _put_in_middle_G1(it, it->time + time_count, BufferData(std::string(line.raw()), 0, fan_speed, true));
374 //found, stop
375 break;
376 }
377 ++it;
378 }
379 if (time_count > 0) {
380 //can't place it in the buffer, use m_current_kickstart
381 m_current_kickstart.fan_speed = fan_speed;
382 m_current_kickstart.time = time_count;
383 m_current_kickstart.raw = line.raw();
384 }
385 m_front_buffer_fan_speed = fan_speed;
386 } else {
387 // first erase everything lower that that value
388 _remove_slow_fan(fan_speed, m_buffer_time_size + 1);
389 // then write the fan command
390 if (!m_buffer.empty() && (m_buffer_time_size - m_buffer.front().time * 0.1) > nb_seconds_delay) {
393 } else {
394 m_process_output += line.raw() + "\n";
395 }
396 m_front_buffer_fan_speed = fan_speed;
397 }
398 } else {
399 if (kickstart <= 0) {
400 //nothing to do
401 //we don't put time = -1; so it will printed in the buffer as other line are done
402 } else if (m_current_kickstart.time > 0) {
403 //cherry-pick this one
404 if (m_back_buffer_fan_speed >= fan_speed) {
405 //stop kickstart
406 m_current_kickstart.time = -1;
407 //this will print me just after as time >=0
408 } else {
409 // add some duration to the kickstart and use it for me.
410 float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f;
411 m_current_kickstart.fan_speed = fan_speed;
412 m_current_kickstart.time += kickstart_duration;
413 m_current_kickstart.raw = line.raw();
414 //i'm printed by the m_current_kickstart
415 time = -1;
416 }
417 } else if(m_back_buffer_fan_speed < fan_speed - 10){ //only kickstart if more than 10% change
418 //don't write this line, as it will need to be delayed
419 time = -1;
420 //get the duration of kickstart
421 float kickstart_duration = kickstart * float(fan_speed - m_back_buffer_fan_speed) / 100.f;
422 //if kickstart, write the M106 S[fan_baseline] first
423 //set the target speed and set the kickstart flag
424 put_in_buffer(BufferData(_set_fan(100)//m_writer.set_fan(100, true)); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing
425 , 0, fan_speed, true));
426 //kickstart!
427 //m_process_output += m_writer.set_fan(100, true);
428 //add the normal speed line for the future
429 m_current_kickstart.fan_speed = fan_speed;
430 m_current_kickstart.time = kickstart_duration;
431 m_current_kickstart.raw = line.raw();
432 }
433 }
434 }
435 //update back buffer fan speed
436 m_back_buffer_fan_speed = fan_speed;
437 } else {
438 // have to flush the buffer to avoid erasing a fan command.
439 need_flush = true;
440 }
441 }
442 break;
443 }
444 }
445 } else {
446 if(!line.raw().empty() && line.raw().front() == ';')
447 {
448 if (line.raw().size() > 10 && line.raw().rfind(";TYPE:", 0) == 0) {
449 // get the type of the next extrusions
450 std::string extrusion_string = line.raw().substr(6, line.raw().size() - 6);
452 }
453 if (line.raw().rfind(";_FAN_MOVER_SKIP_", 0) == 0) {
454 // Internal markers: read here, then dropped from the output.
455 m_is_custom_gcode = line.raw().rfind(";_FAN_MOVER_SKIP_START", 0) == 0;
456 time = -1;
457 }
458 if (line.raw().size() > 16) {
459 if (line.raw().rfind("; custom gcode", 0) != std::string::npos) {
460 if (line.raw().rfind("; custom gcode end", 0) != std::string::npos)
461 m_is_custom_gcode = false;
462 else
463 m_is_custom_gcode = true;
464 }
465 }
466 }
467 }
468
469 if (time >= 0) {
470 BufferData& new_data = put_in_buffer(BufferData(line.raw(), time, fan_speed));
471 new_data.role = current_role;
472 if (line.has(Axis::X)) {
473 new_data.x = reader.x();
474 new_data.dx = line.dist_X(reader);
475 }
476 if (line.has(Axis::Y)) {
477 new_data.y = reader.y();
478 new_data.dy = line.dist_Y(reader);
479 }
480 if (line.has(Axis::Z)) {
481 new_data.z = reader.z();
482 new_data.dz = line.dist_Z(reader);
483 }
484 if (line.has(Axis::E)) {
485 new_data.e = reader.e();
486 if (relative_e)
487 new_data.de = line.e();
488 else
489 new_data.de = line.dist_E(reader);
490 }
491
492 if (m_current_kickstart.time > 0 && time > 0) {
493 m_current_kickstart.time -= time;
494 if (m_current_kickstart.time < 0) {
495 //prev is possible because we just do a emplace_back.
496 _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 });
497 }
498 }
499 }/* else {
500 BufferData& new_data = put_in_buffer(BufferData("; del? "+line.raw(), 0, fan_speed));
501 if (line.has(Axis::X)) {
502 new_data.x = reader.x();
503 new_data.dx = line.dist_X(reader);
504 }
505 if (line.has(Axis::Y)) {
506 new_data.y = reader.y();
507 new_data.dy = line.dist_Y(reader);
508 }
509 if (line.has(Axis::Z)) {
510 new_data.z = reader.z();
511 new_data.dz = line.dist_Z(reader);
512 }
513 if (line.has(Axis::E)) {
514 new_data.e = reader.e();
515 if (relative_e)
516 new_data.de = line.e();
517 else
518 new_data.de = line.dist_E(reader);
519 }
520 }*/
521 // puts the line back into the gcode
522 //if buffer too big, flush it.
523 if (time >= 0) {
524 while (!m_buffer.empty() && (need_flush || m_buffer_time_size - m_buffer.front().time > nb_seconds_delay - EPSILON) ){
525 BufferData& frontdata = m_buffer.front();
526 if (frontdata.fan_speed < 0 || frontdata.fan_speed != m_front_buffer_fan_speed || frontdata.is_kickstart) {
527 if (frontdata.is_kickstart && frontdata.fan_speed < m_front_buffer_fan_speed) {
528 //you have to slow down! not kickstart! rewrite the fan speed.
529 m_process_output += _set_fan(frontdata.fan_speed);//m_writer.set_fan(frontdata.fan_speed,true); //FIXME extruder id (or use the gcode writer, but then you have to disable the multi-thread thing
530
531 m_front_buffer_fan_speed = frontdata.fan_speed;
532 } else {
533 m_process_output += frontdata.raw + "\n";
534 if (frontdata.fan_speed >= 0) {
535 //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
536 //and as this flush all time == 0 lines from the back of the queue...
537 m_front_buffer_fan_speed = frontdata.fan_speed;
538 }
539 }
540 }
542 }
543 }
544 double sum = 0;
545 for (auto& data : m_buffer) sum += data.time;
546 assert( std::abs(m_buffer_time_size - sum) < 0.01);
547}
#define EPSILON
Definition ColorUtils.cpp:64
static ExtrusionRole string_to_role(const std::string_view role)
Definition ExtrusionEntity.cpp:701
void _remove_slow_fan(int16_t min_speed, float past_sec)
Definition FanMover.cpp:237
ExtrusionRole current_role
Definition FanMover.hpp:50
BufferData & put_in_buffer(BufferData &&data)
Definition FanMover.hpp:83
std::list< BufferData > m_buffer
Definition FanMover.hpp:62
void _process_T(const std::string_view command)
Definition FanMover.cpp:283
void _print_in_middle_G1(BufferData &line_to_split, float nb_sec, const std::string &line_to_write)
Definition FanMover.cpp:193
std::string _set_fan(int16_t speed)
Definition FanMover.cpp:254
void _put_in_middle_G1(std::list< BufferData >::iterator item_to_split, float nb_sec, BufferData &&line_to_write)
Definition FanMover.cpp:135
int m_back_buffer_fan_speed
Definition FanMover.hpp:58
int m_front_buffer_fan_speed
Definition FanMover.hpp:57
double m_buffer_time_size
Definition FanMover.hpp:63
bool m_is_custom_gcode
Definition FanMover.hpp:53
double m_current_speed
Definition FanMover.hpp:52
BufferData m_current_kickstart
Definition FanMover.hpp:59
std::list< BufferData >::iterator remove_from_buffer(std::list< BufferData >::iterator data)
Definition FanMover.hpp:88
T dist(const boost::polygon::point_data< T > &p1, const boost::polygon::point_data< T > &p2)
Definition Geometry.cpp:298
@ erOverhangPerimeter
Definition ExtrusionEntity.hpp:30
int16_t get_fan_speed(const std::string &line, GCodeFlavor flavor)
Definition FanMover.cpp:109
@ Y
Definition libslic3r.h:142
@ Z
Definition libslic3r.h:143
@ E
Definition libslic3r.h:144
@ X
Definition libslic3r.h:141

References _print_in_middle_G1(), _process_T(), _put_in_middle_G1(), _remove_slow_fan(), _set_fan(), Slic3r::GCodeReader::GCodeLine::cmd(), current_role, Slic3r::BufferData::de, Slic3r::Geometry::dist(), Slic3r::GCodeReader::GCodeLine::dist_E(), Slic3r::GCodeReader::GCodeLine::dist_X(), Slic3r::GCodeReader::GCodeLine::dist_Y(), Slic3r::GCodeReader::GCodeLine::dist_Z(), Slic3r::BufferData::dx, Slic3r::BufferData::dy, Slic3r::BufferData::dz, Slic3r::E, Slic3r::BufferData::e, Slic3r::GCodeReader::e(), Slic3r::GCodeReader::GCodeLine::e(), EPSILON, Slic3r::erOverhangPerimeter, Slic3r::GCodeReader::GCodeLine::f(), Slic3r::BufferData::fan_speed, Slic3r::get_fan_speed(), Slic3r::GCodeReader::GCodeLine::has(), Slic3r::GCodeReader::GCodeLine::has_f(), Slic3r::BufferData::is_kickstart, kickstart, m_back_buffer_fan_speed, m_buffer, m_buffer_time_size, m_current_kickstart, m_current_speed, m_front_buffer_fan_speed, m_is_custom_gcode, m_process_output, m_writer, nb_seconds_delay, only_overhangs, put_in_buffer(), Slic3r::BufferData::raw, Slic3r::GCodeReader::GCodeLine::raw(), relative_e, remove_from_buffer(), Slic3r::BufferData::role, Slic3r::ExtrusionEntity::string_to_role(), Slic3r::X, Slic3r::BufferData::x, Slic3r::GCodeReader::x(), Slic3r::Y, Slic3r::BufferData::y, Slic3r::GCodeReader::y(), Slic3r::Z, Slic3r::BufferData::z, and Slic3r::GCodeReader::z().

Referenced by process_gcode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_T()

void Slic3r::FanMover::_process_T ( const std::string_view command)
private
284{
285 if (command.length() > 1) {
286 int eid = 0;
287 if (!parse_number(command.substr(1), eid) || eid < 0 || eid > 255) {
288 GCodeFlavor flavor = m_writer.config.gcode_flavor;
289 // Specific to the MMU2 V2 (see https://www.help.prusa3d.com/en/article/prusa-specific-g-codes_112173):
290 if ((flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware) && (command == "Tx" || command == "Tc" || command == "T?"))
291 return;
292
293 // T-1 is a valid gcode line for RepRap Firmwares (used to deselects all tools) see https://github.com/prusa3d/PrusaSlicer/issues/5677
294 if ((flavor != gcfRepRapFirmware && flavor != gcfRepRapSprinter) || eid != -1)
295 m_currrent_extruder = static_cast<uint16_t>(0);
296 } else {
297 m_currrent_extruder = static_cast<uint16_t>(eid);
298 }
299 }
300}
uint16_t m_currrent_extruder
Definition FanMover.hpp:54
GCodeFlavor
Definition PrintConfig.hpp:51
@ gcfMarlinFirmware
Definition PrintConfig.hpp:56
@ gcfRepRapFirmware
Definition PrintConfig.hpp:54
@ gcfMarlinLegacy
Definition PrintConfig.hpp:52
@ gcfRepRapSprinter
Definition PrintConfig.hpp:57
bool parse_number(const std::string_view sv, int &out)
Definition FanMover.cpp:263

References Slic3r::gcfMarlinFirmware, Slic3r::gcfMarlinLegacy, Slic3r::gcfRepRapFirmware, Slic3r::gcfRepRapSprinter, m_currrent_extruder, m_writer, and Slic3r::parse_number().

Referenced by _process_gcode_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _put_in_middle_G1()

void Slic3r::FanMover::_put_in_middle_G1 ( std::list< BufferData >::iterator item_to_split,
float nb_sec,
BufferData && line_to_write )
private
135 {
136 assert(item_to_split != m_buffer.end());
137 if (nb_sec_since_itemtosplit_start > item_to_split->time * 0.9) {
138 // doesn't really need to be split, print it after
139 m_buffer.insert(next(item_to_split), line_to_write);
140 } else if (nb_sec_since_itemtosplit_start < item_to_split->time * 0.1) {
141 // doesn't really need to be split, print it before
142 //will also print before if line_to_split.time == 0
143 m_buffer.insert(item_to_split, line_to_write);
144 } else if (item_to_split->raw.size() > 2
145 && item_to_split->raw[0] == 'G' && item_to_split->raw[1] == '1' && item_to_split->raw[2] == ' ') {
146 float percent = nb_sec_since_itemtosplit_start / item_to_split->time;
147 const int xyz_digits = GCodeFormatter::xyz_digits(high_precision(*item_to_split));
148 const int e_digits = GCodeFormatter::e_digits(high_precision(*item_to_split));
149 BufferData before = *item_to_split;
150 before.time *= percent;
151 item_to_split->time *= (1-percent);
152 if (item_to_split->dx != 0) {
153 before.dx = item_to_split->dx * percent;
154 item_to_split->x += before.dx;
155 item_to_split->dx = item_to_split->dx * (1-percent);
156 change_axis_value(before.raw, 'X', before.x + before.dx, xyz_digits);
157 }
158 if (item_to_split->dy != 0) {
159 before.dy = item_to_split->dy * percent;
160 item_to_split->y += before.dy;
161 item_to_split->dy = item_to_split->dy * (1 - percent);
162 change_axis_value(before.raw, 'Y', before.y + before.dy, xyz_digits);
163 }
164 if (item_to_split->dz != 0) {
165 before.dz = item_to_split->dz * percent;
166 item_to_split->z += before.dz;
167 item_to_split->dz = item_to_split->dz * (1 - percent);
168 change_axis_value(before.raw, 'Z', before.z + before.dz, xyz_digits);
169 }
170 if (item_to_split->de != 0) {
171 if (relative_e) {
172 before.de = item_to_split->de * percent;
173 change_axis_value(before.raw, 'E', before.de, e_digits);
174 item_to_split->de = item_to_split->de * (1 - percent);
175 change_axis_value(item_to_split->raw, 'E', item_to_split->de, e_digits);
176 } else {
177 before.de = item_to_split->de * percent;
178 item_to_split->e += before.de;
179 item_to_split->de = item_to_split->de * (1 - percent);
180 change_axis_value(before.raw, 'E', before.e + before.de, e_digits);
181 }
182 }
183 //add before then line_to_write, then there is the modified data.
184 m_buffer.insert(item_to_split, before);
185 m_buffer.insert(item_to_split, line_to_write);
186
187 } else {
188 //not a G1, print it before
189 m_buffer.insert(item_to_split, line_to_write);
190 }
191}

References Slic3r::change_axis_value(), Slic3r::BufferData::de, Slic3r::BufferData::dx, Slic3r::BufferData::dy, Slic3r::BufferData::dz, Slic3r::BufferData::e, Slic3r::GCodeFormatter::e_digits(), high_precision(), m_buffer, Slic3r::BufferData::raw, relative_e, Slic3r::BufferData::time, Slic3r::BufferData::x, Slic3r::GCodeFormatter::xyz_digits(), Slic3r::BufferData::y, and Slic3r::BufferData::z.

Referenced by _process_gcode_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _remove_slow_fan()

void Slic3r::FanMover::_remove_slow_fan ( int16_t min_speed,
float past_sec )
private
237 {
238 //erase fan in the buffer -> don't slowdown if you are in the process of step-up.
239 //we began at the "recent" side , and remove as long as we don't push past_sec to 0
240 auto it = m_buffer.begin();
241 while (it != m_buffer.end() && past_sec > 0) {
242 past_sec -= it->time;
243 if (it->fan_speed >= 0 && it->fan_speed < min_speed){
244 //found something that is lower than us
245 it = remove_from_buffer(it);
246
247 } else {
248 ++it;
249 }
250 }
251
252}

References m_buffer, and remove_from_buffer().

Referenced by _process_gcode_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _set_fan()

std::string Slic3r::FanMover::_set_fan ( int16_t speed)
private
254 {
255 //const Tool* tool = m_writer.get_tool(m_currrent_extruder < 20 ? m_currrent_extruder : 0);
256 // ORCA: apply the per-printer non-zero fan PWM floor so reposted fan commands respect the clamp too.
257 const int floor_pct = m_writer.config.part_cooling_fan_min_pwm.value;
258 const unsigned int part_cooling_fan_min_pwm = floor_pct > 0 ? static_cast<unsigned int>(floor_pct) : 0u;
259 return GCodeWriter::set_fan(m_writer.config.gcode_flavor.value, speed, part_cooling_fan_min_pwm);
260}
static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm=0)
Definition GCodeWriter.cpp:1552
zaa_minimize_perimeter_height part_cooling_fan_min_pwm((ConfigOptionFloats, filament_diameter))((ConfigOptionBoolsNullable

References m_writer, Slic3r::part_cooling_fan_min_pwm(), and Slic3r::GCodeWriter::set_fan().

Referenced by _process_gcode_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ high_precision()

bool Slic3r::FanMover::high_precision ( const BufferData & line) const
inlineprivate
97{ return m_high_precision && !is_support(line.role); }
bool is_support(ExtrusionRole role)
Definition ExtrusionEntity.hpp:113

References Slic3r::is_support(), m_high_precision, and Slic3r::BufferData::role.

Referenced by _print_in_middle_G1(), and _put_in_middle_G1().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_gcode()

const std::string & Slic3r::FanMover::process_gcode ( const std::string & gcode,
bool flush )
43{
45
46 // recompute buffer time to recover from rounding
48 for (auto& data : m_buffer) m_buffer_time_size += data.time;
49
50 if(!gcode.empty())
51 m_parser.parse_buffer(gcode,
52 [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) { /*m_process_output += line.raw() + "\n";*/ this->_process_gcode_line(reader, line); });
53
54 if (flush) {
55 while (!m_buffer.empty()) {
56 BufferData &front = m_buffer.front();
57 m_process_output += front.raw + "\n";
58 // Orca: Keep the emitted fan state in sync when flushing buffered fan commands.
59 if (front.fan_speed >= 0)
60 m_front_buffer_fan_speed = front.fan_speed;
62 }
63 }
64
65 return m_process_output;
66}
void _process_gcode_line(GCodeReader &reader, const GCodeReader::GCodeLine &line)
Definition FanMover.cpp:302
@ gcode
Definition Time.hpp:14

References _process_gcode_line(), Slic3r::BufferData::fan_speed, m_buffer, m_buffer_time_size, m_front_buffer_fan_speed, m_parser, m_process_output, Slic3r::BufferData::raw, and remove_from_buffer().

Here is the call graph for this function:

◆ put_in_buffer()

BufferData & Slic3r::FanMover::put_in_buffer ( BufferData && data)
inlineprivate
83 {
84 m_buffer_time_size += data.time;
85 m_buffer.emplace_back(data);
86 return m_buffer.back();
87 }

References m_buffer, and m_buffer_time_size.

Referenced by _process_gcode_line().

Here is the caller graph for this function:

◆ remove_from_buffer()

std::list< BufferData >::iterator Slic3r::FanMover::remove_from_buffer ( std::list< BufferData >::iterator data)
inlineprivate
88 {
89 m_buffer_time_size -= data->time;
90 return m_buffer.erase(data);
91 }

References m_buffer, and m_buffer_time_size.

Referenced by _process_gcode_line(), _remove_slow_fan(), and process_gcode().

Here is the caller graph for this function:

Member Data Documentation

◆ current_role

ExtrusionRole Slic3r::FanMover::current_role = ExtrusionRole::erCustom
private

Referenced by _process_gcode_line().

◆ kickstart

const float Slic3r::FanMover::kickstart
private

Referenced by FanMover(), and _process_gcode_line().

◆ m_back_buffer_fan_speed

int Slic3r::FanMover::m_back_buffer_fan_speed = 0
private

Referenced by _process_gcode_line().

◆ m_buffer

◆ m_buffer_time_size

double Slic3r::FanMover::m_buffer_time_size = 0
private

◆ m_current_kickstart

BufferData Slic3r::FanMover::m_current_kickstart {"",-1,0}
private
59{"",-1,0};

Referenced by _process_gcode_line().

◆ m_current_speed

double Slic3r::FanMover::m_current_speed = 1000 / 60.0
private

Referenced by _process_gcode_line().

◆ m_currrent_extruder

uint16_t Slic3r::FanMover::m_currrent_extruder = 0
private

Referenced by _process_T().

◆ m_front_buffer_fan_speed

int Slic3r::FanMover::m_front_buffer_fan_speed = 0
private

◆ m_high_precision

const bool Slic3r::FanMover::m_high_precision
private

Referenced by FanMover(), and high_precision().

◆ m_is_custom_gcode

bool Slic3r::FanMover::m_is_custom_gcode = false
private

Referenced by _process_gcode_line().

◆ m_parser

GCodeReader Slic3r::FanMover::m_parser {}
private
46{};

Referenced by FanMover(), and process_gcode().

◆ m_process_output

std::string Slic3r::FanMover::m_process_output
private

◆ m_writer

const GCodeWriter& Slic3r::FanMover::m_writer
private

◆ nb_seconds_delay

const float Slic3r::FanMover::nb_seconds_delay
private

Referenced by FanMover(), and _process_gcode_line().

◆ only_overhangs

const bool Slic3r::FanMover::only_overhangs
private

Referenced by FanMover(), and _process_gcode_line().

◆ regex_fan_speed

const std::regex Slic3r::FanMover::regex_fan_speed
private

Referenced by FanMover().

◆ relative_e

const bool Slic3r::FanMover::relative_e
private

◆ with_D_option

const bool Slic3r::FanMover::with_D_option
private

Referenced by FanMover().


The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/GCode/FanMover.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/GCode/FanMover.cpp