mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Implemented time estimation for PausePrint (#3544)
DoubleSlider: fixed get_color_for_color_change_tick()
This commit is contained in:
		
							parent
							
								
									90a8076d25
								
							
						
					
					
						commit
						487ac0423e
					
				
					 8 changed files with 127 additions and 59 deletions
				
			
		|  | @ -13,6 +13,12 @@ static constexpr char ColorChangeCode[] = "M600"; | |||
| static constexpr char PausePrintCode[]  = "M601"; | ||||
| static constexpr char ToolChangeCode[]  = "tool_change"; | ||||
| 
 | ||||
| enum CustomGcodeType | ||||
| { | ||||
|     cgtColorChange, | ||||
|     cgtPausePrint, | ||||
| }; | ||||
| 
 | ||||
| namespace CustomGCode { | ||||
| 
 | ||||
| struct Item | ||||
|  |  | |||
|  | @ -1033,9 +1033,9 @@ namespace DoExport { | |||
| 	    print_statistics.clear(); | ||||
| 	    print_statistics.estimated_normal_print_time = normal_time_estimator.get_time_dhm/*s*/(); | ||||
| 	    print_statistics.estimated_silent_print_time = silent_time_estimator_enabled ? silent_time_estimator.get_time_dhm/*s*/() : "N/A"; | ||||
| 	    print_statistics.estimated_normal_color_print_times = normal_time_estimator.get_color_times_dhms(true); | ||||
| 	    print_statistics.estimated_normal_custom_gcode_print_times = normal_time_estimator.get_custom_gcode_times_dhm(true); | ||||
| 	    if (silent_time_estimator_enabled) | ||||
| 	        print_statistics.estimated_silent_color_print_times = silent_time_estimator.get_color_times_dhms(true); | ||||
| 	        print_statistics.estimated_silent_custom_gcode_print_times = silent_time_estimator.get_custom_gcode_times_dhm(true); | ||||
| 	    print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges); | ||||
| 	    if (! extruders.empty()) { | ||||
| 	        std::pair<std::string, unsigned int> out_filament_used_mm ("; filament used [mm] = ", 0); | ||||
|  | @ -1823,7 +1823,7 @@ namespace ProcessLayer | |||
| 	                if (!pause_print_msg.empty()) | ||||
| 	                    gcode += "M117 " + pause_print_msg + "\n"; | ||||
| 	                // add tag for time estimator
 | ||||
| 	                //gcode += "; " + GCodeTimeEstimator::Pause_Print_Tag + "\n";
 | ||||
| 	                gcode += "; " + GCodeTimeEstimator::Pause_Print_Tag + "\n"; | ||||
| 	            } | ||||
| 	            else // custom Gcode
 | ||||
| 	            { | ||||
|  |  | |||
|  | @ -174,6 +174,7 @@ namespace Slic3r { | |||
|     const std::string GCodeTimeEstimator::Silent_Last_M73_Output_Placeholder_Tag = "; _TE_SILENT_LAST_M73_OUTPUT_PLACEHOLDER"; | ||||
| 
 | ||||
|     const std::string GCodeTimeEstimator::Color_Change_Tag = "PRINT_COLOR_CHANGE"; | ||||
|     const std::string GCodeTimeEstimator::Pause_Print_Tag  = "PRINT_PAUSE"; | ||||
| 
 | ||||
|     GCodeTimeEstimator::GCodeTimeEstimator(EMode mode) | ||||
|         : m_mode(mode) | ||||
|  | @ -212,8 +213,8 @@ namespace Slic3r { | |||
|         } | ||||
|         _calculate_time(); | ||||
| 
 | ||||
|         if (m_needs_color_times && (m_color_time_cache != 0.0f)) | ||||
|             m_color_times.push_back(m_color_time_cache); | ||||
|         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 }); | ||||
| 
 | ||||
| #if ENABLE_MOVE_STATS | ||||
|         _log_moves_stats(); | ||||
|  | @ -230,8 +231,8 @@ namespace Slic3r { | |||
| 
 | ||||
|         _calculate_time(); | ||||
| 
 | ||||
|         if (m_needs_color_times && (m_color_time_cache != 0.0f)) | ||||
|             m_color_times.push_back(m_color_time_cache); | ||||
|         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 }); | ||||
| 
 | ||||
| #if ENABLE_MOVE_STATS | ||||
|         _log_moves_stats(); | ||||
|  | @ -245,8 +246,8 @@ namespace Slic3r { | |||
|         m_parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); | ||||
|         _calculate_time(); | ||||
| 
 | ||||
|         if (m_needs_color_times && (m_color_time_cache != 0.0f)) | ||||
|             m_color_times.push_back(m_color_time_cache); | ||||
|         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 }); | ||||
| 
 | ||||
