mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Optimization of the GCodeTimeEstimator to only keep a fixed number
of trapeziodal blocks around. The number is hard coded to 64, and 3x64 blocks are flushed everytime the queue grows over 4x64 blocks. This time estimator is slightly more close to what the firmware does, which keeps a fixed number of blocks and it recalculates all the blocks every time a new block is added while the oldest block is pushed out of the queue. Therefore this optimization shall produce negligible differences to what the previous code produced.
This commit is contained in:
parent
f4cc0ce075
commit
31b0ae164d
2 changed files with 78 additions and 99 deletions
|
@ -207,11 +207,8 @@ namespace Slic3r {
|
|||
{
|
||||
PROFILE_FUNC();
|
||||
if (start_from_beginning)
|
||||
{
|
||||
_reset_time();
|
||||
m_last_st_synchronized_block_id = -1;
|
||||
}
|
||||
_calculate_time();
|
||||
_calculate_time(0);
|
||||
|
||||
if (m_needs_custom_gcode_times && (m_custom_gcode_time_cache != 0.0f))
|
||||
m_custom_gcode_times.push_back({ cgtColorChange, m_custom_gcode_time_cache });
|
||||
|
@ -221,6 +218,7 @@ namespace Slic3r {
|
|||
#endif // ENABLE_MOVE_STATS
|
||||
}
|
||||
|
||||
#if 0
|
||||
void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode)
|
||||
{
|
||||
reset();
|
||||
|
@ -229,7 +227,7 @@ namespace Slic3r {
|
|||
[this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
||||
{ this->_process_gcode_line(reader, line); });
|
||||
|
||||
_calculate_time();
|
||||
_calculate_time(0);
|
||||
|
||||
if (m_needs_custom_gcode_times && (m_custom_gcode_time_cache != 0.0f))
|
||||
m_custom_gcode_times.push_back({ cgtColorChange, m_custom_gcode_time_cache });
|
||||
|
@ -244,7 +242,7 @@ namespace Slic3r {
|
|||
reset();
|
||||
|
||||
m_parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
|
||||
_calculate_time();
|
||||
_calculate_time(0);
|
||||
|
||||
if (m_needs_custom_gcode_times && (m_custom_gcode_time_cache != 0.0f))
|
||||
m_custom_gcode_times.push_back({ cgtColorChange, m_custom_gcode_time_cache });
|
||||
|
@ -262,7 +260,7 @@ namespace Slic3r {
|
|||
{ this->_process_gcode_line(reader, line); };
|
||||
for (const std::string& line : gcode_lines)
|
||||
m_parser.parse_line(line, action);
|
||||
_calculate_time();
|
||||
_calculate_time(0);
|
||||
|
||||
if (m_needs_custom_gcode_times && (m_custom_gcode_time_cache != 0.0f))
|
||||
m_custom_gcode_times.push_back({ cgtColorChange, m_custom_gcode_time_cache});
|
||||
|
@ -271,6 +269,7 @@ namespace Slic3r {
|
|||
_log_moves_stats();
|
||||
#endif // ENABLE_MOVE_STATS
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GCodeTimeEstimator::post_process(const std::string& filename, float interval_sec, const PostProcessData* const normal_mode, const PostProcessData* const silent_mode)
|
||||
{
|
||||
|
@ -317,25 +316,25 @@ namespace Slic3r {
|
|||
if (data == nullptr)
|
||||
return;
|
||||
|
||||
assert((g1_line_id >= (int)data->g1_line_ids.size()) || (data->g1_line_ids[g1_line_id].first >= g1_lines_count));
|
||||
const Block* block = nullptr;
|
||||
if (g1_line_id < (int)data->g1_line_ids.size())
|
||||
assert((g1_line_id >= (int)data->g1_times.size()) || (data->g1_times[g1_line_id].first >= (int)g1_lines_count));
|
||||
float elapsed_time = -1.0f;
|
||||
if (g1_line_id < (int)data->g1_times.size())
|
||||
{
|
||||
const G1LineIdToBlockId& map_item = data->g1_line_ids[g1_line_id];
|
||||
const G1LineIdTime& map_item = data->g1_times[g1_line_id];
|
||||
if (map_item.first == g1_lines_count)
|
||||
{
|
||||
if (line.has_e() && (map_item.second < (unsigned int)data->blocks.size()))
|
||||
block = &data->blocks[map_item.second];
|
||||
if (line.has_e())
|
||||
elapsed_time = map_item.second;
|
||||
++g1_line_id;
|
||||
}
|
||||
}
|
||||
|
||||
if ((block != nullptr) && (block->elapsed_time != -1.0f))
|
||||
if (elapsed_time != -1.0f)
|
||||
{
|
||||
float block_remaining_time = data->time - block->elapsed_time;
|
||||
float block_remaining_time = data->time - elapsed_time;
|
||||
if (std::abs(last_recorded_time - block_remaining_time) > interval_sec)
|
||||
{
|
||||
sprintf(line_M73, time_mask.c_str(), std::to_string((int)(100.0f * block->elapsed_time / data->time)).c_str(), _get_time_minutes(block_remaining_time).c_str());
|
||||
sprintf(line_M73, time_mask.c_str(), std::to_string((int)(100.0f * elapsed_time / data->time)).c_str(), _get_time_minutes(block_remaining_time).c_str());
|
||||
gcode_line += line_M73;
|
||||
|
||||
last_recorded_time = block_remaining_time;
|
||||
|
@ -643,22 +642,6 @@ namespace Slic3r {
|
|||
m_state.extruder_id = m_state.extruder_id_unloaded;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::add_additional_time(float timeSec)
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
m_state.additional_time += timeSec;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::set_additional_time(float timeSec)
|
||||
{
|
||||
m_state.additional_time = timeSec;
|
||||
}
|
||||
|
||||
float GCodeTimeEstimator::get_additional_time() const
|
||||
{
|
||||
return m_state.additional_time;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::set_default()
|
||||
{
|
||||
set_units(Millimeters);
|
||||
|
@ -788,7 +771,7 @@ namespace Slic3r {
|
|||
{
|
||||
size_t out = sizeof(*this);
|
||||
out += SLIC3R_STDVEC_MEMSIZE(this->m_blocks, Block);
|
||||
out += SLIC3R_STDVEC_MEMSIZE(this->m_g1_line_ids, G1LineIdToBlockId);
|
||||
out += SLIC3R_STDVEC_MEMSIZE(this->m_g1_times, G1LineIdTime);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -807,13 +790,9 @@ namespace Slic3r {
|
|||
if (get_e_local_positioning_type() == Absolute)
|
||||
set_axis_position(E, 0.0f);
|
||||
|
||||
set_additional_time(0.0f);
|
||||
|
||||
reset_extruder_id();
|
||||
reset_g1_line_id();
|
||||
m_g1_line_ids.clear();
|
||||
|
||||
m_last_st_synchronized_block_id = -1;
|
||||
m_g1_times.clear();
|
||||
|
||||
m_needs_custom_gcode_times = false;
|
||||
m_custom_gcode_times.clear();
|
||||
|
@ -830,17 +809,19 @@ namespace Slic3r {
|
|||
m_blocks.clear();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_calculate_time()
|
||||
void GCodeTimeEstimator::_calculate_time(size_t keep_last_n_blocks)
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
|
||||
assert(keep_last_n_blocks <= m_blocks.size());
|
||||
|
||||
_forward_pass();
|
||||
_reverse_pass();
|
||||
_recalculate_trapezoids();
|
||||
|
||||
m_time += get_additional_time();
|
||||
m_custom_gcode_time_cache += get_additional_time();
|
||||
|
||||
for (int i = m_last_st_synchronized_block_id + 1; i < (int)m_blocks.size(); ++i)
|
||||
size_t n_blocks_process = m_blocks.size() - keep_last_n_blocks;
|
||||
m_g1_times.reserve(m_g1_times.size() + n_blocks_process);
|
||||
for (size_t i = 0; i < n_blocks_process; ++ i)
|
||||
{
|
||||
Block& block = m_blocks[i];
|
||||
float block_time = 0.0f;
|
||||
|
@ -848,7 +829,8 @@ namespace Slic3r {
|
|||
block_time += block.cruise_time();
|
||||
block_time += block.deceleration_time();
|
||||
m_time += block_time;
|
||||
block.elapsed_time = m_time;
|
||||
if (block.g1_line_id >= 0)
|
||||
m_g1_times.emplace_back(block.g1_line_id, m_time);
|
||||
|
||||
#if ENABLE_MOVE_STATS
|
||||
MovesStatsMap::iterator it = _moves_stats.find(block.move_type);
|
||||
|
@ -862,9 +844,10 @@ namespace Slic3r {
|
|||
m_custom_gcode_time_cache += block_time;
|
||||
}
|
||||
|
||||
m_last_st_synchronized_block_id = (int)m_blocks.size() - 1;
|
||||
// The additional time has been consumed (added to the total time), reset it to zero.
|
||||
set_additional_time(0.);
|
||||
if (keep_last_n_blocks)
|
||||
m_blocks.erase(m_blocks.begin(), m_blocks.begin() + n_blocks_process);
|
||||
else
|
||||
m_blocks.clear();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line)
|
||||
|
@ -1208,8 +1191,11 @@ namespace Slic3r {
|
|||
#endif // ENABLE_MOVE_STATS
|
||||
|
||||
// adds block to blocks list
|
||||
block.g1_line_id = this->get_g1_line_id();
|
||||
m_blocks.emplace_back(block);
|
||||
m_g1_line_ids.emplace_back(G1LineIdToBlockIdMap::value_type(get_g1_line_id(), (unsigned int)m_blocks.size() - 1));
|
||||
|
||||
if (m_blocks.size() > planner_refresh_if_larger)
|
||||
_calculate_time(planner_queue_size);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line)
|
||||
|
@ -1218,8 +1204,9 @@ namespace Slic3r {
|
|||
GCodeFlavor dialect = get_dialect();
|
||||
|
||||
float value;
|
||||
float extra_time = 0.f;
|
||||
if (line.has_value('P', value))
|
||||
add_additional_time(value * MILLISEC_TO_SEC);
|
||||
extra_time += value * MILLISEC_TO_SEC;
|
||||
|
||||
// see: http://reprap.org/wiki/G-code#G4:_Dwell
|
||||
if ((dialect == gcfRepetier) ||
|
||||
|
@ -1228,10 +1215,10 @@ namespace Slic3r {
|
|||
(dialect == gcfRepRap))
|
||||
{
|
||||
if (line.has_value('S', value))
|
||||
add_additional_time(value);
|
||||
extra_time += value;
|
||||
}
|
||||
|
||||
_simulate_st_synchronize();
|
||||
_simulate_st_synchronize(extra_time);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line)
|
||||
|
@ -1296,7 +1283,7 @@ namespace Slic3r {
|
|||
anyFound = true;
|
||||
}
|
||||
else
|
||||
_simulate_st_synchronize();
|
||||
_simulate_st_synchronize(0.f);
|
||||
|
||||
if (!anyFound)
|
||||
{
|
||||
|
@ -1310,7 +1297,7 @@ namespace Slic3r {
|
|||
void GCodeTimeEstimator::_processM1(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
_simulate_st_synchronize();
|
||||
_simulate_st_synchronize(0.f);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line)
|
||||
|
@ -1462,9 +1449,9 @@ namespace Slic3r {
|
|||
// MK3 MMU2 specific M code:
|
||||
// M702 C is expected to be sent by the custom end G-code when finalizing a print.
|
||||
// The MK3 unit shall unload and park the active filament into the MMU2 unit.
|
||||
add_additional_time(get_filament_unload_time(get_extruder_id()));
|
||||
float extra_time = get_filament_unload_time(get_extruder_id());
|
||||
reset_extruder_id();
|
||||
_simulate_st_synchronize();
|
||||
_simulate_st_synchronize(extra_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1478,10 +1465,10 @@ namespace Slic3r {
|
|||
{
|
||||
// Specific to the MK3 MMU2: The initial extruder ID is set to -1 indicating
|
||||
// that the filament is parked in the MMU2 unit and there is nothing to be unloaded yet.
|
||||
add_additional_time(get_filament_unload_time(get_extruder_id()));
|
||||
float extra_time = get_filament_unload_time(get_extruder_id());
|
||||
set_extruder_id(id);
|
||||
add_additional_time(get_filament_load_time(get_extruder_id()));
|
||||
_simulate_st_synchronize();
|
||||
extra_time += get_filament_load_time(get_extruder_id());
|
||||
_simulate_st_synchronize(extra_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1513,7 +1500,9 @@ namespace Slic3r {
|
|||
{
|
||||
PROFILE_FUNC();
|
||||
m_needs_custom_gcode_times = true;
|
||||
_calculate_time();
|
||||
//FIXME this simulates st_synchronize! is it correct?
|
||||
// The estimated time may be longer than the real print time.
|
||||
_simulate_st_synchronize(0.f);
|
||||
if (m_custom_gcode_time_cache != 0.0f)
|
||||
{
|
||||
m_custom_gcode_times.push_back({code, m_custom_gcode_time_cache});
|
||||
|
@ -1521,34 +1510,26 @@ namespace Slic3r {
|
|||
}
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_simulate_st_synchronize()
|
||||
void GCodeTimeEstimator::_simulate_st_synchronize(float extra_time)
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
_calculate_time();
|
||||
m_time += extra_time;
|
||||
m_custom_gcode_time_cache += extra_time;
|
||||
_calculate_time(0);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_forward_pass()
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
if (m_blocks.size() > 1)
|
||||
{
|
||||
for (int i = m_last_st_synchronized_block_id + 1; i < (int)m_blocks.size() - 1; ++i)
|
||||
{
|
||||
_planner_forward_pass_kernel(m_blocks[i], m_blocks[i + 1]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i + 1 < (int)m_blocks.size(); ++i)
|
||||
_planner_forward_pass_kernel(m_blocks[i], m_blocks[i + 1]);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_reverse_pass()
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
if (m_blocks.size() > 1)
|
||||
{
|
||||
for (int i = (int)m_blocks.size() - 1; i >= m_last_st_synchronized_block_id + 2; --i)
|
||||
{
|
||||
_planner_reverse_pass_kernel(m_blocks[i - 1], m_blocks[i]);
|
||||
}
|
||||
}
|
||||
for (int i = (int)m_blocks.size() - 1; i > 0; -- i)
|
||||
_planner_reverse_pass_kernel(m_blocks[i - 1], m_blocks[i]);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_planner_forward_pass_kernel(Block& prev, Block& curr)
|
||||
|
@ -1598,7 +1579,7 @@ namespace Slic3r {
|
|||
Block* curr = nullptr;
|
||||
Block* next = nullptr;
|
||||
|
||||
for (int i = m_last_st_synchronized_block_id + 1; i < (int)m_blocks.size(); ++i)
|
||||
for (size_t i = 0; i < m_blocks.size(); ++ i)
|
||||
{
|
||||
Block& b = m_blocks[i];
|
||||
|
||||
|
@ -1657,7 +1638,7 @@ namespace Slic3r {
|
|||
{
|
||||
char buffer[64];
|
||||
|
||||
int minutes = std::round(time_in_secs / 60.);
|
||||
int minutes = int(std::round(time_in_secs / 60.));
|
||||
if (minutes <= 0) {
|
||||
::sprintf(buffer, "%ds", (int)time_in_secs);
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue