diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8bb921406..709597cba 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -803,8 +803,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ // starts analyzer calculations if (m_enable_analyzer) { BOOST_LOG_TRIVIAL(debug) << "Preparing G-code preview data" << log_memory_info(); - GCodeTimeEstimator* time_estimator = &m_normal_time_estimator; - m_analyzer.calc_gcode_preview_data(*preview_data, *time_estimator, [print]() { print->throw_if_canceled(); }); + m_analyzer.calc_gcode_preview_data(*preview_data, m_normal_time_estimator, [print]() { print->throw_if_canceled(); }); m_analyzer.reset(); } @@ -2504,7 +2503,7 @@ void GCode::process_layer( //switch to mill gcode += "; milling ok\n"; uint32_t current_extruder_filament = m_writer.tool()->id(); - uint32_t milling_extruder_id = config().nozzle_diameter.values.size(); + uint32_t milling_extruder_id = uint32_t(config().nozzle_diameter.values.size()); gcode += "; toolchange:\n"; gcode += m_writer.toolchange(milling_extruder_id); gcode += "; toolchange done\n"; diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index c7e33e82c..431bcdacc 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -22,7 +22,8 @@ static const unsigned int DEFAULT_COLOR_PRINT_ID = 0; static const Slic3r::Vec3d DEFAULT_START_POSITION = Slic3r::Vec3d(0.0f, 0.0f, 0.0f); static const float DEFAULT_START_EXTRUSION = 0.0f; static const float DEFAULT_FAN_SPEED = 0.0f; -static const float DEFAULT_LAYER_TIME = 0.0f; +static const float DEFAULT_LAYER_DURATION = 0.0f; +static const float DEFAULT_LAYER_ELAPSED_TIME = 0.0f; namespace Slic3r { @@ -47,12 +48,13 @@ GCodeAnalyzer::Metadata::Metadata() , height(GCodeAnalyzer::Default_Height) , feedrate(DEFAULT_FEEDRATE) , fan_speed(DEFAULT_FAN_SPEED) - , layer_time(DEFAULT_LAYER_TIME) + , layer_duration(DEFAULT_LAYER_DURATION) + , layer_elapsed_time(DEFAULT_LAYER_ELAPSED_TIME) , cp_color_id(DEFAULT_COLOR_PRINT_ID) { } -GCodeAnalyzer::Metadata::Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, float fan_speed, float layer_time, unsigned int cp_color_id/* = 0*/) +GCodeAnalyzer::Metadata::Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, float fan_speed, float layer_duration, float layer_elapsed_time, unsigned int cp_color_id) : extrusion_role(extrusion_role) , extruder_id(extruder_id) , mm3_per_mm(mm3_per_mm) @@ -60,7 +62,8 @@ GCodeAnalyzer::Metadata::Metadata(ExtrusionRole extrusion_role, unsigned int ext , height(height) , feedrate(feedrate) , fan_speed(fan_speed) - , layer_time(layer_time) + , layer_duration(layer_duration) + , layer_elapsed_time(layer_elapsed_time) , cp_color_id(cp_color_id) { } @@ -88,7 +91,7 @@ bool GCodeAnalyzer::Metadata::operator != (const GCodeAnalyzer::Metadata& other) if (fan_speed != other.fan_speed) return true; - if (layer_time != other.layer_time) + if (layer_duration != other.layer_duration) return true; if (cp_color_id != other.cp_color_id) @@ -97,9 +100,11 @@ bool GCodeAnalyzer::Metadata::operator != (const GCodeAnalyzer::Metadata& other) return false; } -GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, float fan_speed, float layer_time, unsigned int cp_color_id/* = 0*/) +GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, + float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, + float fan_speed, float layer_duration, float layer_elapsed_time, unsigned int cp_color_id) : type(type) - , data(extrusion_role, extruder_id, mm3_per_mm, width, height, feedrate, fan_speed, layer_time, cp_color_id) + , data(extrusion_role, extruder_id, mm3_per_mm, width, height, feedrate, fan_speed, layer_duration, layer_elapsed_time, cp_color_id) , start_position(start_position) , end_position(end_position) , delta_extruder(delta_extruder) @@ -137,7 +142,7 @@ void GCodeAnalyzer::reset() _set_start_position(DEFAULT_START_POSITION); _set_start_extrusion(DEFAULT_START_EXTRUSION); _set_fan_speed(DEFAULT_FAN_SPEED); - _set_layer_time(DEFAULT_LAYER_TIME); + _set_layer_duration(DEFAULT_LAYER_DURATION); _reset_axes_position(); _reset_axes_origin(); _reset_cached_position(); @@ -855,14 +860,14 @@ float GCodeAnalyzer::_get_fan_speed() const return m_state.data.fan_speed; } -void GCodeAnalyzer::_set_layer_time(float layer_time_sec) +void GCodeAnalyzer::_set_layer_duration(float layer_duration_sec) { - m_state.data.layer_time = layer_time_sec; + m_state.data.layer_duration = layer_duration_sec; } -float GCodeAnalyzer::_get_layer_time() const +float GCodeAnalyzer::_get_layer_duration() const { - return m_state.data.layer_time; + return m_state.data.layer_duration; } void GCodeAnalyzer::_set_axis_position(EAxis axis, float position) @@ -952,7 +957,9 @@ void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type) Vec3d start_position = _get_start_position() + extruder_offset; Vec3d end_position = _get_end_position() + extruder_offset; - it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), _get_fan_speed(), _get_layer_time(), _get_cp_color_id()); + it->second.emplace_back(type, _get_extrusion_role(), extruder_id, _get_mm3_per_mm(), + _get_width(), _get_height(), _get_feedrate(), start_position, end_position, _get_delta_extrusion(), + _get_fan_speed(), _get_layer_duration(), m_state.data.layer_elapsed_time, _get_cp_color_id()); } bool GCodeAnalyzer::_is_valid_extrusion_role(int value) const @@ -996,7 +1003,8 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ path.extruder_id = data.extruder_id; path.cp_color_id = data.cp_color_id; path.fan_speed = data.fan_speed; - path.layer_time = data.layer_time; + path.layer_duration = data.layer_duration; + path.elapsed_time = data.layer_elapsed_time; } } }; @@ -1015,18 +1023,19 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ GCodePreviewData::MultiRange feedrate_range; GCodePreviewData::Range volumetric_rate_range; GCodePreviewData::Range fan_speed_range; - GCodePreviewData::Range layer_time_range; + GCodePreviewData::Range layer_duration_range; + GCodePreviewData::Range elapsed_time_range; // to avoid to call the callback too often unsigned int cancel_callback_threshold = (unsigned int)std::max((int)extrude_moves->second.size() / 25, 1); unsigned int cancel_callback_curr = 0; - time_estimator.calculate_layer_time(); + time_estimator.calculate_layer_duration(); for (GCodeMove& move : extrude_moves->second) { z = (float)move.start_position.z(); - float layer_timet = time_estimator.get_layer_time(z); - move.data.layer_time = layer_timet; + move.data.layer_duration = time_estimator.get_layer_duration(z); + move.data.layer_elapsed_time += time_estimator.get_layer_time(z); } time_estimator.reset_layers(); @@ -1060,7 +1069,8 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ feedrate_range.update_from(move.data.feedrate, GCodePreviewData::FeedrateKind::EXTRUSION); volumetric_rate_range.update_from(volumetric_rate); fan_speed_range.update_from(move.data.fan_speed); - layer_time_range.update_from(move.data.layer_time); + layer_duration_range.update_from(move.data.layer_duration); + elapsed_time_range.update_from(move.data.layer_elapsed_time); } else // append end vertex of the move to current polyline @@ -1080,7 +1090,8 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ preview_data.ranges.feedrate.update_from(feedrate_range); preview_data.ranges.volumetric_rate.update_from(volumetric_rate_range); preview_data.ranges.fan_speed.update_from(fan_speed_range); - preview_data.ranges.layer_time.update_from(layer_time_range); + preview_data.ranges.layer_duration.update_from(layer_duration_range); + preview_data.ranges.elapsed_time.update_from(elapsed_time_range); // we need to sort the layers by their z as they can be shuffled in case of sequential prints std::sort(preview_data.extrusion.layers.begin(), preview_data.extrusion.layers.end(), [](const GCodePreviewData::Extrusion::Layer& l1, const GCodePreviewData::Extrusion::Layer& l2)->bool { return l1.z < l2.z; }); diff --git a/src/libslic3r/GCode/Analyzer.hpp b/src/libslic3r/GCode/Analyzer.hpp index 08cf312cc..54fede8b9 100644 --- a/src/libslic3r/GCode/Analyzer.hpp +++ b/src/libslic3r/GCode/Analyzer.hpp @@ -60,11 +60,13 @@ public: float height; // mm float feedrate; // mm/s float fan_speed; // percentage - float layer_time; //s + float layer_duration; //s + float layer_elapsed_time; //s unsigned int cp_color_id; Metadata(); - Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, float fan_speed, float layer_time, unsigned int cp_color_id = 0); + Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, + float width, float height, float feedrate, float fan_speed, float layer_duration, float layer_elapsed_time, unsigned int cp_color_id); bool operator != (const Metadata& other) const; }; @@ -88,7 +90,9 @@ public: Vec3d end_position; float delta_extruder; - GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, float fan_speed, float layer_time, unsigned int cp_color_id = 0); + GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, + float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder, + float fan_speed, float layer_duration, float layer_elapsed_time, unsigned int cp_color_id); GCodeMove(EType type, const Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder); }; @@ -264,8 +268,8 @@ private: void _set_fan_speed(float fan_speed_percentage); float _get_fan_speed() const; - void _set_layer_time(float layer_time_sec); - float _get_layer_time() const; + void _set_layer_duration(float layer_duration_sec); + float _get_layer_duration() const; void _set_axis_position(EAxis axis, float position); float _get_axis_position(EAxis axis) const; diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index 678fe03a1..4298219f8 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -263,7 +263,8 @@ void GCodePreviewData::reset() ranges.fan_speed.reset(); ranges.volumetric_rate.reset(); ranges.fan_speed.reset(); - ranges.layer_time.reset(); + ranges.layer_duration.reset(); + ranges.elapsed_time.reset(); extrusion.layers.clear(); travel.polylines.clear(); retraction.positions.clear(); @@ -300,14 +301,19 @@ Color GCodePreviewData::get_fan_speed_color(float fan_speed) const return ranges.fan_speed.get_color_at(fan_speed); } -Color GCodePreviewData::get_layer_time_color(float layer_time) const +Color GCodePreviewData::get_layer_duration_color(float layer_time) const { - return ranges.layer_time.get_color_at(layer_time); + return ranges.layer_duration.get_color_at(layer_time); } -Color GCodePreviewData::get_layer_time_log_color(float layer_time) const +Color GCodePreviewData::get_layer_duration_log_color(float layer_time) const { - return ranges.layer_time.get_color_at(layer_time, true); + return ranges.layer_duration.get_color_at(layer_time, true); +} + +Color GCodePreviewData::get_elapsed_time_color(float elapsed_time) const +{ + return ranges.elapsed_time.get_color_at(elapsed_time); } Color GCodePreviewData::get_volumetric_rate_color(float rate) const @@ -497,12 +503,17 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: } case Extrusion::LayerTime: { - Helper::FillListFromRange(items, ranges.layer_time, 1, 1.0f, true); + Helper::FillListFromRange(items, ranges.layer_duration, 1, 1.0f, true); break; } case Extrusion::LayerTimeLog: { - Helper::FillListFromRange(items, ranges.layer_time, 1, 1.0f, true, true); + Helper::FillListFromRange(items, ranges.layer_duration, 1, 1.0f, true, true); + break; + } + case Extrusion::Chronology: + { + Helper::FillListFromRange(items, ranges.elapsed_time, 1, 1.0f, true); break; } case Extrusion::VolumetricRate: diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index f2f8f3a36..c97229f55 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -202,7 +202,9 @@ public: // Color mapping by fan speed. Range fan_speed; // Color mapping by layer time. - Range layer_time; + Range layer_duration; + // Color mapping by time. + Range elapsed_time; // Color mapping by volumetric extrusion rate. Range volumetric_rate; }; @@ -228,6 +230,7 @@ public: FanSpeed, LayerTime, LayerTimeLog, + Chronology, VolumetricRate, Tool, Filament, @@ -259,7 +262,9 @@ public: // Fan speed for the extrusion, used for visualization purposes. float fan_speed; // Layer time for the extrusion, used for visualization purposes. - float layer_time; + float layer_duration; + // time since print start, used for visualization purposes. + float elapsed_time; }; using Paths = std::vector; @@ -385,8 +390,9 @@ public: Color get_width_color(float width) const; Color get_feedrate_color(float feedrate) const; Color get_fan_speed_color(float fan_speed) const; - Color get_layer_time_color(float layer_time) const; - Color get_layer_time_log_color(float layer_time) const; + Color get_layer_duration_color(float layer_time) const; + Color get_layer_duration_log_color(float layer_time) const; + Color get_elapsed_time_color(float elapsed_time) const; Color get_volumetric_rate_color(float rate) const; void set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha); diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 17ba4abc1..928146238 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -854,7 +854,7 @@ namespace Slic3r { block_time += block.deceleration_time(); m_time += block_time; block.elapsed_time = m_time; - block.time = block_time; + block.duration = block_time; #if ENABLE_MOVE_STATS MovesStatsMap::iterator it = _moves_stats.find(block.move_type); @@ -1032,7 +1032,6 @@ namespace Slic3r { // updates axes positions from line float new_pos[Num_Axis]; - long raw_axis_absolute_position; for (unsigned char a = X; a < Num_Axis; ++a) { new_pos[a] = axis_absolute_position((EAxis)a, line); @@ -1696,7 +1695,7 @@ namespace Slic3r { m_layers.clear(); } - void GCodeTimeEstimator::calculate_layer_time() + void GCodeTimeEstimator::calculate_layer_duration() { for (int i = 0; i < (int)m_blocks.size(); ++i) { @@ -1707,30 +1706,43 @@ namespace Slic3r { while (j < (int)m_layers.size()) { if (m_blocks[i].z == m_layers[j].z) { - m_layers[j].time += m_blocks[i].time; + m_layers[j].duration += m_blocks[i].duration; + m_layers[j].min_time = std::min(m_layers[j].min_time, m_blocks[i].elapsed_time); layer_found = true; } j++; } if (!layer_found) { - m_layers.push_back({ m_blocks[i].z, m_blocks[i].time }); + m_layers.emplace_back( m_blocks[i].z, m_blocks[i].duration, m_blocks[i].elapsed_time ); } } } + std::sort(m_layers.begin(), m_layers.end(), [](const Layer& e1, const Layer& e2){return e1.z < e2.z; }); + } + + float GCodeTimeEstimator::get_layer_duration(float z) + { + for (const Layer &layer : m_layers) + { + if (z <= layer.z + EPSILON) { + return layer.duration; + } + } + return 0; } float GCodeTimeEstimator::get_layer_time(float z) { - int j = 0; - while (j < (int)m_layers.size()) + float time = 0; + for (const Layer& layer : m_layers) { - if (z == m_layers[j].z) { - return m_layers[j].time; + if (z <= layer.z + EPSILON) { + return time; } - j++; + time += layer.duration; } return 0; - } + } #if ENABLE_MOVE_STATS void GCodeTimeEstimator::_log_moves_stats() const diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index feaf3fbee..d9facd7cb 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -162,7 +162,7 @@ namespace Slic3r { FeedrateProfile feedrate; Trapezoid trapezoid; float elapsed_time; - float time; + float duration; Block(); @@ -209,7 +209,12 @@ namespace Slic3r { struct Layer { float z; - float time; + float duration; + float min_time; + + Layer(float z, float duration, float min_time) + : z(z), duration(duration), min_time(min_time) + {} }; typedef std::vector LayersList; @@ -365,7 +370,9 @@ namespace Slic3r { void set_additional_time(float timeSec); float get_additional_time() const; - void calculate_layer_time(); + //function for layer duration + void calculate_layer_duration(); + float get_layer_duration(float z); float get_layer_time(float z); void reset_layers(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9985577cc..73ecd8699 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6206,9 +6206,11 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat case GCodePreviewData::Extrusion::FanSpeed: return path.fan_speed; case GCodePreviewData::Extrusion::LayerTime: - return path.layer_time; + return path.layer_duration; case GCodePreviewData::Extrusion::LayerTimeLog: - return path.layer_time; + return path.layer_duration; + case GCodePreviewData::Extrusion::Chronology: + return path.elapsed_time; case GCodePreviewData::Extrusion::VolumetricRate: return path.feedrate * (float)path.mm3_per_mm; case GCodePreviewData::Extrusion::Tool: @@ -6238,9 +6240,11 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat case GCodePreviewData::Extrusion::FanSpeed: return data.get_fan_speed_color(value); case GCodePreviewData::Extrusion::LayerTime: - return data.get_layer_time_color(value); + return data.get_layer_duration_color(value); case GCodePreviewData::Extrusion::LayerTimeLog: - return data.get_layer_time_log_color(value); + return data.get_layer_duration_log_color(value); + case GCodePreviewData::Extrusion::Chronology: + return data.get_elapsed_time_color(value); case GCodePreviewData::Extrusion::VolumetricRate: return data.get_volumetric_rate_color(value); case GCodePreviewData::Extrusion::Tool: diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 0054a5959..a58f95177 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -242,7 +242,9 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view m_choice_view_type->Append(_(L("Width"))); m_choice_view_type->Append(_(L("Speed"))); m_choice_view_type->Append(_(L(width_screen == tiny ? "Fan" : "Fan speed"))); - m_choice_view_type->Append(_(L(width_screen == tiny ?"time":"Layer time"))); + m_choice_view_type->Append(_(L(width_screen == tiny ? "time" : "Layer time"))); + m_choice_view_type->Append(_(L(width_screen == tiny ? "Log time" : "Layer time (log)"))); + m_choice_view_type->Append(_(L(width_screen == tiny ? "Chrono" : "Chronology"))); m_choice_view_type->Append(_(L(width_screen == tiny ? "Vol. flow" :"Volumetric flow rate"))); m_choice_view_type->Append(_(L("Tool"))); m_choice_view_type->Append(_(L("Filament")));