| #if ENABLE_MOVE_STATS | ||||
|         _log_moves_stats(); | ||||
|  | @ -263,8 +264,8 @@ namespace Slic3r { | |||
|             m_parser.parse_line(line, action); | ||||
|         _calculate_time(); | ||||
| 
 | ||||
|         if (m_needs_color_times && (m_color_time_cache != 0.0f)) | ||||
|             m_color_times.push_back(m_color_time_cache); | ||||
|         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}); | ||||
| 
 | ||||
| #if ENABLE_MOVE_STATS | ||||
|         _log_moves_stats(); | ||||
|  | @ -351,8 +352,8 @@ namespace Slic3r { | |||
|             } | ||||
| 
 | ||||
|             // check tags
 | ||||
|             // remove color change tag
 | ||||
|             if (gcode_line == "; " + Color_Change_Tag) | ||||
|             // remove Color_Change_Tag and Pause_Print_Tag
 | ||||
|             if (gcode_line == "; " + Color_Change_Tag || gcode_line == "; " + Pause_Print_Tag) | ||||
|                 continue; | ||||
| 
 | ||||
|             // replaces placeholders for initial line M73 with the real lines
 | ||||
|  | @ -717,25 +718,26 @@ namespace Slic3r { | |||
|         return _get_time_minutes(get_time()); | ||||
|     } | ||||
| 
 | ||||
|     std::vector<float> GCodeTimeEstimator::get_color_times() const | ||||
|     std::vector<std::pair<CustomGcodeType, float>> GCodeTimeEstimator::get_custom_gcode_times() const | ||||
|     { | ||||
|         return m_color_times; | ||||
|         return m_custom_gcode_times; | ||||
|     } | ||||
| 
 | ||||
