ENH: seperate skippable part time
jira: NONE Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: I8d2117c7a7114298e966d3e043604d738847a72b
This commit is contained in:
parent
f8369e8796
commit
9a9f634e31
|
@ -46,7 +46,7 @@ static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero();
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
const std::vector<std::string> GCodeProcessor::Reserved_Tags = {
|
||||
const std::vector<std::string> GCodeProcessor::ReservedTags = {
|
||||
" FEATURE: ",
|
||||
" WIPE_START",
|
||||
" WIPE_END",
|
||||
|
@ -71,10 +71,15 @@ const std::vector<std::string> GCodeProcessor::Reserved_Tags = {
|
|||
" NOZZLE_CHANGE_END"
|
||||
};
|
||||
|
||||
const std::string GCodeProcessor::Flush_Start_Tag = " FLUSH_START";
|
||||
const std::string GCodeProcessor::Flush_End_Tag = " FLUSH_END";
|
||||
const std::string GCodeProcessor::VFlush_Start_Tag = " VFLUSH_START";
|
||||
const std::string GCodeProcessor::VFlush_End_Tag = " VFLUSH_END";
|
||||
const std::vector<std::string> GCodeProcessor::CustomTags = {
|
||||
" FLUSH_START",
|
||||
" FLUSH_END",
|
||||
" VFLUSH_START",
|
||||
" VFLUSH_END",
|
||||
" SKIPPABLE_START",
|
||||
" SKIPPABLE_END",
|
||||
" SKIPTYPE: "
|
||||
};
|
||||
|
||||
|
||||
const float GCodeProcessor::Wipe_Width = 0.05f;
|
||||
|
@ -392,6 +397,13 @@ static void recalculate_trapezoids(std::vector<GCodeProcessor::TimeBlock>& block
|
|||
}
|
||||
}
|
||||
|
||||
void GCodeProcessor::TimeMachine::handle_time_block(const TimeBlock& block, float time, int activate_machine_idx, GCodeProcessorResult& result)
|
||||
{
|
||||
if (block.skippable_type != SkipType::stNone)
|
||||
result.skippable_part_time[block.skippable_type] += block.time();
|
||||
result.moves[block.move_id].time[activate_machine_idx] = time;
|
||||
}
|
||||
|
||||
void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, float additional_time, ExtrusionRole target_role, block_handler_t block_handler)
|
||||
{
|
||||
if (!enabled || blocks.size() < 2)
|
||||
|
@ -1332,6 +1344,7 @@ void GCodeProcessorResult::reset() {
|
|||
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
|
||||
layer_filaments.clear();
|
||||
filament_change_count_map.clear();
|
||||
skippable_part_time.clear();
|
||||
warnings.clear();
|
||||
|
||||
//BBS: add mutex for protection of gcode result
|
||||
|
@ -1367,7 +1380,7 @@ bool GCodeProcessor::contains_reserved_tag(const std::string& gcode, std::string
|
|||
std::string comment = line.raw();
|
||||
if (comment.length() > 2 && comment.front() == ';') {
|
||||
comment = comment.substr(1);
|
||||
for (const std::string& s : Reserved_Tags) {
|
||||
for (const std::string& s : ReservedTags) {
|
||||
if (boost::starts_with(comment, s)) {
|
||||
ret = true;
|
||||
found_tag = comment;
|
||||
|
@ -1394,7 +1407,7 @@ bool GCodeProcessor::contains_reserved_tags(const std::string& gcode, unsigned i
|
|||
std::string comment = line.raw();
|
||||
if (comment.length() > 2 && comment.front() == ';') {
|
||||
comment = comment.substr(1);
|
||||
for (const std::string& s : Reserved_Tags) {
|
||||
for (const std::string& s : ReservedTags) {
|
||||
if (boost::starts_with(comment, s)) {
|
||||
ret = true;
|
||||
found_tag.push_back(comment);
|
||||
|
@ -2053,6 +2066,8 @@ void GCodeProcessor::reset()
|
|||
m_wiping = false;
|
||||
m_flushing = false;
|
||||
m_virtual_flushing = false;
|
||||
m_skippable = false;
|
||||
m_skippable_type = SkipType::stNone;
|
||||
m_wipe_tower = false;
|
||||
m_remaining_volume = { 0.f,0.f };
|
||||
// BBS: arc move related data
|
||||
|
@ -2236,9 +2251,9 @@ void GCodeProcessor::finalize(bool post_process)
|
|||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
TimeMachine& machine = m_time_processor.machines[i];
|
||||
TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time;
|
||||
machine.calculate_time(0, 0, ExtrusionRole::erNone, [&moves = m_result.moves, i](const TimeBlock& block, int time) {
|
||||
moves[block.move_id].time[i] = time;
|
||||
});
|
||||
machine.calculate_time(0, 0, ExtrusionRole::erNone, [&result=m_result, i,&machine](const TimeBlock& block, int time) {
|
||||
machine.handle_time_block(block,time,i,result);
|
||||
});
|
||||
if (gcode_time.needed && gcode_time.cache != 0.0f)
|
||||
gcode_time.times.push_back({ CustomGCode::ColorChange, gcode_time.cache });
|
||||
}
|
||||
|
@ -2808,8 +2823,27 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::SKIPPABLE_START))) {
|
||||
m_skippable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::SKIPPABLE_END))) {
|
||||
m_skippable = false;
|
||||
m_skippable_type = SkipType::stNone;
|
||||
return;
|
||||
}
|
||||
|
||||
// skippable type
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::SKIPPABLE_TYPE))) {
|
||||
std::string_view type =comment.substr(custom_tags(CustomETags::SKIPPABLE_TYPE).length());
|
||||
set_skippable_type(type);
|
||||
return;
|
||||
}
|
||||
|
||||
//BBS: flush start tag
|
||||
if (boost::starts_with(comment, GCodeProcessor::Flush_Start_Tag)) {
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::FLUSH_START))) {
|
||||
prev_role = m_extrusion_role;
|
||||
set_extrusion_role(erFlush);
|
||||
m_flushing = true;
|
||||
|
@ -2817,20 +2851,20 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
|
|||
}
|
||||
|
||||
//BBS: flush end tag
|
||||
if (boost::starts_with(comment, GCodeProcessor::Flush_End_Tag)) {
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::FLUSH_END))) {
|
||||
set_extrusion_role(prev_role);
|
||||
m_flushing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (boost::starts_with(comment, GCodeProcessor::VFlush_Start_Tag)) {
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::VFLUSH_START))) {
|
||||
prev_role = m_extrusion_role;
|
||||
set_extrusion_role(erFlush);
|
||||
m_virtual_flushing = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (boost::starts_with(comment, GCodeProcessor::VFlush_End_Tag)) {
|
||||
if (boost::starts_with(comment, custom_tags(CustomETags::VFLUSH_END))) {
|
||||
set_extrusion_role(prev_role);
|
||||
m_virtual_flushing = false;
|
||||
return;
|
||||
|
@ -3624,6 +3658,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
|
||||
TimeBlock block;
|
||||
block.move_type = type;
|
||||
block.skippable_type = m_skippable_type;
|
||||
//BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode.
|
||||
block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone;
|
||||
block.distance = distance;
|
||||
|
@ -3810,9 +3845,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
blocks.push_back(block);
|
||||
|
||||
if (blocks.size() > TimeProcessor::Planner::refresh_threshold) {
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size, 0, erNone,[&moves = m_result.moves, i](const TimeBlock& block, int time) {
|
||||
moves[block.move_id].time[i] = time;
|
||||
});
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size, 0, erNone, [&result=m_result, i,&machine](const TimeBlock& block, int time) {
|
||||
machine.handle_time_block(block,time,i,result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4062,6 +4097,7 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line)
|
|||
|
||||
TimeBlock block;
|
||||
block.move_type = type;
|
||||
block.skippable_type = m_skippable_type;
|
||||
//BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode.
|
||||
block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone;
|
||||
block.distance = distance;
|
||||
|
@ -4248,9 +4284,9 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line)
|
|||
blocks.push_back(block);
|
||||
|
||||
if (blocks.size() > TimeProcessor::Planner::refresh_threshold) {
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size, 0, erNone, [&move = this->m_result.moves,i](const TimeBlock& block, int time) {
|
||||
move[block.move_id].time[i] = time;
|
||||
});
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size, 0, erNone, [&result=m_result, i,&machine](const TimeBlock& block, int time) {
|
||||
machine.handle_time_block(block,time,i,result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4463,6 +4499,7 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line)
|
|||
|
||||
TimeBlock block;
|
||||
block.move_type = type;
|
||||
block.skippable_type = m_skippable_type;
|
||||
//BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode.
|
||||
block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone;
|
||||
block.distance = delta_xyz;
|
||||
|
@ -4630,9 +4667,9 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line)
|
|||
blocks.push_back(block);
|
||||
|
||||
if (blocks.size() > TimeProcessor::Planner::refresh_threshold) {
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size, 0, erNone, [&moves = m_result.moves, i](const TimeBlock& block, int time) {
|
||||
moves[block.move_id].time[i] = time;
|
||||
});
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size, 0, erNone, [&result=m_result, i,&machine](const TimeBlock& block, int time) {
|
||||
machine.handle_time_block(block,time,i,result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5346,6 +5383,7 @@ void GCodeProcessor::process_filament_change(int id)
|
|||
if (!machine.enabled)
|
||||
continue;
|
||||
TimeBlock block;
|
||||
block.skippable_type = m_skippable_type;
|
||||
block.move_id = m_result.moves.size() - 1;
|
||||
block.role = erFlush;
|
||||
block.move_type = EMoveType::Tool_change;
|
||||
|
@ -5427,6 +5465,20 @@ void GCodeProcessor::set_extrusion_role(ExtrusionRole role)
|
|||
m_extrusion_role = role;
|
||||
}
|
||||
|
||||
void GCodeProcessor::set_skippable_type(const std::string_view type)
|
||||
{
|
||||
if (!m_skippable){
|
||||
m_skippable_type = SkipType::stNone;
|
||||
return;
|
||||
}
|
||||
auto iter = skip_type_map.find(type);
|
||||
if(iter!=skip_type_map.end()) {
|
||||
m_skippable_type = iter->second;
|
||||
} else {
|
||||
m_skippable_type = SkipType::stOther;
|
||||
}
|
||||
}
|
||||
|
||||
float GCodeProcessor::minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const
|
||||
{
|
||||
if (m_time_processor.machine_limits.machine_min_extruding_rate.empty())
|
||||
|
@ -5574,9 +5626,9 @@ void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code)
|
|||
gcode_time.needed = true;
|
||||
//FIXME this simulates st_synchronize! is it correct?
|
||||
// The estimated time may be longer than the real print time.
|
||||
machine.simulate_st_synchronize(0, erNone, [&moves = m_result.moves, i](const TimeBlock& block, int time) {
|
||||
moves[block.move_id].time[i] = time;
|
||||
});
|
||||
machine.simulate_st_synchronize(0, erNone, [&result=m_result, i,&machine](const TimeBlock& block, int time) {
|
||||
machine.handle_time_block(block,time,i,result);
|
||||
});
|
||||
if (gcode_time.cache != 0.0f) {
|
||||
gcode_time.times.push_back({ code, gcode_time.cache });
|
||||
gcode_time.cache = 0.0f;
|
||||
|
@ -5606,9 +5658,9 @@ void GCodeProcessor::simulate_st_synchronize(float additional_time, ExtrusionRol
|
|||
if (!machine.enabled)
|
||||
continue;
|
||||
|
||||
machine.simulate_st_synchronize(additional_time, target_role, [&moves = m_result.moves, i](const TimeBlock& block, int time) {
|
||||
moves[block.move_id].time[i] = time;
|
||||
});
|
||||
machine.simulate_st_synchronize(additional_time, target_role, [&result=m_result, i,&machine](const TimeBlock& block, int time) {
|
||||
machine.handle_time_block(block,time,i,result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,16 @@ namespace Slic3r {
|
|||
Count
|
||||
};
|
||||
|
||||
enum SkipType
|
||||
{
|
||||
stTimelapse,
|
||||
stOther,
|
||||
stNone
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string_view, SkipType> skip_type_map {
|
||||
{"timelapse", SkipType::stTimelapse}
|
||||
};
|
||||
struct PrintEstimatedStatistics
|
||||
{
|
||||
enum class ETimeMode : unsigned char
|
||||
|
@ -257,6 +267,8 @@ namespace Slic3r {
|
|||
// first key stores `from` filament, second keys stores the `to` filament
|
||||
std::map<std::pair<int,int>, int > filament_change_count_map;
|
||||
|
||||
std::unordered_map<SkipType, float> skippable_part_time;
|
||||
|
||||
BedType bed_type = BedType::btCount;
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
int64_t time{ 0 };
|
||||
|
@ -294,6 +306,7 @@ namespace Slic3r {
|
|||
filament_printable_reuslt = other.filament_printable_reuslt;
|
||||
layer_filaments = other.layer_filaments;
|
||||
filament_change_count_map = other.filament_change_count_map;
|
||||
skippable_part_time = other.skippable_part_time;
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
time = other.time;
|
||||
#endif
|
||||
|
@ -381,11 +394,8 @@ namespace Slic3r {
|
|||
|
||||
class GCodeProcessor
|
||||
{
|
||||
static const std::vector<std::string> Reserved_Tags;
|
||||
static const std::string Flush_Start_Tag;
|
||||
static const std::string Flush_End_Tag;
|
||||
static const std::string VFlush_Start_Tag;
|
||||
static const std::string VFlush_End_Tag;
|
||||
static const std::vector<std::string> ReservedTags;
|
||||
static const std::vector<std::string> CustomTags;
|
||||
public:
|
||||
enum class ETags : unsigned char
|
||||
{
|
||||
|
@ -413,7 +423,19 @@ namespace Slic3r {
|
|||
NozzleChangeEnd
|
||||
};
|
||||
|
||||
static const std::string& reserved_tag(ETags tag) { return Reserved_Tags[static_cast<unsigned char>(tag)]; }
|
||||
enum class CustomETags : unsigned char
|
||||
{
|
||||
FLUSH_START,
|
||||
FLUSH_END,
|
||||
VFLUSH_START,
|
||||
VFLUSH_END,
|
||||
SKIPPABLE_START,
|
||||
SKIPPABLE_END,
|
||||
SKIPPABLE_TYPE
|
||||
};
|
||||
|
||||
static const std::string& reserved_tag(ETags tag) { return ReservedTags[static_cast<unsigned char>(tag)]; }
|
||||
static const std::string& custom_tags(CustomETags tag) { return CustomTags[static_cast<unsigned char>(tag)]; }
|
||||
// checks the given gcode for reserved tags and returns true when finding the 1st (which is returned into found_tag)
|
||||
static bool contains_reserved_tag(const std::string& gcode, std::string& found_tag);
|
||||
// checks the given gcode for reserved tags and returns true when finding any
|
||||
|
@ -497,6 +519,7 @@ namespace Slic3r {
|
|||
|
||||
EMoveType move_type{ EMoveType::Noop };
|
||||
ExtrusionRole role{ erNone };
|
||||
SkipType skippable_type{ SkipType::stNone };
|
||||
unsigned int move_id{ 0 }; // index of the related move vertex, will be assigned duraing gcode process
|
||||
unsigned int g1_line_id{ 0 };
|
||||
unsigned int layer_id{ 0 };
|
||||
|
@ -610,6 +633,8 @@ namespace Slic3r {
|
|||
* @param block_handler Handler to set the processing logic for each block and its corresponding time.
|
||||
*/
|
||||
void calculate_time(size_t keep_last_n_blocks = 0, float additional_time = 0.0f, ExtrusionRole target_role = ExtrusionRole::erNone, block_handler_t block_handler = block_handler_t());
|
||||
|
||||
void handle_time_block(const TimeBlock& block, float time, int activate_machine_idx, GCodeProcessorResult& result);
|
||||
};
|
||||
|
||||
struct UsedFilaments // filaments per ColorChange
|
||||
|
@ -963,6 +988,8 @@ namespace Slic3r {
|
|||
bool m_flushing; // mark a section with real flush
|
||||
bool m_virtual_flushing; // mark a section with virtual flush, only for statistics
|
||||
bool m_wipe_tower;
|
||||
bool m_skippable;
|
||||
SkipType m_skippable_type;
|
||||
int m_object_label_id{-1};
|
||||
float m_print_z{0.0f};
|
||||
std::vector<float> m_remaining_volume;
|
||||
|
@ -1244,6 +1271,7 @@ namespace Slic3r {
|
|||
void store_move_vertex(EMoveType type, EMovePathType path_type = EMovePathType::Noop_move);
|
||||
|
||||
void set_extrusion_role(ExtrusionRole role);
|
||||
void set_skippable_type(const std::string_view type);
|
||||
|
||||
float minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const;
|
||||
float minimum_travel_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const;
|
||||
|
|
Loading…
Reference in New Issue