577{
579 return;
580
581
584
585
586 if (additional_time > 0.0f)
588 return;
589 }
590
592
593
594
595
597 if (additional_time > 0.0f)
598 additional_buffer.emplace_back(target_move_type, additional_time);
600
601 size_t n_blocks_process;
603 n_blocks_process =
plan_klipper(keep_last_n_blocks != 0);
604 keep_last_n_blocks =
blocks.size() - n_blocks_process;
605 } else {
606 for (
int i =
static_cast<int>(
blocks.size()) - 1; i > 0; --i)
608 for (
size_t i = 0; i + 1 <
blocks.size(); ++i)
611 n_blocks_process =
blocks.size() - keep_last_n_blocks;
612 }
613 size_t additional_buffer_idx = 0;
614 for (size_t i = 0; i < n_blocks_process; ++i) {
615 const TimeBlock& block =
blocks[i];
616 double motion_time;
617 if (
klipper && block.trapezoid.cruise_feedrate > 0.0f) {
618
619
620 const double cruise = block.trapezoid.cruise_feedrate;
621 motion_time = block.distance / cruise;
622 if (block.acceleration > 0.0f) {
623 const double accel_delta = cruise - block.feedrate_profile.entry;
624 const double decel_delta = cruise - block.feedrate_profile.exit;
625 motion_time += (
sqr(accel_delta) +
sqr(decel_delta)) / (2.0 * block.acceleration * cruise);
626 }
627 } else {
628 motion_time = block.time();
629 }
630 double block_time = motion_time;
631 if (additional_buffer_idx < additional_buffer.size()) {
632 const EMoveType buf_move_type = additional_buffer[additional_buffer_idx].first;
633 if (buf_move_type ==
EMoveType::Noop || buf_move_type == block.move_type) {
634 block_time += additional_buffer[additional_buffer_idx].second;
635 ++additional_buffer_idx;
636 }
637 }
638
640
641
642
643
646 result.
moves[block.move_id].time[
static_cast<size_t>(mode)] = block_time;
648
649 if (block.flags.prepare_stage)
651
652 if (block.layer_id == 1)
654
655
657 GCodeProcessorResult::MoveVertex& curr_move =
result.
moves[block.move_id];
661 continue;
662
663 assert(curr_move.actual_feedrate == 0.0f);
664
665 GCodeProcessorResult::MoveVertex& prev_move =
result.
moves[block.move_id - 1];
666 const bool interpolate = (prev_move.type == curr_move.type);
667 if (!interpolate &&
671 prev_move.actual_feedrate = block.feedrate_profile.entry;
672
673 if (
EPSILON < block.trapezoid.accelerate_until && block.trapezoid.accelerate_until < block.distance -
EPSILON) {
674 const float t = block.trapezoid.accelerate_until / block.distance;
675 const Vec3f position =
lerp(prev_move.position, curr_move.position, t);
676 if ((position - prev_move.position).norm() >
EPSILON &&
677 (position - curr_move.position).norm() >
EPSILON) {
678 const float delta_extruder =
interpolate ?
lerp(prev_move.delta_extruder, curr_move.delta_extruder, t) : curr_move.delta_extruder;
679 const float feedrate = curr_move.feedrate;
680
681
684
685 const float mm3_per_mm = curr_move.mm3_per_mm;
686 const float fan_speed = curr_move.fan_speed;
687 const float temperature =
interpolate ?
lerp(prev_move.temperature, curr_move.temperature, t) : curr_move.temperature;
689 block.move_id,
690 position,
691 block.trapezoid.cruise_feedrate,
692 delta_extruder,
693 feedrate,
696 mm3_per_mm,
697 fan_speed,
698 temperature
699 });
700 }
701 }
702
703 const bool has_deceleration = block.trapezoid.deceleration_distance(block.distance) >
EPSILON;
704 if (has_deceleration && block.trapezoid.decelerate_after > block.trapezoid.accelerate_until +
EPSILON) {
705 const float t = block.trapezoid.decelerate_after / block.distance;
706 const Vec3f position =
lerp(prev_move.position, curr_move.position, t);
707 if ((position - prev_move.position).norm() >
EPSILON &&
708 (position - curr_move.position).norm() >
EPSILON) {
709 const float delta_extruder =
interpolate ?
lerp(prev_move.delta_extruder, curr_move.delta_extruder, t) : curr_move.delta_extruder;
710 const float feedrate = curr_move.feedrate;
711
712
715
716 const float mm3_per_mm = curr_move.mm3_per_mm;
717 const float fan_speed = curr_move.fan_speed;
718 const float temperature =
interpolate ?
lerp(prev_move.temperature, curr_move.temperature, t) : curr_move.temperature;
720 block.move_id,
721 position,
722 block.trapezoid.cruise_feedrate,
723 delta_extruder,
724 feedrate,
727 mm3_per_mm,
728 fan_speed,
729 temperature
730 });
731 }
732 }
733
734 const bool is_cruise_only = block.trapezoid.is_cruise_only(block.distance);
736 block.move_id,
737 std::nullopt,
738 (is_cruise_only || !has_deceleration) ? block.trapezoid.cruise_feedrate : block.feedrate_profile.exit,
739 std::nullopt,
740 std::nullopt,
741 std::nullopt,
742 std::nullopt,
743 std::nullopt,
744 std::nullopt,
745 std::nullopt
746 });
747 }
748 g1_times_cache.push_back({ block.g1_line_id, block.remaining_internal_g1_lines, float(
time) });
749
751 [](
const StopTime& t,
unsigned int value) { return t.g1_line_id < value; });
752 if (it_stop_time !=
stop_times.end() && it_stop_time->g1_line_id == block.g1_line_id)
753 it_stop_time->elapsed_time = float(
time);
754 }
755
756
757
759 if (additional_buffer_idx < additional_buffer.size()) {
760 if (is_final) {
761
762
763
764
765
766 float leftover = 0.0f;
767 for (size_t i = additional_buffer_idx; i < additional_buffer.size(); ++i)
768 leftover += additional_buffer[i].second;
769 BOOST_LOG_TRIVIAL(debug) << "calculate_time(is_final): leftover=" << leftover
770 << "s from " << (additional_buffer.size() - additional_buffer_idx) << " items";
771 time += double(leftover);
773 } else {
775 additional_buffer.begin() + additional_buffer_idx,
776 additional_buffer.end());
777 }
778 }
779
780 if (keep_last_n_blocks) {
782
783
784
786 TimeBlock& first_block =
blocks.front();
787 first_block.max_entry_speed = first_block.feedrate_profile.entry;
788 }
789 } else {
791 }
792}
#define EPSILON
Definition ColorUtils.cpp:64
GCodeProcessorResult & result()
Definition GCodeProcessor.hpp:1435
Point interpolate(const Point &a, const Point &b, double t)
Definition ExclusionVolumeTravelAvoidance.cpp:158
coord_t width(const BoundingBox &box)
Definition Arrange.cpp:1184
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:1185
@ stNone
Definition GCodeProcessor.hpp:77
static void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock &curr, const GCodeProcessor::TimeBlock &next)
Definition GCodeProcessor.cpp:422
static void planner_forward_pass_kernel(const GCodeProcessor::TimeBlock &prev, GCodeProcessor::TimeBlock &curr)
Definition GCodeProcessor.cpp:400
static void recalculate_trapezoids(std::vector< GCodeProcessor::TimeBlock > &blocks)
Definition GCodeProcessor.cpp:453
ColorRGB lerp(const ColorRGB &a, const ColorRGB &b, float t)
Definition Color.cpp:244
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:65
EMoveType
Definition GCodeProcessor.hpp:53
@ Travel
Definition GCodeProcessor.hpp:62
@ Noop
Definition GCodeProcessor.hpp:54
@ Wipe
Definition GCodeProcessor.hpp:63
@ Extrude
Definition GCodeProcessor.hpp:64
constexpr T sqr(T x)
Definition libslic3r.h:301
std::vector< MoveVertex > moves
Definition GCodeProcessor.hpp:313
std::unordered_map< SkipType, float > skippable_part_time
Definition GCodeProcessor.hpp:402
bool klipper
Definition GCodeProcessor.hpp:815
AdditionalBuffer m_additional_time_buffer
Definition GCodeProcessor.hpp:849
std::vector< TimeBlock > blocks
Definition GCodeProcessor.hpp:834
std::vector< ActualSpeedMove > actual_speed_moves
Definition GCodeProcessor.hpp:837
static AdditionalBuffer merge_adjacent_additional_time_blocks(const AdditionalBuffer &buffer)
Definition GCodeProcessor.cpp:483
double time
Definition GCodeProcessor.hpp:822
std::vector< StopTime > stop_times
Definition GCodeProcessor.hpp:828
std::vector< G1LinesCacheItem > g1_times_cache
Definition GCodeProcessor.hpp:835
float prepare_time
Definition GCodeProcessor.hpp:839
std::vector< AdditionalBufferBlock > AdditionalBuffer
Definition GCodeProcessor.hpp:848
size_t plan_klipper(bool lazy)
Definition GCodeProcessor.cpp:505
CustomGCodeTime gcode_time
Definition GCodeProcessor.hpp:833
float first_layer_time
Definition GCodeProcessor.hpp:836
bool enabled
Definition GCodeProcessor.hpp:804
Definition GCodeProcessor.hpp:824
@ Normal
Definition GCodeProcessor.hpp:89