|     std::vector<std::string> GCodeTimeEstimator::get_color_times_dhms(bool include_remaining) const | ||||
|     { | ||||
|         std::vector<std::string> ret; | ||||
|         float total_time = 0.0f; | ||||
|         for (float t : m_color_times) | ||||
| //        for (float t : m_color_times)
 | ||||
|         for (auto t : m_custom_gcode_times) | ||||
|         { | ||||
|             std::string time = _get_time_dhms(t); | ||||
|             std::string time = _get_time_dhms(t.second); | ||||
|             if (include_remaining) | ||||
|             { | ||||
|                 time += " ("; | ||||
|                 time += _get_time_dhms(m_time - total_time); | ||||
|                 time += ")"; | ||||
|             } | ||||
|             total_time += t; | ||||
|             total_time += t.second; | ||||
|             ret.push_back(time); | ||||
|         } | ||||
|         return ret; | ||||
|  | @ -745,20 +747,42 @@ namespace Slic3r { | |||
|     { | ||||
|         std::vector<std::string> ret; | ||||
|         float total_time = 0.0f; | ||||
|         for (float t : m_color_times) | ||||
| //        for (float t : m_color_times)
 | ||||
|         for (auto t : m_custom_gcode_times) | ||||
|         { | ||||
|             std::string time = _get_time_minutes(t); | ||||
|             std::string time = _get_time_minutes(t.second); | ||||
|             if (include_remaining) | ||||
|             { | ||||
|                 time += " ("; | ||||
|                 time += _get_time_minutes(m_time - total_time); | ||||
|                 time += ")"; | ||||
|             } | ||||
|             total_time += t; | ||||
|             total_time += t.second; | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     std::vector<std::pair<CustomGcodeType, std::string>> GCodeTimeEstimator::get_custom_gcode_times_dhm(bool include_remaining) const | ||||
|     { | ||||
|         std::vector<std::pair<CustomGcodeType, std::string>> ret; | ||||
| 
 | ||||
|         float total_time = 0.0f; | ||||
|         for (auto t : m_custom_gcode_times) | ||||
|         { | ||||
|             std::string time = _get_time_dhm(t.second); | ||||
|             if (include_remaining) | ||||
|             { | ||||
|                 time += " ("; | ||||
|                 time += _get_time_dhm(m_time - total_time); | ||||
|                 time += ")"; | ||||
|             } | ||||
|             total_time += t.second; | ||||
|             ret.push_back({t.first, time}); | ||||
|         } | ||||
| 
 | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     // Return an estimate of the memory consumed by the time estimator.
 | ||||
| 	size_t GCodeTimeEstimator::memory_used() const | ||||
|     { | ||||
|  | @ -791,9 +815,9 @@ namespace Slic3r { | |||
| 
 | ||||
|         m_last_st_synchronized_block_id = -1; | ||||
| 
 | ||||
|         m_needs_color_times = false; | ||||
|         m_color_times.clear(); | ||||
|         m_color_time_cache = 0.0f; | ||||
|         m_needs_custom_gcode_times = false; | ||||
|         m_custom_gcode_times.clear(); | ||||
|         m_custom_gcode_time_cache = 0.0f; | ||||
|     } | ||||
| 
 | ||||
|     void GCodeTimeEstimator::_reset_time() | ||||
|  | @ -814,7 +838,7 @@ namespace Slic3r { | |||
|         _recalculate_trapezoids(); | ||||
| 
 | ||||
|         m_time += get_additional_time(); | ||||
|         m_color_time_cache += 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) | ||||
|         { | ||||
|  | @ -835,7 +859,7 @@ namespace Slic3r { | |||
|             it->second.time += block_time; | ||||
| #endif // ENABLE_MOVE_STATS
 | ||||
| 
 | ||||
|             m_color_time_cache += block_time; | ||||
|             m_custom_gcode_time_cache += block_time; | ||||
|         } | ||||
| 
 | ||||
|         m_last_st_synchronized_block_id = (int)m_blocks.size() - 1; | ||||
|  | @ -1466,26 +1490,34 @@ namespace Slic3r { | |||
|     { | ||||
|         std::string comment = line.comment(); | ||||
| 
 | ||||
|         // color change tag
 | ||||
|         // Color_Change_Tag
 | ||||
|         size_t pos = comment.find(Color_Change_Tag); | ||||
|         if (pos != comment.npos) | ||||
|         { | ||||
|             _process_color_change_tag(); | ||||
|             _process_custom_gcode_tag(cgtColorChange); | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         // Pause_Print_Tag
 | ||||
|         pos = comment.find(Pause_Print_Tag); | ||||
|         if (pos != comment.npos) | ||||
|         { | ||||
|             _process_custom_gcode_tag(cgtPausePrint); | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     void GCodeTimeEstimator::_process_color_change_tag() | ||||
|     void GCodeTimeEstimator::_process_custom_gcode_tag(CustomGcodeType code) | ||||
|     { | ||||
|         PROFILE_FUNC(); | ||||
|         m_needs_color_times = true; | ||||
|         m_needs_custom_gcode_times = true; | ||||
|         _calculate_time(); | ||||
|         if (m_color_time_cache != 0.0f) | ||||
|         if (m_custom_gcode_time_cache != 0.0f) | ||||
|         { | ||||
|             m_color_times.push_back(m_color_time_cache); | ||||
|             m_color_time_cache = 0.0f; | ||||
|             m_custom_gcode_times.push_back({code, m_custom_gcode_time_cache}); | ||||
|             m_custom_gcode_time_cache = 0.0f; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include "libslic3r.h" | ||||
| #include "PrintConfig.hpp" | ||||
| #include "GCodeReader.hpp" | ||||
| #include "CustomGCode.hpp" | ||||
| 
 | ||||
| #define ENABLE_MOVE_STATS 0 | ||||
| 
 | ||||
|  | @ -23,6 +24,7 @@ namespace Slic3r { | |||
|         static const std::string Silent_Last_M73_Output_Placeholder_Tag; | ||||
| 
 | ||||
|         static const std::string Color_Change_Tag; | ||||
|         static const std::string Pause_Print_Tag; | ||||
| 
 | ||||
|         enum EMode : unsigned char | ||||
|         { | ||||
|  | @ -240,10 +242,10 @@ namespace Slic3r { | |||
|         int m_last_st_synchronized_block_id; | ||||
|         float m_time; // s
 | ||||
| 
 | ||||
|         // data to calculate color print times
 | ||||
|         bool m_needs_color_times; | ||||
|         std::vector<float> m_color_times; | ||||
|         float m_color_time_cache; | ||||
|         // data to calculate custom code times
 | ||||
|         bool m_needs_custom_gcode_times; | ||||
|         std::vector<std::pair<CustomGcodeType, float>> m_custom_gcode_times; | ||||
|         float m_custom_gcode_time_cache; | ||||
| 
 | ||||
| #if ENABLE_MOVE_STATS | ||||
|         MovesStatsMap _moves_stats; | ||||
|  | @ -369,8 +371,8 @@ namespace Slic3r { | |||
|         // Returns the estimated time, in minutes (integer)
 | ||||
|         std::string get_time_minutes() const; | ||||
| 
 | ||||
|         // Returns the estimated time, in seconds, for each color
 | ||||
|         std::vector<float> get_color_times() const; | ||||
|         // Returns the estimated time, in seconds, for each custom gcode
 | ||||
|         std::vector<std::pair<CustomGcodeType, float>> get_custom_gcode_times() const; | ||||
| 
 | ||||
|         // Returns the estimated time, in format DDd HHh MMm SSs, for each color
 | ||||
|         // If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)"
 | ||||
|  | @ -380,6 +382,10 @@ namespace Slic3r { | |||
|         // If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)"
 | ||||
|         std::vector<std::string> get_color_times_minutes(bool include_remaining) const; | ||||
| 
 | ||||
|         // Returns the estimated time, in format DDd HHh MMm, for each custom_gcode
 | ||||
|         // If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)"
 | ||||
|         std::vector<std::pair<CustomGcodeType, std::string>> get_custom_gcode_times_dhm(bool include_remaining) const; | ||||
| 
 | ||||
|         // Return an estimate of the memory consumed by the time estimator.
 | ||||
|         size_t memory_used() const; | ||||
| 
 | ||||
|  | @ -460,8 +466,8 @@ namespace Slic3r { | |||
|         // Returns true if any tag has been processed
 | ||||
|         bool _process_tags(const GCodeReader::GCodeLine& line); | ||||
| 
 | ||||
|         // Processes color change tag
 | ||||
|         void _process_color_change_tag(); | ||||
|         // Processes ColorChangeTag and PausePrintTag
 | ||||
|         void _process_custom_gcode_tag(CustomGcodeType code); | ||||
| 
 | ||||
|         // Simulates firmware st_synchronize() call
 | ||||
|         void _simulate_st_synchronize(); | ||||
|  |  | |||
|  | @ -302,8 +302,8 @@ struct PrintStatistics | |||
|     PrintStatistics() { clear(); } | ||||
|     std::string                     estimated_normal_print_time; | ||||
|     std::string                     estimated_silent_print_time; | ||||
|     std::vector<std::string>        estimated_normal_color_print_times; | ||||
|     std::vector<std::string>        estimated_silent_color_print_times; | ||||
|     std::vector<std::pair<CustomGcodeType, std::string>>    estimated_normal_custom_gcode_print_times; | ||||
|     std::vector<std::pair<CustomGcodeType, std::string>>    estimated_silent_custom_gcode_print_times; | ||||
|     double                          total_used_filament; | ||||
|     double                          total_extruded_volume; | ||||
|     double                          total_cost; | ||||
|  | @ -323,8 +323,8 @@ struct PrintStatistics | |||
|     void clear() { | ||||
|         estimated_normal_print_time.clear(); | ||||
|         estimated_silent_print_time.clear(); | ||||
|         estimated_normal_color_print_times.clear(); | ||||
|         estimated_silent_color_print_times.clear(); | ||||
|         estimated_normal_custom_gcode_print_times.clear(); | ||||
|         estimated_silent_custom_gcode_print_times.clear(); | ||||
|         total_used_filament    = 0.; | ||||
|         total_extruded_volume  = 0.; | ||||
|         total_cost             = 0.; | ||||
|  |  | |||
|  | @ -696,9 +696,11 @@ std::string Control::get_color_for_color_change_tick(std::set<TickCode>::const_i | |||
|         if (it_n->gcode == ToolChangeCode) { | ||||
|             is_tool_change = true; | ||||
|             if (it_n->extruder == it->extruder) | ||||
|                 return m_extruder_colors[it->extruder-1]; // return a color for a specific extruder from the colors list 
 | ||||
|                 return it->color; | ||||
|             break; | ||||
|         } | ||||
|         if (it_n->gcode == ColorChangeCode && it_n->extruder == it->extruder) | ||||
|             return it->color; | ||||
|     } | ||||
|     if (!is_tool_change && it->extruder == def_extruder) | ||||
|         return it->color; | ||||
|  |  | |||
|  | @ -982,12 +982,17 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(  const GLCanvas3D | |||
|         cp_legend_items.emplace_back(I18N::translate_utf8(L("Pause print or custom G-code"))); | ||||
| 
 | ||||
|         int cnt = custom_gcode_per_print_z.size(); | ||||
|         int color_change_idx = color_cnt - extruders_cnt; | ||||
|         for (int i = cnt-1; i >= 0; --i) | ||||
|             if (custom_gcode_per_print_z[i].gcode == ColorChangeCode) { | ||||
|                 ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); | ||||
|                 color_pos += 4; | ||||
|                 color_in_pos -= 4; | ||||
|                 cp_legend_items.emplace_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str()); | ||||
| 
 | ||||
|                 // create label for color change item
 | ||||
|                 std::string id_str = std::to_string(color_change_idx--) + ": "; | ||||
| 
 | ||||
|                 cp_legend_items.emplace_back(id_str + (boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_print_z[i].extruder % custom_gcode_per_print_z[i].print_z).str()); | ||||
|             } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1252,23 +1252,40 @@ void Sidebar::update_sliced_info_sizer() | |||
|             else { | ||||
|                 new_label = _(L("Estimated printing time")) +" :"; | ||||
|                 info_text = ""; | ||||
|                 if (ps.estimated_normal_print_time != "N/A") { | ||||
|                     new_label += wxString::Format("\n    - %s", _(L("normal mode"))); | ||||
|                     info_text += wxString::Format("\n%s", ps.estimated_normal_print_time); | ||||
|                     for (int i = (int)ps.estimated_normal_color_print_times.size() - 1; i >= 0; --i) | ||||
|                 wxString str_color = _(L("Color")); | ||||
|                 wxString str_pause = _(L("Pause")); | ||||
| 
 | ||||
|                 auto fill_labels = [str_color, str_pause](const std::vector<std::pair<CustomGcodeType, std::string>>& times,  | ||||
|                                                           wxString& new_label, wxString& info_text) | ||||
|                 { | ||||
|                     int color_change_count = 0; | ||||
|                     for (auto time : times) | ||||
|                         if (time.first == cgtColorChange) | ||||
|                             color_change_count++; | ||||
| 
 | ||||
|                     for (int i = (int)times.size() - 1; i >= 0; --i) | ||||
|                     { | ||||
|                         new_label += wxString::Format("\n      - %s%d", _(L("Color")) + " ", i + 1); | ||||
|                         info_text += wxString::Format("\n%s", ps.estimated_normal_color_print_times[i]); | ||||
|                         if (i == 0 || times[i - 1].first == cgtPausePrint) | ||||
|                             new_label += wxString::Format("\n      - %s%d", str_color + " ", color_change_count); | ||||
|                         else if (times[i - 1].first == cgtColorChange) | ||||
|                             new_label += wxString::Format("\n      - %s%d", str_color + " ", color_change_count--); | ||||
| 
 | ||||
|                         if (i != (int)times.size() - 1 && times[i].first == cgtPausePrint) | ||||
|                             new_label += wxString::Format(" -> %s", str_pause); | ||||
| 
 | ||||
|                         info_text += wxString::Format("\n%s", times[i].second); | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 if (ps.estimated_normal_print_time != "N/A") { | ||||
|                     new_label += wxString::Format("\n   - %s", _(L("normal mode"))); | ||||
|                     info_text += wxString::Format("\n%s", ps.estimated_normal_print_time); | ||||
|                     fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text); | ||||
|                 } | ||||
|                 if (ps.estimated_silent_print_time != "N/A") { | ||||
|                     new_label += wxString::Format("\n    - %s", _(L("stealth mode"))); | ||||
|                     new_label += wxString::Format("\n   - %s", _(L("stealth mode"))); | ||||
|                     info_text += wxString::Format("\n%s", ps.estimated_silent_print_time); | ||||
|                     for (int i = (int)ps.estimated_silent_color_print_times.size() - 1; i >= 0; --i) | ||||
|                     { | ||||
|                         new_label += wxString::Format("\n      - %s%d", _(L("Color")) + " ", i + 1); | ||||
|                         info_text += wxString::Format("\n%s", ps.estimated_silent_color_print_times[i]); | ||||
|                     } | ||||
|                     fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text); | ||||
|                 } | ||||
|                 p->sliced_info->SetTextAndShow(siEstimatedTime,  info_text,      new_label); | ||||
|             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka