mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 23:01:17 +00:00
perf: speed up G-code export by up to 7% via post-processing fixes (#16031)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
This commit is contained in:
co-authored by
Rodrigo Faselli
parent
c67b54b39d
commit
6e0f04815b
@@ -909,8 +909,8 @@ public:
|
||||
{
|
||||
// Orca: find start pos by seaching G28/G29/PRINT_START/START_PRINT commands
|
||||
auto is_start_pos = [](const std::string& curr_cmd) {
|
||||
return boost::iequals(curr_cmd, "G28") || boost::iequals(curr_cmd, "G29") || boost::iequals(curr_cmd, "PRINT_START") ||
|
||||
boost::iequals(curr_cmd, "START_PRINT");
|
||||
return ascii_iequals(curr_cmd, "G28") || ascii_iequals(curr_cmd, "G29") || ascii_iequals(curr_cmd, "PRINT_START") ||
|
||||
ascii_iequals(curr_cmd, "START_PRINT");
|
||||
};
|
||||
assert(!m_lines.empty());
|
||||
const float time_step = backtrace.time_step();
|
||||
@@ -1265,6 +1265,9 @@ void GCodeProcessor::run_post_process()
|
||||
// Process inline placeholders (print_time_total_sec, print_time_day, print_time_hour, print_time_minute, print_time_sec and used_filament_length)
|
||||
auto process_inline_placeholders = [&](std::string& gcode_line) {
|
||||
bool processed = false;
|
||||
// Every inline placeholder contains '@', so a line without one has nothing to replace.
|
||||
if (gcode_line.find('@') == std::string::npos)
|
||||
return processed;
|
||||
|
||||
const std::string& print_time_total_placeholder = reserved_tag(ETags::Print_Time_Total_Sec_Placeholder);
|
||||
const std::string& print_time_day_placeholder = reserved_tag(ETags::Print_Time_Day_Placeholder);
|
||||
@@ -4007,13 +4010,13 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
|
||||
const std::string_view cmd = line.cmd();
|
||||
if (m_flavor == gcfKlipper)
|
||||
{
|
||||
if (boost::iequals(cmd, "SET_VELOCITY_LIMIT"))
|
||||
if (ascii_iequals(cmd, "SET_VELOCITY_LIMIT"))
|
||||
{
|
||||
process_SET_VELOCITY_LIMIT(line);
|
||||
return;
|
||||
}
|
||||
// ORCA: Add Pressure Advance visualization support
|
||||
if (boost::iequals(cmd, "SET_PRESSURE_ADVANCE"))
|
||||
if (ascii_iequals(cmd, "SET_PRESSURE_ADVANCE"))
|
||||
{
|
||||
process_SET_PRESSURE_ADVANCE(line);
|
||||
return;
|
||||
@@ -7551,51 +7554,72 @@ void GCodeProcessor::calculate_time(GCodeProcessorResult& result, size_t keep_la
|
||||
actual_speed_moves = std::move(machine.actual_speed_moves);
|
||||
}
|
||||
|
||||
// insert actual speed moves into the move list
|
||||
unsigned int inserted_actual_speed_moves_count = 0;
|
||||
std::vector<GCodeProcessorResult::MoveVertex> new_moves;
|
||||
std::map<unsigned int, unsigned int> id_map;
|
||||
for (auto it = actual_speed_moves.begin(); it != actual_speed_moves.end(); ++it) {
|
||||
const unsigned int base_id = it->move_id + inserted_actual_speed_moves_count;
|
||||
if (it->position.has_value()) {
|
||||
// insert actual speed move into the move list
|
||||
// clone from existing move
|
||||
GCodeProcessorResult::MoveVertex new_move = result.moves[base_id];
|
||||
// override modified parameters
|
||||
new_move.time = { 0.0f, 0.0f };
|
||||
new_move.position = *it->position;
|
||||
new_move.actual_feedrate = it->actual_feedrate;
|
||||
new_move.delta_extruder = *it->delta_extruder;
|
||||
new_move.feedrate = *it->feedrate;
|
||||
new_move.width = *it->width;
|
||||
new_move.height = *it->height;
|
||||
new_move.mm3_per_mm = *it->mm3_per_mm;
|
||||
new_move.fan_speed = *it->fan_speed;
|
||||
new_move.temperature = *it->temperature;
|
||||
new_move.internal_only = true;
|
||||
new_moves.push_back(new_move);
|
||||
// actual_speed_moves holds, per block in move order, the moves to insert before the block's move and then an
|
||||
// entry without a position for that move; positioned entries after the last such entry are dropped.
|
||||
std::vector<GCodeProcessorResult::MoveVertex>& moves = result.moves;
|
||||
size_t inserted_actual_speed_moves_count = 0;
|
||||
size_t kept = 0;
|
||||
size_t group_start = 0;
|
||||
for (size_t i = 0; i < actual_speed_moves.size(); ++i) {
|
||||
if (actual_speed_moves[i].position.has_value())
|
||||
continue;
|
||||
const unsigned int move_id = actual_speed_moves[i].move_id;
|
||||
// A VG1 block has no move of its own, so its id can fall behind the previous block's or point past the list.
|
||||
if (move_id < moves.size() && (kept == 0 || move_id > actual_speed_moves[kept - 1].move_id)) {
|
||||
inserted_actual_speed_moves_count += i - group_start;
|
||||
moves[move_id].actual_feedrate = actual_speed_moves[i].actual_feedrate;
|
||||
// A seam vertex right after a block's move shares its actual speed.
|
||||
if (move_id + 1 < moves.size() && moves[move_id + 1].type == EMoveType::Seam)
|
||||
moves[move_id + 1].actual_feedrate = actual_speed_moves[i].actual_feedrate;
|
||||
for (size_t j = group_start; j <= i; ++j, ++kept)
|
||||
if (kept != j)
|
||||
actual_speed_moves[kept] = std::move(actual_speed_moves[j]);
|
||||
}
|
||||
else {
|
||||
result.moves.insert(result.moves.begin() + base_id, new_moves.begin(), new_moves.end());
|
||||
id_map[it->move_id] = base_id + new_moves.size();
|
||||
// update move actual speed
|
||||
result.moves[base_id + new_moves.size()].actual_feedrate = it->actual_feedrate;
|
||||
inserted_actual_speed_moves_count += new_moves.size();
|
||||
// synchronize seams actual speed
|
||||
if (base_id + new_moves.size() + 1 < result.moves.size()) {
|
||||
GCodeProcessorResult::MoveVertex& move = result.moves[base_id + new_moves.size() + 1];
|
||||
if (move.type == EMoveType::Seam)
|
||||
move.actual_feedrate = it->actual_feedrate;
|
||||
}
|
||||
new_moves.clear();
|
||||
group_start = i + 1;
|
||||
}
|
||||
actual_speed_moves.erase(actual_speed_moves.begin() + kept, actual_speed_moves.end());
|
||||
|
||||
// Walks the blocks back to front, so each shifted move is moved once, into its final slot.
|
||||
size_t read = moves.size(); // one past the last move not yet placed
|
||||
moves.resize(moves.size() + inserted_actual_speed_moves_count);
|
||||
size_t write = moves.size(); // one past the last free slot
|
||||
m_actual_speed_id_map.clear();
|
||||
size_t entry = actual_speed_moves.size();
|
||||
while (entry > 0) {
|
||||
const unsigned int block_id = actual_speed_moves[--entry].move_id;
|
||||
assert(block_id < read);
|
||||
while (read > block_id + 1)
|
||||
moves[--write] = moves[--read];
|
||||
const GCodeProcessorResult::MoveVertex block_move = moves[--read];
|
||||
moves[--write] = block_move;
|
||||
m_actual_speed_id_map.emplace_back(block_id, (unsigned int)write);
|
||||
for (; entry > 0 && actual_speed_moves[entry - 1].position.has_value(); --entry) {
|
||||
const TimeMachine::ActualSpeedMove& it = actual_speed_moves[entry - 1];
|
||||
GCodeProcessorResult::MoveVertex new_move = block_move;
|
||||
new_move.time = { 0.0f, 0.0f };
|
||||
new_move.position = *it.position;
|
||||
new_move.actual_feedrate = it.actual_feedrate;
|
||||
new_move.delta_extruder = *it.delta_extruder;
|
||||
new_move.feedrate = *it.feedrate;
|
||||
new_move.width = *it.width;
|
||||
new_move.height = *it.height;
|
||||
new_move.mm3_per_mm = *it.mm3_per_mm;
|
||||
new_move.fan_speed = *it.fan_speed;
|
||||
new_move.temperature = *it.temperature;
|
||||
new_move.internal_only = true;
|
||||
moves[--write] = new_move;
|
||||
}
|
||||
}
|
||||
assert(read == write);
|
||||
|
||||
// synchronize blocks' move_ids with after moves for actual speed insertion
|
||||
std::reverse(m_actual_speed_id_map.begin(), m_actual_speed_id_map.end());
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
for (GCodeProcessor::TimeBlock& block : m_time_processor.machines[i].blocks) {
|
||||
auto it = id_map.find(block.move_id);
|
||||
block.move_id = (it != id_map.end()) ? it->second : block.move_id + inserted_actual_speed_moves_count;
|
||||
auto it = std::lower_bound(m_actual_speed_id_map.begin(), m_actual_speed_id_map.end(), block.move_id,
|
||||
[](const std::pair<unsigned int, unsigned int>& entry, unsigned int id) { return entry.first < id; });
|
||||
block.move_id = (it != m_actual_speed_id_map.end() && it->first == block.move_id) ?
|
||||
it->second : block.move_id + (unsigned int)inserted_actual_speed_moves_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user