328{
329 std::vector<PerExtruderAdjustments> per_extruder_adjustments(
m_extruder_ids.size());
330 std::vector<size_t> map_extruder_to_per_extruder_adjustment(
m_num_extruders, 0);
332 PerExtruderAdjustments &adj = per_extruder_adjustments[i];
334 adj.extruder_id = extruder_id;
335 adj.cooling_slow_down_enabled =
m_config.cooling.get_at(extruder_id);
336 adj.slowdown_below_layer_time = float(
m_config.slowdown_below_layer_time.get_at(extruder_id));
337 adj.min_print_speed = float(
m_config.min_print_speed.get_at(extruder_id));
338 map_extruder_to_per_extruder_adjustment[extruder_id] = i;
339 }
340
342 PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
343 const char *line_start =
gcode.c_str();
344 const char *line_end = line_start;
346
347
348 size_t active_speed_modifier = size_t(-1);
349
350 std::vector<float> new_pos;
351 for (; *line_start != 0; line_start = line_end)
352 {
353 while (*line_end != '\n' && *line_end != 0)
354 ++ line_end;
355
356 std::string_view sline(line_start, line_end - line_start);
357
358 if (*line_end == '\n')
359 ++ line_end;
360 CoolingLine line(0, line_start -
gcode.c_str(), line_end -
gcode.c_str());
361 if (boost::starts_with(sline, "G0 "))
363 else if (boost::starts_with(sline, "G1 "))
365 else if (boost::starts_with(sline, "G92 "))
367 if (line.type) {
368
369
370 new_pos = current_pos;
371 for (auto c = sline.begin() + 3;;) {
372
373 for (;
c != sline.end() && (*
c ==
' ' || *
c ==
'\t'); ++
c);
374 if (c == sline.end() || *
c ==
';')
375 break;
376
377
378 size_t axis = (*
c >=
'X' && *
c <=
'Z') ? (*c -
'X') :
380 if (axis != size_t(-1)) {
381
383 if (axis == 4) {
384
385 new_pos[4] /= 60.f;
387
389 }
390 }
391
392 for (;
c != sline.end() && *c !=
' ' && *c !=
'\t'; ++
c);
393 }
394 bool external_perimeter = boost::contains(sline, ";_EXTERNAL_PERIMETER");
395 bool wipe = boost::contains(sline, ";_WIPE");
396 if (external_perimeter)
398 if (wipe)
400 if (boost::contains(sline, ";_EXTRUDE_SET_SPEED") && ! wipe) {
402 active_speed_modifier = adjustment->lines.size();
403 }
405
406 if (
m_config.use_relative_e_distances.value)
407
408 current_pos[3] = 0.f;
409 float dif[4];
410 for (size_t i = 0; i < 4; ++ i)
411 dif[i] = new_pos[i] - current_pos[i];
412 float dxy2 = dif[0] * dif[0] + dif[1] * dif[1];
413 float dxyz2 = dxy2 + dif[2] * dif[2];
414 if (dxyz2 > 0.f) {
415
416 line.length =
sqrt(dxyz2);
417 } else if (std::abs(dif[3]) > 0.f) {
418
419 line.length = std::abs(dif[3]);
420 }
421 line.feedrate = new_pos[4];
423 if (line.length > 0) {
424 assert(line.feedrate > 0);
425 line.time = line.length / line.feedrate;
426 assert(line.time > 0);
427 }
428 line.time_max = line.time;
430 assert(adjustment->min_print_speed >= 0);
431 line.time_max = (adjustment->min_print_speed == 0.f) ? FLT_MAX :
std::
max(line.time, line.
length / adjustment->min_print_speed);
432 }
434
436 CoolingLine &sm = adjustment->lines[active_speed_modifier];
437 assert(sm.feedrate > 0.f);
438 sm.length += line.length;
439 sm.time += line.time;
440 if (sm.time_max != FLT_MAX) {
441 if (line.time_max == FLT_MAX)
442 sm.time_max = FLT_MAX;
443 else
444 sm.time_max += line.time_max;
445 }
446
447 line.type = 0;
448 }
449 }
450 current_pos = std::move(new_pos);
451 } else if (boost::starts_with(sline, ";_EXTRUDE_END")) {
452
454 if (active_speed_modifier != size_t(-1)) {
455 assert(active_speed_modifier < adjustment->lines.size());
456 CoolingLine &sm = adjustment->lines[active_speed_modifier];
457
458
459 assert(sm.length > 0);
460 assert(sm.time > 0);
461 if (sm.time <= 0) {
462
463
464 sm.type &= ~CoolingLine::TYPE_ADJUSTABLE;
465
467 }
468 }
469 active_speed_modifier = size_t(-1);
471 unsigned int new_extruder = 0;
472 auto res = std::from_chars(sline.data() +
m_toolchange_prefix.size(), sline.data() + sline.size(), new_extruder);
473 if (res.ec != std::errc::invalid_argument) {
474
475 if (new_extruder < map_extruder_to_per_extruder_adjustment.size()) {
476 if (new_extruder != current_extruder) {
477
479 current_extruder = new_extruder;
480 adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
481 }
482 }
483 else {
484
485 if (map_extruder_to_per_extruder_adjustment.size() > 1)
486 BOOST_LOG_TRIVIAL(
error) <<
"CoolingBuffer encountered an invalid toolchange, maybe from a custom gcode: " << sline;
487 }
488 }
489 } else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
491 } else if (boost::starts_with(sline, ";_BRIDGE_FAN_END")) {
493 } else if (boost::starts_with(sline, "G4 ")) {
494
496 size_t pos_S = sline.find('S', 3);
497 size_t pos_P = sline.find('P', 3);
498 bool has_S = pos_S > 0;
499 bool has_P = pos_P > 0;
500 if (has_S || has_P) {
501
503 if (has_P)
504 line.time *= 0.001f;
505 } else
506 line.time = 0;
507 line.time_max = line.time;
508 } else if (boost::contains(sline, ";_SET_FAN_SPEED")) {
509 auto speed_start = sline.find_last_of('D');
510 int speed = 0;
511 for (char num : sline.substr(speed_start + 1)) {
512 speed = speed * 10 + (num - '0');
513 }
515 line.fan_speed = speed;
516 } else if (boost::contains(sline, ";_RESET_FAN_SPEED")) {
518 }
519
520 if (line.type != 0)
521 adjustment->lines.emplace_back(std::move(line));
522 }
523
524 return per_extruder_adjustments;
525}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half() max(const half &a, const half &b)
Definition Half.h:516
double length(const Points &pts)
Definition MultiPoint.hpp:116
extrusion_axis((ConfigOptionFloats, extrusion_multiplier))((ConfigOptionFloats
static template_custom_gcode std::string get_extrusion_axis(const GCodeConfig &cfg)
Definition PrintConfig.hpp:739
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195
from_chars_result from_chars(const char *first, const char *last, T &value, chars_format fmt=chars_format::general) noexcept
Definition fast_float.h:2401
@ TYPE_G4
Definition CoolingBuffer.cpp:58
@ TYPE_G92
Definition CoolingBuffer.cpp:59
@ TYPE_G0
Definition CoolingBuffer.cpp:51
@ TYPE_G1
Definition CoolingBuffer.cpp:52
static char error[256]
Definition tga.cpp:50